Merge branch 'master' into opengl-es-v2

Conflicts:
	src/mesa/main/dd.h
diff --git a/.gitignore b/.gitignore
index 1c3d446..f43ff37 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
 *.ilk
 *.o
 *.obj
+*.os
 *.pc
 *.pdb
 *.pyc
diff --git a/Makefile b/Makefile
index b74e848..16395bc 100644
--- a/Makefile
+++ b/Makefile
@@ -105,6 +105,7 @@
 irix6-o32 \
 irix6-o32-static \
 linux \
+linux-i965 \
 linux-alpha \
 linux-alpha-static \
 linux-cell \
@@ -183,7 +184,7 @@
 
 # Rules for making release tarballs
 
-VERSION=7.7-devel
+VERSION=7.7
 DIRECTORY = Mesa-$(VERSION)
 LIB_NAME = MesaLib-$(VERSION)
 DEMO_NAME = MesaDemos-$(VERSION)
@@ -226,6 +227,11 @@
 	$(DIRECTORY)/include/GL/vms_x_fix.h				\
 	$(DIRECTORY)/include/GL/wglext.h				\
 	$(DIRECTORY)/include/GL/wmesa.h					\
+	$(DIRECTORY)/src/glsl/Makefile					\
+	$(DIRECTORY)/src/glsl/Makefile.template				\
+	$(DIRECTORY)/src/glsl/*/Makefile				\
+	$(DIRECTORY)/src/glsl/*/SConscript				\
+	$(DIRECTORY)/src/glsl/*/*.[ch]					\
 	$(DIRECTORY)/src/Makefile					\
 	$(DIRECTORY)/src/mesa/Makefile*					\
 	$(DIRECTORY)/src/mesa/sources.mak				\
@@ -241,7 +247,6 @@
 	$(DIRECTORY)/src/mesa/shader/*.[chly]				\
 	$(DIRECTORY)/src/mesa/shader/Makefile				\
 	$(DIRECTORY)/src/mesa/shader/descrip.mms			\
-	$(DIRECTORY)/src/mesa/shader/grammar/*.[ch]			\
 	$(DIRECTORY)/src/mesa/shader/slang/*.[ch]			\
 	$(DIRECTORY)/src/mesa/shader/slang/descrip.mms			\
 	$(DIRECTORY)/src/mesa/shader/slang/library/*.[ch]		\
@@ -455,8 +460,7 @@
 	$(DIRECTORY)/progs/windml/Makefile.ugl		\
 	$(DIRECTORY)/progs/windml/*.c			\
 	$(DIRECTORY)/progs/windml/*.bmp			\
-	$(DIRECTORY)/progs/ggi/*.c			\
-	$(DIRECTORY)/windows/VC7/progs/progs.sln
+	$(DIRECTORY)/progs/ggi/*.c
 
 GLUT_FILES = \
 	$(DIRECTORY)/include/GL/glut.h			\
@@ -479,9 +483,7 @@
 	$(DIRECTORY)/src/glut/mini/glut.pc.in		\
 	$(DIRECTORY)/src/glut/directfb/Makefile		\
 	$(DIRECTORY)/src/glut/directfb/NOTES		\
-	$(DIRECTORY)/src/glut/directfb/*[ch]		\
-	$(DIRECTORY)/windows/VC6/progs/glut/glut.dsp	\
-	$(DIRECTORY)/windows/VC7/progs/glut/glut.vcproj
+	$(DIRECTORY)/src/glut/directfb/*[ch]
 
 DEPEND_FILES = \
 	$(TOP)/src/mesa/depend		\
diff --git a/SConstruct b/SConstruct
index d53f440..5f6933e 100644
--- a/SConstruct
+++ b/SConstruct
@@ -32,10 +32,10 @@
 default_statetrackers = 'mesa'
 
 if common.default_platform in ('linux', 'freebsd', 'darwin'):
-	default_drivers = 'softpipe,failover,i915,trace,identity,llvmpipe'
+	default_drivers = 'softpipe,failover,svga,i915,i965,trace,identity,llvmpipe'
 	default_winsys = 'xlib'
 elif common.default_platform in ('winddk',):
-	default_drivers = 'softpipe,i915,trace,identity'
+	default_drivers = 'softpipe,svga,i915,i965,trace,identity'
 	default_winsys = 'all'
 else:
 	default_drivers = 'all'
@@ -46,9 +46,9 @@
 opts.Add(ListVariable('statetrackers', 'state trackers to build', default_statetrackers,
                      ['mesa', 'python', 'xorg']))
 opts.Add(ListVariable('drivers', 'pipe drivers to build', default_drivers,
-                     ['softpipe', 'failover', 'i915', 'cell', 'trace', 'r300', 'identity', 'llvmpipe']))
+                     ['softpipe', 'failover', 'svga', 'i915', 'i965', 'trace', 'r300', 'identity', 'llvmpipe']))
 opts.Add(ListVariable('winsys', 'winsys drivers to build', default_winsys,
-                     ['xlib', 'intel', 'gdi', 'radeon']))
+                     ['xlib', 'vmware', 'intel', 'i965', 'gdi', 'radeon']))
 
 opts.Add(EnumVariable('MSVS_VERSION', 'MS Visual C++ version', None, allowed_values=('7.1', '8.0', '9.0')))
 
@@ -97,6 +97,9 @@
 	'#/src/gallium/drivers',
 ])
 
+if env['msvc']:
+    env.Append(CPPPATH = ['#include/c99'])
+
 
 # Posix
 if platform in ('posix', 'linux', 'freebsd', 'darwin'):
@@ -160,8 +163,36 @@
 # TODO: Build several variants at the same time?
 # http://www.scons.org/wiki/SimultaneousVariantBuilds
 
+if env['platform'] != common.default_platform:
+    # GLSL code has to be built twice -- one for the host OS, another for the target OS...
+
+    host_env = Environment(
+        # options are ignored
+        # default tool is used
+        tools = ['default', 'custom'],
+        toolpath = ['#scons'],	
+        ENV = os.environ,
+    )
+
+    host_env['platform'] = common.default_platform
+    host_env['machine'] = common.default_machine
+    host_env['debug'] = env['debug']
+
+    SConscript(
+        'src/glsl/SConscript',
+        variant_dir = os.path.join(env['build'], 'host'),
+        duplicate = 0, # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html
+        exports={'env':host_env},
+    )
+
 SConscript(
 	'src/SConscript',
 	variant_dir = env['build'],
 	duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html
 )
+
+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/bin/mklib b/bin/mklib
index db97087..9799a4e 100755
--- a/bin/mklib
+++ b/bin/mklib
@@ -25,6 +25,124 @@
 # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
+# Given a list of files, look for .a archives and unpack them.
+# Return the original list of files minus the .a files plus the unpacked files.
+expand_archives() {
+    DIR=$1
+    shift
+    FILES=$@
+    NEWFILES=""
+    ORIG_DIR=`pwd`
+    mkdir -p "$DIR"
+    cd "$DIR"
+    for FILE in $FILES ; do
+        case $FILE in
+            *.a)
+                # extract the .o files from this .a archive
+                case $FILE in
+                    /*) ;;
+                    *)  FILE="$ORIG_DIR/$FILE" ;;
+                esac
+                MEMBERS=`ar t $FILE`
+                ar x $FILE
+                for MEMBER in $MEMBERS ; do
+                    NEWFILES="$NEWFILES $DIR/$MEMBER"
+                done
+                ;;
+            *)
+                # other file type, just add to list
+                NEWFILES="$NEWFILES $FILE"
+                ;;
+        esac
+    done
+    cd "$ORIG_DIR"
+    echo $NEWFILES
+}
+
+
+# Given a list of files, look for .a archives and return a list of all objects
+# in the .a archives.
+contents_of_archives() {
+    FILES=$@
+    NEWFILES=""
+    for FILE in $FILES ; do
+        case $FILE in
+            *.a)
+                # get list of members in this .a archive
+                MEMBERS=`ar t $FILE`
+                NEWFILES="$NEWFILES $MEMBERS"
+                ;;
+            *)
+                # skip other file types
+                ;;
+        esac
+    done
+    echo $NEWFILES
+}
+
+
+# Make static library with 'ar'
+# params:
+#    options to ar
+#    1 or 0 to indicate if ranlib should be run
+#    libname to make
+#    list of object files
+# Return name of library we made
+# Example: "make_ar_static_lib -ru 1 libfoo.a foo.o bar.o"
+make_ar_static_lib() {
+    OPTS=$1
+    shift;
+    RANLIB=$1
+    shift;
+    LIBNAME=$1
+    shift;
+    OBJECTS=$@
+
+    # remove existing lib, if present
+    rm -f ${LIBNAME}
+
+    # make static lib
+    ar ${OPTS} ${LIBNAME} ${OBJECTS}
+
+    # run ranlib
+    if [ ${RANLIB} = 1 ] ; then
+        ranlib ${LIBNAME}
+    fi
+
+    echo ${LIBNAME}
+}
+
+
+# Print usage info.
+usage() {
+    echo 'Usage: mklib [options] objects'
+    echo 'Create a shared library from object files.'
+    echo '  -o LIBRARY    specifies the name of the resulting library, without'
+    echo '                the leading "lib" or any suffix.'
+    echo '                (eg: "-o GL" might result in "libGL.so" being made)'
+    echo '  -major N      specifies major version number (default is 1)'
+    echo '  -minor N      specifies minor version number (default is 0)'
+    echo '  -patch N      specifies patch version number (default is 0)'
+    echo '  -lLIBRARY     specifies a dependency on LIBRARY'
+    echo '  -LDIR         search in DIR for library dependencies at build time'
+    echo '  -RDIR         search in DIR for library dependencies at run time'
+    echo '  -linker L     explicity specify the linker program to use (eg: gcc, g++)'
+    echo '                Not observed on all systems at this time.'
+    echo '  -ldflags OPT  specify any additional linker flags in OPT'
+    echo '  -cplusplus    link with C++ runtime'
+    echo '  -static       make a static library (default is dynamic/shared)'
+    echo '  -dlopen       make a shared library suitable for dynamic loading'
+    echo '  -install DIR  put resulting library file(s) in DIR'
+    echo '  -arch ARCH    override using `uname` to determine host system'
+    echo '  -archopt OPT  specify an extra achitecture-specific option OPT'
+    echo '  -altopts OPTS alternate options to override all others'
+    echo "  -noprefix     don't prefix library name with 'lib' nor add any suffix"
+    echo '  -exports FILE only export the symbols listed in FILE'
+    echo '  -id NAME      Sets the id of the dylib (Darwin)'
+    echo '  -h, --help    display this information and exit'
+}
+
+
 #
 # Option defaults
 #
@@ -52,31 +170,7 @@
 do
     case $1 in
 	'-h' | '--help')
-	    echo 'Usage: mklib [options] objects'
-	    echo 'Create a shared library from object files.'
-	    echo '  -o LIBRARY    specifies the name of the resulting library, without'
-	    echo '                the leading "lib" or any suffix.'
-	    echo '                (eg: "-o GL" might result in "libGL.so" being made)'
-	    echo '  -major N      specifies major version number (default is 1)'
-	    echo '  -minor N      specifies minor version number (default is 0)'
-	    echo '  -patch N      specifies patch version number (default is 0)'
-	    echo '  -lLIBRARY     specifies a dependency on LIBRARY'
-	    echo '  -LDIR         search in DIR for library dependencies at build time'
-	    echo '  -RDIR         search in DIR for library dependencies at run time'
-	    echo '  -linker L     explicity specify the linker program to use (eg: gcc, g++)'
-	    echo '                Not observed on all systems at this time.'
-	    echo '  -ldflags OPT  specify any additional linker flags in OPT'
-	    echo '  -cplusplus    link with C++ runtime'
-	    echo '  -static       make a static library (default is dynamic/shared)'
-	    echo '  -dlopen       make a shared library suitable for dynamic loading'
-	    echo '  -install DIR  put resulting library file(s) in DIR'
-	    echo '  -arch ARCH    override using `uname` to determine host system'
-	    echo '  -archopt OPT  specify an extra achitecture-specific option OPT'
-	    echo '  -altopts OPTS alternate options to override all others'
-	    echo "  -noprefix     don't prefix library name with 'lib' nor add any suffix"
-	    echo '  -exports FILE only export the symbols listed in FILE'
-	    echo '  -id NAME      Sets the id of the dylib (Darwin)'
-	    echo '  -h, --help    display this information and exit'
+	    usage
 	    exit 1
 	    ;;
 	'-o')
@@ -197,11 +291,11 @@
 # Error checking
 #
 if [ "x${LIBNAME}" = "x" ] ; then
-    echo "mklib: Error: no library name specified"
+    echo "mklib: Error: no library name specified (-h for help)"
     exit 1
 fi
 if [ "x${OBJECTS}" = "x" ] ; then
-    echo "mklib: Error: no object files specified"
+    echo "mklib: Error: no object files specified (-h for help)"
     exit 1
 fi
 
@@ -269,45 +363,24 @@
             # finish up
             FINAL_LIBS="${LIBNAME}"
         elif [ $STATIC = 1 ] ; then
+	    # make a static .a library
             LIBNAME="lib${LIBNAME}.a"     # prefix with "lib", suffix with ".a"
             echo "mklib: Making" $ARCH "static library: " ${LIBNAME}
-            LINK="ar"
             OPTS="-ru"
             if [ "${ALTOPTS}" ] ; then
                 OPTS=${ALTOPTS}
             fi
-            rm -f ${LIBNAME}
 
-	    # expand any .a objects into constituent .o files.
-	    NEWOBJECTS=""
-	    DELETIA=""
-	    for OBJ in $OBJECTS ; do
-		case $OBJ in
-		    *.a)
-			# extract the .o files from this .a archive
-			FILES=`ar t $OBJ`
-			ar x $OBJ
-			NEWOBJECTS="$NEWOBJECTS $FILES"
-			# keep track of temporary .o files and delete them below
-			DELETIA="$DELETIA $FILES"
-			;;
-		    *)
-			# ordinary .o file
-			NEWOBJECTS="$NEWOBJECTS $OBJ"
-			;;
-		esac
-	    done
+	    # expand .a into .o files
+	    NEW_OBJECTS=`expand_archives ${LIBNAME}.obj $OBJECTS`
 
-            # make lib
-            ${LINK} ${OPTS} ${LIBNAME} ${NEWOBJECTS}
-            ranlib ${LIBNAME}
+            # make static lib
+	    FINAL_LIBS=`make_ar_static_lib ${OPTS} 1 ${LIBNAME} ${NEW_OBJECTS}`
 
 	    # remove temporary extracted .o files
-	    rm -f ${DELETIA}
-
-            # finish up
-            FINAL_LIBS=${LIBNAME}
+	    rm -rf ${LIBNAME}.obj
         else
+	    # make dynamic library
 	    LIBNAME="lib${LIBNAME}"     # prefix with "lib"
 	    case $ARCH in 'Linux' | 'GNU' | GNU/*)
 		OPTS="-Xlinker -Bsymbolic -shared -Wl,-soname,${LIBNAME}.so.${MAJOR}"
@@ -368,9 +441,7 @@
         if [ $STATIC = 1 ] ; then
 	    LIBNAME="lib${LIBNAME}.a"
 	    echo "mklib: Making SunOS static library: " ${LIBNAME}
-	    rm -f ${LIBNAME}
-	    ar -ruv ${LIBNAME} ${OBJECTS}
-	    FINAL_LIBS=${LIBNAME}
+	    FINAL_LIBS=`make_ar_static_lib -ruv 0 ${LIBNAME} ${OBJECTS}`
 	else
 	    if [ $NOPREFIX = 0 ] ; then
 		LIBNAME="lib${LIBNAME}.so"
@@ -489,13 +560,19 @@
 	    ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
 	    FINAL_LIBS=${LIBNAME}
         elif [ $STATIC = 1 ] ; then
+	    # make a static .a library
 	    STLIB="lib${LIBNAME}.a"
 	    echo "mklib: Making FreeBSD static library: " ${STLIB}
-	    rm -f ${STLIB}
-	    ar cq ${STLIB} ${OBJECTS}
-	    ranlib ${STLIB}
-	    FINAL_LIBS=${STLIB}
+
+	    # expand .a into .o files
+	    NEW_OBJECTS=`expand_archives ${STLIB}.obj $OBJECTS`
+
+	    FINAL_LIBS=`make_ar_static_lib cq 1 ${STLIB} ${NEW_OBJECTS}`
+
+	    # remove temporary extracted .o files
+	    rm -rf ${STLIB}.obj
 	else
+	    # make dynamic library
 	    SHLIB="lib${LIBNAME}.so.${MAJOR}"
 	    OPTS="-shared -Wl,-soname,${SHLIB}"
             if [ "${ALTOPTS}" ] ; then
@@ -513,10 +590,7 @@
         if [ $STATIC = 1 ] ; then
 	    LIBNAME="lib${LIBNAME}_pic.a"
 	    echo "mklib: Making NetBSD PIC static library: " ${LIBNAME}
-	    rm -f ${LIBNAME}
-	    ar cq ${LIBNAME} ${OBJECTS}
-	    ranlib ${LIBNAME}
-	    FINAL_LIBS=${LIBNAME}
+	    FINAL_LIBS=`make_ar_static_lib cq 1 ${LIBNAME} ${OBJECTS}`
 	else
 	    LIBNAME="lib${LIBNAME}.so.${MAJOR}.${MINOR}"
 	    echo "mklib: Making NetBSD PIC shared library: " ${LIBNAME}
@@ -529,9 +603,7 @@
     'IRIX' | 'IRIX64')
         if [ $STATIC = 1 ] ; then
 	    LIBNAME="lib${LIBNAME}.a"
-	    rm -f ${LIBNAME}
-	    ar rc ${LIBNAME} ${OBJECTS}
-	    FINAL_LIBS=${LIBNAME}
+	    FINAL_LIBS=`make_ar_static_lib rc 0 ${LIBNAME} ${OBJECTS}`
 	else
 	    LIBNAME="lib${LIBNAME}.so"  # prefix with "lib", suffix with ".so"
 
@@ -582,9 +654,7 @@
         if [ $STATIC = 1 ] ; then
 	    LIBNAME="lib${LIBNAME}.a"
 	    echo "mklib: Making HP-UX static library: " ${LIBNAME}
-	    rm -f ${LIBNAME}
-	    ar -ruv ${LIBNAME} ${OBJECTS}
-	    FINAL_LIBS=${LIBNAME}
+    	    FINAL_LIBS=`make_ar_static_lib -ruv 0 ${LIBNAME} ${OBJECTS}`
 	else
             # HP uses a .2 for their current GL/GLU libraries
 	    if [ ${LIBNAME} = "GL" -o ${LIBNAME} = "GLU" ] ; then
@@ -614,8 +684,7 @@
 	if [ $STATIC = 1 ] ; then
 	    LIBNAME="lib${LIBNAME}.a"
 	    echo "mklib: Making AIX static library: " ${LIBNAME}
-	    ar -ruv ${X64} ${LIBNAME} ${OBJECTS}
-	    FINAL_LIBS=${LIBNAME}
+    	    FINAL_LIBS=`make_ar_static_lib -ruv 0 ${LIBNAME} ${OBJECTS}`
 	else
 	    EXPFILE="lib${LIBNAME}.exp"
 	    LIBNAME="lib${LIBNAME}.a"  # shared objects are still stored in the .a libraries
@@ -666,9 +735,7 @@
         if [ $STATIC = 1 ] ; then
 	    LIBNAME="lib${LIBNAME}.a"
 	    echo "mklib: Making OSF/1 static library: " ${LIBNAME}
-	    rm -f ${LIBNAME}
-	    ar -ruv ${LIBNAME} ${OBJECTS}
-	    FINAL_LIBS=${LIBNAME}
+    	    FINAL_LIBS=`make_ar_static_lib -ruv 0 ${LIBNAME} ${OBJECTS}`
 	else
 	    VERSION="${MAJOR}.${MINOR}"
 	    LIBNAME="lib${LIBNAME}.so"
@@ -724,22 +791,10 @@
 
 	    # examine first object to determine ABI
     	    set ${OBJECTS}
-            ABI_PPC=`file $1 | grep ' ppc'`
-            ABI_I386=`file $1 | grep ' i386'`
-            ABI_PPC64=`file $1 | grep ' ppc64'`
-            ABI_X86_64=`file $1 | grep ' x86_64'`
-            if [ "${ABI_PPC}" ] ; then
-                OPTS="${OPTS} -arch ppc"
-            fi
-            if [ "${ABI_I386}" ] ; then
-                OPTS="${OPTS} -arch i386"
-            fi
-            if [ "${ABI_PPC64}" ] ; then
-                OPTS="${OPTS} -arch ppc64"
-            fi
-            if [ "${ABI_X86_64}" ] ; then
-                OPTS="${OPTS} -arch x86_64"
-            fi
+            ABIS=`lipo -info $1 | sed s/.*://`
+            for ABI in $ABIS; do
+                OPTS="${OPTS} -arch ${ABI}"
+            done
 
             if [ "${ALTOPTS}" ] ; then
                 OPTS=${ALTOPTS}
@@ -767,16 +822,14 @@
     'LynxOS')
 	LIBNAME="lib${LIBNAME}.a"
 	echo "mklib: Making LynxOS static library: " ${LIBNAME}
-	rm -f ${LIBNAME}
-	ar ru ${LIBNAME} ${OBJECTS}
-	FINAL_LIBS=${LIBNAME}
+        FINAL_LIBS=`make_ar_static_lib -ru 0 ${LIBNAME} ${OBJECTS}`
 	;;
 
     'BeOS')
         if [ $STATIC = 1 ] ; then
             LIBNAME="lib${LIBNAME}.a"
             echo "mklib: Making BeOS static library: " ${LIBNAME}
-            ar -cru "${LIBNAME}" ${OBJECTS}
+            FINAL_LIBS=`make_ar_static_lib -cru 0 ${LIBNAME} ${OBJECTS}`
         else
 	    LIBNAME="lib${LIBNAME}.so"
 	    echo "mklib: Making BeOS shared library: " ${LIBNAME}
@@ -855,9 +908,7 @@
         if [ $STATIC = 1 ] ; then
 	    LIBNAME="lib${LIBNAME}.a"
 	    echo "mklib: Making AIX GCC static library: " ${LIBNAME}
-	    rm -f ${LIBNAME}
-	    ar ru ${LIBNAME} ${OBJECTS}
-	    FINAL_LIBS=${LIBNAME}
+            FINAL_LIBS=`make_ar_static_lib ru 0 ${LIBNAME} ${OBJECTS}`
 	else
 	    LIBNAME="lib${LIBNAME}.so"  # prefix with "lib", suffix with ".so"
 	    echo "mklib: Making AIX GCC shared library: " ${LIBNAME}
@@ -878,9 +929,7 @@
 	fi
 	LIBNAME="lib${LIBNAME}.a"
 	echo "mklib: Making static library for Ultrix: " ${LIBNAME}
-	rm -f ${LIBNAME}
-	ar ru ${LIBNAME} ${OBJECTS}
-	FINAL_LIBS="${LIBNAME}"
+        FINAL_LIBS=`make_ar_static_lib ru 0 ${LIBNAME} ${OBJECTS}`
 	;;
 
      CYGWIN*)
@@ -900,17 +949,13 @@
 	LIBNAME="lib${LIBNAME}"     # prefix with "lib"
 
         if [ $STATIC = 1 ] ; then
-            echo "mklib: Making" $ARCH "static library: " ${LIBNAME}.a
-            LINK="ar"
+	    LIBNAME=${LIBNAME}.a
+            echo "mklib: Making" $ARCH "static library: " ${LIBNAME}
             OPTS="-ru"
             if [ "${ALTOPTS}" ] ; then
                 OPTS=${ALTOPTS}
             fi
-            # make lib
-            ${LINK} ${OPTS} ${LIBNAME}.a ${OBJECTS}
-	    ranlib ${LIBNAME}.a
-            # finish up
-            FINAL_LIBS=${LIBNAME}.a
+            FINAL_LIBS=`make_ar_static_lib ${OPTS} 1 ${LIBNAME} ${OBJECTS}`
         else
 	    OPTS="-shared -Wl,--enable-auto-image-base -Wl,-export-all -Wl,--out-implib=${LIBNAME}-${MAJOR}.dll.a"
             if [ "${ALTOPTS}" ] ; then
@@ -948,9 +993,7 @@
         if [ $STATIC = 1 ] ; then
 	    LIBNAME="lib${LIBNAME}.a"
 	    echo "mklib: Making static library for example arch: " ${LIBNAME}
-	    rm -f ${LIBNAME}
-	    ar rv ${LIBNAME} ${OBJECTS}
-	    FINAL_LIBS="${LIBNAME}"
+            FINAL_LIBS=`make_ar_static_lib rv 0 ${LIBNAME} ${OBJECTS}`
 	else
 	    LIBNAME="lib${LIBNAME}.so"  # prefix with "lib", suffix with ".so"
 	    echo "mklib: Making shared library for example arch: " ${LIBNAME}
diff --git a/common.py b/common.py
index 3b6bf52..101fc55 100644
--- a/common.py
+++ b/common.py
@@ -12,7 +12,7 @@
 
 _platform_map = {
 	'linux2': 'linux',
-	'win32': 'winddk',
+	'win32': 'windows',
 }
 
 default_platform = sys.platform
diff --git a/configs/autoconf.in b/configs/autoconf.in
index a7f3c9d..c6d315e 100644
--- a/configs/autoconf.in
+++ b/configs/autoconf.in
@@ -22,6 +22,8 @@
 EXTRA_LIB_PATH = @EXTRA_LIB_PATH@
 RADEON_CFLAGS = @RADEON_CFLAGS@
 RADEON_LDFLAGS = @RADEON_LDFLAGS@
+INTEL_LIBS = @INTEL_LIBS@
+INTEL_CFLAGS = @INTEL_CFLAGS@
 
 # Assembler
 MESA_ASM_SOURCES = @MESA_ASM_SOURCES@
@@ -52,6 +54,7 @@
 GLUT_LIB_NAME = @GLUT_LIB_NAME@
 GLW_LIB_NAME = @GLW_LIB_NAME@
 OSMESA_LIB_NAME = @OSMESA_LIB_NAME@
+EGL_LIB_NAME = @EGL_LIB_NAME@
 
 # Globs used to install the lib and all symlinks
 GL_LIB_GLOB = @GL_LIB_GLOB@
@@ -59,19 +62,20 @@
 GLUT_LIB_GLOB = @GLUT_LIB_GLOB@
 GLW_LIB_GLOB = @GLW_LIB_GLOB@
 OSMESA_LIB_GLOB = @OSMESA_LIB_GLOB@
+EGL_LIB_GLOB = @EGL_LIB_GLOB@
 
 # Directories to build
 LIB_DIR = @LIB_DIR@
 SRC_DIRS = @SRC_DIRS@
 GLU_DIRS = @GLU_DIRS@
 DRIVER_DIRS = @DRIVER_DIRS@
+EGL_DRIVERS_DIRS = @EGL_DRIVERS_DIRS@
 GALLIUM_DIRS = @GALLIUM_DIRS@
-GALLIUM_AUXILIARY_DIRS = @GALLIUM_AUXILIARY_DIRS@
 GALLIUM_DRIVERS_DIRS = @GALLIUM_DRIVERS_DIRS@
 GALLIUM_WINSYS_DIRS = @GALLIUM_WINSYS_DIRS@
 GALLIUM_WINSYS_DRM_DIRS = @GALLIUM_WINSYS_DRM_DIRS@
 GALLIUM_STATE_TRACKERS_DIRS = @GALLIUM_STATE_TRACKERS_DIRS@
-GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a)
+GALLIUM_AUXILIARIES = $(TOP)/src/gallium/auxiliary/libgallium.a
 GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVERS_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a)
 
 # Which subdirs under $(TOP)/progs/ to enter:
@@ -80,6 +84,7 @@
 # Driver specific build vars
 DRI_DIRS = @DRI_DIRS@ 
 WINDOW_SYSTEM = @WINDOW_SYSTEM@
+EGL_DISPLAYS = @EGL_DISPLAYS@
 USING_EGL = @USING_EGL@
 
 # Dependencies
diff --git a/configs/darwin b/configs/darwin
index 213c397..7556688 100644
--- a/configs/darwin
+++ b/configs/darwin
@@ -12,10 +12,10 @@
 CC = gcc
 CXX = g++
 PIC_FLAGS = -fPIC
-DEFINES =  -D_DARWIN_C_SOURCE -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L \
-	   -D_BSD_SOURCE -D_SVID_SOURCE -D_GNU_SOURCE -DPTHREADS \
+DEFINES =  -D_DARWIN_C_SOURCE -DPTHREADS -D_GNU_SOURCE \
 	   -DGLX_ALIAS_UNSUPPORTED -DGLX_INDIRECT_RENDERING
 
+# -D_GNU_SOURCE          - for src/mesa/main ...
 # -DGLX_DIRECT_RENDERING - pulls in libdrm stuff in glx/x11
 # -DGLX_USE_APPLEGL      - supposed to be used with GLX_DIRECT_RENDERING to use AGL rather than DRM, but doesn't compile
 # -DIN_DRI_DRIVER
@@ -49,7 +49,7 @@
 APP_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) -L$(INSTALL_DIR)/$(LIB_DIR) -L$(X11_DIR)/$(LIB_DIR) -lX11 -lXmu -lXt -lXi -lm
 
 # omit glw lib for now:
-SRC_DIRS = glx/x11 mesa glu glut/glx glew
+SRC_DIRS = glsl glx/x11 mesa gallium glu glut/glx glew
 GLU_DIRS = sgi
 DRIVER_DIRS = osmesa
 #DRIVER_DIRS = dri
diff --git a/configs/default b/configs/default
index c3bb47e..8b4557d 100644
--- a/configs/default
+++ b/configs/default
@@ -9,7 +9,7 @@
 
 # Version info
 MESA_MAJOR=7
-MESA_MINOR=7
+MESA_MINOR=8
 MESA_TINY=0
 MESA_VERSION = $(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY)
 
@@ -55,6 +55,7 @@
 GLEW_LIB = GLEW
 GLW_LIB = GLw
 OSMESA_LIB = OSMesa
+EGL_LIB = EGL
 
 
 # Library names (actual file names)
@@ -64,6 +65,7 @@
 GLEW_LIB_NAME = lib$(GLEW_LIB).a
 GLW_LIB_NAME = lib$(GLW_LIB).so
 OSMESA_LIB_NAME = lib$(OSMESA_LIB).so
+EGL_LIB_NAME = lib$(EGL_LIB).so
 
 # globs used to install the lib and all symlinks
 GL_LIB_GLOB = $(GL_LIB_NAME)*
@@ -71,6 +73,7 @@
 GLUT_LIB_GLOB = $(GLUT_LIB_NAME)*
 GLW_LIB_GLOB = $(GLW_LIB_NAME)*
 OSMESA_LIB_GLOB = $(OSMESA_LIB_NAME)*
+EGL_LIB_GLOB = $(EGL_LIB_NAME)*
 
 # Optional assembly language optimization files for libGL
 MESA_ASM_SOURCES = 
@@ -83,25 +86,26 @@
 
 # Directories to build
 LIB_DIR = lib
-SRC_DIRS = mesa gallium egl gallium/winsys glu glut/glx glew glw
+SRC_DIRS = glsl mesa gallium egl gallium/winsys glu glut/glx glew glw
 GLU_DIRS = sgi
 DRIVER_DIRS = x11 osmesa
 # Which subdirs under $(TOP)/progs/ to enter:
 PROGRAM_DIRS = demos redbook samples glsl objviewer xdemos
 
-# EGL directories
+# EGL drivers to build
 EGL_DRIVERS_DIRS = demo
 
 # Gallium directories and 
 GALLIUM_DIRS = auxiliary drivers state_trackers
-GALLIUM_AUXILIARY_DIRS = rbug draw translate cso_cache pipebuffer tgsi sct rtasm util indices vl
-GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a)
-GALLIUM_DRIVERS_DIRS = softpipe i915 failover trace identity
+GALLIUM_AUXILIARIES = $(TOP)/src/gallium/auxiliary/libgallium.a
+GALLIUM_DRIVERS_DIRS = softpipe failover svga i915 i965 trace identity
 GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVERS_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a)
 GALLIUM_WINSYS_DIRS = xlib egl_xlib
 GALLIUM_WINSYS_DRM_DIRS =
 GALLIUM_STATE_TRACKERS_DIRS = glx
 
+# native displays EGL should support
+EGL_DISPLAYS = x11
 
 # Library dependencies
 #EXTRA_LIB_PATH ?=
diff --git a/configs/linux b/configs/linux
index 73a6b61..c60f0d8 100644
--- a/configs/linux
+++ b/configs/linux
@@ -23,11 +23,11 @@
 X11_INCLUDES = -I/usr/X11R6/include
 
 CFLAGS = -Wall -Wmissing-prototypes -Wdeclaration-after-statement \
-	$(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) \
-	$(DEFINES) $(ASM_FLAGS) $(X11_INCLUDES) -std=c99 -ffast-math 
+	-Wpointer-arith $(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) \
+	$(DEFINES) $(ASM_FLAGS) $(X11_INCLUDES) -std=c99 -ffast-math
 
-CXXFLAGS = -Wall $(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(DEFINES) \
-	$(X11_INCLUDES) 
+CXXFLAGS = -Wall -Wpointer-arith $(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) \
+	$(DEFINES) $(X11_INCLUDES)
 
 # Work around aliasing bugs - developers should comment this out
 CFLAGS += -fno-strict-aliasing
diff --git a/configs/linux-cell b/configs/linux-cell
index 19d435f..221655c 100644
--- a/configs/linux-cell
+++ b/configs/linux-cell
@@ -33,7 +33,7 @@
 CXXFLAGS = $(CFLAGS)
 
 # Omitting glw here:
-SRC_DIRS = gallium mesa gallium/winsys glu glut/glx glew
+SRC_DIRS = glsl mesa gallium gallium/winsys glu glut/glx glew
 
 # Build no traditional Mesa drivers:
 DRIVER_DIRS =
diff --git a/configs/linux-debug b/configs/linux-debug
index bc6d233..8b0b312 100644
--- a/configs/linux-debug
+++ b/configs/linux-debug
@@ -4,5 +4,6 @@
 
 CONFIG_NAME = linux-debug
 
-OPT_FLAGS = -g -ansi -pedantic
+OPT_FLAGS = -g
+CFLAGS += -ansi -pedantic
 DEFINES += -DDEBUG -DDEBUG_MATH
diff --git a/configs/linux-dri b/configs/linux-dri
index 6c3c0ab..ff9bcc9 100644
--- a/configs/linux-dri
+++ b/configs/linux-dri
@@ -60,8 +60,14 @@
 DRIVER_DIRS = dri
 WINDOW_SYSTEM = dri
 GALLIUM_WINSYS_DIRS = drm
-GALLIUM_WINSYS_DRM_DIRS = intel
+GALLIUM_WINSYS_DRM_DIRS = vmware intel i965
 GALLIUM_STATE_TRACKERS_DIRS = egl
 
 DRI_DIRS = i810 i915 i965 mach64 mga r128 r200 r300 radeon \
 	savage sis tdfx unichrome ffb swrast
+
+INTEL_LIBS = `pkg-config --libs libdrm_intel`
+INTEL_CFLAGS = `pkg-config --cflags libdrm_intel`
+
+RADEON_LIBS = `pkg-config --libs libdrm_radeon`
+RADEON_CFLAGS = `pkg-config --cflags libdrm_radeon`
diff --git a/configs/linux-i965 b/configs/linux-i965
new file mode 100644
index 0000000..e66abc3
--- /dev/null
+++ b/configs/linux-i965
@@ -0,0 +1,8 @@
+# Configuration for standalone mode i965 debug
+
+include $(TOP)/configs/linux-debug
+
+CONFIG_NAME = linux-i965
+
+GALLIUM_DRIVER_DIRS = i965
+GALLIUM_WINSYS_DIRS = drm/i965/xlib
diff --git a/configs/linux-llvm b/configs/linux-llvm
index 19b53cc..dbf7e3e 100644
--- a/configs/linux-llvm
+++ b/configs/linux-llvm
@@ -6,8 +6,6 @@
 
 CONFIG_NAME = linux-llvm
 
-#GALLIUM_AUXILIARY_DIRS += gallivm
-
 # Add llvmpipe driver
 GALLIUM_DRIVERS_DIRS += llvmpipe
 
diff --git a/configure.ac b/configure.ac
index 2984ee2..1f94248 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,7 +19,9 @@
 
 dnl Versions for external dependencies
 LIBDRM_REQUIRED=2.4.15
-DRI2PROTO_REQUIRED=1.99.3
+LIBDRM_RADEON_REQUIRED=2.4.17
+DRI2PROTO_REQUIRED=2.2
+GLPROTO_REQUIRED=1.4.11
 
 dnl Check for progs
 AC_PROG_CPP
@@ -94,7 +96,7 @@
 
 dnl Add flags for gcc and g++
 if test "x$GCC" = xyes; then
-    CFLAGS="$CFLAGS -Wall -Wmissing-prototypes -std=c99 -ffast-math"
+    CFLAGS="$CFLAGS -Wall -Wmissing-prototypes -std=c99 -ffast-math -fvisibility=hidden"
 
     # Work around aliasing bugs - developers should comment this out
     CFLAGS="$CFLAGS -fno-strict-aliasing"
@@ -242,24 +244,28 @@
 GLUT_LIB_NAME='lib$(GLUT_LIB).'${LIB_EXTENSION}
 GLW_LIB_NAME='lib$(GLW_LIB).'${LIB_EXTENSION}
 OSMESA_LIB_NAME='lib$(OSMESA_LIB).'${LIB_EXTENSION}
+EGL_LIB_NAME='lib$(EGL_LIB).'${LIB_EXTENSION}
 
 GL_LIB_GLOB='lib$(GL_LIB).*'${LIB_EXTENSION}'*'
 GLU_LIB_GLOB='lib$(GLU_LIB).*'${LIB_EXTENSION}'*'
 GLUT_LIB_GLOB='lib$(GLUT_LIB).*'${LIB_EXTENSION}'*'
 GLW_LIB_GLOB='lib$(GLW_LIB).*'${LIB_EXTENSION}'*'
 OSMESA_LIB_GLOB='lib$(OSMESA_LIB).*'${LIB_EXTENSION}'*'
+EGL_LIB_GLOB='lib$(EGL_LIB).*'${LIB_EXTENSION}'*'
 
 AC_SUBST([GL_LIB_NAME])
 AC_SUBST([GLU_LIB_NAME])
 AC_SUBST([GLUT_LIB_NAME])
 AC_SUBST([GLW_LIB_NAME])
 AC_SUBST([OSMESA_LIB_NAME])
+AC_SUBST([EGL_LIB_NAME])
 
 AC_SUBST([GL_LIB_GLOB])
 AC_SUBST([GLU_LIB_GLOB])
 AC_SUBST([GLUT_LIB_GLOB])
 AC_SUBST([GLW_LIB_GLOB])
 AC_SUBST([OSMESA_LIB_GLOB])
+AC_SUBST([EGL_LIB_GLOB])
 
 dnl
 dnl Arch/platform-specific settings
@@ -413,13 +419,12 @@
 dnl
 dnl Driver specific build directories
 dnl
-SRC_DIRS="mesa glew"
+SRC_DIRS="glsl mesa glew"
 GLU_DIRS="sgi"
 WINDOW_SYSTEM=""
 GALLIUM_DIRS="auxiliary drivers state_trackers"
 GALLIUM_WINSYS_DIRS=""
 GALLIUM_WINSYS_DRM_DIRS=""
-GALLIUM_AUXILIARY_DIRS="rbug draw translate cso_cache pipebuffer tgsi sct rtasm util indices vl"
 GALLIUM_DRIVERS_DIRS="softpipe failover trace identity"
 GALLIUM_STATE_TRACKERS_DIRS=""
 
@@ -446,10 +451,7 @@
 AC_SUBST([GALLIUM_WINSYS_DIRS])
 AC_SUBST([GALLIUM_WINSYS_DRM_DIRS])
 AC_SUBST([GALLIUM_DRIVERS_DIRS])
-AC_SUBST([GALLIUM_AUXILIARY_DIRS])
 AC_SUBST([GALLIUM_STATE_TRACKERS_DIRS])
-AC_SUBST([RADEON_CFLAGS])
-AC_SUBST([RADEON_LDFLAGS])
 
 dnl
 dnl User supplied program configuration
@@ -576,13 +578,7 @@
     PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= $DRI2PROTO_REQUIRED])
     GL_PC_REQ_PRIV="libdrm >= $LIBDRM_REQUIRED dri2proto >= $DRI2PROTO_REQUIRED"
     DRI_PC_REQ_PRIV="libdrm >= $LIBDRM_REQUIRED"
-
-    PKG_CHECK_MODULES([LIBDRM_RADEON], [libdrm_radeon], HAVE_LIBDRM_RADEON=yes, HAVE_LIBDRM_RADEON=no)
-
-    if test "$HAVE_LIBDRM_RADEON" = yes; then
-	RADEON_CFLAGS="-DHAVE_LIBDRM_RADEON=1 $LIBDRM_RADEON_CFLAGS"
-	RADEON_LDFLAGS=$LIBDRM_RADEON_LIBS
-    fi
+    PKG_CHECK_MODULES([GLPROTO], [glproto >= $GLPROTO_REQUIRED])
 
     # find the DRI deps for libGL
     if test "$x11_pkgconfig" = yes; then
@@ -803,6 +799,29 @@
 AC_SUBST([EXPAT_INCLUDES])
 AC_SUBST([DRI_LIB_DEPS])
 
+case $DRI_DIRS in
+*i915*|*i965*)
+    PKG_CHECK_MODULES([INTEL], [libdrm_intel])
+    ;;
+esac
+
+case $DRI_DIRS in
+*radeon*|*r200*|*r300*|*r600*)
+    PKG_CHECK_MODULES([LIBDRM_RADEON],
+		      [libdrm_radeon libdrm >= $LIBDRM_RADEON_REQUIRED],
+		      HAVE_LIBDRM_RADEON=yes,
+		      HAVE_LIBDRM_RADEON=no)
+
+    if test "$HAVE_LIBDRM_RADEON" = yes; then
+	RADEON_CFLAGS="-DHAVE_LIBDRM_RADEON=1 $LIBDRM_RADEON_CFLAGS"
+	RADEON_LDFLAGS=$LIBDRM_RADEON_LIBS
+    fi
+    ;;
+esac
+AC_SUBST([RADEON_CFLAGS])
+AC_SUBST([RADEON_LDFLAGS])
+
+
 dnl
 dnl OSMesa configuration
 dnl
@@ -887,17 +906,15 @@
     [enable_egl=yes])
 if test "x$enable_egl" = xyes; then
     SRC_DIRS="$SRC_DIRS egl"
-
-    if test "$x11_pkgconfig" = yes; then
-        PKG_CHECK_MODULES([EGL], [x11])
-        EGL_LIB_DEPS="$EGL_LIBS"
-    else
-        # should check these...
-        EGL_LIB_DEPS="$X_LIBS -lX11"
+    EGL_LIB_DEPS="$DLOPEN_LIBS -lpthread"
+    EGL_DRIVERS_DIRS=""
+    if test "$enable_static" != yes && test "$mesa_driver" != osmesa; then
+        # build egl_glx when libGL is built
+        EGL_DRIVERS_DIRS="glx"
     fi
-    EGL_LIB_DEPS="$EGL_LIB_DEPS $DLOPEN_LIBS"
 fi
 AC_SUBST([EGL_LIB_DEPS])
+AC_SUBST([EGL_DRIVERS_DIRS])
 
 dnl
 dnl GLU configuration
@@ -1143,7 +1160,14 @@
         GALLIUM_STATE_TRACKERS_DIRS=glx
         ;;
     dri)
-        test "x$enable_egl" = xyes && GALLIUM_STATE_TRACKERS_DIRS=egl
+        GALLIUM_STATE_TRACKERS_DIRS="dri"
+        if test "x$enable_egl" = xyes; then
+            GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl egl_g3d"
+        fi
+        # Have only tested st/xorg on 1.6.0 servers
+        PKG_CHECK_MODULES(XORG, [xorg-server >= 1.6.0],
+            HAVE_XORG="yes"; GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS xorg",
+            HAVE_XORG="no")
         ;;
     esac
     ;;
@@ -1175,6 +1199,35 @@
     ;;
 esac
 
+AC_ARG_WITH([egl-displays],
+    [AS_HELP_STRING([--with-egl-displays@<:@=DIRS...@:>@],
+        [comma delimited native displays libEGL supports, e.g.
+        "x11,kms" @<:@default=auto@:>@])],
+    [with_egl_displays="$withval"],
+    [with_egl_displays=yes])
+
+EGL_DISPLAYS=""
+case "$with_egl_displays" in
+yes)
+    if test "x$enable_egl" = xyes && test "x$mesa_driver" != xosmesa; then
+        EGL_DISPLAYS="x11"
+    fi
+    ;;
+*)
+    if test "x$enable_egl" != xyes; then
+        AC_MSG_ERROR([cannot build egl state tracker without EGL library])
+    fi
+    # verify the requested driver directories exist
+    egl_displays=`IFS=', '; echo $with_egl_displays`
+    for dpy in $egl_displays; do
+        test -d "$srcdir/src/gallium/state_trackers/egl_g3d/$dpy" || \
+            AC_MSG_ERROR([EGL display '$dpy' does't exist])
+    done
+    EGL_DISPLAYS="$egl_displays"
+    ;;
+esac
+AC_SUBST([EGL_DISPLAYS])
+
 AC_ARG_WITH([xorg-driver-dir],
     [AS_HELP_STRING([--with-xorg-driver-dir=DIR],
                     [Default xorg driver directory[[default=${libdir}/xorg/modules/drivers]]])],
@@ -1198,16 +1251,33 @@
 )
 
 dnl
+dnl Gallium SVGA configuration
+dnl
+AC_ARG_ENABLE([gallium-svga],
+    [AS_HELP_STRING([--enable-gallium-svga],
+        [build gallium SVGA @<:@default=disabled@:>@])],
+    [enable_gallium_svga="$enableval"],
+    [enable_gallium_svga=auto])
+if test "x$enable_gallium_svga" = xyes; then
+    GALLIUM_WINSYS_DRM_DIRS="$GALLIUM_WINSYS_DRM_DIRS vmware"
+    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS svga"
+elif test "x$enable_gallium_svga" = xauto; then
+    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS svga"
+fi
+
+dnl
 dnl Gallium Intel configuration
 dnl
 AC_ARG_ENABLE([gallium-intel],
-    [AS_HELP_STRING([--disable-gallium-intel],
-        [build gallium intel @<:@default=enabled@:>@])],
+    [AS_HELP_STRING([--enable-gallium-intel],
+        [build gallium intel @<:@default=disabled@:>@])],
     [enable_gallium_intel="$enableval"],
-    [enable_gallium_intel=yes])
+    [enable_gallium_intel=auto])
 if test "x$enable_gallium_intel" = xyes; then
-    GALLIUM_WINSYS_DRM_DIRS="$GALLIUM_WINSYS_DRM_DIRS intel"
-    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915"
+    GALLIUM_WINSYS_DRM_DIRS="$GALLIUM_WINSYS_DRM_DIRS intel i965"
+    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915 i965"
+elif test "x$enable_gallium_intel" = xauto; then
+    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915 i965"
 fi
 
 dnl
@@ -1289,7 +1359,6 @@
     echo "        Gallium dirs:    $GALLIUM_DIRS"
     echo "        Winsys dirs:     $GALLIUM_WINSYS_DIRS"
     echo "        Winsys drm dirs:$GALLIUM_WINSYS_DRM_DIRS"
-    echo "        Auxiliary dirs:  $GALLIUM_AUXILIARY_DIRS"
     echo "        Driver dirs:     $GALLIUM_DRIVERS_DIRS"
     echo "        Trackers dirs:   $GALLIUM_STATE_TRACKERS_DIRS"
 else
diff --git a/docs/GL3.txt b/docs/GL3.txt
new file mode 100644
index 0000000..df3fd74
--- /dev/null
+++ b/docs/GL3.txt
@@ -0,0 +1,69 @@
+
+Status of OpenGL 3.x features in Mesa
+
+
+Note: when an item is marked as "DONE" it means all the core Mesa
+infrastructure is complete but it may be the case that few (if any) drivers
+implement the features.
+
+
+Feature                                               Status
+----------------------------------------------------- ------------------------
+
+GL 3.0:
+
+GLSL changes (GL_EXT_gpu_shader4, etc)                not started
+Conditional rendering (GL_NV_conditional_render)      DONE (swrast & softpipe)
+Map buffer subranges (GL_APPLE_flush_buffer_range)    not started
+Float textures, renderbuffers                         some infrastructure done
+Framebuffer objects (GL_EXT_framebuffer_object)       DONE
+Half-float                                            some infrastructure done
+Multisample blit                                      DONE
+Non-normalized Integer texture/framebuffer formats    not started
+1D/2D Texture arrays                                  mostly done
+Packed depth/stencil formats                          DONE
+Per-buffer blend and masks (GL_EXT_draw_buffers2)     DONE
+GL_EXT_texture_compression_rgtc                       not started
+Red and red/green texture formats                     Ian?
+Transform feedback (GL_EXT_transform_feedback)        not started
+Vertex array objects (GL_APPLE_vertex_array_object)   DONE
+sRGB framebuffer format (GL_EXT_framebuffer_sRGB)     not started
+glClearBuffer commands                                DONE, except for dispatch
+glGetStringi command                                  DONE, except for dispatch
+glTexParameterI, glGetTexParameterI commands          DONE, except for dispatch
+glVertexAttribI commands                              not started
+glBindFragDataLocation, glGetFragDataLocation cmds    not started
+glBindBufferRange, glBindBufferBase commands          not started
+
+
+GL 3.1:
+
+GLSL 1.30 and 1.40                                    not started
+Instanced drawing (GL_ARB_draw_instanced)             not started
+Buffer copying (GL_ARB_copy_buffer)                   DONE
+Primitive restart (GL_NV_primitive_restart)           not started
+16 vertex texture image units                         not started
+Texture buffer objs (GL_ARB_textur_buffer_object)     not started
+Rectangular textures (GL_ARB_texture_rectangle)       DONE
+Uniform buffer objs (GL_ARB_uniform_buffer_object)    not started
+Signed normalized texture formats                     not started
+
+
+GL 3.2:
+
+Core/compatibility profiles                           not started
+GLSL 1.50                                             not started
+Geometry shaders (GL_ARB_geometry_shader4)            partially done (Zack)
+BGRA vertex order (GL_ARB_vertex_array_bgra)          DONE
+Base vertex offset(GL_ARB_draw_elements_base_vertex)  DONE
+Frag shader coord (GL_ARB_fragment_coord_conventions) not started
+Provoking vertex (GL_ARB_provoking_vertex)            DONE
+Seamless cubemaps (GL_ARB_seamless_cube_map)          DONE, mostly?
+Multisample textures (GL_ARB_texture_multisample)     not started
+Frag depth clamp (GL_ARB_depth_clamp)                 DONE
+Fence objects (GL_ARB_sync)                           DONE
+
+
+
+More info about these features and the work involved can be found at
+http://dri.freedesktop.org/wiki/MissingFunctionality
diff --git a/docs/README.WIN32 b/docs/README.WIN32
index 97e1ffb..204b8e6 100644
--- a/docs/README.WIN32
+++ b/docs/README.WIN32
@@ -27,12 +27,6 @@
 
 http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/
 
-If you are stuck using VC6 or VC7, you may start with these project
-files, but you may need to modify them to reflect changes in the
-Mesa source code tree.  If you sucessfully update the project files,
-please submit them to the author of this document so that they may
-be included in the next distribution. 
-
 The project files to build the core Mesa library, Windows Mesa
 drivers, OSMesa, and GLU are in the mesa directory.  The project files
 to build GLUT and some demo programs are in the progs directory.
@@ -106,23 +100,6 @@
 Build System Notes
 ----- ------ -----
 
-VC6 (not actively supported)
----
-
-Visual Studio 6 does not recognize files with the .cc extension as C++
-language files, without a lot of unnatural tweaking.  So, the VC6
-build process uses custom build steps to compile these files in the
-GLU library.
-
-Two additional configurations are provided, Debug x86 and Release x86
-that activate the shader code compilation by defining SLANG_86.  It is
-unknown if and how this works.
-
-VC7 (not actively supported)
----
-
-The above-mentioned .cc problem does not exist in this version.
-
 VC8
 ---
 
diff --git a/docs/install.html b/docs/install.html
index 8c24cee..5aea92e 100644
--- a/docs/install.html
+++ b/docs/install.html
@@ -352,19 +352,10 @@
 </p>
 
 <p>
-The sample programs are built seperately. To build them do
-<pre>
-    scons -C progs
-</pre>
-And the build output will be placed in progs/build/...
-</p>
-
-<p>
 To build Mesa with SCons for Windows on Linux using the MinGW crosscompiler toolchain do
 </p>
 <pre>
     scons platform=windows toolchain=crossmingw machine=x86 statetrackers=mesa drivers=softpipe,trace winsys=gdi
-    scons -C progs platform=windows toolchain=crossmingw machine=x86 -k
 </pre>
 <p>
 This will create:
diff --git a/docs/libGL.txt b/docs/libGL.txt
new file mode 100644
index 0000000..cb98840
--- /dev/null
+++ b/docs/libGL.txt
@@ -0,0 +1,197 @@
+
+
+
+Introduction
+------------
+
+This document describes the implementation of the XFree86 4.0 libGL.so
+library defined by the Linux/OpenGL Base specification found at
+http://reality.sgi.com/opengl/linux/linuxbase.html.
+
+The documentation is divided into two sections:
+    User's Guide
+    Driver Developer's Guide
+
+Author:  Brian Paul     (brian@precisioninsight.com)
+Date:    February 2000
+
+
+
+User's Guide
+------------
+
+Using libGL.so
+
+The libGL.so library defines the gl- and glX-prefixed functions needed to
+run OpenGL programs.  OpenGL client applications should link with the
+-lGL option to use it.
+
+libGL.so serves two primary functions: GLX protocol generation for indirect
+rendering and loading/management of hardware drivers for direct rendering.
+
+When libGL.so initializes itself it uses the DRI to determine the
+appropriate hardware driver for each screen on the local X display.
+The hardware drivers are expected to be in the /usr/X11R6/lib/modules/dri/
+directory.  Drivers are named with the convention <name>_dri.so where
+<name> is a driver such as "tdfx", "i810", "gamma", etc.
+
+The LIBGL_DRIVERS_DIR environment variable may be used to specify a
+different DRI modules directory, overriding /usr/X11R6/lib/modules/dri/.
+This environment variable is ignored in setuid programs for security
+reasons.
+
+When libGL.so is unable to locate appropriate hardware drivers it will
+fall back to using indirect GLX rendering.
+
+To aid in solving problems, libGL.so will print diagnostic messages to
+stderr if the LIBGL_DEBUG environment variable is defined.
+
+libGL.so is thread safe.  The overhead of thread safety for common,
+single-thread clients is negligible.  However, the overhead of thread
+safety for multi-threaded clients is significant.  Each GL API call
+requires two calls to pthread_get_specific() which can noticably
+impact performance.  Warning:  libGL.so is thread safe but individual
+DRI drivers may not be.  Please consult the documentation for a driver
+to learn if it is thread safe.
+
+
+
+Indirect Rendering
+
+You can force indirect rendering mode by setting the LIBGL_ALWAYS_INDIRECT
+environment variable.  Hardware acceleration will not be used.
+
+
+
+libGL.so Extensibility
+
+libGL.so is designed to be extended without upgrading.  That is,
+drivers may install new OpenGL extension functions into libGL.so
+without requiring libGL.so to be replaced.  Clients of libGL.so should
+use the glXGetProcAddressEXT() function to obtain the address of
+functions by name.  For more details of GLX_ARB_get_proc_address see
+http://oss.sgi.com/projects/ogl-sample/registry/ARB/get_proc_address.spec
+
+libGL.so is also designed with flexibility such that it may be used
+with many generations of hardware drivers to come.
+
+
+
+
+Driver Developer's Guide
+------------------------
+
+This section describes the requirements to make an XFree86 4.0
+libGL.so-compatible hardware driver.  It is not intended for end
+users of libGL.so.
+
+
+XFree86 source files
+
+libGL.so is built inside XFree86 with sources found in xc/lib/GL/.
+Specifically, libGL.so is built from:
+
+	xc/lib/GL/glx/*.c
+	xc/lib/dri/XF86dri.c
+	xc/lib/dri/dri_glx.c
+	xc/lib/GL/mesa/src/glapi.c
+	xc/lib/GL/mesa/src/glapitemp.h
+	xc/lib/GL/mesa/src/glapitable.h
+	xc/lib/GL/mesa/src/glapioffsets.h
+	xc/lib/GL/mesa/src/glapinoop.c
+	xc/lib/GL/mesa/src/glheader.h
+	xc/lib/GL/mesa/src/glthread.c
+	xc/lib/GL/mesa/src/glthread.h
+	xc/lib/GL/mesa/src/X86/glapi_x86.S
+	xc/lib/GL/mesa/src/X86/assyntax.h
+
+Understand that the mesa/src/gl*.[ch] files are not tied to Mesa.  They
+have no dependencies on the rest of Mesa and are designed to be reusable
+in a number of projects.
+
+The glapi_x86.X and assyntax.h files implement x86-optimized dispatch
+of GL functions.  They are not required; C-based dispatch can be used
+instead, with a slight performance penalty.
+
+
+
+Driver loading and binding
+
+When libGL.so initializes itself (via the __glXInitialize function) a
+call is made to driCreateDisplay().  This function uses DRI facilities
+to determine the driver file appropriate for each screen on the local
+display.  Each screen's driver is then opened with dlopen() and asked
+for its __driCreateScreen() function.  The pointers to the __driCreateScreen()
+functions are kept in an array, indexed by screen number, in the
+__DRIdisplayRec struct.
+
+When a driver's __driCreateScreen() function is called, it must initialize
+a __DRIscreenRec struct.  This struct acts as the root of a tree of
+function pointers which are called to create and destroy contexts and
+drawables and perform all the operations needed by the GLX interface.
+See the xc/lib/GL/glx/glxclient.h file for details.
+
+
+
+Dynamic Extension Function Registration
+
+In order to provide forward compatibility with future drivers, libGL.so
+allows drivers to register new OpenGL extension functions which weren't
+known when libGL.so was built.
+
+The register_extensions() function in xc/lib/GL/dri/dri_glx.c is called
+as soon as libGL.so is loaded.  This is done with gcc's constructor
+attribute.  This mechanism will likely have to be changed for other compilers.
+
+register_extensions() loops over all local displays and screens, determines
+the DRI driver for each, and calls the driver's __driRegisterExtensions()
+function, if present.
+
+The __driRegisterExtensions() function can add new entrypoints to libGL
+by calling:
+
+    GLboolean _glapi_add_entrypoint(const char *funcName, GLuint offset)
+
+The parameters are the name of the function (such as "glFoobarEXT") and the
+offset of the dispatch slot in the API dispatch table.  The return value
+indicates success (GL_TRUE) or failure (GL_FALSE).
+
+_glapi_add_entrypoint() will synthesize entrypoint code in assembly
+language.  Assembly languages is required since parameter passing
+can't be handled correctly using a C-based solution.
+
+The address of the new entrypoint is obtained by calling the
+glXGetProcAddressARB() function.
+
+The dispatch offset number MUST be a number allocated by SGI in the same
+manner in which new GL_* constants are allocated.  Using an arbitrary
+offset number will result in many problems.
+
+
+
+Dispatch Management
+
+When a GL context is made current, the driver must install its dispatch
+table as the current dispatch table.  This is done by calling
+
+	void _glapi_set_dispatch(struct _glapi_table *dispatch);
+
+This will install the named dispatch table for the calling thread.
+The current dispatch table for a thread can be obtained by calling
+
+	struct _glapi_table *_glapi_get_dispatch(void);
+
+For higher performance in the common single-thread case, the global
+variable _glapi_Dispatch will point to the current dispatch table.
+This variable will be NULL when in multi-thread mode.
+
+
+
+Context Management
+
+libGL.so uses the XFree86 xthreads package to manage a thread-specific
+current context pointer.  See __glXGet/SetCurrentContext() in glext.c
+
+Drivers may use the _glapi_set/get_context() functions to maintain
+a private thread-specific context pointer.
+
diff --git a/docs/news.html b/docs/news.html
index 93da56a..0a0be71 100644
--- a/docs/news.html
+++ b/docs/news.html
@@ -10,6 +10,17 @@
 
 <H1>News</H1>
 
+<h2>December 21, 2009</h2>
+<p>
+<a href="relnotes-7.6.1.html">Mesa 7.6.1</a> is released.  This is a bug-fix
+release fixing issues found in the 7.6 release.
+</p>
+<p>
+Also, <a href="relnotes-7.7.html">Mesa 7.7</a> is released.  This is a new
+development release.
+</p>
+
+
 <h2>September 28, 2009</h2>
 <p>
 <a href="relnotes-7.6.html">Mesa 7.6</a> is released.  This is a new feature
diff --git a/docs/relnotes-7.6.1.html b/docs/relnotes-7.6.1.html
index 9ee6bab..1d0ecd2 100644
--- a/docs/relnotes-7.6.1.html
+++ b/docs/relnotes-7.6.1.html
@@ -8,7 +8,7 @@
 
 <body bgcolor="#eeeeee">
 
-<H1>Mesa 7.6.1 Release Notes, (date tbd)</H1>
+<H1>Mesa 7.6.1 Release Notes, 21 December 2009</H1>
 
 <p>
 Mesa 7.6.1 is a bug-fix release fixing issues since version 7.6.
@@ -26,7 +26,15 @@
 
 <h2>MD5 checksums</h2>
 <pre>
-tbd
+e80fabad2e3eb7990adae773d6aeacba  MesaLib-7.6.1.tar.gz
+7db4617e9e10ad3aca1b64339fd71b7d  MesaLib-7.6.1.tar.bz2
+dd3275dbf9833480d2e92d0c69b22abd  MesaLib-7.6.1.zip
+f7fdcfe3c0f363e571c60f02f74368fb  MesaDemos-7.6.1.tar.gz
+a4226f06732a02556fcf6be290b86dff  MesaDemos-7.6.1.tar.bz2
+849425f356bd940726cebedfa79de176  MesaDemos-7.6.1.zip
+d40cc7c5e337a85b674e27a8e494f52f  MesaGLUT-7.6.1.tar.gz
+ca9aecb91f05b1da9fd7d5eeb19d47d7  MesaGLUT-7.6.1.tar.bz2
+23fad8398004c977a1d8953079b72ca6  MesaGLUT-7.6.1.zip
 </pre>
 
 
@@ -34,6 +42,7 @@
 <ul>
 <li>Upgraded GL/glext.h to version 56, GL/glxext.h to version 25,
     GL/wglext.h to version 17
+<li>New 3D driver, r600, for Radeon R6xx, R7xx hardware
 </ul>
 
 
@@ -52,7 +61,20 @@
     it returns the actual compressed format chosen.
 <li>Fixed glBitmap bugs in Intel drivers.
 <li>Fixed a number of Microsoft Visual Studio compilation problems.
+<li>Fixed clipping / provoking vertex bugs in i965 driver.
+<li>Assorted build fixes for AIX.
+<li>Endianness fixes for the DRI swrast driver (bug 22767).</li>
+<li>Point sprite fixes for i915/945 driver.
+<li>Fixed assorted memory leaks (usually on error paths)
+<li>Fixed some GLSL compiler bugs (ex: 25579)
+<li>Assorted build fixes for BlueGene
 </ul>
 
+<h2>Changes</h2>
+<ul>
+<li>Removed old VC6, VC7 project files for Windows
+</ul>
+
+
 </body>
 </html>
diff --git a/docs/relnotes-7.7.1.html b/docs/relnotes-7.7.1.html
new file mode 100644
index 0000000..b20c8a7
--- /dev/null
+++ b/docs/relnotes-7.7.1.html
@@ -0,0 +1,50 @@
+<HTML>
+
+<TITLE>Mesa Release Notes</TITLE>
+
+<head><link rel="stylesheet" type="text/css" href="mesa.css"></head>
+
+<BODY>
+
+<body bgcolor="#eeeeee">
+
+<H1>Mesa 7.7.1 Release Notes / date tbd</H1>
+
+<p>
+Mesa 7.7.1 is a bug-fix release.
+</p>
+<p>
+Mesa 7.7.1 implements the OpenGL 2.1 API, but the version reported by
+glGetString(GL_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 2.1.
+</p>
+<p>
+See the <a href="install.html">Compiling/Installing page</a> for prerequisites
+for DRI hardware acceleration.
+</p>
+
+
+<h2>MD5 checksums</h2>
+<pre>
+tbd
+</pre>
+
+
+<h2>New features</h2>
+<ul>
+<li>tbd
+</ul>
+
+
+<h2>Bug fixes</h2>
+<ul>
+<li>Assorted fixes to VMware SVGA gallium driver.
+<li>Fixed broken blending to multiple color buffers in swrast driver.
+<li>Allocate constants more tightly in GL_ARB_vertex/fragment parser.
+<li>Fixed mipmap generation bug caused by invalid viewport state.
+<li>Gallium SSE codegen for XPD didn't always work.
+</ul>
+
+
+</body>
+</html>
diff --git a/docs/relnotes-7.7.html b/docs/relnotes-7.7.html
index 856b8fa..c1ed654 100644
--- a/docs/relnotes-7.7.html
+++ b/docs/relnotes-7.7.html
@@ -8,7 +8,7 @@
 
 <body bgcolor="#eeeeee">
 
-<H1>Mesa 7.7 Release Notes / date TBD</H1>
+<H1>Mesa 7.7 Release Notes / 21 December 2009</H1>
 
 <p>
 Mesa 7.7 is a new development release.
@@ -28,12 +28,23 @@
 
 <h2>MD5 checksums</h2>
 <pre>
-tbd
+395c9516edf1ad54b0934d8db15557bf  MesaLib-7.7.tar.gz
+e3fa64a1508bc23dd9de9dd2cea7cfb1  MesaLib-7.7.tar.bz2
+e54903eb5e49c3969821fa16b32da245  MesaLib-7.7.zip
+53b5b6f78e55de170d43c98cb6aaab7e  MesaDemos-7.7.tar.gz
+6fd616b27b9826d0faa23e08e05d9435  MesaDemos-7.7.tar.bz2
+240fe06159ad73d5e22c27033b66c80a  MesaDemos-7.7.zip
+9fe11a904b2a9d8cd06cc52bc330b716  MesaGLUT-7.7.tar.gz
+e8dceed05a59a2d3c2619d7d734587e3  MesaGLUT-7.7.tar.bz2
+96af041d435349ee23ead4667ec36363  MesaGLUT-7.7.zip
 </pre>
 
 
 <h2>New features</h2>
 <ul>
+<li>VMware "SVGA" Gallium driver.  This is a Gallium3D driver which targets the
+    VMware virtual graphics device.  It allows Linux OpenGL guest applications
+    to utilize the 3D graphics hardware of the host operating system.
 <li>GL_ARB_draw_elements_base_vertex (supported in Intel i965 and software drivers)</li>
 <li>GL_ARB_depth_clamp (supported in Intel i965 DRI and software drivers)</li>
 <li>GL_NV_depth_clamp (supported in Intel i965 DRI and software drivers)</li>
@@ -44,11 +55,15 @@
 
 <h2>Bug fixes</h2>
 <ul>
+<li>Many assorted i965 driver fixes.
+<li>Many r300-gallium driver fixes; this driver is now considered unstable-quality instead of experimental-quality.
 </ul>
 
 
 <h2>Changes</h2>
 <ul>
+<li>New Mesa texture/surface format infrastructure
+<li>Removed some unused Mesa device driver hooks
 </ul>
 
 </body>
diff --git a/docs/relnotes-7.8.html b/docs/relnotes-7.8.html
new file mode 100644
index 0000000..717b962
--- /dev/null
+++ b/docs/relnotes-7.8.html
@@ -0,0 +1,54 @@
+<HTML>
+
+<TITLE>Mesa Release Notes</TITLE>
+
+<head><link rel="stylesheet" type="text/css" href="mesa.css"></head>
+
+<BODY>
+
+<body bgcolor="#eeeeee">
+
+<H1>Mesa 7.8 Release Notes / date TBD</H1>
+
+<p>
+Mesa 7.8 is a new development release.
+People who are concerned with stability and reliability should stick
+with a previous release or wait for Mesa 7.8.1.
+</p>
+<p>
+Mesa 7.8 implements the OpenGL 2.1 API, but the version reported by
+glGetString(GL_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 2.1.
+</p>
+<p>
+See the <a href="install.html">Compiling/Installing page</a> for prerequisites
+for DRI hardware acceleration.
+</p>
+
+
+<h2>MD5 checksums</h2>
+<pre>
+tbd
+</pre>
+
+
+<h2>New features</h2>
+<ul>
+<li>GL_NV_conditional_render extension (swrast driver only)
+<li>GL_EXT_draw_buffers2 extension (swrast driver only)
+</ul>
+
+
+<h2>Bug fixes</h2>
+<ul>
+<li>TBD
+</ul>
+
+
+<h2>Changes</h2>
+<ul>
+<li>TBD
+</ul>
+
+</body>
+</html>
diff --git a/docs/relnotes.html b/docs/relnotes.html
index b301ee0..f1f95c5 100644
--- a/docs/relnotes.html
+++ b/docs/relnotes.html
@@ -13,6 +13,9 @@
 </p>
 
 <UL>
+<<<<<<< HEAD:docs/relnotes.html
+<LI><A HREF="relnotes-7.8.html">7.8 release notes</A>
+<LI><A HREF="relnotes-7.7.1.html">7.7.1 release notes</A>
 <LI><A HREF="relnotes-7.7.html">7.7 release notes</A>
 <LI><A HREF="relnotes-7.6.1.html">7.6.1 release notes</A>
 <LI><A HREF="relnotes-7.6.html">7.6 release notes</A>
diff --git a/include/EGL/eglplatform.h b/include/EGL/eglplatform.h
index 9e83b60..09abb5d 100644
--- a/include/EGL/eglplatform.h
+++ b/include/EGL/eglplatform.h
@@ -18,6 +18,11 @@
 #include <stdint.h>
 #endif
 
+#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303
+#  define EGLAPI __attribute__((visibility("default")))
+#  define EGLAPIENTRY
+#endif
+
 /* Macros used in EGL function prototype declarations.
  *
  * EGLAPI return-type EGLAPIENTRY eglFunction(arguments);
diff --git a/include/GL/gl.h b/include/GL/gl.h
index 5f8bc2b..c163171 100644
--- a/include/GL/gl.h
+++ b/include/GL/gl.h
@@ -85,7 +85,9 @@
  * glut.h or gl.h.
  */
 #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__)
+#ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN 1
+#endif
 #include <windows.h>
 #endif
 
diff --git a/include/GL/gl_mangle.h b/include/GL/gl_mangle.h
index 59f6149..b292840 100644
--- a/include/GL/gl_mangle.h
+++ b/include/GL/gl_mangle.h
@@ -30,6 +30,7 @@
 /*REGENERATE_TO_END-----------ALL LINES BELOW HERE GET REPLACED ON REGENERATION */
 
 #define glAccum		MANGLE(Accum)
+#define glActiveProgramEXT		MANGLE(ActiveProgramEXT)
 #define glActiveStencilFaceEXT		MANGLE(ActiveStencilFaceEXT)
 #define glActiveTextureARB		MANGLE(ActiveTextureARB)
 #define glActiveTexture		MANGLE(ActiveTexture)
@@ -60,6 +61,7 @@
 #define glBeginTransformFeedback		MANGLE(BeginTransformFeedback)
 #define glBeginTransformFeedbackNV		MANGLE(BeginTransformFeedbackNV)
 #define glBeginVertexShaderEXT		MANGLE(BeginVertexShaderEXT)
+#define glBeginVideoCaptureNV		MANGLE(BeginVideoCaptureNV)
 #define glBindAttribLocationARB		MANGLE(BindAttribLocationARB)
 #define glBindAttribLocation		MANGLE(BindAttribLocation)
 #define glBindBufferARB		MANGLE(BindBufferARB)
@@ -93,6 +95,8 @@
 #define glBindVertexArrayAPPLE		MANGLE(BindVertexArrayAPPLE)
 #define glBindVertexArray		MANGLE(BindVertexArray)
 #define glBindVertexShaderEXT		MANGLE(BindVertexShaderEXT)
+#define glBindVideoCaptureStreamBufferNV		MANGLE(BindVideoCaptureStreamBufferNV)
+#define glBindVideoCaptureStreamTextureNV		MANGLE(BindVideoCaptureStreamTextureNV)
 #define glBinormal3bEXT		MANGLE(Binormal3bEXT)
 #define glBinormal3bvEXT		MANGLE(Binormal3bvEXT)
 #define glBinormal3dEXT		MANGLE(Binormal3dEXT)
@@ -126,6 +130,7 @@
 #define glBlendFuncSeparate		MANGLE(BlendFuncSeparate)
 #define glBlitFramebufferEXT		MANGLE(BlitFramebufferEXT)
 #define glBlitFramebuffer		MANGLE(BlitFramebuffer)
+#define glBufferAddressRangeNV		MANGLE(BufferAddressRangeNV)
 #define glBufferDataARB		MANGLE(BufferDataARB)
 #define glBufferData		MANGLE(BufferData)
 #define glBufferParameteriAPPLE		MANGLE(BufferParameteriAPPLE)
@@ -202,6 +207,7 @@
 #define glColor4uiv		MANGLE(Color4uiv)
 #define glColor4us		MANGLE(Color4us)
 #define glColor4usv		MANGLE(Color4usv)
+#define glColorFormatNV		MANGLE(ColorFormatNV)
 #define glColorFragmentOp1ATI		MANGLE(ColorFragmentOp1ATI)
 #define glColorFragmentOp2ATI		MANGLE(ColorFragmentOp2ATI)
 #define glColorFragmentOp3ATI		MANGLE(ColorFragmentOp3ATI)
@@ -276,6 +282,7 @@
 #define glCopyConvolutionFilter1D		MANGLE(CopyConvolutionFilter1D)
 #define glCopyConvolutionFilter2DEXT		MANGLE(CopyConvolutionFilter2DEXT)
 #define glCopyConvolutionFilter2D		MANGLE(CopyConvolutionFilter2D)
+#define glCopyImageSubDataNV		MANGLE(CopyImageSubDataNV)
 #define glCopyMultiTexImage1DEXT		MANGLE(CopyMultiTexImage1DEXT)
 #define glCopyMultiTexImage2DEXT		MANGLE(CopyMultiTexImage2DEXT)
 #define glCopyMultiTexSubImage1DEXT		MANGLE(CopyMultiTexSubImage1DEXT)
@@ -302,6 +309,7 @@
 #define glCreateProgramObjectARB		MANGLE(CreateProgramObjectARB)
 #define glCreateShader		MANGLE(CreateShader)
 #define glCreateShaderObjectARB		MANGLE(CreateShaderObjectARB)
+#define glCreateShaderProgramEXT		MANGLE(CreateShaderProgramEXT)
 #define glCullFace		MANGLE(CullFace)
 #define glCullParameterdvEXT		MANGLE(CullParameterdvEXT)
 #define glCullParameterfvEXT		MANGLE(CullParameterfvEXT)
@@ -379,6 +387,7 @@
 #define glDrawRangeElementsEXT		MANGLE(DrawRangeElementsEXT)
 #define glDrawRangeElements		MANGLE(DrawRangeElements)
 #define glDrawTransformFeedbackNV		MANGLE(DrawTransformFeedbackNV)
+#define glEdgeFlagFormatNV		MANGLE(EdgeFlagFormatNV)
 #define glEdgeFlag		MANGLE(EdgeFlag)
 #define glEdgeFlagPointerEXT		MANGLE(EdgeFlagPointerEXT)
 #define glEdgeFlagPointerListIBM		MANGLE(EdgeFlagPointerListIBM)
@@ -408,6 +417,7 @@
 #define glEndTransformFeedback		MANGLE(EndTransformFeedback)
 #define glEndTransformFeedbackNV		MANGLE(EndTransformFeedbackNV)
 #define glEndVertexShaderEXT		MANGLE(EndVertexShaderEXT)
+#define glEndVideoCaptureNV		MANGLE(EndVideoCaptureNV)
 #define glEvalCoord1d		MANGLE(EvalCoord1d)
 #define glEvalCoord1dv		MANGLE(EvalCoord1dv)
 #define glEvalCoord1f		MANGLE(EvalCoord1f)
@@ -445,6 +455,7 @@
 #define glFogCoorddv		MANGLE(FogCoorddv)
 #define glFogCoordfEXT		MANGLE(FogCoordfEXT)
 #define glFogCoordf		MANGLE(FogCoordf)
+#define glFogCoordFormatNV		MANGLE(FogCoordFormatNV)
 #define glFogCoordfvEXT		MANGLE(FogCoordfvEXT)
 #define glFogCoordfv		MANGLE(FogCoordfv)
 #define glFogCoordhNV		MANGLE(FogCoordhNV)
@@ -544,6 +555,7 @@
 #define glGetBufferParameteri64v		MANGLE(GetBufferParameteri64v)
 #define glGetBufferParameterivARB		MANGLE(GetBufferParameterivARB)
 #define glGetBufferParameteriv		MANGLE(GetBufferParameteriv)
+#define glGetBufferParameterui64vNV		MANGLE(GetBufferParameterui64vNV)
 #define glGetBufferPointervARB		MANGLE(GetBufferPointervARB)
 #define glGetBufferPointerv		MANGLE(GetBufferPointerv)
 #define glGetBufferSubDataARB		MANGLE(GetBufferSubDataARB)
@@ -609,6 +621,8 @@
 #define glGetInteger64v		MANGLE(GetInteger64v)
 #define glGetIntegerIndexedvEXT		MANGLE(GetIntegerIndexedvEXT)
 #define glGetIntegeri_v		MANGLE(GetIntegeri_v)
+#define glGetIntegerui64i_vNV		MANGLE(GetIntegerui64i_vNV)
+#define glGetIntegerui64vNV		MANGLE(GetIntegerui64vNV)
 #define glGetIntegerv		MANGLE(GetIntegerv)
 #define glGetInvariantBooleanvEXT		MANGLE(GetInvariantBooleanvEXT)
 #define glGetInvariantFloatvEXT		MANGLE(GetInvariantFloatvEXT)
@@ -651,6 +665,7 @@
 #define glGetMultiTexParameterIuivEXT		MANGLE(GetMultiTexParameterIuivEXT)
 #define glGetMultiTexParameterivEXT		MANGLE(GetMultiTexParameterivEXT)
 #define glGetNamedBufferParameterivEXT		MANGLE(GetNamedBufferParameterivEXT)
+#define glGetNamedBufferParameterui64vNV		MANGLE(GetNamedBufferParameterui64vNV)
 #define glGetNamedBufferPointervEXT		MANGLE(GetNamedBufferPointervEXT)
 #define glGetNamedBufferSubDataEXT		MANGLE(GetNamedBufferSubDataEXT)
 #define glGetNamedFramebufferAttachmentParameterivEXT		MANGLE(GetNamedFramebufferAttachmentParameterivEXT)
@@ -761,6 +776,7 @@
 #define glGetUniformLocationARB		MANGLE(GetUniformLocationARB)
 #define glGetUniformLocation		MANGLE(GetUniformLocation)
 #define glGetUniformOffsetEXT		MANGLE(GetUniformOffsetEXT)
+#define glGetUniformui64vNV		MANGLE(GetUniformui64vNV)
 #define glGetUniformuivEXT		MANGLE(GetUniformuivEXT)
 #define glGetUniformuiv		MANGLE(GetUniformuiv)
 #define glGetVariantArrayObjectfvATI		MANGLE(GetVariantArrayObjectfvATI)
@@ -788,6 +804,10 @@
 #define glGetVertexAttribPointervARB		MANGLE(GetVertexAttribPointervARB)
 #define glGetVertexAttribPointerv		MANGLE(GetVertexAttribPointerv)
 #define glGetVertexAttribPointervNV		MANGLE(GetVertexAttribPointervNV)
+#define glGetVideoCaptureivNV		MANGLE(GetVideoCaptureivNV)
+#define glGetVideoCaptureStreamdvNV		MANGLE(GetVideoCaptureStreamdvNV)
+#define glGetVideoCaptureStreamfvNV		MANGLE(GetVideoCaptureStreamfvNV)
+#define glGetVideoCaptureStreamivNV		MANGLE(GetVideoCaptureStreamivNV)
 #define glGetVideoi64vNV		MANGLE(GetVideoi64vNV)
 #define glGetVideoivNV		MANGLE(GetVideoivNV)
 #define glGetVideoui64vNV		MANGLE(GetVideoui64vNV)
@@ -812,6 +832,7 @@
 #define glIndexd		MANGLE(Indexd)
 #define glIndexdv		MANGLE(Indexdv)
 #define glIndexf		MANGLE(Indexf)
+#define glIndexFormatNV		MANGLE(IndexFormatNV)
 #define glIndexFuncEXT		MANGLE(IndexFuncEXT)
 #define glIndexfv		MANGLE(Indexfv)
 #define glIndexi		MANGLE(Indexi)
@@ -832,6 +853,7 @@
 #define glIsAsyncMarkerSGIX		MANGLE(IsAsyncMarkerSGIX)
 #define glIsBufferARB		MANGLE(IsBufferARB)
 #define glIsBuffer		MANGLE(IsBuffer)
+#define glIsBufferResidentNV		MANGLE(IsBufferResidentNV)
 #define glIsEnabledi		MANGLE(IsEnabledi)
 #define glIsEnabledIndexedEXT		MANGLE(IsEnabledIndexedEXT)
 #define glIsEnabled		MANGLE(IsEnabled)
@@ -840,6 +862,7 @@
 #define glIsFramebufferEXT		MANGLE(IsFramebufferEXT)
 #define glIsFramebuffer		MANGLE(IsFramebuffer)
 #define glIsList		MANGLE(IsList)
+#define glIsNamedBufferResidentNV		MANGLE(IsNamedBufferResidentNV)
 #define glIsObjectBufferATI		MANGLE(IsObjectBufferATI)
 #define glIsOcclusionQueryNV		MANGLE(IsOcclusionQueryNV)
 #define glIsProgramARB		MANGLE(IsProgramARB)
@@ -888,6 +911,8 @@
 #define glLoadTransposeMatrixf		MANGLE(LoadTransposeMatrixf)
 #define glLockArraysEXT		MANGLE(LockArraysEXT)
 #define glLogicOp		MANGLE(LogicOp)
+#define glMakeBufferNonResidentNV		MANGLE(MakeBufferNonResidentNV)
+#define glMakeBufferResidentNV		MANGLE(MakeBufferResidentNV)
 #define glMap1d		MANGLE(Map1d)
 #define glMap1f		MANGLE(Map1f)
 #define glMap2d		MANGLE(Map2d)
@@ -1060,6 +1085,8 @@
 #define glNamedFramebufferTextureEXT		MANGLE(NamedFramebufferTextureEXT)
 #define glNamedFramebufferTextureFaceEXT		MANGLE(NamedFramebufferTextureFaceEXT)
 #define glNamedFramebufferTextureLayerEXT		MANGLE(NamedFramebufferTextureLayerEXT)
+#define glNamedMakeBufferNonResidentNV		MANGLE(NamedMakeBufferNonResidentNV)
+#define glNamedMakeBufferResidentNV		MANGLE(NamedMakeBufferResidentNV)
 #define glNamedProgramLocalParameter4dEXT		MANGLE(NamedProgramLocalParameter4dEXT)
 #define glNamedProgramLocalParameter4dvEXT		MANGLE(NamedProgramLocalParameter4dvEXT)
 #define glNamedProgramLocalParameter4fEXT		MANGLE(NamedProgramLocalParameter4fEXT)
@@ -1091,6 +1118,7 @@
 #define glNormal3iv		MANGLE(Normal3iv)
 #define glNormal3s		MANGLE(Normal3s)
 #define glNormal3sv		MANGLE(Normal3sv)
+#define glNormalFormatNV		MANGLE(NormalFormatNV)
 #define glNormalPointerEXT		MANGLE(NormalPointerEXT)
 #define glNormalPointerListIBM		MANGLE(NormalPointerListIBM)
 #define glNormalPointer		MANGLE(NormalPointer)
@@ -1234,6 +1262,8 @@
 #define glProgramUniformMatrix4fvEXT		MANGLE(ProgramUniformMatrix4fvEXT)
 #define glProgramUniformMatrix4x2fvEXT		MANGLE(ProgramUniformMatrix4x2fvEXT)
 #define glProgramUniformMatrix4x3fvEXT		MANGLE(ProgramUniformMatrix4x3fvEXT)
+#define glProgramUniformui64NV		MANGLE(ProgramUniformui64NV)
+#define glProgramUniformui64vNV		MANGLE(ProgramUniformui64vNV)
 #define glProgramVertexLimitNV		MANGLE(ProgramVertexLimitNV)
 #define glProvokingVertexEXT		MANGLE(ProvokingVertexEXT)
 #define glProvokingVertex		MANGLE(ProvokingVertex)
@@ -1362,6 +1392,7 @@
 #define glSecondaryColor3us		MANGLE(SecondaryColor3us)
 #define glSecondaryColor3usvEXT		MANGLE(SecondaryColor3usvEXT)
 #define glSecondaryColor3usv		MANGLE(SecondaryColor3usv)
+#define glSecondaryColorFormatNV		MANGLE(SecondaryColorFormatNV)
 #define glSecondaryColorPointerEXT		MANGLE(SecondaryColorPointerEXT)
 #define glSecondaryColorPointerListIBM		MANGLE(SecondaryColorPointerListIBM)
 #define glSecondaryColorPointer		MANGLE(SecondaryColorPointer)
@@ -1475,6 +1506,7 @@
 #define glTexCoord4iv		MANGLE(TexCoord4iv)
 #define glTexCoord4s		MANGLE(TexCoord4s)
 #define glTexCoord4sv		MANGLE(TexCoord4sv)
+#define glTexCoordFormatNV		MANGLE(TexCoordFormatNV)
 #define glTexCoordPointerEXT		MANGLE(TexCoordPointerEXT)
 #define glTexCoordPointerListIBM		MANGLE(TexCoordPointerListIBM)
 #define glTexCoordPointer		MANGLE(TexCoordPointer)
@@ -1513,6 +1545,7 @@
 #define glTexSubImage3DEXT		MANGLE(TexSubImage3DEXT)
 #define glTexSubImage3D		MANGLE(TexSubImage3D)
 #define glTexSubImage4DSGIS		MANGLE(TexSubImage4DSGIS)
+#define glTextureBarrierNV		MANGLE(TextureBarrierNV)
 #define glTextureBufferEXT		MANGLE(TextureBufferEXT)
 #define glTextureColorMaskSGIS		MANGLE(TextureColorMaskSGIS)
 #define glTextureImage1DEXT		MANGLE(TextureImage1DEXT)
@@ -1601,6 +1634,8 @@
 #define glUniformMatrix4fv		MANGLE(UniformMatrix4fv)
 #define glUniformMatrix4x2fv		MANGLE(UniformMatrix4x2fv)
 #define glUniformMatrix4x3fv		MANGLE(UniformMatrix4x3fv)
+#define glUniformui64NV		MANGLE(Uniformui64NV)
+#define glUniformui64vNV		MANGLE(Uniformui64vNV)
 #define glUnlockArraysEXT		MANGLE(UnlockArraysEXT)
 #define glUnmapBufferARB		MANGLE(UnmapBufferARB)
 #define glUnmapBuffer		MANGLE(UnmapBuffer)
@@ -1609,6 +1644,7 @@
 #define glUpdateObjectBufferATI		MANGLE(UpdateObjectBufferATI)
 #define glUseProgram		MANGLE(UseProgram)
 #define glUseProgramObjectARB		MANGLE(UseProgramObjectARB)
+#define glUseShaderProgramEXT		MANGLE(UseShaderProgramEXT)
 #define glValidateProgramARB		MANGLE(ValidateProgramARB)
 #define glValidateProgram		MANGLE(ValidateProgram)
 #define glVariantArrayObjectATI		MANGLE(VariantArrayObjectATI)
@@ -1762,6 +1798,7 @@
 #define glVertexAttrib4usv		MANGLE(VertexAttrib4usv)
 #define glVertexAttribArrayObjectATI		MANGLE(VertexAttribArrayObjectATI)
 #define glVertexAttribDivisorARB		MANGLE(VertexAttribDivisorARB)
+#define glVertexAttribFormatNV		MANGLE(VertexAttribFormatNV)
 #define glVertexAttribI1iEXT		MANGLE(VertexAttribI1iEXT)
 #define glVertexAttribI1i		MANGLE(VertexAttribI1i)
 #define glVertexAttribI1ivEXT		MANGLE(VertexAttribI1ivEXT)
@@ -1802,6 +1839,7 @@
 #define glVertexAttribI4uiv		MANGLE(VertexAttribI4uiv)
 #define glVertexAttribI4usvEXT		MANGLE(VertexAttribI4usvEXT)
 #define glVertexAttribI4usv		MANGLE(VertexAttribI4usv)
+#define glVertexAttribIFormatNV		MANGLE(VertexAttribIFormatNV)
 #define glVertexAttribIPointerEXT		MANGLE(VertexAttribIPointerEXT)
 #define glVertexAttribIPointer		MANGLE(VertexAttribIPointer)
 #define glVertexAttribPointerARB		MANGLE(VertexAttribPointerARB)
@@ -1827,6 +1865,7 @@
 #define glVertexBlendARB		MANGLE(VertexBlendARB)
 #define glVertexBlendEnvfATI		MANGLE(VertexBlendEnvfATI)
 #define glVertexBlendEnviATI		MANGLE(VertexBlendEnviATI)
+#define glVertexFormatNV		MANGLE(VertexFormatNV)
 #define glVertexPointerEXT		MANGLE(VertexPointerEXT)
 #define glVertexPointerListIBM		MANGLE(VertexPointerListIBM)
 #define glVertexPointer		MANGLE(VertexPointer)
@@ -1868,6 +1907,10 @@
 #define glVertexWeighthNV		MANGLE(VertexWeighthNV)
 #define glVertexWeighthvNV		MANGLE(VertexWeighthvNV)
 #define glVertexWeightPointerEXT		MANGLE(VertexWeightPointerEXT)
+#define glVideoCaptureNV		MANGLE(VideoCaptureNV)
+#define glVideoCaptureStreamParameterdvNV		MANGLE(VideoCaptureStreamParameterdvNV)
+#define glVideoCaptureStreamParameterfvNV		MANGLE(VideoCaptureStreamParameterfvNV)
+#define glVideoCaptureStreamParameterivNV		MANGLE(VideoCaptureStreamParameterivNV)
 #define glViewport		MANGLE(Viewport)
 #define glWaitSync		MANGLE(WaitSync)
 #define glWeightbvARB		MANGLE(WeightbvARB)
diff --git a/include/GL/glew.h b/include/GL/glew.h
index 7932a1c..04b8f7e 100644
--- a/include/GL/glew.h
+++ b/include/GL/glew.h
@@ -80,7 +80,7 @@
 #define __glew_h__
 #define __GLEW_H__
 
-#if defined(__gl_h_) || defined(__GL_H__)
+#if defined(__gl_h_) || defined(__GL_H__) || defined(__X_GL_H)
 #error gl.h included before glew.h
 #endif
 #if defined(__glext_h_) || defined(__GLEXT_H_)
@@ -92,6 +92,7 @@
 
 #define __gl_h_
 #define __GL_H__
+#define __X_GL_H
 #define __glext_h_
 #define __GLEXT_H_
 #define __gl_ATI_h_
@@ -106,7 +107,7 @@
 /* <windef.h> */
 #ifndef APIENTRY
 #define GLEW_APIENTRY_DEFINED
-#  if defined(__MINGW32__)
+#  if defined(__MINGW32__) || defined(__CYGWIN__)
 #    define APIENTRY __stdcall
 #  elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__)
 #    define APIENTRY __stdcall
@@ -115,14 +116,14 @@
 #  endif
 #endif
 #ifndef GLAPI
-#  if defined(__MINGW32__)
+#  if defined(__MINGW32__) || defined(__CYGWIN__)
 #    define GLAPI extern
 #  endif
 #endif
 /* <winnt.h> */
 #ifndef CALLBACK
 #define GLEW_CALLBACK_DEFINED
-#  if defined(__MINGW32__)
+#  if defined(__MINGW32__) || defined(__CYGWIN__)
 #    define CALLBACK __attribute__ ((__stdcall__))
 #  elif (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS)
 #    define CALLBACK __stdcall
@@ -159,7 +160,7 @@
 #endif
 
 #ifndef GLAPI
-#  if defined(__MINGW32__)
+#  if defined(__MINGW32__) || defined(__CYGWIN__)
 #    define GLAPI extern
 #  else
 #    define GLAPI WINGDIAPI
@@ -246,12 +247,15 @@
 typedef unsigned long long GLuint64EXT;
 #  endif
 #else
-#  if defined(__MINGW32__)
+#  if defined(__MINGW32__) || defined(__CYGWIN__)
 #include <inttypes.h>
 #  endif
 typedef int64_t GLint64EXT;
 typedef uint64_t GLuint64EXT;
 #endif
+typedef GLint64EXT  GLint64;
+typedef GLuint64EXT GLuint64;
+typedef struct __GLsync *GLsync;
 
 #define GL_ACCUM 0x0100
 #define GL_LOAD 0x0101
@@ -2094,8 +2098,6 @@
 
 typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERPROC) (GLuint, GLenum);
 typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum);
-typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEPROC) (GLenum, GLuint, GLuint);
-typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEPROC) (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr);
 typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONPROC) (GLuint, GLuint, const GLchar*);
 typedef void (GLAPIENTRY * PFNGLCLAMPCOLORPROC) (GLenum, GLenum);
 typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFIPROC) (GLenum, GLint, GLfloat, GLint);
@@ -2109,7 +2111,6 @@
 typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKPROC) (void);
 typedef void (GLAPIENTRY * PFNGLGETBOOLEANI_VPROC) (GLenum, GLuint, GLboolean*);
 typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONPROC) (GLuint, const GLchar*);
-typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VPROC) (GLenum, GLuint, GLint*);
 typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGIPROC) (GLenum, GLuint);
 typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVPROC) (GLenum, GLenum, GLint*);
 typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVPROC) (GLenum, GLenum, GLuint*);
@@ -2120,7 +2121,7 @@
 typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIPROC) (GLenum, GLuint);
 typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVPROC) (GLenum, GLenum, const GLint*);
 typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVPROC) (GLenum, GLenum, const GLuint*);
-typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint, GLsizei, const GLint*, GLenum);
+typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint, GLsizei, const GLchar **, GLenum);
 typedef void (GLAPIENTRY * PFNGLUNIFORM1UIPROC) (GLint, GLuint);
 typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVPROC) (GLint, GLsizei, const GLuint*);
 typedef void (GLAPIENTRY * PFNGLUNIFORM2UIPROC) (GLint, GLuint, GLuint);
@@ -2153,8 +2154,6 @@
 
 #define glBeginConditionalRender GLEW_GET_FUN(__glewBeginConditionalRender)
 #define glBeginTransformFeedback GLEW_GET_FUN(__glewBeginTransformFeedback)
-#define glBindBufferBase GLEW_GET_FUN(__glewBindBufferBase)
-#define glBindBufferRange GLEW_GET_FUN(__glewBindBufferRange)
 #define glBindFragDataLocation GLEW_GET_FUN(__glewBindFragDataLocation)
 #define glClampColor GLEW_GET_FUN(__glewClampColor)
 #define glClearBufferfi GLEW_GET_FUN(__glewClearBufferfi)
@@ -2168,7 +2167,6 @@
 #define glEndTransformFeedback GLEW_GET_FUN(__glewEndTransformFeedback)
 #define glGetBooleani_v GLEW_GET_FUN(__glewGetBooleani_v)
 #define glGetFragDataLocation GLEW_GET_FUN(__glewGetFragDataLocation)
-#define glGetIntegeri_v GLEW_GET_FUN(__glewGetIntegeri_v)
 #define glGetStringi GLEW_GET_FUN(__glewGetStringi)
 #define glGetTexParameterIiv GLEW_GET_FUN(__glewGetTexParameterIiv)
 #define glGetTexParameterIuiv GLEW_GET_FUN(__glewGetTexParameterIuiv)
@@ -2214,6 +2212,97 @@
 
 #endif /* GL_VERSION_3_0 */
 
+/* ----------------------------- GL_VERSION_3_1 ---------------------------- */
+
+#ifndef GL_VERSION_3_1
+#define GL_VERSION_3_1 1
+
+#define GL_TEXTURE_RECTANGLE 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8
+#define GL_SAMPLER_2D_RECT 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64
+#define GL_TEXTURE_BUFFER 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E
+#define GL_SAMPLER_BUFFER 0x8DC2
+#define GL_INT_SAMPLER_2D_RECT 0x8DCD
+#define GL_INT_SAMPLER_BUFFER 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8
+#define GL_RED_SNORM 0x8F90
+#define GL_RG_SNORM 0x8F91
+#define GL_RGB_SNORM 0x8F92
+#define GL_RGBA_SNORM 0x8F93
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_R16_SNORM 0x8F98
+#define GL_RG16_SNORM 0x8F99
+#define GL_RGB16_SNORM 0x8F9A
+#define GL_RGBA16_SNORM 0x8F9B
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_PRIMITIVE_RESTART 0x8F9D
+#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E
+
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum, GLint, GLsizei, GLsizei);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum, GLsizei, GLenum, const GLvoid*, GLsizei);
+typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint);
+typedef void (GLAPIENTRY * PFNGLTEXBUFFERPROC) (GLenum, GLenum, GLuint);
+
+#define glDrawArraysInstanced GLEW_GET_FUN(__glewDrawArraysInstanced)
+#define glDrawElementsInstanced GLEW_GET_FUN(__glewDrawElementsInstanced)
+#define glPrimitiveRestartIndex GLEW_GET_FUN(__glewPrimitiveRestartIndex)
+#define glTexBuffer GLEW_GET_FUN(__glewTexBuffer)
+
+#define GLEW_VERSION_3_1 GLEW_GET_VAR(__GLEW_VERSION_3_1)
+
+#endif /* GL_VERSION_3_1 */
+
+/* ----------------------------- GL_VERSION_3_2 ---------------------------- */
+
+#ifndef GL_VERSION_3_2
+#define GL_VERSION_3_2 1
+
+#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_LINES_ADJACENCY 0x000A
+#define GL_LINE_STRIP_ADJACENCY 0x000B
+#define GL_TRIANGLES_ADJACENCY 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D
+#define GL_PROGRAM_POINT_SIZE 0x8642
+#define GL_GEOMETRY_VERTICES_OUT 0x8916
+#define GL_GEOMETRY_INPUT_TYPE 0x8917
+#define GL_GEOMETRY_OUTPUT_TYPE 0x8918
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
+#define GL_GEOMETRY_SHADER 0x8DD9
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum, GLenum, GLuint, GLint);
+typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum, GLenum, GLint64 *);
+typedef void (GLAPIENTRY * PFNGLGETINTEGER64I_VPROC) (GLenum, GLuint, GLint64 *);
+
+#define glFramebufferTexture GLEW_GET_FUN(__glewFramebufferTexture)
+#define glGetBufferParameteri64v GLEW_GET_FUN(__glewGetBufferParameteri64v)
+#define glGetInteger64i_v GLEW_GET_FUN(__glewGetInteger64i_v)
+
+#define GLEW_VERSION_3_2 GLEW_GET_VAR(__GLEW_VERSION_3_2)
+
+#endif /* GL_VERSION_3_2 */
+
 /* -------------------------- GL_3DFX_multisample -------------------------- */
 
 #ifndef GL_3DFX_multisample
@@ -2253,6 +2342,111 @@
 
 #endif /* GL_3DFX_texture_compression_FXT1 */
 
+/* ----------------------- GL_AMD_draw_buffers_blend ----------------------- */
+
+#ifndef GL_AMD_draw_buffers_blend
+#define GL_AMD_draw_buffers_blend 1
+
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+
+#define glBlendEquationIndexedAMD GLEW_GET_FUN(__glewBlendEquationIndexedAMD)
+#define glBlendEquationSeparateIndexedAMD GLEW_GET_FUN(__glewBlendEquationSeparateIndexedAMD)
+#define glBlendFuncIndexedAMD GLEW_GET_FUN(__glewBlendFuncIndexedAMD)
+#define glBlendFuncSeparateIndexedAMD GLEW_GET_FUN(__glewBlendFuncSeparateIndexedAMD)
+
+#define GLEW_AMD_draw_buffers_blend GLEW_GET_VAR(__GLEW_AMD_draw_buffers_blend)
+
+#endif /* GL_AMD_draw_buffers_blend */
+
+/* ----------------------- GL_AMD_performance_monitor ---------------------- */
+
+#ifndef GL_AMD_performance_monitor
+#define GL_AMD_performance_monitor 1
+
+#define GL_UNSIGNED_INT 0x1405
+#define GL_FLOAT 0x1406
+#define GL_COUNTER_TYPE_AMD 0x8BC0
+#define GL_COUNTER_RANGE_AMD 0x8BC1
+#define GL_UNSIGNED_INT64_AMD 0x8BC2
+#define GL_PERCENTAGE_AMD 0x8BC3
+#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4
+#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5
+#define GL_PERFMON_RESULT_AMD 0x8BC6
+
+typedef void (GLAPIENTRY * PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (GLAPIENTRY * PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors);
+typedef void (GLAPIENTRY * PFNGLENDPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (GLAPIENTRY * PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint *bytesWritten);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void* data);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, char *counterString);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint* numCounters, GLint *maxActiveCounters, GLsizei countersSize, GLuint *counters);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei* length, char *groupString);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint* numGroups, GLsizei groupsSize, GLuint *groups);
+typedef void (GLAPIENTRY * PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* counterList);
+
+#define glBeginPerfMonitorAMD GLEW_GET_FUN(__glewBeginPerfMonitorAMD)
+#define glDeletePerfMonitorsAMD GLEW_GET_FUN(__glewDeletePerfMonitorsAMD)
+#define glEndPerfMonitorAMD GLEW_GET_FUN(__glewEndPerfMonitorAMD)
+#define glGenPerfMonitorsAMD GLEW_GET_FUN(__glewGenPerfMonitorsAMD)
+#define glGetPerfMonitorCounterDataAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterDataAMD)
+#define glGetPerfMonitorCounterInfoAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterInfoAMD)
+#define glGetPerfMonitorCounterStringAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterStringAMD)
+#define glGetPerfMonitorCountersAMD GLEW_GET_FUN(__glewGetPerfMonitorCountersAMD)
+#define glGetPerfMonitorGroupStringAMD GLEW_GET_FUN(__glewGetPerfMonitorGroupStringAMD)
+#define glGetPerfMonitorGroupsAMD GLEW_GET_FUN(__glewGetPerfMonitorGroupsAMD)
+#define glSelectPerfMonitorCountersAMD GLEW_GET_FUN(__glewSelectPerfMonitorCountersAMD)
+
+#define GLEW_AMD_performance_monitor GLEW_GET_VAR(__GLEW_AMD_performance_monitor)
+
+#endif /* GL_AMD_performance_monitor */
+
+/* ------------------------ GL_AMD_texture_texture4 ------------------------ */
+
+#ifndef GL_AMD_texture_texture4
+#define GL_AMD_texture_texture4 1
+
+#define GLEW_AMD_texture_texture4 GLEW_GET_VAR(__GLEW_AMD_texture_texture4)
+
+#endif /* GL_AMD_texture_texture4 */
+
+/* -------------------- GL_AMD_vertex_shader_tessellator ------------------- */
+
+#ifndef GL_AMD_vertex_shader_tessellator
+#define GL_AMD_vertex_shader_tessellator 1
+
+#define GL_SAMPLER_BUFFER_AMD 0x9001
+#define GL_INT_SAMPLER_BUFFER_AMD 0x9002
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003
+#define GL_TESSELLATION_MODE_AMD 0x9004
+#define GL_TESSELLATION_FACTOR_AMD 0x9005
+#define GL_DISCRETE_AMD 0x9006
+#define GL_CONTINUOUS_AMD 0x9007
+
+typedef void (GLAPIENTRY * PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor);
+typedef void (GLAPIENTRY * PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode);
+
+#define glTessellationFactorAMD GLEW_GET_FUN(__glewTessellationFactorAMD)
+#define glTessellationModeAMD GLEW_GET_FUN(__glewTessellationModeAMD)
+
+#define GLEW_AMD_vertex_shader_tessellator GLEW_GET_VAR(__GLEW_AMD_vertex_shader_tessellator)
+
+#endif /* GL_AMD_vertex_shader_tessellator */
+
+/* ----------------------- GL_APPLE_aux_depth_stencil ---------------------- */
+
+#ifndef GL_APPLE_aux_depth_stencil
+#define GL_APPLE_aux_depth_stencil 1
+
+#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14
+
+#define GLEW_APPLE_aux_depth_stencil GLEW_GET_VAR(__GLEW_APPLE_aux_depth_stencil)
+
+#endif /* GL_APPLE_aux_depth_stencil */
+
 /* ------------------------ GL_APPLE_client_storage ------------------------ */
 
 #ifndef GL_APPLE_client_storage
@@ -2361,6 +2555,30 @@
 
 #endif /* GL_APPLE_flush_buffer_range */
 
+/* ----------------------- GL_APPLE_object_purgeable ----------------------- */
+
+#ifndef GL_APPLE_object_purgeable
+#define GL_APPLE_object_purgeable 1
+
+#define GL_BUFFER_OBJECT_APPLE 0x85B3
+#define GL_RELEASED_APPLE 0x8A19
+#define GL_VOLATILE_APPLE 0x8A1A
+#define GL_RETAINED_APPLE 0x8A1B
+#define GL_UNDEFINED_APPLE 0x8A1C
+#define GL_PURGEABLE_APPLE 0x8A1D
+
+typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint* params);
+typedef GLenum (GLAPIENTRY * PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option);
+typedef GLenum (GLAPIENTRY * PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option);
+
+#define glGetObjectParameterivAPPLE GLEW_GET_FUN(__glewGetObjectParameterivAPPLE)
+#define glObjectPurgeableAPPLE GLEW_GET_FUN(__glewObjectPurgeableAPPLE)
+#define glObjectUnpurgeableAPPLE GLEW_GET_FUN(__glewObjectUnpurgeableAPPLE)
+
+#define GLEW_APPLE_object_purgeable GLEW_GET_VAR(__GLEW_APPLE_object_purgeable)
+
+#endif /* GL_APPLE_object_purgeable */
+
 /* ------------------------- GL_APPLE_pixel_buffer ------------------------- */
 
 #ifndef GL_APPLE_pixel_buffer
@@ -2372,6 +2590,31 @@
 
 #endif /* GL_APPLE_pixel_buffer */
 
+/* ---------------------------- GL_APPLE_rgb_422 --------------------------- */
+
+#ifndef GL_APPLE_rgb_422
+#define GL_APPLE_rgb_422 1
+
+#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB
+#define GL_RGB_422_APPLE 0x8A1F
+
+#define GLEW_APPLE_rgb_422 GLEW_GET_VAR(__GLEW_APPLE_rgb_422)
+
+#endif /* GL_APPLE_rgb_422 */
+
+/* --------------------------- GL_APPLE_row_bytes -------------------------- */
+
+#ifndef GL_APPLE_row_bytes
+#define GL_APPLE_row_bytes 1
+
+#define GL_PACK_ROW_BYTES_APPLE 0x8A15
+#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16
+
+#define GLEW_APPLE_row_bytes GLEW_GET_VAR(__GLEW_APPLE_row_bytes)
+
+#endif /* GL_APPLE_row_bytes */
+
 /* ------------------------ GL_APPLE_specular_vector ----------------------- */
 
 #ifndef GL_APPLE_specular_vector
@@ -2462,6 +2705,42 @@
 
 #endif /* GL_APPLE_vertex_array_range */
 
+/* ------------------- GL_APPLE_vertex_program_evaluators ------------------ */
+
+#ifndef GL_APPLE_vertex_program_evaluators
+#define GL_APPLE_vertex_program_evaluators 1
+
+#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00
+#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01
+#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02
+#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03
+#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04
+#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05
+#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06
+#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07
+#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08
+#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09
+
+typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname);
+typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname);
+typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname);
+typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble* points);
+typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat* points);
+typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble* points);
+typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat* points);
+
+#define glDisableVertexAttribAPPLE GLEW_GET_FUN(__glewDisableVertexAttribAPPLE)
+#define glEnableVertexAttribAPPLE GLEW_GET_FUN(__glewEnableVertexAttribAPPLE)
+#define glIsVertexAttribEnabledAPPLE GLEW_GET_FUN(__glewIsVertexAttribEnabledAPPLE)
+#define glMapVertexAttrib1dAPPLE GLEW_GET_FUN(__glewMapVertexAttrib1dAPPLE)
+#define glMapVertexAttrib1fAPPLE GLEW_GET_FUN(__glewMapVertexAttrib1fAPPLE)
+#define glMapVertexAttrib2dAPPLE GLEW_GET_FUN(__glewMapVertexAttrib2dAPPLE)
+#define glMapVertexAttrib2fAPPLE GLEW_GET_FUN(__glewMapVertexAttrib2fAPPLE)
+
+#define GLEW_APPLE_vertex_program_evaluators GLEW_GET_VAR(__GLEW_APPLE_vertex_program_evaluators)
+
+#endif /* GL_APPLE_vertex_program_evaluators */
+
 /* --------------------------- GL_APPLE_ycbcr_422 -------------------------- */
 
 #ifndef GL_APPLE_ycbcr_422
@@ -2494,6 +2773,31 @@
 
 #endif /* GL_ARB_color_buffer_float */
 
+/* -------------------------- GL_ARB_compatibility ------------------------- */
+
+#ifndef GL_ARB_compatibility
+#define GL_ARB_compatibility 1
+
+#define GLEW_ARB_compatibility GLEW_GET_VAR(__GLEW_ARB_compatibility)
+
+#endif /* GL_ARB_compatibility */
+
+/* --------------------------- GL_ARB_copy_buffer -------------------------- */
+
+#ifndef GL_ARB_copy_buffer
+#define GL_ARB_copy_buffer 1
+
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+
+typedef void (GLAPIENTRY * PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size);
+
+#define glCopyBufferSubData GLEW_GET_FUN(__glewCopyBufferSubData)
+
+#define GLEW_ARB_copy_buffer GLEW_GET_VAR(__GLEW_ARB_copy_buffer)
+
+#endif /* GL_ARB_copy_buffer */
+
 /* ----------------------- GL_ARB_depth_buffer_float ----------------------- */
 
 #ifndef GL_ARB_depth_buffer_float
@@ -2507,6 +2811,17 @@
 
 #endif /* GL_ARB_depth_buffer_float */
 
+/* --------------------------- GL_ARB_depth_clamp -------------------------- */
+
+#ifndef GL_ARB_depth_clamp
+#define GL_ARB_depth_clamp 1
+
+#define GL_DEPTH_CLAMP 0x864F
+
+#define GLEW_ARB_depth_clamp GLEW_GET_VAR(__GLEW_ARB_depth_clamp)
+
+#endif /* GL_ARB_depth_clamp */
+
 /* -------------------------- GL_ARB_depth_texture ------------------------- */
 
 #ifndef GL_ARB_depth_texture
@@ -2553,6 +2868,44 @@
 
 #endif /* GL_ARB_draw_buffers */
 
+/* ----------------------- GL_ARB_draw_buffers_blend ----------------------- */
+
+#ifndef GL_ARB_draw_buffers_blend
+#define GL_ARB_draw_buffers_blend 1
+
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst);
+
+#define glBlendEquationSeparateiARB GLEW_GET_FUN(__glewBlendEquationSeparateiARB)
+#define glBlendEquationiARB GLEW_GET_FUN(__glewBlendEquationiARB)
+#define glBlendFuncSeparateiARB GLEW_GET_FUN(__glewBlendFuncSeparateiARB)
+#define glBlendFunciARB GLEW_GET_FUN(__glewBlendFunciARB)
+
+#define GLEW_ARB_draw_buffers_blend GLEW_GET_VAR(__GLEW_ARB_draw_buffers_blend)
+
+#endif /* GL_ARB_draw_buffers_blend */
+
+/* -------------------- GL_ARB_draw_elements_base_vertex ------------------- */
+
+#ifndef GL_ARB_draw_elements_base_vertex
+#define GL_ARB_draw_elements_base_vertex 1
+
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, void* indices, GLint basevertex);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount, GLint basevertex);
+typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, void* indices, GLint basevertex);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei* count, GLenum type, GLvoid**indices, GLsizei primcount, GLint *basevertex);
+
+#define glDrawElementsBaseVertex GLEW_GET_FUN(__glewDrawElementsBaseVertex)
+#define glDrawElementsInstancedBaseVertex GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertex)
+#define glDrawRangeElementsBaseVertex GLEW_GET_FUN(__glewDrawRangeElementsBaseVertex)
+#define glMultiDrawElementsBaseVertex GLEW_GET_FUN(__glewMultiDrawElementsBaseVertex)
+
+#define GLEW_ARB_draw_elements_base_vertex GLEW_GET_VAR(__GLEW_ARB_draw_elements_base_vertex)
+
+#endif /* GL_ARB_draw_elements_base_vertex */
+
 /* ------------------------- GL_ARB_draw_instanced ------------------------- */
 
 #ifndef GL_ARB_draw_instanced
@@ -2568,6 +2921,15 @@
 
 #endif /* GL_ARB_draw_instanced */
 
+/* ------------------- GL_ARB_fragment_coord_conventions ------------------- */
+
+#ifndef GL_ARB_fragment_coord_conventions
+#define GL_ARB_fragment_coord_conventions 1
+
+#define GLEW_ARB_fragment_coord_conventions GLEW_GET_VAR(__GLEW_ARB_fragment_coord_conventions)
+
+#endif /* GL_ARB_fragment_coord_conventions */
+
 /* ------------------------ GL_ARB_fragment_program ------------------------ */
 
 #ifndef GL_ARB_fragment_program
@@ -2702,10 +3064,10 @@
 typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint* framebuffers);
 typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint* renderbuffers);
 typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
-typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target,GLenum attachment, GLuint texture,GLint level,GLint layer);
 typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
 typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
 typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target,GLenum attachment, GLuint texture,GLint level,GLint layer);
 typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers);
 typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers);
 typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPPROC) (GLenum target);
@@ -2723,10 +3085,10 @@
 #define glDeleteFramebuffers GLEW_GET_FUN(__glewDeleteFramebuffers)
 #define glDeleteRenderbuffers GLEW_GET_FUN(__glewDeleteRenderbuffers)
 #define glFramebufferRenderbuffer GLEW_GET_FUN(__glewFramebufferRenderbuffer)
-#define glFramebufferTextureLayer GLEW_GET_FUN(__glewFramebufferTextureLayer)
 #define glFramebufferTexture1D GLEW_GET_FUN(__glewFramebufferTexture1D)
 #define glFramebufferTexture2D GLEW_GET_FUN(__glewFramebufferTexture2D)
 #define glFramebufferTexture3D GLEW_GET_FUN(__glewFramebufferTexture3D)
+#define glFramebufferTextureLayer GLEW_GET_FUN(__glewFramebufferTextureLayer)
 #define glGenFramebuffers GLEW_GET_FUN(__glewGenFramebuffers)
 #define glGenRenderbuffers GLEW_GET_FUN(__glewGenRenderbuffers)
 #define glGenerateMipmap GLEW_GET_FUN(__glewGenerateMipmap)
@@ -3252,6 +3614,51 @@
 
 #endif /* GL_ARB_point_sprite */
 
+/* ------------------------ GL_ARB_provoking_vertex ------------------------ */
+
+#ifndef GL_ARB_provoking_vertex
+#define GL_ARB_provoking_vertex 1
+
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C
+#define GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define GL_PROVOKING_VERTEX 0x8E4F
+
+typedef void (GLAPIENTRY * PFNGLPROVOKINGVERTEXPROC) (GLenum mode);
+
+#define glProvokingVertex GLEW_GET_FUN(__glewProvokingVertex)
+
+#define GLEW_ARB_provoking_vertex GLEW_GET_VAR(__GLEW_ARB_provoking_vertex)
+
+#endif /* GL_ARB_provoking_vertex */
+
+/* ------------------------- GL_ARB_sample_shading ------------------------- */
+
+#ifndef GL_ARB_sample_shading
+#define GL_ARB_sample_shading 1
+
+#define GL_SAMPLE_SHADING_ARB 0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37
+
+typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGARBPROC) (GLclampf value);
+
+#define glMinSampleShadingARB GLEW_GET_FUN(__glewMinSampleShadingARB)
+
+#define GLEW_ARB_sample_shading GLEW_GET_VAR(__GLEW_ARB_sample_shading)
+
+#endif /* GL_ARB_sample_shading */
+
+/* ------------------------ GL_ARB_seamless_cube_map ----------------------- */
+
+#ifndef GL_ARB_seamless_cube_map
+#define GL_ARB_seamless_cube_map 1
+
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+
+#define GLEW_ARB_seamless_cube_map GLEW_GET_VAR(__GLEW_ARB_seamless_cube_map)
+
+#endif /* GL_ARB_seamless_cube_map */
+
 /* ------------------------- GL_ARB_shader_objects ------------------------- */
 
 #ifndef GL_ARB_shader_objects
@@ -3379,6 +3786,15 @@
 
 #endif /* GL_ARB_shader_objects */
 
+/* ----------------------- GL_ARB_shader_texture_lod ----------------------- */
+
+#ifndef GL_ARB_shader_texture_lod
+#define GL_ARB_shader_texture_lod 1
+
+#define GLEW_ARB_shader_texture_lod GLEW_GET_VAR(__GLEW_ARB_shader_texture_lod)
+
+#endif /* GL_ARB_shader_texture_lod */
+
 /* ---------------------- GL_ARB_shading_language_100 ---------------------- */
 
 #ifndef GL_ARB_shading_language_100
@@ -3414,6 +3830,47 @@
 
 #endif /* GL_ARB_shadow_ambient */
 
+/* ------------------------------ GL_ARB_sync ------------------------------ */
+
+#ifndef GL_ARB_sync
+#define GL_ARB_sync 1
+
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_OBJECT_TYPE 0x9112
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_STATUS 0x9114
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_UNSIGNALED 0x9118
+#define GL_SIGNALED 0x9119
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_WAIT_FAILED 0x911D
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF
+
+typedef GLenum (GLAPIENTRY * PFNGLCLIENTWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout);
+typedef void (GLAPIENTRY * PFNGLDELETESYNCPROC) (GLsync GLsync);
+typedef GLsync (GLAPIENTRY * PFNGLFENCESYNCPROC) (GLenum condition,GLbitfield flags);
+typedef void (GLAPIENTRY * PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64* params);
+typedef void (GLAPIENTRY * PFNGLGETSYNCIVPROC) (GLsync GLsync,GLenum pname,GLsizei bufSize,GLsizei* length, GLint *values);
+typedef GLboolean (GLAPIENTRY * PFNGLISSYNCPROC) (GLsync GLsync);
+typedef void (GLAPIENTRY * PFNGLWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout);
+
+#define glClientWaitSync GLEW_GET_FUN(__glewClientWaitSync)
+#define glDeleteSync GLEW_GET_FUN(__glewDeleteSync)
+#define glFenceSync GLEW_GET_FUN(__glewFenceSync)
+#define glGetInteger64v GLEW_GET_FUN(__glewGetInteger64v)
+#define glGetSynciv GLEW_GET_FUN(__glewGetSynciv)
+#define glIsSync GLEW_GET_FUN(__glewIsSync)
+#define glWaitSync GLEW_GET_FUN(__glewWaitSync)
+
+#define GLEW_ARB_sync GLEW_GET_VAR(__GLEW_ARB_sync)
+
+#endif /* GL_ARB_sync */
+
 /* ---------------------- GL_ARB_texture_border_clamp ---------------------- */
 
 #ifndef GL_ARB_texture_border_clamp
@@ -3517,6 +3974,23 @@
 
 #endif /* GL_ARB_texture_cube_map */
 
+/* --------------------- GL_ARB_texture_cube_map_array --------------------- */
+
+#ifndef GL_ARB_texture_cube_map_array
+#define GL_ARB_texture_cube_map_array 1
+
+#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B
+#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F
+
+#define GLEW_ARB_texture_cube_map_array GLEW_GET_VAR(__GLEW_ARB_texture_cube_map_array)
+
+#endif /* GL_ARB_texture_cube_map_array */
+
 /* ------------------------- GL_ARB_texture_env_add ------------------------ */
 
 #ifndef GL_ARB_texture_env_add
@@ -3609,6 +4083,19 @@
 
 #endif /* GL_ARB_texture_float */
 
+/* ------------------------- GL_ARB_texture_gather ------------------------- */
+
+#ifndef GL_ARB_texture_gather
+#define GL_ARB_texture_gather 1
+
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F
+
+#define GLEW_ARB_texture_gather GLEW_GET_VAR(__GLEW_ARB_texture_gather)
+
+#endif /* GL_ARB_texture_gather */
+
 /* --------------------- GL_ARB_texture_mirrored_repeat -------------------- */
 
 #ifndef GL_ARB_texture_mirrored_repeat
@@ -3620,6 +4107,47 @@
 
 #endif /* GL_ARB_texture_mirrored_repeat */
 
+/* ----------------------- GL_ARB_texture_multisample ---------------------- */
+
+#ifndef GL_ARB_texture_multisample
+#define GL_ARB_texture_multisample 1
+
+#define GL_SAMPLE_POSITION 0x8E50
+#define GL_SAMPLE_MASK 0x8E51
+#define GL_SAMPLE_MASK_VALUE 0x8E52
+#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
+#define GL_TEXTURE_SAMPLES 0x9106
+#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
+#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
+#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
+#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
+#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
+#define GL_MAX_INTEGER_SAMPLES 0x9110
+
+typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat* val);
+typedef void (GLAPIENTRY * PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask);
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+
+#define glGetMultisamplefv GLEW_GET_FUN(__glewGetMultisamplefv)
+#define glSampleMaski GLEW_GET_FUN(__glewSampleMaski)
+#define glTexImage2DMultisample GLEW_GET_FUN(__glewTexImage2DMultisample)
+#define glTexImage3DMultisample GLEW_GET_FUN(__glewTexImage3DMultisample)
+
+#define GLEW_ARB_texture_multisample GLEW_GET_VAR(__GLEW_ARB_texture_multisample)
+
+#endif /* GL_ARB_texture_multisample */
+
 /* -------------------- GL_ARB_texture_non_power_of_two -------------------- */
 
 #ifndef GL_ARB_texture_non_power_of_two
@@ -3629,6 +4157,15 @@
 
 #endif /* GL_ARB_texture_non_power_of_two */
 
+/* ------------------------ GL_ARB_texture_query_lod ----------------------- */
+
+#ifndef GL_ARB_texture_query_lod
+#define GL_ARB_texture_query_lod 1
+
+#define GLEW_ARB_texture_query_lod GLEW_GET_VAR(__GLEW_ARB_texture_query_lod)
+
+#endif /* GL_ARB_texture_query_lod */
+
 /* ------------------------ GL_ARB_texture_rectangle ----------------------- */
 
 #ifndef GL_ARB_texture_rectangle
@@ -3651,6 +4188,8 @@
 #define GL_ARB_texture_rg 1
 
 #define GL_RED 0x1903
+#define GL_COMPRESSED_RED 0x8225
+#define GL_COMPRESSED_RG 0x8226
 #define GL_RG 0x8227
 #define GL_RG_INTEGER 0x8228
 #define GL_R8 0x8229
@@ -3702,6 +4241,82 @@
 
 #endif /* GL_ARB_transpose_matrix */
 
+/* ---------------------- GL_ARB_uniform_buffer_object --------------------- */
+
+#ifndef GL_ARB_uniform_buffer_object
+#define GL_ARB_uniform_buffer_object 1
+
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_INVALID_INDEX 0xFFFFFFFF
+
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, char* uniformBlockName);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, char* uniformName);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint* data);
+typedef GLuint (GLAPIENTRY * PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const char* uniformBlockName);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const char** uniformNames, GLuint* uniformIndices);
+typedef void (GLAPIENTRY * PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+
+#define glBindBufferBase GLEW_GET_FUN(__glewBindBufferBase)
+#define glBindBufferRange GLEW_GET_FUN(__glewBindBufferRange)
+#define glGetActiveUniformBlockName GLEW_GET_FUN(__glewGetActiveUniformBlockName)
+#define glGetActiveUniformBlockiv GLEW_GET_FUN(__glewGetActiveUniformBlockiv)
+#define glGetActiveUniformName GLEW_GET_FUN(__glewGetActiveUniformName)
+#define glGetActiveUniformsiv GLEW_GET_FUN(__glewGetActiveUniformsiv)
+#define glGetIntegeri_v GLEW_GET_FUN(__glewGetIntegeri_v)
+#define glGetUniformBlockIndex GLEW_GET_FUN(__glewGetUniformBlockIndex)
+#define glGetUniformIndices GLEW_GET_FUN(__glewGetUniformIndices)
+#define glUniformBlockBinding GLEW_GET_FUN(__glewUniformBlockBinding)
+
+#define GLEW_ARB_uniform_buffer_object GLEW_GET_VAR(__GLEW_ARB_uniform_buffer_object)
+
+#endif /* GL_ARB_uniform_buffer_object */
+
+/* ------------------------ GL_ARB_vertex_array_bgra ----------------------- */
+
+#ifndef GL_ARB_vertex_array_bgra
+#define GL_ARB_vertex_array_bgra 1
+
+#define GL_BGRA 0x80E1
+
+#define GLEW_ARB_vertex_array_bgra GLEW_GET_VAR(__GLEW_ARB_vertex_array_bgra)
+
+#endif /* GL_ARB_vertex_array_bgra */
+
 /* ----------------------- GL_ARB_vertex_array_object ---------------------- */
 
 #ifndef GL_ARB_vertex_array_object
@@ -4390,6 +5005,19 @@
 
 #endif /* GL_ATI_map_object_buffer */
 
+/* ----------------------------- GL_ATI_meminfo ---------------------------- */
+
+#ifndef GL_ATI_meminfo
+#define GL_ATI_meminfo 1
+
+#define GL_VBO_FREE_MEMORY_ATI 0x87FB
+#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
+#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
+
+#define GLEW_ATI_meminfo GLEW_GET_VAR(__GLEW_ATI_meminfo)
+
+#endif /* GL_ATI_meminfo */
+
 /* -------------------------- GL_ATI_pn_triangles -------------------------- */
 
 #ifndef GL_ATI_pn_triangles
@@ -5068,7 +5696,14 @@
 typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
 typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
 typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index);
+typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index);
+typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index);
+typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array);
 typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array);
+typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);
 typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode);
 typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum* bufs);
 typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode);
@@ -5076,8 +5711,10 @@
 typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target);
 typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, void* img);
 typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, void* img);
-typedef void (GLAPIENTRY * PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum pname, GLuint index, GLdouble* params);
-typedef void (GLAPIENTRY * PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum pname, GLuint index, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat* params);
 typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint* param);
 typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params);
 typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params);
@@ -5102,7 +5739,8 @@
 typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, void* string);
 typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint* params);
 typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint* params);
-typedef void (GLAPIENTRY * PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum pname, GLuint index, GLvoid** params);
+typedef void (GLAPIENTRY * PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLvoid** params);
+typedef void (GLAPIENTRY * PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, GLvoid** params);
 typedef void (GLAPIENTRY * PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void* pixels);
 typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat* params);
 typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint* params);
@@ -5110,7 +5748,12 @@
 typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint* params);
 typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat* params);
 typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint* param);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINTEGERVEXTPROC) (GLuint vaobj, GLenum pname, GLint* param);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLvoid** param);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYPOINTERVEXTPROC) (GLuint vaobj, GLenum pname, GLvoid** param);
 typedef GLvoid * (GLAPIENTRY * PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access);
+typedef GLvoid * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);
 typedef void (GLAPIENTRY * PFNGLMATRIXFRUSTUMEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f);
 typedef void (GLAPIENTRY * PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum matrixMode);
 typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m);
@@ -5157,6 +5800,7 @@
 typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels);
 typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const void* data, GLenum usage);
 typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void* data);
+typedef void (GLAPIENTRY * PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
 typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
 typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
 typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
@@ -5228,6 +5872,17 @@
 typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels);
 typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels);
 typedef GLboolean (GLAPIENTRY * PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYINDEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYNORMALOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
 
 #define glBindMultiTextureEXT GLEW_GET_FUN(__glewBindMultiTextureEXT)
 #define glCheckNamedFramebufferStatusEXT GLEW_GET_FUN(__glewCheckNamedFramebufferStatusEXT)
@@ -5255,7 +5910,14 @@
 #define glCopyTextureSubImage2DEXT GLEW_GET_FUN(__glewCopyTextureSubImage2DEXT)
 #define glCopyTextureSubImage3DEXT GLEW_GET_FUN(__glewCopyTextureSubImage3DEXT)
 #define glDisableClientStateIndexedEXT GLEW_GET_FUN(__glewDisableClientStateIndexedEXT)
+#define glDisableClientStateiEXT GLEW_GET_FUN(__glewDisableClientStateiEXT)
+#define glDisableVertexArrayAttribEXT GLEW_GET_FUN(__glewDisableVertexArrayAttribEXT)
+#define glDisableVertexArrayEXT GLEW_GET_FUN(__glewDisableVertexArrayEXT)
 #define glEnableClientStateIndexedEXT GLEW_GET_FUN(__glewEnableClientStateIndexedEXT)
+#define glEnableClientStateiEXT GLEW_GET_FUN(__glewEnableClientStateiEXT)
+#define glEnableVertexArrayAttribEXT GLEW_GET_FUN(__glewEnableVertexArrayAttribEXT)
+#define glEnableVertexArrayEXT GLEW_GET_FUN(__glewEnableVertexArrayEXT)
+#define glFlushMappedNamedBufferRangeEXT GLEW_GET_FUN(__glewFlushMappedNamedBufferRangeEXT)
 #define glFramebufferDrawBufferEXT GLEW_GET_FUN(__glewFramebufferDrawBufferEXT)
 #define glFramebufferDrawBuffersEXT GLEW_GET_FUN(__glewFramebufferDrawBuffersEXT)
 #define glFramebufferReadBufferEXT GLEW_GET_FUN(__glewFramebufferReadBufferEXT)
@@ -5264,7 +5926,9 @@
 #define glGetCompressedMultiTexImageEXT GLEW_GET_FUN(__glewGetCompressedMultiTexImageEXT)
 #define glGetCompressedTextureImageEXT GLEW_GET_FUN(__glewGetCompressedTextureImageEXT)
 #define glGetDoubleIndexedvEXT GLEW_GET_FUN(__glewGetDoubleIndexedvEXT)
+#define glGetDoublei_vEXT GLEW_GET_FUN(__glewGetDoublei_vEXT)
 #define glGetFloatIndexedvEXT GLEW_GET_FUN(__glewGetFloatIndexedvEXT)
+#define glGetFloati_vEXT GLEW_GET_FUN(__glewGetFloati_vEXT)
 #define glGetFramebufferParameterivEXT GLEW_GET_FUN(__glewGetFramebufferParameterivEXT)
 #define glGetMultiTexEnvfvEXT GLEW_GET_FUN(__glewGetMultiTexEnvfvEXT)
 #define glGetMultiTexEnvivEXT GLEW_GET_FUN(__glewGetMultiTexEnvivEXT)
@@ -5290,6 +5954,7 @@
 #define glGetNamedProgramivEXT GLEW_GET_FUN(__glewGetNamedProgramivEXT)
 #define glGetNamedRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetNamedRenderbufferParameterivEXT)
 #define glGetPointerIndexedvEXT GLEW_GET_FUN(__glewGetPointerIndexedvEXT)
+#define glGetPointeri_vEXT GLEW_GET_FUN(__glewGetPointeri_vEXT)
 #define glGetTextureImageEXT GLEW_GET_FUN(__glewGetTextureImageEXT)
 #define glGetTextureLevelParameterfvEXT GLEW_GET_FUN(__glewGetTextureLevelParameterfvEXT)
 #define glGetTextureLevelParameterivEXT GLEW_GET_FUN(__glewGetTextureLevelParameterivEXT)
@@ -5297,7 +5962,12 @@
 #define glGetTextureParameterIuivEXT GLEW_GET_FUN(__glewGetTextureParameterIuivEXT)
 #define glGetTextureParameterfvEXT GLEW_GET_FUN(__glewGetTextureParameterfvEXT)
 #define glGetTextureParameterivEXT GLEW_GET_FUN(__glewGetTextureParameterivEXT)
+#define glGetVertexArrayIntegeri_vEXT GLEW_GET_FUN(__glewGetVertexArrayIntegeri_vEXT)
+#define glGetVertexArrayIntegervEXT GLEW_GET_FUN(__glewGetVertexArrayIntegervEXT)
+#define glGetVertexArrayPointeri_vEXT GLEW_GET_FUN(__glewGetVertexArrayPointeri_vEXT)
+#define glGetVertexArrayPointervEXT GLEW_GET_FUN(__glewGetVertexArrayPointervEXT)
 #define glMapNamedBufferEXT GLEW_GET_FUN(__glewMapNamedBufferEXT)
+#define glMapNamedBufferRangeEXT GLEW_GET_FUN(__glewMapNamedBufferRangeEXT)
 #define glMatrixFrustumEXT GLEW_GET_FUN(__glewMatrixFrustumEXT)
 #define glMatrixLoadIdentityEXT GLEW_GET_FUN(__glewMatrixLoadIdentityEXT)
 #define glMatrixLoadTransposedEXT GLEW_GET_FUN(__glewMatrixLoadTransposedEXT)
@@ -5344,6 +6014,7 @@
 #define glMultiTexSubImage3DEXT GLEW_GET_FUN(__glewMultiTexSubImage3DEXT)
 #define glNamedBufferDataEXT GLEW_GET_FUN(__glewNamedBufferDataEXT)
 #define glNamedBufferSubDataEXT GLEW_GET_FUN(__glewNamedBufferSubDataEXT)
+#define glNamedCopyBufferSubDataEXT GLEW_GET_FUN(__glewNamedCopyBufferSubDataEXT)
 #define glNamedFramebufferRenderbufferEXT GLEW_GET_FUN(__glewNamedFramebufferRenderbufferEXT)
 #define glNamedFramebufferTexture1DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture1DEXT)
 #define glNamedFramebufferTexture2DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture2DEXT)
@@ -5415,6 +6086,17 @@
 #define glTextureSubImage2DEXT GLEW_GET_FUN(__glewTextureSubImage2DEXT)
 #define glTextureSubImage3DEXT GLEW_GET_FUN(__glewTextureSubImage3DEXT)
 #define glUnmapNamedBufferEXT GLEW_GET_FUN(__glewUnmapNamedBufferEXT)
+#define glVertexArrayColorOffsetEXT GLEW_GET_FUN(__glewVertexArrayColorOffsetEXT)
+#define glVertexArrayEdgeFlagOffsetEXT GLEW_GET_FUN(__glewVertexArrayEdgeFlagOffsetEXT)
+#define glVertexArrayFogCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayFogCoordOffsetEXT)
+#define glVertexArrayIndexOffsetEXT GLEW_GET_FUN(__glewVertexArrayIndexOffsetEXT)
+#define glVertexArrayMultiTexCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayMultiTexCoordOffsetEXT)
+#define glVertexArrayNormalOffsetEXT GLEW_GET_FUN(__glewVertexArrayNormalOffsetEXT)
+#define glVertexArraySecondaryColorOffsetEXT GLEW_GET_FUN(__glewVertexArraySecondaryColorOffsetEXT)
+#define glVertexArrayTexCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayTexCoordOffsetEXT)
+#define glVertexArrayVertexAttribIOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribIOffsetEXT)
+#define glVertexArrayVertexAttribOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribOffsetEXT)
+#define glVertexArrayVertexOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexOffsetEXT)
 
 #define GLEW_EXT_direct_state_access GLEW_GET_VAR(__GLEW_EXT_direct_state_access)
 
@@ -6223,6 +6905,24 @@
 
 #endif /* GL_EXT_polygon_offset */
 
+/* ------------------------ GL_EXT_provoking_vertex ------------------------ */
+
+#ifndef GL_EXT_provoking_vertex
+#define GL_EXT_provoking_vertex 1
+
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C
+#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E
+#define GL_PROVOKING_VERTEX_EXT 0x8E4F
+
+typedef void (GLAPIENTRY * PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode);
+
+#define glProvokingVertexEXT GLEW_GET_FUN(__glewProvokingVertexEXT)
+
+#define GLEW_EXT_provoking_vertex GLEW_GET_VAR(__GLEW_EXT_provoking_vertex)
+
+#endif /* GL_EXT_provoking_vertex */
+
 /* ------------------------- GL_EXT_rescale_normal ------------------------- */
 
 #ifndef GL_EXT_rescale_normal
@@ -6302,6 +7002,25 @@
 
 #endif /* GL_EXT_secondary_color */
 
+/* --------------------- GL_EXT_separate_shader_objects -------------------- */
+
+#ifndef GL_EXT_separate_shader_objects
+#define GL_EXT_separate_shader_objects 1
+
+#define GL_ACTIVE_PROGRAM_EXT 0x8B8D
+
+typedef void (GLAPIENTRY * PFNGLACTIVEPROGRAMEXTPROC) (GLuint program);
+typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const char* string);
+typedef void (GLAPIENTRY * PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program);
+
+#define glActiveProgramEXT GLEW_GET_FUN(__glewActiveProgramEXT)
+#define glCreateShaderProgramEXT GLEW_GET_FUN(__glewCreateShaderProgramEXT)
+#define glUseShaderProgramEXT GLEW_GET_FUN(__glewUseShaderProgramEXT)
+
+#define GLEW_EXT_separate_shader_objects GLEW_GET_VAR(__GLEW_EXT_separate_shader_objects)
+
+#endif /* GL_EXT_separate_shader_objects */
+
 /* --------------------- GL_EXT_separate_specular_color -------------------- */
 
 #ifndef GL_EXT_separate_specular_color
@@ -6871,6 +7590,41 @@
 
 #endif /* GL_EXT_texture_shared_exponent */
 
+/* -------------------------- GL_EXT_texture_snorm ------------------------- */
+
+#ifndef GL_EXT_texture_snorm
+#define GL_EXT_texture_snorm 1
+
+#define GL_RED_SNORM 0x8F90
+#define GL_RG_SNORM 0x8F91
+#define GL_RGB_SNORM 0x8F92
+#define GL_RGBA_SNORM 0x8F93
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_R16_SNORM 0x8F98
+#define GL_RG16_SNORM 0x8F99
+#define GL_RGB16_SNORM 0x8F9A
+#define GL_RGBA16_SNORM 0x8F9B
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_ALPHA_SNORM 0x9010
+#define GL_LUMINANCE_SNORM 0x9011
+#define GL_LUMINANCE_ALPHA_SNORM 0x9012
+#define GL_INTENSITY_SNORM 0x9013
+#define GL_ALPHA8_SNORM 0x9014
+#define GL_LUMINANCE8_SNORM 0x9015
+#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016
+#define GL_INTENSITY8_SNORM 0x9017
+#define GL_ALPHA16_SNORM 0x9018
+#define GL_LUMINANCE16_SNORM 0x9019
+#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A
+#define GL_INTENSITY16_SNORM 0x901B
+
+#define GLEW_EXT_texture_snorm GLEW_GET_VAR(__GLEW_EXT_texture_snorm)
+
+#endif /* GL_EXT_texture_snorm */
+
 /* ------------------------- GL_EXT_texture_swizzle ------------------------ */
 
 #ifndef GL_EXT_texture_swizzle
@@ -7686,6 +8440,19 @@
 
 #endif /* GL_NV_copy_depth_to_color */
 
+/* ---------------------------- GL_NV_copy_image --------------------------- */
+
+#ifndef GL_NV_copy_image
+#define GL_NV_copy_image 1
+
+typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+
+#define glCopyImageSubDataNV GLEW_GET_FUN(__glewCopyImageSubDataNV)
+
+#define GLEW_NV_copy_image GLEW_GET_VAR(__GLEW_NV_copy_image)
+
+#endif /* GL_NV_copy_image */
+
 /* ------------------------ GL_NV_depth_buffer_float ----------------------- */
 
 #ifndef GL_NV_depth_buffer_float
@@ -8229,6 +8996,15 @@
 
 #endif /* GL_NV_parameter_buffer_object */
 
+/* --------------------- GL_NV_parameter_buffer_object2 -------------------- */
+
+#ifndef GL_NV_parameter_buffer_object2
+#define GL_NV_parameter_buffer_object2 1
+
+#define GLEW_NV_parameter_buffer_object2 GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object2)
+
+#endif /* GL_NV_parameter_buffer_object2 */
+
 /* ------------------------- GL_NV_pixel_data_range ------------------------ */
 
 #ifndef GL_NV_pixel_data_range
@@ -8288,7 +9064,6 @@
 typedef void (GLAPIENTRY * PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint* params);
 typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3);
 typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1);
-typedef void (GLAPIENTRY * PFNGLVIDEOPARAMETERIVNVPROC) (GLuint video_slot, GLenum pname, const GLint* params);
 
 #define glGetVideoi64vNV GLEW_GET_FUN(__glewGetVideoi64vNV)
 #define glGetVideoivNV GLEW_GET_FUN(__glewGetVideoivNV)
@@ -8296,7 +9071,6 @@
 #define glGetVideouivNV GLEW_GET_FUN(__glewGetVideouivNV)
 #define glPresentFrameDualFillNV GLEW_GET_FUN(__glewPresentFrameDualFillNV)
 #define glPresentFrameKeyedNV GLEW_GET_FUN(__glewPresentFrameKeyedNV)
-#define glVideoParameterivNV GLEW_GET_FUN(__glewVideoParameterivNV)
 
 #define GLEW_NV_present_video GLEW_GET_VAR(__GLEW_NV_present_video)
 
@@ -8426,6 +9200,49 @@
 
 #endif /* GL_NV_register_combiners2 */
 
+/* ------------------------ GL_NV_shader_buffer_load ----------------------- */
+
+#ifndef GL_NV_shader_buffer_load
+#define GL_NV_shader_buffer_load 1
+
+#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D
+#define GL_GPU_ADDRESS_NV 0x8F34
+#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35
+
+typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT* params);
+typedef void (GLAPIENTRY * PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT* result);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT* params);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERRESIDENTNVPROC) (GLenum target);
+typedef GLboolean (GLAPIENTRY * PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access);
+typedef void (GLAPIENTRY * PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value);
+
+#define glGetBufferParameterui64vNV GLEW_GET_FUN(__glewGetBufferParameterui64vNV)
+#define glGetIntegerui64vNV GLEW_GET_FUN(__glewGetIntegerui64vNV)
+#define glGetNamedBufferParameterui64vNV GLEW_GET_FUN(__glewGetNamedBufferParameterui64vNV)
+#define glGetUniformui64vNV GLEW_GET_FUN(__glewGetUniformui64vNV)
+#define glIsBufferResidentNV GLEW_GET_FUN(__glewIsBufferResidentNV)
+#define glIsNamedBufferResidentNV GLEW_GET_FUN(__glewIsNamedBufferResidentNV)
+#define glMakeBufferNonResidentNV GLEW_GET_FUN(__glewMakeBufferNonResidentNV)
+#define glMakeBufferResidentNV GLEW_GET_FUN(__glewMakeBufferResidentNV)
+#define glMakeNamedBufferNonResidentNV GLEW_GET_FUN(__glewMakeNamedBufferNonResidentNV)
+#define glMakeNamedBufferResidentNV GLEW_GET_FUN(__glewMakeNamedBufferResidentNV)
+#define glProgramUniformui64NV GLEW_GET_FUN(__glewProgramUniformui64NV)
+#define glProgramUniformui64vNV GLEW_GET_FUN(__glewProgramUniformui64vNV)
+#define glUniformui64NV GLEW_GET_FUN(__glewUniformui64NV)
+#define glUniformui64vNV GLEW_GET_FUN(__glewUniformui64vNV)
+
+#define GLEW_NV_shader_buffer_load GLEW_GET_VAR(__GLEW_NV_shader_buffer_load)
+
+#endif /* GL_NV_shader_buffer_load */
+
 /* -------------------------- GL_NV_texgen_emboss -------------------------- */
 
 #ifndef GL_NV_texgen_emboss
@@ -8451,6 +9268,19 @@
 
 #endif /* GL_NV_texgen_reflection */
 
+/* ------------------------- GL_NV_texture_barrier ------------------------- */
+
+#ifndef GL_NV_texture_barrier
+#define GL_NV_texture_barrier 1
+
+typedef void (GLAPIENTRY * PFNGLTEXTUREBARRIERNVPROC) (void);
+
+#define glTextureBarrierNV GLEW_GET_FUN(__glewTextureBarrierNV)
+
+#define GLEW_NV_texture_barrier GLEW_GET_VAR(__GLEW_NV_texture_barrier)
+
+#endif /* GL_NV_texture_barrier */
+
 /* --------------------- GL_NV_texture_compression_vtc --------------------- */
 
 #ifndef GL_NV_texture_compression_vtc
@@ -8707,6 +9537,36 @@
 
 #endif /* GL_NV_transform_feedback */
 
+/* ----------------------- GL_NV_transform_feedback2 ----------------------- */
+
+#ifndef GL_NV_transform_feedback2
+#define GL_NV_transform_feedback2 1
+
+#define GL_TRANSFORM_FEEDBACK_NV 0x8E22
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25
+
+typedef void (GLAPIENTRY * PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id);
+typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id);
+typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint* ids);
+typedef GLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void);
+typedef void (GLAPIENTRY * PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void);
+
+#define glBindTransformFeedbackNV GLEW_GET_FUN(__glewBindTransformFeedbackNV)
+#define glDeleteTransformFeedbacksNV GLEW_GET_FUN(__glewDeleteTransformFeedbacksNV)
+#define glDrawTransformFeedbackNV GLEW_GET_FUN(__glewDrawTransformFeedbackNV)
+#define glGenTransformFeedbacksNV GLEW_GET_FUN(__glewGenTransformFeedbacksNV)
+#define glIsTransformFeedbackNV GLEW_GET_FUN(__glewIsTransformFeedbackNV)
+#define glPauseTransformFeedbackNV GLEW_GET_FUN(__glewPauseTransformFeedbackNV)
+#define glResumeTransformFeedbackNV GLEW_GET_FUN(__glewResumeTransformFeedbackNV)
+
+#define GLEW_NV_transform_feedback2 GLEW_GET_VAR(__GLEW_NV_transform_feedback2)
+
+#endif /* GL_NV_transform_feedback2 */
+
 /* ------------------------ GL_NV_vertex_array_range ----------------------- */
 
 #ifndef GL_NV_vertex_array_range
@@ -8739,6 +9599,64 @@
 
 #endif /* GL_NV_vertex_array_range2 */
 
+/* ------------------- GL_NV_vertex_buffer_unified_memory ------------------ */
+
+#ifndef GL_NV_vertex_buffer_unified_memory
+#define GL_NV_vertex_buffer_unified_memory 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E
+#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F
+#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20
+#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21
+#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22
+#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23
+#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24
+#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25
+#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26
+#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27
+#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28
+#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29
+#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A
+#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B
+#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C
+#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D
+#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E
+#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F
+#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30
+#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31
+#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32
+#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33
+
+typedef void (GLAPIENTRY * PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length);
+typedef void (GLAPIENTRY * PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT result[]);
+typedef void (GLAPIENTRY * PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+
+#define glBufferAddressRangeNV GLEW_GET_FUN(__glewBufferAddressRangeNV)
+#define glColorFormatNV GLEW_GET_FUN(__glewColorFormatNV)
+#define glEdgeFlagFormatNV GLEW_GET_FUN(__glewEdgeFlagFormatNV)
+#define glFogCoordFormatNV GLEW_GET_FUN(__glewFogCoordFormatNV)
+#define glGetIntegerui64i_vNV GLEW_GET_FUN(__glewGetIntegerui64i_vNV)
+#define glIndexFormatNV GLEW_GET_FUN(__glewIndexFormatNV)
+#define glNormalFormatNV GLEW_GET_FUN(__glewNormalFormatNV)
+#define glSecondaryColorFormatNV GLEW_GET_FUN(__glewSecondaryColorFormatNV)
+#define glTexCoordFormatNV GLEW_GET_FUN(__glewTexCoordFormatNV)
+#define glVertexAttribFormatNV GLEW_GET_FUN(__glewVertexAttribFormatNV)
+#define glVertexAttribIFormatNV GLEW_GET_FUN(__glewVertexAttribIFormatNV)
+#define glVertexFormatNV GLEW_GET_FUN(__glewVertexFormatNV)
+
+#define GLEW_NV_vertex_buffer_unified_memory GLEW_GET_VAR(__GLEW_NV_vertex_buffer_unified_memory)
+
+#endif /* GL_NV_vertex_buffer_unified_memory */
+
 /* -------------------------- GL_NV_vertex_program ------------------------- */
 
 #ifndef GL_NV_vertex_program
@@ -10460,8 +11378,6 @@
 
 GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender;
 GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback;
-GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEPROC __glewBindBufferBase;
-GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange;
 GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation;
 GLEW_FUN_EXPORT PFNGLCLAMPCOLORPROC __glewClampColor;
 GLEW_FUN_EXPORT PFNGLCLEARBUFFERFIPROC __glewClearBufferfi;
@@ -10475,7 +11391,6 @@
 GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback;
 GLEW_FUN_EXPORT PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v;
 GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation;
-GLEW_FUN_EXPORT PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v;
 GLEW_FUN_EXPORT PFNGLGETSTRINGIPROC __glewGetStringi;
 GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv;
 GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv;
@@ -10517,8 +11432,37 @@
 GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv;
 GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer;
 
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDPROC __glewDrawArraysInstanced;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDPROC __glewDrawElementsInstanced;
+GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXPROC __glewPrimitiveRestartIndex;
+GLEW_FUN_EXPORT PFNGLTEXBUFFERPROC __glewTexBuffer;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREPROC __glewFramebufferTexture;
+GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERI64VPROC __glewGetBufferParameteri64v;
+GLEW_FUN_EXPORT PFNGLGETINTEGER64I_VPROC __glewGetInteger64i_v;
+
 GLEW_FUN_EXPORT PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX;
 
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONINDEXEDAMDPROC __glewBlendEquationIndexedAMD;
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC __glewBlendEquationSeparateIndexedAMD;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCINDEXEDAMDPROC __glewBlendFuncIndexedAMD;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC __glewBlendFuncSeparateIndexedAMD;
+
+GLEW_FUN_EXPORT PFNGLBEGINPERFMONITORAMDPROC __glewBeginPerfMonitorAMD;
+GLEW_FUN_EXPORT PFNGLDELETEPERFMONITORSAMDPROC __glewDeletePerfMonitorsAMD;
+GLEW_FUN_EXPORT PFNGLENDPERFMONITORAMDPROC __glewEndPerfMonitorAMD;
+GLEW_FUN_EXPORT PFNGLGENPERFMONITORSAMDPROC __glewGenPerfMonitorsAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERDATAAMDPROC __glewGetPerfMonitorCounterDataAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERINFOAMDPROC __glewGetPerfMonitorCounterInfoAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC __glewGetPerfMonitorCounterStringAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERSAMDPROC __glewGetPerfMonitorCountersAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORGROUPSTRINGAMDPROC __glewGetPerfMonitorGroupStringAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORGROUPSAMDPROC __glewGetPerfMonitorGroupsAMD;
+GLEW_FUN_EXPORT PFNGLSELECTPERFMONITORCOUNTERSAMDPROC __glewSelectPerfMonitorCountersAMD;
+
+GLEW_FUN_EXPORT PFNGLTESSELLATIONFACTORAMDPROC __glewTessellationFactorAMD;
+GLEW_FUN_EXPORT PFNGLTESSELLATIONMODEAMDPROC __glewTessellationModeAMD;
+
 GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE;
 GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE;
 GLEW_FUN_EXPORT PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE;
@@ -10537,6 +11481,10 @@
 GLEW_FUN_EXPORT PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE;
 GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE;
 
+GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVAPPLEPROC __glewGetObjectParameterivAPPLE;
+GLEW_FUN_EXPORT PFNGLOBJECTPURGEABLEAPPLEPROC __glewObjectPurgeableAPPLE;
+GLEW_FUN_EXPORT PFNGLOBJECTUNPURGEABLEAPPLEPROC __glewObjectUnpurgeableAPPLE;
+
 GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE;
 GLEW_FUN_EXPORT PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE;
 
@@ -10549,10 +11497,30 @@
 GLEW_FUN_EXPORT PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE;
 GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE;
 
+GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBAPPLEPROC __glewDisableVertexAttribAPPLE;
+GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBAPPLEPROC __glewEnableVertexAttribAPPLE;
+GLEW_FUN_EXPORT PFNGLISVERTEXATTRIBENABLEDAPPLEPROC __glewIsVertexAttribEnabledAPPLE;
+GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB1DAPPLEPROC __glewMapVertexAttrib1dAPPLE;
+GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB1FAPPLEPROC __glewMapVertexAttrib1fAPPLE;
+GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB2DAPPLEPROC __glewMapVertexAttrib2dAPPLE;
+GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB2FAPPLEPROC __glewMapVertexAttrib2fAPPLE;
+
 GLEW_FUN_EXPORT PFNGLCLAMPCOLORARBPROC __glewClampColorARB;
 
+GLEW_FUN_EXPORT PFNGLCOPYBUFFERSUBDATAPROC __glewCopyBufferSubData;
+
 GLEW_FUN_EXPORT PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB;
 
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIARBPROC __glewBlendEquationSeparateiARB;
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIARBPROC __glewBlendEquationiARB;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIARBPROC __glewBlendFuncSeparateiARB;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCIARBPROC __glewBlendFunciARB;
+
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSBASEVERTEXPROC __glewDrawElementsBaseVertex;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC __glewDrawElementsInstancedBaseVertex;
+GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC __glewDrawRangeElementsBaseVertex;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC __glewMultiDrawElementsBaseVertex;
+
 GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB;
 GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB;
 
@@ -10563,10 +11531,10 @@
 GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers;
 GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers;
 GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer;
-GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer;
 GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D;
 GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D;
 GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer;
 GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers;
 GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers;
 GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap;
@@ -10675,6 +11643,10 @@
 GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB;
 GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB;
 
+GLEW_FUN_EXPORT PFNGLPROVOKINGVERTEXPROC __glewProvokingVertex;
+
+GLEW_FUN_EXPORT PFNGLMINSAMPLESHADINGARBPROC __glewMinSampleShadingARB;
+
 GLEW_FUN_EXPORT PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB;
 GLEW_FUN_EXPORT PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB;
 GLEW_FUN_EXPORT PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB;
@@ -10715,6 +11687,14 @@
 GLEW_FUN_EXPORT PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB;
 GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB;
 
+GLEW_FUN_EXPORT PFNGLCLIENTWAITSYNCPROC __glewClientWaitSync;
+GLEW_FUN_EXPORT PFNGLDELETESYNCPROC __glewDeleteSync;
+GLEW_FUN_EXPORT PFNGLFENCESYNCPROC __glewFenceSync;
+GLEW_FUN_EXPORT PFNGLGETINTEGER64VPROC __glewGetInteger64v;
+GLEW_FUN_EXPORT PFNGLGETSYNCIVPROC __glewGetSynciv;
+GLEW_FUN_EXPORT PFNGLISSYNCPROC __glewIsSync;
+GLEW_FUN_EXPORT PFNGLWAITSYNCPROC __glewWaitSync;
+
 GLEW_FUN_EXPORT PFNGLTEXBUFFERARBPROC __glewTexBufferARB;
 
 GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB;
@@ -10725,11 +11705,27 @@
 GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB;
 GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB;
 
+GLEW_FUN_EXPORT PFNGLGETMULTISAMPLEFVPROC __glewGetMultisamplefv;
+GLEW_FUN_EXPORT PFNGLSAMPLEMASKIPROC __glewSampleMaski;
+GLEW_FUN_EXPORT PFNGLTEXIMAGE2DMULTISAMPLEPROC __glewTexImage2DMultisample;
+GLEW_FUN_EXPORT PFNGLTEXIMAGE3DMULTISAMPLEPROC __glewTexImage3DMultisample;
+
 GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB;
 GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB;
 GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB;
 GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB;
 
+GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEPROC __glewBindBufferBase;
+GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange;
+GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC __glewGetActiveUniformBlockName;
+GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMBLOCKIVPROC __glewGetActiveUniformBlockiv;
+GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMNAMEPROC __glewGetActiveUniformName;
+GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMSIVPROC __glewGetActiveUniformsiv;
+GLEW_FUN_EXPORT PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMBLOCKINDEXPROC __glewGetUniformBlockIndex;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMINDICESPROC __glewGetUniformIndices;
+GLEW_FUN_EXPORT PFNGLUNIFORMBLOCKBINDINGPROC __glewUniformBlockBinding;
+
 GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray;
 GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays;
 GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays;
@@ -11004,7 +12000,14 @@
 GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT;
 GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT;
 GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT;
+GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEIEXTPROC __glewDisableClientStateiEXT;
+GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC __glewDisableVertexArrayAttribEXT;
+GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYEXTPROC __glewDisableVertexArrayEXT;
 GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT;
+GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEIEXTPROC __glewEnableClientStateiEXT;
+GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYATTRIBEXTPROC __glewEnableVertexArrayAttribEXT;
+GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYEXTPROC __glewEnableVertexArrayEXT;
+GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC __glewFlushMappedNamedBufferRangeEXT;
 GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT;
 GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT;
 GLEW_FUN_EXPORT PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT;
@@ -11013,7 +12016,9 @@
 GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT;
 GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT;
 GLEW_FUN_EXPORT PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT;
+GLEW_FUN_EXPORT PFNGLGETDOUBLEI_VEXTPROC __glewGetDoublei_vEXT;
 GLEW_FUN_EXPORT PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT;
+GLEW_FUN_EXPORT PFNGLGETFLOATI_VEXTPROC __glewGetFloati_vEXT;
 GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT;
 GLEW_FUN_EXPORT PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT;
 GLEW_FUN_EXPORT PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT;
@@ -11039,6 +12044,7 @@
 GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT;
 GLEW_FUN_EXPORT PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT;
 GLEW_FUN_EXPORT PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT;
+GLEW_FUN_EXPORT PFNGLGETPOINTERI_VEXTPROC __glewGetPointeri_vEXT;
 GLEW_FUN_EXPORT PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT;
 GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT;
 GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT;
@@ -11046,7 +12052,12 @@
 GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT;
 GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT;
 GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC __glewGetVertexArrayIntegeri_vEXT;
+GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINTEGERVEXTPROC __glewGetVertexArrayIntegervEXT;
+GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC __glewGetVertexArrayPointeri_vEXT;
+GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYPOINTERVEXTPROC __glewGetVertexArrayPointervEXT;
 GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT;
+GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFERRANGEEXTPROC __glewMapNamedBufferRangeEXT;
 GLEW_FUN_EXPORT PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT;
 GLEW_FUN_EXPORT PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT;
 GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT;
@@ -11093,6 +12104,7 @@
 GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT;
 GLEW_FUN_EXPORT PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT;
 GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC __glewNamedCopyBufferSubDataEXT;
 GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT;
 GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT;
 GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT;
@@ -11164,6 +12176,17 @@
 GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT;
 GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT;
 GLEW_FUN_EXPORT PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYCOLOROFFSETEXTPROC __glewVertexArrayColorOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC __glewVertexArrayEdgeFlagOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC __glewVertexArrayFogCoordOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYINDEXOFFSETEXTPROC __glewVertexArrayIndexOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC __glewVertexArrayMultiTexCoordOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYNORMALOFFSETEXTPROC __glewVertexArrayNormalOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC __glewVertexArraySecondaryColorOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC __glewVertexArrayTexCoordOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC __glewVertexArrayVertexAttribIOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC __glewVertexArrayVertexAttribOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC __glewVertexArrayVertexOffsetEXT;
 
 GLEW_FUN_EXPORT PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT;
 GLEW_FUN_EXPORT PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT;
@@ -11309,6 +12332,8 @@
 
 GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT;
 
+GLEW_FUN_EXPORT PFNGLPROVOKINGVERTEXEXTPROC __glewProvokingVertexEXT;
+
 GLEW_FUN_EXPORT PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT;
 GLEW_FUN_EXPORT PFNGLENDSCENEEXTPROC __glewEndSceneEXT;
 
@@ -11330,6 +12355,10 @@
 GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT;
 GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT;
 
+GLEW_FUN_EXPORT PFNGLACTIVEPROGRAMEXTPROC __glewActiveProgramEXT;
+GLEW_FUN_EXPORT PFNGLCREATESHADERPROGRAMEXTPROC __glewCreateShaderProgramEXT;
+GLEW_FUN_EXPORT PFNGLUSESHADERPROGRAMEXTPROC __glewUseShaderProgramEXT;
+
 GLEW_FUN_EXPORT PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT;
 
 GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT;
@@ -11491,6 +12520,8 @@
 GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV;
 GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV;
 
+GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATANVPROC __glewCopyImageSubDataNV;
+
 GLEW_FUN_EXPORT PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV;
 GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV;
 GLEW_FUN_EXPORT PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV;
@@ -11612,7 +12643,6 @@
 GLEW_FUN_EXPORT PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV;
 GLEW_FUN_EXPORT PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV;
 GLEW_FUN_EXPORT PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV;
-GLEW_FUN_EXPORT PFNGLVIDEOPARAMETERIVNVPROC __glewVideoParameterivNV;
 
 GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV;
 GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV;
@@ -11634,6 +12664,23 @@
 GLEW_FUN_EXPORT PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV;
 GLEW_FUN_EXPORT PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV;
 
+GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERUI64VNVPROC __glewGetBufferParameterui64vNV;
+GLEW_FUN_EXPORT PFNGLGETINTEGERUI64VNVPROC __glewGetIntegerui64vNV;
+GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC __glewGetNamedBufferParameterui64vNV;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMUI64VNVPROC __glewGetUniformui64vNV;
+GLEW_FUN_EXPORT PFNGLISBUFFERRESIDENTNVPROC __glewIsBufferResidentNV;
+GLEW_FUN_EXPORT PFNGLISNAMEDBUFFERRESIDENTNVPROC __glewIsNamedBufferResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKEBUFFERNONRESIDENTNVPROC __glewMakeBufferNonResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKEBUFFERRESIDENTNVPROC __glewMakeBufferResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC __glewMakeNamedBufferNonResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKENAMEDBUFFERRESIDENTNVPROC __glewMakeNamedBufferResidentNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMUI64NVPROC __glewProgramUniformui64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMUI64VNVPROC __glewProgramUniformui64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORMUI64NVPROC __glewUniformui64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORMUI64VNVPROC __glewUniformui64vNV;
+
+GLEW_FUN_EXPORT PFNGLTEXTUREBARRIERNVPROC __glewTextureBarrierNV;
+
 GLEW_FUN_EXPORT PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV;
 GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV;
 GLEW_FUN_EXPORT PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV;
@@ -11646,9 +12693,30 @@
 GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV;
 GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV;
 
+GLEW_FUN_EXPORT PFNGLBINDTRANSFORMFEEDBACKNVPROC __glewBindTransformFeedbackNV;
+GLEW_FUN_EXPORT PFNGLDELETETRANSFORMFEEDBACKSNVPROC __glewDeleteTransformFeedbacksNV;
+GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKNVPROC __glewDrawTransformFeedbackNV;
+GLEW_FUN_EXPORT PFNGLGENTRANSFORMFEEDBACKSNVPROC __glewGenTransformFeedbacksNV;
+GLEW_FUN_EXPORT PFNGLISTRANSFORMFEEDBACKNVPROC __glewIsTransformFeedbackNV;
+GLEW_FUN_EXPORT PFNGLPAUSETRANSFORMFEEDBACKNVPROC __glewPauseTransformFeedbackNV;
+GLEW_FUN_EXPORT PFNGLRESUMETRANSFORMFEEDBACKNVPROC __glewResumeTransformFeedbackNV;
+
 GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV;
 GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV;
 
+GLEW_FUN_EXPORT PFNGLBUFFERADDRESSRANGENVPROC __glewBufferAddressRangeNV;
+GLEW_FUN_EXPORT PFNGLCOLORFORMATNVPROC __glewColorFormatNV;
+GLEW_FUN_EXPORT PFNGLEDGEFLAGFORMATNVPROC __glewEdgeFlagFormatNV;
+GLEW_FUN_EXPORT PFNGLFOGCOORDFORMATNVPROC __glewFogCoordFormatNV;
+GLEW_FUN_EXPORT PFNGLGETINTEGERUI64I_VNVPROC __glewGetIntegerui64i_vNV;
+GLEW_FUN_EXPORT PFNGLINDEXFORMATNVPROC __glewIndexFormatNV;
+GLEW_FUN_EXPORT PFNGLNORMALFORMATNVPROC __glewNormalFormatNV;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLORFORMATNVPROC __glewSecondaryColorFormatNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORDFORMATNVPROC __glewTexCoordFormatNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBFORMATNVPROC __glewVertexAttribFormatNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIFORMATNVPROC __glewVertexAttribIFormatNV;
+GLEW_FUN_EXPORT PFNGLVERTEXFORMATNVPROC __glewVertexFormatNV;
+
 GLEW_FUN_EXPORT PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV;
 GLEW_FUN_EXPORT PFNGLBINDPROGRAMNVPROC __glewBindProgramNV;
 GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV;
@@ -11866,26 +12934,43 @@
 GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_0;
 GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_1;
 GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_0;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_1;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_2;
 GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_multisample;
 GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_tbuffer;
 GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_texture_compression_FXT1;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_draw_buffers_blend;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_performance_monitor;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_texture_texture4;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_tessellator;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_aux_depth_stencil;
 GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_client_storage;
 GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_element_array;
 GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_fence;
 GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_float_pixels;
 GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_flush_buffer_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_object_purgeable;
 GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_pixel_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_rgb_422;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_row_bytes;
 GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_specular_vector;
 GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_range;
 GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_transform_hint;
 GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_object;
 GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_program_evaluators;
 GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_ycbcr_422;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_color_buffer_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compatibility;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_copy_buffer;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_buffer_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_clamp;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_texture;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers_blend;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_elements_base_vertex;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_instanced;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_coord_conventions;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program_shadow;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_shader;
@@ -11904,25 +12989,36 @@
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_pixel_buffer_object;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_parameters;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_sprite;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_provoking_vertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sample_shading;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_seamless_cube_map;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_objects;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_texture_lod;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_100;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow_ambient;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sync;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_border_clamp;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_object;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_rgtc;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map_array;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_add;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_combine;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_crossbar;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_dot3;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_gather;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirrored_repeat;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_multisample;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_non_power_of_two;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_query_lod;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rectangle;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rg;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transpose_matrix;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_uniform_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_bgra;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_object;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_blend;
 GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_buffer_object;
@@ -11938,6 +13034,7 @@
 GLEW_VAR_EXPORT GLboolean __GLEW_ATI_envmap_bumpmap;
 GLEW_VAR_EXPORT GLboolean __GLEW_ATI_fragment_shader;
 GLEW_VAR_EXPORT GLboolean __GLEW_ATI_map_object_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_meminfo;
 GLEW_VAR_EXPORT GLboolean __GLEW_ATI_pn_triangles;
 GLEW_VAR_EXPORT GLboolean __GLEW_ATI_separate_stencil;
 GLEW_VAR_EXPORT GLboolean __GLEW_ATI_shader_texture_lod;
@@ -12000,9 +13097,11 @@
 GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform_color_table;
 GLEW_VAR_EXPORT GLboolean __GLEW_EXT_point_parameters;
 GLEW_VAR_EXPORT GLboolean __GLEW_EXT_polygon_offset;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_provoking_vertex;
 GLEW_VAR_EXPORT GLboolean __GLEW_EXT_rescale_normal;
 GLEW_VAR_EXPORT GLboolean __GLEW_EXT_scene_marker;
 GLEW_VAR_EXPORT GLboolean __GLEW_EXT_secondary_color;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_shader_objects;
 GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_specular_color;
 GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shadow_funcs;
 GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shared_texture_palette;
@@ -12033,6 +13132,7 @@
 GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_rectangle;
 GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB;
 GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_shared_exponent;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_snorm;
 GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_swizzle;
 GLEW_VAR_EXPORT GLboolean __GLEW_EXT_timer_query;
 GLEW_VAR_EXPORT GLboolean __GLEW_EXT_transform_feedback;
@@ -12065,6 +13165,7 @@
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_square;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_conditional_render;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_depth_to_color;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_image;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_buffer_float;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_clamp;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_range_unclamped;
@@ -12087,14 +13188,17 @@
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_occlusion_query;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_depth_stencil;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object2;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_pixel_data_range;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_point_sprite;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_present_video;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_primitive_restart;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_buffer_load;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_emboss;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_reflection;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_barrier;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_vtc;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_env_combine4;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_expand_normal;
@@ -12103,8 +13207,10 @@
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader2;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader3;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback2;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_buffer_unified_memory;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program1_1;
 GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2;
@@ -12244,6 +13350,7 @@
 #undef GLEW_APIENTRY_DEFINED
 #undef APIENTRY
 #undef GLAPIENTRY
+#define GLAPIENTRY
 #endif
 
 #ifdef GLEW_CALLBACK_DEFINED
diff --git a/include/GL/glut.h b/include/GL/glut.h
index 9fdb9cf..d9fc938 100644
--- a/include/GL/glut.h
+++ b/include/GL/glut.h
@@ -452,8 +452,7 @@
 #if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
 GLUTAPI void GLUTAPIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int));
 #ifndef GLUT_BUILDING_LIB
-static void GLUTAPIENTRY glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); }
-#define glutInit glutInit_ATEXIT_HACK
+#define glutInit(__argcp, __argv) __glutInitWithExit(__argcp, __argv, exit)
 #endif
 #endif
 GLUTAPI void GLUTAPIENTRY glutInitDisplayMode(unsigned int mode);
@@ -469,8 +468,7 @@
 #if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
 GLUTAPI int GLUTAPIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int));
 #ifndef GLUT_BUILDING_LIB
-static int GLUTAPIENTRY glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); }
-#define glutCreateWindow glutCreateWindow_ATEXIT_HACK
+#define glutCreateWindow(__title) __glutCreateWindowWithExit(__title, exit)
 #endif
 #endif
 GLUTAPI int GLUTAPIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height);
@@ -515,8 +513,7 @@
 #if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
 GLUTAPI int GLUTAPIENTRY __glutCreateMenuWithExit(void (GLUTCALLBACK *func)(int), void (__cdecl *exitfunc)(int));
 #ifndef GLUT_BUILDING_LIB
-static int GLUTAPIENTRY glutCreateMenu_ATEXIT_HACK(void (GLUTCALLBACK *func)(int)) { return __glutCreateMenuWithExit(func, exit); }
-#define glutCreateMenu glutCreateMenu_ATEXIT_HACK
+#define glutCreateMenu(__func) __glutCreateMenuWithExit(__func, exit)
 #endif
 #endif
 GLUTAPI void GLUTAPIENTRY glutDestroyMenu(int menu);
diff --git a/include/GL/glx.h b/include/GL/glx.h
index 2884401..82b0f22 100644
--- a/include/GL/glx.h
+++ b/include/GL/glx.h
@@ -186,6 +186,16 @@
 typedef XID GLXPbuffer;
 
 
+/*
+** Events.
+** __GLX_NUMBER_EVENTS is set to 17 to account for the BufferClobberSGIX
+**  event - this helps initialization if the server supports the pbuffer
+**  extension and the client doesn't.
+*/
+#define GLX_PbufferClobber	0
+#define GLX_BufferSwapComplete	1
+
+#define __GLX_NUMBER_EVENTS 17
 
 extern XVisualInfo* glXChooseVisual( Display *dpy, int screen,
 				     int *attribList );
@@ -507,8 +517,17 @@
     int count;			/* if nonzero, at least this many more */
 } GLXPbufferClobberEvent;
 
+typedef struct {
+    int event_type;
+    GLXDrawable drawable;
+    int64_t ust;
+    int64_t msc;
+    int64_t sbc;
+} GLXBufferSwapComplete;
+
 typedef union __GLXEvent {
     GLXPbufferClobberEvent glxpbufferclobber;
+    GLXBufferSwapComplete glxbufferswapcomplete;
     long pad[24];
 } GLXEvent;
 
diff --git a/include/GL/glx_mangle.h b/include/GL/glx_mangle.h
index 4439a96..fa664a7 100644
--- a/include/GL/glx_mangle.h
+++ b/include/GL/glx_mangle.h
@@ -76,6 +76,7 @@
 
 /* GLX 1.4 */
 #define glXGetProcAddress mglXGetProcAddress
+#define glXGetProcAddressARB mglXGetProcAddressARB
 
 
 #endif
diff --git a/include/GL/glxew.h b/include/GL/glxew.h
index a29030d..f19e573 100644
--- a/include/GL/glxew.h
+++ b/include/GL/glxew.h
@@ -362,6 +362,19 @@
 
 #endif /* GLX_ARB_create_context */
 
+/* --------------------- GLX_ARB_create_context_profile -------------------- */
+
+#ifndef GLX_ARB_create_context_profile
+#define GLX_ARB_create_context_profile 1
+
+#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
+
+#define GLXEW_ARB_create_context_profile GLXEW_GET_VAR(__GLXEW_ARB_create_context_profile)
+
+#endif /* GLX_ARB_create_context_profile */
+
 /* ------------------------- GLX_ARB_fbconfig_float ------------------------ */
 
 #ifndef GLX_ARB_fbconfig_float
@@ -529,6 +542,22 @@
 
 #endif /* GLX_EXT_scene_marker */
 
+/* -------------------------- GLX_EXT_swap_control ------------------------- */
+
+#ifndef GLX_EXT_swap_control
+#define GLX_EXT_swap_control 1
+
+#define GLX_SWAP_INTERVAL_EXT 0x20F1
+#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
+
+typedef void ( * PFNGLXSWAPINTERVALEXTPROC) (Display* dpy, GLXDrawable drawable, int interval);
+
+#define glXSwapIntervalEXT GLXEW_GET_FUN(__glewXSwapIntervalEXT)
+
+#define GLXEW_EXT_swap_control GLXEW_GET_VAR(__GLXEW_EXT_swap_control)
+
+#endif /* GLX_EXT_swap_control */
+
 /* ---------------------- GLX_EXT_texture_from_pixmap ---------------------- */
 
 #ifndef GLX_EXT_texture_from_pixmap
@@ -683,6 +712,19 @@
 
 #endif /* GLX_MESA_set_3dfx_mode */
 
+/* --------------------------- GLX_NV_copy_image --------------------------- */
+
+#ifndef GLX_NV_copy_image
+#define GLX_NV_copy_image 1
+
+typedef void ( * PFNGLXCOPYIMAGESUBDATANVPROC) (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+
+#define glXCopyImageSubDataNV GLXEW_GET_FUN(__glewXCopyImageSubDataNV)
+
+#define GLXEW_NV_copy_image GLXEW_GET_VAR(__GLXEW_NV_copy_image)
+
+#endif /* GLX_NV_copy_image */
+
 /* -------------------------- GLX_NV_float_buffer -------------------------- */
 
 #ifndef GLX_NV_float_buffer
@@ -1217,6 +1259,8 @@
 extern PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT;
 extern PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT;
 
+extern PFNGLXSWAPINTERVALEXTPROC __glewXSwapIntervalEXT;
+
 extern PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT;
 extern PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT;
 
@@ -1230,6 +1274,8 @@
 
 extern PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA;
 
+extern PFNGLXCOPYIMAGESUBDATANVPROC __glewXCopyImageSubDataNV;
+
 extern PFNGLXBINDVIDEODEVICENVPROC __glewXBindVideoDeviceNV;
 extern PFNGLXENUMERATEVIDEODEVICESNVPROC __glewXEnumerateVideoDevicesNV;
 
@@ -1318,6 +1364,7 @@
 GLXEW_EXPORT GLboolean __GLXEW_VERSION_1_4;
 GLXEW_EXPORT GLboolean __GLXEW_3DFX_multisample;
 GLXEW_EXPORT GLboolean __GLXEW_ARB_create_context;
+GLXEW_EXPORT GLboolean __GLXEW_ARB_create_context_profile;
 GLXEW_EXPORT GLboolean __GLXEW_ARB_fbconfig_float;
 GLXEW_EXPORT GLboolean __GLXEW_ARB_framebuffer_sRGB;
 GLXEW_EXPORT GLboolean __GLXEW_ARB_get_proc_address;
@@ -1328,6 +1375,7 @@
 GLXEW_EXPORT GLboolean __GLXEW_EXT_framebuffer_sRGB;
 GLXEW_EXPORT GLboolean __GLXEW_EXT_import_context;
 GLXEW_EXPORT GLboolean __GLXEW_EXT_scene_marker;
+GLXEW_EXPORT GLboolean __GLXEW_EXT_swap_control;
 GLXEW_EXPORT GLboolean __GLXEW_EXT_texture_from_pixmap;
 GLXEW_EXPORT GLboolean __GLXEW_EXT_visual_info;
 GLXEW_EXPORT GLboolean __GLXEW_EXT_visual_rating;
@@ -1336,6 +1384,7 @@
 GLXEW_EXPORT GLboolean __GLXEW_MESA_pixmap_colormap;
 GLXEW_EXPORT GLboolean __GLXEW_MESA_release_buffers;
 GLXEW_EXPORT GLboolean __GLXEW_MESA_set_3dfx_mode;
+GLXEW_EXPORT GLboolean __GLXEW_NV_copy_image;
 GLXEW_EXPORT GLboolean __GLXEW_NV_float_buffer;
 GLXEW_EXPORT GLboolean __GLXEW_NV_present_video;
 GLXEW_EXPORT GLboolean __GLXEW_NV_swap_group;
diff --git a/include/GL/glxext.h b/include/GL/glxext.h
index 9ac0592..36ee366 100644
--- a/include/GL/glxext.h
+++ b/include/GL/glxext.h
@@ -696,6 +696,14 @@
 typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member);
 #endif
 
+#ifndef GLX_INTEL_swap_event
+#define GLX_INTEL_swap_event
+#define GLX_BUFFER_SWAP_COMPLETE_MASK      0x10000000
+#define GLX_EXCHANGE_COMPLETE              0x8024
+#define GLX_BLIT_COMPLETE                  0x8025
+#define GLX_FLIP_COMPLETE                  0x8026
+#endif
+
 #ifndef GLX_SGIX_swap_barrier
 #define GLX_SGIX_swap_barrier 1
 #ifdef GLX_GLXEXT_PROTOTYPES
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 910c916..ec6238f 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -262,10 +262,22 @@
  * Used by drivers that implement DRI2
  */
 #define __DRI2_FLUSH "DRI2_Flush"
-#define __DRI2_FLUSH_VERSION 1
+#define __DRI2_FLUSH_VERSION 2
 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.
+     *
+     * \param drawable the drawable to flush and invalidate
+     *
+     * \since 2
+     */
+    void (*flushInvalidate)(__DRIdrawable *drawable);
 };
 
 
diff --git a/include/GL/wglew.h b/include/GL/wglew.h
index 2eaad36..7c7a380 100644
--- a/include/GL/wglew.h
+++ b/include/GL/wglew.h
@@ -62,11 +62,12 @@
 
 #define __wglext_h_
 
-#if !defined(APIENTRY) && !defined(__CYGWIN__)
+#if !defined(WINAPI)
 #  ifndef WIN32_LEAN_AND_MEAN
 #    define WIN32_LEAN_AND_MEAN 1
 #  endif
 #include <windows.h>
+#  undef WIN32_LEAN_AND_MEAN
 #endif
 
 /*
@@ -117,6 +118,46 @@
 
 #endif /* WGL_3DL_stereo_control */
 
+/* ------------------------ WGL_AMD_gpu_association ------------------------ */
+
+#ifndef WGL_AMD_gpu_association
+#define WGL_AMD_gpu_association 1
+
+#define WGL_GPU_VENDOR_AMD 0x1F00
+#define WGL_GPU_RENDERER_STRING_AMD 0x1F01
+#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
+#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
+#define WGL_GPU_RAM_AMD 0x21A3
+#define WGL_GPU_CLOCK_AMD 0x21A4
+#define WGL_GPU_NUM_PIPES_AMD 0x21A5
+#define WGL_GPU_NUM_SIMD_AMD 0x21A6
+#define WGL_GPU_NUM_RB_AMD 0x21A7
+#define WGL_GPU_NUM_SPI_AMD 0x21A8
+
+typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id);
+typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int* attribList);
+typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc);
+typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc);
+typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
+typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT* ids);
+typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, INT property, GLenum dataType, UINT size, void* data);
+typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc);
+
+#define wglBlitContextFramebufferAMD WGLEW_GET_FUN(__wglewBlitContextFramebufferAMD)
+#define wglCreateAssociatedContextAMD WGLEW_GET_FUN(__wglewCreateAssociatedContextAMD)
+#define wglCreateAssociatedContextAttribsAMD WGLEW_GET_FUN(__wglewCreateAssociatedContextAttribsAMD)
+#define wglDeleteAssociatedContextAMD WGLEW_GET_FUN(__wglewDeleteAssociatedContextAMD)
+#define wglGetContextGPUIDAMD WGLEW_GET_FUN(__wglewGetContextGPUIDAMD)
+#define wglGetCurrentAssociatedContextAMD WGLEW_GET_FUN(__wglewGetCurrentAssociatedContextAMD)
+#define wglGetGPUIDsAMD WGLEW_GET_FUN(__wglewGetGPUIDsAMD)
+#define wglGetGPUInfoAMD WGLEW_GET_FUN(__wglewGetGPUInfoAMD)
+#define wglMakeAssociatedContextCurrentAMD WGLEW_GET_FUN(__wglewMakeAssociatedContextCurrentAMD)
+
+#define WGLEW_AMD_gpu_association WGLEW_GET_VAR(__WGLEW_AMD_gpu_association)
+
+#endif /* WGL_AMD_gpu_association */
+
 /* ------------------------- WGL_ARB_buffer_region ------------------------- */
 
 #ifndef WGL_ARB_buffer_region
@@ -161,6 +202,19 @@
 
 #endif /* WGL_ARB_create_context */
 
+/* --------------------- WGL_ARB_create_context_profile -------------------- */
+
+#ifndef WGL_ARB_create_context_profile
+#define WGL_ARB_create_context_profile 1
+
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+
+#define WGLEW_ARB_create_context_profile WGLEW_GET_VAR(__WGLEW_ARB_create_context_profile)
+
+#endif /* WGL_ARB_create_context_profile */
+
 /* ----------------------- WGL_ARB_extensions_string ----------------------- */
 
 #ifndef WGL_ARB_extensions_string
@@ -752,6 +806,19 @@
 
 #endif /* WGL_I3D_swap_frame_usage */
 
+/* --------------------------- WGL_NV_copy_image --------------------------- */
+
+#ifndef WGL_NV_copy_image
+#define WGL_NV_copy_image 1
+
+typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+
+#define wglCopyImageSubDataNV WGLEW_GET_FUN(__wglewCopyImageSubDataNV)
+
+#define WGLEW_NV_copy_image WGLEW_GET_VAR(__WGLEW_NV_copy_image)
+
+#endif /* WGL_NV_copy_image */
+
 /* -------------------------- WGL_NV_float_buffer -------------------------- */
 
 #ifndef WGL_NV_float_buffer
@@ -863,7 +930,7 @@
 typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group);
 typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint* count);
 typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint* maxGroups, GLuint *maxBarriers);
-typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint* group);
+typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint* group, GLuint *barrier);
 typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC);
 
 #define wglBindSwapBarrierNV WGLEW_GET_FUN(__wglewBindSwapBarrierNV)
@@ -969,6 +1036,16 @@
 
 WGLEW_EXPORT PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL;
 
+WGLEW_EXPORT PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC __wglewBlitContextFramebufferAMD;
+WGLEW_EXPORT PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC __wglewCreateAssociatedContextAMD;
+WGLEW_EXPORT PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __wglewCreateAssociatedContextAttribsAMD;
+WGLEW_EXPORT PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC __wglewDeleteAssociatedContextAMD;
+WGLEW_EXPORT PFNWGLGETCONTEXTGPUIDAMDPROC __wglewGetContextGPUIDAMD;
+WGLEW_EXPORT PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC __wglewGetCurrentAssociatedContextAMD;
+WGLEW_EXPORT PFNWGLGETGPUIDSAMDPROC __wglewGetGPUIDsAMD;
+WGLEW_EXPORT PFNWGLGETGPUINFOAMDPROC __wglewGetGPUInfoAMD;
+WGLEW_EXPORT PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __wglewMakeAssociatedContextCurrentAMD;
+
 WGLEW_EXPORT PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB;
 WGLEW_EXPORT PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB;
 WGLEW_EXPORT PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB;
@@ -1054,6 +1131,8 @@
 WGLEW_EXPORT PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D;
 WGLEW_EXPORT PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D;
 
+WGLEW_EXPORT PFNWGLCOPYIMAGESUBDATANVPROC __wglewCopyImageSubDataNV;
+
 WGLEW_EXPORT PFNWGLCREATEAFFINITYDCNVPROC __wglewCreateAffinityDCNV;
 WGLEW_EXPORT PFNWGLDELETEDCNVPROC __wglewDeleteDCNV;
 WGLEW_EXPORT PFNWGLENUMGPUDEVICESNVPROC __wglewEnumGpuDevicesNV;
@@ -1089,8 +1168,10 @@
 WGLEW_EXPORT PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML;
 WGLEW_EXPORT GLboolean __WGLEW_3DFX_multisample;
 WGLEW_EXPORT GLboolean __WGLEW_3DL_stereo_control;
+WGLEW_EXPORT GLboolean __WGLEW_AMD_gpu_association;
 WGLEW_EXPORT GLboolean __WGLEW_ARB_buffer_region;
 WGLEW_EXPORT GLboolean __WGLEW_ARB_create_context;
+WGLEW_EXPORT GLboolean __WGLEW_ARB_create_context_profile;
 WGLEW_EXPORT GLboolean __WGLEW_ARB_extensions_string;
 WGLEW_EXPORT GLboolean __WGLEW_ARB_framebuffer_sRGB;
 WGLEW_EXPORT GLboolean __WGLEW_ARB_make_current_read;
@@ -1117,6 +1198,7 @@
 WGLEW_EXPORT GLboolean __WGLEW_I3D_image_buffer;
 WGLEW_EXPORT GLboolean __WGLEW_I3D_swap_frame_lock;
 WGLEW_EXPORT GLboolean __WGLEW_I3D_swap_frame_usage;
+WGLEW_EXPORT GLboolean __WGLEW_NV_copy_image;
 WGLEW_EXPORT GLboolean __WGLEW_NV_float_buffer;
 WGLEW_EXPORT GLboolean __WGLEW_NV_gpu_affinity;
 WGLEW_EXPORT GLboolean __WGLEW_NV_present_video;
diff --git a/include/VG/vgplatform.h b/include/VG/vgplatform.h
index e4f269f..2c626a9 100644
--- a/include/VG/vgplatform.h
+++ b/include/VG/vgplatform.h
@@ -38,6 +38,11 @@
 extern "C" {

 #endif

 

+#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303

+#  define VG_API_CALL __attribute__((visibility("default")))

+#  define VGU_API_CALL __attribute__((visibility("default")))

+#endif

+

 #ifndef VG_API_CALL 

 #if defined(OPENVG_STATIC_LIBRARY)

 #	define VG_API_CALL

diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c b/include/c99/stdbool.h
similarity index 73%
rename from src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c
rename to include/c99/stdbool.h
index f038bfa..99a735d 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c
+++ b/include/c99/stdbool.h
@@ -1,8 +1,8 @@
 /**************************************************************************
- * 
- * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ *
+ * Copyright 2007-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,32 +10,37 @@
  * 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 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
  * THE COPYRIGHT HOLDERS, AUTHORS 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 
+ * 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.
  *
  * The above copyright notice and this permission notice (including the
  * next paragraph) shall be included in all copies or substantial portions
  * of the Software.
- * 
- * 
+ *
  **************************************************************************/
-/*
- * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
- */
 
-#include "radeon_winsys_softpipe.h"
+#ifndef _STDBOOL_H_
+#define _STDBOOL_H_
 
-struct pipe_context *radeon_create_softpipe(struct pipe_winsys* winsys)
-{
-    struct pipe_screen *pipe_screen;
+#ifndef __cplusplus
 
-    pipe_screen = softpipe_create_screen(winsys);
+#define false   0
+#define true    1
+#define bool    _Bool
 
-    return softpipe_create(pipe_screen);
-}
+/* For compilers that don't have the builtin _Bool type. */
+#if defined(_MSC_VER) || (__STDC_VERSION__ < 199901L && __GNUC__ < 3)
+typedef unsigned char _Bool;
+#endif
+
+#endif /* !__cplusplus */
+
+#define __bool_true_false_are_defined   1
+
+#endif /* !_STDBOOL_H_ */
diff --git a/include/c99/stdint.h b/include/c99/stdint.h
new file mode 100644
index 0000000..e380213
--- /dev/null
+++ b/include/c99/stdint.h
@@ -0,0 +1,119 @@
+/**************************************************************************
+ *
+ * Copyright 2007-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 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+/*
+ * stdint.h --
+ *
+ *    Portable subset of C99's stdint.h.
+ *
+ *    At the moment it only supports MSVC, given all other mainstream compilers
+ *    already support C99. If this is necessary for other compilers then it
+ *    might be worth to replace this with
+ *    http://www.azillionmonkeys.com/qed/pstdint.h.
+ */
+
+#ifndef _STDINT_H_
+#define _STDINT_H_
+
+
+#ifndef INT8_MAX
+#define INT8_MAX           127
+#endif
+#ifndef INT8_MIN
+#define INT8_MIN           -128
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX          255
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX          32767
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN          -32768
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX         65535
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX          2147483647
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN          -2147483648
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX         4294967295U
+#endif
+
+#ifndef INT8_C
+#define INT8_C(__val)     __val
+#endif
+#ifndef UINT8_C
+#define UINT8_C(__val)    __val
+#endif
+#ifndef INT16_C
+#define INT16_C(__val)    __val
+#endif
+#ifndef UINT16_C
+#define UINT16_C(__val)   __val
+#endif
+#ifndef INT32_C
+#define INT32_C(__val)    __val
+#endif
+#ifndef UINT32_C
+#define UINT32_C(__val)   __val##U
+#endif
+
+
+#if defined(_MSC_VER)
+
+typedef __int8             int8_t;
+typedef unsigned __int8    uint8_t;
+typedef __int16            int16_t;
+typedef unsigned __int16   uint16_t;
+#ifndef __eglplatform_h_
+typedef __int32            int32_t;
+#endif
+typedef unsigned __int32   uint32_t;
+typedef __int64            int64_t;
+typedef unsigned __int64   uint64_t;
+
+#if defined(_WIN64)
+typedef __int64            intptr_t;
+typedef unsigned __int64   uintptr_t;
+#else
+typedef __int32            intptr_t;
+typedef unsigned __int32   uintptr_t;
+#endif
+
+#define INT64_C(__val)    __val##i64
+#define UINT64_C(__val)   __val##ui64
+
+#else
+#error "Unsupported compiler"
+#endif
+
+#endif /* _STDINT_H_ */
diff --git a/progs/.gitignore b/progs/.gitignore
new file mode 100644
index 0000000..cb77d18
--- /dev/null
+++ b/progs/.gitignore
@@ -0,0 +1 @@
+*.dSYM
diff --git a/progs/Makefile b/progs/Makefile
index 3700707..5bc444e 100644
--- a/progs/Makefile
+++ b/progs/Makefile
@@ -15,22 +15,18 @@
 
 
 subdirs:
-	@if test -n "$(SUBDIRS)" ; then \
-		for dir in $(SUBDIRS) ; do \
-			if [ -d $$dir ] ; then \
-				(cd $$dir && $(MAKE)) || exit 1 ; \
-			fi \
-		done \
-	fi
+	@list='$(SUBDIRS)'; for dir in $$list ; do \
+		if [ -d $$dir ] ; then \
+			(cd $$dir && $(MAKE)) || exit 1 ; \
+		fi \
+	done
 
 # Dummy install target
 install:
 
 clean:
-	-@if test -n "$(SUBDIRS)" ; then \
-		for dir in $(SUBDIRS) tests ; do \
-			if [ -d $$dir ] ; then \
-				(cd $$dir && $(MAKE) clean) ; \
-			fi \
-		done \
-	fi
+	@list='$(SUBDIRS)'; for dir in $$list tests ; do \
+		if [ -d $$dir ] ; then \
+			(cd $$dir && $(MAKE) clean) ; \
+		fi \
+	done
diff --git a/progs/SConscript b/progs/SConscript
index 66eaf9e..3b180d0 100644
--- a/progs/SConscript
+++ b/progs/SConscript
@@ -1,5 +1,43 @@
 SConscript([
     'util/SConscript',
+])
+
+Import('*')
+
+progs_env = env.Clone()
+
+if progs_env['platform'] == 'windows':
+    progs_env.Append(CPPDEFINES = ['NOMINMAX'])
+    progs_env.Prepend(LIBS = [
+        'winmm',
+        'kernel32',
+        'user32',
+        'gdi32',
+    ])
+
+# OpenGL
+if progs_env['platform'] == 'windows':
+    progs_env.Prepend(LIBS = ['glu32', 'opengl32'])
+else:
+    progs_env.Prepend(LIBS = ['GLU', 'GL'])
+
+# Glut
+progs_env.Prepend(LIBS = [glut])
+
+# GLEW
+progs_env.Prepend(LIBS = [glew])
+
+progs_env.Prepend(CPPPATH = [
+	'#progs/util',
+])
+
+progs_env.Prepend(LIBS = [
+	util,
+])
+
+Export('progs_env')
+
+SConscript([
     'demos/SConscript',
     'glsl/SConscript',
     'redbook/SConscript',
diff --git a/progs/SConstruct b/progs/SConstruct
deleted file mode 100644
index 4d268cc..0000000
--- a/progs/SConstruct
+++ /dev/null
@@ -1,65 +0,0 @@
-import os
-import os.path
-import sys
-
-env = Environment(
-    tools = ['generic'],
-    toolpath = ['../scons'],
-    ENV = os.environ,
-)
-
-
-# Use Mesa's headers and libs
-if 1:
-    build_topdir = 'build'
-    build_subdir = env['platform']
-    if env['machine'] != 'generic':
-        build_subdir += '-' + env['machine']
-    if env['debug']:
-        build_subdir += "-debug"
-    if env['profile']:
-        build_subdir += "-profile"
-    build_dir = os.path.join(build_topdir, build_subdir)
-
-    env.Append(CPPDEFINES = ['GLEW_STATIC'])
-    env.Append(CPPPATH = ['#../include'])
-    env.Append(LIBPATH = [
-        '#../' + build_dir + '/glew/',
-        '#../' + build_dir + '/glut/glx',
-    ])
-
-
-conf = Configure(env)
-
-# OpenGL
-if env['platform'] == 'windows':
-    env.Prepend(LIBS = ['glu32', 'opengl32'])
-else:
-    env.Prepend(LIBS = ['GLU', 'GL'])
-
-# Glut
-env['GLUT'] = False
-if conf.CheckCHeader('GL/glut.h'):
-    if env['platform'] == 'windows':
-        env['GLUT_LIB'] = 'glut32'
-    else:
-        env['GLUT_LIB'] = 'glut'
-    env['GLUT'] = True
-
-# GLEW
-env['GLEW'] = False
-if conf.CheckCHeader('GL/glew.h'):
-    env['GLEW_LIB'] = 'glew'
-    env['GLEW'] = True
-    env.Prepend(LIBS = ['glew'])
-
-conf.Finish()
-
-
-Export('env')
-
-SConscript(
-    'SConscript',
-    build_dir = env['build'],
-    duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html
-)
diff --git a/progs/demos/SConscript b/progs/demos/SConscript
index f851870..742dd66 100644
--- a/progs/demos/SConscript
+++ b/progs/demos/SConscript
@@ -1,84 +1,66 @@
 Import('*')
 
-if not env['GLUT']:
-    Return()
-
-env = env.Clone()
-
-env.Prepend(CPPPATH = [
-	'../util',
-])
-
-env.Prepend(LIBS = [
-	util,
-	'$GLUT_LIB'
-])
-
-if env['platform'] == 'windows':
-    env.Append(CPPDEFINES = ['NOMINMAX'])
-    env.Prepend(LIBS = ['winmm'])
-
 progs = [
-	'arbfplight',
-	'arbfslight',
-	'arbocclude',
-	'bounce',
-	'clearspd',
-	'copypix',
-	'cubemap',
-	'drawpix',
-	'engine',
-	'fbo_firecube',
-	'fire',
-	'fogcoord',
-	'fplight',
-	'fslight',
-	'gamma',
-	'gearbox',
-	'gears',
-	'geartrain',
-	'glinfo',
-	'gloss',
-	'gltestperf',
-	'ipers',
-	'isosurf',
-	'lodbias',
-	'morph3d',
-	'multiarb',
-	'paltex',
-	'pointblast',
-	'ray',
-	'readpix',
-	'reflect',
-	'renormal',
-	'shadowtex',
-	'singlebuffer',
-	'spectex',
-	'spriteblast',
-	'stex3d',
-	'teapot',
-	'terrain',
-	'tessdemo',
-	'texcyl',
-	'texenv',
-	'textures',
-	'trispd',
-	'tunnel',
-	'tunnel2',
-	'vao_demo',
-	'winpos',
-        'dinoshade',
-        'fbotexture',
-        'projtex',
+    'arbfplight',
+    'arbfslight',
+    'arbocclude',
+    'bounce',
+    'clearspd',
+    'copypix',
+    'cubemap',
+    'drawpix',
+    'engine',
+    'fbo_firecube',
+    'fire',
+    'fogcoord',
+    'fplight',
+    'fslight',
+    'gamma',
+    'gearbox',
+    'gears',
+    'geartrain',
+    'glinfo',
+    'gloss',
+    'gltestperf',
+    'ipers',
+    'isosurf',
+    'lodbias',
+    'morph3d',
+    'multiarb',
+    'paltex',
+    'pointblast',
+    'ray',
+    'readpix',
+    'reflect',
+    'renormal',
+    'shadowtex',
+    'singlebuffer',
+    'spectex',
+    'spriteblast',
+    'stex3d',
+    'teapot',
+    'terrain',
+    'tessdemo',
+    'texcyl',
+    'texenv',
+    'textures',
+    'trispd',
+    'tunnel',
+    'tunnel2',
+    'vao_demo',
+    'winpos',
+    'dinoshade',
+    'fbotexture',
+    'projtex',
 ]
 
 for prog in progs:
-    env.Program(
+    progs_env.Program(
         target = prog,
         source = prog + '.c',
     )
     
-env.Program(
+progs_env.Program(
     target = 'rain',
     source = [
         'rain.cxx',
diff --git a/progs/demos/arbfplight.c b/progs/demos/arbfplight.c
index 7b7a12b..861b3b7 100644
--- a/progs/demos/arbfplight.c
+++ b/progs/demos/arbfplight.c
@@ -388,9 +388,8 @@
 
 int main( int argc, char *argv[] )
 {
-   glutInit( &argc, argv );
-   glutInitWindowPosition( 0, 0 );
    glutInitWindowSize( 200, 200 );
+   glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
    Win = glutCreateWindow(argv[0]);
    glutReshapeFunc( Reshape );
diff --git a/progs/demos/arbfslight.c b/progs/demos/arbfslight.c
index 275c851..a0ce7f3 100644
--- a/progs/demos/arbfslight.c
+++ b/progs/demos/arbfslight.c
@@ -311,9 +311,8 @@
 
 int main (int argc, char *argv[])
 {
-	glutInit (&argc, argv);
-	glutInitWindowPosition ( 0, 0);
 	glutInitWindowSize (200, 200);
+	glutInit (&argc, argv);
 	glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
 	glutCreateWindow (argv[0]);
 	glutReshapeFunc (Reshape);
diff --git a/progs/demos/arbocclude.c b/progs/demos/arbocclude.c
index 9188ad5..f669a1f 100644
--- a/progs/demos/arbocclude.c
+++ b/progs/demos/arbocclude.c
@@ -268,9 +268,8 @@
 
 int main( int argc, char *argv[] )
 {
-   glutInit( &argc, argv );
-   glutInitWindowPosition( 0, 0 );
    glutInitWindowSize( 400, 400 );
+   glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
    Win = glutCreateWindow(argv[0]);
    glewInit();
diff --git a/progs/demos/bounce.c b/progs/demos/bounce.c
index 436bc7d..a9a291e 100644
--- a/progs/demos/bounce.c
+++ b/progs/demos/bounce.c
@@ -192,10 +192,8 @@
 
 int main(int argc, char *argv[])
 {
-  glutInit(&argc, argv);
-  glutInitWindowPosition(0, 0);
   glutInitWindowSize(600, 450);
-
+  glutInit(&argc, argv);
 
   IndexMode = argc > 1 && strcmp(argv[1], "-ci") == 0;
   if (IndexMode)
diff --git a/progs/demos/clearspd.c b/progs/demos/clearspd.c
index 42953f6..c40f118 100644
--- a/progs/demos/clearspd.c
+++ b/progs/demos/clearspd.c
@@ -187,9 +187,8 @@
 
    Init( argc, argv );
 
-   glutInit( &argc, argv );
    glutInitWindowSize( (int) Width, (int) Height );
-   glutInitWindowPosition( 0, 0 );
+   glutInit( &argc, argv );
 
    mode = ColorMode | GLUT_DOUBLE;
    if (BufferMask & GL_STENCIL_BUFFER_BIT)
diff --git a/progs/demos/copypix.c b/progs/demos/copypix.c
index a13339e..98c835f 100644
--- a/progs/demos/copypix.c
+++ b/progs/demos/copypix.c
@@ -237,6 +237,9 @@
    const char *filename = IMAGE_FILE;
    int i = 1;
 
+   glutInitWindowSize( WinWidth, WinHeight );
+   glutInit( &argc, argv );
+
    if (argc > i && strcmp(argv[i], "-ci")==0) {
       ciMode = GL_TRUE;
       i++;
@@ -245,10 +248,6 @@
       filename = argv[i];
    }
 
-   glutInit( &argc, argv );
-   glutInitWindowPosition( 0, 0 );
-   glutInitWindowSize( WinWidth, WinHeight );
-
    if (ciMode)
       glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE );
    else
diff --git a/progs/demos/cubemap.c b/progs/demos/cubemap.c
index 20332b1..3e79d6a 100644
--- a/progs/demos/cubemap.c
+++ b/progs/demos/cubemap.c
@@ -613,9 +613,8 @@
 
 int main( int argc, char *argv[] )
 {
-   glutInit(&argc, argv);
-   glutInitWindowPosition(0, 0);
    glutInitWindowSize(600, 500);
+   glutInit(&argc, argv);
    glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
    glutCreateWindow("Texture Cube Mapping");
    glewInit();
diff --git a/progs/demos/drawpix.c b/progs/demos/drawpix.c
index 5490bcc..9bc7086 100644
--- a/progs/demos/drawpix.c
+++ b/progs/demos/drawpix.c
@@ -328,6 +328,9 @@
    const char *filename = IMAGE_FILE;
    int i = 1;
 
+   glutInitWindowSize( 500, 400 );
+   glutInit( &argc, argv );
+
    if (argc > i && strcmp(argv[i], "-ci")==0) {
       ciMode = GL_TRUE;
       i++;
@@ -336,10 +339,6 @@
       filename = argv[i];
    }
 
-   glutInit( &argc, argv );
-   glutInitWindowPosition( 0, 0 );
-   glutInitWindowSize( 500, 400 );
-
    if (ciMode)
       glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE );
    else
diff --git a/progs/demos/engine.c b/progs/demos/engine.c
index 3cf311e..c54e3b8 100644
--- a/progs/demos/engine.c
+++ b/progs/demos/engine.c
@@ -1308,8 +1308,8 @@
 int
 main(int argc, char *argv[])
 {
-   glutInit(&argc, argv);
    glutInitWindowSize(WinWidth, WinHeight);
+   glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("OpenGL Engine Demo");
    glewInit();
diff --git a/progs/demos/fbo_firecube.c b/progs/demos/fbo_firecube.c
index b3f7e00..17767a1 100644
--- a/progs/demos/fbo_firecube.c
+++ b/progs/demos/fbo_firecube.c
@@ -1051,11 +1051,11 @@
 int
 main(int argc, char *argv[])
 {
+   glutInitWindowSize(WinWidth, WinHeight);
    glutInit(&argc, argv);
 
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
 
-   glutInitWindowSize(WinWidth, WinHeight);
    Win = glutCreateWindow("fbo_firecube");
    glewInit();
    init(argc, argv);
diff --git a/progs/demos/fire.c b/progs/demos/fire.c
index dd70f61..9c351e8 100644
--- a/progs/demos/fire.c
+++ b/progs/demos/fire.c
@@ -6,6 +6,7 @@
  *            Humanware s.r.l.
  */
 
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
@@ -733,7 +734,6 @@
       HEIGHT = atoi(av[3]);
    }
 
-   glutInitWindowPosition(0, 0);
    glutInitWindowSize(WIDTH, HEIGHT);
    glutInit(&ac, av);
 
@@ -759,6 +759,7 @@
    glFogfv(GL_FOG_COLOR, fogcolor);
    glFogf(GL_FOG_DENSITY, 0.1);
 
+   assert(np > 0);
    p = (part *) malloc(sizeof(part) * np);
 
    for (i = 0; i < np; i++)
diff --git a/progs/demos/fogcoord.c b/progs/demos/fogcoord.c
index 6f50993..336aa58 100644
--- a/progs/demos/fogcoord.c
+++ b/progs/demos/fogcoord.c
@@ -15,8 +15,6 @@
 
 #define DEPTH 5.0f
 
-static PFNGLFOGCOORDPOINTEREXTPROC glFogCoordPointer_ext;
-
 static GLfloat camz;
 
 static GLint fogMode;
@@ -406,8 +404,8 @@
 int
 main( int argc, char *argv[] )
 {
-   glutInit( &argc, argv );
    glutInitWindowSize( 600, 600 );
+   glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
    glutCreateWindow(argv[0]);
    glewInit();
diff --git a/progs/demos/fplight.c b/progs/demos/fplight.c
index c297354..f52a4f7 100644
--- a/progs/demos/fplight.c
+++ b/progs/demos/fplight.c
@@ -268,9 +268,8 @@
 
 int main( int argc, char *argv[] )
 {
-   glutInit( &argc, argv );
-   glutInitWindowPosition( 0, 0 );
    glutInitWindowSize( 200, 200 );
+   glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
    Win = glutCreateWindow(argv[0]);
    glewInit();
diff --git a/progs/demos/fslight.c b/progs/demos/fslight.c
index f0d76a4..395b7ca 100644
--- a/progs/demos/fslight.c
+++ b/progs/demos/fslight.c
@@ -353,6 +353,7 @@
    glNewList(SphereList, GL_COMPILE);
    gluSphere(obj, 2.0f, 10, 5);
    glEndList();
+   gluDeleteQuadric(obj);
 }
 
 static void
@@ -599,9 +600,8 @@
 int
 main(int argc, char *argv[])
 {
-   glutInit(&argc, argv);
-   glutInitWindowPosition( 0, 0);
    glutInitWindowSize(200, 200);
+   glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    win = glutCreateWindow(argv[0]);
    glutReshapeFunc(Reshape);
diff --git a/progs/demos/gamma.c b/progs/demos/gamma.c
index 9b2c3e1..61c6d12 100644
--- a/progs/demos/gamma.c
+++ b/progs/demos/gamma.c
@@ -146,12 +146,9 @@
 int
 main(int argc, char **argv)
 {
+  glutInitWindowSize(500, 400);
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
-
-  glutInitWindowPosition(50, 50);
-  glutInitWindowSize(500, 400);
-
   glutCreateWindow("gamma test patterns");
   glutReshapeFunc(Reshape);
   glutDisplayFunc(display);
diff --git a/progs/demos/gearbox.c b/progs/demos/gearbox.c
index 2dcf32f..71d0281 100644
--- a/progs/demos/gearbox.c
+++ b/progs/demos/gearbox.c
@@ -474,10 +474,10 @@
 int
 main(int argc, char *argv[])
 {
+   glutInitWindowSize(WinWidth, WinHeight);
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
 
-   glutInitWindowSize(WinWidth, WinHeight);
    Win = glutCreateWindow("gearbox");
    init(argc, argv);
 
diff --git a/progs/demos/gears.c b/progs/demos/gears.c
index 6016162..31a5b79 100644
--- a/progs/demos/gears.c
+++ b/progs/demos/gears.c
@@ -385,11 +385,9 @@
 
 int main(int argc, char *argv[])
 {
+  glutInitWindowSize(300, 300);
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
-
-  glutInitWindowPosition(0, 0);
-  glutInitWindowSize(300, 300);
   win = glutCreateWindow("Gears");
   init(argc, argv);
 
diff --git a/progs/demos/geartrain.c b/progs/demos/geartrain.c
index 8fe405e..00b6e78 100644
--- a/progs/demos/geartrain.c
+++ b/progs/demos/geartrain.c
@@ -25,6 +25,7 @@
  */
 
 
+#include <assert.h>
 #include <math.h>
 #include <stdlib.h>
 #include <GL/glut.h>
@@ -129,8 +130,10 @@
 static void
 LoadTriplet (TDA A)
 {
+    int result;
     Clear_Buffers ();
-    fscanf (mainfile, "%s %s %s %s", Buf1, Buf2, Buf3, Buf4);
+    result = fscanf (mainfile, "%s %s %s %s", Buf1, Buf2, Buf3, Buf4);
+    assert(result != EOF);
     A[0] = atof (Buf2);
     A[1] = atof (Buf3);
     A[2] = atof (Buf4);
@@ -140,8 +143,10 @@
 static void
 LoadReal (float *a)
 {
+    int result;
     Clear_Buffers ();
-    fscanf (mainfile, "%s %s", Buf1, Buf2);
+    result = fscanf (mainfile, "%s %s", Buf1, Buf2);
+    assert(result != EOF);
     *a = atof (Buf2);
 }
 
@@ -149,8 +154,10 @@
 static void
 LoadInteger (int *a)
 {
+    int result;
     Clear_Buffers ();
-    fscanf (mainfile, "%s %s", Buf1, Buf2);
+    result = fscanf (mainfile, "%s %s", Buf1, Buf2);
+    assert(result != EOF);
     *a = atoi (Buf2);
 }
 
@@ -158,8 +165,10 @@
 static void
 LoadText (char *a)
 {
+    int result;
     Clear_Buffers ();
-    fscanf (mainfile, "%s %s", Buf1, Buf2);
+    result = fscanf (mainfile, "%s %s", Buf1, Buf2);
+    assert(result != EOF);
     strcpy (a, Buf2);
 }
 
@@ -177,8 +186,10 @@
 
     do
     {
+	int result;
 	Clear_Buffers ();
-	fscanf (mainfile, "%s", Buf1);
+	result = fscanf (mainfile, "%s", Buf1);
+	(void) result;
 	if (ferror (mainfile))
 	{
 	    printf ("\nError opening file !\n");
@@ -1049,19 +1060,18 @@
 {
     char *file;
 
-    if (argc < 2)
-       file = "geartrain.dat";
-    else
-       file = argv[1];
-
-    glutInit(&argc, argv); 
-    glutInitWindowPosition (0, 0);
     glutInitWindowSize(640,480);
+    glutInit(&argc, argv); 
     glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
 
     if (glutCreateWindow ("Gear Train Simulation") == GL_FALSE)
       exit (1);
 
+    if (argc < 2)
+       file = "geartrain.dat";
+    else
+       file = argv[1];
+
     getdata (file);
     process ();
     init ();
diff --git a/progs/demos/gloss.c b/progs/demos/gloss.c
index 69694b2..578736b 100644
--- a/progs/demos/gloss.c
+++ b/progs/demos/gloss.c
@@ -436,8 +436,8 @@
 
 int main( int argc, char *argv[] )
 {
-   glutInit( &argc, argv );
    glutInitWindowSize(WinWidth, WinHeight);
+   glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
    glutCreateWindow(argv[0] );
    glewInit();
diff --git a/progs/demos/gltestperf.c b/progs/demos/gltestperf.c
index 2188b02..3658a39 100644
--- a/progs/demos/gltestperf.c
+++ b/progs/demos/gltestperf.c
@@ -569,10 +569,9 @@
    if (ac == 2)
       frontbuffer = 0;
 
+   glutInitWindowSize(640, 480);
    glutInit(&ac, av);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
-   glutInitWindowPosition(0, 0);
-   glutInitWindowSize(640, 480);
    glutCreateWindow("OpenGL/Mesa Performances");
    glutDisplayFunc(display);
    glutMainLoop();
diff --git a/progs/demos/ipers.c b/progs/demos/ipers.c
index 5d82b0d..265378b 100644
--- a/progs/demos/ipers.c
+++ b/progs/demos/ipers.c
@@ -133,6 +133,8 @@
 
       glEndList();
    }
+
+   gluDeleteQuadric(obj);
 }
 
 static void
@@ -680,7 +682,6 @@
    fprintf(stderr,
 	   "IperS V1.0\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
 
-   glutInitWindowPosition(0, 0);
    glutInitWindowSize(WIDTH, HEIGHT);
    glutInit(&ac, av);
 
diff --git a/progs/demos/isosurf.c b/progs/demos/isosurf.c
index 2e9dff1..dbe4d8d 100644
--- a/progs/demos/isosurf.c
+++ b/progs/demos/isosurf.c
@@ -132,9 +132,11 @@
 
    numverts = 0;
    while (!feof(f) && numverts<maxverts) {
-      fscanf( f, "%f %f %f  %f %f %f",
-	      &data[numverts][0], &data[numverts][1], &data[numverts][2],
-	      &data[numverts][3], &data[numverts][4], &data[numverts][5] );
+      int result;
+      result = fscanf( f, "%f %f %f  %f %f %f",
+	               &data[numverts][0], &data[numverts][1], &data[numverts][2],
+	               &data[numverts][3], &data[numverts][4], &data[numverts][5] );
+      (void) result;
       numverts++;
    }
    numverts--;
@@ -1061,9 +1063,8 @@
 
    read_surface( "isosurf.dat" );
 
-   glutInit( &argc, argv);
-   glutInitWindowPosition(0, 0);
    glutInitWindowSize(400, 400);
+   glutInit( &argc, argv);
 
    type = GLUT_DEPTH;
    type |= GLUT_RGB;
diff --git a/progs/demos/lodbias.c b/progs/demos/lodbias.c
index 8d39bd6..23488b1 100644
--- a/progs/demos/lodbias.c
+++ b/progs/demos/lodbias.c
@@ -282,9 +282,8 @@
 
 int main( int argc, char *argv[] )
 {
-   glutInit( &argc, argv );
-   glutInitWindowPosition( 0, 0 );
    glutInitWindowSize( 350, 350 );
+   glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
    win = glutCreateWindow(argv[0]);
    glutReshapeFunc( Reshape );
diff --git a/progs/demos/morph3d.c b/progs/demos/morph3d.c
index 6aca827..0f8ac42 100644
--- a/progs/demos/morph3d.c
+++ b/progs/demos/morph3d.c
@@ -841,9 +841,8 @@
 
   object=1;
 
-  glutInit(&argc, argv);
-  glutInitWindowPosition(0,0);
   glutInitWindowSize(640,480);
+  glutInit(&argc, argv);
 
   glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB );
 
@@ -887,5 +886,6 @@
   glutIdleFunc( idle_ );
   glutDisplayFunc( draw );
   glutMainLoop();
-  
+
+  return 0;
 }
diff --git a/progs/demos/multiarb.c b/progs/demos/multiarb.c
index 3d89d3a..82796a0 100644
--- a/progs/demos/multiarb.c
+++ b/progs/demos/multiarb.c
@@ -338,9 +338,8 @@
 {
    GLint i;
 
-   glutInit( &argc, argv );
    glutInitWindowSize( 300, 300 );
-   glutInitWindowPosition( 0, 0 );
+   glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
    glutCreateWindow(argv[0] );
    glewInit();
diff --git a/progs/demos/paltex.c b/progs/demos/paltex.c
index d0cbcfb..5d4b866 100644
--- a/progs/demos/paltex.c
+++ b/progs/demos/paltex.c
@@ -248,12 +248,9 @@
 
 int main( int argc, char *argv[] )
 {
-   glutInit( &argc, argv );
-   glutInitWindowPosition( 0, 0 );
    glutInitWindowSize( 400, 300 );
-
+   glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
-
    glutCreateWindow(argv[0]);
    glewInit();
 
diff --git a/progs/demos/pointblast.c b/progs/demos/pointblast.c
index 2d70b72..b4d0a67 100644
--- a/progs/demos/pointblast.c
+++ b/progs/demos/pointblast.c
@@ -427,10 +427,10 @@
 main(int argc, char **argv)
 {
   int i;
+
+  glutInitWindowSize(300, 300);
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
-  glutInitWindowPosition(0, 0);
-  glutInitWindowSize(300, 300);
 
   for (i=1; i<argc; i++) {
     if(!strcmp("-noms", argv[i])) {
diff --git a/progs/demos/projtex.c b/progs/demos/projtex.c
index 99154d7..d162568 100644
--- a/progs/demos/projtex.c
+++ b/progs/demos/projtex.c
@@ -245,6 +245,10 @@
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
      }
      glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
+
+     free(texData3);
+     free(texData4);
+     free(image);
   }
 }
 
@@ -994,18 +998,17 @@
 int
 main(int argc, char **argv)
 {
+  glutInitWindowSize(500,500);
   glutInit(&argc, argv);
+  glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
+  (void) glutCreateWindow("projtex");
+  glewInit();
 
   if (argc > 1) {
      NumTextures = atoi(argv[1]);
   }
   assert(NumTextures <= MAX_TEX);
 
-  glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
-  glutInitWindowSize(500,500);
-  (void) glutCreateWindow("projtex");
-  glewInit();
-
   loadTexture = loadImageTextures;
   drawObject = drawCube;
   initialize();
diff --git a/progs/demos/ray.c b/progs/demos/ray.c
index c2d8e4f..9cc464d 100644
--- a/progs/demos/ray.c
+++ b/progs/demos/ray.c
@@ -834,6 +834,8 @@
    gluQuadricTexture(obj, GL_TRUE);
    gluSphere(obj, SPHERE_RADIUS, 16, 16);
    glEndList();
+
+   gluDeleteQuadric(obj);
 }
 
 int
@@ -854,7 +856,6 @@
       }
     */
 
-   glutInitWindowPosition(0, 0);
    glutInitWindowSize(WIDTH, HEIGHT);
    glutInit(&ac, av);
 
diff --git a/progs/demos/readpix.c b/progs/demos/readpix.c
index bbb3a68..cc4e490 100644
--- a/progs/demos/readpix.c
+++ b/progs/demos/readpix.c
@@ -219,7 +219,7 @@
       GLint reads = 0;
       GLint endTime;
       GLint startTime = glutGet(GLUT_ELAPSED_TIME);
-      GLdouble seconds, pixelsPerSecond;
+      GLdouble seconds, mpixels, mpixelsPerSecond;
       printf("Benchmarking...\n");
       do {
          glReadPixels(APosX, APosY, ImgWidth, ImgHeight,
@@ -228,9 +228,10 @@
          endTime = glutGet(GLUT_ELAPSED_TIME);
       } while (endTime - startTime < 4000);   /* 4 seconds */
       seconds = (double) (endTime - startTime) / 1000.0;
-      pixelsPerSecond = reads * ImgWidth * ImgHeight / seconds;
-      printf("Result:  %d reads in %f seconds = %f pixels/sec\n",
-             reads, seconds, pixelsPerSecond);
+      mpixels = reads * (ImgWidth * ImgHeight / (1000.0 * 1000.0));
+      mpixelsPerSecond = mpixels / seconds;
+      printf("Result:  %d reads in %f seconds = %f Mpixels/sec\n",
+             reads, seconds, mpixelsPerSecond);
       Benchmark = GL_FALSE;
    }
    else {
@@ -382,12 +383,11 @@
 main( int argc, char *argv[] )
 {
    GLboolean ciMode = GL_FALSE;
+   glutInitWindowSize( 750, 250 );
+   glutInit( &argc, argv );
    if (argc > 1 && strcmp(argv[1], "-ci")==0) {
       ciMode = GL_TRUE;
    }
-   glutInit( &argc, argv );
-   glutInitWindowPosition( 0, 0 );
-   glutInitWindowSize( 750, 250 );
    if (ciMode)
       glutInitDisplayMode( GLUT_INDEX | GLUT_DOUBLE );
    else
diff --git a/progs/demos/renormal.c b/progs/demos/renormal.c
index 9e5da95..61dd860 100644
--- a/progs/demos/renormal.c
+++ b/progs/demos/renormal.c
@@ -112,12 +112,9 @@
 
 int main( int argc, char *argv[] )
 {
-   glutInit( &argc, argv );
-   glutInitWindowPosition(0, 0);
    glutInitWindowSize( 400, 400 );
-
+   glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
-
    glutCreateWindow(argv[0]);
 
    Init();
diff --git a/progs/demos/shadowtex.c b/progs/demos/shadowtex.c
index dc5a4bb..036f73d 100644
--- a/progs/demos/shadowtex.c
+++ b/progs/demos/shadowtex.c
@@ -1022,9 +1022,8 @@
 int
 main(int argc, char *argv[])
 {
-   glutInit(&argc, argv);
-   glutInitWindowPosition(0, 0);
    glutInitWindowSize(WindowWidth, WindowHeight);
+   glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);
    glutCreateWindow(argv[0]);
    glewInit();
diff --git a/progs/demos/spectex.c b/progs/demos/spectex.c
index 6ab1191..c1dada9 100644
--- a/progs/demos/spectex.c
+++ b/progs/demos/spectex.c
@@ -239,13 +239,9 @@
 
 int main( int argc, char *argv[] )
 {
-
-   glutInit( &argc, argv );
-   glutInitWindowPosition( 0, 0 );
    glutInitWindowSize( 300, 300 );
-
+   glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
-
    glutCreateWindow( "spectex" );
 
    Init();
diff --git a/progs/demos/spriteblast.c b/progs/demos/spriteblast.c
index d73b680..36e226e 100644
--- a/progs/demos/spriteblast.c
+++ b/progs/demos/spriteblast.c
@@ -493,6 +493,8 @@
 main(int argc, char **argv)
 {
   int i;
+
+  glutInitWindowSize(600,300);
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
 
@@ -506,8 +508,6 @@
       linearFiltering = 0;
     }
   }
-  glutInitWindowPosition(0, 0);
-  glutInitWindowSize(600,300);
   glutCreateWindow("sprite blast");
   glewInit();
   glutReshapeFunc(reshape);
diff --git a/progs/demos/teapot.c b/progs/demos/teapot.c
index 6bf6e06..04a675f 100644
--- a/progs/demos/teapot.c
+++ b/progs/demos/teapot.c
@@ -638,7 +638,6 @@
     }
     */
 
-  glutInitWindowPosition(0,0);
   glutInitWindowSize(WIDTH,HEIGHT);
   glutInit(&ac,av);
 
diff --git a/progs/demos/terrain.c b/progs/demos/terrain.c
index be78ea4..a72c8d3 100644
--- a/progs/demos/terrain.c
+++ b/progs/demos/terrain.c
@@ -8,6 +8,7 @@
  * based on a Mikael SkiZoWalker's (MoDEL) / France (Skizo@Hol.Fr) demo
  */
 
+#include <assert.h>
 #include <stdio.h>
 #include <math.h>
 #include <stdlib.h>
@@ -559,12 +560,14 @@
    FILE *FilePic;
    int i, tmp;
    GLenum gluerr;
+   size_t result;
 
    if ((FilePic = fopen("terrain.dat", "r")) == NULL) {
       fprintf(stderr, "Error loading terrain.dat\n");
       exit(-1);
    }
-   fread(bufferter, 256 * 256, 1, FilePic);
+   result = fread(bufferter, 256 * 256, 1, FilePic);
+   assert(result == 1);
    fclose(FilePic);
 
    for (i = 0; i < (256 * 256); i++) {
@@ -623,7 +626,6 @@
 int
 main(int ac, char **av)
 {
-   glutInitWindowPosition(0, 0);
    glutInitWindowSize(WIDTH, HEIGHT);
    glutInit(&ac, av);
 
diff --git a/progs/demos/tessdemo.c b/progs/demos/tessdemo.c
index f71cea1..8b988e3 100644
--- a/progs/demos/tessdemo.c
+++ b/progs/demos/tessdemo.c
@@ -503,10 +503,9 @@
 
    usage();
 
+   glutInitWindowSize( 400, 400 );
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );
-   glutInitWindowPosition(0, 0);
-   glutInitWindowSize( 400, 400 );
    glutCreateWindow( argv[0] );
 
    /* GH: Bit of a hack...
diff --git a/progs/demos/texcyl.c b/progs/demos/texcyl.c
index 0e6089b..4df97ec 100644
--- a/progs/demos/texcyl.c
+++ b/progs/demos/texcyl.c
@@ -261,10 +261,8 @@
 
 int main( int argc, char *argv[] )
 {
-   glutInit( &argc, argv );
    glutInitWindowSize( 400, 400 );
-   glutInitWindowPosition( 0, 0 );
-
+   glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
 
    Win = glutCreateWindow(argv[0] );
diff --git a/progs/demos/texenv.c b/progs/demos/texenv.c
index c5a8b13..260ca87 100644
--- a/progs/demos/texenv.c
+++ b/progs/demos/texenv.c
@@ -765,6 +765,7 @@
    GLboolean info = GL_FALSE;
    int i;
 
+   glutInitWindowSize( winWidth, winHeight );
    glutInit( &argc, argv );
 
    for ( i = 1 ; i < argc ; i++ ) {
@@ -786,8 +787,6 @@
       glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE );
    }
 
-   glutInitWindowSize( winWidth, winHeight );
-   glutInitWindowPosition( 0, 0 );
    Win = glutCreateWindow( "Texture Environment Test" );
 
    initialize();
diff --git a/progs/demos/textures.c b/progs/demos/textures.c
index b7bf135..1415ef1 100644
--- a/progs/demos/textures.c
+++ b/progs/demos/textures.c
@@ -57,7 +57,7 @@
 {
    Xrot = glutGet(GLUT_ELAPSED_TIME) * 0.02;
    Yrot = glutGet(GLUT_ELAPSED_TIME) * 0.04;
-   //Zrot += 2.0;
+   /* Zrot += 2.0; */
    glutPostRedisplay();
 }
 
@@ -356,9 +356,8 @@
 int
 main(int argc, char *argv[])
 {
-   glutInit(&argc, argv);
-   glutInitWindowPosition(0, 0);
    glutInitWindowSize(700, 700);
+   glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    Win = glutCreateWindow(argv[0]);
    glutReshapeFunc(Reshape);
diff --git a/progs/demos/trispd.c b/progs/demos/trispd.c
index 165d088..c07c340 100644
--- a/progs/demos/trispd.c
+++ b/progs/demos/trispd.c
@@ -227,15 +227,12 @@
 
 int main( int argc, char *argv[] )
 {
-   printf("For options:  %s -help\n", argv[0]);
-   glutInit( &argc, argv );
    glutInitWindowSize( (int) Width, (int) Height );
-   glutInitWindowPosition( 0, 0 );
-
+   glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
-
    glutCreateWindow( argv[0] );
 
+   printf("For options:  %s -help\n", argv[0]);
    if (argc==2 && strcmp(argv[1],"-help")==0) {
       Help(argv[0]);
       return 0;
diff --git a/progs/demos/tunnel.c b/progs/demos/tunnel.c
index 6981da3..efc007c 100644
--- a/progs/demos/tunnel.c
+++ b/progs/demos/tunnel.c
@@ -491,7 +491,6 @@
    fprintf(stderr,
 	   "Tunnel V1.5\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
 
-   glutInitWindowPosition(0, 0);
    glutInitWindowSize(WIDTH, HEIGHT);
    glutInit(&ac, av);
 
diff --git a/progs/demos/tunnel2.c b/progs/demos/tunnel2.c
index 0288ea0..f15da95 100644
--- a/progs/demos/tunnel2.c
+++ b/progs/demos/tunnel2.c
@@ -559,7 +559,6 @@
    fprintf(stderr,
 	   "Tunnel2 V1.0\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
 
-   glutInitWindowPosition(0, 0);
    glutInitWindowSize(WIDTHC0, HEIGHTC0);
    glutInit(&ac, av);
 
diff --git a/progs/demos/vao_demo.c b/progs/demos/vao_demo.c
index 206e06f..5ce07ec 100644
--- a/progs/demos/vao_demo.c
+++ b/progs/demos/vao_demo.c
@@ -317,9 +317,8 @@
 
 int main( int argc, char *argv[] )
 {
-   glutInit( &argc, argv );
-   glutInitWindowPosition( 0, 0 );
    glutInitWindowSize( Width, Height );
+   glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
    Win = glutCreateWindow( "GL_APPLE_vertex_array_object demo" );
    glutReshapeFunc( Reshape );
diff --git a/progs/demos/winpos.c b/progs/demos/winpos.c
index 13a9c7e..f935f9b 100644
--- a/progs/demos/winpos.c
+++ b/progs/demos/winpos.c
@@ -96,9 +96,8 @@
 
 int main( int argc, char *argv[] )
 {
-   glutInit(&argc, argv);
-   glutInitWindowPosition(0, 0);
    glutInitWindowSize(500, 500);
+   glutInit(&argc, argv);
    glutInitDisplayMode( GLUT_RGB );
 
    if (glutCreateWindow("winpos") <= 0) {
diff --git a/progs/egl/demo1.c b/progs/egl/demo1.c
index 34a516e..d892734 100644
--- a/progs/egl/demo1.c
+++ b/progs/egl/demo1.c
@@ -114,6 +114,7 @@
 
    PrintConfigs(d, configs, numConfigs);
 
+   eglBindAPI(EGL_OPENGL_API);
    ctx = eglCreateContext(d, configs[0], EGL_NO_CONTEXT, NULL);
    if (ctx == EGL_NO_CONTEXT) {
       printf("failed to create context\n");
diff --git a/progs/egl/demo2.c b/progs/egl/demo2.c
index 3994656..b9e92f6 100644
--- a/progs/egl/demo2.c
+++ b/progs/egl/demo2.c
@@ -111,11 +111,7 @@
       EGL_HEIGHT, 500,
       EGL_NONE
    };
-   const EGLint screenAttribs[] = {
-      EGL_WIDTH, 1024,
-      EGL_HEIGHT, 768,
-      EGL_NONE
-   };
+   EGLint screenAttribs[32];
    EGLModeMESA mode;
    EGLScreenMESA screen;
    EGLint count;
@@ -149,6 +145,7 @@
    eglGetScreensMESA(d, &screen, 1, &count);
    eglGetModesMESA(d, screen, &mode, 1, &count);
 
+   eglBindAPI(EGL_OPENGL_API);
    ctx = eglCreateContext(d, configs[0], EGL_NO_CONTEXT, NULL);
    if (ctx == EGL_NO_CONTEXT) {
       printf("failed to create context\n");
@@ -169,6 +166,13 @@
 
    b = eglMakeCurrent(d, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
 
+   i = 0;
+   screenAttribs[i++] = EGL_WIDTH;
+   eglGetModeAttribMESA(d, mode, EGL_WIDTH, &screenAttribs[i++]);
+   screenAttribs[i++] = EGL_HEIGHT;
+   eglGetModeAttribMESA(d, mode, EGL_HEIGHT, &screenAttribs[i++]);
+   screenAttribs[i] = EGL_NONE;
+
    screen_surf = eglCreateScreenSurfaceMESA(d, configs[0], screenAttribs);
    if (screen_surf == EGL_NO_SURFACE) {
       printf("failed to create screen surface\n");
diff --git a/progs/egl/demo3.c b/progs/egl/demo3.c
index 0665fd0..64b9ee6 100644
--- a/progs/egl/demo3.c
+++ b/progs/egl/demo3.c
@@ -564,11 +564,8 @@
    EGLint numConfigs, count;
    EGLBoolean b;
    const GLubyte *bitmap;
-   const EGLint screenAttribs[] = {
-      EGL_WIDTH, 1024,
-      EGL_HEIGHT, 768,
-      EGL_NONE
-   };
+   EGLint screenAttribs[32];
+   EGLint i;
 
    EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    assert(d);
@@ -590,12 +587,20 @@
    eglGetScreensMESA(d, &screen, 1, &count);
    eglGetModesMESA(d, screen, &mode, 1, &count);
 
+   eglBindAPI(EGL_OPENGL_API);
    ctx = eglCreateContext(d, configs[0], EGL_NO_CONTEXT, NULL);
    if (ctx == EGL_NO_CONTEXT) {
       printf("failed to create context\n");
       return 0;
    }
 
+   i = 0;
+   screenAttribs[i++] = EGL_WIDTH;
+   eglGetModeAttribMESA(d, mode, EGL_WIDTH, &screenAttribs[i++]);
+   screenAttribs[i++] = EGL_HEIGHT;
+   eglGetModeAttribMESA(d, mode, EGL_HEIGHT, &screenAttribs[i++]);
+   screenAttribs[i] = EGL_NONE;
+
    screen_surf = eglCreateScreenSurfaceMESA(d, configs[0], screenAttribs);
    if (screen_surf == EGL_NO_SURFACE) {
       printf("failed to create screen surface\n");
diff --git a/progs/egl/eglgears.c b/progs/egl/eglgears.c
index 052d0f9..6349095 100644
--- a/progs/egl/eglgears.c
+++ b/progs/egl/eglgears.c
@@ -374,7 +374,8 @@
 	EGLint screenAttribs[10];
 	EGLModeMESA mode[MAX_MODES];
 	EGLScreenMESA screen;
-	EGLint count, chosenMode;
+	EGLint count;
+	EGLint chosenMode = 0;
 	GLboolean printInfo = GL_FALSE;
 	EGLint width = 0, height = 0;
 	
@@ -425,6 +426,7 @@
 	}
 	printf("eglgears: Using screen mode/size %d: %d x %d\n", chosenMode, width, height);
 
+	eglBindAPI(EGL_OPENGL_API);
 	ctx = eglCreateContext(d, configs[0], EGL_NO_CONTEXT, NULL);
 	if (ctx == EGL_NO_CONTEXT) {
 		printf("eglgears: failed to create context\n");
diff --git a/progs/egl/eglscreen.c b/progs/egl/eglscreen.c
index 47b3ce3..520f76e 100644
--- a/progs/egl/eglscreen.c
+++ b/progs/egl/eglscreen.c
@@ -52,7 +52,8 @@
 	EGLint screenAttribs[10];
 	EGLModeMESA mode[MAX_MODES];
 	EGLScreenMESA screen;
-	EGLint count, chosenMode;
+	EGLint count;
+	EGLint chosenMode = 0;
 	EGLint width = 0, height = 0;
 
 	d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
diff --git a/progs/egl/egltri.c b/progs/egl/egltri.c
index 9bbc3cd..006e06e 100644
--- a/progs/egl/egltri.c
+++ b/progs/egl/egltri.c
@@ -208,6 +208,7 @@
 	}
 	printf("egltri: Using screen mode/size %d: %d x %d\n", chosenMode, width, height);
 
+	eglBindAPI(EGL_OPENGL_API);
 	ctx = eglCreateContext(d, configs[0], EGL_NO_CONTEXT, NULL);
 	if (ctx == EGL_NO_CONTEXT) {
 		printf("egltri: failed to create context\n");
diff --git a/progs/egl/xegl_tri.c b/progs/egl/xegl_tri.c
index 65f352d..1f1a005 100644
--- a/progs/egl/xegl_tri.c
+++ b/progs/egl/xegl_tri.c
@@ -120,6 +120,7 @@
       EGL_GREEN_SIZE, 1,
       EGL_BLUE_SIZE, 1,
       EGL_DEPTH_SIZE, 1,
+      EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
       EGL_NONE
    };
 
@@ -138,7 +139,8 @@
    scrnum = DefaultScreen( x_dpy );
    root = RootWindow( x_dpy, scrnum );
 
-   if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
+   if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs) ||
+       !num_configs) {
       printf("Error: couldn't get an EGL visual config\n");
       exit(1);
    }
diff --git a/progs/egl/xeglbindtex.c b/progs/egl/xeglbindtex.c
index fdd9fe2..de0ede9 100644
--- a/progs/egl/xeglbindtex.c
+++ b/progs/egl/xeglbindtex.c
@@ -53,6 +53,7 @@
       EGL_GREEN_SIZE, 8,
       EGL_BLUE_SIZE, 8,
       EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE,
+      EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
       EGL_NONE
    };
    EGLint pbuf_attribs[] = {
@@ -65,7 +66,8 @@
    EGLConfig config;
    EGLint num_configs;
 
-   if (!eglChooseConfig(dpy, config_attribs, &config, 1, &num_configs)) {
+   if (!eglChooseConfig(dpy, config_attribs, &config, 1, &num_configs) ||
+       !num_configs) {
       printf("Error: couldn't get an EGL visual config for pbuffer\n");
       exit(1);
    }
@@ -77,8 +79,6 @@
       printf("failed to allocate pbuffer\n");
       exit(1);
    }
-
-   glGenTextures(1, &tex_pbuf);
 }
 
 static void
@@ -112,6 +112,8 @@
       glTranslatef(0.0, 0.0, -5.0);
 
       glClearColor(0.2, 0.2, 0.2, 0.0);
+
+      glGenTextures(1, &tex_pbuf);
    }
 }
 
@@ -126,6 +128,7 @@
       EGL_BLUE_SIZE, 8,
       EGL_ALPHA_SIZE, 8,
       EGL_DEPTH_SIZE, 8,
+      EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
       EGL_NONE
    };
 
@@ -142,7 +145,8 @@
    scrnum = DefaultScreen( x_dpy );
    root = RootWindow( x_dpy, scrnum );
 
-   if (!eglChooseConfig(dpy, attribs, &config, 1, &num_configs)) {
+   if (!eglChooseConfig(dpy, attribs, &config, 1, &num_configs) ||
+       !num_configs) {
       printf("Error: couldn't get an EGL visual config\n");
       exit(1);
    }
diff --git a/progs/egl/xeglthreads.c b/progs/egl/xeglthreads.c
index 508dbc0..5787fae 100644
--- a/progs/egl/xeglthreads.c
+++ b/progs/egl/xeglthreads.c
@@ -467,6 +467,7 @@
                         EGL_GREEN_SIZE, 1,
                         EGL_BLUE_SIZE, 1,
                         EGL_DEPTH_SIZE, 1,
+                        EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
                         EGL_NONE };
    EGLConfig config;
    EGLint num_configs;
@@ -484,7 +485,8 @@
    scrnum = DefaultScreen(wt->Dpy);
    root = RootWindow(wt->Dpy, scrnum);
 
-   if (!eglChooseConfig(wt->Display, attribs, &config, 1, &num_configs)) {
+   if (!eglChooseConfig(wt->Display, attribs, &config, 1, &num_configs) ||
+       !num_configs) {
       Error("Unable to choose an EGL config");
    }
 
diff --git a/progs/fp/SConscript b/progs/fp/SConscript
index a783185..e209161 100644
--- a/progs/fp/SConscript
+++ b/progs/fp/SConscript
@@ -1,15 +1,4 @@
-Import('env')
-
-if not env['GLUT']:
-    Return()
-
-env = env.Clone()
-
-env.Prepend(CPPPATH = [
-	'../util',
-])
-
-env.Prepend(LIBS = ['$GLUT_LIB'])
+Import('*')
 
 progs = [
     'fp-tri',
@@ -17,14 +6,13 @@
     'tri-depth2',
     'tri-depthwrite',
     'tri-depthwrite2',
-    'tri-inv',
     'tri-param',
     'tri-tex',
     'point-position',
 ]
 
 for prog in progs:
-    env.Program(
+    progs_env.Program(
         target = prog,
         source = [prog + '.c'],
     )
diff --git a/progs/fp/fp-tri.c b/progs/fp/fp-tri.c
index 52a8fcf..70676d4 100644
--- a/progs/fp/fp-tri.c
+++ b/progs/fp/fp-tri.c
@@ -73,7 +73,7 @@
    GLuint Texture;
    GLint errno;
    GLuint prognum;
-   char buf[4096];
+   char buf[50000];
    GLuint sz;
    FILE *f;
 
@@ -176,6 +176,17 @@
    }
 
 
+   {
+      const float Ambient[4] = { 0.0, 1.0, 0.0, 0.0 };
+      const float Diffuse[4] = { 1.0, 0.0, 0.0, 0.0 };
+      const float Specular[4] = { 0.0, 0.0, 1.0, 0.0 };
+      const float Emission[4] = { 0.0, 0.0, 0.0, 1.0 };
+      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Ambient);
+      glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Diffuse);
+      glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Specular);
+      glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Emission);
+   }
+
    glClearColor(.1, .3, .5, 0);
 }
 
@@ -197,7 +208,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/fp/mov-imm.txt b/progs/fp/mov-imm.txt
new file mode 100644
index 0000000..38e4807
--- /dev/null
+++ b/progs/fp/mov-imm.txt
@@ -0,0 +1,3 @@
+!!ARBfp1.0
+MOV result.color, {0.5, 0.8, 0.3, 1.0};
+END
diff --git a/progs/fp/mov-param.txt b/progs/fp/mov-param.txt
new file mode 100644
index 0000000..13d82fe
--- /dev/null
+++ b/progs/fp/mov-param.txt
@@ -0,0 +1,4 @@
+!!ARBfp1.0
+PARAM Diffuse = state.material.diffuse; 
+MOV result.color, Diffuse;
+END
diff --git a/progs/fp/point-position.c b/progs/fp/point-position.c
index c0963d7..1ae753c 100644
--- a/progs/fp/point-position.c
+++ b/progs/fp/point-position.c
@@ -55,7 +55,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/fp/tri-depth.c b/progs/fp/tri-depth.c
index 5488469..a9f3a6a 100644
--- a/progs/fp/tri-depth.c
+++ b/progs/fp/tri-depth.c
@@ -57,7 +57,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/fp/tri-depth2.c b/progs/fp/tri-depth2.c
index 6ed2307..8c43368 100644
--- a/progs/fp/tri-depth2.c
+++ b/progs/fp/tri-depth2.c
@@ -59,7 +59,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/fp/tri-depthwrite.c b/progs/fp/tri-depthwrite.c
index 8e4f3e6..7b9d70f 100644
--- a/progs/fp/tri-depthwrite.c
+++ b/progs/fp/tri-depthwrite.c
@@ -55,7 +55,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/fp/tri-depthwrite2.c b/progs/fp/tri-depthwrite2.c
index 3c0b4d3..5999495 100644
--- a/progs/fp/tri-depthwrite2.c
+++ b/progs/fp/tri-depthwrite2.c
@@ -55,7 +55,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/fp/tri-inv.c b/progs/fp/tri-inv.c
deleted file mode 100644
index 7e8d8c5..0000000
--- a/progs/fp/tri-inv.c
+++ /dev/null
@@ -1,111 +0,0 @@
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <GL/glew.h>
-#include <GL/glut.h>
-
-
-
-static void Init( void )
-{
-   static const char *modulate2D =
-      "!!ARBfp1.0\n"
-      "TEMP R0;\n"
-      "INV result.color, fragment.color; \n"
-      "END"
-      ;
-   GLuint modulateProg;
-
-   if (!GLEW_ARB_fragment_program) {
-      printf("Error: GL_ARB_fragment_program not supported!\n");
-      exit(1);
-   }
-   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
-
-   /* Setup the fragment program */
-   glGenProgramsARB(1, &modulateProg);
-   glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, modulateProg);
-   glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
-                        strlen(modulate2D), (const GLubyte *)modulate2D);
-
-   printf("glGetError = 0x%x\n", (int) glGetError());
-   printf("glError(GL_PROGRAM_ERROR_STRING_ARB) = %s\n",
-          (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB));
-
-   glEnable(GL_FRAGMENT_PROGRAM_ARB);
-
-   glClearColor(.3, .3, .3, 0);
-}
-
-static void Reshape(int width, int height)
-{
-
-    glViewport(0, 0, (GLint)width, (GLint)height);
-
-    glMatrixMode(GL_PROJECTION);
-    glLoadIdentity();
-    glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0);
-    glMatrixMode(GL_MODELVIEW);
-}
-
-static void Key(unsigned char key, int x, int y)
-{
-
-    switch (key) {
-      case 27:
-	exit(1);
-      default:
-	return;
-    }
-
-    glutPostRedisplay();
-}
-
-static void Draw(void)
-{
-   glClear(GL_COLOR_BUFFER_BIT); 
-
-   glBegin(GL_TRIANGLES);
-   glColor3f(0,0,1); 
-   glVertex3f( 0.9, -0.9, -30.0);
-   glColor3f(1,0,0); 
-   glVertex3f( 0.9,  0.9, -30.0);
-   glColor3f(0,1,0); 
-   glVertex3f(-0.9,  0.0, -30.0);
-   glEnd();
-
-   glFlush();
-
-
-}
-
-
-int main(int argc, char **argv)
-{
-    GLenum type;
-
-    glutInit(&argc, argv);
-
-
-
-    glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
-
-    type = GLUT_RGB;
-    type |= GLUT_SINGLE;
-    glutInitDisplayMode(type);
-
-    if (glutCreateWindow("First Tri") == GL_FALSE) {
-	exit(1);
-    }
-
-    glewInit();
-
-    Init();
-
-    glutReshapeFunc(Reshape);
-    glutKeyboardFunc(Key);
-    glutDisplayFunc(Draw);
-    glutMainLoop();
-	return 0;
-}
diff --git a/progs/fp/tri-param.c b/progs/fp/tri-param.c
index 57443d7..26a804d 100644
--- a/progs/fp/tri-param.c
+++ b/progs/fp/tri-param.c
@@ -54,7 +54,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/fp/tri-tex.c b/progs/fp/tri-tex.c
index 1dbbb20..64299e9 100644
--- a/progs/fp/tri-tex.c
+++ b/progs/fp/tri-tex.c
@@ -76,7 +76,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/glsl/CH11-bumpmaptex.frag b/progs/glsl/CH11-bumpmaptex.frag
new file mode 100644
index 0000000..b1f93b7
--- /dev/null
+++ b/progs/glsl/CH11-bumpmaptex.frag
@@ -0,0 +1,47 @@
+//
+// Fragment shader for procedural bumps
+//
+// Authors: John Kessenich, Randi Rost
+//
+// Copyright (c) 2002-2006 3Dlabs Inc. Ltd. 
+//
+// See 3Dlabs-License.txt for license information
+//
+// Texture mapping/modulation added by Brian Paul
+//
+
+varying vec3 LightDir;
+varying vec3 EyeDir;
+
+uniform float BumpDensity;     // = 16.0
+uniform float BumpSize;        // = 0.15
+uniform float SpecularFactor;  // = 0.5
+
+sampler2D Tex;
+
+void main()
+{
+    vec3 ambient = vec3(0.25);
+    vec3 litColor;
+    vec2 c = BumpDensity * gl_TexCoord[0].st;
+    vec2 p = fract(c) - vec2(0.5);
+
+    float d, f;
+    d = p.x * p.x + p.y * p.y;
+    f = inversesqrt(d + 1.0);
+
+    if (d >= BumpSize)
+        { p = vec2(0.0); f = 1.0; }
+
+    vec3 SurfaceColor = texture2D(Tex, gl_TexCoord[0].st).xyz;
+
+    vec3 normDelta = vec3(p.x, p.y, 1.0) * f;
+    litColor = SurfaceColor * (ambient + max(dot(normDelta, LightDir), 0.0));
+    vec3 reflectDir = reflect(LightDir, normDelta);
+    
+    float spec = max(dot(EyeDir, reflectDir), 0.0);
+    spec *= SpecularFactor;
+    litColor = min(litColor + spec, vec3(1.0));
+
+    gl_FragColor = vec4(litColor, 1.0);
+}
diff --git a/progs/glsl/CH18-mandel.frag b/progs/glsl/CH18-mandel.frag
index a472d81..a972d68 100644
--- a/progs/glsl/CH18-mandel.frag
+++ b/progs/glsl/CH18-mandel.frag
@@ -31,7 +31,7 @@
     float iter;
 
 //    for (iter = 0.0; iter < MaxIterations && r2 < 4.0; ++iter)
-    for (iter = 0.0; iter < 12 && r2 < 4.0; ++iter)
+    for (iter = 0.0; iter < 12.0 && r2 < 4.0; ++iter)
     {
         float tempreal = real;
 
diff --git a/progs/glsl/SConscript b/progs/glsl/SConscript
index 7a4549c..8f2ebcf 100644
--- a/progs/glsl/SConscript
+++ b/progs/glsl/SConscript
@@ -1,23 +1,5 @@
 Import('*')
 
-if not env['GLUT']:
-    Return()
-
-env = env.Clone()
-
-env.Prepend(CPPPATH = [
-	'../util',
-])
-
-env.Prepend(LIBS = [
-	util,
-	'$GLUT_LIB'
-])
-
-if env['platform'] == 'windows':
-    env.Append(CPPDEFINES = ['NOMINMAX'])
-    env.Prepend(LIBS = ['winmm'])
-
 progs = [
       'array',
       'bitmap',
@@ -48,7 +30,7 @@
 ]
 
 for prog in progs:
-    env.Program(
+    progs_env.Program(
         target = prog,
         source = prog + '.c',
     )
diff --git a/progs/glsl/bump.c b/progs/glsl/bump.c
index 87669ae..e31afab 100644
--- a/progs/glsl/bump.c
+++ b/progs/glsl/bump.c
@@ -12,15 +12,20 @@
 #include <GL/glew.h>
 #include <GL/glut.h>
 #include "shaderutil.h"
+#include "readtex.h"
 
 
 static char *FragProgFile = "CH11-bumpmap.frag";
+static char *FragTexProgFile = "CH11-bumpmaptex.frag";
 static char *VertProgFile = "CH11-bumpmap.vert";
+static char *TextureFile = "../images/tile.rgb";
 
 /* program/shader objects */
 static GLuint fragShader;
+static GLuint fragTexShader;
 static GLuint vertShader;
 static GLuint program;
+static GLuint texProgram;
 
 
 static struct uniform_info Uniforms[] = {
@@ -32,13 +37,26 @@
    END_OF_UNIFORMS
 };
 
+static struct uniform_info TexUniforms[] = {
+   { "LightPosition",  1, GL_FLOAT_VEC3, { 0.57737, 0.57735, 0.57735, 0.0 }, -1 },
+   { "Tex",            1, GL_INT,   { 0, 0, 0, 0 }, -1 },
+   { "BumpDensity",    1, GL_FLOAT, { 10.0, 0, 0, 0 }, -1 },
+   { "BumpSize",       1, GL_FLOAT, { 0.125, 0, 0, 0 }, -1 },
+   { "SpecularFactor", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 },
+   END_OF_UNIFORMS
+};
+
 static GLint win = 0;
 
 static GLfloat xRot = 20.0f, yRot = 0.0f, zRot = 0.0f;
 
-static GLuint tangentAttrib;
+static GLint tangentAttrib;
+static GLint tangentAttribTex;
+
+static GLuint Texture;
 
 static GLboolean Anim = GL_FALSE;
+static GLboolean Textured = GL_FALSE;
 
 
 static void
@@ -135,6 +153,11 @@
    glRotatef(yRot, 0.0f, 1.0f, 0.0f);
    glRotatef(zRot, 0.0f, 0.0f, 1.0f);
 
+   if (Textured)
+      glUseProgram(texProgram);
+   else
+      glUseProgram(program);
+
    Cube(1.5);
 
    glPopMatrix();
@@ -163,8 +186,10 @@
 CleanUp(void)
 {
    glDeleteShader(fragShader);
+   glDeleteShader(fragTexShader);
    glDeleteShader(vertShader);
    glDeleteProgram(program);
+   glDeleteProgram(texProgram);
    glutDestroyWindow(win);
 }
 
@@ -181,6 +206,9 @@
       Anim = !Anim;
       glutIdleFunc(Anim ? Idle : NULL);
       break;
+   case 't':
+      Textured = !Textured;
+      break;
    case 'z':
       zRot += step;
       break;
@@ -254,6 +282,26 @@
 
    CheckError(__LINE__);
 
+
+   /*
+    * As above, but fragment shader also uses a texture map.
+    */
+   fragTexShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragTexProgFile);
+   texProgram = LinkShaders(vertShader, fragTexShader);
+   glUseProgram(texProgram);
+   assert(glIsProgram(texProgram));
+   assert(glIsShader(fragTexShader));
+   SetUniformValues(texProgram, TexUniforms);
+   PrintUniforms(TexUniforms);
+
+   /*
+    * Load tex image.
+    */
+   glGenTextures(1, &Texture);
+   glBindTexture(GL_TEXTURE_2D, Texture);
+   LoadRGBMipmaps(TextureFile, GL_RGB);
+
+
    glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
 
    glEnable(GL_DEPTH_TEST);
@@ -268,10 +316,13 @@
    int i;
    for (i = 1; i < argc; i++) {
       if (strcmp(argv[i], "-fs") == 0) {
-         FragProgFile = argv[i+1];
+         FragProgFile = argv[++i];
       }
       else if (strcmp(argv[i], "-vs") == 0) {
-         VertProgFile = argv[i+1];
+         VertProgFile = argv[++i];
+      }
+      else if (strcmp(argv[i], "-t") == 0) {
+         TextureFile = argv[++i];
       }
    }
 }
diff --git a/progs/glsl/convolutions.c b/progs/glsl/convolutions.c
index c2fb76e..350e61b 100644
--- a/progs/glsl/convolutions.c
+++ b/progs/glsl/convolutions.c
@@ -369,7 +369,7 @@
    case 27:
       exit(0);
    default:
-      return;
+      break;
    }
    glutPostRedisplay();
 }
diff --git a/progs/glsl/deriv.c b/progs/glsl/deriv.c
index 265a515..588246b 100644
--- a/progs/glsl/deriv.c
+++ b/progs/glsl/deriv.c
@@ -27,11 +27,15 @@
 static GLint win = 0;
 static GLboolean anim = GL_TRUE;
 static GLfloat xRot = 0.0f, yRot = 0.0f;
+static GLint WinSize[2];
+static GLint WinSizeUniform = -1;
 
 
 static void
 Redisplay(void)
 {
+   glUniform2iv(WinSizeUniform, 1, WinSize);
+
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
    glPushMatrix();
@@ -55,6 +59,8 @@
 static void
 Reshape(int width, int height)
 {
+   WinSize[0] = width;
+   WinSize[1] = height;
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
@@ -140,6 +146,7 @@
    glNewList(SphereList, GL_COMPILE);
    gluSphere(obj, 2.0f, 30, 15);
    glEndList();
+   gluDeleteQuadric(obj);
 }
 
 
@@ -162,8 +169,10 @@
 Init(void)
 {
    static const char *fragShaderText =
+      "uniform ivec2 WinSize; \n"
       "void main() {\n"
-      "   gl_FragColor = abs(dFdy(gl_TexCoord[0])) * 50.0;\n"
+      "   vec2 d = dFdy(gl_TexCoord[0].xy) * vec2(WinSize); \n"
+      "   gl_FragColor =  vec4(d.x, d.y, 0.0, 1.0);\n"
       "  // gl_FragColor = gl_TexCoord[0];\n"
       "}\n";
    static const char *vertShaderText =
@@ -180,6 +189,7 @@
    program = LinkShaders(vertShader, fragShader);
 
    glUseProgram(program);
+   WinSizeUniform = glGetUniformLocation(program, "WinSize");
 
    /*assert(glGetError() == 0);*/
 
@@ -219,8 +229,10 @@
 int
 main(int argc, char *argv[])
 {
+   WinSize[0] = WinSize[1] = 200;
+
    glutInit(&argc, argv);
-   glutInitWindowSize(200, 200);
+   glutInitWindowSize(WinSize[0], WinSize[1]);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    win = glutCreateWindow(argv[0]);
    glewInit();
diff --git a/progs/glsl/multinoise.c b/progs/glsl/multinoise.c
index 0d4026e..d504ba1 100644
--- a/progs/glsl/multinoise.c
+++ b/progs/glsl/multinoise.c
@@ -22,22 +22,22 @@
    "void main()\n"
    "{\n"
    "   gl_FragColor.rgb = noise3( gl_TexCoord[ 0 ].w ) * 0.5 + 0.5;\n"
-   "   gl_FragColor.a = 1;\n"
+   "   gl_FragColor.a = 1.0;\n"
    "}\n",
    "void main()\n"
    "{\n"
    "   gl_FragColor.rgb = noise3( gl_TexCoord[ 0 ].xw ) * 0.5 + 0.5;\n"
-   "   gl_FragColor.a = 1;\n"
+   "   gl_FragColor.a = 1.0;\n"
    "}\n",
    "void main()\n"
    "{\n"
    "   gl_FragColor.rgb = noise3( gl_TexCoord[ 0 ].xyw ) * 0.5 + 0.5;\n"
-   "   gl_FragColor.a = 1;\n"
+   "   gl_FragColor.a = 1.0;\n"
    "}\n",
    "void main()\n"
    "{\n"
    "   gl_FragColor.rgb = noise3( gl_TexCoord[ 0 ].xyzw ) * 0.5 + 0.5;\n"
-   "   gl_FragColor.a = 1;\n"
+   "   gl_FragColor.a = 1.0;\n"
    "}\n"
 };
     
@@ -125,6 +125,7 @@
    case 'a':
       Anim = !Anim;
       glutIdleFunc(Anim ? Idle : NULL);
+      break;
    case 's':
       Slice -= step;
       break;
@@ -193,7 +194,7 @@
       GLchar log[1000];
       GLsizei len;
       glGetShaderInfoLog(shader, 1000, &len, log);
-      fprintf(stderr, "noise: problem compiling shader: %s\n", log);
+      fprintf(stderr, "multinoise: problem compiling shader: %s\n", log);
       exit(1);
    }
    else {
diff --git a/progs/glsl/multitex.c b/progs/glsl/multitex.c
index bf46fd5..49b3225 100644
--- a/progs/glsl/multitex.c
+++ b/progs/glsl/multitex.c
@@ -369,12 +369,9 @@
 static void
 InitGL(void)
 {
-   const char *version = (const char *) glGetString(GL_VERSION);
+   if (!ShadersSupported())
+      exit(1);
 
-   if (version[0] != '2' || version[1] != '.') {
-      printf("Warning: this program expects OpenGL 2.0\n");
-      /*exit(1);*/
-   }
    printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
    printf("Usage:\n");
    printf("  a     - toggle arrays vs. immediate mode rendering\n");
diff --git a/progs/glsl/noise.c b/progs/glsl/noise.c
index fdab263..1148580 100644
--- a/progs/glsl/noise.c
+++ b/progs/glsl/noise.c
@@ -28,7 +28,7 @@
    "   vec4 p;\n"
    "   p.xy = gl_TexCoord[0].xy;\n"
    "   p.z = Slice;\n"
-   "   p.w = 0;\n"
+   "   p.w = 0.0;\n"
    "   vec4 n = noise4(p * scale);\n"
    "   gl_FragColor = n * Scale + Bias;\n"
    "}\n";
@@ -119,6 +119,7 @@
    case 'a':
       Anim = !Anim;
       glutIdleFunc(Anim ? Idle : NULL);
+      break;
    case 's':
       Slice -= step;
       break;
diff --git a/progs/glsl/shtest.c b/progs/glsl/shtest.c
index 628a7dd..7b1917b 100644
--- a/progs/glsl/shtest.c
+++ b/progs/glsl/shtest.c
@@ -492,9 +492,8 @@
    conf->num_uniforms = 0;
 
    /* ugly but functional parser */
-   while (!feof(f)) {
-      fgets(line, sizeof(line), f);
-      if (!feof(f) && line[0]) {
+   while (fgets(line, sizeof(line), f) != NULL) {
+      if (line[0]) {
          if (strncmp(line, "vs ", 3) == 0) {
             VertShaderFile = strdup(line + 3);
             VertShaderFile[strlen(VertShaderFile) - 1] = 0;
@@ -550,6 +549,10 @@
 
             type = TypeFromName(typeName);
 
+            if (strlen(name) + 1 > sizeof(conf->uniforms[conf->num_uniforms].name)) {
+               fprintf(stderr, "string overflow\n");
+               exit(1);
+            }
             strcpy(conf->uniforms[conf->num_uniforms].name, name);
             conf->uniforms[conf->num_uniforms].value[0] = v1;
             conf->uniforms[conf->num_uniforms].value[1] = v2;
@@ -627,7 +630,7 @@
    NumAttribs = GetAttribs(Program, Attribs);
    PrintAttribs(Attribs);
 
-   //assert(glGetError() == 0);
+   /* assert(glGetError() == 0); */
 
    glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
 
diff --git a/progs/glsl/texaaline.c b/progs/glsl/texaaline.c
index 2e4f932..00edab7 100644
--- a/progs/glsl/texaaline.c
+++ b/progs/glsl/texaaline.c
@@ -310,8 +310,8 @@
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-   //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4);
-   ////glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 5);
+   /* glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); */
+   /* glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 5); */
 
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 #undef SZ
diff --git a/progs/glsl/texdemo1.c b/progs/glsl/texdemo1.c
index 5b1913a..2076e6a 100644
--- a/progs/glsl/texdemo1.c
+++ b/progs/glsl/texdemo1.c
@@ -400,11 +400,8 @@
 static void
 Init(GLboolean useImageFiles)
 {
-   const char *version = (const char *) glGetString(GL_VERSION);
-
-   if (version[0] != '2' || version[1] != '.') {
-      printf("Warning: this program expects OpenGL 2.0\n");
-      /*exit(1);*/
+   if (!ShadersSupported()) {
+      exit(1);
    }
    printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
 
diff --git a/progs/glsl/trirast.c b/progs/glsl/trirast.c
index 53bd91e..8573426 100644
--- a/progs/glsl/trirast.c
+++ b/progs/glsl/trirast.c
@@ -179,9 +179,9 @@
       "\n"
       "void main() {\n"
       "   vec2 p = gl_FragCoord.xy; \n"
-      "   if (crs(v1 - v0, p - v0) >= 0 && \n"
-      "       crs(v2 - v1, p - v1) >= 0 && \n"
-      "       crs(v0 - v2, p - v2) >= 0) \n"
+      "   if (crs(v1 - v0, p - v0) >= 0.0 && \n"
+      "       crs(v2 - v1, p - v1) >= 0.0 && \n"
+      "       crs(v0 - v2, p - v2) >= 0.0) \n"
       "      gl_FragColor = vec4(1.0); \n"
       "   else \n"
       "      gl_FragColor = vec4(0.5); \n"
diff --git a/progs/glsl/vert-tex.c b/progs/glsl/vert-tex.c
index 4c8bfa5..2b93c78 100644
--- a/progs/glsl/vert-tex.c
+++ b/progs/glsl/vert-tex.c
@@ -40,15 +40,6 @@
 static GLboolean WireFrame = GL_TRUE;
 static GLfloat xRot = -70.0f, yRot = 0.0f, zRot = 0.0f;
 
-
-/* value[0] = tex unit */
-static struct uniform_info Uniforms[] = {
-   { "tex1",  1, GL_SAMPLER_2D, { 0, 0, 0, 0 }, -1 },
-   END_OF_UNIFORMS
-};
-
-
-
 static void
 Idle(void)
 {
diff --git a/progs/objviewer/.gitignore b/progs/objviewer/.gitignore
new file mode 100644
index 0000000..ff094f8
--- /dev/null
+++ b/progs/objviewer/.gitignore
@@ -0,0 +1,8 @@
+extfuncs.h
+objview
+readtex.c
+readtex.h
+shaderutil.c
+shaderutil.h
+trackball.c
+trackball.h
diff --git a/progs/openvg/demos/eglcommon.c b/progs/openvg/demos/eglcommon.c
index bacd568..0316e59 100644
--- a/progs/openvg/demos/eglcommon.c
+++ b/progs/openvg/demos/eglcommon.c
@@ -42,6 +42,7 @@
       EGL_RED_SIZE, 1,
       EGL_GREEN_SIZE, 1,
       EGL_BLUE_SIZE, 1,
+      EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
       EGL_NONE
    };
 
@@ -60,13 +61,13 @@
    scrnum = DefaultScreen( x_dpy );
    root = RootWindow( x_dpy, scrnum );
 
-   if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
+   if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs) ||
+       !num_configs) {
       printf("Error: couldn't get an EGL visual config\n");
       exit(1);
    }
 
    assert(config);
-   assert(num_configs > 0);
 
    if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
       printf("Error: eglGetConfigAttrib() failed\n");
diff --git a/progs/openvg/demos/lion.c b/progs/openvg/demos/lion.c
index 7224fed..adb269b 100644
--- a/progs/openvg/demos/lion.c
+++ b/progs/openvg/demos/lion.c
@@ -67,6 +67,7 @@
       EGL_RED_SIZE, 1,
       EGL_GREEN_SIZE, 1,
       EGL_BLUE_SIZE, 1,
+      EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
       EGL_NONE
    };
 
@@ -85,13 +86,13 @@
    scrnum = DefaultScreen( x_dpy );
    root = RootWindow( x_dpy, scrnum );
 
-   if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
+   if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs) ||
+       !num_configs) {
       printf("Error: couldn't get an EGL visual config\n");
       exit(1);
    }
 
    assert(config);
-   assert(num_configs > 0);
 
    if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
       printf("Error: eglGetConfigAttrib() failed\n");
diff --git a/progs/openvg/trivial/eglcommon.c b/progs/openvg/trivial/eglcommon.c
index bacd568..0316e59 100644
--- a/progs/openvg/trivial/eglcommon.c
+++ b/progs/openvg/trivial/eglcommon.c
@@ -42,6 +42,7 @@
       EGL_RED_SIZE, 1,
       EGL_GREEN_SIZE, 1,
       EGL_BLUE_SIZE, 1,
+      EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
       EGL_NONE
    };
 
@@ -60,13 +61,13 @@
    scrnum = DefaultScreen( x_dpy );
    root = RootWindow( x_dpy, scrnum );
 
-   if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
+   if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs) ||
+       !num_configs) {
       printf("Error: couldn't get an EGL visual config\n");
       exit(1);
    }
 
    assert(config);
-   assert(num_configs > 0);
 
    if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
       printf("Error: eglGetConfigAttrib() failed\n");
diff --git a/progs/osdemos/Makefile b/progs/osdemos/Makefile
index 023ea02..f53515c 100644
--- a/progs/osdemos/Makefile
+++ b/progs/osdemos/Makefile
@@ -5,7 +5,7 @@
 
 INCDIR = $(TOP)/include
 
-OSMESA_LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(OSMESA_LIB) $(APP_LIB_DEPS)
+OSMESA_LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) -l$(OSMESA_LIB) $(APP_LIB_DEPS)
 
 OSMESA16_LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -lOSMesa16 -l$(GLU_LIB) \
 	-l$(GL_LIB) $(APP_LIB_DEPS)
@@ -13,12 +13,6 @@
 OSMESA32_LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -lOSMesa32 -l$(GLU_LIB) \
 	-l$(GL_LIB) $(APP_LIB_DEPS)
 
-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)
-
 PROGS = \
 	osdemo \
 	ostest1
@@ -30,11 +24,6 @@
 .SUFFIXES: .c
 
 
-# make executable from .c file:
-.c: $(LIB_DEP) readtex.o
-	$(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< readtex.o $(LIBS) -o $@
-
-
 ##### TARGETS #####
 
 default: readtex.o $(PROGS)
diff --git a/progs/perf/SConscript b/progs/perf/SConscript
index a5ec9a7..691478a 100644
--- a/progs/perf/SConscript
+++ b/progs/perf/SConscript
@@ -1,11 +1,4 @@
-Import('env')
-
-if not env['GLUT']:
-    Return()
-
-env = env.Clone()
-
-env.Prepend(LIBS = ['$GLUT_LIB'])
+Import('*')
 
 progs = [
       'copytex',
@@ -21,7 +14,7 @@
 ]
 
 for prog in progs:
-    env.Program(
+    progs_env.Program(
         target = prog,
         source = [
             prog + '.c',
diff --git a/progs/perf/genmipmap.c b/progs/perf/genmipmap.c
index 4b7d6ad..20e2fa3 100644
--- a/progs/perf/genmipmap.c
+++ b/progs/perf/genmipmap.c
@@ -27,6 +27,7 @@
  */
 
 #include <string.h>
+#include <stdio.h>
 #include "glmain.h"
 #include "common.h"
 
@@ -53,6 +54,11 @@
 void
 PerfInit(void)
 {
+   if (!PerfExtensionSupported("GL_ARB_framebuffer_object")) {
+      printf("Sorry, this test requires GL_ARB_framebuffer_object\n");
+      exit(1);
+   }
+
    /* setup VBO w/ vertex data */
    glGenBuffersARB(1, &VBO);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
diff --git a/progs/rbug/bin_to_bmp.c b/progs/rbug/bin_to_bmp.c
index cdae348..49a5416 100644
--- a/progs/rbug/bin_to_bmp.c
+++ b/progs/rbug/bin_to_bmp.c
@@ -25,8 +25,10 @@
 #include "pipe/p_compiler.h"
 #include "pipe/p_format.h"
 #include "pipe/p_state.h"
+#include "util/u_format.h"
 #include "util/u_memory.h"
 #include "util/u_debug.h"
+#include "util/u_format.h"
 #include "util/u_network.h"
 #include "util/u_tile.h"
 
@@ -54,10 +56,7 @@
                  unsigned src_stride, enum pipe_format src_format,
                  uint8_t *data, unsigned src_size)
 {
-   struct pipe_format_block src_block;
-
    enum pipe_format dst_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
-   struct pipe_format_block dst_block;
    unsigned dst_stride;
    unsigned dst_size;
    float *rgba;
@@ -65,20 +64,17 @@
    char filename[512];
 
    {
-      pf_get_block(src_format, &src_block);
-      assert(src_stride >= pf_get_stride(&src_block, width));
-      assert(src_size >= pf_get_2d_size(&src_block, src_stride, width));
+      assert(src_stride >= util_format_get_stride(src_format, width));
    }
    {
-      pf_get_block(dst_format, &dst_block);
-      dst_stride = pf_get_stride(&dst_block, width);
-      dst_size = pf_get_2d_size(&dst_block, dst_stride, width);
+      dst_stride = util_format_get_stride(dst_format, width);
+      dst_size = util_format_get_2d_size(dst_format, dst_stride, width);
       rgba = MALLOC(dst_size);
    }
 
    util_snprintf(filename, 512, "%s.bmp", pf_name(src_format));
 
-   if (pf_is_compressed(src_format)) {
+   if (util_format_is_compressed(src_format)) {
       debug_printf("skipping: %s\n", filename);
       return;
    }
diff --git a/progs/rbug/simple_server.c b/progs/rbug/simple_server.c
index 04380c3..3a842c0 100644
--- a/progs/rbug/simple_server.c
+++ b/progs/rbug/simple_server.c
@@ -29,7 +29,7 @@
 
 #include "rbug/rbug.h"
 
-static void wait()
+static void rbug_wait()
 {
    int s = u_socket_listen_on_port(13370);
    int c = u_socket_accept(s);
@@ -57,6 +57,6 @@
 
 int main(int argc, char** argv)
 {
-   wait();
+   rbug_wait();
    return 0;
 }
diff --git a/progs/rbug/tex_dump.c b/progs/rbug/tex_dump.c
index f9e06ee..963f8ee 100644
--- a/progs/rbug/tex_dump.c
+++ b/progs/rbug/tex_dump.c
@@ -27,6 +27,7 @@
 #include "pipe/p_state.h"
 #include "util/u_memory.h"
 #include "util/u_debug.h"
+#include "util/u_format.h"
 #include "util/u_network.h"
 #include "util/u_tile.h"
 #include "rbug/rbug.h"
@@ -49,7 +50,7 @@
    util_snprintf(filename, 512, "%llu_%s_%u.bmp",
                  (unsigned long long)tex, pf_name(info->format), mip);
 
-   if (pf_is_compressed(info->format)) {
+   if (util_format_is_compressed(info->format)) {
       debug_printf("skipping: %s\n", filename);
       return;
    }
diff --git a/progs/redbook/SConscript b/progs/redbook/SConscript
index 242cb66..24d7cff 100644
--- a/progs/redbook/SConscript
+++ b/progs/redbook/SConscript
@@ -1,23 +1,5 @@
 Import('*')
 
-if not env['GLUT']:
-    Return()
-
-env = env.Clone()
-
-env.Prepend(CPPPATH = [
-	'../util',
-])
-
-env.Prepend(LIBS = [
-	util,
-	'$GLUT_LIB'
-])
-
-if env['platform'] == 'windows':
-    env.Append(CPPDEFINES = ['NOMINMAX'])
-    env.Prepend(LIBS = ['winmm'])
-
 progs = [
     'aaindex',
     'aapoly',
@@ -85,7 +67,7 @@
 ]
 
 for prog in progs:
-    env.Program(
+    progs_env.Program(
         target = prog,
         source = prog + '.c',
     )
diff --git a/progs/redbook/aaindex.c b/progs/redbook/aaindex.c
index 7dbc7b4..6011ec4 100644
--- a/progs/redbook/aaindex.c
+++ b/progs/redbook/aaindex.c
@@ -56,7 +56,7 @@
  *  at RAMP1START, and a blue color ramp starting
  *  at RAMP2START. The ramps must be a multiple of 16.
  */
-void init(void)
+static void init(void)
 {
    int i;
 
@@ -76,7 +76,7 @@
 
 /*  Draw 2 diagonal lines to form an X
  */
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT);
 
@@ -101,7 +101,7 @@
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -117,7 +117,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 'r':
diff --git a/progs/redbook/aapoly.c b/progs/redbook/aapoly.c
index 757f0f4..b7b2b27 100644
--- a/progs/redbook/aapoly.c
+++ b/progs/redbook/aapoly.c
@@ -59,7 +59,7 @@
 
 #define NFACE 6
 #define NVERT 8
-void drawCube(GLdouble x0, GLdouble x1, GLdouble y0, GLdouble y1,
+static void drawCube(GLdouble x0, GLdouble x1, GLdouble y0, GLdouble y1,
         GLdouble z0, GLdouble z1)
 {
    static GLfloat v[8][3];
@@ -101,7 +101,7 @@
 /*  Note:  polygons must be drawn from front to back
  *  for proper blending.
  */
-void display(void)
+static void display(void)
 {
    if (polySmooth) {
       glClear (GL_COLOR_BUFFER_BIT);
@@ -126,7 +126,7 @@
    glFlush ();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -137,7 +137,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 't':
diff --git a/progs/redbook/aargb.c b/progs/redbook/aargb.c
index f519841..0021b54 100644
--- a/progs/redbook/aargb.c
+++ b/progs/redbook/aargb.c
@@ -51,7 +51,7 @@
  *  blending, hint, and line width.  Print out implementation
  *  specific info on line width granularity and width.
  */
-void init(void)
+static void init(void)
 {
    GLfloat values[2];
    glGetFloatv (GL_LINE_WIDTH_GRANULARITY, values);
@@ -72,7 +72,7 @@
 
 /* Draw 2 diagonal lines to form an X
  */
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT);
 
@@ -97,7 +97,7 @@
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
@@ -113,7 +113,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 'r':
diff --git a/progs/redbook/accanti.c b/progs/redbook/accanti.c
index 12ca16f..d1b2567 100644
--- a/progs/redbook/accanti.c
+++ b/progs/redbook/accanti.c
@@ -45,7 +45,7 @@
 
 /*  Initialize lighting and other values.
  */
-void myinit(void)
+static void myinit(void)
 {
     GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
     GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
@@ -68,7 +68,7 @@
     glClearAccum(0.0, 0.0, 0.0, 0.0);
 }
 
-void displayObjects(void)
+static void displayObjects(void)
 {
     GLfloat torus_diffuse[] = { 0.7, 0.7, 0.0, 1.0 };
     GLfloat cube_diffuse[] = { 0.0, 0.7, 0.7, 1.0 };
@@ -111,7 +111,7 @@
 
 #define ACSIZE	8
 
-void display(void)
+static void display(void)
 {
     GLint viewport[4];
     int jitter;
@@ -137,7 +137,7 @@
     glFlush();
 }
 
-void myReshape(int w, int h)
+static void myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
     glMatrixMode(GL_PROJECTION);
diff --git a/progs/redbook/accpersp.c b/progs/redbook/accpersp.c
index 46e369a..e172d0a 100644
--- a/progs/redbook/accpersp.c
+++ b/progs/redbook/accpersp.c
@@ -62,7 +62,7 @@
  * probably want to insure that your ModelView matrix has been 
  * initialized to identity before calling accFrustum().
  */
-void accFrustum(GLdouble left, GLdouble right, GLdouble bottom, 
+static void accFrustum(GLdouble left, GLdouble right, GLdouble bottom, 
    GLdouble top, GLdouble nnear, GLdouble ffar, GLdouble pixdx, 
    GLdouble pixdy, GLdouble eyedx, GLdouble eyedy, GLdouble focus)
 {
@@ -99,7 +99,7 @@
  *
  * Note that accPerspective() calls accFrustum().
  */
-void accPerspective(GLdouble fovy, GLdouble aspect, 
+static void accPerspective(GLdouble fovy, GLdouble aspect, 
    GLdouble nnear, GLdouble ffar, GLdouble pixdx, GLdouble pixdy, 
    GLdouble eyedx, GLdouble eyedy, GLdouble focus)
 {
@@ -119,7 +119,7 @@
 
 /*  Initialize lighting and other values.
  */
-void init(void)
+static void init(void)
 {
    GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
@@ -141,7 +141,7 @@
    glClearAccum(0.0, 0.0, 0.0, 0.0);
 }
 
-void displayObjects(void) 
+static void displayObjects(void) 
 {
    GLfloat torus_diffuse[] = { 0.7, 0.7, 0.0, 1.0 };
    GLfloat cube_diffuse[] = { 0.0, 0.7, 0.7, 1.0 };
@@ -185,7 +185,7 @@
 
 #define ACSIZE	8
 
-void display(void)
+static void display(void)
 {
    GLint viewport[4];
    int jitter;
@@ -205,13 +205,13 @@
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/alpha.c b/progs/redbook/alpha.c
index 6eeb45b..b77c65e 100644
--- a/progs/redbook/alpha.c
+++ b/progs/redbook/alpha.c
@@ -80,7 +80,7 @@
    glEnd();
 }
 
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT);
 
@@ -96,7 +96,7 @@
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -108,7 +108,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 't':
diff --git a/progs/redbook/alpha3D.c b/progs/redbook/alpha3D.c
index 6169bd1..494b187 100644
--- a/progs/redbook/alpha3D.c
+++ b/progs/redbook/alpha3D.c
@@ -80,7 +80,7 @@
    glEndList();
 }
 
-void display(void)
+static void display(void)
 {
    GLfloat mat_solid[] = { 0.75, 0.75, 0.0, 1.0 };
    GLfloat mat_zero[] = { 0.0, 0.0, 0.0, 1.0 };
@@ -113,7 +113,7 @@
    glutSwapBuffers();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLint) w, (GLint) h);
    glMatrixMode(GL_PROJECTION);
@@ -128,7 +128,7 @@
    glLoadIdentity();
 }
 
-void animate(void)
+static void animate(void)
 {
    static double t0 = -1.;
    if (solidZ <= MINZ || transparentZ >= MAXZ)
@@ -150,7 +150,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 'a':
diff --git a/progs/redbook/anti.c b/progs/redbook/anti.c
index 9eab0bc..a97a3eb 100644
--- a/progs/redbook/anti.c
+++ b/progs/redbook/anti.c
@@ -49,7 +49,7 @@
  *  blending, hint, and line width.  Print out implementation
  *  specific info on line width granularity and width.
  */
-void myinit(void)
+static void myinit(void)
 {
     GLfloat values[2];
     glGetFloatv (GL_LINE_WIDTH_GRANULARITY, values);
@@ -73,7 +73,7 @@
 
 /*  display() draws an icosahedron with a large alpha value, 1.0.
  */
-void display(void)
+static void display(void)
 {
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glColor4f (1.0, 1.0, 1.0, 1.0);
@@ -81,7 +81,7 @@
     glFlush();
 }
 
-void myReshape(int w, int h)
+static void myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
     glMatrixMode(GL_PROJECTION);
diff --git a/progs/redbook/bezcurve.c b/progs/redbook/bezcurve.c
index 5dee440..60a9c68 100644
--- a/progs/redbook/bezcurve.c
+++ b/progs/redbook/bezcurve.c
@@ -45,7 +45,7 @@
 	{ -4.0, -4.0, 0.0}, { -2.0, 4.0, 0.0}, 
 	{2.0, -4.0, 0.0}, {4.0, 4.0, 0.0}};
 
-void init(void)
+static void init(void)
 {
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
@@ -53,7 +53,7 @@
    glEnable(GL_MAP1_VERTEX_3);
 }
 
-void display(void)
+static void display(void)
 {
    int i;
 
@@ -73,7 +73,7 @@
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -89,7 +89,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/bezmesh.c b/progs/redbook/bezmesh.c
index 55e7e82..1abc748 100644
--- a/progs/redbook/bezmesh.c
+++ b/progs/redbook/bezmesh.c
@@ -68,7 +68,7 @@
         {1.5, 1.5, -1.0}}
 };
 
-void
+static void
 initlights(void)
 {
     GLfloat ambient[] =
@@ -93,7 +93,7 @@
     glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
 }
 
-void
+static void
 display(void)
 {
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -104,7 +104,7 @@
     glFlush();
 }
 
-void
+static void
 myinit(void)
 {
     glClearColor(0.0, 0.0, 0.0, 1.0);
@@ -118,7 +118,7 @@
     initlights();       /* for lighted version only */
 }
 
-void
+static void
 myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
diff --git a/progs/redbook/checker.c b/progs/redbook/checker.c
index 06cbae7..60e6f7b 100644
--- a/progs/redbook/checker.c
+++ b/progs/redbook/checker.c
@@ -50,7 +50,7 @@
 #define	checkImageHeight 64
 GLubyte checkImage[checkImageWidth][checkImageHeight][3];
 
-void makeCheckImage(void)
+static void makeCheckImage(void)
 {
     int i, j, c;
 
@@ -64,7 +64,7 @@
     }
 }
 
-void myinit(void)
+static void myinit(void)
 {
     glClearColor (0.0, 0.0, 0.0, 0.0);
     glEnable(GL_DEPTH_TEST);
@@ -84,7 +84,7 @@
     glShadeModel(GL_FLAT);
 }
 
-void display(void)
+static void display(void)
 {
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glBegin(GL_QUADS);
@@ -101,7 +101,7 @@
     glutSwapBuffers();
 }
 
-void myReshape(int w, int h)
+static void myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
     glMatrixMode(GL_PROJECTION);
diff --git a/progs/redbook/clip.c b/progs/redbook/clip.c
index 90816f2..85c4647 100644
--- a/progs/redbook/clip.c
+++ b/progs/redbook/clip.c
@@ -42,13 +42,13 @@
 #include <GL/glut.h>
 #include <stdlib.h>
 
-void init(void) 
+static void init(void) 
 {
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel (GL_FLAT);
 }
 
-void display(void)
+static void display(void)
 {
    GLdouble eqn[4] = {0.0, 1.0, 0.0, 0.0};
    GLdouble eqn2[4] = {1.0, 0.0, 0.0, 0.0};
@@ -73,7 +73,7 @@
    glFlush ();
 }
 
-void reshape (int w, int h)
+static void reshape (int w, int h)
 {
    glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
    glMatrixMode (GL_PROJECTION);
@@ -83,7 +83,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/colormat.c b/progs/redbook/colormat.c
index 9db4491..d77fcb1 100644
--- a/progs/redbook/colormat.c
+++ b/progs/redbook/colormat.c
@@ -49,7 +49,7 @@
 /*  Initialize material property, light source, lighting model,
  *  and depth buffer.
  */
-void init(void) 
+static void init(void) 
 {
    GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
@@ -68,14 +68,14 @@
    glEnable(GL_COLOR_MATERIAL);
 }
 
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glutSolidSphere(1.0, 20, 16);
    glFlush ();
 }
 
-void reshape (int w, int h)
+static void reshape (int w, int h)
 {
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode (GL_PROJECTION);
@@ -91,7 +91,7 @@
 }
 
 /* ARGSUSED2 */
-void mouse(int button, int state, int x, int y)
+static void mouse(int button, int state, int x, int y)
 {
    switch (button) {
       case GLUT_LEFT_BUTTON:
@@ -127,7 +127,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/cube.c b/progs/redbook/cube.c
index 5ecc628..3c6becb 100644
--- a/progs/redbook/cube.c
+++ b/progs/redbook/cube.c
@@ -44,13 +44,13 @@
 #include <GL/glut.h>
 #include <stdlib.h>
 
-void init(void) 
+static void init(void) 
 {
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel (GL_FLAT);
 }
 
-void display(void)
+static void display(void)
 {
    glClear (GL_COLOR_BUFFER_BIT);
    glColor3f (1.0, 1.0, 1.0);
@@ -62,7 +62,7 @@
    glFlush ();
 }
 
-void reshape (int w, int h)
+static void reshape (int w, int h)
 {
    glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
    glMatrixMode (GL_PROJECTION);
@@ -72,7 +72,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/depthcue.c b/progs/redbook/depthcue.c
index a3e5b74..d4b604b 100644
--- a/progs/redbook/depthcue.c
+++ b/progs/redbook/depthcue.c
@@ -48,7 +48,7 @@
 
 /*  Initialize linear fog for depth cueing.
  */
-void myinit(void)
+static void myinit(void)
 {
     GLfloat fogColor[4] = {0.0, 0.0, 0.0, 1.0};
 
@@ -67,7 +67,7 @@
 
 /*  display() draws an icosahedron.
  */
-void display(void)
+static void display(void)
 {
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glColor3f (1.0, 1.0, 1.0);
@@ -75,7 +75,7 @@
     glFlush();
 }
 
-void myReshape(int w, int h)
+static void myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
     glMatrixMode(GL_PROJECTION);
diff --git a/progs/redbook/dof.c b/progs/redbook/dof.c
index 6673dc2..8558f02 100644
--- a/progs/redbook/dof.c
+++ b/progs/redbook/dof.c
@@ -68,7 +68,7 @@
  *  probably want to insure that your ModelView matrix has been
  *  initialized to identity before calling accFrustum().
  */
-void accFrustum(GLdouble left, GLdouble right, GLdouble bottom,
+static void accFrustum(GLdouble left, GLdouble right, GLdouble bottom,
     GLdouble top, GLdouble nnear, GLdouble ffar, GLdouble pixdx,
     GLdouble pixdy, GLdouble eyedx, GLdouble eyedy, GLdouble focus)
 {
@@ -105,7 +105,7 @@
  *
  *  Note that accPerspective() calls accFrustum().
  */
-void accPerspective(GLdouble fovy, GLdouble aspect,
+static void accPerspective(GLdouble fovy, GLdouble aspect,
     GLdouble nnear, GLdouble ffar, GLdouble pixdx, GLdouble pixdy,
     GLdouble eyedx, GLdouble eyedy, GLdouble focus)
 {
@@ -123,7 +123,7 @@
 	pixdx, pixdy, eyedx, eyedy, focus);
 }
 
-void myinit(void)
+static void myinit(void)
 {
     GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };
     GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
@@ -155,7 +155,7 @@
     glClearAccum(0.0, 0.0, 0.0, 0.0);
 }
 
-void renderTeapot (GLfloat x, GLfloat y, GLfloat z,
+static void renderTeapot (GLfloat x, GLfloat y, GLfloat z,
     GLfloat ambr, GLfloat ambg, GLfloat ambb,
     GLfloat difr, GLfloat difg, GLfloat difb,
     GLfloat specr, GLfloat specg, GLfloat specb, GLfloat shine)
@@ -182,7 +182,7 @@
  *  magnitude of the accPerspective() jitter; in this example, 0.33.
  *  In this example, the teapots are drawn 8 times.  See jitter.h
  */
-void display(void)
+static void display(void)
 {
     int jitter;
     GLint viewport[4];
@@ -214,7 +214,7 @@
     glFlush();
 }
 
-void myReshape(int w, int h)
+static void myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
 }
diff --git a/progs/redbook/double.c b/progs/redbook/double.c
index 3153c70..c4ead22 100644
--- a/progs/redbook/double.c
+++ b/progs/redbook/double.c
@@ -47,7 +47,7 @@
 static GLfloat spin = 0.0;
 static GLdouble t0 = 0.;
 
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT);
    glPushMatrix();
@@ -59,12 +59,12 @@
    glutSwapBuffers();
 }
 
-GLdouble gettime(void)
+static GLdouble gettime(void)
 {
     return (GLdouble)(glutGet(GLUT_ELAPSED_TIME)) / 1000.;
 }
 
-void spinDisplay(void)
+static void spinDisplay(void)
 {
    GLdouble t, dt;
    t = gettime();
@@ -76,13 +76,13 @@
    glutPostRedisplay();
 }
 
-void init(void)
+static void init(void)
 {
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel (GL_FLAT);
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -93,7 +93,7 @@
 }
 
 /* ARGSUSED2 */
-void mouse(int button, int state, int x, int y)
+static void mouse(int button, int state, int x, int y)
 {
    switch (button) {
       case GLUT_LEFT_BUTTON:
diff --git a/progs/redbook/drawf.c b/progs/redbook/drawf.c
index 5bcccb6..6c048be 100644
--- a/progs/redbook/drawf.c
+++ b/progs/redbook/drawf.c
@@ -48,13 +48,13 @@
    0xff, 0x00, 0xff, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
    0xff, 0xc0, 0xff, 0xc0};
 
-void init(void)
+static void init(void)
 {
    glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
    glClearColor (0.0, 0.0, 0.0, 0.0);
 }
 
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f (1.0, 1.0, 1.0);
@@ -65,7 +65,7 @@
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -75,7 +75,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/feedback.c b/progs/redbook/feedback.c
index cc685d5..3c8c8cc 100644
--- a/progs/redbook/feedback.c
+++ b/progs/redbook/feedback.c
@@ -48,7 +48,7 @@
 
 /*  Initialize lighting.
  */
-void init(void)
+static void init(void)
 {
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
@@ -58,7 +58,7 @@
  * be clipped.  If in feedback mode, a passthrough token 
  * is issued between the each primitive.
  */
-void drawGeometry (GLenum mode)
+static void drawGeometry (GLenum mode)
 {
    glBegin (GL_LINE_STRIP);
    glNormal3f (0.0, 0.0, 1.0);
@@ -80,8 +80,8 @@
 }
 
 /* Write contents of one vertex to stdout.	*/
-void print3DcolorVertex (GLint size, GLint *count, 
-                         GLfloat *buffer)
+static void print3DcolorVertex (GLint size, GLint *count, 
+                                GLfloat *buffer)
 {
    int i;
 
@@ -94,7 +94,7 @@
 }
 
 /*  Write contents of entire buffer.  (Parse tokens!)	*/
-void printBuffer(GLint size, GLfloat *buffer)
+static void printBuffer(GLint size, GLfloat *buffer)
 {
    GLint count;
    GLfloat token;
@@ -124,7 +124,7 @@
    }
 }
 
-void display(void)
+static void display(void)
 {
    GLfloat feedBuffer[1024];
    GLint size;
@@ -148,7 +148,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/fog.c b/progs/redbook/fog.c
index 14c7700..4f4b8e3 100644
--- a/progs/redbook/fog.c
+++ b/progs/redbook/fog.c
@@ -52,7 +52,7 @@
 
 GLint fogMode;
 
-void
+static void
 selectFog(int mode)
 {
     switch(mode) {
@@ -73,7 +73,7 @@
 /*  Initialize z-buffer, projection matrix, light source,
  *  and lighting model.  Do not specify a material property here.
  */
-void
+static void
 myinit(void)
 {
     GLfloat position[] =
@@ -106,7 +106,7 @@
     }
 }
 
-void
+static void
 renderRedTeapot(GLfloat x, GLfloat y, GLfloat z)
 {
     float mat[4];
@@ -133,7 +133,7 @@
 
 /*  display() draws 5 teapots at different z positions.
  */
-void
+static void
 display(void)
 {
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -145,7 +145,7 @@
     glFlush();
 }
 
-void
+static void
 myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
diff --git a/progs/redbook/fogindex.c b/progs/redbook/fogindex.c
index b8bb691..6b5aa35 100644
--- a/progs/redbook/fogindex.c
+++ b/progs/redbook/fogindex.c
@@ -53,7 +53,7 @@
 #define NUM_COLORS 32
 #define RAMPSTART 16
 
-void
+static void
 myinit(void)
 {
   int i;
@@ -77,7 +77,7 @@
 
 /*  display() renders 3 cones at different z positions.
  */
-void
+static void
 display(void)
 {
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -104,7 +104,7 @@
   glFlush();
 }
 
-void
+static void
 myReshape(int w, int h)
 {
   glViewport(0, 0, w, h);
diff --git a/progs/redbook/font.c b/progs/redbook/font.c
index 2d92e9b..c7a1035 100644
--- a/progs/redbook/font.c
+++ b/progs/redbook/font.c
@@ -80,7 +80,7 @@
 
 GLuint fontOffset;
 
-void makeRasterFont(void)
+static void makeRasterFont(void)
 {
    GLuint i, j;
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -96,13 +96,13 @@
    glEndList();
 }
 
-void init(void)
+static void init(void)
 {
    glShadeModel (GL_FLAT);
    makeRasterFont();
 }
 
-void printString(char *s)
+static void printString(char *s)
 {
    glPushAttrib (GL_LIST_BIT);
    glListBase(fontOffset);
@@ -115,7 +115,7 @@
  * to call makeRasterFont() before you start making 
  * calls to printString().
  */
-void display(void)
+static void display(void)
 {
    GLfloat white[3] = { 1.0, 1.0, 1.0 };
 
@@ -129,7 +129,7 @@
    glFlush ();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -139,7 +139,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/hello.c b/progs/redbook/hello.c
index fb3dae1..84183b2 100644
--- a/progs/redbook/hello.c
+++ b/progs/redbook/hello.c
@@ -42,7 +42,7 @@
 #include <stdlib.h>
 #include <GL/glut.h>
 
-void display(void)
+static void display(void)
 {
 /* clear all pixels  */
    glClear (GL_COLOR_BUFFER_BIT);
@@ -64,7 +64,7 @@
    glFlush ();
 }
 
-void init (void)
+static void init (void)
 {
 /* select clearing color 	*/
    glClearColor (0.0, 0.0, 0.0, 0.0);
diff --git a/progs/redbook/image.c b/progs/redbook/image.c
index dc1a724..fa3b46f 100644
--- a/progs/redbook/image.c
+++ b/progs/redbook/image.c
@@ -58,7 +58,7 @@
 static GLdouble zoomFactor = 1.0;
 static GLint height;
 
-void makeCheckImage(void)
+static void makeCheckImage(void)
 {
    int i, j, c;
     
@@ -72,7 +72,7 @@
    }
 }
 
-void init(void)
+static void init(void)
 {    
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
@@ -80,7 +80,7 @@
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 }
 
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT);
    glRasterPos2i(0, 0);
@@ -89,7 +89,7 @@
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    height = (GLint) h;
@@ -100,7 +100,7 @@
    glLoadIdentity();
 }
 
-void motion(int x, int y)
+static void motion(int x, int y)
 {
    static GLint screeny;
    
@@ -113,7 +113,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 'r':
diff --git a/progs/redbook/light.c b/progs/redbook/light.c
index 0eed85e..9431dce 100644
--- a/progs/redbook/light.c
+++ b/progs/redbook/light.c
@@ -47,7 +47,7 @@
 /*  Initialize material property, light source, lighting model,
  *  and depth buffer.
  */
-void init(void) 
+static void init(void) 
 {
    GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat mat_shininess[] = { 50.0 };
@@ -65,14 +65,14 @@
    glEnable(GL_DEPTH_TEST);
 }
 
-void display(void)
+static void display(void)
 {
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glutSolidSphere (1.0, 20, 16);
    glFlush ();
 }
 
-void reshape (int w, int h)
+static void reshape (int w, int h)
 {
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode (GL_PROJECTION);
@@ -88,7 +88,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/lines.c b/progs/redbook/lines.c
index b34d4c4..9f12da9 100644
--- a/progs/redbook/lines.c
+++ b/progs/redbook/lines.c
@@ -46,13 +46,13 @@
 #define drawOneLine(x1,y1,x2,y2)  glBegin(GL_LINES);  \
    glVertex2f ((x1),(y1)); glVertex2f ((x2),(y2)); glEnd();
 
-void init(void) 
+static void init(void) 
 {
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel (GL_FLAT);
 }
 
-void display(void)
+static void display(void)
 {
    int i;
 
@@ -104,7 +104,7 @@
    glFlush ();
 }
 
-void reshape (int w, int h)
+static void reshape (int w, int h)
 {
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode (GL_PROJECTION);
@@ -113,7 +113,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/list.c b/progs/redbook/list.c
index 3b4f44b..5dea26f 100644
--- a/progs/redbook/list.c
+++ b/progs/redbook/list.c
@@ -69,7 +69,7 @@
    glEnd ();
 }
 
-void display(void)
+static void display(void)
 {
    GLuint i;
 
@@ -82,7 +82,7 @@
    glFlush ();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
@@ -97,7 +97,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/material.c b/progs/redbook/material.c
index f9a4fc5..5edddd9 100644
--- a/progs/redbook/material.c
+++ b/progs/redbook/material.c
@@ -49,7 +49,7 @@
 /*  Initialize z-buffer, projection matrix, light source,
  *  and lighting model.  Do not specify a material property here.
  */
-void myinit(void)
+static void myinit(void)
 {
     GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };
     GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
@@ -87,7 +87,7 @@
  *  glTranslatef() is used to move spheres to their appropriate locations.
  */
 
-void display(void)
+static void display(void)
 {
     GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };
     GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 };
@@ -260,7 +260,7 @@
     glFlush();
 }
 
-void myReshape(int w, int h)
+static void myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
     glMatrixMode(GL_PROJECTION);
diff --git a/progs/redbook/mipmap.c b/progs/redbook/mipmap.c
index d32dd72..dadde05 100644
--- a/progs/redbook/mipmap.c
+++ b/progs/redbook/mipmap.c
@@ -54,7 +54,7 @@
 GLubyte mipmapImage2[2][2][3];
 GLubyte mipmapImage1[1][1][3];
 
-void makeImages(void)
+static void makeImages(void)
 {
     int i, j;
 
@@ -98,7 +98,7 @@
     mipmapImage1[0][0][2] = 255;
 }
 
-void myinit(void)
+static void myinit(void)
 {
     glEnable(GL_DEPTH_TEST);
     glDepthFunc(GL_LESS);
@@ -128,7 +128,7 @@
     glEnable(GL_TEXTURE_2D);
 }
 
-void display(void)
+static void display(void)
 {
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glBegin(GL_QUADS);
@@ -140,7 +140,7 @@
     glFlush();
 }
 
-void myReshape(int w, int h)
+static void myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
     glMatrixMode(GL_PROJECTION);
diff --git a/progs/redbook/model.c b/progs/redbook/model.c
index 8411ef3..f7c92f4 100644
--- a/progs/redbook/model.c
+++ b/progs/redbook/model.c
@@ -42,13 +42,13 @@
 #include <GL/glut.h>
 #include <stdlib.h>
 
-void init(void) 
+static void init(void) 
 {
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel (GL_FLAT);
 }
 
-void draw_triangle(void)
+static void draw_triangle(void)
 {
    glBegin (GL_LINE_LOOP);
    glVertex2f(0.0, 25.0);
@@ -57,7 +57,7 @@
    glEnd();
 }
 
-void display(void)
+static void display(void)
 {
    glClear (GL_COLOR_BUFFER_BIT);
    glColor3f (1.0, 1.0, 1.0);
@@ -86,7 +86,7 @@
    glFlush ();
 }
 
-void reshape (int w, int h)
+static void reshape (int w, int h)
 {
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode (GL_PROJECTION);
@@ -101,7 +101,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/movelight.c b/progs/redbook/movelight.c
index a108cad..93758a2 100644
--- a/progs/redbook/movelight.c
+++ b/progs/redbook/movelight.c
@@ -58,7 +58,7 @@
 /*  Initialize material property, light source, lighting model,
  *  and depth buffer.
  */
-void init(void) 
+static void init(void) 
 {
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel (GL_SMOOTH);
@@ -72,7 +72,7 @@
  *  light at a new position in world coordinates.  The cube
  *  represents the position of the light.
  */
-void display(void)
+static void display(void)
 {
    GLfloat position[] = { 0.0, 0.0, 1.5, 1.0 };
 
@@ -96,7 +96,7 @@
    glFlush ();
 }
 
-void reshape (int w, int h)
+static void reshape (int w, int h)
 {
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode (GL_PROJECTION);
@@ -107,7 +107,7 @@
 }
 
 /* ARGSUSED2 */
-void mouse(int button, int state, int x, int y)
+static void mouse(int button, int state, int x, int y)
 {
    switch (button) {
       case GLUT_LEFT_BUTTON:
@@ -122,7 +122,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/nurbs.c b/progs/redbook/nurbs.c
index a7c6f0c..fe03ce6 100644
--- a/progs/redbook/nurbs.c
+++ b/progs/redbook/nurbs.c
@@ -89,7 +89,7 @@
 /*  Initialize material property, light source, lighting model,
  *  and depth buffer.
  */
-void myinit(void)
+static void myinit(void)
 {
     GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
     GLfloat mat_diffuse[] = { 1.0, 0.2, 1.0, 1.0 };
@@ -122,7 +122,7 @@
     gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
 }
 
-void display(void)
+static void display(void)
 {
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
@@ -147,7 +147,7 @@
     glFlush();
 }
 
-void myReshape(int w, int h)
+static void myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
     glMatrixMode(GL_PROJECTION);
diff --git a/progs/redbook/pickdepth.c b/progs/redbook/pickdepth.c
index ad5bdc8..91d44a3 100644
--- a/progs/redbook/pickdepth.c
+++ b/progs/redbook/pickdepth.c
@@ -51,7 +51,7 @@
 #include <stdio.h>
 #include <GL/glut.h>
 
-void
+static void
 myinit(void)
 {
   glClearColor(0.0, 0.0, 0.0, 0.0);
@@ -65,7 +65,7 @@
  *  each rectangle is given the same name.  Note that
  *  each rectangle is drawn with a different z value.
  */
-void
+static void
 drawRects(GLenum mode)
 {
   if (mode == GL_SELECT)
@@ -100,7 +100,7 @@
 /*  processHits() prints out the contents of the
  *  selection array.
  */
-void
+static void
 processHits(GLint hits, GLuint buffer[])
 {
   GLint i;
@@ -131,7 +131,7 @@
  */
 #define BUFSIZE 512
 
-void
+static void
 pickRects(int button, int state, int x, int y)
 {
   GLuint selectBuf[BUFSIZE];
@@ -164,7 +164,7 @@
   processHits(hits, selectBuf);
 }
 
-void
+static void
 display(void)
 {
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -172,7 +172,7 @@
   glutSwapBuffers();
 }
 
-void
+static void
 myReshape(int w, int h)
 {
   glViewport(0, 0, w, h);
diff --git a/progs/redbook/picksquare.c b/progs/redbook/picksquare.c
index 636edc9..cc092db 100644
--- a/progs/redbook/picksquare.c
+++ b/progs/redbook/picksquare.c
@@ -49,7 +49,7 @@
 int board[3][3];   /*  amount of color for each square	*/
 
 /*  Clear color value for every square on the board   */
-void init(void)
+static void init(void)
 {
    int i, j;
    for (i = 0; i < 3; i++) 
@@ -64,7 +64,7 @@
  *  square is determined by its position on the grid, and 
  *  the value in the board[][] array.
  */
-void drawSquares(GLenum mode)
+static void drawSquares(GLenum mode)
 {
    GLuint i, j;
    for (i = 0; i < 3; i++) {
@@ -85,7 +85,7 @@
 /*  processHits prints out the contents of the 
  *  selection array.
  */
-void processHits (GLint hits, GLuint buffer[])
+static void processHits (GLint hits, GLuint buffer[])
 {
    GLint i;
    GLuint j, ii = 0, jj = 0, names, *ptr;
@@ -117,7 +117,7 @@
  */
 #define BUFSIZE 512
 
-void pickSquares(int button, int state, int x, int y)
+static void pickSquares(int button, int state, int x, int y)
 {
    GLuint selectBuf[BUFSIZE];
    GLint hits;
@@ -152,14 +152,14 @@
    glutPostRedisplay();
 } 
 
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT);
    drawSquares (GL_RENDER);
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
@@ -170,7 +170,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/plane.c b/progs/redbook/plane.c
index dc17f7b..2c2e2d2 100644
--- a/progs/redbook/plane.c
+++ b/progs/redbook/plane.c
@@ -47,7 +47,7 @@
 
 /*  Initialize material property, light source, and lighting model.
  */
-void myinit(void)
+static void myinit(void)
 {
     GLfloat mat_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
 /*   mat_specular and mat_shininess are NOT default values	*/
@@ -75,7 +75,7 @@
     glEnable(GL_DEPTH_TEST);
 }
 
-void drawPlane(void)
+static void drawPlane(void)
 {
     glBegin (GL_QUADS);
     glNormal3f (0.0, 0.0, 1.0);
@@ -104,7 +104,7 @@
     glEnd();
 }
 
-void display (void)
+static void display (void)
 {
     GLfloat infinite_light[] = { 1.0, 1.0, 1.0, 0.0 };
     GLfloat local_light[] = { 1.0, 1.0, 1.0, 1.0 };
@@ -125,7 +125,7 @@
     glFlush ();
 }
 
-void myReshape(int w, int h)
+static void myReshape(int w, int h)
 {
     glViewport (0, 0, w, h);
     glMatrixMode (GL_PROJECTION);
diff --git a/progs/redbook/planet.c b/progs/redbook/planet.c
index e13672d..cc428b4 100644
--- a/progs/redbook/planet.c
+++ b/progs/redbook/planet.c
@@ -47,13 +47,13 @@
 
 static int year = 0, day = 0;
 
-void init(void) 
+static void init(void) 
 {
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel (GL_FLAT);
 }
 
-void display(void)
+static void display(void)
 {
    glClear (GL_COLOR_BUFFER_BIT);
    glColor3f (1.0, 1.0, 1.0);
@@ -68,7 +68,7 @@
    glutSwapBuffers();
 }
 
-void reshape (int w, int h)
+static void reshape (int w, int h)
 {
    glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
    glMatrixMode (GL_PROJECTION);
@@ -80,7 +80,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard (unsigned char key, int x, int y)
+static void keyboard (unsigned char key, int x, int y)
 {
    switch (key) {
       case 'd':
diff --git a/progs/redbook/polyoff.c b/progs/redbook/polyoff.c
index de34b2e..0e0ce86 100644
--- a/progs/redbook/polyoff.c
+++ b/progs/redbook/polyoff.c
@@ -60,7 +60,7 @@
 /*  display() draws two spheres, one with a gray, diffuse material,
  *  the other sphere with a magenta material with a specular highlight.
  */
-void display (void)
+static void display (void)
 {
     GLfloat gray[] = { 0.8, 0.8, 0.8, 1.0 };
     GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
@@ -108,7 +108,7 @@
  *  create display list with sphere
  *  initialize lighting and depth buffer
  */
-void gfxinit (void)
+static void gfxinit (void)
 {
     GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
     GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
@@ -134,7 +134,7 @@
 }
 
 /*  call when window is resized  */
-void reshape(int width, int height)
+static void reshape(int width, int height)
 {
     glViewport (0, 0, width, height);
     glMatrixMode (GL_PROJECTION);
@@ -176,7 +176,7 @@
 
 /*  call when mouse button is pressed  */
 /* ARGSUSED2 */
-void mouse(int button, int state, int x, int y) {
+static void mouse(int button, int state, int x, int y) {
     switch (button) {
 	case GLUT_LEFT_BUTTON:
 	    switch (state) {
@@ -213,7 +213,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard (unsigned char key, int x, int y)
+static void keyboard (unsigned char key, int x, int y)
 {
    switch (key) {
       case 't':
@@ -268,20 +268,7 @@
    fflush(stdout);
 }
 
-static void
-key(unsigned char k, int x, int y)
-{
-  switch (k) {
-  case 27:  /* Escape */
-    exit(0);
-    break;
-  default:
-    return;
-  }
-  glutPostRedisplay();
-}
-
-GLenum Args(int argc, char **argv)
+static GLenum Args(int argc, char **argv)
 {
     GLint i;
 
diff --git a/progs/redbook/polys.c b/progs/redbook/polys.c
index 409abd1..eeffe23 100644
--- a/progs/redbook/polys.c
+++ b/progs/redbook/polys.c
@@ -44,7 +44,7 @@
 #include <stdlib.h>
 #include <GL/glut.h>
 
-void display(void)
+static void display(void)
 {
     GLubyte fly[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x03, 0x80, 0x01, 0xC0, 0x06, 0xC0, 0x03, 0x60, 0x04, 0x60, 0x06, 0x20,
@@ -89,7 +89,7 @@
     glFlush ();
 }
 
-void myinit (void)
+static void myinit (void)
 {
 /*  clear background to black	*/
     glClearColor (0.0, 0.0, 0.0, 0.0);
diff --git a/progs/redbook/quadric.c b/progs/redbook/quadric.c
index 4e46c85..1cbd395 100644
--- a/progs/redbook/quadric.c
+++ b/progs/redbook/quadric.c
@@ -54,7 +54,7 @@
 
 GLuint startList;
 
-void CALLBACK errorCallback(GLenum errorCode)
+static void CALLBACK errorCallback(GLenum errorCode)
 {
    const GLubyte *estring;
 
@@ -63,7 +63,7 @@
    exit(0);
 }
 
-void init(void) 
+static void init(void) 
 {
    GLUquadricObj *qobj;
    GLfloat mat_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
@@ -116,9 +116,11 @@
    glNewList(startList+3, GL_COMPILE);
       gluPartialDisk(qobj, 0.0, 1.0, 20, 4, 0.0, 225.0);
    glEndList();
+
+   gluDeleteQuadric(qobj);
 }
 
-void display(void)
+static void display(void)
 {
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
@@ -148,7 +150,7 @@
    glFlush();
 }
 
-void reshape (int w, int h)
+static void reshape (int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -164,7 +166,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/robot.c b/progs/redbook/robot.c
index 94e20ac..c90b72a 100644
--- a/progs/redbook/robot.c
+++ b/progs/redbook/robot.c
@@ -47,13 +47,13 @@
 
 static int shoulder = 0, elbow = 0;
 
-void init(void) 
+static void init(void) 
 {
   glClearColor (0.0, 0.0, 0.0, 0.0);
   glShadeModel (GL_FLAT);
 }
 
-void display(void)
+static void display(void)
 {
    glClear (GL_COLOR_BUFFER_BIT);
    glPushMatrix();
@@ -77,7 +77,7 @@
    glutSwapBuffers();
 }
 
-void reshape (int w, int h)
+static void reshape (int w, int h)
 {
    glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
    glMatrixMode (GL_PROJECTION);
@@ -89,7 +89,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard (unsigned char key, int x, int y)
+static void keyboard (unsigned char key, int x, int y)
 {
    switch (key) {
       case 's':
diff --git a/progs/redbook/sccolorlight.c b/progs/redbook/sccolorlight.c
index 0ea750e..d9e0a25 100644
--- a/progs/redbook/sccolorlight.c
+++ b/progs/redbook/sccolorlight.c
@@ -49,7 +49,7 @@
 
 /*  Initialize material property and light source.
  */
-void myinit(void)
+static void myinit(void)
 {
     GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
     GLfloat light_diffuse[] = { 1.0, 0.0, 1.0, 1.0 };
@@ -68,7 +68,7 @@
     glEnable(GL_DEPTH_TEST);
 }
 
-void display(void)
+static void display(void)
 {
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glPushMatrix ();
@@ -95,7 +95,7 @@
     glFlush();
 }
 
-void myReshape(int w, int h)
+static void myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
     glMatrixMode(GL_PROJECTION);
diff --git a/progs/redbook/scene.c b/progs/redbook/scene.c
index c3abc72..6f336a8 100644
--- a/progs/redbook/scene.c
+++ b/progs/redbook/scene.c
@@ -48,7 +48,7 @@
 
 /*  Initialize material property and light source.
  */
-void myinit (void)
+static void myinit (void)
 {
     GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
     GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
@@ -67,7 +67,7 @@
     glEnable(GL_DEPTH_TEST);
 }
 
-void display (void)
+static void display (void)
 {
     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
@@ -95,7 +95,7 @@
     glFlush ();
 }
 
-void myReshape(int w, int h)
+static void myReshape(int w, int h)
 {
     glViewport (0, 0, w, h);
     glMatrixMode (GL_PROJECTION);
diff --git a/progs/redbook/scenebamb.c b/progs/redbook/scenebamb.c
index e7264d2..ea605f8 100644
--- a/progs/redbook/scenebamb.c
+++ b/progs/redbook/scenebamb.c
@@ -47,7 +47,7 @@
 
 /*  Initialize light source and lighting.
  */
-void myinit(void)
+static void myinit(void)
 {
     GLfloat light_ambient[] = { 0.0, 0.0, 1.0, 1.0 };
     GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
@@ -66,7 +66,7 @@
     glEnable(GL_DEPTH_TEST);
 }
 
-void display(void)
+static void display(void)
 {
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
@@ -94,7 +94,7 @@
     glFlush();
 }
 
-void myReshape(int w, int h)
+static void myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
     glMatrixMode(GL_PROJECTION);
diff --git a/progs/redbook/sceneflat.c b/progs/redbook/sceneflat.c
index 10891fb..1b27733 100644
--- a/progs/redbook/sceneflat.c
+++ b/progs/redbook/sceneflat.c
@@ -46,7 +46,7 @@
 
 /*  Initialize light source and shading model (GL_FLAT).
  */
-void myinit(void)
+static void myinit(void)
 {
     GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
     GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
@@ -66,7 +66,7 @@
     glShadeModel (GL_FLAT);
 }
 
-void display(void)
+static void display(void)
 {
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
@@ -94,7 +94,7 @@
     glFlush();
 }
 
-void myReshape(int w, int h)
+static void myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
     glMatrixMode(GL_PROJECTION);
diff --git a/progs/redbook/select.c b/progs/redbook/select.c
index 928373b..537d519 100644
--- a/progs/redbook/select.c
+++ b/progs/redbook/select.c
@@ -57,7 +57,7 @@
 /* draw a triangle with vertices at (x1, y1), (x2, y2) 
  * and (x3, y3) at z units away from the origin.
  */
-void drawTriangle (GLfloat x1, GLfloat y1, GLfloat x2, 
+static void drawTriangle (GLfloat x1, GLfloat y1, GLfloat x2, 
     GLfloat y2, GLfloat x3, GLfloat y3, GLfloat z)
 {
    glBegin (GL_TRIANGLES);
@@ -68,8 +68,8 @@
 }
 
 /* draw a rectangular box with these outer x, y, and z values */
-void drawViewVolume (GLfloat x1, GLfloat x2, GLfloat y1, 
-                     GLfloat y2, GLfloat z1, GLfloat z2)
+static void drawViewVolume (GLfloat x1, GLfloat x2, GLfloat y1, 
+                            GLfloat y2, GLfloat z1, GLfloat z2)
 {
    glColor3f (1.0, 1.0, 1.0);
    glBegin (GL_LINE_LOOP);
@@ -101,7 +101,7 @@
 /* drawScene draws 4 triangles and a wire frame
  * which represents the viewing volume.
  */
-void drawScene (void)
+static void drawScene (void)
 {
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
@@ -122,7 +122,7 @@
 
 /* processHits prints out the contents of the selection array
  */
-void processHits (GLint hits, GLuint buffer[])
+static void processHits (GLint hits, GLuint buffer[])
 {
    GLint i;
    GLuint j, names, *ptr;
@@ -150,7 +150,7 @@
  */
 #define BUFSIZE 512
 
-void selectObjects(void)
+static void selectObjects(void)
 {
    GLuint selectBuf[BUFSIZE];
    GLint hits;
@@ -181,13 +181,13 @@
    processHits (hits, selectBuf);
 } 
 
-void init (void) 
+static void init (void) 
 {
    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_FLAT);
 }
 
-void display(void)
+static void display(void)
 {
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -197,7 +197,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/smooth.c b/progs/redbook/smooth.c
index 9d22fc9..874033d 100644
--- a/progs/redbook/smooth.c
+++ b/progs/redbook/smooth.c
@@ -43,13 +43,13 @@
 #include <GL/glut.h>
 #include <stdlib.h>
 
-void init(void) 
+static void init(void) 
 {
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel (GL_SMOOTH);
 }
 
-void triangle(void)
+static void triangle(void)
 {
    glBegin (GL_TRIANGLES);
    glColor3f (1.0, 0.0, 0.0);
@@ -61,14 +61,14 @@
    glEnd();
 }
 
-void display(void)
+static void display(void)
 {
    glClear (GL_COLOR_BUFFER_BIT);
    triangle ();
    glFlush ();
 }
 
-void reshape (int w, int h)
+static void reshape (int w, int h)
 {
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode (GL_PROJECTION);
@@ -81,7 +81,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/stencil.c b/progs/redbook/stencil.c
index b33e40a..5325abf 100644
--- a/progs/redbook/stencil.c
+++ b/progs/redbook/stencil.c
@@ -64,7 +64,7 @@
 #define YELLOWMAT   1
 #define BLUEMAT 2
 
-void myinit (void)
+static void myinit (void)
 {
     GLfloat yellow_diffuse[] = { 0.7, 0.7, 0.0, 1.0 };
     GLfloat yellow_specular[] = { 1.0, 1.0, 1.0, 1.0 };
@@ -101,7 +101,7 @@
 /*  Draw a sphere in a diamond-shaped section in the
  *  middle of a window with 2 tori.
  */
-void display(void)
+static void display(void)
 {
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
@@ -132,7 +132,7 @@
 /*  Whenever the window is reshaped, redefine the
  *  coordinate system and redraw the stencil area.
  */
-void myReshape(int w, int h)
+static void myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
 
diff --git a/progs/redbook/stroke.c b/progs/redbook/stroke.c
index 19b0391..68b639a 100644
--- a/progs/redbook/stroke.c
+++ b/progs/redbook/stroke.c
@@ -87,7 +87,7 @@
 /*  drawLetter() interprets the instructions from the array
  *  for that letter and renders the letter with line segments.
  */
-void drawLetter(CP *l)
+static void drawLetter(CP *l)
 {
     glBegin(GL_LINE_STRIP);
     for (;;) {
@@ -111,7 +111,7 @@
 }
 
 /*  Create a display list for each of 6 characters	*/
-void myinit (void)
+static void myinit (void)
 {
     GLuint base;
 
@@ -130,13 +130,13 @@
 char *test1 = "A SPARE SERAPE APPEARS AS";
 char *test2 = "APES PREPARE RARE PEPPERS";
 
-void printStrokedString(char *s)
+static void printStrokedString(char *s)
 {
     GLsizei len = (GLsizei) strlen(s);
     glCallLists(len, GL_BYTE, (GLbyte *)s);
 }
 
-void display(void)
+static void display(void)
 {
     glClear(GL_COLOR_BUFFER_BIT);
     glColor3f(1.0, 1.0, 1.0);
diff --git a/progs/redbook/surface.c b/progs/redbook/surface.c
index e33ce14..f0c5ab0 100644
--- a/progs/redbook/surface.c
+++ b/progs/redbook/surface.c
@@ -53,7 +53,7 @@
  *  Initializes the control points of the surface to a small hill.
  *  The control points range from -3 to +3 in x, y, and z
  */
-void init_surface(void)
+static void init_surface(void)
 {
     int u, v;
     for (u = 0; u < 4; u++) {
@@ -71,7 +71,7 @@
 
 /*  Initialize material property and depth buffer.
  */
-void myinit(void)
+static void myinit(void)
 {
     GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 };
     GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
@@ -100,7 +100,7 @@
     glTranslatef (0.0, 0.0, -5.0);
 }
 
-void display(void)
+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;
@@ -140,7 +140,7 @@
     glutSwapBuffers();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
     glViewport(0, 0, w, h);
     glMatrixMode(GL_PROJECTION);
@@ -150,7 +150,7 @@
     glMatrixMode(GL_MODELVIEW);
 }
 
-void
+static void
 menu(int value)
 {
     switch (value) {
@@ -171,7 +171,7 @@
 int down = 0, lastx;
 
 /* ARGSUSED1 */
-void
+static void
 motion(int x, int y)
 {
     if (down) {
@@ -182,7 +182,7 @@
 }
 
 /* ARGSUSED3 */
-void
+static void
 mouse(int button, int state, int x, int y)
 {
     if (button == GLUT_LEFT_BUTTON) {
diff --git a/progs/redbook/teaambient.c b/progs/redbook/teaambient.c
index 53b5111..20ff1a4 100644
--- a/progs/redbook/teaambient.c
+++ b/progs/redbook/teaambient.c
@@ -47,7 +47,7 @@
 
 /*  Initialize light source and lighting model.
  */
-void
+static void
 myinit(void)
 {
     GLfloat light_ambient[] =
@@ -78,7 +78,7 @@
     glEnable(GL_DEPTH_TEST);
 }
 
-void
+static void
 display(void)
 {
     GLfloat low_ambient[] =
@@ -114,7 +114,7 @@
     glFlush();
 }
 
-void
+static void
 myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
diff --git a/progs/redbook/teapots.c b/progs/redbook/teapots.c
index fb7aed3..102c18a 100644
--- a/progs/redbook/teapots.c
+++ b/progs/redbook/teapots.c
@@ -49,7 +49,7 @@
  * Initialize depth buffer, projection matrix, light source, and lighting
  * model.  Do not specify a material property here.
  */
-void
+static void
 myinit(void)
 {
   GLfloat ambient[] =
@@ -83,7 +83,7 @@
  * Move object into position.  Use 3rd through 12th parameters to specify the
  * material property.  Draw a teapot.
  */
-void
+static void
 renderTeapot(GLfloat x, GLfloat y,
   GLfloat ambr, GLfloat ambg, GLfloat ambb,
   GLfloat difr, GLfloat difg, GLfloat difb,
@@ -117,7 +117,7 @@
  *  3rd column:  black, cyan, green, red, white, yellow plastic
  *  4th column:  black, cyan, green, red, white, yellow rubber
  */
-void
+static void
 display(void)
 {
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -173,7 +173,7 @@
   glFlush();
 }
 
-void
+static void
 myReshape(int w, int h)
 {
   glViewport(0, 0, w, h);
diff --git a/progs/redbook/tess.c b/progs/redbook/tess.c
index 238a469..0bf8a8e 100644
--- a/progs/redbook/tess.c
+++ b/progs/redbook/tess.c
@@ -61,7 +61,7 @@
 
 GLuint startList;
 
-void display (void) {
+static void display (void) {
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0, 1.0, 1.0);
    glCallList(startList);
@@ -69,12 +69,12 @@
    glFlush();
 }
 
-void CALLBACK beginCallback(GLenum which)
+static void CALLBACK beginCallback(GLenum which)
 {
    glBegin(which);
 }
 
-void CALLBACK errorCallback(GLenum errorCode)
+static void CALLBACK errorCallback(GLenum errorCode)
 {
    const GLubyte *estring;
 
@@ -83,12 +83,12 @@
    exit(0);
 }
 
-void CALLBACK endCallback(void)
+static void CALLBACK endCallback(void)
 {
    glEnd();
 }
 
-void CALLBACK vertexCallback(GLvoid *vertex)
+static void CALLBACK vertexCallback(GLvoid *vertex)
 {
    const GLdouble *pointer;
 
@@ -102,7 +102,7 @@
  *  but weight[4] may be used to average color, normal, or texture
  *  coordinate data.  In this program, color is weighted.
  */
-void CALLBACK combineCallback(GLdouble coords[3],
+static void CALLBACK combineCallback(GLdouble coords[3],
                      GLdouble *vertex_data[4],
                      GLfloat weight[4], GLdouble **dataOut )
 {
@@ -122,7 +122,7 @@
    *dataOut = vertex;
 }
 
-void init (void)
+static void init (void)
 {
    GLUtesselator *tobj;
    GLdouble rect[4][3] = {{50.0, 50.0, 0.0},
@@ -199,7 +199,7 @@
    gluDeleteTess(tobj);
 }
 
-void reshape (int w, int h)
+static void reshape (int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -208,7 +208,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/tesswind.c b/progs/redbook/tesswind.c
index 7d00c9f..4729880 100644
--- a/progs/redbook/tesswind.c
+++ b/progs/redbook/tesswind.c
@@ -61,7 +61,7 @@
 /*  Make four display lists, 
  *  each with a different tessellated object. 
  */
-void makeNewLists (void) {
+static void makeNewLists (void) {
    int i;
    static GLdouble rects[12][3] = 
       {{ 50.0,  50.0, 0.0}, {300.0,  50.0, 0.0}, 
@@ -153,7 +153,7 @@
    glEndList();
 }
 
-void display (void) {
+static void display (void) {
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0, 1.0, 1.0);
    glPushMatrix(); 
@@ -168,12 +168,12 @@
    glFlush();
 }
 
-void CALLBACK beginCallback(GLenum which)
+static void CALLBACK beginCallback(GLenum which)
 {
    glBegin(which);
 }
 
-void CALLBACK errorCallback(GLenum errorCode)
+static void CALLBACK errorCallback(GLenum errorCode)
 {
    const GLubyte *estring;
 
@@ -182,7 +182,7 @@
    exit(0);
 }
 
-void CALLBACK endCallback(void)
+static void CALLBACK endCallback(void)
 {
    glEnd();
 }
@@ -193,7 +193,7 @@
  *  coordinate data.
  */
 /* ARGSUSED */
-void CALLBACK combineCallback(GLdouble coords[3], GLdouble *data[4],
+static void CALLBACK combineCallback(GLdouble coords[3], GLdouble *data[4],
                      GLfloat weight[4], GLdouble **dataOut )
 {
    GLdouble *vertex;
@@ -205,7 +205,7 @@
    *dataOut = vertex;
 }
 
-void init(void) 
+static void init(void) 
 {
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);    
@@ -226,7 +226,7 @@
    makeNewLists();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -240,7 +240,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 'w':
diff --git a/progs/redbook/texbind.c b/progs/redbook/texbind.c
index 6a828ab..b6404b3 100644
--- a/progs/redbook/texbind.c
+++ b/progs/redbook/texbind.c
@@ -52,7 +52,7 @@
 
 static GLuint texName[2];
 
-void makeCheckImages(void)
+static void makeCheckImages(void)
 {
    int i, j, c;
 
@@ -72,7 +72,7 @@
    }
 }
 
-void init(void)
+static void init(void)
 {
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
@@ -105,7 +105,7 @@
    glEnable(GL_TEXTURE_2D);
 }
 
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBindTexture(GL_TEXTURE_2D, texName[0]);
@@ -125,7 +125,7 @@
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -137,7 +137,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/texgen.c b/progs/redbook/texgen.c
index 7c1802a..5cb97e5 100644
--- a/progs/redbook/texgen.c
+++ b/progs/redbook/texgen.c
@@ -60,7 +60,7 @@
 static GLuint texName;
 #endif
 
-void makeStripeImage(void)
+static void makeStripeImage(void)
 {
    int j;
     
@@ -79,7 +79,7 @@
 static GLenum currentPlane;
 static GLint currentGenMode;
 
-void init(void)
+static void init(void)
 {
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glEnable(GL_DEPTH_TEST);
@@ -122,7 +122,7 @@
    glMaterialf (GL_FRONT, GL_SHININESS, 64.0);
 }
 
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
@@ -136,7 +136,7 @@
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -152,7 +152,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard (unsigned char key, int x, int y)
+static void keyboard (unsigned char key, int x, int y)
 {
    switch (key) {
       case 'e':
diff --git a/progs/redbook/texprox.c b/progs/redbook/texprox.c
index 6f1e853..c2d699a 100644
--- a/progs/redbook/texprox.c
+++ b/progs/redbook/texprox.c
@@ -53,7 +53,7 @@
 #define GL_TEXTURE_INTERNAL_FORMAT GL_TEXTURE_COMPONENTS
 #endif
 
-void init(void) 
+static void init(void) 
 {
    GLint proxyComponents;
 
@@ -84,12 +84,12 @@
    putchar('\n');
 }
 
-void display(void)
+static void display(void)
 {
    exit(0);
 }
 
-void reshape (int w, int h)
+static void reshape (int w, int h)
 {
    glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
    glMatrixMode (GL_PROJECTION);
diff --git a/progs/redbook/texsub.c b/progs/redbook/texsub.c
index 4e82967..7827d5a 100644
--- a/progs/redbook/texsub.c
+++ b/progs/redbook/texsub.c
@@ -58,7 +58,7 @@
 
 static GLuint texName;
 
-void makeCheckImages(void)
+static void makeCheckImages(void)
 {
    int i, j, c;
 
@@ -82,7 +82,7 @@
    }
 }
 
-void init(void)
+static void init(void)
 {
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
@@ -102,7 +102,7 @@
                 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage);
 }
 
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
@@ -123,7 +123,7 @@
    glDisable(GL_TEXTURE_2D);
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -135,7 +135,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard (unsigned char key, int x, int y)
+static void keyboard (unsigned char key, int x, int y)
 {
    switch (key) {
       case 's':
diff --git a/progs/redbook/texturesurf.c b/progs/redbook/texturesurf.c
index 0170070..2023072 100644
--- a/progs/redbook/texturesurf.c
+++ b/progs/redbook/texturesurf.c
@@ -60,7 +60,7 @@
 GLfloat texpts[2][2][2] = {{{0.0, 0.0}, {0.0, 1.0}},
 			{{1.0, 0.0}, {1.0, 1.0}}};
 
-void display(void)
+static void display(void)
 {
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glColor3f(1.0, 1.0, 1.0);
@@ -72,7 +72,7 @@
 #define	imageHeight 64
 GLubyte image[3*imageWidth*imageHeight];
 
-void makeImage(void)
+static void makeImage(void)
 {
     int i, j;
     float ti, tj;
@@ -89,7 +89,7 @@
     }
 }
 
-void myinit(void)
+static void myinit(void)
 {
     glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4,
 	    0, 1, 12, 4, &ctrlpoints[0][0][0]);
@@ -112,7 +112,7 @@
     glShadeModel (GL_FLAT);
 }
 
-void myReshape(int w, int h)
+static void myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
     glMatrixMode(GL_PROJECTION);
diff --git a/progs/redbook/torus.c b/progs/redbook/torus.c
index 7ae4d41..a67d48e 100644
--- a/progs/redbook/torus.c
+++ b/progs/redbook/torus.c
@@ -89,7 +89,7 @@
 }
 
 /* Clear window and draw torus */
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f (1.0, 1.0, 1.0);
@@ -98,7 +98,7 @@
 }
 
 /* Handle window resize */
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -112,7 +112,7 @@
 /* Rotate about x-axis when "x" typed; rotate about y-axis
    when "y" typed; "i" returns torus to original view */
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
    case 'x':
diff --git a/progs/redbook/trim.c b/progs/redbook/trim.c
index f17674f..216f62a 100644
--- a/progs/redbook/trim.c
+++ b/progs/redbook/trim.c
@@ -59,7 +59,7 @@
  *  Initializes the control points of the surface to a small hill.
  *  The control points range from -3 to +3 in x, y, and z
  */
-void init_surface(void)
+static void init_surface(void)
 {
    int u, v;
    for (u = 0; u < 4; u++) {
@@ -75,7 +75,7 @@
    }
 }
 
-void nurbsError(GLenum errorCode)
+static void nurbsError(GLenum errorCode)
 {
    const GLubyte *estring;
 
@@ -86,7 +86,7 @@
 			
 /*  Initialize material property and depth buffer.
  */
-void init(void)
+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 };
@@ -112,7 +112,7 @@
                     (GLvoid (CALLBACK*) ()) nurbsError);
 }
 
-void display(void)
+static void display(void)
 {
    GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
    GLfloat edgePt[5][2] = /* counter clockwise */
@@ -147,7 +147,7 @@
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -160,7 +160,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/unproject.c b/progs/redbook/unproject.c
index 134c361..6d1c7db 100644
--- a/progs/redbook/unproject.c
+++ b/progs/redbook/unproject.c
@@ -45,14 +45,14 @@
 #include <stdlib.h>
 #include <stdio.h>
 
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();
 }
 
 /* Change these values for a different transformation  */
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -62,7 +62,7 @@
    glLoadIdentity();
 }
 
-void mouse(int button, int state, int x, int y) 
+static void mouse(int button, int state, int x, int y) 
 {
    GLint viewport[4];
    GLdouble mvmatrix[16], projmatrix[16];
@@ -98,7 +98,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/varray.c b/progs/redbook/varray.c
index b22e723..8ce39d7 100644
--- a/progs/redbook/varray.c
+++ b/progs/redbook/varray.c
@@ -54,7 +54,7 @@
 int setupMethod = POINTER;
 int derefMethod = DRAWARRAY;
 
-void setupPointers(void)
+static void setupPointers(void)
 {
    static GLint vertices[] = {25, 25,
                        100, 325,
@@ -76,7 +76,7 @@
    glColorPointer (3, GL_FLOAT, 0, colors);
 }
 
-void setupInterleave(void)
+static void setupInterleave(void)
 {
    static GLfloat intertwined[] =
       {1.0, 0.2, 1.0, 100.0, 100.0, 0.0,
@@ -89,14 +89,14 @@
    glInterleavedArrays (GL_C3F_V3F, 0, intertwined);
 }
 
-void init(void) 
+static void init(void) 
 {
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel (GL_SMOOTH);
    setupPointers ();
 }
 
-void display(void)
+static void display(void)
 {
    glClear (GL_COLOR_BUFFER_BIT);
 
@@ -117,7 +117,7 @@
    glFlush ();
 }
 
-void reshape (int w, int h)
+static void reshape (int w, int h)
 {
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode (GL_PROJECTION);
@@ -126,7 +126,7 @@
 }
 
 /* ARGSUSED2 */
-void mouse (int button, int state, int x, int y)
+static void mouse (int button, int state, int x, int y)
 {
    switch (button) {
       case GLUT_LEFT_BUTTON:
@@ -160,7 +160,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 27:
diff --git a/progs/redbook/wrap.c b/progs/redbook/wrap.c
index f9a1f16..6774971 100644
--- a/progs/redbook/wrap.c
+++ b/progs/redbook/wrap.c
@@ -59,7 +59,7 @@
 static GLuint texName;
 #endif
 
-void makeCheckImage(void)
+static void makeCheckImage(void)
 {
    int i, j, c;
     
@@ -74,7 +74,7 @@
    }
 }
 
-void init(void)
+static void init(void)
 {    
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
@@ -101,7 +101,7 @@
 #endif
 }
 
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
@@ -125,7 +125,7 @@
    glDisable(GL_TEXTURE_2D);
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -137,7 +137,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard (unsigned char key, int x, int y)
+static void keyboard (unsigned char key, int x, int y)
 {
    switch (key) {
       case 's':
diff --git a/progs/samples/.gitignore b/progs/samples/.gitignore
index f60d6e9..c15b886 100644
--- a/progs/samples/.gitignore
+++ b/progs/samples/.gitignore
@@ -36,6 +36,7 @@
 quad
 readtex.c
 readtex.h
+rgbtoppm
 select
 shape
 sphere
diff --git a/progs/samples/Makefile b/progs/samples/Makefile
index b300e38..64fa47a 100644
--- a/progs/samples/Makefile
+++ b/progs/samples/Makefile
@@ -10,7 +10,7 @@
 LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
 
 PROGS = accum bitmap1 bitmap2 blendeq blendxor copy cursor depth eval fog \
-	font line logo nurb olympic overlay point prim quad select \
+	font line logo nurb olympic overlay point prim rgbtoppm quad select \
 	shape sphere star stencil stretch texture tri wave
 
 
diff --git a/progs/samples/SConscript b/progs/samples/SConscript
index 7a8a0d62..134dfa9 100644
--- a/progs/samples/SConscript
+++ b/progs/samples/SConscript
@@ -1,23 +1,5 @@
 Import('*')
 
-if not env['GLUT']:
-    Return()
-
-env = env.Clone()
-
-env.Prepend(CPPPATH = [
-	'../util',
-])
-
-env.Prepend(LIBS = [
-	util,
-	'$GLUT_LIB'
-])
-
-if env['platform'] == 'windows':
-    env.Append(CPPDEFINES = ['NOMINMAX'])
-    env.Prepend(LIBS = ['winmm'])
-
 progs = [
     'accum',
     'bitmap1',
@@ -52,7 +34,7 @@
 ]
 
 for prog in progs:
-    env.Program(
+    progs_env.Program(
         target = prog,
         source = prog + '.c',
     )
diff --git a/progs/samples/olympic.c b/progs/samples/olympic.c
index 5385e48..209a8c1 100644
--- a/progs/samples/olympic.c
+++ b/progs/samples/olympic.c
@@ -74,7 +74,7 @@
 GLuint theTorus;
 
 
-void FillTorus(float rc, int numc, float rt, int numt)
+static void FillTorus(float rc, int numc, float rt, int numt)
 {
     int i, j, k;
     double s, t;
@@ -106,7 +106,7 @@
     }
 }
 
-float Clamp(int iters_left, float t)
+static float Clamp(int iters_left, float t)
 {
     if (iters_left < 3) {
 	return 0.0;
@@ -114,7 +114,7 @@
     return (iters_left-2)*t/iters_left;
 }
 
-void DrawScene(void)
+static void DrawScene(void)
 {
     int i, j;
     GLboolean goIdle;
@@ -172,7 +172,7 @@
     }
 }
 
-float MyRand(void)
+static float MyRand(void)
 {
    return 10.0 * ( (float) rand() / (float) RAND_MAX - 0.5 );
 }
@@ -181,12 +181,12 @@
 #define GLUTCALLBACK
 #endif
 
-void GLUTCALLBACK glut_post_redisplay_p(void)
+static void GLUTCALLBACK glut_post_redisplay_p(void)
 {
       glutPostRedisplay();
 }
 
-void ReInit(void)
+static void ReInit(void)
 {
     int i;
     float deviation;
@@ -206,7 +206,7 @@
     glutIdleFunc(glut_post_redisplay_p);
 }
 
-void Init(void)
+static void Init(void)
 {
     float base, height;
     float aspect, x, y;
@@ -312,13 +312,13 @@
     glMatrixMode(GL_MODELVIEW);
 }
 
-void Reshape(int width, int height)
+static void Reshape(int width, int height)
 {
 
     glViewport(0, 0, width, height);
 }
 
-void Key(unsigned char key, int x, int y)
+static void Key(unsigned char key, int x, int y)
 {
 
     switch (key) {
@@ -330,7 +330,7 @@
     }
 }
 
-GLenum Args(int argc, char **argv)
+static GLenum Args(int argc, char **argv)
 {
     GLint i;
 
diff --git a/progs/samples/overlay.c b/progs/samples/overlay.c
index 23b5a47..6087cef 100644
--- a/progs/samples/overlay.c
+++ b/progs/samples/overlay.c
@@ -69,19 +69,19 @@
 float sinTable[MAXANGLES];
 
 
-float Sin(float angle)
+static float Sin(float angle)
 {
 
     return (sinTable[(GLint)angle]);
 }
 
-float Cos(float angle)
+static float Cos(float angle)
 {
 
     return (sinTable[((GLint)angle+(MAXANGLES/4))%MAXANGLES]);
 }
 
-void NewStar(GLint n, GLint d)
+static void NewStar(GLint n, GLint d)
 {
 
     if (rand()%4 == 0) {
@@ -103,7 +103,7 @@
     }
 }
 
-void RotatePoint(float *x, float *y, float rotation)
+static void RotatePoint(float *x, float *y, float rotation)
 {
     float tmpX, tmpY;
 
@@ -113,7 +113,7 @@
     *y = tmpY;
 }
 
-void MoveStars(void)
+static void MoveStars(void)
 {
     float offset;
     GLint n;
@@ -134,7 +134,7 @@
     }
 }
 
-GLenum StarPoint(GLint n)
+static GLenum StarPoint(GLint n)
 {
     float x0, y0, x1, y1, width;
     GLint i;
@@ -182,7 +182,7 @@
     }
 }
 
-void ShowStars(void)
+static void ShowStars(void)
 {
     GLint n;
 
@@ -221,7 +221,7 @@
     glDisable(GL_DITHER);
 }
 
-void Reshape(int width, int height)
+static void Reshape(int width, int height)
 {
 
     windW = (GLint)width;
@@ -262,7 +262,7 @@
     }
 }
 
-void Idle(void)
+static void Idle(void)
 {
 
     if (overlayInit == GL_FALSE) {
diff --git a/progs/samples/rgbtoppm.c b/progs/samples/rgbtoppm.c
index 116d9a8..403578e 100644
--- a/progs/samples/rgbtoppm.c
+++ b/progs/samples/rgbtoppm.c
@@ -3,6 +3,7 @@
 
 /* texload is a simplistic routine for reading an SGI .rgb image file. */
 
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h> 
 #include <string.h>
@@ -25,7 +26,7 @@
     int *rowSize;
 } ImageRec;
 
-void
+static void
 rgbtorgb(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
     while(n--) {
         l[0] = r[0];
@@ -72,6 +73,7 @@
     ImageRec *image;
     int swapFlag;
     int x;
+    int result;
 
     endianTest.testWord = 1;
     if (endianTest.testByte[0] == 1) {
@@ -86,13 +88,20 @@
         exit(1);
     }
     if ((image->file = fopen(fileName, "rb")) == NULL) {
-	return NULL;
+        free(image);
+        return NULL;
     }
 
-    fread(image, 1, 12, image->file);
+    result = fread(image, 1, 12, image->file);
+    assert(result == 12);
 
     if (swapFlag) {
-        ConvertShort(&image->imagic, 6);
+        ConvertShort(&image->imagic, 1);
+        ConvertShort(&image->type, 1);
+        ConvertShort(&image->dim, 1);
+        ConvertShort(&image->xsize, 1);
+        ConvertShort(&image->ysize, 1);
+        ConvertShort(&image->zsize, 1);
     }
 
     image->tmp = (unsigned char *)malloc(image->xsize*256);
@@ -111,8 +120,10 @@
         }
         image->rleEnd = 512 + (2 * x);
         fseek(image->file, 512, SEEK_SET);
-        fread(image->rowStart, 1, x, image->file);
-        fread(image->rowSize, 1, x, image->file);
+        result = fread(image->rowStart, 1, x, image->file);
+        assert(result == x);
+        result = fread(image->rowSize, 1, x, image->file);
+        assert(result == x);
         if (swapFlag) {
             ConvertUint(image->rowStart, x/(int) sizeof(unsigned));
             ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int));
@@ -132,11 +143,13 @@
 ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
     unsigned char *iPtr, *oPtr, pixel;
     int count;
+    int result;
 
     if ((image->type & 0xFF00) == 0x0100) {
         fseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET);
-        fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
-              image->file);
+        result = fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
+                       image->file);
+        assert(result == (unsigned int)image->rowSize[y+z*image->ysize]);
 
         iPtr = image->tmp;
         oPtr = buf;
@@ -160,11 +173,13 @@
     } else {
         fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
               SEEK_SET);
-        fread(buf, 1, image->xsize, image->file);
+        result = fread(buf, 1, image->xsize, image->file);
+        assert(result == image->xsize);
     }
 }
 
-GLubyte *
+#if 0
+static GLubyte *
 read_alpha_texture(char *name, int *width, int *height)
 {
     unsigned char *base, *lptr;
@@ -193,8 +208,9 @@
 
     return (unsigned char *) base;
 }
+#endif
 
-GLubyte *
+static GLubyte *
 read_rgb_texture(char *name, int *width, int *height)
 {
     unsigned char *base, *ptr;
@@ -224,6 +240,7 @@
       if (gbuf) free(gbuf);
       if (bbuf) free(bbuf);
       if (abuf) free(abuf);
+      ImageClose(image); 
       return NULL;
     }
     ptr = base;
@@ -254,7 +271,8 @@
 
 int main(int argc, char **argv)
 {
-	int width, height;
+	int width = 0;
+	int height = 0;
 	GLubyte *data;
         char buff[32];
         int n;
diff --git a/progs/samples/sphere.c b/progs/samples/sphere.c
index 7d0508d..23d4fe3 100644
--- a/progs/samples/sphere.c
+++ b/progs/samples/sphere.c
@@ -445,7 +445,7 @@
 };
 
 
-void BuildCylinder(int numEdges)
+static void BuildCylinder(int numEdges)
 {
     int i, top = 1.0, bottom = -1.0;
     float x[100], y[100], angle;
@@ -481,7 +481,7 @@
     glEndList();
 }
 
-void BuildTorus(float rc, int numc, float rt, int numt)
+static void BuildTorus(float rc, int numc, float rt, int numt)
 {
     int i, j, k;
     double s, t;
@@ -515,7 +515,7 @@
     glEndList();
 }
 
-void BuildCage(void)
+static void BuildCage(void)
 {
     int i;
     float inc;
@@ -609,7 +609,7 @@
     glEndList();
 }
 
-void BuildCube(void)
+static void BuildCube(void)
 {
     int i, j;
 
@@ -628,7 +628,7 @@
     glEndList();
 }
 
-void BuildLists(void)
+static void BuildLists(void)
 {
 
     cube = glGenLists(1);
@@ -646,7 +646,7 @@
     genericObject = torus;
 }
 
-void SetDefaultSettings(void)
+static void SetDefaultSettings(void)
 {
 
     magFilter = nnearest;
@@ -657,7 +657,7 @@
     autoRotate = GL_TRUE;
 }
 
-unsigned char *AlphaPadImage(int bufSize, unsigned char *inData, int alpha)
+static unsigned char *AlphaPadImage(int bufSize, unsigned char *inData, int alpha)
 {
     unsigned char *outData, *out_ptr, *in_ptr;
     int i;
@@ -677,7 +677,7 @@
     return outData;
 }
 
-void Init(void)
+static void Init(void)
 {
     float ambient[] = {0.0, 0.0, 0.0, 1.0};
     float diffuse[] = {1.0, 1.0, 1.0, 1.0};
@@ -753,7 +753,7 @@
     BuildLists();
 }
 
-void ReInit(void)
+static void ReInit(void)
 {
     if (genericObject == torus) {
 	glEnable(GL_DEPTH_TEST);
@@ -773,7 +773,7 @@
     glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, textureEnvironment);
 }
 
-void Draw(void)
+static void Draw(void)
 {
     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 
@@ -806,7 +806,7 @@
     glutSwapBuffers();
 }
 
-void Reshape(int width, int height)
+static void Reshape(int width, int height)
 {
     W = width;
     H = height;
@@ -818,7 +818,7 @@
     glMatrixMode(GL_MODELVIEW);
 }
 
-void Idle(void)
+static void Idle(void)
 {
    static double t0 = -1.;
    double t, dt;
@@ -833,7 +833,7 @@
    glutPostRedisplay();
 }
 
-void Key2(int key, int x, int y)
+static void Key2(int key, int x, int y)
 {
 
     switch (key) {
@@ -863,7 +863,7 @@
     glutPostRedisplay();
 }
 
-void Key(unsigned char key, int x, int y)
+static void Key(unsigned char key, int x, int y)
 {
 
     switch (key) {
@@ -950,7 +950,7 @@
     glutPostRedisplay();
 }
 
-GLenum Args(int argc, char **argv)
+static GLenum Args(int argc, char **argv)
 {
     GLint i;
 
diff --git a/progs/samples/star.c b/progs/samples/star.c
index 2cf470e..2c44ebf 100644
--- a/progs/samples/star.c
+++ b/progs/samples/star.c
@@ -67,19 +67,19 @@
 float sinTable[MAXANGLES];
 
 
-float Sin(float angle)
+static float Sin(float angle)
 {
 
     return (sinTable[(GLint)angle]);
 }
 
-float Cos(float angle)
+static float Cos(float angle)
 {
 
     return (sinTable[((GLint)angle+(MAXANGLES/4))%MAXANGLES]);
 }
 
-void NewStar(GLint n, GLint d)
+static void NewStar(GLint n, GLint d)
 {
 
     if (rand()%4 == 0) {
@@ -101,7 +101,7 @@
     }
 }
 
-void RotatePoint(float *x, float *y, float rotation)
+static void RotatePoint(float *x, float *y, float rotation)
 {
     float tmpX, tmpY;
 
@@ -111,7 +111,7 @@
     *y = tmpY;
 }
 
-void MoveStars(void)
+static void MoveStars(void)
 {
     float offset;
     GLint n;
@@ -142,7 +142,7 @@
     }
 }
 
-GLenum StarPoint(GLint n)
+static GLenum StarPoint(GLint n)
 {
     float x0, y0, x1, y1, width;
     GLint i;
@@ -190,7 +190,7 @@
     }
 }
 
-void ShowStars(void)
+static void ShowStars(void)
 {
     GLint n;
 
@@ -229,7 +229,7 @@
     glDisable(GL_DITHER);
 }
 
-void Reshape(int width, int height)
+static void Reshape(int width, int height)
 {
 
     windW = (GLint)width;
@@ -260,7 +260,7 @@
     }
 }
 
-void Draw(void)
+static void Draw(void)
 {
 
     MoveStars();
@@ -307,7 +307,7 @@
 #define GLUTCALLBACK
 #endif
 
-void GLUTCALLBACK glut_post_redisplay_p(void)
+static void GLUTCALLBACK glut_post_redisplay_p(void)
 {
       glutPostRedisplay();
 }
diff --git a/progs/samples/stretch.c b/progs/samples/stretch.c
index 1fd015d..11201dc 100644
--- a/progs/samples/stretch.c
+++ b/progs/samples/stretch.c
@@ -67,7 +67,7 @@
 GLenum op = OP_NOOP;
 
 
-void DrawImage(void)
+static void DrawImage(void)
 {
 
     glRasterPos2i(0, 0);
@@ -84,7 +84,7 @@
 		 image->data);
 }
 
-void DrawPoint(void)
+static void DrawPoint(void)
 {
     int i;
 
@@ -102,7 +102,7 @@
     }
 }
 
-void InitVList(void)
+static void InitVList(void)
 {
 
     vList[0].x = 0.0;
@@ -141,7 +141,7 @@
     vList[4].tY = cList[0].y / (float)imageSizeY;
 }
 
-void ScaleImage(int sizeX, int sizeY)
+static void ScaleImage(int sizeX, int sizeY)
 {
     GLubyte *buf;
 
@@ -154,7 +154,7 @@
     image->sizeY = sizeY;
 }
 
-void SetPoint(int x, int y)
+static void SetPoint(int x, int y)
 {
 
     cList[cCount].x = (float)x;
@@ -162,7 +162,7 @@
     cCount++;
 }
 
-void Stretch(void)
+static void Stretch(void)
 {
 
     glBegin(GL_TRIANGLES);
@@ -221,7 +221,7 @@
     }
 }
 
-void Key(unsigned char key, int x, int y)
+static void Key(unsigned char key, int x, int y)
 {
 
     switch (key) {
@@ -245,7 +245,7 @@
     glutPostRedisplay();
 }
 
-void Mouse(int button, int state, int mouseX, int mouseY)
+static void Mouse(int button, int state, int mouseX, int mouseY)
 {
 
     if (state != GLUT_DOWN)
@@ -263,7 +263,7 @@
     glutPostRedisplay();
 }
 
-void Animate(void)
+static void Animate(void)
 {
     static double t0 = -1.;
     double t, dt;
@@ -322,7 +322,7 @@
 #define GLUTCALLBACK
 #endif
 
-void GLUTCALLBACK glut_post_redisplay_p(void)
+static void GLUTCALLBACK glut_post_redisplay_p(void)
 {
       glutPostRedisplay();
 }
diff --git a/progs/samples/wave.c b/progs/samples/wave.c
index d3c4687..396a694 100644
--- a/progs/samples/wave.c
+++ b/progs/samples/wave.c
@@ -92,7 +92,7 @@
 #endif
 
 
-void GLUTCALLBACK glut_post_redisplay_p(void)
+static void GLUTCALLBACK glut_post_redisplay_p(void)
 {
     static double t0 = -1.;
     double t, dt;
diff --git a/progs/slang/cltest.c b/progs/slang/cltest.c
index 2753f59..dfff6cb 100644
--- a/progs/slang/cltest.c
+++ b/progs/slang/cltest.c
@@ -237,7 +237,7 @@
       if (p != NULL)
          p++;
    }
-   if (*p != '\0')
+   if (p && *p != '\0')
       printf ("*** %s\n", "I/O error");
 
    nextprogram = program->next;
diff --git a/progs/slang/vstest.c b/progs/slang/vstest.c
index 472ea9b..33c6f09 100644
--- a/progs/slang/vstest.c
+++ b/progs/slang/vstest.c
@@ -220,6 +220,12 @@
 
    fseek (f, 0, SEEK_END);
    size = ftell (f);
+
+   if (size == -1) {
+      fclose (f);
+      return;
+   }
+
    fseek (f, 0, SEEK_SET);
 
    code = (char *) (malloc (size));
diff --git a/progs/tests/Makefile b/progs/tests/Makefile
index 197e14d..836396b 100644
--- a/progs/tests/Makefile
+++ b/progs/tests/Makefile
@@ -37,10 +37,12 @@
 	bug_3195.c \
 	bug_texstore_i8.c \
 	calibrate_rast.c \
+	condrender.c \
 	copypixrate.c \
 	crossbar.c \
 	cva.c \
 	drawbuffers.c \
+	drawbuffers2.c \
 	exactrast.c \
 	ext422square.c \
 	floattex.c \
@@ -98,6 +100,7 @@
 	texdown \
 	texfilt.c \
 	texgenmix.c \
+	texleak.c \
 	texline.c \
 	texobj.c \
 	texobjshare.c \
diff --git a/progs/tests/SConscript b/progs/tests/SConscript
index 3a0da62..e2c6538 100644
--- a/progs/tests/SConscript
+++ b/progs/tests/SConscript
@@ -1,23 +1,5 @@
 Import('*')
 
-if not env['GLUT']:
-    Return()
-
-env = env.Clone()
-
-env.Prepend(CPPPATH = [
-	'../util',
-])
-
-env.Prepend(LIBS = [
-	util,
-	'$GLUT_LIB'
-])
-
-if env['platform'] == 'windows':
-    env.Append(CPPDEFINES = ['NOMINMAX'])
-    env.Prepend(LIBS = ['winmm'])
-
 linux_progs = [
     'api_speed',
 ]
@@ -59,10 +41,12 @@
     'bug_3195',
     'bug_texstore_i8',
     'calibrate_rast',
+    'condrender',
     'copypixrate',
     'crossbar',
     'cva',
     'drawbuffers',
+    'drawbuffers2',
     'exactrast',
     'ext422square',
     'fbotest1',
@@ -138,7 +122,7 @@
 ]
 
 for prog in progs:
-    env.Program(
+    progs_env.Program(
         target = prog,
         source = prog + '.c',
     )
diff --git a/progs/tests/arbgpuprog.c b/progs/tests/arbgpuprog.c
index 23aa899..6098dca 100644
--- a/progs/tests/arbgpuprog.c
+++ b/progs/tests/arbgpuprog.c
@@ -134,6 +134,8 @@
       }
 
       len = fread(buf, 1, 10*1000,f);
+      fclose(f);
+
       glProgramStringARB_func(GL_VERTEX_PROGRAM_ARB,
                               GL_PROGRAM_FORMAT_ASCII_ARB,
                               len,
@@ -170,6 +172,8 @@
       }
 
       len = fread(buf, 1, 10*1000,f);
+      fclose(f);
+
       glProgramStringARB_func(GL_FRAGMENT_PROGRAM_ARB,
                               GL_PROGRAM_FORMAT_ASCII_ARB,
                               len,
diff --git a/progs/tests/bug_texstore_i8.c b/progs/tests/bug_texstore_i8.c
index 10e5eba..b070011 100644
--- a/progs/tests/bug_texstore_i8.c
+++ b/progs/tests/bug_texstore_i8.c
@@ -73,7 +73,7 @@
 			0,
 			sourceFormat,
 			GL_UNSIGNED_BYTE,
-			//GL_UNSIGNED_INT,
+			/* GL_UNSIGNED_INT, */
 			tex2d);
 
 		glEnable(Target);
diff --git a/progs/tests/condrender.c b/progs/tests/condrender.c
new file mode 100644
index 0000000..1db8a7c
--- /dev/null
+++ b/progs/tests/condrender.c
@@ -0,0 +1,242 @@
+/*
+ * Test GL_NV_conditional_render
+ *
+ * Brian Paul
+ * 30 Dec 2009
+ *
+ * Copyright (C) 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, sublicense,
+ * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS 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 <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <GL/glew.h>
+#include <GL/glut.h>
+
+#define TEST_DISPLAY_LISTS 0
+
+static GLboolean Anim = GL_TRUE;
+static GLfloat Xpos = 0;
+static GLuint OccQuery;
+static GLint Win = 0;
+
+
+static void Idle(void)
+{
+   static int lastTime = 0;
+   static int sign = +1;
+   int time = glutGet(GLUT_ELAPSED_TIME);
+   float step;
+
+   if (lastTime == 0)
+      lastTime = time;
+   else if (time - lastTime < 20)  /* 50Hz update */
+      return;
+
+   step = (time - lastTime) / 1000.0 * sign;
+   lastTime = time;
+
+   Xpos += step;
+
+   if (Xpos > 2.5) {
+      Xpos = 2.5;
+      sign = -1;
+   }
+   else if (Xpos < -2.5) {
+      Xpos = -2.5;
+      sign = +1;
+   }
+   glutPostRedisplay();
+}
+
+
+static void Display( void )
+{
+   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+   glEnable(GL_DEPTH_TEST);
+
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
+   glMatrixMode( GL_MODELVIEW );
+   glLoadIdentity();
+   glTranslatef( 0.0, 0.0, -15.0 );
+
+   /* draw the occluding polygons */
+   glColor3f(0, 0.6, 0.8);
+   glBegin(GL_QUADS);
+   glVertex2f(-1.6, -1.5);
+   glVertex2f(-0.4, -1.5);
+   glVertex2f(-0.4,  1.5);
+   glVertex2f(-1.6,  1.5);
+
+   glVertex2f( 0.4, -1.5);
+   glVertex2f( 1.6, -1.5);
+   glVertex2f( 1.6,  1.5);
+   glVertex2f( 0.4,  1.5);
+   glEnd();
+
+   /* draw the test polygon with occlusion testing */
+   glPushMatrix();
+   glTranslatef(Xpos, 0, -0.5);
+   glScalef(0.3, 0.3, 1.0);
+   glRotatef(-90.0 * Xpos, 0, 0, 1);
+
+#if TEST_DISPLAY_LISTS
+   glNewList(10, GL_COMPILE);
+   glBeginQueryARB(GL_SAMPLES_PASSED_ARB, OccQuery);
+   glEndList();
+   glCallList(10);
+#else
+   glBeginQueryARB(GL_SAMPLES_PASSED_ARB, OccQuery);
+#endif
+
+   glColorMask(0, 0, 0, 0);
+   glDepthMask(GL_FALSE);
+
+   glBegin(GL_POLYGON);
+   glVertex3f(-1, -1, 0);
+   glVertex3f( 1, -1, 0);
+   glVertex3f( 1,  1, 0);
+   glVertex3f(-1,  1, 0);
+   glEnd();
+
+#if TEST_DISPLAY_LISTS
+   glNewList(11, GL_COMPILE);
+   glEndQueryARB(GL_SAMPLES_PASSED_ARB);
+   glEndList();
+   glCallList(11);
+#else
+   glEndQueryARB(GL_SAMPLES_PASSED_ARB);
+#endif
+
+   glColorMask(1, 1, 1, 1);
+   glDepthMask(GL_TRUE);
+
+   /* Note: disable depth test here so that we'll always see the orange
+    * box, except when it's totally culled.
+    */
+   glDisable(GL_DEPTH_TEST);
+
+   glBeginConditionalRenderNV(OccQuery, GL_QUERY_WAIT_NV);
+      /* draw the orange rect, so we can see what's going on */
+      glColor3f(0.8, 0.5, 0);
+      glBegin(GL_POLYGON);
+         glVertex3f(-1, -1, 0);
+         glVertex3f( 1, -1, 0);
+         glVertex3f( 1,  1, 0);
+         glVertex3f(-1,  1, 0);
+      glEnd();
+   glEndConditionalRenderNV();
+
+   /* always draw white outline around orange box */
+   glColor3f(1.0, 1.0, 1.0);
+   glBegin(GL_LINE_LOOP);
+      glVertex3f(-1, -1, 0);
+      glVertex3f( 1, -1, 0);
+      glVertex3f( 1,  1, 0);
+       glVertex3f(-1,  1, 0);
+   glEnd();
+
+   glPopMatrix();
+
+   glutSwapBuffers();
+}
+
+
+static void Reshape( int width, int height )
+{
+   glViewport( 0, 0, width, height );
+}
+
+
+static void Key( unsigned char key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+   case 27:
+      glDeleteQueriesARB(1, &OccQuery);
+      glutDestroyWindow(Win);
+      exit(0);
+      break;
+   case ' ':
+      Anim = !Anim;
+      if (Anim)
+         glutIdleFunc(Idle);
+      else
+         glutIdleFunc(NULL);
+      break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void SpecialKey( int key, int x, int y )
+{
+   const GLfloat step = 0.1;
+   (void) x;
+   (void) y;
+   switch (key) {
+   case GLUT_KEY_LEFT:
+      Xpos -= step;
+      break;
+   case GLUT_KEY_RIGHT:
+      Xpos += step;
+      break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void Init( void )
+{
+   if (!glutExtensionSupported("GL_ARB_occlusion_query") ||
+       !glutExtensionSupported("GL_NV_conditional_render")) {
+      printf("Sorry, this demo requires the extensions:\n");
+      printf("  GL_ARB_occlusion_query\n");
+      printf("  GL_NV_conditional_render\n");
+      exit(-1);
+   }
+
+   glGenQueriesARB(1, &OccQuery);
+   assert(OccQuery > 0);
+}
+
+
+int main( int argc, char *argv[] )
+{
+   glutInitWindowSize( 400, 400 );
+   glutInit( &argc, argv );
+   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
+   Win = glutCreateWindow(argv[0]);
+   glewInit();
+   glutReshapeFunc( Reshape );
+   glutKeyboardFunc( Key );
+   glutSpecialFunc( SpecialKey );
+   glutIdleFunc( Idle );
+   glutDisplayFunc( Display );
+   Init();
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/tests/crossbar.c b/progs/tests/crossbar.c
index bd8e05a..2988e20 100644
--- a/progs/tests/crossbar.c
+++ b/progs/tests/crossbar.c
@@ -174,7 +174,7 @@
       exit(1);
    }
 
-   printf("\nAll %u squares should be the same color.\n", NUM_TESTS + 1);
+   printf("\nAll %lu squares should be the same color.\n", (unsigned long) NUM_TESTS + 1);
    
    (void) memset( temp, 0x00, sizeof( temp ) );
    glBindTexture( GL_TEXTURE_2D, 1 );
diff --git a/progs/tests/cva.c b/progs/tests/cva.c
index 8048390..02d1dcb 100644
--- a/progs/tests/cva.c
+++ b/progs/tests/cva.c
@@ -39,7 +39,7 @@
 GLboolean doubleBuffer = GL_TRUE;
 
 
-void init( void )
+static void init( void )
 {
    glClearColor( 0.0, 0.0, 0.0, 0.0 );
    glShadeModel( GL_SMOOTH );
@@ -69,7 +69,7 @@
 #endif
 }
 
-void display( void )
+static void display( void )
 {
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
 
@@ -81,7 +81,7 @@
    }
 }
 
-void keyboard( unsigned char key, int x, int y )
+static void keyboard( unsigned char key, int x, int y )
 {
    switch ( key ) {
       case 27:
@@ -92,7 +92,7 @@
    glutPostRedisplay();
 }
 
-GLboolean args( int argc, char **argv )
+static GLboolean args( int argc, char **argv )
 {
     GLint i;
 
diff --git a/progs/tests/drawbuffers2.c b/progs/tests/drawbuffers2.c
new file mode 100644
index 0000000..7b8cc5c
--- /dev/null
+++ b/progs/tests/drawbuffers2.c
@@ -0,0 +1,364 @@
+/*
+ * Test GL_ARB_draw_buffers2, GL_ARB_draw_buffers, GL_EXT_framebuffer_object
+ * and GLSL's gl_FragData[].
+ *
+ * We draw to two color buffers and show the left half of the first
+ * color buffer on the left side of the window, and show the right
+ * half of the second color buffer on the right side of the window.
+ *
+ * Different color masks are used for the two color buffers.
+ * Blending is enabled for the second buffer only.
+ *
+ * Brian Paul
+ * 31 Dec 2009
+ */
+
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glew.h>
+#include <GL/glut.h>
+#include "extfuncs.h"
+
+static int Win;
+static int Width = 400, Height = 400;
+static GLuint FBobject, RBobjects[3];
+static GLfloat Xrot = 0.0, Yrot = 0.0;
+static GLuint Program;
+static GLboolean Anim = GL_TRUE;
+
+
+static void
+CheckError(int line)
+{
+   GLenum err = glGetError();
+   if (err) {
+      printf("GL Error 0x%x at line %d\n", (int) err, line);
+   }
+}
+
+
+static void
+Display(void)
+{
+   GLubyte *buffer = malloc(Width * Height * 4);
+   static const GLenum buffers[2] = {
+      GL_COLOR_ATTACHMENT0_EXT,
+      GL_COLOR_ATTACHMENT1_EXT
+   };
+
+   glUseProgram_func(Program);
+
+   glEnable(GL_DEPTH_TEST);
+
+   /* draw to user framebuffer */
+   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBobject);
+
+   /* Clear color buffer 0 (blue) */
+   glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+   glClear(GL_COLOR_BUFFER_BIT);
+
+   /* Clear color buffer 1 (1 - blue) */
+   glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
+   glClear(GL_COLOR_BUFFER_BIT);
+
+   glClear(GL_DEPTH_BUFFER_BIT);
+
+   /* draw to two buffers w/ fragment shader */
+   glDrawBuffersARB(2, buffers);
+
+   /* different color masks for each buffer */
+   if (1) {
+   glColorMaskIndexedEXT(0, GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
+   glColorMaskIndexedEXT(1, GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
+   }
+
+   glPushMatrix();
+   glRotatef(Xrot, 1, 0, 0);
+   glRotatef(Yrot, 0, 1, 0);
+   glPushMatrix();
+   glTranslatef(1, 0, 0);
+   glutSolidTorus(1.0, 2.0, 10, 20);
+   glPopMatrix();
+   glPushMatrix();
+   glTranslatef(-1, 0, 0);
+   glRotatef(90, 1, 0, 0);
+   glutSolidTorus(1.0, 2.0, 10, 20);
+   glPopMatrix();
+   glPopMatrix();
+
+   /* restore default color masks */
+   glColorMaskIndexedEXT(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+   glColorMaskIndexedEXT(1, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+   /* read from user framebuffer */
+   /* left half = colorbuffer 0 */
+   glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
+   glPixelStorei(GL_PACK_ROW_LENGTH, Width);
+   glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+   glReadPixels(0, 0, Width / 2, Height, GL_RGBA, GL_UNSIGNED_BYTE,
+                buffer);
+
+   /* right half = colorbuffer 1 */
+   glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
+   glPixelStorei(GL_PACK_SKIP_PIXELS, Width / 2);
+   glReadPixels(Width / 2, 0, Width - Width / 2, Height,
+                GL_RGBA, GL_UNSIGNED_BYTE,
+                buffer);
+
+   /* draw to window */
+   glUseProgram_func(0);
+   glDisable(GL_DEPTH_TEST);
+   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+   glWindowPos2iARB(0, 0);
+   glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+
+   free(buffer);
+   glutSwapBuffers();
+   CheckError(__LINE__);
+}
+
+
+static void
+Idle(void)
+{
+   Xrot = glutGet(GLUT_ELAPSED_TIME) * 0.05;
+   glutPostRedisplay();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+   float ar = (float) width / (float) height;
+
+   glViewport(0, 0, width, height);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glFrustum(-ar, ar, -1.0, 1.0, 5.0, 35.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glTranslatef(0.0, 0.0, -20.0);
+
+   Width = width;
+   Height = height;
+
+   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[0]);
+   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
+   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[1]);
+   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
+   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[2]);
+   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
+                            Width, Height);
+}
+
+
+static void
+CleanUp(void)
+{
+   glDeleteFramebuffersEXT(1, &FBobject);
+   glDeleteRenderbuffersEXT(3, RBobjects);
+   glutDestroyWindow(Win);
+   exit(0);
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+   case ' ':
+      Anim = !Anim;
+      glutIdleFunc(Anim ? Idle : NULL);
+      break;
+   case 'x':
+      Xrot += 5.0;
+      break;
+   case 'X':
+      Xrot -= 5.0;
+      break;
+   case 'y':
+      Yrot += 5.0;
+      break;
+   case 'Y':
+      Yrot -= 5.0;
+      break;
+   case 27:
+      CleanUp();
+      break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void
+CheckExtensions(void)
+{
+   const char *req[] = {
+      "GL_EXT_framebuffer_object",
+      "GL_ARB_draw_buffers",
+      "GL_EXT_draw_buffers2"
+   };
+
+   const char *version = (const char *) glGetString(GL_VERSION);
+   GLint numBuf;
+   GLint i;
+
+   for (i = 0; i < 3; i++) {
+      if (!glutExtensionSupported(req[i])) {
+         printf("Sorry, %s extension is required!\n", req[i]);
+         exit(1);
+      }
+   }
+   if (version[0] != '2') {
+      printf("Sorry, OpenGL 2.0 is required!\n");
+      exit(1);
+   }
+
+   glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &numBuf);
+   printf("GL_MAX_DRAW_BUFFERS_ARB = %d\n", numBuf);
+   if (numBuf < 2) {
+      printf("Sorry, GL_MAX_DRAW_BUFFERS_ARB needs to be >= 2\n");
+      exit(1);
+   }
+
+   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
+}
+
+
+static void
+SetupRenderbuffers(void)
+{
+   glGenFramebuffersEXT(1, &FBobject);
+   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBobject);
+
+   glGenRenderbuffersEXT(3, RBobjects);
+
+   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[0]);
+   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
+
+   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[1]);
+   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
+
+   glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[2]);
+   glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
+                            Width, Height);
+
+   glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+                                GL_RENDERBUFFER_EXT, RBobjects[0]);
+   glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT,
+                                GL_RENDERBUFFER_EXT, RBobjects[1]);
+   glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
+                                GL_RENDERBUFFER_EXT, RBobjects[2]);
+
+   CheckError(__LINE__);
+}
+
+
+static GLuint
+LoadAndCompileShader(GLenum target, const char *text)
+{
+   GLint stat;
+   GLuint shader = glCreateShader_func(target);
+   glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
+   glCompileShader_func(shader);
+   glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
+   if (!stat) {
+      GLchar log[1000];
+      GLsizei len;
+      glGetShaderInfoLog_func(shader, 1000, &len, log);
+      fprintf(stderr, "drawbuffers: problem compiling shader:\n%s\n", log);
+      exit(1);
+   }
+   return shader;
+}
+
+
+static void
+CheckLink(GLuint prog)
+{
+   GLint stat;
+   glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
+   if (!stat) {
+      GLchar log[1000];
+      GLsizei len;
+      glGetProgramInfoLog_func(prog, 1000, &len, log);
+      fprintf(stderr, "drawbuffers: shader link error:\n%s\n", log);
+   }
+}
+
+
+static void
+SetupShaders(void)
+{
+   /* emit same color to both draw buffers */
+   static const char *fragShaderText =
+      "void main() {\n"
+      "   gl_FragData[0] = gl_Color; \n"
+      "   gl_FragData[1] = gl_Color; \n"
+      "}\n";
+
+   GLuint fragShader;
+
+   fragShader = LoadAndCompileShader(GL_FRAGMENT_SHADER, fragShaderText);
+   Program = glCreateProgram_func();
+
+   glAttachShader_func(Program, fragShader);
+   glLinkProgram_func(Program);
+   CheckLink(Program);
+   glUseProgram_func(Program);
+}
+
+
+static void
+SetupLighting(void)
+{
+   static const GLfloat ambient[4] = { 0.0, 0.0, 0.0, 0.0 };
+   static const GLfloat diffuse[4] = { 1.0, 1.0, 1.0, 0.75 };
+
+   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
+   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
+   glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
+
+   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
+   glEnable(GL_LIGHT0);
+   glEnable(GL_LIGHTING);
+}
+
+
+static void
+Init(void)
+{
+   CheckExtensions();
+   GetExtensionFuncs();
+   SetupRenderbuffers();
+   SetupShaders();
+   SetupLighting();
+   glEnable(GL_DEPTH_TEST);
+
+   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+   glEnableIndexedEXT(GL_BLEND, 1);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+   glutInit(&argc, argv);
+   glutInitWindowPosition(0, 0);
+   glutInitWindowSize(Width, Height);
+   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
+   Win = glutCreateWindow(argv[0]);
+   glewInit();
+   glutIdleFunc(Anim ? Idle : NULL);
+   glutReshapeFunc(Reshape);
+   glutKeyboardFunc(Key);
+   glutDisplayFunc(Display);
+   Init();
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/tests/fptest1.c b/progs/tests/fptest1.c
index 2b8f8d0..1f30d57 100644
--- a/progs/tests/fptest1.c
+++ b/progs/tests/fptest1.c
@@ -57,6 +57,7 @@
 
 static void Init( void )
 {
+#if 0
    static const char *prog0 =
       "!!FP1.0\n"
       "MUL   o[COLR], R0, f[WPOS]; \n"
@@ -73,6 +74,7 @@
       "MOV   HC, H2; \n"
       "END \n"
       ;
+#endif
 
    /* masked updates, defines, declarations */
    static const char *prog1 =
diff --git a/progs/tests/getprocaddress.c b/progs/tests/getprocaddress.c
index a09ea58..e699baf 100644
--- a/progs/tests/getprocaddress.c
+++ b/progs/tests/getprocaddress.c
@@ -1188,7 +1188,7 @@
    GLuint bufferID;
    GLint bufferMapped;
    static GLubyte data[BUFFER_DATA_SIZE] = {0};
-   float *dataPtr;
+   float *dataPtr = NULL;
 
    /* Get the function pointers we need.  These are from
     * GL_ARB_vertex_buffer_object and are required in all
@@ -3516,7 +3516,7 @@
    struct name_test_pair *entry;
    int failures = 0, passes = 0, untested = 0;
    int totalFail = 0, totalPass = 0, totalUntested = 0, totalUnsupported = 0;
-   int doTests;
+   int doTests = 0;
    const char *version = (const char *) glGetString(GL_VERSION);
 
    /* The functions list will have "real" entries (consisting of
diff --git a/progs/tests/invert.c b/progs/tests/invert.c
index 3bc97a4..45001b4 100644
--- a/progs/tests/invert.c
+++ b/progs/tests/invert.c
@@ -165,7 +165,7 @@
 	  "square should look upside-down.\n");
    
 
-   image = LoadRGBImage( IMAGE_FILE, & img_width, & img_height,
+   image = LoadRGBImage( IMAGE_FILE, (GLint *) & img_width, (GLint *) & img_height,
 			 & img_format );
    if ( image == NULL ) {
       printf( "Could not open image file \"%s\".\n", IMAGE_FILE );
diff --git a/progs/tests/packedpixels.c b/progs/tests/packedpixels.c
index d318cf5..34df955 100644
--- a/progs/tests/packedpixels.c
+++ b/progs/tests/packedpixels.c
@@ -17,53 +17,53 @@
    GLenum format;
    GLenum type;
    GLint bytes;
-   GLuint redTexel, greenTexel;
+   GLuint redTexel, greenTexel; /* with approx 51% alpha, when applicable */
 };
 
 static const struct pixel_format Formats[] = {
 
    { "GL_RGBA/GL_UNSIGNED_INT_8_8_8_8",
-     GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 4, 0xff000000, 0x00ff0000 },
+     GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 4, 0xff000080, 0x00ff0080 },
    { "GL_RGBA/GL_UNSIGNED_INT_8_8_8_8_REV",
-     GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0x000000ff, 0x0000ff00 },
+     GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0x800000ff, 0x8000ff00 },
    { "GL_RGBA/GL_UNSIGNED_INT_10_10_10_2",
-     GL_RGBA, GL_UNSIGNED_INT_10_10_10_2, 4, 0xffc00000, 0x3ff000 },
+     GL_RGBA, GL_UNSIGNED_INT_10_10_10_2, 4, 0xffc00002, 0x3ff002 },
    { "GL_RGBA/GL_UNSIGNED_INT_2_10_10_10_REV",
-     GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 4, 0x3ff, 0xffc00 },
+     GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 4, 0xc00003ff, 0xc00ffc00 },
    { "GL_RGBA/GL_UNSIGNED_SHORT_4_4_4_4",
-     GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0xf000, 0x0f00 },
+     GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0xf008, 0x0f08 },
    { "GL_RGBA/GL_UNSIGNED_SHORT_4_4_4_4_REV",
-     GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0x000f, 0x00f0 },
+     GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0x800f, 0x80f0 },
    { "GL_RGBA/GL_UNSIGNED_SHORT_5_5_5_1",
-     GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0xf800, 0x7c0 },
+     GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0xf801, 0x7c1 },
    { "GL_RGBA/GL_UNSIGNED_SHORT_1_5_5_5_REV",
-     GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0x1f, 0x3e0 },
+     GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0x801f, 0x83e0 },
 
    { "GL_BGRA/GL_UNSIGNED_INT_8_8_8_8",
-     GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 4, 0x0000ff00, 0x00ff0000 },
+     GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 4, 0x0000ff80, 0x00ff0080 },
    { "GL_BGRA/GL_UNSIGNED_INT_8_8_8_8_REV",
-     GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0x00ff0000, 0x0000ff00 },
+     GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0x80ff0000, 0x8000ff00 },
    { "GL_BGRA/GL_UNSIGNED_SHORT_4_4_4_4",
-     GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0x00f0, 0x0f00 },
+     GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0x00f8, 0x0f08 },
    { "GL_BGRA/GL_UNSIGNED_SHORT_4_4_4_4_REV",
-     GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0x0f00, 0x00f0 },
+     GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0x8f00, 0x80f0 },
    { "GL_BGRA/GL_UNSIGNED_SHORT_5_5_5_1",
-     GL_BGRA, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0x3e, 0x7c0 },
+     GL_BGRA, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0x3f, 0x7c1 },
    { "GL_BGRA/GL_UNSIGNED_SHORT_1_5_5_5_REV",
-     GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0x7c00, 0x3e0 },
+     GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0xfc00, 0x83e0 },
 
    { "GL_ABGR_EXT/GL_UNSIGNED_INT_8_8_8_8",
-     GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, 4, 0x000000ff, 0x0000ff00 },
+     GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, 4, 0x800000ff, 0x8000ff00 },
    { "GL_ABGR_EXT/GL_UNSIGNED_INT_8_8_8_8_REV",
-     GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0xff000000, 0x00ff0000 },
+     GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0xff000080, 0x00ff0080 },
    { "GL_ABGR_EXT/GL_UNSIGNED_SHORT_4_4_4_4",
-     GL_ABGR_EXT, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0x000f, 0x00f0 },
+     GL_ABGR_EXT, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0x800f, 0x80f0 },
    { "GL_ABGR_EXT/GL_UNSIGNED_SHORT_4_4_4_4_REV",
-     GL_ABGR_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0xf000, 0x0f00 },
+     GL_ABGR_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0xf008, 0x0f08 },
    { "GL_ABGR_EXT/GL_UNSIGNED_SHORT_5_5_5_1",
-     GL_ABGR_EXT, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0x1, 0x3e },
+     GL_ABGR_EXT, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0xf801, 0xf83e },
    { "GL_ABGR_EXT/GL_UNSIGNED_SHORT_1_5_5_5_REV",
-     GL_ABGR_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0x8000, 0x7c00 },
+     GL_ABGR_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0x800f, 0x7c0f },
 
    { "GL_RGB/GL_UNSIGNED_SHORT_5_6_5",
      GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2, 0xf800, 0x7e0 },
@@ -108,7 +108,7 @@
 static GLuint CurFormat = 0;
 
 static GLboolean Test3D = GL_FALSE;
-
+static GLboolean Blend = GL_FALSE;
 
 
 static void
@@ -234,6 +234,10 @@
            glEnable(GL_TEXTURE_3D);
         else
            glEnable(GL_TEXTURE_2D);
+
+        if (Blend)
+           glEnable(GL_BLEND);
+
         glBegin(GL_POLYGON);
         glTexCoord3f(0, 0, 0.5);  glVertex2f(0, 0);
         glTexCoord3f(1, 0, 0.5);  glVertex2f(w, 0);
@@ -245,6 +249,9 @@
            glDisable(GL_TEXTURE_3D);
         else
            glDisable(GL_TEXTURE_2D);
+
+        glDisable(GL_BLEND);
+
         glColor3f(0, 0, 0);
         glRasterPos2i(8, 6);
         PrintString(Formats[i].name);
@@ -265,8 +272,8 @@
    glPushMatrix();
    glTranslatef(2, (i + 1) * (h + 2), 0);
    glRasterPos2i(8, 6);
-   sprintf(s, "Internal Texture Format [f/F]: %s (%d of %d)",
-           IntFormats[CurFormat].name, CurFormat + 1, NUM_INT_FORMATS);
+   sprintf(s, "Internal Texture Format [f/F]: %s (%d of %lu)",
+           IntFormats[CurFormat].name, CurFormat + 1, (unsigned long) NUM_INT_FORMATS);
    PrintString(s);
    glPopMatrix();
 
@@ -279,6 +286,15 @@
       PrintString("Target [2/3]: GL_TEXTURE_2D");
    glPopMatrix();
 
+   glPushMatrix();
+   glTranslatef(2, (i + 3) * (h + 2), 0);
+   glRasterPos2i(8, 6);
+   if (Blend)
+      PrintString("Blend: Yes");
+   else
+      PrintString("Blend: No");
+   glPopMatrix();
+
    glutSwapBuffers();
 }
 
@@ -301,6 +317,9 @@
    (void) x;
    (void) y;
    switch (key) {
+      case 'b':
+         Blend = !Blend;
+         break;
       case 'F':
          if (CurFormat == 0)
             CurFormat = NUM_INT_FORMATS - 1;
@@ -336,6 +355,7 @@
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 }
 
 
diff --git a/progs/tests/prog_parameter.c b/progs/tests/prog_parameter.c
index 0241f3a..2de7e29 100644
--- a/progs/tests/prog_parameter.c
+++ b/progs/tests/prog_parameter.c
@@ -192,6 +192,7 @@
    GLfloat * params;
    GLint max_program_env_parameters;
    GLint max_program_local_parameters;
+   int i;
 
 
    printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
@@ -238,6 +239,10 @@
 
    params = malloc(max_program_env_parameters * 4 * sizeof(GLfloat));
 
+   for (i = 0; i < max_program_env_parameters * 4; i++) {
+      params[i] = 0.0F;
+   }
+
    pass &= set_parameter_batch(max_program_env_parameters, params, "Env",
 			       program_env_parameter4fv,
 			       program_env_parameters4fv,
diff --git a/progs/tests/quads.c b/progs/tests/quads.c
index 2098b51..e5b9920 100644
--- a/progs/tests/quads.c
+++ b/progs/tests/quads.c
@@ -17,7 +17,10 @@
 static GLboolean Anim = GL_TRUE;
 static GLuint Vbuffer = 0;
 
+#if 1
+#else
 static GLfloat buf[NUM_QUADS * 6 * 4];
+#endif
 
 static GLboolean doSwapBuffers = GL_TRUE;
 
diff --git a/progs/tests/scissor-viewport.c b/progs/tests/scissor-viewport.c
index 582e65f..4ef307b 100644
--- a/progs/tests/scissor-viewport.c
+++ b/progs/tests/scissor-viewport.c
@@ -104,7 +104,7 @@
 
    glDisable(GL_SCISSOR_TEST);
 
-   //glutSwapBuffers();
+   /* glutSwapBuffers(); */
    glFlush();
 }
 
@@ -120,7 +120,7 @@
    glutInitWindowPosition(100, 0);
    glutInitWindowSize(prog.width, prog.height);
 
-   //type = GLUT_RGB | GLUT_DOUBLE;
+   /* type = GLUT_RGB | GLUT_DOUBLE; */
    type = GLUT_RGB | GLUT_SINGLE;
    glutInitDisplayMode(type);
 
diff --git a/progs/tests/scissor.c b/progs/tests/scissor.c
index 2dfd217..e5a68ff 100644
--- a/progs/tests/scissor.c
+++ b/progs/tests/scissor.c
@@ -134,7 +134,7 @@
 
    glDisable(GL_SCISSOR_TEST);
 
-   //glutSwapBuffers();
+   /* glutSwapBuffers(); */
    glFlush();
 }
 
@@ -150,7 +150,7 @@
    glutInitWindowPosition(100, 0);
    glutInitWindowSize(prog.width, prog.height);
 
-   //type = GLUT_RGB | GLUT_DOUBLE;
+   /* type = GLUT_RGB | GLUT_DOUBLE; */
    type = GLUT_RGB | GLUT_SINGLE;
    glutInitDisplayMode(type);
 
diff --git a/progs/tests/sharedtex.c b/progs/tests/sharedtex.c
index c07ebd7..2337b88 100644
--- a/progs/tests/sharedtex.c
+++ b/progs/tests/sharedtex.c
@@ -424,13 +424,13 @@
 {
    const char *dpyName = XDisplayName(NULL);
 
-   struct window *h0, *h1, *h2, *h3;
+   struct window *h0;
 
    /* four windows and contexts sharing display lists and texture objects */
    h0 = AddWindow(dpyName,  10,  10, NULL);
-   h1 = AddWindow(dpyName, 330,  10, h0);
-   h2 = AddWindow(dpyName,  10, 350, h0);
-   h3 = AddWindow(dpyName, 330, 350, h0);
+   (void) AddWindow(dpyName, 330,  10, h0);
+   (void) AddWindow(dpyName,  10, 350, h0);
+   (void) AddWindow(dpyName, 330, 350, h0);
 
    InitGLstuff(h0);
 
diff --git a/progs/tests/stencilwrap.c b/progs/tests/stencilwrap.c
index 2e219fd..d396fc2 100644
--- a/progs/tests/stencilwrap.c
+++ b/progs/tests/stencilwrap.c
@@ -257,7 +257,7 @@
     * part of GL 1.4.
     */
 
-   ver_str = glGetString( GL_VERSION );
+   ver_str = (char *) glGetString( GL_VERSION );
    version = (ver_str == NULL) ? 1.0 : atof( ver_str );
 
    wrapping = (glutExtensionSupported("GL_EXT_stencil_wrap") || (version >= 1.4));
diff --git a/progs/tests/tex1d.c b/progs/tests/tex1d.c
index 4abe106..7d67451 100644
--- a/progs/tests/tex1d.c
+++ b/progs/tests/tex1d.c
@@ -39,11 +39,13 @@
 
 
 
+/*
 static void idle( void )
 {
    Angle += 2.0;
    glutPostRedisplay();
 }
+*/
 
 
 
diff --git a/progs/tests/texdown.c b/progs/tests/texdown.c
index 7e46045..92df01b 100644
--- a/progs/tests/texdown.c
+++ b/progs/tests/texdown.c
@@ -162,7 +162,7 @@
    const int image_bytes = align(w * h * BytesPerTexel(Format), ALIGN);
    const int bytes = image_bytes * NR_TEXOBJ;
    GLubyte *orig_texImage, *orig_getImage;
-   GLubyte *texImage, *getImage;
+   GLubyte *texImage;
    GLdouble t0, t1, time;
    int count;
    int i;
@@ -176,13 +176,14 @@
    orig_getImage = (GLubyte *) malloc(image_bytes + ALIGN);
    if (!orig_texImage || !orig_getImage) {
       DownloadRate = 0.0;
+      free(orig_texImage);
+      free(orig_getImage);
       return;
    }
 
    printf("alloc %p %p\n", orig_texImage, orig_getImage);
 
    texImage = (GLubyte *)align((unsigned long)orig_texImage, ALIGN);
-   getImage = (GLubyte *)align((unsigned long)orig_getImage, ALIGN);   
 
    for (i = 1; !(((unsigned long)texImage) & i); i<<=1)
       ;
diff --git a/progs/tests/texleak.c b/progs/tests/texleak.c
new file mode 100644
index 0000000..5cf4ff3
--- /dev/null
+++ b/progs/tests/texleak.c
@@ -0,0 +1,140 @@
+/*
+ * 'Texture leak' test
+ *
+ * Allocates and uses an additional texture of the maximum supported size for
+ * each frame. This tests the system's ability to cope with using increasing
+ * amounts of texture memory.
+ *
+ * Michel Dänzer  July 2009  This program is in the public domain.
+ */
+
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <GL/glew.h>
+#include <GL/glut.h>
+
+
+GLint size;
+GLvoid *image;
+static GLuint numTexObj;
+static GLuint *texObj;
+
+
+static void Idle( void )
+{
+   glutPostRedisplay();
+}
+
+
+static void DrawObject(void)
+{
+   static const GLfloat tex_coords[] = {  0.0,  0.0,  1.0,  1.0,  0.0 };
+   static const GLfloat vtx_coords[] = { -1.0, -1.0,  1.0,  1.0, -1.0 };
+   GLint i, j;
+
+   glEnable(GL_TEXTURE_2D);
+
+   for (i = 0; i < numTexObj; i++) {
+      glBindTexture(GL_TEXTURE_2D, texObj[i]);
+      glBegin(GL_QUADS);
+      for (j = 0; j < 4; j++ ) {
+         glTexCoord2f(tex_coords[j], tex_coords[j+1]);
+         glVertex2f( vtx_coords[j], vtx_coords[j+1] );
+      }
+      glEnd();
+   }
+}
+
+
+static void Display( void )
+{
+   struct timeval start, end;
+
+   texObj = realloc(texObj, ++numTexObj * sizeof(*texObj));
+
+   /* allocate a texture object */
+   glGenTextures(1, texObj + (numTexObj - 1));
+
+   glBindTexture(GL_TEXTURE_2D, texObj[numTexObj - 1]);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   memset(image, (16 * numTexObj) & 0xff, 4 * size * size);
+   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0,
+                GL_RGBA, GL_UNSIGNED_BYTE, image);
+
+   gettimeofday(&start, NULL);
+
+   glClear( GL_COLOR_BUFFER_BIT );
+
+   glPushMatrix();
+      glScalef(5.0, 5.0, 5.0);
+      DrawObject();
+   glPopMatrix();
+
+   glutSwapBuffers();
+
+   glFinish();
+   gettimeofday(&end, NULL);
+   printf("Rendering frame took %lu ms using %u MB of textures\n",
+	  end.tv_sec * 1000 + end.tv_usec / 1000 - start.tv_sec * 1000 -
+	  start.tv_usec / 1000, numTexObj * 4 * size / 1024 * size / 1024);
+
+   sleep(1);
+}
+
+
+static void Reshape( int width, int height )
+{
+   glViewport( 0, 0, width, height );
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glOrtho( -6.0, 6.0, -6.0, 6.0, 10.0, 100.0 );
+   glMatrixMode( GL_MODELVIEW );
+   glLoadIdentity();
+   glTranslatef( 0.0, 0.0, -70.0 );
+}
+
+
+static void Init( int argc, char *argv[] )
+{
+   glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size);
+   printf("%d x %d max texture size\n", size, size);
+
+   image = malloc(4 * size * size);
+   if (!image) {
+      fprintf(stderr, "Failed to allocate %u bytes of memory\n", 4 * size * size);
+      exit(1);
+   }
+
+   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+   glShadeModel(GL_FLAT);
+   glClearColor(0.3, 0.3, 0.4, 1.0);
+
+   Idle();
+}
+
+
+int main( int argc, char *argv[] )
+{
+   glutInit( &argc, argv );
+   glutInitWindowSize( 300, 300 );
+   glutInitWindowPosition( 0, 0 );
+   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
+   glutCreateWindow(argv[0] );
+   glewInit();
+
+   Init( argc, argv );
+
+   glutReshapeFunc( Reshape );
+   glutDisplayFunc( Display );
+   glutIdleFunc(Idle);
+
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/tests/unfilledclip.c b/progs/tests/unfilledclip.c
index db6fffa..331cbf2 100644
--- a/progs/tests/unfilledclip.c
+++ b/progs/tests/unfilledclip.c
@@ -31,6 +31,7 @@
 
 static int win_width, win_height;
 
+#if 0
 static void
 line(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
 {
@@ -39,6 +40,7 @@
 	glVertex2f(x2, y2);
 	glEnd();
 }
+#endif
 
 static void
 line3(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2)
diff --git a/progs/tests/vparray.c b/progs/tests/vparray.c
index af9b62d..fe168c6 100644
--- a/progs/tests/vparray.c
+++ b/progs/tests/vparray.c
@@ -37,13 +37,16 @@
    }
 
    numverts = 0;
-   while (!feof(f) && numverts < MAXVERTS) {
-      fscanf( f, "%f %f %f  %f %f %f",
-	      &data[numverts][0], &data[numverts][1], &data[numverts][2],
-	      &data[numverts][3], &data[numverts][4], &data[numverts][5] );
+   while (numverts < MAXVERTS) {
+      int result;
+      result = fscanf( f, "%f %f %f  %f %f %f",
+	               &data[numverts][0], &data[numverts][1], &data[numverts][2],
+	               &data[numverts][3], &data[numverts][4], &data[numverts][5] );
+      if (result == EOF) {
+         break;
+      }
       numverts++;
    }
-   numverts--;
 
    printf("%d vertices, %d triangles\n", numverts, numverts-2);
    printf("data = %p\n", (void *) data);
diff --git a/progs/tests/vpeval.c b/progs/tests/vpeval.c
index f07737f..3e8a732 100644
--- a/progs/tests/vpeval.c
+++ b/progs/tests/vpeval.c
@@ -94,16 +94,16 @@
 };
 
 
-void
+static void
 initlights(void)
 {
+#if 0 /* no lighting for now */
     GLfloat ambient[] = {0.2, 0.2, 0.2, 1.0};
     GLfloat position[] = {0.0, 0.0, 2.0, 1.0};
     GLfloat mat_diffuse[] = {0.6, 0.6, 0.6, 1.0};
     GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};
     GLfloat mat_shininess[] = {50.0};
 
-#if 0 /* no lighting for now */
     glEnable(GL_LIGHTING);
     glEnable(GL_LIGHT0);
 
@@ -116,7 +116,7 @@
 #endif
 }
 
-void
+static void
 display(void)
 {
    glClearColor(.3, .3, .3, 0);
@@ -130,7 +130,7 @@
     glFlush();
 }
 
-void
+static void
 myinit(int argc, char *argv[])
 {
     glClearColor(0.0, 0.0, 0.0, 1.0);
@@ -186,7 +186,7 @@
     }
 }
 
-void
+static void
 myReshape(int w, int h)
 {
     glViewport(0, 0, w, h);
diff --git a/progs/trivial/.gitignore b/progs/trivial/.gitignore
index 4d6e405..4317eb6 100644
--- a/progs/trivial/.gitignore
+++ b/progs/trivial/.gitignore
@@ -147,6 +147,7 @@
 vbo-drawelements
 vbo-drawrange
 vbo-noninterleaved
+vbo-tri
 vp-array
 vp-array-int
 vp-clip
diff --git a/progs/trivial/Makefile b/progs/trivial/Makefile
index 7072861..e15ec33 100644
--- a/progs/trivial/Makefile
+++ b/progs/trivial/Makefile
@@ -153,6 +153,7 @@
 	tristrip-clip.c \
 	tristrip-flat.c \
 	tristrip.c \
+	vbo-tri.c \
 	vbo-drawarrays.c \
 	vbo-noninterleaved.c \
 	vbo-drawelements.c \
diff --git a/progs/trivial/SConscript b/progs/trivial/SConscript
index 9a1f357..613383c 100644
--- a/progs/trivial/SConscript
+++ b/progs/trivial/SConscript
@@ -1,11 +1,4 @@
-Import('env')
-
-if not env['GLUT']:
-    Return()
-
-env = env.Clone()
-
-env.Prepend(LIBS = ['$GLUT_LIB'])
+Import('*')
 
 progs = [
     'clear-fbo-tex',
@@ -154,7 +147,7 @@
 ]
 
 for prog in progs:
-    prog = env.Program(
+    prog = progs_env.Program(
         target = prog,
         source = prog + '.c',
     )
diff --git a/progs/trivial/clear-fbo-tex.c b/progs/trivial/clear-fbo-tex.c
index a206676..ff31706 100644
--- a/progs/trivial/clear-fbo-tex.c
+++ b/progs/trivial/clear-fbo-tex.c
@@ -88,7 +88,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
@@ -102,8 +102,8 @@
 
    /* draw to texture image */
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
-//   glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
-//   glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
+   /* glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT); */
+   /* glReadBuffer(GL_COLOR_ATTACHMENT1_EXT); */
 
    
    glViewport(0, 0, TexWidth, TexHeight);
diff --git a/progs/trivial/clear-fbo.c b/progs/trivial/clear-fbo.c
index 0aeb454..6435c90 100644
--- a/progs/trivial/clear-fbo.c
+++ b/progs/trivial/clear-fbo.c
@@ -73,7 +73,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/clear-random.c b/progs/trivial/clear-random.c
index e3da23a..ab67f84 100644
--- a/progs/trivial/clear-random.c
+++ b/progs/trivial/clear-random.c
@@ -61,7 +61,7 @@
       case 27:
 	exit(0);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/clear-scissor.c b/progs/trivial/clear-scissor.c
index 0173532..2b6dee7 100644
--- a/progs/trivial/clear-scissor.c
+++ b/progs/trivial/clear-scissor.c
@@ -38,7 +38,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
     glutPostRedisplay();
 }
diff --git a/progs/trivial/clear.c b/progs/trivial/clear.c
index 03857b4..56c3ea5 100644
--- a/progs/trivial/clear.c
+++ b/progs/trivial/clear.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(0);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/createwin.c b/progs/trivial/createwin.c
index f2cc6f1..93da30e 100644
--- a/progs/trivial/createwin.c
+++ b/progs/trivial/createwin.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
@@ -116,6 +116,6 @@
     glutReshapeFunc(Reshape);
     glutKeyboardFunc(Key);
     glutDisplayFunc(Draw);
-//    glutMainLoop();
+    /* glutMainLoop(); */
 	return 0;
 }
diff --git a/progs/trivial/dlist-begin-call-end.c b/progs/trivial/dlist-begin-call-end.c
index 0d0aed7..dbfaef3 100644
--- a/progs/trivial/dlist-begin-call-end.c
+++ b/progs/trivial/dlist-begin-call-end.c
@@ -49,7 +49,7 @@
     */
    first_list = glGenLists(1);
    glNewList(first_list, GL_COMPILE); 
-//   glColor3f(0,1,0);
+   /* glColor3f(0,1,0); */
    glEndList();
 
 
@@ -87,7 +87,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/dlist-dangling.c b/progs/trivial/dlist-dangling.c
index de10628..756ab93 100644
--- a/progs/trivial/dlist-dangling.c
+++ b/progs/trivial/dlist-dangling.c
@@ -74,7 +74,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/dlist-edgeflag-dangling.c b/progs/trivial/dlist-edgeflag-dangling.c
index 3d3aaeb..5150447 100644
--- a/progs/trivial/dlist-edgeflag-dangling.c
+++ b/progs/trivial/dlist-edgeflag-dangling.c
@@ -76,7 +76,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/dlist-edgeflag.c b/progs/trivial/dlist-edgeflag.c
index 8002129..9456b96 100644
--- a/progs/trivial/dlist-edgeflag.c
+++ b/progs/trivial/dlist-edgeflag.c
@@ -81,7 +81,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/dlist-flat-tri.c b/progs/trivial/dlist-flat-tri.c
index c3dd792..3ee9b28 100644
--- a/progs/trivial/dlist-flat-tri.c
+++ b/progs/trivial/dlist-flat-tri.c
@@ -93,7 +93,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/dlist-mat-tri.c b/progs/trivial/dlist-mat-tri.c
index ed3a4c5..d17c4b9 100644
--- a/progs/trivial/dlist-mat-tri.c
+++ b/progs/trivial/dlist-mat-tri.c
@@ -103,7 +103,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/dlist-recursive-call.c b/progs/trivial/dlist-recursive-call.c
index fe06b2b..90224f6 100644
--- a/progs/trivial/dlist-recursive-call.c
+++ b/progs/trivial/dlist-recursive-call.c
@@ -118,7 +118,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/dlist-tri-flat-tri.c b/progs/trivial/dlist-tri-flat-tri.c
index 4dbb788..3265a4d 100644
--- a/progs/trivial/dlist-tri-flat-tri.c
+++ b/progs/trivial/dlist-tri-flat-tri.c
@@ -99,7 +99,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/dlist-tri-mat-tri.c b/progs/trivial/dlist-tri-mat-tri.c
index f69854a..053bb12 100644
--- a/progs/trivial/dlist-tri-mat-tri.c
+++ b/progs/trivial/dlist-tri-mat-tri.c
@@ -102,7 +102,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/draw2arrays.c b/progs/trivial/draw2arrays.c
index 95a8998..2345ae9 100644
--- a/progs/trivial/draw2arrays.c
+++ b/progs/trivial/draw2arrays.c
@@ -66,7 +66,7 @@
 
    glEnable(GL_VERTEX_PROGRAM_ARB);
 
-//   glDrawArrays( GL_TRIANGLES, 0, 3 );
+   /* glDrawArrays( GL_TRIANGLES, 0, 3 ); */
    glDrawArrays( GL_TRIANGLES, 1, 3 );
 
    glFlush(); 
diff --git a/progs/trivial/drawarrays.c b/progs/trivial/drawarrays.c
index 27d8668..f5c0a50 100644
--- a/progs/trivial/drawarrays.c
+++ b/progs/trivial/drawarrays.c
@@ -77,7 +77,7 @@
 
    glEnable(GL_VERTEX_PROGRAM_ARB);
 
-//   glDrawArrays( GL_TRIANGLES, 0, 3 );
+   /* glDrawArrays( GL_TRIANGLES, 0, 3 ); */
    glDrawArrays( GL_TRIANGLES, 1, 3 );
 
    glFlush(); 
diff --git a/progs/trivial/line-clip.c b/progs/trivial/line-clip.c
index 5276baf..e4e388e 100644
--- a/progs/trivial/line-clip.c
+++ b/progs/trivial/line-clip.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/line-cull.c b/progs/trivial/line-cull.c
index 1e1b77a..c531ff1 100644
--- a/progs/trivial/line-cull.c
+++ b/progs/trivial/line-cull.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/line-flat.c b/progs/trivial/line-flat.c
index 14f0ac0..e2ddb87 100644
--- a/progs/trivial/line-flat.c
+++ b/progs/trivial/line-flat.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/line-stipple-wide.c b/progs/trivial/line-stipple-wide.c
index 1804ffa..767583b 100644
--- a/progs/trivial/line-stipple-wide.c
+++ b/progs/trivial/line-stipple-wide.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/line-userclip-clip.c b/progs/trivial/line-userclip-clip.c
index 8e030b4..3265b2c 100644
--- a/progs/trivial/line-userclip-clip.c
+++ b/progs/trivial/line-userclip-clip.c
@@ -66,7 +66,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/line-userclip-nop-clip.c b/progs/trivial/line-userclip-nop-clip.c
index 6fcd4bc..0198e27 100644
--- a/progs/trivial/line-userclip-nop-clip.c
+++ b/progs/trivial/line-userclip-nop-clip.c
@@ -66,7 +66,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/line-userclip-nop.c b/progs/trivial/line-userclip-nop.c
index e59fd13..6c863a3 100644
--- a/progs/trivial/line-userclip-nop.c
+++ b/progs/trivial/line-userclip-nop.c
@@ -66,7 +66,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/line-userclip.c b/progs/trivial/line-userclip.c
index e30be55..6cfcb6f 100644
--- a/progs/trivial/line-userclip.c
+++ b/progs/trivial/line-userclip.c
@@ -66,7 +66,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/line-wide.c b/progs/trivial/line-wide.c
index b74021d..1945712c 100644
--- a/progs/trivial/line-wide.c
+++ b/progs/trivial/line-wide.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/line.c b/progs/trivial/line.c
index e1d7328..58ab968 100644
--- a/progs/trivial/line.c
+++ b/progs/trivial/line.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/lineloop-clip.c b/progs/trivial/lineloop-clip.c
index 45fa474..5e6b621 100644
--- a/progs/trivial/lineloop-clip.c
+++ b/progs/trivial/lineloop-clip.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/lineloop.c b/progs/trivial/lineloop.c
index c290dbd..82eccd2 100644
--- a/progs/trivial/lineloop.c
+++ b/progs/trivial/lineloop.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/linestrip-clip.c b/progs/trivial/linestrip-clip.c
index f252822..5e90ea2 100644
--- a/progs/trivial/linestrip-clip.c
+++ b/progs/trivial/linestrip-clip.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/linestrip-flat-stipple.c b/progs/trivial/linestrip-flat-stipple.c
index 5caa724..bae5c3a 100644
--- a/progs/trivial/linestrip-flat-stipple.c
+++ b/progs/trivial/linestrip-flat-stipple.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/linestrip-stipple-wide.c b/progs/trivial/linestrip-stipple-wide.c
index 701c82c..0296941 100644
--- a/progs/trivial/linestrip-stipple-wide.c
+++ b/progs/trivial/linestrip-stipple-wide.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/linestrip-stipple.c b/progs/trivial/linestrip-stipple.c
index df2eef9..a847d47 100644
--- a/progs/trivial/linestrip-stipple.c
+++ b/progs/trivial/linestrip-stipple.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/linestrip.c b/progs/trivial/linestrip.c
index 0219b1a..b6d6882 100644
--- a/progs/trivial/linestrip.c
+++ b/progs/trivial/linestrip.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/point-clip.c b/progs/trivial/point-clip.c
index 4c89ba5..23cfd77 100644
--- a/progs/trivial/point-clip.c
+++ b/progs/trivial/point-clip.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/point-param.c b/progs/trivial/point-param.c
index 6f43720..46bd773 100644
--- a/progs/trivial/point-param.c
+++ b/progs/trivial/point-param.c
@@ -59,7 +59,7 @@
     case 27:
 	exit(1);
     default:
-	return;
+	break;
     }
     glutPostRedisplay();
 }
diff --git a/progs/trivial/point-sprite.c b/progs/trivial/point-sprite.c
index 5d29a6a..16e6771 100644
--- a/progs/trivial/point-sprite.c
+++ b/progs/trivial/point-sprite.c
@@ -96,7 +96,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/point-wide-smooth.c b/progs/trivial/point-wide-smooth.c
index f6e9b8d..752cb8a 100644
--- a/progs/trivial/point-wide-smooth.c
+++ b/progs/trivial/point-wide-smooth.c
@@ -63,7 +63,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/point-wide.c b/progs/trivial/point-wide.c
index 8abd64c..3b00ee9 100644
--- a/progs/trivial/point-wide.c
+++ b/progs/trivial/point-wide.c
@@ -63,7 +63,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/point.c b/progs/trivial/point.c
index 49959dc..8f5299c 100644
--- a/progs/trivial/point.c
+++ b/progs/trivial/point.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/poly-flat-clip.c b/progs/trivial/poly-flat-clip.c
index 5490068..2a968be 100644
--- a/progs/trivial/poly-flat-clip.c
+++ b/progs/trivial/poly-flat-clip.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/poly-flat-unfilled-clip.c b/progs/trivial/poly-flat-unfilled-clip.c
index 26b90ef..89f4e06 100644
--- a/progs/trivial/poly-flat-unfilled-clip.c
+++ b/progs/trivial/poly-flat-unfilled-clip.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/poly-flat.c b/progs/trivial/poly-flat.c
index a4e3cdb..33c2e04 100644
--- a/progs/trivial/poly-flat.c
+++ b/progs/trivial/poly-flat.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/poly-unfilled.c b/progs/trivial/poly-unfilled.c
index 2ad443d..c8c0d7a 100644
--- a/progs/trivial/poly-unfilled.c
+++ b/progs/trivial/poly-unfilled.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/poly.c b/progs/trivial/poly.c
index e5b788e..964eb42 100644
--- a/progs/trivial/poly.c
+++ b/progs/trivial/poly.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quad-clip-all-vertices.c b/progs/trivial/quad-clip-all-vertices.c
index 60c87fc..7712d8c 100644
--- a/progs/trivial/quad-clip-all-vertices.c
+++ b/progs/trivial/quad-clip-all-vertices.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quad-clip.c b/progs/trivial/quad-clip.c
index 063de61..2847c9f 100644
--- a/progs/trivial/quad-clip.c
+++ b/progs/trivial/quad-clip.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quad-degenerate.c b/progs/trivial/quad-degenerate.c
index fdc142b..85e129d 100644
--- a/progs/trivial/quad-degenerate.c
+++ b/progs/trivial/quad-degenerate.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quad-flat.c b/progs/trivial/quad-flat.c
index e3147b3..bed98e3 100644
--- a/progs/trivial/quad-flat.c
+++ b/progs/trivial/quad-flat.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quad-offset-factor.c b/progs/trivial/quad-offset-factor.c
index dfe99bba..1fc57a5 100644
--- a/progs/trivial/quad-offset-factor.c
+++ b/progs/trivial/quad-offset-factor.c
@@ -55,7 +55,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quad-offset-unfilled.c b/progs/trivial/quad-offset-unfilled.c
index 0659002..62f50fb 100644
--- a/progs/trivial/quad-offset-unfilled.c
+++ b/progs/trivial/quad-offset-unfilled.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quad-offset-units.c b/progs/trivial/quad-offset-units.c
index 922529d..1ac2338 100644
--- a/progs/trivial/quad-offset-units.c
+++ b/progs/trivial/quad-offset-units.c
@@ -55,7 +55,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quad-tex-alpha.c b/progs/trivial/quad-tex-alpha.c
index eebaf91..9db6792 100644
--- a/progs/trivial/quad-tex-alpha.c
+++ b/progs/trivial/quad-tex-alpha.c
@@ -88,7 +88,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quad-tex-pbo.c b/progs/trivial/quad-tex-pbo.c
index ad41a9a..b7aa1db 100644
--- a/progs/trivial/quad-tex-pbo.c
+++ b/progs/trivial/quad-tex-pbo.c
@@ -105,7 +105,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quad-unfilled-clip.c b/progs/trivial/quad-unfilled-clip.c
index 761878b..d2e8718 100644
--- a/progs/trivial/quad-unfilled-clip.c
+++ b/progs/trivial/quad-unfilled-clip.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quad-unfilled-stipple.c b/progs/trivial/quad-unfilled-stipple.c
index cd7d276..8c1737e 100644
--- a/progs/trivial/quad-unfilled-stipple.c
+++ b/progs/trivial/quad-unfilled-stipple.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quad-unfilled.c b/progs/trivial/quad-unfilled.c
index d64f17f..b756449 100644
--- a/progs/trivial/quad-unfilled.c
+++ b/progs/trivial/quad-unfilled.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quad.c b/progs/trivial/quad.c
index d360e30..582de78 100644
--- a/progs/trivial/quad.c
+++ b/progs/trivial/quad.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quads.c b/progs/trivial/quads.c
index fe11fef..de7854a 100644
--- a/progs/trivial/quads.c
+++ b/progs/trivial/quads.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quadstrip-cont.c b/progs/trivial/quadstrip-cont.c
index 3295235..4441269 100644
--- a/progs/trivial/quadstrip-cont.c
+++ b/progs/trivial/quadstrip-cont.c
@@ -57,7 +57,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quadstrip-flat.c b/progs/trivial/quadstrip-flat.c
index 228c6c2..0e0b3b4 100644
--- a/progs/trivial/quadstrip-flat.c
+++ b/progs/trivial/quadstrip-flat.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/quadstrip.c b/progs/trivial/quadstrip.c
index d49a9a5..1be815f 100644
--- a/progs/trivial/quadstrip.c
+++ b/progs/trivial/quadstrip.c
@@ -57,7 +57,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/readpixels.c b/progs/trivial/readpixels.c
index 5671618..b063f17 100644
--- a/progs/trivial/readpixels.c
+++ b/progs/trivial/readpixels.c
@@ -39,7 +39,7 @@
    case 27:
       exit(0);
    default:
-      return;
+      break;
    }
    glutPostRedisplay();
 }
diff --git a/progs/trivial/tri-alpha-tex.c b/progs/trivial/tri-alpha-tex.c
index 780ebe6..853d564 100644
--- a/progs/trivial/tri-alpha-tex.c
+++ b/progs/trivial/tri-alpha-tex.c
@@ -88,7 +88,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-alpha.c b/progs/trivial/tri-alpha.c
index aec1cbb..bd1c88e 100644
--- a/progs/trivial/tri-alpha.c
+++ b/progs/trivial/tri-alpha.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-blend-color.c b/progs/trivial/tri-blend-color.c
index 92f0192..629b35c 100644
--- a/progs/trivial/tri-blend-color.c
+++ b/progs/trivial/tri-blend-color.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-blend-max.c b/progs/trivial/tri-blend-max.c
index b39f8f3..b173dab 100644
--- a/progs/trivial/tri-blend-max.c
+++ b/progs/trivial/tri-blend-max.c
@@ -83,7 +83,7 @@
    glDisable (GL_BLEND);
 }
 
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT);
 
@@ -99,7 +99,7 @@
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -111,7 +111,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 't':
diff --git a/progs/trivial/tri-blend-min.c b/progs/trivial/tri-blend-min.c
index 656297c..629139a 100644
--- a/progs/trivial/tri-blend-min.c
+++ b/progs/trivial/tri-blend-min.c
@@ -83,7 +83,7 @@
    glDisable (GL_BLEND);
 }
 
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT);
 
@@ -99,7 +99,7 @@
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -111,7 +111,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 't':
diff --git a/progs/trivial/tri-blend-revsub.c b/progs/trivial/tri-blend-revsub.c
index fe225f1..ef1e92c 100644
--- a/progs/trivial/tri-blend-revsub.c
+++ b/progs/trivial/tri-blend-revsub.c
@@ -83,7 +83,7 @@
    glDisable (GL_BLEND);
 }
 
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT);
 
@@ -99,7 +99,7 @@
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -111,7 +111,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 't':
diff --git a/progs/trivial/tri-blend-sub.c b/progs/trivial/tri-blend-sub.c
index cc1aeaf..3c560ae 100644
--- a/progs/trivial/tri-blend-sub.c
+++ b/progs/trivial/tri-blend-sub.c
@@ -83,7 +83,7 @@
    glDisable (GL_BLEND);
 }
 
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT);
 
@@ -99,7 +99,7 @@
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -111,7 +111,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 't':
diff --git a/progs/trivial/tri-blend.c b/progs/trivial/tri-blend.c
index 58c451c..f41be89b 100644
--- a/progs/trivial/tri-blend.c
+++ b/progs/trivial/tri-blend.c
@@ -81,7 +81,7 @@
    glDisable (GL_BLEND);
 }
 
-void display(void)
+static void display(void)
 {
    glClear(GL_COLOR_BUFFER_BIT);
 
@@ -97,7 +97,7 @@
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -109,7 +109,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 't':
diff --git a/progs/trivial/tri-clear.c b/progs/trivial/tri-clear.c
index f49186b..e52ed81 100644
--- a/progs/trivial/tri-clear.c
+++ b/progs/trivial/tri-clear.c
@@ -63,7 +63,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-clip.c b/progs/trivial/tri-clip.c
index e1deca1..3e3879c 100644
--- a/progs/trivial/tri-clip.c
+++ b/progs/trivial/tri-clip.c
@@ -56,7 +56,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
     glutPostRedisplay();
 }
diff --git a/progs/trivial/tri-cull-both.c b/progs/trivial/tri-cull-both.c
index 864be71..809599d 100644
--- a/progs/trivial/tri-cull-both.c
+++ b/progs/trivial/tri-cull-both.c
@@ -65,7 +65,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-dlist.c b/progs/trivial/tri-dlist.c
index c410be2..62d0a96 100644
--- a/progs/trivial/tri-dlist.c
+++ b/progs/trivial/tri-dlist.c
@@ -75,7 +75,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-fbo-tex.c b/progs/trivial/tri-fbo-tex.c
index 72b4cf3..8d1f871 100644
--- a/progs/trivial/tri-fbo-tex.c
+++ b/progs/trivial/tri-fbo-tex.c
@@ -189,9 +189,6 @@
 static void
 Init(int argc, char *argv[])
 {
-   static const GLfloat mat[4] = { 1.0, 0.5, 0.5, 1.0 };
-   GLint i;
-
    if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
       printf("GL_EXT_framebuffer_object not found!\n");
       exit(0);
diff --git a/progs/trivial/tri-fbo.c b/progs/trivial/tri-fbo.c
index 1ed177f..089180f 100644
--- a/progs/trivial/tri-fbo.c
+++ b/progs/trivial/tri-fbo.c
@@ -75,7 +75,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-flat-clip.c b/progs/trivial/tri-flat-clip.c
index 2aab5ba..a23f8a3 100644
--- a/progs/trivial/tri-flat-clip.c
+++ b/progs/trivial/tri-flat-clip.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-flat.c b/progs/trivial/tri-flat.c
index ea703ec..0614321 100644
--- a/progs/trivial/tri-flat.c
+++ b/progs/trivial/tri-flat.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-fog.c b/progs/trivial/tri-fog.c
index 0cea3d3..7fc254a 100644
--- a/progs/trivial/tri-fog.c
+++ b/progs/trivial/tri-fog.c
@@ -72,7 +72,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-fp-const-imm.c b/progs/trivial/tri-fp-const-imm.c
index d2df442..accea62 100644
--- a/progs/trivial/tri-fp-const-imm.c
+++ b/progs/trivial/tri-fp-const-imm.c
@@ -92,7 +92,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-fp.c b/progs/trivial/tri-fp.c
index 4d15081..6ecfef4 100644
--- a/progs/trivial/tri-fp.c
+++ b/progs/trivial/tri-fp.c
@@ -42,7 +42,7 @@
    static const char *prog1 =
       "!!ARBfp1.0\n"
       "MOV  result.color, fragment.texcoord[1];\n"
-//      "MOV  result.color, fragment.color;\n"
+      /* "MOV  result.color, fragment.color;\n" */
       "END\n";
 
 
@@ -90,7 +90,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-lit-material.c b/progs/trivial/tri-lit-material.c
index ff9fb2c..16cebb2 100644
--- a/progs/trivial/tri-lit-material.c
+++ b/progs/trivial/tri-lit-material.c
@@ -65,7 +65,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-lit.c b/progs/trivial/tri-lit.c
index 15a7ad2..26ebd99 100644
--- a/progs/trivial/tri-lit.c
+++ b/progs/trivial/tri-lit.c
@@ -65,7 +65,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-logicop-none.c b/progs/trivial/tri-logicop-none.c
index 53c2614..2b6a3d6 100644
--- a/progs/trivial/tri-logicop-none.c
+++ b/progs/trivial/tri-logicop-none.c
@@ -101,7 +101,7 @@
    glVertex3f( 0.5, -0.5, -30.0);
    glEnd();
 
-//   glLineWidth(12.0);
+   /* glLineWidth(12.0); */
 
    /* Redraw parts of the lines:
     */
diff --git a/progs/trivial/tri-logicop-xor.c b/progs/trivial/tri-logicop-xor.c
index f018a85..b8207cd 100644
--- a/progs/trivial/tri-logicop-xor.c
+++ b/progs/trivial/tri-logicop-xor.c
@@ -105,7 +105,7 @@
    glVertex3f( 0.5, -0.5, -30.0);
    glEnd();
 
-//   glLineWidth(12.0);
+   /* glLineWidth(12.0); */
 
    /* Redraw parts of the lines to remove them:
     */
diff --git a/progs/trivial/tri-multitex-vbo.c b/progs/trivial/tri-multitex-vbo.c
index e319447..ca4edaa 100644
--- a/progs/trivial/tri-multitex-vbo.c
+++ b/progs/trivial/tri-multitex-vbo.c
@@ -192,7 +192,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-orig.c b/progs/trivial/tri-orig.c
index e7cfee3..f86ac52 100644
--- a/progs/trivial/tri-orig.c
+++ b/progs/trivial/tri-orig.c
@@ -51,7 +51,7 @@
 
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
-/*     glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); */
+    glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0);
     glMatrixMode(GL_MODELVIEW);
 }
 
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
@@ -74,11 +74,11 @@
 
    glBegin(GL_TRIANGLES);
    glColor3f(0,0,.7); 
-   glVertex3f( 0.9, -0.9, -0.0);
+   glVertex3f( 0.9, -0.9, -30.0);
    glColor3f(.8,0,0); 
-   glVertex3f( 0.9,  0.9, -0.0);
+   glVertex3f( 0.9,  0.9, -30.0);
    glColor3f(0,.9,0); 
-   glVertex3f(-0.9,  0.0, -0.0);
+   glVertex3f(-0.9,  0.0, -30.0);
    glEnd();
 
    glFlush();
@@ -119,7 +119,7 @@
 
     glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
 
-    type = GLUT_RGB | GLUT_ALPHA;
+    type = GLUT_RGB;
     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
     glutInitDisplayMode(type);
 
diff --git a/progs/trivial/tri-query.c b/progs/trivial/tri-query.c
index 94956a8..8898f18 100644
--- a/progs/trivial/tri-query.c
+++ b/progs/trivial/tri-query.c
@@ -72,7 +72,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-scissor-tri.c b/progs/trivial/tri-scissor-tri.c
index 608ebf2..d65502d 100644
--- a/progs/trivial/tri-scissor-tri.c
+++ b/progs/trivial/tri-scissor-tri.c
@@ -63,7 +63,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-square.c b/progs/trivial/tri-square.c
index 0b82a1d..2014bd4 100644
--- a/progs/trivial/tri-square.c
+++ b/progs/trivial/tri-square.c
@@ -63,7 +63,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-stipple.c b/progs/trivial/tri-stipple.c
index aa94fa2..15a08fe 100644
--- a/progs/trivial/tri-stipple.c
+++ b/progs/trivial/tri-stipple.c
@@ -77,7 +77,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-tex-3d.c b/progs/trivial/tri-tex-3d.c
index 3ccbe12..073a080 100644
--- a/progs/trivial/tri-tex-3d.c
+++ b/progs/trivial/tri-tex-3d.c
@@ -97,7 +97,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-tex.c b/progs/trivial/tri-tex.c
index 56afb47..244e154 100644
--- a/progs/trivial/tri-tex.c
+++ b/progs/trivial/tri-tex.c
@@ -94,7 +94,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-tri.c b/progs/trivial/tri-tri.c
index f996bd0..7bf4007 100644
--- a/progs/trivial/tri-tri.c
+++ b/progs/trivial/tri-tri.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-unfilled-clip.c b/progs/trivial/tri-unfilled-clip.c
index 2fd894a..585919e 100644
--- a/progs/trivial/tri-unfilled-clip.c
+++ b/progs/trivial/tri-unfilled-clip.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-unfilled-edgeflag.c b/progs/trivial/tri-unfilled-edgeflag.c
index 11c21d1..f536f64 100644
--- a/progs/trivial/tri-unfilled-edgeflag.c
+++ b/progs/trivial/tri-unfilled-edgeflag.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-unfilled-point.c b/progs/trivial/tri-unfilled-point.c
index 750a254..11e276e 100644
--- a/progs/trivial/tri-unfilled-point.c
+++ b/progs/trivial/tri-unfilled-point.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-unfilled-smooth.c b/progs/trivial/tri-unfilled-smooth.c
index eddae17..fa31667 100644
--- a/progs/trivial/tri-unfilled-smooth.c
+++ b/progs/trivial/tri-unfilled-smooth.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-unfilled-tri-lit.c b/progs/trivial/tri-unfilled-tri-lit.c
index 1d42b40..d6baeb4 100644
--- a/progs/trivial/tri-unfilled-tri-lit.c
+++ b/progs/trivial/tri-unfilled-tri-lit.c
@@ -65,7 +65,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-unfilled-tri.c b/progs/trivial/tri-unfilled-tri.c
index 695cc89..75a70b8 100644
--- a/progs/trivial/tri-unfilled-tri.c
+++ b/progs/trivial/tri-unfilled-tri.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-unfilled-userclip-stip.c b/progs/trivial/tri-unfilled-userclip-stip.c
index ddc0dff..02bfa92 100644
--- a/progs/trivial/tri-unfilled-userclip-stip.c
+++ b/progs/trivial/tri-unfilled-userclip-stip.c
@@ -67,7 +67,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-unfilled-userclip.c b/progs/trivial/tri-unfilled-userclip.c
index 0dec0bf..11e53fc 100644
--- a/progs/trivial/tri-unfilled-userclip.c
+++ b/progs/trivial/tri-unfilled-userclip.c
@@ -66,7 +66,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-unfilled.c b/progs/trivial/tri-unfilled.c
index b98cb9a..afa1058 100644
--- a/progs/trivial/tri-unfilled.c
+++ b/progs/trivial/tri-unfilled.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-userclip.c b/progs/trivial/tri-userclip.c
index 8f37e0f..5651c73 100644
--- a/progs/trivial/tri-userclip.c
+++ b/progs/trivial/tri-userclip.c
@@ -66,7 +66,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-z-9.c b/progs/trivial/tri-z-9.c
index 099e89f..37b9e2f 100644
--- a/progs/trivial/tri-z-9.c
+++ b/progs/trivial/tri-z-9.c
@@ -61,7 +61,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-z-eq.c b/progs/trivial/tri-z-eq.c
index b81c992..6bdac47 100644
--- a/progs/trivial/tri-z-eq.c
+++ b/progs/trivial/tri-z-eq.c
@@ -61,7 +61,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tri-z.c b/progs/trivial/tri-z.c
index 014aaa0..092249d 100644
--- a/progs/trivial/tri-z.c
+++ b/progs/trivial/tri-z.c
@@ -101,7 +101,7 @@
    glEnd();
 }
 
-void display(void)
+static void display(void)
 {
    printf("GL_CLEAR_DEPTH = %.2f,  GL_DEPTH_FUNC = %s,  DepthRange(%.1f, %.1f)\n",
           clearVal, funcs[curFunc].str, minZ, maxZ);
@@ -124,7 +124,7 @@
    glFlush();
 }
 
-void reshape(int w, int h)
+static void reshape(int w, int h)
 {
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
@@ -136,7 +136,7 @@
 }
 
 /* ARGSUSED1 */
-void keyboard(unsigned char key, int x, int y)
+static void keyboard(unsigned char key, int x, int y)
 {
    switch (key) {
       case 'n':
diff --git a/progs/trivial/trifan-flat-clip.c b/progs/trivial/trifan-flat-clip.c
index 199f91a..89bc471 100644
--- a/progs/trivial/trifan-flat-clip.c
+++ b/progs/trivial/trifan-flat-clip.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/trifan-flat-unfilled-clip.c b/progs/trivial/trifan-flat-unfilled-clip.c
index ea3e155..3a1a226 100644
--- a/progs/trivial/trifan-flat-unfilled-clip.c
+++ b/progs/trivial/trifan-flat-unfilled-clip.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/trifan-flat.c b/progs/trivial/trifan-flat.c
index d69b488..d25abdf 100644
--- a/progs/trivial/trifan-flat.c
+++ b/progs/trivial/trifan-flat.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/trifan-unfilled.c b/progs/trivial/trifan-unfilled.c
index 91447e4..2e3ff82 100644
--- a/progs/trivial/trifan-unfilled.c
+++ b/progs/trivial/trifan-unfilled.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/trifan.c b/progs/trivial/trifan.c
index 84eb417..b8a7615 100644
--- a/progs/trivial/trifan.c
+++ b/progs/trivial/trifan.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tristrip-clip.c b/progs/trivial/tristrip-clip.c
index 343e293..4e6ee1f 100644
--- a/progs/trivial/tristrip-clip.c
+++ b/progs/trivial/tristrip-clip.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tristrip-flat.c b/progs/trivial/tristrip-flat.c
index 02da97e..a90b8b6 100644
--- a/progs/trivial/tristrip-flat.c
+++ b/progs/trivial/tristrip-flat.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/tristrip.c b/progs/trivial/tristrip.c
index 77bf2fa..29915ff 100644
--- a/progs/trivial/tristrip.c
+++ b/progs/trivial/tristrip.c
@@ -62,7 +62,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/vbo-drawarrays.c b/progs/trivial/vbo-drawarrays.c
index c29954b..cb26e84 100644
--- a/progs/trivial/vbo-drawarrays.c
+++ b/progs/trivial/vbo-drawarrays.c
@@ -83,7 +83,7 @@
 
    glEnable(GL_VERTEX_PROGRAM_ARB);
 
-//   glDrawArrays( GL_TRIANGLES, 0, 3 );
+   /* glDrawArrays( GL_TRIANGLES, 0, 3 ); */
    glDrawArrays( GL_TRIANGLES, 1, 3 );
 
    glFlush(); 
diff --git a/progs/trivial/vbo-noninterleaved.c b/progs/trivial/vbo-noninterleaved.c
index 0672ca5..f7c42a8 100644
--- a/progs/trivial/vbo-noninterleaved.c
+++ b/progs/trivial/vbo-noninterleaved.c
@@ -87,8 +87,8 @@
 
    glEnable(GL_VERTEX_PROGRAM_ARB);
 
-//   glDrawArrays( GL_TRIANGLES, 0, 3 );
-//   glDrawArrays( GL_TRIANGLES, 1, 3 );
+   /* glDrawArrays( GL_TRIANGLES, 0, 3 ); */
+   /* glDrawArrays( GL_TRIANGLES, 1, 3 ); */
    glDrawArrays( GL_QUADS, 0, 4 );
 
    glFlush(); 
diff --git a/progs/trivial/vbo-tri.c b/progs/trivial/vbo-tri.c
new file mode 100644
index 0000000..d4cba14
--- /dev/null
+++ b/progs/trivial/vbo-tri.c
@@ -0,0 +1,131 @@
+/* Even simpler for many drivers than trivial/tri -- pass-through
+ * vertex shader and vertex data in a VBO.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glew.h>
+#include <GL/glut.h>
+
+
+struct {
+   GLfloat pos[4];
+   GLfloat color[4];
+} verts[] =  
+{
+   { {  -0.9, -0.9, 0.0, 1.0 },
+     {.8,0,0, 1}, 
+   },
+
+   { {  0.9,  -0.9, 0.0, 1.0 },
+     { 0, .9, 0, 1 },
+   },
+
+   { { 0,  0.9, 0.0, 1.0 },
+     {0,0,.7, 1}, 
+   },
+};
+
+GLuint arrayObj;
+
+static void Init( void )
+{
+   GLint errno;
+   GLuint prognum;
+   
+   static const char *prog1 =
+      "!!ARBvp1.0\n"
+      "MOV  result.color, vertex.color;\n"
+      "MOV  result.position, vertex.position;\n"
+      "END\n";
+
+
+   glGenProgramsARB(1, &prognum);
+
+   glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prognum);
+   glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+		      strlen(prog1), (const GLubyte *) prog1);
+
+   assert(glIsProgramARB(prognum));
+   errno = glGetError();
+   printf("glGetError = %d\n", errno);
+   if (errno != GL_NO_ERROR)
+   {
+      GLint errorpos;
+
+      glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorpos);
+      printf("errorpos: %d\n", errorpos);
+      printf("%s\n", (char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB));
+   }
+
+
+   glEnableClientState( GL_VERTEX_ARRAY );
+   glEnableClientState( GL_COLOR_ARRAY );
+
+   glGenBuffersARB(1, &arrayObj);
+   glBindBufferARB(GL_ARRAY_BUFFER_ARB, arrayObj);
+   glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts, GL_STATIC_DRAW_ARB);
+
+   glVertexPointer( 4, GL_FLOAT, sizeof(verts[0]), 0 );
+   glColorPointer( 4, GL_FLOAT, sizeof(verts[0]), (void *)(4*sizeof(float)) );
+}
+
+
+
+static void Display( void )
+{
+   glClearColor(0.3, 0.3, 0.3, 1);
+   glClear( GL_COLOR_BUFFER_BIT );
+
+   glEnable(GL_VERTEX_PROGRAM_NV);
+   glDrawArrays( GL_TRIANGLES, 0, 3 );
+
+   glutSwapBuffers();
+}
+
+
+static void Reshape( int width, int height )
+{
+   glViewport( 0, 0, width, height );
+   glMatrixMode( GL_PROJECTION );
+   glLoadIdentity();
+   glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0);
+   glMatrixMode( GL_MODELVIEW );
+   glLoadIdentity();
+   /*glTranslatef( 0.0, 0.0, -15.0 );*/
+}
+
+
+static void Key( unsigned char key, int x, int y )
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+      case 27:
+         exit(0);
+         break;
+   }
+   glutPostRedisplay();
+}
+
+
+
+
+int main( int argc, char *argv[] )
+{
+   glutInit( &argc, argv );
+   glutInitWindowPosition( 0, 0 );
+   glutInitWindowSize( 250, 250 );
+   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
+   glutCreateWindow(argv[0]);
+   glewInit();
+   glutReshapeFunc( Reshape );
+   glutKeyboardFunc( Key );
+   glutDisplayFunc( Display );
+   Init();
+   glutMainLoop();
+   return 0;
+}
diff --git a/progs/trivial/vp-tri-cb-pos.c b/progs/trivial/vp-tri-cb-pos.c
index 42bf980..9cbc4d1 100644
--- a/progs/trivial/vp-tri-cb-pos.c
+++ b/progs/trivial/vp-tri-cb-pos.c
@@ -81,7 +81,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/vp-tri-cb-tex.c b/progs/trivial/vp-tri-cb-tex.c
index 8290226..e543e2e 100644
--- a/progs/trivial/vp-tri-cb-tex.c
+++ b/progs/trivial/vp-tri-cb-tex.c
@@ -114,7 +114,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/trivial/vp-tri-invariant.c b/progs/trivial/vp-tri-invariant.c
index ff24139..4dbe95e 100644
--- a/progs/trivial/vp-tri-invariant.c
+++ b/progs/trivial/vp-tri-invariant.c
@@ -69,7 +69,7 @@
       case 27:
 	exit(1);
       default:
-	return;
+	break;
     }
 
     glutPostRedisplay();
diff --git a/progs/util/readtex.c b/progs/util/readtex.c
index 8e923b6..f6f5114 100644
--- a/progs/util/readtex.c
+++ b/progs/util/readtex.c
@@ -9,6 +9,7 @@
 
 #include <GL/gl.h>
 #include <GL/glu.h>
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h> 
 #include <string.h>
@@ -89,6 +90,7 @@
    rawImageRec *raw;
    GLenum swapFlag;
    int x;
+   size_t result;
 
    endianTest.testWord = 1;
    if (endianTest.testByte[0] == 1) {
@@ -109,14 +111,21 @@
          raw->file = fopen(baseName + 1, "rb");
       if(raw->file == NULL) {
          perror(fileName);
+         free(raw);
          return NULL;
       }
    }
 
-   fread(raw, 1, 12, raw->file);
+   result = fread(raw, 1, 12, raw->file);
+   assert(result == 12);
 
    if (swapFlag) {
-      ConvertShort(&raw->imagic, 6);
+      ConvertShort(&raw->imagic, 1);
+      ConvertShort(&raw->type, 1);
+      ConvertShort(&raw->dim, 1);
+      ConvertShort(&raw->sizeX, 1);
+      ConvertShort(&raw->sizeY, 1);
+      ConvertShort(&raw->sizeZ, 1);
    }
 
    raw->tmp = (unsigned char *)malloc(raw->sizeX*256);
@@ -129,6 +138,12 @@
    if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL ||
        raw->tmpB == NULL) {
       fprintf(stderr, "Out of memory!\n");
+      free(raw->tmp);
+      free(raw->tmpR);
+      free(raw->tmpG);
+      free(raw->tmpB);
+      free(raw->tmpA);
+      free(raw);
       return NULL;
    }
 
@@ -138,12 +153,22 @@
       raw->rowSize = (GLint *)malloc(x);
       if (raw->rowStart == NULL || raw->rowSize == NULL) {
          fprintf(stderr, "Out of memory!\n");
+         free(raw->tmp);
+         free(raw->tmpR);
+         free(raw->tmpG);
+         free(raw->tmpB);
+         free(raw->tmpA);
+         free(raw->rowStart);
+         free(raw->rowSize);
+         free(raw);
          return NULL;
       }
       raw->rleEnd = 512 + (2 * x);
       fseek(raw->file, 512, SEEK_SET);
-      fread(raw->rowStart, 1, x, raw->file);
-      fread(raw->rowSize, 1, x, raw->file);
+      result = fread(raw->rowStart, 1, x, raw->file);
+      assert(result == x);
+      result = fread(raw->rowSize, 1, x, raw->file);
+      assert(result == x);
       if (swapFlag) {
          ConvertLong(raw->rowStart, (long) (x/sizeof(GLuint)));
          ConvertLong((GLuint *)raw->rowSize, (long) (x/sizeof(GLint)));
@@ -173,11 +198,13 @@
 {
    unsigned char *iPtr, *oPtr, pixel;
    int count, done = 0;
+   size_t result;
 
    if ((raw->type & 0xFF00) == 0x0100) {
       fseek(raw->file, (long) raw->rowStart[y+z*raw->sizeY], SEEK_SET);
-      fread(raw->tmp, 1, (unsigned int)raw->rowSize[y+z*raw->sizeY],
-            raw->file);
+      result = fread(raw->tmp, 1, (unsigned int)raw->rowSize[y+z*raw->sizeY],
+                     raw->file);
+      assert(result == (unsigned int)raw->rowSize[y+z*raw->sizeY]);
       
       iPtr = raw->tmp;
       oPtr = buf;
@@ -202,7 +229,8 @@
    } else {
       fseek(raw->file, 512+(y*raw->sizeX)+(z*raw->sizeX*raw->sizeY),
             SEEK_SET);
-      fread(buf, 1, raw->sizeX, raw->file);
+      result = fread(buf, 1, raw->sizeX, raw->file);
+      assert(result == raw->sizeX);
    }
 }
 
@@ -215,6 +243,7 @@
    final->data = (unsigned char *)malloc((raw->sizeX+1)*(raw->sizeY+1)*4);
    if (final->data == NULL) {
       fprintf(stderr, "Out of memory!\n");
+      return;
    }
 
    ptr = final->data;
@@ -250,6 +279,7 @@
    final = (TK_RGBImageRec *)malloc(sizeof(TK_RGBImageRec));
    if (final == NULL) {
       fprintf(stderr, "Out of memory!\n");
+      RawImageClose(raw);
       return NULL;
    }
    final->sizeX = raw->sizeX;
@@ -305,6 +335,7 @@
       fprintf(stderr,
               "Error in LoadRGBMipmaps %d-component images not implemented\n",
               image->components );
+      FreeImage(image);
       return GL_FALSE;
    }
 
@@ -356,6 +387,7 @@
       fprintf(stderr,
               "Error in LoadRGBImage %d-component images not implemented\n",
               image->components );
+      FreeImage(image);
       return NULL;
    }
 
@@ -364,8 +396,10 @@
 
    bytes = image->sizeX * image->sizeY * image->components;
    buffer = (GLubyte *) malloc(bytes);
-   if (!buffer)
+   if (!buffer) {
+      FreeImage(image);
       return NULL;
+   }
 
    memcpy( (void *) buffer, (void *) image->data, bytes );
 
@@ -438,6 +472,7 @@
       fprintf(stderr,
               "Error in LoadYUVImage %d-component images not implemented\n",
               image->components );
+      FreeImage(image);
       return NULL;
    }
 
diff --git a/progs/util/shaderutil.c b/progs/util/shaderutil.c
index af50d64..2f44c38 100644
--- a/progs/util/shaderutil.c
+++ b/progs/util/shaderutil.c
@@ -25,7 +25,11 @@
 ShadersSupported(void)
 {
    const char *version = (const char *) glGetString(GL_VERSION);
-   if (version[0] == '2' && version[1] == '.') {
+
+   /* NVIDIA binary drivers will return "3.0.0", and they clearly support
+    * shaders.
+    */
+   if (version[0] >= '2' && version[1] == '.') {
       return GL_TRUE;
    }
    else if (glutExtensionSupported("GL_ARB_vertex_shader")
@@ -34,7 +38,8 @@
       fprintf(stderr, "Warning: Trying ARB GLSL instead of OpenGL 2.x.  This may not work.\n");
       return GL_TRUE;
    }
-   return GL_TRUE;
+   fprintf(stderr, "Sorry, GLSL not supported with this OpenGL.\n");
+   return GL_FALSE;
 }
 
 
@@ -95,6 +100,7 @@
       shader = CompileShaderText(shaderType, buffer);
    }
    else {
+      fclose(f);
       free(buffer);
       return 0;
    }
diff --git a/progs/vp/SConscript b/progs/vp/SConscript
index 640c5dd..787cb79 100644
--- a/progs/vp/SConscript
+++ b/progs/vp/SConscript
@@ -1,13 +1,6 @@
-Import('env')
+Import('*')
 
-if not env['GLUT']:
-    Return()
-
-env = env.Clone()
-
-env.Prepend(LIBS = ['$GLUT_LIB'])
-
-env.Program(
+progs_env.Program(
         target = 'vp-tris',
         source = ['vp-tris.c'],
     )
diff --git a/progs/vp/add-param-imm.txt b/progs/vp/add-param-imm.txt
new file mode 100644
index 0000000..90bcf96
--- /dev/null
+++ b/progs/vp/add-param-imm.txt
@@ -0,0 +1,7 @@
+!!ARBvp1.0
+TEMP R0;
+PARAM Emission = state.material.emission; 
+ADD R0, vertex.color, {-0.5}.x;
+ADD result.color, R0, Emission.w;
+MOV  result.position, vertex.position;
+END
diff --git a/progs/vp/vp-tris.c b/progs/vp/vp-tris.c
index 1356242..09236c2 100644
--- a/progs/vp/vp-tris.c
+++ b/progs/vp/vp-tris.c
@@ -96,12 +96,15 @@
       exit(1);
    }
 
-   sz = (GLuint) fread(buf, 1, sizeof(buf), f);
+   sz = (GLuint) fread(buf, 1, sizeof(buf) - 1, f);
+   buf[sizeof(buf) - 1] = '\0';
    if (!feof(f)) {
       fprintf(stderr, "file too long\n");
+      fclose(f);
       exit(1);
    }
 
+   fclose(f);
    fprintf(stderr, "%.*s\n", sz, buf);
 
    if (strncmp( buf, "!!VP", 4 ) == 0) {
diff --git a/progs/vpglsl/SConscript b/progs/vpglsl/SConscript
index 640c5dd..787cb79 100644
--- a/progs/vpglsl/SConscript
+++ b/progs/vpglsl/SConscript
@@ -1,13 +1,6 @@
-Import('env')
+Import('*')
 
-if not env['GLUT']:
-    Return()
-
-env = env.Clone()
-
-env.Prepend(LIBS = ['$GLUT_LIB'])
-
-env.Program(
+progs_env.Program(
         target = 'vp-tris',
         source = ['vp-tris.c'],
     )
diff --git a/progs/vpglsl/psiz-mul.glsl b/progs/vpglsl/psiz-mul.glsl
index 77f4a46..d2a90d8 100644
--- a/progs/vpglsl/psiz-mul.glsl
+++ b/progs/vpglsl/psiz-mul.glsl
@@ -1,6 +1,6 @@
 
 void main() {
     gl_FrontColor = gl_Color;
-    gl_PointSize = 10 * gl_Color.x;
+    gl_PointSize = 10.0 * gl_Color.x;
     gl_Position = gl_Vertex;
 }
diff --git a/progs/vpglsl/vp-tris.c b/progs/vpglsl/vp-tris.c
index b2b0508..6a1fa3d 100644
--- a/progs/vpglsl/vp-tris.c
+++ b/progs/vpglsl/vp-tris.c
@@ -84,9 +84,9 @@
 static void setup_uniforms()
 {
    {
-      GLuint loc1f = glGetUniformLocationARB(program, "Offset1f");
-      GLuint loc2f = glGetUniformLocationARB(program, "Offset2f");
-      GLuint loc4f = glGetUniformLocationARB(program, "Offset4f");
+      GLint loc1f = glGetUniformLocationARB(program, "Offset1f");
+      GLint loc2f = glGetUniformLocationARB(program, "Offset2f");
+      GLint loc4f = glGetUniformLocationARB(program, "Offset4f");
       GLfloat vecKer[] =
          { 1.0, 0.0, 0.0,  1.0,
            0.0, 1.0, 0.0,  1.0,
@@ -105,9 +105,9 @@
    }
 
    {
-      GLuint loc1f = glGetUniformLocationARB(program, "KernelValue1f");
-      GLuint loc2f = glGetUniformLocationARB(program, "KernelValue2f");
-      GLuint loc4f = glGetUniformLocationARB(program, "KernelValue4f");
+      GLint loc1f = glGetUniformLocationARB(program, "KernelValue1f");
+      GLint loc2f = glGetUniformLocationARB(program, "KernelValue2f");
+      GLint loc4f = glGetUniformLocationARB(program, "KernelValue4f");
       GLfloat vecKer[] =
          { 1.0, 0.0, 0.0,  0.25,
            0.0, 1.0, 0.0,  0.25,
diff --git a/progs/wgl/SConscript b/progs/wgl/SConscript
index 31f6167..248cc53 100644
--- a/progs/wgl/SConscript
+++ b/progs/wgl/SConscript
@@ -1,25 +1,17 @@
 Import('*')
 
-if env['platform'] != 'windows':
+if progs_env['platform'] != 'windows':
     Return()
 
-env = env.Clone()
-
-env.Append(LIBS = [
-    'kernel32',
-    'user32',
-    'gdi32',
-])
-
 progs = [
     'sharedtex_mt',
     'wglthreads',
 ]
 
 for prog in progs:
-    env.Program(
+    progs_env.Program(
         target = prog,
         source = prog + '/' + prog + '.c',
     )
 
-env.Program('wglinfo', ['wglinfo.c'])
+progs_env.Program('wglinfo', ['wglinfo.c'])
diff --git a/progs/xdemos/.gitignore b/progs/xdemos/.gitignore
index 1b9b3a8..5ae0f5a 100644
--- a/progs/xdemos/.gitignore
+++ b/progs/xdemos/.gitignore
@@ -26,3 +26,4 @@
 xfont
 xrotfontdemo
 yuvrect_client
+msctest
diff --git a/progs/xdemos/Makefile b/progs/xdemos/Makefile
index 53e1c54..f866a32 100644
--- a/progs/xdemos/Makefile
+++ b/progs/xdemos/Makefile
@@ -8,6 +8,9 @@
 
 LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
 
+# Add X11 and pthread libs to satisfy GNU gold.
+APP_LIB_DEPS += -lX11 -lpthread
+
 LIBS = -L$(TOP)/$(LIB_DIR) -l$(GL_LIB) $(APP_LIB_DEPS)
 
 PROGS = \
@@ -26,6 +29,7 @@
 	glxsnoop \
 	glxswapcontrol \
 	manywin \
+	msctest \
 	multictx \
 	offset \
 	overlay \
diff --git a/progs/xdemos/corender.c b/progs/xdemos/corender.c
index f2b8145..640c902 100644
--- a/progs/xdemos/corender.c
+++ b/progs/xdemos/corender.c
@@ -55,6 +55,7 @@
 
       printf("Waiting for connection from another 'corender'\n");
       Sock = AcceptConnection(k);
+      assert(Sock != -1);
 
       printf("Got connection, sending windowID\n");
 
@@ -186,7 +187,7 @@
        * Without this glClear(), depth buffer for the second process
        * is pretty much broken.
        */
-      //glClear(GL_DEPTH_BUFFER_BIT);
+      /* glClear(GL_DEPTH_BUFFER_BIT); */
 
       glPushMatrix();
       glTranslatef(1, 0, 0);
diff --git a/progs/xdemos/glsync.c b/progs/xdemos/glsync.c
index da87306..c00ba9e 100644
--- a/progs/xdemos/glsync.c
+++ b/progs/xdemos/glsync.c
@@ -59,6 +59,7 @@
 
 void (*video_sync_get)();
 void (*video_sync)();
+void (*swap_interval)();
 
 static int GLXExtensionSupported(Display *dpy, const char *extension)
 {
@@ -84,12 +85,12 @@
 
 extern char *optarg;
 extern int optind, opterr, optopt;
-static char optstr[] = "w:h:s:v";
+static char optstr[] = "w:h:s:vi:";
 
 enum sync_type {
 	none = 0,
 	sgi_video_sync,
-	buffer_swap,
+	buffer_swap
 };
 
 static void usage(char *name)
@@ -100,6 +101,7 @@
 	printf("\t\tn: none\n");
 	printf("\t\ts: SGI video sync extension\n");
 	printf("\t\tb: buffer swap\n");
+	printf("\t-i<swap interval>\n");
 	printf("\t-v: verbose (print count)\n");
 	exit(-1);
 }
@@ -109,16 +111,28 @@
 	Display *disp;
 	XVisualInfo *pvi;
 	XSetWindowAttributes swa;
-	int attrib[14];
 	GLint last_val = -1, count = 0;
 	Window winGL;
 	GLXContext context;
 	int dummy;
 	Atom wmDelete;
 	enum sync_type waitforsync = none;
-	int width = 500, height = 500, verbose = 0,
-		countonly = 0;
+	int width = 500, height = 500, verbose = 0, interval = 1;
 	int c, i = 1;
+	int ret;
+	int attribs[] = { GLX_RGBA,
+                     GLX_RED_SIZE, 1,
+                     GLX_GREEN_SIZE, 1,
+                     GLX_BLUE_SIZE, 1,
+                     None };
+	int db_attribs[] = { GLX_RGBA,
+                     GLX_RED_SIZE, 1,
+                     GLX_GREEN_SIZE, 1,
+                     GLX_BLUE_SIZE, 1,
+                     GLX_DOUBLEBUFFER,
+                     GLX_DEPTH_SIZE, 1,
+                     None };
+	XSizeHints sizehints;
 
 	opterr = 0;
 	while ((c = getopt(argc, argv, optstr)) != -1) {
@@ -148,6 +162,9 @@
 		case 'v':
 			verbose = 1;
 			break;
+		case 'i':
+			interval = atoi(optarg);
+			break;
 		default:
 			usage(argv[0]);
 			break;
@@ -170,34 +187,17 @@
 		return -1;
 	}
 
-	attrib[0] = GLX_RGBA;
-	attrib[1] = 1;
-	attrib[2] = GLX_RED_SIZE;
-	attrib[3] = 1;
-	attrib[4] = GLX_GREEN_SIZE;
-	attrib[5] = 1;
-	attrib[6] = GLX_BLUE_SIZE;
-	attrib[7] = 1;
-	if (waitforsync != buffer_swap)
-		attrib[8] = None;
-	else {
-		attrib[8] = GLX_DOUBLEBUFFER;
-		attrib[9] = 1;
-		attrib[10] = None;
+	if (waitforsync != buffer_swap) {
+		pvi = glXChooseVisual(disp, DefaultScreen(disp), attribs);
+	} else {
+		pvi = glXChooseVisual(disp, DefaultScreen(disp), db_attribs);
 	}
 
-	pvi = glXChooseVisual(disp, DefaultScreen(disp), attrib);
 	if (!pvi) {
 		fprintf(stderr, "failed to choose visual, exiting\n");
 		return -1;
 	}
 
-	context = glXCreateContext(disp, pvi, None, GL_TRUE);
-	if (!context) {
-		fprintf(stderr, "failed to create glx context\n");
-		return -1;
-	}
-
 	pvi->screen = DefaultScreen(disp);
 
 	swa.colormap = XCreateColormap(disp, RootWindow(disp, pvi->screen),
@@ -217,24 +217,58 @@
         wmDelete = XInternAtom(disp, "WM_DELETE_WINDOW", True);
         XSetWMProtocols(disp, winGL, &wmDelete, 1);
 
+	sizehints.x = 0;
+	sizehints.y = 0;
+	sizehints.width  = width;
+	sizehints.height = height;
+	sizehints.flags = USSize | USPosition;
+
+	XSetNormalHints(disp, winGL, &sizehints);
 	XSetStandardProperties(disp, winGL, "glsync test", "glsync text",
-			       None, NULL, 0, NULL);
+			       None, NULL, 0, &sizehints);
 
-	XMapRaised(disp, winGL);
+	context = glXCreateContext(disp, pvi, NULL, GL_TRUE);
+	if (!context) {
+		fprintf(stderr, "failed to create glx context\n");
+		return -1;
+	}
 
-	glXMakeCurrent(disp, winGL, context);
+	XMapWindow(disp, winGL);
+	ret = glXMakeCurrent(disp, winGL, context);
+	if (ret) {
+		fprintf(stderr, "failed to make context current: %d\n", ret);
+	}
 
 	video_sync_get = glXGetProcAddress((unsigned char *)"glXGetVideoSyncSGI");
 	video_sync = glXGetProcAddress((unsigned char *)"glXWaitVideoSyncSGI");
 
-	if (!video_sync_get || !video_sync) {
+	swap_interval = glXGetProcAddress((unsigned char *)"glXSwapIntervalSGI");
+
+	if (!video_sync_get || !video_sync || !swap_interval) {
 		fprintf(stderr, "failed to get sync functions\n");
 		return -1;
 	}
 
+	if (waitforsync == buffer_swap) {
+		swap_interval(interval);
+		fprintf(stderr, "set swap interval to %d\n", interval);
+	}
 	video_sync_get(&count);
 	count++;
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 	while (i++) {
+		/* Alternate colors to make tearing obvious */
+		if (i & 1) {
+			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+			glColor3f(1.0f, 1.0f, 1.0f);
+		} else {
+			glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
+			glColor3f(1.0f, 0.0f, 0.0f);
+		}
+
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+		glRectf(0, 0, width, height);
+
 		/* Wait for vsync */
 		if (waitforsync == sgi_video_sync) {
 			if (verbose)
@@ -245,24 +279,19 @@
 			if (count == last_val)
 				fprintf(stderr, "error:  count didn't change: %d\n", count);
 			last_val = count;
+			glFlush();
 		} else if (waitforsync == buffer_swap) {
 			glXSwapBuffers(disp, winGL);
-		}
-
-		if (countonly) {
-			video_sync(2, 1, &count);
-			fprintf(stderr, "current count: %d\n", count);
+		} else {
+			video_sync_get(&count);
 			sleep(1);
-			continue;
+			glFinish();
 		}
 
-		/* Alternate colors to make tearing obvious */
-		if (i & 1)
-			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
-		else
-			glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
-		glClear(GL_COLOR_BUFFER_BIT);
-		glFlush();
+		if (verbose) {
+			video_sync_get(&count);
+			fprintf(stderr, "current count: %d\n", count);
+		}
 	}
 
 	XDestroyWindow(disp, winGL);
diff --git a/progs/xdemos/glxheads.c b/progs/xdemos/glxheads.c
index b1a63d3..edae0a3 100644
--- a/progs/xdemos/glxheads.c
+++ b/progs/xdemos/glxheads.c
@@ -145,14 +145,40 @@
    /* save the info for this head */
    {
       struct head *h = &Heads[NumHeads];
+      const char * tmp;
+
+      if (strlen(displayName) + 1 > sizeof(h->DisplayName)) {
+         Error(displayName, "displayName string length overflow");
+         return NULL;
+      }
       strcpy(h->DisplayName, displayName);
+
       h->Dpy = dpy;
       h->Win = win;
       h->Context = ctx;
       h->Angle = 0.0;
-      strcpy(h->Version, (char *) glGetString(GL_VERSION));
-      strcpy(h->Vendor, (char *) glGetString(GL_VENDOR));
-      strcpy(h->Renderer, (char *) glGetString(GL_RENDERER));
+
+      tmp = (char *) glGetString(GL_VERSION);
+      if (strlen(tmp) + 1 > sizeof(h->Version)) {
+         Error(displayName, "GL_VERSION string length overflow");
+         return NULL;
+      }
+      strcpy(h->Version, tmp);
+
+      tmp = (char *) glGetString(GL_VENDOR);
+      if (strlen(tmp) + 1 > sizeof(h->Vendor)) {
+         Error(displayName, "GL_VENDOR string length overflow");
+         return NULL;
+      }
+      strcpy(h->Vendor, tmp);
+
+      tmp = (char *) glGetString(GL_RENDERER);
+      if (strlen(tmp) + 1 > sizeof(h->Renderer)) {
+         Error(displayName, "GL_RENDERER string length overflow");
+         return NULL;
+      }
+      strcpy(h->Renderer, tmp);
+
       NumHeads++;
       return &Heads[NumHeads-1];
    }
diff --git a/progs/xdemos/glxinfo.c b/progs/xdemos/glxinfo.c
index 445d3ea..30cd568 100644
--- a/progs/xdemos/glxinfo.c
+++ b/progs/xdemos/glxinfo.c
@@ -116,7 +116,7 @@
       return;
 
    width = indent;
-   printf(indentString);
+   printf("%s", indentString);
    i = j = 0;
    while (1) {
       if (ext[j] == ' ' || ext[j] == 0) {
@@ -126,7 +126,7 @@
             /* start a new line */
             printf("\n");
             width = indent;
-            printf(indentString);
+            printf("%s", indentString);
          }
          /* print the extension name between ext[i] and ext[j] */
          while (i < j) {
@@ -401,6 +401,10 @@
 
    root = RootWindow(dpy, scrnum);
 
+   /*
+    * Find a basic GLX visual.  We'll then create a rendering context and
+    * query various info strings.
+    */
    visinfo = glXChooseVisual(dpy, scrnum, attribSingle);
    if (!visinfo)
       visinfo = glXChooseVisual(dpy, scrnum, attribDouble);
@@ -409,26 +413,29 @@
       ctx = glXCreateContext( dpy, visinfo, NULL, allowDirect );
 
 #ifdef GLX_VERSION_1_3
-   {
+   /* Try glXChooseFBConfig() if glXChooseVisual didn't work.
+    * XXX when would that happen?
+    */
+   if (!visinfo) {
       int fbAttribSingle[] = {
 	 GLX_RENDER_TYPE,   GLX_RGBA_BIT,
 	 GLX_RED_SIZE,      1,
 	 GLX_GREEN_SIZE,    1,
 	 GLX_BLUE_SIZE,     1,
-	 GLX_DOUBLEBUFFER,  GL_TRUE,
+	 GLX_DOUBLEBUFFER,  GL_FALSE,
 	 None };
       int fbAttribDouble[] = {
 	 GLX_RENDER_TYPE,   GLX_RGBA_BIT,
 	 GLX_RED_SIZE,      1,
 	 GLX_GREEN_SIZE,    1,
 	 GLX_BLUE_SIZE,     1,
+	 GLX_DOUBLEBUFFER,  GL_TRUE,
 	 None };
       GLXFBConfig *configs = NULL;
       int nConfigs;
 
-      if (!visinfo)
-	 configs = glXChooseFBConfig(dpy, scrnum, fbAttribSingle, &nConfigs);
-      if (!visinfo)
+      configs = glXChooseFBConfig(dpy, scrnum, fbAttribSingle, &nConfigs);
+      if (!configs)
 	 configs = glXChooseFBConfig(dpy, scrnum, fbAttribDouble, &nConfigs);
 
       if (configs) {
@@ -964,8 +971,10 @@
    /* get list of all fbconfigs on this screen */
    fbconfigs = glXGetFBConfigs(dpy, scrnum, &numFBConfigs);
 
-   if (numFBConfigs == 0)
+   if (numFBConfigs == 0) {
+      XFree(fbconfigs);
       return;
+   }
 
    printf("%d GLXFBConfigs:\n", numFBConfigs);
    if (mode == Normal)
diff --git a/progs/xdemos/glxpbdemo.c b/progs/xdemos/glxpbdemo.c
index 91fd30d..ecf318e 100644
--- a/progs/xdemos/glxpbdemo.c
+++ b/progs/xdemos/glxpbdemo.c
@@ -106,6 +106,7 @@
 
    if (0 == nConfigs || !fbConfigs) {
       printf("Error: glxChooseFBConfig failed\n");
+      XFree(fbConfigs);
       XCloseDisplay(dpy);
       return 0;
    }
diff --git a/progs/xdemos/manywin.c b/progs/xdemos/manywin.c
index ee357f3..3b0810b 100644
--- a/progs/xdemos/manywin.c
+++ b/progs/xdemos/manywin.c
@@ -177,14 +177,40 @@
    /* save the info for this head */
    {
       struct head *h = &Heads[NumHeads];
+      const char * tmp;
+
+      if (strlen(name) + 1 > sizeof(h->DisplayName)) {
+         Error(displayName, "name string overflow");
+         return NULL;
+      }
       strcpy(h->DisplayName, name);
+
       h->Dpy = dpy;
       h->Win = win;
       h->Context = ctx;
       h->Angle = 0.0;
-      strcpy(h->Version, (char *) glGetString(GL_VERSION));
-      strcpy(h->Vendor, (char *) glGetString(GL_VENDOR));
-      strcpy(h->Renderer, (char *) glGetString(GL_RENDERER));
+
+      tmp = (char *) glGetString(GL_VERSION);
+      if (strlen(tmp) + 1 > sizeof(h->Version)) {
+         Error(displayName, "GL_VERSION string overflow");
+         return NULL;
+      }
+      strcpy(h->Version, tmp);
+
+      tmp = (char *) glGetString(GL_VENDOR);
+      if (strlen(tmp) + 1 > sizeof(h->Vendor)) {
+         Error(displayName, "GL_VENDOR string overflow");
+         return NULL;
+      }
+      strcpy(h->Vendor, tmp);
+
+      tmp = (char *) glGetString(GL_RENDERER);
+      if (strlen(tmp) + 1 > sizeof(h->Renderer)) {
+         Error(displayName, "GL_RENDERER string overflow");
+         return NULL;
+      }
+      strcpy(h->Renderer, tmp);
+
       NumHeads++;
       return &Heads[NumHeads-1];
    }
diff --git a/progs/xdemos/msctest.c b/progs/xdemos/msctest.c
new file mode 100644
index 0000000..001ecf0
--- /dev/null
+++ b/progs/xdemos/msctest.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * 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, sublicense,
+ * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ *    Jesse Barnes <jesse.barnes@intel.com>
+ *
+ */
+
+/** @file msctest.c
+ * Simple test for MSC functionality.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <GL/glx.h>
+#include <GL/glxext.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+void (*get_sync_values)(Display *dpy, Window winGL, int64_t *ust, int64_t *msc, int64_t *sbc);
+void (*wait_sync)(Display *dpy, Window winGL, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc);
+
+static int GLXExtensionSupported(Display *dpy, const char *extension)
+{
+	const char *extensionsString, *client_extensions, *pos;
+
+	extensionsString = glXQueryExtensionsString(dpy, DefaultScreen(dpy));
+	client_extensions = glXGetClientString(dpy, GLX_EXTENSIONS);
+
+	pos = strstr(extensionsString, extension);
+
+	if (pos != NULL && (pos == extensionsString || pos[-1] == ' ') &&
+	    (pos[strlen(extension)] == ' ' || pos[strlen(extension)] == '\0'))
+		return 1;
+
+	pos = strstr(client_extensions, extension);
+
+	if (pos != NULL && (pos == extensionsString || pos[-1] == ' ') &&
+	    (pos[strlen(extension)] == ' ' || pos[strlen(extension)] == '\0'))
+		return 1;
+
+	return 0;
+}
+
+extern char *optarg;
+extern int optind, opterr, optopt;
+static char optstr[] = "v";
+
+static void usage(char *name)
+{
+	printf("usage: %s\n", name);
+	exit(-1);
+}
+
+int main(int argc, char *argv[])
+{
+	Display *disp;
+	XVisualInfo *pvi;
+	XSetWindowAttributes swa;
+	int attrib[14];
+	Window winGL;
+	GLXContext context;
+	int dummy;
+	Atom wmDelete;
+	int verbose = 0, width = 200, height = 200;
+	int c, i = 1;
+	int64_t ust, msc, sbc;
+
+	opterr = 0;
+	while ((c = getopt(argc, argv, optstr)) != -1) {
+		switch (c) {
+		case 'v':
+			verbose = 1;
+			break;
+		default:
+			usage(argv[0]);
+			break;
+		}
+	}
+
+	disp = XOpenDisplay(NULL);
+	if (!disp) {
+		fprintf(stderr, "failed to open display\n");
+		return -1;
+	}
+
+	if (!glXQueryExtension(disp, &dummy, &dummy)) {
+		fprintf(stderr, "glXQueryExtension failed\n");
+		return -1;
+	}
+
+	if (!GLXExtensionSupported(disp, "GLX_OML_sync_control")) {
+		fprintf(stderr, "GLX_OML_sync_control not supported, exiting\n");
+		return -1;
+	}
+
+	attrib[0] = GLX_RGBA;
+	attrib[1] = 1;
+	attrib[2] = GLX_RED_SIZE;
+	attrib[3] = 1;
+	attrib[4] = GLX_GREEN_SIZE;
+	attrib[5] = 1;
+	attrib[6] = GLX_BLUE_SIZE;
+	attrib[7] = 1;
+	attrib[8] = GLX_DOUBLEBUFFER;
+	attrib[9] = 1;
+	attrib[10] = None;
+
+	pvi = glXChooseVisual(disp, DefaultScreen(disp), attrib);
+	if (!pvi) {
+		fprintf(stderr, "failed to choose visual, exiting\n");
+		return -1;
+	}
+
+	context = glXCreateContext(disp, pvi, None, GL_TRUE);
+	if (!context) {
+		fprintf(stderr, "failed to create glx context\n");
+		return -1;
+	}
+
+	pvi->screen = DefaultScreen(disp);
+
+	swa.colormap = XCreateColormap(disp, RootWindow(disp, pvi->screen),
+				       pvi->visual, AllocNone);
+	swa.border_pixel = 0;
+	swa.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
+		StructureNotifyMask;
+	winGL = XCreateWindow(disp, RootWindow(disp, pvi->screen),
+			      0, 0,
+			      width, height,
+			      0, pvi->depth, InputOutput, pvi->visual,
+			      CWBorderPixel | CWColormap | CWEventMask, &swa);
+	if (!winGL) {
+		fprintf(stderr, "window creation failed\n");
+		return -1;
+	}
+        wmDelete = XInternAtom(disp, "WM_DELETE_WINDOW", True);
+        XSetWMProtocols(disp, winGL, &wmDelete, 1);
+
+	XSetStandardProperties(disp, winGL, "msc test", "msc text",
+			       None, NULL, 0, NULL);
+
+	XMapRaised(disp, winGL);
+
+	glXMakeCurrent(disp, winGL, context);
+
+	get_sync_values = glXGetProcAddress((unsigned char *)"glXGetSyncValuesOML");
+	wait_sync = glXGetProcAddress((unsigned char *)"glXWaitForMscOML");
+
+	if (!get_sync_values || !wait_sync) {
+		fprintf(stderr, "failed to get sync values function\n");
+		return -1;
+	}
+
+	while (i++) {
+		get_sync_values(disp, winGL, &ust, &msc, &sbc);
+		fprintf(stderr, "ust: %llu, msc: %llu, sbc: %llu\n", ust, msc,
+			sbc);
+
+		/* Alternate colors to make tearing obvious */
+		if (i & 1)
+			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+		else
+			glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
+		glClear(GL_COLOR_BUFFER_BIT);
+		glXSwapBuffers(disp, winGL);
+		wait_sync(disp, winGL, 0, 60, 0, &ust, &msc, &sbc);
+		fprintf(stderr,
+			"wait returned ust: %llu, msc: %llu, sbc: %llu\n",
+			ust, msc, sbc);
+		sleep(1);
+	}
+
+	XDestroyWindow(disp, winGL);
+	glXDestroyContext(disp, context);
+	XCloseDisplay(disp);
+
+	return 0;
+}
diff --git a/progs/xdemos/offset.c b/progs/xdemos/offset.c
index 6c5abf3..314a4fc 100644
--- a/progs/xdemos/offset.c
+++ b/progs/xdemos/offset.c
@@ -294,6 +294,7 @@
 	    default:
 		break;
 	    }
+	    break;
 	case ButtonPress:
 	    prevx = event.xbutton.x;
 	    prevy = event.xbutton.y;
diff --git a/progs/xdemos/pbdemo.c b/progs/xdemos/pbdemo.c
index 2573209..277df72 100644
--- a/progs/xdemos/pbdemo.c
+++ b/progs/xdemos/pbdemo.c
@@ -131,6 +131,7 @@
       fbConfigs = ChooseFBConfig(dpy, screen, fbAttribs[attempt], &nConfigs);
       if (nConfigs==0 || !fbConfigs) {
          printf("Note: glXChooseFBConfig(%s) failed\n", fbString[attempt]);
+         XFree(fbConfigs);
          continue;
       }
 
diff --git a/progs/xdemos/pbinfo.c b/progs/xdemos/pbinfo.c
index b43adf1..edfa9c1 100644
--- a/progs/xdemos/pbinfo.c
+++ b/progs/xdemos/pbinfo.c
@@ -27,6 +27,7 @@
    fbConfigs = GetAllFBConfigs(dpy, screen, &nConfigs);
    if (!nConfigs || !fbConfigs) {
       printf("Error: glxGetFBConfigs failed\n");
+      XFree(fbConfigs);
       return;
    }
 
diff --git a/progs/xdemos/sharedtex_mt.c b/progs/xdemos/sharedtex_mt.c
index 07c1bfc..a90903a 100644
--- a/progs/xdemos/sharedtex_mt.c
+++ b/progs/xdemos/sharedtex_mt.c
@@ -174,6 +174,10 @@
    {
       static int id = 0;
       struct window *h = &Windows[NumWindows];
+      if (strlen(displayName) + 1 > sizeof(h->DisplayName)) {
+         Error(displayName, "string overflow");
+         return NULL;
+      }
       strcpy(h->DisplayName, displayName);
       h->Dpy = dpy;
       h->Win = win;
@@ -447,7 +451,7 @@
    const char *dpyName = XDisplayName(NULL);
    pthread_t t0, t1, t2, t3;
    struct thread_init_arg tia0, tia1, tia2, tia3;
-   struct window *h0, *h1, *h2, *h3;
+   struct window *h0;
 
    XInitThreads();
 
@@ -462,9 +466,9 @@
 
    /* four windows and contexts sharing display lists and texture objects */
    h0 = AddWindow(gDpy, dpyName,  10,  10, gCtx);
-   h1 = AddWindow(gDpy, dpyName, 330,  10, gCtx);
-   h2 = AddWindow(gDpy, dpyName,  10, 350, gCtx);
-   h3 = AddWindow(gDpy, dpyName, 330, 350, gCtx);
+   (void) AddWindow(gDpy, dpyName, 330,  10, gCtx);
+   (void) AddWindow(gDpy, dpyName,  10, 350, gCtx);
+   (void) AddWindow(gDpy, dpyName, 330, 350, gCtx);
 
    if (!glXMakeCurrent(gDpy, h0->Win, gCtx)) {
       Error(dpyName, "glXMakeCurrent failed for init thread.");
diff --git a/scons/custom.py b/scons/custom.py
new file mode 100644
index 0000000..572b963
--- /dev/null
+++ b/scons/custom.py
@@ -0,0 +1,167 @@
+"""custom
+
+Custom builders and methods.
+
+"""
+
+#
+# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+# 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.
+#
+
+
+import os
+import os.path
+import re
+
+import SCons.Action
+import SCons.Builder
+import SCons.Scanner
+
+import fixes
+
+
+def quietCommandLines(env):
+    # Quiet command lines
+    # See also http://www.scons.org/wiki/HidingCommandLinesInOutput
+    env['ASCOMSTR'] = "  Assembling $SOURCE ..."
+    env['ASPPCOMSTR'] = "  Assembling $SOURCE ..."
+    env['CCCOMSTR'] = "  Compiling $SOURCE ..."
+    env['SHCCCOMSTR'] = "  Compiling $SOURCE ..."
+    env['CXXCOMSTR'] = "  Compiling $SOURCE ..."
+    env['SHCXXCOMSTR'] = "  Compiling $SOURCE ..."
+    env['ARCOMSTR'] = "  Archiving $TARGET ..."
+    env['RANLIBCOMSTR'] = "  Indexing $TARGET ..."
+    env['LINKCOMSTR'] = "  Linking $TARGET ..."
+    env['SHLINKCOMSTR'] = "  Linking $TARGET ..."
+    env['LDMODULECOMSTR'] = "  Linking $TARGET ..."
+    env['SWIGCOMSTR'] = "  Generating $TARGET ..."
+
+
+def createConvenienceLibBuilder(env):
+    """This is a utility function that creates the ConvenienceLibrary
+    Builder in an Environment if it is not there already.
+
+    If it is already there, we return the existing one.
+
+    Based on the stock StaticLibrary and SharedLibrary builders.
+    """
+
+    try:
+        convenience_lib = env['BUILDERS']['ConvenienceLibrary']
+    except KeyError:
+        action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ]
+        if env.Detect('ranlib'):
+            ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR")
+            action_list.append(ranlib_action)
+
+        convenience_lib = SCons.Builder.Builder(action = action_list,
+                                  emitter = '$LIBEMITTER',
+                                  prefix = '$LIBPREFIX',
+                                  suffix = '$LIBSUFFIX',
+                                  src_suffix = '$SHOBJSUFFIX',
+                                  src_builder = 'SharedObject')
+        env['BUILDERS']['ConvenienceLibrary'] = convenience_lib
+
+    return convenience_lib
+
+
+# TODO: handle import statements with multiple modules
+# TODO: handle from import statements
+import_re = re.compile(r'^import\s+(\S+)$', re.M)
+
+def python_scan(node, env, path):
+    # http://www.scons.org/doc/0.98.5/HTML/scons-user/c2781.html#AEN2789
+    contents = node.get_contents()
+    source_dir = node.get_dir()
+    imports = import_re.findall(contents)
+    results = []
+    for imp in imports:
+        for dir in path:
+            file = os.path.join(str(dir), imp.replace('.', os.sep) + '.py')
+            if os.path.exists(file):
+                results.append(env.File(file))
+                break
+            file = os.path.join(str(dir), imp.replace('.', os.sep), '__init__.py')
+            if os.path.exists(file):
+                results.append(env.File(file))
+                break
+    return results
+
+python_scanner = SCons.Scanner.Scanner(function = python_scan, skeys = ['.py'])
+
+
+def code_generate(env, script, target, source, command):
+    """Method to simplify code generation via python scripts.
+
+    http://www.scons.org/wiki/UsingCodeGenerators
+    http://www.scons.org/doc/0.98.5/HTML/scons-user/c2768.html
+    """
+
+    # We're generating code using Python scripts, so we have to be
+    # careful with our scons elements.  This entry represents
+    # the generator file *in the source directory*.
+    script_src = env.File(script).srcnode()
+
+    # This command creates generated code *in the build directory*.
+    command = command.replace('$SCRIPT', script_src.path)
+    code = env.Command(target, source, command)
+
+    # Explicitly mark that the generated code depends on the generator,
+    # and on implicitly imported python modules
+    path = (script_src.get_dir(),)
+    deps = [script_src]
+    deps += script_src.get_implicit_deps(env, python_scanner, path)
+    env.Depends(code, deps)
+
+    # Running the Python script causes .pyc files to be generated in the
+    # source directory.  When we clean up, they should go too. So add side
+    # effects for .pyc files
+    for dep in deps:
+        pyc = env.File(str(dep) + 'c')
+        env.SideEffect(pyc, code)
+
+    return code
+
+
+def createCodeGenerateMethod(env):
+    env.Append(SCANNERS = python_scanner)
+    env.AddMethod(code_generate, 'CodeGenerate')
+
+
+def generate(env):
+    """Common environment generation code"""
+
+    if env.get('quiet', True):
+        quietCommandLines(env)
+
+    # Custom builders and methods
+    createConvenienceLibBuilder(env)
+    createCodeGenerateMethod(env)
+
+    # for debugging
+    #print env.Dump()
+
+
+def exists(env):
+    return 1
diff --git a/scons/gallium.py b/scons/gallium.py
index 483bd5d..69a3569 100644
--- a/scons/gallium.py
+++ b/scons/gallium.py
@@ -38,116 +38,6 @@
 import SCons.Builder
 import SCons.Scanner
 
-import fixes
-
-
-def quietCommandLines(env):
-    # Quiet command lines
-    # See also http://www.scons.org/wiki/HidingCommandLinesInOutput
-    env['ASCOMSTR'] = "  Assembling $SOURCE ..."
-    env['ASPPCOMSTR'] = "  Assembling $SOURCE ..."
-    env['CCCOMSTR'] = "  Compiling $SOURCE ..."
-    env['SHCCCOMSTR'] = "  Compiling $SOURCE ..."
-    env['CXXCOMSTR'] = "  Compiling $SOURCE ..."
-    env['SHCXXCOMSTR'] = "  Compiling $SOURCE ..."
-    env['ARCOMSTR'] = "  Archiving $TARGET ..."
-    env['RANLIBCOMSTR'] = "  Indexing $TARGET ..."
-    env['LINKCOMSTR'] = "  Linking $TARGET ..."
-    env['SHLINKCOMSTR'] = "  Linking $TARGET ..."
-    env['LDMODULECOMSTR'] = "  Linking $TARGET ..."
-    env['SWIGCOMSTR'] = "  Generating $TARGET ..."
-
-
-def createConvenienceLibBuilder(env):
-    """This is a utility function that creates the ConvenienceLibrary
-    Builder in an Environment if it is not there already.
-
-    If it is already there, we return the existing one.
-
-    Based on the stock StaticLibrary and SharedLibrary builders.
-    """
-
-    try:
-        convenience_lib = env['BUILDERS']['ConvenienceLibrary']
-    except KeyError:
-        action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ]
-        if env.Detect('ranlib'):
-            ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR")
-            action_list.append(ranlib_action)
-
-        convenience_lib = SCons.Builder.Builder(action = action_list,
-                                  emitter = '$LIBEMITTER',
-                                  prefix = '$LIBPREFIX',
-                                  suffix = '$LIBSUFFIX',
-                                  src_suffix = '$SHOBJSUFFIX',
-                                  src_builder = 'SharedObject')
-        env['BUILDERS']['ConvenienceLibrary'] = convenience_lib
-
-    return convenience_lib
-
-
-# TODO: handle import statements with multiple modules
-# TODO: handle from import statements
-import_re = re.compile(r'^import\s+(\S+)$', re.M)
-
-def python_scan(node, env, path):
-    # http://www.scons.org/doc/0.98.5/HTML/scons-user/c2781.html#AEN2789
-    contents = node.get_contents()
-    source_dir = node.get_dir()
-    imports = import_re.findall(contents)
-    results = []
-    for imp in imports:
-        for dir in path:
-            file = os.path.join(str(dir), imp.replace('.', os.sep) + '.py')
-            if os.path.exists(file):
-                results.append(env.File(file))
-                break
-            file = os.path.join(str(dir), imp.replace('.', os.sep), '__init__.py')
-            if os.path.exists(file):
-                results.append(env.File(file))
-                break
-    return results
-
-python_scanner = SCons.Scanner.Scanner(function = python_scan, skeys = ['.py'])
-
-
-def code_generate(env, script, target, source, command):
-    """Method to simplify code generation via python scripts.
-
-    http://www.scons.org/wiki/UsingCodeGenerators
-    http://www.scons.org/doc/0.98.5/HTML/scons-user/c2768.html
-    """
-
-    # We're generating code using Python scripts, so we have to be
-    # careful with our scons elements.  This entry represents
-    # the generator file *in the source directory*.
-    script_src = env.File(script).srcnode()
-
-    # This command creates generated code *in the build directory*.
-    command = command.replace('$SCRIPT', script_src.path)
-    code = env.Command(target, source, command)
-
-    # Explicitly mark that the generated code depends on the generator,
-    # and on implicitly imported python modules
-    path = (script_src.get_dir(),)
-    deps = [script_src]
-    deps += script_src.get_implicit_deps(env, python_scanner, path)
-    env.Depends(code, deps)
-
-    # Running the Python script causes .pyc files to be generated in the
-    # source directory.  When we clean up, they should go too. So add side
-    # effects for .pyc files
-    for dep in deps:
-        pyc = env.File(str(dep) + 'c')
-        env.SideEffect(pyc, code)
-
-    return code
-
-
-def createCodeGenerateMethod(env):
-    env.Append(SCANNERS = python_scanner)
-    env.AddMethod(code_generate, 'CodeGenerate')
-
 
 def symlink(target, source, env):
     target = str(target[0])
@@ -156,19 +46,34 @@
         os.remove(target)
     os.symlink(os.path.basename(source), target)
 
-def install_shared_library(env, source, version = ()):
-    source = str(source[0])
+def install(env, source, subdir):
+    target_dir = os.path.join(env.Dir('#.').srcnode().abspath, env['build'], subdir)
+    env.Install(target_dir, source)
+
+def install_program(env, source):
+    install(env, source, 'bin')
+
+def install_shared_library(env, sources, version = ()):
+    install_dir = os.path.join(env.Dir('#.').srcnode().abspath, env['build'])
     version = tuple(map(str, version))
-    target_dir =  os.path.join(env.Dir('#.').srcnode().abspath, env['build'], 'lib')
-    target_name = '.'.join((str(source),) + version)
-    last = env.InstallAs(os.path.join(target_dir, target_name), source)
-    while len(version):
-        version = version[:-1]
-        target_name = '.'.join((str(source),) + version)
-        action = SCons.Action.Action(symlink, "$TARGET -> $SOURCE")
-        last = env.Command(os.path.join(target_dir, target_name), last, action) 
+    if env['SHLIBSUFFIX'] == '.dll':
+        dlls = env.FindIxes(sources, 'SHLIBPREFIX', 'SHLIBSUFFIX')
+        install(env, dlls, 'bin')
+        libs = env.FindIxes(sources, 'LIBPREFIX', 'LIBSUFFIX')
+        install(env, libs, 'lib')
+    else:
+        for source in sources:
+            target_dir =  os.path.join(install_dir, 'lib')
+            target_name = '.'.join((str(source),) + version)
+            last = env.InstallAs(os.path.join(target_dir, target_name), source)
+            while len(version):
+                version = version[:-1]
+                target_name = '.'.join((str(source),) + version)
+                action = SCons.Action.Action(symlink, "$TARGET -> $SOURCE")
+                last = env.Command(os.path.join(target_dir, target_name), last, action) 
 
 def createInstallMethods(env):
+    env.AddMethod(install_program, 'InstallProgram')
     env.AddMethod(install_shared_library, 'InstallSharedLibrary')
 
 
@@ -194,9 +99,6 @@
 def generate(env):
     """Common environment generation code"""
 
-    if env.get('quiet', True):
-        quietCommandLines(env)
-
     # Toolchain
     platform = env['platform']
     if env['toolchain'] == 'default':
@@ -236,6 +138,8 @@
     env['build'] = build_dir
     env.SConsignFile(os.path.join(build_dir, '.sconsign'))
     env.CacheDir('build/cache')
+    env['CONFIGUREDIR'] = os.path.join(build_dir, 'conf')
+    env['CONFIGURELOG'] = os.path.join(os.path.abspath(build_dir), 'config.log')
 
     # Parallel build
     if env.GetOption('num_jobs') <= 1:
@@ -257,8 +161,6 @@
             #'UNICODE',
             ('_WIN32_WINNT', '0x0501'), # minimum required OS version
             ('WINVER', '0x0501'),
-            # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx,
-            'WIN32_LEAN_AND_MEAN',
         ]
         if msvc and env['toolchain'] != 'winddk':
             cppdefines += [
@@ -366,7 +268,7 @@
         ccflags += [
             '-Wall',
             '-Wmissing-field-initializers',
-            '-Wpointer-arith',
+            '-Werror=pointer-arith',
             '-Wno-long-long',
             '-ffast-math',
             '-fmessage-length=0', # be nice to Eclipse
@@ -390,15 +292,15 @@
         else:
             ccflags += [
                 '/O2', # optimize for speed
-                #'/fp:fast', # fast floating point 
+                '/GL', # enable whole program optimization
             ]
         ccflags += [
+            '/fp:fast', # fast floating point 
             '/W3', # warning level
             #'/Wp64', # enable 64 bit porting warnings
         ]
         if env['machine'] == 'x86':
             ccflags += [
-                #'/QIfist', # Suppress _ftol
                 #'/arch:SSE2', # use the SSE2 instructions
             ]
         if platform == 'windows':
@@ -476,6 +378,11 @@
         ]
         # Handle circular dependencies in the libraries
         env['_LIBFLAGS'] = '-Wl,--start-group ' + env['_LIBFLAGS'] + ' -Wl,--end-group'
+    if msvc:
+        if not env['debug']:
+            # enable Link-time Code Generation
+            linkflags += ['/LTCG']
+            env.Append(ARFLAGS = ['/LTCG'])
     if platform == 'windows' and msvc:
         # See also:
         # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx
@@ -529,8 +436,7 @@
     env.Append(LIBS = [])
 
     # Custom builders and methods
-    createConvenienceLibBuilder(env)
-    createCodeGenerateMethod(env)
+    env.Tool('custom')
     createInstallMethods(env)
 
     # for debugging
diff --git a/scons/generic.py b/scons/generic.py
deleted file mode 100644
index 859bf2a..0000000
--- a/scons/generic.py
+++ /dev/null
@@ -1,590 +0,0 @@
-"""generic
-
-Generic tool that provides a commmon ground for all platforms.
-
-"""
-
-#
-# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
-# 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.
-#
-
-
-import os
-import os.path
-import re
-import platform as _platform
-import sys
-
-import SCons.Action
-import SCons.Builder
-import SCons.Scanner
-
-
-def quietCommandLines(env):
-    # Quiet command lines
-    # See also http://www.scons.org/wiki/HidingCommandLinesInOutput
-    env['CCCOMSTR'] = "Compiling $SOURCE ..."
-    env['CXXCOMSTR'] = "Compiling $SOURCE ..."
-    env['ARCOMSTR'] = "Archiving $TARGET ..."
-    env['RANLIBCOMSTR'] = ""
-    env['LINKCOMSTR'] = "Linking $TARGET ..."
-
-
-def createConvenienceLibBuilder(env):
-    """This is a utility function that creates the ConvenienceLibrary
-    Builder in an Environment if it is not there already.
-
-    If it is already there, we return the existing one.
-
-    Based on the stock StaticLibrary and SharedLibrary builders.
-    """
-
-    try:
-        convenience_lib = env['BUILDERS']['ConvenienceLibrary']
-    except KeyError:
-        action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ]
-        if env.Detect('ranlib'):
-            ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR")
-            action_list.append(ranlib_action)
-
-        convenience_lib = SCons.Builder.Builder(action = action_list,
-                                  emitter = '$LIBEMITTER',
-                                  prefix = '$LIBPREFIX',
-                                  suffix = '$LIBSUFFIX',
-                                  src_suffix = '$SHOBJSUFFIX',
-                                  src_builder = 'SharedObject')
-        env['BUILDERS']['ConvenienceLibrary'] = convenience_lib
-
-    return convenience_lib
-
-
-# TODO: handle import statements with multiple modules
-# TODO: handle from import statements
-import_re = re.compile(r'^import\s+(\S+)$', re.M)
-
-def python_scan(node, env, path):
-    # http://www.scons.org/doc/0.98.5/HTML/scons-user/c2781.html#AEN2789
-    contents = node.get_contents()
-    source_dir = node.get_dir()
-    imports = import_re.findall(contents)
-    results = []
-    for imp in imports:
-        for dir in path:
-            file = os.path.join(str(dir), imp.replace('.', os.sep) + '.py')
-            if os.path.exists(file):
-                results.append(env.File(file))
-                break
-            file = os.path.join(str(dir), imp.replace('.', os.sep), '__init__.py')
-            if os.path.exists(file):
-                results.append(env.File(file))
-                break
-    return results
-
-python_scanner = SCons.Scanner.Scanner(function = python_scan, skeys = ['.py'])
-
-
-def code_generate(env, script, target, source, command):
-    """Method to simplify code generation via python scripts.
-
-    http://www.scons.org/wiki/UsingCodeGenerators
-    http://www.scons.org/doc/0.98.5/HTML/scons-user/c2768.html
-    """
-
-    # We're generating code using Python scripts, so we have to be
-    # careful with our scons elements.  This entry represents
-    # the generator file *in the source directory*.
-    script_src = env.File(script).srcnode()
-
-    # This command creates generated code *in the build directory*.
-    command = command.replace('$SCRIPT', script_src.path)
-    code = env.Command(target, source, command)
-
-    # Explicitly mark that the generated code depends on the generator,
-    # and on implicitly imported python modules
-    path = (script_src.get_dir(),)
-    deps = [script_src]
-    deps += script_src.get_implicit_deps(env, python_scanner, path)
-    env.Depends(code, deps)
-
-    # Running the Python script causes .pyc files to be generated in the
-    # source directory.  When we clean up, they should go too. So add side
-    # effects for .pyc files
-    for dep in deps:
-        pyc = env.File(str(dep) + 'c')
-        env.SideEffect(pyc, code)
-
-    return code
-
-
-def createCodeGenerateMethod(env):
-    env.Append(SCANNERS = python_scanner)
-    env.AddMethod(code_generate, 'CodeGenerate')
-
-
-def symlink(target, source, env):
-    target = str(target[0])
-    source = str(source[0])
-    if os.path.islink(target) or os.path.exists(target):
-        os.remove(target)
-    os.symlink(os.path.basename(source), target)
-
-def install_shared_library(env, source, version = ()):
-    source = str(source[0])
-    version = tuple(map(str, version))
-    target_dir =  os.path.join(env.Dir('#.').srcnode().abspath, env['build'], 'lib')
-    target_name = '.'.join((str(source),) + version)
-    last = env.InstallAs(os.path.join(target_dir, target_name), source)
-    while len(version):
-        version = version[:-1]
-        target_name = '.'.join((str(source),) + version)
-        action = SCons.Action.Action(symlink, "$TARGET -> $SOURCE")
-        last = env.Command(os.path.join(target_dir, target_name), last, action) 
-
-def createInstallMethods(env):
-    env.AddMethod(install_shared_library, 'InstallSharedLibrary')
-
-
-_platform_map = {
-    'linux2': 'linux',
-    'win32': 'windows',
-}
-
-
-_machine_map = {
-	'x86': 'x86',
-	'i386': 'x86',
-	'i486': 'x86',
-	'i586': 'x86',
-	'i686': 'x86',
-	'ppc': 'ppc',
-	'x86_64': 'x86_64',
-}
-
-
-_toolchain_map = {
-    'winddk': 'winddk',
-    'wince': 'wcesdk',
-}
-
-
-_bool_map = {
-    'y': 1, 
-    'yes': 1,
-    't': 1, 
-    'true': 1, 
-    '1': 1,
-    'on': 1,
-    'all': 1, 
-    'n': 0, 
-    'no': 0, 
-    'f': 0, 
-    'false': 0, 
-    '0': 0,
-    'off': 0,
-    'none': 0,
-}
-
-
-def num_jobs():
-    try:
-        return int(os.environ['NUMBER_OF_PROCESSORS'])
-    except (ValueError, KeyError):
-        pass
-
-    try:
-        return os.sysconf('SC_NPROCESSORS_ONLN')
-    except (ValueError, OSError, AttributeError):
-        pass
-
-    try:
-        return int(os.popen2("sysctl -n hw.ncpu")[1].read())
-    except ValueError:
-        pass
-
-    return 1
-
-
-def generate(env):
-    """Common environment generation code"""
-
-    from SCons.Script import ARGUMENTS
-
-    # FIXME: this is already too late
-    #if env.get('quiet', False):
-    #    quietCommandLines(env)
-
-
-    # Platform
-    try:
-        env['platform'] = ARGUMENTS['platform']
-    except KeyError:
-        env['platform'] = _platform_map.get(sys.platform, sys.platform)
-
-    # Machine
-    try:
-        env['machine'] = ARGUMENTS['machine']
-    except KeyError:
-        env['machine'] = _machine_map.get(os.environ.get('PROCESSOR_ARCHITECTURE', _platform.machine()), 'generic')
-
-    # Toolchain
-    try:
-        env['toolchain'] = ARGUMENTS['toolchain']
-    except KeyError:
-        if env['platform'] in ('windows', 'winddk', 'wince') and sys.platform != 'win32':
-            env['toolchain'] = 'crossmingw'
-        else:
-            env['toolchain'] = _toolchain_map.get(env['platform'], 'default')
-    if env['toolchain'] == 'crossmingw' and env['machine'] not in ('generic', 'x86'):
-            env['machine'] = 'x86'
-
-    try:
-        env['MSVS_VERSION'] = ARGUMENTS['MSVS_VERSION']
-    except KeyError:
-        pass
-
-    # Build type
-    env['debug'] = _bool_map[ARGUMENTS.get('debug', 'no')]
-    env['profile'] = _bool_map[ARGUMENTS.get('profile', 'no')]
-
-    # Put build output in a separate dir, which depends on the current
-    # configuration. See also http://www.scons.org/wiki/AdvancedBuildExample
-    try:
-        env['build'] = ARGUMENTS['build']
-    except KeyError:
-        build_topdir = 'build'
-        build_subdir = env['platform']
-        if env['machine'] != 'generic':
-            build_subdir += '-' + env['machine']
-        if env['debug']:
-            build_subdir += "-debug"
-        if env['profile']:
-            build_subdir += "-profile"
-        env['build'] = os.path.join(build_topdir, build_subdir)
-    # Place the .sconsign file in the build dir too, to avoid issues with
-    # different scons versions building the same source file
-    env.SConsignFile(os.path.join(env['build'], '.sconsign'))
-
-    # Parallel build
-    if env.GetOption('num_jobs') <= 1:
-        env.SetOption('num_jobs', num_jobs())
-
-    # Summary
-    print
-    print '  platform=%s' % env['platform']
-    print '  machine=%s' % env['machine']
-    print '  toolchain=%s' % env['toolchain']
-    print '  debug=%s' % ['no', 'yes'][env['debug']]
-    print '  profile=%s' % ['no', 'yes'][env['profile']]
-    print '  build=%s' % env['build']
-    print '  %s jobs' % env.GetOption('num_jobs')
-    print
-
-    # Load tool chain
-    env.Tool(env['toolchain'])
-
-    env['gcc'] = 'gcc' in os.path.basename(env['CC']).split('-')
-    env['msvc'] = env['CC'] == 'cl'
-
-    # shortcuts
-    debug = env['debug']
-    machine = env['machine']
-    platform = env['platform']
-    x86 = env['machine'] == 'x86'
-    ppc = env['machine'] == 'ppc'
-    gcc = env['gcc']
-    msvc = env['msvc']
-
-    # C preprocessor options
-    cppdefines = []
-    if debug:
-        cppdefines += ['DEBUG']
-    else:
-        cppdefines += ['NDEBUG']
-    if env['profile']:
-        cppdefines += ['PROFILE']
-    if platform == 'windows':
-        cppdefines += [
-            'WIN32',
-            '_WINDOWS',
-            #'_UNICODE',
-            #'UNICODE',
-            # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx,
-            #'WIN32_LEAN_AND_MEAN',
-        ]
-        if msvc:
-            cppdefines += [
-                'VC_EXTRALEAN',
-                '_USE_MATH_DEFINES',
-                '_CRT_SECURE_NO_WARNINGS',
-                '_CRT_SECURE_NO_DEPRECATE',
-                '_SCL_SECURE_NO_WARNINGS',
-                '_SCL_SECURE_NO_DEPRECATE',
-            ]
-        if debug:
-            cppdefines += ['_DEBUG']
-    if platform == 'winddk':
-        # Mimic WINDDK's builtin flags. See also:
-        # - WINDDK's bin/makefile.new i386mk.inc for more info.
-        # - buildchk_wxp_x86.log files, generated by the WINDDK's build
-        # - http://alter.org.ua/docs/nt_kernel/vc8_proj/
-        cppdefines += [
-            ('_X86_', '1'),
-            ('i386', '1'),
-            'STD_CALL',
-            ('CONDITION_HANDLING', '1'),
-            ('NT_INST', '0'),
-            ('WIN32', '100'),
-            ('_NT1X_', '100'),
-            ('WINNT', '1'),
-            ('_WIN32_WINNT', '0x0501'), # minimum required OS version
-            ('WINVER', '0x0501'),
-            ('_WIN32_IE', '0x0603'),
-            ('WIN32_LEAN_AND_MEAN', '1'),
-            ('DEVL', '1'),
-            ('__BUILDMACHINE__', 'WinDDK'),
-            ('FPO', '0'),
-        ]
-        if debug:
-            cppdefines += [('DBG', 1)]
-    if platform == 'wince':
-        cppdefines += [
-            '_CRT_SECURE_NO_DEPRECATE',
-            '_USE_32BIT_TIME_T',
-            'UNICODE',
-            '_UNICODE',
-            ('UNDER_CE', '600'),
-            ('_WIN32_WCE', '0x600'),
-            'WINCEOEM',
-            'WINCEINTERNAL',
-            'WIN32',
-            'STRICT',
-            'x86',
-            '_X86_',
-            'INTERNATIONAL',
-            ('INTLMSG_CODEPAGE', '1252'),
-        ]
-    env.Append(CPPDEFINES = cppdefines)
-
-    # C preprocessor includes
-    if platform == 'winddk':
-        env.Append(CPPPATH = [
-            env['SDK_INC_PATH'],
-            env['DDK_INC_PATH'],
-            env['WDM_INC_PATH'],
-            env['CRT_INC_PATH'],
-        ])
-
-    # C compiler options
-    cflags = [] # C
-    cxxflags = [] # C++
-    ccflags = [] # C & C++
-    if gcc:
-        if debug:
-            ccflags += ['-O0', '-g3']
-        elif env['toolchain'] == 'crossmingw':
-            ccflags += ['-O0', '-g3'] # mingw 4.2.1 optimizer is broken
-        else:
-            ccflags += ['-O3', '-g0']
-        if env['machine'] == 'x86':
-            ccflags += [
-                '-m32',
-                #'-march=pentium4',
-                '-mmmx', '-msse', '-msse2', # enable SIMD intrinsics
-                #'-mfpmath=sse',
-            ]
-        if env['machine'] == 'x86_64':
-            ccflags += ['-m64']
-        # See also:
-        # - http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
-        ccflags += [
-            '-Wall',
-            '-Wmissing-field-initializers',
-            '-Wpointer-arith',
-            '-Wno-long-long',
-            '-ffast-math',
-            '-fmessage-length=0', # be nice to Eclipse
-        ]
-        cflags += [
-            '-Werror=declaration-after-statement',
-            '-Wmissing-prototypes',
-            '-std=gnu99',
-        ]
-    if msvc:
-        # See also:
-        # - http://msdn.microsoft.com/en-us/library/19z1t1wy.aspx
-        # - cl /?
-        if debug:
-            ccflags += [
-              '/Od', # disable optimizations
-              '/Oi', # enable intrinsic functions
-              '/Oy-', # disable frame pointer omission
-              '/GL-', # disable whole program optimization
-            ]
-        else:
-            ccflags += [
-              '/Ox', # maximum optimizations
-              '/Oi', # enable intrinsic functions
-              '/Ot', # favor code speed
-              #'/fp:fast', # fast floating point 
-            ]
-        ccflags += [
-            '/W3', # warning level
-            #'/Wp64', # enable 64 bit porting warnings
-        ]
-        if env['machine'] == 'x86':
-            ccflags += [
-                #'/QIfist', # Suppress _ftol
-                #'/arch:SSE2', # use the SSE2 instructions
-            ]
-        if platform == 'windows':
-            ccflags += [
-                # TODO
-            ]
-        if platform == 'winddk':
-            ccflags += [
-                '/Zl', # omit default library name in .OBJ
-                '/Zp8', # 8bytes struct member alignment
-                '/Gy', # separate functions for linker
-                '/Gm-', # disable minimal rebuild
-                '/WX', # treat warnings as errors
-                '/Gz', # __stdcall Calling convention
-                '/GX-', # disable C++ EH
-                '/GR-', # disable C++ RTTI
-                '/GF', # enable read-only string pooling
-                '/G6', # optimize for PPro, P-II, P-III
-                '/Ze', # enable extensions
-                '/Gi-', # disable incremental compilation
-                '/QIfdiv-', # disable Pentium FDIV fix
-                '/hotpatch', # prepares an image for hotpatching.
-                #'/Z7', #enable old-style debug info
-            ]
-        if platform == 'wince':
-            # See also C:\WINCE600\public\common\oak\misc\makefile.def
-            ccflags += [
-                '/Zl', # omit default library name in .OBJ
-                '/GF', # enable read-only string pooling
-                '/GR-', # disable C++ RTTI
-                '/GS', # enable security checks
-                # Allow disabling language conformance to maintain backward compat
-                #'/Zc:wchar_t-', # don't force wchar_t as native type, instead of typedef
-                #'/Zc:forScope-', # don't enforce Standard C++ for scoping rules
-                #'/wd4867',
-                #'/wd4430',
-                #'/MT',
-                #'/U_MT',
-            ]
-        # Automatic pdb generation
-        # See http://scons.tigris.org/issues/show_bug.cgi?id=1656
-        env.EnsureSConsVersion(0, 98, 0)
-        env['PDB'] = '${TARGET.base}.pdb'
-    env.Append(CCFLAGS = ccflags)
-    env.Append(CFLAGS = cflags)
-    env.Append(CXXFLAGS = cxxflags)
-
-    if env['platform'] == 'windows' and msvc:
-        # Choose the appropriate MSVC CRT
-        # http://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx
-        if env['debug']:
-            env.Append(CCFLAGS = ['/MTd'])
-            env.Append(SHCCFLAGS = ['/LDd'])
-        else:
-            env.Append(CCFLAGS = ['/MT'])
-            env.Append(SHCCFLAGS = ['/LD'])
-    
-    # Assembler options
-    if gcc:
-        if env['machine'] == 'x86':
-            env.Append(ASFLAGS = ['-m32'])
-        if env['machine'] == 'x86_64':
-            env.Append(ASFLAGS = ['-m64'])
-
-    # Linker options
-    linkflags = []
-    if gcc:
-        if env['machine'] == 'x86':
-            linkflags += ['-m32']
-        if env['machine'] == 'x86_64':
-            linkflags += ['-m64']
-    if platform == 'windows' and msvc:
-        # See also:
-        # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx
-        linkflags += [
-            '/fixed:no',
-            '/incremental:no',
-        ]
-    if platform == 'winddk':
-        linkflags += [
-            '/merge:_PAGE=PAGE',
-            '/merge:_TEXT=.text',
-            '/section:INIT,d',
-            '/opt:ref',
-            '/opt:icf',
-            '/ignore:4198,4010,4037,4039,4065,4070,4078,4087,4089,4221',
-            '/incremental:no',
-            '/fullbuild',
-            '/release',
-            '/nodefaultlib',
-            '/wx',
-            '/debug',
-            '/debugtype:cv',
-            '/version:5.1',
-            '/osversion:5.1',
-            '/functionpadmin:5',
-            '/safeseh',
-            '/pdbcompress',
-            '/stack:0x40000,0x1000',
-            '/driver',
-            '/align:0x80',
-            '/subsystem:native,5.01',
-            '/base:0x10000',
-
-            '/entry:DrvEnableDriver',
-        ]
-        if env['debug'] or env['profile']:
-            linkflags += [
-                '/MAP', # http://msdn.microsoft.com/en-us/library/k7xkk3e2.aspx
-            ]
-    if platform == 'wince':
-        linkflags += [
-            '/nodefaultlib',
-            #'/incremental:no',
-            #'/fullbuild',
-            '/entry:_DllMainCRTStartup',
-        ]
-    env.Append(LINKFLAGS = linkflags)
-
-    # Default libs
-    env.Append(LIBS = [])
-
-    # Custom builders and methods
-    createConvenienceLibBuilder(env)
-    createCodeGenerateMethod(env)
-    createInstallMethods(env)
-
-    # for debugging
-    #print env.Dump()
-
-
-def exists(env):
-    return 1
diff --git a/scons/llvm.py b/scons/llvm.py
index 73e9310..37c503e 100644
--- a/scons/llvm.py
+++ b/scons/llvm.py
@@ -58,45 +58,58 @@
 
         env.PrependENVPath('PATH', llvm_bin_dir)
 
-    if env['msvc']:
+    if env['platform'] == 'windows':
         # XXX: There is no llvm-config on Windows, so assume a standard layout
         if llvm_dir is not None:
             env.Prepend(CPPPATH = [os.path.join(llvm_dir, 'include')])
+            env.AppendUnique(CPPDEFINES = [
+                '__STDC_LIMIT_MACROS', 
+                '__STDC_CONSTANT_MACROS',
+                'HAVE_STDINT_H',
+            ])
             env.Prepend(LIBPATH = [os.path.join(llvm_dir, 'lib')])
             env.Prepend(LIBS = [
+                'LLVMX86AsmParser',
+                'LLVMX86AsmPrinter',
+                'LLVMX86CodeGen',
+                'LLVMX86Info',
+                'LLVMLinker',
+                'LLVMipo',
+                'LLVMInterpreter',
+                'LLVMInstrumentation',
+                'LLVMJIT',
+                'LLVMExecutionEngine',
+                'LLVMDebugger',
                 'LLVMBitWriter',
-                'LLVMCore',
-                'LLVMSupport',
-                'LLVMSystem',
-                'LLVMSupport',
-                'LLVMSystem',
-                'LLVMCore',
-                'LLVMCodeGen',
+                'LLVMAsmParser',
+                'LLVMArchive',
+                'LLVMBitReader',
                 'LLVMSelectionDAG',
                 'LLVMAsmPrinter',
-                'LLVMBitReader',
-                'LLVMBitWriter',
-                'LLVMTransformUtils',
-                'LLVMInstrumentation',
+                'LLVMCodeGen',
                 'LLVMScalarOpts',
-                'LLVMipo',
-                'LLVMHello',
-                'LLVMLinker',
-                'LLVMAnalysis',
+                'LLVMTransformUtils',
                 'LLVMipa',
-                'LLVMX86CodeGen',
-                'LLVMX86AsmPrinter',
-                'LLVMExecutionEngine',
-                'LLVMInterpreter',
-                'LLVMJIT',
+                'LLVMAnalysis',
                 'LLVMTarget',
-                'LLVMAsmParser',
-                'LLVMDebugger',
-                'LLVMArchive',
+                'LLVMMC',
+                'LLVMCore',
+                'LLVMSupport',
+                'LLVMSystem',
                 'imagehlp',
                 'psapi',
             ])
-            env['LLVM_VERSION'] = '2.5'
+            if env['msvc']:
+                # Some of the LLVM C headers use the inline keyword without
+                # defining it.
+                env.Append(CPPDEFINES = [('inline', '__inline')])
+                if env['debug']:
+                    # LLVM libraries are static, build with /MT, and they
+                    # automatically link agains LIBCMT. When we're doing a
+                    # debug build we'll be linking against LIBCMTD, so disable
+                    # that.
+                    env.Append(LINKFLAGS = ['/nodefaultlib:LIBCMT'])
+            env['LLVM_VERSION'] = '2.6'
         return
     elif env.Detect('llvm-config'):
         version = env.backtick('llvm-config --version').rstrip()
diff --git a/scons/mslib_sa.py b/scons/mslib_sa.py
index 50d47ee..bdc0dd9 100644
--- a/scons/mslib_sa.py
+++ b/scons/mslib_sa.py
@@ -7,7 +7,7 @@
 """
 
 #
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation
 #
 # Permission is hereby granted, free of charge, to any person obtaining
 # a copy of this software and associated documentation files (the
@@ -130,4 +130,8 @@
 def exists(env):
     return env.Detect('lib') or env.Detect('link')
 
-# vim:set ts=4 sw=4 et:
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/scons/mslink_sa.py b/scons/mslink_sa.py
index 53331de..0ecdf24 100644
--- a/scons/mslink_sa.py
+++ b/scons/mslink_sa.py
@@ -7,7 +7,7 @@
 """
 
 #
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation
 #
 # Permission is hereby granted, free of charge, to any person obtaining
 # a copy of this software and associated documentation files (the
@@ -45,9 +45,9 @@
     except (AttributeError, IndexError):
         return None
 
-def windowsShlinkTargets(target, source, env, for_signature):
+def _dllTargets(target, source, env, for_signature, paramtp):
     listCmd = []
-    dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX')
+    dll = env.FindIxes(target, '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp)
     if dll: listCmd.append("/out:%s"%dll.get_string(for_signature))
 
     implib = env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX')
@@ -55,12 +55,15 @@
 
     return listCmd
 
-def windowsShlinkSources(target, source, env, for_signature):
+def _dllSources(target, source, env, for_signature, paramtp):
     listCmd = []
 
     deffile = env.FindIxes(source, "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX")
     for src in source:
-        if src == deffile:
+        # Check explicitly for a non-None deffile so that the __cmp__
+        # method of the base SCons.Util.Proxy class used for some Node
+        # proxies doesn't try to use a non-existent __dict__ attribute.
+        if deffile and src == deffile:
             # Treat this source as a .def file.
             listCmd.append("/def:%s" % src.get_string(for_signature))
         else:
@@ -68,17 +71,32 @@
             listCmd.append(src)
     return listCmd
 
-def windowsLibEmitter(target, source, env):
+def windowsShlinkTargets(target, source, env, for_signature):
+    return _dllTargets(target, source, env, for_signature, 'SHLIB')
+
+def windowsShlinkSources(target, source, env, for_signature):
+    return _dllSources(target, source, env, for_signature, 'SHLIB')
+
+def _windowsLdmodTargets(target, source, env, for_signature):
+    """Get targets for loadable modules."""
+    return _dllTargets(target, source, env, for_signature, 'LDMODULE')
+
+def _windowsLdmodSources(target, source, env, for_signature):
+    """Get sources for loadable modules."""
+    return _dllSources(target, source, env, for_signature, 'LDMODULE')
+
+def _dllEmitter(target, source, env, paramtp):
+    """Common implementation of dll emitter."""
     SCons.Tool.msvc.validate_vars(env)
 
     extratargets = []
     extrasources = []
 
-    dll = env.FindIxes(target, "SHLIBPREFIX", "SHLIBSUFFIX")
+    dll = env.FindIxes(target, '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp)
     no_import_lib = env.get('no_import_lib', 0)
 
     if not dll:
-        raise SCons.Errors.UserError, "A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX")
+        raise SCons.Errors.UserError, 'A shared library should have exactly one target with the suffix: %s' % env.subst('$%sSUFFIX' % paramtp)
 
     insert_def = env.subst("$WINDOWS_INSERT_DEF")
     if not insert_def in ['', '0', 0] and \
@@ -87,7 +105,7 @@
         # append a def file to the list of sources
         extrasources.append(
             env.ReplaceIxes(dll,
-                            "SHLIBPREFIX", "SHLIBSUFFIX",
+                            '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp,
                             "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX"))
 
     if env.has_key('PDB') and env['PDB']:
@@ -100,16 +118,27 @@
         # Append an import library to the list of targets.
         extratargets.append(
             env.ReplaceIxes(dll,
-                            "SHLIBPREFIX", "SHLIBSUFFIX",
+                            '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp,
                             "LIBPREFIX", "LIBSUFFIX"))
         # and .exp file is created if there are exports from a DLL
         extratargets.append(
             env.ReplaceIxes(dll,
-                            "SHLIBPREFIX", "SHLIBSUFFIX",
+                            '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp,
                             "WINDOWSEXPPREFIX", "WINDOWSEXPSUFFIX"))
 
     return (target+extratargets, source+extrasources)
 
+def windowsLibEmitter(target, source, env):
+    return _dllEmitter(target, source, env, 'SHLIB')
+
+def ldmodEmitter(target, source, env):
+    """Emitter for loadable modules.
+    
+    Loadable modules are identical to shared libraries on Windows, but building
+    them is subject to different parameters (LDMODULE*).
+    """
+    return _dllEmitter(target, source, env, 'LDMODULE')
+
 def prog_emitter(target, source, env):
     SCons.Tool.msvc.validate_vars(env)
 
@@ -138,8 +167,10 @@
 
 regServerAction = SCons.Action.Action("$REGSVRCOM", "$REGSVRCOMSTR")
 regServerCheck = SCons.Action.Action(RegServerFunc, None)
-shlibLinkAction = SCons.Action.Action('${TEMPFILE("$SHLINK $SHLINKFLAGS $_SHLINK_TARGETS $( $_LIBDIRFLAGS $) $_LIBFLAGS $_PDB $_SHLINK_SOURCES")}')
-compositeLinkAction = shlibLinkAction + regServerCheck
+shlibLinkAction = SCons.Action.Action('${TEMPFILE("$SHLINK $SHLINKFLAGS $_SHLINK_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_SHLINK_SOURCES")}')
+compositeShLinkAction = shlibLinkAction + regServerCheck
+ldmodLinkAction = SCons.Action.Action('${TEMPFILE("$LDMODULE $LDMODULEFLAGS $_LDMODULE_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_LDMODULE_SOURCES")}')
+compositeLdmodAction = ldmodLinkAction + regServerCheck
 
 def generate(env):
     """Add Builders and construction variables for ar to an Environment."""
@@ -150,12 +181,12 @@
     env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS /dll')
     env['_SHLINK_TARGETS'] = windowsShlinkTargets
     env['_SHLINK_SOURCES'] = windowsShlinkSources
-    env['SHLINKCOM']   =  compositeLinkAction
+    env['SHLINKCOM']   =  compositeShLinkAction
     env.Append(SHLIBEMITTER = [windowsLibEmitter])
     env['LINK']        = 'link'
     env['LINKFLAGS']   = SCons.Util.CLVar('/nologo')
     env['_PDB'] = pdbGenerator
-    env['LINKCOM'] = '${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $( $_LIBDIRFLAGS $) $_LIBFLAGS $_PDB $SOURCES.windows")}'
+    env['LINKCOM'] = '${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $_LIBDIRFLAGS $_LIBFLAGS $_PDB $SOURCES.windows")}'
     env.Append(PROGEMITTER = [prog_emitter])
     env['LIBDIRPREFIX']='/LIBPATH:'
     env['LIBDIRSUFFIX']=''
@@ -184,19 +215,19 @@
     env['REGSVRFLAGS'] = '/s '
     env['REGSVRCOM'] = '$REGSVR $REGSVRFLAGS ${TARGET.windows}'
 
-    # For most platforms, a loadable module is the same as a shared
-    # library.  Platforms which are different can override these, but
-    # setting them the same means that LoadableModule works everywhere.
+    # Loadable modules are on Windows the same as shared libraries, but they
+    # are subject to different build parameters (LDMODULE* variables).
+    # Therefore LDMODULE* variables correspond as much as possible to
+    # SHLINK*/SHLIB* ones.
     SCons.Tool.createLoadableModuleBuilder(env)
     env['LDMODULE'] = '$SHLINK'
     env['LDMODULEPREFIX'] = '$SHLIBPREFIX'
     env['LDMODULESUFFIX'] = '$SHLIBSUFFIX'
     env['LDMODULEFLAGS'] = '$SHLINKFLAGS'
-    # We can't use '$SHLINKCOM' here because that will stringify the
-    # action list on expansion, and will then try to execute expanded
-    # strings, with the upshot that it would try to execute RegServerFunc
-    # as a command.
-    env['LDMODULECOM'] = compositeLinkAction
+    env['_LDMODULE_TARGETS'] = _windowsLdmodTargets
+    env['_LDMODULE_SOURCES'] = _windowsLdmodSources
+    env['LDMODULEEMITTER'] = [ldmodEmitter]
+    env['LDMODULECOM'] = compositeLdmodAction
 
 def exists(env):
     platform = env.get('PLATFORM', '')
@@ -208,4 +239,8 @@
         return env.Detect('link')
     return None
 
-# vim:set ts=4 sw=4 et:
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/scons/msvc_sa.py b/scons/msvc_sa.py
index 136d305..a913662 100644
--- a/scons/msvc_sa.py
+++ b/scons/msvc_sa.py
@@ -7,7 +7,7 @@
 """
 
 #
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation
 #
 # Permission is hereby granted, free of charge, to any person obtaining
 # a copy of this software and associated documentation files (the
@@ -40,6 +40,7 @@
 import SCons.Tool
 import SCons.Util
 import SCons.Warnings
+import SCons.Scanner.RC
 
 CSuffixes = ['.c', '.C']
 CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++']
@@ -97,47 +98,114 @@
 pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch',
                                     emitter=pch_emitter,
                                     source_scanner=SCons.Tool.SourceFileScanner)
+
+
+# Logic to build .rc files into .res files (resource files)
+res_scanner = SCons.Scanner.RC.RCScan()
 res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR')
 res_builder = SCons.Builder.Builder(action=res_action,
                                     src_suffix='.rc',
                                     suffix='.res',
                                     src_builder=[],
-                                    source_scanner=SCons.Tool.SourceFileScanner)
-SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan)
+                                    source_scanner=res_scanner)
+
+def msvc_batch_key(action, env, target, source):
+    """
+    Returns a key to identify unique batches of sources for compilation.
+
+    If batching is enabled (via the $MSVC_BATCH setting), then all
+    target+source pairs that use the same action, defined by the same
+    environment, and have the same target and source directories, will
+    be batched.
+
+    Returning None specifies that the specified target+source should not
+    be batched with other compilations.
+    """
+    b = env.subst('$MSVC_BATCH')
+    if b in (None, '', '0'):
+        # We're not using batching; return no key.
+        return None
+    t = target[0]
+    s = source[0]
+    if os.path.splitext(t.name)[0] != os.path.splitext(s.name)[0]:
+        # The base names are different, so this *must* be compiled
+        # separately; return no key.
+        return None
+    return (id(action), id(env), t.dir, s.dir)
+
+def msvc_output_flag(target, source, env, for_signature):
+    """
+    Returns the correct /Fo flag for batching.
+
+    If batching is disabled or there's only one source file, then we
+    return an /Fo string that specifies the target explicitly.  Otherwise,
+    we return an /Fo string that just specifies the first target's
+    directory (where the Visual C/C++ compiler will put the .obj files).
+    """
+    b = env.subst('$MSVC_BATCH')
+    if b in (None, '', '0') or len(source) == 1:
+        return '/Fo$TARGET'
+    else:
+        # The Visual C/C++ compiler requires a \ at the end of the /Fo
+        # option to indicate an output directory.  We use os.sep here so
+        # that the test(s) for this can be run on non-Windows systems
+        # without having a hard-coded backslash mess up command-line
+        # argument parsing.
+        return '/Fo${TARGET.dir}' + os.sep
+
+CAction = SCons.Action.Action("$CCCOM", "$CCCOMSTR",
+                              batch_key=msvc_batch_key,
+                              targets='$CHANGED_TARGETS')
+ShCAction = SCons.Action.Action("$SHCCCOM", "$SHCCCOMSTR",
+                                batch_key=msvc_batch_key,
+                                targets='$CHANGED_TARGETS')
+CXXAction = SCons.Action.Action("$CXXCOM", "$CXXCOMSTR",
+                                batch_key=msvc_batch_key,
+                                targets='$CHANGED_TARGETS')
+ShCXXAction = SCons.Action.Action("$SHCXXCOM", "$SHCXXCOMSTR",
+                                  batch_key=msvc_batch_key,
+                                  targets='$CHANGED_TARGETS')
 
 def generate(env):
     """Add Builders and construction variables for MSVC++ to an Environment."""
     static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
 
+    # TODO(batch):  shouldn't reach in to cmdgen this way; necessary
+    # for now to bypass the checks in Builder.DictCmdGenerator.__call__()
+    # and allow .cc and .cpp to be compiled in the same command line.
+    static_obj.cmdgen.source_ext_match = False
+    shared_obj.cmdgen.source_ext_match = False
+
     for suffix in CSuffixes:
-        static_obj.add_action(suffix, SCons.Defaults.CAction)
-        shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
+        static_obj.add_action(suffix, CAction)
+        shared_obj.add_action(suffix, ShCAction)
         static_obj.add_emitter(suffix, static_object_emitter)
         shared_obj.add_emitter(suffix, shared_object_emitter)
 
     for suffix in CXXSuffixes:
-        static_obj.add_action(suffix, SCons.Defaults.CXXAction)
-        shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction)
+        static_obj.add_action(suffix, CXXAction)
+        shared_obj.add_action(suffix, ShCXXAction)
         static_obj.add_emitter(suffix, static_object_emitter)
         shared_obj.add_emitter(suffix, shared_object_emitter)
 
     env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Z7") or ""}'])
     env['CCPCHFLAGS'] = SCons.Util.CLVar(['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}'])
-    env['CCCOMFLAGS'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET $CCPCHFLAGS $CCPDBFLAGS'
+    env['_MSVC_OUTPUT_FLAG'] = msvc_output_flag
+    env['_CCCOMCOM']  = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $CCPCHFLAGS $CCPDBFLAGS'
     env['CC']         = 'cl'
     env['CCFLAGS']    = SCons.Util.CLVar('/nologo')
     env['CFLAGS']     = SCons.Util.CLVar('')
-    env['CCCOM']      = '$CC $CFLAGS $CCFLAGS $CCCOMFLAGS'
+    env['CCCOM']      = '$CC $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CFLAGS $CCFLAGS $_CCCOMCOM'
     env['SHCC']       = '$CC'
     env['SHCCFLAGS']  = SCons.Util.CLVar('$CCFLAGS')
     env['SHCFLAGS']   = SCons.Util.CLVar('$CFLAGS')
-    env['SHCCCOM']    = '$SHCC $SHCFLAGS $SHCCFLAGS $CCCOMFLAGS'
+    env['SHCCCOM']    = '$SHCC $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCFLAGS $SHCCFLAGS $_CCCOMCOM'
     env['CXX']        = '$CC'
-    env['CXXFLAGS']   = SCons.Util.CLVar('$CCFLAGS $( /TP $)')
-    env['CXXCOM']     = '$CXX $CXXFLAGS $CCCOMFLAGS'
+    env['CXXFLAGS']   = SCons.Util.CLVar('$( /TP $)')
+    env['CXXCOM']     = '$CXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CXXFLAGS $CCFLAGS $_CCCOMCOM'
     env['SHCXX']      = '$CXX'
     env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
-    env['SHCXXCOM']   = '$SHCXX $SHCXXFLAGS $CCCOMFLAGS'
+    env['SHCXXCOM']   = '$SHCXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM'
     env['CPPDEFPREFIX']  = '/D'
     env['CPPDEFSUFFIX']  = ''
     env['INCPREFIX']  = '/I'
@@ -148,6 +216,7 @@
 
     env['RC'] = 'rc'
     env['RCFLAGS'] = SCons.Util.CLVar('')
+    env['RCSUFFIXES']=['.rc','.rc2']
     env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES'
     env['BUILDERS']['RES'] = res_builder
     env['OBJPREFIX']      = ''
@@ -159,7 +228,7 @@
     env['CXXFILESUFFIX'] = '.cc'
 
     env['PCHPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Yd") or ""}'])
-    env['PCHCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo${TARGETS[1]} /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS'
+    env['PCHCOM'] = '$CXX /Fo${TARGETS[1]} $CXXFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS'
     env['BUILDERS']['PCH'] = pch_builder
 
     if not env.has_key('ENV'):
@@ -170,4 +239,8 @@
 def exists(env):
     return env.Detect('cl')
 
-# vim:set ts=4 sw=4 et:
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/SConscript b/src/SConscript
index 5440acd..6083fcb 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -1,5 +1,6 @@
 Import('*')
 
+SConscript('glsl/SConscript')
 SConscript('gallium/SConscript')
 
 if 'mesa' in env['statetrackers']:
diff --git a/src/egl/drivers/dri/egldri.c b/src/egl/drivers/dri/egldri.c
index 9e400be..ca6821d 100644
--- a/src/egl/drivers/dri/egldri.c
+++ b/src/egl/drivers/dri/egldri.c
@@ -675,13 +675,13 @@
                              drm_context_t * hHWContext)
 {
     __DRIscreen *pDRIScreen;
-    __DRIscreenPrivate *psp;
+    __DRIscreen *psp;
 
     pDRIScreen = __eglFindDRIScreen(ndpy, screen);
     if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
         return GL_FALSE;
     }
-    psp = (__DRIscreenPrivate *) pDRIScreen->private;
+    psp = (__DRIscreen *) pDRIScreen->private;
     if (psp->fd) {
         if (drmCreateContext(psp->fd, hHWContext)) {
             _eglLog(_EGL_WARNING, "drmCreateContext failed.");
@@ -691,14 +691,14 @@
     }
 #if 0
     __DRIscreen *pDRIScreen;
-    __DRIscreenPrivate *psp;
+    __DRIscreen *psp;
 
     pDRIScreen = __glXFindDRIScreen(dpy, screen);
     if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
         return GL_FALSE;
     }
 
-    psp = (__DRIscreenPrivate *) pDRIScreen->private;
+    psp = (__DRIscreen *) pDRIScreen->private;
 
     if (psp->fd) {
         if (drmCreateContext(psp->fd, hHWContext)) {
@@ -716,13 +716,13 @@
 __eglDestroyContext( __DRInativeDisplay * ndpy, int screen,  __DRIid context )
 {
     __DRIscreen *pDRIScreen;
-    __DRIscreenPrivate *psp;
+    __DRIscreen *psp;
 
     pDRIScreen = __eglFindDRIScreen(ndpy, screen);
     if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
         return GL_FALSE;
     }
-    psp = (__DRIscreenPrivate *) pDRIScreen->private;
+    psp = (__DRIscreen *) pDRIScreen->private;
     if (psp->fd)
       drmDestroyContext(psp->fd, context);
 
@@ -735,13 +735,13 @@
                     __DRIid drawable, drm_drawable_t * hHWDrawable)
 {
     __DRIscreen *pDRIScreen;
-    __DRIscreenPrivate *psp;
+    __DRIscreen *psp;
 
     pDRIScreen = __eglFindDRIScreen(ndpy, screen);
     if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
         return GL_FALSE;
     }
-    psp = (__DRIscreenPrivate *) pDRIScreen->private;
+    psp = (__DRIscreen *) pDRIScreen->private;
     if (psp->fd) {
         if (drmCreateDrawable(psp->fd, hHWDrawable)) {
             _eglLog(_EGL_WARNING, "drmCreateDrawable failed.");
@@ -756,13 +756,13 @@
 __eglDestroyDrawable( __DRInativeDisplay * ndpy, int screen, __DRIid drawable )
 {
     __DRIscreen *pDRIScreen;
-    __DRIscreenPrivate *psp;
+    __DRIscreen *psp;
 
     pDRIScreen = __eglFindDRIScreen(ndpy, screen);
     if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
         return GL_FALSE;
     }
-    psp = (__DRIscreenPrivate *) pDRIScreen->private;
+    psp = (__DRIscreen *) pDRIScreen->private;
     if (psp->fd)
       drmDestroyDrawable(psp->fd, drawable);
 
@@ -778,7 +778,7 @@
                      int* numBackClipRects, drm_clip_rect_t ** pBackClipRects )
 {
     __DRIscreen *pDRIScreen;
-    __DRIscreenPrivate *psp;
+    __DRIscreen *psp;
     driSurface *surf = Lookup_driSurface((EGLSurface) drawable);
 
    pDRIScreen = __eglFindDRIScreen(ndpy, screen);
@@ -786,7 +786,7 @@
    if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
        return GL_FALSE;
    }
-   psp = (__DRIscreenPrivate *) pDRIScreen->private;
+   psp = (__DRIscreen *) pDRIScreen->private;
    *X = 0;
    *Y = 0;
    *W = surf->Base.Width;
@@ -807,7 +807,7 @@
     GLXDrawable drawable = (GLXDrawable) draw;
     drm_clip_rect_t * cliprect;
     Display* display = (Display*)dpy;
-    __DRIcontextPrivate *pcp = (__DRIcontextPrivate *)CurrentContext->driContext.private;
+    __DRIcontext *pcp = (__DRIcontext *)CurrentContext->driContext.private;
     if (drawable == 0) {
         return GL_FALSE;
     }
diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile
index c951b07..ec326a8 100644
--- a/src/egl/main/Makefile
+++ b/src/egl/main/Makefile
@@ -4,7 +4,10 @@
 include $(TOP)/configs/current
 
 
-INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/mesa/glapi $(X11_INCLUDES)
+EGL_MAJOR = 1
+EGL_MINOR = 0
+
+INCLUDE_DIRS = -I$(TOP)/include
 
 HEADERS = \
 	eglcompiler.h \
@@ -43,7 +46,7 @@
 OBJECTS = $(SOURCES:.c=.o)
 
 
-# Undefined for now
+# use dl*() to load drivers
 LOCAL_CFLAGS = -D_EGL_PLATFORM_X=1
 
 
@@ -56,21 +59,21 @@
 
 
 # EGL Library
-library: $(TOP)/$(LIB_DIR)/libEGL.so
+library: $(TOP)/$(LIB_DIR)/$(EGL_LIB_NAME)
 
-$(TOP)/$(LIB_DIR)/libEGL.so: $(OBJECTS)
-	$(MKLIB) -o EGL -linker '$(CC)' -ldflags '$(LDFLAGS)' \
-		-major 1 -minor 0 \
-		-install $(TOP)/$(LIB_DIR) \
+$(TOP)/$(LIB_DIR)/$(EGL_LIB_NAME): $(OBJECTS)
+	$(MKLIB) -o $(EGL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+		-major $(EGL_MAJOR) -minor $(EGL_MINOR) \
+		-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
 		$(EGL_LIB_DEPS) $(OBJECTS)
 
 install: default
 	$(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)
-	$(MINSTALL) $(TOP)/$(LIB_DIR)/libEGL.so* $(DESTDIR)$(INSTALL_LIB_DIR)
+	$(MINSTALL) $(TOP)/$(LIB_DIR)/$(EGL_LIB_GLOB) \
+		$(DESTDIR)$(INSTALL_LIB_DIR)
 
 clean:
-	-rm -f *.o *.so*
-	-rm -f core.*
+	-rm -f *.o
 	-rm -f depend depend.bak
 
 
@@ -82,5 +85,5 @@
 		$(SOURCES) $(HEADERS) > /dev/null 2>/dev/null
 
 
-include depend
+-include depend
 # DO NOT DELETE
diff --git a/src/egl/main/eglcompiler.h b/src/egl/main/eglcompiler.h
index 6b639b7..f7c93f1 100644
--- a/src/egl/main/eglcompiler.h
+++ b/src/egl/main/eglcompiler.h
@@ -61,4 +61,14 @@
 #endif
 
 
+/**
+ * Function visibility
+ */
+#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303
+#  define PUBLIC __attribute__((visibility("default")))
+#else
+#  define PUBLIC
+#endif
+
+
 #endif /* EGLCOMPILER_INCLUDED */
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index 31d69a7..4d14960 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -324,6 +324,7 @@
             mask = EGL_PBUFFER_BIT |
                    EGL_PIXMAP_BIT |
                    EGL_WINDOW_BIT |
+                   EGL_SCREEN_BIT_MESA | /* XXX should check the extension */
                    EGL_VG_COLORSPACE_LINEAR_BIT |
                    EGL_VG_ALPHA_FORMAT_PRE_BIT |
                    EGL_MULTISAMPLE_RESOLVE_BOX_BIT |
diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h
index 6b8a259..799bf4e 100644
--- a/src/egl/main/eglconfig.h
+++ b/src/egl/main/eglconfig.h
@@ -91,11 +91,11 @@
 }
 
 
-extern void
+PUBLIC void
 _eglInitConfig(_EGLConfig *config, EGLint id);
 
 
-extern EGLConfig
+PUBLIC EGLConfig
 _eglAddConfig(_EGLDisplay *dpy, _EGLConfig *conf);
 
 
@@ -144,24 +144,24 @@
 }
 
 
-extern EGLBoolean
+PUBLIC EGLBoolean
 _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching);
 
 
-extern EGLBoolean
+PUBLIC EGLBoolean
 _eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria);
 
 
-extern EGLBoolean
+PUBLIC EGLBoolean
 _eglParseConfigAttribList(_EGLConfig *conf, const EGLint *attrib_list);
 
 
-extern EGLint
+PUBLIC EGLint
 _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
                    const _EGLConfig *criteria, EGLBoolean compare_id);
 
 
-extern void
+PUBLIC void
 _eglSortConfigs(const _EGLConfig **configs, EGLint count,
                 EGLint (*compare)(const _EGLConfig *, const _EGLConfig *,
                                   void *),
diff --git a/src/egl/main/eglconfigutil.h b/src/egl/main/eglconfigutil.h
index 8c923ee..9f8906d 100644
--- a/src/egl/main/eglconfigutil.h
+++ b/src/egl/main/eglconfigutil.h
@@ -7,16 +7,16 @@
 #include "eglconfig.h"
 
 
-extern void
+PUBLIC void
 _eglConfigToContextModesRec(const _EGLConfig *config, __GLcontextModes *mode);
 
 
-extern EGLBoolean
+PUBLIC EGLBoolean
 _eglConfigFromContextModesRec(_EGLConfig *conf, const __GLcontextModes *m,
                               EGLint conformant, EGLint renderable_type);
 
 
-extern EGLBoolean
+PUBLIC EGLBoolean
 _eglFillInConfigs( _EGLConfig *configs,
                    EGLenum fb_format, EGLenum fb_type,
                    const uint8_t * depth_bits, const uint8_t * stencil_bits,
diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h
index 45c7b47..cb9e3f4 100644
--- a/src/egl/main/eglcontext.h
+++ b/src/egl/main/eglcontext.h
@@ -30,7 +30,7 @@
 };
 
 
-extern EGLBoolean
+PUBLIC EGLBoolean
 _eglInitContext(_EGLDriver *drv, _EGLContext *ctx,
                 _EGLConfig *config, const EGLint *attrib_list);
 
@@ -47,7 +47,7 @@
 _eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLint attribute, EGLint *value);
 
 
-extern EGLBoolean
+PUBLIC EGLBoolean
 _eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx);
 
 
diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h
index 9503e0a..c4478b3 100644
--- a/src/egl/main/eglcurrent.h
+++ b/src/egl/main/eglcurrent.h
@@ -60,7 +60,7 @@
 }
 
 
-extern _EGLThreadInfo *
+PUBLIC _EGLThreadInfo *
 _eglGetCurrentThread(void);
 
 
@@ -72,19 +72,19 @@
 _eglIsCurrentThreadDummy(void);
 
 
-extern _EGLContext *
+PUBLIC _EGLContext *
 _eglGetCurrentContext(void);
 
 
-extern _EGLDisplay *
+PUBLIC _EGLDisplay *
 _eglGetCurrentDisplay(void);
 
 
-extern _EGLSurface *
+PUBLIC _EGLSurface *
 _eglGetCurrentSurface(EGLint readdraw);
 
 
-extern EGLBoolean
+PUBLIC EGLBoolean
 _eglError(EGLint errCode, const char *msg);
 
 
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index ea4e35a..4f619e5 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -78,11 +78,11 @@
 _eglFindDisplay(NativeDisplayType nativeDisplay);
 
 
-extern void
+PUBLIC void
 _eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *dpy);
 
 
-extern void
+PUBLIC void
 _eglCleanupDisplay(_EGLDisplay *disp);
 
 
diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h
index 6c848eb..59bd195 100644
--- a/src/egl/main/egldriver.h
+++ b/src/egl/main/egldriver.h
@@ -25,7 +25,8 @@
 };
 
 
-extern _EGLDriver *_eglMain(const char *args);
+PUBLIC _EGLDriver *
+_eglMain(const char *args);
 
 
 extern const char *
@@ -48,11 +49,11 @@
 _eglLookupDriver(EGLDisplay d);
 
 
-extern void
+PUBLIC void
 _eglInitDriverFallbacks(_EGLDriver *drv);
 
 
-extern EGLint
+PUBLIC EGLint
 _eglFindAPIs(void);
 
 
diff --git a/src/egl/main/egllog.h b/src/egl/main/egllog.h
index 83c8bb7..3a99bfe 100644
--- a/src/egl/main/egllog.h
+++ b/src/egl/main/egllog.h
@@ -12,15 +12,15 @@
 typedef void (*_EGLLogProc)(EGLint level, const char *msg);
 
 
-extern void
+PUBLIC void
 _eglSetLogProc(_EGLLogProc logger);
 
 
-extern void
+PUBLIC void
 _eglSetLogLevel(EGLint level);
 
 
-extern void
+PUBLIC void
 _eglLog(EGLint level, const char *fmtStr, ...);
 
 
diff --git a/src/egl/main/eglmode.h b/src/egl/main/eglmode.h
index af7c2c5..a089a5e 100644
--- a/src/egl/main/eglmode.h
+++ b/src/egl/main/eglmode.h
@@ -29,7 +29,7 @@
 _eglLookupMode(EGLModeMESA mode, _EGLDisplay *dpy);
 
 
-extern _EGLMode *
+PUBLIC _EGLMode *
 _eglAddNewMode(_EGLScreen *screen, EGLint width, EGLint height,
                EGLint refreshRate, const char *name);
 
diff --git a/src/egl/main/eglscreen.h b/src/egl/main/eglscreen.h
index 8860a2a..d52e538 100644
--- a/src/egl/main/eglscreen.h
+++ b/src/egl/main/eglscreen.h
@@ -30,7 +30,7 @@
 _eglAllocScreenHandle(void);
 
 
-extern void
+PUBLIC void
 _eglInitScreen(_EGLScreen *screen);
 
 
@@ -38,7 +38,7 @@
 _eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *dpy);
 
 
-extern void
+PUBLIC void
 _eglAddScreen(_EGLDisplay *display, _EGLScreen *screen);
 
 
@@ -83,7 +83,7 @@
 _eglDestroyScreenModes(_EGLScreen *scrn);
 
 
-extern void
+PUBLIC void
 _eglDestroyScreen(_EGLScreen *scrn);
 
 
diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h
index b75fa9c..dacdf7e 100644
--- a/src/egl/main/eglsurface.h
+++ b/src/egl/main/eglsurface.h
@@ -40,7 +40,7 @@
 };
 
 
-extern EGLBoolean
+PUBLIC EGLBoolean
 _eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type,
                 _EGLConfig *config, const EGLint *attrib_list);
 
diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template
index 63983c5..1364235 100644
--- a/src/gallium/Makefile.template
+++ b/src/gallium/Makefile.template
@@ -54,13 +54,13 @@
 ##### RULES #####
 
 .c.o:
-	$(CC) -c $(INCLUDES) $(CFLAGS) $(LIBRARY_DEFINES) $< -o $@
+	$(CC) -c $(INCLUDES) $(DEFINES) $(CFLAGS) $(LIBRARY_DEFINES) $< -o $@
 
 .cpp.o:
-	$(CXX) -c $(INCLUDES) $(CXXFLAGS) $(LIBRARY_DEFINES) $< -o $@
+	$(CXX) -c $(INCLUDES) $(DEFINES) $(CXXFLAGS) $(LIBRARY_DEFINES) $< -o $@
 
 .S.o:
-	$(CC) -c $(INCLUDES) $(CFLAGS) $(LIBRARY_DEFINES)  $< -o $@
+	$(CC) -c $(INCLUDES) $(DEFINES) $(CFLAGS) $(LIBRARY_DEFINES)  $< -o $@
 
 
 sinclude depend
diff --git a/src/gallium/SConscript b/src/gallium/SConscript
index 8be84cd..eea32b1 100644
--- a/src/gallium/SConscript
+++ b/src/gallium/SConscript
@@ -2,29 +2,7 @@
 
 Import('*')
 
-env = env.Clone()
-
-auxiliaries = []
-
-Export('auxiliaries')
-
-
-if llvm:
-	SConscript(['auxiliary/gallivm/SConscript'])
-
-SConscript([
-	# NOTE: order matters!
-	'auxiliary/util/SConscript',
-	'auxiliary/rtasm/SConscript',
-	'auxiliary/tgsi/SConscript',
-	'auxiliary/cso_cache/SConscript',
-	'auxiliary/translate/SConscript',
-	'auxiliary/draw/SConscript',
-	'auxiliary/pipebuffer/SConscript',
-	'auxiliary/indices/SConscript',
-	'auxiliary/rbug/SConscript',
-	'auxiliary/vl/SConscript',
-])
+SConscript('auxiliary/SConscript')
 
 for driver in env['drivers']:
 	SConscript(os.path.join('drivers', driver, 'SConscript'))
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile
index 5446eb6..e3af41c 100644
--- a/src/gallium/auxiliary/Makefile
+++ b/src/gallium/auxiliary/Makefile
@@ -1,12 +1,177 @@
-# src/gallium/auxiliary/Makefile
 TOP = ../../..
 include $(TOP)/configs/current
 
-SUBDIRS = $(GALLIUM_AUXILIARY_DIRS)
+LIBNAME = gallium
 
-default install clean:
-	@for dir in $(SUBDIRS) ; do \
-		if [ -d $$dir ] ; then \
-			(cd $$dir && $(MAKE) $@) || exit 1; \
-		fi \
-	done
+C_SOURCES = \
+	cso_cache/cso_context.c \
+	cso_cache/cso_cache.c \
+	cso_cache/cso_hash.c \
+	draw/draw_context.c \
+	draw/draw_gs.c \
+	draw/draw_pipe.c \
+	draw/draw_pipe_aaline.c \
+	draw/draw_pipe_aapoint.c \
+	draw/draw_pipe_clip.c \
+	draw/draw_pipe_cull.c \
+	draw/draw_pipe_flatshade.c \
+	draw/draw_pipe_offset.c \
+	draw/draw_pipe_pstipple.c \
+	draw/draw_pipe_stipple.c \
+	draw/draw_pipe_twoside.c \
+	draw/draw_pipe_unfilled.c \
+	draw/draw_pipe_util.c \
+	draw/draw_pipe_validate.c \
+	draw/draw_pipe_vbuf.c \
+	draw/draw_pipe_wide_line.c \
+	draw/draw_pipe_wide_point.c \
+	draw/draw_pt.c \
+	draw/draw_pt_elts.c \
+	draw/draw_pt_emit.c \
+	draw/draw_pt_fetch.c \
+	draw/draw_pt_fetch_emit.c \
+	draw/draw_pt_fetch_shade_emit.c \
+	draw/draw_pt_fetch_shade_pipeline.c \
+	draw/draw_pt_post_vs.c \
+	draw/draw_pt_util.c \
+	draw/draw_pt_varray.c \
+	draw/draw_pt_vcache.c \
+	draw/draw_vertex.c \
+	draw/draw_vs.c \
+	draw/draw_vs_varient.c \
+	draw/draw_vs_aos.c \
+	draw/draw_vs_aos_io.c \
+	draw/draw_vs_aos_machine.c \
+	draw/draw_vs_exec.c \
+	draw/draw_vs_llvm.c \
+	draw/draw_vs_ppc.c \
+	draw/draw_vs_sse.c \
+	indices/u_indices_gen.c \
+	indices/u_unfilled_gen.c \
+	pipebuffer/pb_buffer_fenced.c \
+	pipebuffer/pb_buffer_malloc.c \
+	pipebuffer/pb_bufmgr_alt.c \
+	pipebuffer/pb_bufmgr_cache.c \
+	pipebuffer/pb_bufmgr_debug.c \
+	pipebuffer/pb_bufmgr_fenced.c \
+	pipebuffer/pb_bufmgr_mm.c \
+	pipebuffer/pb_bufmgr_ondemand.c \
+	pipebuffer/pb_bufmgr_pool.c \
+	pipebuffer/pb_bufmgr_slab.c \
+	pipebuffer/pb_validate.c \
+	rbug/rbug_connection.c \
+	rbug/rbug_core.c \
+	rbug/rbug_texture.c \
+	rbug/rbug_context.c \
+	rbug/rbug_shader.c \
+	rbug/rbug_demarshal.c \
+	rtasm/rtasm_cpu.c \
+	rtasm/rtasm_execmem.c \
+	rtasm/rtasm_x86sse.c \
+	rtasm/rtasm_ppc.c \
+	rtasm/rtasm_ppc_spe.c \
+	tgsi/tgsi_sanity.c \
+	tgsi/tgsi_build.c \
+	tgsi/tgsi_dump.c \
+	tgsi/tgsi_exec.c \
+	tgsi/tgsi_info.c \
+	tgsi/tgsi_iterate.c \
+	tgsi/tgsi_parse.c \
+	tgsi/tgsi_ppc.c \
+	tgsi/tgsi_scan.c \
+	tgsi/tgsi_sse2.c \
+	tgsi/tgsi_text.c \
+	tgsi/tgsi_transform.c \
+	tgsi/tgsi_ureg.c \
+	tgsi/tgsi_util.c \
+	translate/translate_generic.c \
+	translate/translate_sse.c \
+	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_blit.c \
+	util/u_blitter.c \
+	util/u_cache.c \
+	util/u_cpu_detect.c \
+	util/u_dl.c \
+	util/u_draw_quad.c \
+	util/u_format.c \
+	util/u_format_access.c \
+	util/u_format_table.c \
+	util/u_gen_mipmap.c \
+	util/u_handle_table.c \
+	util/u_hash_table.c \
+	util/u_hash.c \
+	util/u_keymap.c \
+	util/u_linear.c \
+	util/u_network.c \
+	util/u_math.c \
+	util/u_mm.c \
+	util/u_rect.c \
+	util/u_simple_shaders.c \
+	util/u_snprintf.c \
+	util/u_stream_stdc.c \
+	util/u_stream_wd.c \
+	util/u_surface.c \
+	util/u_texture.c \
+	util/u_tile.c \
+	util/u_time.c \
+	util/u_timed_winsys.c \
+	util/u_upload_mgr.c \
+	util/u_simple_screen.c \
+	vl/vl_bitstream_parser.c \
+	vl/vl_mpeg12_mc_renderer.c \
+	vl/vl_compositor.c \
+	vl/vl_csc.c \
+	vl/vl_shader_build.c
+
+GALLIVM_SOURCES = \
+	gallivm/gallivm.cpp  \
+	gallivm/gallivm_cpu.cpp \
+	gallivm/instructions.cpp  \
+	gallivm/loweringpass.cpp \
+	gallivm/tgsitollvm.cpp \
+	gallivm/storage.cpp \
+	gallivm/storagesoa.cpp \
+	gallivm/instructionssoa.cpp
+
+INC_SOURCES = \
+	gallivm/gallivm_builtins.cpp \
+	gallivm/gallivmsoabuiltins.cpp
+
+# XXX: gallivm doesn't build correctly so disable for now
+#ifeq ($(MESA_LLVM),1)
+#DEFINES += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
+#CPP_SOURCES += \
+#	$(GALLIVM_SOURCES)
+#endif
+
+
+include ../Makefile.template
+
+
+gallivm/gallivm_builtins.cpp: gallivm/llvm_builtins.c
+	clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp1.bin
+	(echo "static const unsigned char llvm_builtins_data[] = {"; od -txC temp1.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/,0x00};/") >$@
+	rm temp1.bin
+
+gallivm/gallivmsoabuiltins.cpp: gallivm/soabuiltins.c
+	clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp2.bin
+	(echo "static const unsigned char soabuiltins_data[] = {"; od -txC temp2.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/,0x00};/") >$@
+	rm temp2.bin
+
+
+indices/u_indices_gen.c: indices/u_indices_gen.py
+	python $< > $@
+
+indices/u_unfilled_gen.c: indices/u_unfilled_gen.py
+	python $< > $@
+
+util/u_format_table.c: util/u_format_table.py util/u_format_parse.py util/u_format.csv
+	python util/u_format_table.py util/u_format.csv > $@
+
+util/u_format_access.c: util/u_format_access.py util/u_format_parse.py util/u_format.csv
+	python util/u_format_access.py util/u_format.csv > $@
diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript
new file mode 100644
index 0000000..782eb53
--- /dev/null
+++ b/src/gallium/auxiliary/SConscript
@@ -0,0 +1,185 @@
+Import('*')
+
+from sys import executable as python_cmd
+
+env.Append(CPPPATH = [
+    'indices',
+    'util',
+])
+
+env.CodeGenerate(
+    target = 'indices/u_indices_gen.c', 
+    script = 'indices/u_indices_gen.py', 
+    source = [],
+    command = python_cmd + ' $SCRIPT > $TARGET'
+)
+
+env.CodeGenerate(
+    target = 'indices/u_unfilled_gen.c', 
+    script = 'indices/u_unfilled_gen.py', 
+    source = [],
+    command = python_cmd + ' $SCRIPT > $TARGET'
+)
+
+env.CodeGenerate(
+    target = 'util/u_format_table.c',
+    script = 'util/u_format_table.py',
+    source = ['util/u_format.csv'],
+    command = 'python $SCRIPT $SOURCE > $TARGET'
+)
+
+env.CodeGenerate(
+    target = 'util/u_format_access.c',
+    script = 'util/u_format_access.py',
+    source = ['util/u_format.csv'],
+    command = 'python $SCRIPT $SOURCE > $TARGET'
+)
+
+source = [
+    'cso_cache/cso_context.c',
+    'cso_cache/cso_cache.c',
+    'cso_cache/cso_hash.c',
+    'draw/draw_context.c',
+    'draw/draw_pipe.c',
+    'draw/draw_pipe_aaline.c',
+    'draw/draw_pipe_aapoint.c',
+    'draw/draw_pipe_clip.c',
+    'draw/draw_pipe_cull.c',
+    'draw/draw_pipe_flatshade.c',
+    'draw/draw_pipe_offset.c',
+    'draw/draw_pipe_pstipple.c',
+    'draw/draw_pipe_stipple.c',
+    'draw/draw_pipe_twoside.c',
+    'draw/draw_pipe_unfilled.c',
+    'draw/draw_pipe_util.c',
+    'draw/draw_pipe_validate.c',
+    'draw/draw_pipe_vbuf.c',
+    'draw/draw_pipe_wide_line.c',
+    'draw/draw_pipe_wide_point.c',
+    'draw/draw_pt.c',
+    'draw/draw_pt_elts.c',
+    'draw/draw_pt_emit.c',
+    'draw/draw_pt_fetch.c',
+    'draw/draw_pt_fetch_emit.c',
+    'draw/draw_pt_fetch_shade_emit.c',
+    'draw/draw_pt_fetch_shade_pipeline.c',
+    'draw/draw_pt_post_vs.c',
+    'draw/draw_pt_util.c',
+    'draw/draw_pt_varray.c',
+    'draw/draw_pt_vcache.c',
+    'draw/draw_vertex.c',
+    'draw/draw_vs.c',
+    'draw/draw_vs_aos.c',
+    'draw/draw_vs_aos_io.c',
+    'draw/draw_vs_aos_machine.c',
+    'draw/draw_vs_exec.c',
+    'draw/draw_vs_llvm.c',
+    'draw/draw_vs_ppc.c',
+    'draw/draw_vs_sse.c',
+    'draw/draw_vs_varient.c',
+    'draw/draw_gs.c',
+    #'indices/u_indices.c',
+    #'indices/u_unfilled_indices.c',
+    'indices/u_indices_gen.c',
+    'indices/u_unfilled_gen.c',
+    'pipebuffer/pb_buffer_fenced.c',
+    'pipebuffer/pb_buffer_malloc.c',
+    'pipebuffer/pb_bufmgr_alt.c',
+    'pipebuffer/pb_bufmgr_cache.c',
+    'pipebuffer/pb_bufmgr_debug.c',
+    'pipebuffer/pb_bufmgr_fenced.c',
+    'pipebuffer/pb_bufmgr_mm.c',
+    'pipebuffer/pb_bufmgr_ondemand.c',
+    'pipebuffer/pb_bufmgr_pool.c',
+    'pipebuffer/pb_bufmgr_slab.c',
+    'pipebuffer/pb_validate.c',
+    'rbug/rbug_core.c',
+    'rbug/rbug_shader.c',
+    'rbug/rbug_context.c',
+    'rbug/rbug_texture.c',
+    'rbug/rbug_demarshal.c',
+    'rbug/rbug_connection.c',
+    'rtasm/rtasm_cpu.c',
+    'rtasm/rtasm_execmem.c',
+    'rtasm/rtasm_x86sse.c',
+    'rtasm/rtasm_ppc.c',
+    'rtasm/rtasm_ppc_spe.c',
+    'tgsi/tgsi_build.c',
+    'tgsi/tgsi_dump.c',
+    'tgsi/tgsi_dump_c.c',
+    'tgsi/tgsi_exec.c',
+    'tgsi/tgsi_info.c',
+    'tgsi/tgsi_iterate.c',
+    'tgsi/tgsi_parse.c',
+    'tgsi/tgsi_sanity.c',
+    'tgsi/tgsi_scan.c',
+    'tgsi/tgsi_ppc.c',
+    'tgsi/tgsi_sse2.c',
+    'tgsi/tgsi_text.c',
+    'tgsi/tgsi_transform.c',
+    'tgsi/tgsi_ureg.c',
+    'tgsi/tgsi_util.c',
+    'translate/translate_generic.c',
+    'translate/translate_sse.c',
+    'translate/translate.c',
+    'translate/translate_cache.c',
+    'util/u_bitmask.c',
+    'util/u_blit.c',
+    'util/u_blitter.c',
+    '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_dl.c',
+    'util/u_draw_quad.c',
+    'util/u_format.c',
+    'util/u_format_access.c',
+    'util/u_format_table.c',
+    'util/u_gen_mipmap.c',
+    'util/u_handle_table.c',
+    'util/u_hash.c',
+    'util/u_hash_table.c',
+    'util/u_keymap.c',
+    'util/u_network.c',
+    'util/u_math.c',
+    'util/u_mm.c',
+    'util/u_rect.c',
+    'util/u_simple_shaders.c',
+    'util/u_snprintf.c',
+    'util/u_stream_stdc.c',
+    'util/u_stream_wd.c',
+    'util/u_surface.c',
+    'util/u_texture.c',
+    'util/u_tile.c',
+    'util/u_time.c',
+    'util/u_timed_winsys.c',
+    'util/u_upload_mgr.c',
+    'util/u_simple_screen.c',
+    'vl/vl_bitstream_parser.c',
+    'vl/vl_mpeg12_mc_renderer.c',
+    'vl/vl_compositor.c',
+    'vl/vl_csc.c',
+    'vl/vl_shader_build.c',
+]
+
+if env['llvm']:
+    source += [
+        'gallivm/gallivm.cpp',
+        'gallivm/gallivm_cpu.cpp',
+        'gallivm/instructions.cpp',
+        'gallivm/loweringpass.cpp',
+        'gallivm/tgsitollvm.cpp',
+        'gallivm/storage.cpp',
+        'gallivm/storagesoa.cpp',
+        'gallivm/instructionssoa.cpp',
+    ]
+
+gallium = env.ConvenienceLibrary(
+    target = 'gallium',
+    source = source,
+)
+
+Export('gallium')
diff --git a/src/gallium/auxiliary/cso_cache/Makefile b/src/gallium/auxiliary/cso_cache/Makefile
deleted file mode 100644
index 8726afc..0000000
--- a/src/gallium/auxiliary/cso_cache/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = cso_cache
-
-C_SOURCES = \
-	cso_context.c \
-	cso_cache.c \
-	cso_hash.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/cso_cache/SConscript b/src/gallium/auxiliary/cso_cache/SConscript
deleted file mode 100644
index 651e68a..0000000
--- a/src/gallium/auxiliary/cso_cache/SConscript
+++ /dev/null
@@ -1,11 +0,0 @@
-Import('*')
-
-cso_cache = env.ConvenienceLibrary(
-	target = 'cso_cache',
-	source = [
-		'cso_context.c',
-		'cso_cache.c',
-		'cso_hash.c',
-	])
-
-auxiliaries.insert(0, cso_cache)
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index 4f13b3e..2b16332 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -42,6 +42,7 @@
 #include "cso_cache/cso_context.h"
 #include "cso_cache/cso_cache.h"
 #include "cso_cache/cso_hash.h"
+#include "cso_context.h"
 
 struct cso_context {
    struct pipe_context *pipe;
@@ -50,28 +51,43 @@
    struct {
       void *samplers[PIPE_MAX_SAMPLERS];
       unsigned nr_samplers;
+
+      void *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS];
+      unsigned nr_vertex_samplers;
    } hw;
 
    void *samplers[PIPE_MAX_SAMPLERS];
    unsigned nr_samplers;
 
+   void *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS];
+   unsigned nr_vertex_samplers;
+
    unsigned nr_samplers_saved;
    void *samplers_saved[PIPE_MAX_SAMPLERS];
 
+   unsigned nr_vertex_samplers_saved;
+   void *vertex_samplers_saved[PIPE_MAX_VERTEX_SAMPLERS];
+
    struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
    uint nr_textures;
 
+   struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
+   uint nr_vertex_textures;
+
    uint nr_textures_saved;
    struct pipe_texture *textures_saved[PIPE_MAX_SAMPLERS];
 
+   uint nr_vertex_textures_saved;
+   struct pipe_texture *vertex_textures_saved[PIPE_MAX_SAMPLERS];
+
    /** Current and saved state.
     * The saved state is used as a 1-deep stack.
     */
    void *blend, *blend_saved;
    void *depth_stencil, *depth_stencil_saved;
    void *rasterizer, *rasterizer_saved;
-   void *fragment_shader, *fragment_shader_saved;
-   void *vertex_shader, *vertex_shader_saved;
+   void *fragment_shader, *fragment_shader_saved, *geometry_shader;
+   void *vertex_shader, *vertex_shader_saved, *geometry_shader_saved;
 
    struct pipe_framebuffer_state fb, fb_saved;
    struct pipe_viewport_state vp, vp_saved;
@@ -244,7 +260,9 @@
    if (ctx->pipe) {
       ctx->pipe->bind_blend_state( ctx->pipe, NULL );
       ctx->pipe->bind_rasterizer_state( ctx->pipe, NULL );
-      ctx->pipe->bind_sampler_states( ctx->pipe, 0, NULL );
+      ctx->pipe->bind_fragment_sampler_states( ctx->pipe, 0, NULL );
+      if (ctx->pipe->bind_vertex_sampler_states)
+         ctx->pipe->bind_vertex_sampler_states(ctx->pipe, 0, NULL);
       ctx->pipe->bind_depth_stencil_alpha_state( ctx->pipe, NULL );
       ctx->pipe->bind_fs_state( ctx->pipe, NULL );
       ctx->pipe->bind_vs_state( ctx->pipe, NULL );
@@ -255,6 +273,11 @@
       pipe_texture_reference(&ctx->textures_saved[i], NULL);
    }
 
+   for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+      pipe_texture_reference(&ctx->vertex_textures[i], NULL);
+      pipe_texture_reference(&ctx->vertex_textures_saved[i], NULL);
+   }
+
    free_framebuffer_state(&ctx->fb);
    free_framebuffer_state(&ctx->fb_saved);
 
@@ -378,6 +401,46 @@
    return PIPE_OK;
 }
 
+enum pipe_error
+cso_single_vertex_sampler(struct cso_context *ctx,
+                          unsigned idx,
+                          const struct pipe_sampler_state *templ)
+{
+   void *handle = NULL;
+
+   if (templ != NULL) {
+      unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_sampler_state));
+      struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
+                                                          hash_key, CSO_SAMPLER,
+                                                          (void*)templ);
+
+      if (cso_hash_iter_is_null(iter)) {
+         struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler));
+         if (!cso)
+            return PIPE_ERROR_OUT_OF_MEMORY;
+
+         memcpy(&cso->state, templ, sizeof(*templ));
+         cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state);
+         cso->delete_state = (cso_state_callback)ctx->pipe->delete_sampler_state;
+         cso->context = ctx->pipe;
+
+         iter = cso_insert_state(ctx->cache, hash_key, CSO_SAMPLER, cso);
+         if (cso_hash_iter_is_null(iter)) {
+            FREE(cso);
+            return PIPE_ERROR_OUT_OF_MEMORY;
+         }
+
+         handle = cso->data;
+      }
+      else {
+         handle = ((struct cso_sampler *)cso_hash_iter_data(iter))->data;
+      }
+   }
+
+   ctx->vertex_samplers[idx] = handle;
+   return PIPE_OK;
+}
+
 void cso_single_sampler_done( struct cso_context *ctx )
 {
    unsigned i;
@@ -398,7 +461,36 @@
       memcpy(ctx->hw.samplers, ctx->samplers, ctx->nr_samplers * sizeof(void *));
       ctx->hw.nr_samplers = ctx->nr_samplers;
 
-      ctx->pipe->bind_sampler_states(ctx->pipe, ctx->nr_samplers, ctx->samplers);
+      ctx->pipe->bind_fragment_sampler_states(ctx->pipe, ctx->nr_samplers, ctx->samplers);
+   }
+}
+
+void
+cso_single_vertex_sampler_done(struct cso_context *ctx)
+{
+   unsigned i;
+
+   /* find highest non-null sampler */
+   for (i = PIPE_MAX_VERTEX_SAMPLERS; i > 0; i--) {
+      if (ctx->vertex_samplers[i - 1] != NULL)
+         break;
+   }
+
+   ctx->nr_vertex_samplers = i;
+
+   if (ctx->hw.nr_vertex_samplers != ctx->nr_vertex_samplers ||
+       memcmp(ctx->hw.vertex_samplers,
+              ctx->vertex_samplers,
+              ctx->nr_vertex_samplers * sizeof(void *)) != 0) 
+   {
+      memcpy(ctx->hw.vertex_samplers,
+             ctx->vertex_samplers,
+             ctx->nr_vertex_samplers * sizeof(void *));
+      ctx->hw.nr_vertex_samplers = ctx->nr_vertex_samplers;
+
+      ctx->pipe->bind_vertex_sampler_states(ctx->pipe,
+                                            ctx->nr_vertex_samplers,
+                                            ctx->vertex_samplers);
    }
 }
 
@@ -447,6 +539,21 @@
    cso_single_sampler_done( ctx );
 }
 
+void
+cso_save_vertex_samplers(struct cso_context *ctx)
+{
+   ctx->nr_vertex_samplers_saved = ctx->nr_vertex_samplers;
+   memcpy(ctx->vertex_samplers_saved, ctx->vertex_samplers, sizeof(ctx->vertex_samplers));
+}
+
+void
+cso_restore_vertex_samplers(struct cso_context *ctx)
+{
+   ctx->nr_vertex_samplers = ctx->nr_vertex_samplers_saved;
+   memcpy(ctx->vertex_samplers, ctx->vertex_samplers_saved, sizeof(ctx->vertex_samplers));
+   cso_single_vertex_sampler_done(ctx);
+}
+
 
 enum pipe_error cso_set_sampler_textures( struct cso_context *ctx,
                                           uint count,
@@ -461,7 +568,7 @@
    for ( ; i < PIPE_MAX_SAMPLERS; i++)
       pipe_texture_reference(&ctx->textures[i], NULL);
 
-   ctx->pipe->set_sampler_textures(ctx->pipe, count, textures);
+   ctx->pipe->set_fragment_sampler_textures(ctx->pipe, count, textures);
 
    return PIPE_OK;
 }
@@ -491,13 +598,71 @@
    for ( ; i < PIPE_MAX_SAMPLERS; i++)
       pipe_texture_reference(&ctx->textures[i], NULL);
 
-   ctx->pipe->set_sampler_textures(ctx->pipe, ctx->nr_textures, ctx->textures);
+   ctx->pipe->set_fragment_sampler_textures(ctx->pipe, ctx->nr_textures, ctx->textures);
 
    ctx->nr_textures_saved = 0;
 }
 
 
 
+enum pipe_error
+cso_set_vertex_sampler_textures(struct cso_context *ctx,
+                                uint count,
+                                struct pipe_texture **textures)
+{
+   uint i;
+
+   ctx->nr_vertex_textures = count;
+
+   for (i = 0; i < count; i++) {
+      pipe_texture_reference(&ctx->vertex_textures[i], textures[i]);
+   }
+   for ( ; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+      pipe_texture_reference(&ctx->vertex_textures[i], NULL);
+   }
+
+   ctx->pipe->set_vertex_sampler_textures(ctx->pipe, count, textures);
+
+   return PIPE_OK;
+}
+
+void
+cso_save_vertex_sampler_textures(struct cso_context *ctx)
+{
+   uint i;
+
+   ctx->nr_vertex_textures_saved = ctx->nr_vertex_textures;
+   for (i = 0; i < ctx->nr_vertex_textures; i++) {
+      assert(!ctx->vertex_textures_saved[i]);
+      pipe_texture_reference(&ctx->vertex_textures_saved[i], ctx->vertex_textures[i]);
+   }
+}
+
+void
+cso_restore_vertex_sampler_textures(struct cso_context *ctx)
+{
+   uint i;
+
+   ctx->nr_vertex_textures = ctx->nr_vertex_textures_saved;
+
+   for (i = 0; i < ctx->nr_vertex_textures; i++) {
+      pipe_texture_reference(&ctx->vertex_textures[i], NULL);
+      ctx->vertex_textures[i] = ctx->vertex_textures_saved[i];
+      ctx->vertex_textures_saved[i] = NULL;
+   }
+   for ( ; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+      pipe_texture_reference(&ctx->vertex_textures[i], NULL);
+   }
+
+   ctx->pipe->set_vertex_sampler_textures(ctx->pipe,
+                                          ctx->nr_vertex_textures,
+                                          ctx->vertex_textures);
+
+   ctx->nr_vertex_textures_saved = 0;
+}
+
+
+
 enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx,
                                             const struct pipe_depth_stencil_alpha_state *templ)
 {
@@ -863,3 +1028,38 @@
    }
    return PIPE_OK;
 }
+
+enum pipe_error cso_set_geometry_shader_handle(struct cso_context *ctx,
+                                               void *handle)
+{
+   if (ctx->geometry_shader != handle) {
+      ctx->geometry_shader = handle;
+      ctx->pipe->bind_gs_state(ctx->pipe, handle);
+   }
+   return PIPE_OK;
+}
+
+void cso_delete_geometry_shader(struct cso_context *ctx, void *handle)
+{
+    if (handle == ctx->geometry_shader) {
+      /* unbind before deleting */
+      ctx->pipe->bind_gs_state(ctx->pipe, NULL);
+      ctx->geometry_shader = NULL;
+   }
+   ctx->pipe->delete_gs_state(ctx->pipe, handle);
+}
+
+void cso_save_geometry_shader(struct cso_context *ctx)
+{
+   assert(!ctx->geometry_shader_saved);
+   ctx->geometry_shader_saved = ctx->geometry_shader;
+}
+
+void cso_restore_geometry_shader(struct cso_context *ctx)
+{
+   if (ctx->geometry_shader_saved != ctx->geometry_shader) {
+      ctx->pipe->bind_gs_state(ctx->pipe, ctx->geometry_shader_saved);
+      ctx->geometry_shader = ctx->geometry_shader_saved;
+   }
+   ctx->geometry_shader_saved = NULL;
+}
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h
index 69630e9..b9e313e 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.h
+++ b/src/gallium/auxiliary/cso_cache/cso_context.h
@@ -84,6 +84,20 @@
 
 void cso_single_sampler_done( struct cso_context *cso );
 
+void
+cso_save_vertex_samplers(struct cso_context *cso);
+
+void
+cso_restore_vertex_samplers(struct cso_context *cso);
+
+enum pipe_error
+cso_single_vertex_sampler(struct cso_context *cso,
+                          unsigned nr,
+                          const struct pipe_sampler_state *states);
+
+void
+cso_single_vertex_sampler_done(struct cso_context *cso);
+
 
 
 enum pipe_error cso_set_sampler_textures( struct cso_context *cso,
@@ -94,6 +108,17 @@
 
 
 
+enum pipe_error
+cso_set_vertex_sampler_textures(struct cso_context *cso,
+                                uint count,
+                                struct pipe_texture **textures);
+void
+cso_save_vertex_sampler_textures(struct cso_context *cso);
+void
+cso_restore_vertex_sampler_textures(struct cso_context *cso);
+
+
+
 /* These aren't really sensible -- most of the time the api provides
  * object semantics for shaders anyway, and the cases where it doesn't
  * (eg mesa's internall-generated texenv programs), it will be up to
@@ -121,6 +146,13 @@
 void cso_restore_vertex_shader(struct cso_context *cso);
 
 
+enum pipe_error cso_set_geometry_shader_handle(struct cso_context *ctx,
+                                               void *handle);
+void cso_delete_geometry_shader(struct cso_context *ctx, void *handle);
+void cso_save_geometry_shader(struct cso_context *cso);
+void cso_restore_geometry_shader(struct cso_context *cso);
+
+
 
 enum pipe_error cso_set_framebuffer(struct cso_context *cso,
                                     const struct pipe_framebuffer_state *fb);
diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile
deleted file mode 100644
index 5041dcc..0000000
--- a/src/gallium/auxiliary/draw/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = draw
-
-C_SOURCES = \
-	draw_context.c \
-	draw_pipe.c \
-	draw_pipe_aaline.c \
-	draw_pipe_aapoint.c \
-	draw_pipe_clip.c \
-	draw_pipe_cull.c \
-	draw_pipe_flatshade.c \
-	draw_pipe_offset.c \
-	draw_pipe_pstipple.c \
-	draw_pipe_stipple.c \
-	draw_pipe_twoside.c \
-	draw_pipe_unfilled.c \
-	draw_pipe_util.c \
-	draw_pipe_validate.c \
-	draw_pipe_vbuf.c \
-	draw_pipe_wide_line.c \
-	draw_pipe_wide_point.c \
-	draw_pt.c \
-	draw_pt_elts.c \
-	draw_pt_emit.c \
-	draw_pt_fetch.c \
-	draw_pt_fetch_emit.c \
-	draw_pt_fetch_shade_emit.c \
-	draw_pt_fetch_shade_pipeline.c \
-	draw_pt_post_vs.c \
-        draw_pt_util.c \
-        draw_pt_varray.c \
-	draw_pt_vcache.c \
-	draw_vertex.c \
-	draw_vs.c \
-	draw_vs_varient.c \
-	draw_vs_aos.c \
-	draw_vs_aos_io.c \
-	draw_vs_aos_machine.c \
-	draw_vs_exec.c \
-	draw_vs_llvm.c \
-	draw_vs_ppc.c  \
-	draw_vs_sse.c 
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript
deleted file mode 100644
index 5f05aa3..0000000
--- a/src/gallium/auxiliary/draw/SConscript
+++ /dev/null
@@ -1,46 +0,0 @@
-Import('*')
-
-draw = env.ConvenienceLibrary(
-	target = 'draw',
-	source = [
-		'draw_context.c',
-		'draw_pipe.c',
-		'draw_pipe_aaline.c',
-		'draw_pipe_aapoint.c',
-		'draw_pipe_clip.c',
-		'draw_pipe_cull.c',
-		'draw_pipe_flatshade.c',
-		'draw_pipe_offset.c',
-		'draw_pipe_pstipple.c',
-		'draw_pipe_stipple.c',
-		'draw_pipe_twoside.c',
-		'draw_pipe_unfilled.c',
-		'draw_pipe_util.c',
-		'draw_pipe_validate.c',
-		'draw_pipe_vbuf.c',
-		'draw_pipe_wide_line.c',
-		'draw_pipe_wide_point.c',
-		'draw_pt.c',
-		'draw_pt_elts.c',
-		'draw_pt_emit.c',
-		'draw_pt_fetch.c',
-		'draw_pt_fetch_emit.c',
-		'draw_pt_fetch_shade_emit.c',
-		'draw_pt_fetch_shade_pipeline.c',
-		'draw_pt_post_vs.c',
-		'draw_pt_util.c',
-		'draw_pt_varray.c',
-		'draw_pt_vcache.c',
-		'draw_vertex.c',
-		'draw_vs.c',
-		'draw_vs_aos.c',
-		'draw_vs_aos_io.c',
-		'draw_vs_aos_machine.c',
-		'draw_vs_exec.c',
-		'draw_vs_llvm.c',
-		'draw_vs_ppc.c',
-		'draw_vs_sse.c',
-		'draw_vs_varient.c'
-	])
-
-auxiliaries.insert(0, draw)
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index a4f1fcd..667aa46 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -36,6 +36,7 @@
 #include "draw_context.h"
 #include "draw_vbuf.h"
 #include "draw_vs.h"
+#include "draw_gs.h"
 #include "draw_pt.h"
 #include "draw_pipe.h"
 
@@ -67,6 +68,9 @@
    if (!draw_vs_init( draw ))
       goto fail;
 
+   if (!draw_gs_init( draw ))
+      goto fail;
+
    return draw;
 
 fail:
@@ -231,11 +235,19 @@
 
 void
 draw_set_mapped_constant_buffer(struct draw_context *draw,
-                                const void *buffer, 
+                                unsigned shader_type,
+                                const void *buffer,
                                 unsigned size )
 {
-   draw->pt.user.constants = buffer;
-   draw_vs_set_constants( draw, (const float (*)[4])buffer, size );
+   debug_assert(shader_type == PIPE_SHADER_VERTEX ||
+                shader_type == PIPE_SHADER_GEOMETRY);
+   if (shader_type == PIPE_SHADER_VERTEX) {
+      draw->pt.user.vs_constants = buffer;
+      draw_vs_set_constants( draw, (const float (*)[4])buffer, size );
+   } else if (shader_type == PIPE_SHADER_GEOMETRY) {
+      draw->pt.user.gs_constants = buffer;
+      draw_gs_set_constants( draw, (const float (*)[4])buffer, size );
+   }
 }
 
 
@@ -298,7 +310,7 @@
  * a post-transformed vertex.
  *
  * With this function, drivers that use the draw module should have no reason
- * to track the current vertex shader.
+ * to track the current vertex/geometry shader.
  *
  * Note that the draw module may sometimes generate vertices with extra
  * attributes (such as texcoords for AA lines).  The driver can call this
@@ -309,43 +321,59 @@
  * work for the drivers.
  */
 int
-draw_find_vs_output(const struct draw_context *draw,
-                    uint semantic_name, uint semantic_index)
+draw_find_shader_output(const struct draw_context *draw,
+                        uint semantic_name, uint semantic_index)
 {
    const struct draw_vertex_shader *vs = draw->vs.vertex_shader;
+   const struct draw_geometry_shader *gs = draw->gs.geometry_shader;
    uint i;
-   for (i = 0; i < vs->info.num_outputs; i++) {
-      if (vs->info.output_semantic_name[i] == semantic_name &&
-          vs->info.output_semantic_index[i] == semantic_index)
+   const struct tgsi_shader_info *info = &vs->info;
+
+   if (gs)
+      info = &gs->info;
+
+   for (i = 0; i < info->num_outputs; i++) {
+      if (info->output_semantic_name[i] == semantic_name &&
+          info->output_semantic_index[i] == semantic_index)
          return i;
    }
 
    /* XXX there may be more than one extra vertex attrib.
     * For example, simulated gl_FragCoord and gl_PointCoord.
     */
-   if (draw->extra_vp_outputs.semantic_name == semantic_name &&
-       draw->extra_vp_outputs.semantic_index == semantic_index) {
-      return draw->extra_vp_outputs.slot;
+   if (draw->extra_shader_outputs.semantic_name == semantic_name &&
+       draw->extra_shader_outputs.semantic_index == semantic_index) {
+      return draw->extra_shader_outputs.slot;
    }
+
    return 0;
 }
 
 
 /**
- * Return number of vertex shader outputs.
+ * Return number of the shader outputs.
+ *
+ * If geometry shader is present, its output will be returned,
+ * if not vertex shader is used.
  */
 uint
-draw_num_vs_outputs(const struct draw_context *draw)
+draw_num_shader_outputs(const struct draw_context *draw)
 {
    uint count = draw->vs.vertex_shader->info.num_outputs;
-   if (draw->extra_vp_outputs.slot > 0)
+
+   /* if geometry shader is present, its outputs go to te
+    * driver, not the vertex shaders */
+   if (draw->gs.geometry_shader)
+      count = draw->gs.geometry_shader->info.num_outputs;
+
+   if (draw->extra_shader_outputs.slot > 0)
       count++;
    return count;
 }
 
 
 /**
- * Provide TGSI sampler objects for vertex shaders that use texture fetches.
+ * Provide TGSI sampler objects for vertex/geometry shaders that use texture fetches.
  * This might only be used by software drivers for the time being.
  */
 void
@@ -355,6 +383,8 @@
 {
    draw->vs.num_samplers = num_samplers;
    draw->vs.samplers = samplers;
+   draw->gs.num_samplers = num_samplers;
+   draw->gs.samplers = samplers;
 }
 
 
@@ -366,13 +396,6 @@
    draw->render = render;
 }
 
-void draw_set_edgeflags( struct draw_context *draw,
-                         const unsigned *edgeflag )
-{
-   draw->pt.user.edgeflag = edgeflag;
-}
-
-
 
 
 /**
@@ -428,3 +451,18 @@
       draw->flushing = FALSE;
    }
 }
+
+
+int draw_current_shader_outputs(struct draw_context *draw)
+{
+   if (draw->gs.geometry_shader)
+      return draw->gs.num_gs_outputs;
+   return draw->vs.num_vs_outputs;
+}
+
+int draw_current_shader_position_output(struct draw_context *draw)
+{
+   if (draw->gs.geometry_shader)
+      return draw->gs.position_output;
+   return draw->vs.position_output;
+}
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index d529e4e..b716209 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -45,6 +45,7 @@
 struct draw_context;
 struct draw_stage;
 struct draw_vertex_shader;
+struct draw_geometry_shader;
 struct tgsi_sampler;
 
 
@@ -85,11 +86,11 @@
 
 
 int
-draw_find_vs_output(const struct draw_context *draw,
-                    uint semantic_name, uint semantic_index);
+draw_find_shader_output(const struct draw_context *draw,
+                        uint semantic_name, uint semantic_index);
 
 uint
-draw_num_vs_outputs(const struct draw_context *draw);
+draw_num_shader_outputs(const struct draw_context *draw);
 
 
 void
@@ -112,6 +113,17 @@
                                struct draw_vertex_shader *dvs);
 
 
+/*
+ * Geometry shader functions
+ */
+struct draw_geometry_shader *
+draw_create_geometry_shader(struct draw_context *draw,
+                            const struct pipe_shader_state *shader);
+void draw_bind_geometry_shader(struct draw_context *draw,
+                               struct draw_geometry_shader *dvs);
+void draw_delete_geometry_shader(struct draw_context *draw,
+                                 struct draw_geometry_shader *dvs);
+
 
 /*
  * Vertex data functions
@@ -140,12 +152,10 @@
                                    unsigned attr, const void *buffer);
 
 void draw_set_mapped_constant_buffer(struct draw_context *draw,
+                                     unsigned shader_type,
                                      const void *buffer,
                                      unsigned size );
 
-void draw_set_edgeflags( struct draw_context *draw,
-                         const unsigned *edgeflag );
-
 
 /***********************************************************************
  * draw_prim.c 
diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c
new file mode 100644
index 0000000..5db2e75
--- /dev/null
+++ b/src/gallium/auxiliary/draw/draw_gs.c
@@ -0,0 +1,338 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+#include "draw_gs.h"
+
+#include "draw_private.h"
+#include "draw_context.h"
+
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_exec.h"
+
+#include "pipe/p_shader_tokens.h"
+
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#define MAX_PRIM_VERTICES 6
+/* fixme: move it from here */
+#define MAX_PRIMITIVES 64
+
+boolean
+draw_gs_init( struct draw_context *draw )
+{
+   draw->gs.machine = tgsi_exec_machine_create();
+   if (!draw->gs.machine)
+      return FALSE;
+
+   draw->gs.machine->Primitives = align_malloc(
+      MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector), 16);
+   if (!draw->gs.machine->Primitives)
+      return FALSE;
+   memset(draw->gs.machine->Primitives, 0,
+          MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector));
+
+   return TRUE;
+}
+
+
+void draw_gs_set_constants( struct draw_context *draw,
+                            const float (*constants)[4],
+                            unsigned size )
+{
+}
+
+
+struct draw_geometry_shader *
+draw_create_geometry_shader(struct draw_context *draw,
+                            const struct pipe_shader_state *state)
+{
+   struct draw_geometry_shader *gs;
+   int i;
+
+   gs = CALLOC_STRUCT(draw_geometry_shader);
+
+   if (!gs)
+      return NULL;
+
+   gs->state = *state;
+   gs->state.tokens = tgsi_dup_tokens(state->tokens);
+   if (!gs->state.tokens) {
+      FREE(gs);
+      return NULL;
+   }
+
+   tgsi_scan_shader(state->tokens, &gs->info);
+
+   /* setup the defaults */
+   gs->input_primitive = PIPE_PRIM_TRIANGLES;
+   gs->output_primitive = PIPE_PRIM_TRIANGLE_STRIP;
+   gs->max_output_vertices = 32;
+
+   for (i = 0; i < gs->info.num_properties; ++i) {
+      if (gs->info.properties[i].name ==
+          TGSI_PROPERTY_GS_INPUT_PRIM)
+         gs->input_primitive = gs->info.properties[i].data[0];
+      else if (gs->info.properties[i].name ==
+               TGSI_PROPERTY_GS_OUTPUT_PRIM)
+         gs->output_primitive = gs->info.properties[i].data[0];
+      else if (gs->info.properties[i].name ==
+               TGSI_PROPERTY_GS_MAX_VERTICES)
+         gs->max_output_vertices = gs->info.properties[i].data[0];
+   }
+
+   gs->machine = draw->gs.machine;
+
+   if (gs)
+   {
+      uint i;
+      for (i = 0; i < gs->info.num_outputs; i++) {
+         if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
+             gs->info.output_semantic_index[i] == 0)
+            gs->position_output = i;
+      }
+   }
+
+   return gs;
+}
+
+void draw_bind_geometry_shader(struct draw_context *draw,
+                               struct draw_geometry_shader *dgs)
+{
+   draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
+
+   if (dgs) {
+      draw->gs.geometry_shader = dgs;
+      draw->gs.num_gs_outputs = dgs->info.num_outputs;
+      draw->gs.position_output = dgs->position_output;
+      draw_geometry_shader_prepare(dgs, draw);
+   }
+   else {
+      draw->gs.geometry_shader = NULL;
+      draw->gs.num_gs_outputs = 0;
+   }
+}
+
+void draw_delete_geometry_shader(struct draw_context *draw,
+                                 struct draw_geometry_shader *dgs)
+{
+   FREE(dgs);
+}
+
+static INLINE int num_vertices_for_prim(int prim)
+{
+   switch(prim) {
+   case PIPE_PRIM_POINTS:
+      return 1;
+   case PIPE_PRIM_LINES:
+      return 2;
+   case PIPE_PRIM_LINE_LOOP:
+      return 2;
+   case PIPE_PRIM_LINE_STRIP:
+      return 2;
+   case PIPE_PRIM_TRIANGLES:
+      return 3;
+   case PIPE_PRIM_TRIANGLE_STRIP:
+      return 3;
+   case PIPE_PRIM_TRIANGLE_FAN:
+      return 3;
+   case PIPE_PRIM_LINES_ADJACENCY:
+   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+      return 4;
+   case PIPE_PRIM_TRIANGLES_ADJACENCY:
+   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
+      return 6;
+   default:
+      assert(!"Bad geometry shader input");
+      return 0;
+   }
+}
+
+static void draw_fetch_geometry_input(struct draw_geometry_shader *shader,
+                                      int start_primitive,
+                                      int num_primitives,
+                                      const float (*input_ptr)[4],
+                                      unsigned input_vertex_stride,
+                                      unsigned inputs_from_vs)
+{
+   struct tgsi_exec_machine *machine = shader->machine;
+   unsigned slot, vs_slot, k, j;
+   unsigned num_vertices = num_vertices_for_prim(shader->input_primitive);
+   int idx = 0;
+
+   for (slot = 0, vs_slot = 0; slot < shader->info.num_inputs; slot++) {
+      /*debug_printf("Slot = %d (semantic = %d)\n", slot,
+        shader->info.input_semantic_name[slot]);*/
+      if (shader->info.input_semantic_name[slot] ==
+          TGSI_SEMANTIC_PRIMID) {
+         for (j = 0; j < num_primitives; ++j) {
+            machine->Inputs[idx].xyzw[0].f[j] = (float)start_primitive + j;
+            machine->Inputs[idx].xyzw[1].f[j] = (float)start_primitive + j;
+            machine->Inputs[idx].xyzw[2].f[j] = (float)start_primitive + j;
+            machine->Inputs[idx].xyzw[3].f[j] = (float)start_primitive + j;
+         }
+         ++idx;
+      } else {
+         for (j = 0; j < num_primitives; ++j) {
+            int vidx = idx;
+            const float (*prim_ptr)[4];
+            /*debug_printf("    %d) Prim (num_verts = %d)\n", start_primitive + j,
+              num_vertices);*/
+            prim_ptr = (const float (*)[4])(
+               (const char *)input_ptr +
+               (j * num_vertices * input_vertex_stride));
+
+            for (k = 0; k < num_vertices; ++k, ++vidx) {
+               const float (*input)[4];
+               input = (const float (*)[4])(
+                  (const char *)prim_ptr + (k * input_vertex_stride));
+               vidx = k * TGSI_EXEC_MAX_INPUT_ATTRIBS + slot;
+               /*debug_printf("\t%d)(%d) Input vert:\n", vidx, k);*/
+#if 1
+               assert(!util_is_inf_or_nan(input[vs_slot][0]));
+               assert(!util_is_inf_or_nan(input[vs_slot][1]));
+               assert(!util_is_inf_or_nan(input[vs_slot][2]));
+               assert(!util_is_inf_or_nan(input[vs_slot][3]));
+#endif
+               machine->Inputs[vidx].xyzw[0].f[j] = input[vs_slot][0];
+               machine->Inputs[vidx].xyzw[1].f[j] = input[vs_slot][1];
+               machine->Inputs[vidx].xyzw[2].f[j] = input[vs_slot][2];
+               machine->Inputs[vidx].xyzw[3].f[j] = input[vs_slot][3];
+#if 0
+               debug_printf("\t\t%d %f %f %f %f\n", slot,
+                            machine->Inputs[vidx].xyzw[0].f[j],
+                            machine->Inputs[vidx].xyzw[1].f[j],
+                            machine->Inputs[vidx].xyzw[2].f[j],
+                            machine->Inputs[vidx].xyzw[3].f[j]);
+#endif
+            }
+         }
+         ++vs_slot;
+         idx += num_vertices;
+      }
+   }
+}
+
+static INLINE void
+draw_geometry_fetch_outputs(struct draw_geometry_shader *shader,
+                            int num_primitives,
+                            float (*output)[4],
+                            unsigned vertex_size)
+{
+   struct tgsi_exec_machine *machine = shader->machine;
+   unsigned prim_idx, j, slot;
+
+   /* Unswizzle all output results.
+    */
+   /* FIXME: handle all the primitives produced by the gs, not just
+    * the first one
+    unsigned prim_count =
+    mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0];*/
+   for (prim_idx = 0; prim_idx < num_primitives; ++prim_idx) {
+      unsigned num_verts_per_prim = machine->Primitives[0];
+      for (j = 0; j < num_verts_per_prim; j++) {
+         int idx = (prim_idx * num_verts_per_prim + j) *
+                   shader->info.num_outputs;
+#ifdef DEBUG_OUTPUTS
+         debug_printf("%d) Output vert:\n", idx);
+#endif
+         for (slot = 0; slot < shader->info.num_outputs; slot++) {
+            output[slot][0] = machine->Outputs[idx + slot].xyzw[0].f[prim_idx];
+            output[slot][1] = machine->Outputs[idx + slot].xyzw[1].f[prim_idx];
+            output[slot][2] = machine->Outputs[idx + slot].xyzw[2].f[prim_idx];
+            output[slot][3] = machine->Outputs[idx + slot].xyzw[3].f[prim_idx];
+#ifdef DEBUG_OUTPUTS
+            debug_printf("\t%d: %f %f %f %f\n", slot,
+                         output[slot][0],
+                         output[slot][1],
+                         output[slot][2],
+                         output[slot][3]);
+#endif
+            debug_assert(!util_is_inf_or_nan(output[slot][0]));
+         }
+         output = (float (*)[4])((char *)output + vertex_size);
+      }
+   }
+}
+
+void draw_geometry_shader_run(struct draw_geometry_shader *shader,
+                              const float (*input)[4],
+                              float (*output)[4],
+                              const float (*constants)[4],
+                              unsigned count,
+                              unsigned input_stride,
+                              unsigned vertex_size)
+{
+   struct tgsi_exec_machine *machine = shader->machine;
+   unsigned int i;
+   unsigned num_vertices = num_vertices_for_prim(shader->input_primitive);
+   unsigned num_primitives = count/num_vertices;
+   unsigned inputs_from_vs = 0;
+
+   machine->Consts = constants;
+
+   for (i = 0; i < shader->info.num_inputs; ++i) {
+      if (shader->info.input_semantic_name[i] != TGSI_SEMANTIC_PRIMID)
+         ++inputs_from_vs;
+   }
+
+   for (i = 0; i < num_primitives; ++i) {
+      unsigned int max_primitives = 1;
+
+      draw_fetch_geometry_input(shader, i, max_primitives, input,
+                                input_stride, inputs_from_vs);
+
+      tgsi_set_exec_mask(machine,
+                         1,
+                         max_primitives > 1,
+                         max_primitives > 2,
+                         max_primitives > 3);
+
+      /* run interpreter */
+      tgsi_exec_machine_run(machine);
+
+      draw_geometry_fetch_outputs(shader, max_primitives,
+                                  output, vertex_size);
+   }
+}
+
+void draw_geometry_shader_delete(struct draw_geometry_shader *shader)
+{
+   FREE((void*) shader->state.tokens);
+   FREE(shader);
+}
+
+void draw_geometry_shader_prepare(struct draw_geometry_shader *shader,
+                                  struct draw_context *draw)
+{
+    if (shader->machine->Tokens != shader->state.tokens) {
+       tgsi_exec_machine_bind_shader(shader->machine,
+                                     shader->state.tokens,
+                                     draw->gs.num_samplers,
+                                     draw->gs.samplers);
+    }
+}
diff --git a/src/gallium/auxiliary/draw/draw_gs.h b/src/gallium/auxiliary/draw/draw_gs.h
new file mode 100644
index 0000000..d6a97d9
--- /dev/null
+++ b/src/gallium/auxiliary/draw/draw_gs.h
@@ -0,0 +1,76 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#ifndef DRAW_GS_H
+#define DRAW_GS_H
+
+#include "draw_context.h"
+#include "draw_private.h"
+
+
+#define MAX_TGSI_PRIMITIVES 4
+
+struct draw_context;
+
+/**
+ * Private version of the compiled geometry shader
+ */
+struct draw_geometry_shader {
+   struct draw_context *draw;
+
+   struct tgsi_exec_machine *machine;
+
+   /* This member will disappear shortly:*/
+   struct pipe_shader_state state;
+
+   struct tgsi_shader_info info;
+   unsigned position_output;
+
+   unsigned max_output_vertices;
+   unsigned input_primitive;
+   unsigned output_primitive;
+
+   /* Extracted from shader:
+    */
+   const float (*immediates)[4];
+};
+
+void draw_geometry_shader_run(struct draw_geometry_shader *shader,
+                              const float (*input)[4],
+                              float (*output)[4],
+                              const float (*constants)[4],
+                              unsigned count,
+                              unsigned input_stride,
+                              unsigned output_stride);
+
+void draw_geometry_shader_prepare(struct draw_geometry_shader *shader,
+                                  struct draw_context *draw);
+
+void draw_geometry_shader_delete(struct draw_geometry_shader *shader);
+
+
+#endif
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
index 9f95671..4585dcd 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
@@ -35,6 +35,8 @@
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_shader_tokens.h"
+
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 
@@ -139,29 +141,29 @@
    struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
 
    if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
-       decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR &&
-       decl->Semantic.SemanticIndex == 0) {
-      aactx->colorOutput = decl->DeclarationRange.First;
+       decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
+       decl->Semantic.Index == 0) {
+      aactx->colorOutput = decl->Range.First;
    }
    else if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
       uint i;
-      for (i = decl->DeclarationRange.First;
-           i <= decl->DeclarationRange.Last; i++) {
+      for (i = decl->Range.First;
+           i <= decl->Range.Last; i++) {
          aactx->samplersUsed |= 1 << i;
       }
    }
    else if (decl->Declaration.File == TGSI_FILE_INPUT) {
-      if ((int) decl->DeclarationRange.Last > aactx->maxInput)
-         aactx->maxInput = decl->DeclarationRange.Last;
-      if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC &&
-           (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) {
-         aactx->maxGeneric = decl->Semantic.SemanticIndex;
+      if ((int) decl->Range.Last > aactx->maxInput)
+         aactx->maxInput = decl->Range.Last;
+      if (decl->Semantic.Name == TGSI_SEMANTIC_GENERIC &&
+           (int) decl->Semantic.Index > aactx->maxGeneric) {
+         aactx->maxGeneric = decl->Semantic.Index;
       }
    }
    else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
       uint i;
-      for (i = decl->DeclarationRange.First;
-           i <= decl->DeclarationRange.Last; i++) {
+      for (i = decl->Range.First;
+           i <= decl->Range.Last; i++) {
          aactx->tempsUsed |= (1 << i);
       }
    }
@@ -228,30 +230,30 @@
       /* XXX this could be linear... */
       decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
       decl.Declaration.Semantic = 1;
-      decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC;
-      decl.Semantic.SemanticIndex = aactx->maxGeneric + 1;
-      decl.DeclarationRange.First = 
-      decl.DeclarationRange.Last = aactx->maxInput + 1;
+      decl.Semantic.Name = TGSI_SEMANTIC_GENERIC;
+      decl.Semantic.Index = aactx->maxGeneric + 1;
+      decl.Range.First = 
+      decl.Range.Last = aactx->maxInput + 1;
       ctx->emit_declaration(ctx, &decl);
 
       /* declare new sampler */
       decl = tgsi_default_full_declaration();
       decl.Declaration.File = TGSI_FILE_SAMPLER;
-      decl.DeclarationRange.First = 
-      decl.DeclarationRange.Last = aactx->freeSampler;
+      decl.Range.First = 
+      decl.Range.Last = aactx->freeSampler;
       ctx->emit_declaration(ctx, &decl);
 
       /* declare new temp regs */
       decl = tgsi_default_full_declaration();
       decl.Declaration.File = TGSI_FILE_TEMPORARY;
-      decl.DeclarationRange.First = 
-      decl.DeclarationRange.Last = aactx->texTemp;
+      decl.Range.First = 
+      decl.Range.Last = aactx->texTemp;
       ctx->emit_declaration(ctx, &decl);
 
       decl = tgsi_default_full_declaration();
       decl.Declaration.File = TGSI_FILE_TEMPORARY;
-      decl.DeclarationRange.First = 
-      decl.DeclarationRange.Last = aactx->colorTemp;
+      decl.Range.First = 
+      decl.Range.Last = aactx->colorTemp;
       ctx->emit_declaration(ctx, &decl);
 
       aactx->firstInstruction = FALSE;
@@ -265,14 +267,15 @@
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_TEX;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = aactx->texTemp;
+      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Dst[0].Register.Index = aactx->texTemp;
       newInst.Instruction.NumSrcRegs = 2;
-      newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->maxInput + 1;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->freeSampler;
+      newInst.Instruction.Texture = TRUE;
+      newInst.Texture.Texture = TGSI_TEXTURE_2D;
+      newInst.Src[0].Register.File = TGSI_FILE_INPUT;
+      newInst.Src[0].Register.Index = aactx->maxInput + 1;
+      newInst.Src[1].Register.File = TGSI_FILE_SAMPLER;
+      newInst.Src[1].Register.Index = aactx->freeSampler;
 
       ctx->emit_instruction(ctx, &newInst);
 
@@ -280,26 +283,26 @@
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_MOV;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
-      newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ;
+      newInst.Dst[0].Register.File = TGSI_FILE_OUTPUT;
+      newInst.Dst[0].Register.Index = aactx->colorOutput;
+      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZ;
       newInst.Instruction.NumSrcRegs = 1;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp;
+      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[0].Register.Index = aactx->colorTemp;
       ctx->emit_instruction(ctx, &newInst);
 
       /* MUL alpha */
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
-      newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
+      newInst.Dst[0].Register.File = TGSI_FILE_OUTPUT;
+      newInst.Dst[0].Register.Index = aactx->colorOutput;
+      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_W;
       newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->texTemp;
+      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[0].Register.Index = aactx->colorTemp;
+      newInst.Src[1].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[1].Register.Index = aactx->texTemp;
       ctx->emit_instruction(ctx, &newInst);
 
       /* END */
@@ -316,11 +319,11 @@
       uint i;
 
       for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
-         struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
-         if (dst->DstRegister.File == TGSI_FILE_OUTPUT &&
-             dst->DstRegister.Index == aactx->colorOutput) {
-            dst->DstRegister.File = TGSI_FILE_TEMPORARY;
-            dst->DstRegister.Index = aactx->colorTemp;
+         struct tgsi_full_dst_register *dst = &inst->Dst[i];
+         if (dst->Register.File == TGSI_FILE_OUTPUT &&
+             dst->Register.Index == aactx->colorOutput) {
+            dst->Register.File = TGSI_FILE_TEMPORARY;
+            dst->Register.Index = aactx->colorTemp;
          }
       }
 
@@ -398,10 +401,9 @@
    texTemp.target = PIPE_TEXTURE_2D;
    texTemp.format = PIPE_FORMAT_A8_UNORM; /* XXX verify supported by driver! */
    texTemp.last_level = MAX_TEXTURE_LEVEL;
-   texTemp.width[0] = 1 << MAX_TEXTURE_LEVEL;
-   texTemp.height[0] = 1 << MAX_TEXTURE_LEVEL;
-   texTemp.depth[0] = 1;
-   pf_get_block(texTemp.format, &texTemp.block);
+   texTemp.width0 = 1 << MAX_TEXTURE_LEVEL;
+   texTemp.height0 = 1 << MAX_TEXTURE_LEVEL;
+   texTemp.depth0 = 1;
 
    aaline->texture = screen->texture_create(screen, &texTemp);
    if (!aaline->texture)
@@ -413,11 +415,11 @@
     */
    for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) {
       struct pipe_transfer *transfer;
-      const uint size = aaline->texture->width[level];
+      const uint size = u_minify(aaline->texture->width0, level);
       ubyte *data;
       uint i, j;
 
-      assert(aaline->texture->width[level] == aaline->texture->height[level]);
+      assert(aaline->texture->width0 == aaline->texture->height0);
 
       /* This texture is new, no need to flush. 
        */
@@ -658,13 +660,13 @@
    }
 
    /* update vertex attrib info */
-   aaline->tex_slot = draw->vs.num_vs_outputs;
-   aaline->pos_slot = draw->vs.position_output;
+   aaline->tex_slot = draw_current_shader_outputs(draw);
+   aaline->pos_slot = draw_current_shader_position_output(draw);;
 
    /* advertise the extra post-transformed vertex attribute */
-   draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
-   draw->extra_vp_outputs.semantic_index = aaline->fs->generic_attrib;
-   draw->extra_vp_outputs.slot = aaline->tex_slot;
+   draw->extra_shader_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
+   draw->extra_shader_outputs.semantic_index = aaline->fs->generic_attrib;
+   draw->extra_shader_outputs.slot = aaline->tex_slot;
 
    /* how many samplers? */
    /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
@@ -705,7 +707,7 @@
                                        aaline->state.texture);
    draw->suspend_flushing = FALSE;
 
-   draw->extra_vp_outputs.slot = 0;
+   draw->extra_shader_outputs.slot = 0;
 }
 
 
@@ -896,16 +898,16 @@
    aaline->driver_bind_fs_state = pipe->bind_fs_state;
    aaline->driver_delete_fs_state = pipe->delete_fs_state;
 
-   aaline->driver_bind_sampler_states = pipe->bind_sampler_states;
-   aaline->driver_set_sampler_textures = pipe->set_sampler_textures;
+   aaline->driver_bind_sampler_states = pipe->bind_fragment_sampler_states;
+   aaline->driver_set_sampler_textures = pipe->set_fragment_sampler_textures;
 
    /* override the driver's functions */
    pipe->create_fs_state = aaline_create_fs_state;
    pipe->bind_fs_state = aaline_bind_fs_state;
    pipe->delete_fs_state = aaline_delete_fs_state;
 
-   pipe->bind_sampler_states = aaline_bind_sampler_states;
-   pipe->set_sampler_textures = aaline_set_sampler_textures;
+   pipe->bind_fragment_sampler_states = aaline_bind_sampler_states;
+   pipe->set_fragment_sampler_textures = aaline_set_sampler_textures;
    
    /* Install once everything is known to be OK:
     */
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
index ae1712f..d86717e 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
@@ -131,22 +131,22 @@
    struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
 
    if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
-       decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR &&
-       decl->Semantic.SemanticIndex == 0) {
-      aactx->colorOutput = decl->DeclarationRange.First;
+       decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
+       decl->Semantic.Index == 0) {
+      aactx->colorOutput = decl->Range.First;
    }
    else if (decl->Declaration.File == TGSI_FILE_INPUT) {
-      if ((int) decl->DeclarationRange.Last > aactx->maxInput)
-         aactx->maxInput = decl->DeclarationRange.Last;
-      if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC &&
-           (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) {
-         aactx->maxGeneric = decl->Semantic.SemanticIndex;
+      if ((int) decl->Range.Last > aactx->maxInput)
+         aactx->maxInput = decl->Range.Last;
+      if (decl->Semantic.Name == TGSI_SEMANTIC_GENERIC &&
+           (int) decl->Semantic.Index > aactx->maxGeneric) {
+         aactx->maxGeneric = decl->Semantic.Index;
       }
    }
    else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
       uint i;
-      for (i = decl->DeclarationRange.First;
-           i <= decl->DeclarationRange.Last; i++) {
+      for (i = decl->Range.First;
+           i <= decl->Range.Last; i++) {
          aactx->tempsUsed |= (1 << i);
       }
    }
@@ -198,23 +198,23 @@
       /* XXX this could be linear... */
       decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
       decl.Declaration.Semantic = 1;
-      decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC;
-      decl.Semantic.SemanticIndex = aactx->maxGeneric + 1;
-      decl.DeclarationRange.First = 
-      decl.DeclarationRange.Last = texInput;
+      decl.Semantic.Name = TGSI_SEMANTIC_GENERIC;
+      decl.Semantic.Index = aactx->maxGeneric + 1;
+      decl.Range.First = 
+      decl.Range.Last = texInput;
       ctx->emit_declaration(ctx, &decl);
 
       /* declare new temp regs */
       decl = tgsi_default_full_declaration();
       decl.Declaration.File = TGSI_FILE_TEMPORARY;
-      decl.DeclarationRange.First = 
-      decl.DeclarationRange.Last = tmp0;
+      decl.Range.First = 
+      decl.Range.Last = tmp0;
       ctx->emit_declaration(ctx, &decl);
 
       decl = tgsi_default_full_declaration();
       decl.Declaration.File = TGSI_FILE_TEMPORARY;
-      decl.DeclarationRange.First = 
-      decl.DeclarationRange.Last = aactx->colorTemp;
+      decl.Range.First = 
+      decl.Range.Last = aactx->colorTemp;
       ctx->emit_declaration(ctx, &decl);
 
       aactx->firstInstruction = FALSE;
@@ -234,30 +234,30 @@
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XY;
+      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Dst[0].Register.Index = tmp0;
+      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XY;
       newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
+      newInst.Src[0].Register.File = TGSI_FILE_INPUT;
+      newInst.Src[0].Register.Index = texInput;
+      newInst.Src[1].Register.File = TGSI_FILE_INPUT;
+      newInst.Src[1].Register.Index = texInput;
       ctx->emit_instruction(ctx, &newInst);
 
       /* ADD t0.x, t0.x, t0.y;  # x^2 + y^2 */
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_ADD;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X;
+      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Dst[0].Register.Index = tmp0;
+      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_X;
       newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
+      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[0].Register.Index = tmp0;
+      newInst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_X;
+      newInst.Src[1].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[1].Register.Index = tmp0;
+      newInst.Src[1].Register.SwizzleX = TGSI_SWIZZLE_Y;
       ctx->emit_instruction(ctx, &newInst);
 
 #if NORMALIZE  /* OPTIONAL normalization of length */
@@ -265,24 +265,24 @@
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_RSQ;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X;
+      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Dst[0].Register.Index = tmp0;
+      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_X;
       newInst.Instruction.NumSrcRegs = 1;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
+      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[0].Register.Index = tmp0;
       ctx->emit_instruction(ctx, &newInst);
 
       /* RCP t0.x, t0.x; */
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_RCP;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X;
+      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Dst[0].Register.Index = tmp0;
+      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_X;
       newInst.Instruction.NumSrcRegs = 1;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
+      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[0].Register.Index = tmp0;
       ctx->emit_instruction(ctx, &newInst);
 #endif
 
@@ -290,16 +290,16 @@
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_SGT;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y;
+      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Dst[0].Register.Index = tmp0;
+      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_Y;
       newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
+      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[0].Register.Index = tmp0;
+      newInst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X;
+      newInst.Src[1].Register.File = TGSI_FILE_INPUT;
+      newInst.Src[1].Register.Index = texInput;
+      newInst.Src[1].Register.SwizzleY = TGSI_SWIZZLE_W;
       ctx->emit_instruction(ctx, &newInst);
 
       /* KIL -tmp0.yyyy;   # if -tmp0.y < 0, KILL */
@@ -307,13 +307,13 @@
       newInst.Instruction.Opcode = TGSI_OPCODE_KIL;
       newInst.Instruction.NumDstRegs = 0;
       newInst.Instruction.NumSrcRegs = 1;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[0].SrcRegister.Negate = 1;
+      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[0].Register.Index = tmp0;
+      newInst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_Y;
+      newInst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_Y;
+      newInst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_Y;
+      newInst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_Y;
+      newInst.Src[0].Register.Negate = 1;
       ctx->emit_instruction(ctx, &newInst);
 
 
@@ -323,77 +323,77 @@
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_SUB;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z;
+      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Dst[0].Register.Index = tmp0;
+      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_Z;
       newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
+      newInst.Src[0].Register.File = TGSI_FILE_INPUT;
+      newInst.Src[0].Register.Index = texInput;
+      newInst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_W;
+      newInst.Src[1].Register.File = TGSI_FILE_INPUT;
+      newInst.Src[1].Register.Index = texInput;
+      newInst.Src[1].Register.SwizzleZ = TGSI_SWIZZLE_Z;
       ctx->emit_instruction(ctx, &newInst);
 
       /* RCP t0.z, t0.z;  # t0.z = 1 / m */
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_RCP;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z;
+      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Dst[0].Register.Index = tmp0;
+      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_Z;
       newInst.Instruction.NumSrcRegs = 1;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Z;
+      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[0].Register.Index = tmp0;
+      newInst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_Z;
       ctx->emit_instruction(ctx, &newInst);
 
       /* SUB t0.y, 1, t0.x;  # d = 1 - d */
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_SUB;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y;
+      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Dst[0].Register.Index = tmp0;
+      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_Y;
       newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
+      newInst.Src[0].Register.File = TGSI_FILE_INPUT;
+      newInst.Src[0].Register.Index = texInput;
+      newInst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_W;
+      newInst.Src[1].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[1].Register.Index = tmp0;
+      newInst.Src[1].Register.SwizzleY = TGSI_SWIZZLE_X;
       ctx->emit_instruction(ctx, &newInst);
 
       /* MUL t0.w, t0.y, t0.z;   # coverage = d * m */
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
+      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Dst[0].Register.Index = tmp0;
+      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_W;
       newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Z;
+      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[0].Register.Index = tmp0;
+      newInst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_Y;
+      newInst.Src[1].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[1].Register.Index = tmp0;
+      newInst.Src[1].Register.SwizzleW = TGSI_SWIZZLE_Z;
       ctx->emit_instruction(ctx, &newInst);
 
       /* SLE t0.y, t0.x, tex.z;  # bool b = distance <= k */
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_SLE;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y;
+      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Dst[0].Register.Index = tmp0;
+      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_Y;
       newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Z;
+      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[0].Register.Index = tmp0;
+      newInst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X;
+      newInst.Src[1].Register.File = TGSI_FILE_INPUT;
+      newInst.Src[1].Register.Index = texInput;
+      newInst.Src[1].Register.SwizzleY = TGSI_SWIZZLE_Z;
       ctx->emit_instruction(ctx, &newInst);
 
       /* CMP t0.w, -t0.y, tex.w, t0.w;
@@ -405,29 +405,29 @@
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_CMP;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
+      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Dst[0].Register.Index = tmp0;
+      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_W;
       newInst.Instruction.NumSrcRegs = 3;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[0].SrcRegister.Negate = 1;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[2].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
+      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[0].Register.Index = tmp0;
+      newInst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_Y;
+      newInst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_Y;
+      newInst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_Y;
+      newInst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_Y;
+      newInst.Src[0].Register.Negate = 1;
+      newInst.Src[1].Register.File = TGSI_FILE_INPUT;
+      newInst.Src[1].Register.Index = texInput;
+      newInst.Src[1].Register.SwizzleX = TGSI_SWIZZLE_W;
+      newInst.Src[1].Register.SwizzleY = TGSI_SWIZZLE_W;
+      newInst.Src[1].Register.SwizzleZ = TGSI_SWIZZLE_W;
+      newInst.Src[1].Register.SwizzleW = TGSI_SWIZZLE_W;
+      newInst.Src[2].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[2].Register.Index = tmp0;
+      newInst.Src[2].Register.SwizzleX = TGSI_SWIZZLE_W;
+      newInst.Src[2].Register.SwizzleY = TGSI_SWIZZLE_W;
+      newInst.Src[2].Register.SwizzleZ = TGSI_SWIZZLE_W;
+      newInst.Src[2].Register.SwizzleW = TGSI_SWIZZLE_W;
       ctx->emit_instruction(ctx, &newInst);
 
    }
@@ -439,26 +439,26 @@
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_MOV;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
-      newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ;
+      newInst.Dst[0].Register.File = TGSI_FILE_OUTPUT;
+      newInst.Dst[0].Register.Index = aactx->colorOutput;
+      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZ;
       newInst.Instruction.NumSrcRegs = 1;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp;
+      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[0].Register.Index = aactx->colorTemp;
       ctx->emit_instruction(ctx, &newInst);
 
       /* MUL result.color.w, colorTemp, tmp0.w; */
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
-      newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
+      newInst.Dst[0].Register.File = TGSI_FILE_OUTPUT;
+      newInst.Dst[0].Register.Index = aactx->colorOutput;
+      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_W;
       newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->tmp0;
+      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[0].Register.Index = aactx->colorTemp;
+      newInst.Src[1].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[1].Register.Index = aactx->tmp0;
       ctx->emit_instruction(ctx, &newInst);
    }
    else {
@@ -468,11 +468,11 @@
       uint i;
 
       for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
-         struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
-         if (dst->DstRegister.File == TGSI_FILE_OUTPUT &&
-             dst->DstRegister.Index == aactx->colorOutput) {
-            dst->DstRegister.File = TGSI_FILE_TEMPORARY;
-            dst->DstRegister.Index = aactx->colorTemp;
+         struct tgsi_full_dst_register *dst = &inst->Dst[i];
+         if (dst->Register.File == TGSI_FILE_OUTPUT &&
+             dst->Register.Index == aactx->colorOutput) {
+            dst->Register.File = TGSI_FILE_TEMPORARY;
+            dst->Register.Index = aactx->colorTemp;
          }
       }
    }
@@ -687,14 +687,14 @@
    bind_aapoint_fragment_shader(aapoint);
 
    /* update vertex attrib info */
-   aapoint->tex_slot = draw->vs.num_vs_outputs;
+   aapoint->tex_slot = draw_current_shader_outputs(draw);
    assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */
 
-   aapoint->pos_slot = draw->vs.position_output;
+   aapoint->pos_slot = draw_current_shader_position_output(draw);
 
-   draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
-   draw->extra_vp_outputs.semantic_index = aapoint->fs->generic_attrib;
-   draw->extra_vp_outputs.slot = aapoint->tex_slot;
+   draw->extra_shader_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
+   draw->extra_shader_outputs.semantic_index = aapoint->fs->generic_attrib;
+   draw->extra_shader_outputs.slot = aapoint->tex_slot;
 
    /* find psize slot in post-transform vertex */
    aapoint->psize_slot = -1;
@@ -731,7 +731,7 @@
    aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs);
    draw->suspend_flushing = FALSE;
 
-   draw->extra_vp_outputs.slot = 0;
+   draw->extra_shader_outputs.slot = 0;
 }
 
 
diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c
index 0670268..205cda5 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_clip.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c
@@ -114,8 +114,8 @@
 		    const struct vertex_header *out, 
 		    const struct vertex_header *in )
 {
-   const unsigned nr_attrs = clip->stage.draw->vs.num_vs_outputs;
-   const unsigned pos_attr = clip->stage.draw->vs.position_output;
+   const unsigned nr_attrs = draw_current_shader_outputs(clip->stage.draw);
+   const unsigned pos_attr = draw_current_shader_position_output(clip->stage.draw);
    unsigned j;
 
    /* Vertex header.
diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c
index 0a70483..11b39db 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_cull.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c
@@ -55,7 +55,7 @@
 static void cull_tri( struct draw_stage *stage,
 		      struct prim_header *header )
 {
-   const unsigned pos = stage->draw->vs.position_output;
+   const unsigned pos = draw_current_shader_position_output(stage->draw);
 
    /* Window coords: */
    const float *v0 = header->v[0]->data[pos];
diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c
index 40798a5..e829492 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_offset.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c
@@ -63,7 +63,7 @@
 static void do_offset_tri( struct draw_stage *stage,
 			   struct prim_header *header )
 {
-   const unsigned pos = stage->draw->vs.position_output;
+   const unsigned pos = draw_current_shader_position_output(stage->draw);
    struct offset_stage *offset = offset_stage(stage);   
    float inv_det = 1.0f / header->det;
 
diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
index 283502c..0cc2b71 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
@@ -38,6 +38,7 @@
 #include "pipe/p_defines.h"
 #include "pipe/p_shader_tokens.h"
 
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 
@@ -133,20 +134,20 @@
 
    if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
       uint i;
-      for (i = decl->DeclarationRange.First;
-           i <= decl->DeclarationRange.Last; i++) {
+      for (i = decl->Range.First;
+           i <= decl->Range.Last; i++) {
          pctx->samplersUsed |= 1 << i;
       }
    }
    else if (decl->Declaration.File == TGSI_FILE_INPUT) {
-      pctx->maxInput = MAX2(pctx->maxInput, (int) decl->DeclarationRange.Last);
-      if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION)
-         pctx->wincoordInput = (int) decl->DeclarationRange.First;
+      pctx->maxInput = MAX2(pctx->maxInput, (int) decl->Range.Last);
+      if (decl->Semantic.Name == TGSI_SEMANTIC_POSITION)
+         pctx->wincoordInput = (int) decl->Range.First;
    }
    else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
       uint i;
-      for (i = decl->DeclarationRange.First;
-           i <= decl->DeclarationRange.Last; i++) {
+      for (i = decl->Range.First;
+           i <= decl->Range.Last; i++) {
          pctx->tempsUsed |= (1 << i);
       }
    }
@@ -226,25 +227,25 @@
          decl.Declaration.File = TGSI_FILE_INPUT;
          decl.Declaration.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */
          decl.Declaration.Semantic = 1;
-         decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION;
-         decl.Semantic.SemanticIndex = 0;
-         decl.DeclarationRange.First = 
-            decl.DeclarationRange.Last = wincoordInput;
+         decl.Semantic.Name = TGSI_SEMANTIC_POSITION;
+         decl.Semantic.Index = 0;
+         decl.Range.First = 
+            decl.Range.Last = wincoordInput;
          ctx->emit_declaration(ctx, &decl);
       }
 
       /* declare new sampler */
       decl = tgsi_default_full_declaration();
       decl.Declaration.File = TGSI_FILE_SAMPLER;
-      decl.DeclarationRange.First = 
-      decl.DeclarationRange.Last = pctx->freeSampler;
+      decl.Range.First = 
+      decl.Range.Last = pctx->freeSampler;
       ctx->emit_declaration(ctx, &decl);
 
       /* declare new temp regs */
       decl = tgsi_default_full_declaration();
       decl.Declaration.File = TGSI_FILE_TEMPORARY;
-      decl.DeclarationRange.First = 
-      decl.DeclarationRange.Last = pctx->texTemp;
+      decl.Range.First = 
+      decl.Range.Last = pctx->texTemp;
       ctx->emit_declaration(ctx, &decl);
 
       /* emit immediate = {1/32, 1/32, 1, 1}
@@ -280,27 +281,28 @@
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp;
+      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Dst[0].Register.Index = pctx->texTemp;
       newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = wincoordInput;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_IMMEDIATE;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->numImmed;
+      newInst.Src[0].Register.File = TGSI_FILE_INPUT;
+      newInst.Src[0].Register.Index = wincoordInput;
+      newInst.Src[1].Register.File = TGSI_FILE_IMMEDIATE;
+      newInst.Src[1].Register.Index = pctx->numImmed;
       ctx->emit_instruction(ctx, &newInst);
 
       /* TEX texTemp, texTemp, sampler; */
       newInst = tgsi_default_full_instruction();
       newInst.Instruction.Opcode = TGSI_OPCODE_TEX;
       newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp;
+      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Dst[0].Register.Index = pctx->texTemp;
       newInst.Instruction.NumSrcRegs = 2;
-      newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->freeSampler;
+      newInst.Instruction.Texture = TRUE;
+      newInst.Texture.Texture = TGSI_TEXTURE_2D;
+      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[0].Register.Index = pctx->texTemp;
+      newInst.Src[1].Register.File = TGSI_FILE_SAMPLER;
+      newInst.Src[1].Register.Index = pctx->freeSampler;
       ctx->emit_instruction(ctx, &newInst);
 
       /* KIL -texTemp;   # if -texTemp < 0, KILL fragment */
@@ -308,9 +310,9 @@
       newInst.Instruction.Opcode = TGSI_OPCODE_KIL;
       newInst.Instruction.NumDstRegs = 0;
       newInst.Instruction.NumSrcRegs = 1;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp;
-      newInst.FullSrcRegisters[0].SrcRegister.Negate = 1;
+      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+      newInst.Src[0].Register.Index = pctx->texTemp;
+      newInst.Src[0].Register.Negate = 1;
       ctx->emit_instruction(ctx, &newInst);
    }
 
@@ -427,10 +429,9 @@
    texTemp.target = PIPE_TEXTURE_2D;
    texTemp.format = PIPE_FORMAT_A8_UNORM; /* XXX verify supported by driver! */
    texTemp.last_level = 0;
-   texTemp.width[0] = 32;
-   texTemp.height[0] = 32;
-   texTemp.depth[0] = 1;
-   pf_get_block(texTemp.format, &texTemp.block);
+   texTemp.width0 = 32;
+   texTemp.height0 = 32;
+   texTemp.depth0 = 1;
 
    pstip->texture = screen->texture_create(screen, &texTemp);
    if (pstip->texture == NULL)
@@ -754,8 +755,8 @@
    pstip->driver_bind_fs_state = pipe->bind_fs_state;
    pstip->driver_delete_fs_state = pipe->delete_fs_state;
 
-   pstip->driver_bind_sampler_states = pipe->bind_sampler_states;
-   pstip->driver_set_sampler_textures = pipe->set_sampler_textures;
+   pstip->driver_bind_sampler_states = pipe->bind_fragment_sampler_states;
+   pstip->driver_set_sampler_textures = pipe->set_fragment_sampler_textures;
    pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple;
 
    /* override the driver's functions */
@@ -763,8 +764,8 @@
    pipe->bind_fs_state = pstip_bind_fs_state;
    pipe->delete_fs_state = pstip_delete_fs_state;
 
-   pipe->bind_sampler_states = pstip_bind_sampler_states;
-   pipe->set_sampler_textures = pstip_set_sampler_textures;
+   pipe->bind_fragment_sampler_states = pstip_bind_sampler_states;
+   pipe->set_fragment_sampler_textures = pstip_set_sampler_textures;
    pipe->set_polygon_stipple = pstip_set_polygon_stipple;
 
    return TRUE;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c
index 6e921ba..70fbab9 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_stipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_stipple.c
@@ -73,7 +73,8 @@
                const struct vertex_header *v1 )
 {
    uint attr;
-   for (attr = 0; attr < draw->vs.num_vs_outputs; attr++) {
+   int num_outputs = draw_current_shader_outputs(draw);
+   for (attr = 0; attr < num_outputs; attr++) {
       const float *val0 = v0->data[attr];
       const float *val1 = v1->data[attr];
       float *newv = dst->data[attr];
@@ -121,7 +122,7 @@
    struct stipple_stage *stipple = stipple_stage(stage);
    struct vertex_header *v0 = header->v[0];
    struct vertex_header *v1 = header->v[1];
-   const unsigned pos = stage->draw->vs.position_output;
+   const unsigned pos = draw_current_shader_position_output(stage->draw);
    const float *pos0 = v0->data[pos];
    const float *pos1 = v1->data[pos];
    float start = 0;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
index f32cbef..3073c87 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
@@ -59,7 +59,7 @@
                            struct prim_header *header )
 {
    /*const struct wideline_stage *wide = wideline_stage(stage);*/
-   const unsigned pos = stage->draw->vs.position_output;
+   const unsigned pos = draw_current_shader_position_output(stage->draw);
    const float half_width = 0.5f * stage->draw->rasterizer->line_width;
 
    struct prim_header tri;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
index 7d76a7d..8dc50c0 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
@@ -112,7 +112,7 @@
 
    if (wide->point_coord_fs_input >= 0) {
       /* put gl_PointCoord into the extra vertex slot */
-      uint slot = wide->stage.draw->extra_vp_outputs.slot;
+      uint slot = wide->stage.draw->extra_shader_outputs.slot;
       v->data[slot][0] = tc[0];
       v->data[slot][1] = tc[1];
       v->data[slot][2] = 0.0F;
@@ -130,7 +130,7 @@
                              struct prim_header *header )
 {
    const struct widepoint_stage *wide = widepoint_stage(stage);
-   const unsigned pos = stage->draw->vs.position_output;
+   const unsigned pos = draw_current_shader_position_output(stage->draw);
    const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite;
    float half_size;
    float left_adj, right_adj, bot_adj, top_adj;
@@ -257,13 +257,13 @@
       wide->point_coord_fs_input = find_pntc_input_attrib(draw);
 
       /* setup extra vp output (point coord implemented as a texcoord) */
-      draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
-      draw->extra_vp_outputs.semantic_index = 0;
-      draw->extra_vp_outputs.slot = draw->vs.num_vs_outputs;
+      draw->extra_shader_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
+      draw->extra_shader_outputs.semantic_index = 0;
+      draw->extra_shader_outputs.slot = draw_current_shader_outputs(draw);
    }
    else {
       wide->point_coord_fs_input = -1;
-      draw->extra_vp_outputs.slot = 0;
+      draw->extra_shader_outputs.slot = 0;
    }
 
    wide->psize_slot = -1;
@@ -287,7 +287,7 @@
 {
    stage->point = widepoint_first_point;
    stage->next->flush( stage->next, flags );
-   stage->draw->extra_vp_outputs.slot = 0;
+   stage->draw->extra_shader_outputs.slot = 0;
 }
 
 
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 41fcb16..e490415 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -142,8 +142,6 @@
 
       /* user-space vertex data, buffers */
       struct {
-         const unsigned *edgeflag;
-
          /** vertex element/index buffer (ex: glDrawElements) */
          const void *elts;
          /** bytes per index (0, 1, 2 or 4) */
@@ -154,8 +152,9 @@
          /** vertex arrays */
          const void *vbuffer[PIPE_MAX_ATTRIBS];
          
-         /** constant buffer (for vertex shader) */
-         const void *constants;
+         /** constant buffer (for vertex/geometry shader) */
+         const void *vs_constants;
+         const void *gs_constants;
       } user;
 
       boolean test_fse;         /* enable FSE even though its not correct (eg for softpipe) */
@@ -184,6 +183,7 @@
       struct draw_vertex_shader *vertex_shader;
       uint num_vs_outputs;  /**< convenience, from vertex_shader */
       uint position_output;
+      uint edgeflag_output;
 
       /** TGSI program interpreter runtime state */
       struct tgsi_exec_machine *machine;
@@ -212,6 +212,18 @@
       struct translate_cache *emit_cache;
    } vs;
 
+   struct {
+      struct draw_geometry_shader *geometry_shader;
+      uint num_gs_outputs;  /**< convenience, from geometry_shader */
+      uint position_output;
+
+      /** TGSI program interpreter runtime state */
+      struct tgsi_exec_machine *machine;
+
+      uint num_samplers;
+      struct tgsi_sampler **samplers;
+   } gs;
+
    /* Clip derived state:
     */
    float plane[12][4];
@@ -223,7 +235,7 @@
       uint semantic_name;
       uint semantic_index;
       int slot;
-   } extra_vp_outputs;
+   } extra_shader_outputs;
 
    unsigned reduced_prim;
 
@@ -246,6 +258,19 @@
 
 
 
+/*******************************************************************************
+ * Geometry shading code:
+ */
+boolean draw_gs_init( struct draw_context *draw );
+void draw_gs_set_constants( struct draw_context *,
+                            const float (*constants)[4],
+                            unsigned size );
+
+/*******************************************************************************
+ * Common shading code:
+ */
+int draw_current_shader_outputs(struct draw_context *draw);
+int draw_current_shader_position_output(struct draw_context *draw);
 
 /*******************************************************************************
  * Vertex processing (was passthrough) code:
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index dbb5ac7..2801dba 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -192,7 +192,8 @@
                 prim, start, count);
 
    for (i = 0; i < count; i++) {
-      uint ii, j;
+      uint ii = 0;
+      uint j;
 
       if (draw->pt.user.elts) {
          /* indexed arrays */
@@ -313,12 +314,3 @@
    /* drawing done here: */
    draw_pt_arrays(draw, prim, start, count);
 }
-
-boolean draw_pt_get_edgeflag( struct draw_context *draw,
-                              unsigned idx )
-{
-   if (draw->pt.user.edgeflag)
-      return (draw->pt.user.edgeflag[idx/32] & (1 << (idx%32))) != 0;
-   else
-      return 1;
-}
diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h
index 7a17a9f..20edf7a 100644
--- a/src/gallium/auxiliary/draw/draw_pt.h
+++ b/src/gallium/auxiliary/draw/draw_pt.h
@@ -149,11 +149,6 @@
 struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *draw);
 
 
-/* More helpers:
- */
-boolean draw_pt_get_edgeflag( struct draw_context *draw,
-                              unsigned idx );
-
 
 /*******************************************************************************
  * HW vertex emit:
@@ -217,7 +212,8 @@
 void draw_pt_post_vs_prepare( struct pt_post_vs *pvs,
 			      boolean bypass_clipping,
 			      boolean bypass_viewport,
-			      boolean opengl );
+			      boolean opengl,
+			      boolean need_edgeflags );
 
 struct pt_post_vs *draw_pt_post_vs_create( struct draw_context *draw );
 
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c
index 65c3a34..305bfef 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c
@@ -42,11 +42,11 @@
    struct translate *translate;
 
    unsigned vertex_size;
-   boolean need_edgeflags;
 
    struct translate_cache *cache;
 };
 
+
 /* Perform the fetch from API vertex elements & vertex buffers, to a
  * contiguous set of float[4] attributes as required for the
  * vertex_shader->run_linear() method.
@@ -120,7 +120,12 @@
       fetch->translate = translate_cache_find(fetch->cache, &key);
 
       {
-         static struct vertex_header vh = { 0, 1, 0, UNDEFINED_VERTEX_ID, { .0f, .0f, .0f, .0f } };
+         static struct vertex_header vh = { 0,
+                                            1,
+                                            0,
+                                            UNDEFINED_VERTEX_ID,
+                                            { .0f, .0f, .0f, .0f } };
+
 	 fetch->translate->set_buffer(fetch->translate,
 				      draw->pt.nr_vertex_buffers,
 				      &vh,
@@ -128,9 +133,6 @@
       }
    }
 
-   fetch->need_edgeflags = ((draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
-                             draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) &&
-                            draw->pt.user.edgeflag);
 }
 
 
@@ -158,17 +160,6 @@
 			count,
 			verts );
 
-   /* Edgeflags are hard to fit into a translate program, populate
-    * them separately if required.  In the setup above they are
-    * defaulted to one, so only need this if there is reason to change
-    * that default:
-    */
-   if (fetch->need_edgeflags) {
-      for (i = 0; i < count; i++) {
-         struct vertex_header *vh = (struct vertex_header *)(verts + i * fetch->vertex_size);
-         vh->edgeflag = draw_pt_get_edgeflag( draw, elts[i] );
-      }
-   }
 }
 
 
@@ -193,18 +184,6 @@
                    start,
                    count,
                    verts );
-
-   /* Edgeflags are hard to fit into a translate program, populate
-    * them separately if required.  In the setup above they are
-    * defaulted to one, so only need this if there is reason to change
-    * that default:
-    */
-   if (fetch->need_edgeflags) {
-      for (i = 0; i < count; i++) {
-         struct vertex_header *vh = (struct vertex_header *)(verts + i * fetch->vertex_size);
-         vh->edgeflag = draw_pt_get_edgeflag( draw, start + i );
-      }
-   }
 }
 
 
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
index df6c265..1a9df4c 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -32,6 +32,7 @@
 #include "draw/draw_vertex.h"
 #include "draw/draw_pt.h"
 #include "draw/draw_vs.h"
+#include "draw/draw_gs.h"
 #include "translate/translate.h"
 
 
@@ -85,9 +86,9 @@
    draw_pt_post_vs_prepare( fpme->post_vs,
 			    (boolean)draw->bypass_clipping,
 			    (boolean)(draw->identity_viewport ||
-                                      draw->rasterizer->bypass_vs_clip_and_viewport),
-			    (boolean)draw->rasterizer->gl_rasterization_rules );
-			    
+			    draw->rasterizer->bypass_vs_clip_and_viewport),
+			    (boolean)draw->rasterizer->gl_rasterization_rules,
+			    (draw->vs.edgeflag_output ? true : false) );    
 
    if (!(opt & PT_PIPELINE)) {
       draw_pt_emit_prepare( fpme->emit, 
@@ -119,7 +120,8 @@
 {
    struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
    struct draw_context *draw = fpme->draw;
-   struct draw_vertex_shader *shader = draw->vs.vertex_shader;
+   struct draw_vertex_shader *vshader = draw->vs.vertex_shader;
+   struct draw_geometry_shader *gshader = draw->gs.geometry_shader;
    unsigned opt = fpme->opt;
    unsigned alloc_count = align( fetch_count, 4 );
 
@@ -147,13 +149,21 @@
     */
    if (opt & PT_SHADE)
    {
-      shader->run_linear(shader, 
-			 (const float (*)[4])pipeline_verts->data,
-			 (      float (*)[4])pipeline_verts->data,
-			 (const float (*)[4])draw->pt.user.constants,
-			 fetch_count,
-			 fpme->vertex_size,
-			 fpme->vertex_size);
+      vshader->run_linear(vshader,
+                          (const float (*)[4])pipeline_verts->data,
+                          (      float (*)[4])pipeline_verts->data,
+                          (const float (*)[4])draw->pt.user.vs_constants,
+                          fetch_count,
+                          fpme->vertex_size,
+                          fpme->vertex_size);
+      if (gshader)
+         draw_geometry_shader_run(gshader,
+                                  (const float (*)[4])pipeline_verts->data,
+                                  (      float (*)[4])pipeline_verts->data,
+                                  (const float (*)[4])draw->pt.user.gs_constants,
+                                  fetch_count,
+                                  fpme->vertex_size,
+                                  fpme->vertex_size);
    }
 
    if (draw_pt_post_vs_run( fpme->post_vs,
@@ -196,6 +206,7 @@
    struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
    struct draw_context *draw = fpme->draw;
    struct draw_vertex_shader *shader = draw->vs.vertex_shader;
+   struct draw_geometry_shader *geometry_shader = draw->gs.geometry_shader;
    unsigned opt = fpme->opt;
    unsigned alloc_count = align( count, 4 );
 
@@ -226,10 +237,19 @@
       shader->run_linear(shader,
 			 (const float (*)[4])pipeline_verts->data,
 			 (      float (*)[4])pipeline_verts->data,
-			 (const float (*)[4])draw->pt.user.constants,
+			 (const float (*)[4])draw->pt.user.vs_constants,
 			 count,
 			 fpme->vertex_size,
 			 fpme->vertex_size);
+
+      if (geometry_shader)
+         draw_geometry_shader_run(geometry_shader,
+                                  (const float (*)[4])pipeline_verts->data,
+                                  (      float (*)[4])pipeline_verts->data,
+                                  (const float (*)[4])draw->pt.user.gs_constants,
+                                  count,
+                                  fpme->vertex_size,
+                                  fpme->vertex_size);
    }
 
    if (draw_pt_post_vs_run( fpme->post_vs,
@@ -270,6 +290,7 @@
    struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
    struct draw_context *draw = fpme->draw;
    struct draw_vertex_shader *shader = draw->vs.vertex_shader;
+   struct draw_geometry_shader *geometry_shader = draw->gs.geometry_shader;
    unsigned opt = fpme->opt;
    unsigned alloc_count = align( count, 4 );
 
@@ -296,10 +317,19 @@
       shader->run_linear(shader,
 			 (const float (*)[4])pipeline_verts->data,
 			 (      float (*)[4])pipeline_verts->data,
-			 (const float (*)[4])draw->pt.user.constants,
+			 (const float (*)[4])draw->pt.user.vs_constants,
 			 count,
 			 fpme->vertex_size,
 			 fpme->vertex_size);
+
+      if (geometry_shader)
+         draw_geometry_shader_run(geometry_shader,
+                                  (const float (*)[4])pipeline_verts->data,
+                                  (      float (*)[4])pipeline_verts->data,
+                                  (const float (*)[4])draw->pt.user.gs_constants,
+                                  count,
+                                  fpme->vertex_size,
+                                  fpme->vertex_size);
    }
 
    if (draw_pt_post_vs_run( fpme->post_vs,
diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
index 6c1cb48..5515182 100644
--- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c
+++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
@@ -100,7 +100,7 @@
    struct vertex_header *out = vertices;
    const float *scale = pvs->draw->viewport.scale;
    const float *trans = pvs->draw->viewport.translate;
-   const unsigned pos = pvs->draw->vs.position_output;
+   const unsigned pos = draw_current_shader_position_output(pvs->draw);
    unsigned clipped = 0;
    unsigned j;
 
@@ -147,6 +147,39 @@
 
 
 
+/* As above plus edgeflags
+ */
+static boolean 
+post_vs_cliptest_viewport_gl_edgeflag(struct pt_post_vs *pvs,
+                                      struct vertex_header *vertices,
+                                      unsigned count,
+                                      unsigned stride )
+{
+   unsigned j;
+   boolean needpipe;
+
+   needpipe = post_vs_cliptest_viewport_gl( pvs, vertices, count, stride);
+
+   /* If present, copy edgeflag VS output into vertex header.
+    * Otherwise, leave header as is.
+    */
+   if (pvs->draw->vs.edgeflag_output) {
+      struct vertex_header *out = vertices;
+      int ef = pvs->draw->vs.edgeflag_output;
+
+      for (j = 0; j < count; j++) {
+         const float *edgeflag = out->data[ef];
+         out->edgeflag = !(edgeflag[0] != 1.0f);
+         needpipe |= !out->edgeflag;
+         out = (struct vertex_header *)( (char *)out + stride );
+      }
+   }
+   return needpipe;
+}
+
+
+
+
 /* If bypass_clipping is set, skip cliptest and rhw divide.
  */
 static boolean post_vs_viewport( struct pt_post_vs *pvs,
@@ -157,7 +190,7 @@
    struct vertex_header *out = vertices;
    const float *scale = pvs->draw->viewport.scale;
    const float *trans = pvs->draw->viewport.translate;
-   const unsigned pos = pvs->draw->vs.position_output;
+   const unsigned pos = draw_current_shader_position_output(pvs->draw);
    unsigned j;
 
    if (0) debug_printf("%s\n", __FUNCTION__);
@@ -201,17 +234,29 @@
 void draw_pt_post_vs_prepare( struct pt_post_vs *pvs,
 			      boolean bypass_clipping,
 			      boolean bypass_viewport,
-			      boolean opengl )
+			      boolean opengl,
+			      boolean need_edgeflags )
 {
-   if (bypass_clipping) {
-      if (bypass_viewport)
-	 pvs->run = post_vs_none;
-      else
-	 pvs->run = post_vs_viewport;
+   if (!need_edgeflags) {
+      if (bypass_clipping) {
+         if (bypass_viewport)
+            pvs->run = post_vs_none;
+         else
+            pvs->run = post_vs_viewport;
+      }
+      else {
+         /* if (opengl) */
+         pvs->run = post_vs_cliptest_viewport_gl;
+      }
    }
    else {
-      /* if (opengl) */
-      pvs->run = post_vs_cliptest_viewport_gl;
+      /* If we need to copy edgeflags to the vertex header, it should
+       * mean we're running the primitive pipeline.  Hence the bypass
+       * flags should be false.
+       */
+      assert(!bypass_clipping);
+      assert(!bypass_viewport);
+      pvs->run = post_vs_cliptest_viewport_gl_edgeflag;
    }
 }
 
diff --git a/src/gallium/auxiliary/draw/draw_pt_util.c b/src/gallium/auxiliary/draw/draw_pt_util.c
index b61fa29..17c3b8c 100644
--- a/src/gallium/auxiliary/draw/draw_pt_util.c
+++ b/src/gallium/auxiliary/draw/draw_pt_util.c
@@ -50,16 +50,32 @@
       *first = 2;
       *incr = 1;
       break;
+   case PIPE_PRIM_LINES_ADJACENCY:
+      *first = 4;
+      *incr = 2;
+      break;
+   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+      *first = 4;
+      *incr = 1;
+      break;
    case PIPE_PRIM_TRIANGLES:
       *first = 3;
       *incr = 3;
       break;
+   case PIPE_PRIM_TRIANGLES_ADJACENCY:
+      *first = 6;
+      *incr = 3;
+      break;
    case PIPE_PRIM_TRIANGLE_STRIP:
    case PIPE_PRIM_TRIANGLE_FAN:
    case PIPE_PRIM_POLYGON:
       *first = 3;
       *incr = 1;
       break;
+   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
+      *first = 6;
+      *incr = 1;
+      break;
    case PIPE_PRIM_QUADS:
       *first = 4;
       *incr = 4;
diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
index 010c7a1..f0aec5f 100644
--- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
+++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
@@ -36,6 +36,10 @@
    case PIPE_PRIM_TRIANGLE_STRIP:
    case PIPE_PRIM_QUADS:
    case PIPE_PRIM_QUAD_STRIP:
+   case PIPE_PRIM_LINES_ADJACENCY:
+   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+   case PIPE_PRIM_TRIANGLES_ADJACENCY:
+   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
       for (j = 0; j < count;) {
          unsigned remaining = count - j;
          unsigned nr = trim( MIN2(varray->driver_fetch_max, remaining), first, incr );
diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c
index d3f179c..757c487 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vcache.c
+++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c
@@ -346,7 +346,8 @@
                        vcache->fetch_max,
                        draw_count);
       
-   if (max_index == 0xffffffff ||
+   if (max_index >= DRAW_PIPE_MAX_VERTICES ||
+       fetch_count >= UNDEFINED_VERTEX_ID ||
        fetch_count > draw_count) {
       if (0) debug_printf("fail\n");
       goto fail;
diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c
index 790e89e..3553689 100644
--- a/src/gallium/auxiliary/draw/draw_vs.c
+++ b/src/gallium/auxiliary/draw/draw_vs.c
@@ -101,6 +101,9 @@
          if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
              vs->info.output_semantic_index[i] == 0)
             vs->position_output = i;
+         else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_EDGEFLAG &&
+             vs->info.output_semantic_index[i] == 0)
+            vs->edgeflag_output = i;
       }
    }
 
@@ -120,6 +123,7 @@
       draw->vs.vertex_shader = dvs;
       draw->vs.num_vs_outputs = dvs->info.num_outputs;
       draw->vs.position_output = dvs->position_output;
+      draw->vs.edgeflag_output = dvs->edgeflag_output;
       dvs->prepare( dvs, draw );
    }
    else {
diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h
index 89ae158..e3b807e 100644
--- a/src/gallium/auxiliary/draw/draw_vs.h
+++ b/src/gallium/auxiliary/draw/draw_vs.h
@@ -107,6 +107,7 @@
 
    struct tgsi_shader_info info;
    unsigned position_output;
+   unsigned edgeflag_output;
 
    /* Extracted from shader:
     */
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c
index 88bc790..1aaae4a 100644
--- a/src/gallium/auxiliary/draw/draw_vs_aos.c
+++ b/src/gallium/auxiliary/draw/draw_vs_aos.c
@@ -361,8 +361,8 @@
 static struct x86_reg get_dst_ptr( struct aos_compilation *cp, 
                                    const struct tgsi_full_dst_register *dst )
 {
-   unsigned file = dst->DstRegister.File;
-   unsigned idx = dst->DstRegister.Index;
+   unsigned file = dst->Register.File;
+   unsigned idx = dst->Register.Index;
    unsigned i;
    
 
@@ -529,8 +529,8 @@
                                  const struct tgsi_full_src_register *src ) 
 {
    struct x86_reg arg0 = aos_get_shader_reg(cp, 
-                                            src->SrcRegister.File, 
-                                            src->SrcRegister.Index);
+                                            src->Register.File, 
+                                            src->Register.Index);
    unsigned i;
    ubyte swz = 0;
    unsigned negs = 0;
@@ -620,8 +620,8 @@
                          unsigned channel ) 
 {
    struct x86_reg arg0 = aos_get_shader_reg_ptr(cp, 
-                                                src->SrcRegister.File, 
-                                                src->SrcRegister.Index);
+                                                src->Register.File, 
+                                                src->Register.Index);
 
    unsigned swizzle = tgsi_util_get_full_src_register_swizzle( src, channel );
    unsigned neg = tgsi_util_get_full_src_register_sign_mode( src, channel );
@@ -669,15 +669,15 @@
 {
    struct x86_reg dst;
 
-   switch (reg->DstRegister.WriteMask) {
+   switch (reg->Register.WriteMask) {
    case 0:
       return;
    
    case TGSI_WRITEMASK_XYZW:
       aos_adopt_xmm_reg(cp, 
                         get_xmm_writable(cp, result), 
-                        reg->DstRegister.File,
-                        reg->DstRegister.Index,
+                        reg->Register.File,
+                        reg->Register.Index,
                         TRUE);
       return;
    default: 
@@ -685,10 +685,10 @@
    }
 
    dst = aos_get_shader_reg_xmm(cp, 
-                                reg->DstRegister.File,
-                                reg->DstRegister.Index);
+                                reg->Register.File,
+                                reg->Register.Index);
 
-   switch (reg->DstRegister.WriteMask) {
+   switch (reg->Register.WriteMask) {
    case TGSI_WRITEMASK_X:
       sse_movss(cp->func, dst, get_xmm(cp, result));
       break;
@@ -710,14 +710,14 @@
       break;
 
    default:
-      mask_write(cp, dst, result, reg->DstRegister.WriteMask);
+      mask_write(cp, dst, result, reg->Register.WriteMask);
       break;
    }
 
    aos_adopt_xmm_reg(cp, 
                      dst, 
-                     reg->DstRegister.File,
-                     reg->DstRegister.Index,
+                     reg->Register.File,
+                     reg->Register.Index,
                      TRUE);
 
 }
@@ -737,7 +737,7 @@
                                const struct tgsi_full_dst_register *reg,
                                struct x86_reg result )
 {
-   unsigned writemask = reg->DstRegister.WriteMask;
+   unsigned writemask = reg->Register.WriteMask;
    struct x86_reg dst;
 
    if (writemask != TGSI_WRITEMASK_X &&
@@ -754,12 +754,12 @@
 
    result = get_xmm(cp, result);
    dst = aos_get_shader_reg_xmm(cp, 
-                                reg->DstRegister.File,
-                                reg->DstRegister.Index);
+                                reg->Register.File,
+                                reg->Register.Index);
 
 
 
-   switch (reg->DstRegister.WriteMask) {
+   switch (reg->Register.WriteMask) {
    case TGSI_WRITEMASK_X:
       sse_movss(cp->func, dst, result);
       break;
@@ -782,8 +782,8 @@
 
    aos_adopt_xmm_reg(cp, 
                      dst, 
-                     reg->DstRegister.File,
-                     reg->DstRegister.Index,
+                     reg->Register.File,
+                     reg->Register.Index,
                      TRUE);
 }
    
@@ -819,7 +819,7 @@
                             const struct tgsi_full_dst_register *dst )
 {
    struct x86_reg ptr = get_dst_ptr(cp, dst); 
-   unsigned writemask = dst->DstRegister.WriteMask;
+   unsigned writemask = dst->Register.WriteMask;
 
    x87_fst_or_nop(cp->func, writemask, 0, ptr);
    x87_fst_or_nop(cp->func, writemask, 1, ptr);
@@ -956,7 +956,7 @@
 
 static boolean emit_ABS( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
 {
-   struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
+   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
    struct x86_reg neg = aos_get_internal(cp, IMM_NEGS);
    struct x86_reg tmp = aos_get_xmm_reg(cp);
 
@@ -964,27 +964,27 @@
    sse_mulps(cp->func, tmp, neg);
    sse_maxps(cp->func, tmp, arg0);
    
-   store_dest(cp, &op->FullDstRegisters[0], tmp);
+   store_dest(cp, &op->Dst[0], tmp);
    return TRUE;
 }
 
 static boolean emit_ADD( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
-   struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]);
+   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
+   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
    struct x86_reg dst = get_xmm_writable(cp, arg0);
 
    sse_addps(cp->func, dst, arg1);
 
-   store_dest(cp, &op->FullDstRegisters[0], dst);
+   store_dest(cp, &op->Dst[0], dst);
    return TRUE;
 }
 
 static boolean emit_COS( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
 {
-   x87_fld_src(cp, &op->FullSrcRegisters[0], 0);
+   x87_fld_src(cp, &op->Src[0], 0);
    x87_fcos(cp->func);
-   x87_fstp_dest4(cp, &op->FullDstRegisters[0]);
+   x87_fstp_dest4(cp, &op->Dst[0]);
    return TRUE;
 }
 
@@ -993,8 +993,8 @@
  */
 static boolean emit_DP3( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
-   struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]);
+   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
+   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
    struct x86_reg tmp = aos_get_xmm_reg(cp); 
    struct x86_reg dst = get_xmm_writable(cp, arg0);
 
@@ -1007,14 +1007,14 @@
    sse_addss(cp->func, dst, tmp);
    
    aos_release_xmm_reg(cp, tmp.idx);
-   store_scalar_dest(cp, &op->FullDstRegisters[0], dst);
+   store_scalar_dest(cp, &op->Dst[0], dst);
    return TRUE;
 }
 
 static boolean emit_DP4( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
-   struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]);
+   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
+   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
    struct x86_reg tmp = aos_get_xmm_reg(cp);      
    struct x86_reg dst = get_xmm_writable(cp, arg0);
 
@@ -1028,14 +1028,14 @@
    sse_addss(cp->func, dst, tmp);
 
    aos_release_xmm_reg(cp, tmp.idx);
-   store_scalar_dest(cp, &op->FullDstRegisters[0], dst);
+   store_scalar_dest(cp, &op->Dst[0], dst);
    return TRUE;
 }
 
 static boolean emit_DPH( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
-   struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]);
+   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
+   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
    struct x86_reg tmp = aos_get_xmm_reg(cp);
    struct x86_reg dst = get_xmm_writable(cp, arg0);
 
@@ -1051,14 +1051,14 @@
    sse_addss(cp->func, dst, tmp);
 
    aos_release_xmm_reg(cp, tmp.idx);
-   store_scalar_dest(cp, &op->FullDstRegisters[0], dst);
+   store_scalar_dest(cp, &op->Dst[0], dst);
    return TRUE;
 }
 
 static boolean emit_DST( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
-    struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
-    struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]);
+    struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
+    struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
     struct x86_reg dst = aos_get_xmm_reg(cp);
     struct x86_reg tmp = aos_get_xmm_reg(cp);
     struct x86_reg ones = aos_get_internal(cp, IMM_ONES);
@@ -1073,25 +1073,25 @@
     sse_mulps(cp->func, dst, tmp);
 
     aos_release_xmm_reg(cp, tmp.idx);
-    store_dest(cp, &op->FullDstRegisters[0], dst);
+    store_dest(cp, &op->Dst[0], dst);
     return TRUE;
 }
 
 static boolean emit_LG2( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
 {
    x87_fld1(cp->func);		/* 1 */
-   x87_fld_src(cp, &op->FullSrcRegisters[0], 0);	/* a0 1 */
+   x87_fld_src(cp, &op->Src[0], 0);	/* a0 1 */
    x87_fyl2x(cp->func);	/* log2(a0) */
-   x87_fstp_dest4(cp, &op->FullDstRegisters[0]);
+   x87_fstp_dest4(cp, &op->Dst[0]);
    return TRUE;
 }
 
 #if 0
 static boolean emit_EX2( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
 {
-   x87_fld_src(cp, &op->FullSrcRegisters[0], 0);
+   x87_fld_src(cp, &op->Src[0], 0);
    x87_emit_ex2(cp);
-   x87_fstp_dest4(cp, &op->FullDstRegisters[0]);
+   x87_fstp_dest4(cp, &op->Dst[0]);
    return TRUE;
 }
 #endif
@@ -1099,8 +1099,8 @@
 
 static boolean emit_FLR( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
 {
-   struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); 
-   unsigned writemask = op->FullDstRegisters[0].DstRegister.WriteMask;
+   struct x86_reg dst = get_dst_ptr(cp, &op->Dst[0]); 
+   unsigned writemask = op->Dst[0].Register.WriteMask;
    int i;
 
    set_fpu_round_neg_inf( cp );
@@ -1109,7 +1109,7 @@
     */
    for (i = 3; i >= 0; i--) {
       if (writemask & (1<<i)) {
-         x87_fld_src(cp, &op->FullSrcRegisters[0], i);   
+         x87_fld_src(cp, &op->Src[0], i);   
       }
    }
 
@@ -1126,8 +1126,8 @@
 
 static boolean emit_RND( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
 {
-   struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); 
-   unsigned writemask = op->FullDstRegisters[0].DstRegister.WriteMask;
+   struct x86_reg dst = get_dst_ptr(cp, &op->Dst[0]); 
+   unsigned writemask = op->Dst[0].Register.WriteMask;
    int i;
 
    set_fpu_round_nearest( cp );
@@ -1136,7 +1136,7 @@
     */
    for (i = 3; i >= 0; i--) {
       if (writemask & (1<<i)) {
-         x87_fld_src(cp, &op->FullSrcRegisters[0], i);   
+         x87_fld_src(cp, &op->Src[0], i);   
       }
    }
 
@@ -1153,10 +1153,10 @@
 
 static boolean emit_FRC( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
 {
-   struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); 
+   struct x86_reg dst = get_dst_ptr(cp, &op->Dst[0]); 
    struct x86_reg st0 = x86_make_reg(file_x87, 0);
    struct x86_reg st1 = x86_make_reg(file_x87, 1);
-   unsigned writemask = op->FullDstRegisters[0].DstRegister.WriteMask;
+   unsigned writemask = op->Dst[0].Register.WriteMask;
    int i;
 
    set_fpu_round_neg_inf( cp );
@@ -1166,7 +1166,7 @@
     */
    for (i = 3; i >= 0; i--) {
       if (writemask & (1<<i)) {
-         x87_fld_src(cp, &op->FullSrcRegisters[0], i);   
+         x87_fld_src(cp, &op->Src[0], i);   
       }
    }
 
@@ -1190,7 +1190,7 @@
 static boolean emit_LIT( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
    struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX );
-   unsigned writemask = op->FullDstRegisters[0].DstRegister.WriteMask;
+   unsigned writemask = op->Dst[0].Register.WriteMask;
    unsigned lit_count = cp->lit_count++;
    struct x86_reg result, arg0;
    unsigned i;
@@ -1209,10 +1209,10 @@
    if (writemask != TGSI_WRITEMASK_XYZW) 
       result = x86_make_disp(cp->machine_EDX, Offset(struct aos_machine, tmp[0]));
    else 
-      result = get_dst_ptr(cp, &op->FullDstRegisters[0]);    
+      result = get_dst_ptr(cp, &op->Dst[0]);    
 
    
-   arg0 = fetch_src( cp, &op->FullSrcRegisters[0] );
+   arg0 = fetch_src( cp, &op->Src[0] );
    if (arg0.file == file_XMM) {
       struct x86_reg tmp = x86_make_disp(cp->machine_EDX, 
                                          Offset(struct aos_machine, tmp[1]));
@@ -1259,7 +1259,7 @@
 
    if (writemask != TGSI_WRITEMASK_XYZW) {
       store_dest( cp, 
-                  &op->FullDstRegisters[0],
+                  &op->Dst[0],
                   get_xmm_writable( cp, result ) );
    }
 
@@ -1269,8 +1269,8 @@
 #if 0   
 static boolean emit_inline_LIT( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
-   struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); 
-   unsigned writemask = op->FullDstRegisters[0].DstRegister.WriteMask;
+   struct x86_reg dst = get_dst_ptr(cp, &op->Dst[0]); 
+   unsigned writemask = op->Dst[0].Register.WriteMask;
 
    if (writemask & TGSI_WRITEMASK_YZ) {
       struct x86_reg st1 = x86_make_reg(file_x87, 1);
@@ -1286,13 +1286,13 @@
        */
       x87_fldz(cp->func);                           /* 1 0  */
 #endif
-      x87_fld_src(cp, &op->FullSrcRegisters[0], 1); /* a1 1 0  */
+      x87_fld_src(cp, &op->Src[0], 1); /* a1 1 0  */
       x87_fcomi(cp->func, st2);	                    /* a1 1 0  */
       x87_fcmovb(cp->func, st1);                    /* a1' 1 0  */
       x87_fstp(cp->func, st1);                      /* a1' 0  */
       x87_fstp(cp->func, st1);                      /* a1'  */
 
-      x87_fld_src(cp, &op->FullSrcRegisters[0], 3); /* a3 a1'  */
+      x87_fld_src(cp, &op->Src[0], 3); /* a3 a1'  */
       x87_fxch(cp->func, st1);                      /* a1' a3  */
       
 
@@ -1305,7 +1305,7 @@
       /* a0' = max2(a0, 0):
        */
       x87_fldz(cp->func);                           /* 0 r2 */
-      x87_fld_src(cp, &op->FullSrcRegisters[0], 0); /* a0 0 r2 */
+      x87_fld_src(cp, &op->Src[0], 0); /* a0 0 r2 */
       x87_fcomi(cp->func, st1);	
       x87_fcmovb(cp->func, st1);                    /* a0' 0 r2 */
 
@@ -1333,58 +1333,58 @@
 
 static boolean emit_MAX( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
-   struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]);
+   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
+   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
    struct x86_reg dst = get_xmm_writable(cp, arg0);
 
    sse_maxps(cp->func, dst, arg1);
 
-   store_dest(cp, &op->FullDstRegisters[0], dst);
+   store_dest(cp, &op->Dst[0], dst);
    return TRUE;
 }
 
 
 static boolean emit_MIN( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
-   struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]);
+   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
+   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
    struct x86_reg dst = get_xmm_writable(cp, arg0);
 
    sse_minps(cp->func, dst, arg1);
 
-   store_dest(cp, &op->FullDstRegisters[0], dst);
+   store_dest(cp, &op->Dst[0], dst);
    return TRUE;
 }
 
 static boolean emit_MOV( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
-   struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
+   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
    struct x86_reg dst = get_xmm_writable(cp, arg0);
 
    /* potentially nothing to do */
 
-   store_dest(cp, &op->FullDstRegisters[0], dst);
+   store_dest(cp, &op->Dst[0], dst);
    return TRUE;
 }
 
 static boolean emit_MUL( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
-   struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]);
+   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
+   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
    struct x86_reg dst = get_xmm_writable(cp, arg0);
 
    sse_mulps(cp->func, dst, arg1);
 
-   store_dest(cp, &op->FullDstRegisters[0], dst);
+   store_dest(cp, &op->Dst[0], dst);
    return TRUE;
 }
 
 
 static boolean emit_MAD( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
-   struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]);
-   struct x86_reg arg2 = fetch_src(cp, &op->FullSrcRegisters[2]);
+   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
+   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
+   struct x86_reg arg2 = fetch_src(cp, &op->Src[2]);
 
    /* If we can't clobber old contents of arg0, get a temporary & copy
     * it there, then clobber it...
@@ -1393,7 +1393,7 @@
 
    sse_mulps(cp->func, arg0, arg1);
    sse_addps(cp->func, arg0, arg2);
-   store_dest(cp, &op->FullDstRegisters[0], arg0);
+   store_dest(cp, &op->Dst[0], arg0);
    return TRUE;
 }
 
@@ -1425,13 +1425,13 @@
 static boolean emit_POW( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
 {
 #if 0
-   x87_fld_src(cp, &op->FullSrcRegisters[1], 0);  /* a1.x */
-   x87_fld_src(cp, &op->FullSrcRegisters[0], 0);	/* a0.x a1.x */
+   x87_fld_src(cp, &op->Src[1], 0);  /* a1.x */
+   x87_fld_src(cp, &op->Src[0], 0);	/* a0.x a1.x */
    x87_fyl2x(cp->func);	                                /* a1*log2(a0) */
 
    x87_emit_ex2( cp );		/* 2^(a1*log2(a0)) */
 
-   x87_fstp_dest4(cp, &op->FullDstRegisters[0]);
+   x87_fstp_dest4(cp, &op->Dst[0]);
 #else
    uint i;
 
@@ -1450,9 +1450,9 @@
 
    x86_lea( cp->func, cp->stack_ESP, x86_make_disp(cp->stack_ESP, -8) );
 
-   x87_fld_src( cp, &op->FullSrcRegisters[1], 0 );
+   x87_fld_src( cp, &op->Src[1], 0 );
    x87_fstp( cp->func, x86_make_disp( cp->stack_ESP, 4 ) );
-   x87_fld_src( cp, &op->FullSrcRegisters[0], 0 );
+   x87_fld_src( cp, &op->Src[0], 0 );
    x87_fstp( cp->func, x86_make_disp( cp->stack_ESP, 0 ) );
 
    /* tmp_EAX has been pushed & will be restored below */
@@ -1467,7 +1467,7 @@
     */
    cp->func->x87_stack++;
 
-   x87_fstp_dest4( cp, &op->FullDstRegisters[0] );
+   x87_fstp_dest4( cp, &op->Dst[0] );
 #endif
    return TRUE;
 }
@@ -1493,7 +1493,7 @@
 
    x86_lea( cp->func, cp->stack_ESP, x86_make_disp(cp->stack_ESP, -4) );
 
-   x87_fld_src( cp, &op->FullSrcRegisters[0], 0 );
+   x87_fld_src( cp, &op->Src[0], 0 );
    x87_fstp( cp->func, x86_make_disp( cp->stack_ESP, 0 ) );
 
    /* tmp_EAX has been pushed & will be restored below */
@@ -1508,7 +1508,7 @@
     */
    cp->func->x87_stack++;
 
-   x87_fstp_dest4( cp, &op->FullDstRegisters[0] );
+   x87_fstp_dest4( cp, &op->Dst[0] );
 
    return TRUE;
 }
@@ -1517,7 +1517,7 @@
 
 static boolean emit_RCP( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
-   struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
+   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
    struct x86_reg dst = aos_get_xmm_reg(cp);
 
    if (cp->have_sse2) {
@@ -1531,7 +1531,7 @@
       sse_divss(cp->func, dst, arg0);
    }
 
-   store_scalar_dest(cp, &op->FullDstRegisters[0], dst);
+   store_scalar_dest(cp, &op->Dst[0], dst);
    return TRUE;
 }
 
@@ -1551,14 +1551,14 @@
 static boolean emit_RSQ( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
    if (0) {
-      struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
+      struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
       struct x86_reg r = aos_get_xmm_reg(cp);
       sse_rsqrtss(cp->func, r, arg0);
-      store_scalar_dest(cp, &op->FullDstRegisters[0], r);
+      store_scalar_dest(cp, &op->Dst[0], r);
       return TRUE;
    }
    else {
-      struct x86_reg arg0           = fetch_src(cp, &op->FullSrcRegisters[0]);
+      struct x86_reg arg0           = fetch_src(cp, &op->Src[0]);
       struct x86_reg r              = aos_get_xmm_reg(cp);
 
       struct x86_reg neg_half       = get_reg_ptr( cp, AOS_FILE_INTERNAL, IMM_RSQ );
@@ -1578,7 +1578,7 @@
       sse_addss(   cp->func, tmp, one_point_five ); /* 1.5 - .5 * a * r * r */
       sse_mulss(   cp->func, r,  tmp );             /* r * (1.5 - .5 * a * r * r) */
 
-      store_scalar_dest(cp, &op->FullDstRegisters[0], r);
+      store_scalar_dest(cp, &op->Dst[0], r);
 
       aos_release_xmm_reg(cp, tmp.idx);
 
@@ -1589,23 +1589,23 @@
 
 static boolean emit_SGE( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
-   struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]);
+   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
+   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
    struct x86_reg ones = aos_get_internal(cp, IMM_ONES);
    struct x86_reg dst = get_xmm_writable(cp, arg0);
 
    sse_cmpps(cp->func, dst, arg1, cc_NotLessThan);
    sse_andps(cp->func, dst, ones);
 
-   store_dest(cp, &op->FullDstRegisters[0], dst);
+   store_dest(cp, &op->Dst[0], dst);
    return TRUE;
 }
 
 static boolean emit_SIN( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
 {
-   x87_fld_src(cp, &op->FullSrcRegisters[0], 0);
+   x87_fld_src(cp, &op->Src[0], 0);
    x87_fsin(cp->func);
-   x87_fstp_dest4(cp, &op->FullDstRegisters[0]);
+   x87_fstp_dest4(cp, &op->Dst[0]);
    return TRUE;
 }
 
@@ -1613,46 +1613,46 @@
 
 static boolean emit_SLT( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
-   struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]);
+   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
+   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
    struct x86_reg ones = aos_get_internal(cp, IMM_ONES);
    struct x86_reg dst = get_xmm_writable(cp, arg0);
    
    sse_cmpps(cp->func, dst, arg1, cc_LessThan);
    sse_andps(cp->func, dst, ones);
 
-   store_dest(cp, &op->FullDstRegisters[0], dst);
+   store_dest(cp, &op->Dst[0], dst);
    return TRUE;
 }
 
 static boolean emit_SUB( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
 {
-   struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]);
+   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
+   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
    struct x86_reg dst = get_xmm_writable(cp, arg0);
 
    sse_subps(cp->func, dst, arg1);
 
-   store_dest(cp, &op->FullDstRegisters[0], dst);
+   store_dest(cp, &op->Dst[0], dst);
    return TRUE;
 }
 
 static boolean emit_TRUNC( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
 {
-   struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
+   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
    struct x86_reg tmp0 = aos_get_xmm_reg(cp);
 
    sse2_cvttps2dq(cp->func, tmp0, arg0);
    sse2_cvtdq2ps(cp->func, tmp0, tmp0);
 
-   store_dest(cp, &op->FullDstRegisters[0], tmp0);
+   store_dest(cp, &op->Dst[0], tmp0);
    return TRUE;
 }
 
 static boolean emit_XPD( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) 
 {
-   struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
-   struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]);
+   struct x86_reg arg0 = fetch_src(cp, &op->Src[0]);
+   struct x86_reg arg1 = fetch_src(cp, &op->Src[1]);
    struct x86_reg tmp0 = aos_get_xmm_reg(cp);
    struct x86_reg tmp1 = aos_get_xmm_reg(cp);
 
@@ -1670,7 +1670,7 @@
 
 
    aos_release_xmm_reg(cp, tmp0.idx);
-   store_dest(cp, &op->FullDstRegisters[0], tmp1);
+   store_dest(cp, &op->Dst[0], tmp1);
    return TRUE;
 }
 
@@ -1897,10 +1897,10 @@
          continue;
 
       for (i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++) {
-         if (parse.FullToken.FullInstruction.FullDstRegisters[i].DstRegister.File ==
+         if (parse.FullToken.FullInstruction.Dst[i].Register.File ==
              TGSI_FILE_OUTPUT) 
          {
-            unsigned idx = parse.FullToken.FullInstruction.FullDstRegisters[i].DstRegister.Index;
+            unsigned idx = parse.FullToken.FullInstruction.Dst[i].Register.Index;
             cp->output_last_write[idx] = this_instruction;
          }
       }
diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c
index 7ee567d..d166925 100644
--- a/src/gallium/auxiliary/draw/draw_vs_varient.c
+++ b/src/gallium/auxiliary/draw/draw_vs_varient.c
@@ -147,11 +147,12 @@
    vsvg->base.vs->run_linear( vsvg->base.vs, 
                               temp_buffer,
                               temp_buffer,
-                              (const float (*)[4])vsvg->base.vs->draw->pt.user.constants,
+                              (const float (*)[4])vsvg->base.vs->draw->pt.user.vs_constants,
                               count,
                               temp_vertex_stride, 
                               temp_vertex_stride);
 
+   /* FIXME: geometry shading? */
 
    if (vsvg->base.key.clip) {
       /* not really handling clipping, just do the rhw so we can
@@ -207,7 +208,7 @@
    vsvg->base.vs->run_linear( vsvg->base.vs, 
                               temp_buffer,
                               temp_buffer,
-                              (const float (*)[4])vsvg->base.vs->draw->pt.user.constants,
+                              (const float (*)[4])vsvg->base.vs->draw->pt.user.vs_constants,
                               count,
                               temp_vertex_stride, 
                               temp_vertex_stride);
diff --git a/src/gallium/auxiliary/gallivm/Makefile b/src/gallium/auxiliary/gallivm/Makefile
deleted file mode 100644
index 5a96d94..0000000
--- a/src/gallium/auxiliary/gallivm/Makefile
+++ /dev/null
@@ -1,92 +0,0 @@
-# -*-makefile-*-
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = gallivm
-
-
-GALLIVM_SOURCES = \
-        gallivm.cpp  \
-        gallivm_cpu.cpp \
-        instructions.cpp  \
-        loweringpass.cpp \
-        tgsitollvm.cpp \
-        storage.cpp \
-        storagesoa.cpp \
-        instructionssoa.cpp
-
-INC_SOURCES = gallivm_builtins.cpp gallivmsoabuiltins.cpp
-
-CPP_SOURCES = \
-	$(GALLIVM_SOURCES)
-
-C_SOURCES =
-ASM_SOURCES =
-
-OBJECTS = $(C_SOURCES:.c=.o) \
-          $(CPP_SOURCES:.cpp=.o) \
-	  $(ASM_SOURCES:.S=.o)
-
-### Include directories
-INCLUDES = \
-	-I. \
-	-I$(TOP)/src/gallium/drivers \
-	-I$(TOP)/src/gallium/auxiliary \
-	-I$(TOP)/src/gallium/include \
-	-I$(TOP)/src/mesa \
-	-I$(TOP)/include
-
-
-##### RULES #####
-
-.c.o:
-	$(CC) -c $(INCLUDES) $(LLVM_CFLAGS) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@
-
-.cpp.o:
-	$(CXX) -c $(INCLUDES) $(LLVM_CXXFLAGS) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@
-
-.S.o:
-	$(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES)  $< -o $@
-
-##### TARGETS #####
-
-default:: depend symlinks $(LIBNAME)
-
-
-$(LIBNAME): $(OBJECTS) Makefile
-	$(TOP)/bin/mklib -o $@ -static $(OBJECTS)
-
-
-depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES)
-	rm -f depend
-	touch depend
-	$(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \
-		$(ASM_SOURCES) $(INC_SOURCES) 2> /dev/null
-
-
-gallivm_builtins.cpp: llvm_builtins.c
-	clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp1.bin
-	(echo "static const unsigned char llvm_builtins_data[] = {"; od -txC temp1.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/,0x00};/") >$@
-	rm temp1.bin
-
-gallivmsoabuiltins.cpp: soabuiltins.c
-	clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp2.bin
-	(echo "static const unsigned char soabuiltins_data[] = {"; od -txC temp2.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/,0x00};/") >$@
-	rm temp2.bin
-
-# Emacs tags
-tags:
-	etags `find . -name \*.[ch]` `find ../include`
-
-
-# Remove .o and backup files
-clean:
-	-rm -f *.o */*.o *~ *.so *~ server/*.o
-	-rm -f depend depend.bak
-	-rm -f gallivm_builtins.cpp
-	-rm -f gallivmsoabuiltins.cpp
-
-symlinks:
-
-
-include depend
diff --git a/src/gallium/auxiliary/gallivm/SConscript b/src/gallium/auxiliary/gallivm/SConscript
deleted file mode 100644
index c0aa51b..0000000
--- a/src/gallium/auxiliary/gallivm/SConscript
+++ /dev/null
@@ -1,16 +0,0 @@
-Import('*')
-
-gallivm = env.ConvenienceLibrary(
-	target = 'gallivm',
-	source = [
-        'gallivm.cpp',
-        'gallivm_cpu.cpp',
-        'instructions.cpp',
-        'loweringpass.cpp',
-        'tgsitollvm.cpp',
-        'storage.cpp',
-        'storagesoa.cpp',
-        'instructionssoa.cpp',
-	])
-
-auxiliaries.insert(0, gallivm)
diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
index bf84401..8f7d3b7 100644
--- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
+++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
@@ -94,8 +94,8 @@
       unsigned first, last, mask;
       uint interp_method;
 
-      first = decl->DeclarationRange.First;
-      last = decl->DeclarationRange.Last;
+      first = decl->Range.First;
+      last = decl->Range.Last;
       mask = decl->Declaration.UsageMask;
 
       /* Do not touch WPOS.xy */
@@ -149,7 +149,7 @@
                       struct tgsi_full_declaration *)
 {
    if (decl->Declaration.File == TGSI_FILE_ADDRESS) {
-      int idx = decl->DeclarationRange.First;
+      int idx = decl->Range.First;
       storage->addAddress(idx);
    }
 }
@@ -234,26 +234,26 @@
    inputs[3] = 0;
 
    for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) {
-      struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i];
+      struct tgsi_full_src_register *src = &inst->Src[i];
       llvm::Value *val = 0;
       llvm::Value *indIdx = 0;
 
-      if (src->SrcRegister.Indirect) {
-         indIdx = storage->addrElement(src->SrcRegisterInd.Index);
+      if (src->Register.Indirect) {
+         indIdx = storage->addrElement(src->Indirect.Index);
          indIdx = storage->extractIndex(indIdx);
       }
-      if (src->SrcRegister.File == TGSI_FILE_CONSTANT) {
-         val = storage->constElement(src->SrcRegister.Index, indIdx);
-      } else if (src->SrcRegister.File == TGSI_FILE_INPUT) {
-         val = storage->inputElement(src->SrcRegister.Index, indIdx);
-      } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) {
-         val = storage->tempElement(src->SrcRegister.Index);
-      } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) {
-         val = storage->outputElement(src->SrcRegister.Index, indIdx);
-      } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) {
-         val = storage->immediateElement(src->SrcRegister.Index);
+      if (src->Register.File == TGSI_FILE_CONSTANT) {
+         val = storage->constElement(src->Register.Index, indIdx);
+      } else if (src->Register.File == TGSI_FILE_INPUT) {
+         val = storage->inputElement(src->Register.Index, indIdx);
+      } else if (src->Register.File == TGSI_FILE_TEMPORARY) {
+         val = storage->tempElement(src->Register.Index);
+      } else if (src->Register.File == TGSI_FILE_OUTPUT) {
+         val = storage->outputElement(src->Register.Index, indIdx);
+      } else if (src->Register.File == TGSI_FILE_IMMEDIATE) {
+         val = storage->immediateElement(src->Register.Index);
       } else {
-         fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File);
+         fprintf(stderr, "ERROR: not supported llvm source %d\n", src->Register.File);
          return;
       }
 
@@ -552,7 +552,7 @@
       break;
    case TGSI_OPCODE_SHL:
       break;
-   case TGSI_OPCODE_SHR:
+   case TGSI_OPCODE_ISHR:
       break;
    case TGSI_OPCODE_AND:
       break;
@@ -656,14 +656,14 @@
 
    /* store results  */
    for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) {
-      struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
+      struct tgsi_full_dst_register *dst = &inst->Dst[i];
 
-      if (dst->DstRegister.File == TGSI_FILE_OUTPUT) {
-         storage->setOutputElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
-      } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) {
-         storage->setTempElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
-      } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) {
-         storage->setAddrElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask);
+      if (dst->Register.File == TGSI_FILE_OUTPUT) {
+         storage->setOutputElement(dst->Register.Index, out, dst->Register.WriteMask);
+      } else if (dst->Register.File == TGSI_FILE_TEMPORARY) {
+         storage->setTempElement(dst->Register.Index, out, dst->Register.WriteMask);
+      } else if (dst->Register.File == TGSI_FILE_ADDRESS) {
+         storage->setAddrElement(dst->Register.Index, out, dst->Register.WriteMask);
       } else {
          fprintf(stderr, "ERROR: unsupported LLVM destination!");
          assert(!"wrong destination");
@@ -683,16 +683,16 @@
    std::vector< std::vector<llvm::Value*> > inputs(inst->Instruction.NumSrcRegs);
 
    for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) {
-      struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i];
+      struct tgsi_full_src_register *src = &inst->Src[i];
       std::vector<llvm::Value*> val;
       llvm::Value *indIdx = 0;
       int swizzle = swizzleInt(src);
 
-      if (src->SrcRegister.Indirect) {
-         indIdx = storage->addrElement(src->SrcRegisterInd.Index);
+      if (src->Register.Indirect) {
+         indIdx = storage->addrElement(src->Indirect.Index);
       }
-      val = storage->load((enum tgsi_file_type)src->SrcRegister.File,
-                          src->SrcRegister.Index, swizzle, instr->getIRBuilder(), indIdx);
+      val = storage->load((enum tgsi_file_type)src->Register.File,
+                          src->Register.Index, swizzle, instr->getIRBuilder(), indIdx);
 
       inputs[i] = val;
    }
@@ -919,7 +919,7 @@
       break;
    case TGSI_OPCODE_SHL:
       break;
-   case TGSI_OPCODE_SHR:
+   case TGSI_OPCODE_ISHR:
       break;
    case TGSI_OPCODE_AND:
       break;
@@ -993,9 +993,9 @@
 
    /* store results  */
    for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) {
-      struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
-      storage->store((enum tgsi_file_type)dst->DstRegister.File,
-                     dst->DstRegister.Index, out, dst->DstRegister.WriteMask,
+      struct tgsi_full_dst_register *dst = &inst->Dst[i];
+      storage->store((enum tgsi_file_type)dst->Register.File,
+                     dst->Register.Index, out, dst->Register.WriteMask,
 		     instr->getIRBuilder() );
    }
 }
diff --git a/src/gallium/auxiliary/indices/Makefile b/src/gallium/auxiliary/indices/Makefile
deleted file mode 100644
index f2ebc3f..0000000
--- a/src/gallium/auxiliary/indices/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = indices
-
-C_SOURCES = \
-	u_indices_gen.c \
-	u_unfilled_gen.c 
-
-include ../../Makefile.template
-
-u_indices_gen.c: u_indices_gen.py
-	python $< > $@
-
-u_unfilled_gen.c: u_unfilled_gen.py
-	python $< > $@
diff --git a/src/gallium/auxiliary/indices/SConscript b/src/gallium/auxiliary/indices/SConscript
deleted file mode 100644
index 712e215..0000000
--- a/src/gallium/auxiliary/indices/SConscript
+++ /dev/null
@@ -1,28 +0,0 @@
-Import('*')
-
-from sys import executable as python_cmd
-
-env.CodeGenerate(
-	target = 'u_indices_gen.c', 
-	script = 'u_indices_gen.py', 
-	source = [],
-	command = python_cmd + ' $SCRIPT > $TARGET'
-)
-
-env.CodeGenerate(
-	target = 'u_unfilled_gen.c', 
-	script = 'u_unfilled_gen.py', 
-	source = [],
-	command = python_cmd + ' $SCRIPT > $TARGET'
-)
-
-indices = env.ConvenienceLibrary(
-	target = 'indices',
-	source = [
-#               'u_indices.c',
-#               'u_unfilled_indices.c',
-               'u_indices_gen.c',
-               'u_unfilled_gen.c',
-	])
-
-auxiliaries.insert(0, indices)
diff --git a/src/gallium/auxiliary/pipebuffer/Makefile b/src/gallium/auxiliary/pipebuffer/Makefile
deleted file mode 100644
index 1c00ba8..0000000
--- a/src/gallium/auxiliary/pipebuffer/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = pipebuffer
-
-C_SOURCES = \
-	pb_buffer_fenced.c \
-	pb_buffer_malloc.c \
-	pb_bufmgr_alt.c \
-	pb_bufmgr_cache.c \
-	pb_bufmgr_debug.c \
-	pb_bufmgr_fenced.c \
-	pb_bufmgr_mm.c \
-	pb_bufmgr_ondemand.c \
-	pb_bufmgr_pool.c \
-	pb_bufmgr_slab.c \
-	pb_validate.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/pipebuffer/SConscript b/src/gallium/auxiliary/pipebuffer/SConscript
deleted file mode 100644
index 8e9f06a..0000000
--- a/src/gallium/auxiliary/pipebuffer/SConscript
+++ /dev/null
@@ -1,19 +0,0 @@
-Import('*')
-
-pipebuffer = env.ConvenienceLibrary(
-	target = 'pipebuffer',
-	source = [
-		'pb_buffer_fenced.c',
-		'pb_buffer_malloc.c',
-		'pb_bufmgr_alt.c',
-		'pb_bufmgr_cache.c',
-		'pb_bufmgr_debug.c',
-		'pb_bufmgr_fenced.c',
-		'pb_bufmgr_mm.c',
-		'pb_bufmgr_ondemand.c',
-		'pb_bufmgr_pool.c',
-		'pb_bufmgr_slab.c',
-		'pb_validate.c',
-	])
-
-auxiliaries.insert(0, pipebuffer)
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h
index 4ef3722..eb7e84b 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h
@@ -237,8 +237,9 @@
 {
    struct pb_buffer *old = *dst;
 
-   if (pipe_reference((struct pipe_reference**)dst, &src->base.reference))
+   if (pipe_reference(&(*dst)->base.reference, &src->base.reference))
       pb_destroy( old );
+   *dst = src;
 }
 
 
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
index 2ef4293..ba6f7b1 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
@@ -1,6 +1,6 @@
 /**************************************************************************
  *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2007-2009 VMware, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -18,7 +18,7 @@
  * 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.
@@ -80,11 +80,27 @@
  */
 struct fenced_buffer
 {
-   struct pb_buffer base;
-   
-   struct pb_buffer *buffer;
+   /*
+    * Immutable members.
+    */
 
-   /* FIXME: protect access with mutex */
+   struct pb_buffer base;
+   struct pb_buffer *buffer;
+   struct fenced_buffer_list *list;
+
+   /**
+    * Protected by fenced_buffer_list::mutex
+    */
+   struct list_head head;
+
+   /**
+    * Following members are mutable and protected by this mutex.
+    * 
+    * You may lock this mutex alone, or lock it with fenced_buffer_list::mutex
+    * held, but in order to prevent deadlocks you must never lock 
+    * fenced_buffer_list::mutex with this mutex held.
+    */
+   pipe_mutex mutex;
 
    /**
     * A bitmask of PIPE_BUFFER_USAGE_CPU/GPU_READ/WRITE describing the current
@@ -96,9 +112,6 @@
    struct pb_validate *vl;
    unsigned validation_flags;
    struct pipe_fence_handle *fence;
-
-   struct list_head head;
-   struct fenced_buffer_list *list;
 };
 
 
@@ -110,15 +123,24 @@
 }
 
 
+/**
+ * Add the buffer to the fenced list.
+ * 
+ * fenced_buffer_list::mutex and fenced_buffer::mutex must be held, in this
+ * order, before calling this function.
+ * 
+ * Reference count should be incremented before calling this function.
+ */
 static INLINE void
-_fenced_buffer_add(struct fenced_buffer *fenced_buf)
+fenced_buffer_add_locked(struct fenced_buffer_list *fenced_list, 
+                         struct fenced_buffer *fenced_buf)
 {
-   struct fenced_buffer_list *fenced_list = fenced_buf->list;
-
    assert(pipe_is_referenced(&fenced_buf->base.base.reference));
    assert(fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE);
    assert(fenced_buf->fence);
 
+   /* TODO: Move the reference count increment here */
+   
 #ifdef DEBUG
    LIST_DEL(&fenced_buf->head);
    assert(fenced_list->numUnfenced);
@@ -130,32 +152,16 @@
 
 
 /**
- * Actually destroy the buffer.
+ * Remove the buffer from the fenced list.
+ * 
+ * fenced_buffer_list::mutex and fenced_buffer::mutex must be held, in this 
+ * order before calling this function.
+ * 
+ * Reference count should be decremented after calling this function.
  */
 static INLINE void
-_fenced_buffer_destroy(struct fenced_buffer *fenced_buf)
-{
-   struct fenced_buffer_list *fenced_list = fenced_buf->list;
-   
-   assert(!pipe_is_referenced(&fenced_buf->base.base.reference));
-   assert(!fenced_buf->fence);
-#ifdef DEBUG
-   assert(fenced_buf->head.prev);
-   assert(fenced_buf->head.next);
-   LIST_DEL(&fenced_buf->head);
-   assert(fenced_list->numUnfenced);
-   --fenced_list->numUnfenced;
-#else
-   (void)fenced_list;
-#endif
-   pb_reference(&fenced_buf->buffer, NULL);
-   FREE(fenced_buf);
-}
-
-
-static INLINE void
-_fenced_buffer_remove(struct fenced_buffer_list *fenced_list,
-                      struct fenced_buffer *fenced_buf)
+fenced_buffer_remove_locked(struct fenced_buffer_list *fenced_list,
+                            struct fenced_buffer *fenced_buf)
 {
    struct pb_fence_ops *ops = fenced_list->ops;
 
@@ -177,37 +183,56 @@
    ++fenced_list->numUnfenced;
 #endif
    
-   /**
-    * FIXME!!!
-    */
-
-   if(!pipe_is_referenced(&fenced_buf->base.base.reference))
-      _fenced_buffer_destroy(fenced_buf);
+   /* TODO: Move the reference count decrement and destruction here */
 }
 
 
+/**
+ * Wait for the fence to expire, and remove it from the fenced list.
+ * 
+ * fenced_buffer::mutex must be held. fenced_buffer_list::mutex must not be 
+ * held -- it will be acquired internally.
+ */
 static INLINE enum pipe_error
-_fenced_buffer_finish(struct fenced_buffer *fenced_buf)
+fenced_buffer_finish_locked(struct fenced_buffer_list *fenced_list,
+                              struct fenced_buffer *fenced_buf)
 {
-   struct fenced_buffer_list *fenced_list = fenced_buf->list;
    struct pb_fence_ops *ops = fenced_list->ops;
+   enum pipe_error ret = PIPE_ERROR;
 
 #if 0
    debug_warning("waiting for GPU");
 #endif
 
+   assert(pipe_is_referenced(&fenced_buf->base.base.reference));
    assert(fenced_buf->fence);
+
+   /*
+    * Acquire the global lock. Must release buffer mutex first to preserve
+    * lock order.
+    */
+   pipe_mutex_unlock(fenced_buf->mutex);
+   pipe_mutex_lock(fenced_list->mutex);
+   pipe_mutex_lock(fenced_buf->mutex);
+
    if(fenced_buf->fence) {
-      if(ops->fence_finish(ops, fenced_buf->fence, 0) != 0) {
-	 return PIPE_ERROR;
+      if(ops->fence_finish(ops, fenced_buf->fence, 0) == 0) {
+         /* Remove from the fenced list */
+         /* TODO: remove consequents */
+         fenced_buffer_remove_locked(fenced_list, fenced_buf);
+
+         p_atomic_dec(&fenced_buf->base.base.reference.count);
+         assert(pipe_is_referenced(&fenced_buf->base.base.reference));
+
+         fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE;
+
+         ret = PIPE_OK;
       }
-      /* Remove from the fenced list */
-      /* TODO: remove consequents */
-      _fenced_buffer_remove(fenced_list, fenced_buf);
    }
 
-   fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE;
-   return PIPE_OK;
+   pipe_mutex_unlock(fenced_list->mutex);
+
+   return ret;
 }
 
 
@@ -215,12 +240,13 @@
  * Free as many fenced buffers from the list head as possible. 
  */
 static void
-_fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, 
-                               int wait)
+fenced_buffer_list_check_free_locked(struct fenced_buffer_list *fenced_list, 
+                                     int wait)
 {
    struct pb_fence_ops *ops = fenced_list->ops;
    struct list_head *curr, *next;
    struct fenced_buffer *fenced_buf;
+   struct pb_buffer *pb_buf;
    struct pipe_fence_handle *prev_fence = NULL;
 
    curr = fenced_list->delayed.next;
@@ -228,21 +254,29 @@
    while(curr != &fenced_list->delayed) {
       fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
 
+      pipe_mutex_lock(fenced_buf->mutex);
+
       if(fenced_buf->fence != prev_fence) {
 	 int signaled;
 	 if (wait)
 	    signaled = ops->fence_finish(ops, fenced_buf->fence, 0);
 	 else
 	    signaled = ops->fence_signalled(ops, fenced_buf->fence, 0);
-	 if (signaled != 0)
+	 if (signaled != 0) {
+            pipe_mutex_unlock(fenced_buf->mutex);
 	    break;
+         }
 	 prev_fence = fenced_buf->fence;
       }
       else {
 	 assert(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0);
       }
 
-      _fenced_buffer_remove(fenced_list, fenced_buf);
+      fenced_buffer_remove_locked(fenced_list, fenced_buf);
+      pipe_mutex_unlock(fenced_buf->mutex);
+
+      pb_buf = &fenced_buf->base;
+      pb_reference(&pb_buf, NULL);
 
       curr = next; 
       next = curr->next;
@@ -256,30 +290,25 @@
    struct fenced_buffer *fenced_buf = fenced_buffer(buf);   
    struct fenced_buffer_list *fenced_list = fenced_buf->list;
 
-   pipe_mutex_lock(fenced_list->mutex);
    assert(!pipe_is_referenced(&fenced_buf->base.base.reference));
-   if (fenced_buf->fence) {
-      struct pb_fence_ops *ops = fenced_list->ops;
-      if(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0) {
-	 struct list_head *curr, *prev;
-	 curr = &fenced_buf->head;
-	 prev = curr->prev;
-	 do {
-	    fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
-	    assert(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0);
-	    _fenced_buffer_remove(fenced_list, fenced_buf);
-	    curr = prev;
-	    prev = curr->prev;
-	 } while (curr != &fenced_list->delayed);
-      }	  
-      else {
-	 /* delay destruction */
-      }
-   }
-   else {
-      _fenced_buffer_destroy(fenced_buf);
-   }
+   assert(!fenced_buf->fence);
+
+#ifdef DEBUG
+   pipe_mutex_lock(fenced_list->mutex);
+   assert(fenced_buf->head.prev);
+   assert(fenced_buf->head.next);
+   LIST_DEL(&fenced_buf->head);
+   assert(fenced_list->numUnfenced);
+   --fenced_list->numUnfenced;
    pipe_mutex_unlock(fenced_list->mutex);
+#else
+   (void)fenced_list;
+#endif
+
+   pb_reference(&fenced_buf->buffer, NULL);
+
+   pipe_mutex_destroy(fenced_buf->mutex);
+   FREE(fenced_buf);
 }
 
 
@@ -290,24 +319,23 @@
    struct fenced_buffer *fenced_buf = fenced_buffer(buf);
    struct fenced_buffer_list *fenced_list = fenced_buf->list;
    struct pb_fence_ops *ops = fenced_list->ops;
-   void *map;
+   void *map = NULL;
+
+   pipe_mutex_lock(fenced_buf->mutex);
 
    assert(!(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE));
    
    /* Serialize writes */
    if((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE) ||
       ((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ) && (flags & PIPE_BUFFER_USAGE_CPU_WRITE))) {
-      if(flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
+      if((flags & PIPE_BUFFER_USAGE_DONTBLOCK) &&
+          ops->fence_signalled(ops, fenced_buf->fence, 0) == 0) {
          /* Don't wait for the GPU to finish writing */
-         if(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0)
-            _fenced_buffer_remove(fenced_list, fenced_buf);
-         else
-            return NULL;
+         goto done;
       }
-      else {
-         /* Wait for the GPU to finish writing */
-         _fenced_buffer_finish(fenced_buf);
-      }
+
+      /* Wait for the GPU to finish writing */
+      fenced_buffer_finish_locked(fenced_list, fenced_buf);
    }
 
 #if 0
@@ -324,6 +352,9 @@
       fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE;
    }
 
+done:
+   pipe_mutex_unlock(fenced_buf->mutex);
+   
    return map;
 }
 
@@ -332,6 +363,9 @@
 fenced_buffer_unmap(struct pb_buffer *buf)
 {
    struct fenced_buffer *fenced_buf = fenced_buffer(buf);
+   
+   pipe_mutex_lock(fenced_buf->mutex);
+   
    assert(fenced_buf->mapcount);
    if(fenced_buf->mapcount) {
       pb_unmap(fenced_buf->buffer);
@@ -339,6 +373,8 @@
       if(!fenced_buf->mapcount)
 	 fenced_buf->flags &= ~PIPE_BUFFER_USAGE_CPU_READ_WRITE;
    }
+   
+   pipe_mutex_unlock(fenced_buf->mutex);
 }
 
 
@@ -350,11 +386,14 @@
    struct fenced_buffer *fenced_buf = fenced_buffer(buf);
    enum pipe_error ret;
    
+   pipe_mutex_lock(fenced_buf->mutex);
+
    if(!vl) {
       /* invalidate */
       fenced_buf->vl = NULL;
       fenced_buf->validation_flags = 0;
-      return PIPE_OK;
+      ret = PIPE_OK;
+      goto done;
    }
    
    assert(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE);
@@ -362,14 +401,17 @@
    flags &= PIPE_BUFFER_USAGE_GPU_READ_WRITE;
 
    /* Buffer cannot be validated in two different lists */ 
-   if(fenced_buf->vl && fenced_buf->vl != vl)
-      return PIPE_ERROR_RETRY;
+   if(fenced_buf->vl && fenced_buf->vl != vl) {
+      ret = PIPE_ERROR_RETRY;
+      goto done;
+   }
    
 #if 0
    /* Do not validate if buffer is still mapped */
    if(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) {
       /* TODO: wait for the thread that mapped the buffer to unmap it */
-      return PIPE_ERROR_RETRY;
+      ret = PIPE_ERROR_RETRY;
+      goto done;
    }
    /* Final sanity checking */
    assert(!(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE));
@@ -379,17 +421,21 @@
    if(fenced_buf->vl == vl &&
       (fenced_buf->validation_flags & flags) == flags) {
       /* Nothing to do -- buffer already validated */
-      return PIPE_OK;
+      ret = PIPE_OK;
+      goto done;
    }
    
    ret = pb_validate(fenced_buf->buffer, vl, flags);
    if (ret != PIPE_OK)
-      return ret;
+      goto done;
    
    fenced_buf->vl = vl;
    fenced_buf->validation_flags |= flags;
    
-   return PIPE_OK;
+done:
+   pipe_mutex_unlock(fenced_buf->mutex);
+
+   return ret;
 }
 
 
@@ -404,29 +450,36 @@
    fenced_buf = fenced_buffer(buf);
    fenced_list = fenced_buf->list;
    ops = fenced_list->ops;
-   
-   if(fence == fenced_buf->fence) {
-      /* Nothing to do */
-      return;
-   }
 
-   assert(fenced_buf->vl);
-   assert(fenced_buf->validation_flags);
-   
    pipe_mutex_lock(fenced_list->mutex);
-   if (fenced_buf->fence)
-      _fenced_buffer_remove(fenced_list, fenced_buf);
-   if (fence) {
-      ops->fence_reference(ops, &fenced_buf->fence, fence);
-      fenced_buf->flags |= fenced_buf->validation_flags;
-      _fenced_buffer_add(fenced_buf);
-   }
-   pipe_mutex_unlock(fenced_list->mutex);
-   
-   pb_fence(fenced_buf->buffer, fence);
+   pipe_mutex_lock(fenced_buf->mutex);
 
-   fenced_buf->vl = NULL;
-   fenced_buf->validation_flags = 0;
+   assert(pipe_is_referenced(&fenced_buf->base.base.reference));
+
+   if(fence != fenced_buf->fence) {
+      assert(fenced_buf->vl);
+      assert(fenced_buf->validation_flags);
+      
+      if (fenced_buf->fence) {
+         fenced_buffer_remove_locked(fenced_list, fenced_buf);
+         p_atomic_dec(&fenced_buf->base.base.reference.count);
+         assert(pipe_is_referenced(&fenced_buf->base.base.reference));
+      }
+      if (fence) {
+         ops->fence_reference(ops, &fenced_buf->fence, fence);
+         fenced_buf->flags |= fenced_buf->validation_flags;
+         p_atomic_inc(&fenced_buf->base.base.reference.count);
+         fenced_buffer_add_locked(fenced_list, fenced_buf);
+      }
+
+      pb_fence(fenced_buf->buffer, fence);
+   
+      fenced_buf->vl = NULL;
+      fenced_buf->validation_flags = 0;
+   }
+
+   pipe_mutex_unlock(fenced_buf->mutex);
+   pipe_mutex_unlock(fenced_list->mutex);
 }
 
 
@@ -436,6 +489,7 @@
                               pb_size *offset)
 {
    struct fenced_buffer *fenced_buf = fenced_buffer(buf);
+   /* NOTE: accesses immutable members only -- mutex not necessary */
    pb_get_base_buffer(fenced_buf->buffer, base_buf, offset);
 }
 
@@ -475,6 +529,8 @@
    buf->buffer = buffer;
    buf->list = fenced_list;
    
+   pipe_mutex_init(buf->mutex);
+
 #ifdef DEBUG
    pipe_mutex_lock(fenced_list->mutex);
    LIST_ADDTAIL(&buf->head, &fenced_list->unfenced);
@@ -516,7 +572,7 @@
                               int wait)
 {
    pipe_mutex_lock(fenced_list->mutex);
-   _fenced_buffer_list_check_free(fenced_list, wait);
+   fenced_buffer_list_check_free_locked(fenced_list, wait);
    pipe_mutex_unlock(fenced_list->mutex);
 }
 
@@ -538,11 +594,13 @@
    next = curr->next;
    while(curr != &fenced_list->unfenced) {
       fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
+      pipe_mutex_lock(fenced_buf->mutex);
       assert(!fenced_buf->fence);
       debug_printf("%10p %7u %7u\n",
                    (void *) fenced_buf,
                    fenced_buf->base.base.size,
                    p_atomic_read(&fenced_buf->base.base.reference.count));
+      pipe_mutex_unlock(fenced_buf->mutex);
       curr = next; 
       next = curr->next;
    }
@@ -552,6 +610,7 @@
    while(curr != &fenced_list->delayed) {
       int signaled;
       fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
+      pipe_mutex_lock(fenced_buf->mutex);
       signaled = ops->fence_signalled(ops, fenced_buf->fence, 0);
       debug_printf("%10p %7u %7u %10p %s\n",
                    (void *) fenced_buf,
@@ -559,6 +618,7 @@
                    p_atomic_read(&fenced_buf->base.base.reference.count),
                    (void *) fenced_buf->fence,
                    signaled == 0 ? "y" : "n");
+      pipe_mutex_unlock(fenced_buf->mutex);
       curr = next; 
       next = curr->next;
    }
@@ -579,8 +639,8 @@
 #if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
       sched_yield();
 #endif
-      _fenced_buffer_list_check_free(fenced_list, 1);
       pipe_mutex_lock(fenced_list->mutex);
+      fenced_buffer_list_check_free_locked(fenced_list, 1);
    }
 
 #ifdef DEBUG
@@ -588,6 +648,7 @@
 #endif
       
    pipe_mutex_unlock(fenced_list->mutex);
+   pipe_mutex_destroy(fenced_list->mutex);
    
    fenced_list->ops->destroy(fenced_list->ops);
    
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
index 57d1ede..7b34c8e 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
@@ -294,7 +294,7 @@
       LIST_DEL(&buf->head);
       pipe_mutex_unlock(mgr->mutex);
       /* Increase refcount */
-      pb_reference((struct pb_buffer**)&buf, &buf->base);
+      pipe_reference(NULL, &buf->base.base.reference);
       return &buf->base;
    }
    
diff --git a/src/gallium/auxiliary/rbug/Makefile b/src/gallium/auxiliary/rbug/Makefile
deleted file mode 100644
index cd12e84..0000000
--- a/src/gallium/auxiliary/rbug/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = rbug
-
-C_SOURCES = \
-	rbug_connection.c \
-	rbug_core.c \
-	rbug_texture.c \
-	rbug_context.c \
-	rbug_shader.c \
-	rbug_demarshal.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/rbug/README b/src/gallium/auxiliary/rbug/README
index 33d7637..d984067 100644
--- a/src/gallium/auxiliary/rbug/README
+++ b/src/gallium/auxiliary/rbug/README
@@ -16,6 +16,10 @@
 
 progs/rbug/README
 
+for a GUI see:
+
+  http://cgit.freedesktop.org/mesa/rbug-gui
+
 
 --
 Jakob Bornecrantz <jakob@vmware.com>
diff --git a/src/gallium/auxiliary/rbug/SConscript b/src/gallium/auxiliary/rbug/SConscript
deleted file mode 100644
index 4a9afb4..0000000
--- a/src/gallium/auxiliary/rbug/SConscript
+++ /dev/null
@@ -1,14 +0,0 @@
-Import('*')
-
-rbug = env.ConvenienceLibrary(
-	target = 'rbug',
-	source = [
-		'rbug_core.c',
-		'rbug_shader.c',
-		'rbug_context.c',
-		'rbug_texture.c',
-		'rbug_demarshal.c',
-		'rbug_connection.c',
-	])
-
-auxiliaries.insert(0, rbug)
diff --git a/src/gallium/auxiliary/rbug/rbug_connection.c b/src/gallium/auxiliary/rbug/rbug_connection.c
index 52acb70..ae4e27f 100644
--- a/src/gallium/auxiliary/rbug/rbug_connection.c
+++ b/src/gallium/auxiliary/rbug/rbug_connection.c
@@ -87,6 +87,7 @@
    if (!data) {
       return NULL;
    }
+   data->opcode = 0;
 
    do {
       uint8_t *ptr = ((uint8_t*)data) + read;
diff --git a/src/gallium/auxiliary/rbug/rbug_context.h b/src/gallium/auxiliary/rbug/rbug_context.h
index da61c23..03126d6 100644
--- a/src/gallium/auxiliary/rbug/rbug_context.h
+++ b/src/gallium/auxiliary/rbug/rbug_context.h
@@ -46,7 +46,7 @@
 	RBUG_BLOCK_BEFORE = 1,
 	RBUG_BLOCK_AFTER = 2,
 	RBUG_BLOCK_RULE = 4,
-	RBUG_BLOCK_MASK = 7,
+	RBUG_BLOCK_MASK = 7
 } rbug_block_t;
 
 struct rbug_proto_context_list
diff --git a/src/gallium/auxiliary/rbug/rbug_proto.h b/src/gallium/auxiliary/rbug/rbug_proto.h
index d273be0..4f3eb75 100644
--- a/src/gallium/auxiliary/rbug/rbug_proto.h
+++ b/src/gallium/auxiliary/rbug/rbug_proto.h
@@ -65,7 +65,7 @@
 	RBUG_OP_SHADER_DISABLE = 770,
 	RBUG_OP_SHADER_REPLACE = 771,
 	RBUG_OP_SHADER_LIST_REPLY = -768,
-	RBUG_OP_SHADER_INFO_REPLY = -769,
+	RBUG_OP_SHADER_INFO_REPLY = -769
 };
 
 /**
diff --git a/src/gallium/auxiliary/rtasm/Makefile b/src/gallium/auxiliary/rtasm/Makefile
deleted file mode 100644
index ab8ea46..0000000
--- a/src/gallium/auxiliary/rtasm/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = rtasm
-
-C_SOURCES = \
-	rtasm_cpu.c \
-	rtasm_execmem.c \
-	rtasm_x86sse.c \
-	rtasm_ppc.c \
-	rtasm_ppc_spe.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/rtasm/SConscript b/src/gallium/auxiliary/rtasm/SConscript
deleted file mode 100644
index eb48368..0000000
--- a/src/gallium/auxiliary/rtasm/SConscript
+++ /dev/null
@@ -1,13 +0,0 @@
-Import('*')
-
-rtasm = env.ConvenienceLibrary(
-	target = 'rtasm',
-	source = [
-		'rtasm_cpu.c',
-		'rtasm_execmem.c',
-		'rtasm_x86sse.c',
-		'rtasm_ppc.c',
-		'rtasm_ppc_spe.c',
-	])
-
-auxiliaries.insert(0, rtasm)
diff --git a/src/gallium/auxiliary/rtasm/rtasm_execmem.c b/src/gallium/auxiliary/rtasm/rtasm_execmem.c
index 01811d5..ffed768 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_execmem.c
+++ b/src/gallium/auxiliary/rtasm/rtasm_execmem.c
@@ -41,6 +41,12 @@
 #define MAP_ANONYMOUS MAP_ANON
 #endif
 
+#if defined(PIPE_OS_WINDOWS)
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
+#include <windows.h>
+#endif
 
 #if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
 
@@ -118,7 +124,29 @@
 }
 
 
-#else /* PIPE_OS_LINUX || PIPE_OS_BSD || PIPE_OS_SOLARIS */
+#elif defined(PIPE_OS_WINDOWS)
+
+
+/*
+ * Avoid Data Execution Prevention.
+ */
+
+void *
+rtasm_exec_malloc(size_t size)
+{
+   return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+}
+
+
+void
+rtasm_exec_free(void *addr)
+{
+   VirtualFree(addr, 0, MEM_RELEASE);
+}
+
+
+#else
+
 
 /*
  * Just use regular memory.
@@ -138,4 +166,4 @@
 }
 
 
-#endif /* PIPE_OS_LINUX || PIPE_OS_BSD || PIPE_OS_SOLARIS */
+#endif
diff --git a/src/gallium/auxiliary/sct/Makefile b/src/gallium/auxiliary/sct/Makefile
deleted file mode 100644
index a7d111b..0000000
--- a/src/gallium/auxiliary/sct/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = sct
-
-C_SOURCES = \
-	sct.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/sct/SConscript b/src/gallium/auxiliary/sct/SConscript
deleted file mode 100644
index 76927d9..0000000
--- a/src/gallium/auxiliary/sct/SConscript
+++ /dev/null
@@ -1,9 +0,0 @@
-Import('*')
-
-sct = env.ConvenienceLibrary(
-	target = 'sct',
-	source = [
-		'sct.c'
-	])
-
-auxiliaries.insert(0, sct)
diff --git a/src/gallium/auxiliary/sct/sct.c b/src/gallium/auxiliary/sct/sct.c
deleted file mode 100644
index 722d2b7..0000000
--- a/src/gallium/auxiliary/sct/sct.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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.
- * 
- **************************************************************************/
-
-
-#include "util/u_memory.h"
-#include "pipe/p_state.h"
-#include "sct.h"
-
-
-struct texture_list
-{
-   struct pipe_texture *texture;
-   struct texture_list *next;
-};
-
-
-
-#define MAX_SURFACES  ((PIPE_MAX_COLOR_BUFS) + 1)
-
-struct sct_context
-{
-   const struct pipe_context *context;
-
-   /** surfaces the context is drawing into */
-   struct pipe_surface *surfaces[MAX_SURFACES];
-
-   /** currently bound textures */
-   struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
-
-   /** previously bound textures, used but not flushed */
-   struct texture_list *textures_used;
-
-   boolean needs_flush;
-
-   struct sct_context *next;
-};
-
-
-
-struct sct_surface
-{
-   const struct pipe_surface *surface;
-
-   /** list of contexts drawing to this surface */
-   struct sct_context_list *contexts;
-
-   struct sct_surface *next;
-};
-
-
-
-/**
- * Find the surface_info for the given pipe_surface
- */
-static struct sct_surface *
-find_surface_info(struct surface_context_tracker *sct,
-                  const struct pipe_surface *surface)
-{
-   struct sct_surface *si;
-   for (si = sct->surfaces; si; si = si->next)
-      if (si->surface == surface)
-         return si;
-   return NULL;
-}
-
-
-/**
- * As above, but create new surface_info if surface is new.
- */
-static struct sct_surface *
-find_create_surface_info(struct surface_context_tracker *sct,
-                         const struct pipe_surface *surface)
-{
-   struct sct_surface *si = find_surface_info(sct, surface);
-   if (si)
-      return si;
-
-   /* alloc new */
-   si = CALLOC_STRUCT(sct_surface);
-   if (si) {
-      si->surface = surface;
-
-      /* insert at head */
-      si->next = sct->surfaces;
-      sct->surfaces = si;
-   }
-
-   return si;
-}
-
-
-/**
- * Find a context_info for the given context.
- */
-static struct sct_context *
-find_context_info(struct surface_context_tracker *sct,
-                  const struct pipe_context *context)
-{
-   struct sct_context *ci;
-   for (ci = sct->contexts; ci; ci = ci->next)
-      if (ci->context == context)
-         return ci;
-   return NULL;
-}
-
-
-/**
- * As above, but create new context_info if context is new.
- */
-static struct sct_context *
-find_create_context_info(struct surface_context_tracker *sct,
-                         const struct pipe_context *context)
-{
-   struct sct_context *ci = find_context_info(sct, context);
-   if (ci)
-      return ci;
-
-   /* alloc new */
-   ci = CALLOC_STRUCT(sct_context);
-   if (ci) {
-      ci->context = context;
-
-      /* insert at head */
-      ci->next = sct->contexts;
-      sct->contexts = ci;
-   }
-
-   return ci;
-}
-
-
-/**
- * Is the context already bound to the surface?
- */
-static boolean
-find_surface_context(const struct sct_surface *si,
-                     const struct pipe_context *context)
-{
-   const struct sct_context_list *cl;
-   for (cl = si->contexts; cl; cl = cl->next) {
-      if (cl->context == context) {
-         return TRUE;
-      }
-   }
-   return FALSE;
-}
-
-
-/**
- * Add a context to the list of contexts associated with a surface.
- */
-static void
-add_context_to_surface(struct sct_surface *si,
-                       const struct pipe_context *context)
-{
-   struct sct_context_list *cl = CALLOC_STRUCT(sct_context_list);
-   if (cl) {
-      cl->context = context;
-      /* insert at head of list of contexts */
-      cl->next = si->contexts;
-      si->contexts = cl;
-   }
-}
-
-
-/**
- * Remove a context from the list of contexts associated with a surface.
- */
-static void
-remove_context_from_surface(struct sct_surface *si,
-                            const struct pipe_context *context)
-{
-   struct sct_context_list *prev = NULL, *curr, *next;
-
-   for (curr = si->contexts; curr; curr = next) {
-      if (curr->context == context) {
-         /* remove */
-         if (prev)
-            prev->next = curr->next;
-         else
-            si->contexts = curr->next;
-         next = curr->next;
-         FREE(curr);
-      }
-      else {
-         prev = curr;
-         next = curr->next;
-      }
-   }
-}
-
-
-/**
- * Unbind context from surface.
- */
-static void
-unbind_context_surface(struct surface_context_tracker *sct,
-                       struct pipe_context *context,
-                       struct pipe_surface *surface)
-{
-   struct sct_surface *si = find_surface_info(sct, surface);
-   if (si) {
-      remove_context_from_surface(si, context);
-   }
-}
-
-
-/**
- * Bind context to a set of surfaces (color + Z).
- * Like MakeCurrent().
- */
-void
-sct_bind_surfaces(struct surface_context_tracker *sct,
-                  struct pipe_context *context,
-                  uint num_surf,
-                  struct pipe_surface **surfaces)
-{
-   struct sct_context *ci = find_create_context_info(sct, context);
-   uint i;
-
-   if (!ci) {
-      return; /* out of memory */
-   }
-
-   /* unbind currently bound surfaces */
-   for (i = 0; i < MAX_SURFACES; i++) {
-      if (ci->surfaces[i]) {
-         unbind_context_surface(sct, context, ci->surfaces[i]);
-      }
-   }
-
-   /* bind new surfaces */
-   for (i = 0; i < num_surf; i++) {
-      struct sct_surface *si = find_create_surface_info(sct, surfaces[i]);
-      if (!find_surface_context(si, context)) {
-         add_context_to_surface(si, context);
-      }
-   }
-}
-
-
-/**
- * Return list of contexts bound to a surface.
- */
-const struct sct_context_list *
-sct_get_surface_contexts(struct surface_context_tracker *sct,
-                         const struct pipe_surface *surface)
-{
-   const struct sct_surface *si = find_surface_info(sct, surface);
-   return si->contexts;
-}
-
-
-
-static boolean
-find_texture(const struct sct_context *ci,
-             const struct pipe_texture *texture)
-{
-   const struct texture_list *tl;
-
-   for (tl = ci->textures_used; tl; tl = tl->next) {
-      if (tl->texture == texture) {
-         return TRUE;
-      }
-   }
-   return FALSE;
-}
-
-
-/**
- * Add the given texture to the context's list of used textures.
- */
-static void
-add_texture_used(struct sct_context *ci,
-                 struct pipe_texture *texture)
-{
-   if (!find_texture(ci, texture)) {
-      /* add to list */
-      struct texture_list *tl = CALLOC_STRUCT(texture_list);
-      if (tl) {
-         pipe_texture_reference(&tl->texture, texture);
-         /* insert at head */
-         tl->next = ci->textures_used;
-         ci->textures_used = tl;
-      }
-   }
-}
-
-
-/**
- * Bind a texture to a rendering context.
- */
-void
-sct_bind_texture(struct surface_context_tracker *sct,
-                 struct pipe_context *context,
-                 uint unit,
-                 struct pipe_texture *tex)
-{
-   struct sct_context *ci = find_context_info(sct, context);
-
-   if (ci->textures[unit] != tex) {
-      /* put texture on the 'used' list */
-      add_texture_used(ci, tex);
-      /* bind new */
-      pipe_texture_reference(&ci->textures[unit], tex);
-   }
-}
-
-
-/**
- * Check if the given texture has been used by the rendering context
- * since the last call to sct_flush_textures().
- */
-boolean
-sct_is_texture_used(struct surface_context_tracker *sct,
-                    const struct pipe_context *context,
-                    const struct pipe_texture *texture)
-{
-   const struct sct_context *ci = find_context_info(sct, context);
-   return find_texture(ci, texture);
-}
-
-
-/**
- * To be called when the image contents of a texture are changed, such
- * as for gl[Copy]TexSubImage().
- * XXX this may not be needed
- */
-void
-sct_update_texture(struct pipe_texture *tex)
-{
-
-}
-
-
-/**
- * When a scene is flushed/rendered we can release the list of
- * used textures.
- */
-void
-sct_flush_textures(struct surface_context_tracker *sct,
-                   struct pipe_context *context)
-{
-   struct sct_context *ci = find_context_info(sct, context);
-   struct texture_list *tl, *next;
-   uint i;
-
-   for (tl = ci->textures_used; tl; tl = next) {
-      next = tl->next;
-      pipe_texture_reference(&tl->texture, NULL);
-      FREE(tl);
-   }
-   ci->textures_used = NULL;
-
-   /* put the currently bound textures on the 'used' list */
-   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
-      add_texture_used(ci, ci->textures[i]);
-   }
-}
-
-
-
-void
-sct_destroy_context(struct surface_context_tracker *sct,
-                    struct pipe_context *context)
-{
-   /* XXX should we require an unbinding first? */
-   {
-      struct sct_surface *si;
-      for (si = sct->surfaces; si; si = si->next) {
-         remove_context_from_surface(si, context);
-      }
-   }
-
-   /* remove context from context_info list */
-   {
-      struct sct_context *ci, *next, *prev = NULL;
-      for (ci = sct->contexts; ci; ci = next) {
-         next = ci->next;
-         if (ci->context == context) {
-            if (prev)
-               prev->next = ci->next;
-            else
-               sct->contexts = ci->next;
-            FREE(ci);
-         }
-         else {
-            prev = ci;
-         }
-      }
-   }
-
-}
-
-
-void
-sct_destroy_surface(struct surface_context_tracker *sct,
-                    struct pipe_surface *surface)
-{
-   if (1) {
-      /* debug/sanity: no context should be bound to surface */
-      struct sct_context *ci;
-      uint i;
-      for (ci = sct->contexts; ci; ci = ci->next) {
-         for (i = 0; i < MAX_SURFACES; i++) {
-            assert(ci->surfaces[i] != surface);
-         }
-      }
-   }
-
-   /* remove surface from sct_surface list */
-   {
-      struct sct_surface *si, *next, *prev = NULL;
-      for (si = sct->surfaces; si; si = next) {
-         next = si->next;
-         if (si->surface == surface) {
-            /* unlink */
-            if (prev)
-               prev->next = si->next;
-            else
-               sct->surfaces = si->next;
-            FREE(si);
-         }
-         else {
-            prev = si;
-         }
-      }
-   }
-}
diff --git a/src/gallium/auxiliary/sct/sct.h b/src/gallium/auxiliary/sct/sct.h
deleted file mode 100644
index cf7c4d3..0000000
--- a/src/gallium/auxiliary/sct/sct.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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.
- * 
- **************************************************************************/
-
-/**
- * Surface/Context Tracking
- *
- * For some drivers, we need to monitor the binding between contexts and
- * surfaces/textures.
- * This code may evolve quite a bit...
- */
-
-
-#ifndef SCT_H
-#define SCT_H
-
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-
-struct pipe_context;
-struct pipe_surface;
-
-struct sct_context;
-struct sct_surface;
-
-
-/**
- * Per-device info, basically
- */
-struct surface_context_tracker
-{
-   struct sct_context *contexts;
-   struct sct_surface *surfaces;
-};
-
-
-
-/**
- * Simple linked list of contexts
- */
-struct sct_context_list
-{
-   const struct pipe_context *context;
-   struct sct_context_list *next;
-};
-
-
-
-extern void
-sct_bind_surfaces(struct surface_context_tracker *sct,
-                  struct pipe_context *context,
-                  uint num_surf,
-                  struct pipe_surface **surfaces);
-
-
-extern void
-sct_bind_texture(struct surface_context_tracker *sct,
-                 struct pipe_context *context,
-                 uint unit,
-                 struct pipe_texture *texture);
-
-
-extern void
-sct_update_texture(struct pipe_texture *tex);
-
-
-extern boolean
-sct_is_texture_used(struct surface_context_tracker *sct,
-                    const struct pipe_context *context,
-                    const struct pipe_texture *texture);
-
-extern void
-sct_flush_textures(struct surface_context_tracker *sct,
-                   struct pipe_context *context);
-
-
-extern const struct sct_context_list *
-sct_get_surface_contexts(struct surface_context_tracker *sct,
-                         const struct pipe_surface *surf);
-
-
-extern void
-sct_destroy_context(struct surface_context_tracker *sct,
-                    struct pipe_context *context);
-
-
-extern void
-sct_destroy_surface(struct surface_context_tracker *sct,
-                    struct pipe_surface *surface);
-
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif /* SCT_H */
diff --git a/src/gallium/auxiliary/sct/usage.c b/src/gallium/auxiliary/sct/usage.c
deleted file mode 100644
index 6227f19..0000000
--- a/src/gallium/auxiliary/sct/usage.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* surface / context tracking */
-
-
-/*
-
-context A:
-  render to texture T
-
-context B:
-  texture from T
-
------------------------
-
-flush surface:
-  which contexts are bound to the surface?
-
------------------------
-
-glTexSubImage():
-  which contexts need to be flushed?
-
- */
-
-
-/*
-
-in MakeCurrent():
-
-  call sct_bind_surfaces(context, list of surfaces) to update the
-  dependencies between context and surfaces
-
-
-in SurfaceFlush(), or whatever it is in D3D:
-
-  call sct_get_surface_contexts(surface) to get a list of contexts
-  which are currently bound to the surface.
-
-
-
-in BindTexture():
-
-  call sct_bind_texture(context, texture) to indicate that the texture
-  is used in the scene.
-
-
-in glTexSubImage() or RenderToTexture():
-
-  call sct_is_texture_used(context, texture) to determine if the texture
-  has been used in the scene, but the scene's not flushed.  If TRUE is
-  returned it means the scene has to be rendered/flushed before the contents
-  of the texture can be changed.
-
-
-in psb_scene_flush/terminate():
-
-  call sct_flush_textures(context) to tell the SCT that the textures which
-  were used in the scene can be released.
-
-
-
-*/
diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile
deleted file mode 100644
index 5f0a580..0000000
--- a/src/gallium/auxiliary/tgsi/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = tgsi
-
-C_SOURCES = \
-	tgsi_sanity.c \
-	tgsi_build.c \
-	tgsi_dump.c \
-	tgsi_exec.c \
-	tgsi_info.c \
-	tgsi_iterate.c \
-	tgsi_parse.c \
-	tgsi_ppc.c \
-	tgsi_scan.c \
-	tgsi_sse2.c \
-	tgsi_text.c \
-	tgsi_transform.c \
-	tgsi_ureg.c \
-	tgsi_util.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript
deleted file mode 100644
index b6bc292..0000000
--- a/src/gallium/auxiliary/tgsi/SConscript
+++ /dev/null
@@ -1,23 +0,0 @@
-Import('*')
-
-tgsi = env.ConvenienceLibrary(
-	target = 'tgsi',
-	source = [
-		'tgsi_build.c',
-		'tgsi_dump.c',
-		'tgsi_dump_c.c',
-		'tgsi_exec.c',
-		'tgsi_info.c',
-		'tgsi_iterate.c',
-		'tgsi_parse.c',
-		'tgsi_sanity.c',
-		'tgsi_scan.c',
-		'tgsi_ppc.c',
-		'tgsi_sse2.c',
-		'tgsi_text.c',
-		'tgsi_transform.c',
-		'tgsi_ureg.c',
-		'tgsi_util.c',
-	])
-
-auxiliaries.insert(0, tgsi)
diff --git a/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt b/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt
index eb49207..080fd4c 100644
--- a/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt
+++ b/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt
@@ -1129,3 +1129,35 @@
 
   target            Label of target instruction.
 
+
+3  Other tokens
+===============
+
+
+3.1  Declaration Semantic
+-------------------------
+
+
+  Follows Declaration token if Semantic bit is set.
+
+  Since its purpose is to link a shader with other stages of the pipeline,
+  it is valid to follow only those Declaration tokens that declare a register
+  either in INPUT or OUTPUT file.
+
+  SemanticName field contains the semantic name of the register being declared.
+  There is no default value.
+
+  SemanticIndex is an optional subscript that can be used to distinguish
+  different register declarations with the same semantic name. The default value
+  is 0.
+
+  The meanings of the individual semantic names are explained in the following
+  sections.
+
+
+3.1.1  FACE
+
+  Valid only in a fragment shader INPUT declaration.
+
+  FACE.x is negative when the primitive is back facing. FACE.x is positive
+  when the primitive is front facing.
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
index 4fa10e2..de9cbc8 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
@@ -30,21 +30,6 @@
 #include "tgsi_build.h"
 #include "tgsi_parse.h"
 
-/*
- * version
- */
-
-struct tgsi_version
-tgsi_build_version( void )
-{
-   struct tgsi_version  version;
-
-   version.MajorVersion = 1;
-   version.MinorVersion = 1;
-   version.Padding = 0;
-
-   return version;
-}
 
 /*
  * header
@@ -122,7 +107,6 @@
    declaration.Centroid = 0;
    declaration.Invariant = 0;
    declaration.Padding = 0;
-   declaration.Extended = 0;
 
    return declaration;
 }
@@ -173,7 +157,7 @@
    struct tgsi_full_declaration  full_declaration;
 
    full_declaration.Declaration  = tgsi_default_declaration();
-   full_declaration.DeclarationRange = tgsi_default_declaration_range();
+   full_declaration.Range = tgsi_default_declaration_range();
    full_declaration.Semantic = tgsi_default_declaration_semantic();
 
    return full_declaration;
@@ -210,8 +194,8 @@
    size++;
 
    *dr = tgsi_build_declaration_range(
-      full_decl->DeclarationRange.First,
-      full_decl->DeclarationRange.Last,
+      full_decl->Range.First,
+      full_decl->Range.Last,
       declaration,
       header );
 
@@ -224,8 +208,8 @@
       size++;
 
       *ds = tgsi_build_declaration_semantic(
-         full_decl->Semantic.SemanticName,
-         full_decl->Semantic.SemanticIndex,
+         full_decl->Semantic.Name,
+         full_decl->Semantic.Index,
          declaration,
          header );
    }
@@ -270,8 +254,8 @@
 {
    struct tgsi_declaration_semantic ds;
 
-   ds.SemanticName = TGSI_SEMANTIC_POSITION;
-   ds.SemanticIndex = 0;
+   ds.Name = TGSI_SEMANTIC_POSITION;
+   ds.Index = 0;
    ds.Padding = 0;
 
    return ds;
@@ -290,8 +274,8 @@
    assert( semantic_index <= 0xFFFF );
 
    ds = tgsi_default_declaration_semantic();
-   ds.SemanticName = semantic_name;
-   ds.SemanticIndex = semantic_index;
+   ds.Name = semantic_name;
+   ds.Index = semantic_index;
 
    declaration_grow( declaration, header );
 
@@ -311,7 +295,6 @@
    immediate.NrTokens = 1;
    immediate.DataType = TGSI_IMM_FLOAT32;
    immediate.Padding = 0;
-   immediate.Extended = 0;
 
    return immediate;
 }
@@ -416,24 +399,26 @@
    struct tgsi_instruction instruction;
 
    instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION;
-   instruction.NrTokens = 1;
+   instruction.NrTokens = 0;
    instruction.Opcode = TGSI_OPCODE_MOV;
    instruction.Saturate = TGSI_SAT_NONE;
+   instruction.Predicate = 0;
    instruction.NumDstRegs = 1;
    instruction.NumSrcRegs = 1;
+   instruction.Label = 0;
+   instruction.Texture = 0;
    instruction.Padding  = 0;
-   instruction.Extended = 0;
 
    return instruction;
 }
 
 struct tgsi_instruction
-tgsi_build_instruction(
-   unsigned opcode,
-   unsigned saturate,
-   unsigned num_dst_regs,
-   unsigned num_src_regs,
-   struct tgsi_header *header )
+tgsi_build_instruction(unsigned opcode,
+                       unsigned saturate,
+                       unsigned predicate,
+                       unsigned num_dst_regs,
+                       unsigned num_src_regs,
+                       struct tgsi_header *header)
 {
    struct tgsi_instruction instruction;
 
@@ -445,6 +430,7 @@
    instruction = tgsi_default_instruction();
    instruction.Opcode = opcode;
    instruction.Saturate = saturate;
+   instruction.Predicate = predicate;
    instruction.NumDstRegs = num_dst_regs;
    instruction.NumSrcRegs = num_src_regs;
 
@@ -472,18 +458,16 @@
    unsigned i;
 
    full_instruction.Instruction = tgsi_default_instruction();
-   full_instruction.InstructionExtLabel = tgsi_default_instruction_ext_label();
-   full_instruction.InstructionExtTexture = tgsi_default_instruction_ext_texture();
-   full_instruction.InstructionExtPredicate = tgsi_default_instruction_ext_predicate();
+   full_instruction.Predicate = tgsi_default_instruction_predicate();
+   full_instruction.Label = tgsi_default_instruction_label();
+   full_instruction.Texture = tgsi_default_instruction_texture();
    for( i = 0;  i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) {
-      full_instruction.FullDstRegisters[i] = tgsi_default_full_dst_register();
+      full_instruction.Dst[i] = tgsi_default_full_dst_register();
    }
    for( i = 0;  i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) {
-      full_instruction.FullSrcRegisters[i] = tgsi_default_full_src_register();
+      full_instruction.Src[i] = tgsi_default_full_src_register();
    }
 
-   full_instruction.Flags = 0x0;
-
    return full_instruction;
 }
 
@@ -504,77 +488,70 @@
    instruction = (struct tgsi_instruction *) &tokens[size];
    size++;
 
-   *instruction = tgsi_build_instruction(
-      full_inst->Instruction.Opcode,
-      full_inst->Instruction.Saturate,
-      full_inst->Instruction.NumDstRegs,
-      full_inst->Instruction.NumSrcRegs,
-      header );
+   *instruction = tgsi_build_instruction(full_inst->Instruction.Opcode,
+                                         full_inst->Instruction.Saturate,
+                                         full_inst->Instruction.Predicate,
+                                         full_inst->Instruction.NumDstRegs,
+                                         full_inst->Instruction.NumSrcRegs,
+                                         header);
    prev_token = (struct tgsi_token  *) instruction;
 
-   if( tgsi_compare_instruction_ext_label(
-         full_inst->InstructionExtLabel,
-         tgsi_default_instruction_ext_label() ) ) {
-      struct tgsi_instruction_ext_label *instruction_ext_label;
-
-      if( maxsize <= size )
-         return 0;
-      instruction_ext_label =
-         (struct  tgsi_instruction_ext_label *) &tokens[size];
-      size++;
-
-      *instruction_ext_label = tgsi_build_instruction_ext_label(
-         full_inst->InstructionExtLabel.Label,
-         prev_token,
-         instruction,
-         header );
-      prev_token = (struct tgsi_token  *) instruction_ext_label;
-   }
-
-   if( tgsi_compare_instruction_ext_texture(
-         full_inst->InstructionExtTexture,
-         tgsi_default_instruction_ext_texture() ) ) {
-      struct tgsi_instruction_ext_texture *instruction_ext_texture;
-
-      if( maxsize <= size )
-         return 0;
-      instruction_ext_texture =
-         (struct  tgsi_instruction_ext_texture *) &tokens[size];
-      size++;
-
-      *instruction_ext_texture = tgsi_build_instruction_ext_texture(
-         full_inst->InstructionExtTexture.Texture,
-         prev_token,
-         instruction,
-         header   );
-      prev_token = (struct tgsi_token  *) instruction_ext_texture;
-   }
-
-   if (tgsi_compare_instruction_ext_predicate(full_inst->InstructionExtPredicate,
-                                              tgsi_default_instruction_ext_predicate())) {
-      struct tgsi_instruction_ext_predicate *instruction_ext_predicate;
+   if (full_inst->Instruction.Predicate) {
+      struct tgsi_instruction_predicate *instruction_predicate;
 
       if (maxsize <= size) {
          return 0;
       }
-      instruction_ext_predicate = (struct tgsi_instruction_ext_predicate *)&tokens[size];
+      instruction_predicate = (struct tgsi_instruction_predicate *)&tokens[size];
       size++;
 
-      *instruction_ext_predicate =
-         tgsi_build_instruction_ext_predicate(full_inst->InstructionExtPredicate.SrcIndex,
-                                              full_inst->InstructionExtPredicate.Negate,
-                                              full_inst->InstructionExtPredicate.SwizzleX,
-                                              full_inst->InstructionExtPredicate.SwizzleY,
-                                              full_inst->InstructionExtPredicate.SwizzleZ,
-                                              full_inst->InstructionExtPredicate.SwizzleW,
-                                              prev_token,
-                                              instruction,
-                                              header);
-      prev_token = (struct tgsi_token *)instruction_ext_predicate;
+      *instruction_predicate =
+         tgsi_build_instruction_predicate(full_inst->Predicate.Index,
+                                          full_inst->Predicate.Negate,
+                                          full_inst->Predicate.SwizzleX,
+                                          full_inst->Predicate.SwizzleY,
+                                          full_inst->Predicate.SwizzleZ,
+                                          full_inst->Predicate.SwizzleW,
+                                          instruction,
+                                          header);
+   }
+
+   if (full_inst->Instruction.Label) {
+      struct tgsi_instruction_label *instruction_label;
+
+      if( maxsize <= size )
+         return 0;
+      instruction_label =
+         (struct  tgsi_instruction_label *) &tokens[size];
+      size++;
+
+      *instruction_label = tgsi_build_instruction_label(
+         full_inst->Label.Label,
+         prev_token,
+         instruction,
+         header );
+      prev_token = (struct tgsi_token  *) instruction_label;
+   }
+
+   if (full_inst->Instruction.Texture) {
+      struct tgsi_instruction_texture *instruction_texture;
+
+      if( maxsize <= size )
+         return 0;
+      instruction_texture =
+         (struct  tgsi_instruction_texture *) &tokens[size];
+      size++;
+
+      *instruction_texture = tgsi_build_instruction_texture(
+         full_inst->Texture.Texture,
+         prev_token,
+         instruction,
+         header   );
+      prev_token = (struct tgsi_token  *) instruction_texture;
    }
 
    for( i = 0;  i <   full_inst->Instruction.NumDstRegs; i++ ) {
-      const struct tgsi_full_dst_register *reg = &full_inst->FullDstRegisters[i];
+      const struct tgsi_full_dst_register *reg = &full_inst->Dst[i];
       struct tgsi_dst_register *dst_register;
       struct tgsi_token *prev_token;
 
@@ -584,34 +561,15 @@
       size++;
 
       *dst_register = tgsi_build_dst_register(
-         reg->DstRegister.File,
-         reg->DstRegister.WriteMask,
-         reg->DstRegister.Indirect,
-         reg->DstRegister.Index,
+         reg->Register.File,
+         reg->Register.WriteMask,
+         reg->Register.Indirect,
+         reg->Register.Index,
          instruction,
          header );
       prev_token = (struct tgsi_token  *) dst_register;
 
-      if( tgsi_compare_dst_register_ext_modulate(
-            reg->DstRegisterExtModulate,
-            tgsi_default_dst_register_ext_modulate() ) ) {
-         struct tgsi_dst_register_ext_modulate *dst_register_ext_modulate;
-
-         if( maxsize <= size )
-            return 0;
-         dst_register_ext_modulate =
-            (struct  tgsi_dst_register_ext_modulate *) &tokens[size];
-         size++;
-
-         *dst_register_ext_modulate = tgsi_build_dst_register_ext_modulate(
-            reg->DstRegisterExtModulate.Modulate,
-            prev_token,
-            instruction,
-            header );
-         prev_token = (struct tgsi_token  *) dst_register_ext_modulate;
-      }
-
-      if( reg->DstRegister.Indirect ) {
+      if( reg->Register.Indirect ) {
          struct tgsi_src_register *ind;
 
          if( maxsize <= size )
@@ -620,22 +578,23 @@
          size++;
 
          *ind = tgsi_build_src_register(
-            reg->DstRegisterInd.File,
-            reg->DstRegisterInd.SwizzleX,
-            reg->DstRegisterInd.SwizzleY,
-            reg->DstRegisterInd.SwizzleZ,
-            reg->DstRegisterInd.SwizzleW,
-            reg->DstRegisterInd.Negate,
-            reg->DstRegisterInd.Indirect,
-            reg->DstRegisterInd.Dimension,
-            reg->DstRegisterInd.Index,
+            reg->Indirect.File,
+            reg->Indirect.SwizzleX,
+            reg->Indirect.SwizzleY,
+            reg->Indirect.SwizzleZ,
+            reg->Indirect.SwizzleW,
+            reg->Indirect.Negate,
+            reg->Indirect.Absolute,
+            reg->Indirect.Indirect,
+            reg->Indirect.Dimension,
+            reg->Indirect.Index,
             instruction,
             header );
       }
    }
 
    for( i = 0;  i < full_inst->Instruction.NumSrcRegs; i++ ) {
-      const struct tgsi_full_src_register *reg = &full_inst->FullSrcRegisters[i];
+      const struct tgsi_full_src_register *reg = &full_inst->Src[i];
       struct tgsi_src_register *src_register;
       struct tgsi_token *prev_token;
 
@@ -645,43 +604,21 @@
       size++;
 
       *src_register = tgsi_build_src_register(
-         reg->SrcRegister.File,
-         reg->SrcRegister.SwizzleX,
-         reg->SrcRegister.SwizzleY,
-         reg->SrcRegister.SwizzleZ,
-         reg->SrcRegister.SwizzleW,
-         reg->SrcRegister.Negate,
-         reg->SrcRegister.Indirect,
-         reg->SrcRegister.Dimension,
-         reg->SrcRegister.Index,
+         reg->Register.File,
+         reg->Register.SwizzleX,
+         reg->Register.SwizzleY,
+         reg->Register.SwizzleZ,
+         reg->Register.SwizzleW,
+         reg->Register.Negate,
+         reg->Register.Absolute,
+         reg->Register.Indirect,
+         reg->Register.Dimension,
+         reg->Register.Index,
          instruction,
          header );
       prev_token = (struct tgsi_token  *) src_register;
 
-      if( tgsi_compare_src_register_ext_mod(
-            reg->SrcRegisterExtMod,
-            tgsi_default_src_register_ext_mod() ) ) {
-         struct tgsi_src_register_ext_mod *src_register_ext_mod;
-
-         if( maxsize <= size )
-            return 0;
-         src_register_ext_mod =
-            (struct  tgsi_src_register_ext_mod *) &tokens[size];
-         size++;
-
-         *src_register_ext_mod = tgsi_build_src_register_ext_mod(
-            reg->SrcRegisterExtMod.Complement,
-            reg->SrcRegisterExtMod.Bias,
-            reg->SrcRegisterExtMod.Scale2X,
-            reg->SrcRegisterExtMod.Absolute,
-            reg->SrcRegisterExtMod.Negate,
-            prev_token,
-            instruction,
-            header );
-         prev_token = (struct tgsi_token  *) src_register_ext_mod;
-      }
-
-      if( reg->SrcRegister.Indirect ) {
+      if( reg->Register.Indirect ) {
          struct  tgsi_src_register *ind;
 
          if( maxsize <= size )
@@ -690,23 +627,24 @@
          size++;
 
          *ind = tgsi_build_src_register(
-            reg->SrcRegisterInd.File,
-            reg->SrcRegisterInd.SwizzleX,
-            reg->SrcRegisterInd.SwizzleY,
-            reg->SrcRegisterInd.SwizzleZ,
-            reg->SrcRegisterInd.SwizzleW,
-            reg->SrcRegisterInd.Negate,
-            reg->SrcRegisterInd.Indirect,
-            reg->SrcRegisterInd.Dimension,
-            reg->SrcRegisterInd.Index,
+            reg->Indirect.File,
+            reg->Indirect.SwizzleX,
+            reg->Indirect.SwizzleY,
+            reg->Indirect.SwizzleZ,
+            reg->Indirect.SwizzleW,
+            reg->Indirect.Negate,
+            reg->Indirect.Absolute,
+            reg->Indirect.Indirect,
+            reg->Indirect.Dimension,
+            reg->Indirect.Index,
             instruction,
             header );
       }
 
-      if( reg->SrcRegister.Dimension ) {
+      if( reg->Register.Dimension ) {
          struct  tgsi_dimension *dim;
 
-         assert( !reg->SrcRegisterDim.Dimension );
+         assert( !reg->Dimension.Dimension );
 
          if( maxsize <= size )
             return 0;
@@ -714,12 +652,12 @@
          size++;
 
          *dim = tgsi_build_dimension(
-            reg->SrcRegisterDim.Indirect,
-            reg->SrcRegisterDim.Index,
+            reg->Dimension.Indirect,
+            reg->Dimension.Index,
             instruction,
             header );
 
-         if( reg->SrcRegisterDim.Indirect ) {
+         if( reg->Dimension.Indirect ) {
             struct tgsi_src_register *ind;
 
             if( maxsize <= size )
@@ -728,15 +666,16 @@
             size++;
 
             *ind = tgsi_build_src_register(
-               reg->SrcRegisterDimInd.File,
-               reg->SrcRegisterDimInd.SwizzleX,
-               reg->SrcRegisterDimInd.SwizzleY,
-               reg->SrcRegisterDimInd.SwizzleZ,
-               reg->SrcRegisterDimInd.SwizzleW,
-               reg->SrcRegisterDimInd.Negate,
-               reg->SrcRegisterDimInd.Indirect,
-               reg->SrcRegisterDimInd.Dimension,
-               reg->SrcRegisterDimInd.Index,
+               reg->DimIndirect.File,
+               reg->DimIndirect.SwizzleX,
+               reg->DimIndirect.SwizzleY,
+               reg->DimIndirect.SwizzleZ,
+               reg->DimIndirect.SwizzleW,
+               reg->DimIndirect.Negate,
+               reg->DimIndirect.Absolute,
+               reg->DimIndirect.Indirect,
+               reg->DimIndirect.Dimension,
+               reg->DimIndirect.Index,
                instruction,
                header );
          }
@@ -746,147 +685,103 @@
    return size;
 }
 
-/** test for inequality of 32-bit values pointed to by a and b */
-static INLINE boolean
-compare32(const void *a, const void *b)
+struct tgsi_instruction_predicate
+tgsi_default_instruction_predicate(void)
 {
-   return *((uint32_t *) a) != *((uint32_t *) b);
+   struct tgsi_instruction_predicate instruction_predicate;
+
+   instruction_predicate.SwizzleX = TGSI_SWIZZLE_X;
+   instruction_predicate.SwizzleY = TGSI_SWIZZLE_Y;
+   instruction_predicate.SwizzleZ = TGSI_SWIZZLE_Z;
+   instruction_predicate.SwizzleW = TGSI_SWIZZLE_W;
+   instruction_predicate.Negate = 0;
+   instruction_predicate.Index = 0;
+   instruction_predicate.Padding = 0;
+
+   return instruction_predicate;
 }
 
-struct tgsi_instruction_ext_label
-tgsi_default_instruction_ext_label( void )
+struct tgsi_instruction_predicate
+tgsi_build_instruction_predicate(int index,
+                                 unsigned negate,
+                                 unsigned swizzleX,
+                                 unsigned swizzleY,
+                                 unsigned swizzleZ,
+                                 unsigned swizzleW,
+                                 struct tgsi_instruction *instruction,
+                                 struct tgsi_header *header)
 {
-   struct tgsi_instruction_ext_label instruction_ext_label;
+   struct tgsi_instruction_predicate instruction_predicate;
 
-   instruction_ext_label.Type = TGSI_INSTRUCTION_EXT_TYPE_LABEL;
-   instruction_ext_label.Label = 0;
-   instruction_ext_label.Padding = 0;
-   instruction_ext_label.Extended = 0;
+   instruction_predicate = tgsi_default_instruction_predicate();
+   instruction_predicate.SwizzleX = swizzleX;
+   instruction_predicate.SwizzleY = swizzleY;
+   instruction_predicate.SwizzleZ = swizzleZ;
+   instruction_predicate.SwizzleW = swizzleW;
+   instruction_predicate.Negate = negate;
+   instruction_predicate.Index = index;
 
-   return instruction_ext_label;
+   instruction_grow(instruction, header);
+
+   return instruction_predicate;
 }
 
-unsigned
-tgsi_compare_instruction_ext_label(
-   struct tgsi_instruction_ext_label a,
-   struct tgsi_instruction_ext_label b )
+struct tgsi_instruction_label
+tgsi_default_instruction_label( void )
 {
-   a.Padding = b.Padding = 0;
-   a.Extended = b.Extended = 0;
-   return compare32(&a, &b);
+   struct tgsi_instruction_label instruction_label;
+
+   instruction_label.Label = 0;
+   instruction_label.Padding = 0;
+
+   return instruction_label;
 }
 
-struct tgsi_instruction_ext_label
-tgsi_build_instruction_ext_label(
+struct tgsi_instruction_label
+tgsi_build_instruction_label(
    unsigned label,
    struct tgsi_token  *prev_token,
    struct tgsi_instruction *instruction,
    struct tgsi_header *header )
 {
-   struct tgsi_instruction_ext_label instruction_ext_label;
+   struct tgsi_instruction_label instruction_label;
 
-   instruction_ext_label = tgsi_default_instruction_ext_label();
-   instruction_ext_label.Label = label;
+   instruction_label = tgsi_default_instruction_label();
+   instruction_label.Label = label;
+   instruction->Label = 1;
 
-   prev_token->Extended = 1;
    instruction_grow( instruction, header );
 
-   return instruction_ext_label;
+   return instruction_label;
 }
 
-struct tgsi_instruction_ext_texture
-tgsi_default_instruction_ext_texture( void )
+struct tgsi_instruction_texture
+tgsi_default_instruction_texture( void )
 {
-   struct tgsi_instruction_ext_texture instruction_ext_texture;
+   struct tgsi_instruction_texture instruction_texture;
 
-   instruction_ext_texture.Type = TGSI_INSTRUCTION_EXT_TYPE_TEXTURE;
-   instruction_ext_texture.Texture = TGSI_TEXTURE_UNKNOWN;
-   instruction_ext_texture.Padding = 0;
-   instruction_ext_texture.Extended = 0;
+   instruction_texture.Texture = TGSI_TEXTURE_UNKNOWN;
+   instruction_texture.Padding = 0;
 
-   return instruction_ext_texture;
+   return instruction_texture;
 }
 
-unsigned
-tgsi_compare_instruction_ext_texture(
-   struct tgsi_instruction_ext_texture a,
-   struct tgsi_instruction_ext_texture b )
-{
-   a.Padding = b.Padding = 0;
-   a.Extended = b.Extended = 0;
-   return compare32(&a, &b);
-}
-
-struct tgsi_instruction_ext_texture
-tgsi_build_instruction_ext_texture(
+struct tgsi_instruction_texture
+tgsi_build_instruction_texture(
    unsigned texture,
    struct tgsi_token *prev_token,
    struct tgsi_instruction *instruction,
    struct tgsi_header *header )
 {
-   struct tgsi_instruction_ext_texture instruction_ext_texture;
+   struct tgsi_instruction_texture instruction_texture;
 
-   instruction_ext_texture = tgsi_default_instruction_ext_texture();
-   instruction_ext_texture.Texture = texture;
+   instruction_texture = tgsi_default_instruction_texture();
+   instruction_texture.Texture = texture;
+   instruction->Texture = 1;
 
-   prev_token->Extended = 1;
    instruction_grow( instruction, header );
 
-   return instruction_ext_texture;
-}
-
-struct tgsi_instruction_ext_predicate
-tgsi_default_instruction_ext_predicate(void)
-{
-   struct tgsi_instruction_ext_predicate instruction_ext_predicate;
-
-   instruction_ext_predicate.Type = TGSI_INSTRUCTION_EXT_TYPE_PREDICATE;
-   instruction_ext_predicate.SwizzleX = TGSI_SWIZZLE_X;
-   instruction_ext_predicate.SwizzleY = TGSI_SWIZZLE_Y;
-   instruction_ext_predicate.SwizzleZ = TGSI_SWIZZLE_Z;
-   instruction_ext_predicate.SwizzleW = TGSI_SWIZZLE_W;
-   instruction_ext_predicate.Negate = 0;
-   instruction_ext_predicate.SrcIndex = 0;
-   instruction_ext_predicate.Padding = 0;
-   instruction_ext_predicate.Extended = 0;
-
-   return instruction_ext_predicate;
-}
-
-unsigned
-tgsi_compare_instruction_ext_predicate(struct tgsi_instruction_ext_predicate a,
-                                       struct tgsi_instruction_ext_predicate b)
-{
-   a.Padding = b.Padding = 0;
-   a.Extended = b.Extended = 0;
-   return compare32(&a, &b);
-}
-
-struct tgsi_instruction_ext_predicate
-tgsi_build_instruction_ext_predicate(unsigned index,
-                                     unsigned negate,
-                                     unsigned swizzleX,
-                                     unsigned swizzleY,
-                                     unsigned swizzleZ,
-                                     unsigned swizzleW,
-                                     struct tgsi_token *prev_token,
-                                     struct tgsi_instruction *instruction,
-                                     struct tgsi_header *header)
-{
-   struct tgsi_instruction_ext_predicate instruction_ext_predicate;
-
-   instruction_ext_predicate = tgsi_default_instruction_ext_predicate();
-   instruction_ext_predicate.SwizzleX = swizzleX;
-   instruction_ext_predicate.SwizzleY = swizzleY;
-   instruction_ext_predicate.SwizzleZ = swizzleZ;
-   instruction_ext_predicate.SwizzleW = swizzleW;
-   instruction_ext_predicate.Negate = negate;
-   instruction_ext_predicate.SrcIndex = index;
-
-   prev_token->Extended = 1;
-   instruction_grow(instruction, header);
-
-   return instruction_ext_predicate;
+   return instruction_texture;
 }
 
 struct tgsi_src_register
@@ -900,10 +795,10 @@
    src_register.SwizzleZ = TGSI_SWIZZLE_Z;
    src_register.SwizzleW = TGSI_SWIZZLE_W;
    src_register.Negate = 0;
+   src_register.Absolute = 0;
    src_register.Indirect = 0;
    src_register.Dimension = 0;
    src_register.Index = 0;
-   src_register.Extended = 0;
 
    return src_register;
 }
@@ -916,6 +811,7 @@
    unsigned swizzle_z,
    unsigned swizzle_w,
    unsigned negate,
+   unsigned absolute,
    unsigned indirect,
    unsigned dimension,
    int index,
@@ -939,6 +835,7 @@
    src_register.SwizzleZ = swizzle_z;
    src_register.SwizzleW = swizzle_w;
    src_register.Negate = negate;
+   src_register.Absolute = absolute;
    src_register.Indirect = indirect;
    src_register.Dimension = dimension;
    src_register.Index = index;
@@ -953,75 +850,15 @@
 {
    struct tgsi_full_src_register full_src_register;
 
-   full_src_register.SrcRegister = tgsi_default_src_register();
-   full_src_register.SrcRegisterExtMod = tgsi_default_src_register_ext_mod();
-   full_src_register.SrcRegisterInd = tgsi_default_src_register();
-   full_src_register.SrcRegisterDim = tgsi_default_dimension();
-   full_src_register.SrcRegisterDimInd = tgsi_default_src_register();
+   full_src_register.Register = tgsi_default_src_register();
+   full_src_register.Indirect = tgsi_default_src_register();
+   full_src_register.Dimension = tgsi_default_dimension();
+   full_src_register.DimIndirect = tgsi_default_src_register();
 
    return full_src_register;
 }
 
 
-struct tgsi_src_register_ext_mod
-tgsi_default_src_register_ext_mod( void )
-{
-   struct tgsi_src_register_ext_mod src_register_ext_mod;
-
-   src_register_ext_mod.Type = TGSI_SRC_REGISTER_EXT_TYPE_MOD;
-   src_register_ext_mod.Complement = 0;
-   src_register_ext_mod.Bias = 0;
-   src_register_ext_mod.Scale2X = 0;
-   src_register_ext_mod.Absolute = 0;
-   src_register_ext_mod.Negate = 0;
-   src_register_ext_mod.Padding = 0;
-   src_register_ext_mod.Extended = 0;
-
-   return src_register_ext_mod;
-}
-
-unsigned
-tgsi_compare_src_register_ext_mod(
-   struct tgsi_src_register_ext_mod a,
-   struct tgsi_src_register_ext_mod b )
-{
-   a.Padding = b.Padding = 0;
-   a.Extended = b.Extended = 0;
-   return compare32(&a, &b);
-}
-
-struct tgsi_src_register_ext_mod
-tgsi_build_src_register_ext_mod(
-   unsigned complement,
-   unsigned bias,
-   unsigned scale_2x,
-   unsigned absolute,
-   unsigned negate,
-   struct tgsi_token *prev_token,
-   struct tgsi_instruction *instruction,
-   struct tgsi_header *header )
-{
-   struct tgsi_src_register_ext_mod src_register_ext_mod;
-
-   assert( complement <= 1 );
-   assert( bias <= 1 );
-   assert( scale_2x <= 1 );
-   assert( absolute <= 1 );
-   assert( negate <= 1 );
-
-   src_register_ext_mod = tgsi_default_src_register_ext_mod();
-   src_register_ext_mod.Complement = complement;
-   src_register_ext_mod.Bias = bias;
-   src_register_ext_mod.Scale2X = scale_2x;
-   src_register_ext_mod.Absolute = absolute;
-   src_register_ext_mod.Negate = negate;
-
-   prev_token->Extended = 1;
-   instruction_grow( instruction, header );
-
-   return src_register_ext_mod;
-}
-
 struct tgsi_dimension
 tgsi_default_dimension( void )
 {
@@ -1031,7 +868,6 @@
    dimension.Dimension = 0;
    dimension.Padding = 0;
    dimension.Index = 0;
-   dimension.Extended = 0;
 
    return dimension;
 }
@@ -1065,7 +901,6 @@
    dst_register.Dimension = 0;
    dst_register.Index = 0;
    dst_register.Padding = 0;
-   dst_register.Extended = 0;
 
    return dst_register;
 }
@@ -1101,53 +936,113 @@
 {
    struct tgsi_full_dst_register full_dst_register;
 
-   full_dst_register.DstRegister = tgsi_default_dst_register();
-   full_dst_register.DstRegisterInd = tgsi_default_src_register();
-   full_dst_register.DstRegisterExtModulate =
-      tgsi_default_dst_register_ext_modulate();
+   full_dst_register.Register = tgsi_default_dst_register();
+   full_dst_register.Indirect = tgsi_default_src_register();
 
    return full_dst_register;
 }
 
-struct tgsi_dst_register_ext_modulate
-tgsi_default_dst_register_ext_modulate( void )
+struct tgsi_property
+tgsi_default_property( void )
 {
-   struct tgsi_dst_register_ext_modulate dst_register_ext_modulate;
+   struct tgsi_property property;
 
-   dst_register_ext_modulate.Type = TGSI_DST_REGISTER_EXT_TYPE_MODULATE;
-   dst_register_ext_modulate.Modulate = TGSI_MODULATE_1X;
-   dst_register_ext_modulate.Padding = 0;
-   dst_register_ext_modulate.Extended = 0;
+   property.Type = TGSI_TOKEN_TYPE_PROPERTY;
+   property.NrTokens = 1;
+   property.PropertyName = TGSI_PROPERTY_GS_INPUT_PRIM;
+   property.Padding = 0;
 
-   return dst_register_ext_modulate;
+   return property;
+}
+
+struct tgsi_property
+tgsi_build_property(unsigned property_name,
+                    struct tgsi_header *header)
+{
+   struct tgsi_property property;
+
+   property = tgsi_default_property();
+   property.PropertyName = property_name;
+
+   header_bodysize_grow( header );
+
+   return property;
+}
+
+
+struct tgsi_full_property
+tgsi_default_full_property( void )
+{
+   struct tgsi_full_property  full_property;
+
+   full_property.Property  = tgsi_default_property();
+   memset(full_property.u, 0,
+          sizeof(struct tgsi_property_data) * 8);
+
+   return full_property;
+}
+
+static void
+property_grow(
+   struct tgsi_property *property,
+   struct tgsi_header *header )
+{
+   assert( property->NrTokens < 0xFF );
+
+   property->NrTokens++;
+
+   header_bodysize_grow( header );
+}
+
+struct tgsi_property_data
+tgsi_build_property_data(
+   unsigned value,
+   struct tgsi_property *property,
+   struct tgsi_header *header )
+{
+   struct tgsi_property_data property_data;
+
+   property_data.Data = value;
+
+   property_grow( property, header );
+
+   return property_data;
 }
 
 unsigned
-tgsi_compare_dst_register_ext_modulate(
-   struct tgsi_dst_register_ext_modulate a,
-   struct tgsi_dst_register_ext_modulate b )
+tgsi_build_full_property(
+   const struct tgsi_full_property *full_prop,
+   struct tgsi_token *tokens,
+   struct tgsi_header *header,
+   unsigned maxsize )
 {
-   a.Padding = b.Padding = 0;
-   a.Extended = b.Extended = 0;
-   return compare32(&a, &b);
-}
+   unsigned size = 0, i;
+   struct tgsi_property *property;
 
-struct tgsi_dst_register_ext_modulate
-tgsi_build_dst_register_ext_modulate(
-   unsigned modulate,
-   struct tgsi_token *prev_token,
-   struct tgsi_instruction *instruction,
-   struct tgsi_header *header )
-{
-   struct tgsi_dst_register_ext_modulate dst_register_ext_modulate;
+   if( maxsize <= size )
+      return 0;
+   property = (struct tgsi_property *) &tokens[size];
+   size++;
 
-   assert( modulate <= TGSI_MODULATE_EIGHTH );
+   *property = tgsi_build_property(
+      full_prop->Property.PropertyName,
+      header );
 
-   dst_register_ext_modulate = tgsi_default_dst_register_ext_modulate();
-   dst_register_ext_modulate.Modulate = modulate;
+   assert( full_prop->Property.NrTokens <= 8 + 1 );
 
-   prev_token->Extended = 1;
-   instruction_grow( instruction, header );
+   for( i = 0; i < full_prop->Property.NrTokens - 1; i++ ) {
+      struct tgsi_property_data *data;
 
-   return dst_register_ext_modulate;
+      if( maxsize <= size )
+         return  0;
+      data = (struct tgsi_property_data *) &tokens[size];
+      size++;
+
+      *data = tgsi_build_property_data(
+         full_prop->u[i].Data,
+         property,
+         header );
+   }
+
+   return size;
 }
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.h b/src/gallium/auxiliary/tgsi/tgsi_build.h
index 669712e..9de2757 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.h
@@ -36,12 +36,6 @@
 extern "C" {
 #endif
 
-/*
- * version
- */
-
-struct tgsi_version
-tgsi_build_version( void );
 
 /*
  * header
@@ -133,6 +127,34 @@
    unsigned maxsize );
 
 /*
+ * properties
+ */
+
+struct tgsi_property
+tgsi_default_property( void );
+
+struct tgsi_property
+tgsi_build_property(
+   unsigned property_name,
+   struct tgsi_header *header );
+
+struct tgsi_full_property
+tgsi_default_full_property( void );
+
+struct tgsi_property_data
+tgsi_build_property_data(
+   unsigned value,
+   struct tgsi_property *property,
+   struct tgsi_header *header );
+
+unsigned
+tgsi_build_full_property(
+   const struct tgsi_full_property *full_prop,
+   struct tgsi_token *tokens,
+   struct tgsi_header *header,
+   unsigned maxsize );
+
+/*
  * instruction
  */
 
@@ -143,6 +165,7 @@
 tgsi_build_instruction(
    unsigned opcode,
    unsigned saturate,
+   unsigned predicate,
    unsigned num_dst_regs,
    unsigned num_src_regs,
    struct tgsi_header *header );
@@ -157,54 +180,39 @@
    struct tgsi_header *header,
    unsigned maxsize );
 
-struct tgsi_instruction_ext_label
-tgsi_default_instruction_ext_label( void );
+struct tgsi_instruction_predicate
+tgsi_default_instruction_predicate(void);
 
-unsigned
-tgsi_compare_instruction_ext_label(
-   struct tgsi_instruction_ext_label a,
-   struct tgsi_instruction_ext_label b );
+struct tgsi_instruction_predicate
+tgsi_build_instruction_predicate(int index,
+                                 unsigned negate,
+                                 unsigned swizzleX,
+                                 unsigned swizzleY,
+                                 unsigned swizzleZ,
+                                 unsigned swizzleW,
+                                 struct tgsi_instruction *instruction,
+                                 struct tgsi_header *header);
 
-struct tgsi_instruction_ext_label
-tgsi_build_instruction_ext_label(
+struct tgsi_instruction_label
+tgsi_default_instruction_label( void );
+
+struct tgsi_instruction_label
+tgsi_build_instruction_label(
    unsigned label,
    struct tgsi_token *prev_token,
    struct tgsi_instruction *instruction,
    struct tgsi_header *header );
 
-struct tgsi_instruction_ext_texture
-tgsi_default_instruction_ext_texture( void );
+struct tgsi_instruction_texture
+tgsi_default_instruction_texture( void );
 
-unsigned
-tgsi_compare_instruction_ext_texture(
-   struct tgsi_instruction_ext_texture a,
-   struct tgsi_instruction_ext_texture b );
-
-struct tgsi_instruction_ext_texture
-tgsi_build_instruction_ext_texture(
+struct tgsi_instruction_texture
+tgsi_build_instruction_texture(
    unsigned texture,
    struct tgsi_token *prev_token,
    struct tgsi_instruction *instruction,
    struct tgsi_header *header );
 
-struct tgsi_instruction_ext_predicate
-tgsi_default_instruction_ext_predicate(void);
-
-unsigned
-tgsi_compare_instruction_ext_predicate(struct tgsi_instruction_ext_predicate a,
-                                       struct tgsi_instruction_ext_predicate b);
-
-struct tgsi_instruction_ext_predicate
-tgsi_build_instruction_ext_predicate(unsigned index,
-                                     unsigned negate,
-                                     unsigned swizzleX,
-                                     unsigned swizzleY,
-                                     unsigned swizzleZ,
-                                     unsigned swizzleW,
-                                     struct tgsi_token *prev_token,
-                                     struct tgsi_instruction *instruction,
-                                     struct tgsi_header *header);
-
 struct tgsi_src_register
 tgsi_default_src_register( void );
 
@@ -216,6 +224,7 @@
    unsigned swizzle_z,
    unsigned swizzle_w,
    unsigned negate,
+   unsigned absolute,
    unsigned indirect,
    unsigned dimension,
    int index,
@@ -225,24 +234,6 @@
 struct tgsi_full_src_register
 tgsi_default_full_src_register( void );
 
-struct tgsi_src_register_ext_mod
-tgsi_default_src_register_ext_mod( void );
-
-unsigned
-tgsi_compare_src_register_ext_mod(
-   struct tgsi_src_register_ext_mod a,
-   struct tgsi_src_register_ext_mod b );
-
-struct tgsi_src_register_ext_mod
-tgsi_build_src_register_ext_mod(
-   unsigned complement,
-   unsigned bias,
-   unsigned scale_2x,
-   unsigned absolute,
-   unsigned negate,
-   struct tgsi_token *prev_token,
-   struct tgsi_instruction *instruction,
-   struct tgsi_header *header );
 
 struct tgsi_dimension
 tgsi_default_dimension( void );
@@ -269,20 +260,6 @@
 struct tgsi_full_dst_register
 tgsi_default_full_dst_register( void );
 
-struct tgsi_dst_register_ext_modulate
-tgsi_default_dst_register_ext_modulate( void );
-
-unsigned
-tgsi_compare_dst_register_ext_modulate(
-   struct tgsi_dst_register_ext_modulate a,
-   struct tgsi_dst_register_ext_modulate b );
-
-struct tgsi_dst_register_ext_modulate
-tgsi_build_dst_register_ext_modulate(
-   unsigned modulate,
-   struct tgsi_token *prev_token,
-   struct tgsi_instruction *instruction,
-   struct tgsi_header *header );
 
 #if defined __cplusplus
 }
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index d16e64f..e2e5394 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -101,7 +101,8 @@
    "ADDR",
    "IMM",
    "LOOP",
-   "PRED"
+   "PRED",
+   "SV"
 };
 
 static const char *interpolate_names[] =
@@ -120,12 +121,16 @@
    "PSIZE",
    "GENERIC",
    "NORMAL",
-   "FACE"
+   "FACE",
+   "EDGEFLAG",
+   "PRIM_ID"
 };
 
 static const char *immediate_type_names[] =
 {
-   "FLT32"
+   "FLT32",
+   "UINT32",
+   "INT32"
 };
 
 static const char *swizzle_names[] =
@@ -149,26 +154,42 @@
    "SHADOWRECT"
 };
 
-
-static const char *modulate_names[TGSI_MODULATE_COUNT] =
+static const char *property_names[] =
 {
-   "",
-   "_2X",
-   "_4X",
-   "_8X",
-   "_D2",
-   "_D4",
-   "_D8"
+   "GS_INPUT_PRIMITIVE",
+   "GS_OUTPUT_PRIMITIVE",
+   "GS_MAX_OUTPUT_VERTICES"
 };
 
+static const char *primitive_names[] =
+{
+   "POINTS",
+   "LINES",
+   "LINE_LOOP",
+   "LINE_STRIP",
+   "TRIANGLES",
+   "TRIANGLE_STRIP",
+   "TRIANGLE_FAN",
+   "QUADS",
+   "QUAD_STRIP",
+   "POLYGON"
+};
+
+
 static void
-_dump_register(
+_dump_register_decl(
    struct dump_ctx *ctx,
    uint file,
    int first,
    int last )
 {
    ENM( file, file_names );
+
+   /* all geometry shader inputs are two dimensional */
+   if (file == TGSI_FILE_INPUT &&
+       ctx->iter.processor.Processor == TGSI_PROCESSOR_GEOMETRY)
+      TXT("[]");
+
    CHR( '[' );
    SID( first );
    if (first != last) {
@@ -179,6 +200,52 @@
 }
 
 static void
+_dump_register_dst(
+   struct dump_ctx *ctx,
+   uint file,
+   int index)
+{
+   ENM( file, file_names );
+
+   CHR( '[' );
+   SID( index );
+   CHR( ']' );
+}
+
+
+static void
+_dump_register_src(
+   struct dump_ctx *ctx,
+   const struct tgsi_full_src_register *src )
+{
+   if (src->Register.Indirect) {
+      ENM( src->Register.File, file_names );
+      CHR( '[' );
+      ENM( src->Indirect.File, file_names );
+      CHR( '[' );
+      SID( src->Indirect.Index );
+      TXT( "]." );
+      ENM( src->Indirect.SwizzleX, swizzle_names );
+      if (src->Register.Index != 0) {
+         if (src->Register.Index > 0)
+            CHR( '+' );
+         SID( src->Register.Index );
+      }
+      CHR( ']' );
+   } else {
+      ENM( src->Register.File, file_names );
+      CHR( '[' );
+      SID( src->Register.Index );
+      CHR( ']' );
+   }
+   if (src->Register.Dimension) {
+      CHR( '[' );
+      SID( src->Dimension.Index );
+      CHR( ']' );
+   }
+}
+
+static void
 _dump_register_ind(
    struct dump_ctx *ctx,
    uint file,
@@ -232,22 +299,22 @@
 
    TXT( "DCL " );
 
-   _dump_register(
+   _dump_register_decl(
       ctx,
       decl->Declaration.File,
-      decl->DeclarationRange.First,
-      decl->DeclarationRange.Last );
+      decl->Range.First,
+      decl->Range.Last );
    _dump_writemask(
       ctx,
       decl->Declaration.UsageMask );
 
    if (decl->Declaration.Semantic) {
       TXT( ", " );
-      ENM( decl->Semantic.SemanticName, semantic_names );
-      if (decl->Semantic.SemanticIndex != 0 ||
-          decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC) {
+      ENM( decl->Semantic.Name, semantic_names );
+      if (decl->Semantic.Index != 0 ||
+          decl->Semantic.Name == TGSI_SEMANTIC_GENERIC) {
          CHR( '[' );
-         UID( decl->Semantic.SemanticIndex );
+         UID( decl->Semantic.Index );
          CHR( ']' );
       }
    }
@@ -284,6 +351,50 @@
 }
 
 static boolean
+iter_property(
+   struct tgsi_iterate_context *iter,
+   struct tgsi_full_property *prop )
+{
+   int i;
+   struct dump_ctx *ctx = (struct dump_ctx *)iter;
+
+   assert(Elements(property_names) == TGSI_PROPERTY_COUNT);
+
+   TXT( "PROPERTY " );
+   ENM(prop->Property.PropertyName, property_names);
+
+   if (prop->Property.NrTokens > 1)
+      TXT(" ");
+
+   for (i = 0; i < prop->Property.NrTokens - 1; ++i) {
+      switch (prop->Property.PropertyName) {
+      case TGSI_PROPERTY_GS_INPUT_PRIM:
+      case TGSI_PROPERTY_GS_OUTPUT_PRIM:
+         ENM(prop->u[i].Data, primitive_names);
+         break;
+      default:
+         SID( prop->u[i].Data );
+         break;
+      }
+      if (i < prop->Property.NrTokens - 2)
+         TXT( ", " );
+   }
+   EOL();
+
+   return TRUE;
+}
+
+void tgsi_dump_property(
+   const struct tgsi_full_property *prop )
+{
+   struct dump_ctx ctx;
+
+   ctx.printf = dump_ctx_printf;
+
+   iter_property( &ctx.iter, (struct tgsi_full_property *)prop );
+}
+
+static boolean
 iter_immediate(
    struct tgsi_iterate_context *iter,
    struct tgsi_full_immediate *imm )
@@ -303,6 +414,12 @@
       case TGSI_IMM_FLOAT32:
          FLT( imm->u[i].Float );
          break;
+      case TGSI_IMM_UINT32:
+         UID(imm->u[i].Uint);
+         break;
+      case TGSI_IMM_INT32:
+         SID(imm->u[i].Int);
+         break;
       default:
          assert( 0 );
       }
@@ -363,99 +480,66 @@
    }
 
    for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
-      const struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
+      const struct tgsi_full_dst_register *dst = &inst->Dst[i];
 
       if (!first_reg)
          CHR( ',' );
       CHR( ' ' );
 
-      if (dst->DstRegister.Indirect) {
+      if (dst->Register.Indirect) {
          _dump_register_ind(
             ctx,
-            dst->DstRegister.File,
-            dst->DstRegister.Index,
-            dst->DstRegisterInd.File,
-            dst->DstRegisterInd.Index,
-            dst->DstRegisterInd.SwizzleX );
+            dst->Register.File,
+            dst->Register.Index,
+            dst->Indirect.File,
+            dst->Indirect.Index,
+            dst->Indirect.SwizzleX );
       }
       else {
-         _dump_register(
+         _dump_register_dst(
             ctx,
-            dst->DstRegister.File,
-            dst->DstRegister.Index,
-            dst->DstRegister.Index );
+            dst->Register.File,
+            dst->Register.Index );
       }
-      ENM( dst->DstRegisterExtModulate.Modulate, modulate_names );
-      _dump_writemask( ctx, dst->DstRegister.WriteMask );
+      _dump_writemask( ctx, dst->Register.WriteMask );
 
       first_reg = FALSE;
    }
 
    for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
-      const struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i];
+      const struct tgsi_full_src_register *src = &inst->Src[i];
 
       if (!first_reg)
          CHR( ',' );
       CHR( ' ' );
 
-      if (src->SrcRegisterExtMod.Negate)
-         TXT( "-(" );
-      if (src->SrcRegisterExtMod.Absolute)
-         CHR( '|' );
-      if (src->SrcRegisterExtMod.Scale2X)
-         TXT( "2*(" );
-      if (src->SrcRegisterExtMod.Bias)
-         CHR( '(' );
-      if (src->SrcRegisterExtMod.Complement)
-         TXT( "1-(" );
-      if (src->SrcRegister.Negate)
+      if (src->Register.Negate)
          CHR( '-' );
-
-      if (src->SrcRegister.Indirect) {
-         _dump_register_ind(
-            ctx,
-            src->SrcRegister.File,
-            src->SrcRegister.Index,
-            src->SrcRegisterInd.File,
-            src->SrcRegisterInd.Index,
-            src->SrcRegisterInd.SwizzleX );
-      }
-      else {
-         _dump_register(
-            ctx,
-            src->SrcRegister.File,
-            src->SrcRegister.Index,
-            src->SrcRegister.Index );
-      }
-
-      if (src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X ||
-          src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y ||
-          src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z ||
-          src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W) {
-         CHR( '.' );
-         ENM( src->SrcRegister.SwizzleX, swizzle_names );
-         ENM( src->SrcRegister.SwizzleY, swizzle_names );
-         ENM( src->SrcRegister.SwizzleZ, swizzle_names );
-         ENM( src->SrcRegister.SwizzleW, swizzle_names );
-      }
-
-      if (src->SrcRegisterExtMod.Complement)
-         CHR( ')' );
-      if (src->SrcRegisterExtMod.Bias)
-         TXT( ")-.5" );
-      if (src->SrcRegisterExtMod.Scale2X)
-         CHR( ')' );
-      if (src->SrcRegisterExtMod.Absolute)
+      if (src->Register.Absolute)
          CHR( '|' );
-      if (src->SrcRegisterExtMod.Negate)
-         CHR( ')' );
+
+      _dump_register_src(ctx, src);
+
+      if (src->Register.SwizzleX != TGSI_SWIZZLE_X ||
+          src->Register.SwizzleY != TGSI_SWIZZLE_Y ||
+          src->Register.SwizzleZ != TGSI_SWIZZLE_Z ||
+          src->Register.SwizzleW != TGSI_SWIZZLE_W) {
+         CHR( '.' );
+         ENM( src->Register.SwizzleX, swizzle_names );
+         ENM( src->Register.SwizzleY, swizzle_names );
+         ENM( src->Register.SwizzleZ, swizzle_names );
+         ENM( src->Register.SwizzleW, swizzle_names );
+      }
+
+      if (src->Register.Absolute)
+         CHR( '|' );
 
       first_reg = FALSE;
    }
 
-   if (inst->InstructionExtTexture.Texture != TGSI_TEXTURE_UNKNOWN) {
+   if (inst->Instruction.Texture) {
       TXT( ", " );
-      ENM( inst->InstructionExtTexture.Texture, texture_names );
+      ENM( inst->Texture.Texture, texture_names );
    }
 
    switch (inst->Instruction.Opcode) {
@@ -465,7 +549,7 @@
    case TGSI_OPCODE_ENDLOOP:
    case TGSI_OPCODE_CAL:
       TXT( " :" );
-      UID( inst->InstructionExtLabel.Label );
+      UID( inst->Label.Label );
       break;
    }
 
@@ -503,9 +587,6 @@
 {
    struct dump_ctx *ctx = (struct dump_ctx *) iter;
    ENM( iter->processor.Processor, processor_type_names );
-   UID( iter->version.MajorVersion );
-   CHR( '.' );
-   UID( iter->version.MinorVersion );
    EOL();
    return TRUE;
 }
@@ -521,6 +602,7 @@
    ctx.iter.iterate_instruction = iter_instruction;
    ctx.iter.iterate_declaration = iter_declaration;
    ctx.iter.iterate_immediate = iter_immediate;
+   ctx.iter.iterate_property = iter_property;
    ctx.iter.epilog = NULL;
 
    ctx.instno = 0;
@@ -575,6 +657,7 @@
    ctx.base.iter.iterate_instruction = iter_instruction;
    ctx.base.iter.iterate_declaration = iter_declaration;
    ctx.base.iter.iterate_immediate = iter_immediate;
+   ctx.base.iter.iterate_property = iter_property;
    ctx.base.iter.epilog = NULL;
 
    ctx.base.instno = 0;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.h b/src/gallium/auxiliary/tgsi/tgsi_dump.h
index ad1e647..4cd2731 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.h
@@ -49,6 +49,7 @@
 struct tgsi_full_immediate;
 struct tgsi_full_instruction;
 struct tgsi_full_declaration;
+struct tgsi_full_property;
 
 void
 tgsi_dump_immediate(
@@ -63,6 +64,10 @@
 tgsi_dump_declaration(
    const struct tgsi_full_declaration *decl );
 
+void
+tgsi_dump_property(
+   const struct tgsi_full_property *prop );
+
 #if defined __cplusplus
 }
 #endif
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump_c.c b/src/gallium/auxiliary/tgsi/tgsi_dump_c.c
index 4648051..47fd1dd 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump_c.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump_c.c
@@ -113,13 +113,6 @@
    "SAT_MINUS_PLUS_ONE"
 };
 
-static const char *TGSI_INSTRUCTION_EXTS[] =
-{
-   "",
-   "INSTRUCTION_EXT_TYPE_LABEL",
-   "INSTRUCTION_EXT_TYPE_TEXTURE"
-};
-
 static const char *TGSI_SWIZZLES[] =
 {
    "SWIZZLE_X",
@@ -141,12 +134,6 @@
    "TEXTURE_SHADOWRECT"
 };
 
-static const char *TGSI_SRC_REGISTER_EXTS[] =
-{
-   "",
-   "SRC_REGISTER_EXT_TYPE_MOD"
-};
-
 static const char *TGSI_WRITEMASKS[] =
 {
    "0",
@@ -167,23 +154,6 @@
    "WRITEMASK_XYZW"
 };
 
-static const char *TGSI_DST_REGISTER_EXTS[] =
-{
-   "",
-   "DST_REGISTER_EXT_TYPE_MODULATE"
-};
-
-static const char *TGSI_MODULATES[] =
-{
-   "MODULATE_1X",
-   "MODULATE_2X",
-   "MODULATE_4X",
-   "MODULATE_8X",
-   "MODULATE_HALF",
-   "MODULATE_QUARTER",
-   "MODULATE_EIGHTH"
-};
-
 static void
 dump_declaration_verbose(
    struct tgsi_full_declaration  *decl,
@@ -216,6 +186,14 @@
       TXT( "\nSemantic   : " );
       UID( decl->Declaration.Semantic );
    }
+   if (deflt || fd->Declaration.Centroid != decl->Declaration.Centroid) {
+      TXT("\nCentroid   : ");
+      UID(decl->Declaration.Centroid);
+   }
+   if (deflt || fd->Declaration.Invariant != decl->Declaration.Invariant) {
+      TXT("\nInvariant  : ");
+      UID(decl->Declaration.Invariant);
+   }
    if( ignored ) {
       TXT( "\nPadding    : " );
       UIX( decl->Declaration.Padding );
@@ -223,16 +201,16 @@
 
    EOL();
    TXT( "\nFirst: " );
-   UID( decl->DeclarationRange.First );
+   UID( decl->Range.First );
    TXT( "\nLast : " );
-   UID( decl->DeclarationRange.Last );
+   UID( decl->Range.Last );
 
    if( decl->Declaration.Semantic ) {
       EOL();
-      TXT( "\nSemanticName : " );
-      ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS );
-      TXT( "\nSemanticIndex: " );
-      UID( decl->Semantic.SemanticIndex );
+      TXT( "\nName : " );
+      ENM( decl->Semantic.Name, TGSI_SEMANTICS );
+      TXT( "\nIndex: " );
+      UID( decl->Semantic.Index );
       if( ignored ) {
          TXT( "\nPadding      : " );
          UIX( decl->Semantic.Padding );
@@ -292,180 +270,122 @@
       TXT( "\nNumSrcRegs : " );
       UID( inst->Instruction.NumSrcRegs );
    }
+   if (deflt || fi->Instruction.Predicate != inst->Instruction.Predicate) {
+      TXT("\nPredicate  : ");
+      UID(inst->Instruction.Predicate);
+   }
+   if (deflt || fi->Instruction.Label != inst->Instruction.Label) {
+      TXT("\nLabel      : ");
+      UID(inst->Instruction.Label);
+   }
+   if (deflt || fi->Instruction.Texture != inst->Instruction.Texture) {
+      TXT("\nTexture    : ");
+      UID(inst->Instruction.Texture);
+   }
    if( ignored ) {
       TXT( "\nPadding    : " );
       UIX( inst->Instruction.Padding );
    }
 
-   if( deflt || tgsi_compare_instruction_ext_label( inst->InstructionExtLabel, fi->InstructionExtLabel ) ) {
+   if (deflt || inst->Instruction.Label) {
       EOL();
-      TXT( "\nType    : " );
-      ENM( inst->InstructionExtLabel.Type, TGSI_INSTRUCTION_EXTS );
-      if( deflt || fi->InstructionExtLabel.Label != inst->InstructionExtLabel.Label ) {
+      if (deflt || fi->Label.Label != inst->Label.Label) {
          TXT( "\nLabel   : " );
-         UID( inst->InstructionExtLabel.Label );
+         UID(inst->Label.Label);
       }
       if( ignored ) {
          TXT( "\nPadding : " );
-         UIX( inst->InstructionExtLabel.Padding );
-         if( deflt || fi->InstructionExtLabel.Extended != inst->InstructionExtLabel.Extended ) {
-            TXT( "\nExtended: " );
-            UID( inst->InstructionExtLabel.Extended );
-         }
+         UIX(inst->Label.Padding);
       }
    }
 
-   if( deflt || tgsi_compare_instruction_ext_texture( inst->InstructionExtTexture, fi->InstructionExtTexture ) ) {
+   if (deflt || inst->Instruction.Texture) {
       EOL();
-      TXT( "\nType    : " );
-      ENM( inst->InstructionExtTexture.Type, TGSI_INSTRUCTION_EXTS );
-      if( deflt || fi->InstructionExtTexture.Texture != inst->InstructionExtTexture.Texture ) {
+      if (deflt || fi->Texture.Texture != inst->Texture.Texture) {
          TXT( "\nTexture : " );
-         ENM( inst->InstructionExtTexture.Texture, TGSI_TEXTURES );
+         ENM(inst->Texture.Texture, TGSI_TEXTURES);
       }
       if( ignored ) {
          TXT( "\nPadding : " );
-         UIX( inst->InstructionExtTexture.Padding );
-         if( deflt || fi->InstructionExtTexture.Extended != inst->InstructionExtTexture.Extended ) {
-            TXT( "\nExtended: " );
-            UID( inst->InstructionExtTexture.Extended );
-         }
+         UIX(inst->Texture.Padding);
       }
    }
 
    for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) {
-      struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
-      struct tgsi_full_dst_register *fd = &fi->FullDstRegisters[i];
+      struct tgsi_full_dst_register *dst = &inst->Dst[i];
+      struct tgsi_full_dst_register *fd = &fi->Dst[i];
 
       EOL();
       TXT( "\nFile     : " );
-      ENM( dst->DstRegister.File, TGSI_FILES );
-      if( deflt || fd->DstRegister.WriteMask != dst->DstRegister.WriteMask ) {
+      ENM( dst->Register.File, TGSI_FILES );
+      if( deflt || fd->Register.WriteMask != dst->Register.WriteMask ) {
          TXT( "\nWriteMask: " );
-         ENM( dst->DstRegister.WriteMask, TGSI_WRITEMASKS );
+         ENM( dst->Register.WriteMask, TGSI_WRITEMASKS );
       }
       if( ignored ) {
-         if( deflt || fd->DstRegister.Indirect != dst->DstRegister.Indirect ) {
+         if( deflt || fd->Register.Indirect != dst->Register.Indirect ) {
             TXT( "\nIndirect : " );
-            UID( dst->DstRegister.Indirect );
+            UID( dst->Register.Indirect );
          }
-         if( deflt || fd->DstRegister.Dimension != dst->DstRegister.Dimension ) {
+         if( deflt || fd->Register.Dimension != dst->Register.Dimension ) {
             TXT( "\nDimension: " );
-            UID( dst->DstRegister.Dimension );
+            UID( dst->Register.Dimension );
          }
       }
-      if( deflt || fd->DstRegister.Index != dst->DstRegister.Index ) {
+      if( deflt || fd->Register.Index != dst->Register.Index ) {
          TXT( "\nIndex    : " );
-         SID( dst->DstRegister.Index );
+         SID( dst->Register.Index );
       }
       if( ignored ) {
          TXT( "\nPadding  : " );
-         UIX( dst->DstRegister.Padding );
-         if( deflt || fd->DstRegister.Extended != dst->DstRegister.Extended ) {
-            TXT( "\nExtended : " );
-            UID( dst->DstRegister.Extended );
-         }
-      }
-
-      if( deflt || tgsi_compare_dst_register_ext_modulate( dst->DstRegisterExtModulate, fd->DstRegisterExtModulate ) ) {
-         EOL();
-         TXT( "\nType    : " );
-         ENM( dst->DstRegisterExtModulate.Type, TGSI_DST_REGISTER_EXTS );
-         if( deflt || fd->DstRegisterExtModulate.Modulate != dst->DstRegisterExtModulate.Modulate ) {
-            TXT( "\nModulate: " );
-            ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES );
-         }
-         if( ignored ) {
-            TXT( "\nPadding : " );
-            UIX( dst->DstRegisterExtModulate.Padding );
-            if( deflt || fd->DstRegisterExtModulate.Extended != dst->DstRegisterExtModulate.Extended ) {
-               TXT( "\nExtended: " );
-               UID( dst->DstRegisterExtModulate.Extended );
-            }
-         }
+         UIX( dst->Register.Padding );
       }
    }
 
    for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) {
-      struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i];
-      struct tgsi_full_src_register *fs = &fi->FullSrcRegisters[i];
+      struct tgsi_full_src_register *src = &inst->Src[i];
+      struct tgsi_full_src_register *fs = &fi->Src[i];
 
       EOL();
       TXT( "\nFile     : ");
-      ENM( src->SrcRegister.File, TGSI_FILES );
-      if( deflt || fs->SrcRegister.SwizzleX != src->SrcRegister.SwizzleX ) {
+      ENM( src->Register.File, TGSI_FILES );
+      if( deflt || fs->Register.SwizzleX != src->Register.SwizzleX ) {
          TXT( "\nSwizzleX : " );
-         ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES );
+         ENM( src->Register.SwizzleX, TGSI_SWIZZLES );
       }
-      if( deflt || fs->SrcRegister.SwizzleY != src->SrcRegister.SwizzleY ) {
+      if( deflt || fs->Register.SwizzleY != src->Register.SwizzleY ) {
          TXT( "\nSwizzleY : " );
-         ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES );
+         ENM( src->Register.SwizzleY, TGSI_SWIZZLES );
       }
-      if( deflt || fs->SrcRegister.SwizzleZ != src->SrcRegister.SwizzleZ ) {
+      if( deflt || fs->Register.SwizzleZ != src->Register.SwizzleZ ) {
          TXT( "\nSwizzleZ : " );
-         ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES );
+         ENM( src->Register.SwizzleZ, TGSI_SWIZZLES );
       }
-      if( deflt || fs->SrcRegister.SwizzleW != src->SrcRegister.SwizzleW ) {
+      if( deflt || fs->Register.SwizzleW != src->Register.SwizzleW ) {
          TXT( "\nSwizzleW : " );
-         ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES );
+         ENM( src->Register.SwizzleW, TGSI_SWIZZLES );
       }
-      if( deflt || fs->SrcRegister.Negate != src->SrcRegister.Negate ) {
+      if (deflt || fs->Register.Absolute != src->Register.Absolute) {
+         TXT("\nAbsolute : ");
+         UID(src->Register.Absolute);
+      }
+      if( deflt || fs->Register.Negate != src->Register.Negate ) {
          TXT( "\nNegate   : " );
-         UID( src->SrcRegister.Negate );
+         UID( src->Register.Negate );
       }
       if( ignored ) {
-         if( deflt || fs->SrcRegister.Indirect != src->SrcRegister.Indirect ) {
+         if( deflt || fs->Register.Indirect != src->Register.Indirect ) {
             TXT( "\nIndirect : " );
-            UID( src->SrcRegister.Indirect );
+            UID( src->Register.Indirect );
          }
-         if( deflt || fs->SrcRegister.Dimension != src->SrcRegister.Dimension ) {
+         if( deflt || fs->Register.Dimension != src->Register.Dimension ) {
             TXT( "\nDimension: " );
-            UID( src->SrcRegister.Dimension );
+            UID( src->Register.Dimension );
          }
       }
-      if( deflt || fs->SrcRegister.Index != src->SrcRegister.Index ) {
+      if( deflt || fs->Register.Index != src->Register.Index ) {
          TXT( "\nIndex    : " );
-         SID( src->SrcRegister.Index );
-      }
-      if( ignored ) {
-         if( deflt || fs->SrcRegister.Extended != src->SrcRegister.Extended ) {
-            TXT( "\nExtended : " );
-            UID( src->SrcRegister.Extended );
-         }
-      }
-
-      if( deflt || tgsi_compare_src_register_ext_mod( src->SrcRegisterExtMod, fs->SrcRegisterExtMod ) ) {
-         EOL();
-         TXT( "\nType     : " );
-         ENM( src->SrcRegisterExtMod.Type, TGSI_SRC_REGISTER_EXTS );
-         if( deflt || fs->SrcRegisterExtMod.Complement != src->SrcRegisterExtMod.Complement ) {
-            TXT( "\nComplement: " );
-            UID( src->SrcRegisterExtMod.Complement );
-         }
-         if( deflt || fs->SrcRegisterExtMod.Bias != src->SrcRegisterExtMod.Bias ) {
-            TXT( "\nBias     : " );
-            UID( src->SrcRegisterExtMod.Bias );
-         }
-         if( deflt || fs->SrcRegisterExtMod.Scale2X != src->SrcRegisterExtMod.Scale2X ) {
-            TXT( "\nScale2X   : " );
-            UID( src->SrcRegisterExtMod.Scale2X );
-         }
-         if( deflt || fs->SrcRegisterExtMod.Absolute != src->SrcRegisterExtMod.Absolute ) {
-            TXT( "\nAbsolute  : " );
-            UID( src->SrcRegisterExtMod.Absolute );
-         }
-         if( deflt || fs->SrcRegisterExtMod.Negate != src->SrcRegisterExtMod.Negate ) {
-            TXT( "\nNegate   : " );
-            UID( src->SrcRegisterExtMod.Negate );
-         }
-         if( ignored ) {
-            TXT( "\nPadding   : " );
-            UIX( src->SrcRegisterExtMod.Padding );
-            if( deflt || fs->SrcRegisterExtMod.Extended != src->SrcRegisterExtMod.Extended ) {
-               TXT( "\nExtended  : " );
-               UID( src->SrcRegisterExtMod.Extended );
-            }
-         }
+         SID( src->Register.Index );
       }
    }
 }
@@ -485,12 +405,6 @@
 
    TXT( "tgsi-dump begin -----------------" );
 
-   TXT( "\nMajorVersion: " );
-   UID( parse.FullVersion.Version.MajorVersion );
-   TXT( "\nMinorVersion: " );
-   UID( parse.FullVersion.Version.MinorVersion );
-   EOL();
-
    TXT( "\nHeaderSize: " );
    UID( parse.FullHeader.Header.HeaderSize );
    TXT( "\nBodySize  : " );
@@ -510,10 +424,6 @@
       if( ignored ) {
          TXT( "\nSize       : " );
          UID( parse.FullToken.Token.NrTokens );
-         if( deflt || parse.FullToken.Token.Extended ) {
-            TXT( "\nExtended   : " );
-            UID( parse.FullToken.Token.Extended );
-         }
       }
 
       switch( parse.FullToken.Token.Type ) {
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 1989045..2bcb333 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -2,6 +2,7 @@
  * 
  * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
+ * Copyright 2009-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
@@ -60,21 +61,337 @@
 #include "util/u_memory.h"
 #include "util/u_math.h"
 
-#define FAST_MATH 1
 
-/** for tgsi_full_instruction::Flags */
-#define SOA_DEPENDENCY_FLAG 0x1
+#define FAST_MATH 1
 
 #define TILE_TOP_LEFT     0
 #define TILE_TOP_RIGHT    1
 #define TILE_BOTTOM_LEFT  2
 #define TILE_BOTTOM_RIGHT 3
 
+static void
+micro_abs(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = fabsf(src->f[0]);
+   dst->f[1] = fabsf(src->f[1]);
+   dst->f[2] = fabsf(src->f[2]);
+   dst->f[3] = fabsf(src->f[3]);
+}
+
+static void
+micro_arl(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->i[0] = (int)floorf(src->f[0]);
+   dst->i[1] = (int)floorf(src->f[1]);
+   dst->i[2] = (int)floorf(src->f[2]);
+   dst->i[3] = (int)floorf(src->f[3]);
+}
+
+static void
+micro_arr(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->i[0] = (int)floorf(src->f[0] + 0.5f);
+   dst->i[1] = (int)floorf(src->f[1] + 0.5f);
+   dst->i[2] = (int)floorf(src->f[2] + 0.5f);
+   dst->i[3] = (int)floorf(src->f[3] + 0.5f);
+}
+
+static void
+micro_ceil(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->f[0] = ceilf(src->f[0]);
+   dst->f[1] = ceilf(src->f[1]);
+   dst->f[2] = ceilf(src->f[2]);
+   dst->f[3] = ceilf(src->f[3]);
+}
+
+static void
+micro_cos(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = cosf(src->f[0]);
+   dst->f[1] = cosf(src->f[1]);
+   dst->f[2] = cosf(src->f[2]);
+   dst->f[3] = cosf(src->f[3]);
+}
+
+static void
+micro_ddx(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] =
+   dst->f[1] =
+   dst->f[2] =
+   dst->f[3] = src->f[TILE_BOTTOM_RIGHT] - src->f[TILE_BOTTOM_LEFT];
+}
+
+static void
+micro_ddy(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] =
+   dst->f[1] =
+   dst->f[2] =
+   dst->f[3] = src->f[TILE_BOTTOM_LEFT] - src->f[TILE_TOP_LEFT];
+}
+
+static void
+micro_exp2(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+#if FAST_MATH
+   dst->f[0] = util_fast_exp2(src->f[0]);
+   dst->f[1] = util_fast_exp2(src->f[1]);
+   dst->f[2] = util_fast_exp2(src->f[2]);
+   dst->f[3] = util_fast_exp2(src->f[3]);
+#else
+#if DEBUG
+   /* Inf is okay for this instruction, so clamp it to silence assertions. */
+   uint i;
+   union tgsi_exec_channel clamped;
+
+   for (i = 0; i < 4; i++) {
+      if (src->f[i] > 127.99999f) {
+         clamped.f[i] = 127.99999f;
+      } else if (src->f[i] < -126.99999f) {
+         clamped.f[i] = -126.99999f;
+      } else {
+         clamped.f[i] = src->f[i];
+      }
+   }
+   src = &clamped;
+#endif /* DEBUG */
+
+   dst->f[0] = powf(2.0f, src->f[0]);
+   dst->f[1] = powf(2.0f, src->f[1]);
+   dst->f[2] = powf(2.0f, src->f[2]);
+   dst->f[3] = powf(2.0f, src->f[3]);
+#endif /* FAST_MATH */
+}
+
+static void
+micro_flr(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = floorf(src->f[0]);
+   dst->f[1] = floorf(src->f[1]);
+   dst->f[2] = floorf(src->f[2]);
+   dst->f[3] = floorf(src->f[3]);
+}
+
+static void
+micro_frc(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = src->f[0] - floorf(src->f[0]);
+   dst->f[1] = src->f[1] - floorf(src->f[1]);
+   dst->f[2] = src->f[2] - floorf(src->f[2]);
+   dst->f[3] = src->f[3] - floorf(src->f[3]);
+}
+
+static void
+micro_iabs(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->i[0] = src->i[0] >= 0 ? src->i[0] : -src->i[0];
+   dst->i[1] = src->i[1] >= 0 ? src->i[1] : -src->i[1];
+   dst->i[2] = src->i[2] >= 0 ? src->i[2] : -src->i[2];
+   dst->i[3] = src->i[3] >= 0 ? src->i[3] : -src->i[3];
+}
+
+static void
+micro_ineg(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->i[0] = -src->i[0];
+   dst->i[1] = -src->i[1];
+   dst->i[2] = -src->i[2];
+   dst->i[3] = -src->i[3];
+}
+
+static void
+micro_lg2(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+#if FAST_MATH
+   dst->f[0] = util_fast_log2(src->f[0]);
+   dst->f[1] = util_fast_log2(src->f[1]);
+   dst->f[2] = util_fast_log2(src->f[2]);
+   dst->f[3] = util_fast_log2(src->f[3]);
+#else
+   dst->f[0] = logf(src->f[0]) * 1.442695f;
+   dst->f[1] = logf(src->f[1]) * 1.442695f;
+   dst->f[2] = logf(src->f[2]) * 1.442695f;
+   dst->f[3] = logf(src->f[3]) * 1.442695f;
+#endif
+}
+
+static void
+micro_lrp(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = src[0].f[0] * (src[1].f[0] - src[2].f[0]) + src[2].f[0];
+   dst->f[1] = src[0].f[1] * (src[1].f[1] - src[2].f[1]) + src[2].f[1];
+   dst->f[2] = src[0].f[2] * (src[1].f[2] - src[2].f[2]) + src[2].f[2];
+   dst->f[3] = src[0].f[3] * (src[1].f[3] - src[2].f[3]) + src[2].f[3];
+}
+
+static void
+micro_mad(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = src[0].f[0] * src[1].f[0] + src[2].f[0];
+   dst->f[1] = src[0].f[1] * src[1].f[1] + src[2].f[1];
+   dst->f[2] = src[0].f[2] * src[1].f[2] + src[2].f[2];
+   dst->f[3] = src[0].f[3] * src[1].f[3] + src[2].f[3];
+}
+
+static void
+micro_mov(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src->u[0];
+   dst->u[1] = src->u[1];
+   dst->u[2] = src->u[2];
+   dst->u[3] = src->u[3];
+}
+
+static void
+micro_rcp(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = 1.0f / src->f[0];
+   dst->f[1] = 1.0f / src->f[1];
+   dst->f[2] = 1.0f / src->f[2];
+   dst->f[3] = 1.0f / src->f[3];
+}
+
+static void
+micro_rnd(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = floorf(src->f[0] + 0.5f);
+   dst->f[1] = floorf(src->f[1] + 0.5f);
+   dst->f[2] = floorf(src->f[2] + 0.5f);
+   dst->f[3] = floorf(src->f[3] + 0.5f);
+}
+
+static void
+micro_rsq(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = 1.0f / sqrtf(fabsf(src->f[0]));
+   dst->f[1] = 1.0f / sqrtf(fabsf(src->f[1]));
+   dst->f[2] = 1.0f / sqrtf(fabsf(src->f[2]));
+   dst->f[3] = 1.0f / sqrtf(fabsf(src->f[3]));
+}
+
+static void
+micro_seq(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = src[0].f[0] == src[1].f[0] ? 1.0f : 0.0f;
+   dst->f[1] = src[0].f[1] == src[1].f[1] ? 1.0f : 0.0f;
+   dst->f[2] = src[0].f[2] == src[1].f[2] ? 1.0f : 0.0f;
+   dst->f[3] = src[0].f[3] == src[1].f[3] ? 1.0f : 0.0f;
+}
+
+static void
+micro_sge(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = src[0].f[0] >= src[1].f[0] ? 1.0f : 0.0f;
+   dst->f[1] = src[0].f[1] >= src[1].f[1] ? 1.0f : 0.0f;
+   dst->f[2] = src[0].f[2] >= src[1].f[2] ? 1.0f : 0.0f;
+   dst->f[3] = src[0].f[3] >= src[1].f[3] ? 1.0f : 0.0f;
+}
+
+static void
+micro_sgn(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = src->f[0] < 0.0f ? -1.0f : src->f[0] > 0.0f ? 1.0f : 0.0f;
+   dst->f[1] = src->f[1] < 0.0f ? -1.0f : src->f[1] > 0.0f ? 1.0f : 0.0f;
+   dst->f[2] = src->f[2] < 0.0f ? -1.0f : src->f[2] > 0.0f ? 1.0f : 0.0f;
+   dst->f[3] = src->f[3] < 0.0f ? -1.0f : src->f[3] > 0.0f ? 1.0f : 0.0f;
+}
+
+static void
+micro_sgt(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = src[0].f[0] > src[1].f[0] ? 1.0f : 0.0f;
+   dst->f[1] = src[0].f[1] > src[1].f[1] ? 1.0f : 0.0f;
+   dst->f[2] = src[0].f[2] > src[1].f[2] ? 1.0f : 0.0f;
+   dst->f[3] = src[0].f[3] > src[1].f[3] ? 1.0f : 0.0f;
+}
+
+static void
+micro_sin(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = sinf(src->f[0]);
+   dst->f[1] = sinf(src->f[1]);
+   dst->f[2] = sinf(src->f[2]);
+   dst->f[3] = sinf(src->f[3]);
+}
+
+static void
+micro_sle(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = src[0].f[0] <= src[1].f[0] ? 1.0f : 0.0f;
+   dst->f[1] = src[0].f[1] <= src[1].f[1] ? 1.0f : 0.0f;
+   dst->f[2] = src[0].f[2] <= src[1].f[2] ? 1.0f : 0.0f;
+   dst->f[3] = src[0].f[3] <= src[1].f[3] ? 1.0f : 0.0f;
+}
+
+static void
+micro_slt(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = src[0].f[0] < src[1].f[0] ? 1.0f : 0.0f;
+   dst->f[1] = src[0].f[1] < src[1].f[1] ? 1.0f : 0.0f;
+   dst->f[2] = src[0].f[2] < src[1].f[2] ? 1.0f : 0.0f;
+   dst->f[3] = src[0].f[3] < src[1].f[3] ? 1.0f : 0.0f;
+}
+
+static void
+micro_sne(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = src[0].f[0] != src[1].f[0] ? 1.0f : 0.0f;
+   dst->f[1] = src[0].f[1] != src[1].f[1] ? 1.0f : 0.0f;
+   dst->f[2] = src[0].f[2] != src[1].f[2] ? 1.0f : 0.0f;
+   dst->f[3] = src[0].f[3] != src[1].f[3] ? 1.0f : 0.0f;
+}
+
+static void
+micro_trunc(union tgsi_exec_channel *dst,
+            const union tgsi_exec_channel *src)
+{
+   dst->f[0] = (float)(int)src->f[0];
+   dst->f[1] = (float)(int)src->f[1];
+   dst->f[2] = (float)(int)src->f[2];
+   dst->f[3] = (float)(int)src->f[3];
+}
+
+
 #define CHAN_X  0
 #define CHAN_Y  1
 #define CHAN_Z  2
 #define CHAN_W  3
 
+enum tgsi_exec_datatype {
+   TGSI_EXEC_DATA_FLOAT,
+   TGSI_EXEC_DATA_INT,
+   TGSI_EXEC_DATA_UINT
+};
+
 /*
  * Shorthand locations of various utility registers (_I = Index, _C = Channel)
  */
@@ -110,10 +427,10 @@
 #define TEMP_P0            TGSI_EXEC_TEMP_P0
 
 #define IS_CHANNEL_ENABLED(INST, CHAN)\
-   ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN)))
+   ((INST).Dst[0].Register.WriteMask & (1 << (CHAN)))
 
 #define IS_CHANNEL_ENABLED2(INST, CHAN)\
-   ((INST).FullDstRegisters[1].DstRegister.WriteMask & (1 << (CHAN)))
+   ((INST).Dst[1].Register.WriteMask & (1 << (CHAN)))
 
 #define FOR_EACH_ENABLED_CHANNEL(INST, CHAN)\
    for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++)\
@@ -126,23 +443,19 @@
 
 /** The execution mask depends on the conditional mask and the loop mask */
 #define UPDATE_EXEC_MASK(MACH) \
-      MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask & MACH->FuncMask
+      MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask & MACH->Switch.mask & MACH->FuncMask
 
 
 static const union tgsi_exec_channel ZeroVec =
    { { 0.0, 0.0, 0.0, 0.0 } };
 
 
-#ifdef DEBUG
-static void
-check_inf_or_nan(const union tgsi_exec_channel *chan)
-{
-   assert(!util_is_inf_or_nan(chan->f[0]));
-   assert(!util_is_inf_or_nan(chan->f[1]));
-   assert(!util_is_inf_or_nan(chan->f[2]));
-   assert(!util_is_inf_or_nan(chan->f[3]));
-}
-#endif
+#define CHECK_INF_OR_NAN(chan) do {\
+      assert(!util_is_inf_or_nan((chan)->f[0]));\
+      assert(!util_is_inf_or_nan((chan)->f[1]));\
+      assert(!util_is_inf_or_nan((chan)->f[2]));\
+      assert(!util_is_inf_or_nan((chan)->f[3]));\
+   } while (0)
 
 
 #ifdef DEBUG
@@ -191,7 +504,7 @@
 {
    uint i, chan;
 
-   uint writemask = inst->FullDstRegisters[0].DstRegister.WriteMask;
+   uint writemask = inst->Dst[0].Register.WriteMask;
    if (writemask == TGSI_WRITEMASK_X ||
        writemask == TGSI_WRITEMASK_Y ||
        writemask == TGSI_WRITEMASK_Z ||
@@ -203,15 +516,15 @@
 
    /* loop over src regs */
    for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
-      if ((inst->FullSrcRegisters[i].SrcRegister.File ==
-           inst->FullDstRegisters[0].DstRegister.File) &&
-          (inst->FullSrcRegisters[i].SrcRegister.Index ==
-           inst->FullDstRegisters[0].DstRegister.Index)) {
+      if ((inst->Src[i].Register.File ==
+           inst->Dst[0].Register.File) &&
+          (inst->Src[i].Register.Index ==
+           inst->Dst[0].Register.Index)) {
          /* loop over dest channels */
          uint channelsWritten = 0x0;
          FOR_EACH_ENABLED_CHANNEL(*inst, chan) {
             /* check if we're reading a channel that's been written */
-            uint swizzle = tgsi_util_get_full_src_register_swizzle(&inst->FullSrcRegisters[i], chan);
+            uint swizzle = tgsi_util_get_full_src_register_swizzle(&inst->Src[i], chan);
             if (channelsWritten & (1 << swizzle)) {
                return TRUE;
             }
@@ -295,6 +608,14 @@
                                    * sizeof(struct tgsi_full_declaration));
             maxDeclarations += 10;
          }
+         if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_OUTPUT) {
+            unsigned reg;
+            for (reg = parse.FullToken.FullDeclaration.Range.First;
+                 reg <= parse.FullToken.FullDeclaration.Range.Last;
+                 ++reg) {
+               ++mach->NumOutputs;
+            }
+         }
          memcpy(declarations + numDeclarations,
                 &parse.FullToken.FullDeclaration,
                 sizeof(declarations[0]));
@@ -332,20 +653,6 @@
             maxInstructions += 10;
          }
 
-         if (tgsi_check_soa_dependencies(&parse.FullToken.FullInstruction)) {
-            uint opcode = parse.FullToken.FullInstruction.Instruction.Opcode;
-            parse.FullToken.FullInstruction.Flags = SOA_DEPENDENCY_FLAG;
-            /* XXX we only handle SOA dependencies properly for MOV/SWZ
-             * at this time!
-             */
-            if (opcode != TGSI_OPCODE_MOV) {
-               debug_printf("Warning: SOA dependency in instruction"
-                            " is not handled:\n");
-               tgsi_dump_instruction(&parse.FullToken.FullInstruction,
-                                     numInstructions);
-            }
-         }
-
          memcpy(instructions + numInstructions,
                 &parse.FullToken.FullInstruction,
                 sizeof(instructions[0]));
@@ -353,6 +660,9 @@
          numInstructions++;
          break;
 
+      case TGSI_TOKEN_TYPE_PROPERTY:
+         break;
+
       default:
          assert( 0 );
       }
@@ -386,6 +696,8 @@
    memset(mach, 0, sizeof(*mach));
 
    mach->Addrs = &mach->Temps[TGSI_EXEC_TEMP_ADDR];
+   mach->MaxGeometryShaderOutputs = TGSI_MAX_TOTAL_VERTICES;
+   mach->Predicates = &mach->Temps[TGSI_EXEC_TEMP_P0];
 
    /* Setup constants. */
    for( i = 0; i < 4; i++ ) {
@@ -426,18 +738,6 @@
    align_free(mach);
 }
 
-
-static void
-micro_abs(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-   dst->f[0] = fabsf( src->f[0] );
-   dst->f[1] = fabsf( src->f[1] );
-   dst->f[2] = fabsf( src->f[2] );
-   dst->f[3] = fabsf( src->f[3] );
-}
-
 static void
 micro_add(
    union tgsi_exec_channel *dst,
@@ -450,76 +750,6 @@
    dst->f[3] = src0->f[3] + src1->f[3];
 }
 
-#if 0
-static void
-micro_iadd(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1 )
-{
-   dst->i[0] = src0->i[0] + src1->i[0];
-   dst->i[1] = src0->i[1] + src1->i[1];
-   dst->i[2] = src0->i[2] + src1->i[2];
-   dst->i[3] = src0->i[3] + src1->i[3];
-}
-#endif
-
-static void
-micro_and(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1 )
-{
-   dst->u[0] = src0->u[0] & src1->u[0];
-   dst->u[1] = src0->u[1] & src1->u[1];
-   dst->u[2] = src0->u[2] & src1->u[2];
-   dst->u[3] = src0->u[3] & src1->u[3];
-}
-
-static void
-micro_ceil(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-   dst->f[0] = ceilf( src->f[0] );
-   dst->f[1] = ceilf( src->f[1] );
-   dst->f[2] = ceilf( src->f[2] );
-   dst->f[3] = ceilf( src->f[3] );
-}
-
-static void
-micro_cos(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-   dst->f[0] = cosf( src->f[0] );
-   dst->f[1] = cosf( src->f[1] );
-   dst->f[2] = cosf( src->f[2] );
-   dst->f[3] = cosf( src->f[3] );
-}
-
-static void
-micro_ddx(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-   dst->f[0] =
-   dst->f[1] =
-   dst->f[2] =
-   dst->f[3] = src->f[TILE_BOTTOM_RIGHT] - src->f[TILE_BOTTOM_LEFT];
-}
-
-static void
-micro_ddy(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-   dst->f[0] =
-   dst->f[1] =
-   dst->f[2] =
-   dst->f[3] = src->f[TILE_TOP_LEFT] - src->f[TILE_BOTTOM_LEFT];
-}
-
 static void
 micro_div(
    union tgsi_exec_channel *dst,
@@ -540,81 +770,6 @@
    }
 }
 
-#if 0
-static void
-micro_udiv(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1 )
-{
-   dst->u[0] = src0->u[0] / src1->u[0];
-   dst->u[1] = src0->u[1] / src1->u[1];
-   dst->u[2] = src0->u[2] / src1->u[2];
-   dst->u[3] = src0->u[3] / src1->u[3];
-}
-#endif
-
-static void
-micro_eq(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1,
-   const union tgsi_exec_channel *src2,
-   const union tgsi_exec_channel *src3 )
-{
-   dst->f[0] = src0->f[0] == src1->f[0] ? src2->f[0] : src3->f[0];
-   dst->f[1] = src0->f[1] == src1->f[1] ? src2->f[1] : src3->f[1];
-   dst->f[2] = src0->f[2] == src1->f[2] ? src2->f[2] : src3->f[2];
-   dst->f[3] = src0->f[3] == src1->f[3] ? src2->f[3] : src3->f[3];
-}
-
-#if 0
-static void
-micro_ieq(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1,
-   const union tgsi_exec_channel *src2,
-   const union tgsi_exec_channel *src3 )
-{
-   dst->i[0] = src0->i[0] == src1->i[0] ? src2->i[0] : src3->i[0];
-   dst->i[1] = src0->i[1] == src1->i[1] ? src2->i[1] : src3->i[1];
-   dst->i[2] = src0->i[2] == src1->i[2] ? src2->i[2] : src3->i[2];
-   dst->i[3] = src0->i[3] == src1->i[3] ? src2->i[3] : src3->i[3];
-}
-#endif
-
-static void
-micro_exp2(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src)
-{
-#if FAST_MATH
-   dst->f[0] = util_fast_exp2( src->f[0] );
-   dst->f[1] = util_fast_exp2( src->f[1] );
-   dst->f[2] = util_fast_exp2( src->f[2] );
-   dst->f[3] = util_fast_exp2( src->f[3] );
-#else
-   dst->f[0] = powf( 2.0f, src->f[0] );
-   dst->f[1] = powf( 2.0f, src->f[1] );
-   dst->f[2] = powf( 2.0f, src->f[2] );
-   dst->f[3] = powf( 2.0f, src->f[3] );
-#endif
-}
-
-#if 0
-static void
-micro_f2ut(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-   dst->u[0] = (uint) src->f[0];
-   dst->u[1] = (uint) src->f[1];
-   dst->u[2] = (uint) src->f[2];
-   dst->u[3] = (uint) src->f[3];
-}
-#endif
-
 static void
 micro_float_clamp(union tgsi_exec_channel *dst,
                   const union tgsi_exec_channel *src)
@@ -642,71 +797,6 @@
 }
 
 static void
-micro_flr(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-   dst->f[0] = floorf( src->f[0] );
-   dst->f[1] = floorf( src->f[1] );
-   dst->f[2] = floorf( src->f[2] );
-   dst->f[3] = floorf( src->f[3] );
-}
-
-static void
-micro_frc(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-   dst->f[0] = src->f[0] - floorf( src->f[0] );
-   dst->f[1] = src->f[1] - floorf( src->f[1] );
-   dst->f[2] = src->f[2] - floorf( src->f[2] );
-   dst->f[3] = src->f[3] - floorf( src->f[3] );
-}
-
-static void
-micro_i2f(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-   dst->f[0] = (float) src->i[0];
-   dst->f[1] = (float) src->i[1];
-   dst->f[2] = (float) src->i[2];
-   dst->f[3] = (float) src->i[3];
-}
-
-static void
-micro_lg2(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-#if FAST_MATH
-   dst->f[0] = util_fast_log2( src->f[0] );
-   dst->f[1] = util_fast_log2( src->f[1] );
-   dst->f[2] = util_fast_log2( src->f[2] );
-   dst->f[3] = util_fast_log2( src->f[3] );
-#else
-   dst->f[0] = logf( src->f[0] ) * 1.442695f;
-   dst->f[1] = logf( src->f[1] ) * 1.442695f;
-   dst->f[2] = logf( src->f[2] ) * 1.442695f;
-   dst->f[3] = logf( src->f[3] ) * 1.442695f;
-#endif
-}
-
-static void
-micro_le(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1,
-   const union tgsi_exec_channel *src2,
-   const union tgsi_exec_channel *src3 )
-{
-   dst->f[0] = src0->f[0] <= src1->f[0] ? src2->f[0] : src3->f[0];
-   dst->f[1] = src0->f[1] <= src1->f[1] ? src2->f[1] : src3->f[1];
-   dst->f[2] = src0->f[2] <= src1->f[2] ? src2->f[2] : src3->f[2];
-   dst->f[3] = src0->f[3] <= src1->f[3] ? src2->f[3] : src3->f[3];
-}
-
-static void
 micro_lt(
    union tgsi_exec_channel *dst,
    const union tgsi_exec_channel *src0,
@@ -720,38 +810,6 @@
    dst->f[3] = src0->f[3] < src1->f[3] ? src2->f[3] : src3->f[3];
 }
 
-#if 0
-static void
-micro_ilt(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1,
-   const union tgsi_exec_channel *src2,
-   const union tgsi_exec_channel *src3 )
-{
-   dst->i[0] = src0->i[0] < src1->i[0] ? src2->i[0] : src3->i[0];
-   dst->i[1] = src0->i[1] < src1->i[1] ? src2->i[1] : src3->i[1];
-   dst->i[2] = src0->i[2] < src1->i[2] ? src2->i[2] : src3->i[2];
-   dst->i[3] = src0->i[3] < src1->i[3] ? src2->i[3] : src3->i[3];
-}
-#endif
-
-#if 0
-static void
-micro_ult(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1,
-   const union tgsi_exec_channel *src2,
-   const union tgsi_exec_channel *src3 )
-{
-   dst->u[0] = src0->u[0] < src1->u[0] ? src2->u[0] : src3->u[0];
-   dst->u[1] = src0->u[1] < src1->u[1] ? src2->u[1] : src3->u[1];
-   dst->u[2] = src0->u[2] < src1->u[2] ? src2->u[2] : src3->u[2];
-   dst->u[3] = src0->u[3] < src1->u[3] ? src2->u[3] : src3->u[3];
-}
-#endif
-
 static void
 micro_max(
    union tgsi_exec_channel *dst,
@@ -764,34 +822,6 @@
    dst->f[3] = src0->f[3] > src1->f[3] ? src0->f[3] : src1->f[3];
 }
 
-#if 0
-static void
-micro_imax(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1 )
-{
-   dst->i[0] = src0->i[0] > src1->i[0] ? src0->i[0] : src1->i[0];
-   dst->i[1] = src0->i[1] > src1->i[1] ? src0->i[1] : src1->i[1];
-   dst->i[2] = src0->i[2] > src1->i[2] ? src0->i[2] : src1->i[2];
-   dst->i[3] = src0->i[3] > src1->i[3] ? src0->i[3] : src1->i[3];
-}
-#endif
-
-#if 0
-static void
-micro_umax(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1 )
-{
-   dst->u[0] = src0->u[0] > src1->u[0] ? src0->u[0] : src1->u[0];
-   dst->u[1] = src0->u[1] > src1->u[1] ? src0->u[1] : src1->u[1];
-   dst->u[2] = src0->u[2] > src1->u[2] ? src0->u[2] : src1->u[2];
-   dst->u[3] = src0->u[3] > src1->u[3] ? src0->u[3] : src1->u[3];
-}
-#endif
-
 static void
 micro_min(
    union tgsi_exec_channel *dst,
@@ -804,48 +834,6 @@
    dst->f[3] = src0->f[3] < src1->f[3] ? src0->f[3] : src1->f[3];
 }
 
-#if 0
-static void
-micro_imin(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1 )
-{
-   dst->i[0] = src0->i[0] < src1->i[0] ? src0->i[0] : src1->i[0];
-   dst->i[1] = src0->i[1] < src1->i[1] ? src0->i[1] : src1->i[1];
-   dst->i[2] = src0->i[2] < src1->i[2] ? src0->i[2] : src1->i[2];
-   dst->i[3] = src0->i[3] < src1->i[3] ? src0->i[3] : src1->i[3];
-}
-#endif
-
-#if 0
-static void
-micro_umin(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1 )
-{
-   dst->u[0] = src0->u[0] < src1->u[0] ? src0->u[0] : src1->u[0];
-   dst->u[1] = src0->u[1] < src1->u[1] ? src0->u[1] : src1->u[1];
-   dst->u[2] = src0->u[2] < src1->u[2] ? src0->u[2] : src1->u[2];
-   dst->u[3] = src0->u[3] < src1->u[3] ? src0->u[3] : src1->u[3];
-}
-#endif
-
-#if 0
-static void
-micro_umod(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1 )
-{
-   dst->u[0] = src0->u[0] % src1->u[0];
-   dst->u[1] = src0->u[1] % src1->u[1];
-   dst->u[2] = src0->u[2] % src1->u[2];
-   dst->u[3] = src0->u[3] % src1->u[3];
-}
-#endif
-
 static void
 micro_mul(
    union tgsi_exec_channel *dst,
@@ -860,20 +848,6 @@
 
 #if 0
 static void
-micro_imul(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1 )
-{
-   dst->i[0] = src0->i[0] * src1->i[0];
-   dst->i[1] = src0->i[1] * src1->i[1];
-   dst->i[2] = src0->i[2] * src1->i[2];
-   dst->i[3] = src0->i[3] * src1->i[3];
-}
-#endif
-
-#if 0
-static void
 micro_imul64(
    union tgsi_exec_channel *dst0,
    union tgsi_exec_channel *dst1,
@@ -937,42 +911,6 @@
    dst->f[3] = -src->f[3];
 }
 
-#if 0
-static void
-micro_ineg(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-   dst->i[0] = -src->i[0];
-   dst->i[1] = -src->i[1];
-   dst->i[2] = -src->i[2];
-   dst->i[3] = -src->i[3];
-}
-#endif
-
-static void
-micro_not(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-   dst->u[0] = ~src->u[0];
-   dst->u[1] = ~src->u[1];
-   dst->u[2] = ~src->u[2];
-   dst->u[3] = ~src->u[3];
-}
-
-static void
-micro_or(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1 )
-{
-   dst->u[0] = src0->u[0] | src1->u[0];
-   dst->u[1] = src0->u[1] | src1->u[1];
-   dst->u[2] = src0->u[2] | src1->u[2];
-   dst->u[3] = src0->u[3] | src1->u[3];
-}
-
 static void
 micro_pow(
    union tgsi_exec_channel *dst,
@@ -993,88 +931,6 @@
 }
 
 static void
-micro_rnd(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-   dst->f[0] = floorf( src->f[0] + 0.5f );
-   dst->f[1] = floorf( src->f[1] + 0.5f );
-   dst->f[2] = floorf( src->f[2] + 0.5f );
-   dst->f[3] = floorf( src->f[3] + 0.5f );
-}
-
-static void
-micro_sgn(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-   dst->f[0] = src->f[0] < 0.0f ? -1.0f : src->f[0] > 0.0f ? 1.0f : 0.0f;
-   dst->f[1] = src->f[1] < 0.0f ? -1.0f : src->f[1] > 0.0f ? 1.0f : 0.0f;
-   dst->f[2] = src->f[2] < 0.0f ? -1.0f : src->f[2] > 0.0f ? 1.0f : 0.0f;
-   dst->f[3] = src->f[3] < 0.0f ? -1.0f : src->f[3] > 0.0f ? 1.0f : 0.0f;
-}
-
-static void
-micro_shl(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1 )
-{
-   dst->i[0] = src0->i[0] << src1->i[0];
-   dst->i[1] = src0->i[1] << src1->i[1];
-   dst->i[2] = src0->i[2] << src1->i[2];
-   dst->i[3] = src0->i[3] << src1->i[3];
-}
-
-static void
-micro_ishr(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1 )
-{
-   dst->i[0] = src0->i[0] >> src1->i[0];
-   dst->i[1] = src0->i[1] >> src1->i[1];
-   dst->i[2] = src0->i[2] >> src1->i[2];
-   dst->i[3] = src0->i[3] >> src1->i[3];
-}
-
-static void
-micro_trunc(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0 )
-{
-   dst->f[0] = (float) (int) src0->f[0];
-   dst->f[1] = (float) (int) src0->f[1];
-   dst->f[2] = (float) (int) src0->f[2];
-   dst->f[3] = (float) (int) src0->f[3];
-}
-
-#if 0
-static void
-micro_ushr(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1 )
-{
-   dst->u[0] = src0->u[0] >> src1->u[0];
-   dst->u[1] = src0->u[1] >> src1->u[1];
-   dst->u[2] = src0->u[2] >> src1->u[2];
-   dst->u[3] = src0->u[3] >> src1->u[3];
-}
-#endif
-
-static void
-micro_sin(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-   dst->f[0] = sinf( src->f[0] );
-   dst->f[1] = sinf( src->f[1] );
-   dst->f[2] = sinf( src->f[2] );
-   dst->f[3] = sinf( src->f[3] );
-}
-
-static void
 micro_sqrt( union tgsi_exec_channel *dst,
             const union tgsi_exec_channel *src )
 {
@@ -1096,31 +952,6 @@
    dst->f[3] = src0->f[3] - src1->f[3];
 }
 
-#if 0
-static void
-micro_u2f(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src )
-{
-   dst->f[0] = (float) src->u[0];
-   dst->f[1] = (float) src->u[1];
-   dst->f[2] = (float) src->u[2];
-   dst->f[3] = (float) src->u[3];
-}
-#endif
-
-static void
-micro_xor(
-   union tgsi_exec_channel *dst,
-   const union tgsi_exec_channel *src0,
-   const union tgsi_exec_channel *src1 )
-{
-   dst->u[0] = src0->u[0] ^ src1->u[0];
-   dst->u[1] = src0->u[1] ^ src1->u[1];
-   dst->u[2] = src0->u[2] ^ src1->u[2];
-   dst->u[3] = src0->u[3] ^ src1->u[3];
-}
-
 static void
 fetch_src_file_channel(
    const struct tgsi_exec_machine *mach,
@@ -1156,6 +987,7 @@
          break;
 
       case TGSI_FILE_INPUT:
+      case TGSI_FILE_SYSTEM_VALUE:
          chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0];
          chan->u[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1];
          chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2];
@@ -1193,10 +1025,10 @@
          assert(index->i[1] < TGSI_EXEC_NUM_PREDS);
          assert(index->i[2] < TGSI_EXEC_NUM_PREDS);
          assert(index->i[3] < TGSI_EXEC_NUM_PREDS);
-         chan->u[0] = mach->Addrs[0].xyzw[swizzle].u[0];
-         chan->u[1] = mach->Addrs[0].xyzw[swizzle].u[1];
-         chan->u[2] = mach->Addrs[0].xyzw[swizzle].u[2];
-         chan->u[3] = mach->Addrs[0].xyzw[swizzle].u[3];
+         chan->u[0] = mach->Predicates[0].xyzw[swizzle].u[0];
+         chan->u[1] = mach->Predicates[0].xyzw[swizzle].u[1];
+         chan->u[2] = mach->Predicates[0].xyzw[swizzle].u[2];
+         chan->u[3] = mach->Predicates[0].xyzw[swizzle].u[3];
          break;
 
       case TGSI_FILE_OUTPUT:
@@ -1218,11 +1050,11 @@
 }
 
 static void
-fetch_source(
-   const struct tgsi_exec_machine *mach,
-   union tgsi_exec_channel *chan,
-   const struct tgsi_full_src_register *reg,
-   const uint chan_index )
+fetch_source(const struct tgsi_exec_machine *mach,
+             union tgsi_exec_channel *chan,
+             const struct tgsi_full_src_register *reg,
+             const uint chan_index,
+             enum tgsi_exec_datatype src_datatype)
 {
    union tgsi_exec_channel index;
    uint swizzle;
@@ -1231,13 +1063,13 @@
     *
     *    file[1],
     *    where:
-    *       file = SrcRegister.File
-    *       [1] = SrcRegister.Index
+    *       file = Register.File
+    *       [1] = Register.Index
     */
    index.i[0] =
    index.i[1] =
    index.i[2] =
-   index.i[3] = reg->SrcRegister.Index;
+   index.i[3] = reg->Register.Index;
 
    /* There is an extra source register that indirectly subscripts
     * a register file. The direct index now becomes an offset
@@ -1245,11 +1077,11 @@
     *
     *    file[ind[2].x+1],
     *    where:
-    *       ind = SrcRegisterInd.File
-    *       [2] = SrcRegisterInd.Index
-    *       .x = SrcRegisterInd.SwizzleX
+    *       ind = Indirect.File
+    *       [2] = Indirect.Index
+    *       .x = Indirect.SwizzleX
     */
-   if (reg->SrcRegister.Indirect) {
+   if (reg->Register.Indirect) {
       union tgsi_exec_channel index2;
       union tgsi_exec_channel indir_index;
       const uint execmask = mach->ExecMask;
@@ -1259,22 +1091,22 @@
       index2.i[0] =
       index2.i[1] =
       index2.i[2] =
-      index2.i[3] = reg->SrcRegisterInd.Index;
+      index2.i[3] = reg->Indirect.Index;
 
       /* get current value of address register[swizzle] */
-      swizzle = tgsi_util_get_src_register_swizzle( &reg->SrcRegisterInd, CHAN_X );
+      swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect, CHAN_X );
       fetch_src_file_channel(
          mach,
-         reg->SrcRegisterInd.File,
+         reg->Indirect.File,
          swizzle,
          &index2,
          &indir_index );
 
       /* add value of address register to the offset */
-      index.i[0] += (int) indir_index.f[0];
-      index.i[1] += (int) indir_index.f[1];
-      index.i[2] += (int) indir_index.f[2];
-      index.i[3] += (int) indir_index.f[3];
+      index.i[0] += indir_index.i[0];
+      index.i[1] += indir_index.i[1];
+      index.i[2] += indir_index.i[2];
+      index.i[3] += indir_index.i[3];
 
       /* for disabled execution channels, zero-out the index to
        * avoid using a potential garbage value.
@@ -1291,15 +1123,16 @@
     *
     *    file[1][3] == file[1*sizeof(file[1])+3],
     *    where:
-    *       [3] = SrcRegisterDim.Index
+    *       [3] = Dimension.Index
     */
-   if (reg->SrcRegister.Dimension) {
+   if (reg->Register.Dimension) {
       /* The size of the first-order array depends on the register file type.
        * We need to multiply the index to the first array to get an effective,
        * "flat" index that points to the beginning of the second-order array.
        */
-      switch (reg->SrcRegister.File) {
+      switch (reg->Register.File) {
       case TGSI_FILE_INPUT:
+      case TGSI_FILE_SYSTEM_VALUE:
          index.i[0] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
          index.i[1] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
          index.i[2] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
@@ -1315,10 +1148,10 @@
          assert( 0 );
       }
 
-      index.i[0] += reg->SrcRegisterDim.Index;
-      index.i[1] += reg->SrcRegisterDim.Index;
-      index.i[2] += reg->SrcRegisterDim.Index;
-      index.i[3] += reg->SrcRegisterDim.Index;
+      index.i[0] += reg->Dimension.Index;
+      index.i[1] += reg->Dimension.Index;
+      index.i[2] += reg->Dimension.Index;
+      index.i[3] += reg->Dimension.Index;
 
       /* Again, the second subscript index can be addressed indirectly
        * identically to the first one.
@@ -1327,11 +1160,11 @@
        *
        *    file[1][ind[4].y+3],
        *    where:
-       *       ind = SrcRegisterDimInd.File
-       *       [4] = SrcRegisterDimInd.Index
-       *       .y = SrcRegisterDimInd.SwizzleX
+       *       ind = DimIndirect.File
+       *       [4] = DimIndirect.Index
+       *       .y = DimIndirect.SwizzleX
        */
-      if (reg->SrcRegisterDim.Indirect) {
+      if (reg->Dimension.Indirect) {
          union tgsi_exec_channel index2;
          union tgsi_exec_channel indir_index;
          const uint execmask = mach->ExecMask;
@@ -1340,20 +1173,20 @@
          index2.i[0] =
          index2.i[1] =
          index2.i[2] =
-         index2.i[3] = reg->SrcRegisterDimInd.Index;
+         index2.i[3] = reg->DimIndirect.Index;
 
-         swizzle = tgsi_util_get_src_register_swizzle( &reg->SrcRegisterDimInd, CHAN_X );
+         swizzle = tgsi_util_get_src_register_swizzle( &reg->DimIndirect, CHAN_X );
          fetch_src_file_channel(
             mach,
-            reg->SrcRegisterDimInd.File,
+            reg->DimIndirect.File,
             swizzle,
             &index2,
             &indir_index );
 
-         index.i[0] += (int) indir_index.f[0];
-         index.i[1] += (int) indir_index.f[1];
-         index.i[2] += (int) indir_index.f[2];
-         index.i[3] += (int) indir_index.f[3];
+         index.i[0] += indir_index.i[0];
+         index.i[1] += indir_index.i[1];
+         index.i[2] += indir_index.i[2];
+         index.i[3] += indir_index.i[3];
 
          /* for disabled execution channels, zero-out the index to
           * avoid using a potential garbage value.
@@ -1365,7 +1198,7 @@
       }
 
       /* If by any chance there was a need for a 3D array of register
-       * files, we would have to check whether SrcRegisterDim is followed
+       * files, we would have to check whether Dimension is followed
        * by a dimension register and continue the saga.
        */
    }
@@ -1373,41 +1206,35 @@
    swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index );
    fetch_src_file_channel(
       mach,
-      reg->SrcRegister.File,
+      reg->Register.File,
       swizzle,
       &index,
       chan );
 
-   switch (tgsi_util_get_full_src_register_sign_mode( reg, chan_index )) {
-   case TGSI_UTIL_SIGN_CLEAR:
-      micro_abs( chan, chan );
-      break;
-
-   case TGSI_UTIL_SIGN_SET:
-      micro_abs( chan, chan );
-      micro_neg( chan, chan );
-      break;
-
-   case TGSI_UTIL_SIGN_TOGGLE:
-      micro_neg( chan, chan );
-      break;
-
-   case TGSI_UTIL_SIGN_KEEP:
-      break;
+   if (reg->Register.Absolute) {
+      if (src_datatype == TGSI_EXEC_DATA_FLOAT) {
+         micro_abs(chan, chan);
+      } else {
+         micro_iabs(chan, chan);
+      }
    }
 
-   if (reg->SrcRegisterExtMod.Complement) {
-      micro_sub( chan, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], chan );
+   if (reg->Register.Negate) {
+      if (src_datatype == TGSI_EXEC_DATA_FLOAT) {
+         micro_neg(chan, chan);
+      } else {
+         micro_ineg(chan, chan);
+      }
    }
 }
 
 static void
-store_dest(
-   struct tgsi_exec_machine *mach,
-   const union tgsi_exec_channel *chan,
-   const struct tgsi_full_dst_register *reg,
-   const struct tgsi_full_instruction *inst,
-   uint chan_index )
+store_dest(struct tgsi_exec_machine *mach,
+           const union tgsi_exec_channel *chan,
+           const struct tgsi_full_dst_register *reg,
+           const struct tgsi_full_instruction *inst,
+           uint chan_index,
+           enum tgsi_exec_datatype dst_datatype)
 {
    uint i;
    union tgsi_exec_channel null;
@@ -1416,9 +1243,9 @@
    int offset = 0;  /* indirection offset */
    int index;
 
-#ifdef DEBUG
-   check_inf_or_nan(chan);
-#endif
+   if (dst_datatype == TGSI_EXEC_DATA_FLOAT) {
+      CHECK_INF_OR_NAN(chan);
+   }
 
    /* There is an extra source register that indirectly subscripts
     * a register file. The direct index now becomes an offset
@@ -1426,11 +1253,11 @@
     *
     *    file[ind[2].x+1],
     *    where:
-    *       ind = DstRegisterInd.File
-    *       [2] = DstRegisterInd.Index
-    *       .x = DstRegisterInd.SwizzleX
+    *       ind = Indirect.File
+    *       [2] = Indirect.Index
+    *       .x = Indirect.SwizzleX
     */
-   if (reg->DstRegister.Indirect) {
+   if (reg->Register.Indirect) {
       union tgsi_exec_channel index;
       union tgsi_exec_channel indir_index;
       uint swizzle;
@@ -1439,49 +1266,65 @@
       index.i[0] =
       index.i[1] =
       index.i[2] =
-      index.i[3] = reg->DstRegisterInd.Index;
+      index.i[3] = reg->Indirect.Index;
 
       /* get current value of address register[swizzle] */
-      swizzle = tgsi_util_get_src_register_swizzle( &reg->DstRegisterInd, CHAN_X );
+      swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect, CHAN_X );
 
       /* fetch values from the address/indirection register */
       fetch_src_file_channel(
          mach,
-         reg->DstRegisterInd.File,
+         reg->Indirect.File,
          swizzle,
          &index,
          &indir_index );
 
       /* save indirection offset */
-      offset = (int) indir_index.f[0];
+      offset = indir_index.i[0];
    }
 
-   switch (reg->DstRegister.File) {
+   switch (reg->Register.File) {
    case TGSI_FILE_NULL:
       dst = &null;
       break;
 
    case TGSI_FILE_OUTPUT:
       index = mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0]
-         + reg->DstRegister.Index;
+         + reg->Register.Index;
       dst = &mach->Outputs[offset + index].xyzw[chan_index];
+#if 0
+      if (TGSI_PROCESSOR_GEOMETRY == mach->Processor) {
+         fprintf(stderr, "STORING OUT[%d] mask(%d), = (", offset + index, execmask);
+         for (i = 0; i < QUAD_SIZE; i++)
+            if (execmask & (1 << i))
+               fprintf(stderr, "%f, ", chan->f[i]);
+         fprintf(stderr, ")\n");
+      }
+#endif
       break;
 
    case TGSI_FILE_TEMPORARY:
-      index = reg->DstRegister.Index;
+      index = reg->Register.Index;
       assert( index < TGSI_EXEC_NUM_TEMPS );
       dst = &mach->Temps[offset + index].xyzw[chan_index];
       break;
 
    case TGSI_FILE_ADDRESS:
-      index = reg->DstRegister.Index;
+      index = reg->Register.Index;
       dst = &mach->Addrs[index].xyzw[chan_index];
       break;
 
+   case TGSI_FILE_LOOP:
+      assert(reg->Register.Index == 0);
+      assert(mach->LoopCounterStackTop > 0);
+      assert(chan_index == CHAN_X);
+      dst = &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[chan_index];
+      break;
+
    case TGSI_FILE_PREDICATE:
-      index = reg->DstRegister.Index;
+      index = reg->Register.Index;
       assert(index < TGSI_EXEC_NUM_PREDS);
-      dst = &mach->Addrs[index].xyzw[chan_index];
+      dst = &mach->Predicates[index].xyzw[chan_index];
       break;
 
    default:
@@ -1489,6 +1332,47 @@
       return;
    }
 
+   if (inst->Instruction.Predicate) {
+      uint swizzle;
+      union tgsi_exec_channel *pred;
+
+      switch (chan_index) {
+      case CHAN_X:
+         swizzle = inst->Predicate.SwizzleX;
+         break;
+      case CHAN_Y:
+         swizzle = inst->Predicate.SwizzleY;
+         break;
+      case CHAN_Z:
+         swizzle = inst->Predicate.SwizzleZ;
+         break;
+      case CHAN_W:
+         swizzle = inst->Predicate.SwizzleW;
+         break;
+      default:
+         assert(0);
+         return;
+      }
+
+      assert(inst->Predicate.Index == 0);
+
+      pred = &mach->Predicates[inst->Predicate.Index].xyzw[swizzle];
+
+      if (inst->Predicate.Negate) {
+         for (i = 0; i < QUAD_SIZE; i++) {
+            if (pred->u[i]) {
+               execmask &= ~(1 << i);
+            }
+         }
+      } else {
+         for (i = 0; i < QUAD_SIZE; i++) {
+            if (!pred->u[i]) {
+               execmask &= ~(1 << i);
+            }
+         }
+      }
+   }
+
    switch (inst->Instruction.Saturate) {
    case TGSI_SAT_NONE:
       for (i = 0; i < QUAD_SIZE; i++)
@@ -1526,10 +1410,10 @@
 }
 
 #define FETCH(VAL,INDEX,CHAN)\
-    fetch_source (mach, VAL, &inst->FullSrcRegisters[INDEX], CHAN)
+    fetch_source(mach, VAL, &inst->Src[INDEX], CHAN, TGSI_EXEC_DATA_FLOAT)
 
 #define STORE(VAL,INDEX,CHAN)\
-    store_dest (mach, VAL, &inst->FullDstRegisters[INDEX], inst, CHAN )
+   store_dest(mach, VAL, &inst->Dst[INDEX], inst, CHAN, TGSI_EXEC_DATA_FLOAT)
 
 
 /**
@@ -1555,7 +1439,7 @@
 
       /* unswizzle channel */
       swizzle = tgsi_util_get_full_src_register_swizzle (
-                        &inst->FullSrcRegisters[0],
+                        &inst->Src[0],
                         chan_index);
 
       /* check if the component has not been already tested */
@@ -1587,6 +1471,35 @@
    mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask;
 }
 
+static void
+emit_vertex(struct tgsi_exec_machine *mach)
+{
+   /* FIXME: check for exec mask correctly
+   unsigned i;
+   for (i = 0; i < QUAD_SIZE; ++i) {
+         if ((mach->ExecMask & (1 << i)))
+   */
+   if (mach->ExecMask) {
+      mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += mach->NumOutputs;
+      mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]]++;
+   }
+}
+
+static void
+emit_primitive(struct tgsi_exec_machine *mach)
+{
+   unsigned *prim_count = &mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0];
+   /* FIXME: check for exec mask correctly
+   unsigned i;
+   for (i = 0; i < QUAD_SIZE; ++i) {
+         if ((mach->ExecMask & (1 << i)))
+   */
+   if (mach->ExecMask) {
+      ++(*prim_count);
+      debug_assert((*prim_count * mach->NumOutputs) < mach->MaxGeometryShaderOutputs);
+      mach->Primitives[*prim_count] = 0;
+   }
+}
 
 /*
  * Fetch a four texture samples using STR texture coordinates.
@@ -1596,7 +1509,8 @@
              const union tgsi_exec_channel *s,
              const union tgsi_exec_channel *t,
              const union tgsi_exec_channel *p,
-             float lodbias,  /* XXX should be float[4] */
+             const union tgsi_exec_channel *c0,
+             enum tgsi_sampler_control control,
              union tgsi_exec_channel *r,
              union tgsi_exec_channel *g,
              union tgsi_exec_channel *b,
@@ -1605,7 +1519,7 @@
    uint j;
    float rgba[NUM_CHANNELS][QUAD_SIZE];
 
-   sampler->get_samples(sampler, s->f, t->f, p->f, lodbias, rgba);
+   sampler->get_samples(sampler, s->f, t->f, p->f, c0->f, control, rgba);
 
    for (j = 0; j < 4; j++) {
       r->f[j] = rgba[0][j];
@@ -1616,40 +1530,120 @@
 }
 
 
+#define TEX_MODIFIER_NONE           0
+#define TEX_MODIFIER_PROJECTED      1
+#define TEX_MODIFIER_LOD_BIAS       2
+#define TEX_MODIFIER_EXPLICIT_LOD   3
+
+
 static void
 exec_tex(struct tgsi_exec_machine *mach,
          const struct tgsi_full_instruction *inst,
-         boolean biasLod,
-         boolean projected)
+         uint modifier)
 {
-   const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index;
+   const uint unit = inst->Src[1].Register.Index;
+   union tgsi_exec_channel r[4];
+   const union tgsi_exec_channel *lod = &ZeroVec;
+   enum tgsi_sampler_control control;
+   uint chan_index;
+
+   if (modifier != TEX_MODIFIER_NONE) {
+      FETCH(&r[3], 0, CHAN_W);
+      if (modifier != TEX_MODIFIER_PROJECTED) {
+         lod = &r[3];
+      }
+   }
+
+   if (modifier == TEX_MODIFIER_EXPLICIT_LOD) {
+      control = tgsi_sampler_lod_explicit;
+   } else {
+      control = tgsi_sampler_lod_bias;
+   }
+
+   switch (inst->Texture.Texture) {
+   case TGSI_TEXTURE_1D:
+   case TGSI_TEXTURE_SHADOW1D:
+      FETCH(&r[0], 0, CHAN_X);
+
+      if (modifier == TEX_MODIFIER_PROJECTED) {
+         micro_div(&r[0], &r[0], &r[3]);
+      }
+
+      fetch_texel(mach->Samplers[unit],
+                  &r[0], &ZeroVec, &ZeroVec, lod,  /* S, T, P, LOD */
+                  control,
+                  &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
+      break;
+
+   case TGSI_TEXTURE_2D:
+   case TGSI_TEXTURE_RECT:
+   case TGSI_TEXTURE_SHADOW2D:
+   case TGSI_TEXTURE_SHADOWRECT:
+      FETCH(&r[0], 0, CHAN_X);
+      FETCH(&r[1], 0, CHAN_Y);
+      FETCH(&r[2], 0, CHAN_Z);
+
+      if (modifier == TEX_MODIFIER_PROJECTED) {
+         micro_div(&r[0], &r[0], &r[3]);
+         micro_div(&r[1], &r[1], &r[3]);
+         micro_div(&r[2], &r[2], &r[3]);
+      }
+
+      fetch_texel(mach->Samplers[unit],
+                  &r[0], &r[1], &r[2], lod,     /* S, T, P, LOD */
+                  control,
+                  &r[0], &r[1], &r[2], &r[3]);  /* outputs */
+      break;
+
+   case TGSI_TEXTURE_3D:
+   case TGSI_TEXTURE_CUBE:
+      FETCH(&r[0], 0, CHAN_X);
+      FETCH(&r[1], 0, CHAN_Y);
+      FETCH(&r[2], 0, CHAN_Z);
+
+      if (modifier == TEX_MODIFIER_PROJECTED) {
+         micro_div(&r[0], &r[0], &r[3]);
+         micro_div(&r[1], &r[1], &r[3]);
+         micro_div(&r[2], &r[2], &r[3]);
+      }
+
+      fetch_texel(mach->Samplers[unit],
+                  &r[0], &r[1], &r[2], lod,
+                  control,
+                  &r[0], &r[1], &r[2], &r[3]);
+      break;
+
+   default:
+      assert(0);
+   }
+
+   FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
+      STORE(&r[chan_index], 0, chan_index);
+   }
+}
+
+static void
+exec_txd(struct tgsi_exec_machine *mach,
+         const struct tgsi_full_instruction *inst)
+{
+   const uint unit = inst->Src[3].Register.Index;
    union tgsi_exec_channel r[4];
    uint chan_index;
-   float lodBias;
 
-   /*   debug_printf("Sampler %u unit %u\n", sampler, unit); */
+   /*
+    * XXX: This is fake TXD -- the derivatives are not taken into account, yet.
+    */
 
-   switch (inst->InstructionExtTexture.Texture) {
+   switch (inst->Texture.Texture) {
    case TGSI_TEXTURE_1D:
    case TGSI_TEXTURE_SHADOW1D:
 
       FETCH(&r[0], 0, CHAN_X);
 
-      if (projected) {
-         FETCH(&r[1], 0, CHAN_W);
-         micro_div( &r[0], &r[0], &r[1] );
-      }
-
-      if (biasLod) {
-         FETCH(&r[1], 0, CHAN_W);
-         lodBias = r[2].f[0];
-      }
-      else
-         lodBias = 0.0;
-
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &ZeroVec, &ZeroVec, lodBias,  /* S, T, P, BIAS */
-                  &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
+                  &r[0], &ZeroVec, &ZeroVec, &ZeroVec,   /* S, T, P, BIAS */
+                  tgsi_sampler_lod_bias,
+                  &r[0], &r[1], &r[2], &r[3]);           /* R, G, B, A */
       break;
 
    case TGSI_TEXTURE_2D:
@@ -1661,23 +1655,10 @@
       FETCH(&r[1], 0, CHAN_Y);
       FETCH(&r[2], 0, CHAN_Z);
 
-      if (projected) {
-         FETCH(&r[3], 0, CHAN_W);
-         micro_div( &r[0], &r[0], &r[3] );
-         micro_div( &r[1], &r[1], &r[3] );
-         micro_div( &r[2], &r[2], &r[3] );
-      }
-
-      if (biasLod) {
-         FETCH(&r[3], 0, CHAN_W);
-         lodBias = r[3].f[0];
-      }
-      else
-         lodBias = 0.0;
-
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], lodBias,  /* inputs */
-                  &r[0], &r[1], &r[2], &r[3]);  /* outputs */
+                  &r[0], &r[1], &r[2], &ZeroVec,   /* inputs */
+                  tgsi_sampler_lod_bias,
+                  &r[0], &r[1], &r[2], &r[3]);     /* outputs */
       break;
 
    case TGSI_TEXTURE_3D:
@@ -1687,31 +1668,18 @@
       FETCH(&r[1], 0, CHAN_Y);
       FETCH(&r[2], 0, CHAN_Z);
 
-      if (projected) {
-         FETCH(&r[3], 0, CHAN_W);
-         micro_div( &r[0], &r[0], &r[3] );
-         micro_div( &r[1], &r[1], &r[3] );
-         micro_div( &r[2], &r[2], &r[3] );
-      }
-
-      if (biasLod) {
-         FETCH(&r[3], 0, CHAN_W);
-         lodBias = r[3].f[0];
-      }
-      else
-         lodBias = 0.0;
-
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], lodBias,
+                  &r[0], &r[1], &r[2], &ZeroVec,
+                  tgsi_sampler_lod_bias,
                   &r[0], &r[1], &r[2], &r[3]);
       break;
 
    default:
-      assert (0);
+      assert(0);
    }
 
-   FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-      STORE( &r[chan_index], 0, chan_index );
+   FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
+      STORE(&r[chan_index], 0, chan_index);
    }
 }
 
@@ -1784,53 +1752,59 @@
    unsigned chan );
 
 static void
-exec_declaration(
-   struct tgsi_exec_machine *mach,
-   const struct tgsi_full_declaration *decl )
+exec_declaration(struct tgsi_exec_machine *mach,
+                 const struct tgsi_full_declaration *decl)
 {
-   if( mach->Processor == TGSI_PROCESSOR_FRAGMENT ) {
-      if( decl->Declaration.File == TGSI_FILE_INPUT ) {
-         unsigned first, last, mask;
-         eval_coef_func eval;
+   if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) {
+      if (decl->Declaration.File == TGSI_FILE_INPUT ||
+          decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE) {
+         uint first, last, mask;
 
-         first = decl->DeclarationRange.First;
-         last = decl->DeclarationRange.Last;
+         first = decl->Range.First;
+         last = decl->Range.Last;
          mask = decl->Declaration.UsageMask;
 
-         switch( decl->Declaration.Interpolate ) {
-         case TGSI_INTERPOLATE_CONSTANT:
-            eval = eval_constant_coef;
-            break;
+         if (decl->Semantic.Name == TGSI_SEMANTIC_POSITION) {
+            assert(decl->Semantic.Index == 0);
+            assert(first == last);
+            assert(mask == TGSI_WRITEMASK_XYZW);
 
-         case TGSI_INTERPOLATE_LINEAR:
-            eval = eval_linear_coef;
-            break;
+            mach->Inputs[first] = mach->QuadPos;
+         } else if (decl->Semantic.Name == TGSI_SEMANTIC_FACE) {
+            uint i;
 
-         case TGSI_INTERPOLATE_PERSPECTIVE:
-            eval = eval_perspective_coef;
-            break;
+            assert(decl->Semantic.Index == 0);
+            assert(first == last);
 
-         default:
-            eval = NULL;
-            assert( 0 );
-         }
-
-         if( mask == TGSI_WRITEMASK_XYZW ) {
-            unsigned i, j;
-
-            for( i = first; i <= last; i++ ) {
-               for( j = 0; j < NUM_CHANNELS; j++ ) {
-                  eval( mach, i, j );
-               }
+            for (i = 0; i < QUAD_SIZE; i++) {
+               mach->Inputs[first].xyzw[0].f[i] = mach->Face;
             }
-         }
-         else {
-            unsigned i, j;
+         } else {
+            eval_coef_func eval;
+            uint i, j;
 
-            for( j = 0; j < NUM_CHANNELS; j++ ) {
-               if( mask & (1 << j) ) {
-                  for( i = first; i <= last; i++ ) {
-                     eval( mach, i, j );
+            switch (decl->Declaration.Interpolate) {
+            case TGSI_INTERPOLATE_CONSTANT:
+               eval = eval_constant_coef;
+               break;
+
+            case TGSI_INTERPOLATE_LINEAR:
+               eval = eval_linear_coef;
+               break;
+
+            case TGSI_INTERPOLATE_PERSPECTIVE:
+               eval = eval_perspective_coef;
+               break;
+
+            default:
+               assert(0);
+               return;
+            }
+
+            for (j = 0; j < NUM_CHANNELS; j++) {
+               if (mask & (1 << j)) {
+                  for (i = first; i <= last; i++) {
+                     eval(mach, i, j);
                   }
                }
             }
@@ -1839,6 +1813,585 @@
    }
 }
 
+typedef void (* micro_op)(union tgsi_exec_channel *dst,
+                          const union tgsi_exec_channel *src);
+
+static void
+exec_scalar_unary(struct tgsi_exec_machine *mach,
+                  const struct tgsi_full_instruction *inst,
+                  micro_op op,
+                  enum tgsi_exec_datatype dst_datatype,
+                  enum tgsi_exec_datatype src_datatype)
+{
+   unsigned int chan;
+   union tgsi_exec_channel src;
+   union tgsi_exec_channel dst;
+
+   fetch_source(mach, &src, &inst->Src[0], CHAN_X, src_datatype);
+   op(&dst, &src);
+   for (chan = 0; chan < NUM_CHANNELS; chan++) {
+      if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+         store_dest(mach, &dst, &inst->Dst[0], inst, chan, dst_datatype);
+      }
+   }
+}
+
+static void
+exec_vector_unary(struct tgsi_exec_machine *mach,
+                  const struct tgsi_full_instruction *inst,
+                  micro_op op,
+                  enum tgsi_exec_datatype dst_datatype,
+                  enum tgsi_exec_datatype src_datatype)
+{
+   unsigned int chan;
+   struct tgsi_exec_vector dst;
+
+   for (chan = 0; chan < NUM_CHANNELS; chan++) {
+      if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+         union tgsi_exec_channel src;
+
+         fetch_source(mach, &src, &inst->Src[0], chan, src_datatype);
+         op(&dst.xyzw[chan], &src);
+      }
+   }
+   for (chan = 0; chan < NUM_CHANNELS; chan++) {
+      if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+         store_dest(mach, &dst.xyzw[chan], &inst->Dst[0], inst, chan, dst_datatype);
+      }
+   }
+}
+
+static void
+exec_vector_binary(struct tgsi_exec_machine *mach,
+                   const struct tgsi_full_instruction *inst,
+                   micro_op op,
+                   enum tgsi_exec_datatype dst_datatype,
+                   enum tgsi_exec_datatype src_datatype)
+{
+   unsigned int chan;
+   struct tgsi_exec_vector dst;
+
+   for (chan = 0; chan < NUM_CHANNELS; chan++) {
+      if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+         union tgsi_exec_channel src[2];
+
+         fetch_source(mach, &src[0], &inst->Src[0], chan, src_datatype);
+         fetch_source(mach, &src[1], &inst->Src[1], chan, src_datatype);
+         op(&dst.xyzw[chan], src);
+      }
+   }
+   for (chan = 0; chan < NUM_CHANNELS; chan++) {
+      if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+         store_dest(mach, &dst.xyzw[chan], &inst->Dst[0], inst, chan, dst_datatype);
+      }
+   }
+}
+
+static void
+exec_vector_trinary(struct tgsi_exec_machine *mach,
+                    const struct tgsi_full_instruction *inst,
+                    micro_op op,
+                    enum tgsi_exec_datatype dst_datatype,
+                    enum tgsi_exec_datatype src_datatype)
+{
+   unsigned int chan;
+   struct tgsi_exec_vector dst;
+
+   for (chan = 0; chan < NUM_CHANNELS; chan++) {
+      if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+         union tgsi_exec_channel src[3];
+
+         fetch_source(mach, &src[0], &inst->Src[0], chan, src_datatype);
+         fetch_source(mach, &src[1], &inst->Src[1], chan, src_datatype);
+         fetch_source(mach, &src[2], &inst->Src[2], chan, src_datatype);
+         op(&dst.xyzw[chan], src);
+      }
+   }
+   for (chan = 0; chan < NUM_CHANNELS; chan++) {
+      if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+         store_dest(mach, &dst.xyzw[chan], &inst->Dst[0], inst, chan, dst_datatype);
+      }
+   }
+}
+
+static void
+exec_dp3(struct tgsi_exec_machine *mach,
+         const struct tgsi_full_instruction *inst)
+{
+   unsigned int chan;
+   union tgsi_exec_channel arg[3];
+
+   fetch_source(mach, &arg[0], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+   fetch_source(mach, &arg[1], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+   micro_mul(&arg[2], &arg[0], &arg[1]);
+
+   for (chan = CHAN_Y; chan <= CHAN_Z; chan++) {
+      fetch_source(mach, &arg[0], &inst->Src[0], chan, TGSI_EXEC_DATA_FLOAT);
+      fetch_source(mach, &arg[1], &inst->Src[1], chan, TGSI_EXEC_DATA_FLOAT);
+      micro_mad(&arg[2], arg);
+   }
+
+   for (chan = 0; chan < NUM_CHANNELS; chan++) {
+      if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+         store_dest(mach, &arg[2], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+      }
+   }
+}
+
+static void
+exec_dp4(struct tgsi_exec_machine *mach,
+         const struct tgsi_full_instruction *inst)
+{
+   unsigned int chan;
+   union tgsi_exec_channel arg[3];
+
+   fetch_source(mach, &arg[0], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+   fetch_source(mach, &arg[1], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+   micro_mul(&arg[2], &arg[0], &arg[1]);
+
+   for (chan = CHAN_Y; chan <= CHAN_W; chan++) {
+      fetch_source(mach, &arg[0], &inst->Src[0], chan, TGSI_EXEC_DATA_FLOAT);
+      fetch_source(mach, &arg[1], &inst->Src[1], chan, TGSI_EXEC_DATA_FLOAT);
+      micro_mad(&arg[2], arg);
+   }
+
+   for (chan = 0; chan < NUM_CHANNELS; chan++) {
+      if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+         store_dest(mach, &arg[2], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+      }
+   }
+}
+
+static void
+exec_dp2a(struct tgsi_exec_machine *mach,
+          const struct tgsi_full_instruction *inst)
+{
+   unsigned int chan;
+   union tgsi_exec_channel arg[3];
+
+   fetch_source(mach, &arg[0], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+   fetch_source(mach, &arg[1], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+   micro_mul(&arg[2], &arg[0], &arg[1]);
+
+   fetch_source(mach, &arg[0], &inst->Src[0], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
+   fetch_source(mach, &arg[1], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
+   micro_mad(&arg[0], arg);
+
+   fetch_source(mach, &arg[1], &inst->Src[2], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+   micro_add(&arg[0], &arg[0], &arg[1]);
+
+   for (chan = 0; chan < NUM_CHANNELS; chan++) {
+      if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+         store_dest(mach, &arg[0], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+      }
+   }
+}
+
+static void
+exec_dph(struct tgsi_exec_machine *mach,
+         const struct tgsi_full_instruction *inst)
+{
+   unsigned int chan;
+   union tgsi_exec_channel arg[3];
+
+   fetch_source(mach, &arg[0], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+   fetch_source(mach, &arg[1], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+   micro_mul(&arg[2], &arg[0], &arg[1]);
+
+   fetch_source(mach, &arg[0], &inst->Src[0], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
+   fetch_source(mach, &arg[1], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
+   micro_mad(&arg[2], arg);
+
+   fetch_source(mach, &arg[0], &inst->Src[0], CHAN_Z, TGSI_EXEC_DATA_FLOAT);
+   fetch_source(mach, &arg[1], &inst->Src[1], CHAN_Z, TGSI_EXEC_DATA_FLOAT);
+   micro_mad(&arg[0], arg);
+
+   fetch_source(mach, &arg[1], &inst->Src[1], CHAN_W, TGSI_EXEC_DATA_FLOAT);
+   micro_add(&arg[0], &arg[0], &arg[1]);
+
+   for (chan = 0; chan < NUM_CHANNELS; chan++) {
+      if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+         store_dest(mach, &arg[0], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+      }
+   }
+}
+
+static void
+exec_dp2(struct tgsi_exec_machine *mach,
+         const struct tgsi_full_instruction *inst)
+{
+   unsigned int chan;
+   union tgsi_exec_channel arg[3];
+
+   fetch_source(mach, &arg[0], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+   fetch_source(mach, &arg[1], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+   micro_mul(&arg[2], &arg[0], &arg[1]);
+
+   fetch_source(mach, &arg[0], &inst->Src[0], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
+   fetch_source(mach, &arg[1], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
+   micro_mad(&arg[2], arg);
+
+   for (chan = 0; chan < NUM_CHANNELS; chan++) {
+      if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+         store_dest(mach, &arg[2], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+      }
+   }
+}
+
+static void
+exec_break(struct tgsi_exec_machine *mach)
+{
+   if (mach->BreakType == TGSI_EXEC_BREAK_INSIDE_LOOP) {
+      /* turn off loop channels for each enabled exec channel */
+      mach->LoopMask &= ~mach->ExecMask;
+      /* Todo: if mach->LoopMask == 0, jump to end of loop */
+      UPDATE_EXEC_MASK(mach);
+   } else {
+      assert(mach->BreakType == TGSI_EXEC_BREAK_INSIDE_SWITCH);
+
+      mach->Switch.mask = 0x0;
+
+      UPDATE_EXEC_MASK(mach);
+   }
+}
+
+static void
+exec_switch(struct tgsi_exec_machine *mach,
+            const struct tgsi_full_instruction *inst)
+{
+   assert(mach->SwitchStackTop < TGSI_EXEC_MAX_SWITCH_NESTING);
+   assert(mach->BreakStackTop < TGSI_EXEC_MAX_BREAK_STACK);
+
+   mach->SwitchStack[mach->SwitchStackTop++] = mach->Switch;
+   fetch_source(mach, &mach->Switch.selector, &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_UINT);
+   mach->Switch.mask = 0x0;
+   mach->Switch.defaultMask = 0x0;
+
+   mach->BreakStack[mach->BreakStackTop++] = mach->BreakType;
+   mach->BreakType = TGSI_EXEC_BREAK_INSIDE_SWITCH;
+
+   UPDATE_EXEC_MASK(mach);
+}
+
+static void
+exec_case(struct tgsi_exec_machine *mach,
+          const struct tgsi_full_instruction *inst)
+{
+   uint prevMask = mach->SwitchStack[mach->SwitchStackTop - 1].mask;
+   union tgsi_exec_channel src;
+   uint mask = 0;
+
+   fetch_source(mach, &src, &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_UINT);
+
+   if (mach->Switch.selector.u[0] == src.u[0]) {
+      mask |= 0x1;
+   }
+   if (mach->Switch.selector.u[1] == src.u[1]) {
+      mask |= 0x2;
+   }
+   if (mach->Switch.selector.u[2] == src.u[2]) {
+      mask |= 0x4;
+   }
+   if (mach->Switch.selector.u[3] == src.u[3]) {
+      mask |= 0x8;
+   }
+
+   mach->Switch.defaultMask |= mask;
+
+   mach->Switch.mask |= mask & prevMask;
+
+   UPDATE_EXEC_MASK(mach);
+}
+
+static void
+exec_default(struct tgsi_exec_machine *mach)
+{
+   uint prevMask = mach->SwitchStack[mach->SwitchStackTop - 1].mask;
+
+   mach->Switch.mask |= ~mach->Switch.defaultMask & prevMask;
+
+   UPDATE_EXEC_MASK(mach);
+}
+
+static void
+exec_endswitch(struct tgsi_exec_machine *mach)
+{
+   mach->Switch = mach->SwitchStack[--mach->SwitchStackTop];
+   mach->BreakType = mach->BreakStack[--mach->BreakStackTop];
+
+   UPDATE_EXEC_MASK(mach);
+}
+
+static void
+micro_i2f(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = (float)src->i[0];
+   dst->f[1] = (float)src->i[1];
+   dst->f[2] = (float)src->i[2];
+   dst->f[3] = (float)src->i[3];
+}
+
+static void
+micro_not(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->u[0] = ~src->u[0];
+   dst->u[1] = ~src->u[1];
+   dst->u[2] = ~src->u[2];
+   dst->u[3] = ~src->u[3];
+}
+
+static void
+micro_shl(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src[0].u[0] << src[1].u[0];
+   dst->u[1] = src[0].u[1] << src[1].u[1];
+   dst->u[2] = src[0].u[2] << src[1].u[2];
+   dst->u[3] = src[0].u[3] << src[1].u[3];
+}
+
+static void
+micro_and(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src[0].u[0] & src[1].u[0];
+   dst->u[1] = src[0].u[1] & src[1].u[1];
+   dst->u[2] = src[0].u[2] & src[1].u[2];
+   dst->u[3] = src[0].u[3] & src[1].u[3];
+}
+
+static void
+micro_or(union tgsi_exec_channel *dst,
+         const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src[0].u[0] | src[1].u[0];
+   dst->u[1] = src[0].u[1] | src[1].u[1];
+   dst->u[2] = src[0].u[2] | src[1].u[2];
+   dst->u[3] = src[0].u[3] | src[1].u[3];
+}
+
+static void
+micro_xor(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src[0].u[0] ^ src[1].u[0];
+   dst->u[1] = src[0].u[1] ^ src[1].u[1];
+   dst->u[2] = src[0].u[2] ^ src[1].u[2];
+   dst->u[3] = src[0].u[3] ^ src[1].u[3];
+}
+
+static void
+micro_f2i(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->i[0] = (int)src->f[0];
+   dst->i[1] = (int)src->f[1];
+   dst->i[2] = (int)src->f[2];
+   dst->i[3] = (int)src->f[3];
+}
+
+static void
+micro_idiv(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->i[0] = src[0].i[0] / src[1].i[0];
+   dst->i[1] = src[0].i[1] / src[1].i[1];
+   dst->i[2] = src[0].i[2] / src[1].i[2];
+   dst->i[3] = src[0].i[3] / src[1].i[3];
+}
+
+static void
+micro_imax(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->i[0] = src[0].i[0] > src[1].i[0] ? src[0].i[0] : src[1].i[0];
+   dst->i[1] = src[0].i[1] > src[1].i[1] ? src[0].i[1] : src[1].i[1];
+   dst->i[2] = src[0].i[2] > src[1].i[2] ? src[0].i[2] : src[1].i[2];
+   dst->i[3] = src[0].i[3] > src[1].i[3] ? src[0].i[3] : src[1].i[3];
+}
+
+static void
+micro_imin(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->i[0] = src[0].i[0] < src[1].i[0] ? src[0].i[0] : src[1].i[0];
+   dst->i[1] = src[0].i[1] < src[1].i[1] ? src[0].i[1] : src[1].i[1];
+   dst->i[2] = src[0].i[2] < src[1].i[2] ? src[0].i[2] : src[1].i[2];
+   dst->i[3] = src[0].i[3] < src[1].i[3] ? src[0].i[3] : src[1].i[3];
+}
+
+static void
+micro_isge(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->i[0] = src[0].i[0] >= src[1].i[0] ? -1 : 0;
+   dst->i[1] = src[0].i[1] >= src[1].i[1] ? -1 : 0;
+   dst->i[2] = src[0].i[2] >= src[1].i[2] ? -1 : 0;
+   dst->i[3] = src[0].i[3] >= src[1].i[3] ? -1 : 0;
+}
+
+static void
+micro_ishr(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->i[0] = src[0].i[0] >> src[1].i[0];
+   dst->i[1] = src[0].i[1] >> src[1].i[1];
+   dst->i[2] = src[0].i[2] >> src[1].i[2];
+   dst->i[3] = src[0].i[3] >> src[1].i[3];
+}
+
+static void
+micro_islt(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->i[0] = src[0].i[0] < src[1].i[0] ? -1 : 0;
+   dst->i[1] = src[0].i[1] < src[1].i[1] ? -1 : 0;
+   dst->i[2] = src[0].i[2] < src[1].i[2] ? -1 : 0;
+   dst->i[3] = src[0].i[3] < src[1].i[3] ? -1 : 0;
+}
+
+static void
+micro_f2u(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->u[0] = (uint)src->f[0];
+   dst->u[1] = (uint)src->f[1];
+   dst->u[2] = (uint)src->f[2];
+   dst->u[3] = (uint)src->f[3];
+}
+
+static void
+micro_u2f(union tgsi_exec_channel *dst,
+          const union tgsi_exec_channel *src)
+{
+   dst->f[0] = (float)src->u[0];
+   dst->f[1] = (float)src->u[1];
+   dst->f[2] = (float)src->u[2];
+   dst->f[3] = (float)src->u[3];
+}
+
+static void
+micro_uadd(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src[0].u[0] + src[1].u[0];
+   dst->u[1] = src[0].u[1] + src[1].u[1];
+   dst->u[2] = src[0].u[2] + src[1].u[2];
+   dst->u[3] = src[0].u[3] + src[1].u[3];
+}
+
+static void
+micro_udiv(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src[0].u[0] / src[1].u[0];
+   dst->u[1] = src[0].u[1] / src[1].u[1];
+   dst->u[2] = src[0].u[2] / src[1].u[2];
+   dst->u[3] = src[0].u[3] / src[1].u[3];
+}
+
+static void
+micro_umad(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src[0].u[0] * src[1].u[0] + src[2].u[0];
+   dst->u[1] = src[0].u[1] * src[1].u[1] + src[2].u[1];
+   dst->u[2] = src[0].u[2] * src[1].u[2] + src[2].u[2];
+   dst->u[3] = src[0].u[3] * src[1].u[3] + src[2].u[3];
+}
+
+static void
+micro_umax(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src[0].u[0] > src[1].u[0] ? src[0].u[0] : src[1].u[0];
+   dst->u[1] = src[0].u[1] > src[1].u[1] ? src[0].u[1] : src[1].u[1];
+   dst->u[2] = src[0].u[2] > src[1].u[2] ? src[0].u[2] : src[1].u[2];
+   dst->u[3] = src[0].u[3] > src[1].u[3] ? src[0].u[3] : src[1].u[3];
+}
+
+static void
+micro_umin(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src[0].u[0] < src[1].u[0] ? src[0].u[0] : src[1].u[0];
+   dst->u[1] = src[0].u[1] < src[1].u[1] ? src[0].u[1] : src[1].u[1];
+   dst->u[2] = src[0].u[2] < src[1].u[2] ? src[0].u[2] : src[1].u[2];
+   dst->u[3] = src[0].u[3] < src[1].u[3] ? src[0].u[3] : src[1].u[3];
+}
+
+static void
+micro_umod(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src[0].u[0] % src[1].u[0];
+   dst->u[1] = src[0].u[1] % src[1].u[1];
+   dst->u[2] = src[0].u[2] % src[1].u[2];
+   dst->u[3] = src[0].u[3] % src[1].u[3];
+}
+
+static void
+micro_umul(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src[0].u[0] * src[1].u[0];
+   dst->u[1] = src[0].u[1] * src[1].u[1];
+   dst->u[2] = src[0].u[2] * src[1].u[2];
+   dst->u[3] = src[0].u[3] * src[1].u[3];
+}
+
+static void
+micro_useq(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src[0].u[0] == src[1].u[0] ? ~0 : 0;
+   dst->u[1] = src[0].u[1] == src[1].u[1] ? ~0 : 0;
+   dst->u[2] = src[0].u[2] == src[1].u[2] ? ~0 : 0;
+   dst->u[3] = src[0].u[3] == src[1].u[3] ? ~0 : 0;
+}
+
+static void
+micro_usge(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src[0].u[0] >= src[1].u[0] ? ~0 : 0;
+   dst->u[1] = src[0].u[1] >= src[1].u[1] ? ~0 : 0;
+   dst->u[2] = src[0].u[2] >= src[1].u[2] ? ~0 : 0;
+   dst->u[3] = src[0].u[3] >= src[1].u[3] ? ~0 : 0;
+}
+
+static void
+micro_ushr(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src[0].u[0] >> src[1].u[0];
+   dst->u[1] = src[0].u[1] >> src[1].u[1];
+   dst->u[2] = src[0].u[2] >> src[1].u[2];
+   dst->u[3] = src[0].u[3] >> src[1].u[3];
+}
+
+static void
+micro_uslt(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src[0].u[0] < src[1].u[0] ? ~0 : 0;
+   dst->u[1] = src[0].u[1] < src[1].u[1] ? ~0 : 0;
+   dst->u[2] = src[0].u[2] < src[1].u[2] ? ~0 : 0;
+   dst->u[3] = src[0].u[3] < src[1].u[3] ? ~0 : 0;
+}
+
+static void
+micro_usne(union tgsi_exec_channel *dst,
+           const union tgsi_exec_channel *src)
+{
+   dst->u[0] = src[0].u[0] != src[1].u[0] ? ~0 : 0;
+   dst->u[1] = src[0].u[1] != src[1].u[1] ? ~0 : 0;
+   dst->u[2] = src[0].u[2] != src[1].u[2] ? ~0 : 0;
+   dst->u[3] = src[0].u[3] != src[1].u[3] ? ~0 : 0;
+}
+
 static void
 exec_instruction(
    struct tgsi_exec_machine *mach,
@@ -1847,50 +2400,24 @@
 {
    uint chan_index;
    union tgsi_exec_channel r[10];
+   union tgsi_exec_channel d[8];
 
    (*pc)++;
 
    switch (inst->Instruction.Opcode) {
    case TGSI_OPCODE_ARL:
-   case TGSI_OPCODE_FLR:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         micro_flr( &r[0], &r[0] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_unary(mach, inst, micro_arl, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_MOV:
-      if (inst->Flags & SOA_DEPENDENCY_FLAG) {
-         /* Do all fetches into temp regs, then do all stores to avoid
-          * intermediate/accidental clobbering.  This could be done all the
-          * time for MOV but for other instructions we'll need more temps...
-          */
-         FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-            FETCH( &r[chan_index], 0, chan_index );
-         }
-         FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-            STORE( &r[chan_index], 0, chan_index );
-         }
-      }
-      else {
-         FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-            FETCH( &r[0], 0, chan_index );
-            STORE( &r[0], 0, chan_index );
-         }
-      }
+      exec_vector_unary(mach, inst, micro_mov, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_LIT:
-      if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) {
-         STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X );
-      }
-
       if (IS_CHANNEL_ENABLED( *inst, CHAN_Y ) || IS_CHANNEL_ENABLED( *inst, CHAN_Z )) {
          FETCH( &r[0], 0, CHAN_X );
          if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) {
-            micro_max( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] );
-            STORE( &r[0], 0, CHAN_Y );
+            micro_max(&d[CHAN_Y], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]);
          }
 
          if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) {
@@ -1901,34 +2428,30 @@
             micro_min( &r[2], &r[2], &mach->Temps[TEMP_128_I].xyzw[TEMP_128_C] );
             micro_max( &r[2], &r[2], &mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C] );
             micro_pow( &r[1], &r[1], &r[2] );
-            micro_lt( &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] );
-            STORE( &r[0], 0, CHAN_Z );
+            micro_lt(&d[CHAN_Z], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]);
+         }
+
+         if (IS_CHANNEL_ENABLED(*inst, CHAN_Y)) {
+            STORE(&d[CHAN_Y], 0, CHAN_Y);
+         }
+         if (IS_CHANNEL_ENABLED(*inst, CHAN_Z)) {
+            STORE(&d[CHAN_Z], 0, CHAN_Z);
          }
       }
-
+      if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) {
+         STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X );
+      }
       if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) {
          STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W );
       }
       break;
 
    case TGSI_OPCODE_RCP:
-   /* TGSI_OPCODE_RECIP */
-      FETCH( &r[0], 0, CHAN_X );
-      micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] );
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_scalar_unary(mach, inst, micro_rcp, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_RSQ:
-   /* TGSI_OPCODE_RECIPSQRT */
-      FETCH( &r[0], 0, CHAN_X );
-      micro_abs( &r[0], &r[0] );
-      micro_sqrt( &r[0], &r[0] );
-      micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] );
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_scalar_unary(mach, inst, micro_rsq, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_EXP:
@@ -1973,14 +2496,13 @@
       break;
 
    case TGSI_OPCODE_MUL:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index )
-      {
+      FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
          FETCH(&r[0], 0, chan_index);
          FETCH(&r[1], 1, chan_index);
-
-         micro_mul( &r[0], &r[0], &r[1] );
-
-         STORE(&r[0], 0, chan_index);
+         micro_mul(&d[chan_index], &r[0], &r[1]);
+      }
+      FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
+         STORE(&d[chan_index], 0, chan_index);
       }
       break;
 
@@ -1988,82 +2510,45 @@
       FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
          FETCH( &r[0], 0, chan_index );
          FETCH( &r[1], 1, chan_index );
-         micro_add( &r[0], &r[0], &r[1] );
-         STORE( &r[0], 0, chan_index );
+         micro_add(&d[chan_index], &r[0], &r[1]);
+      }
+      FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
+         STORE(&d[chan_index], 0, chan_index);
       }
       break;
 
    case TGSI_OPCODE_DP3:
-   /* TGSI_OPCODE_DOT3 */
-      FETCH( &r[0], 0, CHAN_X );
-      FETCH( &r[1], 1, CHAN_X );
-      micro_mul( &r[0], &r[0], &r[1] );
-
-      FETCH( &r[1], 0, CHAN_Y );
-      FETCH( &r[2], 1, CHAN_Y );
-      micro_mul( &r[1], &r[1], &r[2] );
-      micro_add( &r[0], &r[0], &r[1] );
-
-      FETCH( &r[1], 0, CHAN_Z );
-      FETCH( &r[2], 1, CHAN_Z );
-      micro_mul( &r[1], &r[1], &r[2] );
-      micro_add( &r[0], &r[0], &r[1] );
-
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_dp3(mach, inst);
       break;
 
-    case TGSI_OPCODE_DP4:
-    /* TGSI_OPCODE_DOT4 */
-       FETCH(&r[0], 0, CHAN_X);
-       FETCH(&r[1], 1, CHAN_X);
-
-       micro_mul( &r[0], &r[0], &r[1] );
-
-       FETCH(&r[1], 0, CHAN_Y);
-       FETCH(&r[2], 1, CHAN_Y);
-
-       micro_mul( &r[1], &r[1], &r[2] );
-       micro_add( &r[0], &r[0], &r[1] );
-
-       FETCH(&r[1], 0, CHAN_Z);
-       FETCH(&r[2], 1, CHAN_Z);
-
-       micro_mul( &r[1], &r[1], &r[2] );
-       micro_add( &r[0], &r[0], &r[1] );
-
-       FETCH(&r[1], 0, CHAN_W);
-       FETCH(&r[2], 1, CHAN_W);
-
-       micro_mul( &r[1], &r[1], &r[2] );
-       micro_add( &r[0], &r[0], &r[1] );
-
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( &r[0], 0, chan_index );
-      }
+   case TGSI_OPCODE_DP4:
+      exec_dp4(mach, inst);
       break;
 
    case TGSI_OPCODE_DST:
-      if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) {
-         STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X );
-      }
-
       if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) {
          FETCH( &r[0], 0, CHAN_Y );
          FETCH( &r[1], 1, CHAN_Y);
-         micro_mul( &r[0], &r[0], &r[1] );
-         STORE( &r[0], 0, CHAN_Y );
+         micro_mul(&d[CHAN_Y], &r[0], &r[1]);
       }
-
       if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) {
-         FETCH( &r[0], 0, CHAN_Z );
-         STORE( &r[0], 0, CHAN_Z );
+         FETCH(&d[CHAN_Z], 0, CHAN_Z);
+      }
+      if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) {
+         FETCH(&d[CHAN_W], 1, CHAN_W);
       }
 
-      if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) {
-         FETCH( &r[0], 1, CHAN_W );
-         STORE( &r[0], 0, CHAN_W );
+      if (IS_CHANNEL_ENABLED(*inst, CHAN_X)) {
+         STORE(&mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X);
+      }
+      if (IS_CHANNEL_ENABLED(*inst, CHAN_Y)) {
+         STORE(&d[CHAN_Y], 0, CHAN_Y);
+      }
+      if (IS_CHANNEL_ENABLED(*inst, CHAN_Z)) {
+         STORE(&d[CHAN_Z], 0, CHAN_Z);
+      }
+      if (IS_CHANNEL_ENABLED(*inst, CHAN_W)) {
+         STORE(&d[CHAN_W], 0, CHAN_W);
       }
       break;
 
@@ -2073,9 +2558,10 @@
          FETCH(&r[1], 1, chan_index);
 
          /* XXX use micro_min()?? */
-         micro_lt( &r[0], &r[0], &r[1], &r[0], &r[1] );
-
-         STORE(&r[0], 0, chan_index);
+         micro_lt(&d[chan_index], &r[0], &r[1], &r[0], &r[1]);
+      }
+      FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
+         STORE(&d[chan_index], 0, chan_index);
       }
       break;
 
@@ -2085,67 +2571,38 @@
          FETCH(&r[1], 1, chan_index);
 
          /* XXX use micro_max()?? */
-         micro_lt( &r[0], &r[0], &r[1], &r[1], &r[0] );
-
-         STORE(&r[0], 0, chan_index );
+         micro_lt(&d[chan_index], &r[0], &r[1], &r[1], &r[0] );
+      }
+      FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
+         STORE(&d[chan_index], 0, chan_index);
       }
       break;
 
    case TGSI_OPCODE_SLT:
-   /* TGSI_OPCODE_SETLT */
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         FETCH( &r[1], 1, chan_index );
-         micro_lt( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_binary(mach, inst, micro_slt, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_SGE:
-   /* TGSI_OPCODE_SETGE */
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         FETCH( &r[1], 1, chan_index );
-         micro_le( &r[0], &r[1], &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_binary(mach, inst, micro_sge, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_MAD:
-   /* TGSI_OPCODE_MADD */
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         FETCH( &r[1], 1, chan_index );
-         micro_mul( &r[0], &r[0], &r[1] );
-         FETCH( &r[1], 2, chan_index );
-         micro_add( &r[0], &r[0], &r[1] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_trinary(mach, inst, micro_mad, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_SUB:
       FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
          FETCH(&r[0], 0, chan_index);
          FETCH(&r[1], 1, chan_index);
-
-         micro_sub( &r[0], &r[0], &r[1] );
-
-         STORE(&r[0], 0, chan_index);
+         micro_sub(&d[chan_index], &r[0], &r[1]);
+      }
+      FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
+         STORE(&d[chan_index], 0, chan_index);
       }
       break;
 
    case TGSI_OPCODE_LRP:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH(&r[0], 0, chan_index);
-         FETCH(&r[1], 1, chan_index);
-         FETCH(&r[2], 2, chan_index);
-
-         micro_sub( &r[1], &r[1], &r[2] );
-         micro_mul( &r[0], &r[0], &r[1] );
-         micro_add( &r[0], &r[0], &r[2] );
-
-         STORE(&r[0], 0, chan_index);
-      }
+      exec_vector_trinary(mach, inst, micro_lrp, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_CND:
@@ -2153,35 +2610,19 @@
          FETCH(&r[0], 0, chan_index);
          FETCH(&r[1], 1, chan_index);
          FETCH(&r[2], 2, chan_index);
-         micro_lt(&r[0], &mach->Temps[TEMP_HALF_I].xyzw[TEMP_HALF_C], &r[2], &r[0], &r[1]);
-         STORE(&r[0], 0, chan_index);
+         micro_lt(&d[chan_index], &mach->Temps[TEMP_HALF_I].xyzw[TEMP_HALF_C], &r[2], &r[0], &r[1]);
+      }
+      FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
+         STORE(&d[chan_index], 0, chan_index);
       }
       break;
 
    case TGSI_OPCODE_DP2A:
-      FETCH( &r[0], 0, CHAN_X );
-      FETCH( &r[1], 1, CHAN_X );
-      micro_mul( &r[0], &r[0], &r[1] );
-
-      FETCH( &r[1], 0, CHAN_Y );
-      FETCH( &r[2], 1, CHAN_Y );
-      micro_mul( &r[1], &r[1], &r[2] );
-      micro_add( &r[0], &r[0], &r[1] );
-
-      FETCH( &r[2], 2, CHAN_X );
-      micro_add( &r[0], &r[0], &r[2] );
-
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_dp2a(mach, inst);
       break;
 
    case TGSI_OPCODE_FRC:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         micro_frc( &r[0], &r[0] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_unary(mach, inst, micro_frc, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_CLAMP:
@@ -2190,40 +2631,27 @@
          FETCH(&r[1], 1, chan_index);
          micro_max(&r[0], &r[0], &r[1]);
          FETCH(&r[1], 2, chan_index);
-         micro_min(&r[0], &r[0], &r[1]);
-         STORE(&r[0], 0, chan_index);
+         micro_min(&d[chan_index], &r[0], &r[1]);
       }
+      FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
+         STORE(&d[chan_index], 0, chan_index);
+      }
+      break;
+
+   case TGSI_OPCODE_FLR:
+      exec_vector_unary(mach, inst, micro_flr, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_ROUND:
-   case TGSI_OPCODE_ARR:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         micro_rnd( &r[0], &r[0] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_unary(mach, inst, micro_rnd, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_EX2:
-      FETCH(&r[0], 0, CHAN_X);
-
-#if FAST_MATH
-      micro_exp2( &r[0], &r[0] );
-#else
-      micro_pow( &r[0], &mach->Temps[TEMP_2_I].xyzw[TEMP_2_C], &r[0] );
-#endif
-
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_scalar_unary(mach, inst, micro_exp2, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_LG2:
-      FETCH( &r[0], 0, CHAN_X );
-      micro_lg2( &r[0], &r[0] );
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_scalar_unary(mach, inst, micro_lg2, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_POW:
@@ -2247,11 +2675,7 @@
       FETCH(&r[4], 1, CHAN_Y);
 
       micro_mul( &r[5], &r[3], &r[4] );
-      micro_sub( &r[2], &r[2], &r[5] );
-
-      if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) {
-         STORE( &r[2], 0, CHAN_X );
-      }
+      micro_sub(&d[CHAN_X], &r[2], &r[5]);
 
       FETCH(&r[2], 1, CHAN_X);
 
@@ -2260,34 +2684,29 @@
       FETCH(&r[5], 0, CHAN_X);
 
       micro_mul( &r[1], &r[1], &r[5] );
-      micro_sub( &r[3], &r[3], &r[1] );
-
-      if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) {
-         STORE( &r[3], 0, CHAN_Y );
-      }
+      micro_sub(&d[CHAN_Y], &r[3], &r[1]);
 
       micro_mul( &r[5], &r[5], &r[4] );
       micro_mul( &r[0], &r[0], &r[2] );
-      micro_sub( &r[5], &r[5], &r[0] );
+      micro_sub(&d[CHAN_Z], &r[5], &r[0]);
 
-      if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) {
-         STORE( &r[5], 0, CHAN_Z );
+      if (IS_CHANNEL_ENABLED(*inst, CHAN_X)) {
+         STORE(&d[CHAN_X], 0, CHAN_X);
       }
-
+      if (IS_CHANNEL_ENABLED(*inst, CHAN_Y)) {
+         STORE(&d[CHAN_Y], 0, CHAN_Y);
+      }
+      if (IS_CHANNEL_ENABLED(*inst, CHAN_Z)) {
+         STORE(&d[CHAN_Z], 0, CHAN_Z);
+      }
       if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) {
          STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W );
       }
       break;
 
-    case TGSI_OPCODE_ABS:
-       FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-          FETCH(&r[0], 0, chan_index);
-
-          micro_abs( &r[0], &r[0] );
-
-          STORE(&r[0], 0, chan_index);
-       }
-       break;
+   case TGSI_OPCODE_ABS:
+      exec_vector_unary(mach, inst, micro_abs, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
+      break;
 
    case TGSI_OPCODE_RCC:
       FETCH(&r[0], 0, CHAN_X);
@@ -2299,56 +2718,19 @@
       break;
 
    case TGSI_OPCODE_DPH:
-      FETCH(&r[0], 0, CHAN_X);
-      FETCH(&r[1], 1, CHAN_X);
-
-      micro_mul( &r[0], &r[0], &r[1] );
-
-      FETCH(&r[1], 0, CHAN_Y);
-      FETCH(&r[2], 1, CHAN_Y);
-
-      micro_mul( &r[1], &r[1], &r[2] );
-      micro_add( &r[0], &r[0], &r[1] );
-
-      FETCH(&r[1], 0, CHAN_Z);
-      FETCH(&r[2], 1, CHAN_Z);
-
-      micro_mul( &r[1], &r[1], &r[2] );
-      micro_add( &r[0], &r[0], &r[1] );
-
-      FETCH(&r[1], 1, CHAN_W);
-
-      micro_add( &r[0], &r[0], &r[1] );
-
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_dph(mach, inst);
       break;
 
    case TGSI_OPCODE_COS:
-      FETCH(&r[0], 0, CHAN_X);
-
-      micro_cos( &r[0], &r[0] );
-
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_scalar_unary(mach, inst, micro_cos, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_DDX:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         micro_ddx( &r[0], &r[0] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_unary(mach, inst, micro_ddx, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_DDY:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         micro_ddy( &r[0], &r[0] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_unary(mach, inst, micro_ddy, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_KILP:
@@ -2425,14 +2807,7 @@
       break;
 
    case TGSI_OPCODE_SEQ:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         FETCH( &r[1], 1, chan_index );
-         micro_eq( &r[0], &r[0], &r[1],
-                   &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C],
-                   &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_binary(mach, inst, micro_seq, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_SFL:
@@ -2442,38 +2817,19 @@
       break;
 
    case TGSI_OPCODE_SGT:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         FETCH( &r[1], 1, chan_index );
-         micro_le( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_binary(mach, inst, micro_sgt, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_SIN:
-      FETCH( &r[0], 0, CHAN_X );
-      micro_sin( &r[0], &r[0] );
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_scalar_unary(mach, inst, micro_sin, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_SLE:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         FETCH( &r[1], 1, chan_index );
-         micro_le( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_binary(mach, inst, micro_sle, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_SNE:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         FETCH( &r[1], 1, chan_index );
-         micro_eq( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_binary(mach, inst, micro_sne, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_STR:
@@ -2486,14 +2842,14 @@
       /* simple texture lookup */
       /* src[0] = texcoord */
       /* src[1] = sampler unit */
-      exec_tex(mach, inst, FALSE, FALSE);
+      exec_tex(mach, inst, TEX_MODIFIER_NONE);
       break;
 
    case TGSI_OPCODE_TXB:
       /* Texture lookup with lod bias */
       /* src[0] = texcoord (src[0].w = LOD bias) */
       /* src[1] = sampler unit */
-      exec_tex(mach, inst, TRUE, FALSE);
+      exec_tex(mach, inst, TEX_MODIFIER_LOD_BIAS);
       break;
 
    case TGSI_OPCODE_TXD:
@@ -2502,21 +2858,21 @@
       /* src[1] = d[strq]/dx */
       /* src[2] = d[strq]/dy */
       /* src[3] = sampler unit */
-      assert (0);
+      exec_txd(mach, inst);
       break;
 
    case TGSI_OPCODE_TXL:
       /* Texture lookup with explit LOD */
       /* src[0] = texcoord (src[0].w = LOD) */
       /* src[1] = sampler unit */
-      exec_tex(mach, inst, TRUE, FALSE);
+      exec_tex(mach, inst, TEX_MODIFIER_EXPLICIT_LOD);
       break;
 
    case TGSI_OPCODE_TXP:
       /* Texture lookup with projection */
       /* src[0] = texcoord (src[0].w = projection) */
       /* src[1] = sampler unit */
-      exec_tex(mach, inst, FALSE, TRUE);
+      exec_tex(mach, inst, TEX_MODIFIER_PROJECTED);
       break;
 
    case TGSI_OPCODE_UP2H:
@@ -2546,13 +2902,8 @@
          micro_mul(&r[3], &r[3], &r[1]);
          micro_add(&r[2], &r[2], &r[3]);
          FETCH(&r[3], 0, CHAN_X);
-         micro_add(&r[2], &r[2], &r[3]);
-         if (IS_CHANNEL_ENABLED(*inst, CHAN_X)) {
-            STORE(&r[2], 0, CHAN_X);
-         }
-         if (IS_CHANNEL_ENABLED(*inst, CHAN_Z)) {
-            STORE(&r[2], 0, CHAN_Z);
-         }
+         micro_add(&d[CHAN_X], &r[2], &r[3]);
+         
       }
       if (IS_CHANNEL_ENABLED(*inst, CHAN_Y) ||
           IS_CHANNEL_ENABLED(*inst, CHAN_W)) {
@@ -2562,13 +2913,20 @@
          micro_mul(&r[3], &r[3], &r[1]);
          micro_add(&r[2], &r[2], &r[3]);
          FETCH(&r[3], 0, CHAN_Y);
-         micro_add(&r[2], &r[2], &r[3]);
-         if (IS_CHANNEL_ENABLED(*inst, CHAN_Y)) {
-            STORE(&r[2], 0, CHAN_Y);
-         }
-         if (IS_CHANNEL_ENABLED(*inst, CHAN_W)) {
-            STORE(&r[2], 0, CHAN_W);
-         }
+         micro_add(&d[CHAN_Y], &r[2], &r[3]);
+         
+      }
+      if (IS_CHANNEL_ENABLED(*inst, CHAN_X)) {
+         STORE(&d[CHAN_X], 0, CHAN_X);
+      }
+      if (IS_CHANNEL_ENABLED(*inst, CHAN_Y)) {
+         STORE(&d[CHAN_Y], 0, CHAN_Y);
+      }
+      if (IS_CHANNEL_ENABLED(*inst, CHAN_Z)) {
+         STORE(&d[CHAN_X], 0, CHAN_Z);
+      }
+      if (IS_CHANNEL_ENABLED(*inst, CHAN_W)) {
+         STORE(&d[CHAN_Y], 0, CHAN_W);
       }
       break;
 
@@ -2576,6 +2934,10 @@
       assert (0);
       break;
 
+   case TGSI_OPCODE_ARR:
+      exec_vector_unary(mach, inst, micro_arr, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_FLOAT);
+      break;
+
    case TGSI_OPCODE_BRA:
       assert (0);
       break;
@@ -2595,6 +2957,8 @@
          mach->CallStack[mach->CallStackTop].CondStackTop = mach->CondStackTop;
          mach->CallStack[mach->CallStackTop].LoopStackTop = mach->LoopStackTop;
          mach->CallStack[mach->CallStackTop].ContStackTop = mach->ContStackTop;
+         mach->CallStack[mach->CallStackTop].SwitchStackTop = mach->SwitchStackTop;
+         mach->CallStack[mach->CallStackTop].BreakStackTop = mach->BreakStackTop;
          /* note that PC was already incremented above */
          mach->CallStack[mach->CallStackTop].ReturnAddr = *pc;
 
@@ -2602,16 +2966,21 @@
 
          /* Second, push the Cond, Loop, Cont, Func stacks */
          assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING);
-         mach->CondStack[mach->CondStackTop++] = mach->CondMask;
          assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
-         mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
          assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
-         mach->ContStack[mach->ContStackTop++] = mach->ContMask;
+         assert(mach->SwitchStackTop < TGSI_EXEC_MAX_SWITCH_NESTING);
+         assert(mach->BreakStackTop < TGSI_EXEC_MAX_BREAK_STACK);
          assert(mach->FuncStackTop < TGSI_EXEC_MAX_CALL_NESTING);
+
+         mach->CondStack[mach->CondStackTop++] = mach->CondMask;
+         mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
+         mach->ContStack[mach->ContStackTop++] = mach->ContMask;
+         mach->SwitchStack[mach->SwitchStackTop++] = mach->Switch;
+         mach->BreakStack[mach->BreakStackTop++] = mach->BreakType;
          mach->FuncStack[mach->FuncStackTop++] = mach->FuncMask;
 
          /* Finally, jump to the subroutine */
-         *pc = inst->InstructionExtLabel.Label;
+         *pc = inst->Label.Label;
       }
       break;
 
@@ -2640,6 +3009,12 @@
          mach->ContStackTop = mach->CallStack[mach->CallStackTop].ContStackTop;
          mach->ContMask = mach->ContStack[mach->ContStackTop];
 
+         mach->SwitchStackTop = mach->CallStack[mach->CallStackTop].SwitchStackTop;
+         mach->Switch = mach->SwitchStack[mach->SwitchStackTop];
+
+         mach->BreakStackTop = mach->CallStack[mach->CallStackTop].BreakStackTop;
+         mach->BreakType = mach->BreakStack[mach->BreakStackTop];
+
          assert(mach->FuncStackTop > 0);
          mach->FuncMask = mach->FuncStack[--mach->FuncStackTop];
 
@@ -2650,12 +3025,7 @@
       break;
 
    case TGSI_OPCODE_SSG:
-   /* TGSI_OPCODE_SGN */
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         micro_sgn( &r[0], &r[0] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_unary(mach, inst, micro_sgn, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_CMP:
@@ -2663,10 +3033,10 @@
          FETCH(&r[0], 0, chan_index);
          FETCH(&r[1], 1, chan_index);
          FETCH(&r[2], 2, chan_index);
-
-         micro_lt( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[1], &r[2] );
-
-         STORE(&r[0], 0, chan_index);
+         micro_lt(&d[chan_index], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[1], &r[2]);
+      }
+      FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
+         STORE(&d[chan_index], 0, chan_index);
       }
       break;
 
@@ -2762,18 +3132,7 @@
       break;
 
    case TGSI_OPCODE_DP2:
-      FETCH( &r[0], 0, CHAN_X );
-      FETCH( &r[1], 1, CHAN_X );
-      micro_mul( &r[0], &r[0], &r[1] );
-
-      FETCH( &r[1], 0, CHAN_Y );
-      FETCH( &r[2], 1, CHAN_Y );
-      micro_mul( &r[1], &r[1], &r[2] );
-      micro_add( &r[0], &r[0], &r[1] );
-
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_dp2(mach, inst);
       break;
 
    case TGSI_OPCODE_IF:
@@ -2839,71 +3198,31 @@
       break;
 
    case TGSI_OPCODE_CEIL:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         micro_ceil( &r[0], &r[0] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_unary(mach, inst, micro_ceil, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_I2F:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         micro_i2f( &r[0], &r[0] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_unary(mach, inst, micro_i2f, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_INT);
       break;
 
    case TGSI_OPCODE_NOT:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         micro_not( &r[0], &r[0] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_unary(mach, inst, micro_not, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
       break;
 
    case TGSI_OPCODE_TRUNC:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         micro_trunc( &r[0], &r[0] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_unary(mach, inst, micro_trunc, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_SHL:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         FETCH( &r[1], 1, chan_index );
-         micro_shl( &r[0], &r[0], &r[1] );
-         STORE( &r[0], 0, chan_index );
-      }
-      break;
-
-   case TGSI_OPCODE_SHR:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         FETCH( &r[1], 1, chan_index );
-         micro_ishr( &r[0], &r[0], &r[1] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_binary(mach, inst, micro_shl, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
       break;
 
    case TGSI_OPCODE_AND:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         FETCH( &r[1], 1, chan_index );
-         micro_and( &r[0], &r[0], &r[1] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_binary(mach, inst, micro_and, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
       break;
 
    case TGSI_OPCODE_OR:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         FETCH( &r[1], 1, chan_index );
-         micro_or( &r[0], &r[0], &r[1] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_binary(mach, inst, micro_or, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
       break;
 
    case TGSI_OPCODE_MOD:
@@ -2911,12 +3230,7 @@
       break;
 
    case TGSI_OPCODE_XOR:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         FETCH( &r[1], 1, chan_index );
-         micro_xor( &r[0], &r[0], &r[1] );
-         STORE( &r[0], 0, chan_index );
-      }
+      exec_vector_binary(mach, inst, micro_xor, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
       break;
 
    case TGSI_OPCODE_SAD:
@@ -2932,13 +3246,11 @@
       break;
 
    case TGSI_OPCODE_EMIT:
-      mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += 16;
-      mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]]++;
+      emit_vertex(mach);
       break;
 
    case TGSI_OPCODE_ENDPRIM:
-      mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]++;
-      mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0;
+      emit_primitive(mach);
       break;
 
    case TGSI_OPCODE_BGNFOR:
@@ -2946,43 +3258,62 @@
       for (chan_index = 0; chan_index < 3; chan_index++) {
          FETCH( &mach->LoopCounterStack[mach->LoopCounterStackTop].xyzw[chan_index], 0, chan_index );
       }
-      STORE( &mach->LoopCounterStack[mach->LoopCounterStackTop].xyzw[CHAN_Y], 0, CHAN_X );
       ++mach->LoopCounterStackTop;
+      STORE(&mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X], 0, CHAN_X);
+      /* update LoopMask */
+      if (mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y].f[0] <= 0.0f) {
+         mach->LoopMask &= ~0x1;
+      }
+      if (mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y].f[1] <= 0.0f) {
+         mach->LoopMask &= ~0x2;
+      }
+      if (mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y].f[2] <= 0.0f) {
+         mach->LoopMask &= ~0x4;
+      }
+      if (mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y].f[3] <= 0.0f) {
+         mach->LoopMask &= ~0x8;
+      }
+      /* TODO: if mach->LoopMask == 0, jump to end of loop */
+      UPDATE_EXEC_MASK(mach);
       /* fall-through (for now) */
    case TGSI_OPCODE_BGNLOOP:
       /* push LoopMask and ContMasks */
       assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
-      mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
       assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
-      mach->ContStack[mach->ContStackTop++] = mach->ContMask;
       assert(mach->LoopLabelStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
+      assert(mach->BreakStackTop < TGSI_EXEC_MAX_BREAK_STACK);
+
+      mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
+      mach->ContStack[mach->ContStackTop++] = mach->ContMask;
       mach->LoopLabelStack[mach->LoopLabelStackTop++] = *pc - 1;
+      mach->BreakStack[mach->BreakStackTop++] = mach->BreakType;
+      mach->BreakType = TGSI_EXEC_BREAK_INSIDE_LOOP;
       break;
 
    case TGSI_OPCODE_ENDFOR:
       assert(mach->LoopCounterStackTop > 0);
-      micro_sub( &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X], 
-                 &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X],
-                 &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] );
+      micro_sub(&mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y], 
+                &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y],
+                &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]);
       /* update LoopMask */
-      if( mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X].f[0] <= 0) {
+      if (mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y].f[0] <= 0.0f) {
          mach->LoopMask &= ~0x1;
       }
-      if( mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X].f[1] <= 0 ) {
+      if (mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y].f[1] <= 0.0f) {
          mach->LoopMask &= ~0x2;
       }
-      if( mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X].f[2] <= 0 ) {
+      if (mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y].f[2] <= 0.0f) {
          mach->LoopMask &= ~0x4;
       }
-      if( mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X].f[3] <= 0 ) {
+      if (mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y].f[3] <= 0.0f) {
          mach->LoopMask &= ~0x8;
       }
-      micro_add( &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y], 
-                 &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y], 
-                 &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Z]);
+      micro_add(&mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X], 
+                &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X], 
+                &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Z]);
       assert(mach->LoopLabelStackTop > 0);
       inst = mach->Instructions + mach->LoopLabelStack[mach->LoopLabelStackTop - 1];
-      STORE( &mach->LoopCounterStack[mach->LoopCounterStackTop].xyzw[CHAN_Y], 0, CHAN_X );
+      STORE(&mach->LoopCounterStack[mach->LoopCounterStackTop].xyzw[CHAN_X], 0, CHAN_X);
       /* Restore ContMask, but don't pop */
       assert(mach->ContStackTop > 0);
       mach->ContMask = mach->ContStack[mach->ContStackTop - 1];
@@ -3003,6 +3334,8 @@
          --mach->LoopLabelStackTop;
          assert(mach->LoopCounterStackTop > 0);
          --mach->LoopCounterStackTop;
+
+         mach->BreakType = mach->BreakStack[--mach->BreakStackTop];
       }
       UPDATE_EXEC_MASK(mach);
       break;
@@ -3026,15 +3359,14 @@
          mach->ContMask = mach->ContStack[--mach->ContStackTop];
          assert(mach->LoopLabelStackTop > 0);
          --mach->LoopLabelStackTop;
+
+         mach->BreakType = mach->BreakStack[--mach->BreakStackTop];
       }
       UPDATE_EXEC_MASK(mach);
       break;
 
    case TGSI_OPCODE_BRK:
-      /* turn off loop channels for each enabled exec channel */
-      mach->LoopMask &= ~mach->ExecMask;
-      /* Todo: if mach->LoopMask == 0, jump to end of loop */
-      UPDATE_EXEC_MASK(mach);
+      exec_break(mach);
       break;
 
    case TGSI_OPCODE_CONT:
@@ -3049,18 +3381,171 @@
       break;
 
    case TGSI_OPCODE_ENDSUB:
-      /* no-op */
+      /*
+       * XXX: This really should be a no-op. We should never reach this opcode.
+       */
+
+      assert(mach->CallStackTop > 0);
+      mach->CallStackTop--;
+
+      mach->CondStackTop = mach->CallStack[mach->CallStackTop].CondStackTop;
+      mach->CondMask = mach->CondStack[mach->CondStackTop];
+
+      mach->LoopStackTop = mach->CallStack[mach->CallStackTop].LoopStackTop;
+      mach->LoopMask = mach->LoopStack[mach->LoopStackTop];
+
+      mach->ContStackTop = mach->CallStack[mach->CallStackTop].ContStackTop;
+      mach->ContMask = mach->ContStack[mach->ContStackTop];
+
+      mach->SwitchStackTop = mach->CallStack[mach->CallStackTop].SwitchStackTop;
+      mach->Switch = mach->SwitchStack[mach->SwitchStackTop];
+
+      mach->BreakStackTop = mach->CallStack[mach->CallStackTop].BreakStackTop;
+      mach->BreakType = mach->BreakStack[mach->BreakStackTop];
+
+      assert(mach->FuncStackTop > 0);
+      mach->FuncMask = mach->FuncStack[--mach->FuncStackTop];
+
+      *pc = mach->CallStack[mach->CallStackTop].ReturnAddr;
+
+      UPDATE_EXEC_MASK(mach);
       break;
 
    case TGSI_OPCODE_NOP:
       break;
 
+   case TGSI_OPCODE_BREAKC:
+      FETCH(&r[0], 0, CHAN_X);
+      /* update CondMask */
+      if (r[0].u[0] && (mach->ExecMask & 0x1)) {
+         mach->LoopMask &= ~0x1;
+      }
+      if (r[0].u[1] && (mach->ExecMask & 0x2)) {
+         mach->LoopMask &= ~0x2;
+      }
+      if (r[0].u[2] && (mach->ExecMask & 0x4)) {
+         mach->LoopMask &= ~0x4;
+      }
+      if (r[0].u[3] && (mach->ExecMask & 0x8)) {
+         mach->LoopMask &= ~0x8;
+      }
+      /* Todo: if mach->LoopMask == 0, jump to end of loop */
+      UPDATE_EXEC_MASK(mach);
+      break;
+
+   case TGSI_OPCODE_F2I:
+      exec_vector_unary(mach, inst, micro_f2i, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_FLOAT);
+      break;
+
+   case TGSI_OPCODE_IDIV:
+      exec_vector_binary(mach, inst, micro_idiv, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
+      break;
+
+   case TGSI_OPCODE_IMAX:
+      exec_vector_binary(mach, inst, micro_imax, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
+      break;
+
+   case TGSI_OPCODE_IMIN:
+      exec_vector_binary(mach, inst, micro_imin, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
+      break;
+
+   case TGSI_OPCODE_INEG:
+      exec_vector_unary(mach, inst, micro_ineg, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
+      break;
+
+   case TGSI_OPCODE_ISGE:
+      exec_vector_binary(mach, inst, micro_isge, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
+      break;
+
+   case TGSI_OPCODE_ISHR:
+      exec_vector_binary(mach, inst, micro_ishr, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
+      break;
+
+   case TGSI_OPCODE_ISLT:
+      exec_vector_binary(mach, inst, micro_islt, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
+      break;
+
+   case TGSI_OPCODE_F2U:
+      exec_vector_unary(mach, inst, micro_f2u, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_FLOAT);
+      break;
+
+   case TGSI_OPCODE_U2F:
+      exec_vector_unary(mach, inst, micro_u2f, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_UINT);
+      break;
+
+   case TGSI_OPCODE_UADD:
+      exec_vector_binary(mach, inst, micro_uadd, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+      break;
+
+   case TGSI_OPCODE_UDIV:
+      exec_vector_binary(mach, inst, micro_udiv, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+      break;
+
+   case TGSI_OPCODE_UMAD:
+      exec_vector_trinary(mach, inst, micro_umad, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+      break;
+
+   case TGSI_OPCODE_UMAX:
+      exec_vector_binary(mach, inst, micro_umax, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+      break;
+
+   case TGSI_OPCODE_UMIN:
+      exec_vector_binary(mach, inst, micro_umin, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+      break;
+
+   case TGSI_OPCODE_UMOD:
+      exec_vector_binary(mach, inst, micro_umod, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+      break;
+
+   case TGSI_OPCODE_UMUL:
+      exec_vector_binary(mach, inst, micro_umul, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+      break;
+
+   case TGSI_OPCODE_USEQ:
+      exec_vector_binary(mach, inst, micro_useq, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+      break;
+
+   case TGSI_OPCODE_USGE:
+      exec_vector_binary(mach, inst, micro_usge, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+      break;
+
+   case TGSI_OPCODE_USHR:
+      exec_vector_binary(mach, inst, micro_ushr, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+      break;
+
+   case TGSI_OPCODE_USLT:
+      exec_vector_binary(mach, inst, micro_uslt, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+      break;
+
+   case TGSI_OPCODE_USNE:
+      exec_vector_binary(mach, inst, micro_usne, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+      break;
+
+   case TGSI_OPCODE_SWITCH:
+      exec_switch(mach, inst);
+      break;
+
+   case TGSI_OPCODE_CASE:
+      exec_case(mach, inst);
+      break;
+
+   case TGSI_OPCODE_DEFAULT:
+      exec_default(mach);
+      break;
+
+   case TGSI_OPCODE_ENDSWITCH:
+      exec_endswitch(mach);
+      break;
+
    default:
       assert( 0 );
    }
 }
 
 
+#define DEBUG_EXECUTION 0
+
+
 /**
  * Run TGSI interpreter.
  * \return bitmask of "alive" quad components
@@ -3077,9 +3562,13 @@
    mach->FuncMask = 0xf;
    mach->ExecMask = 0xf;
 
+   mach->Switch.mask = 0xf;
+
    assert(mach->CondStackTop == 0);
    assert(mach->LoopStackTop == 0);
    assert(mach->ContStackTop == 0);
+   assert(mach->SwitchStackTop == 0);
+   assert(mach->BreakStackTop == 0);
    assert(mach->CallStackTop == 0);
 
    mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0;
@@ -3103,10 +3592,67 @@
       exec_declaration( mach, mach->Declarations+i );
    }
 
-   /* execute instructions, until pc is set to -1 */
-   while (pc != -1) {
-      assert(pc < (int) mach->NumInstructions);
-      exec_instruction( mach, mach->Instructions + pc, &pc );
+   {
+#if DEBUG_EXECUTION
+      struct tgsi_exec_vector temps[TGSI_EXEC_NUM_TEMPS + TGSI_EXEC_NUM_TEMP_EXTRAS];
+      struct tgsi_exec_vector outputs[PIPE_MAX_ATTRIBS];
+      uint inst = 1;
+
+      memcpy(temps, mach->Temps, sizeof(temps));
+      memcpy(outputs, mach->Outputs, sizeof(outputs));
+#endif
+
+      /* execute instructions, until pc is set to -1 */
+      while (pc != -1) {
+
+#if DEBUG_EXECUTION
+         uint i;
+
+         tgsi_dump_instruction(&mach->Instructions[pc], inst++);
+#endif
+
+         assert(pc < (int) mach->NumInstructions);
+         exec_instruction(mach, mach->Instructions + pc, &pc);
+
+#if DEBUG_EXECUTION
+         for (i = 0; i < TGSI_EXEC_NUM_TEMPS + TGSI_EXEC_NUM_TEMP_EXTRAS; i++) {
+            if (memcmp(&temps[i], &mach->Temps[i], sizeof(temps[i]))) {
+               uint j;
+
+               memcpy(&temps[i], &mach->Temps[i], sizeof(temps[i]));
+               debug_printf("TEMP[%2u] = ", i);
+               for (j = 0; j < 4; j++) {
+                  if (j > 0) {
+                     debug_printf("           ");
+                  }
+                  debug_printf("(%6f %u, %6f %u, %6f %u, %6f %u)\n",
+                               temps[i].xyzw[0].f[j], temps[i].xyzw[0].u[j],
+                               temps[i].xyzw[1].f[j], temps[i].xyzw[1].u[j],
+                               temps[i].xyzw[2].f[j], temps[i].xyzw[2].u[j],
+                               temps[i].xyzw[3].f[j], temps[i].xyzw[3].u[j]);
+               }
+            }
+         }
+         for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
+            if (memcmp(&outputs[i], &mach->Outputs[i], sizeof(outputs[i]))) {
+               uint j;
+
+               memcpy(&outputs[i], &mach->Outputs[i], sizeof(outputs[i]));
+               debug_printf("OUT[%2u] =  ", i);
+               for (j = 0; j < 4; j++) {
+                  if (j > 0) {
+                     debug_printf("           ");
+                  }
+                  debug_printf("(%6f %u, %6f %u, %6f %u, %6f %u)\n",
+                               outputs[i].xyzw[0].f[j], outputs[i].xyzw[0].u[j],
+                               outputs[i].xyzw[1].f[j], outputs[i].xyzw[1].u[j],
+                               outputs[i].xyzw[2].f[j], outputs[i].xyzw[2].u[j],
+                               outputs[i].xyzw[3].f[j], outputs[i].xyzw[3].u[j]);
+               }
+            }
+         }
+#endif
+      }
    }
 
 #if 0
@@ -3120,5 +3666,12 @@
    }
 #endif
 
+   assert(mach->CondStackTop == 0);
+   assert(mach->LoopStackTop == 0);
+   assert(mach->ContStackTop == 0);
+   assert(mach->SwitchStackTop == 0);
+   assert(mach->BreakStackTop == 0);
+   assert(mach->CallStackTop == 0);
+
    return ~mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0];
 }
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index 471f591..59e3b44 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -2,6 +2,7 @@
  * 
  * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
+ * Copyright 2009-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
@@ -35,11 +36,13 @@
 extern "C" {
 #endif
 
+
 #define MAX_LABELS (4 * 1024)  /**< basically, max instructions */
 
 #define NUM_CHANNELS 4  /* R,G,B,A */
 #define QUAD_SIZE    4  /* 4 pixel/quad */
 
+
 /**
   * Registers may be treated as float, signed int or unsigned int.
   */
@@ -69,6 +72,11 @@
    float dady[NUM_CHANNELS];
 };
 
+enum tgsi_sampler_control {
+   tgsi_sampler_lod_bias,
+   tgsi_sampler_lod_explicit
+};
+
 /**
  * Information for sampling textures, which must be implemented
  * by code outside the TGSI executor.
@@ -80,7 +88,8 @@
                        const float s[QUAD_SIZE],
                        const float t[QUAD_SIZE],
                        const float p[QUAD_SIZE],
-                       float lodbias,
+                       const float c0[QUAD_SIZE],
+                       enum tgsi_sampler_control control,
                        float rgba[NUM_CHANNELS][QUAD_SIZE]);
 };
 
@@ -179,6 +188,7 @@
 
 #define TGSI_EXEC_MAX_COND_NESTING  32
 #define TGSI_EXEC_MAX_LOOP_NESTING  32
+#define TGSI_EXEC_MAX_SWITCH_NESTING 32
 #define TGSI_EXEC_MAX_CALL_NESTING  32
 
 /* The maximum number of input attributes per vertex. For 2D
@@ -191,6 +201,14 @@
  */
 #define TGSI_EXEC_MAX_CONST_BUFFER  4096
 
+/* The maximum number of vertices per primitive */
+#define TGSI_MAX_PRIM_VERTICES 6
+
+/* The maximum number of primitives to be generated */
+#define TGSI_MAX_PRIMITIVES 64
+
+/* The maximum total number of vertices */
+#define TGSI_MAX_TOTAL_VERTICES (TGSI_MAX_PRIM_VERTICES * TGSI_MAX_PRIMITIVES * PIPE_MAX_ATTRIBS)
 
 /** function call/activation record */
 struct tgsi_call_record
@@ -198,10 +216,29 @@
    uint CondStackTop;
    uint LoopStackTop;
    uint ContStackTop;
+   int SwitchStackTop;
+   int BreakStackTop;
    uint ReturnAddr;
 };
 
 
+/* Switch-case block state. */
+struct tgsi_switch_record {
+   uint mask;                          /**< execution mask */
+   union tgsi_exec_channel selector;   /**< a value case statements are compared to */
+   uint defaultMask;                   /**< non-execute mask for default case */
+};
+
+
+enum tgsi_break_type {
+   TGSI_EXEC_BREAK_INSIDE_LOOP,
+   TGSI_EXEC_BREAK_INSIDE_SWITCH
+};
+
+
+#define TGSI_EXEC_MAX_BREAK_STACK (TGSI_EXEC_MAX_LOOP_NESTING + TGSI_EXEC_MAX_SWITCH_NESTING)
+
+
 /**
  * Run-time virtual machine state for executing TGSI shader.
  */
@@ -214,10 +251,11 @@
 
    float                         Imms[TGSI_EXEC_NUM_IMMEDIATES][4];
 
-   struct tgsi_exec_vector       Inputs[PIPE_MAX_ATTRIBS];
-   struct tgsi_exec_vector       Outputs[PIPE_MAX_ATTRIBS];
+   struct tgsi_exec_vector       Inputs[TGSI_MAX_PRIM_VERTICES * PIPE_MAX_ATTRIBS];
+   struct tgsi_exec_vector       Outputs[TGSI_MAX_TOTAL_VERTICES];
 
    struct tgsi_exec_vector       *Addrs;
+   struct tgsi_exec_vector       *Predicates;
 
    struct tgsi_sampler           **Samplers;
 
@@ -228,10 +266,13 @@
 
    /* GEOMETRY processor only. */
    unsigned                      *Primitives;
+   unsigned                       NumOutputs;
+   unsigned                       MaxGeometryShaderOutputs;
 
    /* FRAGMENT processor only. */
    const struct tgsi_interp_coef *InterpCoefs;
    struct tgsi_exec_vector       QuadPos;
+   float                         Face;    /**< +1 if front facing, -1 if back facing */
 
    /* Conditional execution masks */
    uint CondMask;  /**< For IF/ELSE/ENDIF */
@@ -240,6 +281,12 @@
    uint FuncMask;  /**< For function calls */
    uint ExecMask;  /**< = CondMask & LoopMask */
 
+   /* Current switch-case state. */
+   struct tgsi_switch_record Switch;
+
+   /* Current break type. */
+   enum tgsi_break_type BreakType;
+
    /** Condition mask stack (for nested conditionals) */
    uint CondStack[TGSI_EXEC_MAX_COND_NESTING];
    int CondStackTop;
@@ -252,7 +299,7 @@
    uint LoopLabelStack[TGSI_EXEC_MAX_LOOP_NESTING];
    int LoopLabelStackTop;
 
-   /** Loop counter stack (x = count, y = current, z = step) */
+   /** Loop counter stack (x = index, y = counter, z = step) */
    struct tgsi_exec_vector LoopCounterStack[TGSI_EXEC_MAX_LOOP_NESTING];
    int LoopCounterStackTop;
    
@@ -260,6 +307,13 @@
    uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING];
    int ContStackTop;
 
+   /** Switch case stack */
+   struct tgsi_switch_record SwitchStack[TGSI_EXEC_MAX_SWITCH_NESTING];
+   int SwitchStackTop;
+
+   enum tgsi_break_type BreakStack[TGSI_EXEC_MAX_BREAK_STACK];
+   int BreakStackTop;
+
    /** Function execution mask stack (for executing subroutine code) */
    uint FuncStack[TGSI_EXEC_MAX_CALL_NESTING];
    int FuncStackTop;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c
index be375ca..de0e09c 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_info.c
@@ -119,7 +119,7 @@
    { 1, 1, 0, 0, 0, 0, "NOT", TGSI_OPCODE_NOT },
    { 1, 1, 0, 0, 0, 0, "TRUNC", TGSI_OPCODE_TRUNC },
    { 1, 2, 0, 0, 0, 0, "SHL", TGSI_OPCODE_SHL },
-   { 1, 2, 0, 0, 0, 0, "SHR", TGSI_OPCODE_SHR },
+   { 0, 0, 0, 0, 0, 0, "", 88 },      /* removed */
    { 1, 2, 0, 0, 0, 0, "AND", TGSI_OPCODE_AND },
    { 1, 2, 0, 0, 0, 0, "OR", TGSI_OPCODE_OR },
    { 1, 2, 0, 0, 0, 0, "MOD", TGSI_OPCODE_MOD },
@@ -149,7 +149,33 @@
    { 0, 1, 0, 0, 0, 0, "BREAKC", TGSI_OPCODE_BREAKC },
    { 0, 1, 0, 0, 0, 0, "KIL", TGSI_OPCODE_KIL },
    { 0, 0, 0, 0, 0, 0, "END", TGSI_OPCODE_END },
-   { 0, 0, 0, 0, 0, 0, "", 118 }      /* removed */
+   { 0, 0, 0, 0, 0, 0, "", 118 },     /* removed */
+   { 1, 1, 0, 0, 0, 0, "F2I", TGSI_OPCODE_F2I },
+   { 1, 2, 0, 0, 0, 0, "IDIV", TGSI_OPCODE_IDIV },
+   { 1, 2, 0, 0, 0, 0, "IMAX", TGSI_OPCODE_IMAX },
+   { 1, 2, 0, 0, 0, 0, "IMIN", TGSI_OPCODE_IMIN },
+   { 1, 1, 0, 0, 0, 0, "INEG", TGSI_OPCODE_INEG },
+   { 1, 2, 0, 0, 0, 0, "ISGE", TGSI_OPCODE_ISGE },
+   { 1, 2, 0, 0, 0, 0, "ISHR", TGSI_OPCODE_ISHR },
+   { 1, 2, 0, 0, 0, 0, "ISLT", TGSI_OPCODE_ISLT },
+   { 1, 1, 0, 0, 0, 0, "F2U", TGSI_OPCODE_F2U },
+   { 1, 1, 0, 0, 0, 0, "U2F", TGSI_OPCODE_U2F },
+   { 1, 2, 0, 0, 0, 0, "UADD", TGSI_OPCODE_UADD },
+   { 1, 2, 0, 0, 0, 0, "UDIV", TGSI_OPCODE_UDIV },
+   { 1, 3, 0, 0, 0, 0, "UMAD", TGSI_OPCODE_UMAD },
+   { 1, 2, 0, 0, 0, 0, "UMAX", TGSI_OPCODE_UMAX },
+   { 1, 2, 0, 0, 0, 0, "UMIN", TGSI_OPCODE_UMIN },
+   { 1, 2, 0, 0, 0, 0, "UMOD", TGSI_OPCODE_UMOD },
+   { 1, 2, 0, 0, 0, 0, "UMUL", TGSI_OPCODE_UMUL },
+   { 1, 2, 0, 0, 0, 0, "USEQ", TGSI_OPCODE_USEQ },
+   { 1, 2, 0, 0, 0, 0, "USGE", TGSI_OPCODE_USGE },
+   { 1, 2, 0, 0, 0, 0, "USHR", TGSI_OPCODE_USHR },
+   { 1, 2, 0, 0, 0, 0, "USLT", TGSI_OPCODE_USLT },
+   { 1, 2, 0, 0, 0, 0, "USNE", TGSI_OPCODE_USNE },
+   { 0, 1, 0, 0, 0, 0, "SWITCH", TGSI_OPCODE_SWITCH },
+   { 0, 1, 0, 0, 0, 0, "CASE", TGSI_OPCODE_CASE },
+   { 0, 0, 0, 0, 0, 0, "DEFAULT", TGSI_OPCODE_DEFAULT },
+   { 0, 0, 0, 0, 0, 0, "ENDSWITCH", TGSI_OPCODE_ENDSWITCH }
 };
 
 const struct tgsi_opcode_info *
diff --git a/src/gallium/auxiliary/tgsi/tgsi_iterate.c b/src/gallium/auxiliary/tgsi/tgsi_iterate.c
index d88c255..0ba5fe4 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_iterate.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_iterate.c
@@ -39,7 +39,6 @@
       return FALSE;
 
    ctx->processor = parse.FullHeader.Processor;
-   ctx->version = parse.FullVersion.Version;
 
    if (ctx->prolog)
       if (!ctx->prolog( ctx ))
@@ -67,6 +66,12 @@
                goto fail;
          break;
 
+      case TGSI_TOKEN_TYPE_PROPERTY:
+         if (ctx->iterate_property)
+            if (!ctx->iterate_property( ctx,  &parse.FullToken.FullProperty ))
+               goto fail;
+         break;
+
       default:
          assert( 0 );
       }
diff --git a/src/gallium/auxiliary/tgsi/tgsi_iterate.h b/src/gallium/auxiliary/tgsi/tgsi_iterate.h
index ec7b85b..8d67f22 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_iterate.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_iterate.h
@@ -57,11 +57,15 @@
       struct tgsi_full_immediate *imm );
 
    boolean
+   (* iterate_property)(
+      struct tgsi_iterate_context *ctx,
+      struct tgsi_full_property *prop );
+
+   boolean
    (* epilog)(
       struct tgsi_iterate_context *ctx );
 
    struct tgsi_processor processor;
-   struct tgsi_version version;
 };
 
 boolean
diff --git a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
index b34263d..e4af15c 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
@@ -124,7 +124,6 @@
 OP11(NOT)
 OP11(TRUNC)
 OP12(SHL)
-OP12(SHR)
 OP12(AND)
 OP12(OR)
 OP12(MOD)
@@ -146,6 +145,28 @@
 OP01(BREAKC)
 OP01(KIL)
 OP00(END)
+OP11(F2I)
+OP12(IDIV)
+OP12(IMAX)
+OP12(IMIN)
+OP11(INEG)
+OP12(ISGE)
+OP12(ISHR)
+OP12(ISLT)
+OP11(F2U)
+OP11(U2F)
+OP12(UADD)
+OP12(UDIV)
+OP13(UMAD)
+OP12(UMAX)
+OP12(UMIN)
+OP12(UMOD)
+OP12(UMUL)
+OP12(USEQ)
+OP12(USGE)
+OP12(USHR)
+OP12(USLT)
+OP12(USNE)
 
 
 #undef OP00
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c
index 83f9df1..8c7062d 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
@@ -28,44 +28,23 @@
 #include "util/u_debug.h"
 #include "pipe/p_shader_tokens.h"
 #include "tgsi_parse.h"
-#include "tgsi_build.h"
 #include "util/u_memory.h"
 
-void
-tgsi_full_token_init(
-   union tgsi_full_token *full_token )
-{
-   full_token->Token.Type = TGSI_TOKEN_TYPE_DECLARATION;
-}
-
-void
-tgsi_full_token_free(
-   union tgsi_full_token *full_token )
-{
-}
-
 unsigned
 tgsi_parse_init(
    struct tgsi_parse_context *ctx,
    const struct tgsi_token *tokens )
 {
-   ctx->FullVersion.Version = *(struct tgsi_version *) &tokens[0];
-   if( ctx->FullVersion.Version.MajorVersion > 1 ) {
+   ctx->FullHeader.Header = *(struct tgsi_header *) &tokens[0];
+   if( ctx->FullHeader.Header.HeaderSize >= 2 ) {
+      ctx->FullHeader.Processor = *(struct tgsi_processor *) &tokens[1];
+   }
+   else {
       return TGSI_PARSE_ERROR;
    }
 
-   ctx->FullHeader.Header = *(struct tgsi_header *) &tokens[1];
-   if( ctx->FullHeader.Header.HeaderSize >= 2 ) {
-      ctx->FullHeader.Processor = *(struct tgsi_processor *) &tokens[2];
-   }
-   else {
-      ctx->FullHeader.Processor = tgsi_default_processor();
-   }
-
    ctx->Tokens = tokens;
-   ctx->Position = 1 + ctx->FullHeader.Header.HeaderSize;
-
-   tgsi_full_token_init( &ctx->FullToken );
+   ctx->Position = ctx->FullHeader.Header.HeaderSize;
 
    return TGSI_PARSE_OK;
 }
@@ -74,7 +53,6 @@
 tgsi_parse_free(
    struct tgsi_parse_context *ctx )
 {
-   tgsi_full_token_free( &ctx->FullToken );
 }
 
 boolean
@@ -82,7 +60,7 @@
    struct tgsi_parse_context *ctx )
 {
    return ctx->Position >=
-      1 + ctx->FullHeader.Header.HeaderSize + ctx->FullHeader.Header.BodySize;
+      ctx->FullHeader.Header.HeaderSize + ctx->FullHeader.Header.BodySize;
 }
 
 
@@ -119,9 +97,6 @@
    struct tgsi_token token;
    unsigned i;
 
-   tgsi_full_token_free( &ctx->FullToken );
-   tgsi_full_token_init( &ctx->FullToken );
-
    next_token( ctx, &token );
 
    switch( token.Type ) {
@@ -129,10 +104,10 @@
    {
       struct tgsi_full_declaration *decl = &ctx->FullToken.FullDeclaration;
 
-      *decl = tgsi_default_full_declaration();
+      memset(decl, 0, sizeof *decl);
       copy_token(&decl->Declaration, &token);
 
-      next_token( ctx, &decl->DeclarationRange );
+      next_token( ctx, &decl->Range );
 
       if( decl->Declaration.Semantic ) {
          next_token( ctx, &decl->Semantic );
@@ -144,18 +119,29 @@
    case TGSI_TOKEN_TYPE_IMMEDIATE:
    {
       struct tgsi_full_immediate *imm = &ctx->FullToken.FullImmediate;
+      uint imm_count;
 
-      *imm = tgsi_default_full_immediate();
+      memset(imm, 0, sizeof *imm);
       copy_token(&imm->Immediate, &token);
-      assert( !imm->Immediate.Extended );
+
+      imm_count = imm->Immediate.NrTokens - 1;
 
       switch (imm->Immediate.DataType) {
       case TGSI_IMM_FLOAT32:
-         {
-            uint imm_count = imm->Immediate.NrTokens - 1;
-            for (i = 0; i < imm_count; i++) {
-               next_token(ctx, &imm->u[i]);
-            }
+         for (i = 0; i < imm_count; i++) {
+            next_token(ctx, &imm->u[i].Float);
+         }
+         break;
+
+      case TGSI_IMM_UINT32:
+         for (i = 0; i < imm_count; i++) {
+            next_token(ctx, &imm->u[i].Uint);
+         }
+         break;
+
+      case TGSI_IMM_INT32:
+         for (i = 0; i < imm_count; i++) {
+            next_token(ctx, &imm->u[i].Int);
          }
          break;
 
@@ -169,137 +155,76 @@
    case TGSI_TOKEN_TYPE_INSTRUCTION:
    {
       struct tgsi_full_instruction *inst = &ctx->FullToken.FullInstruction;
-      unsigned extended;
 
-      *inst = tgsi_default_full_instruction();
+      memset(inst, 0, sizeof *inst);
       copy_token(&inst->Instruction, &token);
-      extended = inst->Instruction.Extended;
 
-      while( extended ) {
-         struct tgsi_src_register_ext token;
+      if (inst->Instruction.Predicate) {
+         next_token(ctx, &inst->Predicate);
+      }
 
-         next_token( ctx, &token );
+      if (inst->Instruction.Label) {
+         next_token( ctx, &inst->Label);
+      }
 
-         switch( token.Type ) {
-         case TGSI_INSTRUCTION_EXT_TYPE_LABEL:
-            copy_token(&inst->InstructionExtLabel, &token);
-            break;
-
-         case TGSI_INSTRUCTION_EXT_TYPE_TEXTURE:
-            copy_token(&inst->InstructionExtTexture, &token);
-            break;
-
-         case TGSI_INSTRUCTION_EXT_TYPE_PREDICATE:
-            copy_token(&inst->InstructionExtPredicate, &token);
-            break;
-
-         default:
-            assert( 0 );
-         }
-
-         extended = token.Extended;
+      if (inst->Instruction.Texture) {
+         next_token( ctx, &inst->Texture);
       }
 
       assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS );
 
       for(  i = 0; i < inst->Instruction.NumDstRegs; i++ ) {
-         unsigned extended;
 
-         next_token( ctx, &inst->FullDstRegisters[i].DstRegister );
+         next_token( ctx, &inst->Dst[i].Register );
 
          /*
           * No support for indirect or multi-dimensional addressing.
           */
-         assert( !inst->FullDstRegisters[i].DstRegister.Dimension );
+         assert( !inst->Dst[i].Register.Dimension );
 
-         extended = inst->FullDstRegisters[i].DstRegister.Extended;
-
-         while( extended ) {
-            struct tgsi_src_register_ext token;
-
-            next_token( ctx, &token );
-
-            switch( token.Type ) {
-            case TGSI_DST_REGISTER_EXT_TYPE_MODULATE:
-               copy_token(&inst->FullDstRegisters[i].DstRegisterExtModulate,
-                          &token);
-               break;
-
-            default:
-               assert( 0 );
-            }
-
-            extended = token.Extended;
-         }
-
-         if( inst->FullDstRegisters[i].DstRegister.Indirect ) {
-            next_token( ctx, &inst->FullDstRegisters[i].DstRegisterInd );
+         if( inst->Dst[i].Register.Indirect ) {
+            next_token( ctx, &inst->Dst[i].Indirect );
 
             /*
              * No support for indirect or multi-dimensional addressing.
              */
-            assert( !inst->FullDstRegisters[i].DstRegisterInd.Indirect );
-            assert( !inst->FullDstRegisters[i].DstRegisterInd.Dimension );
-            assert( !inst->FullDstRegisters[i].DstRegisterInd.Extended );
+            assert( !inst->Dst[i].Indirect.Dimension );
+            assert( !inst->Dst[i].Indirect.Indirect );
          }
       }
 
       assert( inst->Instruction.NumSrcRegs <= TGSI_FULL_MAX_SRC_REGISTERS );
 
       for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) {
-         unsigned extended;
 
-         next_token( ctx, &inst->FullSrcRegisters[i].SrcRegister );
+         next_token( ctx, &inst->Src[i].Register );
 
-         extended = inst->FullSrcRegisters[i].SrcRegister.Extended;
-
-         while( extended ) {
-            struct tgsi_src_register_ext token;
-
-            next_token( ctx, &token );
-
-            switch( token.Type ) {
-            case TGSI_SRC_REGISTER_EXT_TYPE_MOD:
-               copy_token(&inst->FullSrcRegisters[i].SrcRegisterExtMod,
-                          &token);
-               break;
-
-            default:
-               assert( 0 );
-            }
-
-            extended = token.Extended;
-         }
-
-         if( inst->FullSrcRegisters[i].SrcRegister.Indirect ) {
-            next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterInd );
+         if( inst->Src[i].Register.Indirect ) {
+            next_token( ctx, &inst->Src[i].Indirect );
 
             /*
              * No support for indirect or multi-dimensional addressing.
              */
-            assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect );
-            assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension );
-            assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended );
+            assert( !inst->Src[i].Indirect.Indirect );
+            assert( !inst->Src[i].Indirect.Dimension );
          }
 
-         if( inst->FullSrcRegisters[i].SrcRegister.Dimension ) {
-            next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDim );
+         if( inst->Src[i].Register.Dimension ) {
+            next_token( ctx, &inst->Src[i].Dimension );
 
             /*
              * No support for multi-dimensional addressing.
              */
-            assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Dimension );
-            assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Extended );
+            assert( !inst->Src[i].Dimension.Dimension );
 
-            if( inst->FullSrcRegisters[i].SrcRegisterDim.Indirect ) {
-               next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDimInd );
+            if( inst->Src[i].Dimension.Indirect ) {
+               next_token( ctx, &inst->Src[i].DimIndirect );
 
                /*
                * No support for indirect or multi-dimensional addressing.
                */
-               assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect );
-               assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension );
-               assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended );
+               assert( !inst->Src[i].Indirect.Indirect );
+               assert( !inst->Src[i].Indirect.Dimension );
             }
          }
       }
@@ -307,6 +232,22 @@
       break;
    }
 
+   case TGSI_TOKEN_TYPE_PROPERTY:
+   {
+      struct tgsi_full_property *prop = &ctx->FullToken.FullProperty;
+      uint prop_count;
+
+      memset(prop, 0, sizeof *prop);
+      copy_token(&prop->Property, &token);
+
+      prop_count = prop->Property.NrTokens - 1;
+      for (i = 0; i < prop_count; i++) {
+         next_token(ctx, &prop->u[i]);
+      }
+
+      break;
+   }
+
    default:
       assert( 0 );
    }
@@ -319,8 +260,7 @@
    struct tgsi_parse_context ctx;
    if (tgsi_parse_init(&ctx, tokens) == TGSI_PARSE_OK) {
       unsigned len = (ctx.FullHeader.Header.HeaderSize +
-                      ctx.FullHeader.Header.BodySize +
-                      1);
+                      ctx.FullHeader.Header.BodySize);
       return len;
    }
    return 0;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h
index 76f1676..439a572 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h
@@ -34,11 +34,6 @@
 extern "C" {
 #endif
 
-struct tgsi_full_version
-{
-   struct tgsi_version  Version;
-};
-
 struct tgsi_full_header
 {
    struct tgsi_header      Header;
@@ -47,24 +42,22 @@
 
 struct tgsi_full_dst_register
 {
-   struct tgsi_dst_register               DstRegister;
-   struct tgsi_src_register               DstRegisterInd;
-   struct tgsi_dst_register_ext_modulate  DstRegisterExtModulate;
+   struct tgsi_dst_register               Register;
+   struct tgsi_src_register               Indirect;
 };
 
 struct tgsi_full_src_register
 {
-   struct tgsi_src_register         SrcRegister;
-   struct tgsi_src_register_ext_mod SrcRegisterExtMod;
-   struct tgsi_src_register         SrcRegisterInd;
-   struct tgsi_dimension            SrcRegisterDim;
-   struct tgsi_src_register         SrcRegisterDimInd;
+   struct tgsi_src_register         Register;
+   struct tgsi_src_register         Indirect;
+   struct tgsi_dimension            Dimension;
+   struct tgsi_src_register         DimIndirect;
 };
 
 struct tgsi_full_declaration
 {
    struct tgsi_declaration Declaration;
-   struct tgsi_declaration_range DeclarationRange;
+   struct tgsi_declaration_range Range;
    struct tgsi_declaration_semantic Semantic;
 };
 
@@ -74,18 +67,23 @@
    union tgsi_immediate_data u[4];
 };
 
+struct tgsi_full_property
+{
+   struct tgsi_property   Property;
+   struct tgsi_property_data u[8];
+};
+
 #define TGSI_FULL_MAX_DST_REGISTERS 2
 #define TGSI_FULL_MAX_SRC_REGISTERS 4 /* TXD has 4 */
 
 struct tgsi_full_instruction
 {
    struct tgsi_instruction             Instruction;
-   struct tgsi_instruction_ext_label   InstructionExtLabel;
-   struct tgsi_instruction_ext_texture InstructionExtTexture;
-   struct tgsi_instruction_ext_predicate InstructionExtPredicate;
-   struct tgsi_full_dst_register       FullDstRegisters[TGSI_FULL_MAX_DST_REGISTERS];
-   struct tgsi_full_src_register       FullSrcRegisters[TGSI_FULL_MAX_SRC_REGISTERS];
-   uint Flags;  /**< user-defined usage */
+   struct tgsi_instruction_predicate   Predicate;
+   struct tgsi_instruction_label       Label;
+   struct tgsi_instruction_texture     Texture;
+   struct tgsi_full_dst_register       Dst[TGSI_FULL_MAX_DST_REGISTERS];
+   struct tgsi_full_src_register       Src[TGSI_FULL_MAX_SRC_REGISTERS];
 };
 
 union tgsi_full_token
@@ -94,21 +92,13 @@
    struct tgsi_full_declaration  FullDeclaration;
    struct tgsi_full_immediate    FullImmediate;
    struct tgsi_full_instruction  FullInstruction;
+   struct tgsi_full_property     FullProperty;
 };
 
-void
-tgsi_full_token_init(
-   union tgsi_full_token *full_token );
-
-void
-tgsi_full_token_free(
-   union tgsi_full_token *full_token );
-
 struct tgsi_parse_context
 {
    const struct tgsi_token    *Tokens;
    unsigned                   Position;
-   struct tgsi_full_version   FullVersion;
    struct tgsi_full_header    FullHeader;
    union tgsi_full_token      FullToken;
 };
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ppc.c b/src/gallium/auxiliary/tgsi/tgsi_ppc.c
index 617fd7f..138d2d0 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ppc.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ppc.c
@@ -60,7 +60,7 @@
    for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++)
 
 #define IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
-   ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN)))
+   ((INST).Dst[0].Register.WriteMask & (1 << (CHAN)))
 
 #define IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
    if (IS_DST0_CHANNEL_ENABLED( INST, CHAN ))
@@ -156,8 +156,8 @@
 static boolean
 is_ppc_vec_temporary(const struct tgsi_full_src_register *reg)
 {
-   return (reg->SrcRegister.File == TGSI_FILE_TEMPORARY &&
-           reg->SrcRegister.Index < MAX_PPC_TEMPS);
+   return (reg->Register.File == TGSI_FILE_TEMPORARY &&
+           reg->Register.Index < MAX_PPC_TEMPS);
 }
 
 
@@ -167,8 +167,8 @@
 static boolean
 is_ppc_vec_temporary_dst(const struct tgsi_full_dst_register *reg)
 {
-   return (reg->DstRegister.File == TGSI_FILE_TEMPORARY &&
-           reg->DstRegister.Index < MAX_PPC_TEMPS);
+   return (reg->Register.File == TGSI_FILE_TEMPORARY &&
+           reg->Register.Index < MAX_PPC_TEMPS);
 }
 
 
@@ -291,10 +291,11 @@
    case TGSI_SWIZZLE_Y:
    case TGSI_SWIZZLE_Z:
    case TGSI_SWIZZLE_W:
-      switch (reg->SrcRegister.File) {
+      switch (reg->Register.File) {
       case TGSI_FILE_INPUT:
+      case TGSI_FILE_SYSTEM_VALUE:
          {
-            int offset = (reg->SrcRegister.Index * 4 + swizzle) * 16;
+            int offset = (reg->Register.Index * 4 + swizzle) * 16;
             int offset_reg = emit_li_offset(gen, offset);
             dst_vec = ppc_allocate_vec_register(gen->f);
             ppc_lvx(gen->f, dst_vec, gen->inputs_reg, offset_reg);
@@ -303,11 +304,11 @@
       case TGSI_FILE_TEMPORARY:
          if (is_ppc_vec_temporary(reg)) {
             /* use PPC vec register */
-            dst_vec = gen->temps_map[reg->SrcRegister.Index][swizzle];
+            dst_vec = gen->temps_map[reg->Register.Index][swizzle];
          }
          else {
             /* use memory-based temp register "file" */
-            int offset = (reg->SrcRegister.Index * 4 + swizzle) * 16;
+            int offset = (reg->Register.Index * 4 + swizzle) * 16;
             int offset_reg = emit_li_offset(gen, offset);
             dst_vec = ppc_allocate_vec_register(gen->f);
             ppc_lvx(gen->f, dst_vec, gen->temps_reg, offset_reg);
@@ -315,7 +316,7 @@
          break;
       case TGSI_FILE_IMMEDIATE:
          {
-            int offset = (reg->SrcRegister.Index * 4 + swizzle) * 4;
+            int offset = (reg->Register.Index * 4 + swizzle) * 4;
             int offset_reg = emit_li_offset(gen, offset);
             dst_vec = ppc_allocate_vec_register(gen->f);
             /* Load 4-byte word into vector register.
@@ -331,7 +332,7 @@
          break;
       case TGSI_FILE_CONSTANT:
          {
-            int offset = (reg->SrcRegister.Index * 4 + swizzle) * 4;
+            int offset = (reg->Register.Index * 4 + swizzle) * 4;
             int offset_reg = emit_li_offset(gen, offset);
             dst_vec = ppc_allocate_vec_register(gen->f);
             /* Load 4-byte word into vector register.
@@ -404,9 +405,9 @@
 {
    int swz_a, swz_b;
    int sign_a, sign_b;
-   if (a->SrcRegister.File != b->SrcRegister.File)
+   if (a->Register.File != b->Register.File)
       return FALSE;
-   if (a->SrcRegister.Index != b->SrcRegister.Index)
+   if (a->Register.Index != b->Register.Index)
       return FALSE;
    swz_a = tgsi_util_get_full_src_register_swizzle(a, chan_a);
    swz_b = tgsi_util_get_full_src_register_swizzle(b, chan_b);
@@ -431,7 +432,7 @@
             struct tgsi_full_instruction *inst, int src_reg, uint chan)
 {
    const const struct tgsi_full_src_register *src = 
-      &inst->FullSrcRegisters[src_reg];
+      &inst->Src[src_reg];
    int vec;
    uint i;
 
@@ -482,10 +483,10 @@
             const struct tgsi_full_instruction *inst,
             unsigned chan_index)
 {
-   const struct tgsi_full_dst_register *reg = &inst->FullDstRegisters[0];
+   const struct tgsi_full_dst_register *reg = &inst->Dst[0];
 
    if (is_ppc_vec_temporary_dst(reg)) {
-      int vec = gen->temps_map[reg->DstRegister.Index][chan_index];
+      int vec = gen->temps_map[reg->Register.Index][chan_index];
       return vec;
    }
    else {
@@ -505,12 +506,12 @@
            unsigned chan_index,
            boolean free_vec)
 {
-   const struct tgsi_full_dst_register *reg = &inst->FullDstRegisters[0];
+   const struct tgsi_full_dst_register *reg = &inst->Dst[0];
 
-   switch (reg->DstRegister.File) {
+   switch (reg->Register.File) {
    case TGSI_FILE_OUTPUT:
       {
-         int offset = (reg->DstRegister.Index * 4 + chan_index) * 16;
+         int offset = (reg->Register.Index * 4 + chan_index) * 16;
          int offset_reg = emit_li_offset(gen, offset);
          ppc_stvx(gen->f, src_vec, gen->outputs_reg, offset_reg);
       }
@@ -518,14 +519,14 @@
    case TGSI_FILE_TEMPORARY:
       if (is_ppc_vec_temporary_dst(reg)) {
          if (!free_vec) {
-            int dst_vec = gen->temps_map[reg->DstRegister.Index][chan_index];
+            int dst_vec = gen->temps_map[reg->Register.Index][chan_index];
             if (dst_vec != src_vec)
                ppc_vmove(gen->f, dst_vec, src_vec);
          }
          free_vec = FALSE;
       }
       else {
-         int offset = (reg->DstRegister.Index * 4 + chan_index) * 16;
+         int offset = (reg->Register.Index * 4 + chan_index) * 16;
          int offset_reg = emit_li_offset(gen, offset);
          ppc_stvx(gen->f, src_vec, gen->temps_reg, offset_reg);
       }
@@ -535,7 +536,7 @@
       emit_addrs(
          func,
          xmm,
-         reg->DstRegister.Index,
+         reg->Register.Index,
          chan_index );
       break;
 #endif
@@ -1173,13 +1174,14 @@
    struct ppc_function *func,
    struct tgsi_full_declaration *decl )
 {
-   if( decl->Declaration.File == TGSI_FILE_INPUT ) {
+   if( decl->Declaration.File == TGSI_FILE_INPUT ||
+       decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE ) {
 #if 0
       unsigned first, last, mask;
       unsigned i, j;
 
-      first = decl->DeclarationRange.First;
-      last = decl->DeclarationRange.Last;
+      first = decl->Range.First;
+      last = decl->Range.Last;
       mask = decl->Declaration.UsageMask;
 
       for( i = first; i <= last; i++ ) {
@@ -1339,6 +1341,9 @@
          }
          break;
 
+      case TGSI_TOKEN_TYPE_PROPERTY:
+         break;
+
       default:
 	 ok = 0;
          assert( 0 );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
index 36e27ea..7f1c8e5 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
@@ -26,32 +26,112 @@
  **************************************************************************/
 
 #include "util/u_debug.h"
+#include "util/u_memory.h"
+#include "util/u_prim.h"
+#include "cso_cache/cso_hash.h"
 #include "tgsi_sanity.h"
 #include "tgsi_info.h"
 #include "tgsi_iterate.h"
 
-typedef uint reg_flag;
-
-#define BITS_IN_REG_FLAG (sizeof( reg_flag ) * 8)
-
-#define MAX_REGISTERS 256
-#define MAX_REG_FLAGS ((MAX_REGISTERS + BITS_IN_REG_FLAG - 1) / BITS_IN_REG_FLAG)
+typedef struct {
+   uint file : 28;
+   /* max 2 dimensions */
+   uint dimensions : 4;
+   uint indices[2];
+} scan_register;
 
 struct sanity_check_ctx
 {
    struct tgsi_iterate_context iter;
+   struct cso_hash *regs_decl;
+   struct cso_hash *regs_used;
+   struct cso_hash *regs_ind_used;
 
-   reg_flag regs_decl[TGSI_FILE_COUNT][MAX_REG_FLAGS];
-   reg_flag regs_used[TGSI_FILE_COUNT][MAX_REG_FLAGS];
-   boolean regs_ind_used[TGSI_FILE_COUNT];
    uint num_imms;
    uint num_instructions;
    uint index_of_END;
 
    uint errors;
    uint warnings;
+   uint implied_array_size;
 };
 
+static INLINE unsigned
+scan_register_key(const scan_register *reg)
+{
+   unsigned key = reg->file;
+   key |= (reg->indices[0] << 4);
+   key |= (reg->indices[1] << 18);
+
+   return key;
+}
+
+static void
+fill_scan_register1d(scan_register *reg,
+                     uint file, uint index)
+{
+   reg->file = file;
+   reg->dimensions = 1;
+   reg->indices[0] = index;
+   reg->indices[1] = 0;
+}
+
+static void
+fill_scan_register2d(scan_register *reg,
+                     uint file, uint index1, uint index2)
+{
+   reg->file = file;
+   reg->dimensions = 2;
+   reg->indices[0] = index1;
+   reg->indices[1] = index2;
+}
+
+static void
+scan_register_dst(scan_register *reg,
+                  struct tgsi_full_dst_register *dst)
+{
+   fill_scan_register1d(reg,
+                        dst->Register.File,
+                        dst->Register.Index);
+}
+
+static void
+scan_register_src(scan_register *reg,
+                  struct tgsi_full_src_register *src)
+{
+   if (src->Register.Dimension) {
+      /*FIXME: right now we don't support indirect
+       * multidimensional addressing */
+      debug_assert(!src->Dimension.Indirect);
+      fill_scan_register2d(reg,
+                           src->Register.File,
+                           src->Register.Index,
+                           src->Dimension.Index);
+   } else {
+      fill_scan_register1d(reg,
+                           src->Register.File,
+                           src->Register.Index);
+   }
+}
+
+static scan_register *
+create_scan_register_src(struct tgsi_full_src_register *src)
+{
+   scan_register *reg = MALLOC(sizeof(scan_register));
+   scan_register_src(reg, src);
+
+   return reg;
+}
+
+static scan_register *
+create_scan_register_dst(struct tgsi_full_dst_register *dst)
+{
+   scan_register *reg = MALLOC(sizeof(scan_register));
+   scan_register_dst(reg, dst);
+
+   return reg;
+}
+
 static void
 report_error(
    struct sanity_check_ctx *ctx,
@@ -99,12 +179,12 @@
 static boolean
 is_register_declared(
    struct sanity_check_ctx *ctx,
-   uint file,
-   int index )
+   const scan_register *reg)
 {
-   assert( index >= 0 && index < MAX_REGISTERS );
-
-   return (ctx->regs_decl[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE;
+   void *data = cso_hash_find_data_from_template(
+      ctx->regs_decl, scan_register_key(reg),
+      (void*)reg, sizeof(scan_register));
+   return  data ? TRUE : FALSE;
 }
 
 static boolean
@@ -112,23 +192,37 @@
    struct sanity_check_ctx *ctx,
    uint file )
 {
-   uint i;
+   struct cso_hash_iter iter =
+      cso_hash_first_node(ctx->regs_decl);
 
-   for (i = 0; i < MAX_REG_FLAGS; i++)
-      if (ctx->regs_decl[file][i])
+   while (!cso_hash_iter_is_null(iter)) {
+      scan_register *reg = (scan_register *)cso_hash_iter_data(iter);
+      if (reg->file == file)
          return TRUE;
+      iter = cso_hash_iter_next(iter);
+   }
+
    return FALSE;
 }
 
 static boolean
 is_register_used(
    struct sanity_check_ctx *ctx,
-   uint file,
-   int index )
+   scan_register *reg)
 {
-   assert( index < MAX_REGISTERS );
+   void *data = cso_hash_find_data_from_template(
+      ctx->regs_used, scan_register_key(reg),
+      reg, sizeof(scan_register));
+   return  data ? TRUE : FALSE;
+}
 
-   return (ctx->regs_used[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE;
+
+static boolean
+is_ind_register_used(
+   struct sanity_check_ctx *ctx,
+   scan_register *reg)
+{
+   return cso_hash_contains(ctx->regs_ind_used, reg->file);
 }
 
 static const char *file_names[TGSI_FILE_COUNT] =
@@ -148,31 +242,42 @@
 static boolean
 check_register_usage(
    struct sanity_check_ctx *ctx,
-   uint file,
-   int index,
+   scan_register *reg,
    const char *name,
    boolean indirect_access )
 {
-   if (!check_file_name( ctx, file ))
+   if (!check_file_name( ctx, reg->file )) {
+      FREE(reg);
       return FALSE;
+   }
 
    if (indirect_access) {
       /* Note that 'index' is an offset relative to the value of the
-       * address register.  No range checking done here.
-       */
-      if (!is_any_register_declared( ctx, file ))
-         report_error( ctx, "%s: Undeclared %s register", file_names[file], name );
-      ctx->regs_ind_used[file] = TRUE;
+       * address register.  No range checking done here.*/
+      reg->indices[0] = 0;
+      reg->indices[1] = 0;
+      if (!is_any_register_declared( ctx, reg->file ))
+         report_error( ctx, "%s: Undeclared %s register", file_names[reg->file], name );
+      if (!is_ind_register_used(ctx, reg))
+         cso_hash_insert(ctx->regs_ind_used, reg->file, reg);
+      else
+         FREE(reg);
    }
    else {
-      if (index < 0 || index >= MAX_REGISTERS) {
-         report_error( ctx, "%s[%d]: Invalid %s index", file_names[file], index, name );
-         return FALSE;
+      if (!is_register_declared( ctx, reg )) {
+         if (reg->dimensions == 2) {
+            report_error( ctx, "%s[%d][%d]: Undeclared %s register", file_names[reg->file],
+                          reg->indices[0], reg->indices[1], name );
+         }
+         else {
+            report_error( ctx, "%s[%d]: Undeclared %s register", file_names[reg->file],
+                          reg->indices[0], name );
+         }
       }
-
-      if (!is_register_declared( ctx, file, index ))
-         report_error( ctx, "%s[%d]: Undeclared %s register", file_names[file], index, name );
-      ctx->regs_used[file][index / BITS_IN_REG_FLAG] |= (1 << (index % BITS_IN_REG_FLAG));
+      if (!is_register_used( ctx, reg ))
+         cso_hash_insert(ctx->regs_used, scan_register_key(reg), reg);
+      else
+         FREE(reg);
    }
    return TRUE;
 }
@@ -210,43 +315,43 @@
     * Mark the registers as used.
     */
    for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
+      scan_register *reg = create_scan_register_dst(&inst->Dst[i]);
       check_register_usage(
          ctx,
-         inst->FullDstRegisters[i].DstRegister.File,
-         inst->FullDstRegisters[i].DstRegister.Index,
+         reg,
          "destination",
          FALSE );
    }
    for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
+      scan_register *reg = create_scan_register_src(&inst->Src[i]);
       check_register_usage(
          ctx,
-         inst->FullSrcRegisters[i].SrcRegister.File,
-         inst->FullSrcRegisters[i].SrcRegister.Index,
+         reg,
          "source",
-         (boolean)inst->FullSrcRegisters[i].SrcRegister.Indirect );
-      if (inst->FullSrcRegisters[i].SrcRegister.Indirect) {
-         uint file;
-         int index;
+         (boolean)inst->Src[i].Register.Indirect );
+      if (inst->Src[i].Register.Indirect) {
+         scan_register *ind_reg = MALLOC(sizeof(scan_register));
 
-         file = inst->FullSrcRegisters[i].SrcRegisterInd.File;
-         index = inst->FullSrcRegisters[i].SrcRegisterInd.Index;
-         check_register_usage(
-            ctx,
-            file,
-            index,
-            "indirect",
-            FALSE );
-         if (!(file == TGSI_FILE_ADDRESS || file == TGSI_FILE_LOOP) || index != 0) {
+         fill_scan_register1d(ind_reg,
+                              inst->Src[i].Indirect.File,
+                              inst->Src[i].Indirect.Index);
+         if (!(reg->file == TGSI_FILE_ADDRESS || reg->file == TGSI_FILE_LOOP) ||
+             reg->indices[0] != 0) {
             report_warning(ctx, "Indirect register neither ADDR[0] nor LOOP[0]");
          }
+         check_register_usage(
+            ctx,
+            reg,
+            "indirect",
+            FALSE );
       }
    }
 
    switch (inst->Instruction.Opcode) {
    case TGSI_OPCODE_BGNFOR:
    case TGSI_OPCODE_ENDFOR:
-      if (inst->FullDstRegisters[0].DstRegister.File != TGSI_FILE_LOOP ||
-          inst->FullDstRegisters[0].DstRegister.Index != 0) {
+      if (inst->Dst[0].Register.File != TGSI_FILE_LOOP ||
+          inst->Dst[0].Register.Index != 0) {
          report_error(ctx, "Destination register must be LOOP[0]");
       }
       break;
@@ -254,8 +359,8 @@
 
    switch (inst->Instruction.Opcode) {
    case TGSI_OPCODE_BGNFOR:
-      if (inst->FullSrcRegisters[0].SrcRegister.File != TGSI_FILE_CONSTANT &&
-          inst->FullSrcRegisters[0].SrcRegister.File != TGSI_FILE_IMMEDIATE) {
+      if (inst->Src[0].Register.File != TGSI_FILE_CONSTANT &&
+          inst->Src[0].Register.File != TGSI_FILE_IMMEDIATE) {
          report_error(ctx, "Source register file must be either CONST or IMM");
       }
       break;
@@ -266,6 +371,19 @@
    return TRUE;
 }
 
+static void
+check_and_declare(struct sanity_check_ctx *ctx,
+                  scan_register *reg)
+{
+   if (is_register_declared( ctx, reg))
+      report_error( ctx, "%s[%u]: The same register declared more than once",
+                    file_names[reg->file], reg->indices[0] );
+   cso_hash_insert(ctx->regs_decl,
+                   scan_register_key(reg),
+                   reg);
+}
+
+
 static boolean
 iter_declaration(
    struct tgsi_iterate_context *iter,
@@ -286,10 +404,22 @@
    file = decl->Declaration.File;
    if (!check_file_name( ctx, file ))
       return TRUE;
-   for (i = decl->DeclarationRange.First; i <= decl->DeclarationRange.Last; i++) {
-      if (is_register_declared( ctx, file, i ))
-         report_error( ctx, "%s[%u]: The same register declared more than once", file_names[file], i );
-      ctx->regs_decl[file][i / BITS_IN_REG_FLAG] |= (1 << (i % BITS_IN_REG_FLAG));
+   for (i = decl->Range.First; i <= decl->Range.Last; i++) {
+      /* declared TGSI_FILE_INPUT's for geometry processor
+       * have an implied second dimension */
+      if (file == TGSI_FILE_INPUT &&
+          ctx->iter.processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
+         uint vert;
+         for (vert = 0; vert < ctx->implied_array_size; ++vert) {
+            scan_register *reg = MALLOC(sizeof(scan_register));
+            fill_scan_register2d(reg, file, vert, i);
+            check_and_declare(ctx, reg);
+         }
+      } else {
+         scan_register *reg = MALLOC(sizeof(scan_register));
+         fill_scan_register1d(reg, file, i);
+         check_and_declare(ctx, reg);
+      }
    }
 
    return TRUE;
@@ -301,8 +431,7 @@
    struct tgsi_full_immediate *imm )
 {
    struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
-
-   assert( ctx->num_imms < MAX_REGISTERS );
+   scan_register *reg;
 
    /* No immediates allowed after the first instruction.
     */
@@ -311,12 +440,16 @@
 
    /* Mark the register as declared.
     */
-   ctx->regs_decl[TGSI_FILE_IMMEDIATE][ctx->num_imms / BITS_IN_REG_FLAG] |= (1 << (ctx->num_imms % BITS_IN_REG_FLAG));
+   reg = MALLOC(sizeof(scan_register));
+   fill_scan_register1d(reg, TGSI_FILE_IMMEDIATE, ctx->num_imms);
+   cso_hash_insert(ctx->regs_decl, scan_register_key(reg), reg);
    ctx->num_imms++;
 
    /* Check data type validity.
     */
-   if (imm->Immediate.DataType != TGSI_IMM_FLOAT32) {
+   if (imm->Immediate.DataType != TGSI_IMM_FLOAT32 &&
+       imm->Immediate.DataType != TGSI_IMM_UINT32 &&
+       imm->Immediate.DataType != TGSI_IMM_INT32) {
       report_error( ctx, "(%u): Invalid immediate data type", imm->Immediate.DataType );
       return TRUE;
    }
@@ -324,12 +457,26 @@
    return TRUE;
 }
 
+
+static boolean
+iter_property(
+   struct tgsi_iterate_context *iter,
+   struct tgsi_full_property *prop )
+{
+   struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
+
+   if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY &&
+       prop->Property.PropertyName == TGSI_PROPERTY_GS_INPUT_PRIM) {
+      ctx->implied_array_size = u_vertices_per_prim(prop->u[0].Data);
+   }
+   return TRUE;
+}
+
 static boolean
 epilog(
    struct tgsi_iterate_context *iter )
 {
    struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
-   uint file;
 
    /* There must be an END instruction somewhere.
     */
@@ -339,13 +486,17 @@
 
    /* Check if all declared registers were used.
     */
-   for (file = TGSI_FILE_NULL; file < TGSI_FILE_COUNT; file++) {
-      uint i;
+   {
+      struct cso_hash_iter iter =
+         cso_hash_first_node(ctx->regs_decl);
 
-      for (i = 0; i < MAX_REGISTERS; i++) {
-         if (is_register_declared( ctx, file, i ) && !is_register_used( ctx, file, i ) && !ctx->regs_ind_used[file]) {
-            report_warning( ctx, "%s[%u]: Register never used", file_names[file], i );
+      while (!cso_hash_iter_is_null(iter)) {
+         scan_register *reg = (scan_register *)cso_hash_iter_data(iter);
+         if (!is_register_used(ctx, reg) && !is_ind_register_used(ctx, reg)) {
+            report_warning( ctx, "%s[%u]: Register never used",
+                            file_names[reg->file], reg->indices[0] );
          }
+         iter = cso_hash_iter_next(iter);
       }
    }
 
@@ -357,6 +508,19 @@
    return TRUE;
 }
 
+static void
+regs_hash_destroy(struct cso_hash *hash)
+{
+   struct cso_hash_iter iter = cso_hash_first_node(hash);
+   while (!cso_hash_iter_is_null(iter)) {
+      scan_register *reg = (scan_register *)cso_hash_iter_data(iter);
+      iter = cso_hash_erase(hash, iter);
+      assert(reg->file < TGSI_FILE_COUNT);
+      FREE(reg);
+   }
+   cso_hash_delete(hash);
+}
+
 boolean
 tgsi_sanity_check(
    const struct tgsi_token *tokens )
@@ -367,20 +531,26 @@
    ctx.iter.iterate_instruction = iter_instruction;
    ctx.iter.iterate_declaration = iter_declaration;
    ctx.iter.iterate_immediate = iter_immediate;
+   ctx.iter.iterate_property = iter_property;
    ctx.iter.epilog = epilog;
 
-   memset( ctx.regs_decl, 0, sizeof( ctx.regs_decl ) );
-   memset( ctx.regs_used, 0, sizeof( ctx.regs_used ) );
-   memset( ctx.regs_ind_used, 0, sizeof( ctx.regs_ind_used ) );
+   ctx.regs_decl = cso_hash_create();
+   ctx.regs_used = cso_hash_create();
+   ctx.regs_ind_used = cso_hash_create();
+
    ctx.num_imms = 0;
    ctx.num_instructions = 0;
    ctx.index_of_END = ~0;
 
    ctx.errors = 0;
    ctx.warnings = 0;
+   ctx.implied_array_size = 0;
 
    if (!tgsi_iterate_shader( tokens, &ctx.iter ))
       return FALSE;
 
+   regs_hash_destroy(ctx.regs_decl);
+   regs_hash_destroy(ctx.regs_used);
+   regs_hash_destroy(ctx.regs_ind_used);
    return ctx.errors == 0;
 }
diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c
index f9c16f1..a6cc773 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_scan.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c
@@ -35,7 +35,6 @@
 
 
 #include "util/u_math.h"
-#include "tgsi/tgsi_build.h"
 #include "tgsi/tgsi_parse.h"
 #include "tgsi/tgsi_scan.h"
 
@@ -97,14 +96,15 @@
                uint i;
                for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
                   const struct tgsi_full_src_register *src =
-                     &fullinst->FullSrcRegisters[i];
-                  if (src->SrcRegister.File == TGSI_FILE_INPUT) {
-                     const int ind = src->SrcRegister.Index;
+                     &fullinst->Src[i];
+                  if (src->Register.File == TGSI_FILE_INPUT ||
+                      src->Register.File == TGSI_FILE_SYSTEM_VALUE) {
+                     const int ind = src->Register.Index;
                      if (info->input_semantic_name[ind] == TGSI_SEMANTIC_FOG) {
-                        if (src->SrcRegister.SwizzleX == TGSI_SWIZZLE_X) {
+                        if (src->Register.SwizzleX == TGSI_SWIZZLE_X) {
                            info->uses_fogcoord = TRUE;
                         }
-                        else if (src->SrcRegister.SwizzleX == TGSI_SWIZZLE_Y) {
+                        else if (src->Register.SwizzleX == TGSI_SWIZZLE_Y) {
                            info->uses_frontfacing = TRUE;
                         }
                      }
@@ -120,8 +120,8 @@
                = &parse.FullToken.FullDeclaration;
             const uint file = fulldecl->Declaration.File;
             uint reg;
-            for (reg = fulldecl->DeclarationRange.First;
-                 reg <= fulldecl->DeclarationRange.Last;
+            for (reg = fulldecl->Range.First;
+                 reg <= fulldecl->Range.Last;
                  reg++) {
 
                /* only first 32 regs will appear in this bitfield */
@@ -129,25 +129,29 @@
                info->file_count[file]++;
                info->file_max[file] = MAX2(info->file_max[file], (int)reg);
 
-               if (file == TGSI_FILE_INPUT) {
-                  info->input_semantic_name[reg] = (ubyte)fulldecl->Semantic.SemanticName;
-                  info->input_semantic_index[reg] = (ubyte)fulldecl->Semantic.SemanticIndex;
+               if (file == TGSI_FILE_INPUT || file == TGSI_FILE_SYSTEM_VALUE) {
+                  info->input_semantic_name[reg] = (ubyte)fulldecl->Semantic.Name;
+                  info->input_semantic_index[reg] = (ubyte)fulldecl->Semantic.Index;
                   info->input_interpolate[reg] = (ubyte)fulldecl->Declaration.Interpolate;
                   info->num_inputs++;
                }
                else if (file == TGSI_FILE_OUTPUT) {
-                  info->output_semantic_name[reg] = (ubyte)fulldecl->Semantic.SemanticName;
-                  info->output_semantic_index[reg] = (ubyte)fulldecl->Semantic.SemanticIndex;
+                  info->output_semantic_name[reg] = (ubyte)fulldecl->Semantic.Name;
+                  info->output_semantic_index[reg] = (ubyte)fulldecl->Semantic.Index;
                   info->num_outputs++;
+
+                  /* extra info for special outputs */
+                  if (procType == TGSI_PROCESSOR_FRAGMENT &&
+                      fulldecl->Semantic.Name == TGSI_SEMANTIC_POSITION) {
+                     info->writes_z = TRUE;
+                  }
+                  if (procType == TGSI_PROCESSOR_VERTEX &&
+                      fulldecl->Semantic.Name == TGSI_SEMANTIC_EDGEFLAG) {
+                     info->writes_edgeflag = TRUE;
+                  }
                }
 
-               /* special case */
-               if (procType == TGSI_PROCESSOR_FRAGMENT &&
-                   file == TGSI_FILE_OUTPUT &&
-                   fulldecl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) {
-                  info->writes_z = TRUE;
-               }
-            }
+             }
          }
          break;
 
@@ -161,6 +165,19 @@
             info->file_max[file] = MAX2(info->file_max[file], (int)reg);
          }
          break;
+      case TGSI_TOKEN_TYPE_PROPERTY:
+      {
+         const struct tgsi_full_property *fullprop
+            = &parse.FullToken.FullProperty;
+
+         info->properties[info->num_properties].name =
+            fullprop->Property.PropertyName;
+         memcpy(info->properties[info->num_properties].data,
+                fullprop->u, 8 * sizeof(unsigned));;
+
+         ++info->num_properties;
+      }
+      break;
 
       default:
          assert( 0 );
@@ -206,29 +223,26 @@
             struct tgsi_full_instruction *fullinst =
                &parse.FullToken.FullInstruction;
             const struct tgsi_full_src_register *src =
-               &fullinst->FullSrcRegisters[0];
+               &fullinst->Src[0];
             const struct tgsi_full_dst_register *dst =
-               &fullinst->FullDstRegisters[0];
+               &fullinst->Dst[0];
 
             /* Do a whole bunch of checks for a simple move */
             if (fullinst->Instruction.Opcode != TGSI_OPCODE_MOV ||
-                src->SrcRegister.File != TGSI_FILE_INPUT ||
-                dst->DstRegister.File != TGSI_FILE_OUTPUT ||
-                src->SrcRegister.Index != dst->DstRegister.Index ||
+                (src->Register.File != TGSI_FILE_INPUT &&
+                 src->Register.File != TGSI_FILE_SYSTEM_VALUE) ||
+                dst->Register.File != TGSI_FILE_OUTPUT ||
+                src->Register.Index != dst->Register.Index ||
 
-                src->SrcRegister.Negate ||
-                src->SrcRegisterExtMod.Negate ||
-                src->SrcRegisterExtMod.Absolute ||
-                src->SrcRegisterExtMod.Scale2X ||
-                src->SrcRegisterExtMod.Bias ||
-                src->SrcRegisterExtMod.Complement ||
+                src->Register.Negate ||
+                src->Register.Absolute ||
 
-                src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X ||
-                src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y ||
-                src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z ||
-                src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W ||
+                src->Register.SwizzleX != TGSI_SWIZZLE_X ||
+                src->Register.SwizzleY != TGSI_SWIZZLE_Y ||
+                src->Register.SwizzleZ != TGSI_SWIZZLE_Z ||
+                src->Register.SwizzleW != TGSI_SWIZZLE_W ||
 
-                dst->DstRegister.WriteMask != TGSI_WRITEMASK_XYZW)
+                dst->Register.WriteMask != TGSI_WRITEMASK_XYZW)
             {
                tgsi_parse_free(&parse);
                return FALSE;
@@ -240,6 +254,8 @@
          /* fall-through */
       case TGSI_TOKEN_TYPE_IMMEDIATE:
          /* fall-through */
+      case TGSI_TOKEN_TYPE_PROPERTY:
+         /* fall-through */
       default:
          ; /* no-op */
       }
diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.h b/src/gallium/auxiliary/tgsi/tgsi_scan.h
index 8a7ee0c..dae5376 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_scan.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h
@@ -33,7 +33,6 @@
 #include "pipe/p_state.h"
 #include "pipe/p_shader_tokens.h"
 
-
 /**
  * Shader summary info
  */
@@ -58,11 +57,17 @@
    uint opcode_count[TGSI_OPCODE_LAST];  /**< opcode histogram */
 
    boolean writes_z;  /**< does fragment shader write Z value? */
+   boolean writes_edgeflag; /**< vertex shader outputs edgeflag */
    boolean uses_kill;  /**< KIL or KILP instruction used? */
    boolean uses_fogcoord; /**< fragment shader uses fog coord? */
    boolean uses_frontfacing; /**< fragment shader uses front/back-face flag? */
-};
 
+   struct {
+      unsigned name;
+      unsigned data[8];
+   } properties[TGSI_PROPERTY_COUNT];
+   uint num_properties;
+};
 
 extern void
 tgsi_scan_shader(const struct tgsi_token *tokens,
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
index a96fc94..a85cc46 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
@@ -2,6 +2,7 @@
  * 
  * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
+ * Copyright 2009-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
@@ -58,7 +59,7 @@
    for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++)
 
 #define IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
-   ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN)))
+   ((INST).Dst[0].Register.WriteMask & (1 << (CHAN)))
 
 #define IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
    if (IS_DST0_CHANNEL_ENABLED( INST, CHAN ))
@@ -1267,31 +1268,32 @@
    case TGSI_SWIZZLE_Y:
    case TGSI_SWIZZLE_Z:
    case TGSI_SWIZZLE_W:
-      switch (reg->SrcRegister.File) {
+      switch (reg->Register.File) {
       case TGSI_FILE_CONSTANT:
          emit_const(
             func,
             xmm,
-            reg->SrcRegister.Index,
+            reg->Register.Index,
             swizzle,
-            reg->SrcRegister.Indirect,
-            reg->SrcRegisterInd.File,
-            reg->SrcRegisterInd.Index );
+            reg->Register.Indirect,
+            reg->Indirect.File,
+            reg->Indirect.Index );
          break;
 
       case TGSI_FILE_IMMEDIATE:
          emit_immediate(
             func,
             xmm,
-            reg->SrcRegister.Index,
+            reg->Register.Index,
             swizzle );
          break;
 
       case TGSI_FILE_INPUT:
+      case TGSI_FILE_SYSTEM_VALUE:
          emit_inputf(
             func,
             xmm,
-            reg->SrcRegister.Index,
+            reg->Register.Index,
             swizzle );
          break;
 
@@ -1299,7 +1301,7 @@
          emit_tempf(
             func,
             xmm,
-            reg->SrcRegister.Index,
+            reg->Register.Index,
             swizzle );
          break;
 
@@ -1331,7 +1333,7 @@
 }
 
 #define FETCH( FUNC, INST, XMM, INDEX, CHAN )\
-   emit_fetch( FUNC, XMM, &(INST).FullSrcRegisters[INDEX], CHAN )
+   emit_fetch( FUNC, XMM, &(INST).Src[INDEX], CHAN )
 
 /**
  * Register store.
@@ -1371,12 +1373,12 @@
    }
 
 
-   switch( reg->DstRegister.File ) {
+   switch( reg->Register.File ) {
    case TGSI_FILE_OUTPUT:
       emit_output(
          func,
          xmm,
-         reg->DstRegister.Index,
+         reg->Register.Index,
          chan_index );
       break;
 
@@ -1384,7 +1386,7 @@
       emit_temps(
          func,
          xmm,
-         reg->DstRegister.Index,
+         reg->Register.Index,
          chan_index );
       break;
 
@@ -1392,7 +1394,7 @@
       emit_addrs(
          func,
          xmm,
-         reg->DstRegister.Index,
+         reg->Register.Index,
          chan_index );
       break;
 
@@ -1402,7 +1404,7 @@
 }
 
 #define STORE( FUNC, INST, XMM, INDEX, CHAN )\
-   emit_store( FUNC, XMM, &(INST).FullDstRegisters[INDEX], &(INST), CHAN )
+   emit_store( FUNC, XMM, &(INST).Dst[INDEX], &(INST), CHAN )
 
 
 static void PIPE_CDECL
@@ -1417,13 +1419,13 @@
                 sampler, *sampler,
                 store );
 
-   debug_printf("lodbias %f\n", store[12]);
-
    for (j = 0; j < 4; j++)
-      debug_printf("sample %d texcoord %f %f\n", 
+      debug_printf("sample %d texcoord %f %f %f lodbias %f\n",
                    j, 
                    store[0+j],
-                   store[4+j]);
+                   store[4+j],
+                   store[8 + j],
+                   store[12 + j]);
 #endif
 
    {
@@ -1432,7 +1434,8 @@
                               &store[0],  /* s */
                               &store[4],  /* t */
                               &store[8],  /* r */
-                              store[12],  /* lodbias */
+                              &store[12], /* lodbias */
+                              tgsi_sampler_lod_bias,
                               rgba);      /* results */
 
       memcpy( store, rgba, 16 * sizeof(float));
@@ -1459,12 +1462,13 @@
           boolean lodbias,
           boolean projected)
 {
-   const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index;
+   const uint unit = inst->Src[1].Register.Index;
    struct x86_reg args[2];
    unsigned count;
    unsigned i;
 
-   switch (inst->InstructionExtTexture.Texture) {
+   assert(inst->Instruction.Texture);
+   switch (inst->Texture.Texture) {
    case TGSI_TEXTURE_1D:
       count = 1;
       break;
@@ -1719,15 +1723,15 @@
 {
    uint i;
    for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
-      const struct tgsi_full_src_register *reg = &inst->FullSrcRegisters[i];
-      if (reg->SrcRegister.File == TGSI_FILE_TEMPORARY &&
-          reg->SrcRegister.Indirect)
+      const struct tgsi_full_src_register *reg = &inst->Src[i];
+      if (reg->Register.File == TGSI_FILE_TEMPORARY &&
+          reg->Register.Indirect)
          return TRUE;
    }
    for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
-      const struct tgsi_full_dst_register *reg = &inst->FullDstRegisters[i];
-      if (reg->DstRegister.File == TGSI_FILE_TEMPORARY &&
-          reg->DstRegister.Indirect)
+      const struct tgsi_full_dst_register *reg = &inst->Dst[i];
+      if (reg->Register.File == TGSI_FILE_TEMPORARY &&
+          reg->Register.Indirect)
          return TRUE;
    }
    return FALSE;
@@ -2142,40 +2146,50 @@
       break;
 
    case TGSI_OPCODE_XPD:
+      /* Note: we do all stores after all operands have been fetched
+       * to avoid src/dst register aliasing issues for an instruction
+       * such as:  XPD TEMP[2].xyz, TEMP[0], TEMP[2];
+       */
       if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ||
           IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) {
-         FETCH( func, *inst, 1, 1, CHAN_Z );
-         FETCH( func, *inst, 3, 0, CHAN_Z );
+         FETCH( func, *inst, 1, 1, CHAN_Z ); /* xmm[1] = src[1].z */
+         FETCH( func, *inst, 3, 0, CHAN_Z ); /* xmm[3] = src[0].z */
       }
       if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ||
           IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) {
-         FETCH( func, *inst, 0, 0, CHAN_Y );
-         FETCH( func, *inst, 4, 1, CHAN_Y );
+         FETCH( func, *inst, 0, 0, CHAN_Y ); /* xmm[0] = src[0].y */
+         FETCH( func, *inst, 4, 1, CHAN_Y ); /* xmm[4] = src[1].y */
       }
       IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) {
-         emit_MOV( func, 2, 0 );
-         emit_mul( func, 2, 1 );
-         emit_MOV( func, 5, 3 );
-         emit_mul( func, 5, 4 );
-         emit_sub( func, 2, 5 );
-         STORE( func, *inst, 2, 0, CHAN_X );
+         emit_MOV( func, 7, 0 );  /* xmm[7] = xmm[0] */
+         emit_mul( func, 7, 1 );  /* xmm[7] = xmm[2] * xmm[1] */
+         emit_MOV( func, 5, 3 );  /* xmm[5] = xmm[3] */
+         emit_mul( func, 5, 4 );  /* xmm[5] = xmm[5] * xmm[4] */
+         emit_sub( func, 7, 5 );  /* xmm[7] = xmm[2] - xmm[5] */
+         /* store xmm[7] in dst.x below */
       }
       if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ||
           IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) {
-         FETCH( func, *inst, 2, 1, CHAN_X );
-         FETCH( func, *inst, 5, 0, CHAN_X );
+         FETCH( func, *inst, 2, 1, CHAN_X ); /* xmm[2] = src[1].x */
+         FETCH( func, *inst, 5, 0, CHAN_X ); /* xmm[5] = src[0].x */
       }
       IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) {
-         emit_mul( func, 3, 2 );
-         emit_mul( func, 1, 5 );
-         emit_sub( func, 3, 1 );
-         STORE( func, *inst, 3, 0, CHAN_Y );
+         emit_mul( func, 3, 2 );  /* xmm[3] = xmm[3] * xmm[2] */
+         emit_mul( func, 1, 5 );  /* xmm[1] = xmm[1] * xmm[5] */
+         emit_sub( func, 3, 1 );  /* xmm[3] = xmm[3] - xmm[1] */
+         /* store xmm[3] in dst.y below */
       }
       IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) {
-         emit_mul( func, 5, 4 );
-         emit_mul( func, 0, 2 );
-         emit_sub( func, 5, 0 );
-         STORE( func, *inst, 5, 0, CHAN_Z );
+         emit_mul( func, 5, 4 );  /* xmm[5] = xmm[5] * xmm[4] */
+         emit_mul( func, 0, 2 );  /* xmm[0] = xmm[0] * xmm[2] */
+         emit_sub( func, 5, 0 );  /* xmm[5] = xmm[5] - xmm[0] */
+         STORE( func, *inst, 5, 0, CHAN_Z ); /* dst.z = xmm[5] */
+      }
+      IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) {
+         STORE( func, *inst, 7, 0, CHAN_X ); /* dst.x = xmm[7] */
+      }
+      IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) {
+         STORE( func, *inst, 3, 0, CHAN_Y ); /* dst.y = xmm[3] */
       }
       IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) {
 	 emit_tempf(
@@ -2243,7 +2257,7 @@
 
    case TGSI_OPCODE_KIL:
       /* conditional kill */
-      emit_kil( func, &inst->FullSrcRegisters[0] );
+      emit_kil( func, &inst->Src[0] );
       break;
 
    case TGSI_OPCODE_PK2H:
@@ -2504,7 +2518,7 @@
       break;
 
    case TGSI_OPCODE_TXL:
-      emit_tex( func, inst, TRUE, FALSE );
+      return 0;
       break;
 
    case TGSI_OPCODE_TXP:
@@ -2576,7 +2590,7 @@
       return 0;
       break;
 
-   case TGSI_OPCODE_SHR:
+   case TGSI_OPCODE_ISHR:
       return 0;
       break;
 
@@ -2632,12 +2646,13 @@
    struct x86_function *func,
    struct tgsi_full_declaration *decl )
 {
-   if( decl->Declaration.File == TGSI_FILE_INPUT ) {
+   if( decl->Declaration.File == TGSI_FILE_INPUT ||
+       decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE ) {
       unsigned first, last, mask;
       unsigned i, j;
 
-      first = decl->DeclarationRange.First;
-      last = decl->DeclarationRange.Last;
+      first = decl->Range.First;
+      last = decl->Range.Last;
       mask = decl->Declaration.UsageMask;
 
       for( i = first; i <= last; i++ ) {
@@ -2951,6 +2966,9 @@
             num_immediates++;
          }
          break;
+      case TGSI_TOKEN_TYPE_PROPERTY:
+         /* we just ignore them for now */
+         break;
 
       default:
 	 ok = 0;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index d2b03ff..9fcffed 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -27,6 +27,9 @@
 
 #include "util/u_debug.h"
 #include "util/u_memory.h"
+#include "util/u_prim.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_inlines.h"
 #include "tgsi_text.h"
 #include "tgsi_build.h"
 #include "tgsi_info.h"
@@ -59,6 +62,23 @@
    return c;
 }
 
+/*
+ * Ignore case of str1 and assume str1 is already uppercase.
+ * Return TRUE iff str1 and str2 are equal.
+ */
+static int
+streq_nocase_uprcase(const char *str1,
+                     const char *str2)
+{
+   while (*str1 && *str2) {
+      if (*str1 != uprcase(*str2))
+         return FALSE;
+      str1++;
+      str2++;
+   }
+   return TRUE;
+}
+
 static boolean str_match_no_case( const char **pcur, const char *str )
 {
    const char *cur = *pcur;
@@ -110,6 +130,20 @@
    return FALSE;
 }
 
+static boolean parse_identifier( const char **pcur, char *ret )
+{
+   const char *cur = *pcur;
+   int i = 0;
+   if (is_alpha_underscore( cur )) {
+      ret[i++] = *cur++;
+      while (is_alpha_underscore( cur ))
+         ret[i++] = *cur++;
+      *pcur = cur;
+      return TRUE;
+   }
+   return FALSE;
+}
+
 /* Parse floating point.
  */
 static boolean parse_float( const char **pcur, float *val )
@@ -163,28 +197,43 @@
    struct tgsi_token *tokens_cur;
    struct tgsi_token *tokens_end;
    struct tgsi_header *header;
+   unsigned processor : 4;
+   int implied_array_size : 5;
 };
 
 static void report_error( struct translate_ctx *ctx, const char *msg )
 {
-   debug_printf( "\nError: %s", msg );
+   int line = 1;
+   int column = 1;
+   const char *itr = ctx->text;
+
+   while (itr != ctx->cur) {
+      if (*itr == '\n') {
+         column = 1;
+         ++line;
+      }
+      ++column;
+      ++itr;
+   }
+
+   debug_printf( "\nTGSI asm error: %s [%d : %d] \n", msg, line, column );
 }
 
 /* Parse shader header.
  * Return TRUE for one of the following headers.
- *    FRAG1.1
- *    GEOM1.1
- *    VERT1.1
+ *    FRAG
+ *    GEOM
+ *    VERT
  */
 static boolean parse_header( struct translate_ctx *ctx )
 {
    uint processor;
 
-   if (str_match_no_case( &ctx->cur, "FRAG1.1" ))
+   if (str_match_no_case( &ctx->cur, "FRAG" ))
       processor = TGSI_PROCESSOR_FRAGMENT;
-   else if (str_match_no_case( &ctx->cur, "VERT1.1" ))
+   else if (str_match_no_case( &ctx->cur, "VERT" ))
       processor = TGSI_PROCESSOR_VERTEX;
-   else if (str_match_no_case( &ctx->cur, "GEOM1.1" ))
+   else if (str_match_no_case( &ctx->cur, "GEOM" ))
       processor = TGSI_PROCESSOR_GEOMETRY;
    else {
       report_error( ctx, "Unknown header" );
@@ -193,16 +242,13 @@
 
    if (ctx->tokens_cur >= ctx->tokens_end)
       return FALSE;
-   *(struct tgsi_version *) ctx->tokens_cur++ = tgsi_build_version();
-
-   if (ctx->tokens_cur >= ctx->tokens_end)
-      return FALSE;
    ctx->header = (struct tgsi_header *) ctx->tokens_cur++;
    *ctx->header = tgsi_build_header();
 
    if (ctx->tokens_cur >= ctx->tokens_end)
       return FALSE;
    *(struct tgsi_processor *) ctx->tokens_cur++ = tgsi_build_processor( processor, ctx->header );
+   ctx->processor = processor;
 
    return TRUE;
 }
@@ -233,7 +279,8 @@
    "ADDR",
    "IMM",
    "LOOP",
-   "PRED"
+   "PRED",
+   "SV"
 };
 
 static boolean
@@ -298,6 +345,125 @@
    return TRUE;
 }
 
+static boolean
+parse_register_dst( struct translate_ctx *ctx,
+                    uint *file,
+                    int *index );
+
+struct parsed_src_bracket {
+   int index;
+
+   uint ind_file;
+   int ind_index;
+   uint ind_comp;
+};
+
+
+static boolean
+parse_register_src_bracket(
+   struct translate_ctx *ctx,
+   struct parsed_src_bracket *brackets)
+{
+   const char *cur;
+   uint uindex;
+
+   memset(brackets, 0, sizeof(struct parsed_src_bracket));
+
+   eat_opt_white( &ctx->cur );
+
+   cur = ctx->cur;
+   if (parse_file( &cur, &brackets->ind_file )) {
+      if (!parse_register_dst( ctx, &brackets->ind_file,
+                               &brackets->ind_index ))
+         return FALSE;
+      eat_opt_white( &ctx->cur );
+
+      if (*ctx->cur == '.') {
+         ctx->cur++;
+         eat_opt_white(&ctx->cur);
+
+         switch (uprcase(*ctx->cur)) {
+         case 'X':
+            brackets->ind_comp = TGSI_SWIZZLE_X;
+            break;
+         case 'Y':
+            brackets->ind_comp = TGSI_SWIZZLE_Y;
+            break;
+         case 'Z':
+            brackets->ind_comp = TGSI_SWIZZLE_Z;
+            break;
+         case 'W':
+            brackets->ind_comp = TGSI_SWIZZLE_W;
+            break;
+         default:
+            report_error(ctx, "Expected indirect register swizzle component `x', `y', `z' or `w'");
+            return FALSE;
+         }
+         ctx->cur++;
+         eat_opt_white(&ctx->cur);
+      }
+
+      if (*ctx->cur == '+' || *ctx->cur == '-') {
+         boolean negate;
+
+         negate = *ctx->cur == '-';
+         ctx->cur++;
+         eat_opt_white( &ctx->cur );
+         if (!parse_uint( &ctx->cur, &uindex )) {
+            report_error( ctx, "Expected literal unsigned integer" );
+            return FALSE;
+         }
+         if (negate)
+            brackets->index = -(int) uindex;
+         else
+            brackets->index = (int) uindex;
+      }
+      else {
+         brackets->index = 0;
+      }
+   }
+   else {
+      if (!parse_uint( &ctx->cur, &uindex )) {
+         report_error( ctx, "Expected literal unsigned integer" );
+         return FALSE;
+      }
+      brackets->index = (int) uindex;
+      brackets->ind_file = TGSI_FILE_NULL;
+      brackets->ind_index = 0;
+   }
+   eat_opt_white( &ctx->cur );
+   if (*ctx->cur != ']') {
+      report_error( ctx, "Expected `]'" );
+      return FALSE;
+   }
+   ctx->cur++;
+   return TRUE;
+}
+
+static boolean
+parse_opt_register_src_bracket(
+   struct translate_ctx *ctx,
+   struct parsed_src_bracket *brackets,
+   int *parsed_brackets)
+{
+   const char *cur = ctx->cur;
+
+   *parsed_brackets = 0;
+
+   eat_opt_white( &cur );
+   if (cur[0] == '[') {
+      ++cur;
+      ctx->cur = cur;
+
+      if (!parse_register_src_bracket(ctx, brackets))
+         return FALSE;
+
+      *parsed_brackets = 1;
+   }
+
+   return TRUE;
+}
+
 /* <register_file_bracket> ::= <file> `['
  */
 static boolean
@@ -339,6 +505,128 @@
    return TRUE;
 }
 
+/* Parse source register operand.
+ *    <register_src> ::= <register_file_bracket_index> `]' |
+ *                       <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `]' |
+ *                       <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `+' <uint> `]' |
+ *                       <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `-' <uint> `]'
+ */
+static boolean
+parse_register_src(
+   struct translate_ctx *ctx,
+   uint *file,
+   struct parsed_src_bracket *brackets)
+{
+
+   brackets->ind_comp = TGSI_SWIZZLE_X;
+   if (!parse_register_file_bracket( ctx, file ))
+      return FALSE;
+   if (!parse_register_src_bracket( ctx, brackets ))
+       return FALSE;
+
+   return TRUE;
+}
+
+struct parsed_dcl_bracket {
+   uint first;
+   uint last;
+};
+
+static boolean
+parse_register_dcl_bracket(
+   struct translate_ctx *ctx,
+   struct parsed_dcl_bracket *bracket)
+{
+   uint uindex;
+   memset(bracket, 0, sizeof(struct parsed_dcl_bracket));
+
+   eat_opt_white( &ctx->cur );
+
+   if (!parse_uint( &ctx->cur, &uindex )) {
+      /* it can be an empty bracket [] which means its range
+       * is from 0 to some implied size */
+      if (ctx->cur[0] == ']' && ctx->implied_array_size != 0) {
+         bracket->first = 0;
+         bracket->last = ctx->implied_array_size - 1;
+         goto cleanup;
+      }
+      report_error( ctx, "Expected literal unsigned integer" );
+      return FALSE;
+   }
+   bracket->first = (int) uindex;
+
+   eat_opt_white( &ctx->cur );
+
+   if (ctx->cur[0] == '.' && ctx->cur[1] == '.') {
+      uint uindex;
+
+      ctx->cur += 2;
+      eat_opt_white( &ctx->cur );
+      if (!parse_uint( &ctx->cur, &uindex )) {
+         report_error( ctx, "Expected literal integer" );
+         return FALSE;
+      }
+      bracket->last = (int) uindex;
+      eat_opt_white( &ctx->cur );
+   }
+   else {
+      bracket->last = bracket->first;
+   }
+
+cleanup:
+   if (*ctx->cur != ']') {
+      report_error( ctx, "Expected `]' or `..'" );
+      return FALSE;
+   }
+   ctx->cur++;
+   return TRUE;
+}
+
+/* Parse register declaration.
+ *    <register_dcl> ::= <register_file_bracket_index> `]' |
+ *                       <register_file_bracket_index> `..' <index> `]'
+ */
+static boolean
+parse_register_dcl(
+   struct translate_ctx *ctx,
+   uint *file,
+   struct parsed_dcl_bracket *brackets,
+   int *num_brackets)
+{
+   const char *cur;
+
+   *num_brackets = 0;
+
+   if (!parse_register_file_bracket( ctx, file ))
+      return FALSE;
+   if (!parse_register_dcl_bracket( ctx, &brackets[0] ))
+      return FALSE;
+
+   *num_brackets = 1;
+
+   cur = ctx->cur;
+   eat_opt_white( &cur );
+
+   if (cur[0] == '[') {
+      ++cur;
+      ctx->cur = cur;
+      if (!parse_register_dcl_bracket( ctx, &brackets[1] ))
+         return FALSE;
+      /* for geometry shader we don't really care about
+       * the first brackets it's always the size of the
+       * input primitive. so we want to declare just
+       * the index relevant to the semantics which is in
+       * the second bracket */
+      if (ctx->processor == TGSI_PROCESSOR_GEOMETRY) {
+         brackets[0] = brackets[1];
+      }
+      *num_brackets = 2;
+   }
+
+   return TRUE;
+}
+
+
 /* Parse destination register operand.
  *    <register_dst> ::= <register_file_bracket_index> `]'
  */
@@ -359,144 +647,6 @@
    return TRUE;
 }
 
-/* Parse source register operand.
- *    <register_src> ::= <register_file_bracket_index> `]' |
- *                       <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `]' |
- *                       <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `+' <uint> `]' |
- *                       <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `-' <uint> `]'
- */
-static boolean
-parse_register_src(
-   struct translate_ctx *ctx,
-   uint *file,
-   int *index,
-   uint *ind_file,
-   int *ind_index,
-   uint *ind_comp)
-{
-   const char *cur;
-   uint uindex;
-
-   *ind_comp = TGSI_SWIZZLE_X;
-   if (!parse_register_file_bracket( ctx, file ))
-      return FALSE;
-   eat_opt_white( &ctx->cur );
-   cur = ctx->cur;
-   if (parse_file( &cur, ind_file )) {
-      if (!parse_register_dst( ctx, ind_file, ind_index ))
-         return FALSE;
-      eat_opt_white( &ctx->cur );
-
-      if (*ctx->cur == '.') {
-         ctx->cur++;
-         eat_opt_white(&ctx->cur);
-
-         switch (uprcase(*ctx->cur)) {
-         case 'X':
-            *ind_comp = TGSI_SWIZZLE_X;
-            break;
-         case 'Y':
-            *ind_comp = TGSI_SWIZZLE_Y;
-            break;
-         case 'Z':
-            *ind_comp = TGSI_SWIZZLE_Z;
-            break;
-         case 'W':
-            *ind_comp = TGSI_SWIZZLE_W;
-            break;
-         default:
-            report_error(ctx, "Expected indirect register swizzle component `x', `y', `z' or `w'");
-            return FALSE;
-         }
-         ctx->cur++;
-         eat_opt_white(&ctx->cur);
-      }
-
-      if (*ctx->cur == '+' || *ctx->cur == '-') {
-         boolean negate;
-
-         negate = *ctx->cur == '-';
-         ctx->cur++;
-         eat_opt_white( &ctx->cur );
-         if (!parse_uint( &ctx->cur, &uindex )) {
-            report_error( ctx, "Expected literal unsigned integer" );
-            return FALSE;
-         }
-         if (negate)
-            *index = -(int) uindex;
-         else
-            *index = (int) uindex;
-      }
-      else {
-         *index = 0;
-      }
-   }
-   else {
-      if (!parse_uint( &ctx->cur, &uindex )) {
-         report_error( ctx, "Expected literal unsigned integer" );
-         return FALSE;
-      }
-      *index = (int) uindex;
-      *ind_file = TGSI_FILE_NULL;
-      *ind_index = 0;
-   }
-   eat_opt_white( &ctx->cur );
-   if (*ctx->cur != ']') {
-      report_error( ctx, "Expected `]'" );
-      return FALSE;
-   }
-   ctx->cur++;
-   return TRUE;
-}
-
-/* Parse register declaration.
- *    <register_dcl> ::= <register_file_bracket_index> `]' |
- *                       <register_file_bracket_index> `..' <index> `]'
- */
-static boolean
-parse_register_dcl(
-   struct translate_ctx *ctx,
-   uint *file,
-   int *first,
-   int *last )
-{
-   if (!parse_register_file_bracket_index( ctx, file, first ))
-      return FALSE;
-   eat_opt_white( &ctx->cur );
-   if (ctx->cur[0] == '.' && ctx->cur[1] == '.') {
-      uint uindex;
-
-      ctx->cur += 2;
-      eat_opt_white( &ctx->cur );
-      if (!parse_uint( &ctx->cur, &uindex )) {
-         report_error( ctx, "Expected literal integer" );
-         return FALSE;
-      }
-      *last = (int) uindex;
-      eat_opt_white( &ctx->cur );
-   }
-   else {
-      *last = *first;
-   }
-   if (*ctx->cur != ']') {
-      report_error( ctx, "Expected `]' or `..'" );
-      return FALSE;
-   }
-   ctx->cur++;
-   return TRUE;
-}
-
-static const char *modulate_names[TGSI_MODULATE_COUNT] =
-{
-   "_1X",
-   "_2X",
-   "_4X",
-   "_8X",
-   "_D2",
-   "_D4",
-   "_D8"
-};
-
 static boolean
 parse_dst_operand(
    struct translate_ctx *ctx,
@@ -512,26 +662,13 @@
 
    cur = ctx->cur;
    eat_opt_white( &cur );
-   if (*cur == '_') {
-      uint i;
-
-      for (i = 0; i < TGSI_MODULATE_COUNT; i++) {
-         if (str_match_no_case( &cur, modulate_names[i] )) {
-            if (!is_digit_alpha_underscore( cur )) {
-               dst->DstRegisterExtModulate.Modulate = i;
-               ctx->cur = cur;
-               break;
-            }
-         }
-      }
-   }
 
    if (!parse_opt_writemask( ctx, &writemask ))
       return FALSE;
 
-   dst->DstRegister.File = file;
-   dst->DstRegister.Index = index;
-   dst->DstRegister.WriteMask = writemask;
+   dst->Register.File = file;
+   dst->Register.Index = index;
+   dst->Register.WriteMask = writemask;
    return TRUE;
 }
 
@@ -577,162 +714,59 @@
    struct translate_ctx *ctx,
    struct tgsi_full_src_register *src )
 {
-   const char *cur;
-   float value;
    uint file;
-   int index;
-   uint ind_file;
-   int ind_index;
-   uint ind_comp;
    uint swizzle[4];
-   boolean parsed_ext_negate_paren = FALSE;
    boolean parsed_swizzle;
-
-   if (*ctx->cur == '-') {
-      cur = ctx->cur;
-      cur++;
-      eat_opt_white( &cur );
-      if (*cur == '(') {
-         cur++;
-         src->SrcRegisterExtMod.Negate = 1;
-         eat_opt_white( &cur );
-         ctx->cur = cur;
-         parsed_ext_negate_paren = TRUE;
-      }
-      else if (*cur == '|') {
-         cur++;
-         src->SrcRegisterExtMod.Negate = 1;
-         src->SrcRegisterExtMod.Absolute = 1;
-         eat_opt_white(&cur);
-         ctx->cur = cur;
-      }
-   }
-   else if (*ctx->cur == '|') {
-      ctx->cur++;
-      eat_opt_white( &ctx->cur );
-      src->SrcRegisterExtMod.Absolute = 1;
-   }
+   struct parsed_src_bracket bracket[2];
+   int parsed_opt_brackets;
 
    if (*ctx->cur == '-') {
       ctx->cur++;
       eat_opt_white( &ctx->cur );
-      src->SrcRegister.Negate = 1;
+      src->Register.Negate = 1;
    }
 
-   cur = ctx->cur;
-   if (parse_float( &cur, &value )) {
-      if (value == 2.0f) {
-         eat_opt_white( &cur );
-         if (*cur != '*') {
-            report_error( ctx, "Expected `*'" );
-            return FALSE;
-         }
-         cur++;
-         if (*cur != '(') {
-            report_error( ctx, "Expected `('" );
-            return FALSE;
-         }
-         cur++;
-         src->SrcRegisterExtMod.Scale2X = 1;
-         eat_opt_white( &cur );
-         ctx->cur = cur;
-      }
-   }
-
-   if (*ctx->cur == '(') {
+   if (*ctx->cur == '|') {
       ctx->cur++;
       eat_opt_white( &ctx->cur );
-      src->SrcRegisterExtMod.Bias = 1;
+      src->Register.Absolute = 1;
    }
 
-   cur = ctx->cur;
-   if (parse_float( &cur, &value )) {
-      if (value == 1.0f) {
-         eat_opt_white( &cur );
-         if (*cur != '-') {
-            report_error( ctx, "Expected `-'" );
-            return FALSE;
-         }
-         cur++;
-         if (*cur != '(') {
-            report_error( ctx, "Expected `('" );
-            return FALSE;
-         }
-         cur++;
-         src->SrcRegisterExtMod.Complement = 1;
-         eat_opt_white( &cur );
-         ctx->cur = cur;
-      }
-   }
-
-   if (!parse_register_src(ctx, &file, &index, &ind_file, &ind_index, &ind_comp))
+   if (!parse_register_src(ctx, &file, &bracket[0]))
       return FALSE;
-   src->SrcRegister.File = file;
-   src->SrcRegister.Index = index;
-   if (ind_file != TGSI_FILE_NULL) {
-      src->SrcRegister.Indirect = 1;
-      src->SrcRegisterInd.File = ind_file;
-      src->SrcRegisterInd.Index = ind_index;
-      src->SrcRegisterInd.SwizzleX = ind_comp;
-      src->SrcRegisterInd.SwizzleY = ind_comp;
-      src->SrcRegisterInd.SwizzleZ = ind_comp;
-      src->SrcRegisterInd.SwizzleW = ind_comp;
+   if (!parse_opt_register_src_bracket(ctx, &bracket[1], &parsed_opt_brackets))
+      return FALSE;
+
+   src->Register.File = file;
+   src->Register.Index = bracket[0].index;
+   if (bracket[0].ind_file != TGSI_FILE_NULL) {
+      src->Register.Indirect = 1;
+      src->Indirect.File = bracket[0].ind_file;
+      src->Indirect.Index = bracket[0].ind_index;
+      src->Indirect.SwizzleX = bracket[0].ind_comp;
+      src->Indirect.SwizzleY = bracket[0].ind_comp;
+      src->Indirect.SwizzleZ = bracket[0].ind_comp;
+      src->Indirect.SwizzleW = bracket[0].ind_comp;
+   }
+   if (parsed_opt_brackets) {
+      src->Register.Dimension = 1;
+      src->Dimension.Indirect = 0;
+      src->Dimension.Dimension = 0;
+      src->Dimension.Index = bracket[1].index;
    }
 
    /* Parse optional swizzle.
     */
    if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle )) {
       if (parsed_swizzle) {
-         src->SrcRegister.SwizzleX = swizzle[0];
-         src->SrcRegister.SwizzleY = swizzle[1];
-         src->SrcRegister.SwizzleZ = swizzle[2];
-         src->SrcRegister.SwizzleW = swizzle[3];
+         src->Register.SwizzleX = swizzle[0];
+         src->Register.SwizzleY = swizzle[1];
+         src->Register.SwizzleZ = swizzle[2];
+         src->Register.SwizzleW = swizzle[3];
       }
    }
 
-   if (src->SrcRegisterExtMod.Complement) {
-      eat_opt_white( &ctx->cur );
-      if (*ctx->cur != ')') {
-         report_error( ctx, "Expected `)'" );
-         return FALSE;
-      }
-      ctx->cur++;
-   }
-
-   if (src->SrcRegisterExtMod.Bias) {
-      eat_opt_white( &ctx->cur );
-      if (*ctx->cur != ')') {
-         report_error( ctx, "Expected `)'" );
-         return FALSE;
-      }
-      ctx->cur++;
-      eat_opt_white( &ctx->cur );
-      if (*ctx->cur != '-') {
-         report_error( ctx, "Expected `-'" );
-         return FALSE;
-      }
-      ctx->cur++;
-      eat_opt_white( &ctx->cur );
-      if (!parse_float( &ctx->cur, &value )) {
-         report_error( ctx, "Expected literal floating point" );
-         return FALSE;
-      }
-      if (value != 0.5f) {
-         report_error( ctx, "Expected 0.5" );
-         return FALSE;
-      }
-   }
-
-   if (src->SrcRegisterExtMod.Scale2X) {
-      eat_opt_white( &ctx->cur );
-      if (*ctx->cur != ')') {
-         report_error( ctx, "Expected `)'" );
-         return FALSE;
-      }
-      ctx->cur++;
-   }
-
-   if (src->SrcRegisterExtMod.Absolute) {
+   if (src->Register.Absolute) {
       eat_opt_white( &ctx->cur );
       if (*ctx->cur != '|') {
          report_error( ctx, "Expected `|'" );
@@ -741,14 +775,6 @@
       ctx->cur++;
    }
 
-   if (parsed_ext_negate_paren) {
-      eat_opt_white( &ctx->cur );
-      if (*ctx->cur != ')') {
-         report_error( ctx, "Expected `)'" );
-         return FALSE;
-      }
-      ctx->cur++;
-   }
 
    return TRUE;
 }
@@ -840,11 +866,11 @@
       }
 
       if (i < info->num_dst) {
-         if (!parse_dst_operand( ctx, &inst.FullDstRegisters[i] ))
+         if (!parse_dst_operand( ctx, &inst.Dst[i] ))
             return FALSE;
       }
       else if (i < info->num_dst + info->num_src) {
-         if (!parse_src_operand( ctx, &inst.FullSrcRegisters[i - info->num_dst] ))
+         if (!parse_src_operand( ctx, &inst.Src[i - info->num_dst] ))
             return FALSE;
       }
       else {
@@ -853,7 +879,8 @@
          for (j = 0; j < TGSI_TEXTURE_COUNT; j++) {
             if (str_match_no_case( &ctx->cur, texture_names[j] )) {
                if (!is_digit_alpha_underscore( ctx->cur )) {
-                  inst.InstructionExtTexture.Texture = j;
+                  inst.Instruction.Texture = 1;
+                  inst.Texture.Texture = j;
                   break;
                }
             }
@@ -879,7 +906,8 @@
          report_error( ctx, "Expected a label" );
          return FALSE;
       }
-      inst.InstructionExtLabel.Label = target;
+      inst.Instruction.Label = 1;
+      inst.Label.Label = target;
    }
 
    advance = tgsi_build_full_instruction(
@@ -903,7 +931,9 @@
    "PSIZE",
    "GENERIC",
    "NORMAL",
-   "FACE"
+   "FACE",
+   "EDGEFLAG",
+   "PRIM_ID"
 };
 
 static const char *interpolate_names[TGSI_INTERPOLATE_COUNT] =
@@ -917,8 +947,8 @@
 {
    struct tgsi_full_declaration decl;
    uint file;
-   int first;
-   int last;
+   struct parsed_dcl_bracket brackets[2];
+   int num_brackets;
    uint writemask;
    const char *cur;
    uint advance;
@@ -930,7 +960,7 @@
       report_error( ctx, "Syntax error" );
       return FALSE;
    }
-   if (!parse_register_dcl( ctx, &file, &first, &last ))
+   if (!parse_register_dcl( ctx, &file, brackets, &num_brackets))
       return FALSE;
    if (!parse_opt_writemask( ctx, &writemask ))
       return FALSE;
@@ -938,8 +968,8 @@
    decl = tgsi_default_full_declaration();
    decl.Declaration.File = file;
    decl.Declaration.UsageMask = writemask;
-   decl.DeclarationRange.First = first;
-   decl.DeclarationRange.Last = last;
+   decl.Range.First = brackets[0].first;
+   decl.Range.Last = brackets[0].last;
 
    cur = ctx->cur;
    eat_opt_white( &cur );
@@ -970,13 +1000,13 @@
                }
                cur2++;
 
-               decl.Semantic.SemanticIndex = index;
+               decl.Semantic.Index = index;
 
                cur = cur2;
             }
 
             decl.Declaration.Semantic = 1;
-            decl.Semantic.SemanticName = i;
+            decl.Semantic.Name = i;
 
             ctx->cur = cur;
             break;
@@ -1082,6 +1112,110 @@
    return TRUE;
 }
 
+static const char *property_names[] =
+{
+   "GS_INPUT_PRIMITIVE",
+   "GS_OUTPUT_PRIMITIVE",
+   "GS_MAX_OUTPUT_VERTICES"
+};
+
+static const char *primitive_names[] =
+{
+   "POINTS",
+   "LINES",
+   "LINE_LOOP",
+   "LINE_STRIP",
+   "TRIANGLES",
+   "TRIANGLE_STRIP",
+   "TRIANGLE_FAN",
+   "QUADS",
+   "QUAD_STRIP",
+   "POLYGON"
+};
+
+static boolean
+parse_primitive( const char **pcur, uint *primitive )
+{
+   uint i;
+
+   for (i = 0; i < PIPE_PRIM_MAX; i++) {
+      const char *cur = *pcur;
+
+      if (str_match_no_case( &cur, primitive_names[i])) {
+         *primitive = i;
+         *pcur = cur;
+         return TRUE;
+      }
+   }
+   return FALSE;
+}
+
+
+static boolean parse_property( struct translate_ctx *ctx )
+{
+   struct tgsi_full_property prop;
+   uint property_name;
+   uint values[8];
+   uint advance;
+   char id[64];
+
+   if (!eat_white( &ctx->cur )) {
+      report_error( ctx, "Syntax error" );
+      return FALSE;
+   }
+   if (!parse_identifier( &ctx->cur, id )) {
+      report_error( ctx, "Syntax error" );
+      return FALSE;
+   }
+   for (property_name = 0; property_name < TGSI_PROPERTY_COUNT;
+        ++property_name) {
+      if (streq_nocase_uprcase(property_names[property_name], id)) {
+         break;
+      }
+   }
+   if (property_name >= TGSI_PROPERTY_COUNT) {
+      debug_printf( "\nError: Unknown property : '%s'", id );
+      return FALSE;
+   }
+
+   eat_opt_white( &ctx->cur );
+   switch(property_name) {
+   case TGSI_PROPERTY_GS_INPUT_PRIM:
+   case TGSI_PROPERTY_GS_OUTPUT_PRIM:
+      if (!parse_primitive(&ctx->cur, &values[0] )) {
+         report_error( ctx, "Unknown primitive name as property!" );
+         return FALSE;
+      }
+      if (property_name == TGSI_PROPERTY_GS_INPUT_PRIM &&
+          ctx->processor == TGSI_PROCESSOR_GEOMETRY) {
+         ctx->implied_array_size = u_vertices_per_prim(values[0]);
+      }
+      break;
+   default:
+      if (!parse_uint(&ctx->cur, &values[0] )) {
+         report_error( ctx, "Expected unsigned integer as property!" );
+         return FALSE;
+      }
+   }
+
+   prop = tgsi_default_full_property();
+   prop.Property.PropertyName = property_name;
+   prop.Property.NrTokens += 1;
+   prop.u[0].Data = values[0];
+
+   advance = tgsi_build_full_property(
+      &prop,
+      ctx->tokens_cur,
+      ctx->header,
+      (uint) (ctx->tokens_end - ctx->tokens_cur) );
+   if (advance == 0)
+      return FALSE;
+   ctx->tokens_cur += advance;
+
+   return TRUE;
+}
+
+
 static boolean translate( struct translate_ctx *ctx )
 {
    eat_opt_white( &ctx->cur );
@@ -1090,7 +1224,6 @@
 
    while (*ctx->cur != '\0') {
       uint label_val = 0;
-
       if (!eat_white( &ctx->cur )) {
          report_error( ctx, "Syntax error" );
          return FALSE;
@@ -1098,7 +1231,6 @@
 
       if (*ctx->cur == '\0')
          break;
-
       if (parse_label( ctx, &label_val )) {
          if (!parse_instruction( ctx, TRUE ))
             return FALSE;
@@ -1111,6 +1243,10 @@
          if (!parse_immediate( ctx ))
             return FALSE;
       }
+      else if (str_match_no_case( &ctx->cur, "PROPERTY" )) {
+         if (!parse_property( ctx ))
+            return FALSE;
+      }
       else if (!parse_instruction( ctx, FALSE )) {
          return FALSE;
       }
diff --git a/src/gallium/auxiliary/tgsi/tgsi_transform.c b/src/gallium/auxiliary/tgsi/tgsi_transform.c
index bc9c18f..ae875f2 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_transform.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_transform.c
@@ -79,6 +79,19 @@
 }
 
 
+static void
+emit_property(struct tgsi_transform_context *ctx,
+              const struct tgsi_full_property *prop)
+{
+   uint ti = ctx->ti;
+
+   ti += tgsi_build_full_property(prop,
+                                  ctx->tokens_out + ti,
+                                  ctx->header,
+                                  ctx->max_tokens_out - ti);
+   ctx->ti = ti;
+}
+
 
 /**
  * Apply user-defined transformations to the input shader to produce
@@ -110,6 +123,7 @@
    ctx->emit_instruction = emit_instruction;
    ctx->emit_declaration = emit_declaration;
    ctx->emit_immediate = emit_immediate;
+   ctx->emit_property = emit_property;
    ctx->tokens_out = tokens_out;
    ctx->max_tokens_out = max_tokens_out;
 
@@ -130,15 +144,13 @@
    /**
     **  Setup output shader
     **/
-   *(struct tgsi_version *) &tokens_out[0] = tgsi_build_version();
-
-   ctx->header = (struct tgsi_header *) (tokens_out + 1);
+   ctx->header = (struct tgsi_header *)tokens_out;
    *ctx->header = tgsi_build_header();
 
-   processor = (struct tgsi_processor *) (tokens_out + 2);
+   processor = (struct tgsi_processor *) (tokens_out + 1);
    *processor = tgsi_build_processor( procType, ctx->header );
 
-   ctx->ti = 3;
+   ctx->ti = 2;
 
 
    /**
@@ -184,6 +196,17 @@
                ctx->emit_immediate(ctx, fullimm);
          }
          break;
+      case TGSI_TOKEN_TYPE_PROPERTY:
+         {
+            struct tgsi_full_property *fullprop
+               = &parse.FullToken.FullProperty;
+
+            if (ctx->transform_property)
+               ctx->transform_property(ctx, fullprop);
+            else
+               ctx->emit_property(ctx, fullprop);
+         }
+         break;
 
       default:
          assert( 0 );
@@ -215,7 +238,7 @@
                     uint max_tokens_out )
 {
    const char *text = 
-      "FRAG1.1\n"
+      "FRAG\n"
       "DCL IN[0], COLOR, CONSTANT\n"
       "DCL OUT[0], COLOR\n"
       "  0: MOV OUT[0], IN[0]\n"
diff --git a/src/gallium/auxiliary/tgsi/tgsi_transform.h b/src/gallium/auxiliary/tgsi/tgsi_transform.h
index a121adb..818478e 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_transform.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_transform.h
@@ -53,6 +53,8 @@
 
    void (*transform_immediate)(struct tgsi_transform_context *ctx,
                                struct tgsi_full_immediate *imm);
+   void (*transform_property)(struct tgsi_transform_context *ctx,
+                              struct tgsi_full_property *prop);
 
    /**
     * Called at end of input program to allow caller to append extra
@@ -73,6 +75,8 @@
                             const struct tgsi_full_declaration *decl);
    void (*emit_immediate)(struct tgsi_transform_context *ctx,
                           const struct tgsi_full_immediate *imm);
+   void (*emit_property)(struct tgsi_transform_context *ctx,
+                         const struct tgsi_full_property *prop);
 
    struct tgsi_header *header;
    uint max_tokens_out;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index 4731e3b..e64e2b7 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -37,7 +37,6 @@
 #include "util/u_math.h"
 
 union tgsi_any_token {
-   struct tgsi_version version;
    struct tgsi_header header;
    struct tgsi_processor processor;
    struct tgsi_token token;
@@ -47,14 +46,12 @@
    struct tgsi_immediate imm;
    union  tgsi_immediate_data imm_data;
    struct tgsi_instruction insn;
-   struct tgsi_instruction_ext_label insn_ext_label;
-   struct tgsi_instruction_ext_texture insn_ext_texture;
-   struct tgsi_instruction_ext_predicate insn_ext_predicate;
+   struct tgsi_instruction_predicate insn_predicate;
+   struct tgsi_instruction_label insn_label;
+   struct tgsi_instruction_texture insn_texture;
    struct tgsi_src_register src;
-   struct tgsi_src_register_ext_mod src_ext_mod;
    struct tgsi_dimension dim;
    struct tgsi_dst_register dst;
-   struct tgsi_dst_register_ext_modulate dst_ext_mod;
    unsigned value;
 };
 
@@ -72,6 +69,7 @@
 #define UREG_MAX_IMMEDIATE 32
 #define UREG_MAX_TEMP 256
 #define UREG_MAX_ADDR 2
+#define UREG_MAX_LOOP 1
 #define UREG_MAX_PRED 1
 
 #define DOMAIN_DECL 0
@@ -92,14 +90,24 @@
    unsigned vs_inputs[UREG_MAX_INPUT/32];
 
    struct {
+      unsigned index;
+   } gs_input[UREG_MAX_INPUT];
+   unsigned nr_gs_inputs;
+
+   struct {
       unsigned semantic_name;
       unsigned semantic_index;
    } output[UREG_MAX_OUTPUT];
    unsigned nr_outputs;
 
    struct {
-      float v[4];
+      union {
+         float f[4];
+         unsigned u[4];
+         int i[4];
+      } value;
       unsigned nr;
+      unsigned type;
    } immediate[UREG_MAX_IMMEDIATE];
    unsigned nr_immediates;
 
@@ -117,6 +125,7 @@
 
    unsigned nr_addrs;
    unsigned nr_preds;
+   unsigned nr_loops;
    unsigned nr_instructions;
 
    struct ureg_tokens domain[2];
@@ -140,8 +149,9 @@
 {
    unsigned old_size = tokens->size * sizeof(unsigned);
 
-   if (tokens->tokens == error_tokens)
-      goto fail;
+   if (tokens->tokens == error_tokens) {
+      return;
+   }
 
    while (tokens->count + count > tokens->size) {
       tokens->size = (1 << ++tokens->order);
@@ -150,13 +160,9 @@
    tokens->tokens = REALLOC(tokens->tokens, 
                             old_size,
                             tokens->size * sizeof(unsigned));
-   if (tokens->tokens == NULL) 
-      goto fail;
-
-   return;
-          
-fail:
-   tokens_error(tokens);
+   if (tokens->tokens == NULL) {
+      tokens_error(tokens);
+   }
 }
 
 static void set_bad( struct ureg_program *ureg )
@@ -282,6 +288,22 @@
 }
 
 
+struct ureg_src
+ureg_DECL_gs_input(struct ureg_program *ureg,
+                   unsigned index)
+{
+   if (ureg->nr_gs_inputs < UREG_MAX_INPUT) {
+      ureg->gs_input[ureg->nr_gs_inputs].index = index;
+      ureg->nr_gs_inputs++;
+   } else {
+      set_bad(ureg);
+   }
+
+   /* XXX: Add suport for true 2D input registers. */
+   return ureg_src_register(TGSI_FILE_INPUT, index);
+}
+
+
 struct ureg_dst 
 ureg_DECL_output( struct ureg_program *ureg,
                   unsigned name,
@@ -353,6 +375,7 @@
       i = ureg->nr_constant_ranges++;
       ureg->constant_range[i].first = index;
       ureg->constant_range[i].last = index;
+      goto out;
    }
 
    /* Collapse all ranges down to one:
@@ -420,6 +443,19 @@
    return ureg_dst_register( TGSI_FILE_ADDRESS, 0 );
 }
 
+/* Allocate a new loop register.
+ */
+struct ureg_dst
+ureg_DECL_loop(struct ureg_program *ureg)
+{
+   if (ureg->nr_loops < UREG_MAX_LOOP) {
+      return ureg_dst_register(TGSI_FILE_LOOP, ureg->nr_loops++);
+   }
+
+   assert(0);
+   return ureg_dst_register(TGSI_FILE_LOOP, 0);
+}
+
 /* Allocate a new predicate register.
  */
 struct ureg_dst
@@ -455,22 +491,22 @@
 }
 
 
-
-
-static int match_or_expand_immediate( const float *v,
-                                      unsigned nr,
-                                      float *v2,
-                                      unsigned *nr2,
-                                      unsigned *swizzle )
+static int
+match_or_expand_immediate( const unsigned *v,
+                           unsigned nr,
+                           unsigned *v2,
+                           unsigned *pnr2,
+                           unsigned *swizzle )
 {
+   unsigned nr2 = *pnr2;
    unsigned i, j;
-   
+
    *swizzle = 0;
 
    for (i = 0; i < nr; i++) {
       boolean found = FALSE;
 
-      for (j = 0; j < *nr2 && !found; j++) {
+      for (j = 0; j < nr2 && !found; j++) {
          if (v[i] == v2[j]) {
             *swizzle |= j << (i * 2);
             found = TRUE;
@@ -478,24 +514,28 @@
       }
 
       if (!found) {
-         if (*nr2 >= 4) 
+         if (nr2 >= 4) {
             return FALSE;
+         }
 
-         v2[*nr2] = v[i];
-         *swizzle |= *nr2 << (i * 2);
-         (*nr2)++;
+         v2[nr2] = v[i];
+         *swizzle |= nr2 << (i * 2);
+         nr2++;
       }
    }
 
+   /* Actually expand immediate only when fully succeeded.
+    */
+   *pnr2 = nr2;
    return TRUE;
 }
 
 
-
-
-struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg, 
-                                     const float *v,
-                                     unsigned nr )
+static struct ureg_src
+decl_immediate( struct ureg_program *ureg,
+                const unsigned *v,
+                unsigned nr,
+                unsigned type )
 {
    unsigned i, j;
    unsigned swizzle;
@@ -505,38 +545,82 @@
     */
 
    for (i = 0; i < ureg->nr_immediates; i++) {
-      if (match_or_expand_immediate( v, 
-                                     nr,
-                                     ureg->immediate[i].v,
-                                     &ureg->immediate[i].nr, 
-                                     &swizzle ))
+      if (ureg->immediate[i].type != type) {
+         continue;
+      }
+      if (match_or_expand_immediate(v,
+                                    nr,
+                                    ureg->immediate[i].value.u,
+                                    &ureg->immediate[i].nr,
+                                    &swizzle)) {
          goto out;
+      }
    }
 
    if (ureg->nr_immediates < UREG_MAX_IMMEDIATE) {
       i = ureg->nr_immediates++;
-      if (match_or_expand_immediate( v,
-                                     nr,
-                                     ureg->immediate[i].v,
-                                     &ureg->immediate[i].nr, 
-                                     &swizzle ))
+      ureg->immediate[i].type = type;
+      if (match_or_expand_immediate(v,
+                                    nr,
+                                    ureg->immediate[i].value.u,
+                                    &ureg->immediate[i].nr,
+                                    &swizzle)) {
          goto out;
+      }
    }
 
-   set_bad( ureg );
+   set_bad(ureg);
 
 out:
    /* Make sure that all referenced elements are from this immediate.
     * Has the effect of making size-one immediates into scalars.
     */
-   for (j = nr; j < 4; j++)
+   for (j = nr; j < 4; j++) {
       swizzle |= (swizzle & 0x3) << (j * 2);
+   }
 
-   return ureg_swizzle( ureg_src_register( TGSI_FILE_IMMEDIATE, i ),
-                        (swizzle >> 0) & 0x3,
-                        (swizzle >> 2) & 0x3,
-                        (swizzle >> 4) & 0x3,
-                        (swizzle >> 6) & 0x3);
+   return ureg_swizzle(ureg_src_register(TGSI_FILE_IMMEDIATE, i),
+                       (swizzle >> 0) & 0x3,
+                       (swizzle >> 2) & 0x3,
+                       (swizzle >> 4) & 0x3,
+                       (swizzle >> 6) & 0x3);
+}
+
+
+struct ureg_src
+ureg_DECL_immediate( struct ureg_program *ureg,
+                     const float *v,
+                     unsigned nr )
+{
+   union {
+      float f[4];
+      unsigned u[4];
+   } fu;
+   unsigned int i;
+
+   for (i = 0; i < nr; i++) {
+      fu.f[i] = v[i];
+   }
+
+   return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT32);
+}
+
+
+struct ureg_src
+ureg_DECL_immediate_uint( struct ureg_program *ureg,
+                          const unsigned *v,
+                          unsigned nr )
+{
+   return decl_immediate(ureg, v, nr, TGSI_IMM_UINT32);
+}
+
+
+struct ureg_src
+ureg_DECL_immediate_int( struct ureg_program *ureg,
+                         const int *v,
+                         unsigned nr )
+{
+   return decl_immediate(ureg, (const unsigned *)v, nr, TGSI_IMM_INT32);
 }
 
 
@@ -544,9 +628,7 @@
 ureg_emit_src( struct ureg_program *ureg,
                struct ureg_src src )
 {
-   unsigned size = (1 + 
-                    (src.Absolute ? 1 : 0) +
-                    (src.Indirect ? 1 : 0));
+   unsigned size = 1 + (src.Indirect ? 1 : 0);
 
    union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
    unsigned n = 0;
@@ -563,17 +645,8 @@
    out[n].src.SwizzleW = src.SwizzleW;
    out[n].src.Index = src.Index;
    out[n].src.Negate = src.Negate;
+   out[0].src.Absolute = src.Absolute;
    n++;
-   
-   if (src.Absolute) {
-      out[0].src.Extended = 1;
-      out[0].src.Negate = 0;
-      out[n].value = 0;
-      out[n].src_ext_mod.Type = TGSI_SRC_REGISTER_EXT_TYPE_MOD;
-      out[n].src_ext_mod.Absolute = 1;
-      out[n].src_ext_mod.Negate = src.Negate;
-      n++;
-   }
 
    if (src.Indirect) {
       out[0].src.Indirect = 1;
@@ -664,35 +737,27 @@
    validate( opcode, num_dst, num_src );
    
    out = get_tokens( ureg, DOMAIN_INSN, count );
-   out[0].value = 0;
-   out[0].insn.Type = TGSI_TOKEN_TYPE_INSTRUCTION;
-   out[0].insn.NrTokens = 0;
+   out[0].insn = tgsi_default_instruction();
    out[0].insn.Opcode = opcode;
    out[0].insn.Saturate = saturate;
    out[0].insn.NumDstRegs = num_dst;
    out[0].insn.NumSrcRegs = num_src;
-   out[0].insn.Padding = 0;
 
    result.insn_token = ureg->domain[DOMAIN_INSN].count - count;
+   result.extended_token = result.insn_token;
 
    if (predicate) {
-      out[0].insn.Extended = 1;
-      out[1].insn_ext_predicate = tgsi_default_instruction_ext_predicate();
-      out[1].insn_ext_predicate.Negate = pred_negate;
-      out[1].insn_ext_predicate.SwizzleX = pred_swizzle_x;
-      out[1].insn_ext_predicate.SwizzleY = pred_swizzle_y;
-      out[1].insn_ext_predicate.SwizzleZ = pred_swizzle_z;
-      out[1].insn_ext_predicate.SwizzleW = pred_swizzle_w;
-
-      result.extended_token = result.insn_token + 1;
-   } else {
-      out[0].insn.Extended = 0;
-
-      result.extended_token = result.insn_token;
+      out[0].insn.Predicate = 1;
+      out[1].insn_predicate = tgsi_default_instruction_predicate();
+      out[1].insn_predicate.Negate = pred_negate;
+      out[1].insn_predicate.SwizzleX = pred_swizzle_x;
+      out[1].insn_predicate.SwizzleY = pred_swizzle_y;
+      out[1].insn_predicate.SwizzleZ = pred_swizzle_z;
+      out[1].insn_predicate.SwizzleW = pred_swizzle_w;
    }
 
    ureg->nr_instructions++;
-   
+
    return result;
 }
 
@@ -708,13 +773,11 @@
       return;
 
    out = get_tokens( ureg, DOMAIN_INSN, 1 );
-   insn = retrieve_token( ureg, DOMAIN_INSN, extended_token );
-
-   insn->token.Extended = 1;
-
    out[0].value = 0;
-   out[0].insn_ext_label.Type = TGSI_INSTRUCTION_EXT_TYPE_LABEL;
-   
+
+   insn = retrieve_token( ureg, DOMAIN_INSN, extended_token );
+   insn->insn.Label = 1;
+
    *label_token = ureg->domain[DOMAIN_INSN].count - 1;
 }
 
@@ -737,8 +800,7 @@
 {
    union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, label_token );
 
-   assert(out->insn_ext_label.Type == TGSI_INSTRUCTION_EXT_TYPE_LABEL);
-   out->insn_ext_label.Label = instruction_number;
+   out->insn_label.Label = instruction_number;
 }
 
 
@@ -752,11 +814,10 @@
    out = get_tokens( ureg, DOMAIN_INSN, 1 );
    insn = retrieve_token( ureg, DOMAIN_INSN, extended_token );
 
-   insn->token.Extended = 1;
+   insn->insn.Texture = 1;
 
    out[0].value = 0;
-   out[0].insn_ext_texture.Type = TGSI_INSTRUCTION_EXT_TYPE_TEXTURE;
-   out[0].insn_ext_texture.Texture = target;
+   out[0].insn_texture.Texture = target;
 }
 
 
@@ -783,8 +844,8 @@
    unsigned i;
    boolean saturate;
    boolean predicate;
-   boolean negate;
-   unsigned swizzle[4];
+   boolean negate = FALSE;
+   unsigned swizzle[4] = { 0 };
 
    saturate = nr_dst ? dst[0].Saturate : FALSE;
    predicate = nr_dst ? dst[0].Predicate : FALSE;
@@ -830,8 +891,8 @@
    unsigned i;
    boolean saturate;
    boolean predicate;
-   boolean negate;
-   unsigned swizzle[4];
+   boolean negate = FALSE;
+   unsigned swizzle[4] = { 0 };
 
    saturate = nr_dst ? dst[0].Saturate : FALSE;
    predicate = nr_dst ? dst[0].Predicate : FALSE;
@@ -921,8 +982,8 @@
       out[1].decl_range.Last = index;
 
    out[2].value = 0;
-   out[2].decl_semantic.SemanticName = semantic_name;
-   out[2].decl_semantic.SemanticIndex = semantic_index;
+   out[2].decl_semantic.Name = semantic_name;
+   out[2].decl_semantic.Index = semantic_index;
 
 }
 
@@ -947,22 +1008,23 @@
    out[1].decl_range.Last = first + count - 1;
 }
 
-static void emit_immediate( struct ureg_program *ureg,
-                            const float *v )
+static void
+emit_immediate( struct ureg_program *ureg,
+                const unsigned *v,
+                unsigned type )
 {
    union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 5 );
 
    out[0].value = 0;
    out[0].imm.Type = TGSI_TOKEN_TYPE_IMMEDIATE;
    out[0].imm.NrTokens = 5;
-   out[0].imm.DataType = TGSI_IMM_FLOAT32;
+   out[0].imm.DataType = type;
    out[0].imm.Padding = 0;
-   out[0].imm.Extended = 0;
 
-   out[1].imm_data.Float = v[0];
-   out[2].imm_data.Float = v[1];
-   out[3].imm_data.Float = v[2];
-   out[4].imm_data.Float = v[3];
+   out[1].imm_data.Uint = v[0];
+   out[2].imm_data.Uint = v[1];
+   out[3].imm_data.Uint = v[2];
+   out[4].imm_data.Uint = v[3];
 }
 
 
@@ -978,8 +1040,7 @@
             emit_decl_range( ureg, TGSI_FILE_INPUT, i, 1 );
          }
       }
-   }
-   else {
+   } else if (ureg->processor == TGSI_PROCESSOR_FRAGMENT) {
       for (i = 0; i < ureg->nr_fs_inputs; i++) {
          emit_decl( ureg, 
                     TGSI_FILE_INPUT, 
@@ -988,6 +1049,13 @@
                     ureg->fs_input[i].semantic_index,
                     ureg->fs_input[i].interp );
       }
+   } else {
+      for (i = 0; i < ureg->nr_gs_inputs; i++) {
+         emit_decl_range(ureg, 
+                         TGSI_FILE_INPUT, 
+                         ureg->gs_input[i].index,
+                         1);
+      }
    }
 
    for (i = 0; i < ureg->nr_outputs; i++) {
@@ -1026,6 +1094,13 @@
                        0, ureg->nr_addrs );
    }
 
+   if (ureg->nr_loops) {
+      emit_decl_range(ureg,
+                      TGSI_FILE_LOOP,
+                      0,
+                      ureg->nr_loops);
+   }
+
    if (ureg->nr_preds) {
       emit_decl_range(ureg,
                       TGSI_FILE_PREDICATE,
@@ -1035,7 +1110,8 @@
 
    for (i = 0; i < ureg->nr_immediates; i++) {
       emit_immediate( ureg,
-                      ureg->immediate[i].v );
+                      ureg->immediate[i].value.u,
+                      ureg->immediate[i].type );
    }
 }
 
@@ -1058,26 +1134,22 @@
 static void
 fixup_header_size(struct ureg_program *ureg)
 {
-   union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 1 );
+   union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 0 );
 
-   out->header.BodySize = ureg->domain[DOMAIN_DECL].count - 3;
+   out->header.BodySize = ureg->domain[DOMAIN_DECL].count - 2;
 }
 
 
 static void
 emit_header( struct ureg_program *ureg )
 {
-   union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 3 );
+   union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 );
 
-   out[0].version.MajorVersion = 1;
-   out[0].version.MinorVersion = 1;
-   out[0].version.Padding = 0;
+   out[0].header.HeaderSize = 2;
+   out[0].header.BodySize = 0;
 
-   out[1].header.HeaderSize = 2;
-   out[1].header.BodySize = 0;
-
-   out[2].processor.Processor = ureg->processor;
-   out[2].processor.Padding = 0;
+   out[1].processor.Processor = ureg->processor;
+   out[1].processor.Padding = 0;
 }
 
 
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
index dae4291..6f11273 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
@@ -133,6 +133,10 @@
 ureg_DECL_vs_input( struct ureg_program *,
                     unsigned index );
 
+struct ureg_src
+ureg_DECL_gs_input(struct ureg_program *,
+                   unsigned index);
+
 struct ureg_dst
 ureg_DECL_output( struct ureg_program *,
                   unsigned semantic_name,
@@ -144,6 +148,16 @@
                      unsigned nr );
 
 struct ureg_src
+ureg_DECL_immediate_uint( struct ureg_program *,
+                          const unsigned *v,
+                          unsigned nr );
+
+struct ureg_src
+ureg_DECL_immediate_int( struct ureg_program *,
+                         const int *v,
+                         unsigned nr );
+
+struct ureg_src
 ureg_DECL_constant( struct ureg_program *,
                     unsigned index );
 
@@ -158,6 +172,9 @@
 ureg_DECL_address( struct ureg_program * );
 
 struct ureg_dst
+ureg_DECL_loop( struct ureg_program * );
+
+struct ureg_dst
 ureg_DECL_predicate(struct ureg_program *);
 
 /* Supply an index to the sampler declaration as this is the hook to
@@ -214,6 +231,90 @@
    return ureg_DECL_immediate( ureg, v, 1 );
 }
 
+static INLINE struct ureg_src
+ureg_imm4u( struct ureg_program *ureg,
+            unsigned a, unsigned b,
+            unsigned c, unsigned d)
+{
+   unsigned v[4];
+   v[0] = a;
+   v[1] = b;
+   v[2] = c;
+   v[3] = d;
+   return ureg_DECL_immediate_uint( ureg, v, 4 );
+}
+
+static INLINE struct ureg_src
+ureg_imm3u( struct ureg_program *ureg,
+            unsigned a, unsigned b,
+            unsigned c)
+{
+   unsigned v[3];
+   v[0] = a;
+   v[1] = b;
+   v[2] = c;
+   return ureg_DECL_immediate_uint( ureg, v, 3 );
+}
+
+static INLINE struct ureg_src
+ureg_imm2u( struct ureg_program *ureg,
+            unsigned a, unsigned b)
+{
+   unsigned v[2];
+   v[0] = a;
+   v[1] = b;
+   return ureg_DECL_immediate_uint( ureg, v, 2 );
+}
+
+static INLINE struct ureg_src
+ureg_imm1u( struct ureg_program *ureg,
+            unsigned a)
+{
+   return ureg_DECL_immediate_uint( ureg, &a, 1 );
+}
+
+static INLINE struct ureg_src
+ureg_imm4i( struct ureg_program *ureg,
+            int a, int b,
+            int c, int d)
+{
+   int v[4];
+   v[0] = a;
+   v[1] = b;
+   v[2] = c;
+   v[3] = d;
+   return ureg_DECL_immediate_int( ureg, v, 4 );
+}
+
+static INLINE struct ureg_src
+ureg_imm3i( struct ureg_program *ureg,
+            int a, int b,
+            int c)
+{
+   int v[3];
+   v[0] = a;
+   v[1] = b;
+   v[2] = c;
+   return ureg_DECL_immediate_int( ureg, v, 3 );
+}
+
+static INLINE struct ureg_src
+ureg_imm2i( struct ureg_program *ureg,
+            int a, int b)
+{
+   int v[2];
+   v[0] = a;
+   v[1] = b;
+   return ureg_DECL_immediate_int( ureg, v, 2 );
+}
+
+static INLINE struct ureg_src
+ureg_imm1i( struct ureg_program *ureg,
+            int a)
+{
+   return ureg_DECL_immediate_int( ureg, &a, 1 );
+}
+
 /***********************************************************************
  * Functions for patching up labels
  */
diff --git a/src/gallium/auxiliary/tgsi/tgsi_util.c b/src/gallium/auxiliary/tgsi/tgsi_util.c
index 4dee1be..f4ca9e2 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_util.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_util.c
@@ -76,7 +76,7 @@
    unsigned component )
 {
    return tgsi_util_get_src_register_swizzle(
-      &reg->SrcRegister,
+      &reg->Register,
       component );
 }
 
@@ -111,10 +111,10 @@
 {
    unsigned sign_mode;
 
-   if( reg->SrcRegisterExtMod.Absolute ) {
+   if( reg->Register.Absolute ) {
       /* Consider only the post-abs negation. */
 
-      if( reg->SrcRegisterExtMod.Negate ) {
+      if( reg->Register.Negate ) {
          sign_mode = TGSI_UTIL_SIGN_SET;
       }
       else {
@@ -122,17 +122,7 @@
       }
    }
    else {
-      /* Accumulate the three negations. */
-
-      unsigned negate;
-
-      negate = reg->SrcRegister.Negate;
-
-      if( reg->SrcRegisterExtMod.Negate ) {
-         negate = !negate;
-      }
-
-      if( negate ) {
+      if( reg->Register.Negate ) {
          sign_mode = TGSI_UTIL_SIGN_TOGGLE;
       }
       else {
@@ -151,27 +141,23 @@
    switch (sign_mode)
    {
    case TGSI_UTIL_SIGN_CLEAR:
-      reg->SrcRegister.Negate = 0;
-      reg->SrcRegisterExtMod.Absolute = 1;
-      reg->SrcRegisterExtMod.Negate = 0;
+      reg->Register.Negate = 0;
+      reg->Register.Absolute = 1;
       break;
 
    case TGSI_UTIL_SIGN_SET:
-      reg->SrcRegister.Negate = 0;
-      reg->SrcRegisterExtMod.Absolute = 1;
-      reg->SrcRegisterExtMod.Negate = 1;
+      reg->Register.Absolute = 1;
+      reg->Register.Negate = 1;
       break;
 
    case TGSI_UTIL_SIGN_TOGGLE:
-      reg->SrcRegister.Negate = 1;
-      reg->SrcRegisterExtMod.Absolute = 0;
-      reg->SrcRegisterExtMod.Negate = 0;
+      reg->Register.Negate = 1;
+      reg->Register.Absolute = 0;
       break;
 
    case TGSI_UTIL_SIGN_KEEP:
-      reg->SrcRegister.Negate = 0;
-      reg->SrcRegisterExtMod.Absolute = 0;
-      reg->SrcRegisterExtMod.Negate = 0;
+      reg->Register.Negate = 0;
+      reg->Register.Absolute = 0;
       break;
 
    default:
diff --git a/src/gallium/auxiliary/translate/Makefile b/src/gallium/auxiliary/translate/Makefile
deleted file mode 100644
index 3c82f8a..0000000
--- a/src/gallium/auxiliary/translate/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = translate
-
-C_SOURCES = \
-	translate_generic.c \
-	translate_sse.c \
-	translate.c \
-        translate_cache.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/translate/SConscript b/src/gallium/auxiliary/translate/SConscript
deleted file mode 100644
index 9553a67..0000000
--- a/src/gallium/auxiliary/translate/SConscript
+++ /dev/null
@@ -1,12 +0,0 @@
-Import('*')
-
-translate = env.ConvenienceLibrary(
-	target = 'translate',
-	source = [
-		'translate_generic.c',
-		'translate_sse.c',
-		'translate.c',
-		'translate_cache.c',
-	])
-
-auxiliaries.insert(0, translate)
diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile
deleted file mode 100644
index 1d8bb55..0000000
--- a/src/gallium/auxiliary/util/Makefile
+++ /dev/null
@@ -1,45 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = util
-
-C_SOURCES = \
-	u_debug.c \
-	u_debug_dump.c \
-	u_debug_symbol.c \
-	u_debug_stack.c \
-	u_blit.c \
-	u_cache.c \
-	u_cpu_detect.c \
-	u_draw_quad.c \
-	u_format.c \
-	u_format_access.c \
-	u_format_table.c \
-	u_gen_mipmap.c \
-	u_handle_table.c \
-	u_hash_table.c \
-	u_hash.c \
-	u_keymap.c \
-	u_linear.c \
-	u_network.c \
-	u_math.c \
-	u_mm.c \
-	u_rect.c \
-	u_simple_shaders.c \
-	u_snprintf.c \
-	u_stream_stdc.c \
-	u_stream_wd.c \
-	u_surface.c \
-	u_tile.c \
-	u_time.c \
-	u_timed_winsys.c \
-	u_upload_mgr.c \
-	u_simple_screen.c
-
-include ../../Makefile.template
-
-u_format_table.c: u_format_table.py u_format_parse.py u_format.csv
-	python u_format_table.py u_format.csv > $@
-
-u_format_access.c: u_format_access.py u_format_parse.py u_format.csv
-	python u_format_access.py u_format.csv > $@
diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript
deleted file mode 100644
index 8d99106..0000000
--- a/src/gallium/auxiliary/util/SConscript
+++ /dev/null
@@ -1,58 +0,0 @@
-Import('*')
-
-env.Clone()
-
-env.Append(CPPPATH = ['.'])
-
-env.CodeGenerate(
-	target = 'u_format_table.c',
-	script = 'u_format_table.py',
-	source = ['u_format.csv'],
-	command = 'python $SCRIPT $SOURCE > $TARGET'
-)
-
-env.CodeGenerate(
-	target = 'u_format_access.c',
-	script = 'u_format_access.py',
-	source = ['u_format.csv'],
-	command = 'python $SCRIPT $SOURCE > $TARGET'
-)
-
-util = env.ConvenienceLibrary(
-	target = 'util',
-	source = [
-		'u_bitmask.c',
-		'u_blit.c',
-		'u_cache.c',
-		'u_cpu_detect.c',
-		'u_debug.c',
-		'u_debug_dump.c',
-		'u_debug_memory.c',
-		'u_debug_stack.c',
-		'u_debug_symbol.c',
-		'u_draw_quad.c',
-		'u_format.c',
-		'u_format_access.c',
-		'u_format_table.c',
-		'u_gen_mipmap.c',
-		'u_handle_table.c',
-		'u_hash.c',
-		'u_hash_table.c',
-		'u_keymap.c',
-		'u_network.c',
-		'u_math.c',
-		'u_mm.c',
-		'u_rect.c',
-		'u_simple_shaders.c',
-		'u_snprintf.c',
-		'u_stream_stdc.c',
-		'u_stream_wd.c',
-		'u_surface.c',
-		'u_tile.c',
-		'u_time.c',
-		'u_timed_winsys.c',
-		'u_upload_mgr.c',
-		'u_simple_screen.c',
-	])
-
-auxiliaries.insert(0, util)
diff --git a/src/gallium/auxiliary/util/u_bitmask.c b/src/gallium/auxiliary/util/u_bitmask.c
index 77587c0..23c93a3 100644
--- a/src/gallium/auxiliary/util/u_bitmask.c
+++ b/src/gallium/auxiliary/util/u_bitmask.c
@@ -97,12 +97,12 @@
    if(!minimum_size)
       return FALSE;
       
-   if(bm->size > minimum_size)
+   if(bm->size >= minimum_size)
       return TRUE;
 
    assert(bm->size % UTIL_BITMASK_BITS_PER_WORD == 0);
    new_size = bm->size;
-   while(!(new_size > minimum_size)) {
+   while(new_size < minimum_size) {
       new_size *= 2;
       /* Check integer overflow */
       if(new_size < bm->size)
@@ -136,7 +136,7 @@
                         unsigned index)
 {
    assert(bm->filled <= bm->size);
-   assert(index <= bm->size);
+   assert(index < bm->size);
    
    if(index == bm->filled) {
       ++bm->filled;
@@ -149,7 +149,7 @@
                           unsigned index)
 {
    assert(bm->filled <= bm->size);
-   assert(index <= bm->size);
+   assert(index < bm->size);
    
    if(index < bm->filled)
       bm->filled = index;
@@ -182,7 +182,7 @@
       mask = 1;
    }
 found:
-   
+
    /* grow the bitmask if necessary */
    if(!util_bitmask_resize(bm, bm->filled))
       return UTIL_BITMASK_INVALID_INDEX;
@@ -198,9 +198,9 @@
 util_bitmask_set(struct util_bitmask *bm, 
                  unsigned index)
 {
-   unsigned word = index / UTIL_BITMASK_BITS_PER_WORD;
-   unsigned bit  = index % UTIL_BITMASK_BITS_PER_WORD;
-   util_bitmask_word mask = 1 << bit;
+   unsigned word;
+   unsigned bit;
+   util_bitmask_word mask;
    
    assert(bm);
    
@@ -208,6 +208,10 @@
    if(!util_bitmask_resize(bm, index))
       return UTIL_BITMASK_INVALID_INDEX;
 
+   word = index / UTIL_BITMASK_BITS_PER_WORD;
+   bit  = index % UTIL_BITMASK_BITS_PER_WORD;
+   mask = 1 << bit;
+
    bm->words[word] |= mask;
 
    util_bitmask_filled_set(bm, index);
@@ -220,15 +224,19 @@
 util_bitmask_clear(struct util_bitmask *bm, 
                    unsigned index)
 {
-   unsigned word = index / UTIL_BITMASK_BITS_PER_WORD;
-   unsigned bit  = index % UTIL_BITMASK_BITS_PER_WORD;
-   util_bitmask_word mask = 1 << bit;
+   unsigned word;
+   unsigned bit;
+   util_bitmask_word mask;
    
    assert(bm);
    
    if(index >= bm->size)
       return;
 
+   word = index / UTIL_BITMASK_BITS_PER_WORD;
+   bit  = index % UTIL_BITMASK_BITS_PER_WORD;
+   mask = 1 << bit;
+
    bm->words[word] &= ~mask;
    
    util_bitmask_filled_unset(bm, index);
@@ -250,7 +258,7 @@
       return TRUE;
    }
 
-   if(index > bm->size)
+   if(index >= bm->size)
       return FALSE;
 
    if(bm->words[word] & mask) {
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 5038642..3f74e2a 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -42,6 +42,7 @@
 
 #include "util/u_blit.h"
 #include "util/u_draw_quad.h"
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "util/u_simple_shaders.h"
@@ -126,7 +127,8 @@
    }
 
    /* fragment shader */
-   ctx->fs[TGSI_WRITEMASK_XYZW] = util_make_fragment_tex_shader(pipe);
+   ctx->fs[TGSI_WRITEMASK_XYZW] =
+      util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D);
    ctx->vbuf = NULL;
 
    /* init vertex data that doesn't change */
@@ -354,10 +356,9 @@
       texTemp.target = PIPE_TEXTURE_2D;
       texTemp.format = src->format;
       texTemp.last_level = 0;
-      texTemp.width[0] = srcW;
-      texTemp.height[0] = srcH;
-      texTemp.depth[0] = 1;
-      pf_get_block(src->format, &texTemp.block);
+      texTemp.width0 = srcW;
+      texTemp.height0 = srcH;
+      texTemp.depth0 = 1;
 
       tex = screen->texture_create(screen, &texTemp);
       if (!tex)
@@ -389,10 +390,10 @@
    }
    else {
       pipe_texture_reference(&tex, src->texture);
-      s0 = srcX0 / (float)tex->width[0];
-      s1 = srcX1 / (float)tex->width[0];
-      t0 = srcY0 / (float)tex->height[0];
-      t1 = srcY1 / (float)tex->height[0];
+      s0 = srcX0 / (float)tex->width0;
+      s1 = srcX1 / (float)tex->width0;
+      t0 = srcY0 / (float)tex->height0;
+      t1 = srcY1 / (float)tex->height0;
    }
 
 
@@ -421,7 +422,9 @@
    cso_set_sampler_textures(ctx->cso, 1, &tex);
 
    if (ctx->fs[writemask] == NULL)
-      ctx->fs[writemask] = util_make_fragment_tex_shader_writemask(pipe, writemask);
+      ctx->fs[writemask] =
+         util_make_fragment_tex_shader_writemask(pipe, TGSI_TEXTURE_2D,
+                                                 writemask);
 
    /* shaders */
    cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]);
@@ -518,13 +521,13 @@
    assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
           filter == PIPE_TEX_MIPFILTER_LINEAR);
 
-   assert(tex->width[0] != 0);
-   assert(tex->height[0] != 0);
+   assert(tex->width0 != 0);
+   assert(tex->height0 != 0);
 
-   s0 = srcX0 / (float)tex->width[0];
-   s1 = srcX1 / (float)tex->width[0];
-   t0 = srcY0 / (float)tex->height[0];
-   t1 = srcY1 / (float)tex->height[0];
+   s0 = srcX0 / (float)tex->width0;
+   s1 = srcX1 / (float)tex->width0;
+   t0 = srcY0 / (float)tex->height0;
+   t1 = srcY1 / (float)tex->height0;
 
    assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format,
                                                  PIPE_TEXTURE_2D,
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
new file mode 100644
index 0000000..46b4706
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -0,0 +1,813 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Blitter utility to facilitate acceleration of the clear, surface_copy,
+ * and surface_fill functions.
+ *
+ * @author Marek Olšák
+ */
+
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_inlines.h"
+#include "pipe/p_shader_tokens.h"
+#include "pipe/p_state.h"
+
+#include "util/u_format.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "util/u_blitter.h"
+#include "util/u_draw_quad.h"
+#include "util/u_pack_color.h"
+#include "util/u_rect.h"
+#include "util/u_simple_shaders.h"
+#include "util/u_texture.h"
+
+#define INVALID_PTR ((void*)~0)
+
+struct blitter_context_priv
+{
+   struct blitter_context blitter;
+
+   struct pipe_context *pipe; /**< pipe context */
+   struct pipe_buffer *vbuf;  /**< quad */
+
+   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.*/
+
+   /* Fragment shaders. */
+   /* FS which outputs a color to multiple color buffers. */
+   void *fs_col[PIPE_MAX_COLOR_BUFS];
+
+   /* FS which outputs a color from a texture,
+      where the index is PIPE_TEXTURE_* to be sampled. */
+   void *fs_texfetch_col[PIPE_MAX_TEXTURE_TYPES];
+
+   /* FS which outputs a depth from a texture,
+      where the index is PIPE_TEXTURE_* to be sampled. */
+   void *fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES];
+
+   /* Blend state. */
+   void *blend_write_color;   /**< blend state with writemask of RGBA */
+   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_keep_stencil;
+   void *dsa_keep_depth_stencil;
+
+   /* Sampler state for clamping to a miplevel. */
+   void *sampler_state[PIPE_MAX_TEXTURE_LEVELS];
+
+   /* Rasterizer state. */
+   void *rs_state;
+};
+
+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_sampler_state *sampler_state;
+   unsigned i;
+
+   ctx = CALLOC_STRUCT(blitter_context_priv);
+   if (!ctx)
+      return NULL;
+
+   ctx->pipe = pipe;
+
+   /* init state objects for them to be considered invalid */
+   ctx->blitter.saved_blend_state = INVALID_PTR;
+   ctx->blitter.saved_dsa_state = INVALID_PTR;
+   ctx->blitter.saved_rs_state = INVALID_PTR;
+   ctx->blitter.saved_fs = INVALID_PTR;
+   ctx->blitter.saved_vs = INVALID_PTR;
+   ctx->blitter.saved_fb_state.nr_cbufs = ~0;
+   ctx->blitter.saved_num_textures = ~0;
+   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.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);
+
+   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);
+
+   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;
+   /* The DSA state objects which write depth and stencil are created
+    * on-demand. */
+
+   /* sampler state */
+   sampler_state = &ctx->template_sampler_state;
+   sampler_state->wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+   sampler_state->wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+   sampler_state->wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+   /* The sampler state objects which sample from a specified mipmap level
+    * are created on-demand. */
+
+   /* rasterizer state */
+   memset(&rs_state, 0, sizeof(rs_state));
+   rs_state.front_winding = PIPE_WINDING_CW;
+   rs_state.cull_mode = PIPE_WINDING_NONE;
+   rs_state.bypass_vs_clip_and_viewport = 1;
+   rs_state.gl_rasterization_rules = 1;
+   rs_state.flatshade = 1;
+   ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
+
+   /* fragment shaders are created on-demand */
+
+   /* vertex shaders */
+   {
+      const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+                                      TGSI_SEMANTIC_COLOR };
+      const uint semantic_indices[] = { 0, 0 };
+      ctx->vs_col =
+         util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
+                                             semantic_indices);
+   }
+   {
+      const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+                                      TGSI_SEMANTIC_GENERIC };
+      const uint semantic_indices[] = { 0, 0 };
+      ctx->vs_tex =
+         util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
+                                             semantic_indices);
+   }
+
+   /* set invariant vertex coordinates */
+   for (i = 0; i < 4; i++)
+      ctx->vertices[i][0][3] = 1; /*v.w*/
+
+   /* create the vertex buffer */
+   ctx->vbuf = pipe_buffer_create(ctx->pipe->screen,
+                                  32,
+                                  PIPE_BUFFER_USAGE_VERTEX,
+                                  sizeof(ctx->vertices));
+
+   return &ctx->blitter;
+}
+
+void util_blitter_destroy(struct blitter_context *blitter)
+{
+   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+   struct pipe_context *pipe = ctx->pipe;
+   int i;
+
+   pipe->delete_blend_state(pipe, ctx->blend_write_color);
+   pipe->delete_blend_state(pipe, ctx->blend_keep_color);
+   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_rasterizer_state(pipe, ctx->rs_state);
+   pipe->delete_vs_state(pipe, ctx->vs_col);
+   pipe->delete_vs_state(pipe, ctx->vs_tex);
+
+   for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
+      if (ctx->fs_texfetch_col[i])
+         pipe->delete_fs_state(pipe, ctx->fs_texfetch_col[i]);
+      if (ctx->fs_texfetch_depth[i])
+         pipe->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]);
+   }
+
+   for (i = 0; i < PIPE_MAX_COLOR_BUFS && ctx->fs_col[i]; i++)
+      if (ctx->fs_col[i])
+         pipe->delete_fs_state(pipe, ctx->fs_col[i]);
+
+   for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
+      if (ctx->sampler_state[i])
+         pipe->delete_sampler_state(pipe, ctx->sampler_state[i]);
+
+   pipe_buffer_reference(&ctx->vbuf, NULL);
+   FREE(ctx);
+}
+
+static void blitter_check_saved_CSOs(struct blitter_context_priv *ctx)
+{
+   /* make sure these CSOs have been saved */
+   assert(ctx->blitter.saved_blend_state != INVALID_PTR &&
+          ctx->blitter.saved_dsa_state != INVALID_PTR &&
+          ctx->blitter.saved_rs_state != INVALID_PTR &&
+          ctx->blitter.saved_fs != INVALID_PTR &&
+          ctx->blitter.saved_vs != INVALID_PTR);
+}
+
+static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
+{
+   struct pipe_context *pipe = ctx->pipe;
+
+   /* restore the state objects which are always required to be saved */
+   pipe->bind_blend_state(pipe, ctx->blitter.saved_blend_state);
+   pipe->bind_depth_stencil_alpha_state(pipe, ctx->blitter.saved_dsa_state);
+   pipe->bind_rasterizer_state(pipe, ctx->blitter.saved_rs_state);
+   pipe->bind_fs_state(pipe, ctx->blitter.saved_fs);
+   pipe->bind_vs_state(pipe, ctx->blitter.saved_vs);
+
+   ctx->blitter.saved_blend_state = INVALID_PTR;
+   ctx->blitter.saved_dsa_state = INVALID_PTR;
+   ctx->blitter.saved_rs_state = INVALID_PTR;
+   ctx->blitter.saved_fs = INVALID_PTR;
+   ctx->blitter.saved_vs = INVALID_PTR;
+
+   /* restore the state objects which are required to be saved before copy/fill
+    */
+   if (ctx->blitter.saved_fb_state.nr_cbufs != ~0) {
+      pipe->set_framebuffer_state(pipe, &ctx->blitter.saved_fb_state);
+      ctx->blitter.saved_fb_state.nr_cbufs = ~0;
+   }
+
+   if (ctx->blitter.saved_num_sampler_states != ~0) {
+      pipe->bind_fragment_sampler_states(pipe,
+                                         ctx->blitter.saved_num_sampler_states,
+                                         ctx->blitter.saved_sampler_states);
+      ctx->blitter.saved_num_sampler_states = ~0;
+   }
+
+   if (ctx->blitter.saved_num_textures != ~0) {
+      pipe->set_fragment_sampler_textures(pipe,
+                                          ctx->blitter.saved_num_textures,
+                                          ctx->blitter.saved_textures);
+      ctx->blitter.saved_num_textures = ~0;
+   }
+}
+
+static void blitter_set_rectangle(struct blitter_context_priv *ctx,
+                                  unsigned x1, unsigned y1,
+                                  unsigned x2, unsigned y2,
+                                  float depth)
+{
+   int i;
+
+   /* set vertex positions */
+   ctx->vertices[0][0][0] = x1; /*v0.x*/
+   ctx->vertices[0][0][1] = y1; /*v0.y*/
+
+   ctx->vertices[1][0][0] = x2; /*v1.x*/
+   ctx->vertices[1][0][1] = y1; /*v1.y*/
+
+   ctx->vertices[2][0][0] = x2; /*v2.x*/
+   ctx->vertices[2][0][1] = y2; /*v2.y*/
+
+   ctx->vertices[3][0][0] = x1; /*v3.x*/
+   ctx->vertices[3][0][1] = y2; /*v3.y*/
+
+   for (i = 0; i < 4; i++)
+      ctx->vertices[i][0][2] = depth; /*z*/
+}
+
+static void blitter_set_clear_color(struct blitter_context_priv *ctx,
+                                    const float *rgba)
+{
+   int i;
+
+   for (i = 0; i < 4; i++) {
+      ctx->vertices[i][1][0] = rgba[0];
+      ctx->vertices[i][1][1] = rgba[1];
+      ctx->vertices[i][1][2] = rgba[2];
+      ctx->vertices[i][1][3] = rgba[3];
+   }
+}
+
+static void blitter_set_texcoords_2d(struct blitter_context_priv *ctx,
+                                     struct pipe_surface *surf,
+                                     unsigned x1, unsigned y1,
+                                     unsigned x2, unsigned y2)
+{
+   int i;
+   float s1 = x1 / (float)surf->width;
+   float t1 = y1 / (float)surf->height;
+   float s2 = x2 / (float)surf->width;
+   float t2 = y2 / (float)surf->height;
+
+   ctx->vertices[0][1][0] = s1; /*t0.s*/
+   ctx->vertices[0][1][1] = t1; /*t0.t*/
+
+   ctx->vertices[1][1][0] = s2; /*t1.s*/
+   ctx->vertices[1][1][1] = t1; /*t1.t*/
+
+   ctx->vertices[2][1][0] = s2; /*t2.s*/
+   ctx->vertices[2][1][1] = t2; /*t2.t*/
+
+   ctx->vertices[3][1][0] = s1; /*t3.s*/
+   ctx->vertices[3][1][1] = t2; /*t3.t*/
+
+   for (i = 0; i < 4; i++) {
+      ctx->vertices[i][1][2] = 0; /*r*/
+      ctx->vertices[i][1][3] = 1; /*q*/
+   }
+}
+
+static void blitter_set_texcoords_3d(struct blitter_context_priv *ctx,
+                                     struct pipe_surface *surf,
+                                     unsigned x1, unsigned y1,
+                                     unsigned x2, unsigned y2)
+{
+   int i;
+   float depth = u_minify(surf->texture->depth0, surf->level);
+   float r = surf->zslice / depth;
+
+   blitter_set_texcoords_2d(ctx, surf, x1, y1, x2, y2);
+
+   for (i = 0; i < 4; i++)
+      ctx->vertices[i][1][2] = r; /*r*/
+}
+
+static void blitter_set_texcoords_cube(struct blitter_context_priv *ctx,
+                                       struct pipe_surface *surf,
+                                       unsigned x1, unsigned y1,
+                                       unsigned x2, unsigned y2)
+{
+   int i;
+   float s1 = x1 / (float)surf->width;
+   float t1 = y1 / (float)surf->height;
+   float s2 = x2 / (float)surf->width;
+   float t2 = y2 / (float)surf->height;
+   const float st[4][2] = {
+      {s1, t1}, {s2, t1}, {s2, t2}, {s1, t2}
+   };
+
+   util_map_texcoords2d_onto_cubemap(surf->face,
+                                     /* pointer, stride in floats */
+                                     &st[0][0], 2,
+                                     &ctx->vertices[0][1][0], 8);
+
+   for (i = 0; i < 4; i++)
+      ctx->vertices[i][1][3] = 1; /*q*/
+}
+
+static void blitter_draw_quad(struct blitter_context_priv *ctx)
+{
+   struct pipe_context *pipe = ctx->pipe;
+
+   /* write vertices and draw them */
+   pipe_buffer_write(pipe->screen, ctx->vbuf,
+                     0, sizeof(ctx->vertices), ctx->vertices);
+
+   util_draw_vertex_buffer(pipe, ctx->vbuf, 0, PIPE_PRIM_TRIANGLE_FAN,
+                           4,  /* verts */
+                           2); /* attribs/vert */
+}
+
+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)
+{
+   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_sampler_state *sampler_state = &ctx->template_sampler_state;
+
+   assert(miplevel < PIPE_MAX_TEXTURE_LEVELS);
+
+   /* Create the sampler state on-demand. */
+   if (!ctx->sampler_state[miplevel]) {
+      sampler_state->lod_bias = miplevel;
+      sampler_state->min_lod = miplevel;
+      sampler_state->max_lod = miplevel;
+
+      ctx->sampler_state[miplevel] = pipe->create_sampler_state(pipe,
+                                                                sampler_state);
+   }
+
+   /* Return void** so that it can be passed to bind_fragment_sampler_states
+    * directly. */
+   return &ctx->sampler_state[miplevel];
+}
+
+static INLINE
+void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs)
+{
+   struct pipe_context *pipe = ctx->pipe;
+   unsigned index = num_cbufs ? num_cbufs - 1 : 0;
+
+   assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
+
+   if (!ctx->fs_col[index])
+      ctx->fs_col[index] =
+         util_make_fragment_clonecolor_shader(pipe, num_cbufs);
+
+   return ctx->fs_col[index];
+}
+
+static INLINE
+void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
+                                  unsigned tex_target)
+{
+   struct pipe_context *pipe = ctx->pipe;
+
+   assert(tex_target < PIPE_MAX_TEXTURE_TYPES);
+
+   /* Create the fragment shader on-demand. */
+   if (!ctx->fs_texfetch_col[tex_target]) {
+      switch (tex_target) {
+         case PIPE_TEXTURE_1D:
+            ctx->fs_texfetch_col[PIPE_TEXTURE_1D] =
+               util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D);
+            break;
+         case PIPE_TEXTURE_2D:
+            ctx->fs_texfetch_col[PIPE_TEXTURE_2D] =
+               util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D);
+            break;
+         case PIPE_TEXTURE_3D:
+            ctx->fs_texfetch_col[PIPE_TEXTURE_3D] =
+               util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_3D);
+            break;
+         case PIPE_TEXTURE_CUBE:
+            ctx->fs_texfetch_col[PIPE_TEXTURE_CUBE] =
+               util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE);
+            break;
+         default:;
+      }
+   }
+
+   return ctx->fs_texfetch_col[tex_target];
+}
+
+static INLINE
+void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
+                                    unsigned tex_target)
+{
+   struct pipe_context *pipe = ctx->pipe;
+
+   assert(tex_target < PIPE_MAX_TEXTURE_TYPES);
+
+   /* Create the fragment shader on-demand. */
+   if (!ctx->fs_texfetch_depth[tex_target]) {
+      switch (tex_target) {
+         case PIPE_TEXTURE_1D:
+            ctx->fs_texfetch_depth[PIPE_TEXTURE_1D] =
+               util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_1D);
+            break;
+         case PIPE_TEXTURE_2D:
+            ctx->fs_texfetch_depth[PIPE_TEXTURE_2D] =
+               util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_2D);
+            break;
+         case PIPE_TEXTURE_3D:
+            ctx->fs_texfetch_depth[PIPE_TEXTURE_3D] =
+               util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_3D);
+            break;
+         case PIPE_TEXTURE_CUBE:
+            ctx->fs_texfetch_depth[PIPE_TEXTURE_CUBE] =
+               util_make_fragment_tex_shader_writedepth(pipe,TGSI_TEXTURE_CUBE);
+            break;
+         default:;
+      }
+   }
+
+   return ctx->fs_texfetch_depth[tex_target];
+}
+
+void util_blitter_clear(struct blitter_context *blitter,
+                        unsigned width, unsigned height,
+                        unsigned num_cbufs,
+                        unsigned clear_buffers,
+                        const float *rgba,
+                        double depth, unsigned stencil)
+{
+   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+   struct pipe_context *pipe = ctx->pipe;
+
+   assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
+
+   blitter_check_saved_CSOs(ctx);
+
+   /* bind CSOs */
+   if (clear_buffers & PIPE_CLEAR_COLOR)
+      pipe->bind_blend_state(pipe, ctx->blend_write_color);
+   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));
+   else
+      pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
+
+   pipe->bind_rasterizer_state(pipe, ctx->rs_state);
+   pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs));
+   pipe->bind_vs_state(pipe, ctx->vs_col);
+
+   blitter_set_clear_color(ctx, rgba);
+   blitter_set_rectangle(ctx, 0, 0, width, height, depth);
+   blitter_draw_quad(ctx);
+   blitter_restore_CSOs(ctx);
+}
+
+static boolean
+is_overlap(unsigned sx1, unsigned sx2, unsigned sy1, unsigned sy2,
+           unsigned dx1, unsigned dx2, unsigned dy1, unsigned dy2)
+{
+    if (sx1 >= dx2 || sx2 <= dx1 || sy1 >= dy2 || sy2 <= dy1) {
+        return FALSE;
+    } else {
+        return TRUE;
+    }
+}
+
+static void util_blitter_do_copy(struct blitter_context *blitter,
+				 struct pipe_surface *dst,
+				 unsigned dstx, unsigned dsty,
+				 struct pipe_surface *src,
+				 unsigned srcx, unsigned srcy,
+				 unsigned width, unsigned height,
+				 boolean is_depth)
+{
+   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_framebuffer_state fb_state;
+
+   assert(blitter->saved_fb_state.nr_cbufs != ~0);
+   assert(blitter->saved_num_textures != ~0);
+   assert(blitter->saved_num_sampler_states != ~0);
+   assert(src->texture->target < PIPE_MAX_TEXTURE_TYPES);
+
+   /* bind CSOs */
+   fb_state.width = dst->width;
+   fb_state.height = dst->height;
+
+   if (is_depth) {
+      pipe->bind_blend_state(pipe, ctx->blend_keep_color);
+      pipe->bind_depth_stencil_alpha_state(pipe,
+                                           ctx->dsa_write_depth_keep_stencil);
+      pipe->bind_fs_state(pipe,
+         blitter_get_fs_texfetch_depth(ctx, src->texture->target));
+
+      fb_state.nr_cbufs = 0;
+      fb_state.zsbuf = dst;
+   } else {
+      pipe->bind_blend_state(pipe, ctx->blend_write_color);
+      pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
+      pipe->bind_fs_state(pipe,
+         blitter_get_fs_texfetch_col(ctx, src->texture->target));
+
+      fb_state.nr_cbufs = 1;
+      fb_state.cbufs[0] = dst;
+      fb_state.zsbuf = 0;
+   }
+
+   pipe->bind_rasterizer_state(pipe, ctx->rs_state);
+   pipe->bind_vs_state(pipe, ctx->vs_tex);
+   pipe->bind_fragment_sampler_states(pipe, 1,
+      blitter_get_sampler_state(ctx, src->level));
+   pipe->set_fragment_sampler_textures(pipe, 1, &src->texture);
+   pipe->set_framebuffer_state(pipe, &fb_state);
+
+   /* set texture coordinates */
+   switch (src->texture->target) {
+      case PIPE_TEXTURE_1D:
+      case PIPE_TEXTURE_2D:
+         blitter_set_texcoords_2d(ctx, src, srcx, srcy,
+                                  srcx+width, srcy+height);
+         break;
+      case PIPE_TEXTURE_3D:
+         blitter_set_texcoords_3d(ctx, src, srcx, srcy,
+                                  srcx+width, srcy+height);
+         break;
+      case PIPE_TEXTURE_CUBE:
+         blitter_set_texcoords_cube(ctx, src, srcx, srcy,
+                                    srcx+width, srcy+height);
+         break;
+      default:
+         assert(0);
+   }
+
+   blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0);
+   blitter_draw_quad(ctx);
+
+}
+
+static void util_blitter_overlap_copy(struct blitter_context *blitter,
+				      struct pipe_surface *dst,
+				      unsigned dstx, unsigned dsty,
+				      struct pipe_surface *src,
+				      unsigned srcx, unsigned srcy,
+				      unsigned width, unsigned height)
+{
+   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_screen *screen = pipe->screen;
+
+   struct pipe_texture texTemp;
+   struct pipe_texture *texture;
+   struct pipe_surface *tex_surf;
+
+   /* check whether the states are properly saved */
+   blitter_check_saved_CSOs(ctx);
+
+   memset(&texTemp, 0, sizeof(texTemp));
+   texTemp.target = PIPE_TEXTURE_2D;
+   texTemp.format = dst->texture->format; /* XXX verify supported by driver! */
+   texTemp.last_level = 0;
+   texTemp.width0 = width;
+   texTemp.height0 = height;
+   texTemp.depth0 = 1;
+
+   texture = screen->texture_create(screen, &texTemp);
+   if (!texture)
+      return;
+
+   tex_surf = screen->get_tex_surface(screen, texture, 0, 0, 0,
+				      PIPE_BUFFER_USAGE_GPU_READ | 
+				      PIPE_BUFFER_USAGE_GPU_WRITE);
+
+   /* blit from the src to the temp */
+   util_blitter_do_copy(blitter, tex_surf, 0, 0,
+			src, srcx, srcy,
+			width, height,
+			FALSE);
+   util_blitter_do_copy(blitter, dst, dstx, dsty,
+			tex_surf, 0, 0,
+			width, height,
+			FALSE);
+   pipe_surface_reference(&tex_surf, NULL);
+   pipe_texture_reference(&texture, NULL);
+   blitter_restore_CSOs(ctx);
+}
+
+void util_blitter_copy(struct blitter_context *blitter,
+                       struct pipe_surface *dst,
+                       unsigned dstx, unsigned dsty,
+                       struct pipe_surface *src,
+                       unsigned srcx, unsigned srcy,
+                       unsigned width, unsigned height,
+                       boolean ignore_stencil)
+{
+   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_screen *screen = pipe->screen;
+   boolean is_stencil, is_depth;
+   unsigned dst_tex_usage;
+
+   /* give up if textures are not set */
+   assert(dst->texture && src->texture);
+   if (!dst->texture || !src->texture)
+      return;
+
+   if (dst->texture == src->texture) {
+      if (is_overlap(srcx, srcx + width, srcy, srcy + height,
+		             dstx, dstx + width, dsty, dsty + height)) {
+         util_blitter_overlap_copy(blitter, dst, dstx, dsty, src, srcx, srcy,
+                                   width, height);
+         return;
+      }
+   }
+		   
+   is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0;
+   is_stencil = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 1) != 0;
+   dst_tex_usage = is_depth || is_stencil ? PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
+                                            PIPE_TEXTURE_USAGE_RENDER_TARGET;
+
+   /* check if we can sample from and render to the surfaces */
+   /* (assuming copying a stencil buffer is not possible) */
+   if ((!ignore_stencil && is_stencil) ||
+       !screen->is_format_supported(screen, dst->format, dst->texture->target,
+                                    dst_tex_usage, 0) ||
+       !screen->is_format_supported(screen, src->format, src->texture->target,
+                                    PIPE_TEXTURE_USAGE_SAMPLER, 0)) {
+      util_surface_copy(pipe, FALSE, dst, dstx, dsty, src, srcx, srcy,
+                        width, height);
+      return;
+   }
+
+   /* check whether the states are properly saved */
+   blitter_check_saved_CSOs(ctx);
+   util_blitter_do_copy(blitter,
+			dst, dstx, dsty,
+			src, srcx, srcy,
+			width, height, is_depth);
+   blitter_restore_CSOs(ctx);
+}
+
+void util_blitter_fill(struct blitter_context *blitter,
+                       struct pipe_surface *dst,
+                       unsigned dstx, unsigned dsty,
+                       unsigned width, unsigned height,
+                       unsigned value)
+{
+   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_screen *screen = pipe->screen;
+   struct pipe_framebuffer_state fb_state;
+   float rgba[4];
+   ubyte ub_rgba[4] = {0};
+   union util_color color;
+   int i;
+
+   assert(dst->texture);
+   if (!dst->texture)
+      return;
+
+   /* check if we can render to the surface */
+   if (util_format_is_depth_or_stencil(dst->format) || /* unlikely, but you never know */
+       !screen->is_format_supported(screen, dst->format, dst->texture->target,
+                                    PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
+      util_surface_fill(pipe, dst, dstx, dsty, width, height, value);
+      return;
+   }
+
+   /* unpack the color */
+   color.ui = value;
+   util_unpack_color_ub(dst->format, &color,
+                        ub_rgba, ub_rgba+1, ub_rgba+2, ub_rgba+3);
+   for (i = 0; i < 4; i++)
+      rgba[i] = ubyte_to_float(ub_rgba[i]);
+
+   /* check the saved state */
+   blitter_check_saved_CSOs(ctx);
+   assert(blitter->saved_fb_state.nr_cbufs != ~0);
+
+   /* bind CSOs */
+   pipe->bind_blend_state(pipe, ctx->blend_write_color);
+   pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
+   pipe->bind_rasterizer_state(pipe, ctx->rs_state);
+   pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1));
+   pipe->bind_vs_state(pipe, ctx->vs_col);
+
+   /* set a framebuffer state */
+   fb_state.width = dst->width;
+   fb_state.height = dst->height;
+   fb_state.nr_cbufs = 1;
+   fb_state.cbufs[0] = dst;
+   fb_state.zsbuf = 0;
+   pipe->set_framebuffer_state(pipe, &fb_state);
+
+   blitter_set_clear_color(ctx, rgba);
+   blitter_set_rectangle(ctx, 0, 0, width, height, 0);
+   blitter_draw_quad(ctx);
+   blitter_restore_CSOs(ctx);
+}
diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h
new file mode 100644
index 0000000..3da5a6c
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_blitter.h
@@ -0,0 +1,230 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+#ifndef U_BLITTER_H
+#define U_BLITTER_H
+
+#include "util/u_memory.h"
+
+#include "pipe/p_state.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct pipe_context;
+
+struct blitter_context
+{
+   /* Private members, really. */
+   void *saved_blend_state;   /**< blend state */
+   void *saved_dsa_state;     /**< depth stencil alpha state */
+   void *saved_rs_state;      /**< rasterizer state */
+   void *saved_fs, *saved_vs; /**< fragment shader, vertex shader */
+
+   struct pipe_framebuffer_state saved_fb_state;  /**< framebuffer state */
+
+   int saved_num_sampler_states;
+   void *saved_sampler_states[32];
+
+   int saved_num_textures;
+   struct pipe_texture *saved_textures[32]; /* is 32 enough? */
+};
+
+/**
+ * Create a blitter context.
+ */
+struct blitter_context *util_blitter_create(struct pipe_context *pipe);
+
+/**
+ * Destroy a blitter context.
+ */
+void util_blitter_destroy(struct blitter_context *blitter);
+
+/*
+ * These CSOs must be saved before any of the following functions is called:
+ * - blend state
+ * - depth stencil alpha state
+ * - rasterizer state
+ * - vertex shader
+ * - fragment shader
+ */
+
+/**
+ * Clear a specified set of currently bound buffers to specified values.
+ */
+void util_blitter_clear(struct blitter_context *blitter,
+                        unsigned width, unsigned height,
+                        unsigned num_cbufs,
+                        unsigned clear_buffers,
+                        const float *rgba,
+                        double depth, unsigned stencil);
+
+/**
+ * Copy a block of pixels from one surface to another.
+ *
+ * You can copy from any color format to any other color format provided
+ * the former can be sampled and the latter can be rendered to. Otherwise,
+ * a software fallback path is taken and both surfaces must be of the same
+ * format.
+ *
+ * The same holds for depth-stencil formats with the exception that stencil
+ * cannot be copied unless you set ignore_stencil to FALSE. In that case,
+ * a software fallback path is taken and both surfaces must be of the same
+ * format.
+ *
+ * Use pipe_screen->is_format_supported to know your options.
+ *
+ * These states must be saved in the blitter in addition to the state objects
+ * already required to be saved:
+ * - framebuffer state
+ * - fragment sampler states
+ * - fragment sampler textures
+ */
+void util_blitter_copy(struct blitter_context *blitter,
+                       struct pipe_surface *dst,
+                       unsigned dstx, unsigned dsty,
+                       struct pipe_surface *src,
+                       unsigned srcx, unsigned srcy,
+                       unsigned width, unsigned height,
+                       boolean ignore_stencil);
+
+/**
+ * Fill a region of a surface with a constant value.
+ *
+ * If the surface cannot be rendered to or it's a depth-stencil format,
+ * a software fallback path is taken.
+ *
+ * These states must be saved in the blitter in addition to the state objects
+ * already required to be saved:
+ * - framebuffer state
+ */
+void util_blitter_fill(struct blitter_context *blitter,
+                       struct pipe_surface *dst,
+                       unsigned dstx, unsigned dsty,
+                       unsigned width, unsigned height,
+                       unsigned value);
+
+/**
+ * Copy all pixels from one surface to another.
+ *
+ * The rules are the same as in util_blitter_copy with the addition that
+ * surfaces must have the same size.
+ */
+static INLINE
+void util_blitter_copy_surface(struct blitter_context *blitter,
+                               struct pipe_surface *dst,
+                               struct pipe_surface *src,
+                               boolean ignore_stencil)
+{
+   assert(dst->width == src->width && dst->height == src->height);
+
+   util_blitter_copy(blitter, dst, 0, 0, src, 0, 0, src->width, src->height,
+                     ignore_stencil);
+}
+
+
+/* The functions below should be used to save currently bound constant state
+ * objects inside a driver. The objects are automatically restored at the end
+ * of the util_blitter_{clear, fill, copy, copy_surface} functions and then
+ * forgotten.
+ *
+ * CSOs not listed here are not affected by util_blitter. */
+
+static INLINE
+void util_blitter_save_blend(struct blitter_context *blitter,
+                             void *state)
+{
+   blitter->saved_blend_state = state;
+}
+
+static INLINE
+void util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter,
+                                           void *state)
+{
+   blitter->saved_dsa_state = state;
+}
+
+static INLINE
+void util_blitter_save_rasterizer(struct blitter_context *blitter,
+                                  void *state)
+{
+   blitter->saved_rs_state = state;
+}
+
+static INLINE
+void util_blitter_save_fragment_shader(struct blitter_context *blitter,
+                                       void *fs)
+{
+   blitter->saved_fs = fs;
+}
+
+static INLINE
+void util_blitter_save_vertex_shader(struct blitter_context *blitter,
+                                     void *vs)
+{
+   blitter->saved_vs = vs;
+}
+
+static INLINE
+void util_blitter_save_framebuffer(struct blitter_context *blitter,
+                                   struct pipe_framebuffer_state *state)
+{
+   blitter->saved_fb_state = *state;
+}
+
+static INLINE
+void util_blitter_save_fragment_sampler_states(
+                  struct blitter_context *blitter,
+                  int num_sampler_states,
+                  void **sampler_states)
+{
+   assert(num_sampler_states <= Elements(blitter->saved_sampler_states));
+
+   blitter->saved_num_sampler_states = num_sampler_states;
+   memcpy(blitter->saved_sampler_states, sampler_states,
+          num_sampler_states * sizeof(void *));
+}
+
+static INLINE
+void util_blitter_save_fragment_sampler_textures(
+                  struct blitter_context *blitter,
+                  int num_textures,
+                  struct pipe_texture **textures)
+{
+   assert(num_textures <= Elements(blitter->saved_textures));
+
+   blitter->saved_num_textures = num_textures;
+   memcpy(blitter->saved_textures, textures,
+          num_textures * sizeof(struct pipe_texture *));
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/gallium/auxiliary/util/u_clear.h b/src/gallium/auxiliary/util/u_clear.h
index 1e65a03..2c32db6 100644
--- a/src/gallium/auxiliary/util/u_clear.h
+++ b/src/gallium/auxiliary/util/u_clear.h
@@ -46,13 +46,13 @@
 {
    if (buffers & PIPE_CLEAR_COLOR) {
       struct pipe_surface *ps = framebuffer->cbufs[0];
-      unsigned color;
+      union util_color uc;
 
-      util_pack_color(rgba, ps->format, &color);
+      util_pack_color(rgba, ps->format, &uc);
       if (pipe->surface_fill) {
-         pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color);
+         pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, uc.ui);
       } else {
-         util_surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color);
+         util_surface_fill(pipe, ps, 0, 0, ps->width, ps->height, uc.ui);
       }
    }
 
diff --git a/src/gallium/auxiliary/util/u_cpu_detect.c b/src/gallium/auxiliary/util/u_cpu_detect.c
index facbe69..a082419 100644
--- a/src/gallium/auxiliary/util/u_cpu_detect.c
+++ b/src/gallium/auxiliary/util/u_cpu_detect.c
@@ -80,7 +80,7 @@
 #if defined(PIPE_ARCH_X86)
 
 /* The sigill handlers */
-#if defined(PIPE_OS_LINUX) //&& defined(_POSIX_SOURCE) && defined(X86_FXSR_MAGIC)
+#if defined(PIPE_OS_LINUX) /*&& defined(_POSIX_SOURCE) && defined(X86_FXSR_MAGIC)*/
 static void
 sigill_handler_sse(int signal, struct sigcontext sc)
 {
@@ -240,7 +240,7 @@
       __asm __volatile ("xorps %xmm0, %xmm0");
 #elif defined(PIPE_CC_MSVC)
       __asm {
-          xorps xmm0, xmm0        // executing SSE instruction
+          xorps xmm0, xmm0        /* executing SSE instruction */
       }
 #else
 #error Unsupported compiler
@@ -283,7 +283,7 @@
     * and therefore to be safe I'm going to leave this test in here.
     */
    if (util_cpu_caps.has_sse) {
-      //      test_os_katmai_exception_support();
+      /* test_os_katmai_exception_support(); */
    }
 
    /* Restore the original signal handlers.
diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c
index 96d400c..9b4e6ca 100644
--- a/src/gallium/auxiliary/util/u_debug.c
+++ b/src/gallium/auxiliary/util/u_debug.c
@@ -64,11 +64,13 @@
 #include "pipe/p_format.h" 
 #include "pipe/p_state.h" 
 #include "pipe/p_inlines.h" 
+#include "util/u_format.h"
 #include "util/u_memory.h" 
 #include "util/u_string.h" 
 #include "util/u_stream.h" 
 #include "util/u_math.h" 
 #include "util/u_tile.h" 
+#include "util/u_prim.h" 
 
 
 #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
@@ -452,7 +454,8 @@
 	    util_strncat(output, "|", sizeof(output));
 	 else
 	    first = 0;
-	 util_strncat(output, names->name, sizeof(output));
+	 util_strncat(output, names->name, sizeof(output) - 1);
+	 output[sizeof(output) - 1] = '\0';
 	 value &= ~names->value;
       }
       ++names;
@@ -465,7 +468,8 @@
 	 first = 0;
       
       util_snprintf(rest, sizeof(rest), "0x%08lx", value);
-      util_strncat(output, rest, sizeof(output));
+      util_strncat(output, rest, sizeof(output) - 1);
+      output[sizeof(output) - 1] = '\0';
    }
    
    if(first)
@@ -600,6 +604,32 @@
 }
 
 
+
+static const struct debug_named_value pipe_prim_names[] = {
+#ifdef DEBUG
+   DEBUG_NAMED_VALUE(PIPE_PRIM_POINTS),
+   DEBUG_NAMED_VALUE(PIPE_PRIM_LINES),
+   DEBUG_NAMED_VALUE(PIPE_PRIM_LINE_LOOP),
+   DEBUG_NAMED_VALUE(PIPE_PRIM_LINE_STRIP),
+   DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLES),
+   DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLE_STRIP),
+   DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLE_FAN),
+   DEBUG_NAMED_VALUE(PIPE_PRIM_QUADS),
+   DEBUG_NAMED_VALUE(PIPE_PRIM_QUAD_STRIP),
+   DEBUG_NAMED_VALUE(PIPE_PRIM_POLYGON),
+#endif
+   DEBUG_NAMED_VALUE_END
+};
+
+
+const char *u_prim_name( unsigned prim )
+{
+   return debug_dump_enum(pipe_prim_names, prim);
+}
+
+
+
+
 #ifdef DEBUG
 void debug_dump_image(const char *prefix,
                       unsigned format, unsigned cpp,
@@ -669,10 +699,10 @@
       goto error;
    
    debug_dump_image(prefix, 
-                    transfer->format,
-                    transfer->block.size, 
-                    transfer->nblocksx,
-                    transfer->nblocksy,
+                    texture->format,
+                    util_format_get_blocksize(texture->format), 
+                    util_format_get_nblocksx(texture->format, transfer->width),
+                    util_format_get_nblocksy(texture->format, transfer->height),
                     transfer->stride,
                     data);
    
diff --git a/src/gallium/auxiliary/util/u_debug.h b/src/gallium/auxiliary/util/u_debug.h
index abd834c..facc30a 100644
--- a/src/gallium/auxiliary/util/u_debug.h
+++ b/src/gallium/auxiliary/util/u_debug.h
@@ -188,7 +188,7 @@
 #ifdef DEBUG
 #define debug_assert(expr) ((expr) ? (void)0 : _debug_assert_fail(#expr, __FILE__, __LINE__, __FUNCTION__))
 #else
-#define debug_assert(expr) ((void)0)
+#define debug_assert(expr) do { } while (0 && (expr))
 #endif
 
 
diff --git a/src/gallium/auxiliary/util/u_debug_dump.c b/src/gallium/auxiliary/util/u_debug_dump.c
index 0986688..61624d0 100644
--- a/src/gallium/auxiliary/util/u_debug_dump.c
+++ b/src/gallium/auxiliary/util/u_debug_dump.c
@@ -255,15 +255,13 @@
 static const char *
 debug_dump_tex_filter_names[] = {
    "PIPE_TEX_FILTER_NEAREST",
-   "PIPE_TEX_FILTER_LINEAR",
-   "PIPE_TEX_FILTER_ANISO"
+   "PIPE_TEX_FILTER_LINEAR"
 };
 
 static const char *
 debug_dump_tex_filter_short_names[] = {
    "nearest",
-   "linear",
-   "aniso"
+   "linear"
 };
 
 DEFINE_DEBUG_DUMP_CONTINUOUS(tex_filter)
diff --git a/src/gallium/auxiliary/util/u_debug_memory.c b/src/gallium/auxiliary/util/u_debug_memory.c
index 7623cb9..d6484f4 100644
--- a/src/gallium/auxiliary/util/u_debug_memory.c
+++ b/src/gallium/auxiliary/util/u_debug_memory.c
@@ -297,9 +297,9 @@
 
       if((start_no <= hdr->no && hdr->no < last_no) ||
 	 (last_no < start_no && (hdr->no < last_no || start_no <= hdr->no))) {
-	 debug_printf("%s:%u:%s: %u bytes at %p not freed\n",
+	 debug_printf("%s:%u:%s: %lu bytes at %p not freed\n",
 		      hdr->file, hdr->line, hdr->function,
-		      hdr->size, ptr);
+		      (unsigned long) hdr->size, ptr);
 #if DEBUG_MEMORY_STACK
 	 debug_backtrace_dump(hdr->backtrace, DEBUG_MEMORY_STACK);
 #endif
@@ -315,8 +315,8 @@
    }
 
    if(total_size) {
-      debug_printf("Total of %u KB of system memory apparently leaked\n",
-		   (total_size + 1023)/1024);
+      debug_printf("Total of %lu KB of system memory apparently leaked\n",
+		   (unsigned long) (total_size + 1023)/1024);
    }
    else {
       debug_printf("No memory leaks detected.\n");
diff --git a/src/gallium/auxiliary/util/u_dl.c b/src/gallium/auxiliary/util/u_dl.c
new file mode 100644
index 0000000..b42b429
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_dl.c
@@ -0,0 +1,79 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * Copyright 1999-2008  Brian Paul
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), 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 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+#include "pipe/p_config.h"
+
+#if defined(PIPE_OS_UNIX)
+#include <dlfcn.h>
+#endif
+#if defined(PIPE_OS_WINDOWS)
+#include <windows.h>
+#endif
+
+#include "u_dl.h"
+
+
+struct util_dl_library *
+util_dl_open(const char *filename)
+{
+#if defined(PIPE_OS_UNIX)
+   return (struct util_dl_library *)dlopen(filename, RTLD_LAZY | RTLD_GLOBAL);
+#elif defined(PIPE_OS_WINDOWS)
+   return (struct util_dl_library *)LoadLibraryA(filename);
+#else
+   return NULL;
+#endif
+}
+
+
+util_dl_proc
+util_dl_get_proc_address(struct util_dl_library *library,
+                         const char *procname)
+{
+#if defined(PIPE_OS_UNIX)
+   return (util_dl_proc)dlsym((void *)library, procname);
+#elif defined(PIPE_OS_WINDOWS)
+   return (util_dl_proc)GetProcAddress((HMODULE)library, procname);
+#else
+   return (util_dl_proc)NULL;
+#endif
+}
+
+
+void
+util_dl_close(struct util_dl_library *library)
+{
+#if defined(PIPE_OS_UNIX)
+   dlclose((void *)library);
+#elif defined(PIPE_OS_WINDOWS)
+   FreeLibrary((HMODULE)library);
+#else
+   (void)library;
+#endif
+}
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c b/src/gallium/auxiliary/util/u_dl.h
similarity index 63%
copy from src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c
copy to src/gallium/auxiliary/util/u_dl.h
index f038bfa..85296c5 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c
+++ b/src/gallium/auxiliary/util/u_dl.h
@@ -1,8 +1,8 @@
 /**************************************************************************
- * 
- * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ *
+ * 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
@@ -10,32 +10,64 @@
  * 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 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
  * THE COPYRIGHT HOLDERS, AUTHORS 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 
+ * 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.
  *
  * The above copyright notice and this permission notice (including the
  * next paragraph) shall be included in all copies or substantial portions
  * of the Software.
- * 
- * 
+ *
  **************************************************************************/
-/*
- * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
+
+
+#ifndef U_DL_H_
+#define U_DL_H_
+
+
+#include "pipe/p_config.h"
+
+
+#if defined(PIPE_OS_WINDOWS)
+#  define UTIL_DL_EXT ".dll"
+#elif defined(PIPE_OS_APPLE)
+#  define UTIL_DL_EXT ".dylib"
+#else
+#  define UTIL_DL_EXT ".so"
+#endif
+
+
+struct util_dl_library;
+
+
+typedef void (*util_dl_proc)(void);
+
+
+/**
+ * Open a library dynamically.
  */
+struct util_dl_library *
+util_dl_open(const char *filename);
 
-#include "radeon_winsys_softpipe.h"
 
-struct pipe_context *radeon_create_softpipe(struct pipe_winsys* winsys)
-{
-    struct pipe_screen *pipe_screen;
+/**
+ * Lookup a function in a library.
+ */
+util_dl_proc
+util_dl_get_proc_address(struct util_dl_library *library,
+                         const char *procname);
 
-    pipe_screen = softpipe_create_screen(winsys);
 
-    return softpipe_create(pipe_screen);
-}
+/**
+ * Close a library.
+ */
+void
+util_dl_close(struct util_dl_library *library);
+
+
+#endif /* U_DL_H_ */
diff --git a/src/gallium/auxiliary/util/u_format.c b/src/gallium/auxiliary/util/u_format.c
index 98ea13b..e0724a1 100644
--- a/src/gallium/auxiliary/util/u_format.c
+++ b/src/gallium/auxiliary/util/u_format.c
@@ -32,15 +32,14 @@
 const struct util_format_description *
 util_format_description(enum pipe_format format)
 {
-   const struct util_format_description *desc = util_format_description_table;
+   const struct util_format_description *desc;
 
-   while(TRUE) {
-      if(desc->format == format)
-         return desc;
+   if (format >= PIPE_FORMAT_COUNT) {
+      return NULL;
+   }
 
-      if(desc->format == PIPE_FORMAT_NONE)
-         return NULL;
+   desc = &util_format_description_table[format];
+   assert(desc->format == format);
 
-      ++desc;
-   };
+   return desc;
 }
diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv
index f1bf94f..9f16b42 100644
--- a/src/gallium/auxiliary/util/u_format.csv
+++ b/src/gallium/auxiliary/util/u_format.csv
@@ -11,6 +11,8 @@
 PIPE_FORMAT_I8_UNORM              , arith , 1, 1, un8 ,     ,     ,     , xxxx, rgb
 PIPE_FORMAT_A8L8_UNORM            , arith , 1, 1, un8 , un8 ,     ,     , xxxy, rgb
 PIPE_FORMAT_L16_UNORM             , arith , 1, 1, un16,     ,     ,     , xxx1, rgb
+PIPE_FORMAT_YCBCR                 , yuv   , 2, 1, x32 ,     ,     ,     , xyz1, yuv
+PIPE_FORMAT_YCBCR_REV             , yuv   , 2, 1, x32 ,     ,     ,     , xyz1, yuv
 PIPE_FORMAT_Z16_UNORM             , array , 1, 1, un16,     ,     ,     , x___, zs 
 PIPE_FORMAT_Z32_UNORM             , array , 1, 1, un32,     ,     ,     , x___, zs 
 PIPE_FORMAT_Z32_FLOAT             , array , 1, 1, f32 ,     ,     ,     , x___, zs 
@@ -74,9 +76,9 @@
 PIPE_FORMAT_R8G8B8_SNORM          , array , 1, 1, sn8 , sn8 , sn8 ,     , xyz1, rgb
 PIPE_FORMAT_R8G8B8A8_SNORM        , array , 1, 1, sn8 , sn8 , sn8 , sn8 , xyzw, rgb
 PIPE_FORMAT_R8G8B8X8_SNORM        , array , 1, 1, sn8 , sn8 , sn8 , sn8 , xyz1, rgb
-PIPE_FORMAT_B6G5R5_SNORM          , arith , 1, 1, sn5 , sn5 , sn6 ,     , zyx1, rgb
-PIPE_FORMAT_A8B8G8R8_SNORM        , arith , 1, 1, sn8 , sn8 , sn8 , sn8 , zyxw, rgb
-PIPE_FORMAT_X8B8G8R8_SNORM        , arith , 1, 1, sn8 , sn8 , sn8 , sn8 , zyx1, rgb
+PIPE_FORMAT_B6G5R5_SNORM          , arith , 1, 1, sn5 , sn5 , sn6 ,     , xyz1, rgb
+PIPE_FORMAT_A8B8G8R8_SNORM        , array , 1, 1, sn8 , sn8 , sn8 , sn8 , wzyx, rgb
+PIPE_FORMAT_X8B8G8R8_SNORM        , array , 1, 1, sn8 , sn8 , sn8 , sn8 , wzy1, rgb
 PIPE_FORMAT_R8_SSCALED            , array , 1, 1, s8  ,     ,     ,     , x001, rgb
 PIPE_FORMAT_R8G8_SSCALED          , array , 1, 1, s8  , s8  ,     ,     , xy01, rgb
 PIPE_FORMAT_R8G8B8_SSCALED        , array , 1, 1, s8  , s8  , s8  ,     , xyz1, rgb
@@ -88,12 +90,20 @@
 PIPE_FORMAT_R32G32B32A32_FIXED    , array , 1, 1, h32 , h32 , h32 , h32 , xyzw, rgb
 PIPE_FORMAT_L8_SRGB               , arith , 1, 1, u8  ,     ,     ,     , xxx1, srgb 
 PIPE_FORMAT_A8L8_SRGB             , arith , 1, 1, u8  , u8  ,     ,     , xxxy, srgb 
-PIPE_FORMAT_R8G8B8_SRGB           , arith , 1, 1, u8  , u8  , u8  ,     , xyz1, srgb 
-PIPE_FORMAT_R8G8B8A8_SRGB         , arith , 1, 1, u8  , u8  , u8  , u8  , xyzw, srgb 
-PIPE_FORMAT_R8G8B8X8_SRGB         , arith , 1, 1, u8  , u8  , u8  , u8  , xyz1, srgb 
-PIPE_FORMAT_A8R8G8B8_SRGB         , arith , 1, 1, u8  , u8  , u8  , u8  , wxyz, srgb 
-PIPE_FORMAT_X8R8G8B8_SRGB         , arith , 1, 1, u8  , u8  , u8  , u8  , 1xyz, srgb 
-PIPE_FORMAT_B8G8R8A8_SRGB         , arith , 1, 1, u8  , u8  , u8  , u8  , zyxw, srgb 
-PIPE_FORMAT_B8G8R8X8_SRGB         , arith , 1, 1, u8  , u8  , u8  , u8  , zyx1, srgb 
-PIPE_FORMAT_X8UB8UG8SR8S_NORM     , arith , 1, 1, sn8 , sn8 , un8 , x8  , 1zyx, rgb
+PIPE_FORMAT_R8G8B8_SRGB           , array , 1, 1, u8  , u8  , u8  ,     , xyz1, srgb 
+PIPE_FORMAT_R8G8B8A8_SRGB         , array , 1, 1, u8  , u8  , u8  , u8  , xyzw, srgb 
+PIPE_FORMAT_R8G8B8X8_SRGB         , array , 1, 1, u8  , u8  , u8  , u8  , xyz1, srgb 
+PIPE_FORMAT_A8R8G8B8_SRGB         , array , 1, 1, u8  , u8  , u8  , u8  , yzwx, srgb 
+PIPE_FORMAT_X8R8G8B8_SRGB         , array , 1, 1, u8  , u8  , u8  , u8  , yzw1, srgb 
+PIPE_FORMAT_B8G8R8A8_SRGB         , array , 1, 1, u8  , u8  , u8  , u8  , zyxw, srgb 
+PIPE_FORMAT_B8G8R8X8_SRGB         , array , 1, 1, u8  , u8  , u8  , u8  , zyx1, srgb 
+PIPE_FORMAT_X8UB8UG8SR8S_NORM     , array , 1, 1, sn8 , sn8 , un8 , x8  , wzy1, rgb
 PIPE_FORMAT_B6UG5SR5S_NORM        , arith , 1, 1, sn5 , sn5 , un6 ,     , xyz1, rgb
+PIPE_FORMAT_DXT1_RGB              , dxt   , 4, 4, x64 ,     ,     ,     , xyz1, rgb
+PIPE_FORMAT_DXT1_RGBA             , dxt   , 4, 4, x64 ,     ,     ,     , xyzw, rgb
+PIPE_FORMAT_DXT3_RGBA             , dxt   , 4, 4, x128,     ,     ,     , xyzw, rgb
+PIPE_FORMAT_DXT5_RGBA             , dxt   , 4, 4, x128,     ,     ,     , xyzw, rgb
+PIPE_FORMAT_DXT1_SRGB             , dxt   , 4, 4, x64 ,     ,     ,     , xyz1, srgb
+PIPE_FORMAT_DXT1_SRGBA            , dxt   , 4, 4, x64 ,     ,     ,     , xyzw, srgb
+PIPE_FORMAT_DXT3_SRGBA            , dxt   , 4, 4, x128,     ,     ,     , xyzw, srgb
+PIPE_FORMAT_DXT5_SRGBA            , dxt   , 4, 4, x128,     ,     ,     , xyzw, srgb
diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h
index 7b5b7fc..a558923 100644
--- a/src/gallium/auxiliary/util/u_format.h
+++ b/src/gallium/auxiliary/util/u_format.h
@@ -32,11 +32,51 @@
 
 #include "pipe/p_format.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
+
+/**
+ * Describe how to best pack/unpack pixels into/from the prescribed format.
+ *
+ * These are used for automatic code generation of pixel packing and unpacking
+ * routines (in compile time, e.g., u_format_access.py, or in runtime, like
+ * llvmpipe does).
+ *
+ * Thumb rule is: if you're not code generating pixel packing/unpacking then
+ * these are irrelevant for you.
+ *
+ * Note that this can be deduced from other values in util_format_description
+ * structure. This is by design, to make code generation of pixel
+ * packing/unpacking/sampling routines simple and efficient.
+ *
+ * XXX: This should be renamed to something like util_format_pack.
+ */
 enum util_format_layout {
+   /**
+    * Single scalar component.
+    */
    UTIL_FORMAT_LAYOUT_SCALAR = 0,
+
+   /**
+    * One or more components of mixed integer formats, arithmetically encoded
+    * in a word up to 32bits.
+    */
    UTIL_FORMAT_LAYOUT_ARITH = 1,
+
+   /**
+    * One or more components, no mixed formats, each with equal power of two
+    * number of bytes.
+    */
    UTIL_FORMAT_LAYOUT_ARRAY = 2,
+
+   /**
+    * XXX: Not used yet. These might go away and be replaced by a single entry,
+    * for formats where multiple pixels have to be
+    * read in order to determine a single pixel value (i.e., block.width > 1
+    * || block.height > 1)
+    */
    UTIL_FORMAT_LAYOUT_YUV = 3,
    UTIL_FORMAT_LAYOUT_DXT = 4
 };
@@ -50,7 +90,7 @@
    /** Block height in pixels */
    unsigned height;
 
-   /** Block size in bytes */
+   /** Block size in bits */
    unsigned bits;
 };
 
@@ -79,7 +119,7 @@
    UTIL_FORMAT_COLORSPACE_RGB = 0,
    UTIL_FORMAT_COLORSPACE_SRGB = 1,
    UTIL_FORMAT_COLORSPACE_YUV = 2,
-   UTIL_FORMAT_COLORSPACE_ZS = 3,
+   UTIL_FORMAT_COLORSPACE_ZS = 3
 };
 
 
@@ -111,6 +151,250 @@
 util_format_description(enum pipe_format format);
 
 
+/*
+ * Format query functions.
+ */
+
+static INLINE boolean 
+util_format_is_compressed(enum pipe_format format)
+{
+   const struct util_format_description *desc = util_format_description(format);
+
+   assert(format);
+   if (!format) {
+      return FALSE;
+   }
+
+   return desc->layout == UTIL_FORMAT_LAYOUT_DXT ? TRUE : FALSE;
+}
+
+static INLINE boolean 
+util_format_is_depth_or_stencil(enum pipe_format format)
+{
+   const struct util_format_description *desc = util_format_description(format);
+
+   assert(format);
+   if (!format) {
+      return FALSE;
+   }
+
+   return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ? TRUE : FALSE;
+}
+
+static INLINE boolean 
+util_format_is_depth_and_stencil(enum pipe_format format)
+{
+   const struct util_format_description *desc = util_format_description(format);
+
+   assert(format);
+   if (!format) {
+      return FALSE;
+   }
+
+   if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) {
+      return FALSE;
+   }
+
+   return (desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE &&
+           desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE) ? TRUE : FALSE;
+}
+
+
+/**
+ * Return total bits needed for the pixel format per block.
+ */
+static INLINE uint
+util_format_get_blocksizebits(enum pipe_format format)
+{
+   const struct util_format_description *desc = util_format_description(format);
+
+   assert(format);
+   if (!format) {
+      return 0;
+   }
+
+   return desc->block.bits;
+}
+
+/**
+ * Return bytes per block (not pixel) for the given format.
+ */
+static INLINE uint
+util_format_get_blocksize(enum pipe_format format)
+{
+   uint bits = util_format_get_blocksizebits(format);
+
+   assert(bits % 8 == 0);
+
+   return bits / 8;
+}
+
+static INLINE uint
+util_format_get_blockwidth(enum pipe_format format)
+{
+   const struct util_format_description *desc = util_format_description(format);
+
+   assert(format);
+   if (!format) {
+      return 1;
+   }
+
+   switch (desc->layout) {
+   case UTIL_FORMAT_LAYOUT_YUV:
+      return 2;
+   case UTIL_FORMAT_LAYOUT_DXT:
+      return 4;
+   default:
+      return 1;
+   }
+}
+
+static INLINE uint
+util_format_get_blockheight(enum pipe_format format)
+{
+   const struct util_format_description *desc = util_format_description(format);
+
+   assert(format);
+   if (!format) {
+      return 1;
+   }
+
+   switch (desc->layout) {
+   case UTIL_FORMAT_LAYOUT_DXT:
+      return 4;
+   default:
+      return 1;
+   }
+}
+
+static INLINE unsigned
+util_format_get_nblocksx(enum pipe_format format,
+                         unsigned x)
+{
+   unsigned blockwidth = util_format_get_blockwidth(format);
+   return (x + blockwidth - 1) / blockwidth;
+}
+
+static INLINE unsigned
+util_format_get_nblocksy(enum pipe_format format,
+                         unsigned y)
+{
+   unsigned blockheight = util_format_get_blockheight(format);
+   return (y + blockheight - 1) / blockheight;
+}
+
+static INLINE unsigned
+util_format_get_nblocks(enum pipe_format format,
+                        unsigned width,
+                        unsigned height)
+{
+   return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height);
+}
+
+static INLINE size_t
+util_format_get_stride(enum pipe_format format,
+                       unsigned width)
+{
+   return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format);
+}
+
+static INLINE size_t
+util_format_get_2d_size(enum pipe_format format,
+                        size_t stride,
+                        unsigned height)
+{
+   return util_format_get_nblocksy(format, height) * stride;
+}
+
+static INLINE uint
+util_format_get_component_bits(enum pipe_format format,
+                               enum util_format_colorspace colorspace,
+                               uint component)
+{
+   const struct util_format_description *desc = util_format_description(format);
+   enum util_format_colorspace desc_colorspace;
+
+   assert(format);
+   if (!format) {
+      return 0;
+   }
+
+   assert(component < 4);
+
+   /* Treat RGB and SRGB as equivalent. */
+   if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
+      colorspace = UTIL_FORMAT_COLORSPACE_RGB;
+   }
+   if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
+      desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;
+   } else {
+      desc_colorspace = desc->colorspace;
+   }
+
+   if (desc_colorspace != colorspace) {
+      return 0;
+   }
+
+   switch (desc->swizzle[component]) {
+   case UTIL_FORMAT_SWIZZLE_X:
+      return desc->channel[0].size;
+   case UTIL_FORMAT_SWIZZLE_Y:
+      return desc->channel[1].size;
+   case UTIL_FORMAT_SWIZZLE_Z:
+      return desc->channel[2].size;
+   case UTIL_FORMAT_SWIZZLE_W:
+      return desc->channel[3].size;
+   default:
+      return 0;
+   }
+}
+
+static INLINE boolean
+util_format_has_alpha(enum pipe_format format)
+{
+   const struct util_format_description *desc = util_format_description(format);
+
+   assert(format);
+   if (!format) {
+      return FALSE;
+   }
+
+   switch (desc->layout) {
+   case UTIL_FORMAT_LAYOUT_SCALAR:
+   case UTIL_FORMAT_LAYOUT_ARITH:
+   case UTIL_FORMAT_LAYOUT_ARRAY:
+      /* FIXME: pf_get_component_bits( PIPE_FORMAT_A8L8_UNORM, PIPE_FORMAT_COMP_A ) should not return 0 right? */
+      if (format == PIPE_FORMAT_A8_UNORM ||
+          format == PIPE_FORMAT_A8L8_UNORM ||
+          format == PIPE_FORMAT_A8L8_SRGB) {
+         return TRUE;
+      }
+      return util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3) != 0;
+   case UTIL_FORMAT_LAYOUT_YUV:
+      return FALSE;
+   case UTIL_FORMAT_LAYOUT_DXT:
+      switch (format) {
+      case PIPE_FORMAT_DXT1_RGBA:
+      case PIPE_FORMAT_DXT3_RGBA:
+      case PIPE_FORMAT_DXT5_RGBA:
+      case PIPE_FORMAT_DXT1_SRGBA:
+      case PIPE_FORMAT_DXT3_SRGBA:
+      case PIPE_FORMAT_DXT5_SRGBA:
+         return TRUE;
+      default:
+         return FALSE;
+      }
+   default:
+      assert(0);
+      return FALSE;
+   }
+}
+
+
+/*
+ * Format access functions.
+ */
+
 void
 util_format_read_4f(enum pipe_format format,
                     float *dst, unsigned dst_stride, 
@@ -135,4 +419,8 @@
                       void *dst, unsigned dst_stride, 
                       unsigned x, unsigned y, unsigned w, unsigned h);
 
+#ifdef __cplusplus
+} // extern "C" {
+#endif
+
 #endif /* ! U_FORMAT_H */
diff --git a/src/gallium/auxiliary/util/u_format_access.py b/src/gallium/auxiliary/util/u_format_access.py
index eeb1a96..0b05ddb 100644
--- a/src/gallium/auxiliary/util/u_format_access.py
+++ b/src/gallium/auxiliary/util/u_format_access.py
@@ -325,14 +325,14 @@
             elif swizzle == SWIZZLE_0:
                 value = '0'
             elif swizzle == SWIZZLE_1:
-                value = '1'
+                value = get_one(dst_type)
             else:
                 assert False
         elif format.colorspace == 'zs':
             if i < 3:
                 value = 'z'
             else:
-                value = '1'
+                value = get_one(dst_type)
         else:
             assert False
         print '         *dst_pixel++ = %s; /* %s */' % (value, 'rgba'[i])
diff --git a/src/gallium/auxiliary/util/u_format_table.py b/src/gallium/auxiliary/util/u_format_table.py
index 8834568..571cab5 100755
--- a/src/gallium/auxiliary/util/u_format_table.py
+++ b/src/gallium/auxiliary/util/u_format_table.py
@@ -44,11 +44,10 @@
 
 
 colorspace_channels_map = {
-    'rgb': 'rgba',
-    'rgba': 'rgba',
-    'zs': 'zs',
-    'yuv': ['y1', 'y2', 'u', 'v'],
-    'dxt': []
+    'rgb': ['r', 'g', 'b', 'a'],
+    'srgb': ['sr', 'sg', 'sb', 'a'],
+    'zs': ['z', 's'],
+    'yuv': ['y', 'u', 'v'],
 }
 
 
@@ -90,36 +89,6 @@
     print 'const struct util_format_description'
     print 'util_format_description_table[] = '
     print "{"
-    for format in formats:
-        print "   {"
-        print "      %s," % (format.name,)
-        print "      \"%s\"," % (format.name,)
-        print "      {%u, %u, %u}, /* block */" % (format.block_width, format.block_height, format.block_size())
-        print "      %s," % (layout_map(format.layout),)
-        print "      {"
-        for i in range(4):
-            type = format.in_types[i]
-            if i < 3:
-                sep = ","
-            else:
-                sep = ""
-            print "         {%s, %s, %u}%s /* %s */" % (kind_map[type.kind], bool_map(type.norm), type.size, sep, "xyzw"[i])
-        print "      },"
-        print "      {"
-        for i in range(4):
-            swizzle = format.out_swizzle[i]
-            if i < 3:
-                sep = ","
-            else:
-                sep = ""
-            try:
-                comment = layout_channels_map[format.layout][i]
-            except:
-                comment = 'ignored'
-            print "         %s%s /* %s */" % (swizzle_map[swizzle], sep, comment)
-        print "      },"
-        print "      %s," % (colorspace_map(format.colorspace),)
-        print "   },"
     print "   {"
     print "      PIPE_FORMAT_NONE,"
     print "      \"PIPE_FORMAT_NONE\","
@@ -129,6 +98,36 @@
     print "      {0, 0, 0, 0},"
     print "      0"
     print "   },"
+    for format in formats:
+        print "   {"
+        print "      %s," % (format.name,)
+        print "      \"%s\"," % (format.name,)
+        print "      {%u, %u, %u},\t/* block */" % (format.block_width, format.block_height, format.block_size())
+        print "      %s," % (layout_map(format.layout),)
+        print "      {"
+        for i in range(4):
+            type = format.in_types[i]
+            if i < 3:
+                sep = ","
+            else:
+                sep = ""
+            print "         {%s, %s, %u}%s\t/* %s */" % (kind_map[type.kind], bool_map(type.norm), type.size, sep, "xyzw"[i])
+        print "      },"
+        print "      {"
+        for i in range(4):
+            swizzle = format.out_swizzle[i]
+            if i < 3:
+                sep = ","
+            else:
+                sep = ""
+            try:
+                comment = colorspace_channels_map[format.colorspace][i]
+            except (KeyError, IndexError):
+                comment = 'ignored'
+            print "         %s%s\t/* %s */" % (swizzle_map[swizzle], sep, comment)
+        print "      },"
+        print "      %s," % (colorspace_map(format.colorspace),)
+        print "   },"
     print "};"
 
 
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index aa823aa..7602379 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -41,10 +41,13 @@
 #include "pipe/p_shader_tokens.h"
 #include "pipe/p_state.h"
 
+#include "util/u_format.h"
 #include "util/u_memory.h"
 #include "util/u_draw_quad.h"
 #include "util/u_gen_mipmap.h"
 #include "util/u_simple_shaders.h"
+#include "util/u_math.h"
+#include "util/u_texture.h"
 
 #include "cso_cache/cso_context.h"
 
@@ -60,7 +63,7 @@
    struct pipe_sampler_state sampler;
 
    void *vs;
-   void *fs;
+   void *fs2d, *fsCube;
 
    struct pipe_buffer *vbuf;  /**< quad vertices */
    unsigned vbuf_slot;
@@ -995,7 +998,7 @@
 {
    enum dtype datatype;
    uint comps;
-   const int bpt = pf_get_size(pformat);
+   const int bpt = util_format_get_blocksize(pformat);
    const ubyte *srcA, *srcB;
    ubyte *dst;
    int row;
@@ -1034,7 +1037,7 @@
           int dstWidth, int dstHeight, int dstDepth,
           int dstRowStride, ubyte *dstPtr)
 {
-   const int bpt = pf_get_size(pformat);
+   const int bpt = util_format_get_blocksize(pformat);
    const int border = 0;
    int img, row;
    int bytesPerSrcImage, bytesPerDstImage;
@@ -1125,12 +1128,12 @@
       
       srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice,
                                           PIPE_TRANSFER_READ, 0, 0,
-                                          pt->width[srcLevel],
-                                          pt->height[srcLevel]);
+                                          u_minify(pt->width0, srcLevel),
+                                          u_minify(pt->height0, srcLevel));
       dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice,
                                           PIPE_TRANSFER_WRITE, 0, 0,
-                                          pt->width[dstLevel],
-                                          pt->height[dstLevel]);
+                                          u_minify(pt->width0, dstLevel),
+                                          u_minify(pt->height0, dstLevel));
 
       srcMap = (ubyte *) screen->transfer_map(screen, srcTrans);
       dstMap = (ubyte *) screen->transfer_map(screen, dstTrans);
@@ -1158,8 +1161,8 @@
    const uint zslice = 0;
    uint dstLevel;
    
-   assert(pt->block.width == 1);
-   assert(pt->block.height == 1);
+   assert(util_format_get_blockwidth(pt->format) == 1);
+   assert(util_format_get_blockheight(pt->format) == 1);
 
    for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
       const uint srcLevel = dstLevel - 1;
@@ -1168,12 +1171,12 @@
       
       srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice,
                                           PIPE_TRANSFER_READ, 0, 0,
-                                          pt->width[srcLevel],
-                                          pt->height[srcLevel]);
+                                          u_minify(pt->width0, srcLevel),
+                                          u_minify(pt->height0, srcLevel));
       dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice,
                                           PIPE_TRANSFER_WRITE, 0, 0,
-                                          pt->width[dstLevel],
-                                          pt->height[dstLevel]);
+                                          u_minify(pt->width0, dstLevel),
+                                          u_minify(pt->height0, dstLevel));
 
       srcMap = (ubyte *) screen->transfer_map(screen, srcTrans);
       dstMap = (ubyte *) screen->transfer_map(screen, dstTrans);
@@ -1203,8 +1206,8 @@
    struct pipe_screen *screen = pipe->screen;
    uint dstLevel, zslice = 0;
 
-   assert(pt->block.width == 1);
-   assert(pt->block.height == 1);
+   assert(util_format_get_blockwidth(pt->format) == 1);
+   assert(util_format_get_blockheight(pt->format) == 1);
 
    for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
       const uint srcLevel = dstLevel - 1;
@@ -1213,12 +1216,12 @@
       
       srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice,
                                           PIPE_TRANSFER_READ, 0, 0,
-                                          pt->width[srcLevel],
-                                          pt->height[srcLevel]);
+                                          u_minify(pt->width0, srcLevel),
+                                          u_minify(pt->height0, srcLevel));
       dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice,
                                           PIPE_TRANSFER_WRITE, 0, 0,
-                                          pt->width[dstLevel],
-                                          pt->height[dstLevel]);
+                                          u_minify(pt->width0, dstLevel),
+                                          u_minify(pt->height0, dstLevel));
 
       srcMap = (ubyte *) screen->transfer_map(screen, srcTrans);
       dstMap = (ubyte *) screen->transfer_map(screen, dstTrans);
@@ -1316,7 +1319,8 @@
    }
 
    /* fragment shader */
-   ctx->fs = util_make_fragment_tex_shader(pipe);
+   ctx->fs2d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D);
+   ctx->fsCube = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE);
 
    /* vertex data that doesn't change */
    for (i = 0; i < 4; i++) {
@@ -1382,59 +1386,9 @@
       static const float st[4][2] = {
          {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}
       };
-      float rx, ry, rz;
-      uint i;
 
-      /* loop over quad verts */
-      for (i = 0; i < 4; i++) {
-         /* Compute sc = +/-scale and tc = +/-scale.
-          * Not +/-1 to avoid cube face selection ambiguity near the edges,
-          * though that can still sometimes happen with this scale factor...
-          */
-         const float scale = 0.9999f;
-         const float sc = (2.0f * st[i][0] - 1.0f) * scale;
-         const float tc = (2.0f * st[i][1] - 1.0f) * scale;
-
-         switch (face) {
-         case PIPE_TEX_FACE_POS_X:
-            rx = 1.0f;
-            ry = -tc;
-            rz = -sc;
-            break;
-         case PIPE_TEX_FACE_NEG_X:
-            rx = -1.0f;
-            ry = -tc;
-            rz = sc;
-            break;
-         case PIPE_TEX_FACE_POS_Y:
-            rx = sc;
-            ry = 1.0f;
-            rz = tc;
-            break;
-         case PIPE_TEX_FACE_NEG_Y:
-            rx = sc;
-            ry = -1.0f;
-            rz = -tc;
-            break;
-         case PIPE_TEX_FACE_POS_Z:
-            rx = sc;
-            ry = -tc;
-            rz = 1.0f;
-            break;
-         case PIPE_TEX_FACE_NEG_Z:
-            rx = -sc;
-            ry = -tc;
-            rz = -1.0f;
-            break;
-         default:
-            rx = ry = rz = 0.0f;
-            assert(0);
-         }
-
-         ctx->vertices[i][1][0] = rx; /*s*/
-         ctx->vertices[i][1][1] = ry; /*t*/
-         ctx->vertices[i][1][2] = rz; /*r*/
-      }
+      util_map_texcoords2d_onto_cubemap(face, &st[0][0], 2,
+                                        &ctx->vertices[0][1][0], 8);
    }
    else {
       /* 1D/2D */
@@ -1474,7 +1428,8 @@
    struct pipe_context *pipe = ctx->pipe;
 
    pipe->delete_vs_state(pipe, ctx->vs);
-   pipe->delete_fs_state(pipe, ctx->fs);
+   pipe->delete_fs_state(pipe, ctx->fs2d);
+   pipe->delete_fs_state(pipe, ctx->fsCube);
 
    pipe_buffer_reference(&ctx->vbuf, NULL);
 
@@ -1512,6 +1467,7 @@
    struct pipe_context *pipe = ctx->pipe;
    struct pipe_screen *screen = pipe->screen;
    struct pipe_framebuffer_state fb;
+   void *fs = (pt->target == PIPE_TEXTURE_CUBE) ? ctx->fsCube : ctx->fs2d;
    uint dstLevel;
    uint zslice = 0;
    uint offset;
@@ -1549,7 +1505,7 @@
    cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
    cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
 
-   cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
+   cso_set_fragment_shader_handle(ctx->cso, fs);
    cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
 
    /* init framebuffer state */
@@ -1575,8 +1531,8 @@
        * Setup framebuffer / dest surface
        */
       fb.cbufs[0] = surf;
-      fb.width = pt->width[dstLevel];
-      fb.height = pt->height[dstLevel];
+      fb.width = u_minify(pt->width0, dstLevel);
+      fb.height = u_minify(pt->height0, dstLevel);
       cso_set_framebuffer(ctx->cso, &fb);
 
       /*
@@ -1597,8 +1553,8 @@
       offset = set_vertex_data(ctx,
                                pt->target,
                                face,
-                               (float) pt->width[dstLevel],
-                               (float) pt->height[dstLevel]);
+                               (float) u_minify(pt->width0, dstLevel),
+                               (float) u_minify(pt->height0, dstLevel));
 
       util_draw_vertex_buffer(ctx->pipe, 
                               ctx->vbuf,
diff --git a/src/gallium/auxiliary/util/u_linear.c b/src/gallium/auxiliary/util/u_linear.c
index a1dce3f..f1aef21 100644
--- a/src/gallium/auxiliary/util/u_linear.c
+++ b/src/gallium/auxiliary/util/u_linear.c
@@ -82,7 +82,7 @@
 
 void
 pipe_linear_fill_info(struct pipe_tile_info *t,
-		      const struct pipe_format_block *block,
+		      const struct u_linear_format_block *block,
 		      unsigned tile_width, unsigned tile_height,
 		      unsigned tiles_x, unsigned tiles_y)
 {
diff --git a/src/gallium/auxiliary/util/u_linear.h b/src/gallium/auxiliary/util/u_linear.h
index b74308f..42c40b2 100644
--- a/src/gallium/auxiliary/util/u_linear.h
+++ b/src/gallium/auxiliary/util/u_linear.h
@@ -35,6 +35,19 @@
 
 #include "pipe/p_format.h"
 
+struct u_linear_format_block
+{
+   /** Block size in bytes */
+   unsigned size;
+   
+   /** Block width in pixels */
+   unsigned width;
+   
+   /** Block height in pixels */
+   unsigned height;
+};
+
+
 struct pipe_tile_info
 {
    unsigned size;
@@ -49,10 +62,10 @@
    unsigned rows;
 
    /* Describe the tile in pixels */
-   struct pipe_format_block tile;
+   struct u_linear_format_block tile;
 
    /* Describe each block within the tile */
-   struct pipe_format_block block;
+   struct u_linear_format_block block;
 };
 
 void pipe_linear_to_tile(size_t src_stride, const void *src_ptr,
@@ -71,7 +84,7 @@
  * @tiles_y number of tiles in y axis
  */
 void pipe_linear_fill_info(struct pipe_tile_info *t,
-			   const struct pipe_format_block *block,
+			   const struct u_linear_format_block *block,
 			   unsigned tile_width, unsigned tile_height,
 			   unsigned tiles_x, unsigned tiles_y);
 
diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h
index 75b075f..b2969a2 100644
--- a/src/gallium/auxiliary/util/u_math.h
+++ b/src/gallium/auxiliary/util/u_math.h
@@ -491,6 +491,47 @@
 
 
 /**
+ * Return number of bits set in n.
+ */
+static INLINE unsigned
+util_bitcount(unsigned n)
+{
+#if defined(PIPE_CC_GCC)
+   return __builtin_popcount(n);
+#else
+   /* K&R classic bitcount.
+    *
+    * For each iteration, clear the LSB from the bitfield.
+    * Requires only one iteration per set bit, instead of
+    * one iteration per bit less than highest set bit.
+    */
+   unsigned bits = 0;
+   for (bits; n; bits++) {
+      n &= n - 1;
+   }
+   return bits;
+#endif
+}
+
+
+/**
+ * Reverse byte order of a 32 bit word.
+ */
+static INLINE uint32_t
+util_bswap32(uint32_t n)
+{
+#if defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION >= 403)
+   return __builtin_bswap32(n);
+#else
+   return (n >> 24) |
+          ((n >> 8) & 0x0000ff00) |
+          ((n << 8) & 0x00ff0000) |
+          (n << 24);
+#endif
+}
+
+
+/**
  * Clamp X to [MIN, MAX].
  * This is a macro to allow float, int, uint, etc. types.
  */
@@ -499,6 +540,9 @@
 #define MIN2( A, B )   ( (A)<(B) ? (A) : (B) )
 #define MAX2( A, B )   ( (A)>(B) ? (A) : (B) )
 
+#define MIN3( A, B, C ) MIN2( MIN2( A, B ), C )
+#define MAX3( A, B, C ) MAX2( MAX2( A, B ), C )
+
 
 static INLINE int
 align(int value, int alignment)
@@ -507,9 +551,9 @@
 }
 
 static INLINE unsigned
-minify(unsigned value)
+u_minify(unsigned value, unsigned levels)
 {
-    return MAX2(1, value >> 1);
+    return MAX2(1, value >> levels);
 }
 
 #ifndef COPY_4V
@@ -539,6 +583,18 @@
 #endif
 
 
+static INLINE uint32_t util_unsigned_fixed(float value, unsigned frac_bits)
+{
+   return value < 0 ? 0 : (uint32_t)(value * (1<<frac_bits));
+}
+
+static INLINE int32_t util_signed_fixed(float value, unsigned frac_bits)
+{
+   return (int32_t)(value * (1<<frac_bits));
+}
+
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/gallium/auxiliary/util/u_mm.c b/src/gallium/auxiliary/util/u_mm.c
index 4b75d4b..82f8370 100644
--- a/src/gallium/auxiliary/util/u_mm.c
+++ b/src/gallium/auxiliary/util/u_mm.c
@@ -39,13 +39,20 @@
    }
    else {
       const struct mem_block *p;
+      int total_used = 0, total_free = 0;
 
       for (p = heap->next; p != heap; p = p->next) {
 	 debug_printf("  Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size,
                       p->free ? 'F':'.',
                       p->reserved ? 'R':'.');
+         if (p->free)
+            total_free += p->size;
+         else
+            total_used += p->size;
       }
 
+      debug_printf("'\nMemory stats: total = %d, used = %d, free = %d\n",
+                   total_used + total_free, total_used, total_free);
       debug_printf("\nFree list:\n");
 
       for (p = heap->next_free; p != heap; p = p->next_free) {
diff --git a/src/gallium/auxiliary/util/u_network.c b/src/gallium/auxiliary/util/u_network.c
index 6269c72..87ee0e4 100644
--- a/src/gallium/auxiliary/util/u_network.c
+++ b/src/gallium/auxiliary/util/u_network.c
@@ -6,7 +6,7 @@
 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
 #  include <winsock2.h>
 #  include <windows.h>
-#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_BSD)
+#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_APPLE)
 #  include <sys/socket.h>
 #  include <netinet/in.h>
 #  include <unistd.h>
@@ -54,7 +54,7 @@
    if (s < 0)
       return;
 
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_BSD)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_APPLE)
    shutdown(s, SHUT_RDWR);
    close(s);
 #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
@@ -117,7 +117,7 @@
    if (!host)
       return -1;
 
-   memcpy((char *)&sa.sin_addr,host->h_addr,host->h_length);
+   memcpy((char *)&sa.sin_addr,host->h_addr_list[0],host->h_length);
    sa.sin_family= host->h_addrtype;
    sa.sin_port = htons(port);
 
@@ -169,7 +169,7 @@
 void
 u_socket_block(int s, boolean block)
 {
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_BSD)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_APPLE)
    int old = fcntl(s, F_GETFL, 0);
    if (old == -1)
       return;
diff --git a/src/gallium/auxiliary/util/u_network.h b/src/gallium/auxiliary/util/u_network.h
index 0aa898b..187dcab 100644
--- a/src/gallium/auxiliary/util/u_network.h
+++ b/src/gallium/auxiliary/util/u_network.h
@@ -6,7 +6,7 @@
 
 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
 #  define PIPE_HAVE_SOCKETS
-#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_BSD)
+#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_APPLE)
 #  define PIPE_HAVE_SOCKETS
 #endif
 
diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h
index eda883b..43eb015 100644
--- a/src/gallium/auxiliary/util/u_pack_color.h
+++ b/src/gallium/auxiliary/util/u_pack_color.h
@@ -37,106 +37,110 @@
 
 #include "pipe/p_compiler.h"
 #include "pipe/p_format.h"
+#include "util/u_format.h"
 #include "util/u_math.h"
 
 
+
+union util_color {
+   ubyte ub;
+   ushort us;
+   uint ui;
+   float f[4];
+};
+
 /**
  * Pack ubyte R,G,B,A into dest pixel.
  */
 static INLINE void
 util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a,
-                   enum pipe_format format, void *dest)
+                   enum pipe_format format, union util_color *uc)
 {
    switch (format) {
    case PIPE_FORMAT_R8G8B8A8_UNORM:
       {
-         uint *d = (uint *) dest;
-         *d = (r << 24) | (g << 16) | (b << 8) | a;
+         uc->ui = (r << 24) | (g << 16) | (b << 8) | a;
       }
       return;
    case PIPE_FORMAT_R8G8B8X8_UNORM:
       {
-         uint *d = (uint *) dest;
-         *d = (r << 24) | (g << 16) | (b << 8) | 0xff;
+         uc->ui = (r << 24) | (g << 16) | (b << 8) | 0xff;
       }
       return;
    case PIPE_FORMAT_A8R8G8B8_UNORM:
       {
-         uint *d = (uint *) dest;
-         *d = (a << 24) | (r << 16) | (g << 8) | b;
+         uc->ui = (a << 24) | (r << 16) | (g << 8) | b;
       }
       return;
    case PIPE_FORMAT_X8R8G8B8_UNORM:
       {
-         uint *d = (uint *) dest;
-         *d = (0xff << 24) | (r << 16) | (g << 8) | b;
+         uc->ui = (0xff << 24) | (r << 16) | (g << 8) | b;
       }
       return;
    case PIPE_FORMAT_B8G8R8A8_UNORM:
       {
-         uint *d = (uint *) dest;
-         *d = (b << 24) | (g << 16) | (r << 8) | a;
+         uc->ui = (b << 24) | (g << 16) | (r << 8) | a;
       }
       return;
    case PIPE_FORMAT_B8G8R8X8_UNORM:
       {
-         uint *d = (uint *) dest;
-         *d = (b << 24) | (g << 16) | (r << 8) | 0xff;
+         uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff;
       }
       return;
    case PIPE_FORMAT_R5G6B5_UNORM:
       {
-         ushort *d = (ushort *) dest;
-         *d = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
+         uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
       }
       return;
    case PIPE_FORMAT_A1R5G5B5_UNORM:
       {
-         ushort *d = (ushort *) dest;
-         *d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
+         uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
       }
       return;
    case PIPE_FORMAT_A4R4G4B4_UNORM:
       {
-         ushort *d = (ushort *) dest;
-         *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
+         uc->us = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
       }
       return;
    case PIPE_FORMAT_A8_UNORM:
       {
-         ubyte *d = (ubyte *) dest;
-         *d = a;
+         uc->ub = a;
       }
       return;
    case PIPE_FORMAT_L8_UNORM:
    case PIPE_FORMAT_I8_UNORM:
       {
-         ubyte *d = (ubyte *) dest;
-         *d = r;
+         uc->ub = a;
       }
       return;
    case PIPE_FORMAT_R32G32B32A32_FLOAT:
       {
-         float *d = (float *) dest;
-         d[0] = (float)r / 255.0f;
-         d[1] = (float)g / 255.0f;
-         d[2] = (float)b / 255.0f;
-         d[3] = (float)a / 255.0f;
+         uc->f[0] = (float)r / 255.0f;
+         uc->f[1] = (float)g / 255.0f;
+         uc->f[2] = (float)b / 255.0f;
+         uc->f[3] = (float)a / 255.0f;
       }
       return;
    case PIPE_FORMAT_R32G32B32_FLOAT:
       {
-         float *d = (float *) dest;
-         d[0] = (float)r / 255.0f;
-         d[1] = (float)g / 255.0f;
-         d[2] = (float)b / 255.0f;
+         uc->f[0] = (float)r / 255.0f;
+         uc->f[1] = (float)g / 255.0f;
+         uc->f[2] = (float)b / 255.0f;
       }
       return;
 
-   /* XXX lots more cases to add */
+   /* Handle other cases with a generic function.
+    */
    default:
-      debug_print_format("gallium: unhandled format in util_pack_color_ub()", format);
-      assert(0);
+      {
+         ubyte src[4];
+
+         src[0] = r;
+         src[1] = g;
+         src[2] = b;
+         src[3] = a;
+         util_format_write_4ub(format, src, 0, uc, 0, 0, 0, 1, 1);
+      }
    }
 }
  
@@ -145,13 +149,13 @@
  * Unpack RGBA from a packed pixel, returning values as ubytes in [0,255].
  */
 static INLINE void
-util_unpack_color_ub(enum pipe_format format, const void *src,
+util_unpack_color_ub(enum pipe_format format, union util_color *uc,
                      ubyte *r, ubyte *g, ubyte *b, ubyte *a)
 {
    switch (format) {
    case PIPE_FORMAT_R8G8B8A8_UNORM:
       {
-         uint p = ((const uint *) src)[0];
+         uint p = uc->ui;
          *r = (ubyte) ((p >> 24) & 0xff);
          *g = (ubyte) ((p >> 16) & 0xff);
          *b = (ubyte) ((p >>  8) & 0xff);
@@ -160,7 +164,7 @@
       return;
    case PIPE_FORMAT_R8G8B8X8_UNORM:
       {
-         uint p = ((const uint *) src)[0];
+         uint p = uc->ui;
          *r = (ubyte) ((p >> 24) & 0xff);
          *g = (ubyte) ((p >> 16) & 0xff);
          *b = (ubyte) ((p >>  8) & 0xff);
@@ -169,7 +173,7 @@
       return;
    case PIPE_FORMAT_A8R8G8B8_UNORM:
       {
-         uint p = ((const uint *) src)[0];
+         uint p = uc->ui;
          *r = (ubyte) ((p >> 16) & 0xff);
          *g = (ubyte) ((p >>  8) & 0xff);
          *b = (ubyte) ((p >>  0) & 0xff);
@@ -178,7 +182,7 @@
       return;
    case PIPE_FORMAT_X8R8G8B8_UNORM:
       {
-         uint p = ((const uint *) src)[0];
+         uint p = uc->ui;
          *r = (ubyte) ((p >> 16) & 0xff);
          *g = (ubyte) ((p >>  8) & 0xff);
          *b = (ubyte) ((p >>  0) & 0xff);
@@ -187,7 +191,7 @@
       return;
    case PIPE_FORMAT_B8G8R8A8_UNORM:
       {
-         uint p = ((const uint *) src)[0];
+         uint p = uc->ui;
          *r = (ubyte) ((p >>  8) & 0xff);
          *g = (ubyte) ((p >> 16) & 0xff);
          *b = (ubyte) ((p >> 24) & 0xff);
@@ -196,7 +200,7 @@
       return;
    case PIPE_FORMAT_B8G8R8X8_UNORM:
       {
-         uint p = ((const uint *) src)[0];
+         uint p = uc->ui;
          *r = (ubyte) ((p >>  8) & 0xff);
          *g = (ubyte) ((p >> 16) & 0xff);
          *b = (ubyte) ((p >> 24) & 0xff);
@@ -205,7 +209,7 @@
       return;
    case PIPE_FORMAT_R5G6B5_UNORM:
       {
-         ushort p = ((const ushort *) src)[0];
+         ushort p = uc->us;
          *r = (ubyte) (((p >> 8) & 0xf8) | ((p >> 13) & 0x7));
          *g = (ubyte) (((p >> 3) & 0xfc) | ((p >>  9) & 0x3));
          *b = (ubyte) (((p << 3) & 0xf8) | ((p >>  2) & 0x7));
@@ -214,7 +218,7 @@
       return;
    case PIPE_FORMAT_A1R5G5B5_UNORM:
       {
-         ushort p = ((const ushort *) src)[0];
+         ushort p = uc->us;
          *r = (ubyte) (((p >>  7) & 0xf8) | ((p >> 12) & 0x7));
          *g = (ubyte) (((p >>  2) & 0xf8) | ((p >>  7) & 0x7));
          *b = (ubyte) (((p <<  3) & 0xf8) | ((p >>  2) & 0x7));
@@ -223,7 +227,7 @@
       return;
    case PIPE_FORMAT_A4R4G4B4_UNORM:
       {
-         ushort p = ((const ushort *) src)[0];
+         ushort p = uc->us;
          *r = (ubyte) (((p >> 4) & 0xf0) | ((p >>  8) & 0xf));
          *g = (ubyte) (((p >> 0) & 0xf0) | ((p >>  4) & 0xf));
          *b = (ubyte) (((p << 4) & 0xf0) | ((p >>  0) & 0xf));
@@ -232,27 +236,27 @@
       return;
    case PIPE_FORMAT_A8_UNORM:
       {
-         ubyte p = ((const ubyte *) src)[0];
+         ubyte p = uc->ub;
          *r = *g = *b = (ubyte) 0xff;
          *a = p;
       }
       return;
    case PIPE_FORMAT_L8_UNORM:
       {
-         ubyte p = ((const ubyte *) src)[0];
+         ubyte p = uc->ub;
          *r = *g = *b = p;
          *a = (ubyte) 0xff;
       }
       return;
    case PIPE_FORMAT_I8_UNORM:
       {
-         ubyte p = ((const ubyte *) src)[0];
+         ubyte p = uc->ub;
          *r = *g = *b = *a = p;
       }
       return;
    case PIPE_FORMAT_R32G32B32A32_FLOAT:
       {
-         const float *p = (const float *) src;
+         const float *p = &uc->f[0];
          *r = float_to_ubyte(p[0]);
          *g = float_to_ubyte(p[1]);
          *b = float_to_ubyte(p[2]);
@@ -261,7 +265,7 @@
       return;
    case PIPE_FORMAT_R32G32B32_FLOAT:
       {
-         const float *p = (const float *) src;
+         const float *p = &uc->f[0];
          *r = float_to_ubyte(p[0]);
          *g = float_to_ubyte(p[1]);
          *b = float_to_ubyte(p[2]);
@@ -271,7 +275,7 @@
 
    case PIPE_FORMAT_R32G32_FLOAT:
       {
-         const float *p = (const float *) src;
+         const float *p = &uc->f[0];
          *r = float_to_ubyte(p[0]);
          *g = float_to_ubyte(p[1]);
          *b = *a = (ubyte) 0xff;
@@ -280,31 +284,40 @@
 
    case PIPE_FORMAT_R32_FLOAT:
       {
-         const float *p = (const float *) src;
+         const float *p = &uc->f[0];
          *r = float_to_ubyte(p[0]);
          *g = *b = *a = (ubyte) 0xff;
       }
       return;
 
-   /* XXX lots more cases to add */
+   /* Handle other cases with a generic function.
+    */
    default:
-      debug_print_format("gallium: unhandled format in util_unpack_color_ub()",
-                         format);
-      assert(0);
+      {
+         ubyte dst[4];
+
+         util_format_read_4ub(format, dst, 0, uc, 0, 0, 0, 1, 1);
+         *r = dst[0];
+         *g = dst[1];
+         *b = dst[2];
+         *a = dst[3];
+      }
    }
 }
- 
 
 
 /**
  * Note rgba outside [0,1] will be clamped for int pixel formats.
  */
 static INLINE void
-util_pack_color(const float rgba[4], enum pipe_format format, void *dest)
+util_pack_color(const float rgba[4], enum pipe_format format, union util_color *uc)
 {
-   ubyte r, g, b, a;
+   ubyte r = 0;
+   ubyte g = 0;
+   ubyte b = 0;
+   ubyte a = 0;
 
-   if (pf_size_x(format) <= 8) {
+   if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0) <= 8) {
       /* format uses 8-bit components or less */
       r = float_to_ubyte(rgba[0]);
       g = float_to_ubyte(rgba[1]);
@@ -315,92 +328,80 @@
    switch (format) {
    case PIPE_FORMAT_R8G8B8A8_UNORM:
       {
-         uint *d = (uint *) dest;
-         *d = (r << 24) | (g << 16) | (b << 8) | a;
+         uc->ui = (r << 24) | (g << 16) | (b << 8) | a;
       }
       return;
    case PIPE_FORMAT_R8G8B8X8_UNORM:
       {
-         uint *d = (uint *) dest;
-         *d = (r << 24) | (g << 16) | (b << 8) | 0xff;
+         uc->ui = (r << 24) | (g << 16) | (b << 8) | 0xff;
       }
       return;
    case PIPE_FORMAT_A8R8G8B8_UNORM:
       {
-         uint *d = (uint *) dest;
-         *d = (a << 24) | (r << 16) | (g << 8) | b;
+         uc->ui = (a << 24) | (r << 16) | (g << 8) | b;
       }
       return;
    case PIPE_FORMAT_X8R8G8B8_UNORM:
       {
-         uint *d = (uint *) dest;
-         *d = (0xff << 24) | (r << 16) | (g << 8) | b;
+         uc->ui = (0xff << 24) | (r << 16) | (g << 8) | b;
       }
       return;
    case PIPE_FORMAT_B8G8R8A8_UNORM:
       {
-         uint *d = (uint *) dest;
-         *d = (b << 24) | (g << 16) | (r << 8) | a;
+         uc->ui = (b << 24) | (g << 16) | (r << 8) | a;
       }
       return;
    case PIPE_FORMAT_B8G8R8X8_UNORM:
       {
-         uint *d = (uint *) dest;
-         *d = (b << 24) | (g << 16) | (r << 8) | 0xff;
+         uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff;
       }
       return;
    case PIPE_FORMAT_R5G6B5_UNORM:
       {
-         ushort *d = (ushort *) dest;
-         *d = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
+         uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
       }
       return;
    case PIPE_FORMAT_A1R5G5B5_UNORM:
       {
-         ushort *d = (ushort *) dest;
-         *d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
+         uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
       }
       return;
    case PIPE_FORMAT_A4R4G4B4_UNORM:
       {
-         ushort *d = (ushort *) dest;
-         *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
+         uc->ub = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
       }
       return;
    case PIPE_FORMAT_A8_UNORM:
       {
-         ubyte *d = (ubyte *) dest;
-         *d = a;
+         uc->ub = a;
       }
       return;
    case PIPE_FORMAT_L8_UNORM:
    case PIPE_FORMAT_I8_UNORM:
       {
-         ubyte *d = (ubyte *) dest;
-         *d = r;
+         uc->ub = r;
       }
       return;
    case PIPE_FORMAT_R32G32B32A32_FLOAT:
       {
-         float *d = (float *) dest;
-         d[0] = rgba[0];
-         d[1] = rgba[1];
-         d[2] = rgba[2];
-         d[3] = rgba[3];
+         uc->f[0] = rgba[0];
+         uc->f[1] = rgba[1];
+         uc->f[2] = rgba[2];
+         uc->f[3] = rgba[3];
       }
       return;
    case PIPE_FORMAT_R32G32B32_FLOAT:
       {
-         float *d = (float *) dest;
-         d[0] = rgba[0];
-         d[1] = rgba[1];
-         d[2] = rgba[2];
+         uc->f[0] = rgba[0];
+         uc->f[1] = rgba[1];
+         uc->f[2] = rgba[2];
       }
       return;
-   /* XXX lots more cases to add */
+
+   /* Handle other cases with a generic function.
+    */
    default:
-      debug_print_format("gallium: unhandled format in util_pack_color()", format);
-      assert(0);
+      util_format_write_4f(format, rgba, 0, uc, 0, 0, 0, 1, 1);
    }
 }
  
diff --git a/src/gallium/auxiliary/util/u_prim.h b/src/gallium/auxiliary/util/u_prim.h
index a9b533e..10a874f 100644
--- a/src/gallium/auxiliary/util/u_prim.h
+++ b/src/gallium/auxiliary/util/u_prim.h
@@ -135,4 +135,39 @@
    }
 }
 
+static INLINE unsigned
+u_vertices_per_prim(int primitive)
+{
+   switch(primitive) {
+   case PIPE_PRIM_POINTS:
+      return 1;
+   case PIPE_PRIM_LINES:
+   case PIPE_PRIM_LINE_LOOP:
+   case PIPE_PRIM_LINE_STRIP:
+      return 2;
+   case PIPE_PRIM_TRIANGLES:
+   case PIPE_PRIM_TRIANGLE_STRIP:
+   case PIPE_PRIM_TRIANGLE_FAN:
+      return 3;
+   case PIPE_PRIM_LINES_ADJACENCY:
+   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+      return 4;
+   case PIPE_PRIM_TRIANGLES_ADJACENCY:
+   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
+      return 6;
+
+   /* following primitives should never be used
+    * with geometry shaders abd their size is
+    * undefined */
+   case PIPE_PRIM_POLYGON:
+   case PIPE_PRIM_QUADS:
+   case PIPE_PRIM_QUAD_STRIP:
+   default:
+      debug_printf("Unrecognized geometry shader primitive");
+      return 3;
+   }
+}
+
+const char *u_prim_name( unsigned pipe_prim );
+
 #endif
diff --git a/src/gallium/auxiliary/util/u_rect.c b/src/gallium/auxiliary/util/u_rect.c
index 9866b6f..8479161 100644
--- a/src/gallium/auxiliary/util/u_rect.c
+++ b/src/gallium/auxiliary/util/u_rect.c
@@ -34,17 +34,18 @@
 #include "pipe/p_format.h"
 #include "pipe/p_context.h"
 #include "pipe/p_screen.h"
+#include "util/u_format.h"
 #include "util/u_rect.h"
 
 
 /**
  * Copy 2D rect from one place to another.
  * Position and sizes are in pixels.
- * src_pitch may be negative to do vertical flip of pixels from source.
+ * src_stride may be negative to do vertical flip of pixels from source.
  */
 void
 util_copy_rect(ubyte * dst,
-               const struct pipe_format_block *block,
+               enum pipe_format format,
                unsigned dst_stride,
                unsigned dst_x,
                unsigned dst_y,
@@ -53,31 +54,30 @@
                const ubyte * src,
                int src_stride,
                unsigned src_x, 
-               int src_y)
+               unsigned src_y)
 {
    unsigned i;
    int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
+   int blocksize = util_format_get_blocksize(format);
+   int blockwidth = util_format_get_blockwidth(format);
+   int blockheight = util_format_get_blockheight(format);
 
-   assert(block->size > 0);
-   assert(block->width > 0);
-   assert(block->height > 0);
-   assert(src_x >= 0);
-   assert(src_y >= 0);
-   assert(dst_x >= 0);
-   assert(dst_y >= 0);
+   assert(blocksize > 0);
+   assert(blockwidth > 0);
+   assert(blockheight > 0);
 
-   dst_x /= block->width;
-   dst_y /= block->height;
-   width = (width + block->width - 1)/block->width;
-   height = (height + block->height - 1)/block->height;
-   src_x /= block->width;
-   src_y /= block->height;
+   dst_x /= blockwidth;
+   dst_y /= blockheight;
+   width = (width + blockwidth - 1)/blockwidth;
+   height = (height + blockheight - 1)/blockheight;
+   src_x /= blockwidth;
+   src_y /= blockheight;
    
-   dst += dst_x * block->size;
-   src += src_x * block->size;
+   dst += dst_x * blocksize;
+   src += src_x * blocksize;
    dst += dst_y * dst_stride;
    src += src_y * src_stride_pos;
-   width *= block->size;
+   width *= blocksize;
 
    if (width == dst_stride && width == src_stride)
       memcpy(dst, src, height * width);
@@ -92,7 +92,7 @@
 
 void
 util_fill_rect(ubyte * dst,
-               const struct pipe_format_block *block,
+               enum pipe_format format,
                unsigned dst_stride,
                unsigned dst_x,
                unsigned dst_y,
@@ -102,23 +102,24 @@
 {
    unsigned i, j;
    unsigned width_size;
+   int blocksize = util_format_get_blocksize(format);
+   int blockwidth = util_format_get_blockwidth(format);
+   int blockheight = util_format_get_blockheight(format);
 
-   assert(block->size > 0);
-   assert(block->width > 0);
-   assert(block->height > 0);
-   assert(dst_x >= 0);
-   assert(dst_y >= 0);
+   assert(blocksize > 0);
+   assert(blockwidth > 0);
+   assert(blockheight > 0);
 
-   dst_x /= block->width;
-   dst_y /= block->height;
-   width = (width + block->width - 1)/block->width;
-   height = (height + block->height - 1)/block->height;
+   dst_x /= blockwidth;
+   dst_y /= blockheight;
+   width = (width + blockwidth - 1)/blockwidth;
+   height = (height + blockheight - 1)/blockheight;
    
-   dst += dst_x * block->size;
+   dst += dst_x * blocksize;
    dst += dst_y * dst_stride;
-   width_size = width * block->size;
+   width_size = width * blocksize;
    
-   switch (block->size) {
+   switch (blocksize) {
    case 1:
       if(dst_stride == width_size)
 	 memset(dst, (ubyte) value, height * width_size);
@@ -172,10 +173,15 @@
    struct pipe_transfer *src_trans, *dst_trans;
    void *dst_map;
    const void *src_map;
+   enum pipe_format src_format, dst_format;
 
    assert(src->texture && dst->texture);
    if (!src->texture || !dst->texture)
       return;
+
+   src_format = src->texture->format;
+   dst_format = dst->texture->format;
+
    src_trans = screen->get_tex_transfer(screen,
                                         src->texture,
                                         src->face,
@@ -192,9 +198,9 @@
                                         PIPE_TRANSFER_WRITE,
                                         dst_x, dst_y, w, h);
 
-   assert(dst_trans->block.size == src_trans->block.size);
-   assert(dst_trans->block.width == src_trans->block.width);
-   assert(dst_trans->block.height == src_trans->block.height);
+   assert(util_format_get_blocksize(dst_format) == util_format_get_blocksize(src_format));
+   assert(util_format_get_blockwidth(dst_format) == util_format_get_blockwidth(src_format));
+   assert(util_format_get_blockheight(dst_format) == util_format_get_blockheight(src_format));
 
    src_map = pipe->screen->transfer_map(screen, src_trans);
    dst_map = pipe->screen->transfer_map(screen, dst_trans);
@@ -205,7 +211,7 @@
    if (src_map && dst_map) {
       /* If do_flip, invert src_y position and pass negative src stride */
       util_copy_rect(dst_map,
-                     &dst_trans->block,
+                     dst_format,
                      dst_trans->stride,
                      0, 0,
                      w, h,
@@ -259,11 +265,11 @@
    if (dst_map) {
       assert(dst_trans->stride > 0);
 
-      switch (dst_trans->block.size) {
+      switch (util_format_get_blocksize(dst_trans->texture->format)) {
       case 1:
       case 2:
       case 4:
-         util_fill_rect(dst_map, &dst_trans->block, dst_trans->stride,
+         util_fill_rect(dst_map, dst_trans->texture->format, dst_trans->stride,
                         0, 0, width, height, value);
          break;
       case 8:
diff --git a/src/gallium/auxiliary/util/u_rect.h b/src/gallium/auxiliary/util/u_rect.h
index daa5083..b44d821 100644
--- a/src/gallium/auxiliary/util/u_rect.h
+++ b/src/gallium/auxiliary/util/u_rect.h
@@ -42,13 +42,13 @@
 
 
 extern void
-util_copy_rect(ubyte * dst, const struct pipe_format_block *block,
+util_copy_rect(ubyte * dst, enum pipe_format format,
                unsigned dst_stride, unsigned dst_x, unsigned dst_y,
                unsigned width, unsigned height, const ubyte * src,
-               int src_stride, unsigned src_x, int src_y);
+               int src_stride, unsigned src_x, unsigned src_y);
 
 extern void
-util_fill_rect(ubyte * dst, const struct pipe_format_block *block,
+util_fill_rect(ubyte * dst, enum pipe_format format,
                unsigned dst_stride, unsigned dst_x, unsigned dst_y,
                unsigned width, unsigned height, uint32_t value);
 
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
index 1c8b157..b751e29 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -2,6 +2,7 @@
  *
  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -30,6 +31,7 @@
  * Simple vertex/fragment shader generators.
  *  
  * @author Brian Paul
+           Marek Olšák
  */
 
 
@@ -42,13 +44,15 @@
 
 /**
  * Make simple vertex pass-through shader.
+ * \param num_attribs  number of attributes to pass through
+ * \param semantic_names  array of semantic names for each attribute
+ * \param semantic_indexes  array of semantic indexes for each attribute
  */
 void *
 util_make_vertex_passthrough_shader(struct pipe_context *pipe,
                                     uint num_attribs,
                                     const uint *semantic_names,
                                     const uint *semantic_indexes)
-                                    
 {
    struct ureg_program *ureg;
    uint i;
@@ -76,8 +80,6 @@
 }
 
 
-
-
 /**
  * Make simple fragment texture shader:
  *  IMM {0,0,0,1}                         // (if writemask != 0xf)
@@ -87,6 +89,7 @@
  */
 void *
 util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
+                                        unsigned tex_target,
                                         unsigned writemask )
 {
    struct ureg_program *ureg;
@@ -116,20 +119,71 @@
 
    ureg_TEX( ureg, 
              ureg_writemask(out, writemask),
-             TGSI_TEXTURE_2D, tex, sampler );
+             tex_target, tex, sampler );
    ureg_END( ureg );
 
    return ureg_create_shader_and_destroy( ureg, pipe );
 }
 
+
+/**
+ * Make a simple fragment shader that sets the output color to a color
+ * taken from a texture.
+ * \param tex_target  one of PIPE_TEXTURE_x
+ */
 void *
-util_make_fragment_tex_shader(struct pipe_context *pipe )
+util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target )
 {
    return util_make_fragment_tex_shader_writemask( pipe,
+                                                   tex_target,
                                                    TGSI_WRITEMASK_XYZW );
 }
 
 
+/**
+ * Make a simple fragment texture shader which reads an X component from
+ * a texture and writes it as depth.
+ */
+void *
+util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
+                                         unsigned tex_target)
+{
+   struct ureg_program *ureg;
+   struct ureg_src sampler;
+   struct ureg_src tex;
+   struct ureg_dst out, depth;
+   struct ureg_src imm;
+
+   ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
+   if (ureg == NULL)
+      return NULL;
+
+   sampler = ureg_DECL_sampler( ureg, 0 );
+
+   tex = ureg_DECL_fs_input( ureg,
+                             TGSI_SEMANTIC_GENERIC, 0,
+                             TGSI_INTERPOLATE_PERSPECTIVE );
+
+   out = ureg_DECL_output( ureg,
+                           TGSI_SEMANTIC_COLOR,
+                           0 );
+
+   depth = ureg_DECL_output( ureg,
+                             TGSI_SEMANTIC_POSITION,
+                             0 );
+
+   imm = ureg_imm4f( ureg, 0, 0, 0, 1 );
+
+   ureg_MOV( ureg, out, imm );
+
+   ureg_TEX( ureg,
+             ureg_writemask(depth, TGSI_WRITEMASK_Z),
+             tex_target, tex, sampler );
+   ureg_END( ureg );
+
+   return ureg_create_shader_and_destroy( ureg, pipe );
+}
+
 
 /**
  * Make simple fragment color pass-through shader.
@@ -137,9 +191,22 @@
 void *
 util_make_fragment_passthrough_shader(struct pipe_context *pipe)
 {
+   return util_make_fragment_clonecolor_shader(pipe, 1);
+}
+
+
+/**
+ * Make a fragment shader that copies the input color to N output colors.
+ */
+void *
+util_make_fragment_clonecolor_shader(struct pipe_context *pipe, int num_cbufs)
+{
    struct ureg_program *ureg;
    struct ureg_src src;
-   struct ureg_dst dst;
+   struct ureg_dst dst[PIPE_MAX_COLOR_BUFS];
+   int i;
+
+   assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
 
    ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
    if (ureg == NULL)
@@ -148,12 +215,13 @@
    src = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_COLOR, 0, 
                              TGSI_INTERPOLATE_PERSPECTIVE );
 
-   dst = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 );
+   for (i = 0; i < num_cbufs; i++)
+      dst[i] = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, i );
 
-   ureg_MOV( ureg, dst, src );
+   for (i = 0; i < num_cbufs; i++)
+      ureg_MOV( ureg, dst[i], src );
+
    ureg_END( ureg );
 
    return ureg_create_shader_and_destroy( ureg, pipe );
 }
-
-
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h
index d2e80d6..6e76094 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.h
+++ b/src/gallium/auxiliary/util/u_simple_shaders.h
@@ -51,16 +51,25 @@
 
 extern void *
 util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, 
-                                        unsigned writemask );
+                                        unsigned tex_target,
+                                        unsigned writemask);
 
 extern void *
-util_make_fragment_tex_shader(struct pipe_context *pipe);
+util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target);
+
+
+extern void *
+util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
+                                         unsigned tex_target);
 
 
 extern void *
 util_make_fragment_passthrough_shader(struct pipe_context *pipe);
 
 
+extern void *
+util_make_fragment_clonecolor_shader(struct pipe_context *pipe, int num_cbufs);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/gallium/auxiliary/util/u_stream_stdc.c b/src/gallium/auxiliary/util/u_stream_stdc.c
index 5cd05b2..4d976d6 100644
--- a/src/gallium/auxiliary/util/u_stream_stdc.c
+++ b/src/gallium/auxiliary/util/u_stream_stdc.c
@@ -32,7 +32,7 @@
 
 #include "pipe/p_config.h"
 
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_APPLE)
 
 #include <stdio.h>
 
diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c
index 85e4432..35c4978 100644
--- a/src/gallium/auxiliary/util/u_surface.c
+++ b/src/gallium/auxiliary/util/u_surface.c
@@ -36,6 +36,7 @@
 #include "pipe/p_state.h"
 #include "pipe/p_defines.h"
 
+#include "util/u_format.h"
 #include "util/u_surface.h"
 
 
@@ -79,10 +80,9 @@
    templ.target = target;
    templ.format = format;
    templ.last_level = 0;
-   templ.width[0] = width;
-   templ.height[0] = height;
-   templ.depth[0] = 1;
-   pf_get_block(format, &templ.block);
+   templ.width0 = width;
+   templ.height0 = height;
+   templ.depth0 = 1;
    templ.tex_usage = usage;
 
    *textureOut = screen->texture_create(screen, &templ);
diff --git a/src/gallium/auxiliary/util/u_texture.c b/src/gallium/auxiliary/util/u_texture.c
new file mode 100644
index 0000000..cd477ab
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_texture.c
@@ -0,0 +1,102 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * Copyright 2008 VMware, Inc.  All rights reserved.
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Texture mapping utility functions.
+ *
+ * @author Brian Paul
+ *         Marek Olšák
+ */
+
+#include "pipe/p_defines.h"
+
+#include "util/u_texture.h"
+
+void util_map_texcoords2d_onto_cubemap(unsigned face,
+                                       const float *in_st, unsigned in_stride,
+                                       float *out_str, unsigned out_stride)
+{
+   int i;
+   float rx, ry, rz;
+
+   /* loop over quad verts */
+   for (i = 0; i < 4; i++) {
+      /* Compute sc = +/-scale and tc = +/-scale.
+       * Not +/-1 to avoid cube face selection ambiguity near the edges,
+       * though that can still sometimes happen with this scale factor...
+       */
+      const float scale = 0.9999f;
+      const float sc = (2 * in_st[0] - 1) * scale;
+      const float tc = (2 * in_st[1] - 1) * scale;
+
+      switch (face) {
+         case PIPE_TEX_FACE_POS_X:
+            rx = 1;
+            ry = -tc;
+            rz = -sc;
+            break;
+         case PIPE_TEX_FACE_NEG_X:
+            rx = -1;
+            ry = -tc;
+            rz = sc;
+            break;
+         case PIPE_TEX_FACE_POS_Y:
+            rx = sc;
+            ry = 1;
+            rz = tc;
+            break;
+         case PIPE_TEX_FACE_NEG_Y:
+            rx = sc;
+            ry = -1;
+            rz = -tc;
+            break;
+         case PIPE_TEX_FACE_POS_Z:
+            rx = sc;
+            ry = -tc;
+            rz = 1;
+            break;
+         case PIPE_TEX_FACE_NEG_Z:
+            rx = -sc;
+            ry = -tc;
+            rz = -1;
+            break;
+         default:
+            rx = ry = rz = 0;
+            assert(0);
+      }
+
+      out_str[0] = rx; /*s*/
+      out_str[1] = ry; /*t*/
+      out_str[2] = rz; /*r*/
+
+      in_st += in_stride;
+      out_str += out_stride;
+   }
+}
diff --git a/src/mesa/state_tracker/st_cb_get.h b/src/gallium/auxiliary/util/u_texture.h
similarity index 60%
copy from src/mesa/state_tracker/st_cb_get.h
copy to src/gallium/auxiliary/util/u_texture.h
index 8e9f3e9..93b2f1e 100644
--- a/src/mesa/state_tracker/st_cb_get.h
+++ b/src/gallium/auxiliary/util/u_texture.h
@@ -1,8 +1,7 @@
 /**************************************************************************
- * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
+ *
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
+ *
  * 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,11 +9,11 @@
  * 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.
@@ -22,16 +21,34 @@
  * 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.
- * 
+ *
  **************************************************************************/
 
+#ifndef U_TEXTURE_H
+#define U_TEXTURE_H
 
-#ifndef ST_CB_GET_H
-#define ST_CB_GET_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Convert 2D texture coordinates of 4 vertices into cubemap coordinates
+ * in the given face.
+ * Coordinates must be in the range [0,1].
+ *
+ * \param face          Cubemap face.
+ * \param in_st         4 pairs of 2D texture coordinates to convert.
+ * \param in_stride     Stride of in_st in floats.
+ * \param out_str       STR cubemap texture coordinates to compute.
+ * \param out_stride    Stride of out_str in floats.
+ */
+void util_map_texcoords2d_onto_cubemap(unsigned face,
+                                       const float *in_st, unsigned in_stride,
+                                       float *out_str, unsigned out_stride);
 
 
-extern void
-st_init_get_functions(struct dd_function_table *functions);
-
+#ifdef __cplusplus
+}
+#endif
 
 #endif
diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c
index 8a22f58..1ba82bb 100644
--- a/src/gallium/auxiliary/util/u_tile.c
+++ b/src/gallium/auxiliary/util/u_tile.c
@@ -34,6 +34,7 @@
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
 
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "util/u_rect.h"
@@ -52,7 +53,7 @@
    const void *src;
 
    if (dst_stride == 0)
-      dst_stride = pf_get_nblocksx(&pt->block, w) * pt->block.size;
+      dst_stride = util_format_get_stride(pt->texture->format, w);
 
    if (pipe_clip_tile(x, y, &w, &h, pt))
       return;
@@ -62,7 +63,7 @@
    if(!src)
       return;
 
-   util_copy_rect(dst, &pt->block, dst_stride, 0, 0, w, h, src, pt->stride, x, y);
+   util_copy_rect(dst, pt->texture->format, dst_stride, 0, 0, w, h, src, pt->stride, x, y);
 
    screen->transfer_unmap(screen, pt);
 }
@@ -78,9 +79,10 @@
 {
    struct pipe_screen *screen = pt->texture->screen;
    void *dst;
+   enum pipe_format format = pt->texture->format;
 
    if (src_stride == 0)
-      src_stride = pf_get_nblocksx(&pt->block, w) * pt->block.size;
+      src_stride = util_format_get_stride(format, w);
 
    if (pipe_clip_tile(x, y, &w, &h, pt))
       return;
@@ -90,7 +92,7 @@
    if(!dst)
       return;
 
-   util_copy_rect(dst, &pt->block, pt->stride, x, y, w, h, src, src_stride, 0, 0);
+   util_copy_rect(dst, format, pt->stride, x, y, w, h, src, src_stride, 0, 0);
 
    screen->transfer_unmap(screen, pt);
 }
@@ -246,6 +248,53 @@
 }
 
 
+/*** PIPE_FORMAT_R8G8B8A8_UNORM ***/
+
+static void
+r8g8b8a8_get_tile_rgba(const unsigned *src,
+                       unsigned w, unsigned h,
+                       float *p,
+                       unsigned dst_stride)
+{
+   unsigned i, j;
+
+   for (i = 0; i < h; i++) {
+      float *pRow = p;
+      for (j = 0; j < w; j++, pRow += 4) {
+         const unsigned pixel = *src++;
+         pRow[0] = ubyte_to_float((pixel >> 24) & 0xff);
+         pRow[1] = ubyte_to_float((pixel >> 16) & 0xff);
+         pRow[2] = ubyte_to_float((pixel >>  8) & 0xff);
+         pRow[3] = ubyte_to_float((pixel >>  0) & 0xff);
+      }
+      p += dst_stride;
+   }
+}
+
+
+static void
+r8g8b8a8_put_tile_rgba(unsigned *dst,
+                       unsigned w, unsigned h,
+                       const float *p,
+                       unsigned src_stride)
+{
+   unsigned i, j;
+
+   for (i = 0; i < h; i++) {
+      const float *pRow = p;
+      for (j = 0; j < w; j++, pRow += 4) {
+         unsigned r, g, b, a;
+         r = float_to_ubyte(pRow[0]);
+         g = float_to_ubyte(pRow[1]);
+         b = float_to_ubyte(pRow[2]);
+         a = float_to_ubyte(pRow[3]);
+         *dst++ = (r << 24) | (g << 16) | (b << 8) | a;
+      }
+      p += src_stride;
+   }
+}
+
+
 /*** PIPE_FORMAT_A1R5G5B5_UNORM ***/
 
 static void
@@ -1106,27 +1155,6 @@
 }
 
 
-static void
-fake_get_tile_rgba(const ushort *src,
-                   unsigned w, unsigned h,
-                   float *p,
-                   unsigned dst_stride)
-{
-   unsigned i, j;
-
-   for (i = 0; i < h; i++) {
-      float *pRow = p;
-      for (j = 0; j < w; j++, pRow += 4) {
-         pRow[0] =
-         pRow[1] =
-         pRow[2] =
-         pRow[3] = (i ^ j) & 1 ? 1.0f : 0.0f;
-      }
-      p += dst_stride;
-   }
-}
-
-
 void
 pipe_tile_raw_to_rgba(enum pipe_format format,
                       void *src,
@@ -1143,6 +1171,9 @@
    case PIPE_FORMAT_B8G8R8A8_UNORM:
       b8g8r8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
       break;
+   case PIPE_FORMAT_R8G8B8A8_UNORM:
+      r8g8b8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
+      break;
    case PIPE_FORMAT_A1R5G5B5_UNORM:
       a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
       break;
@@ -1206,8 +1237,10 @@
       ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, TRUE);
       break;
    default:
-      debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(format));
-      fake_get_tile_rgba(src, w, h, dst, dst_stride);
+      util_format_read_4f(format,
+                          dst, dst_stride * sizeof(float),
+                          src, util_format_get_stride(format, w),
+                          0, 0, w, h);
    }
 }
 
@@ -1219,21 +1252,22 @@
 {
    unsigned dst_stride = w * 4;
    void *packed;
+   enum pipe_format format = pt->texture->format;
 
    if (pipe_clip_tile(x, y, &w, &h, pt))
       return;
 
-   packed = MALLOC(pf_get_nblocks(&pt->block, w, h) * pt->block.size);
+   packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
 
    if (!packed)
       return;
 
-   if(pt->format == PIPE_FORMAT_YCBCR || pt->format == PIPE_FORMAT_YCBCR_REV)
+   if(format == PIPE_FORMAT_YCBCR || format == PIPE_FORMAT_YCBCR_REV)
       assert((x & 1) == 0);
 
    pipe_get_tile_raw(pt, x, y, w, h, packed, 0);
 
-   pipe_tile_raw_to_rgba(pt->format, packed, w, h, p, dst_stride);
+   pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride);
 
    FREE(packed);
 }
@@ -1246,16 +1280,17 @@
 {
    unsigned src_stride = w * 4;
    void *packed;
+   enum pipe_format format = pt->texture->format;
 
    if (pipe_clip_tile(x, y, &w, &h, pt))
       return;
 
-   packed = MALLOC(pf_get_nblocks(&pt->block, w, h) * pt->block.size);
+   packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
 
    if (!packed)
       return;
 
-   switch (pt->format) {
+   switch (format) {
    case PIPE_FORMAT_A8R8G8B8_UNORM:
       a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
       break;
@@ -1265,6 +1300,9 @@
    case PIPE_FORMAT_B8G8R8A8_UNORM:
       b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
       break;
+   case PIPE_FORMAT_R8G8B8A8_UNORM:
+      r8g8b8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
+      break;
    case PIPE_FORMAT_A1R5G5B5_UNORM:
       a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
       break;
@@ -1274,9 +1312,6 @@
    case PIPE_FORMAT_R8G8B8_UNORM:
       r8g8b8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
       break;
-   case PIPE_FORMAT_R8G8B8A8_UNORM:
-      assert(0);
-      break;
    case PIPE_FORMAT_A4R4G4B4_UNORM:
       a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
       break;
@@ -1322,7 +1357,7 @@
       /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
       break;
    default:
-      debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(pt->format));
+      debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(format));
    }
 
    pipe_put_tile_raw(pt, x, y, w, h, packed, 0);
@@ -1344,6 +1379,7 @@
    ubyte *map;
    uint *pDest = z;
    uint i, j;
+   enum pipe_format format = pt->texture->format;
 
    if (pipe_clip_tile(x, y, &w, &h, pt))
       return;
@@ -1354,7 +1390,7 @@
       return;
    }
 
-   switch (pt->format) {
+   switch (format) {
    case PIPE_FORMAT_Z32_UNORM:
       {
          const uint *ptrc
@@ -1428,6 +1464,7 @@
    const uint *ptrc = zSrc;
    ubyte *map;
    uint i, j;
+   enum pipe_format format = pt->texture->format;
 
    if (pipe_clip_tile(x, y, &w, &h, pt))
       return;
@@ -1438,7 +1475,7 @@
       return;
    }
 
-   switch (pt->format) {
+   switch (format) {
    case PIPE_FORMAT_Z32_UNORM:
       {
          uint *pDest = (uint *) (map + y * pt->stride + x*4);
diff --git a/src/gallium/auxiliary/util/u_upload_mgr.h b/src/gallium/auxiliary/util/u_upload_mgr.h
index 745b583..e158bed 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.h
+++ b/src/gallium/auxiliary/util/u_upload_mgr.h
@@ -32,6 +32,8 @@
 #ifndef U_UPLOAD_MGR_H
 #define U_UPLOAD_MGR_H
 
+#include "pipe/p_defines.h"
+
 struct pipe_screen;
 struct pipe_buffer;
 struct u_upload_mgr;
diff --git a/src/gallium/auxiliary/vl/Makefile b/src/gallium/auxiliary/vl/Makefile
deleted file mode 100644
index 4314c1e..0000000
--- a/src/gallium/auxiliary/vl/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = vl
-
-C_SOURCES = \
-	vl_bitstream_parser.c \
-	vl_mpeg12_mc_renderer.c \
-	vl_compositor.c \
-        vl_csc.c \
-	vl_shader_build.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/vl/SConscript b/src/gallium/auxiliary/vl/SConscript
deleted file mode 100644
index aed69f5..0000000
--- a/src/gallium/auxiliary/vl/SConscript
+++ /dev/null
@@ -1,13 +0,0 @@
-Import('*')
-
-vl = env.ConvenienceLibrary(
-	target = 'vl',
-	source = [
-		'vl_bitstream_parser.c',
-		'vl_mpeg12_mc_renderer.c',
-		'vl_compositor.c',
-                'vl_csc.c',
-		'vl_shader_build.c',
-	])
-
-auxiliaries.insert(0, vl)
diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c
index cda6dc1..fc2a1c5 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.c
+++ b/src/gallium/auxiliary/vl/vl_compositor.c
@@ -95,12 +95,11 @@
    assert(c);
 
    tokens = (struct tgsi_token*)MALLOC(max_tokens * sizeof(struct tgsi_token));
-   *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
-   header = (struct tgsi_header*)&tokens[1];
+   header = (struct tgsi_header*)&tokens[0];
    *header = tgsi_build_header();
-   *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
+   *(struct tgsi_processor*)&tokens[1] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
 
-   ti = 3;
+   ti = 2;
 
    /*
     * decl i0             ; Vertex pos
@@ -172,12 +171,11 @@
    assert(c);
 
    tokens = (struct tgsi_token*)MALLOC(max_tokens * sizeof(struct tgsi_token));
-   *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
-   header = (struct tgsi_header*)&tokens[1];
+   header = (struct tgsi_header*)&tokens[0];
    *header = tgsi_build_header();
-   *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
+   *(struct tgsi_processor*)&tokens[1] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
 
-   ti = 3;
+   ti = 2;
 
    /* decl i0             ; Texcoords for s0 */
    decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, 0, 0, TGSI_INTERPOLATE_LINEAR);
@@ -213,7 +211,7 @@
     */
    for (i = 0; i < 4; ++i) {
       inst = vl_inst3(TGSI_OPCODE_DP4, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, i);
-      inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i;
+      inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_X << i;
       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
    }
 
@@ -455,8 +453,8 @@
    assert(dst_area);
    assert(picture_type == PIPE_MPEG12_PICTURE_TYPE_FRAME);
 
-   compositor->fb_state.width = dst_surface->width[0];
-   compositor->fb_state.height = dst_surface->height[0];
+   compositor->fb_state.width = dst_surface->width0;
+   compositor->fb_state.height = dst_surface->height0;
    compositor->fb_state.cbufs[0] = compositor->pipe->screen->get_tex_surface
    (
       compositor->pipe->screen,
@@ -479,8 +477,8 @@
    compositor->pipe->set_framebuffer_state(compositor->pipe, &compositor->fb_state);
    compositor->pipe->set_viewport_state(compositor->pipe, &compositor->viewport);
    compositor->pipe->set_scissor_state(compositor->pipe, &compositor->scissor);
-   compositor->pipe->bind_sampler_states(compositor->pipe, 1, &compositor->sampler);
-   compositor->pipe->set_sampler_textures(compositor->pipe, 1, &src_surface);
+   compositor->pipe->bind_fragment_sampler_states(compositor->pipe, 1, &compositor->sampler);
+   compositor->pipe->set_fragment_sampler_textures(compositor->pipe, 1, &src_surface);
    compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader);
    compositor->pipe->bind_fs_state(compositor->pipe, compositor->fragment_shader);
    compositor->pipe->set_vertex_buffers(compositor->pipe, 2, compositor->vertex_bufs);
@@ -504,12 +502,12 @@
    vs_consts->dst_trans.z = 0;
    vs_consts->dst_trans.w = 0;
 
-   vs_consts->src_scale.x = src_area->w / (float)src_surface->width[0];
-   vs_consts->src_scale.y = src_area->h / (float)src_surface->height[0];
+   vs_consts->src_scale.x = src_area->w / (float)src_surface->width0;
+   vs_consts->src_scale.y = src_area->h / (float)src_surface->height0;
    vs_consts->src_scale.z = 1;
    vs_consts->src_scale.w = 1;
-   vs_consts->src_trans.x = src_area->x / (float)src_surface->width[0];
-   vs_consts->src_trans.y = src_area->y / (float)src_surface->height[0];
+   vs_consts->src_trans.x = src_area->x / (float)src_surface->width0;
+   vs_consts->src_trans.y = src_area->y / (float)src_surface->height0;
    vs_consts->src_trans.z = 0;
    vs_consts->src_trans.w = 0;
 
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
index c4ba698..caf581a 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
@@ -29,6 +29,7 @@
 #include <assert.h>
 #include <pipe/p_context.h>
 #include <pipe/p_inlines.h>
+#include <util/u_format.h>
 #include <util/u_math.h>
 #include <util/u_memory.h>
 #include <tgsi/tgsi_parse.h>
@@ -115,12 +116,11 @@
    assert(r);
 
    tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token));
-   *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
-   header = (struct tgsi_header *) &tokens[1];
+   header = (struct tgsi_header *) &tokens[0];
    *header = tgsi_build_header();
-   *(struct tgsi_processor *) &tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
+   *(struct tgsi_processor *) &tokens[1] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
 
-   ti = 3;
+   ti = 2;
 
    /*
     * decl i0              ; Vertex pos
@@ -185,12 +185,11 @@
    assert(r);
 
    tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token));
-   *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
-   header = (struct tgsi_header *) &tokens[1];
+   header = (struct tgsi_header *) &tokens[0];
    *header = tgsi_build_header();
-   *(struct tgsi_processor *) &tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
+   *(struct tgsi_processor *) &tokens[1] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
 
-   ti = 3;
+   ti = 2;
 
    /*
     * decl i0                      ; Luma texcoords
@@ -237,10 +236,10 @@
       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
       inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
-      inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-      inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-      inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
-      inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i;
+      inst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_X;
+      inst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X;
+      inst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_X;
+      inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_X << i;
       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
    }
 
@@ -278,12 +277,11 @@
    assert(r);
 
    tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token));
-   *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
-   header = (struct tgsi_header *) &tokens[1];
+   header = (struct tgsi_header *) &tokens[0];
    *header = tgsi_build_header();
-   *(struct tgsi_processor *) &tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
+   *(struct tgsi_processor *) &tokens[1] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
 
-   ti = 3;
+   ti = 2;
 
    /*
     * decl i0              ; Vertex pos
@@ -336,11 +334,13 @@
    free(tokens);
 }
 
+#if 0
 static void
 create_field_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
 {
    assert(false);
 }
+#endif
 
 static void
 create_frame_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
@@ -361,12 +361,11 @@
    assert(r);
 
    tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token));
-   *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
-   header = (struct tgsi_header *) &tokens[1];
+   header = (struct tgsi_header *) &tokens[0];
    *header = tgsi_build_header();
-   *(struct tgsi_processor *) &tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
+   *(struct tgsi_processor *) &tokens[1] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
 
-   ti = 3;
+   ti = 2;
 
    /*
     * decl i0                      ; Luma texcoords
@@ -415,10 +414,10 @@
       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
       inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
-      inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-      inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-      inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
-      inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i;
+      inst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_X;
+      inst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X;
+      inst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_X;
+      inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_X << i;
       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
    }
 
@@ -445,11 +444,13 @@
    free(tokens);
 }
 
+#if 0
 static void
 create_field_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
 {
    assert(false);
 }
+#endif
 
 static void
 create_frame_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
@@ -470,12 +471,11 @@
    assert(r);
 
    tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token));
-   *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
-   header = (struct tgsi_header *) &tokens[1];
+   header = (struct tgsi_header *) &tokens[0];
    *header = tgsi_build_header();
-   *(struct tgsi_processor *) &tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
+   *(struct tgsi_processor *) &tokens[1] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
 
-   ti = 3;
+   ti = 2;
 
    /*
     * decl i0              ; Vertex pos
@@ -536,11 +536,13 @@
    free(tokens);
 }
 
+#if 0
 static void
 create_field_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
 {
    assert(false);
 }
+#endif
 
 static void
 create_frame_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
@@ -561,12 +563,11 @@
    assert(r);
 
    tokens = (struct tgsi_token *) malloc(max_tokens * sizeof(struct tgsi_token));
-   *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
-   header = (struct tgsi_header *) &tokens[1];
+   header = (struct tgsi_header *) &tokens[0];
    *header = tgsi_build_header();
-   *(struct tgsi_processor *) &tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
+   *(struct tgsi_processor *) &tokens[1] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
 
-   ti = 3;
+   ti = 2;
 
    /*
     * decl i0                      ; Luma texcoords
@@ -620,10 +621,10 @@
       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
       inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
-      inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-      inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-      inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
-      inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i;
+      inst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_X;
+      inst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X;
+      inst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_X;
+      inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_X << i;
       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
    }
 
@@ -642,10 +643,10 @@
 
    /* lerp t1, c1.x, t1, t2        ; Blend past and future texels */
    inst = vl_inst4(TGSI_OPCODE_LRP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
-   inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-   inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-   inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
-   inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X;
+   inst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_X;
+   inst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X;
+   inst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_X;
+   inst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_X;
    ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
    /* add o0, t0, t1               ; Add past/future ref and differential to form final output */
@@ -663,11 +664,13 @@
    free(tokens);
 }
 
+#if 0
 static void
 create_field_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
 {
    assert(false);
 }
+#endif
 
 static void
 xfer_buffers_map(struct vl_mpeg12_mc_renderer *r)
@@ -681,7 +684,7 @@
       (
          r->pipe->screen, r->textures.all[i],
          0, 0, 0, PIPE_TRANSFER_WRITE, 0, 0,
-         r->textures.all[i]->width[0], r->textures.all[i]->height[0]
+         r->textures.all[i]->width0, r->textures.all[i]->height0
       );
 
       r->texels[i] = r->pipe->screen->transfer_map(r->pipe->screen, r->tex_transfer[i]);
@@ -835,26 +838,25 @@
    /* TODO: Accomodate HW that can't do this and also for cases when this isn't precise enough */
    template.format = PIPE_FORMAT_R16_SNORM;
    template.last_level = 0;
-   template.width[0] = r->pot_buffers ?
+   template.width0 = r->pot_buffers ?
       util_next_power_of_two(r->picture_width) : r->picture_width;
-   template.height[0] = r->pot_buffers ?
+   template.height0 = r->pot_buffers ?
       util_next_power_of_two(r->picture_height) : r->picture_height;
-   template.depth[0] = 1;
-   pf_get_block(template.format, &template.block);
+   template.depth0 = 1;
    template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_DYNAMIC;
 
    r->textures.individual.y = r->pipe->screen->texture_create(r->pipe->screen, &template);
 
    if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
-      template.width[0] = r->pot_buffers ?
+      template.width0 = r->pot_buffers ?
          util_next_power_of_two(r->picture_width / 2) :
          r->picture_width / 2;
-      template.height[0] = r->pot_buffers ?
+      template.height0 = r->pot_buffers ?
          util_next_power_of_two(r->picture_height / 2) :
          r->picture_height / 2;
    }
    else if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422)
-      template.height[0] = r->pot_buffers ?
+      template.height0 = r->pot_buffers ?
          util_next_power_of_two(r->picture_height / 2) :
          r->picture_height / 2;
 
@@ -1087,6 +1089,9 @@
    assert(ycbcr_vb);
    assert(pos < r->macroblocks_per_batch);
 
+   mo_vec[1].x = 0;
+   mo_vec[1].y = 0;
+
    switch (mb->mb_type) {
       case PIPE_MPEG12_MACROBLOCK_TYPE_BI:
       {
@@ -1283,8 +1288,8 @@
       PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
    );
 
-   vs_consts->denorm.x = r->surface->width[0];
-   vs_consts->denorm.y = r->surface->height[0];
+   vs_consts->denorm.x = r->surface->width0;
+   vs_consts->denorm.y = r->surface->height0;
 
    pipe_buffer_unmap(r->pipe->screen, r->vs_const_buf.buffer);
 
@@ -1296,8 +1301,8 @@
    if (num_macroblocks[MACROBLOCK_TYPE_INTRA] > 0) {
       r->pipe->set_vertex_buffers(r->pipe, 1, r->vertex_bufs.all);
       r->pipe->set_vertex_elements(r->pipe, 4, r->vertex_elems);
-      r->pipe->set_sampler_textures(r->pipe, 3, r->textures.all);
-      r->pipe->bind_sampler_states(r->pipe, 3, r->samplers.all);
+      r->pipe->set_fragment_sampler_textures(r->pipe, 3, r->textures.all);
+      r->pipe->bind_fragment_sampler_states(r->pipe, 3, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->i_vs);
       r->pipe->bind_fs_state(r->pipe, r->i_fs);
 
@@ -1310,8 +1315,8 @@
       r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
       r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems);
       r->textures.individual.ref[0] = r->past;
-      r->pipe->set_sampler_textures(r->pipe, 4, r->textures.all);
-      r->pipe->bind_sampler_states(r->pipe, 4, r->samplers.all);
+      r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
+      r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->p_vs[0]);
       r->pipe->bind_fs_state(r->pipe, r->p_fs[0]);
 
@@ -1324,8 +1329,8 @@
       r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
       r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems);
       r->textures.individual.ref[0] = r->past;
-      r->pipe->set_sampler_textures(r->pipe, 4, r->textures.all);
-      r->pipe->bind_sampler_states(r->pipe, 4, r->samplers.all);
+      r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
+      r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->p_vs[1]);
       r->pipe->bind_fs_state(r->pipe, r->p_fs[1]);
 
@@ -1338,8 +1343,8 @@
       r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
       r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems);
       r->textures.individual.ref[0] = r->future;
-      r->pipe->set_sampler_textures(r->pipe, 4, r->textures.all);
-      r->pipe->bind_sampler_states(r->pipe, 4, r->samplers.all);
+      r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
+      r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->p_vs[0]);
       r->pipe->bind_fs_state(r->pipe, r->p_fs[0]);
 
@@ -1352,8 +1357,8 @@
       r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
       r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems);
       r->textures.individual.ref[0] = r->future;
-      r->pipe->set_sampler_textures(r->pipe, 4, r->textures.all);
-      r->pipe->bind_sampler_states(r->pipe, 4, r->samplers.all);
+      r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
+      r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->p_vs[1]);
       r->pipe->bind_fs_state(r->pipe, r->p_fs[1]);
 
@@ -1367,8 +1372,8 @@
       r->pipe->set_vertex_elements(r->pipe, 8, r->vertex_elems);
       r->textures.individual.ref[0] = r->past;
       r->textures.individual.ref[1] = r->future;
-      r->pipe->set_sampler_textures(r->pipe, 5, r->textures.all);
-      r->pipe->bind_sampler_states(r->pipe, 5, r->samplers.all);
+      r->pipe->set_fragment_sampler_textures(r->pipe, 5, r->textures.all);
+      r->pipe->bind_fragment_sampler_states(r->pipe, 5, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->b_vs[0]);
       r->pipe->bind_fs_state(r->pipe, r->b_fs[0]);
 
@@ -1382,8 +1387,8 @@
       r->pipe->set_vertex_elements(r->pipe, 8, r->vertex_elems);
       r->textures.individual.ref[0] = r->past;
       r->textures.individual.ref[1] = r->future;
-      r->pipe->set_sampler_textures(r->pipe, 5, r->textures.all);
-      r->pipe->bind_sampler_states(r->pipe, 5, r->samplers.all);
+      r->pipe->set_fragment_sampler_textures(r->pipe, 5, r->textures.all);
+      r->pipe->bind_fragment_sampler_states(r->pipe, 5, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->b_vs[1]);
       r->pipe->bind_fs_state(r->pipe, r->b_fs[1]);
 
@@ -1450,7 +1455,7 @@
    assert(r);
    assert(blocks);
 
-   tex_pitch = r->tex_transfer[0]->stride / r->tex_transfer[0]->block.size;
+   tex_pitch = r->tex_transfer[0]->stride / util_format_get_blocksize(r->tex_transfer[0]->texture->format);
    texels = r->texels[0] + mbpy * tex_pitch + mbpx;
 
    for (y = 0; y < 2; ++y) {
@@ -1489,7 +1494,7 @@
    mbpy /= 2;
 
    for (tb = 0; tb < 2; ++tb) {
-      tex_pitch = r->tex_transfer[tb + 1]->stride / r->tex_transfer[tb + 1]->block.size;
+      tex_pitch = r->tex_transfer[tb + 1]->stride / util_format_get_blocksize(r->tex_transfer[tb + 1]->texture->format);
       texels = r->texels[tb + 1] + mbpy * tex_pitch + mbpx;
 
       if ((cbp >> (1 - tb)) & 1) {
@@ -1633,8 +1638,8 @@
       renderer->past = past;
       renderer->future = future;
       renderer->fence = fence;
-      renderer->surface_tex_inv_size.x = 1.0f / surface->width[0];
-      renderer->surface_tex_inv_size.y = 1.0f / surface->height[0];
+      renderer->surface_tex_inv_size.x = 1.0f / surface->width0;
+      renderer->surface_tex_inv_size.y = 1.0f / surface->height0;
    }
 
    while (num_macroblocks) {
diff --git a/src/gallium/auxiliary/vl/vl_shader_build.c b/src/gallium/auxiliary/vl/vl_shader_build.c
index faa20a9..d011ef9 100644
--- a/src/gallium/auxiliary/vl/vl_shader_build.c
+++ b/src/gallium/auxiliary/vl/vl_shader_build.c
@@ -36,10 +36,10 @@
 
    decl.Declaration.File = TGSI_FILE_INPUT;
    decl.Declaration.Semantic = 1;
-   decl.Semantic.SemanticName = name;
-   decl.Semantic.SemanticIndex = index;
-   decl.DeclarationRange.First = first;
-   decl.DeclarationRange.Last = last;
+   decl.Semantic.Name = name;
+   decl.Semantic.Index = index;
+   decl.Range.First = first;
+   decl.Range.Last = last;
 
    return decl;
 }
@@ -64,11 +64,11 @@
 
    decl.Declaration.File = TGSI_FILE_INPUT;
    decl.Declaration.Semantic = 1;
-   decl.Semantic.SemanticName = name;
-   decl.Semantic.SemanticIndex = index;
+   decl.Semantic.Name = name;
+   decl.Semantic.Index = index;
    decl.Declaration.Interpolate = interpolation;;
-   decl.DeclarationRange.First = first;
-   decl.DeclarationRange.Last = last;
+   decl.Range.First = first;
+   decl.Range.Last = last;
 
    return decl;
 }
@@ -79,10 +79,10 @@
 
    decl.Declaration.File = TGSI_FILE_CONSTANT;
    decl.Declaration.Semantic = 1;
-   decl.Semantic.SemanticName = name;
-   decl.Semantic.SemanticIndex = index;
-   decl.DeclarationRange.First = first;
-   decl.DeclarationRange.Last = last;
+   decl.Semantic.Name = name;
+   decl.Semantic.Index = index;
+   decl.Range.First = first;
+   decl.Range.Last = last;
 
    return decl;
 }
@@ -93,10 +93,10 @@
 
    decl.Declaration.File = TGSI_FILE_OUTPUT;
    decl.Declaration.Semantic = 1;
-   decl.Semantic.SemanticName = name;
-   decl.Semantic.SemanticIndex = index;
-   decl.DeclarationRange.First = first;
-   decl.DeclarationRange.Last = last;
+   decl.Semantic.Name = name;
+   decl.Semantic.Index = index;
+   decl.Range.First = first;
+   decl.Range.Last = last;
 
    return decl;
 }
@@ -107,8 +107,8 @@
 
    decl = tgsi_default_full_declaration();
    decl.Declaration.File = TGSI_FILE_TEMPORARY;
-   decl.DeclarationRange.First = first;
-   decl.DeclarationRange.Last = last;
+   decl.Range.First = first;
+   decl.Range.Last = last;
 
    return decl;
 }
@@ -119,8 +119,8 @@
 
    decl = tgsi_default_full_declaration();
    decl.Declaration.File = TGSI_FILE_SAMPLER;
-   decl.DeclarationRange.First = first;
-   decl.DeclarationRange.Last = last;
+   decl.Range.First = first;
+   decl.Range.Last = last;
 
    return decl;
 }
@@ -138,11 +138,11 @@
 
    inst.Instruction.Opcode = opcode;
    inst.Instruction.NumDstRegs = 1;
-   inst.FullDstRegisters[0].DstRegister.File = dst_file;
-   inst.FullDstRegisters[0].DstRegister.Index = dst_index;
+   inst.Dst[0].Register.File = dst_file;
+   inst.Dst[0].Register.Index = dst_index;
    inst.Instruction.NumSrcRegs = 1;
-   inst.FullSrcRegisters[0].SrcRegister.File = src_file;
-   inst.FullSrcRegisters[0].SrcRegister.Index = src_index;
+   inst.Src[0].Register.File = src_file;
+   inst.Src[0].Register.Index = src_index;
 
    return inst;
 }
@@ -162,13 +162,13 @@
 
    inst.Instruction.Opcode = opcode;
    inst.Instruction.NumDstRegs = 1;
-   inst.FullDstRegisters[0].DstRegister.File = dst_file;
-   inst.FullDstRegisters[0].DstRegister.Index = dst_index;
+   inst.Dst[0].Register.File = dst_file;
+   inst.Dst[0].Register.Index = dst_index;
    inst.Instruction.NumSrcRegs = 2;
-   inst.FullSrcRegisters[0].SrcRegister.File = src1_file;
-   inst.FullSrcRegisters[0].SrcRegister.Index = src1_index;
-   inst.FullSrcRegisters[1].SrcRegister.File = src2_file;
-   inst.FullSrcRegisters[1].SrcRegister.Index = src2_index;
+   inst.Src[0].Register.File = src1_file;
+   inst.Src[0].Register.Index = src1_index;
+   inst.Src[1].Register.File = src2_file;
+   inst.Src[1].Register.Index = src2_index;
 
    return inst;
 }
@@ -188,14 +188,15 @@
 
    inst.Instruction.Opcode = TGSI_OPCODE_TEX;
    inst.Instruction.NumDstRegs = 1;
-   inst.FullDstRegisters[0].DstRegister.File = dst_file;
-   inst.FullDstRegisters[0].DstRegister.Index = dst_index;
+   inst.Dst[0].Register.File = dst_file;
+   inst.Dst[0].Register.Index = dst_index;
    inst.Instruction.NumSrcRegs = 2;
-   inst.InstructionExtTexture.Texture = tex;
-   inst.FullSrcRegisters[0].SrcRegister.File = src1_file;
-   inst.FullSrcRegisters[0].SrcRegister.Index = src1_index;
-   inst.FullSrcRegisters[1].SrcRegister.File = src2_file;
-   inst.FullSrcRegisters[1].SrcRegister.Index = src2_index;
+   inst.Instruction.Texture = 1;
+   inst.Texture.Texture = tex;
+   inst.Src[0].Register.File = src1_file;
+   inst.Src[0].Register.Index = src1_index;
+   inst.Src[1].Register.File = src2_file;
+   inst.Src[1].Register.Index = src2_index;
 
    return inst;
 }
@@ -217,15 +218,15 @@
 
    inst.Instruction.Opcode = opcode;
    inst.Instruction.NumDstRegs = 1;
-   inst.FullDstRegisters[0].DstRegister.File = dst_file;
-   inst.FullDstRegisters[0].DstRegister.Index = dst_index;
+   inst.Dst[0].Register.File = dst_file;
+   inst.Dst[0].Register.Index = dst_index;
    inst.Instruction.NumSrcRegs = 3;
-   inst.FullSrcRegisters[0].SrcRegister.File = src1_file;
-   inst.FullSrcRegisters[0].SrcRegister.Index = src1_index;
-   inst.FullSrcRegisters[1].SrcRegister.File = src2_file;
-   inst.FullSrcRegisters[1].SrcRegister.Index = src2_index;
-   inst.FullSrcRegisters[2].SrcRegister.File = src3_file;
-   inst.FullSrcRegisters[2].SrcRegister.Index = src3_index;
+   inst.Src[0].Register.File = src1_file;
+   inst.Src[0].Register.Index = src1_index;
+   inst.Src[1].Register.File = src2_file;
+   inst.Src[1].Register.Index = src2_index;
+   inst.Src[2].Register.File = src3_file;
+   inst.Src[2].Register.Index = src3_index;
 
    return inst;
 }
diff --git a/src/gallium/docs/Makefile b/src/gallium/docs/Makefile
new file mode 100644
index 0000000..d4a5be4
--- /dev/null
+++ b/src/gallium/docs/Makefile
@@ -0,0 +1,89 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+
+.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html      to make standalone HTML files"
+	@echo "  dirhtml   to make HTML files named index.html in directories"
+	@echo "  pickle    to make pickle files"
+	@echo "  json      to make JSON files"
+	@echo "  htmlhelp  to make HTML files and a HTML help project"
+	@echo "  qthelp    to make HTML files and a qthelp project"
+	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  changes   to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck to check all external links for integrity"
+	@echo "  doctest   to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Gallium.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Gallium.qhc"
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+	      "run these through (pdf)latex."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/src/gallium/docs/make.bat b/src/gallium/docs/make.bat
new file mode 100644
index 0000000..6f97e07
--- /dev/null
+++ b/src/gallium/docs/make.bat
@@ -0,0 +1,113 @@
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+set SPHINXBUILD=sphinx-build
+set BUILDDIR=build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
+if NOT "%PAPER%" == "" (
+	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+	:help
+	echo.Please use `make ^<target^>` where ^<target^> is one of
+	echo.  html      to make standalone HTML files
+	echo.  dirhtml   to make HTML files named index.html in directories
+	echo.  pickle    to make pickle files
+	echo.  json      to make JSON files
+	echo.  htmlhelp  to make HTML files and a HTML help project
+	echo.  qthelp    to make HTML files and a qthelp project
+	echo.  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+	echo.  changes   to make an overview over all changed/added/deprecated items
+	echo.  linkcheck to check all external links for integrity
+	echo.  doctest   to run all doctests embedded in the documentation if enabled
+	goto end
+)
+
+if "%1" == "clean" (
+	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+	del /q /s %BUILDDIR%\*
+	goto end
+)
+
+if "%1" == "html" (
+	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+	goto end
+)
+
+if "%1" == "dirhtml" (
+	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+	goto end
+)
+
+if "%1" == "pickle" (
+	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+	echo.
+	echo.Build finished; now you can process the pickle files.
+	goto end
+)
+
+if "%1" == "json" (
+	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+	echo.
+	echo.Build finished; now you can process the JSON files.
+	goto end
+)
+
+if "%1" == "htmlhelp" (
+	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+	echo.
+	echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+	goto end
+)
+
+if "%1" == "qthelp" (
+	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+	echo.
+	echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Gallium.qhcp
+	echo.To view the help file:
+	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Gallium.ghc
+	goto end
+)
+
+if "%1" == "latex" (
+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+	echo.
+	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+	goto end
+)
+
+if "%1" == "changes" (
+	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+	echo.
+	echo.The overview file is in %BUILDDIR%/changes.
+	goto end
+)
+
+if "%1" == "linkcheck" (
+	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+	echo.
+	echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+	goto end
+)
+
+if "%1" == "doctest" (
+	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+	echo.
+	echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+	goto end
+)
+
+:end
diff --git a/src/gallium/docs/source/conf.py b/src/gallium/docs/source/conf.py
new file mode 100644
index 0000000..9b0c86b
--- /dev/null
+++ b/src/gallium/docs/source/conf.py
@@ -0,0 +1,197 @@
+# -*- coding: utf-8 -*-
+#
+# Gallium documentation build configuration file, created by
+# sphinx-quickstart on Sun Dec 20 14:09:05 2009.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.append(os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.pngmath']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Gallium'
+copyright = u'2009, VMWare, X.org, Nouveau'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0.3'
+# The full version, including alpha/beta/rc tags.
+release = '0.3'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# List of directories, relative to source directory, that shouldn't be searched
+# for source files.
+exclude_trees = []
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# The language for highlighting source code.
+highlight_language = 'c'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  Major themes that come with
+# Sphinx are currently 'default' and 'sphinxdoc'.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'Galliumdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'Gallium.tex', u'Gallium Documentation',
+   u'VMWare, X.org, Nouveau', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True
diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst
new file mode 100644
index 0000000..21f5f91
--- /dev/null
+++ b/src/gallium/docs/source/context.rst
@@ -0,0 +1,128 @@
+Context
+=======
+
+The context object represents the purest, most directly accessible, abilities
+of the device's 3D rendering pipeline.
+
+Methods
+-------
+
+CSO State
+^^^^^^^^^
+
+All CSO state is created, bound, and destroyed, with triplets of methods that
+all follow a specific naming scheme. For example, ``create_blend_state``,
+``bind_blend_state``, and ``destroy_blend_state``.
+
+CSO objects handled by the context object:
+
+* :ref:`Blend`: ``*_blend_state``
+* :ref:`Sampler`: These are special; they can be bound to either vertex or
+  fragment samplers, and they are bound in groups.
+  ``bind_fragment_sampler_states``, ``bind_vertex_sampler_states``
+* :ref:`Rasterizer`: ``*_rasterizer_state``
+* :ref:`Depth, Stencil, & Alpha`: ``*_depth_stencil_alpha_state``
+* :ref:`Shader`: These have two sets of methods. ``*_fs_state`` is for
+  fragment shaders, and ``*_vs_state`` is for vertex shaders.
+
+
+Resource Binding State
+^^^^^^^^^^^^^^^^^^^^^^
+
+This state describes how resources in various flavours (textures,
+buffers, surfaces) are bound to the driver.
+
+
+* ``set_constant_buffer``
+* ``set_framebuffer_state``
+* ``set_fragment_sampler_textures``
+* ``set_vertex_sampler_textures``
+* ``set_vertex_buffers``
+
+
+Non-CSO State
+^^^^^^^^^^^^^
+
+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_edgeflags``
+* ``set_blend_color``
+* ``set_clip_state``
+* ``set_polygon_stipple``
+* ``set_scissor_state``
+* ``set_viewport_state``
+* ``set_vertex_elements``
+
+
+Clearing
+^^^^^^^^
+
+``clear`` initializes some or all of the surfaces currently bound to
+the framebuffer to particular RGBA, depth, or stencil values.
+
+Clear is one of the most difficult concepts to nail down to a single
+interface and it seems likely that we will want to add additional
+clear paths, for instance clearing surfaces not bound to the
+framebuffer, or read-modify-write clears such as depth-only or
+stencil-only clears of packed depth-stencil buffers.  
+
+
+Drawing
+^^^^^^^
+
+``draw_arrays``
+
+``draw_elements``
+
+``draw_range_elements``
+
+
+Queries
+^^^^^^^
+
+Queries gather some statistic from the 3D pipeline over one or more
+draws.  Queries may be nested, though no state tracker currently
+exercises this.  
+
+Queries can be created with ``create_query`` and deleted with
+``destroy_query``. To enable a query, use ``begin_query``, and when finished,
+use ``end_query`` to stop the query. Finally, ``get_query_result`` is used
+to retrieve the results.
+
+Flushing
+^^^^^^^^
+
+``flush``
+
+
+Resource Busy Queries
+^^^^^^^^^^^^^^^^^^^^^
+
+``is_texture_referenced``
+
+``is_buffer_referenced``
+
+
+
+Blitting
+^^^^^^^^
+
+These methods emulate classic blitter controls. They are not guaranteed to be
+available; if they are set to NULL, then they are not present.
+
+These methods operate directly on ``pipe_surface`` objects, and stand
+apart from any 3D state in the context.  Blitting functionality may be
+moved to a separate abstraction at some point in the future.
+
+``surface_fill`` performs a fill operation on a section of a surface.
+
+``surface_copy`` blits a region of a surface to a region of another surface,
+provided that both surfaces are the same format. The source and destination
+may be the same surface, and overlapping blits are permitted.
+
+The interfaces to these calls are likely to change to make it easier
+for a driver to batch multiple blits with the same source and
+destination.
+
diff --git a/src/gallium/docs/source/cso.rst b/src/gallium/docs/source/cso.rst
new file mode 100644
index 0000000..dab1ee5
--- /dev/null
+++ b/src/gallium/docs/source/cso.rst
@@ -0,0 +1,14 @@
+CSO
+===
+
+CSO, Constant State Objects, are a core part of Gallium's API.
+
+CSO work on the principle of reusable state; they are created by filling
+out a state object with the desired properties, then passing that object
+to a context. The context returns an opaque context-specific handle which
+can be bound at any time for the desired effect.
+
+.. toctree::
+   :glob:
+
+   cso/*
diff --git a/src/gallium/docs/source/cso/blend.rst b/src/gallium/docs/source/cso/blend.rst
new file mode 100644
index 0000000..fd9e4a1
--- /dev/null
+++ b/src/gallium/docs/source/cso/blend.rst
@@ -0,0 +1,14 @@
+.. _blend:
+
+Blend
+=====
+
+This state controls blending of the final fragments into the target rendering
+buffers.
+
+XXX it is unresolved what behavior should result if blend_enable is off.
+
+Members
+-------
+
+XXX undocumented members
diff --git a/src/gallium/docs/source/cso/dsa.rst b/src/gallium/docs/source/cso/dsa.rst
new file mode 100644
index 0000000..12abaa9
--- /dev/null
+++ b/src/gallium/docs/source/cso/dsa.rst
@@ -0,0 +1,58 @@
+.. _depth,stencil,&alpha:
+
+Depth, Stencil, & Alpha
+=======================
+
+These three states control the depth, stencil, and alpha tests, used to
+discard fragments that have passed through the fragment shader.
+
+Traditionally, these three tests have been clumped together in hardware, so
+they are all stored in one structure.
+
+During actual execution, the order of operations done on fragments is always:
+
+* Stencil
+* Depth
+* Alpha
+
+Depth Members
+-------------
+
+enabled
+    Whether the depth test is enabled.
+writemask
+    Whether the depth buffer receives depth writes.
+func
+    The depth test function. One of PIPE_FUNC.
+
+Stencil Members
+---------------
+
+XXX document valuemask, writemask
+
+enabled
+    Whether the stencil test is enabled. For the second stencil, whether the
+    two-sided stencil is enabled.
+func
+    The stencil test function. One of PIPE_FUNC.
+ref_value
+    Stencil test reference value; used for certain functions.
+fail_op
+    The operation to carry out if the stencil test fails. One of
+    PIPE_STENCIL_OP.
+zfail_op
+    The operation to carry out if the stencil test passes but the depth test
+    fails. One of PIPE_STENCIL_OP.
+zpass_op
+    The operation to carry out if the stencil test and depth test both pass.
+    One of PIPE_STENCIL_OP.
+
+Alpha Members
+-------------
+
+enabled
+    Whether the alpha test is enabled.
+func
+    The alpha test function. One of PIPE_FUNC.
+ref_value
+    Alpha test reference value; used for certain functions.
diff --git a/src/gallium/docs/source/cso/rasterizer.rst b/src/gallium/docs/source/cso/rasterizer.rst
new file mode 100644
index 0000000..4d8e170
--- /dev/null
+++ b/src/gallium/docs/source/cso/rasterizer.rst
@@ -0,0 +1,152 @@
+.. _rasterizer:
+
+Rasterizer
+==========
+
+The rasterizer state controls the rendering of points, lines and triangles.
+Attributes include polygon culling state, line width, line stipple,
+multisample state, scissoring and flat/smooth shading.
+
+
+Members
+-------
+
+flatshade
+    If set, the provoking vertex of each polygon is used to determine the
+    color of the entire polygon.  If not set, fragment colors will be
+    interpolated between the vertex colors.
+    Note that this is separate from the fragment shader input attributes
+    CONSTANT, LINEAR and PERSPECTIVE.  We need the flatshade state at
+    clipping time to determine how to set the color of new vertices.
+    Also note that the draw module can implement flat shading by copying
+    the provoking vertex color to all the other vertices in the primitive.
+
+flatshade_first
+    Whether the first vertex should be the provoking vertex, for most
+    primitives. If not set, the last vertex is the provoking vertex.
+
+light_twoside
+    If set, there are per-vertex back-facing colors.  The draw module
+    uses this state along with the front/back information to set the
+    final vertex colors prior to rasterization.
+
+front_winding
+    Indicates the window order of front-facing polygons, either
+    PIPE_WINDING_CW or PIPE_WINDING_CCW
+cull_mode
+    Indicates which polygons to cull, either PIPE_WINDING_NONE (cull no
+    polygons), PIPE_WINDING_CW (cull clockwise-winding polygons),
+    PIPE_WINDING_CCW (cull counter clockwise-winding polygons), or
+    PIPE_WINDING_BOTH (cull all polygons).
+
+fill_cw
+    Indicates how to fill clockwise polygons, either PIPE_POLYGON_MODE_FILL,
+    PIPE_POLYGON_MODE_LINE or PIPE_POLYGON_MODE_POINT.
+fill_ccw
+    Indicates how to fill counter clockwise polygons, either
+    PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE or PIPE_POLYGON_MODE_POINT.
+
+poly_stipple_enable
+    Whether polygon stippling is enabled.
+poly_smooth
+    Controls OpenGL-style polygon smoothing/antialiasing
+offset_cw
+    If set, clockwise polygons will have polygon offset factors applied
+offset_ccw
+    If set, counter clockwise polygons will have polygon offset factors applied
+offset_units
+    Specifies the polygon offset bias
+offset_scale
+    Specifies the polygon offset scale
+
+line_width
+    The width of lines.
+line_smooth
+    Whether lines should be smoothed. Line smoothing is simply anti-aliasing.
+line_stipple_enable
+    Whether line stippling is enabled.
+line_stipple_pattern
+    16-bit bitfield of on/off flags, used to pattern the line stipple.
+line_stipple_factor
+    When drawinga stippled line, each bit in the stipple pattern is
+    repeated N times, where N = line_stipple_factor + 1.
+line_last_pixel
+    Controls whether the last pixel in a line is drawn or not.  OpenGL
+    omits the last pixel to avoid double-drawing pixels at the ends of lines
+    when drawing connected lines.
+
+point_smooth
+    Whether points should be smoothed. Point smoothing turns rectangular
+    points into circles or ovals.
+point_size_per_vertex
+    Whether vertices have a point size element.
+point_size
+    The size of points, if not specified per-vertex.
+point_size_min
+    The minimum size of points.
+point_size_max
+    The maximum size of points.
+point_sprite
+    Whether points are drawn as sprites (textured quads)
+sprite_coord_mode
+    Specifies how the value for each shader output should be computed when
+    drawing sprites.  If PIPE_SPRITE_COORD_NONE, don't change the vertex
+    shader output.  Otherwise, the four vertices of the resulting quad will
+    be assigned texture coordinates.  For PIPE_SPRITE_COORD_LOWER_LEFT, the
+    lower left vertex will have coordinate (0,0,0,1).
+    For PIPE_SPRITE_COORD_UPPER_LEFT, the upper-left vertex will have
+    coordinate (0,0,0,1).
+    This state is needed by the 'draw' module because that's where each
+    point vertex is converted into four quad vertices.  There's no other
+    place to emit the new vertex texture coordinates which are required for
+    sprite rendering.
+    Note that when geometry shaders are available, this state could be
+    removed.  A special geometry shader defined by the state tracker could
+    converts the incoming points into quads with the proper texture coords.
+
+scissor
+    Whether the scissor test is enabled.
+
+multisample
+    Whether :ref:`MSAA` is enabled.
+
+bypass_vs_clip_and_viewport
+    Whether the entire TCL pipeline should be bypassed. This implies that
+    vertices are pre-transformed for the viewport, and will not be run
+    through the vertex shader. Note that implementations may still clip away
+    vertices that are not in the viewport.
+
+gl_rasterization_rules
+    Whether the rasterizer should use (0.5, 0.5) pixel centers. When not set,
+    the rasterizer will use (0, 0) for pixel centers.
+
+
+Notes
+-----
+
+flatshade
+^^^^^^^^^
+
+The actual interpolated shading algorithm is obviously
+implementation-dependent, but will usually be Gourard for most hardware.
+
+bypass_vs_clip_and_viewport
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When set, this implies that vertices are pre-transformed for the viewport, and
+will not be run through the vertex shader. Note that implementations may still
+clip away vertices that are not visible.
+
+flatshade_first
+^^^^^^^^^^^^^^^
+
+There are several important exceptions to the specification of this rule.
+
+* ``PIPE_PRIMITIVE_POLYGON``: The provoking vertex is always the first
+  vertex. If the caller wishes to change the provoking vertex, they merely
+  need to rotate the vertices themselves.
+* ``PIPE_PRIMITIVE_QUAD``, ``PIPE_PRIMITIVE_QUAD_STRIP``: This option has no
+  effect; the provoking vertex is always the last vertex.
+* ``PIPE_PRIMITIVE_TRIANGLE_FAN``: When set, the provoking vertex is the
+  second vertex, not the first. This permits each segment of the fan to have
+  a different color.
diff --git a/src/gallium/docs/source/cso/sampler.rst b/src/gallium/docs/source/cso/sampler.rst
new file mode 100644
index 0000000..e3f1757
--- /dev/null
+++ b/src/gallium/docs/source/cso/sampler.rst
@@ -0,0 +1,46 @@
+.. _sampler:
+
+Sampler
+=======
+
+Texture units have many options for selecting texels from loaded textures;
+this state controls an individual texture unit's texel-sampling settings.
+
+Texture coordinates are always treated as four-dimensional, and referred to
+with the traditional (S, T, R, Q) notation.
+
+Members
+-------
+
+XXX undocumented compare_mode, compare_func
+
+wrap_s
+    How to wrap the S coordinate. One of PIPE_TEX_WRAP.
+wrap_t
+    How to wrap the T coordinate. One of PIPE_TEX_WRAP.
+wrap_r
+    How to wrap the R coordinate. One of PIPE_TEX_WRAP.
+min_img_filter
+    The filter to use when minifying texels. One of PIPE_TEX_FILTER.
+min_mip_filter
+    The filter to use when minifying mipmapped textures. One of
+    PIPE_TEX_FILTER.
+mag_img_filter
+    The filter to use when magnifying texels. One of PIPE_TEX_FILTER.
+normalized_coords
+    Whether the texture coordinates are normalized. If normalized, they will
+    always be in [0, 1]. If not, they will be in the range of each dimension
+    of the loaded texture.
+prefilter
+    XXX From the Doxy, "weird sampling state exposed by some APIs." Refine.
+lod_bias
+    The bias to apply to the level of detail.
+min_lod
+    Minimum level of detail, used to clamp LoD after bias.
+max_lod
+    Maximum level of detail, used to clamp LoD after bias.
+border_color
+    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.
diff --git a/src/gallium/docs/source/cso/shader.rst b/src/gallium/docs/source/cso/shader.rst
new file mode 100644
index 0000000..0ee42c8
--- /dev/null
+++ b/src/gallium/docs/source/cso/shader.rst
@@ -0,0 +1,12 @@
+.. _shader:
+
+Shader
+======
+
+One of the two types of shaders supported by Gallium.
+
+Members
+-------
+
+tokens
+    A list of tgsi_tokens.
diff --git a/src/gallium/docs/source/distro.rst b/src/gallium/docs/source/distro.rst
new file mode 100644
index 0000000..33e846e
--- /dev/null
+++ b/src/gallium/docs/source/distro.rst
@@ -0,0 +1,141 @@
+Distribution
+============
+
+Along with the interface definitions, the following drivers, state trackers,
+and auxiliary modules are shipped in the standard Gallium distribution.
+
+Drivers
+-------
+
+Cell
+^^^^
+
+Failover
+^^^^^^^^
+
+Deprecated.
+
+Intel i915
+^^^^^^^^^^
+
+Intel i965
+^^^^^^^^^^
+
+Highly experimental.
+
+Identity
+^^^^^^^^
+
+Wrapper driver.
+
+LLVM Softpipe
+^^^^^^^^^^^^^
+
+nVidia nv04
+^^^^^^^^^^^
+
+Deprecated.
+
+nVidia nv10
+^^^^^^^^^^^
+
+Deprecated.
+
+nVidia nv20
+^^^^^^^^^^^
+
+Deprecated.
+
+nVidia nv30
+^^^^^^^^^^^
+
+nVidia nv40
+^^^^^^^^^^^
+
+nVidia nv50
+^^^^^^^^^^^
+
+VMWare SVGA
+^^^^^^^^^^^
+
+ATI r300
+^^^^^^^^
+
+AMD/ATI r600
+^^^^^^^^^^^^
+
+Highly experimental.
+
+Softpipe
+^^^^^^^^
+
+Reference software rasterizer.
+
+Trace
+^^^^^
+
+Wrapper driver.
+
+State Trackers
+--------------
+
+Direct Rendering Infrastructure
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+EGL
+^^^
+
+GLX
+^^^
+
+MesaGL
+^^^^^^
+
+Python
+^^^^^^
+
+OpenVG
+^^^^^^
+
+WGL
+^^^
+
+Xorg XFree86 DDX
+^^^^^^^^^^^^^^^^
+
+Auxiliary
+---------
+
+CSO Cache
+^^^^^^^^^
+
+Draw
+^^^^
+
+Gallivm
+^^^^^^^
+
+Indices
+^^^^^^^
+
+Pipe Buffer Manager
+^^^^^^^^^^^^^^^^^^^
+
+Remote Debugger
+^^^^^^^^^^^^^^^
+
+Runtime Assembly Emission
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Surface Context Tracker
+^^^^^^^^^^^^^^^^^^^^^^^
+
+TGSI
+^^^^
+
+Translate
+^^^^^^^^^
+
+Util
+^^^^
+
diff --git a/src/gallium/docs/source/glossary.rst b/src/gallium/docs/source/glossary.rst
new file mode 100644
index 0000000..6a9110c
--- /dev/null
+++ b/src/gallium/docs/source/glossary.rst
@@ -0,0 +1,10 @@
+Glossary
+========
+
+.. glossary::
+   :sorted:
+
+   MSAA
+      Multi-Sampled Anti-Aliasing. A basic anti-aliasing technique that takes
+      multiple samples of the depth buffer, and uses this information to
+      smooth the edges of polygons.
diff --git a/src/gallium/docs/source/index.rst b/src/gallium/docs/source/index.rst
new file mode 100644
index 0000000..54bc883
--- /dev/null
+++ b/src/gallium/docs/source/index.rst
@@ -0,0 +1,28 @@
+.. Gallium documentation master file, created by
+   sphinx-quickstart on Sun Dec 20 14:09:05 2009.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to Gallium's documentation!
+===================================
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   intro
+   tgsi
+   screen
+   context
+   cso
+   distro
+   glossary
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/src/gallium/docs/source/intro.rst b/src/gallium/docs/source/intro.rst
new file mode 100644
index 0000000..1ea1038
--- /dev/null
+++ b/src/gallium/docs/source/intro.rst
@@ -0,0 +1,9 @@
+Introduction
+============
+
+What is Gallium?
+----------------
+
+Gallium is essentially an API for writing graphics drivers in a largely
+device-agnostic fashion. It provides several objects which encapsulate the
+core services of graphics hardware in a straightforward manner.
diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst
new file mode 100644
index 0000000..9631e69
--- /dev/null
+++ b/src/gallium/docs/source/screen.rst
@@ -0,0 +1,39 @@
+Screen
+======
+
+A screen is an object representing the context-independent part of a device.
+
+Methods
+-------
+
+XXX moar; got bored
+
+get_name
+^^^^^^^^
+
+Returns an identifying name for the screen.
+
+get_vendor
+^^^^^^^^^^
+
+Returns the screen vendor.
+
+get_param
+^^^^^^^^^
+
+Get an integer/boolean screen parameter.
+
+get_paramf
+^^^^^^^^^^
+
+Get a floating-point screen parameter.
+
+is_format_supported
+^^^^^^^^^^^^^^^^^^^
+
+See if a format can be used in a specific manner.
+
+texture_create
+^^^^^^^^^^^^^^
+
+Given a template of texture setup, create a BO-backed texture.
diff --git a/src/gallium/docs/source/tgsi.rst b/src/gallium/docs/source/tgsi.rst
new file mode 100644
index 0000000..ebee490
--- /dev/null
+++ b/src/gallium/docs/source/tgsi.rst
@@ -0,0 +1,1270 @@
+TGSI
+====
+
+TGSI, Tungsten Graphics Shader Infrastructure, is an intermediate language
+for describing shaders. Since Gallium is inherently shaderful, shaders are
+an important part of the API. TGSI is the only intermediate representation
+used by all drivers.
+
+Instruction Set
+---------------
+
+From GL_NV_vertex_program
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+
+ARL - Address Register Load
+
+.. math::
+
+  dst.x = \lfloor src.x\rfloor
+
+  dst.y = \lfloor src.y\rfloor
+
+  dst.z = \lfloor src.z\rfloor
+
+  dst.w = \lfloor src.w\rfloor
+
+
+MOV - Move
+
+.. math::
+
+  dst.x = src.x
+
+  dst.y = src.y
+
+  dst.z = src.z
+
+  dst.w = src.w
+
+
+LIT - Light Coefficients
+
+.. math::
+
+  dst.x = 1
+
+  dst.y = max(src.x, 0)
+
+  dst.z = (src.x > 0) ? max(src.y, 0)^{clamp(src.w, -128, 128))} : 0
+
+  dst.w = 1
+
+
+RCP - Reciprocal
+
+.. math::
+
+  dst.x = \frac{1}{src.x}
+
+  dst.y = \frac{1}{src.x}
+
+  dst.z = \frac{1}{src.x}
+
+  dst.w = \frac{1}{src.x}
+
+
+RSQ - Reciprocal Square Root
+
+.. math::
+
+  dst.x = \frac{1}{\sqrt{|src.x|}}
+
+  dst.y = \frac{1}{\sqrt{|src.x|}}
+
+  dst.z = \frac{1}{\sqrt{|src.x|}}
+
+  dst.w = \frac{1}{\sqrt{|src.x|}}
+
+
+EXP - Approximate Exponential Base 2
+
+.. math::
+
+  dst.x = 2^{\lfloor src.x\rfloor}
+
+  dst.y = src.x - \lfloor src.x\rfloor
+
+  dst.z = 2^{src.x}
+
+  dst.w = 1
+
+
+LOG - Approximate Logarithm Base 2
+
+.. math::
+
+  dst.x = \lfloor\log_2{|src.x|}\rfloor
+
+  dst.y = \frac{|src.x|}{2^{\lfloor\log_2{|src.x|}\rfloor}}
+
+  dst.z = \log_2{|src.x|}
+
+  dst.w = 1
+
+
+MUL - Multiply
+
+.. math::
+
+  dst.x = src0.x \times src1.x
+
+  dst.y = src0.y \times src1.y
+
+  dst.z = src0.z \times src1.z
+
+  dst.w = src0.w \times src1.w
+
+
+ADD - Add
+
+.. math::
+
+  dst.x = src0.x + src1.x
+
+  dst.y = src0.y + src1.y
+
+  dst.z = src0.z + src1.z
+
+  dst.w = src0.w + src1.w
+
+
+DP3 - 3-component Dot Product
+
+.. math::
+
+  dst.x = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z
+
+  dst.y = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z
+
+  dst.z = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z
+
+  dst.w = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z
+
+
+DP4 - 4-component Dot Product
+
+.. math::
+
+  dst.x = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src0.w \times src1.w
+
+  dst.y = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src0.w \times src1.w
+
+  dst.z = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src0.w \times src1.w
+
+  dst.w = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src0.w \times src1.w
+
+
+DST - Distance Vector
+
+.. math::
+
+  dst.x = 1
+
+  dst.y = src0.y \times src1.y
+
+  dst.z = src0.z
+
+  dst.w = src1.w
+
+
+MIN - Minimum
+
+.. math::
+
+  dst.x = min(src0.x, src1.x)
+
+  dst.y = min(src0.y, src1.y)
+
+  dst.z = min(src0.z, src1.z)
+
+  dst.w = min(src0.w, src1.w)
+
+
+MAX - Maximum
+
+.. math::
+
+  dst.x = max(src0.x, src1.x)
+
+  dst.y = max(src0.y, src1.y)
+
+  dst.z = max(src0.z, src1.z)
+
+  dst.w = max(src0.w, src1.w)
+
+
+SLT - Set On Less Than
+
+.. math::
+
+  dst.x = (src0.x < src1.x) ? 1 : 0
+
+  dst.y = (src0.y < src1.y) ? 1 : 0
+
+  dst.z = (src0.z < src1.z) ? 1 : 0
+
+  dst.w = (src0.w < src1.w) ? 1 : 0
+
+
+SGE - Set On Greater Equal Than
+
+.. math::
+
+  dst.x = (src0.x >= src1.x) ? 1 : 0
+
+  dst.y = (src0.y >= src1.y) ? 1 : 0
+
+  dst.z = (src0.z >= src1.z) ? 1 : 0
+
+  dst.w = (src0.w >= src1.w) ? 1 : 0
+
+
+MAD - Multiply And Add
+
+.. math::
+
+  dst.x = src0.x \times src1.x + src2.x
+
+  dst.y = src0.y \times src1.y + src2.y
+
+  dst.z = src0.z \times src1.z + src2.z
+
+  dst.w = src0.w \times src1.w + src2.w
+
+
+SUB - Subtract
+
+.. math::
+
+  dst.x = src0.x - src1.x
+
+  dst.y = src0.y - src1.y
+
+  dst.z = src0.z - src1.z
+
+  dst.w = src0.w - src1.w
+
+
+LRP - Linear Interpolate
+
+.. math::
+
+  dst.x = src0.x \times src1.x + (1 - src0.x) \times src2.x
+
+  dst.y = src0.y \times src1.y + (1 - src0.y) \times src2.y
+
+  dst.z = src0.z \times src1.z + (1 - src0.z) \times src2.z
+
+  dst.w = src0.w \times src1.w + (1 - src0.w) \times src2.w
+
+
+CND - Condition
+
+.. math::
+
+  dst.x = (src2.x > 0.5) ? src0.x : src1.x
+
+  dst.y = (src2.y > 0.5) ? src0.y : src1.y
+
+  dst.z = (src2.z > 0.5) ? src0.z : src1.z
+
+  dst.w = (src2.w > 0.5) ? src0.w : src1.w
+
+
+DP2A - 2-component Dot Product And Add
+
+.. math::
+
+  dst.x = src0.x \times src1.x + src0.y \times src1.y + src2.x
+
+  dst.y = src0.x \times src1.x + src0.y \times src1.y + src2.x
+
+  dst.z = src0.x \times src1.x + src0.y \times src1.y + src2.x
+
+  dst.w = src0.x \times src1.x + src0.y \times src1.y + src2.x
+
+
+FRAC - Fraction
+
+.. math::
+
+  dst.x = src.x - \lfloor src.x\rfloor
+
+  dst.y = src.y - \lfloor src.y\rfloor
+
+  dst.z = src.z - \lfloor src.z\rfloor
+
+  dst.w = src.w - \lfloor src.w\rfloor
+
+
+CLAMP - Clamp
+
+.. math::
+
+  dst.x = clamp(src0.x, src1.x, src2.x)
+
+  dst.y = clamp(src0.y, src1.y, src2.y)
+
+  dst.z = clamp(src0.z, src1.z, src2.z)
+
+  dst.w = clamp(src0.w, src1.w, src2.w)
+
+
+FLR - Floor
+
+This is identical to ARL.
+
+.. math::
+
+  dst.x = \lfloor src.x\rfloor
+
+  dst.y = \lfloor src.y\rfloor
+
+  dst.z = \lfloor src.z\rfloor
+
+  dst.w = \lfloor src.w\rfloor
+
+
+ROUND - Round
+
+.. math::
+
+  dst.x = round(src.x)
+
+  dst.y = round(src.y)
+
+  dst.z = round(src.z)
+
+  dst.w = round(src.w)
+
+
+EX2 - Exponential Base 2
+
+.. math::
+
+  dst.x = 2^{src.x}
+
+  dst.y = 2^{src.x}
+
+  dst.z = 2^{src.x}
+
+  dst.w = 2^{src.x}
+
+
+LG2 - Logarithm Base 2
+
+.. math::
+
+  dst.x = \log_2{src.x}
+
+  dst.y = \log_2{src.x}
+
+  dst.z = \log_2{src.x}
+
+  dst.w = \log_2{src.x}
+
+
+POW - Power
+
+.. math::
+
+  dst.x = src0.x^{src1.x}
+
+  dst.y = src0.x^{src1.x}
+
+  dst.z = src0.x^{src1.x}
+
+  dst.w = src0.x^{src1.x}
+
+XPD - Cross Product
+
+.. math::
+
+  dst.x = src0.y \times src1.z - src1.y \times src0.z
+
+  dst.y = src0.z \times src1.x - src1.z \times src0.x
+
+  dst.z = src0.x \times src1.y - src1.x \times src0.y
+
+  dst.w = 1
+
+
+ABS - Absolute
+
+.. math::
+
+  dst.x = |src.x|
+
+  dst.y = |src.y|
+
+  dst.z = |src.z|
+
+  dst.w = |src.w|
+
+
+RCC - Reciprocal Clamped
+
+XXX cleanup on aisle three
+
+.. math::
+
+  dst.x = (1 / src.x) > 0 ? clamp(1 / src.x, 5.42101e-020, 1.884467e+019) : clamp(1 / src.x, -1.884467e+019, -5.42101e-020)
+
+  dst.y = (1 / src.x) > 0 ? clamp(1 / src.x, 5.42101e-020, 1.884467e+019) : clamp(1 / src.x, -1.884467e+019, -5.42101e-020)
+
+  dst.z = (1 / src.x) > 0 ? clamp(1 / src.x, 5.42101e-020, 1.884467e+019) : clamp(1 / src.x, -1.884467e+019, -5.42101e-020)
+
+  dst.w = (1 / src.x) > 0 ? clamp(1 / src.x, 5.42101e-020, 1.884467e+019) : clamp(1 / src.x, -1.884467e+019, -5.42101e-020)
+
+
+DPH - Homogeneous Dot Product
+
+.. math::
+
+  dst.x = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src1.w
+
+  dst.y = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src1.w
+
+  dst.z = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src1.w
+
+  dst.w = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src1.w
+
+
+COS - Cosine
+
+.. math::
+
+  dst.x = \cos{src.x}
+
+  dst.y = \cos{src.x}
+
+  dst.z = \cos{src.x}
+
+  dst.w = \cos{src.x}
+
+
+DDX - Derivative Relative To X
+
+.. math::
+
+  dst.x = partialx(src.x)
+
+  dst.y = partialx(src.y)
+
+  dst.z = partialx(src.z)
+
+  dst.w = partialx(src.w)
+
+
+DDY - Derivative Relative To Y
+
+.. math::
+
+  dst.x = partialy(src.x)
+
+  dst.y = partialy(src.y)
+
+  dst.z = partialy(src.z)
+
+  dst.w = partialy(src.w)
+
+
+KILP - Predicated Discard
+
+  discard
+
+
+PK2H - Pack Two 16-bit Floats
+
+  TBD
+
+
+PK2US - Pack Two Unsigned 16-bit Scalars
+
+  TBD
+
+
+PK4B - Pack Four Signed 8-bit Scalars
+
+  TBD
+
+
+PK4UB - Pack Four Unsigned 8-bit Scalars
+
+  TBD
+
+
+RFL - Reflection Vector
+
+.. math::
+
+  dst.x = 2 \times (src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z) / (src0.x \times src0.x + src0.y \times src0.y + src0.z \times src0.z) \times src0.x - src1.x
+
+  dst.y = 2 \times (src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z) / (src0.x \times src0.x + src0.y \times src0.y + src0.z \times src0.z) \times src0.y - src1.y
+
+  dst.z = 2 \times (src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z) / (src0.x \times src0.x + src0.y \times src0.y + src0.z \times src0.z) \times src0.z - src1.z
+
+  dst.w = 1
+
+Considered for removal.
+
+
+SEQ - Set On Equal
+
+.. math::
+
+  dst.x = (src0.x == src1.x) ? 1 : 0
+  dst.y = (src0.y == src1.y) ? 1 : 0
+  dst.z = (src0.z == src1.z) ? 1 : 0
+  dst.w = (src0.w == src1.w) ? 1 : 0
+
+
+SFL - Set On False
+
+.. math::
+
+  dst.x = 0
+  dst.y = 0
+  dst.z = 0
+  dst.w = 0
+
+Considered for removal.
+
+SGT - Set On Greater Than
+
+.. math::
+
+  dst.x = (src0.x > src1.x) ? 1 : 0
+  dst.y = (src0.y > src1.y) ? 1 : 0
+  dst.z = (src0.z > src1.z) ? 1 : 0
+  dst.w = (src0.w > src1.w) ? 1 : 0
+
+
+SIN - Sine
+
+.. math::
+
+  dst.x = \sin{src.x}
+
+  dst.y = \sin{src.x}
+
+  dst.z = \sin{src.x}
+
+  dst.w = \sin{src.x}
+
+
+SLE - Set On Less Equal Than
+
+.. math::
+
+  dst.x = (src0.x <= src1.x) ? 1 : 0
+  dst.y = (src0.y <= src1.y) ? 1 : 0
+  dst.z = (src0.z <= src1.z) ? 1 : 0
+  dst.w = (src0.w <= src1.w) ? 1 : 0
+
+
+SNE - Set On Not Equal
+
+.. math::
+
+  dst.x = (src0.x != src1.x) ? 1 : 0
+  dst.y = (src0.y != src1.y) ? 1 : 0
+  dst.z = (src0.z != src1.z) ? 1 : 0
+  dst.w = (src0.w != src1.w) ? 1 : 0
+
+
+STR - Set On True
+
+.. math::
+
+  dst.x = 1
+  dst.y = 1
+  dst.z = 1
+  dst.w = 1
+
+
+TEX - Texture Lookup
+
+  TBD
+
+
+TXD - Texture Lookup with Derivatives
+
+  TBD
+
+
+TXP - Projective Texture Lookup
+
+  TBD
+
+
+UP2H - Unpack Two 16-Bit Floats
+
+  TBD
+
+  Considered for removal.
+
+UP2US - Unpack Two Unsigned 16-Bit Scalars
+
+  TBD
+
+  Considered for removal.
+
+UP4B - Unpack Four Signed 8-Bit Values
+
+  TBD
+
+  Considered for removal.
+
+UP4UB - Unpack Four Unsigned 8-Bit Scalars
+
+  TBD
+
+  Considered for removal.
+
+X2D - 2D Coordinate Transformation
+
+.. math::
+
+  dst.x = src0.x + src1.x \times src2.x + src1.y \times src2.y
+  dst.y = src0.y + src1.x \times src2.z + src1.y \times src2.w
+  dst.z = src0.x + src1.x \times src2.x + src1.y \times src2.y
+  dst.w = src0.y + src1.x \times src2.z + src1.y \times src2.w
+
+Considered for removal.
+
+
+From GL_NV_vertex_program2
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+
+ARA - Address Register Add
+
+  TBD
+
+  Considered for removal.
+
+ARR - Address Register Load With Round
+
+.. math::
+
+  dst.x = round(src.x)
+
+  dst.y = round(src.y)
+
+  dst.z = round(src.z)
+
+  dst.w = round(src.w)
+
+
+BRA - Branch
+
+  pc = target
+
+  Considered for removal.
+
+CAL - Subroutine Call
+
+  push(pc)
+  pc = target
+
+
+RET - Subroutine Call Return
+
+  pc = pop()
+
+  Potential restrictions:  
+  * Only occurs at end of function.
+
+SSG - Set Sign
+
+.. math::
+
+  dst.x = (src.x > 0) ? 1 : (src.x < 0) ? -1 : 0
+
+  dst.y = (src.y > 0) ? 1 : (src.y < 0) ? -1 : 0
+
+  dst.z = (src.z > 0) ? 1 : (src.z < 0) ? -1 : 0
+
+  dst.w = (src.w > 0) ? 1 : (src.w < 0) ? -1 : 0
+
+
+CMP - Compare
+
+.. math::
+
+  dst.x = (src0.x < 0) ? src1.x : src2.x
+
+  dst.y = (src0.y < 0) ? src1.y : src2.y
+
+  dst.z = (src0.z < 0) ? src1.z : src2.z
+
+  dst.w = (src0.w < 0) ? src1.w : src2.w
+
+
+KIL - Conditional Discard
+
+.. math::
+
+  if (src.x < 0 || src.y < 0 || src.z < 0 || src.w < 0)
+    discard
+  endif
+
+
+SCS - Sine Cosine
+
+.. math::
+
+  dst.x = \cos{src.x}
+
+  dst.y = \sin{src.x}
+
+  dst.z = 0
+
+  dst.y = 1
+
+
+TXB - Texture Lookup With Bias
+
+  TBD
+
+
+NRM - 3-component Vector Normalise
+
+.. math::
+
+  dst.x = src.x / (src.x \times src.x + src.y \times src.y + src.z \times src.z)
+
+  dst.y = src.y / (src.x \times src.x + src.y \times src.y + src.z \times src.z)
+
+  dst.z = src.z / (src.x \times src.x + src.y \times src.y + src.z \times src.z)
+
+  dst.w = 1
+
+
+DIV - Divide
+
+.. math::
+
+  dst.x = \frac{src0.x}{src1.x}
+
+  dst.y = \frac{src0.y}{src1.y}
+
+  dst.z = \frac{src0.z}{src1.z}
+
+  dst.w = \frac{src0.w}{src1.w}
+
+
+DP2 - 2-component Dot Product
+
+.. math::
+
+  dst.x = src0.x \times src1.x + src0.y \times src1.y
+
+  dst.y = src0.x \times src1.x + src0.y \times src1.y
+
+  dst.z = src0.x \times src1.x + src0.y \times src1.y
+
+  dst.w = src0.x \times src1.x + src0.y \times src1.y
+
+
+TXL - Texture Lookup With LOD
+
+  TBD
+
+
+BRK - Break
+
+  TBD
+
+
+IF - If
+
+  TBD
+
+
+BGNFOR - Begin a For-Loop
+
+  dst.x = floor(src.x)
+  dst.y = floor(src.y)
+  dst.z = floor(src.z)
+
+  if (dst.y <= 0)
+    pc = [matching ENDFOR] + 1
+  endif
+
+  Note: The destination must be a loop register.
+        The source must be a constant register.
+
+  Considered for cleanup / removal.
+
+
+REP - Repeat
+
+  TBD
+
+
+ELSE - Else
+
+  TBD
+
+
+ENDIF - End If
+
+  TBD
+
+
+ENDFOR - End a For-Loop
+
+  dst.x = dst.x + dst.z
+  dst.y = dst.y - 1.0
+
+  if (dst.y > 0)
+    pc = [matching BGNFOR instruction] + 1
+  endif
+
+  Note: The destination must be a loop register.
+
+  Considered for cleanup / removal.
+
+ENDREP - End Repeat
+
+  TBD
+
+
+PUSHA - Push Address Register On Stack
+
+  push(src.x)
+  push(src.y)
+  push(src.z)
+  push(src.w)
+
+  Considered for cleanup / removal.
+
+POPA - Pop Address Register From Stack
+
+  dst.w = pop()
+  dst.z = pop()
+  dst.y = pop()
+  dst.x = pop()
+
+  Considered for cleanup / removal.
+
+
+From GL_NV_gpu_program4
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Support for these opcodes indicated by a special pipe capability bit (TBD).
+
+CEIL - Ceiling
+
+.. math::
+
+  dst.x = \lceil src.x\rceil
+
+  dst.y = \lceil src.y\rceil
+
+  dst.z = \lceil src.z\rceil
+
+  dst.w = \lceil src.w\rceil
+
+
+I2F - Integer To Float
+
+.. math::
+
+  dst.x = (float) src.x
+
+  dst.y = (float) src.y
+
+  dst.z = (float) src.z
+
+  dst.w = (float) src.w
+
+
+NOT - Bitwise Not
+
+.. math::
+
+  dst.x = ~src.x
+
+  dst.y = ~src.y
+
+  dst.z = ~src.z
+
+  dst.w = ~src.w
+
+
+TRUNC - Truncate
+
+.. math::
+
+  dst.x = trunc(src.x)
+
+  dst.y = trunc(src.y)
+
+  dst.z = trunc(src.z)
+
+  dst.w = trunc(src.w)
+
+
+SHL - Shift Left
+
+.. math::
+
+  dst.x = src0.x << src1.x
+
+  dst.y = src0.y << src1.x
+
+  dst.z = src0.z << src1.x
+
+  dst.w = src0.w << src1.x
+
+
+SHR - Shift Right
+
+.. math::
+
+  dst.x = src0.x >> src1.x
+
+  dst.y = src0.y >> src1.x
+
+  dst.z = src0.z >> src1.x
+
+  dst.w = src0.w >> src1.x
+
+
+AND - Bitwise And
+
+.. math::
+
+  dst.x = src0.x & src1.x
+
+  dst.y = src0.y & src1.y
+
+  dst.z = src0.z & src1.z
+
+  dst.w = src0.w & src1.w
+
+
+OR - Bitwise Or
+
+.. math::
+
+  dst.x = src0.x | src1.x
+
+  dst.y = src0.y | src1.y
+
+  dst.z = src0.z | src1.z
+
+  dst.w = src0.w | src1.w
+
+
+MOD - Modulus
+
+.. math::
+
+  dst.x = src0.x \bmod src1.x
+
+  dst.y = src0.y \bmod src1.y
+
+  dst.z = src0.z \bmod src1.z
+
+  dst.w = src0.w \bmod src1.w
+
+
+XOR - Bitwise Xor
+
+.. math::
+
+  dst.x = src0.x ^ src1.x
+
+  dst.y = src0.y ^ src1.y
+
+  dst.z = src0.z ^ src1.z
+
+  dst.w = src0.w ^ src1.w
+
+
+SAD - Sum Of Absolute Differences
+
+.. math::
+
+  dst.x = |src0.x - src1.x| + src2.x
+
+  dst.y = |src0.y - src1.y| + src2.y
+
+  dst.z = |src0.z - src1.z| + src2.z
+
+  dst.w = |src0.w - src1.w| + src2.w
+
+
+TXF - Texel Fetch
+
+  TBD
+
+
+TXQ - Texture Size Query
+
+  TBD
+
+
+CONT - Continue
+
+  TBD
+
+
+From GL_NV_geometry_program4
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+
+EMIT - Emit
+
+  TBD
+
+
+ENDPRIM - End Primitive
+
+  TBD
+
+
+From GLSL
+^^^^^^^^^^
+
+
+BGNLOOP - Begin a Loop
+
+  TBD
+
+
+BGNSUB - Begin Subroutine
+
+  TBD
+
+
+ENDLOOP - End a Loop
+
+  TBD
+
+
+ENDSUB - End Subroutine
+
+  TBD
+
+
+NOP - No Operation
+
+  Do nothing.
+
+
+NRM4 - 4-component Vector Normalise
+
+.. math::
+
+  dst.x = \frac{src.x}{src.x \times src.x + src.y \times src.y + src.z \times src.z + src.w \times src.w}
+
+  dst.y = \frac{src.y}{src.x \times src.x + src.y \times src.y + src.z \times src.z + src.w \times src.w}
+
+  dst.z = \frac{src.z}{src.x \times src.x + src.y \times src.y + src.z \times src.z + src.w \times src.w}
+
+  dst.w = \frac{src.w}{src.x \times src.x + src.y \times src.y + src.z \times src.z + src.w \times src.w}
+
+
+ps_2_x
+^^^^^^^^^^^^
+
+
+CALLNZ - Subroutine Call If Not Zero
+
+  TBD
+
+
+IFC - If
+
+  TBD
+
+
+BREAKC - Break Conditional
+
+  TBD
+
+
+Explanation of symbols used
+------------------------------
+
+
+Functions
+^^^^^^^^^^^^^^
+
+
+  :math:`|x|`       Absolute value of `x`.
+
+  :math:`\lceil x \rceil` Ceiling of `x`.
+
+  clamp(x,y,z)      Clamp x between y and z.
+                    (x < y) ? y : (x > z) ? z : x
+
+  :math:`\lfloor x\rfloor` Floor of `x`.
+
+  :math:`\log_2{x}` Logarithm of `x`, base 2.
+
+  max(x,y)          Maximum of x and y.
+                    (x > y) ? x : y
+
+  min(x,y)          Minimum of x and y.
+                    (x < y) ? x : y
+
+  partialx(x)       Derivative of x relative to fragment's X.
+
+  partialy(x)       Derivative of x relative to fragment's Y.
+
+  pop()             Pop from stack.
+
+  :math:`x^y`       `x` to the power `y`.
+
+  push(x)           Push x on stack.
+
+  round(x)          Round x.
+
+  trunc(x)          Truncate x, i.e. drop the fraction bits.
+
+
+Keywords
+^^^^^^^^^^^^^
+
+
+  discard           Discard fragment.
+
+  dst               First destination register.
+
+  dst0              First destination register.
+
+  pc                Program counter.
+
+  src               First source register.
+
+  src0              First source register.
+
+  src1              Second source register.
+
+  src2              Third source register.
+
+  target            Label of target instruction.
+
+
+Other tokens
+---------------
+
+
+Declaration Semantic
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+
+  Follows Declaration token if Semantic bit is set.
+
+  Since its purpose is to link a shader with other stages of the pipeline,
+  it is valid to follow only those Declaration tokens that declare a register
+  either in INPUT or OUTPUT file.
+
+  SemanticName field contains the semantic name of the register being declared.
+  There is no default value.
+
+  SemanticIndex is an optional subscript that can be used to distinguish
+  different register declarations with the same semantic name. The default value
+  is 0.
+
+  The meanings of the individual semantic names are explained in the following
+  sections.
+
+TGSI_SEMANTIC_POSITION
+""""""""""""""""""""""
+
+Position, sometimes known as HPOS or WPOS for historical reasons, is the
+location of the vertex in space, in ``(x, y, z, w)`` format. ``x``, ``y``, and ``z``
+are the Cartesian coordinates, and ``w`` is the homogenous coordinate and used
+for the perspective divide, if enabled.
+
+As a vertex shader output, position should be scaled to the viewport. When
+used in fragment shaders, position will ---
+
+XXX --- wait a minute. Should position be in [0,1] for x and y?
+
+XXX additionally, is there a way to configure the perspective divide? it's
+accelerated on most chipsets AFAIK...
+
+Position, if not specified, usually defaults to ``(0, 0, 0, 1)``, and can
+be partially specified as ``(x, y, 0, 1)`` or ``(x, y, z, 1)``.
+
+XXX usually? can we solidify that?
+
+TGSI_SEMANTIC_COLOR
+"""""""""""""""""""
+
+Colors are used to, well, color the primitives. Colors are always in
+``(r, g, b, a)`` format.
+
+If alpha is not specified, it defaults to 1.
+
+TGSI_SEMANTIC_BCOLOR
+""""""""""""""""""""
+
+Back-facing colors are only used for back-facing polygons, and are only valid
+in vertex shader outputs. After rasterization, all polygons are front-facing
+and COLOR and BCOLOR end up occupying the same slots in the fragment, so
+all BCOLORs effectively become regular COLORs in the fragment shader.
+
+TGSI_SEMANTIC_FOG
+"""""""""""""""""
+
+The fog coordinate historically has been used to replace the depth coordinate
+for generation of fog in dedicated fog blocks. Gallium, however, does not use
+dedicated fog acceleration, placing it entirely in the fragment shader
+instead.
+
+The fog coordinate should be written in ``(f, 0, 0, 1)`` format. Only the first
+component matters when writing from the vertex shader; the driver will ensure
+that the coordinate is in this format when used as a fragment shader input.
+
+TGSI_SEMANTIC_PSIZE
+"""""""""""""""""""
+
+PSIZE, or point size, is used to specify point sizes per-vertex. It should
+be in ``(p, n, x, f)`` format, where ``p`` is the point size, ``n`` is the minimum
+size, ``x`` is the maximum size, and ``f`` is the fade threshold.
+
+XXX this is arb_vp. is this what we actually do? should double-check...
+
+When using this semantic, be sure to set the appropriate state in the
+:ref:`rasterizer` first.
+
+TGSI_SEMANTIC_GENERIC
+"""""""""""""""""""""
+
+Generic semantics are nearly always used for texture coordinate attributes,
+in ``(s, t, r, q)`` format. ``t`` and ``r`` may be unused for certain kinds
+of lookups, and ``q`` is the level-of-detail bias for biased sampling.
+
+These attributes are called "generic" because they may be used for anything
+else, including parameters, texture generation information, or anything that
+can be stored inside a four-component vector.
+
+TGSI_SEMANTIC_NORMAL
+""""""""""""""""""""
+
+Vertex normal; could be used to implement per-pixel lighting for legacy APIs
+that allow mixing fixed-function and programmable stages.
+
+TGSI_SEMANTIC_FACE
+""""""""""""""""""
+
+FACE is the facing bit, to store the facing information for the fragment
+shader. ``(f, 0, 0, 1)`` is the format. The first component will be positive
+when the fragment is front-facing, and negative when the component is
+back-facing.
+
+TGSI_SEMANTIC_EDGEFLAG
+""""""""""""""""""""""
+
+XXX no clue
diff --git a/src/gallium/drivers/cell/ppu/cell_clear.c b/src/gallium/drivers/cell/ppu/cell_clear.c
index 79ad687..3a3f968 100644
--- a/src/gallium/drivers/cell/ppu/cell_clear.c
+++ b/src/gallium/drivers/cell/ppu/cell_clear.c
@@ -59,9 +59,9 @@
 
    if (buffers & PIPE_CLEAR_COLOR) {
       uint surfIndex = 0;
-      uint clearValue;
+      union util_color uc;
 
-      util_pack_color(rgba, cell->framebuffer.cbufs[0]->format, &clearValue);
+      util_pack_color(rgba, cell->framebuffer.cbufs[0]->format, &uc);
 
       /* Build a CLEAR command and place it in the current batch buffer */
       STATIC_ASSERT(sizeof(struct cell_command_clear_surface) % 16 == 0);
@@ -70,7 +70,7 @@
          cell_batch_alloc16(cell, sizeof(*clr));
       clr->opcode[0] = CELL_CMD_CLEAR_SURFACE;
       clr->surface = surfIndex;
-      clr->value = clearValue;
+      clr->value = uc.ui;
    }
 
    if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
index 644496d..3fa8b97 100644
--- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
+++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
@@ -59,7 +59,7 @@
       }
    }
 
-   draw_set_mapped_constant_buffer(sp->draw,
+   draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX,
                                    sp->mapped_constants[PIPE_SHADER_VERTEX],
                                    sp->constants[PIPE_SHADER_VERTEX].buffer->size);
 }
@@ -85,7 +85,7 @@
  *
  * XXX should the element buffer be specified/bound with a separate function?
  */
-static boolean
+static void
 cell_draw_range_elements(struct pipe_context *pipe,
                          struct pipe_buffer *indexBuffer,
                          unsigned indexSize,
@@ -145,47 +145,35 @@
 
    /* Note: leave drawing surfaces mapped */
    cell_unmap_constant_buffers(sp);
-
-   return TRUE;
 }
 
 
-static boolean
+static void
 cell_draw_elements(struct pipe_context *pipe,
                    struct pipe_buffer *indexBuffer,
                    unsigned indexSize,
                    unsigned mode, unsigned start, unsigned count)
 {
-   return cell_draw_range_elements( pipe, indexBuffer,
-                                    indexSize,
-                                    0, 0xffffffff,
-                                    mode, start, count );
-}
-
-
-static boolean
-cell_draw_arrays(struct pipe_context *pipe, unsigned mode,
-                     unsigned start, unsigned count)
-{
-   return cell_draw_elements(pipe, NULL, 0, mode, start, count);
+   cell_draw_range_elements( pipe, indexBuffer,
+                             indexSize,
+                             0, 0xffffffff,
+                             mode, start, count );
 }
 
 
 static void
-cell_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags)
+cell_draw_arrays(struct pipe_context *pipe, unsigned mode,
+                     unsigned start, unsigned count)
 {
-   struct cell_context *cell = cell_context(pipe);
-   draw_set_edgeflags(cell->draw, edgeflags);
+   cell_draw_elements(pipe, NULL, 0, mode, start, count);
 }
 
 
-
 void
 cell_init_draw_functions(struct cell_context *cell)
 {
    cell->pipe.draw_arrays = cell_draw_arrays;
    cell->pipe.draw_elements = cell_draw_elements;
    cell->pipe.draw_range_elements = cell_draw_range_elements;
-   cell->pipe.set_edgeflags = cell_set_edgeflags;
 }
 
diff --git a/src/gallium/drivers/cell/ppu/cell_gen_fp.c b/src/gallium/drivers/cell/ppu/cell_gen_fp.c
index 19e3ab0..1d8a11a 100644
--- a/src/gallium/drivers/cell/ppu/cell_gen_fp.c
+++ b/src/gallium/drivers/cell/ppu/cell_gen_fp.c
@@ -237,8 +237,8 @@
    if (swizzle > TGSI_SWIZZLE_W || sign_op != TGSI_UTIL_SIGN_KEEP) {
       return FALSE;
    }
-   if (src->SrcRegister.File == TGSI_FILE_TEMPORARY ||
-       src->SrcRegister.File == TGSI_FILE_IMMEDIATE) {
+   if (src->Register.File == TGSI_FILE_TEMPORARY ||
+       src->Register.File == TGSI_FILE_IMMEDIATE) {
       return TRUE;
    }
    return FALSE;
@@ -249,7 +249,7 @@
 is_memory_dst(struct codegen *gen, int channel,
               const struct tgsi_full_dst_register *dst)
 {
-   if (dst->DstRegister.File == TGSI_FILE_OUTPUT) {
+   if (dst->Register.File == TGSI_FILE_OUTPUT) {
       return TRUE;
    }
    else {
@@ -279,15 +279,15 @@
    assert(swizzle <= TGSI_SWIZZLE_W);
 
    {
-      int index = src->SrcRegister.Index;
+      int index = src->Register.Index;
 
       assert(swizzle < 4);
 
-      if (src->SrcRegister.Indirect) {
+      if (src->Register.Indirect) {
          /* XXX unfinished */
       }
 
-      switch (src->SrcRegister.File) {
+      switch (src->Register.File) {
       case TGSI_FILE_TEMPORARY:
          reg = gen->temp_regs[index][swizzle];
          break;
@@ -374,12 +374,12 @@
 {
    int reg = -1;
 
-   switch (dest->DstRegister.File) {
+   switch (dest->Register.File) {
    case TGSI_FILE_TEMPORARY:
       if (gen->if_nesting > 0 || gen->loop_nesting > 0)
          reg = get_itemp(gen);
       else
-         reg = gen->temp_regs[dest->DstRegister.Index][channel];
+         reg = gen->temp_regs[dest->Register.Index][channel];
       break;
    case TGSI_FILE_OUTPUT:
       reg = get_itemp(gen);
@@ -419,10 +419,10 @@
    }
 #endif
 
-   switch (dest->DstRegister.File) {
+   switch (dest->Register.File) {
    case TGSI_FILE_TEMPORARY:
       if (gen->if_nesting > 0 || gen->loop_nesting > 0) {
-         int d_reg = gen->temp_regs[dest->DstRegister.Index][channel];
+         int d_reg = gen->temp_regs[dest->Register.Index][channel];
          int exec_reg = get_exec_mask_reg(gen);
          /* Mix d with new value according to exec mask:
           * d[i] = mask_reg[i] ? value_reg : d_reg
@@ -437,7 +437,7 @@
    case TGSI_FILE_OUTPUT:
       {
          /* offset is measured in quadwords, not bytes */
-         int offset = dest->DstRegister.Index * 4 + channel;
+         int offset = dest->Register.Index * 4 + channel;
          if (gen->if_nesting > 0 || gen->loop_nesting > 0) {
             int exec_reg = get_exec_mask_reg(gen);
             int curval_reg = get_itemp(gen);
@@ -544,7 +544,7 @@
 
 #define FOR_EACH_ENABLED_CHANNEL(inst, ch) \
    for (ch = 0; ch < 4; ch++) \
-      if (inst->FullDstRegisters[0].DstRegister.WriteMask & (1 << ch))
+      if (inst->Dst[0].Register.WriteMask & (1 << ch))
 
 
 static boolean
@@ -552,7 +552,7 @@
 {
    int ch = 0, src_reg, addr_reg;
 
-   src_reg = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
+   src_reg = get_src_reg(gen, ch, &inst->Src[0]);
    addr_reg = get_address_reg(gen);
 
    /* convert float to int */
@@ -570,19 +570,19 @@
    int ch, src_reg[4], dst_reg[4];
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      src_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
-      dst_reg[ch] = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      src_reg[ch] = get_src_reg(gen, ch, &inst->Src[0]);
+      dst_reg[ch] = get_dst_reg(gen, ch, &inst->Dst[0]);
    }
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      if (is_register_src(gen, ch, &inst->FullSrcRegisters[0]) &&
-          is_memory_dst(gen, ch, &inst->FullDstRegisters[0])) {
+      if (is_register_src(gen, ch, &inst->Src[0]) &&
+          is_memory_dst(gen, ch, &inst->Dst[0])) {
          /* special-case: register to memory store */
-         store_dest_reg(gen, src_reg[ch], ch, &inst->FullDstRegisters[0]);
+         store_dest_reg(gen, src_reg[ch], ch, &inst->Dst[0]);
       }
       else {
          spe_move(gen->f, dst_reg[ch], src_reg[ch]);
-         store_dest_reg(gen, dst_reg[ch], ch, &inst->FullDstRegisters[0]);
+         store_dest_reg(gen, dst_reg[ch], ch, &inst->Dst[0]);
       }
    }
 
@@ -601,9 +601,9 @@
 
    /* Loop over Red/Green/Blue/Alpha channels, fetch src operands */
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
-      s2_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[1]);
-      d_reg[ch] = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      s1_reg[ch] = get_src_reg(gen, ch, &inst->Src[0]);
+      s2_reg[ch] = get_src_reg(gen, ch, &inst->Src[1]);
+      d_reg[ch] = get_dst_reg(gen, ch, &inst->Dst[0]);
    }
 
    /* Loop over Red/Green/Blue/Alpha channels, do the op, store results */
@@ -626,7 +626,7 @@
 
    /* Store the result (a no-op for TGSI_FILE_TEMPORARY dests) */
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      store_dest_reg(gen, d_reg[ch], ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, d_reg[ch], ch, &inst->Dst[0]);
    }
 
    /* Free any intermediate temps we allocated */
@@ -645,16 +645,16 @@
    int ch, s1_reg[4], s2_reg[4], s3_reg[4], d_reg[4];
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
-      s2_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[1]);
-      s3_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[2]);
-      d_reg[ch] = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      s1_reg[ch] = get_src_reg(gen, ch, &inst->Src[0]);
+      s2_reg[ch] = get_src_reg(gen, ch, &inst->Src[1]);
+      s3_reg[ch] = get_src_reg(gen, ch, &inst->Src[2]);
+      d_reg[ch] = get_dst_reg(gen, ch, &inst->Dst[0]);
    }
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
       spe_fma(gen->f, d_reg[ch], s1_reg[ch], s2_reg[ch], s3_reg[ch]);
    }
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      store_dest_reg(gen, d_reg[ch], ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, d_reg[ch], ch, &inst->Dst[0]);
    }
    free_itemps(gen);
    return TRUE;
@@ -671,10 +671,10 @@
 
    /* setup/get src/dst/temp regs */
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
-      s2_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[1]);
-      s3_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[2]);
-      d_reg[ch] = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      s1_reg[ch] = get_src_reg(gen, ch, &inst->Src[0]);
+      s2_reg[ch] = get_src_reg(gen, ch, &inst->Src[1]);
+      s3_reg[ch] = get_src_reg(gen, ch, &inst->Src[2]);
+      d_reg[ch] = get_dst_reg(gen, ch, &inst->Dst[0]);
       tmp_reg[ch] = get_itemp(gen);
    }
 
@@ -687,7 +687,7 @@
       spe_fma(gen->f, d_reg[ch], tmp_reg[ch], s1_reg[ch], s3_reg[ch]);
    }
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      store_dest_reg(gen, d_reg[ch], ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, d_reg[ch], ch, &inst->Dst[0]);
    }
    free_itemps(gen);
    return TRUE;
@@ -704,8 +704,8 @@
    int ch, s1_reg[4], d_reg[4], tmp_reg[4];
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
-      d_reg[ch] = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      s1_reg[ch] = get_src_reg(gen, ch, &inst->Src[0]);
+      d_reg[ch] = get_dst_reg(gen, ch, &inst->Dst[0]);
       tmp_reg[ch] = get_itemp(gen);
    }
 
@@ -726,7 +726,7 @@
    }
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      store_dest_reg(gen, d_reg[ch], ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, d_reg[ch], ch, &inst->Dst[0]);
    }
 
    free_itemps(gen);
@@ -747,8 +747,8 @@
    spe_load_uint(gen->f, bit31mask_reg, (1 << 31));
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
-      d_reg[ch] = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      s1_reg[ch] = get_src_reg(gen, ch, &inst->Src[0]);
+      d_reg[ch] = get_dst_reg(gen, ch, &inst->Dst[0]);
    }
 
    /* d = sign bit cleared in s1 */
@@ -757,7 +757,7 @@
    }
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      store_dest_reg(gen, d_reg[ch], ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, d_reg[ch], ch, &inst->Dst[0]);
    }
 
    free_itemps(gen);
@@ -775,12 +775,12 @@
    int s2x_reg, s2y_reg, s2z_reg;
    int t0_reg = get_itemp(gen), t1_reg = get_itemp(gen);
 
-   s1x_reg = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[0]);
-   s2x_reg = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[1]);
-   s1y_reg = get_src_reg(gen, CHAN_Y, &inst->FullSrcRegisters[0]);
-   s2y_reg = get_src_reg(gen, CHAN_Y, &inst->FullSrcRegisters[1]);
-   s1z_reg = get_src_reg(gen, CHAN_Z, &inst->FullSrcRegisters[0]);
-   s2z_reg = get_src_reg(gen, CHAN_Z, &inst->FullSrcRegisters[1]);
+   s1x_reg = get_src_reg(gen, CHAN_X, &inst->Src[0]);
+   s2x_reg = get_src_reg(gen, CHAN_X, &inst->Src[1]);
+   s1y_reg = get_src_reg(gen, CHAN_Y, &inst->Src[0]);
+   s2y_reg = get_src_reg(gen, CHAN_Y, &inst->Src[1]);
+   s1z_reg = get_src_reg(gen, CHAN_Z, &inst->Src[0]);
+   s2z_reg = get_src_reg(gen, CHAN_Z, &inst->Src[1]);
 
    /* t0 = x0 * x1 */
    spe_fm(gen->f, t0_reg, s1x_reg, s2x_reg);
@@ -795,9 +795,9 @@
    spe_fa(gen->f, t0_reg, t0_reg, t1_reg);
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      int d_reg = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      int d_reg = get_dst_reg(gen, ch, &inst->Dst[0]);
       spe_move(gen->f, d_reg, t0_reg);
-      store_dest_reg(gen, d_reg, ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, d_reg, ch, &inst->Dst[0]);
    }
 
    free_itemps(gen);
@@ -815,14 +815,14 @@
    int s1x_reg, s1y_reg, s1z_reg, s1w_reg;
    int t0_reg = get_itemp(gen), t1_reg = get_itemp(gen);
 
-   s0x_reg = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[0]);
-   s1x_reg = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[1]);
-   s0y_reg = get_src_reg(gen, CHAN_Y, &inst->FullSrcRegisters[0]);
-   s1y_reg = get_src_reg(gen, CHAN_Y, &inst->FullSrcRegisters[1]);
-   s0z_reg = get_src_reg(gen, CHAN_Z, &inst->FullSrcRegisters[0]);
-   s1z_reg = get_src_reg(gen, CHAN_Z, &inst->FullSrcRegisters[1]);
-   s0w_reg = get_src_reg(gen, CHAN_W, &inst->FullSrcRegisters[0]);
-   s1w_reg = get_src_reg(gen, CHAN_W, &inst->FullSrcRegisters[1]);
+   s0x_reg = get_src_reg(gen, CHAN_X, &inst->Src[0]);
+   s1x_reg = get_src_reg(gen, CHAN_X, &inst->Src[1]);
+   s0y_reg = get_src_reg(gen, CHAN_Y, &inst->Src[0]);
+   s1y_reg = get_src_reg(gen, CHAN_Y, &inst->Src[1]);
+   s0z_reg = get_src_reg(gen, CHAN_Z, &inst->Src[0]);
+   s1z_reg = get_src_reg(gen, CHAN_Z, &inst->Src[1]);
+   s0w_reg = get_src_reg(gen, CHAN_W, &inst->Src[0]);
+   s1w_reg = get_src_reg(gen, CHAN_W, &inst->Src[1]);
 
    /* t0 = x0 * x1 */
    spe_fm(gen->f, t0_reg, s0x_reg, s1x_reg);
@@ -840,9 +840,9 @@
    spe_fa(gen->f, t0_reg, t0_reg, t1_reg);
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      int d_reg = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      int d_reg = get_dst_reg(gen, ch, &inst->Dst[0]);
       spe_move(gen->f, d_reg, t0_reg);
-      store_dest_reg(gen, d_reg, ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, d_reg, ch, &inst->Dst[0]);
    }
 
    free_itemps(gen);
@@ -857,31 +857,31 @@
 {
    /* XXX rewrite this function to look more like DP3/DP4 */
    int ch;
-   int s1_reg = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[0]);
-   int s2_reg = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[1]);
+   int s1_reg = get_src_reg(gen, CHAN_X, &inst->Src[0]);
+   int s2_reg = get_src_reg(gen, CHAN_X, &inst->Src[1]);
    int tmp_reg = get_itemp(gen);
 
    /* t = x0 * x1 */
    spe_fm(gen->f, tmp_reg, s1_reg, s2_reg);
 
-   s1_reg = get_src_reg(gen, CHAN_Y, &inst->FullSrcRegisters[0]);
-   s2_reg = get_src_reg(gen, CHAN_Y, &inst->FullSrcRegisters[1]);
+   s1_reg = get_src_reg(gen, CHAN_Y, &inst->Src[0]);
+   s2_reg = get_src_reg(gen, CHAN_Y, &inst->Src[1]);
    /* t = y0 * y1 + t */
    spe_fma(gen->f, tmp_reg, s1_reg, s2_reg, tmp_reg);
 
-   s1_reg = get_src_reg(gen, CHAN_Z, &inst->FullSrcRegisters[0]);
-   s2_reg = get_src_reg(gen, CHAN_Z, &inst->FullSrcRegisters[1]);
+   s1_reg = get_src_reg(gen, CHAN_Z, &inst->Src[0]);
+   s2_reg = get_src_reg(gen, CHAN_Z, &inst->Src[1]);
    /* t = z0 * z1 + t */
    spe_fma(gen->f, tmp_reg, s1_reg, s2_reg, tmp_reg);
 
-   s2_reg = get_src_reg(gen, CHAN_W, &inst->FullSrcRegisters[1]);
+   s2_reg = get_src_reg(gen, CHAN_W, &inst->Src[1]);
    /* t = w1 + t */
    spe_fa(gen->f, tmp_reg, s2_reg, tmp_reg);
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      int d_reg = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      int d_reg = get_dst_reg(gen, ch, &inst->Dst[0]);
       spe_move(gen->f, d_reg, tmp_reg);
-      store_dest_reg(gen, tmp_reg, ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, tmp_reg, ch, &inst->Dst[0]);
    }
 
    free_itemps(gen);
@@ -898,9 +898,9 @@
    int src_reg[3];
    int t0_reg = get_itemp(gen), t1_reg = get_itemp(gen);
 
-   src_reg[0] = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[0]);
-   src_reg[1] = get_src_reg(gen, CHAN_Y, &inst->FullSrcRegisters[0]);
-   src_reg[2] = get_src_reg(gen, CHAN_Z, &inst->FullSrcRegisters[0]);
+   src_reg[0] = get_src_reg(gen, CHAN_X, &inst->Src[0]);
+   src_reg[1] = get_src_reg(gen, CHAN_Y, &inst->Src[0]);
+   src_reg[2] = get_src_reg(gen, CHAN_Z, &inst->Src[0]);
 
    /* t0 = x * x */
    spe_fm(gen->f, t0_reg, src_reg[0], src_reg[0]);
@@ -919,10 +919,10 @@
    spe_fi(gen->f, t1_reg, t0_reg, t1_reg);
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      int d_reg = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      int d_reg = get_dst_reg(gen, ch, &inst->Dst[0]);
       /* dst = src[ch] * t1 */
       spe_fm(gen->f, d_reg, src_reg[ch], t1_reg);
-      store_dest_reg(gen, d_reg, ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, d_reg, ch, &inst->Dst[0]);
    }
 
    free_itemps(gen);
@@ -936,48 +936,48 @@
 static boolean
 emit_XPD(struct codegen *gen, const struct tgsi_full_instruction *inst)
 {
-   int s1_reg = get_src_reg(gen, CHAN_Z, &inst->FullSrcRegisters[0]);
-   int s2_reg = get_src_reg(gen, CHAN_Y, &inst->FullSrcRegisters[1]);
+   int s1_reg = get_src_reg(gen, CHAN_Z, &inst->Src[0]);
+   int s2_reg = get_src_reg(gen, CHAN_Y, &inst->Src[1]);
    int tmp_reg = get_itemp(gen);
 
    /* t = z0 * y1 */
    spe_fm(gen->f, tmp_reg, s1_reg, s2_reg);
 
-   s1_reg = get_src_reg(gen, CHAN_Y, &inst->FullSrcRegisters[0]);
-   s2_reg = get_src_reg(gen, CHAN_Z, &inst->FullSrcRegisters[1]);
+   s1_reg = get_src_reg(gen, CHAN_Y, &inst->Src[0]);
+   s2_reg = get_src_reg(gen, CHAN_Z, &inst->Src[1]);
    /* t = y0 * z1 - t */
    spe_fms(gen->f, tmp_reg, s1_reg, s2_reg, tmp_reg);
 
-   if (inst->FullDstRegisters[0].DstRegister.WriteMask & (1 << CHAN_X)) {
-      store_dest_reg(gen, tmp_reg, CHAN_X, &inst->FullDstRegisters[0]);
+   if (inst->Dst[0].Register.WriteMask & (1 << CHAN_X)) {
+      store_dest_reg(gen, tmp_reg, CHAN_X, &inst->Dst[0]);
    }
 
-   s1_reg = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[0]);
-   s2_reg = get_src_reg(gen, CHAN_Z, &inst->FullSrcRegisters[1]);
+   s1_reg = get_src_reg(gen, CHAN_X, &inst->Src[0]);
+   s2_reg = get_src_reg(gen, CHAN_Z, &inst->Src[1]);
    /* t = x0 * z1 */
    spe_fm(gen->f, tmp_reg, s1_reg, s2_reg);
 
-   s1_reg = get_src_reg(gen, CHAN_Z, &inst->FullSrcRegisters[0]);
-   s2_reg = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[1]);
+   s1_reg = get_src_reg(gen, CHAN_Z, &inst->Src[0]);
+   s2_reg = get_src_reg(gen, CHAN_X, &inst->Src[1]);
    /* t = z0 * x1 - t */
    spe_fms(gen->f, tmp_reg, s1_reg, s2_reg, tmp_reg);
 
-   if (inst->FullDstRegisters[0].DstRegister.WriteMask & (1 << CHAN_Y)) {
-      store_dest_reg(gen, tmp_reg, CHAN_Y, &inst->FullDstRegisters[0]);
+   if (inst->Dst[0].Register.WriteMask & (1 << CHAN_Y)) {
+      store_dest_reg(gen, tmp_reg, CHAN_Y, &inst->Dst[0]);
    }
 
-   s1_reg = get_src_reg(gen, CHAN_Y, &inst->FullSrcRegisters[0]);
-   s2_reg = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[1]);
+   s1_reg = get_src_reg(gen, CHAN_Y, &inst->Src[0]);
+   s2_reg = get_src_reg(gen, CHAN_X, &inst->Src[1]);
    /* t = y0 * x1 */
    spe_fm(gen->f, tmp_reg, s1_reg, s2_reg);
 
-   s1_reg = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[0]);
-   s2_reg = get_src_reg(gen, CHAN_Y, &inst->FullSrcRegisters[1]);
+   s1_reg = get_src_reg(gen, CHAN_X, &inst->Src[0]);
+   s2_reg = get_src_reg(gen, CHAN_Y, &inst->Src[1]);
    /* t = x0 * y1 - t */
    spe_fms(gen->f, tmp_reg, s1_reg, s2_reg, tmp_reg);
 
-   if (inst->FullDstRegisters[0].DstRegister.WriteMask & (1 << CHAN_Z)) {
-      store_dest_reg(gen, tmp_reg, CHAN_Z, &inst->FullDstRegisters[0]);
+   if (inst->Dst[0].Register.WriteMask & (1 << CHAN_Z)) {
+      store_dest_reg(gen, tmp_reg, CHAN_Z, &inst->Dst[0]);
    }
 
    free_itemps(gen);
@@ -995,14 +995,14 @@
 emit_inequality(struct codegen *gen, const struct tgsi_full_instruction *inst)
 {
    int ch, s1_reg[4], s2_reg[4], d_reg[4], one_reg;
-   bool complement = FALSE;
+   boolean complement = FALSE;
 
    one_reg = get_const_one_reg(gen);
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
-      s2_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[1]);
-      d_reg[ch] = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      s1_reg[ch] = get_src_reg(gen, ch, &inst->Src[0]);
+      s2_reg[ch] = get_src_reg(gen, ch, &inst->Src[1]);
+      d_reg[ch] = get_dst_reg(gen, ch, &inst->Dst[0]);
    }
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
@@ -1043,7 +1043,7 @@
    }
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      store_dest_reg(gen, d_reg[ch], ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, d_reg[ch], ch, &inst->Dst[0]);
    }
 
    free_itemps(gen);
@@ -1060,10 +1060,10 @@
    int ch;
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      int s1_reg = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
-      int s2_reg = get_src_reg(gen, ch, &inst->FullSrcRegisters[1]);
-      int s3_reg = get_src_reg(gen, ch, &inst->FullSrcRegisters[2]);
-      int d_reg = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      int s1_reg = get_src_reg(gen, ch, &inst->Src[0]);
+      int s2_reg = get_src_reg(gen, ch, &inst->Src[1]);
+      int s3_reg = get_src_reg(gen, ch, &inst->Src[2]);
+      int d_reg = get_dst_reg(gen, ch, &inst->Dst[0]);
       int zero_reg = get_itemp(gen);
    
       spe_zero(gen->f, zero_reg);
@@ -1072,7 +1072,7 @@
       spe_fcgt(gen->f, d_reg, zero_reg, s1_reg);
       spe_selb(gen->f, d_reg, s3_reg, s2_reg, d_reg);
 
-      store_dest_reg(gen, d_reg, ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, d_reg, ch, &inst->Dst[0]);
       free_itemps(gen);
    }
 
@@ -1090,8 +1090,8 @@
    int ch, s1_reg[4], d_reg[4];
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
-      d_reg[ch] = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      s1_reg[ch] = get_src_reg(gen, ch, &inst->Src[0]);
+      d_reg[ch] = get_dst_reg(gen, ch, &inst->Dst[0]);
    }
 
    /* Convert float to int */
@@ -1105,7 +1105,7 @@
    }
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      store_dest_reg(gen, d_reg[ch], ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, d_reg[ch], ch, &inst->Dst[0]);
    }
 
    free_itemps(gen);
@@ -1129,8 +1129,8 @@
    one_reg = get_const_one_reg(gen);
    
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
-      d_reg[ch] = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      s1_reg[ch] = get_src_reg(gen, ch, &inst->Src[0]);
+      d_reg[ch] = get_dst_reg(gen, ch, &inst->Dst[0]);
       tmp_reg[ch] = get_itemp(gen);
    }
 
@@ -1156,7 +1156,7 @@
    }
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      store_dest_reg(gen, d_reg[ch], ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, d_reg[ch], ch, &inst->Dst[0]);
    }
 
    free_itemps(gen);
@@ -1177,8 +1177,8 @@
    one_reg = get_const_one_reg(gen);
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
-      d_reg[ch] = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      s1_reg[ch] = get_src_reg(gen, ch, &inst->Src[0]);
+      d_reg[ch] = get_dst_reg(gen, ch, &inst->Dst[0]);
       tmp_reg[ch] = get_itemp(gen);
    }
 
@@ -1210,7 +1210,7 @@
 
    /* store result */
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      store_dest_reg(gen, d_reg[ch], ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, d_reg[ch], ch, &inst->Dst[0]);
    }
 
    free_itemps(gen);
@@ -1272,7 +1272,7 @@
 
    if (scalar) {
       for (a = 0; a < num_args; a++) {
-         s_regs[a] = get_src_reg(gen, CHAN_X, &inst->FullSrcRegisters[a]);
+         s_regs[a] = get_src_reg(gen, CHAN_X, &inst->Src[a]);
       }
       /* we'll call the function, put the return value in this register,
        * then replicate it across all write-enabled components in d_reg.
@@ -1287,11 +1287,11 @@
 
       if (!scalar) {
          for (a = 0; a < num_args; a++) {
-            s_regs[a] = get_src_reg(gen, ch, &inst->FullSrcRegisters[a]);
+            s_regs[a] = get_src_reg(gen, ch, &inst->Src[a]);
          }
       }
 
-      d_reg = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      d_reg = get_dst_reg(gen, ch, &inst->Dst[0]);
 
       if (!scalar || !func_called) {
          /* for a scalar function, we'll really only call the function once */
@@ -1336,7 +1336,7 @@
          spe_move(gen->f, d_reg, retval_reg);
       }
 
-      store_dest_reg(gen, d_reg, ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, d_reg, ch, &inst->Dst[0]);
       free_itemps(gen);
    }
 
@@ -1351,8 +1351,8 @@
 static boolean
 emit_TEX(struct codegen *gen, const struct tgsi_full_instruction *inst)
 {
-   const uint target = inst->InstructionExtTexture.Texture;
-   const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index;
+   const uint target = inst->Texture.Texture;
+   const uint unit = inst->Src[1].Register.Index;
    uint addr;
    int ch;
    int coord_regs[4], d_regs[4];
@@ -1373,14 +1373,14 @@
       return FALSE;
    }
 
-   assert(inst->FullSrcRegisters[1].SrcRegister.File == TGSI_FILE_SAMPLER);
+   assert(inst->Src[1].Register.File == TGSI_FILE_SAMPLER);
 
    spe_comment(gen->f, -4, "CALL tex:");
 
    /* get src/dst reg info */
    for (ch = 0; ch < 4; ch++) {
-      coord_regs[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
-      d_regs[ch] = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      coord_regs[ch] = get_src_reg(gen, ch, &inst->Src[0]);
+      d_regs[ch] = get_dst_reg(gen, ch, &inst->Dst[0]);
    }
 
    {
@@ -1425,7 +1425,7 @@
    }
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      store_dest_reg(gen, d_regs[ch], ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, d_regs[ch], ch, &inst->Dst[0]);
       free_itemps(gen);
    }
 
@@ -1452,7 +1452,7 @@
 
    /* get src regs */
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      s_regs[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
+      s_regs[ch] = get_src_reg(gen, ch, &inst->Src[0]);
    }
 
    /* test if any src regs are < 0 */
@@ -1500,9 +1500,9 @@
    int ch, s0_reg[4], s1_reg[4], d_reg[4], tmp_reg[4];
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      s0_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
-      s1_reg[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[1]);
-      d_reg[ch] = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      s0_reg[ch] = get_src_reg(gen, ch, &inst->Src[0]);
+      s1_reg[ch] = get_src_reg(gen, ch, &inst->Src[1]);
+      d_reg[ch] = get_dst_reg(gen, ch, &inst->Dst[0]);
       tmp_reg[ch] = get_itemp(gen);         
    }
 
@@ -1518,7 +1518,7 @@
    }
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      store_dest_reg(gen, d_reg[ch], ch, &inst->FullDstRegisters[0]);
+      store_dest_reg(gen, d_reg[ch], ch, &inst->Dst[0]);
    }
 
    free_itemps(gen);
@@ -1575,7 +1575,7 @@
 
    /* update conditional execution mask with the predicate register */
    int tmp_reg = get_itemp(gen);
-   int s1_reg = get_src_reg(gen, channel, &inst->FullSrcRegisters[0]);
+   int s1_reg = get_src_reg(gen, channel, &inst->Src[0]);
 
    /* tmp = (s1_reg == 0) */
    spe_ceqi(gen->f, tmp_reg, s1_reg, 0);
@@ -1699,8 +1699,8 @@
    int ch;
 
    FOR_EACH_ENABLED_CHANNEL(inst, ch) {
-      int s_reg = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
-      int d_reg = get_dst_reg(gen, ch, &inst->FullDstRegisters[0]);
+      int s_reg = get_src_reg(gen, ch, &inst->Src[0]);
+      int d_reg = get_dst_reg(gen, ch, &inst->Dst[0]);
 
       int t1_reg = get_itemp(gen);
       int t2_reg = get_itemp(gen);
@@ -1909,8 +1909,8 @@
 
    switch (decl->Declaration.File) {
    case TGSI_FILE_TEMPORARY:
-      for (i = decl->DeclarationRange.First;
-           i <= decl->DeclarationRange.Last;
+      for (i = decl->Range.First;
+           i <= decl->Range.Last;
            i++) {
          assert(i < MAX_TEMPS);
          for (ch = 0; ch < 4; ch++) {
diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
index ccd0fef..c18a5d0 100644
--- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c
+++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
@@ -383,10 +383,10 @@
    cell->pipe.delete_blend_state = cell_delete_blend_state;
 
    cell->pipe.create_sampler_state = cell_create_sampler_state;
-   cell->pipe.bind_sampler_states = cell_bind_sampler_states;
+   cell->pipe.bind_fragment_sampler_states = cell_bind_sampler_states;
    cell->pipe.delete_sampler_state = cell_delete_sampler_state;
 
-   cell->pipe.set_sampler_textures = cell_set_sampler_textures;
+   cell->pipe.set_fragment_sampler_textures = cell_set_sampler_textures;
 
    cell->pipe.create_depth_stencil_alpha_state = cell_create_depth_stencil_alpha_state;
    cell->pipe.bind_depth_stencil_alpha_state   = cell_bind_depth_stencil_alpha_state;
diff --git a/src/gallium/drivers/cell/ppu/cell_state_derived.c b/src/gallium/drivers/cell/ppu/cell_state_derived.c
index efc4f78..b723e79 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_derived.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_derived.c
@@ -66,7 +66,7 @@
    vinfo->num_attribs = 0;
 
    /* we always want to emit vertex pos */
-   src = draw_find_vs_output(cell->draw, TGSI_SEMANTIC_POSITION, 0);
+   src = draw_find_shader_output(cell->draw, TGSI_SEMANTIC_POSITION, 0);
    assert(src >= 0);
    draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
 
@@ -82,14 +82,14 @@
          break;
 
       case TGSI_SEMANTIC_COLOR:
-         src = draw_find_vs_output(cell->draw, TGSI_SEMANTIC_COLOR, 
+         src = draw_find_shader_output(cell->draw, TGSI_SEMANTIC_COLOR, 
                                    fs->info.input_semantic_index[i]);
          assert(src >= 0);
          draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
          break;
 
       case TGSI_SEMANTIC_FOG:
-         src = draw_find_vs_output(cell->draw, TGSI_SEMANTIC_FOG, 0);
+         src = draw_find_shader_output(cell->draw, TGSI_SEMANTIC_FOG, 0);
 #if 1
          if (src < 0) /* XXX temp hack, try demos/fogcoord.c with this */
             src = 0;
@@ -100,7 +100,7 @@
 
       case TGSI_SEMANTIC_GENERIC:
          /* this includes texcoords and varying vars */
-         src = draw_find_vs_output(cell->draw, TGSI_SEMANTIC_GENERIC,
+         src = draw_find_shader_output(cell->draw, TGSI_SEMANTIC_GENERIC,
                               fs->info.input_semantic_index[i]);
          assert(src >= 0);
          draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c
index 9479c08..5b87286 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_emit.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c
@@ -27,6 +27,7 @@
 
 #include "pipe/p_inlines.h"
 #include "util/u_memory.h"
+#include "util/u_math.h"
 #include "cell_context.h"
 #include "cell_gen_fragment.h"
 #include "cell_state.h"
@@ -299,9 +300,9 @@
                for (level = 0; level < CELL_MAX_TEXTURE_LEVELS; level++) {
                   texture->start[level] = (ct->mapped +
                                            ct->level_offset[level]);
-                  texture->width[level] = ct->base.width[level];
-                  texture->height[level] = ct->base.height[level];
-                  texture->depth[level] = ct->base.depth[level];
+                  texture->width[level] = u_minify(ct->base.width0, level);
+                  texture->height[level] = u_minify(ct->base.height0, level);
+                  texture->depth[level] = u_minify(ct->base.depth0, level);
                }
                texture->target = ct->base.target;
             }
@@ -330,7 +331,7 @@
       const struct draw_context *const draw = cell->draw;
       struct cell_shader_info info;
 
-      info.num_outputs = draw_num_vs_outputs(draw);
+      info.num_outputs = draw_num_shader_outputs(draw);
       info.declarations = (uintptr_t) draw->vs.machine.Declarations;
       info.num_declarations = draw->vs.machine.NumDeclarations;
       info.instructions = (uintptr_t) draw->vs.machine.Instructions;
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c
index ae4c61e..998944f 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.c
+++ b/src/gallium/drivers/cell/ppu/cell_texture.c
@@ -35,6 +35,8 @@
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
 #include "pipe/internal/p_winsys_screen.h"
+
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 
@@ -49,9 +51,9 @@
 {
    struct pipe_texture *pt = &ct->base;
    unsigned level;
-   unsigned width = pt->width[0];
-   unsigned height = pt->height[0];
-   unsigned depth = pt->depth[0];
+   unsigned width = pt->width0;
+   unsigned height = pt->height0;
+   unsigned depth = pt->depth0;
 
    ct->buffer_size = 0;
 
@@ -65,17 +67,11 @@
       w_tile = align(width, TILE_SIZE);
       h_tile = align(height, TILE_SIZE);
 
-      pt->width[level] = width;
-      pt->height[level] = height;
-      pt->depth[level] = depth;
-      pt->nblocksx[level] = pf_get_nblocksx(&pt->block, w_tile);  
-      pt->nblocksy[level] = pf_get_nblocksy(&pt->block, h_tile);  
-
-      ct->stride[level] = pt->nblocksx[level] * pt->block.size;
+      ct->stride[level] = util_format_get_stride(pt->format, w_tile);
 
       ct->level_offset[level] = ct->buffer_size;
 
-      size = pt->nblocksx[level] * pt->nblocksy[level] * pt->block.size;
+      size = ct->stride[level] * util_format_get_nblocksy(pt->format, h_tile);
       if (pt->target == PIPE_TEXTURE_CUBE)
          size *= 6;
       else
@@ -83,9 +79,9 @@
 
       ct->buffer_size += size;
 
-      width = minify(width);
-      height = minify(height);
-      depth = minify(depth);
+      width = u_minify(width, 1);
+      height = u_minify(height, 1);
+      depth = u_minify(depth, 1);
    }
 }
 
@@ -276,8 +272,8 @@
       pipe_reference_init(&ps->reference, 1);
       pipe_texture_reference(&ps->texture, pt);
       ps->format = pt->format;
-      ps->width = pt->width[level];
-      ps->height = pt->height[level];
+      ps->width = u_minify(pt->width0, level);
+      ps->height = u_minify(pt->height0, level);
       ps->offset = ct->level_offset[level];
       /* XXX may need to override usage flags (see sp_texture.c) */
       ps->usage = usage;
@@ -286,10 +282,12 @@
       ps->zslice = zslice;
 
       if (pt->target == PIPE_TEXTURE_CUBE) {
-         ps->offset += face * pt->nblocksy[level] * ct->stride[level];
+         unsigned h_tile = align(ps->height, TILE_SIZE);
+         ps->offset += face * util_format_get_nblocksy(ps->format, h_tile) * ct->stride[level];
       }
       else if (pt->target == PIPE_TEXTURE_3D) {
-         ps->offset += zslice * pt->nblocksy[level] * ct->stride[level];
+         unsigned h_tile = align(ps->height, TILE_SIZE);
+         ps->offset += zslice * util_format_get_nblocksy(ps->format, h_tile) * ct->stride[level];
       }
       else {
          assert(face == 0);
@@ -330,14 +328,10 @@
    if (ctrans) {
       struct pipe_transfer *pt = &ctrans->base;
       pipe_texture_reference(&pt->texture, texture);
-      pt->format = texture->format;
-      pt->block = texture->block;
       pt->x = x;
       pt->y = y;
       pt->width = w;
       pt->height = h;
-      pt->nblocksx = texture->nblocksx[level];
-      pt->nblocksy = texture->nblocksy[level];
       pt->stride = ct->stride[level];
       pt->usage = usage;
       pt->face = face;
@@ -347,10 +341,12 @@
       ctrans->offset = ct->level_offset[level];
 
       if (texture->target == PIPE_TEXTURE_CUBE) {
-         ctrans->offset += face * pt->nblocksy * pt->stride;
+         unsigned h_tile = align(u_minify(texture->height0, level), TILE_SIZE);
+         ctrans->offset += face * util_format_get_nblocksy(texture->format, h_tile) * pt->stride;
       }
       else if (texture->target == PIPE_TEXTURE_3D) {
-         ctrans->offset += zslice * pt->nblocksy * pt->stride;
+         unsigned h_tile = align(u_minify(texture->height0, level), TILE_SIZE);
+         ctrans->offset += zslice * util_format_get_nblocksy(texture->format, h_tile) * pt->stride;
       }
       else {
          assert(face == 0);
@@ -386,8 +382,8 @@
    struct pipe_texture *pt = transfer->texture;
    struct cell_texture *ct = cell_texture(pt);
    const uint level = ctrans->base.level;
-   const uint texWidth = pt->width[level];
-   const uint texHeight = pt->height[level];
+   const uint texWidth = u_minify(pt->width0, level);
+   const uint texHeight = u_minify(pt->height0, level);
    const uint stride = ct->stride[level];
    unsigned size;
 
@@ -403,7 +399,8 @@
     * Create a buffer of ordinary memory for the linear texture.
     * This is the memory that the user will read/write.
     */
-   size = pt->nblocksx[level] * pt->nblocksy[level] * pt->block.size;
+   size = util_format_get_stride(pt->format, align(texWidth, TILE_SIZE)) *
+          util_format_get_nblocksy(pt->format, align(texHeight, TILE_SIZE));
 
    ctrans->map = align_malloc(size, 16);
    if (!ctrans->map)
@@ -411,7 +408,7 @@
 
    if (transfer->usage & PIPE_TRANSFER_READ) {
       /* need to untwiddle the texture to make a linear version */
-      const uint bpp = pf_get_size(ct->base.format);
+      const uint bpp = util_format_get_blocksize(ct->base.format);
       if (bpp == 4) {
          const uint *src = (uint *) (ct->mapped + ctrans->offset);
          uint *dst = ctrans->map;
@@ -440,8 +437,8 @@
    struct pipe_texture *pt = transfer->texture;
    struct cell_texture *ct = cell_texture(pt);
    const uint level = ctrans->base.level;
-   const uint texWidth = pt->width[level];
-   const uint texHeight = pt->height[level];
+   const uint texWidth = u_minify(pt->width0, level);
+   const uint texHeight = u_minify(pt->height0, level);
    const uint stride = ct->stride[level];
 
    if (!ct->mapped) {
@@ -454,7 +451,7 @@
       /* The user wrote new texture data into the mapped buffer.
        * We need to convert the new linear data into the twiddled/tiled format.
        */
-      const uint bpp = pf_get_size(ct->base.format);
+      const uint bpp = util_format_get_blocksize(ct->base.format);
       if (bpp == 4) {
          const uint *src = ctrans->map;
          uint *dst = (uint *) (ct->mapped + ctrans->offset);
diff --git a/src/gallium/drivers/cell/spu/spu_command.c b/src/gallium/drivers/cell/spu/spu_command.c
index 5c0179d..12b855a 100644
--- a/src/gallium/drivers/cell/spu/spu_command.c
+++ b/src/gallium/drivers/cell/spu/spu_command.c
@@ -405,8 +405,6 @@
    case PIPE_TEX_FILTER_LINEAR:
       spu.min_sample_texture_2d[unit] = sample_texture_2d_bilinear;
       break;
-   case PIPE_TEX_FILTER_ANISO:
-      /* fall-through, for now */
    case PIPE_TEX_FILTER_NEAREST:
       spu.min_sample_texture_2d[unit] = sample_texture_2d_nearest;
       break;
@@ -418,8 +416,6 @@
    case PIPE_TEX_FILTER_LINEAR:
       spu.mag_sample_texture_2d[unit] = sample_texture_2d_bilinear;
       break;
-   case PIPE_TEX_FILTER_ANISO:
-      /* fall-through, for now */
    case PIPE_TEX_FILTER_NEAREST:
       spu.mag_sample_texture_2d[unit] = sample_texture_2d_nearest;
       break;
diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c
index 4c32b2d..d86d8e0 100644
--- a/src/gallium/drivers/cell/spu/spu_exec.c
+++ b/src/gallium/drivers/cell/spu/spu_exec.c
@@ -108,10 +108,10 @@
    for (CHAN = 0; CHAN < 4; CHAN++)
 
 #define IS_CHANNEL_ENABLED(INST, CHAN)\
-   ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN)))
+   ((INST).Dst[0].Register.WriteMask & (1 << (CHAN)))
 
 #define IS_CHANNEL_ENABLED2(INST, CHAN)\
-   ((INST).FullDstRegisters[1].DstRegister.WriteMask & (1 << (CHAN)))
+   ((INST).Dst[1].Register.WriteMask & (1 << (CHAN)))
 
 #define FOR_EACH_ENABLED_CHANNEL(INST, CHAN)\
    FOR_EACH_CHANNEL( CHAN )\
@@ -431,22 +431,22 @@
    index.i[0] =
    index.i[1] =
    index.i[2] =
-   index.i[3] = reg->SrcRegister.Index;
+   index.i[3] = reg->Register.Index;
 
-   if (reg->SrcRegister.Indirect) {
+   if (reg->Register.Indirect) {
       union spu_exec_channel index2;
       union spu_exec_channel indir_index;
 
       index2.i[0] =
       index2.i[1] =
       index2.i[2] =
-      index2.i[3] = reg->SrcRegisterInd.Index;
+      index2.i[3] = reg->Indirect.Index;
 
-      swizzle = tgsi_util_get_src_register_swizzle(&reg->SrcRegisterInd,
+      swizzle = tgsi_util_get_src_register_swizzle(&reg->Indirect,
                                                    CHAN_X);
       fetch_src_file_channel(
          mach,
-         reg->SrcRegisterInd.File,
+         reg->Indirect.File,
          swizzle,
          &index2,
          &indir_index );
@@ -454,8 +454,8 @@
       index.q = si_a(index.q, indir_index.q);
    }
 
-   if( reg->SrcRegister.Dimension ) {
-      switch( reg->SrcRegister.File ) {
+   if( reg->Register.Dimension ) {
+      switch( reg->Register.File ) {
       case TGSI_FILE_INPUT:
          index.q = si_mpyi(index.q, 17);
          break;
@@ -466,24 +466,24 @@
          ASSERT( 0 );
       }
 
-      index.i[0] += reg->SrcRegisterDim.Index;
-      index.i[1] += reg->SrcRegisterDim.Index;
-      index.i[2] += reg->SrcRegisterDim.Index;
-      index.i[3] += reg->SrcRegisterDim.Index;
+      index.i[0] += reg->Dimension.Index;
+      index.i[1] += reg->Dimension.Index;
+      index.i[2] += reg->Dimension.Index;
+      index.i[3] += reg->Dimension.Index;
 
-      if (reg->SrcRegisterDim.Indirect) {
+      if (reg->Dimension.Indirect) {
          union spu_exec_channel index2;
          union spu_exec_channel indir_index;
 
          index2.i[0] =
          index2.i[1] =
          index2.i[2] =
-         index2.i[3] = reg->SrcRegisterDimInd.Index;
+         index2.i[3] = reg->DimIndirect.Index;
 
-         swizzle = tgsi_util_get_src_register_swizzle( &reg->SrcRegisterDimInd, CHAN_X );
+         swizzle = tgsi_util_get_src_register_swizzle( &reg->DimIndirect, CHAN_X );
          fetch_src_file_channel(
             mach,
-            reg->SrcRegisterDimInd.File,
+            reg->DimIndirect.File,
             swizzle,
             &index2,
             &indir_index );
@@ -495,7 +495,7 @@
    swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index );
    fetch_src_file_channel(
       mach,
-      reg->SrcRegister.File,
+      reg->Register.File,
       swizzle,
       &index,
       chan );
@@ -517,7 +517,7 @@
       break;
    }
 
-   if (reg->SrcRegisterExtMod.Complement) {
+   if (reg->RegisterExtMod.Complement) {
       chan->q = si_fs(mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].q, chan->q);
    }
 }
@@ -532,21 +532,21 @@
 {
    union spu_exec_channel *dst;
 
-   switch( reg->DstRegister.File ) {
+   switch( reg->Register.File ) {
    case TGSI_FILE_NULL:
       return;
 
    case TGSI_FILE_OUTPUT:
       dst = &mach->Outputs[mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0]
-                           + reg->DstRegister.Index].xyzw[chan_index];
+                           + reg->Register.Index].xyzw[chan_index];
       break;
 
    case TGSI_FILE_TEMPORARY:
-      dst = &mach->Temps[reg->DstRegister.Index].xyzw[chan_index];
+      dst = &mach->Temps[reg->Register.Index].xyzw[chan_index];
       break;
 
    case TGSI_FILE_ADDRESS:
-      dst = &mach->Addrs[reg->DstRegister.Index].xyzw[chan_index];
+      dst = &mach->Addrs[reg->Register.Index].xyzw[chan_index];
       break;
 
    default:
@@ -583,10 +583,10 @@
 }
 
 #define FETCH(VAL,INDEX,CHAN)\
-    fetch_source (mach, VAL, &inst->FullSrcRegisters[INDEX], CHAN)
+    fetch_source (mach, VAL, &inst->Src[INDEX], CHAN)
 
 #define STORE(VAL,INDEX,CHAN)\
-    store_dest (mach, VAL, &inst->FullDstRegisters[INDEX], inst, CHAN )
+    store_dest (mach, VAL, &inst->Dst[INDEX], inst, CHAN )
 
 
 /**
@@ -612,7 +612,7 @@
 
       /* unswizzle channel */
       swizzle = tgsi_util_get_full_src_register_swizzle (
-                        &inst->FullSrcRegisters[0],
+                        &inst->Src[0],
                         chan_index);
 
       /* check if the component has not been already tested */
@@ -677,7 +677,7 @@
          const struct tgsi_full_instruction *inst,
          boolean biasLod, boolean projected)
 {
-   const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index;
+   const uint unit = inst->Src[1].Register.Index;
    union spu_exec_channel r[8];
    uint chan_index;
    float lodBias;
@@ -833,8 +833,8 @@
          unsigned first, last, mask;
          interpolation_func interp;
 
-         first = decl->DeclarationRange.First;
-         last = decl->DeclarationRange.Last;
+         first = decl->Range.First;
+         last = decl->Range.Last;
          mask = decl->Declaration.UsageMask;
 
          switch( decl->Declaration.Interpolate ) {
@@ -1681,7 +1681,7 @@
       }
       break;
 
-   case TGSI_OPCODE_SHR:
+   case TGSI_OPCODE_ISHR:
       FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
          FETCH( &r[0], 0, chan_index );
          FETCH( &r[1], 1, chan_index );
diff --git a/src/gallium/drivers/cell/spu/spu_util.c b/src/gallium/drivers/cell/spu/spu_util.c
index c2c32b2..24057e2 100644
--- a/src/gallium/drivers/cell/spu/spu_util.c
+++ b/src/gallium/drivers/cell/spu/spu_util.c
@@ -33,7 +33,7 @@
    unsigned component )
 {
    return tgsi_util_get_src_register_swizzle(
-      reg->SrcRegister,
+      reg->Register,
       component );
 }
 
@@ -45,10 +45,10 @@
 {
    unsigned sign_mode;
 
-   if( reg->SrcRegisterExtMod.Absolute ) {
+   if( reg->RegisterExtMod.Absolute ) {
       /* Consider only the post-abs negation. */
 
-      if( reg->SrcRegisterExtMod.Negate ) {
+      if( reg->RegisterExtMod.Negate ) {
          sign_mode = TGSI_UTIL_SIGN_SET;
       }
       else {
@@ -60,8 +60,8 @@
 
       unsigned negate;
 
-      negate = reg->SrcRegister.Negate;
-      if( reg->SrcRegisterExtMod.Negate ) {
+      negate = reg->Register.Negate;
+      if( reg->RegisterExtMod.Negate ) {
          negate = !negate;
       }
 
diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c
index 37184ea..46e4338 100644
--- a/src/gallium/drivers/failover/fo_context.c
+++ b/src/gallium/drivers/failover/fo_context.c
@@ -44,11 +44,19 @@
 }
 
 
+void failover_fail_over( struct failover_context *failover )
+{
+   failover->dirty = TRUE;
+   failover->mode = FO_SW;
+}
 
-static boolean failover_draw_elements( struct pipe_context *pipe,
-				       struct pipe_buffer *indexBuffer,
-				       unsigned indexSize,
-				       unsigned prim, unsigned start, unsigned count)
+
+static void failover_draw_elements( struct pipe_context *pipe,
+                                    struct pipe_buffer *indexBuffer,
+                                    unsigned indexSize,
+                                    unsigned prim, 
+                                    unsigned start, 
+                                    unsigned count)
 {
    struct failover_context *failover = failover_context( pipe );
 
@@ -62,24 +70,22 @@
    /* Try hardware:
     */
    if (failover->mode == FO_HW) {
-      if (!failover->hw->draw_elements( failover->hw, 
-					indexBuffer, 
-					indexSize, 
-					prim, 
-					start, 
-					count )) {
-
-	 failover->hw->flush( failover->hw, ~0, NULL );
-	 failover->mode = FO_SW;
-      }
+      failover->hw->draw_elements( failover->hw, 
+                                   indexBuffer, 
+                                   indexSize, 
+                                   prim, 
+                                   start, 
+                                   count );
    }
 
    /* Possibly try software:
     */
    if (failover->mode == FO_SW) {
 
-      if (failover->dirty) 
+      if (failover->dirty) {
+         failover->hw->flush( failover->hw, ~0, NULL );
 	 failover_state_emit( failover );
+      }
 
       failover->sw->draw_elements( failover->sw, 
 				   indexBuffer, 
@@ -94,15 +100,13 @@
        */
       failover->sw->flush( failover->sw, ~0, NULL );
    }
-
-   return TRUE;
 }
 
 
-static boolean failover_draw_arrays( struct pipe_context *pipe,
+static void failover_draw_arrays( struct pipe_context *pipe,
 				     unsigned prim, unsigned start, unsigned count)
 {
-   return failover_draw_elements(pipe, NULL, 0, prim, start, count);
+   failover_draw_elements(pipe, NULL, 0, prim, start, count);
 }
 
 static unsigned int
diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h
index 9ba86ba..1493937 100644
--- a/src/gallium/drivers/failover/fo_context.h
+++ b/src/gallium/drivers/failover/fo_context.h
@@ -72,6 +72,7 @@
     */
    const struct fo_state     *blend;
    const struct fo_state     *sampler[PIPE_MAX_SAMPLERS];
+   const struct fo_state     *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS];
    const struct fo_state     *depth_stencil;
    const struct fo_state     *rasterizer;
    const struct fo_state     *fragment_shader;
@@ -83,6 +84,7 @@
    struct pipe_poly_stipple poly_stipple;
    struct pipe_scissor_state scissor;
    struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
+   struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
    struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS];
@@ -92,11 +94,15 @@
 
    void *sw_sampler_state[PIPE_MAX_SAMPLERS];
    void *hw_sampler_state[PIPE_MAX_SAMPLERS];
+   void *sw_vertex_sampler_state[PIPE_MAX_VERTEX_SAMPLERS];
+   void *hw_vertex_sampler_state[PIPE_MAX_VERTEX_SAMPLERS];
 
    unsigned dirty;
 
    unsigned num_samplers;
+   unsigned num_vertex_samplers;
    unsigned num_textures;
+   unsigned num_vertex_textures;
 
    unsigned mode;
    struct pipe_context *hw;
diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c
index c8eb926..3f5f556 100644
--- a/src/gallium/drivers/failover/fo_state.c
+++ b/src/gallium/drivers/failover/fo_state.c
@@ -322,8 +322,9 @@
 }
 
 static void
-failover_bind_sampler_states(struct pipe_context *pipe,
-                             unsigned num, void **sampler)
+failover_bind_fragment_sampler_states(struct pipe_context *pipe,
+                                      unsigned num,
+                                      void **sampler)
 {
    struct failover_context *failover = failover_context(pipe);
    struct fo_state *state = (struct fo_state*)sampler;
@@ -339,10 +340,40 @@
    }
    failover->dirty |= FO_NEW_SAMPLER;
    failover->num_samplers = num;
-   failover->sw->bind_sampler_states(failover->sw, num,
-                                     failover->sw_sampler_state);
-   failover->hw->bind_sampler_states(failover->hw, num,
-                                     failover->hw_sampler_state);
+   failover->sw->bind_fragment_sampler_states(failover->sw, num,
+                                              failover->sw_sampler_state);
+   failover->hw->bind_fragment_sampler_states(failover->hw, num,
+                                              failover->hw_sampler_state);
+}
+
+static void
+failover_bind_vertex_sampler_states(struct pipe_context *pipe,
+                                    unsigned num_samplers,
+                                    void **samplers)
+{
+   struct failover_context *failover = failover_context(pipe);
+   struct fo_state *state = (struct fo_state*)samplers;
+   uint i;
+
+   assert(num_samplers <= PIPE_MAX_VERTEX_SAMPLERS);
+
+   /* Check for no-op */
+   if (num_samplers == failover->num_vertex_samplers &&
+       !memcmp(failover->vertex_samplers, samplers, num_samplers * sizeof(void *))) {
+      return;
+   }
+   for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+      failover->sw_vertex_sampler_state[i] = i < num_samplers ? state[i].sw_state : NULL;
+      failover->hw_vertex_sampler_state[i] = i < num_samplers ? state[i].hw_state : NULL;
+   }
+   failover->dirty |= FO_NEW_SAMPLER;
+   failover->num_vertex_samplers = num_samplers;
+   failover->sw->bind_vertex_sampler_states(failover->sw,
+                                            num_samplers,
+                                            failover->sw_vertex_sampler_state);
+   failover->hw->bind_vertex_sampler_states(failover->hw,
+                                            num_samplers,
+                                            failover->hw_vertex_sampler_state);
 }
 
 static void
@@ -360,9 +391,9 @@
 
 
 static void
-failover_set_sampler_textures(struct pipe_context *pipe,
-                              unsigned num,
-                              struct pipe_texture **texture)
+failover_set_fragment_sampler_textures(struct pipe_context *pipe,
+                                       unsigned num,
+                                       struct pipe_texture **texture)
 {
    struct failover_context *failover = failover_context(pipe);
    uint i;
@@ -381,8 +412,38 @@
                              NULL);
    failover->dirty |= FO_NEW_TEXTURE;
    failover->num_textures = num;
-   failover->sw->set_sampler_textures( failover->sw, num, texture );
-   failover->hw->set_sampler_textures( failover->hw, num, texture );
+   failover->sw->set_fragment_sampler_textures( failover->sw, num, texture );
+   failover->hw->set_fragment_sampler_textures( failover->hw, num, texture );
+}
+
+
+static void
+failover_set_vertex_sampler_textures(struct pipe_context *pipe,
+                                     unsigned num_textures,
+                                     struct pipe_texture **textures)
+{
+   struct failover_context *failover = failover_context(pipe);
+   uint i;
+
+   assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS);
+
+   /* Check for no-op */
+   if (num_textures == failover->num_vertex_textures &&
+       !memcmp(failover->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) {
+      return;
+   }
+   for (i = 0; i < num_textures; i++) {
+      pipe_texture_reference((struct pipe_texture **)&failover->vertex_textures[i],
+                             textures[i]);
+   }
+   for (i = num_textures; i < failover->num_vertex_textures; i++) {
+      pipe_texture_reference((struct pipe_texture **)&failover->vertex_textures[i],
+                             NULL);
+   }
+   failover->dirty |= FO_NEW_TEXTURE;
+   failover->num_vertex_textures = num_textures;
+   failover->sw->set_vertex_sampler_textures(failover->sw, num_textures, textures);
+   failover->hw->set_vertex_sampler_textures(failover->hw, num_textures, textures);
 }
 
 
@@ -453,7 +514,8 @@
    failover->pipe.bind_blend_state   = failover_bind_blend_state;
    failover->pipe.delete_blend_state = failover_delete_blend_state;
    failover->pipe.create_sampler_state = failover_create_sampler_state;
-   failover->pipe.bind_sampler_states  = failover_bind_sampler_states;
+   failover->pipe.bind_fragment_sampler_states  = failover_bind_fragment_sampler_states;
+   failover->pipe.bind_vertex_sampler_states  = failover_bind_vertex_sampler_states;
    failover->pipe.delete_sampler_state = failover_delete_sampler_state;
    failover->pipe.create_depth_stencil_alpha_state = failover_create_depth_stencil_state;
    failover->pipe.bind_depth_stencil_alpha_state   = failover_bind_depth_stencil_state;
@@ -473,7 +535,8 @@
    failover->pipe.set_framebuffer_state = failover_set_framebuffer_state;
    failover->pipe.set_polygon_stipple = failover_set_polygon_stipple;
    failover->pipe.set_scissor_state = failover_set_scissor_state;
-   failover->pipe.set_sampler_textures = failover_set_sampler_textures;
+   failover->pipe.set_fragment_sampler_textures = failover_set_fragment_sampler_textures;
+   failover->pipe.set_vertex_sampler_textures = failover_set_vertex_sampler_textures;
    failover->pipe.set_viewport_state = failover_set_viewport_state;
    failover->pipe.set_vertex_buffers = failover_set_vertex_buffers;
    failover->pipe.set_vertex_elements = failover_set_vertex_elements;
diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c
index bd4fce9..a3341e3 100644
--- a/src/gallium/drivers/failover/fo_state_emit.c
+++ b/src/gallium/drivers/failover/fo_state_emit.c
@@ -92,13 +92,19 @@
       failover->sw->set_viewport_state( failover->sw, &failover->viewport );
 
    if (failover->dirty & FO_NEW_SAMPLER) {
-      failover->sw->bind_sampler_states( failover->sw, failover->num_samplers,
-                                         failover->sw_sampler_state );
+      failover->sw->bind_fragment_sampler_states( failover->sw, failover->num_samplers,
+                                                  failover->sw_sampler_state );
+      failover->sw->bind_vertex_sampler_states(failover->sw,
+                                               failover->num_vertex_samplers,
+                                               failover->sw_vertex_sampler_state);
    }
 
    if (failover->dirty & FO_NEW_TEXTURE) {
-      failover->sw->set_sampler_textures( failover->sw, failover->num_textures, 
-                                          failover->texture );
+      failover->sw->set_fragment_sampler_textures( failover->sw, failover->num_textures, 
+                                                   failover->texture );
+      failover->sw->set_vertex_sampler_textures(failover->sw,
+                                                failover->num_vertex_textures, 
+                                                failover->vertex_textures);
    }
 
    if (failover->dirty & FO_NEW_VERTEX_BUFFER) {
diff --git a/src/gallium/drivers/failover/fo_winsys.h b/src/gallium/drivers/failover/fo_winsys.h
index a8ce997..533122b 100644
--- a/src/gallium/drivers/failover/fo_winsys.h
+++ b/src/gallium/drivers/failover/fo_winsys.h
@@ -36,10 +36,13 @@
 
 
 struct pipe_context;
+struct failover_context;
 
 
 struct pipe_context *failover_create( struct pipe_context *hw,
 				      struct pipe_context *sw );
 
 
+void failover_fail_over( struct failover_context *failover );
+
 #endif /* FO_WINSYS_H */
diff --git a/src/gallium/drivers/i915/i915_buffer.c b/src/gallium/drivers/i915/i915_buffer.c
index effeba1..6699647 100644
--- a/src/gallium/drivers/i915/i915_buffer.c
+++ b/src/gallium/drivers/i915/i915_buffer.c
@@ -111,6 +111,7 @@
 {
    struct i915_buffer *buf = i915_buffer(buffer);
    assert(!buf->ibuf);
+   (void) buf;
 }
 
 static void
diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c
index e745f33..89feead 100644
--- a/src/gallium/drivers/i915/i915_context.c
+++ b/src/gallium/drivers/i915/i915_context.c
@@ -45,7 +45,7 @@
  */
 
 
-static boolean
+static void
 i915_draw_range_elements(struct pipe_context *pipe,
                          struct pipe_buffer *indexBuffer,
                          unsigned indexSize,
@@ -84,7 +84,7 @@
    }
 
 
-   draw_set_mapped_constant_buffer(draw,
+   draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX,
                                    i915->current.constants[PIPE_SHADER_VERTEX],
                                    (i915->current.num_user_constants[PIPE_SHADER_VERTEX] * 
                                       4 * sizeof(float)));
@@ -106,27 +106,25 @@
       pipe_buffer_unmap(pipe->screen, indexBuffer);
       draw_set_mapped_element_buffer_range(draw, 0, start, start + count - 1, NULL);
    }
-
-   return TRUE;
 }
 
-static boolean
+static void
 i915_draw_elements(struct pipe_context *pipe,
                    struct pipe_buffer *indexBuffer,
                    unsigned indexSize,
                    unsigned prim, unsigned start, unsigned count)
 {
-   return i915_draw_range_elements(pipe, indexBuffer,
-                                   indexSize,
-                                   0, 0xffffffff,
-                                   prim, start, count);
+   i915_draw_range_elements(pipe, indexBuffer,
+                            indexSize,
+                            0, 0xffffffff,
+                            prim, start, count);
 }
 
-static boolean
+static void
 i915_draw_arrays(struct pipe_context *pipe,
                  unsigned prim, unsigned start, unsigned count)
 {
-   return i915_draw_elements(pipe, NULL, 0, prim, start, count);
+   i915_draw_elements(pipe, NULL, 0, prim, start, count);
 }
 
 
@@ -155,15 +153,11 @@
 i915_is_buffer_referenced(struct pipe_context *pipe,
                           struct pipe_buffer *buf)
 {
-   /**
-    * FIXME: Return the corrent result. We can't alays return referenced
-    *        since it causes a double flush within the vbo module.
+   /*
+    * Since we never expose hardware buffers to the state tracker
+    * they can never be referenced, so this isn't a lie
     */
-#if 0
-   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
-#else
    return 0;
-#endif
 }
 
 
diff --git a/src/gallium/drivers/i915/i915_debug.c b/src/gallium/drivers/i915/i915_debug.c
index e6640e5..c6e6d6f 100644
--- a/src/gallium/drivers/i915/i915_debug.c
+++ b/src/gallium/drivers/i915/i915_debug.c
@@ -851,6 +851,7 @@
       default:
 	 return debug(stream, "", 0);
       }
+      break;
    default:
       assert(0);
       return 0;
diff --git a/src/gallium/drivers/i915/i915_fpc_translate.c b/src/gallium/drivers/i915/i915_fpc_translate.c
index 379d47e..25c5321 100644
--- a/src/gallium/drivers/i915/i915_fpc_translate.c
+++ b/src/gallium/drivers/i915/i915_fpc_translate.c
@@ -143,12 +143,12 @@
 src_vector(struct i915_fp_compile *p,
            const struct tgsi_full_src_register *source)
 {
-   uint index = source->SrcRegister.Index;
+   uint index = source->Register.Index;
    uint src = 0, sem_name, sem_ind;
 
-   switch (source->SrcRegister.File) {
+   switch (source->Register.File) {
    case TGSI_FILE_TEMPORARY:
-      if (source->SrcRegister.Index >= I915_MAX_TEMPORARY) {
+      if (source->Register.Index >= I915_MAX_TEMPORARY) {
          i915_program_error(p, "Exceeded max temporary reg");
          return 0;
       }
@@ -215,26 +215,25 @@
    }
 
    src = swizzle(src,
-		 source->SrcRegister.SwizzleX,
-		 source->SrcRegister.SwizzleY,
-		 source->SrcRegister.SwizzleZ,
-		 source->SrcRegister.SwizzleW);
+		 source->Register.SwizzleX,
+		 source->Register.SwizzleY,
+		 source->Register.SwizzleZ,
+		 source->Register.SwizzleW);
 
 
    /* There's both negate-all-components and per-component negation.
     * Try to handle both here.
     */
    {
-      int n = source->SrcRegister.Negate;
+      int n = source->Register.Negate;
       src = negate(src, n, n, n, n);
    }
 
-   /* no abs() or post-abs negation */
+   /* no abs() */
 #if 0
    /* XXX assertions disabled to allow arbfplight.c to run */
    /* XXX enable these assertions, or fix things */
-   assert(!source->SrcRegisterExtMod.Absolute);
-   assert(!source->SrcRegisterExtMod.Negate);
+   assert(!source->Register.Absolute);
 #endif
    return src;
 }
@@ -247,10 +246,10 @@
 get_result_vector(struct i915_fp_compile *p,
                   const struct tgsi_full_dst_register *dest)
 {
-   switch (dest->DstRegister.File) {
+   switch (dest->Register.File) {
    case TGSI_FILE_OUTPUT:
       {
-         uint sem_name = p->shader->info.output_semantic_name[dest->DstRegister.Index];
+         uint sem_name = p->shader->info.output_semantic_name[dest->Register.Index];
          switch (sem_name) {
          case TGSI_SEMANTIC_POSITION:
             return UREG(REG_TYPE_OD, 0);
@@ -262,7 +261,7 @@
          }
       }
    case TGSI_FILE_TEMPORARY:
-      return UREG(REG_TYPE_R, dest->DstRegister.Index);
+      return UREG(REG_TYPE_R, dest->Register.Index);
    default:
       i915_program_error(p, "Bad inst->DstReg.File");
       return 0;
@@ -277,7 +276,7 @@
 get_result_flags(const struct tgsi_full_instruction *inst)
 {
    const uint writeMask
-      = inst->FullDstRegisters[0].DstRegister.WriteMask;
+      = inst->Dst[0].Register.WriteMask;
    uint flags = 0x0;
 
    if (inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE)
@@ -339,14 +338,14 @@
          const struct tgsi_full_instruction *inst,
          uint opcode)
 {
-   uint texture = inst->InstructionExtTexture.Texture;
-   uint unit = inst->FullSrcRegisters[1].SrcRegister.Index;
+   uint texture = inst->Texture.Texture;
+   uint unit = inst->Src[1].Register.Index;
    uint tex = translate_tex_src_target( p, texture );
    uint sampler = i915_emit_decl(p, REG_TYPE_S, unit, tex);
-   uint coord = src_vector( p, &inst->FullSrcRegisters[0]);
+   uint coord = src_vector( p, &inst->Src[0]);
 
    i915_emit_texld( p,
-                    get_result_vector( p, &inst->FullDstRegisters[0] ),
+                    get_result_vector( p, &inst->Dst[0] ),
                     get_result_flags( inst ),
                     sampler,
                     coord,
@@ -368,13 +367,13 @@
 
    assert(numArgs <= 3);
 
-   arg1 = (numArgs < 1) ? 0 : src_vector( p, &inst->FullSrcRegisters[0] );
-   arg2 = (numArgs < 2) ? 0 : src_vector( p, &inst->FullSrcRegisters[1] );
-   arg3 = (numArgs < 3) ? 0 : src_vector( p, &inst->FullSrcRegisters[2] );
+   arg1 = (numArgs < 1) ? 0 : src_vector( p, &inst->Src[0] );
+   arg2 = (numArgs < 2) ? 0 : src_vector( p, &inst->Src[1] );
+   arg3 = (numArgs < 3) ? 0 : src_vector( p, &inst->Src[2] );
 
    i915_emit_arith( p,
                     opcode,
-                    get_result_vector( p, &inst->FullDstRegisters[0]),
+                    get_result_vector( p, &inst->Dst[0]),
                     get_result_flags( inst ), 0,
                     arg1,
                     arg2,
@@ -394,8 +393,8 @@
 
    /* transpose first two registers */
    inst2 = *inst;
-   inst2.FullSrcRegisters[0] = inst->FullSrcRegisters[1];
-   inst2.FullSrcRegisters[1] = inst->FullSrcRegisters[0];
+   inst2.Src[0] = inst->Src[1];
+   inst2.Src[1] = inst->Src[0];
 
    emit_simple_arith(p, &inst2, opcode, numArgs);
 }
@@ -424,10 +423,10 @@
 
    switch (inst->Instruction.Opcode) {
    case TGSI_OPCODE_ABS:
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
+      src0 = src_vector(p, &inst->Src[0]);
       i915_emit_arith(p,
                       A0_MAX,
-                      get_result_vector(p, &inst->FullDstRegisters[0]),
+                      get_result_vector(p, &inst->Dst[0]),
                       get_result_flags(inst), 0,
                       src0, negate(src0, 1, 1, 1, 1), 0);
       break;
@@ -437,17 +436,17 @@
       break;
 
    case TGSI_OPCODE_CMP:
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
-      src1 = src_vector(p, &inst->FullSrcRegisters[1]);
-      src2 = src_vector(p, &inst->FullSrcRegisters[2]);
+      src0 = src_vector(p, &inst->Src[0]);
+      src1 = src_vector(p, &inst->Src[1]);
+      src2 = src_vector(p, &inst->Src[2]);
       i915_emit_arith(p, A0_CMP, 
-                      get_result_vector(p, &inst->FullDstRegisters[0]),
+                      get_result_vector(p, &inst->Dst[0]),
                       get_result_flags(inst), 
                       0, src0, src2, src1);   /* NOTE: order of src2, src1 */
       break;
 
    case TGSI_OPCODE_COS:
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
+      src0 = src_vector(p, &inst->Src[0]);
       tmp = i915_get_utemp(p);
 
       i915_emit_arith(p,
@@ -490,7 +489,7 @@
 
       i915_emit_arith(p,
                       A0_DP4,
-                      get_result_vector(p, &inst->FullDstRegisters[0]),
+                      get_result_vector(p, &inst->Dst[0]),
                       get_result_flags(inst), 0,
                       swizzle(tmp, ONE, Z, Y, X),
                       i915_emit_const4fv(p, cos_constants), 0);
@@ -505,19 +504,19 @@
       break;
 
    case TGSI_OPCODE_DPH:
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
-      src1 = src_vector(p, &inst->FullSrcRegisters[1]);
+      src0 = src_vector(p, &inst->Src[0]);
+      src1 = src_vector(p, &inst->Src[1]);
 
       i915_emit_arith(p,
                       A0_DP4,
-                      get_result_vector(p, &inst->FullDstRegisters[0]),
+                      get_result_vector(p, &inst->Dst[0]),
                       get_result_flags(inst), 0,
                       swizzle(src0, X, Y, Z, ONE), src1, 0);
       break;
 
    case TGSI_OPCODE_DST:
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
-      src1 = src_vector(p, &inst->FullSrcRegisters[1]);
+      src0 = src_vector(p, &inst->Src[0]);
+      src1 = src_vector(p, &inst->Src[1]);
 
       /* result[0] = 1    * 1;
        * result[1] = a[1] * b[1];
@@ -526,7 +525,7 @@
        */
       i915_emit_arith(p,
                       A0_MUL,
-                      get_result_vector(p, &inst->FullDstRegisters[0]),
+                      get_result_vector(p, &inst->Dst[0]),
                       get_result_flags(inst), 0,
                       swizzle(src0, ONE, Y, Z, ONE),
                       swizzle(src1, ONE, Y, ONE, W), 0);
@@ -537,11 +536,11 @@
       break;
 
    case TGSI_OPCODE_EX2:
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
+      src0 = src_vector(p, &inst->Src[0]);
 
       i915_emit_arith(p,
                       A0_EXP,
-                      get_result_vector(p, &inst->FullDstRegisters[0]),
+                      get_result_vector(p, &inst->Dst[0]),
                       get_result_flags(inst), 0,
                       swizzle(src0, X, X, X, X), 0, 0);
       break;
@@ -556,7 +555,7 @@
 
    case TGSI_OPCODE_KIL:
       /* kill if src[0].x < 0 || src[0].y < 0 ... */
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
+      src0 = src_vector(p, &inst->Src[0]);
       tmp = i915_get_utemp(p);
 
       i915_emit_texld(p,
@@ -572,17 +571,17 @@
       break;
 
    case TGSI_OPCODE_LG2:
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
+      src0 = src_vector(p, &inst->Src[0]);
 
       i915_emit_arith(p,
                       A0_LOG,
-                      get_result_vector(p, &inst->FullDstRegisters[0]),
+                      get_result_vector(p, &inst->Dst[0]),
                       get_result_flags(inst), 0,
                       swizzle(src0, X, X, X, X), 0, 0);
       break;
 
    case TGSI_OPCODE_LIT:
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
+      src0 = src_vector(p, &inst->Src[0]);
       tmp = i915_get_utemp(p);
 
       /* tmp = max( a.xyzw, a.00zw )
@@ -606,7 +605,7 @@
                       swizzle(tmp, Y, Y, Y, Y), 0, 0);
 
       i915_emit_arith(p, A0_CMP,
-                      get_result_vector(p, &inst->FullDstRegisters[0]),
+                      get_result_vector(p, &inst->Dst[0]),
                       get_result_flags(inst), 0,
                       negate(swizzle(tmp, ONE, ONE, X, ONE), 0, 0, 1, 0),
                       swizzle(tmp, ONE, X, ZERO, ONE),
@@ -615,9 +614,9 @@
       break;
 
    case TGSI_OPCODE_LRP:
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
-      src1 = src_vector(p, &inst->FullSrcRegisters[1]);
-      src2 = src_vector(p, &inst->FullSrcRegisters[2]);
+      src0 = src_vector(p, &inst->Src[0]);
+      src1 = src_vector(p, &inst->Src[1]);
+      src2 = src_vector(p, &inst->Src[2]);
       flags = get_result_flags(inst);
       tmp = i915_get_utemp(p);
 
@@ -632,7 +631,7 @@
                       flags & A0_DEST_CHANNEL_ALL, 0, src1, src0, src2);
 
       i915_emit_arith(p, A0_MAD,
-                      get_result_vector(p, &inst->FullDstRegisters[0]),
+                      get_result_vector(p, &inst->Dst[0]),
                       flags, 0, negate(src2, 1, 1, 1, 1), src0, tmp);
       break;
 
@@ -645,8 +644,8 @@
       break;
 
    case TGSI_OPCODE_MIN:
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
-      src1 = src_vector(p, &inst->FullSrcRegisters[1]);
+      src0 = src_vector(p, &inst->Src[0]);
+      src1 = src_vector(p, &inst->Src[1]);
       tmp = i915_get_utemp(p);
       flags = get_result_flags(inst);
 
@@ -658,7 +657,7 @@
 
       i915_emit_arith(p,
                       A0_MOV,
-                      get_result_vector(p, &inst->FullDstRegisters[0]),
+                      get_result_vector(p, &inst->Dst[0]),
                       flags, 0, negate(tmp, 1, 1, 1, 1), 0, 0);
       break;
 
@@ -671,8 +670,8 @@
       break;
 
    case TGSI_OPCODE_POW:
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
-      src1 = src_vector(p, &inst->FullSrcRegisters[1]);
+      src0 = src_vector(p, &inst->Src[0]);
+      src1 = src_vector(p, &inst->Src[1]);
       tmp = i915_get_utemp(p);
       flags = get_result_flags(inst);
 
@@ -687,7 +686,7 @@
 
       i915_emit_arith(p,
                       A0_EXP,
-                      get_result_vector(p, &inst->FullDstRegisters[0]),
+                      get_result_vector(p, &inst->Dst[0]),
                       flags, 0, swizzle(tmp, X, X, X, X), 0, 0);
       break;
       
@@ -696,27 +695,27 @@
       break;
       
    case TGSI_OPCODE_RCP:
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
+      src0 = src_vector(p, &inst->Src[0]);
 
       i915_emit_arith(p,
                       A0_RCP,
-                      get_result_vector(p, &inst->FullDstRegisters[0]),
+                      get_result_vector(p, &inst->Dst[0]),
                          get_result_flags(inst), 0,
                       swizzle(src0, X, X, X, X), 0, 0);
       break;
 
    case TGSI_OPCODE_RSQ:
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
+      src0 = src_vector(p, &inst->Src[0]);
 
       i915_emit_arith(p,
                       A0_RSQ,
-                      get_result_vector(p, &inst->FullDstRegisters[0]),
+                      get_result_vector(p, &inst->Dst[0]),
                       get_result_flags(inst), 0,
                       swizzle(src0, X, X, X, X), 0, 0);
       break;
 
    case TGSI_OPCODE_SCS:
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
+      src0 = src_vector(p, &inst->Src[0]);
       tmp = i915_get_utemp(p);
 
       /* 
@@ -739,7 +738,7 @@
                       swizzle(tmp, X, Y, X, Y),
                       swizzle(tmp, X, X, ONE, ONE), 0);
 
-      writemask = inst->FullDstRegisters[0].DstRegister.WriteMask;
+      writemask = inst->Dst[0].Register.WriteMask;
 
       if (writemask & TGSI_WRITEMASK_Y) {
          uint tmp1;
@@ -757,7 +756,7 @@
 
          i915_emit_arith(p,
                          A0_DP4,
-                         get_result_vector(p, &inst->FullDstRegisters[0]),
+                         get_result_vector(p, &inst->Dst[0]),
                          A0_DEST_CHANNEL_Y, 0,
                          swizzle(tmp1, W, Z, Y, X),
                          i915_emit_const4fv(p, sin_constants), 0);
@@ -772,7 +771,7 @@
 
          i915_emit_arith(p,
                          A0_DP4,
-                         get_result_vector(p, &inst->FullDstRegisters[0]),
+                         get_result_vector(p, &inst->Dst[0]),
                          A0_DEST_CHANNEL_X, 0,
                          swizzle(tmp, ONE, Z, Y, X),
                          i915_emit_const4fv(p, cos_constants), 0);
@@ -789,7 +788,7 @@
       break;
 
    case TGSI_OPCODE_SIN:
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
+      src0 = src_vector(p, &inst->Src[0]);
       tmp = i915_get_utemp(p);
 
       i915_emit_arith(p,
@@ -832,7 +831,7 @@
 
       i915_emit_arith(p,
                       A0_DP4,
-                      get_result_vector(p, &inst->FullDstRegisters[0]),
+                      get_result_vector(p, &inst->Dst[0]),
                       get_result_flags(inst), 0,
                       swizzle(tmp, W, Z, Y, X),
                       i915_emit_const4fv(p, sin_constants), 0);
@@ -848,12 +847,12 @@
       break;
 
    case TGSI_OPCODE_SUB:
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
-      src1 = src_vector(p, &inst->FullSrcRegisters[1]);
+      src0 = src_vector(p, &inst->Src[0]);
+      src1 = src_vector(p, &inst->Src[1]);
 
       i915_emit_arith(p,
                       A0_ADD,
-                      get_result_vector(p, &inst->FullDstRegisters[0]),
+                      get_result_vector(p, &inst->Dst[0]),
                       get_result_flags(inst), 0,
                       src0, negate(src1, 1, 1, 1, 1), 0);
       break;
@@ -877,8 +876,8 @@
        *      result.z = src0.x * src1.y - src0.y * src1.x;
        *      result.w = undef;
        */
-      src0 = src_vector(p, &inst->FullSrcRegisters[0]);
-      src1 = src_vector(p, &inst->FullSrcRegisters[1]);
+      src0 = src_vector(p, &inst->Src[0]);
+      src1 = src_vector(p, &inst->Src[1]);
       tmp = i915_get_utemp(p);
 
       i915_emit_arith(p,
@@ -889,7 +888,7 @@
 
       i915_emit_arith(p,
                       A0_MAD,
-                      get_result_vector(p, &inst->FullDstRegisters[0]),
+                      get_result_vector(p, &inst->Dst[0]),
                       get_result_flags(inst), 0,
                       swizzle(src0, Y, Z, X, ONE),
                       swizzle(src1, Z, X, Y, ONE),
@@ -929,8 +928,8 @@
          if (parse.FullToken.FullDeclaration.Declaration.File
                   == TGSI_FILE_CONSTANT) {
             uint i;
-            for (i = parse.FullToken.FullDeclaration.DeclarationRange.First;
-                 i <= parse.FullToken.FullDeclaration.DeclarationRange.Last;
+            for (i = parse.FullToken.FullDeclaration.Range.First;
+                 i <= parse.FullToken.FullDeclaration.Range.Last;
                  i++) {
                assert(ifs->constant_flags[i] == 0x0);
                ifs->constant_flags[i] = I915_CONSTFLAG_USER;
@@ -940,8 +939,8 @@
          else if (parse.FullToken.FullDeclaration.Declaration.File
                   == TGSI_FILE_TEMPORARY) {
             uint i;
-            for (i = parse.FullToken.FullDeclaration.DeclarationRange.First;
-                 i <= parse.FullToken.FullDeclaration.DeclarationRange.Last;
+            for (i = parse.FullToken.FullDeclaration.Range.First;
+                 i <= parse.FullToken.FullDeclaration.Range.Last;
                  i++) {
                assert(i < I915_MAX_TEMPORARY);
                /* XXX just use shader->info->file_mask[TGSI_FILE_TEMPORARY] */
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index c66558c..d4ee8f5 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -271,6 +271,7 @@
    default:
       debug_printf("%s: unknown pci id 0x%x, cannot create screen\n", 
                    __FUNCTION__, pci_id);
+      FREE(is);
       return NULL;
    }
 
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index 7d48e6e..5f5b6f8 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -58,8 +58,10 @@
       return TEXCOORDMODE_CLAMP_EDGE;
    case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
       return TEXCOORDMODE_CLAMP_BORDER;
-//   case PIPE_TEX_WRAP_MIRRORED_REPEAT:
-//      return TEXCOORDMODE_MIRROR;
+   /*         
+   case PIPE_TEX_WRAP_MIRRORED_REPEAT:
+      return TEXCOORDMODE_MIRROR;
+    */
    default:
       return TEXCOORDMODE_WRAP;
    }
@@ -72,8 +74,6 @@
       return FILTER_NEAREST;
    case PIPE_TEX_FILTER_LINEAR:
       return FILTER_LINEAR;
-   case PIPE_TEX_FILTER_ANISO:
-      return FILTER_ANISOTROPIC;
    default:
       assert(0);
       return FILTER_NEAREST;
@@ -219,6 +219,9 @@
    minFilt = translate_img_filter( sampler->min_img_filter );
    magFilt = translate_img_filter( sampler->mag_img_filter );
    
+   if (sampler->max_anisotropy > 1.0)
+      minFilt = magFilt = FILTER_ANISOTROPIC;
+
    if (sampler->max_anisotropy > 2.0) {
       cso->state[0] |= SS2_MAX_ANISO_4;
    }
@@ -750,22 +753,15 @@
 }
 
 
-static void i915_set_edgeflags(struct pipe_context *pipe,
-                               const unsigned *bitfield)
-{
-   /* TODO do something here */
-}
-
 void
 i915_init_state_functions( struct i915_context *i915 )
 {
-   i915->base.set_edgeflags = i915_set_edgeflags;
    i915->base.create_blend_state = i915_create_blend_state;
    i915->base.bind_blend_state = i915_bind_blend_state;
    i915->base.delete_blend_state = i915_delete_blend_state;
 
    i915->base.create_sampler_state = i915_create_sampler_state;
-   i915->base.bind_sampler_states = i915_bind_sampler_states;
+   i915->base.bind_fragment_sampler_states = i915_bind_sampler_states;
    i915->base.delete_sampler_state = i915_delete_sampler_state;
 
    i915->base.create_depth_stencil_alpha_state = i915_create_depth_stencil_state;
@@ -789,7 +785,7 @@
 
    i915->base.set_polygon_stipple = i915_set_polygon_stipple;
    i915->base.set_scissor_state = i915_set_scissor_state;
-   i915->base.set_sampler_textures = i915_set_sampler_textures;
+   i915->base.set_fragment_sampler_textures = i915_set_sampler_textures;
    i915->base.set_viewport_state = i915_set_viewport_state;
    i915->base.set_vertex_buffers = i915_set_vertex_buffers;
    i915->base.set_vertex_elements = i915_set_vertex_elements;
diff --git a/src/gallium/drivers/i915/i915_state_derived.c b/src/gallium/drivers/i915/i915_state_derived.c
index 178d4e8..03dd509 100644
--- a/src/gallium/drivers/i915/i915_state_derived.c
+++ b/src/gallium/drivers/i915/i915_state_derived.c
@@ -84,7 +84,7 @@
 
    
    /* pos */
-   src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_POSITION, 0);
+   src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_POSITION, 0);
    if (needW) {
       draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src);
       vinfo.hwfmt[0] |= S4_VFMT_XYZW;
@@ -101,21 +101,21 @@
 
    /* primary color */
    if (colors[0]) {
-      src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_COLOR, 0);
+      src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 0);
       draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src);
       vinfo.hwfmt[0] |= S4_VFMT_COLOR;
    }
 
    /* secondary color */
    if (colors[1]) {
-      src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_COLOR, 1);
+      src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 1);
       draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src);
       vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG;
    }
 
    /* fog coord, not fog blend factor */
    if (fog) {
-      src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_FOG, 0);
+      src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FOG, 0);
       draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src);
       vinfo.hwfmt[0] |= S4_VFMT_FOG_PARAM;
    }
@@ -125,7 +125,7 @@
       uint hwtc;
       if (texCoords[i]) {
          hwtc = TEXCOORDFMT_4D;
-         src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_GENERIC, i);
+         src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_GENERIC, i);
          draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
       }
       else {
diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c
index c5e9084..cbac417 100644
--- a/src/gallium/drivers/i915/i915_state_sampler.c
+++ b/src/gallium/drivers/i915/i915_state_sampler.c
@@ -231,7 +231,7 @@
 {
    const struct pipe_texture *pt = &tex->base;
    uint format, pitch;
-   const uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0];
+   const uint width = pt->width0, height = pt->height0, depth = pt->depth0;
    const uint num_levels = pt->last_level;
    unsigned max_lod = num_levels * 4;
    unsigned tiled = MS3_USE_FENCE_REGS;
diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c
index ab8331f..c693eb3 100644
--- a/src/gallium/drivers/i915/i915_surface.c
+++ b/src/gallium/drivers/i915/i915_surface.c
@@ -32,6 +32,7 @@
 #include "pipe/p_inlines.h"
 #include "pipe/p_inlines.h"
 #include "pipe/internal/p_winsys_screen.h"
+#include "util/u_format.h"
 #include "util/u_tile.h"
 #include "util/u_rect.h"
 
@@ -48,17 +49,19 @@
 {
    struct i915_texture *dst_tex = (struct i915_texture *)dst->texture;
    struct i915_texture *src_tex = (struct i915_texture *)src->texture;
+   struct pipe_texture *dpt = &dst_tex->base;
+   struct pipe_texture *spt = &src_tex->base;
 
    assert( dst != src );
-   assert( dst_tex->base.block.size == src_tex->base.block.size );
-   assert( dst_tex->base.block.width == src_tex->base.block.height );
-   assert( dst_tex->base.block.height == src_tex->base.block.height );
-   assert( dst_tex->base.block.width == 1 );
-   assert( dst_tex->base.block.height == 1 );
+   assert( util_format_get_blocksize(dpt->format) == util_format_get_blocksize(spt->format) );
+   assert( util_format_get_blockwidth(dpt->format) == util_format_get_blockwidth(spt->format) );
+   assert( util_format_get_blockheight(dpt->format) == util_format_get_blockheight(spt->format) );
+   assert( util_format_get_blockwidth(dpt->format) == 1 );
+   assert( util_format_get_blockheight(dpt->format) == 1 );
 
    i915_copy_blit( i915_context(pipe),
                    FALSE,
-                   dst_tex->base.block.size,
+                   util_format_get_blocksize(dpt->format),
                    (unsigned short) src_tex->stride, src_tex->buffer, src->offset,
                    (unsigned short) dst_tex->stride, dst_tex->buffer, dst->offset,
                    (short) srcx, (short) srcy, (short) dstx, (short) dsty, (short) width, (short) height );
@@ -72,12 +75,13 @@
 		  unsigned width, unsigned height, unsigned value)
 {
    struct i915_texture *tex = (struct i915_texture *)dst->texture;
+   struct pipe_texture *pt = &tex->base;
 
-   assert(tex->base.block.width == 1);
-   assert(tex->base.block.height == 1);
+   assert(util_format_get_blockwidth(pt->format) == 1);
+   assert(util_format_get_blockheight(pt->format) == 1);
 
    i915_fill_blit( i915_context(pipe),
-                   tex->base.block.size,
+                   util_format_get_blocksize(pt->format),
                    (unsigned short) tex->stride,
                    tex->buffer, dst->offset,
                    (short) dstx, (short) dsty,
diff --git a/src/gallium/drivers/i915/i915_texture.c b/src/gallium/drivers/i915/i915_texture.c
index 286c9ac..50a9e19 100644
--- a/src/gallium/drivers/i915/i915_texture.c
+++ b/src/gallium/drivers/i915/i915_texture.c
@@ -35,6 +35,7 @@
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
 #include "pipe/internal/p_winsys_screen.h"
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 
@@ -74,6 +75,9 @@
    {-1, 1}
 };
 
+/* XXX really need twice the size if x is already pot?
+   Otherwise just use util_next_power_of_two?
+*/
 static unsigned
 power_of_two(unsigned x)
 {
@@ -83,13 +87,6 @@
    return value;
 }
 
-static unsigned
-round_up(unsigned n, unsigned multiple)
-{
-   return (n + multiple - 1) & ~(multiple - 1);
-}
-
-
 /*
  * More advanced helper funcs
  */
@@ -101,17 +98,8 @@
                              unsigned nr_images,
                              unsigned w, unsigned h, unsigned d)
 {
-   struct pipe_texture *pt = &tex->base;
-
    assert(level < PIPE_MAX_TEXTURE_LEVELS);
 
-   pt->width[level] = w;
-   pt->height[level] = h;
-   pt->depth[level] = d;
-   
-   pt->nblocksx[level] = pf_get_nblocksx(&pt->block, w);
-   pt->nblocksy[level] = pf_get_nblocksy(&pt->block, h);
-
    tex->nr_images[level] = nr_images;
 
    /*
@@ -142,7 +130,7 @@
 
    assert(img < tex->nr_images[level]);
 
-   tex->image_offset[level][img] = y * tex->stride + x * tex->base.block.size;
+   tex->image_offset[level][img] = y * tex->stride + x * util_format_get_blocksize(tex->base.format);
 
    /*
    printf("%s level %d img %d pos %d,%d image_offset %x\n",
@@ -164,28 +152,28 @@
 {
    struct pipe_texture *pt = &tex->base;
 
-   if (pt->last_level > 0 || pt->block.size != 4)
+   if (pt->last_level > 0 || util_format_get_blocksize(pt->format) != 4)
       return FALSE;
 
    i915_miptree_set_level_info(tex, 0, 1,
-                               tex->base.width[0],
-                               tex->base.height[0],
+                               pt->width0,
+                               pt->height0,
                                1);
    i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
 
-   if (tex->base.width[0] >= 240) {
-      tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
-      tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
+   if (pt->width0 >= 240) {
+      tex->stride = power_of_two(util_format_get_stride(pt->format, pt->width0));
+      tex->total_nblocksy = align(util_format_get_nblocksy(pt->format, pt->height0), 8);
       tex->hw_tiled = INTEL_TILE_X;
-   } else if (tex->base.width[0] == 64 && tex->base.height[0] == 64) {
-      tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
-      tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
+   } else if (pt->width0 == 64 && pt->height0 == 64) {
+      tex->stride = power_of_two(util_format_get_stride(pt->format, pt->width0));
+      tex->total_nblocksy = align(util_format_get_nblocksy(pt->format, pt->height0), 8);
    } else {
       return FALSE;
    }
 
    debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
-      tex->base.width[0], tex->base.height[0], pt->block.size,
+      pt->width0, pt->height0, util_format_get_blocksize(pt->format),
       tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy);
 
    return TRUE;
@@ -199,25 +187,25 @@
 {
    struct pipe_texture *pt = &tex->base;
 
-   if (pt->last_level > 0 || pt->block.size != 4)
+   if (pt->last_level > 0 || util_format_get_blocksize(pt->format) != 4)
       return FALSE;
 
    /* fallback to normal textures for small textures */
-   if (tex->base.width[0] < 240)
+   if (pt->width0 < 240)
       return FALSE;
 
    i915_miptree_set_level_info(tex, 0, 1,
-                               tex->base.width[0],
-                               tex->base.height[0],
+                               pt->width0,
+                               pt->height0,
                                1);
    i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
 
-   tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
-   tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
+   tex->stride = power_of_two(util_format_get_stride(pt->format, pt->width0));
+   tex->total_nblocksy = align(util_format_get_nblocksy(pt->format, pt->height0), 8);
    tex->hw_tiled = INTEL_TILE_X;
 
    debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
-      tex->base.width[0], tex->base.height[0], pt->block.size,
+      pt->width0, pt->height0, util_format_get_blocksize(pt->format),
       tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy);
 
    return TRUE;
@@ -228,36 +216,34 @@
 {
    struct pipe_texture *pt = &tex->base;
    unsigned level;
-   unsigned width = pt->width[0];
-   unsigned height = pt->height[0];
-   unsigned nblocksx = pt->nblocksx[0];
-   unsigned nblocksy = pt->nblocksy[0];
+   unsigned width = pt->width0;
+   unsigned height = pt->height0;
+   unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->width0);
 
    /* used for scanouts that need special layouts */
-   if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+   if (pt->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
       if (i915_scanout_layout(tex))
          return;
 
    /* for shared buffers we use some very like scanout */
-   if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
+   if (pt->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
       if (i915_display_target_layout(tex))
          return;
 
-   tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
+   tex->stride = align(util_format_get_stride(pt->format, pt->width0), 4);
    tex->total_nblocksy = 0;
 
    for (level = 0; level <= pt->last_level; level++) {
       i915_miptree_set_level_info(tex, level, 1, width, height, 1);
       i915_miptree_set_image_offset(tex, level, 0, 0, tex->total_nblocksy);
 
-      nblocksy = round_up(MAX2(2, nblocksy), 2);
+      nblocksy = align(MAX2(2, nblocksy), 2);
 
       tex->total_nblocksy += nblocksy;
 
-      width = minify(width);
-      height = minify(height);
-      nblocksx = pf_get_nblocksx(&pt->block, width);
-      nblocksy = pf_get_nblocksy(&pt->block, height);
+      width = u_minify(width, 1);
+      height = u_minify(height, 1);
+      nblocksy = util_format_get_nblocksy(pt->format, height);
    }
 }
 
@@ -267,16 +253,15 @@
    struct pipe_texture *pt = &tex->base;
    unsigned level;
 
-   unsigned width = pt->width[0];
-   unsigned height = pt->height[0];
-   unsigned depth = pt->depth[0];
-   unsigned nblocksx = pt->nblocksx[0];
-   unsigned nblocksy = pt->nblocksy[0];
+   unsigned width = pt->width0;
+   unsigned height = pt->height0;
+   unsigned depth = pt->depth0;
+   unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->height0);
    unsigned stack_nblocksy = 0;
 
    /* Calculate the size of a single slice. 
     */
-   tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
+   tex->stride = align(util_format_get_stride(pt->format, pt->width0), 4);
 
    /* XXX: hardware expects/requires 9 levels at minimum.
     */
@@ -285,44 +270,41 @@
 
       stack_nblocksy += MAX2(2, nblocksy);
 
-      width = minify(width);
-      height = minify(height);
-      depth = minify(depth);
-      nblocksx = pf_get_nblocksx(&pt->block, width);
-      nblocksy = pf_get_nblocksy(&pt->block, height);
+      width = u_minify(width, 1);
+      height = u_minify(height, 1);
+      nblocksy = util_format_get_nblocksy(pt->format, height);
    }
 
    /* Fixup depth image_offsets: 
     */
-   depth = pt->depth[0];
    for (level = 0; level <= pt->last_level; level++) {
       unsigned i;
       for (i = 0; i < depth; i++) 
          i915_miptree_set_image_offset(tex, level, i, 0, i * stack_nblocksy);
 
-      depth = minify(depth);
+      depth = u_minify(depth, 1);
    }
 
    /* Multiply slice size by texture depth for total size.  It's
     * remarkable how wasteful of memory the i915 texture layouts
     * are.  They are largely fixed in the i945.
     */
-   tex->total_nblocksy = stack_nblocksy * pt->depth[0];
+   tex->total_nblocksy = stack_nblocksy * pt->depth0;
 }
 
 static void
 i915_miptree_layout_cube(struct i915_texture *tex)
 {
    struct pipe_texture *pt = &tex->base;
-   unsigned width = pt->width[0], height = pt->height[0];
-   const unsigned nblocks = pt->nblocksx[0];
+   unsigned width = pt->width0, height = pt->height0;
+   const unsigned nblocks = util_format_get_nblocksx(pt->format, pt->width0);
    unsigned level;
    unsigned face;
 
    assert(width == height); /* cubemap images are square */
 
    /* double pitch for cube layouts */
-   tex->stride = round_up(nblocks * pt->block.size * 2, 4);
+   tex->stride = align(nblocks * util_format_get_blocksize(pt->format) * 2, 4);
    tex->total_nblocksy = nblocks * 4;
 
    for (level = 0; level <= pt->last_level; level++) {
@@ -383,10 +365,10 @@
    unsigned level;
    unsigned x = 0;
    unsigned y = 0;
-   unsigned width = pt->width[0];
-   unsigned height = pt->height[0];
-   unsigned nblocksx = pt->nblocksx[0];
-   unsigned nblocksy = pt->nblocksy[0];
+   unsigned width = pt->width0;
+   unsigned height = pt->height0;
+   unsigned nblocksx = util_format_get_nblocksx(pt->format, pt->width0);
+   unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->height0);
 
    /* used for scanouts that need special layouts */
    if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
@@ -398,7 +380,7 @@
       if (i915_display_target_layout(tex))
          return;
 
-   tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
+   tex->stride = align(util_format_get_stride(pt->format, pt->width0), 4);
 
    /* May need to adjust pitch to accomodate the placement of
     * the 2nd mipmap level.  This occurs when the alignment
@@ -407,11 +389,11 @@
     */
    if (pt->last_level > 0) {
       unsigned mip1_nblocksx 
-         = align(pf_get_nblocksx(&pt->block, minify(width)), align_x)
-         + pf_get_nblocksx(&pt->block, minify(minify(width)));
+         = align(util_format_get_nblocksx(pt->format, u_minify(width, 1)), align_x)
+         + util_format_get_nblocksx(pt->format, u_minify(width, 2));
 
       if (mip1_nblocksx > nblocksx)
-         tex->stride = mip1_nblocksx * pt->block.size;
+         tex->stride = mip1_nblocksx * util_format_get_blocksize(pt->format);
    }
 
    /* Pitch must be a whole number of dwords
@@ -439,10 +421,10 @@
          y += nblocksy;
       }
 
-      width  = minify(width);
-      height = minify(height);
-      nblocksx = pf_get_nblocksx(&pt->block, width);
-      nblocksy = pf_get_nblocksy(&pt->block, height);
+      width  = u_minify(width, 1);
+      height = u_minify(height, 1);
+      nblocksx = util_format_get_nblocksx(pt->format, width);
+      nblocksy = util_format_get_nblocksy(pt->format, height);
    }
 }
 
@@ -450,20 +432,19 @@
 i945_miptree_layout_3d(struct i915_texture *tex)
 {
    struct pipe_texture *pt = &tex->base;
-   unsigned width = pt->width[0];
-   unsigned height = pt->height[0];
-   unsigned depth = pt->depth[0];
-   unsigned nblocksx = pt->nblocksx[0];
-   unsigned nblocksy = pt->nblocksy[0];
+   unsigned width = pt->width0;
+   unsigned height = pt->height0;
+   unsigned depth = pt->depth0;
+   unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->width0);
    unsigned pack_x_pitch, pack_x_nr;
    unsigned pack_y_pitch;
    unsigned level;
 
-   tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
+   tex->stride = align(util_format_get_stride(pt->format, pt->width0), 4);
    tex->total_nblocksy = 0;
 
-   pack_y_pitch = MAX2(pt->nblocksy[0], 2);
-   pack_x_pitch = tex->stride / pt->block.size;
+   pack_y_pitch = MAX2(nblocksy, 2);
+   pack_x_pitch = tex->stride / util_format_get_blocksize(pt->format);
    pack_x_nr = 1;
 
    for (level = 0; level <= pt->last_level; level++) {
@@ -488,18 +469,17 @@
       if (pack_x_pitch > 4) {
          pack_x_pitch >>= 1;
          pack_x_nr <<= 1;
-         assert(pack_x_pitch * pack_x_nr * pt->block.size <= tex->stride);
+         assert(pack_x_pitch * pack_x_nr * util_format_get_blocksize(pt->format) <= tex->stride);
       }
 
       if (pack_y_pitch > 2) {
          pack_y_pitch >>= 1;
       }
 
-      width = minify(width);
-      height = minify(height);
-      depth = minify(depth);
-      nblocksx = pf_get_nblocksx(&pt->block, width);
-      nblocksy = pf_get_nblocksy(&pt->block, height);
+      width = u_minify(width, 1);
+      height = u_minify(height, 1);
+      depth = u_minify(depth, 1);
+      nblocksy = util_format_get_nblocksy(pt->format, height);
    }
 }
 
@@ -509,13 +489,13 @@
    struct pipe_texture *pt = &tex->base;
    unsigned level;
 
-   const unsigned nblocks = pt->nblocksx[0];
+   const unsigned nblocks = util_format_get_nblocksx(pt->format, pt->width0);
    unsigned face;
-   unsigned width = pt->width[0];
-   unsigned height = pt->height[0];
+   unsigned width = pt->width0;
+   unsigned height = pt->height0;
 
    /*
-   printf("%s %i, %i\n", __FUNCTION__, pt->width[0], pt->height[0]);
+   printf("%s %i, %i\n", __FUNCTION__, pt->width0, pt->height0);
    */
 
    assert(width == height); /* cubemap images are square */
@@ -529,9 +509,9 @@
     * or the final row of 4x4, 2x2 and 1x1 faces below this.
     */
    if (nblocks > 32)
-      tex->stride = round_up(nblocks * pt->block.size * 2, 4);
+      tex->stride = align(nblocks * util_format_get_blocksize(pt->format) * 2, 4);
    else
-      tex->stride = 14 * 8 * pt->block.size;
+      tex->stride = 14 * 8 * util_format_get_blocksize(pt->format);
 
    tex->total_nblocksy = nblocks * 4;
 
@@ -651,9 +631,6 @@
    pipe_reference_init(&tex->base.reference, 1);
    tex->base.screen = screen;
 
-   tex->base.nblocksx[0] = pf_get_nblocksx(&tex->base.block, tex->base.width[0]);
-   tex->base.nblocksy[0] = pf_get_nblocksy(&tex->base.block, tex->base.height[0]);
-   
    if (is->is_i945) {
       if (!i945_miptree_layout(tex))
          goto fail;
@@ -667,7 +644,7 @@
 
 
    /* for scanouts and cursors, cursors arn't scanouts */
-   if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY && templat->width[0] != 64)
+   if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY && templat->width0 != 64)
       buf_usage = INTEL_NEW_SCANOUT;
    else
       buf_usage = INTEL_NEW_TEXTURE;
@@ -710,7 +687,7 @@
    /* Only supports one type */
    if (base->target != PIPE_TEXTURE_2D ||
        base->last_level != 0 ||
-       base->depth[0] != 1) {
+       base->depth0 != 1) {
       return NULL;
    }
 
@@ -724,7 +701,7 @@
 
    tex->stride = stride[0];
 
-   i915_miptree_set_level_info(tex, 0, 1, base->width[0], base->height[0], 1);
+   i915_miptree_set_level_info(tex, 0, 1, base->width0, base->height0, 1);
    i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
 
    pipe_buffer_reference(&tex->buffer, buffer);
@@ -788,8 +765,8 @@
       pipe_reference_init(&ps->reference, 1);
       pipe_texture_reference(&ps->texture, pt);
       ps->format = pt->format;
-      ps->width = pt->width[level];
-      ps->height = pt->height[level];
+      ps->width = u_minify(pt->width0, level);
+      ps->height = u_minify(pt->height0, level);
       ps->offset = offset;
       ps->usage = flags;
    }
@@ -835,14 +812,10 @@
    trans = CALLOC_STRUCT(i915_transfer);
    if (trans) {
       pipe_texture_reference(&trans->base.texture, texture);
-      trans->base.format = trans->base.format;
       trans->base.x = x;
       trans->base.y = y;
       trans->base.width = w;
       trans->base.height = h;
-      trans->base.block = texture->block;
-      trans->base.nblocksx = texture->nblocksx[level];
-      trans->base.nblocksy = texture->nblocksy[level];
       trans->base.stride = tex->stride;
       trans->offset = offset;
       trans->base.usage = usage;
@@ -858,6 +831,7 @@
    struct intel_winsys *iws = i915_screen(tex->base.screen)->iws;
    char *map;
    boolean write = FALSE;
+   enum pipe_format format = tex->base.format;
 
    if (transfer->usage & PIPE_TRANSFER_WRITE)
       write = TRUE;
@@ -867,8 +841,8 @@
       return NULL;
 
    return map + i915_transfer(transfer)->offset +
-      transfer->y / transfer->block.height * transfer->stride +
-      transfer->x / transfer->block.width * transfer->block.size;
+      transfer->y / util_format_get_blockheight(format) * transfer->stride +
+      transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
 }
 
 static void
@@ -919,7 +893,7 @@
    /* Only supports one type */
    if (base->target != PIPE_TEXTURE_2D ||
        base->last_level != 0 ||
-       base->depth[0] != 1) {
+       base->depth0 != 1) {
       return NULL;
    }
 
@@ -933,7 +907,7 @@
 
    tex->stride = stride;
 
-   i915_miptree_set_level_info(tex, 0, 1, base->width[0], base->height[0], 1);
+   i915_miptree_set_level_info(tex, 0, 1, base->width0, base->height0, 1);
    i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
 
    tex->buffer = buffer;
diff --git a/src/gallium/drivers/i915/intel_winsys.h b/src/gallium/drivers/i915/intel_winsys.h
index 2c8dc63..c6bf6e6 100644
--- a/src/gallium/drivers/i915/intel_winsys.h
+++ b/src/gallium/drivers/i915/intel_winsys.h
@@ -42,21 +42,21 @@
    INTEL_USAGE_2D_TARGET = 0x04,
    INTEL_USAGE_2D_SOURCE = 0x08,
    /* use on vertex */
-   INTEL_USAGE_VERTEX    = 0x10,
+   INTEL_USAGE_VERTEX    = 0x10
 };
 
 enum intel_buffer_type
 {
    INTEL_NEW_TEXTURE,
    INTEL_NEW_SCANOUT, /**< a texture used for scanning out from */
-   INTEL_NEW_VERTEX,
+   INTEL_NEW_VERTEX
 };
 
 enum intel_buffer_tile
 {
    INTEL_TILE_NONE,
    INTEL_TILE_X,
-   INTEL_TILE_Y,
+   INTEL_TILE_Y
 };
 
 struct intel_batchbuffer {
diff --git a/src/gallium/drivers/i965/Makefile b/src/gallium/drivers/i965/Makefile
new file mode 100644
index 0000000..95fd3cd
--- /dev/null
+++ b/src/gallium/drivers/i965/Makefile
@@ -0,0 +1,74 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = i965
+
+C_SOURCES = \
+	brw_cc.c \
+	brw_clip.c \
+	brw_clip_line.c \
+	brw_clip_point.c \
+	brw_clip_state.c \
+	brw_clip_tri.c \
+	brw_clip_unfilled.c \
+	brw_clip_util.c \
+	brw_context.c \
+	brw_curbe.c \
+	brw_disasm.c \
+	brw_draw.c \
+	brw_draw_upload.c \
+	brw_eu.c \
+	brw_eu_debug.c \
+	brw_eu_emit.c \
+	brw_eu_util.c \
+	brw_gs.c \
+	brw_gs_emit.c \
+	brw_gs_state.c \
+	brw_misc_state.c \
+	brw_pipe_blend.c \
+	brw_pipe_depth.c \
+	brw_pipe_fb.c \
+	brw_pipe_query.c \
+	brw_pipe_shader.c \
+	brw_pipe_flush.c \
+	brw_pipe_misc.c \
+	brw_pipe_sampler.c \
+	brw_pipe_vertex.c \
+	brw_pipe_clear.c \
+	brw_pipe_rast.c \
+	brw_sf.c \
+	brw_sf_emit.c \
+	brw_sf_state.c \
+	brw_state_batch.c \
+	brw_state_debug.c \
+	brw_state_cache.c \
+	brw_state_upload.c \
+	brw_structs_dump.c \
+	brw_swtnl.c \
+	brw_urb.c \
+	brw_util.c \
+	brw_vs.c \
+	brw_vs_emit.c \
+	brw_vs_state.c \
+	brw_vs_surface_state.c \
+	brw_wm.c \
+	brw_wm_debug.c \
+	brw_wm_emit.c \
+	brw_wm_fp.c \
+	brw_wm_iz.c \
+	brw_wm_pass0.c \
+	brw_wm_pass1.c \
+	brw_wm_pass2.c \
+	brw_wm_sampler_state.c \
+	brw_wm_state.c \
+	brw_wm_surface_state.c \
+	brw_screen.c \
+	brw_screen_buffers.c \
+	brw_screen_tex_layout.c \
+	brw_screen_texture.c \
+	brw_screen_surface.c \
+	brw_batchbuffer.c \
+	brw_winsys_debug.c \
+	intel_decode.c
+
+include ../../Makefile.template
diff --git a/src/gallium/drivers/i965/SConscript b/src/gallium/drivers/i965/SConscript
new file mode 100644
index 0000000..9c2faaf
--- /dev/null
+++ b/src/gallium/drivers/i965/SConscript
@@ -0,0 +1,77 @@
+Import('*')
+
+env = env.Clone()
+
+i965 = env.ConvenienceLibrary(
+	target = 'i965',
+	source = [
+		'brw_batchbuffer.c',
+		'brw_cc.c',
+		'brw_clip.c',
+		'brw_clip_line.c',
+		'brw_clip_point.c',
+		'brw_clip_state.c',
+		'brw_clip_tri.c',
+		'brw_clip_unfilled.c',
+		'brw_clip_util.c',
+		'brw_context.c',
+		'brw_curbe.c',
+		'brw_disasm.c',
+		'brw_draw.c',
+		'brw_draw_upload.c',
+		'brw_eu.c',
+		'brw_eu_debug.c',
+		'brw_eu_emit.c',
+		'brw_eu_util.c',
+		'brw_gs.c',
+		'brw_gs_emit.c',
+		'brw_gs_state.c',
+		'brw_misc_state.c',
+		'brw_pipe_blend.c',
+		'brw_pipe_clear.c',
+		'brw_pipe_depth.c',
+		'brw_pipe_fb.c',
+		'brw_pipe_flush.c',
+		'brw_pipe_misc.c',
+		'brw_pipe_query.c',
+		'brw_pipe_rast.c',
+		'brw_pipe_sampler.c',
+		'brw_pipe_shader.c',
+		'brw_pipe_vertex.c',
+		'brw_screen_buffers.c',
+		'brw_screen.c',
+		'brw_screen_surface.c',
+		'brw_screen_tex_layout.c',
+		'brw_screen_texture.c',
+		'brw_structs_dump.c',
+		'brw_sf.c',
+		'brw_sf_emit.c',
+		'brw_sf_state.c',
+		'brw_state_batch.c',
+		'brw_state_cache.c',
+#		'brw_state_debug.c',
+		'brw_state_upload.c',
+		'brw_swtnl.c',
+		'brw_urb.c',
+		'brw_util.c',
+		'brw_vs.c',
+		'brw_vs_emit.c',
+		'brw_vs_state.c',
+		'brw_vs_surface_state.c',
+		'brw_wm.c',
+#		'brw_wm_constant_buffer.c',
+		'brw_wm_debug.c',
+		'brw_wm_emit.c',
+		'brw_wm_fp.c',
+#		'brw_wm_glsl.c',
+		'brw_wm_iz.c',
+		'brw_wm_pass0.c',
+		'brw_wm_pass1.c',
+		'brw_wm_pass2.c',
+		'brw_wm_sampler_state.c',
+		'brw_wm_state.c',
+		'brw_wm_surface_state.c',
+		'intel_decode.c',
+	])
+
+Export('i965')
diff --git a/src/gallium/drivers/i965/brw_batchbuffer.c b/src/gallium/drivers/i965/brw_batchbuffer.c
new file mode 100644
index 0000000..22607dc
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_batchbuffer.c
@@ -0,0 +1,202 @@
+/**************************************************************************
+ * 
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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.
+ * 
+ **************************************************************************/
+
+#include "util/u_memory.h"
+
+#include "brw_batchbuffer.h"
+#include "brw_reg.h"
+#include "brw_winsys.h"
+#include "brw_debug.h"
+#include "brw_structs.h"
+
+#define ALWAYS_EMIT_MI_FLUSH 1
+
+enum pipe_error
+brw_batchbuffer_reset(struct brw_batchbuffer *batch)
+{
+   enum pipe_error ret;
+
+   ret = batch->sws->bo_alloc( batch->sws,
+                               BRW_BUFFER_TYPE_BATCH,
+                               BRW_BATCH_SIZE, 4096,
+                               &batch->buf );
+   if (ret)
+      return ret;
+
+   batch->size = BRW_BATCH_SIZE;
+
+   /* With map_range semantics, the winsys can decide whether to
+    * inject a malloc'ed bounce buffer instead of mapping directly.
+    */
+   batch->map = batch->sws->bo_map(batch->buf,
+                                   BRW_DATA_BATCH_BUFFER,
+                                   0, batch->size,
+                                   GL_TRUE,
+                                   GL_TRUE,
+                                   GL_TRUE);
+
+   batch->ptr = batch->map;
+   return PIPE_OK;
+}
+
+struct brw_batchbuffer *
+brw_batchbuffer_alloc(struct brw_winsys_screen *sws,
+                      struct brw_chipset chipset)
+{
+   struct brw_batchbuffer *batch = CALLOC_STRUCT(brw_batchbuffer);
+
+   batch->sws = sws;
+   batch->chipset = chipset;
+   brw_batchbuffer_reset(batch);
+
+   return batch;
+}
+
+void
+brw_batchbuffer_free(struct brw_batchbuffer *batch)
+{
+   if (batch->map) {
+      batch->sws->bo_unmap(batch->buf);
+      batch->map = NULL;
+   }
+
+   bo_reference(&batch->buf, NULL);
+   FREE(batch);
+}
+
+
+void
+_brw_batchbuffer_flush(struct brw_batchbuffer *batch, 
+		       const char *file,
+		       int line)
+{
+   GLuint used = batch->ptr - batch->map;
+
+   if (used == 0)
+      return;
+
+   /* Post-swap throttling done by the state tracker.
+    */
+
+   if (BRW_DEBUG & DEBUG_BATCH)
+      debug_printf("%s:%d: Batchbuffer flush with %db used\n", 
+		   file, line, used);
+
+   if (ALWAYS_EMIT_MI_FLUSH) {
+      *(GLuint *) (batch->ptr) = MI_FLUSH | BRW_FLUSH_STATE_CACHE;
+      batch->ptr += 4;
+      used = batch->ptr - batch->map;
+   }
+
+   /* Round batchbuffer usage to 2 DWORDs. 
+    */
+   if ((used & 4) == 0) {
+      *(GLuint *) (batch->ptr) = 0; /* noop */
+      batch->ptr += 4;
+      used = batch->ptr - batch->map;
+   }
+
+   /* Mark the end of the buffer. 
+    */
+   *(GLuint *) (batch->ptr) = MI_BATCH_BUFFER_END;
+   batch->ptr += 4;
+   used = batch->ptr - batch->map;
+
+   batch->sws->bo_flush_range(batch->buf, 0, used);
+   batch->sws->bo_unmap(batch->buf);
+   batch->map = NULL;
+   batch->ptr = NULL;
+      
+   batch->sws->bo_exec(batch->buf, used );
+
+   if (BRW_DEBUG & DEBUG_SYNC) {
+      /* Abuse map/unmap to achieve wait-for-fence.
+       *
+       * XXX: hide this inside the winsys and export a fence
+       * interface.
+       */
+      debug_printf("waiting for idle\n");
+      batch->sws->bo_wait_idle(batch->buf);
+   }
+
+   /* Reset the buffer:
+    */
+   brw_batchbuffer_reset(batch);
+}
+
+
+/* The OUT_RELOC() macro ends up here, generating a relocation within
+ * the batch buffer.
+ */
+enum pipe_error
+brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch,
+			   struct brw_winsys_buffer *buffer,
+			   uint32_t usage,
+			   uint32_t delta)
+{
+   int ret;
+
+   if (batch->ptr - batch->map > batch->buf->size) {
+      debug_printf("bad relocation ptr %p map %p offset %d size %d\n",
+		   batch->ptr, batch->map, batch->ptr - batch->map, batch->buf->size);
+
+      return PIPE_ERROR_OUT_OF_MEMORY;
+   }
+
+   ret = batch->sws->bo_emit_reloc(batch->buf,
+				   usage,
+				   delta, 
+				   batch->ptr - batch->map,
+				   buffer);
+   if (ret != 0)
+      return ret;
+
+   /* bo_emit_reloc was resposible for writing a zero into the
+    * batchbuffer if necessary.  Just need to update our pointer.
+    */
+   batch->ptr += 4;
+
+   return 0;
+}
+
+enum pipe_error
+brw_batchbuffer_data(struct brw_batchbuffer *batch,
+                       const void *data, GLuint bytes,
+		       enum cliprect_mode cliprect_mode)
+{
+   enum pipe_error ret;
+
+   assert((bytes & 3) == 0);
+
+   ret = brw_batchbuffer_require_space(batch, bytes);
+   if (ret)
+      return ret;
+
+   memcpy(batch->ptr, data, bytes);
+   batch->ptr += bytes;
+   return 0;
+}
diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h
new file mode 100644
index 0000000..7473f5b
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_batchbuffer.h
@@ -0,0 +1,148 @@
+#ifndef BRW_BATCHBUFFER_H
+#define BRW_BATCHBUFFER_H
+
+#include "util/u_debug.h"
+
+#include "brw_types.h"
+#include "brw_winsys.h"
+#include "brw_reg.h"
+
+#define BATCH_SZ 16384
+#define BATCH_RESERVED 16
+
+/* All ignored:
+ */
+enum cliprect_mode {
+   IGNORE_CLIPRECTS,
+   LOOP_CLIPRECTS,
+   NO_LOOP_CLIPRECTS,
+   REFERENCES_CLIPRECTS
+};
+
+
+
+
+struct brw_batchbuffer {
+
+   struct brw_winsys_screen *sws;
+   struct brw_winsys_buffer *buf;
+   struct brw_chipset chipset;
+
+   /**
+    * Values exported to speed up the writing the batchbuffer,
+    * instead of having to go trough a accesor function for
+    * each dword written.
+    */
+   /*{@*/
+   uint8_t *map;
+   uint8_t *ptr;
+   size_t size;
+   struct {
+      uint8_t *end_ptr;
+   } emit;
+
+
+   size_t relocs;
+   size_t max_relocs;
+   /*@}*/
+};
+
+struct brw_batchbuffer *brw_batchbuffer_alloc( struct brw_winsys_screen *sws,
+                                               struct brw_chipset chipset );
+
+void brw_batchbuffer_free(struct brw_batchbuffer *batch);
+
+void _brw_batchbuffer_flush(struct brw_batchbuffer *batch,
+			      const char *file, int line);
+
+
+enum pipe_error
+brw_batchbuffer_reset(struct brw_batchbuffer *batch);
+
+
+/* Unlike bmBufferData, this currently requires the buffer be mapped.
+ * Consider it a convenience function wrapping multple
+ * intel_buffer_dword() calls.
+ */
+int brw_batchbuffer_data(struct brw_batchbuffer *batch,
+                            const void *data, GLuint bytes,
+			    enum cliprect_mode cliprect_mode);
+
+
+int brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch,
+			       struct brw_winsys_buffer *buffer,
+			       enum brw_buffer_usage usage,
+			       uint32_t offset);
+
+/* Inline functions - might actually be better off with these
+ * non-inlined.  Certainly better off switching all command packets to
+ * be passed as structs rather than dwords, but that's a little bit of
+ * work...
+ */
+static INLINE GLint
+brw_batchbuffer_space(struct brw_batchbuffer *batch)
+{
+   return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
+}
+
+
+static INLINE void
+brw_batchbuffer_emit_dword(struct brw_batchbuffer *batch, GLuint dword)
+{
+   assert(batch->map);
+   assert(brw_batchbuffer_space(batch) >= 4);
+   *(GLuint *) (batch->ptr) = dword;
+   batch->ptr += 4;
+}
+
+static INLINE enum pipe_error
+brw_batchbuffer_require_space(struct brw_batchbuffer *batch,
+                                GLuint sz)
+{
+   assert(sz < batch->size - 8);
+   if (brw_batchbuffer_space(batch) < sz) {
+      assert(0);
+      return PIPE_ERROR_OUT_OF_MEMORY;
+   }
+#ifdef DEBUG
+   batch->emit.end_ptr = batch->ptr + sz;
+#endif
+   return 0;
+}
+
+/* Here are the crusty old macros, to be removed:
+ */
+#define BEGIN_BATCH(n, cliprect_mode) do {				\
+      brw_batchbuffer_require_space(brw->batch, (n)*4);			\
+   } while (0)
+
+#define OUT_BATCH(d) brw_batchbuffer_emit_dword(brw->batch, d)
+
+#define OUT_RELOC(buf, usage, delta) do {				\
+      assert((unsigned) (delta) < buf->size);				\
+      brw_batchbuffer_emit_reloc(brw->batch, buf,			\
+				 usage, delta);				\
+   } while (0)
+
+#ifdef DEBUG
+#define ADVANCE_BATCH() do {						\
+      unsigned int _n = brw->batch->ptr - brw->batch->emit.end_ptr;	\
+      if (_n != 0) {							\
+	 debug_printf("%s: %d too many bytes emitted to batch\n",	\
+		      __FUNCTION__, _n);				\
+	 abort();							\
+      }									\
+      brw->batch->emit.end_ptr = NULL;					\
+   } while(0)
+#else
+#define ADVANCE_BATCH()
+#endif
+
+static INLINE void
+brw_batchbuffer_emit_mi_flush(struct brw_batchbuffer *batch)
+{
+   brw_batchbuffer_require_space(batch, 4);
+   brw_batchbuffer_emit_dword(batch, MI_FLUSH);
+}
+
+#endif
diff --git a/src/gallium/drivers/i965/brw_cc.c b/src/gallium/drivers/i965/brw_cc.c
new file mode 100644
index 0000000..3e070f5
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_cc.c
@@ -0,0 +1,111 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+
+
+static enum pipe_error prepare_cc_vp( struct brw_context *brw )
+{
+   return brw_cache_data( &brw->cache, 
+                         BRW_CC_VP,
+                         &brw->curr.ccv,
+                         NULL, 0,
+                         &brw->cc.reloc[CC_RELOC_VP].bo );
+}
+
+const struct brw_tracked_state brw_cc_vp = {
+   .dirty = {
+      .mesa = PIPE_NEW_VIEWPORT,
+      .brw = BRW_NEW_CONTEXT,
+      .cache = 0
+   },
+   .prepare = prepare_cc_vp
+};
+
+
+/* A long-winded way to OR two unsigned integers together:
+ */
+static INLINE struct brw_cc3
+combine_cc3( struct brw_cc3 a, struct brw_cc3 b )
+{
+   union { struct brw_cc3 cc3; unsigned i; } ca, cb;
+   ca.cc3 = a;
+   cb.cc3 = b;
+   ca.i |= cb.i;
+   return ca.cc3;
+}
+
+
+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.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;
+
+   return brw_cache_data_sz(&brw->cache, BRW_CC_UNIT,
+                           &brw->cc.cc, sizeof(brw->cc.cc),
+                           brw->cc.reloc, 1,
+                           &brw->cc.state_bo);
+}
+
+const struct brw_tracked_state brw_cc_unit = {
+   .dirty = {
+      .mesa = PIPE_NEW_DEPTH_STENCIL_ALPHA | PIPE_NEW_BLEND,
+      .brw = 0,
+      .cache = CACHE_NEW_CC_VP
+   },
+   .prepare = prepare_cc_unit,
+};
+
+
+void brw_hw_cc_init( struct brw_context *brw )
+{
+   make_reloc(&brw->cc.reloc[0],
+              BRW_USAGE_STATE,
+              0,
+              offsetof(struct brw_cc_unit_state, cc4),
+              NULL);
+}
+
+
+void brw_hw_cc_cleanup( struct brw_context *brw )
+{
+   bo_reference(&brw->cc.state_bo, NULL);
+   bo_reference(&brw->cc.reloc[0].bo, NULL);
+}
diff --git a/src/gallium/drivers/i965/brw_clip.c b/src/gallium/drivers/i965/brw_clip.c
new file mode 100644
index 0000000..d67a1a6
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_clip.c
@@ -0,0 +1,224 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "pipe/p_state.h"
+
+#include "util/u_math.h"
+
+#include "brw_screen.h"
+#include "brw_batchbuffer.h"
+#include "brw_defines.h"
+#include "brw_context.h"
+#include "brw_eu.h"
+#include "brw_util.h"
+#include "brw_state.h"
+#include "brw_pipe_rast.h"
+#include "brw_clip.h"
+
+
+#define FRONT_UNFILLED_BIT  0x1
+#define BACK_UNFILLED_BIT   0x2
+
+
+static enum pipe_error
+compile_clip_prog( struct brw_context *brw,
+                   struct brw_clip_prog_key *key,
+                   struct brw_winsys_buffer **bo_out )
+{
+   enum pipe_error ret;
+   struct brw_clip_compile c;
+   const GLuint *program;
+   GLuint program_size;
+   GLuint delta;
+
+   memset(&c, 0, sizeof(c));
+   
+   /* Begin the compilation:
+    */
+   brw_init_compile(brw, &c.func);
+
+   c.func.single_program_flow = 1;
+
+   c.chipset = brw->chipset;
+   c.key = *key;
+   c.need_ff_sync = c.chipset.is_igdng;
+
+   /* Need to locate the two positions present in vertex + header.
+    * These are currently hardcoded:
+    */
+   c.header_position_offset = ATTR_SIZE;
+
+   if (c.chipset.is_igdng)
+       delta = 3 * REG_SIZE;
+   else
+       delta = REG_SIZE;
+
+   c.offset_hpos = delta + c.key.output_hpos * ATTR_SIZE;
+
+   if (c.key.output_color0 != BRW_OUTPUT_NOT_PRESENT)
+      c.offset_color0 = delta + c.key.output_color0 * ATTR_SIZE;
+
+   if (c.key.output_color1 != BRW_OUTPUT_NOT_PRESENT)
+      c.offset_color1 = delta + c.key.output_color1 * ATTR_SIZE;
+
+   if (c.key.output_bfc0 != BRW_OUTPUT_NOT_PRESENT)
+      c.offset_bfc0 = delta + c.key.output_bfc0 * ATTR_SIZE;
+
+   if (c.key.output_bfc1 != BRW_OUTPUT_NOT_PRESENT)
+      c.offset_bfc1 = delta + c.key.output_bfc1 * ATTR_SIZE;
+
+   if (c.key.output_edgeflag != BRW_OUTPUT_NOT_PRESENT)
+      c.offset_edgeflag = delta + c.key.output_edgeflag * ATTR_SIZE;
+   
+   if (BRW_IS_IGDNG(brw))
+       c.nr_regs = (c.key.nr_attrs + 1) / 2 + 3;  /* are vertices packed, or reg-aligned? */
+   else
+       c.nr_regs = (c.key.nr_attrs + 1) / 2 + 1;  /* are vertices packed, or reg-aligned? */
+
+   c.nr_bytes = c.nr_regs * REG_SIZE;
+
+   c.prog_data.clip_mode = c.key.clip_mode; /* XXX */
+
+   /* For some reason the thread is spawned with only 4 channels
+    * unmasked.  
+    */
+   brw_set_mask_control(&c.func, BRW_MASK_DISABLE);
+
+
+   /* Would ideally have the option of producing a program which could
+    * do all three:
+    */
+   switch (key->primitive) {
+   case PIPE_PRIM_TRIANGLES: 
+      if (key->do_unfilled)
+	 brw_emit_unfilled_clip( &c );
+      else
+	 brw_emit_tri_clip( &c );
+      break;
+   case PIPE_PRIM_LINES:
+      brw_emit_line_clip( &c );
+      break;
+   case PIPE_PRIM_POINTS:
+      brw_emit_point_clip( &c );
+      break;
+   default:
+      assert(0);
+      return PIPE_ERROR_BAD_INPUT;
+   }
+
+	 
+
+   /* get the program
+    */
+   ret = brw_get_program(&c.func, &program, &program_size);
+   if (ret)
+      return ret;
+
+   /* Upload
+    */
+   ret = brw_upload_cache( &brw->cache,
+                           BRW_CLIP_PROG,
+                           &c.key, sizeof(c.key),
+                           NULL, 0,
+                           program, program_size,
+                           &c.prog_data,
+                           &brw->clip.prog_data,
+                           bo_out );
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+/* Calculate interpolants for triangle and line rasterization.
+ */
+static enum pipe_error
+upload_clip_prog(struct brw_context *brw)
+{
+   const struct brw_vertex_shader *vs = brw->curr.vertex_shader;
+   struct brw_clip_prog_key key;
+   enum pipe_error ret;
+
+   /* Populate the key, starting from the almost-complete version from
+    * the rast state. 
+    */
+
+   /* PIPE_NEW_RAST */
+   key = brw->curr.rast->clip_key;
+   
+   /* BRW_NEW_REDUCED_PRIMITIVE */
+   key.primitive = brw->reduced_primitive;
+
+   /* XXX: if edgeflag is moved to a proper TGSI vs output, can remove
+    * dependency on CACHE_NEW_VS_PROG
+    */
+   /* CACHE_NEW_VS_PROG */
+   key.nr_attrs        = brw->vs.prog_data->nr_outputs;
+
+   /* PIPE_NEW_VS */
+   key.output_hpos     = vs->output_hpos;
+   key.output_color0   = vs->output_color0;
+   key.output_color1   = vs->output_color1;
+   key.output_bfc0     = vs->output_bfc0;
+   key.output_bfc1     = vs->output_bfc1;
+   key.output_edgeflag = vs->output_edgeflag;
+
+   /* PIPE_NEW_CLIP */
+   key.nr_userclip = brw->curr.ucp.nr;
+
+   /* Already cached?
+    */
+   if (brw_search_cache(&brw->cache, BRW_CLIP_PROG,
+                        &key, sizeof(key),
+                        NULL, 0,
+                        &brw->clip.prog_data,
+                        &brw->clip.prog_bo))
+      return PIPE_OK;
+
+   /* Compile new program:
+    */
+   ret = compile_clip_prog( brw, &key, &brw->clip.prog_bo );
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+
+const struct brw_tracked_state brw_clip_prog = {
+   .dirty = {
+      .mesa  = (PIPE_NEW_RAST | 
+		PIPE_NEW_CLIP),
+      .brw   = (BRW_NEW_REDUCED_PRIMITIVE),
+      .cache = CACHE_NEW_VS_PROG
+   },
+   .prepare = upload_clip_prog
+};
diff --git a/src/gallium/drivers/i965/brw_clip.h b/src/gallium/drivers/i965/brw_clip.h
new file mode 100644
index 0000000..80e3a11
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_clip.h
@@ -0,0 +1,199 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#ifndef BRW_CLIP_H
+#define BRW_CLIP_H
+
+#include "pipe/p_state.h"
+#include "brw_reg.h"
+#include "brw_eu.h"
+
+#define MAX_VERTS (3+6+6)	
+
+/* Note that if unfilled primitives are being emitted, we have to fix
+ * up polygon offset and flatshading at this point:
+ */
+struct brw_clip_prog_key {
+   GLuint nr_attrs:6;
+   GLuint primitive:4;
+   GLuint nr_userclip:3;
+   GLuint do_flat_shading:1;
+   GLuint do_unfilled:1;
+   GLuint fill_cw:2;		/* includes cull information */
+   GLuint fill_ccw:2;		/* includes cull information */
+   GLuint offset_cw:1;
+   GLuint offset_ccw:1;
+   GLuint copy_bfc_cw:1;
+   GLuint copy_bfc_ccw:1;
+   GLuint clip_mode:3;
+   GLuint output_hpos:6;        /* not always zero? */
+
+   GLuint output_color0:6;
+   GLuint output_color1:6;
+   GLuint output_bfc0:6;
+   GLuint output_bfc1:6;
+   GLuint output_edgeflag:6;
+   GLuint pad1:2;
+   
+   GLfloat offset_factor;
+   GLfloat offset_units;
+};
+
+struct brw_clip_prog_data {
+   GLuint curb_read_length;	/* user planes? */
+   GLuint clip_mode;
+   GLuint urb_read_length;
+   GLuint total_grf;
+};
+
+#define CLIP_LINE   0
+#define CLIP_POINT  1
+#define CLIP_FILL   2
+#define CLIP_CULL   3
+
+
+#define PRIM_MASK  (0x1f)
+
+struct brw_clip_compile {
+   struct brw_compile func;
+   struct brw_clip_prog_key key;
+   struct brw_clip_prog_data prog_data;
+   
+   struct {
+      struct brw_reg R0;
+      struct brw_reg vertex[MAX_VERTS];
+
+      struct brw_reg t;
+      struct brw_reg t0, t1;
+      struct brw_reg dp0, dp1;
+
+      struct brw_reg dpPrev;
+      struct brw_reg dp;
+      struct brw_reg loopcount;
+      struct brw_reg nr_verts;
+      struct brw_reg planemask;
+
+      struct brw_reg inlist;
+      struct brw_reg outlist;
+      struct brw_reg freelist;
+
+      struct brw_reg dir;
+      struct brw_reg tmp0, tmp1;
+      struct brw_reg offset;
+      
+      struct brw_reg fixed_planes;
+      struct brw_reg plane_equation;
+       
+      struct brw_reg ff_sync;
+   } reg;
+
+   /* 3 different ways of expressing vertex size, including
+    * key.nr_attrs.
+    */
+   GLuint nr_regs;
+   GLuint nr_bytes;
+
+   GLuint first_tmp;
+   GLuint last_tmp;
+
+   GLboolean need_direction;
+   struct brw_chipset chipset;
+
+   GLuint last_mrf;
+
+   GLuint header_position_offset;
+   GLboolean need_ff_sync;
+
+   GLuint nr_color_attrs;
+   GLuint offset_color0;
+   GLuint offset_color1;
+   GLuint offset_bfc0;
+   GLuint offset_bfc1;
+
+   GLuint offset_hpos;
+   GLuint offset_edgeflag;
+};
+
+#define ATTR_SIZE  (4*4)
+
+/* Points are only culled, so no need for a clip routine, however it
+ * works out easier to have a dummy one.
+ */
+void brw_emit_unfilled_clip( struct brw_clip_compile *c );
+void brw_emit_tri_clip( struct brw_clip_compile *c );
+void brw_emit_line_clip( struct brw_clip_compile *c );
+void brw_emit_point_clip( struct brw_clip_compile *c );
+
+/* brw_clip_tri.c, for use by the unfilled clip routine:
+ */
+void brw_clip_tri_init_vertices( struct brw_clip_compile *c );
+void brw_clip_tri_flat_shade( struct brw_clip_compile *c );
+void brw_clip_tri( struct brw_clip_compile *c );
+void brw_clip_tri_emit_polygon( struct brw_clip_compile *c );
+void brw_clip_tri_alloc_regs( struct brw_clip_compile *c, 
+			      GLuint nr_verts );
+
+
+/* Utils:
+ */
+
+void brw_clip_interp_vertex( struct brw_clip_compile *c,
+			     struct brw_indirect dest_ptr,
+			     struct brw_indirect v0_ptr, /* from */
+			     struct brw_indirect v1_ptr, /* to */
+			     struct brw_reg t0,
+			     GLboolean force_edgeflag );
+
+void brw_clip_init_planes( struct brw_clip_compile *c );
+
+void brw_clip_emit_vue(struct brw_clip_compile *c, 
+		       struct brw_indirect vert,
+		       GLboolean allocate,
+		       GLboolean eot,
+		       GLuint header);
+
+void brw_clip_kill_thread(struct brw_clip_compile *c);
+
+struct brw_reg brw_clip_plane_stride( struct brw_clip_compile *c );
+struct brw_reg brw_clip_plane0_address( struct brw_clip_compile *c );
+
+void brw_clip_copy_colors( struct brw_clip_compile *c,
+			   GLuint to, GLuint from );
+
+void brw_clip_init_clipmask( struct brw_clip_compile *c );
+
+struct brw_reg get_tmp( struct brw_clip_compile *c );
+
+void brw_clip_project_position(struct brw_clip_compile *c,
+             struct brw_reg pos );
+void brw_clip_ff_sync(struct brw_clip_compile *c);
+void brw_clip_init_ff_sync(struct brw_clip_compile *c);
+#endif
diff --git a/src/gallium/drivers/i965/brw_clip_line.c b/src/gallium/drivers/i965/brw_clip_line.c
new file mode 100644
index 0000000..54282d9
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_clip_line.c
@@ -0,0 +1,271 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "util/u_debug.h"
+
+#include "brw_defines.h"
+#include "brw_eu.h"
+#include "brw_util.h"
+#include "brw_clip.h"
+
+
+
+
+static void brw_clip_line_alloc_regs( struct brw_clip_compile *c )
+{
+   GLuint i = 0,j;
+
+   /* Register usage is static, precompute here:
+    */
+   c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
+
+   if (c->key.nr_userclip) {
+      c->reg.fixed_planes = brw_vec4_grf(i, 0);
+      i += (6 + c->key.nr_userclip + 1) / 2;
+
+      c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2;
+   }
+   else
+      c->prog_data.curb_read_length = 0;
+
+
+   /* Payload vertices plus space for more generated vertices:
+    */
+   for (j = 0; j < 4; j++) {
+      c->reg.vertex[j] = brw_vec4_grf(i, 0);
+      i += c->nr_regs;
+   }
+
+   c->reg.t           = brw_vec1_grf(i, 0);
+   c->reg.t0          = brw_vec1_grf(i, 1);
+   c->reg.t1          = brw_vec1_grf(i, 2);
+   c->reg.planemask   = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD);
+   c->reg.plane_equation = brw_vec4_grf(i, 4);
+   i++;
+
+   c->reg.dp0         = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */
+   c->reg.dp1         = brw_vec1_grf(i, 4);
+   i++;
+
+   if (!c->key.nr_userclip) {
+      c->reg.fixed_planes = brw_vec8_grf(i, 0); 
+      i++;
+   }
+
+   if (c->need_ff_sync) {
+      c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
+      i++;
+   }
+
+   c->first_tmp = i;
+   c->last_tmp = i;
+
+   c->prog_data.urb_read_length = c->nr_regs; /* ? */
+   c->prog_data.total_grf = i;
+}
+
+
+
+/* Line clipping, more or less following the following algorithm:
+ *
+ *  for (p=0;p<MAX_PLANES;p++) {
+ *     if (clipmask & (1 << p)) {
+ *        GLfloat dp0 = DOTPROD( vtx0, plane[p] );
+ *        GLfloat dp1 = DOTPROD( vtx1, plane[p] );
+ *
+ *        if (IS_NEGATIVE(dp1)) {
+ *           GLfloat t = dp1 / (dp1 - dp0);
+ *           if (t > t1) t1 = t;
+ *        } else {
+ *           GLfloat t = dp0 / (dp0 - dp1);
+ *           if (t > t0) t0 = t;
+ *        }
+ *  
+ *        if (t0 + t1 >= 1.0)
+ *           return;
+ *     }
+ *  }
+ *
+ *  interp( ctx, newvtx0, vtx0, vtx1, t0 );
+ *  interp( ctx, newvtx1, vtx1, vtx0, t1 );
+ *
+ */
+static void clip_and_emit_line( struct brw_clip_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_indirect vtx0     = brw_indirect(0, 0);
+   struct brw_indirect vtx1      = brw_indirect(1, 0);
+   struct brw_indirect newvtx0   = brw_indirect(2, 0);
+   struct brw_indirect newvtx1   = brw_indirect(3, 0);
+   struct brw_indirect plane_ptr = brw_indirect(4, 0);
+   struct brw_instruction *plane_loop;
+   struct brw_instruction *plane_active;
+   struct brw_instruction *is_negative;
+   struct brw_instruction *is_neg2 = NULL;
+   struct brw_instruction *not_culled;
+   struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD);
+
+   brw_MOV(p, get_addr_reg(vtx0),      brw_address(c->reg.vertex[0]));
+   brw_MOV(p, get_addr_reg(vtx1),      brw_address(c->reg.vertex[1]));
+   brw_MOV(p, get_addr_reg(newvtx0),   brw_address(c->reg.vertex[2]));
+   brw_MOV(p, get_addr_reg(newvtx1),   brw_address(c->reg.vertex[3]));
+   brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c));
+
+   /* Note: init t0, t1 together: 
+    */
+   brw_MOV(p, vec2(c->reg.t0), brw_imm_f(0));
+
+   brw_clip_init_planes(c);
+   brw_clip_init_clipmask(c);
+
+   /* -ve rhw workaround */
+   if (c->chipset.is_965) {
+      brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+      brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
+              brw_imm_ud(1<<20));
+      brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(0x3f));
+   }
+
+   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+   plane_loop = brw_DO(p, BRW_EXECUTE_1);
+   {
+      /* if (planemask & 1)
+       */
+      brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+      brw_AND(p, v1_null_ud, c->reg.planemask, brw_imm_ud(1));
+      
+      plane_active = brw_IF(p, BRW_EXECUTE_1);
+      {
+	 if (c->key.nr_userclip)
+	    brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
+	 else
+	    brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
+
+	 /* dp = DP4(vtx->position, plane) 
+	  */
+	 brw_DP4(p, vec4(c->reg.dp0), deref_4f(vtx0, c->offset_hpos), c->reg.plane_equation);
+
+	 /* if (IS_NEGATIVE(dp1)) 
+	  */
+	 brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
+	 brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, c->offset_hpos), c->reg.plane_equation);
+	 is_negative = brw_IF(p, BRW_EXECUTE_1);
+	 {
+             /*
+              * Both can be negative on GM965/G965 due to RHW workaround
+              * if so, this object should be rejected.
+              */
+             if (c->chipset.is_965) {
+                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, c->reg.dp0, brw_imm_f(0.0));
+                 is_neg2 = brw_IF(p, BRW_EXECUTE_1);
+                 {
+                     brw_clip_kill_thread(c);
+                 }
+                 brw_ENDIF(p, is_neg2);
+             }
+
+             brw_ADD(p, c->reg.t, c->reg.dp1, negate(c->reg.dp0));
+             brw_math_invert(p, c->reg.t, c->reg.t);
+             brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp1);
+
+             brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t1 );
+             brw_MOV(p, c->reg.t1, c->reg.t);
+             brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+	 } 
+	 is_negative = brw_ELSE(p, is_negative);
+	 {
+             /* Coming back in.  We know that both cannot be negative
+              * because the line would have been culled in that case.
+              */
+
+             /* If both are positive, do nothing */
+             /* Only on GM965/G965 */
+             if (c->chipset.is_965) {
+                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0));
+                 is_neg2 = brw_IF(p, BRW_EXECUTE_1);
+             }
+
+             {
+                 brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1));
+                 brw_math_invert(p, c->reg.t, c->reg.t);
+                 brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0);
+
+                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 );
+                 brw_MOV(p, c->reg.t0, c->reg.t);
+                 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+             }
+
+             if (c->chipset.is_965) {
+                 brw_ENDIF(p, is_neg2);
+             }
+         }
+	 brw_ENDIF(p, is_negative);	 
+      }
+      brw_ENDIF(p, plane_active);
+      
+      /* plane_ptr++;
+       */
+      brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
+
+      /* while (planemask>>=1) != 0
+       */
+      brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+      brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
+   }
+   brw_WHILE(p, plane_loop);
+
+   brw_ADD(p, c->reg.t, c->reg.t0, c->reg.t1);
+   brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0));
+   not_culled = brw_IF(p, BRW_EXECUTE_1);
+   {
+      brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, FALSE);
+      brw_clip_interp_vertex(c, newvtx1, vtx1, vtx0, c->reg.t1, FALSE);
+
+      brw_clip_emit_vue(c, newvtx0, 1, 0, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_START);
+      brw_clip_emit_vue(c, newvtx1, 0, 1, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_END); 
+   }
+   brw_ENDIF(p, not_culled);
+   brw_clip_kill_thread(c);
+}
+
+
+
+void brw_emit_line_clip( struct brw_clip_compile *c )
+{
+   brw_clip_line_alloc_regs(c);
+   brw_clip_init_ff_sync(c);
+
+   if (c->key.do_flat_shading)
+      brw_clip_copy_colors(c, 0, 1);
+                
+   clip_and_emit_line(c);
+}
diff --git a/src/gallium/drivers/i965/brw_clip_point.c b/src/gallium/drivers/i965/brw_clip_point.c
new file mode 100644
index 0000000..e0a5330
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_clip_point.c
@@ -0,0 +1,48 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "brw_defines.h"
+#include "brw_eu.h"
+#include "brw_util.h"
+#include "brw_clip.h"
+
+
+/* Point clipping, nothing to do?
+ */
+void brw_emit_point_clip( struct brw_clip_compile *c )
+{
+   /* Send an empty message to kill the thread:
+    */
+   brw_clip_tri_alloc_regs(c, 0);
+   brw_clip_init_ff_sync(c);
+
+   brw_clip_kill_thread(c);
+}
diff --git a/src/gallium/drivers/i965/brw_clip_state.c b/src/gallium/drivers/i965/brw_clip_state.c
new file mode 100644
index 0000000..5c3ccfd
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_clip_state.c
@@ -0,0 +1,209 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "util/u_math.h"
+
+#include "brw_context.h"
+#include "brw_clip.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+#include "brw_debug.h"
+
+struct brw_clip_unit_key {
+   unsigned int total_grf;
+   unsigned int urb_entry_read_length;
+   unsigned int curb_entry_read_length;
+   unsigned int clip_mode;
+
+   unsigned int curbe_offset;
+
+   unsigned int nr_urb_entries, urb_size;
+
+   GLboolean depth_clamp;
+};
+
+static void
+clip_unit_populate_key(struct brw_context *brw, struct brw_clip_unit_key *key)
+{
+   memset(key, 0, sizeof(*key));
+
+   /* CACHE_NEW_CLIP_PROG */
+   key->total_grf = brw->clip.prog_data->total_grf;
+   key->urb_entry_read_length = brw->clip.prog_data->urb_read_length;
+   key->curb_entry_read_length = brw->clip.prog_data->curb_read_length;
+   key->clip_mode = brw->clip.prog_data->clip_mode;
+
+   /* BRW_NEW_CURBE_OFFSETS */
+   key->curbe_offset = brw->curbe.clip_start;
+
+   /* BRW_NEW_URB_FENCE */
+   key->nr_urb_entries = brw->urb.nr_clip_entries;
+   key->urb_size = brw->urb.vsize;
+
+   /*  */
+   key->depth_clamp = 0; /* XXX: add this to gallium: ctx->Transform.DepthClamp; */
+}
+
+static enum pipe_error
+clip_unit_create_from_key(struct brw_context *brw,
+                          struct brw_clip_unit_key *key,
+                          struct brw_winsys_reloc *reloc,
+                          struct brw_winsys_buffer **bo_out)
+{
+   struct brw_clip_unit_state clip;
+   enum pipe_error ret;
+
+   memset(&clip, 0, sizeof(clip));
+
+   clip.thread0.grf_reg_count = align(key->total_grf, 16) / 16 - 1;
+   /* reloc */
+   clip.thread0.kernel_start_pointer = 0;
+
+   clip.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
+   clip.thread1.single_program_flow = 1;
+
+   clip.thread3.urb_entry_read_length = key->urb_entry_read_length;
+   clip.thread3.const_urb_entry_read_length = key->curb_entry_read_length;
+   clip.thread3.const_urb_entry_read_offset = key->curbe_offset * 2;
+   clip.thread3.dispatch_grf_start_reg = 1;
+   clip.thread3.urb_entry_read_offset = 0;
+
+   clip.thread4.nr_urb_entries = key->nr_urb_entries;
+   clip.thread4.urb_entry_allocation_size = key->urb_size - 1;
+   /* If we have enough clip URB entries to run two threads, do so.
+    */
+   if (key->nr_urb_entries >= 10) {
+      /* Half of the URB entries go to each thread, and it has to be an
+       * even number.
+       */
+      assert(key->nr_urb_entries % 2 == 0);
+      
+      /* Although up to 16 concurrent Clip threads are allowed on IGDNG, 
+       * only 2 threads can output VUEs at a time.
+       */
+      if (BRW_IS_IGDNG(brw))
+         clip.thread4.max_threads = 16 - 1;        
+      else
+         clip.thread4.max_threads = 2 - 1;
+   } else {
+      assert(key->nr_urb_entries >= 5);
+      clip.thread4.max_threads = 1 - 1;
+   }
+
+   if (BRW_DEBUG & DEBUG_SINGLE_THREAD)
+      clip.thread4.max_threads = 0;
+
+   if (BRW_DEBUG & DEBUG_STATS)
+      clip.thread4.stats_enable = 1;
+
+   clip.clip5.userclip_enable_flags = 0x7f;
+   clip.clip5.userclip_must_clip = 1;
+   clip.clip5.guard_band_enable = 0;
+   if (!key->depth_clamp)
+      clip.clip5.viewport_z_clip_enable = 1;
+   clip.clip5.viewport_xy_clip_enable = 1;
+   clip.clip5.vertex_position_space = BRW_CLIP_NDCSPACE;
+   clip.clip5.api_mode = BRW_CLIP_API_OGL;
+   clip.clip5.clip_mode = key->clip_mode;
+
+   if (BRW_IS_G4X(brw))
+      clip.clip5.negative_w_clip_test = 1;
+
+   clip.clip6.clipper_viewport_state_ptr = 0;
+   clip.viewport_xmin = -1;
+   clip.viewport_xmax = 1;
+   clip.viewport_ymin = -1;
+   clip.viewport_ymax = 1;
+
+   ret = brw_upload_cache(&brw->cache, BRW_CLIP_UNIT,
+                          key, sizeof(*key),
+                          reloc, 1,
+                          &clip, sizeof(clip),
+                          NULL, NULL,
+                          bo_out);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+static int upload_clip_unit( struct brw_context *brw )
+{
+   struct brw_clip_unit_key key;
+   struct brw_winsys_reloc reloc[1];
+   unsigned grf_reg_count;
+   enum pipe_error ret;
+
+   clip_unit_populate_key(brw, &key);
+
+   grf_reg_count = align(key.total_grf, 16) / 16 - 1;
+
+   /* clip program relocation
+    *
+    * XXX: these reloc structs are long lived and only need to be
+    * updated when the bound BO changes.  Hopefully the stuff mixed in
+    * in the delta's is non-orthogonal.
+    */
+   assert(brw->clip.prog_bo);
+   make_reloc(&reloc[0],
+              BRW_USAGE_STATE,
+              grf_reg_count << 1,
+              offsetof(struct brw_clip_unit_state, thread0),
+              brw->clip.prog_bo);
+
+
+   if (brw_search_cache(&brw->cache, BRW_CLIP_UNIT,
+                        &key, sizeof(key),
+                        reloc, 1,
+                        NULL,
+                        &brw->clip.state_bo))
+      return PIPE_OK;
+      
+   /* Create new:
+    */
+   ret = clip_unit_create_from_key(brw, &key, 
+                                   reloc,
+                                   &brw->clip.state_bo);
+   if (ret)
+      return ret;
+   
+   return PIPE_OK;
+}
+
+const struct brw_tracked_state brw_clip_unit = {
+   .dirty = {
+      .mesa  = 0,
+      .brw   = (BRW_NEW_CURBE_OFFSETS |
+		BRW_NEW_URB_FENCE),
+      .cache = CACHE_NEW_CLIP_PROG
+   },
+   .prepare = upload_clip_unit,
+};
diff --git a/src/gallium/drivers/i965/brw_clip_tri.c b/src/gallium/drivers/i965/brw_clip_tri.c
new file mode 100644
index 0000000..4cde729
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_clip_tri.c
@@ -0,0 +1,595 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "brw_defines.h"
+#include "brw_eu.h"
+#include "brw_util.h"
+#include "brw_clip.h"
+
+static void release_tmps( struct brw_clip_compile *c )
+{
+   c->last_tmp = c->first_tmp;
+}
+
+
+void brw_clip_tri_alloc_regs( struct brw_clip_compile *c, 
+			      GLuint nr_verts )
+{
+   GLuint i = 0,j;
+
+   /* Register usage is static, precompute here:
+    */
+   c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
+
+   if (c->key.nr_userclip) {
+      c->reg.fixed_planes = brw_vec4_grf(i, 0);
+      i += (6 + c->key.nr_userclip + 1) / 2;
+
+      c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2;
+   }
+   else
+      c->prog_data.curb_read_length = 0;
+
+
+   /* Payload vertices plus space for more generated vertices:
+    */
+   for (j = 0; j < nr_verts; j++) {
+      c->reg.vertex[j] = brw_vec4_grf(i, 0);
+      i += c->nr_regs;
+   }
+
+   if (c->key.nr_attrs & 1) {
+      for (j = 0; j < 3; j++) {
+	 GLuint delta = c->key.nr_attrs*16 + 32;
+
+         if (c->chipset.is_igdng)
+             delta = c->key.nr_attrs * 16 + 32 * 3;
+
+	 brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0));
+      }
+   }
+
+   c->reg.t          = brw_vec1_grf(i, 0);
+   c->reg.loopcount  = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_D);
+   c->reg.nr_verts   = retype(brw_vec1_grf(i, 2), BRW_REGISTER_TYPE_UD);
+   c->reg.planemask  = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD);
+   c->reg.plane_equation = brw_vec4_grf(i, 4);
+   i++;
+
+   c->reg.dpPrev     = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */
+   c->reg.dp         = brw_vec1_grf(i, 4);
+   i++;
+
+   c->reg.inlist     = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
+   i++;
+
+   c->reg.outlist    = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
+   i++;
+
+   c->reg.freelist   = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
+   i++;
+
+   if (!c->key.nr_userclip) {
+      c->reg.fixed_planes = brw_vec8_grf(i, 0); 
+      i++;
+   }
+
+   if (c->key.do_unfilled) {
+      c->reg.dir     = brw_vec4_grf(i, 0);
+      c->reg.offset  = brw_vec4_grf(i, 4);
+      i++;
+      c->reg.tmp0    = brw_vec4_grf(i, 0);
+      c->reg.tmp1    = brw_vec4_grf(i, 4);
+      i++;
+   }
+
+   if (c->need_ff_sync) {
+      c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
+      i++;
+   }
+
+   c->first_tmp = i;
+   c->last_tmp = i;
+
+   c->prog_data.urb_read_length = c->nr_regs; /* ? */
+   c->prog_data.total_grf = i;
+}
+
+
+
+void brw_clip_tri_init_vertices( struct brw_clip_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
+   struct brw_instruction *is_rev;
+
+   /* Initial list of indices for incoming vertexes:
+    */
+   brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); 
+   brw_CMP(p, 
+	   vec1(brw_null_reg()), 
+	   BRW_CONDITIONAL_EQ, 
+	   tmp0,
+	   brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE));
+
+   /* XXX: Is there an easier way to do this?  Need to reverse every
+    * second tristrip element:  Can ignore sometimes?
+    */
+   is_rev = brw_IF(p, BRW_EXECUTE_1);
+   {   
+      brw_MOV(p, get_element(c->reg.inlist, 0),  brw_address(c->reg.vertex[1]) );
+      brw_MOV(p, get_element(c->reg.inlist, 1),  brw_address(c->reg.vertex[0]) );
+      if (c->need_direction)
+	 brw_MOV(p, c->reg.dir, brw_imm_f(-1));
+   }
+   is_rev = brw_ELSE(p, is_rev);
+   {
+      brw_MOV(p, get_element(c->reg.inlist, 0),  brw_address(c->reg.vertex[0]) );
+      brw_MOV(p, get_element(c->reg.inlist, 1),  brw_address(c->reg.vertex[1]) );
+      if (c->need_direction)
+	 brw_MOV(p, c->reg.dir, brw_imm_f(1));
+   }
+   brw_ENDIF(p, is_rev);
+
+   brw_MOV(p, get_element(c->reg.inlist, 2),  brw_address(c->reg.vertex[2]) );
+   brw_MOV(p, brw_vec8_grf(c->reg.outlist.nr, 0), brw_imm_f(0));
+   brw_MOV(p, c->reg.nr_verts, brw_imm_ud(3));
+}
+
+
+
+void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_instruction *is_poly;
+   struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
+
+   brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); 
+   brw_CMP(p, 
+	   vec1(brw_null_reg()), 
+	   BRW_CONDITIONAL_EQ, 
+	   tmp0,
+	   brw_imm_ud(_3DPRIM_POLYGON));
+
+   is_poly = brw_IF(p, BRW_EXECUTE_1);
+   {   
+      brw_clip_copy_colors(c, 1, 0);
+      brw_clip_copy_colors(c, 2, 0);
+   }
+   is_poly = brw_ELSE(p, is_poly);
+   {
+      brw_clip_copy_colors(c, 0, 2);
+      brw_clip_copy_colors(c, 1, 2);
+   }
+   brw_ENDIF(p, is_poly);
+}
+
+
+
+/* Use mesa's clipping algorithms, translated to GEN4 assembly.
+ */
+void brw_clip_tri( struct brw_clip_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_indirect vtx = brw_indirect(0, 0);
+   struct brw_indirect vtxPrev = brw_indirect(1, 0);
+   struct brw_indirect vtxOut = brw_indirect(2, 0);
+   struct brw_indirect plane_ptr = brw_indirect(3, 0);
+   struct brw_indirect inlist_ptr = brw_indirect(4, 0);
+   struct brw_indirect outlist_ptr = brw_indirect(5, 0);
+   struct brw_indirect freelist_ptr = brw_indirect(6, 0);
+   struct brw_instruction *plane_loop;
+   struct brw_instruction *plane_active;
+   struct brw_instruction *vertex_loop;
+   struct brw_instruction *next_test;
+   struct brw_instruction *prev_test;
+   
+   brw_MOV(p, get_addr_reg(vtxPrev),     brw_address(c->reg.vertex[2]) );
+   brw_MOV(p, get_addr_reg(plane_ptr),   brw_clip_plane0_address(c));
+   brw_MOV(p, get_addr_reg(inlist_ptr),  brw_address(c->reg.inlist));
+   brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
+
+   brw_MOV(p, get_addr_reg(freelist_ptr), brw_address(c->reg.vertex[3]) );
+
+   plane_loop = brw_DO(p, BRW_EXECUTE_1);
+   {
+      /* if (planemask & 1)
+       */
+      brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+      brw_AND(p, vec1(brw_null_reg()), c->reg.planemask, brw_imm_ud(1));
+      
+      plane_active = brw_IF(p, BRW_EXECUTE_1);
+      {
+	 /* vtxOut = freelist_ptr++ 
+	  */
+	 brw_MOV(p, get_addr_reg(vtxOut),       get_addr_reg(freelist_ptr) );
+	 brw_ADD(p, get_addr_reg(freelist_ptr), get_addr_reg(freelist_ptr), brw_imm_uw(c->nr_regs * REG_SIZE));
+
+	 if (c->key.nr_userclip)
+	    brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
+	 else
+	    brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
+	    
+	 brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
+	 brw_MOV(p, c->reg.nr_verts, brw_imm_ud(0));
+
+	 vertex_loop = brw_DO(p, BRW_EXECUTE_1);
+	 {
+	    /* vtx = *input_ptr;
+	     */
+	    brw_MOV(p, get_addr_reg(vtx), deref_1uw(inlist_ptr, 0));
+
+	    /* IS_NEGATIVE(prev) */
+	    brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
+	    brw_DP4(p, vec4(c->reg.dpPrev), deref_4f(vtxPrev, c->offset_hpos), c->reg.plane_equation);
+	    prev_test = brw_IF(p, BRW_EXECUTE_1);
+	    {
+	       /* IS_POSITIVE(next)
+		*/
+	       brw_set_conditionalmod(p, BRW_CONDITIONAL_GE);
+	       brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset_hpos), c->reg.plane_equation);
+	       next_test = brw_IF(p, BRW_EXECUTE_1);
+	       {
+
+		  /* Coming back in.
+		   */
+		  brw_ADD(p, c->reg.t, c->reg.dpPrev, negate(c->reg.dp));
+		  brw_math_invert(p, c->reg.t, c->reg.t);
+		  brw_MUL(p, c->reg.t, c->reg.t, c->reg.dpPrev);
+
+		  /* If (vtxOut == 0) vtxOut = vtxPrev
+		   */
+		  brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
+		  brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtxPrev) );
+		  brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+		  brw_clip_interp_vertex(c, vtxOut, vtxPrev, vtx, c->reg.t, GL_FALSE);
+
+		  /* *outlist_ptr++ = vtxOut;
+		   * nr_verts++; 
+		   * vtxOut = 0;
+		   */
+		  brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
+		  brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
+		  brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
+		  brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
+	       }
+	       brw_ENDIF(p, next_test);
+	       
+	    }
+	    prev_test = brw_ELSE(p, prev_test);
+	    {
+	       /* *outlist_ptr++ = vtxPrev;
+		* nr_verts++;
+		*/
+	       brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxPrev));
+	       brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
+	       brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
+
+	       /* IS_NEGATIVE(next)
+		*/
+	       brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
+	       brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset_hpos), c->reg.plane_equation);
+	       next_test = brw_IF(p, BRW_EXECUTE_1);
+	       {
+		  /* Going out of bounds.  Avoid division by zero as we
+		   * know dp != dpPrev from DIFFERENT_SIGNS, above.
+		   */
+		  brw_ADD(p, c->reg.t, c->reg.dp, negate(c->reg.dpPrev));
+		  brw_math_invert(p, c->reg.t, c->reg.t);
+		  brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp);
+
+		  /* If (vtxOut == 0) vtxOut = vtx
+		   */
+		  brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
+		  brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtx) );
+		  brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+		  brw_clip_interp_vertex(c, vtxOut, vtx, vtxPrev, c->reg.t, GL_TRUE);		  
+
+		  /* *outlist_ptr++ = vtxOut;
+		   * nr_verts++; 
+		   * vtxOut = 0;
+		   */
+		  brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
+		  brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
+		  brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
+		  brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
+	       } 	       
+	       brw_ENDIF(p, next_test);
+	    }
+	    brw_ENDIF(p, prev_test);
+	    
+	    /* vtxPrev = vtx;
+	     * inlist_ptr++;
+	     */
+	    brw_MOV(p, get_addr_reg(vtxPrev), get_addr_reg(vtx));
+	    brw_ADD(p, get_addr_reg(inlist_ptr), get_addr_reg(inlist_ptr), brw_imm_uw(sizeof(short)));
+
+	    /* while (--loopcount != 0)
+	     */
+	    brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+	    brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
+	 } 
+	 brw_WHILE(p, vertex_loop);
+
+	 /* vtxPrev = *(outlist_ptr-1)  OR: outlist[nr_verts-1]
+	  * inlist = outlist
+	  * inlist_ptr = &inlist[0]
+	  * outlist_ptr = &outlist[0]
+	  */
+	 brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_w(-2));
+	 brw_MOV(p, get_addr_reg(vtxPrev), deref_1uw(outlist_ptr, 0));
+	 brw_MOV(p, brw_vec8_grf(c->reg.inlist.nr, 0), brw_vec8_grf(c->reg.outlist.nr, 0));
+	 brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist));
+	 brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
+      }
+      brw_ENDIF(p, plane_active);
+      
+      /* plane_ptr++;
+       */
+      brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
+
+      /* nr_verts >= 3 
+       */
+      brw_CMP(p,
+	      vec1(brw_null_reg()),
+	      BRW_CONDITIONAL_GE,
+	      c->reg.nr_verts,
+	      brw_imm_ud(3));
+   
+      /* && (planemask>>=1) != 0
+       */
+      brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+      brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
+   }
+   brw_WHILE(p, plane_loop);
+}
+
+
+
+void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
+{
+   struct brw_compile *p = &c->func;
+   struct brw_instruction *loop, *if_insn;
+
+   /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
+    */
+   brw_set_conditionalmod(p, BRW_CONDITIONAL_G);
+   brw_ADD(p,
+	   c->reg.loopcount,
+	   c->reg.nr_verts,
+	   brw_imm_d(-2));
+
+   if_insn = brw_IF(p, BRW_EXECUTE_1);
+   {
+      struct brw_indirect v0 = brw_indirect(0, 0);
+      struct brw_indirect vptr = brw_indirect(1, 0);
+
+      brw_MOV(p, get_addr_reg(vptr), brw_address(c->reg.inlist));
+      brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
+
+      brw_clip_emit_vue(c, v0, 1, 0, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_START));
+      
+      brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
+      brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
+
+      loop = brw_DO(p, BRW_EXECUTE_1);
+      {
+	 brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_TRIFAN << 2));
+  
+	 brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
+	 brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
+
+	 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+	 brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
+      }
+      brw_WHILE(p, loop);
+
+      brw_clip_emit_vue(c, v0, 0, 1, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_END));
+   }
+   brw_ENDIF(p, if_insn);
+}
+
+static void do_clip_tri( struct brw_clip_compile *c )
+{
+   brw_clip_init_planes(c);
+
+   brw_clip_tri(c);
+}
+
+
+static void maybe_do_clip_tri( struct brw_clip_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_instruction *do_clip;
+
+   brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0));
+   do_clip = brw_IF(p, BRW_EXECUTE_1);
+   {
+      do_clip_tri(c);
+   }
+   brw_ENDIF(p, do_clip);
+}
+
+static void brw_clip_test( struct brw_clip_compile *c )
+{
+    struct brw_reg t = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
+    struct brw_reg t1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
+    struct brw_reg t2 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
+    struct brw_reg t3 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
+
+    struct brw_reg v0 = get_tmp(c);
+    struct brw_reg v1 = get_tmp(c);
+    struct brw_reg v2 = get_tmp(c);
+
+    struct brw_indirect vt0 = brw_indirect(0, 0);
+    struct brw_indirect vt1 = brw_indirect(1, 0);
+    struct brw_indirect vt2 = brw_indirect(2, 0);
+
+    struct brw_compile *p = &c->func;
+    struct brw_instruction *is_outside;
+    struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
+
+    brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0]));
+    brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1]));
+    brw_MOV(p, get_addr_reg(vt2), brw_address(c->reg.vertex[2]));
+    brw_MOV(p, v0, deref_4f(vt0, c->offset_hpos));
+    brw_MOV(p, v1, deref_4f(vt1, c->offset_hpos));
+    brw_MOV(p, v2, deref_4f(vt2, c->offset_hpos));
+    brw_AND(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(~0x3f));
+
+    /* test nearz, xmin, ymin plane */
+    /* clip.xyz < -clip.w */
+    brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, negate(get_element(v0, 3))); 
+    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+    brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, negate(get_element(v1, 3))); 
+    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+    brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, negate(get_element(v2, 3))); 
+    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+    /* All vertices are outside of a plane, rejected */
+    brw_AND(p, t, t1, t2);
+    brw_AND(p, t, t, t3);
+    brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
+    brw_OR(p, tmp0, tmp0, get_element(t, 2));
+    brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+    brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
+    is_outside = brw_IF(p, BRW_EXECUTE_1);
+    {
+        brw_clip_kill_thread(c);
+    }
+    brw_ENDIF(p, is_outside);
+    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+    /* some vertices are inside a plane, some are outside,need to clip */
+    brw_XOR(p, t, t1, t2);
+    brw_XOR(p, t1, t2, t3);
+    brw_OR(p, t, t, t1);
+    brw_AND(p, t, t, brw_imm_ud(0x1));
+    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+            get_element(t, 0), brw_imm_ud(0));
+    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5)));
+    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+            get_element(t, 1), brw_imm_ud(0));
+    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3)));
+    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+            get_element(t, 2), brw_imm_ud(0));
+    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1)));
+    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+    /* test farz, xmax, ymax plane */
+    /* clip.xyz > clip.w */
+    brw_CMP(p, t1, BRW_CONDITIONAL_G, v0, get_element(v0, 3)); 
+    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+    brw_CMP(p, t2, BRW_CONDITIONAL_G, v1, get_element(v1, 3)); 
+    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+    brw_CMP(p, t3, BRW_CONDITIONAL_G, v2, get_element(v2, 3)); 
+    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+    /* All vertices are outside of a plane, rejected */
+    brw_AND(p, t, t1, t2);
+    brw_AND(p, t, t, t3);
+    brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
+    brw_OR(p, tmp0, tmp0, get_element(t, 2));
+    brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+    brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
+    is_outside = brw_IF(p, BRW_EXECUTE_1);
+    {
+        brw_clip_kill_thread(c);
+    }
+    brw_ENDIF(p, is_outside);
+    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+    /* some vertices are inside a plane, some are outside,need to clip */
+    brw_XOR(p, t, t1, t2);
+    brw_XOR(p, t1, t2, t3);
+    brw_OR(p, t, t, t1);
+    brw_AND(p, t, t, brw_imm_ud(0x1));
+    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+            get_element(t, 0), brw_imm_ud(0));
+    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4)));
+    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+            get_element(t, 1), brw_imm_ud(0));
+    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2)));
+    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+            get_element(t, 2), brw_imm_ud(0));
+    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0)));
+    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+    release_tmps(c);
+}
+
+
+void brw_emit_tri_clip( struct brw_clip_compile *c )
+{
+   struct brw_instruction *neg_rhw;
+   struct brw_compile *p = &c->func;
+   brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
+   brw_clip_tri_init_vertices(c);
+   brw_clip_init_clipmask(c);
+   brw_clip_init_ff_sync(c);
+
+   /* if -ve rhw workaround bit is set, 
+      do cliptest */
+   if (c->chipset.is_965) {
+      brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+      brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), 
+              brw_imm_ud(1<<20));
+      neg_rhw = brw_IF(p, BRW_EXECUTE_1); 
+      {
+         brw_clip_test(c);
+      }
+      brw_ENDIF(p, neg_rhw);
+   }
+   /* Can't push into do_clip_tri because with polygon (or quad)
+    * flatshading, need to apply the flatshade here because we don't
+    * respect the PV when converting to trifan for emit:
+    */
+   if (c->key.do_flat_shading) 
+      brw_clip_tri_flat_shade(c); 
+      
+   if ((c->key.clip_mode == BRW_CLIPMODE_NORMAL) ||
+       (c->key.clip_mode == BRW_CLIPMODE_KERNEL_CLIP))
+      do_clip_tri(c);
+   else 
+      maybe_do_clip_tri(c);
+
+   brw_clip_tri_emit_polygon(c);
+
+   /* Send an empty message to kill the thread:
+    */
+   brw_clip_kill_thread(c);
+}
diff --git a/src/gallium/drivers/i965/brw_clip_unfilled.c b/src/gallium/drivers/i965/brw_clip_unfilled.c
new file mode 100644
index 0000000..aec835b
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_clip_unfilled.c
@@ -0,0 +1,497 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "brw_defines.h"
+#include "brw_eu.h"
+#include "brw_util.h"
+#include "brw_clip.h"
+
+
+
+/* This is performed against the original triangles, so no indirection
+ * required:
+BZZZT!
+ */
+static void compute_tri_direction( struct brw_clip_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg e = c->reg.tmp0;
+   struct brw_reg f = c->reg.tmp1;
+   struct brw_reg v0 = byte_offset(c->reg.vertex[0], c->offset_hpos); 
+   struct brw_reg v1 = byte_offset(c->reg.vertex[1], c->offset_hpos); 
+   struct brw_reg v2 = byte_offset(c->reg.vertex[2], c->offset_hpos); 
+
+
+   struct brw_reg v0n = get_tmp(c);
+   struct brw_reg v1n = get_tmp(c);
+   struct brw_reg v2n = get_tmp(c);
+
+   /* Convert to NDC.
+    * NOTE: We can't modify the original vertex coordinates,
+    * as it may impact further operations.
+    * So, we have to keep normalized coordinates in temp registers.
+    *
+    * TBD-KC
+    * Try to optimize unnecessary MOV's.
+    */
+   brw_MOV(p, v0n, v0);
+   brw_MOV(p, v1n, v1);
+   brw_MOV(p, v2n, v2);
+
+   brw_clip_project_position(c, v0n);
+   brw_clip_project_position(c, v1n);
+   brw_clip_project_position(c, v2n);
+
+   /* Calculate the vectors of two edges of the triangle:
+    */
+   brw_ADD(p, e, v0n, negate(v2n)); 
+   brw_ADD(p, f, v1n, negate(v2n)); 
+
+   /* Take their crossproduct:
+    */
+   brw_set_access_mode(p, BRW_ALIGN_16);
+   brw_MUL(p, vec4(brw_null_reg()), brw_swizzle(e, 1,2,0,3),  brw_swizzle(f,2,0,1,3));
+   brw_MAC(p, vec4(e),  negate(brw_swizzle(e, 2,0,1,3)), brw_swizzle(f,1,2,0,3));
+   brw_set_access_mode(p, BRW_ALIGN_1);
+
+   brw_MUL(p, c->reg.dir, c->reg.dir, vec4(e));
+}
+
+
+static void cull_direction( struct brw_clip_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_instruction *ccw;
+   GLuint conditional;
+
+   assert (!(c->key.fill_ccw == CLIP_CULL &&
+	     c->key.fill_cw == CLIP_CULL));
+
+   if (c->key.fill_ccw == CLIP_CULL)
+      conditional = BRW_CONDITIONAL_GE;
+   else
+      conditional = BRW_CONDITIONAL_L;
+
+   brw_CMP(p,
+	   vec1(brw_null_reg()),
+	   conditional,
+	   get_element(c->reg.dir, 2),
+	   brw_imm_f(0));
+   
+   ccw = brw_IF(p, BRW_EXECUTE_1);
+   {
+      brw_clip_kill_thread(c);
+   }
+   brw_ENDIF(p, ccw);
+}
+
+
+
+static void copy_bfc( struct brw_clip_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_instruction *ccw;
+   GLuint conditional;
+
+   /* Do we have any colors to copy? 
+    */
+   if ((c->offset_color0 == 0 || c->offset_bfc0 == 0) &&
+       (c->offset_color1 == 0 || c->offset_bfc1 == 0))
+      return;
+
+   /* In some wierd degnerate cases we can end up testing the
+    * direction twice, once for culling and once for bfc copying.  Oh
+    * well, that's what you get for setting wierd GL state.
+    */
+   if (c->key.copy_bfc_ccw)
+      conditional = BRW_CONDITIONAL_GE;
+   else
+      conditional = BRW_CONDITIONAL_L;
+
+   brw_CMP(p,
+	   vec1(brw_null_reg()),
+	   conditional,
+	   get_element(c->reg.dir, 2),
+	   brw_imm_f(0));
+   
+   ccw = brw_IF(p, BRW_EXECUTE_1);
+   {
+      GLuint i;
+
+      for (i = 0; i < 3; i++) {
+	 if (c->offset_color0 && c->offset_bfc0)
+	    brw_MOV(p, 
+		    byte_offset(c->reg.vertex[i], c->offset_color0),
+		    byte_offset(c->reg.vertex[i], c->offset_bfc0));
+
+	 if (c->offset_color1 && c->offset_bfc1)
+	    brw_MOV(p, 
+		    byte_offset(c->reg.vertex[i], c->offset_color0),
+		    byte_offset(c->reg.vertex[i], c->offset_bfc0));
+      }
+   }
+   brw_ENDIF(p, ccw);
+}
+
+
+
+
+/*
+  GLfloat iz	= 1.0 / dir.z;
+  GLfloat ac	= dir.x * iz;
+  GLfloat bc	= dir.y * iz;
+  offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
+  offset += MAX2( abs(ac), abs(bc) ) * ctx->Polygon.OffsetFactor;
+  offset *= MRD;
+*/
+static void compute_offset( struct brw_clip_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg off = c->reg.offset;
+   struct brw_reg dir = c->reg.dir;
+   
+   brw_math_invert(p, get_element(off, 2), get_element(dir, 2));
+   brw_MUL(p, vec2(off), dir, get_element(off, 2));
+
+   brw_CMP(p, 
+	   vec1(brw_null_reg()), 
+	   BRW_CONDITIONAL_GE,
+	   brw_abs(get_element(off, 0)), 
+	   brw_abs(get_element(off, 1)));
+
+   brw_SEL(p, vec1(off), brw_abs(get_element(off, 0)), brw_abs(get_element(off, 1)));
+   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+   brw_MUL(p, vec1(off), off, brw_imm_f(c->key.offset_factor));
+   brw_ADD(p, vec1(off), off, brw_imm_f(c->key.offset_units));
+}
+
+
+static void merge_edgeflags( struct brw_clip_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_instruction *is_poly;
+   struct brw_reg tmp0 = get_element_ud(c->reg.tmp0, 0);
+
+   brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); 
+   brw_CMP(p, 
+	   vec1(brw_null_reg()), 
+	   BRW_CONDITIONAL_EQ, 
+	   tmp0,
+	   brw_imm_ud(_3DPRIM_POLYGON));
+
+   /* Get away with using reg.vertex because we know that this is not
+    * a _3DPRIM_TRISTRIP_REVERSE:
+    */
+   is_poly = brw_IF(p, BRW_EXECUTE_1);
+   {   
+      brw_set_conditionalmod(p, BRW_CONDITIONAL_EQ);
+      brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<8));
+      brw_MOV(p, byte_offset(c->reg.vertex[0], c->offset_edgeflag), brw_imm_f(0));
+      brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+      brw_set_conditionalmod(p, BRW_CONDITIONAL_EQ);
+      brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<9));
+      brw_MOV(p, byte_offset(c->reg.vertex[2], c->offset_edgeflag), brw_imm_f(0));
+      brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+   }
+   brw_ENDIF(p, is_poly);
+}
+
+
+
+static void apply_one_offset( struct brw_clip_compile *c,
+			  struct brw_indirect vert )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg z = deref_1f(vert, c->header_position_offset +
+			       2 * type_sz(BRW_REGISTER_TYPE_F));
+
+   brw_ADD(p, z, z, vec1(c->reg.offset));
+}
+
+
+
+/***********************************************************************
+ * Output clipped polygon as an unfilled primitive:
+ */
+static void emit_lines(struct brw_clip_compile *c,
+		       GLboolean do_offset)
+{
+   struct brw_compile *p = &c->func;
+   struct brw_instruction *loop;
+   struct brw_instruction *draw_edge;
+   struct brw_indirect v0 = brw_indirect(0, 0);
+   struct brw_indirect v1 = brw_indirect(1, 0);
+   struct brw_indirect v0ptr = brw_indirect(2, 0);
+   struct brw_indirect v1ptr = brw_indirect(3, 0);
+
+   /* Need a seperate loop for offset:
+    */
+   if (do_offset) {
+      brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
+      brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist));
+
+      loop = brw_DO(p, BRW_EXECUTE_1);
+      {
+	 brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0));
+	 brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2));
+	    
+	 apply_one_offset(c, v0);
+	    
+	 brw_set_conditionalmod(p, BRW_CONDITIONAL_G);
+	 brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
+      }
+      brw_WHILE(p, loop);
+   }
+
+   /* v1ptr = &inlist[nr_verts]
+    * *v1ptr = v0
+    */
+   brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
+   brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist));
+   brw_ADD(p, get_addr_reg(v1ptr), get_addr_reg(v0ptr), retype(c->reg.nr_verts, BRW_REGISTER_TYPE_UW));
+   brw_ADD(p, get_addr_reg(v1ptr), get_addr_reg(v1ptr), retype(c->reg.nr_verts, BRW_REGISTER_TYPE_UW));
+   brw_MOV(p, deref_1uw(v1ptr, 0), deref_1uw(v0ptr, 0));
+
+   loop = brw_DO(p, BRW_EXECUTE_1);
+   {
+      brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0));
+      brw_MOV(p, get_addr_reg(v1), deref_1uw(v0ptr, 2));
+      brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2));
+
+      /* draw edge if edgeflag != 0 */
+      brw_CMP(p, 
+	      vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, 
+	      deref_1f(v0, c->offset_edgeflag),
+	      brw_imm_f(0));
+      draw_edge = brw_IF(p, BRW_EXECUTE_1);
+      {
+	 brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_START);
+	 brw_clip_emit_vue(c, v1, 1, 0, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_END);
+      }
+      brw_ENDIF(p, draw_edge);
+
+      brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+      brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
+   }
+   brw_WHILE(p, loop);
+}
+
+
+
+static void emit_points(struct brw_clip_compile *c,
+			GLboolean do_offset )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_instruction *loop;
+   struct brw_instruction *draw_point;
+
+   struct brw_indirect v0 = brw_indirect(0, 0);
+   struct brw_indirect v0ptr = brw_indirect(2, 0);
+
+   brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
+   brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist));
+
+   loop = brw_DO(p, BRW_EXECUTE_1);
+   {
+      brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0));
+      brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2));
+
+      /* draw if edgeflag != 0 
+       */
+      brw_CMP(p, 
+	      vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, 
+	      deref_1f(v0, c->offset_edgeflag),
+	      brw_imm_f(0));
+      draw_point = brw_IF(p, BRW_EXECUTE_1);
+      {
+	 if (do_offset)
+	    apply_one_offset(c, v0);
+
+	 brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_POINTLIST << 2) | R02_PRIM_START | R02_PRIM_END);
+      }
+      brw_ENDIF(p, draw_point);
+
+      brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+      brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
+   }
+   brw_WHILE(p, loop);
+}
+
+
+
+
+
+
+
+static void emit_primitives( struct brw_clip_compile *c,
+			     GLuint mode, 
+			     GLboolean do_offset )
+{
+   switch (mode) {
+   case CLIP_FILL:
+      brw_clip_tri_emit_polygon(c);
+      break;
+
+   case CLIP_LINE:
+      emit_lines(c, do_offset);
+      break;
+
+   case CLIP_POINT:
+      emit_points(c, do_offset);
+      break;
+
+   case CLIP_CULL:
+      assert(0);
+      break;
+   }
+} 
+
+
+
+static void emit_unfilled_primitives( struct brw_clip_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_instruction *ccw;
+
+   /* Direction culling has already been done.
+    */
+   if (c->key.fill_ccw != c->key.fill_cw &&
+       c->key.fill_ccw != CLIP_CULL &&
+       c->key.fill_cw != CLIP_CULL)
+   {
+      brw_CMP(p,
+	      vec1(brw_null_reg()),
+	      BRW_CONDITIONAL_GE,
+	      get_element(c->reg.dir, 2),
+	      brw_imm_f(0));
+   
+      ccw = brw_IF(p, BRW_EXECUTE_1);
+      {
+	 emit_primitives(c, c->key.fill_ccw, c->key.offset_ccw);
+      }
+      ccw = brw_ELSE(p, ccw);
+      {
+	 emit_primitives(c, c->key.fill_cw, c->key.offset_cw);
+      }
+      brw_ENDIF(p, ccw);
+   }
+   else if (c->key.fill_cw != CLIP_CULL) {
+      emit_primitives(c, c->key.fill_cw, c->key.offset_cw);
+   }
+   else if (c->key.fill_ccw != CLIP_CULL) { 
+      emit_primitives(c, c->key.fill_ccw, c->key.offset_ccw);
+   }
+}
+
+
+
+
+static void check_nr_verts( struct brw_clip_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_instruction *if_insn;
+
+   brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.nr_verts, brw_imm_d(3));      
+   if_insn = brw_IF(p, BRW_EXECUTE_1);
+   {
+      brw_clip_kill_thread(c);
+   }
+   brw_ENDIF(p, if_insn);
+}
+
+
+void brw_emit_unfilled_clip( struct brw_clip_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_instruction *do_clip;
+   
+
+   c->need_direction = ((c->key.offset_ccw || c->key.offset_cw) ||
+			(c->key.fill_ccw != c->key.fill_cw) ||
+			c->key.fill_ccw == CLIP_CULL ||
+			c->key.fill_cw == CLIP_CULL ||
+			c->key.copy_bfc_cw ||
+			c->key.copy_bfc_ccw);
+
+   brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
+   brw_clip_tri_init_vertices(c);
+   brw_clip_init_ff_sync(c);
+
+   assert(c->offset_edgeflag);
+
+   if (c->key.fill_ccw == CLIP_CULL &&
+       c->key.fill_cw == CLIP_CULL) {
+      brw_clip_kill_thread(c);
+      return;
+   }
+
+   merge_edgeflags(c);
+
+   /* Need to use the inlist indirection here: 
+    */
+   if (c->need_direction) 
+      compute_tri_direction(c);
+   
+   if (c->key.fill_ccw == CLIP_CULL ||
+       c->key.fill_cw == CLIP_CULL)
+      cull_direction(c);
+
+   if (c->key.offset_ccw ||
+       c->key.offset_cw)
+      compute_offset(c);
+
+   if (c->key.copy_bfc_ccw ||
+       c->key.copy_bfc_cw)
+      copy_bfc(c);
+
+   /* Need to do this whether we clip or not:
+    */
+   if (c->key.do_flat_shading)
+      brw_clip_tri_flat_shade(c);
+   
+   brw_clip_init_clipmask(c);
+   brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0));
+   do_clip = brw_IF(p, BRW_EXECUTE_1);
+   {
+      brw_clip_init_planes(c);
+      brw_clip_tri(c);
+      check_nr_verts(c);
+   }
+   brw_ENDIF(p, do_clip);
+   
+   emit_unfilled_primitives(c);
+   brw_clip_kill_thread(c);
+}
+
+
+
diff --git a/src/gallium/drivers/i965/brw_clip_util.c b/src/gallium/drivers/i965/brw_clip_util.c
new file mode 100644
index 0000000..97a5710
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_clip_util.c
@@ -0,0 +1,388 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+
+#include "brw_defines.h"
+#include "brw_eu.h"
+#include "brw_util.h"
+#include "brw_clip.h"
+
+
+
+
+struct brw_reg get_tmp( struct brw_clip_compile *c )
+{
+   struct brw_reg tmp = brw_vec4_grf(c->last_tmp, 0);
+
+   if (++c->last_tmp > c->prog_data.total_grf)
+      c->prog_data.total_grf = c->last_tmp;
+
+   return tmp;
+}
+
+static void release_tmp( struct brw_clip_compile *c, struct brw_reg tmp )
+{
+   if (tmp.nr == c->last_tmp-1)
+      c->last_tmp--;
+}
+
+
+static struct brw_reg make_plane_ud(GLuint x, GLuint y, GLuint z, GLuint w)
+{
+   return brw_imm_ud((w<<24) | (z<<16) | (y<<8) | x);
+}
+
+
+void brw_clip_init_planes( struct brw_clip_compile *c )
+{
+   struct brw_compile *p = &c->func;
+
+   if (!c->key.nr_userclip) {
+      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 0), make_plane_ud( 0,    0, 0xff, 1));
+      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 1), make_plane_ud( 0,    0,    1, 1));
+      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 2), make_plane_ud( 0, 0xff,    0, 1));
+      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 3), make_plane_ud( 0,    1,    0, 1));
+      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 4), make_plane_ud(0xff,  0,    0, 1));
+      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 5), make_plane_ud( 1,    0,    0, 1));
+   }
+}
+
+
+
+#define W 3
+
+/* Project 'pos' to screen space (or back again), overwrite with results:
+ */
+void brw_clip_project_position(struct brw_clip_compile *c, struct brw_reg pos )
+{
+   struct brw_compile *p = &c->func;
+
+   /* calc rhw 
+    */
+   brw_math_invert(p, get_element(pos, W), get_element(pos, W));
+
+   /* value.xyz *= value.rhw
+    */
+   brw_set_access_mode(p, BRW_ALIGN_16);
+   brw_MUL(p, brw_writemask(pos, BRW_WRITEMASK_XYZ), pos, brw_swizzle1(pos, W));
+   brw_set_access_mode(p, BRW_ALIGN_1);
+}
+
+
+static void brw_clip_project_vertex( struct brw_clip_compile *c, 
+				     struct brw_indirect vert_addr )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg tmp = get_tmp(c);
+
+   /* Fixup position.  Extract from the original vertex and re-project
+    * to screen space:
+    */
+   brw_MOV(p, tmp, deref_4f(vert_addr, c->offset_hpos));
+   brw_clip_project_position(c, tmp);
+   brw_MOV(p, deref_4f(vert_addr, c->header_position_offset), tmp);
+	 
+   release_tmp(c, tmp);
+}
+
+
+
+
+/* Interpolate between two vertices and put the result into a0.0.  
+ * Increment a0.0 accordingly.
+ */
+void brw_clip_interp_vertex( struct brw_clip_compile *c,
+			     struct brw_indirect dest_ptr,
+			     struct brw_indirect v0_ptr, /* from */
+			     struct brw_indirect v1_ptr, /* to */
+			     struct brw_reg t0,
+			     GLboolean force_edgeflag)
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg tmp = get_tmp(c);
+   GLuint i;
+
+   /* Just copy the vertex header:
+    */
+   /*
+    * After CLIP stage, only first 256 bits of the VUE are read
+    * back on IGDNG, so needn't change it
+    */
+   brw_copy_indirect_to_indirect(p, dest_ptr, v0_ptr, 1);
+      
+   /* Iterate over each attribute (could be done in pairs?)
+    */
+   for (i = 0; i < c->key.nr_attrs; i++) {
+      GLuint delta = i*16 + 32;
+
+      if (c->chipset.is_igdng)
+          delta = i * 16 + 32 * 3;
+
+      if (delta == c->offset_edgeflag) {
+	 if (force_edgeflag) 
+	    brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(1));
+	 else
+	    brw_MOV(p, deref_4f(dest_ptr, delta), deref_4f(v0_ptr, delta));
+      }
+      else {
+	 /* Interpolate: 
+	  *
+	  *        New = attr0 + t*attr1 - t*attr0
+	  */
+	 brw_MUL(p, 
+		 vec4(brw_null_reg()),
+		 deref_4f(v1_ptr, delta),
+		 t0);
+
+	 brw_MAC(p, 
+		 tmp,	      
+		 negate(deref_4f(v0_ptr, delta)),
+		 t0); 
+	      
+	 brw_ADD(p,
+		 deref_4f(dest_ptr, delta), 
+		 deref_4f(v0_ptr, delta),
+		 tmp);
+      }
+   }
+
+   if (i & 1) {
+      GLuint delta = i*16 + 32;
+
+      if (c->chipset.is_igdng)
+          delta = i * 16 + 32 * 3;
+
+      brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0));
+   }
+
+   release_tmp(c, tmp);
+
+   /* Recreate the projected (NDC) coordinate in the new vertex
+    * header:
+    */
+   brw_clip_project_vertex(c, dest_ptr );
+}
+
+
+
+
+#define MAX_MRF 16
+
+void brw_clip_emit_vue(struct brw_clip_compile *c, 
+		       struct brw_indirect vert,
+		       GLboolean allocate,
+		       GLboolean eot,
+		       GLuint header)
+{
+   struct brw_compile *p = &c->func;
+   GLuint start = c->last_mrf;
+
+   brw_clip_ff_sync(c);
+
+   assert(!(allocate && eot));
+   
+   /* Cycle through mrf regs - probably futile as we have to wait for
+    * the allocation response anyway.  Also, the order this function
+    * is invoked doesn't correspond to the order the instructions will
+    * be executed, so it won't have any effect in many cases.
+    */
+#if 0
+   if (start + c->nr_regs + 1 >= MAX_MRF)
+      start = 0;
+
+   c->last_mrf = start + c->nr_regs + 1;
+#endif
+	
+   /* Copy the vertex from vertn into m1..mN+1:
+    */
+   brw_copy_from_indirect(p, brw_message_reg(start+1), vert, c->nr_regs);
+
+   /* Overwrite PrimType and PrimStart in the message header, for
+    * each vertex in turn:
+    */
+   brw_MOV(p, get_element_ud(c->reg.R0, 2), brw_imm_ud(header));
+
+
+   /* Send each vertex as a seperate write to the urb.  This
+    * is different to the concept in brw_sf_emit.c, where
+    * subsequent writes are used to build up a single urb
+    * entry.  Each of these writes instantiates a seperate
+    * urb entry - (I think... what about 'allocate'?)
+    */
+   brw_urb_WRITE(p, 
+		 allocate ? c->reg.R0 : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
+		 start,
+		 c->reg.R0,
+		 allocate,
+		 1,		/* used */
+		 c->nr_regs + 1, /* msg length */
+		 allocate ? 1 : 0, /* response_length */ 
+		 eot,		/* eot */
+		 1,		/* writes_complete */
+		 0,		/* urb offset */
+		 BRW_URB_SWIZZLE_NONE);
+}
+
+
+
+void brw_clip_kill_thread(struct brw_clip_compile *c)
+{
+   struct brw_compile *p = &c->func;
+
+   brw_clip_ff_sync(c);
+   /* Send an empty message to kill the thread and release any
+    * allocated urb entry:
+    */
+   brw_urb_WRITE(p, 
+		 retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
+		 0,
+		 c->reg.R0,
+		 0,		/* allocate */
+		 0,		/* used */
+		 1, 		/* msg len */
+		 0, 		/* response len */
+		 1, 		/* eot */
+		 1,		/* writes complete */
+		 0,
+		 BRW_URB_SWIZZLE_NONE);
+}
+
+
+
+
+struct brw_reg brw_clip_plane0_address( struct brw_clip_compile *c )
+{
+   return brw_address(c->reg.fixed_planes);
+}
+
+
+struct brw_reg brw_clip_plane_stride( struct brw_clip_compile *c )
+{
+   if (c->key.nr_userclip) {
+      return brw_imm_uw(16);
+   }
+   else {
+      return brw_imm_uw(4);
+   }
+}
+
+
+/* If flatshading, distribute color from provoking vertex prior to
+ * clipping.
+ */
+void brw_clip_copy_colors( struct brw_clip_compile *c,
+			   GLuint to, GLuint from )
+{
+   struct brw_compile *p = &c->func;
+
+   if (c->offset_color0)
+      brw_MOV(p, 
+	      byte_offset(c->reg.vertex[to], c->offset_color0),
+	      byte_offset(c->reg.vertex[from], c->offset_color0));
+
+   if (c->offset_color1)
+      brw_MOV(p, 
+	      byte_offset(c->reg.vertex[to], c->offset_color1),
+	      byte_offset(c->reg.vertex[from], c->offset_color1));
+
+   if (c->offset_bfc0)
+      brw_MOV(p, 
+	      byte_offset(c->reg.vertex[to], c->offset_bfc0),
+	      byte_offset(c->reg.vertex[from], c->offset_bfc0));
+
+   if (c->offset_bfc1)
+      brw_MOV(p, 
+	      byte_offset(c->reg.vertex[to], c->offset_bfc1),
+	      byte_offset(c->reg.vertex[from], c->offset_bfc1));
+}
+
+
+
+void brw_clip_init_clipmask( struct brw_clip_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg incoming = get_element_ud(c->reg.R0, 2);
+   
+   /* Shift so that lowest outcode bit is rightmost: 
+    */
+   brw_SHR(p, c->reg.planemask, incoming, brw_imm_ud(26));
+
+   if (c->key.nr_userclip) {
+      struct brw_reg tmp = retype(vec1(get_tmp(c)), BRW_REGISTER_TYPE_UD);
+
+      /* Rearrange userclip outcodes so that they come directly after
+       * the fixed plane bits.
+       */
+      brw_AND(p, tmp, incoming, brw_imm_ud(0x3f<<14));
+      brw_SHR(p, tmp, tmp, brw_imm_ud(8));
+      brw_OR(p, c->reg.planemask, c->reg.planemask, tmp);
+      
+      release_tmp(c, tmp);
+   }
+}
+
+void brw_clip_ff_sync(struct brw_clip_compile *c)
+{
+    if (c->need_ff_sync) {
+        struct brw_compile *p = &c->func;
+        struct brw_instruction *need_ff_sync;
+
+        brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
+        brw_AND(p, brw_null_reg(), c->reg.ff_sync, brw_imm_ud(0x1));
+        need_ff_sync = brw_IF(p, BRW_EXECUTE_1);
+        {
+            brw_OR(p, c->reg.ff_sync, c->reg.ff_sync, brw_imm_ud(0x1));
+            brw_ff_sync(p, 
+                    c->reg.R0,
+                    0,
+                    c->reg.R0,
+                    1,	
+                    1,		/* used */
+                    1,  	/* msg length */
+                    1,		/* response length */
+                    0,		/* eot */
+                    1,		/* write compelete */
+                    0,		/* urb offset */
+                    BRW_URB_SWIZZLE_NONE);
+        }
+        brw_ENDIF(p, need_ff_sync);
+        brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+    }
+}
+
+void brw_clip_init_ff_sync(struct brw_clip_compile *c)
+{
+    if (c->need_ff_sync) {
+	struct brw_compile *p = &c->func;
+        
+        brw_MOV(p, c->reg.ff_sync, brw_imm_ud(0));
+    }
+}
diff --git a/src/gallium/drivers/i965/brw_context.c b/src/gallium/drivers/i965/brw_context.c
new file mode 100644
index 0000000..e675518
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_context.c
@@ -0,0 +1,154 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+
+#include "pipe/p_context.h"
+#include "util/u_simple_list.h"
+
+#include "brw_context.h"
+#include "brw_defines.h"
+#include "brw_draw.h"
+#include "brw_state.h"
+#include "brw_batchbuffer.h"
+#include "brw_winsys.h"
+#include "brw_screen.h"
+
+
+static void brw_destroy_context( struct pipe_context *pipe )
+{
+   struct brw_context *brw = brw_context(pipe);
+   int i;
+
+   brw_context_flush( brw );
+   brw_batchbuffer_free( brw->batch );
+   brw_destroy_state(brw);
+
+   brw_draw_cleanup( brw );
+
+   brw_pipe_blend_cleanup( brw );
+   brw_pipe_depth_stencil_cleanup( brw );
+   brw_pipe_framebuffer_cleanup( brw );
+   brw_pipe_flush_cleanup( brw );
+   brw_pipe_misc_cleanup( brw );
+   brw_pipe_query_cleanup( brw );
+   brw_pipe_rast_cleanup( brw );
+   brw_pipe_sampler_cleanup( brw );
+   brw_pipe_shader_cleanup( brw );
+   brw_pipe_vertex_cleanup( brw );
+   brw_pipe_clear_cleanup( brw );
+
+   brw_hw_cc_cleanup( brw );
+
+
+   FREE(brw->wm.compile_data);
+
+   for (i = 0; i < brw->curr.fb.nr_cbufs; i++)
+      pipe_surface_reference(&brw->curr.fb.cbufs[i], NULL);
+   brw->curr.fb.nr_cbufs = 0;
+   pipe_surface_reference(&brw->curr.fb.zsbuf, NULL);
+
+   bo_reference(&brw->curbe.curbe_bo, NULL);
+   bo_reference(&brw->vs.prog_bo, NULL);
+   bo_reference(&brw->vs.state_bo, NULL);
+   bo_reference(&brw->vs.bind_bo, NULL);
+   bo_reference(&brw->gs.prog_bo, NULL);
+   bo_reference(&brw->gs.state_bo, NULL);
+   bo_reference(&brw->clip.prog_bo, NULL);
+   bo_reference(&brw->clip.state_bo, NULL);
+   bo_reference(&brw->clip.vp_bo, NULL);
+   bo_reference(&brw->sf.prog_bo, NULL);
+   bo_reference(&brw->sf.state_bo, NULL);
+   bo_reference(&brw->sf.vp_bo, NULL);
+
+   for (i = 0; i < Elements(brw->wm.sdc_bo); i++)
+      bo_reference(&brw->wm.sdc_bo[i], NULL);
+
+   bo_reference(&brw->wm.bind_bo, NULL);
+
+   for (i = 0; i < Elements(brw->wm.surf_bo); i++)
+      bo_reference(&brw->wm.surf_bo[i], NULL);
+
+   bo_reference(&brw->wm.sampler_bo, NULL);
+   bo_reference(&brw->wm.prog_bo, NULL);
+   bo_reference(&brw->wm.state_bo, NULL);
+}
+
+
+struct pipe_context *brw_create_context(struct pipe_screen *screen)
+{
+   struct brw_context *brw = (struct brw_context *) CALLOC_STRUCT(brw_context);
+
+   if (!brw) {
+      debug_printf("%s: failed to alloc context\n", __FUNCTION__);
+      return NULL;
+   }
+
+   brw->base.screen = screen;
+   brw->base.destroy = brw_destroy_context;
+   brw->sws = brw_screen(screen)->sws;
+   brw->chipset = brw_screen(screen)->chipset;
+
+   brw_pipe_blend_init( brw );
+   brw_pipe_depth_stencil_init( brw );
+   brw_pipe_framebuffer_init( brw );
+   brw_pipe_flush_init( brw );
+   brw_pipe_misc_init( brw );
+   brw_pipe_query_init( brw );
+   brw_pipe_rast_init( brw );
+   brw_pipe_sampler_init( brw );
+   brw_pipe_shader_init( brw );
+   brw_pipe_vertex_init( brw );
+   brw_pipe_clear_init( brw );
+
+   brw_hw_cc_init( brw );
+
+   brw_init_state( brw );
+   brw_draw_init( brw );
+
+   brw->state.dirty.mesa = ~0;
+   brw->state.dirty.brw = ~0;
+
+   brw->flags.always_emit_state = 0;
+
+   make_empty_list(&brw->query.active_head);
+
+   brw->batch = brw_batchbuffer_alloc( brw->sws, brw->chipset );
+   if (brw->batch == NULL)
+      goto fail;
+
+   return &brw->base;
+
+fail:
+   if (brw->batch)
+      brw_batchbuffer_free( brw->batch );
+   return NULL;
+}
+
diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h
new file mode 100644
index 0000000..8c006bb
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_context.h
@@ -0,0 +1,858 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+
+#ifndef BRWCONTEXT_INC
+#define BRWCONTEXT_INC
+
+#include "brw_structs.h"
+#include "brw_winsys.h"
+#include "brw_reg.h"
+#include "pipe/p_state.h"
+#include "pipe/p_context.h"
+#include "tgsi/tgsi_scan.h"
+
+
+/* Glossary:
+ *
+ * URB - uniform resource buffer.  A mid-sized buffer which is
+ * partitioned between the fixed function units and used for passing
+ * values (vertices, primitives, constants) between them.
+ *
+ * CURBE - constant URB entry.  An urb region (entry) used to hold
+ * constant values which the fixed function units can be instructed to
+ * preload into the GRF when spawning a thread.
+ *
+ * VUE - vertex URB entry.  An urb entry holding a vertex and usually
+ * a vertex header.  The header contains control information and
+ * things like primitive type, Begin/end flags and clip codes.  
+ *
+ * PUE - primitive URB entry.  An urb entry produced by the setup (SF)
+ * unit holding rasterization and interpolation parameters.
+ *
+ * GRF - general register file.  One of several register files
+ * addressable by programmed threads.  The inputs (r0, payload, curbe,
+ * urb) of the thread are preloaded to this area before the thread is
+ * spawned.  The registers are individually 8 dwords wide and suitable
+ * for general usage.  Registers holding thread input values are not
+ * special and may be overwritten.
+ *
+ * MRF - message register file.  Threads communicate (and terminate)
+ * by sending messages.  Message parameters are placed in contiguous
+ * MRF registers.  All program output is via these messages.  URB
+ * entries are populated by sending a message to the shared URB
+ * function containing the new data, together with a control word,
+ * often an unmodified copy of R0.
+ *
+ * R0 - GRF register 0.  Typically holds control information used when
+ * sending messages to other threads.
+ *
+ * EU or GEN4 EU: The name of the programmable subsystem of the
+ * i965 hardware.  Threads are executed by the EU, the registers
+ * described above are part of the EU architecture.
+ *
+ * Fixed function units:
+ *
+ * CS - Command streamer.  Notional first unit, little software
+ * interaction.  Holds the URB entries used for constant data, ie the
+ * CURBEs.
+ *
+ * VF/VS - Vertex Fetch / Vertex Shader.  The fixed function part of
+ * this unit is responsible for pulling vertices out of vertex buffers
+ * in vram and injecting them into the processing pipe as VUEs.  If
+ * enabled, it first passes them to a VS thread which is a good place
+ * for the driver to implement any active vertex shader.
+ *
+ * GS - Geometry Shader.  This corresponds to a new DX10 concept.  If
+ * enabled, incoming strips etc are passed to GS threads in individual
+ * line/triangle/point units.  The GS thread may perform arbitary
+ * computation and emit whatever primtives with whatever vertices it
+ * chooses.  This makes GS an excellent place to implement GL's
+ * unfilled polygon modes, though of course it is capable of much
+ * more.  Additionally, GS is used to translate away primitives not
+ * handled by latter units, including Quads and Lineloops.
+ *
+ * CS - Clipper.  Mesa's clipping algorithms are imported to run on
+ * this unit.  The fixed function part performs cliptesting against
+ * the 6 fixed clipplanes and makes decisions on whether or not the
+ * incoming primitive needs to be passed to a thread for clipping.
+ * User clip planes are handled via cooperation with the VS thread.
+ *
+ * SF - Strips Fans or Setup: Triangles are prepared for
+ * rasterization.  Interpolation coefficients are calculated.
+ * Flatshading and two-side lighting usually performed here.
+ *
+ * WM - Windower.  Interpolation of vertex attributes performed here.
+ * Fragment shader implemented here.  SIMD aspects of EU taken full
+ * advantage of, as pixels are processed in blocks of 16.
+ *
+ * CC - Color Calculator.  No EU threads associated with this unit.
+ * Handles blending and (presumably) depth and stencil testing.
+ */
+
+#define BRW_MAX_CURBE                    (32*16)
+
+
+/* Need a value to say a particular vertex shader output isn't
+ * present.  Limits us to 63 outputs currently.
+ */
+#define BRW_OUTPUT_NOT_PRESENT           ((1<<6)-1)
+
+
+struct brw_context;
+
+struct brw_depth_stencil_state {
+   /* Precalculated hardware state:
+    */
+   struct brw_cc0 cc0;
+   struct brw_cc1 cc1;
+   struct brw_cc2 cc2;
+   struct brw_cc3 cc3;
+   struct brw_cc7 cc7;
+
+   unsigned iz_lookup;
+};
+
+
+struct brw_blend_state {
+   /* Precalculated hardware state:
+    */
+   struct brw_cc2 cc2;
+   struct brw_cc3 cc3;
+   struct brw_cc5 cc5;
+   struct brw_cc6 cc6;
+
+   struct brw_surf_ss0 ss0;
+};
+
+
+struct brw_rasterizer_state;
+
+struct brw_immediate_data {
+   unsigned nr;
+   float (*data)[4];
+};
+
+struct brw_vertex_shader {
+   const struct tgsi_token *tokens;
+   struct brw_winsys_buffer *const_buffer;    /** Program constant buffer/surface */
+
+   struct tgsi_shader_info info;
+   struct brw_immediate_data immediates;
+
+   GLuint has_flow_control:1;
+   GLuint use_const_buffer:1;
+
+   /* Offsets of special vertex shader outputs required for clipping.
+    */
+   GLuint output_hpos:6;        /* not always zero? */
+   GLuint output_color0:6;
+   GLuint output_color1:6;
+   GLuint output_bfc0:6;
+   GLuint output_bfc1:6;
+   GLuint output_edgeflag:6;
+
+   unsigned id;
+};
+
+struct brw_fs_signature {
+   GLuint nr_inputs;
+   struct {
+      GLuint interp:3;          /* TGSI_INTERPOLATE_x */
+      GLuint semantic:5;        /* TGSI_SEMANTIC_x */
+      GLuint semantic_index:24;
+   } input[PIPE_MAX_SHADER_INPUTS];
+};
+
+#define brw_fs_signature_size(s) (offsetof(struct brw_fs_signature, input) + \
+                                  ((s)->nr_inputs * sizeof (s)->input[0])) 
+
+
+struct brw_fragment_shader {
+   const struct tgsi_token *tokens;
+   struct tgsi_shader_info info;
+
+   struct brw_fs_signature signature;
+   struct brw_immediate_data immediates;
+
+   unsigned iz_lookup;
+   /*unsigned wm_lookup;*/
+   
+   unsigned  uses_depth:1;
+   unsigned  has_flow_control:1;
+
+   unsigned id;
+   struct brw_winsys_buffer *const_buffer;    /** Program constant buffer/surface */
+   GLboolean use_const_buffer;
+};
+
+
+struct brw_sampler {
+   struct brw_ss0 ss0;
+   struct brw_ss1 ss1;
+   float border_color[4];
+   struct brw_ss3 ss3;
+};
+
+
+
+#define PIPE_NEW_DEPTH_STENCIL_ALPHA    0x1
+#define PIPE_NEW_RAST                   0x2
+#define PIPE_NEW_BLEND                  0x4
+#define PIPE_NEW_VIEWPORT               0x8
+#define PIPE_NEW_SAMPLERS               0x10
+#define PIPE_NEW_VERTEX_BUFFER          0x20
+#define PIPE_NEW_VERTEX_ELEMENT         0x40
+#define PIPE_NEW_FRAGMENT_SHADER        0x80
+#define PIPE_NEW_VERTEX_SHADER          0x100
+#define PIPE_NEW_FRAGMENT_CONSTANTS     0x200
+#define PIPE_NEW_VERTEX_CONSTANTS       0x400
+#define PIPE_NEW_CLIP                   0x800
+#define PIPE_NEW_INDEX_BUFFER           0x1000
+#define PIPE_NEW_INDEX_RANGE            0x2000
+#define PIPE_NEW_BLEND_COLOR            0x4000
+#define PIPE_NEW_POLYGON_STIPPLE        0x8000
+#define PIPE_NEW_FRAMEBUFFER_DIMENSIONS 0x10000
+#define PIPE_NEW_DEPTH_BUFFER           0x20000
+#define PIPE_NEW_COLOR_BUFFERS          0x40000
+#define PIPE_NEW_QUERY                  0x80000
+#define PIPE_NEW_SCISSOR                0x100000
+#define PIPE_NEW_BOUND_TEXTURES         0x200000
+#define PIPE_NEW_NR_CBUFS               0x400000
+#define PIPE_NEW_FRAGMENT_SIGNATURE     0x800000
+
+
+
+#define BRW_NEW_URB_FENCE               0x1
+#define BRW_NEW_FRAGMENT_PROGRAM        0x2
+#define BRW_NEW_VERTEX_PROGRAM          0x4
+#define BRW_NEW_INPUT_DIMENSIONS        0x8
+#define BRW_NEW_CURBE_OFFSETS           0x10
+#define BRW_NEW_REDUCED_PRIMITIVE       0x20
+#define BRW_NEW_PRIMITIVE               0x40
+#define BRW_NEW_CONTEXT                 0x80
+#define BRW_NEW_WM_INPUT_DIMENSIONS     0x100
+#define BRW_NEW_PSP                     0x800
+#define BRW_NEW_WM_SURFACES		0x1000
+#define BRW_NEW_xxx                     0x2000 /* was FENCE */
+#define BRW_NEW_INDICES			0x4000
+
+/**
+ * Used for any batch entry with a relocated pointer that will be used
+ * by any 3D rendering.  Need to re-emit these fresh in each
+ * batchbuffer as the referenced buffers may be relocated in the
+ * meantime.
+ */
+#define BRW_NEW_BATCH			0x10000
+#define BRW_NEW_NR_WM_SURFACES		0x40000
+#define BRW_NEW_NR_VS_SURFACES		0x80000
+#define BRW_NEW_INDEX_BUFFER		0x100000
+
+struct brw_state_flags {
+   /** State update flags signalled by mesa internals */
+   GLuint mesa;
+   /**
+    * State update flags signalled as the result of brw_tracked_state updates
+    */
+   GLuint brw;
+   /** State update flags signalled by brw_state_cache.c searches */
+   GLuint cache;
+};
+
+
+
+/* Data about a particular attempt to compile a program.  Note that
+ * there can be many of these, each in a different GL state
+ * corresponding to a different brw_wm_prog_key struct, with different
+ * compiled programs:
+ */
+struct brw_wm_prog_data {
+   GLuint curb_read_length;
+   GLuint urb_read_length;
+
+   GLuint first_curbe_grf;
+   GLuint total_grf;
+   GLuint total_scratch;
+
+   GLuint nr_params;       /**< number of float params/constants */
+   GLboolean error;
+
+   /* Pointer to tracked values (only valid once
+    * _mesa_load_state_parameters has been called at runtime).
+    */
+   const GLfloat *param[BRW_MAX_CURBE];
+};
+
+struct brw_sf_prog_data {
+   GLuint urb_read_length;
+   GLuint total_grf;
+
+   /* Each vertex may have upto 12 attributes, 4 components each,
+    * except WPOS which requires only 2.  (11*4 + 2) == 44 ==> 11
+    * rows.
+    *
+    * Actually we use 4 for each, so call it 12 rows.
+    */
+   GLuint urb_entry_size;
+};
+
+
+struct brw_clip_prog_data;
+
+struct brw_gs_prog_data {
+   GLuint urb_read_length;
+   GLuint total_grf;
+};
+
+struct brw_vs_prog_data {
+   GLuint curb_read_length;
+   GLuint urb_read_length;
+   GLuint total_grf;
+
+   GLuint nr_outputs;
+   GLuint nr_inputs;
+
+   GLuint nr_params;       /**< number of TGSI_FILE_CONSTANT's */
+
+   GLboolean writes_psiz;
+
+   /* Used for calculating urb partitions:
+    */
+   GLuint urb_entry_size;
+};
+
+
+/* Size == 0 if output either not written, or always [0,0,0,1]
+ */
+struct brw_vs_ouput_sizes {
+   GLubyte output_size[PIPE_MAX_SHADER_OUTPUTS];
+};
+
+
+/** Number of texture sampler units */
+#define BRW_MAX_TEX_UNIT 16
+
+/** Max number of render targets in a shader */
+#define BRW_MAX_DRAW_BUFFERS 4
+
+/**
+ * Size of our surface binding table for the WM.
+ * This contains pointers to the drawing surfaces and current texture
+ * objects and shader constant buffers (+2).
+ */
+#define BRW_WM_MAX_SURF (BRW_MAX_DRAW_BUFFERS + BRW_MAX_TEX_UNIT + 1)
+
+/**
+ * Helpers to convert drawing buffers, textures and constant buffers
+ * to surface binding table indexes, for WM.
+ */
+#define BTI_COLOR_BUF(d)          (d)
+#define BTI_FRAGMENT_CONSTANTS    (BRW_MAX_DRAW_BUFFERS) 
+#define BTI_TEXTURE(t)            (BRW_MAX_DRAW_BUFFERS + 1 + (t))
+
+/**
+ * Size of surface binding table for the VS.
+ * Only one constant buffer for now.
+ */
+#define BRW_VS_MAX_SURF 1
+
+/**
+ * Only a VS constant buffer
+ */
+#define SURF_INDEX_VERT_CONST_BUFFER 0
+
+
+/* Bit of a hack to align these with the winsys buffer_data_type enum.
+ */
+enum brw_cache_id {
+   BRW_CC_VP         = BRW_DATA_GS_CC_VP,
+   BRW_CC_UNIT       = BRW_DATA_GS_CC_UNIT,
+   BRW_WM_PROG       = BRW_DATA_GS_WM_PROG,
+   BRW_SAMPLER_DEFAULT_COLOR    = BRW_DATA_GS_SAMPLER_DEFAULT_COLOR,
+   BRW_SAMPLER       = BRW_DATA_GS_SAMPLER,
+   BRW_WM_UNIT       = BRW_DATA_GS_WM_UNIT,
+   BRW_SF_PROG       = BRW_DATA_GS_SF_PROG,
+   BRW_SF_VP         = BRW_DATA_GS_SF_VP,
+   BRW_SF_UNIT       = BRW_DATA_GS_SF_UNIT,
+   BRW_VS_UNIT       = BRW_DATA_GS_VS_UNIT,
+   BRW_VS_PROG       = BRW_DATA_GS_VS_PROG,
+   BRW_GS_UNIT       = BRW_DATA_GS_GS_UNIT,
+   BRW_GS_PROG       = BRW_DATA_GS_GS_PROG,
+   BRW_CLIP_VP       = BRW_DATA_GS_CLIP_VP,
+   BRW_CLIP_UNIT     = BRW_DATA_GS_CLIP_UNIT,
+   BRW_CLIP_PROG     = BRW_DATA_GS_CLIP_PROG,
+   BRW_SS_SURFACE    = BRW_DATA_SS_SURFACE,
+   BRW_SS_SURF_BIND  = BRW_DATA_SS_SURF_BIND,
+
+   BRW_MAX_CACHE
+};
+
+struct brw_cache_item {
+   /**
+    * Effectively part of the key, cache_id identifies what kind of state
+    * buffer is involved, and also which brw->state.dirty.cache flag should
+    * be set when this cache item is chosen.
+    */
+   enum brw_cache_id cache_id;
+   /** 32-bit hash of the key data */
+   GLuint hash;
+   GLuint key_size;		/* for variable-sized keys */
+   const void *key;
+   struct brw_winsys_reloc *relocs;
+   GLuint nr_relocs;
+
+   struct brw_winsys_buffer *bo;
+   GLuint data_size;
+
+   struct brw_cache_item *next;
+};   
+
+
+
+struct brw_cache {
+   struct brw_context *brw;
+   struct brw_winsys_screen *sws;
+
+   struct brw_cache_item **items;
+   GLuint size, n_items;
+
+   enum brw_buffer_type buffer_type;
+
+   GLuint key_size[BRW_MAX_CACHE];		/* for fixed-size keys */
+   GLuint aux_size[BRW_MAX_CACHE];
+   char *name[BRW_MAX_CACHE];
+   
+
+   /* Record of the last BOs chosen for each cache_id.  Used to set
+    * brw->state.dirty.cache when a new cache item is chosen.
+    */
+   struct brw_winsys_buffer *last_bo[BRW_MAX_CACHE];
+};
+
+
+struct brw_tracked_state {
+   struct brw_state_flags dirty;
+   int (*prepare)( struct brw_context *brw );
+   int (*emit)( struct brw_context *brw );
+};
+
+/* Flags for brw->state.cache.
+ */
+#define CACHE_NEW_CC_VP                  (1<<BRW_CC_VP)
+#define CACHE_NEW_CC_UNIT                (1<<BRW_CC_UNIT)
+#define CACHE_NEW_WM_PROG                (1<<BRW_WM_PROG)
+#define CACHE_NEW_SAMPLER_DEFAULT_COLOR  (1<<BRW_SAMPLER_DEFAULT_COLOR)
+#define CACHE_NEW_SAMPLER                (1<<BRW_SAMPLER)
+#define CACHE_NEW_WM_UNIT                (1<<BRW_WM_UNIT)
+#define CACHE_NEW_SF_PROG                (1<<BRW_SF_PROG)
+#define CACHE_NEW_SF_VP                  (1<<BRW_SF_VP)
+#define CACHE_NEW_SF_UNIT                (1<<BRW_SF_UNIT)
+#define CACHE_NEW_VS_UNIT                (1<<BRW_VS_UNIT)
+#define CACHE_NEW_VS_PROG                (1<<BRW_VS_PROG)
+#define CACHE_NEW_GS_UNIT                (1<<BRW_GS_UNIT)
+#define CACHE_NEW_GS_PROG                (1<<BRW_GS_PROG)
+#define CACHE_NEW_CLIP_VP                (1<<BRW_CLIP_VP)
+#define CACHE_NEW_CLIP_UNIT              (1<<BRW_CLIP_UNIT)
+#define CACHE_NEW_CLIP_PROG              (1<<BRW_CLIP_PROG)
+#define CACHE_NEW_SURFACE                (1<<BRW_SS_SURFACE)
+#define CACHE_NEW_SURF_BIND              (1<<BRW_SS_SURF_BIND)
+
+struct brw_cached_batch_item {
+   struct header *header;
+   GLuint sz;
+   struct brw_cached_batch_item *next;
+};
+   
+
+
+/* Protect against a future where VERT_ATTRIB_MAX > 32.  Wouldn't life
+ * be easier if C allowed arrays of packed elements?
+ */
+#define VS_INPUT_BITMASK_DWORDS  ((PIPE_MAX_SHADER_INPUTS+31)/32)
+
+
+
+
+struct brw_vertex_info {
+   GLuint sizes[VS_INPUT_BITMASK_DWORDS * 2]; /* sizes:2[VERT_ATTRIB_MAX] */
+};
+
+
+struct brw_query_object {
+   /** Doubly linked list of active query objects in the context. */
+   struct brw_query_object *prev, *next;
+
+   /** Last query BO associated with this query. */
+   struct brw_winsys_buffer *bo;
+   /** First index in bo with query data for this object. */
+   int first_index;
+   /** Last index in bo with query data for this object. */
+   int last_index;
+
+   /* Total count of pixels from previous BOs */
+   uint64_t result;
+};
+
+#define CC_RELOC_VP 0
+
+
+/**
+ * brw_context is derived from pipe_context
+ */
+struct brw_context 
+{
+   struct pipe_context base;
+   struct brw_chipset chipset;
+
+   struct brw_winsys_screen *sws;
+
+   struct brw_batchbuffer *batch;
+
+   GLuint primitive;
+   GLuint reduced_primitive;
+
+   /* Active state from the state tracker: 
+    */
+   struct {
+      struct brw_vertex_shader *vertex_shader;
+      struct brw_fragment_shader *fragment_shader;
+      const struct brw_blend_state *blend;
+      const struct brw_rasterizer_state *rast;
+      const struct brw_depth_stencil_state *zstencil;
+
+      const struct brw_sampler *sampler[PIPE_MAX_SAMPLERS];
+      unsigned num_samplers;
+
+      struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
+      struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+      struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
+      unsigned num_vertex_elements;
+      unsigned num_textures;
+      unsigned num_vertex_buffers;
+
+      struct pipe_scissor_state scissor;
+      struct pipe_viewport_state viewport;
+      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_polygon_stipple bps;
+      struct brw_cc_viewport ccv;
+
+      /**
+       * Index buffer for this draw_prims call.
+       *
+       * Updates are signaled by PIPE_NEW_INDEX_BUFFER.
+       */
+      struct pipe_buffer *index_buffer;
+      unsigned index_size;
+
+      /* Updates are signalled by PIPE_NEW_INDEX_RANGE:
+       */
+      unsigned min_index;
+      unsigned max_index;
+
+   } curr;
+
+   struct {
+      struct brw_state_flags dirty;
+
+      /**
+       * List of buffers accumulated in brw_validate_state to receive
+       * dri_bo_check_aperture treatment before exec, so we can know if we
+       * should flush the batch and try again before emitting primitives.
+       *
+       * This can be a fixed number as we only have a limited number of
+       * objects referenced from the batchbuffer in a primitive emit,
+       * consisting of the vertex buffers, pipelined state pointers,
+       * the CURBE, the depth buffer, and a query BO.
+       */
+      struct brw_winsys_buffer *validated_bos[PIPE_MAX_SHADER_INPUTS + 16];
+      int validated_bo_count;
+   } state;
+
+   struct brw_cache cache;  /** non-surface items */
+   struct brw_cache surface_cache;  /* surface items */
+   struct brw_cached_batch_item *cached_batch_items;
+
+   struct {
+      struct u_upload_mgr *upload_vertex;
+      struct u_upload_mgr *upload_index;
+      
+      /* Information on uploaded vertex buffers:
+       */
+      struct {
+	 unsigned stride;	/* in bytes between successive vertices */
+	 unsigned offset;	/* in bytes, of first vertex in bo */
+	 unsigned vertex_count;	/* count of valid vertices which may be accessed */
+	 struct brw_winsys_buffer *bo;
+      } vb[PIPE_MAX_ATTRIBS];
+
+      unsigned nr_vb;		/* currently the same as curr.num_vertex_buffers */
+   } vb;
+
+   struct {
+      /* Updates to these fields are signaled by BRW_NEW_INDEX_BUFFER. */
+      struct brw_winsys_buffer *bo;
+      unsigned int offset;
+      unsigned int size;
+      /* Offset to index buffer index to use in CMD_3D_PRIM so that we can
+       * avoid re-uploading the IB packet over and over if we're actually
+       * referencing the same index buffer.
+       */
+      unsigned int start_vertex_offset;
+   } ib;
+
+
+   /* BRW_NEW_URB_ALLOCATIONS:
+    */
+   struct {
+      GLuint vsize;		/* vertex size plus header in urb registers */
+      GLuint csize;		/* constant buffer size in urb registers */
+      GLuint sfsize;		/* setup data size in urb registers */
+
+      GLboolean constrained;
+
+      GLuint nr_vs_entries;
+      GLuint nr_gs_entries;
+      GLuint nr_clip_entries;
+      GLuint nr_sf_entries;
+      GLuint nr_cs_entries;
+
+      GLuint vs_start;
+      GLuint gs_start;
+      GLuint clip_start;
+      GLuint sf_start;
+      GLuint cs_start;
+   } urb;
+
+   
+   /* BRW_NEW_CURBE_OFFSETS: 
+    */
+   struct {
+      GLuint wm_start;  /**< pos of first wm const in CURBE buffer */
+      GLuint wm_size;   /**< number of float[4] consts, multiple of 16 */
+      GLuint clip_start;
+      GLuint clip_size;
+      GLuint vs_start;
+      GLuint vs_size;
+      GLuint total_size;
+
+      struct brw_winsys_buffer *curbe_bo;
+      /** Offset within curbe_bo of space for current curbe entry */
+      GLuint curbe_offset;
+      /** Offset within curbe_bo of space for next curbe entry */
+      GLuint curbe_next_offset;
+
+      GLfloat *last_buf;
+      GLuint last_bufsz;
+      /**
+       *  Whether we should create a new bo instead of reusing the old one
+       * (if we just dispatch the batch pointing at the old one.
+       */
+      GLboolean need_new_bo;
+   } curbe;
+
+   struct {
+      struct brw_vs_prog_data *prog_data;
+
+      struct brw_winsys_buffer *prog_bo;
+      struct brw_winsys_buffer *state_bo;
+
+      /** Binding table of pointers to surf_bo entries */
+      struct brw_winsys_buffer *bind_bo;
+      struct brw_winsys_buffer *surf_bo[BRW_VS_MAX_SURF];
+      GLuint nr_surfaces;      
+   } vs;
+
+   struct {
+      struct brw_gs_prog_data *prog_data;
+
+      GLboolean prog_active;
+      struct brw_winsys_buffer *prog_bo;
+      struct brw_winsys_buffer *state_bo;
+   } gs;
+
+   struct {
+      struct brw_clip_prog_data *prog_data;
+
+      struct brw_winsys_buffer *prog_bo;
+      struct brw_winsys_buffer *state_bo;
+      struct brw_winsys_buffer *vp_bo;
+   } clip;
+
+
+   struct {
+      struct brw_sf_prog_data *prog_data;
+
+      struct brw_winsys_buffer *prog_bo;
+      struct brw_winsys_buffer *state_bo;
+      struct brw_winsys_buffer *vp_bo;
+   } sf;
+
+   struct {
+      struct brw_wm_prog_data *prog_data;
+      struct brw_wm_compile *compile_data;
+
+      /** Input sizes, calculated from active vertex program.
+       * One bit per fragment program input attribute.
+       */
+      /*GLbitfield input_size_masks[4];*/
+
+      /** Array of surface default colors (texture border color) */
+      struct brw_winsys_buffer *sdc_bo[BRW_MAX_TEX_UNIT];
+
+      GLuint render_surf;
+      GLuint nr_surfaces;      
+
+      GLuint max_threads;
+      struct brw_winsys_buffer *scratch_bo;
+
+      GLuint sampler_count;
+      struct brw_winsys_buffer *sampler_bo;
+
+      /** Binding table of pointers to surf_bo entries */
+      struct brw_winsys_buffer *bind_bo;
+      struct brw_winsys_buffer *surf_bo[BRW_WM_MAX_SURF];
+
+      struct brw_winsys_buffer *prog_bo;
+      struct brw_winsys_buffer *state_bo;
+   } wm;
+
+
+   struct {
+      struct brw_winsys_buffer *state_bo;
+
+      struct brw_cc_unit_state cc;
+      struct brw_winsys_reloc reloc[1];
+   } cc;
+
+   struct {
+      struct brw_query_object active_head;
+      struct brw_winsys_buffer *bo;
+      int index;
+      GLboolean active;
+      int stats_wm;
+   } query;
+
+   struct {
+      unsigned always_emit_state:1;
+      unsigned always_flush_batch:1;
+      unsigned force_swtnl:1;
+      unsigned no_swtnl:1;
+   } flags;
+
+   /* Used to give every program string a unique id
+    */
+   GLuint program_id;
+};
+
+
+
+/*======================================================================
+ * brw_queryobj.c
+ */
+void brw_init_query(struct brw_context *brw);
+enum pipe_error brw_prepare_query_begin(struct brw_context *brw);
+void brw_emit_query_begin(struct brw_context *brw);
+void brw_emit_query_end(struct brw_context *brw);
+
+/*======================================================================
+ * brw_state_dump.c
+ */
+void brw_debug_batch(struct brw_context *intel);
+
+
+/*======================================================================
+ * brw_pipe_*.c
+ */
+void brw_pipe_blend_init( struct brw_context *brw );
+void brw_pipe_depth_stencil_init( struct brw_context *brw );
+void brw_pipe_framebuffer_init( struct brw_context *brw );
+void brw_pipe_flush_init( struct brw_context *brw );
+void brw_pipe_misc_init( struct brw_context *brw );
+void brw_pipe_query_init( struct brw_context *brw );
+void brw_pipe_rast_init( struct brw_context *brw );
+void brw_pipe_sampler_init( struct brw_context *brw );
+void brw_pipe_shader_init( struct brw_context *brw );
+void brw_pipe_vertex_init( struct brw_context *brw );
+void brw_pipe_clear_init( struct brw_context *brw );
+
+
+void brw_pipe_blend_cleanup( struct brw_context *brw );
+void brw_pipe_depth_stencil_cleanup( struct brw_context *brw );
+void brw_pipe_framebuffer_cleanup( struct brw_context *brw );
+void brw_pipe_flush_cleanup( struct brw_context *brw );
+void brw_pipe_misc_cleanup( struct brw_context *brw );
+void brw_pipe_query_cleanup( struct brw_context *brw );
+void brw_pipe_rast_cleanup( struct brw_context *brw );
+void brw_pipe_sampler_cleanup( struct brw_context *brw );
+void brw_pipe_shader_cleanup( struct brw_context *brw );
+void brw_pipe_vertex_cleanup( struct brw_context *brw );
+void brw_pipe_clear_cleanup( struct brw_context *brw );
+
+void brw_hw_cc_init( struct brw_context *brw );
+void brw_hw_cc_cleanup( struct brw_context *brw );
+
+
+
+void brw_context_flush( struct brw_context *brw );
+
+
+/* brw_urb.c
+ */
+int brw_upload_urb_fence(struct brw_context *brw);
+
+/* brw_curbe.c
+ */
+int brw_upload_cs_urb_state(struct brw_context *brw);
+
+
+/*======================================================================
+ * Inline conversion functions.  These are better-typed than the
+ * macros used previously:
+ */
+static INLINE struct brw_context *
+brw_context( struct pipe_context *ctx )
+{
+   return (struct brw_context *)ctx;
+}
+
+
+#define BRW_IS_965(brw)    ((brw)->chipset.is_965)
+#define BRW_IS_IGDNG(brw)  ((brw)->chipset.is_igdng)
+#define BRW_IS_G4X(brw)    ((brw)->chipset.is_g4x)
+
+
+#endif
+
diff --git a/src/gallium/drivers/i965/brw_curbe.c b/src/gallium/drivers/i965/brw_curbe.c
new file mode 100644
index 0000000..3f03157
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_curbe.c
@@ -0,0 +1,390 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "brw_batchbuffer.h"
+#include "brw_context.h"
+#include "brw_defines.h"
+#include "brw_state.h"
+#include "brw_util.h"
+#include "brw_debug.h"
+#include "brw_screen.h"
+
+
+/**
+ * Partition the CURBE between the various users of constant values:
+ * Note that vertex and fragment shaders can now fetch constants out
+ * of constant buffers.  We no longer allocatea block of the GRF for
+ * constants.  That greatly reduces the demand for space in the CURBE.
+ * Some of the comments within are dated...
+ */
+static int calculate_curbe_offsets( struct brw_context *brw )
+{
+   /* CACHE_NEW_WM_PROG */
+   const GLuint nr_fp_regs = brw->wm.prog_data->curb_read_length;
+   
+   /* BRW_NEW_VERTEX_PROGRAM */
+   const GLuint nr_vp_regs = brw->vs.prog_data->curb_read_length;
+   GLuint nr_clip_regs = 0;
+   GLuint total_regs;
+
+   /* PIPE_NEW_CLIP */
+   if (brw->curr.ucp.nr) {
+      GLuint nr_planes = 6 + brw->curr.ucp.nr;
+      nr_clip_regs = (nr_planes * 4 + 15) / 16;
+   }
+
+
+   total_regs = nr_fp_regs + nr_vp_regs + nr_clip_regs;
+
+   /* When this is > 32, want to use a true constant buffer to hold
+    * the extra constants.
+    */
+   assert(total_regs <= 32);
+
+   /* Lazy resize:
+    */
+   if (nr_fp_regs > brw->curbe.wm_size ||
+       nr_vp_regs > brw->curbe.vs_size ||
+       nr_clip_regs != brw->curbe.clip_size ||
+       (total_regs < brw->curbe.total_size / 4 &&
+	brw->curbe.total_size > 16)) {
+
+      GLuint reg = 0;
+
+      /* Calculate a new layout: 
+       */
+      reg = 0;
+      brw->curbe.wm_start = reg;
+      brw->curbe.wm_size = nr_fp_regs; reg += nr_fp_regs;
+      brw->curbe.clip_start = reg;
+      brw->curbe.clip_size = nr_clip_regs; reg += nr_clip_regs;
+      brw->curbe.vs_start = reg;
+      brw->curbe.vs_size = nr_vp_regs; reg += nr_vp_regs;
+      brw->curbe.total_size = reg;
+
+      if (BRW_DEBUG & DEBUG_CURBE)
+	 debug_printf("curbe wm %d+%d clip %d+%d vs %d+%d\n",
+		      brw->curbe.wm_start,
+		      brw->curbe.wm_size,
+		      brw->curbe.clip_start,
+		      brw->curbe.clip_size,
+		      brw->curbe.vs_start,
+		      brw->curbe.vs_size );
+
+      brw->state.dirty.brw |= BRW_NEW_CURBE_OFFSETS;
+   }
+
+   return 0;
+}
+
+
+const struct brw_tracked_state brw_curbe_offsets = {
+   .dirty = {
+      .mesa = PIPE_NEW_CLIP,
+      .brw  = BRW_NEW_VERTEX_PROGRAM,
+      .cache = CACHE_NEW_WM_PROG
+   },
+   .prepare = calculate_curbe_offsets
+};
+
+
+
+
+/* Define the number of curbes within CS's urb allocation.  Multiple
+ * urb entries -> multiple curbes.  These will be used by
+ * fixed-function hardware in a double-buffering scheme to avoid a
+ * pipeline stall each time the contents of the curbe is changed.
+ */
+int brw_upload_cs_urb_state(struct brw_context *brw)
+{
+   struct brw_cs_urb_state cs_urb;
+   memset(&cs_urb, 0, sizeof(cs_urb));
+
+   /* It appears that this is the state packet for the CS unit, ie. the
+    * urb entries detailed here are housed in the CS range from the
+    * URB_FENCE command.
+    */
+   cs_urb.header.opcode = CMD_CS_URB_STATE;
+   cs_urb.header.length = sizeof(cs_urb)/4 - 2;
+
+   /* BRW_NEW_URB_FENCE */
+   cs_urb.bits0.nr_urb_entries = brw->urb.nr_cs_entries;
+   cs_urb.bits0.urb_entry_size = brw->urb.csize - 1;
+
+   assert(brw->urb.nr_cs_entries);
+   BRW_CACHED_BATCH_STRUCT(brw, &cs_urb);
+   return 0;
+}
+
+static GLfloat fixed_plane[6][4] = {
+   { 0,    0,   -1, 1 },
+   { 0,    0,    1, 1 },
+   { 0,   -1,    0, 1 },
+   { 0,    1,    0, 1 },
+   {-1,    0,    0, 1 },
+   { 1,    0,    0, 1 }
+};
+
+/* Upload a new set of constants.  Too much variability to go into the
+ * cache mechanism, but maybe would benefit from a comparison against
+ * the current uploaded set of constants.
+ */
+static enum pipe_error prepare_curbe_buffer(struct brw_context *brw)
+{
+   struct pipe_screen *screen = brw->base.screen;
+   const GLuint sz = brw->curbe.total_size;
+   const GLuint bufsz = sz * 16 * sizeof(GLfloat);
+   enum pipe_error ret;
+   GLfloat *buf;
+   GLuint i;
+
+   if (sz == 0) {
+      if (brw->curbe.last_buf) {
+	 free(brw->curbe.last_buf);
+	 brw->curbe.last_buf = NULL;
+	 brw->curbe.last_bufsz  = 0;
+      }
+      return 0;
+   }
+
+   buf = (GLfloat *) CALLOC(bufsz, 1);
+
+   /* fragment shader constants */
+   if (brw->curbe.wm_size) {
+      const struct brw_fragment_shader *fs = brw->curr.fragment_shader;
+      GLuint offset = brw->curbe.wm_start * 16;
+      GLuint nr_immediate, nr_const;
+
+      nr_immediate = fs->immediates.nr;
+      if (nr_immediate) {
+         memcpy(&buf[offset], 
+                fs->immediates.data,
+                nr_immediate * 4 * sizeof(float));
+
+         offset += nr_immediate * 4;
+      }
+
+      nr_const = fs->info.file_max[TGSI_FILE_CONSTANT] + 1;
+/*      nr_const = brw->wm.prog_data->nr_params; */
+      if (nr_const) {
+         const GLfloat *value = screen->buffer_map( screen,
+                                                    brw->curr.fragment_constants,
+                                                    PIPE_BUFFER_USAGE_CPU_READ);
+
+         memcpy(&buf[offset], value,
+                nr_const * 4 * sizeof(float));
+         
+         screen->buffer_unmap( screen, 
+                               brw->curr.fragment_constants );
+      }
+   }
+
+
+   /* The clipplanes are actually delivered to both CLIP and VS units.
+    * VS uses them to calculate the outcode bitmasks.
+    */
+   if (brw->curbe.clip_size) {
+      GLuint offset = brw->curbe.clip_start * 16;
+      GLuint j;
+
+      /* If any planes are going this way, send them all this way:
+       */
+      for (i = 0; i < 6; i++) {
+	 buf[offset + i * 4 + 0] = fixed_plane[i][0];
+	 buf[offset + i * 4 + 1] = fixed_plane[i][1];
+	 buf[offset + i * 4 + 2] = fixed_plane[i][2];
+	 buf[offset + i * 4 + 3] = fixed_plane[i][3];
+      }
+
+      /* Clip planes:
+       */
+      assert(brw->curr.ucp.nr <= 6);
+      for (j = 0; j < brw->curr.ucp.nr; j++) {
+	 buf[offset + i * 4 + 0] = brw->curr.ucp.ucp[j][0];
+	 buf[offset + i * 4 + 1] = brw->curr.ucp.ucp[j][1];
+	 buf[offset + i * 4 + 2] = brw->curr.ucp.ucp[j][2];
+	 buf[offset + i * 4 + 3] = brw->curr.ucp.ucp[j][3];
+	 i++;
+      }
+   }
+
+   /* vertex shader constants */
+   if (brw->curbe.vs_size) {
+      GLuint offset = brw->curbe.vs_start * 16;
+      const struct brw_vertex_shader *vs = brw->curr.vertex_shader;
+      GLuint nr_immediate, nr_const;
+
+      nr_immediate = vs->immediates.nr;
+      if (nr_immediate) {
+         memcpy(&buf[offset], 
+                vs->immediates.data,
+                nr_immediate * 4 * sizeof(float));
+
+         offset += nr_immediate * 4;
+      }
+
+      nr_const = vs->info.file_max[TGSI_FILE_CONSTANT] + 1;
+      if (nr_const) {
+         /* XXX: note that constant buffers are currently *already* in
+          * buffer objects.  If we want to keep on putting them into the
+          * curbe, makes sense to treat constbuf's specially with malloc.
+          */
+         const GLfloat *value = screen->buffer_map( screen,
+                                                    brw->curr.vertex_constants,
+                                                    PIPE_BUFFER_USAGE_CPU_READ);
+         
+         /* XXX: what if user's constant buffer is too small?
+          */
+         memcpy(&buf[offset], value, nr_const * 4 * sizeof(float));
+         
+         screen->buffer_unmap( screen, brw->curr.vertex_constants );
+      }
+   }
+
+   if (BRW_DEBUG & DEBUG_CURBE) {
+      for (i = 0; i < sz*16; i+=4) 
+	 debug_printf("curbe %d.%d: %f %f %f %f\n", i/8, i&4,
+		      buf[i+0], buf[i+1], buf[i+2], buf[i+3]);
+
+      debug_printf("last_buf %p buf %p sz %d/%d cmp %d\n",
+		   (void *)brw->curbe.last_buf, (void *)buf,
+		   bufsz, brw->curbe.last_bufsz,
+		   brw->curbe.last_buf ? memcmp(buf, brw->curbe.last_buf, bufsz) : -1);
+   }
+
+   if (brw->curbe.curbe_bo != NULL &&
+       brw->curbe.last_buf &&
+       bufsz == brw->curbe.last_bufsz &&
+       memcmp(buf, brw->curbe.last_buf, bufsz) == 0) {
+      /* constants have not changed */
+      FREE(buf);
+   } 
+   else {
+      /* constants have changed */
+      FREE(brw->curbe.last_buf);
+
+      brw->curbe.last_buf = buf;
+      brw->curbe.last_bufsz = bufsz;
+
+      if (brw->curbe.curbe_bo != NULL &&
+	  (brw->curbe.need_new_bo ||
+	   brw->curbe.curbe_next_offset + bufsz > brw->curbe.curbe_bo->size))
+      {
+	 bo_reference(&brw->curbe.curbe_bo, NULL);
+      }
+
+      if (brw->curbe.curbe_bo == NULL) {
+	 /* Allocate a single page for CURBE entries for this
+	  * batchbuffer.  They're generally around 64b.  We will
+	  * discard the curbe buffer after the batch is flushed to
+	  * avoid synchronous updates.
+	  */
+	 ret = brw->sws->bo_alloc(brw->sws, 
+                                  BRW_BUFFER_TYPE_CURBE,
+                                  4096, 1 << 6,
+                                  &brw->curbe.curbe_bo);
+         if (ret)
+            return ret;
+
+	 brw->curbe.curbe_next_offset = 0;
+      }
+
+      brw->curbe.curbe_offset = brw->curbe.curbe_next_offset;
+      brw->curbe.curbe_next_offset += bufsz;
+      brw->curbe.curbe_next_offset = align(brw->curbe.curbe_next_offset, 64);
+
+      /* Copy data to the buffer:
+       */
+      brw->sws->bo_subdata(brw->curbe.curbe_bo,
+                           BRW_DATA_CONSTANT_BUFFER,
+			   brw->curbe.curbe_offset,
+			   bufsz,
+			   buf,
+                           NULL, 0);
+   }
+
+   brw_add_validated_bo(brw, brw->curbe.curbe_bo);
+
+   /* Because this provokes an action (ie copy the constants into the
+    * URB), it shouldn't be shortcircuited if identical to the
+    * previous time - because eg. the urb destination may have
+    * changed, or the urb contents different to last time.
+    *
+    * Note that the data referred to is actually copied internally,
+    * not just used in place according to passed pointer.
+    *
+    * It appears that the CS unit takes care of using each available
+    * URB entry (Const URB Entry == CURBE) in turn, and issuing
+    * flushes as necessary when doublebuffering of CURBEs isn't
+    * possible.
+    */
+
+   return 0;
+}
+
+static enum pipe_error emit_curbe_buffer(struct brw_context *brw)
+{
+   GLuint sz = brw->curbe.total_size;
+
+   BEGIN_BATCH(2, IGNORE_CLIPRECTS);
+   if (sz == 0) {
+      OUT_BATCH((CMD_CONST_BUFFER << 16) | (2 - 2));
+      OUT_BATCH(0);
+   } else {
+      OUT_BATCH((CMD_CONST_BUFFER << 16) | (1 << 8) | (2 - 2));
+      OUT_RELOC(brw->curbe.curbe_bo,
+		BRW_USAGE_STATE,
+		(sz - 1) + brw->curbe.curbe_offset);
+   }
+   ADVANCE_BATCH();
+   return 0;
+}
+
+const struct brw_tracked_state brw_curbe_buffer = {
+   .dirty = {
+      .mesa = (PIPE_NEW_FRAGMENT_CONSTANTS |
+	       PIPE_NEW_VERTEX_CONSTANTS |
+	       PIPE_NEW_CLIP),
+      .brw  = (BRW_NEW_FRAGMENT_PROGRAM |
+	       BRW_NEW_VERTEX_PROGRAM |
+	       BRW_NEW_URB_FENCE | /* Implicit - hardware requires this, not used above */
+	       BRW_NEW_PSP | /* Implicit - hardware requires this, not used above */
+	       BRW_NEW_CURBE_OFFSETS |
+	       BRW_NEW_BATCH),
+      .cache = (CACHE_NEW_WM_PROG) 
+   },
+   .prepare = prepare_curbe_buffer,
+   .emit = emit_curbe_buffer,
+};
+
diff --git a/src/gallium/drivers/i965/brw_debug.h b/src/gallium/drivers/i965/brw_debug.h
new file mode 100644
index 0000000..ae8e925
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_debug.h
@@ -0,0 +1,43 @@
+#ifndef BRW_DEBUG_H
+#define BRW_DEBUG_H
+
+/* ================================================================
+ * Debugging:
+ */
+
+#define DEBUG_TEXTURE	        0x1
+#define DEBUG_STATE	        0x2
+#define DEBUG_IOCTL	        0x4
+#define DEBUG_BLIT	        0x8
+#define DEBUG_CURBE             0x10
+#define DEBUG_FALLBACKS	        0x20
+#define DEBUG_VERBOSE	        0x40
+#define DEBUG_BATCH             0x80
+#define DEBUG_PIXEL             0x100
+#define DEBUG_WINSYS            0x200
+#define DEBUG_MIN_URB           0x400
+#define DEBUG_DISASSEM           0x800
+#define DEBUG_unused3           0x1000
+#define DEBUG_SYNC	        0x2000
+#define DEBUG_PRIMS	        0x4000
+#define DEBUG_VERTS	        0x8000
+#define DEBUG_unused4           0x10000
+#define DEBUG_DMA               0x20000
+#define DEBUG_SANITY            0x40000
+#define DEBUG_SLEEP             0x80000
+#define DEBUG_STATS             0x100000
+#define DEBUG_unused5           0x200000
+#define DEBUG_SINGLE_THREAD     0x400000
+#define DEBUG_WM                0x800000
+#define DEBUG_URB               0x1000000
+#define DEBUG_VS                0x2000000
+
+#ifdef DEBUG
+extern int BRW_DEBUG;
+#else
+#define BRW_DEBUG 0
+#endif
+
+
+
+#endif
diff --git a/src/gallium/drivers/i965/brw_defines.h b/src/gallium/drivers/i965/brw_defines.h
new file mode 100644
index 0000000..e201ce4
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_defines.h
@@ -0,0 +1,847 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+ 
+
+#ifndef BRW_DEFINES_H
+#define BRW_DEFINES_H
+
+/* 3D state:
+ */
+#define _3DOP_3DSTATE_PIPELINED       0x0
+#define _3DOP_3DSTATE_NONPIPELINED    0x1
+#define _3DOP_3DCONTROL               0x2
+#define _3DOP_3DPRIMITIVE             0x3
+
+#define _3DSTATE_PIPELINED_POINTERS       0x00
+#define _3DSTATE_BINDING_TABLE_POINTERS   0x01
+#define _3DSTATE_VERTEX_BUFFERS           0x08
+#define _3DSTATE_VERTEX_ELEMENTS          0x09
+#define _3DSTATE_INDEX_BUFFER             0x0A
+#define _3DSTATE_VF_STATISTICS            0x0B
+#define _3DSTATE_DRAWING_RECTANGLE            0x00
+#define _3DSTATE_CONSTANT_COLOR               0x01
+#define _3DSTATE_SAMPLER_PALETTE_LOAD         0x02
+#define _3DSTATE_CHROMA_KEY                   0x04
+#define _3DSTATE_DEPTH_BUFFER                 0x05
+#define _3DSTATE_POLY_STIPPLE_OFFSET          0x06
+#define _3DSTATE_POLY_STIPPLE_PATTERN         0x07
+#define _3DSTATE_LINE_STIPPLE                 0x08
+#define _3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP    0x09
+#define _3DCONTROL    0x00
+
+#define PIPE_CONTROL_NOWRITE          0x00
+#define PIPE_CONTROL_WRITEIMMEDIATE   0x01
+#define PIPE_CONTROL_WRITEDEPTH       0x02
+#define PIPE_CONTROL_WRITETIMESTAMP   0x03
+
+#define PIPE_CONTROL_GTTWRITE_PROCESS_LOCAL 0x00
+#define PIPE_CONTROL_GTTWRITE_GLOBAL        0x01
+
+#define _3DPRIM_POINTLIST         0x01
+#define _3DPRIM_LINELIST          0x02
+#define _3DPRIM_LINESTRIP         0x03
+#define _3DPRIM_TRILIST           0x04
+#define _3DPRIM_TRISTRIP          0x05
+#define _3DPRIM_TRIFAN            0x06
+#define _3DPRIM_QUADLIST          0x07
+#define _3DPRIM_QUADSTRIP         0x08
+#define _3DPRIM_LINELIST_ADJ      0x09
+#define _3DPRIM_LINESTRIP_ADJ     0x0A
+#define _3DPRIM_TRILIST_ADJ       0x0B
+#define _3DPRIM_TRISTRIP_ADJ      0x0C
+#define _3DPRIM_TRISTRIP_REVERSE  0x0D
+#define _3DPRIM_POLYGON           0x0E
+#define _3DPRIM_RECTLIST          0x0F
+#define _3DPRIM_LINELOOP          0x10
+#define _3DPRIM_POINTLIST_BF      0x11
+#define _3DPRIM_LINESTRIP_CONT    0x12
+#define _3DPRIM_LINESTRIP_BF      0x13
+#define _3DPRIM_LINESTRIP_CONT_BF 0x14
+#define _3DPRIM_TRIFAN_NOSTIPPLE  0x15
+
+#define _3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL 0
+#define _3DPRIM_VERTEXBUFFER_ACCESS_RANDOM     1
+
+#define BRW_ANISORATIO_2     0 
+#define BRW_ANISORATIO_4     1 
+#define BRW_ANISORATIO_6     2 
+#define BRW_ANISORATIO_8     3 
+#define BRW_ANISORATIO_10    4 
+#define BRW_ANISORATIO_12    5 
+#define BRW_ANISORATIO_14    6 
+#define BRW_ANISORATIO_16    7
+
+#define BRW_BLENDFACTOR_ONE                 0x1
+#define BRW_BLENDFACTOR_SRC_COLOR           0x2
+#define BRW_BLENDFACTOR_SRC_ALPHA           0x3
+#define BRW_BLENDFACTOR_DST_ALPHA           0x4
+#define BRW_BLENDFACTOR_DST_COLOR           0x5
+#define BRW_BLENDFACTOR_SRC_ALPHA_SATURATE  0x6
+#define BRW_BLENDFACTOR_CONST_COLOR         0x7
+#define BRW_BLENDFACTOR_CONST_ALPHA         0x8
+#define BRW_BLENDFACTOR_SRC1_COLOR          0x9
+#define BRW_BLENDFACTOR_SRC1_ALPHA          0x0A
+#define BRW_BLENDFACTOR_ZERO                0x11
+#define BRW_BLENDFACTOR_INV_SRC_COLOR       0x12
+#define BRW_BLENDFACTOR_INV_SRC_ALPHA       0x13
+#define BRW_BLENDFACTOR_INV_DST_ALPHA       0x14
+#define BRW_BLENDFACTOR_INV_DST_COLOR       0x15
+#define BRW_BLENDFACTOR_INV_CONST_COLOR     0x17
+#define BRW_BLENDFACTOR_INV_CONST_ALPHA     0x18
+#define BRW_BLENDFACTOR_INV_SRC1_COLOR      0x19
+#define BRW_BLENDFACTOR_INV_SRC1_ALPHA      0x1A
+
+#define BRW_BLENDFUNCTION_ADD               0
+#define BRW_BLENDFUNCTION_SUBTRACT          1
+#define BRW_BLENDFUNCTION_REVERSE_SUBTRACT  2
+#define BRW_BLENDFUNCTION_MIN               3
+#define BRW_BLENDFUNCTION_MAX               4
+
+#define BRW_ALPHATEST_FORMAT_UNORM8         0
+#define BRW_ALPHATEST_FORMAT_FLOAT32        1
+
+#define BRW_CHROMAKEY_KILL_ON_ANY_MATCH  0
+#define BRW_CHROMAKEY_REPLACE_BLACK      1
+
+#define BRW_CLIP_API_OGL     0
+#define BRW_CLIP_API_DX      1
+
+#define BRW_CLIPMODE_NORMAL              0
+#define BRW_CLIPMODE_CLIP_ALL            1
+#define BRW_CLIPMODE_CLIP_NON_REJECTED   2
+#define BRW_CLIPMODE_REJECT_ALL          3
+#define BRW_CLIPMODE_ACCEPT_ALL          4
+#define BRW_CLIPMODE_KERNEL_CLIP         5
+
+#define BRW_CLIP_NDCSPACE     0
+#define BRW_CLIP_SCREENSPACE  1
+
+#define BRW_COMPAREFUNCTION_ALWAYS       0
+#define BRW_COMPAREFUNCTION_NEVER        1
+#define BRW_COMPAREFUNCTION_LESS         2
+#define BRW_COMPAREFUNCTION_EQUAL        3
+#define BRW_COMPAREFUNCTION_LEQUAL       4
+#define BRW_COMPAREFUNCTION_GREATER      5
+#define BRW_COMPAREFUNCTION_NOTEQUAL     6
+#define BRW_COMPAREFUNCTION_GEQUAL       7
+
+#define BRW_COVERAGE_PIXELS_HALF     0
+#define BRW_COVERAGE_PIXELS_1        1
+#define BRW_COVERAGE_PIXELS_2        2
+#define BRW_COVERAGE_PIXELS_4        3
+
+#define BRW_CULLMODE_BOTH        0
+#define BRW_CULLMODE_NONE        1
+#define BRW_CULLMODE_FRONT       2
+#define BRW_CULLMODE_BACK        3
+
+#define BRW_DEFAULTCOLOR_R8G8B8A8_UNORM      0
+#define BRW_DEFAULTCOLOR_R32G32B32A32_FLOAT  1
+
+#define BRW_DEPTHFORMAT_D32_FLOAT_S8X24_UINT     0
+#define BRW_DEPTHFORMAT_D32_FLOAT                1
+#define BRW_DEPTHFORMAT_D24_UNORM_S8_UINT        2
+#define BRW_DEPTHFORMAT_D16_UNORM                5
+
+#define BRW_FLOATING_POINT_IEEE_754        0
+#define BRW_FLOATING_POINT_NON_IEEE_754    1
+
+#define BRW_FRONTWINDING_CW      0
+#define BRW_FRONTWINDING_CCW     1
+
+#define BRW_SPRITE_POINT_ENABLE  16
+
+#define BRW_INDEX_BYTE     0
+#define BRW_INDEX_WORD     1
+#define BRW_INDEX_DWORD    2
+
+#define BRW_LOGICOPFUNCTION_CLEAR            0
+#define BRW_LOGICOPFUNCTION_NOR              1
+#define BRW_LOGICOPFUNCTION_AND_INVERTED     2
+#define BRW_LOGICOPFUNCTION_COPY_INVERTED    3
+#define BRW_LOGICOPFUNCTION_AND_REVERSE      4
+#define BRW_LOGICOPFUNCTION_INVERT           5
+#define BRW_LOGICOPFUNCTION_XOR              6
+#define BRW_LOGICOPFUNCTION_NAND             7
+#define BRW_LOGICOPFUNCTION_AND              8
+#define BRW_LOGICOPFUNCTION_EQUIV            9
+#define BRW_LOGICOPFUNCTION_NOOP             10
+#define BRW_LOGICOPFUNCTION_OR_INVERTED      11
+#define BRW_LOGICOPFUNCTION_COPY             12
+#define BRW_LOGICOPFUNCTION_OR_REVERSE       13
+#define BRW_LOGICOPFUNCTION_OR               14
+#define BRW_LOGICOPFUNCTION_SET              15  
+
+#define BRW_MAPFILTER_NEAREST        0x0 
+#define BRW_MAPFILTER_LINEAR         0x1 
+#define BRW_MAPFILTER_ANISOTROPIC    0x2
+
+#define BRW_MIPFILTER_NONE        0   
+#define BRW_MIPFILTER_NEAREST     1   
+#define BRW_MIPFILTER_LINEAR      3
+
+#define BRW_POLYGON_FRONT_FACING     0
+#define BRW_POLYGON_BACK_FACING      1
+
+#define BRW_PREFILTER_ALWAYS     0x0 
+#define BRW_PREFILTER_NEVER      0x1
+#define BRW_PREFILTER_LESS       0x2
+#define BRW_PREFILTER_EQUAL      0x3
+#define BRW_PREFILTER_LEQUAL     0x4
+#define BRW_PREFILTER_GREATER    0x5
+#define BRW_PREFILTER_NOTEQUAL   0x6
+#define BRW_PREFILTER_GEQUAL     0x7
+
+#define BRW_PROVOKING_VERTEX_0    0
+#define BRW_PROVOKING_VERTEX_1    1 
+#define BRW_PROVOKING_VERTEX_2    2
+
+#define BRW_RASTRULE_UPPER_LEFT  0    
+#define BRW_RASTRULE_UPPER_RIGHT 1
+/* These are listed as "Reserved, but not seen as useful"
+ * in Intel documentation (page 212, "Point Rasterization Rule",
+ * section 7.4 "SF Pipeline State Summary", of document
+ * "Intel® 965 Express Chipset Family and Intel® G35 Express
+ * Chipset Graphics Controller Programmer's Reference Manual,
+ * Volume 2: 3D/Media", Revision 1.0b as of January 2008,
+ * available at 
+ *     http://intellinuxgraphics.org/documentation.html
+ * at the time of this writing).
+ *
+ * These appear to be supported on at least some
+ * i965-family devices, and the BRW_RASTRULE_LOWER_RIGHT
+ * is useful when using OpenGL to render to a FBO
+ * (which has the pixel coordinate Y orientation inverted
+ * with respect to the normal OpenGL pixel coordinate system).
+ */
+#define BRW_RASTRULE_LOWER_LEFT  2
+#define BRW_RASTRULE_LOWER_RIGHT 3
+
+#define BRW_RENDERTARGET_CLAMPRANGE_UNORM    0
+#define BRW_RENDERTARGET_CLAMPRANGE_SNORM    1
+#define BRW_RENDERTARGET_CLAMPRANGE_FORMAT   2
+
+#define BRW_STENCILOP_KEEP               0
+#define BRW_STENCILOP_ZERO               1
+#define BRW_STENCILOP_REPLACE            2
+#define BRW_STENCILOP_INCRSAT            3
+#define BRW_STENCILOP_DECRSAT            4
+#define BRW_STENCILOP_INCR               5
+#define BRW_STENCILOP_DECR               6
+#define BRW_STENCILOP_INVERT             7
+
+#define BRW_SURFACE_MIPMAPLAYOUT_BELOW   0
+#define BRW_SURFACE_MIPMAPLAYOUT_RIGHT   1
+
+#define BRW_SURFACEFORMAT_R32G32B32A32_FLOAT             0x000 
+#define BRW_SURFACEFORMAT_R32G32B32A32_SINT              0x001 
+#define BRW_SURFACEFORMAT_R32G32B32A32_UINT              0x002 
+#define BRW_SURFACEFORMAT_R32G32B32A32_UNORM             0x003 
+#define BRW_SURFACEFORMAT_R32G32B32A32_SNORM             0x004 
+#define BRW_SURFACEFORMAT_R64G64_FLOAT                   0x005 
+#define BRW_SURFACEFORMAT_R32G32B32X32_FLOAT             0x006 
+#define BRW_SURFACEFORMAT_R32G32B32A32_SSCALED           0x007
+#define BRW_SURFACEFORMAT_R32G32B32A32_USCALED           0x008
+#define BRW_SURFACEFORMAT_R32G32B32_FLOAT                0x040 
+#define BRW_SURFACEFORMAT_R32G32B32_SINT                 0x041 
+#define BRW_SURFACEFORMAT_R32G32B32_UINT                 0x042 
+#define BRW_SURFACEFORMAT_R32G32B32_UNORM                0x043 
+#define BRW_SURFACEFORMAT_R32G32B32_SNORM                0x044 
+#define BRW_SURFACEFORMAT_R32G32B32_SSCALED              0x045 
+#define BRW_SURFACEFORMAT_R32G32B32_USCALED              0x046 
+#define BRW_SURFACEFORMAT_R16G16B16A16_UNORM             0x080 
+#define BRW_SURFACEFORMAT_R16G16B16A16_SNORM             0x081 
+#define BRW_SURFACEFORMAT_R16G16B16A16_SINT              0x082 
+#define BRW_SURFACEFORMAT_R16G16B16A16_UINT              0x083 
+#define BRW_SURFACEFORMAT_R16G16B16A16_FLOAT             0x084 
+#define BRW_SURFACEFORMAT_R32G32_FLOAT                   0x085 
+#define BRW_SURFACEFORMAT_R32G32_SINT                    0x086 
+#define BRW_SURFACEFORMAT_R32G32_UINT                    0x087 
+#define BRW_SURFACEFORMAT_R32_FLOAT_X8X24_TYPELESS       0x088 
+#define BRW_SURFACEFORMAT_X32_TYPELESS_G8X24_UINT        0x089 
+#define BRW_SURFACEFORMAT_L32A32_FLOAT                   0x08A 
+#define BRW_SURFACEFORMAT_R32G32_UNORM                   0x08B 
+#define BRW_SURFACEFORMAT_R32G32_SNORM                   0x08C 
+#define BRW_SURFACEFORMAT_R64_FLOAT                      0x08D 
+#define BRW_SURFACEFORMAT_R16G16B16X16_UNORM             0x08E 
+#define BRW_SURFACEFORMAT_R16G16B16X16_FLOAT             0x08F 
+#define BRW_SURFACEFORMAT_A32X32_FLOAT                   0x090 
+#define BRW_SURFACEFORMAT_L32X32_FLOAT                   0x091 
+#define BRW_SURFACEFORMAT_I32X32_FLOAT                   0x092 
+#define BRW_SURFACEFORMAT_R16G16B16A16_SSCALED           0x093
+#define BRW_SURFACEFORMAT_R16G16B16A16_USCALED           0x094
+#define BRW_SURFACEFORMAT_R32G32_SSCALED                 0x095
+#define BRW_SURFACEFORMAT_R32G32_USCALED                 0x096
+#define BRW_SURFACEFORMAT_B8G8R8A8_UNORM                 0x0C0 
+#define BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB            0x0C1 
+#define BRW_SURFACEFORMAT_R10G10B10A2_UNORM              0x0C2 
+#define BRW_SURFACEFORMAT_R10G10B10A2_UNORM_SRGB         0x0C3 
+#define BRW_SURFACEFORMAT_R10G10B10A2_UINT               0x0C4 
+#define BRW_SURFACEFORMAT_R10G10B10_SNORM_A2_UNORM       0x0C5 
+#define BRW_SURFACEFORMAT_R8G8B8A8_UNORM                 0x0C7 
+#define BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB            0x0C8 
+#define BRW_SURFACEFORMAT_R8G8B8A8_SNORM                 0x0C9 
+#define BRW_SURFACEFORMAT_R8G8B8A8_SINT                  0x0CA 
+#define BRW_SURFACEFORMAT_R8G8B8A8_UINT                  0x0CB 
+#define BRW_SURFACEFORMAT_R16G16_UNORM                   0x0CC 
+#define BRW_SURFACEFORMAT_R16G16_SNORM                   0x0CD 
+#define BRW_SURFACEFORMAT_R16G16_SINT                    0x0CE 
+#define BRW_SURFACEFORMAT_R16G16_UINT                    0x0CF 
+#define BRW_SURFACEFORMAT_R16G16_FLOAT                   0x0D0 
+#define BRW_SURFACEFORMAT_B10G10R10A2_UNORM              0x0D1 
+#define BRW_SURFACEFORMAT_B10G10R10A2_UNORM_SRGB         0x0D2 
+#define BRW_SURFACEFORMAT_R11G11B10_FLOAT                0x0D3 
+#define BRW_SURFACEFORMAT_R32_SINT                       0x0D6 
+#define BRW_SURFACEFORMAT_R32_UINT                       0x0D7 
+#define BRW_SURFACEFORMAT_R32_FLOAT                      0x0D8 
+#define BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS          0x0D9 
+#define BRW_SURFACEFORMAT_X24_TYPELESS_G8_UINT           0x0DA 
+#define BRW_SURFACEFORMAT_L16A16_UNORM                   0x0DF 
+#define BRW_SURFACEFORMAT_I24X8_UNORM                    0x0E0 
+#define BRW_SURFACEFORMAT_L24X8_UNORM                    0x0E1 
+#define BRW_SURFACEFORMAT_A24X8_UNORM                    0x0E2 
+#define BRW_SURFACEFORMAT_I32_FLOAT                      0x0E3 
+#define BRW_SURFACEFORMAT_L32_FLOAT                      0x0E4 
+#define BRW_SURFACEFORMAT_A32_FLOAT                      0x0E5 
+#define BRW_SURFACEFORMAT_B8G8R8X8_UNORM                 0x0E9 
+#define BRW_SURFACEFORMAT_B8G8R8X8_UNORM_SRGB            0x0EA 
+#define BRW_SURFACEFORMAT_R8G8B8X8_UNORM                 0x0EB 
+#define BRW_SURFACEFORMAT_R8G8B8X8_UNORM_SRGB            0x0EC 
+#define BRW_SURFACEFORMAT_R9G9B9E5_SHAREDEXP             0x0ED 
+#define BRW_SURFACEFORMAT_B10G10R10X2_UNORM              0x0EE 
+#define BRW_SURFACEFORMAT_L16A16_FLOAT                   0x0F0 
+#define BRW_SURFACEFORMAT_R32_UNORM                      0x0F1 
+#define BRW_SURFACEFORMAT_R32_SNORM                      0x0F2 
+#define BRW_SURFACEFORMAT_R10G10B10X2_USCALED            0x0F3
+#define BRW_SURFACEFORMAT_R8G8B8A8_SSCALED               0x0F4
+#define BRW_SURFACEFORMAT_R8G8B8A8_USCALED               0x0F5
+#define BRW_SURFACEFORMAT_R16G16_SSCALED                 0x0F6
+#define BRW_SURFACEFORMAT_R16G16_USCALED                 0x0F7
+#define BRW_SURFACEFORMAT_R32_SSCALED                    0x0F8
+#define BRW_SURFACEFORMAT_R32_USCALED                    0x0F9
+#define BRW_SURFACEFORMAT_B5G6R5_UNORM                   0x100 
+#define BRW_SURFACEFORMAT_B5G6R5_UNORM_SRGB              0x101 
+#define BRW_SURFACEFORMAT_B5G5R5A1_UNORM                 0x102 
+#define BRW_SURFACEFORMAT_B5G5R5A1_UNORM_SRGB            0x103 
+#define BRW_SURFACEFORMAT_B4G4R4A4_UNORM                 0x104 
+#define BRW_SURFACEFORMAT_B4G4R4A4_UNORM_SRGB            0x105 
+#define BRW_SURFACEFORMAT_R8G8_UNORM                     0x106 
+#define BRW_SURFACEFORMAT_R8G8_SNORM                     0x107 
+#define BRW_SURFACEFORMAT_R8G8_SINT                      0x108 
+#define BRW_SURFACEFORMAT_R8G8_UINT                      0x109 
+#define BRW_SURFACEFORMAT_R16_UNORM                      0x10A 
+#define BRW_SURFACEFORMAT_R16_SNORM                      0x10B 
+#define BRW_SURFACEFORMAT_R16_SINT                       0x10C 
+#define BRW_SURFACEFORMAT_R16_UINT                       0x10D 
+#define BRW_SURFACEFORMAT_R16_FLOAT                      0x10E 
+#define BRW_SURFACEFORMAT_I16_UNORM                      0x111 
+#define BRW_SURFACEFORMAT_L16_UNORM                      0x112 
+#define BRW_SURFACEFORMAT_A16_UNORM                      0x113 
+#define BRW_SURFACEFORMAT_L8A8_UNORM                     0x114 
+#define BRW_SURFACEFORMAT_I16_FLOAT                      0x115
+#define BRW_SURFACEFORMAT_L16_FLOAT                      0x116
+#define BRW_SURFACEFORMAT_A16_FLOAT                      0x117
+#define BRW_SURFACEFORMAT_L8A8_UNORM_SRGB                0x118
+#define BRW_SURFACEFORMAT_R5G5_SNORM_B6_UNORM            0x119
+#define BRW_SURFACEFORMAT_B5G5R5X1_UNORM                 0x11A
+#define BRW_SURFACEFORMAT_B5G5R5X1_UNORM_SRGB            0x11B
+#define BRW_SURFACEFORMAT_R8G8_SSCALED                   0x11C
+#define BRW_SURFACEFORMAT_R8G8_USCALED                   0x11D
+#define BRW_SURFACEFORMAT_R16_SSCALED                    0x11E
+#define BRW_SURFACEFORMAT_R16_USCALED                    0x11F
+#define BRW_SURFACEFORMAT_R8_UNORM                       0x140 
+#define BRW_SURFACEFORMAT_R8_SNORM                       0x141 
+#define BRW_SURFACEFORMAT_R8_SINT                        0x142 
+#define BRW_SURFACEFORMAT_R8_UINT                        0x143 
+#define BRW_SURFACEFORMAT_A8_UNORM                       0x144 
+#define BRW_SURFACEFORMAT_I8_UNORM                       0x145 
+#define BRW_SURFACEFORMAT_L8_UNORM                       0x146 
+#define BRW_SURFACEFORMAT_P4A4_UNORM                     0x147 
+#define BRW_SURFACEFORMAT_A4P4_UNORM                     0x148
+#define BRW_SURFACEFORMAT_R8_SSCALED                     0x149
+#define BRW_SURFACEFORMAT_R8_USCALED                     0x14A
+#define BRW_SURFACEFORMAT_L8_UNORM_SRGB                  0x14C
+#define BRW_SURFACEFORMAT_R1_UINT                        0x181 
+#define BRW_SURFACEFORMAT_YCRCB_NORMAL                   0x182 
+#define BRW_SURFACEFORMAT_YCRCB_SWAPUVY                  0x183 
+#define BRW_SURFACEFORMAT_BC1_UNORM                      0x186 
+#define BRW_SURFACEFORMAT_BC2_UNORM                      0x187 
+#define BRW_SURFACEFORMAT_BC3_UNORM                      0x188 
+#define BRW_SURFACEFORMAT_BC4_UNORM                      0x189 
+#define BRW_SURFACEFORMAT_BC5_UNORM                      0x18A 
+#define BRW_SURFACEFORMAT_BC1_UNORM_SRGB                 0x18B 
+#define BRW_SURFACEFORMAT_BC2_UNORM_SRGB                 0x18C 
+#define BRW_SURFACEFORMAT_BC3_UNORM_SRGB                 0x18D 
+#define BRW_SURFACEFORMAT_MONO8                          0x18E 
+#define BRW_SURFACEFORMAT_YCRCB_SWAPUV                   0x18F 
+#define BRW_SURFACEFORMAT_YCRCB_SWAPY                    0x190 
+#define BRW_SURFACEFORMAT_DXT1_RGB                       0x191 
+#define BRW_SURFACEFORMAT_FXT1                           0x192 
+#define BRW_SURFACEFORMAT_R8G8B8_UNORM                   0x193 
+#define BRW_SURFACEFORMAT_R8G8B8_SNORM                   0x194 
+#define BRW_SURFACEFORMAT_R8G8B8_SSCALED                 0x195 
+#define BRW_SURFACEFORMAT_R8G8B8_USCALED                 0x196 
+#define BRW_SURFACEFORMAT_R64G64B64A64_FLOAT             0x197 
+#define BRW_SURFACEFORMAT_R64G64B64_FLOAT                0x198 
+#define BRW_SURFACEFORMAT_BC4_SNORM                      0x199 
+#define BRW_SURFACEFORMAT_BC5_SNORM                      0x19A 
+#define BRW_SURFACEFORMAT_R16G16B16_UNORM                0x19C 
+#define BRW_SURFACEFORMAT_R16G16B16_SNORM                0x19D 
+#define BRW_SURFACEFORMAT_R16G16B16_SSCALED              0x19E 
+#define BRW_SURFACEFORMAT_R16G16B16_USCALED              0x19F
+#define BRW_SURFACEFORMAT_INVALID                        0xFFF
+
+#define BRW_SURFACERETURNFORMAT_FLOAT32  0
+#define BRW_SURFACERETURNFORMAT_S1       1
+
+#define BRW_SURFACE_1D      0
+#define BRW_SURFACE_2D      1
+#define BRW_SURFACE_3D      2
+#define BRW_SURFACE_CUBE    3
+#define BRW_SURFACE_BUFFER  4
+#define BRW_SURFACE_NULL    7
+
+#define BRW_TEXCOORDMODE_WRAP            0
+#define BRW_TEXCOORDMODE_MIRROR          1
+#define BRW_TEXCOORDMODE_CLAMP           2
+#define BRW_TEXCOORDMODE_CUBE            3
+#define BRW_TEXCOORDMODE_CLAMP_BORDER    4
+#define BRW_TEXCOORDMODE_MIRROR_ONCE     5
+
+#define BRW_THREAD_PRIORITY_NORMAL   0
+#define BRW_THREAD_PRIORITY_HIGH     1
+
+#define BRW_TILEWALK_XMAJOR                 0
+#define BRW_TILEWALK_YMAJOR                 1
+
+#define BRW_VERTEX_SUBPIXEL_PRECISION_8BITS  0
+#define BRW_VERTEX_SUBPIXEL_PRECISION_4BITS  1
+
+/* Execution Unit (EU) defines
+ */
+
+#define BRW_ALIGN_1   0
+#define BRW_ALIGN_16  1
+
+#define BRW_ADDRESS_DIRECT                        0
+#define BRW_ADDRESS_REGISTER_INDIRECT_REGISTER    1
+
+#define BRW_CHANNEL_X     0
+#define BRW_CHANNEL_Y     1
+#define BRW_CHANNEL_Z     2
+#define BRW_CHANNEL_W     3
+
+#define BRW_COMPRESSION_NONE          0
+#define BRW_COMPRESSION_2NDHALF       1
+#define BRW_COMPRESSION_COMPRESSED    2
+
+#define BRW_CONDITIONAL_NONE  0
+#define BRW_CONDITIONAL_Z     1
+#define BRW_CONDITIONAL_NZ    2
+#define BRW_CONDITIONAL_EQ    1	/* Z */
+#define BRW_CONDITIONAL_NEQ   2	/* NZ */
+#define BRW_CONDITIONAL_G     3
+#define BRW_CONDITIONAL_GE    4
+#define BRW_CONDITIONAL_L     5
+#define BRW_CONDITIONAL_LE    6
+#define BRW_CONDITIONAL_R     7
+#define BRW_CONDITIONAL_O     8
+#define BRW_CONDITIONAL_U     9
+
+#define BRW_DEBUG_NONE        0
+#define BRW_DEBUG_BREAKPOINT  1
+
+#define BRW_DEPENDENCY_NORMAL         0
+#define BRW_DEPENDENCY_NOTCLEARED     1
+#define BRW_DEPENDENCY_NOTCHECKED     2
+#define BRW_DEPENDENCY_DISABLE        3
+
+#define BRW_EXECUTE_1     0
+#define BRW_EXECUTE_2     1
+#define BRW_EXECUTE_4     2
+#define BRW_EXECUTE_8     3
+#define BRW_EXECUTE_16    4
+#define BRW_EXECUTE_32    5
+
+#define BRW_HORIZONTAL_STRIDE_0   0
+#define BRW_HORIZONTAL_STRIDE_1   1
+#define BRW_HORIZONTAL_STRIDE_2   2
+#define BRW_HORIZONTAL_STRIDE_4   3
+
+#define BRW_INSTRUCTION_NORMAL    0
+#define BRW_INSTRUCTION_SATURATE  1
+
+#define BRW_MASK_ENABLE   0
+#define BRW_MASK_DISABLE  1
+
+#define BRW_OPCODE_MOV        1
+#define BRW_OPCODE_SEL        2
+#define BRW_OPCODE_NOT        4
+#define BRW_OPCODE_AND        5
+#define BRW_OPCODE_OR         6
+#define BRW_OPCODE_XOR        7
+#define BRW_OPCODE_SHR        8
+#define BRW_OPCODE_SHL        9
+#define BRW_OPCODE_RSR        10
+#define BRW_OPCODE_RSL        11
+#define BRW_OPCODE_ASR        12
+#define BRW_OPCODE_CMP        16
+#define BRW_OPCODE_CMPN       17
+#define BRW_OPCODE_JMPI       32
+#define BRW_OPCODE_IF         34
+#define BRW_OPCODE_IFF        35
+#define BRW_OPCODE_ELSE       36
+#define BRW_OPCODE_ENDIF      37
+#define BRW_OPCODE_DO         38
+#define BRW_OPCODE_WHILE      39
+#define BRW_OPCODE_BREAK      40
+#define BRW_OPCODE_CONTINUE   41
+#define BRW_OPCODE_HALT       42
+#define BRW_OPCODE_MSAVE      44
+#define BRW_OPCODE_MRESTORE   45
+#define BRW_OPCODE_PUSH       46
+#define BRW_OPCODE_POP        47
+#define BRW_OPCODE_WAIT       48
+#define BRW_OPCODE_SEND       49
+#define BRW_OPCODE_ADD        64
+#define BRW_OPCODE_MUL        65
+#define BRW_OPCODE_AVG        66
+#define BRW_OPCODE_FRC        67
+#define BRW_OPCODE_RNDU       68
+#define BRW_OPCODE_RNDD       69
+#define BRW_OPCODE_RNDE       70
+#define BRW_OPCODE_RNDZ       71
+#define BRW_OPCODE_MAC        72
+#define BRW_OPCODE_MACH       73
+#define BRW_OPCODE_LZD        74
+#define BRW_OPCODE_SAD2       80
+#define BRW_OPCODE_SADA2      81
+#define BRW_OPCODE_DP4        84
+#define BRW_OPCODE_DPH        85
+#define BRW_OPCODE_DP3        86
+#define BRW_OPCODE_DP2        87
+#define BRW_OPCODE_DPA2       88
+#define BRW_OPCODE_LINE       89
+#define BRW_OPCODE_NOP        126
+
+#define BRW_PREDICATE_NONE             0
+#define BRW_PREDICATE_NORMAL           1
+#define BRW_PREDICATE_ALIGN1_ANYV             2
+#define BRW_PREDICATE_ALIGN1_ALLV             3
+#define BRW_PREDICATE_ALIGN1_ANY2H            4
+#define BRW_PREDICATE_ALIGN1_ALL2H            5
+#define BRW_PREDICATE_ALIGN1_ANY4H            6
+#define BRW_PREDICATE_ALIGN1_ALL4H            7
+#define BRW_PREDICATE_ALIGN1_ANY8H            8
+#define BRW_PREDICATE_ALIGN1_ALL8H            9
+#define BRW_PREDICATE_ALIGN1_ANY16H           10
+#define BRW_PREDICATE_ALIGN1_ALL16H           11
+#define BRW_PREDICATE_ALIGN16_REPLICATE_X     2
+#define BRW_PREDICATE_ALIGN16_REPLICATE_Y     3
+#define BRW_PREDICATE_ALIGN16_REPLICATE_Z     4
+#define BRW_PREDICATE_ALIGN16_REPLICATE_W     5
+#define BRW_PREDICATE_ALIGN16_ANY4H           6
+#define BRW_PREDICATE_ALIGN16_ALL4H           7
+
+#define BRW_ARCHITECTURE_REGISTER_FILE    0
+#define BRW_GENERAL_REGISTER_FILE         1
+#define BRW_MESSAGE_REGISTER_FILE         2
+#define BRW_IMMEDIATE_VALUE               3
+
+#define BRW_REGISTER_TYPE_UD  0
+#define BRW_REGISTER_TYPE_D   1
+#define BRW_REGISTER_TYPE_UW  2
+#define BRW_REGISTER_TYPE_W   3
+#define BRW_REGISTER_TYPE_UB  4
+#define BRW_REGISTER_TYPE_B   5
+#define BRW_REGISTER_TYPE_VF  5	/* packed float vector, immediates only? */
+#define BRW_REGISTER_TYPE_HF  6
+#define BRW_REGISTER_TYPE_V   6	/* packed int vector, immediates only, uword dest only */
+#define BRW_REGISTER_TYPE_F   7
+
+#define BRW_ARF_NULL                  0x00
+#define BRW_ARF_ADDRESS               0x10
+#define BRW_ARF_ACCUMULATOR           0x20   
+#define BRW_ARF_FLAG                  0x30
+#define BRW_ARF_MASK                  0x40
+#define BRW_ARF_MASK_STACK            0x50
+#define BRW_ARF_MASK_STACK_DEPTH      0x60
+#define BRW_ARF_STATE                 0x70
+#define BRW_ARF_CONTROL               0x80
+#define BRW_ARF_NOTIFICATION_COUNT    0x90
+#define BRW_ARF_IP                    0xA0
+
+#define BRW_AMASK   0
+#define BRW_IMASK   1
+#define BRW_LMASK   2
+#define BRW_CMASK   3
+
+
+
+#define BRW_THREAD_NORMAL     0
+#define BRW_THREAD_ATOMIC     1
+#define BRW_THREAD_SWITCH     2
+
+#define BRW_VERTICAL_STRIDE_0                 0
+#define BRW_VERTICAL_STRIDE_1                 1
+#define BRW_VERTICAL_STRIDE_2                 2
+#define BRW_VERTICAL_STRIDE_4                 3
+#define BRW_VERTICAL_STRIDE_8                 4
+#define BRW_VERTICAL_STRIDE_16                5
+#define BRW_VERTICAL_STRIDE_32                6
+#define BRW_VERTICAL_STRIDE_64                7
+#define BRW_VERTICAL_STRIDE_128               8
+#define BRW_VERTICAL_STRIDE_256               9
+#define BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL   0xF
+
+#define BRW_WIDTH_1       0
+#define BRW_WIDTH_2       1
+#define BRW_WIDTH_4       2
+#define BRW_WIDTH_8       3
+#define BRW_WIDTH_16      4
+
+#define BRW_STATELESS_BUFFER_BOUNDARY_1K      0
+#define BRW_STATELESS_BUFFER_BOUNDARY_2K      1
+#define BRW_STATELESS_BUFFER_BOUNDARY_4K      2
+#define BRW_STATELESS_BUFFER_BOUNDARY_8K      3
+#define BRW_STATELESS_BUFFER_BOUNDARY_16K     4
+#define BRW_STATELESS_BUFFER_BOUNDARY_32K     5
+#define BRW_STATELESS_BUFFER_BOUNDARY_64K     6
+#define BRW_STATELESS_BUFFER_BOUNDARY_128K    7
+#define BRW_STATELESS_BUFFER_BOUNDARY_256K    8
+#define BRW_STATELESS_BUFFER_BOUNDARY_512K    9
+#define BRW_STATELESS_BUFFER_BOUNDARY_1M      10
+#define BRW_STATELESS_BUFFER_BOUNDARY_2M      11
+
+#define BRW_POLYGON_FACING_FRONT      0
+#define BRW_POLYGON_FACING_BACK       1
+
+#define BRW_MESSAGE_TARGET_NULL               0
+#define BRW_MESSAGE_TARGET_MATH               1
+#define BRW_MESSAGE_TARGET_SAMPLER            2
+#define BRW_MESSAGE_TARGET_GATEWAY            3
+#define BRW_MESSAGE_TARGET_DATAPORT_READ      4
+#define BRW_MESSAGE_TARGET_DATAPORT_WRITE     5
+#define BRW_MESSAGE_TARGET_URB                6
+#define BRW_MESSAGE_TARGET_THREAD_SPAWNER     7
+
+#define BRW_SAMPLER_RETURN_FORMAT_FLOAT32     0
+#define BRW_SAMPLER_RETURN_FORMAT_UINT32      2
+#define BRW_SAMPLER_RETURN_FORMAT_SINT32      3
+
+#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE              0
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE             0
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS        0
+#define BRW_SAMPLER_MESSAGE_SIMD8_KILLPIX             1
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD        1
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD         1
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_GRADIENTS  2
+#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS    2
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE    0
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE     2
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_RESINFO           2
+#define BRW_SAMPLER_MESSAGE_SIMD8_RESINFO             2
+#define BRW_SAMPLER_MESSAGE_SIMD16_RESINFO            2
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_LD                3
+#define BRW_SAMPLER_MESSAGE_SIMD8_LD                  3
+#define BRW_SAMPLER_MESSAGE_SIMD16_LD                 3
+
+#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_IGDNG            0
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_IGDNG          0
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_IGDNG           0
+#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_BIAS_IGDNG       1
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_BIAS_IGDNG     1
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS_IGDNG      1
+#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_LOD_IGDNG        2
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD_IGDNG      2
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD_IGDNG       2
+#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_COMPARE_IGDNG    3
+#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE_IGDNG  3
+#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE_IGDNG   3
+
+/* for IGDNG only */
+#define BRW_SAMPLER_SIMD_MODE_SIMD4X2                   0
+#define BRW_SAMPLER_SIMD_MODE_SIMD8                     1
+#define BRW_SAMPLER_SIMD_MODE_SIMD16                    2
+#define BRW_SAMPLER_SIMD_MODE_SIMD32_64                 3
+
+#define BRW_DATAPORT_OWORD_BLOCK_1_OWORDLOW   0
+#define BRW_DATAPORT_OWORD_BLOCK_1_OWORDHIGH  1
+#define BRW_DATAPORT_OWORD_BLOCK_2_OWORDS     2
+#define BRW_DATAPORT_OWORD_BLOCK_4_OWORDS     3
+#define BRW_DATAPORT_OWORD_BLOCK_8_OWORDS     4
+
+#define BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD     0
+#define BRW_DATAPORT_OWORD_DUAL_BLOCK_4OWORDS    2
+
+#define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS   2
+#define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS  3
+
+#define BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ          0
+#define BRW_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ     1
+#define BRW_DATAPORT_READ_MESSAGE_DWORD_BLOCK_READ          2
+#define BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ      3
+
+#define BRW_DATAPORT_READ_TARGET_DATA_CACHE      0
+#define BRW_DATAPORT_READ_TARGET_RENDER_CACHE    1
+#define BRW_DATAPORT_READ_TARGET_SAMPLER_CACHE   2
+
+#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE                0
+#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE_REPLICATED     1
+#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01         2
+#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN23         3
+#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01       4
+
+#define BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE                0
+#define BRW_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE           1
+#define BRW_DATAPORT_WRITE_MESSAGE_DWORD_BLOCK_WRITE                2
+#define BRW_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE            3
+#define BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE              4
+#define BRW_DATAPORT_WRITE_MESSAGE_STREAMED_VERTEX_BUFFER_WRITE     5
+#define BRW_DATAPORT_WRITE_MESSAGE_FLUSH_RENDER_CACHE               7
+
+#define BRW_MATH_FUNCTION_INV                              1
+#define BRW_MATH_FUNCTION_LOG                              2
+#define BRW_MATH_FUNCTION_EXP                              3
+#define BRW_MATH_FUNCTION_SQRT                             4
+#define BRW_MATH_FUNCTION_RSQ                              5
+#define BRW_MATH_FUNCTION_SIN                              6 /* was 7 */
+#define BRW_MATH_FUNCTION_COS                              7 /* was 8 */
+#define BRW_MATH_FUNCTION_SINCOS                           8 /* was 6 */
+#define BRW_MATH_FUNCTION_TAN                              9
+#define BRW_MATH_FUNCTION_POW                              10
+#define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER   11
+#define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT                 12
+#define BRW_MATH_FUNCTION_INT_DIV_REMAINDER                13
+
+#define BRW_MATH_INTEGER_UNSIGNED     0
+#define BRW_MATH_INTEGER_SIGNED       1
+
+#define BRW_MATH_PRECISION_FULL        0
+#define BRW_MATH_PRECISION_PARTIAL     1
+
+#define BRW_MATH_SATURATE_NONE         0
+#define BRW_MATH_SATURATE_SATURATE     1
+
+#define BRW_MATH_DATA_VECTOR  0
+#define BRW_MATH_DATA_SCALAR  1
+
+#define BRW_URB_OPCODE_WRITE  0
+
+#define BRW_URB_SWIZZLE_NONE          0
+#define BRW_URB_SWIZZLE_INTERLEAVE    1
+#define BRW_URB_SWIZZLE_TRANSPOSE     2
+
+#define BRW_SCRATCH_SPACE_SIZE_1K     0
+#define BRW_SCRATCH_SPACE_SIZE_2K     1
+#define BRW_SCRATCH_SPACE_SIZE_4K     2
+#define BRW_SCRATCH_SPACE_SIZE_8K     3
+#define BRW_SCRATCH_SPACE_SIZE_16K    4
+#define BRW_SCRATCH_SPACE_SIZE_32K    5
+#define BRW_SCRATCH_SPACE_SIZE_64K    6
+#define BRW_SCRATCH_SPACE_SIZE_128K   7
+#define BRW_SCRATCH_SPACE_SIZE_256K   8
+#define BRW_SCRATCH_SPACE_SIZE_512K   9
+#define BRW_SCRATCH_SPACE_SIZE_1M     10
+#define BRW_SCRATCH_SPACE_SIZE_2M     11
+
+
+
+
+#define CMD_URB_FENCE                 0x6000
+#define CMD_CS_URB_STATE              0x6001
+#define CMD_CONST_BUFFER              0x6002
+
+#define CMD_STATE_BASE_ADDRESS        0x6101
+#define CMD_STATE_INSN_POINTER        0x6102
+#define CMD_PIPELINE_SELECT_965       0x6104
+#define CMD_PIPELINE_SELECT_GM45      0x6904
+
+#define CMD_PIPELINED_STATE_POINTERS  0x7800
+#define CMD_BINDING_TABLE_PTRS        0x7801
+
+#define CMD_VERTEX_BUFFER             0x7808
+# define BRW_VB0_INDEX_SHIFT		27
+# define BRW_VB0_ACCESS_VERTEXDATA	(0 << 26)
+# define BRW_VB0_ACCESS_INSTANCEDATA	(1 << 26)
+# define BRW_VB0_PITCH_SHIFT		0
+
+#define CMD_VERTEX_ELEMENT            0x7809
+# define BRW_VE0_INDEX_SHIFT		27
+# define BRW_VE0_FORMAT_SHIFT		16
+# define BRW_VE0_VALID			(1 << 26)
+# define BRW_VE0_SRC_OFFSET_SHIFT	0
+# define BRW_VE1_COMPONENT_NOSTORE	0
+# define BRW_VE1_COMPONENT_STORE_SRC	1
+# define BRW_VE1_COMPONENT_STORE_0	2
+# define BRW_VE1_COMPONENT_STORE_1_FLT	3
+# define BRW_VE1_COMPONENT_STORE_1_INT	4
+# define BRW_VE1_COMPONENT_STORE_VID	5
+# define BRW_VE1_COMPONENT_STORE_IID	6
+# define BRW_VE1_COMPONENT_STORE_PID	7
+# define BRW_VE1_COMPONENT_0_SHIFT	28
+# define BRW_VE1_COMPONENT_1_SHIFT	24
+# define BRW_VE1_COMPONENT_2_SHIFT	20
+# define BRW_VE1_COMPONENT_3_SHIFT	16
+# define BRW_VE1_DST_OFFSET_SHIFT	0
+
+#define CMD_INDEX_BUFFER              0x780a
+#define CMD_VF_STATISTICS_965         0x780b
+#define CMD_VF_STATISTICS_GM45        0x680b
+
+#define CMD_DRAW_RECT                 0x7900
+#define CMD_BLEND_CONSTANT_COLOR      0x7901
+#define CMD_CHROMA_KEY                0x7904
+#define CMD_DEPTH_BUFFER              0x7905
+#define CMD_POLY_STIPPLE_OFFSET       0x7906
+#define CMD_POLY_STIPPLE_PATTERN      0x7907
+#define CMD_LINE_STIPPLE_PATTERN      0x7908
+#define CMD_GLOBAL_DEPTH_OFFSET_CLAMP 0x7909
+#define CMD_AA_LINE_PARAMETERS        0x790a
+
+#define CMD_PIPE_CONTROL              0x7a00
+
+#define CMD_3D_PRIM                   0x7b00
+
+#define CMD_MI_FLUSH                  0x0200
+
+
+/* Various values from the R0 vertex header:
+ */
+#define R02_PRIM_END    0x1
+#define R02_PRIM_START  0x2
+
+#define URB_SIZES(brw)                  (BRW_IS_IGDNG(brw) ? 1024 : \
+                                         (BRW_IS_G4X(brw) ? 384 : 256))  /* 512 bit units */
+
+
+
+#endif
diff --git a/src/gallium/drivers/i965/brw_disasm.c b/src/gallium/drivers/i965/brw_disasm.c
new file mode 100644
index 0000000..65db272
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_disasm.c
@@ -0,0 +1,922 @@
+/*
+ * Copyright © 2008 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+#include "brw_disasm.h"
+#include "brw_structs.h"
+#include "brw_reg.h"
+#include "brw_defines.h"
+
+struct {
+    char    *name;
+    int	    nsrc;
+    int	    ndst;
+} opcode[128] = {
+    [BRW_OPCODE_MOV] = { .name = "mov", .nsrc = 1, .ndst = 1 },
+    [BRW_OPCODE_FRC] = { .name = "frc", .nsrc = 1, .ndst = 1 },
+    [BRW_OPCODE_RNDU] = { .name = "rndu", .nsrc = 1, .ndst = 1 },
+    [BRW_OPCODE_RNDD] = { .name = "rndd", .nsrc = 1, .ndst = 1 },
+    [BRW_OPCODE_RNDE] = { .name = "rnde", .nsrc = 1, .ndst = 1 },
+    [BRW_OPCODE_RNDZ] = { .name = "rndz", .nsrc = 1, .ndst = 1 },
+    [BRW_OPCODE_NOT] = { .name = "not", .nsrc = 1, .ndst = 1 },
+    [BRW_OPCODE_LZD] = { .name = "lzd", .nsrc = 1, .ndst = 1 },
+
+    [BRW_OPCODE_MUL] = { .name = "mul", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_MAC] = { .name = "mac", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_MACH] = { .name = "mach", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_LINE] = { .name = "line", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_SAD2] = { .name = "sad2", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_SADA2] = { .name = "sada2", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_DP4] = { .name = "dp4", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_DPH] = { .name = "dph", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_DP3] = { .name = "dp3", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_DP2] = { .name = "dp2", .nsrc = 2, .ndst = 1 },
+
+    [BRW_OPCODE_AVG] = { .name = "avg", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_ADD] = { .name = "add", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_SEL] = { .name = "sel", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_AND] = { .name = "and", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_OR] = { .name = "or", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_XOR] = { .name = "xor", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_SHR] = { .name = "shr", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_SHL] = { .name = "shl", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_ASR] = { .name = "asr", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_CMP] = { .name = "cmp", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_CMPN] = { .name = "cmpn", .nsrc = 2, .ndst = 1 },
+
+    [BRW_OPCODE_SEND] = { .name = "send", .nsrc = 1, .ndst = 1 },
+    [BRW_OPCODE_NOP] = { .name = "nop", .nsrc = 0, .ndst = 0 },
+    [BRW_OPCODE_JMPI] = { .name = "jmpi", .nsrc = 1, .ndst = 0 },
+    [BRW_OPCODE_IF] = { .name = "if", .nsrc = 2, .ndst = 0 },
+    [BRW_OPCODE_IFF] = { .name = "iff", .nsrc = 1, .ndst = 01 },
+    [BRW_OPCODE_WHILE] = { .name = "while", .nsrc = 1, .ndst = 0 },
+    [BRW_OPCODE_ELSE] = { .name = "else", .nsrc = 2, .ndst = 0 },
+    [BRW_OPCODE_BREAK] = { .name = "break", .nsrc = 1, .ndst = 0 },
+    [BRW_OPCODE_CONTINUE] = { .name = "cont", .nsrc = 1, .ndst = 0 },
+    [BRW_OPCODE_HALT] = { .name = "halt", .nsrc = 1, .ndst = 0 },
+    [BRW_OPCODE_MSAVE] = { .name = "msave", .nsrc = 1, .ndst = 1 },
+    [BRW_OPCODE_PUSH] = { .name = "push", .nsrc = 1, .ndst = 1 },
+    [BRW_OPCODE_MRESTORE] = { .name = "mrest", .nsrc = 1, .ndst = 1 },
+    [BRW_OPCODE_POP] = { .name = "pop", .nsrc = 2, .ndst = 0 },
+    [BRW_OPCODE_WAIT] = { .name = "wait", .nsrc = 1, .ndst = 0 },
+    [BRW_OPCODE_DO] = { .name = "do", .nsrc = 0, .ndst = 0 },
+    [BRW_OPCODE_ENDIF] = { .name = "endif", .nsrc = 2, .ndst = 0 },
+};
+
+char *conditional_modifier[16] = {
+    [BRW_CONDITIONAL_NONE] = "",
+    [BRW_CONDITIONAL_Z] = ".e",
+    [BRW_CONDITIONAL_NZ] = ".ne",
+    [BRW_CONDITIONAL_G] = ".g",
+    [BRW_CONDITIONAL_GE] = ".ge",
+    [BRW_CONDITIONAL_L] = ".l",
+    [BRW_CONDITIONAL_LE] = ".le",
+    [BRW_CONDITIONAL_R] = ".r",
+    [BRW_CONDITIONAL_O] = ".o",
+    [BRW_CONDITIONAL_U] = ".u",
+};
+
+char *negate[2] = {
+    [0] = "",
+    [1] = "-",
+};
+
+char *_abs[2] = {
+    [0] = "",
+    [1] = "(abs)",
+};
+
+char *vert_stride[16] = {
+    [0] = "0",
+    [1] = "1",
+    [2] = "2",
+    [3] = "4",
+    [4] = "8",
+    [5] = "16",
+    [6] = "32",
+    [15] = "VxH",
+};
+
+char *width[8] = {
+    [0] = "1",
+    [1] = "2",
+    [2] = "4",
+    [3] = "8",
+    [4] = "16",
+};
+
+char *horiz_stride[4] = {
+    [0] = "0",
+    [1] = "1",
+    [2] = "2",
+    [3] = "4"
+};
+
+char *chan_sel[4] = {
+    [0] = "x",
+    [1] = "y",
+    [2] = "z",
+    [3] = "w",
+};
+
+char *dest_condmod[16] = {
+   [0] = NULL
+};
+
+char *debug_ctrl[2] = {
+    [0] = "",
+    [1] = ".breakpoint"
+};
+
+char *saturate[2] = {
+    [0] = "",
+    [1] = ".sat"
+};
+
+char *exec_size[8] = {
+    [0] = "1",
+    [1] = "2",
+    [2] = "4",
+    [3] = "8",
+    [4] = "16",
+    [5] = "32"
+};
+
+char *pred_inv[2] = {
+    [0] = "+",
+    [1] = "-"
+};
+
+char *pred_ctrl_align16[16] = {
+    [1] = "",
+    [2] = ".x",
+    [3] = ".y",
+    [4] = ".z",
+    [5] = ".w",
+    [6] = ".any4h",
+    [7] = ".all4h",
+};
+
+char *pred_ctrl_align1[16] = {
+    [1] = "",
+    [2] = ".anyv",
+    [3] = ".allv",
+    [4] = ".any2h",
+    [5] = ".all2h",
+    [6] = ".any4h",
+    [7] = ".all4h",
+    [8] = ".any8h",
+    [9] = ".all8h",
+    [10] = ".any16h",
+    [11] = ".all16h",
+};
+
+char *thread_ctrl[4] = {
+    [0] = "",
+    [2] = "switch"
+};
+
+char *compr_ctrl[4] = {
+    [0] = "",
+    [1] = "sechalf",
+    [2] = "compr",
+};
+
+char *dep_ctrl[4] = {
+    [0] = "",
+    [1] = "NoDDClr",
+    [2] = "NoDDChk",
+    [3] = "NoDDClr,NoDDChk",
+};
+
+char *mask_ctrl[4] = {
+    [0] = "",
+    [1] = "nomask",
+};
+
+char *access_mode[2] = {
+    [0] = "align1",
+    [1] = "align16",
+};
+
+char *reg_encoding[8] = {
+    [0] = "UD",
+    [1] = "D",
+    [2] = "UW",
+    [3] = "W",
+    [4] = "UB",
+    [5] = "B",
+    [7] = "F"
+};
+
+char *imm_encoding[8] = {
+    [0] = "UD",
+    [1] = "D",
+    [2] = "UW",
+    [3] = "W",
+    [5] = "VF",
+    [5] = "V",
+    [7] = "F"
+};
+
+char *reg_file[4] = {
+    [0] = "A",
+    [1] = "g",
+    [2] = "m",
+    [3] = "imm",
+};
+
+char *writemask[16] = {
+    [0x0] = ".",
+    [0x1] = ".x",
+    [0x2] = ".y",
+    [0x3] = ".xy",
+    [0x4] = ".z",
+    [0x5] = ".xz",
+    [0x6] = ".yz",
+    [0x7] = ".xyz",
+    [0x8] = ".w",
+    [0x9] = ".xw",
+    [0xa] = ".yw",
+    [0xb] = ".xyw",
+    [0xc] = ".zw",
+    [0xd] = ".xzw",
+    [0xe] = ".yzw",
+    [0xf] = "",
+};
+
+char *end_of_thread[2] = {
+    [0] = "",
+    [1] = "EOT"
+};
+
+char *target_function[16] = {
+    [BRW_MESSAGE_TARGET_NULL] = "null",
+    [BRW_MESSAGE_TARGET_MATH] = "math",
+    [BRW_MESSAGE_TARGET_SAMPLER] = "sampler",
+    [BRW_MESSAGE_TARGET_GATEWAY] = "gateway",
+    [BRW_MESSAGE_TARGET_DATAPORT_READ] = "read",
+    [BRW_MESSAGE_TARGET_DATAPORT_WRITE] = "write",
+    [BRW_MESSAGE_TARGET_URB] = "urb",
+    [BRW_MESSAGE_TARGET_THREAD_SPAWNER] = "thread_spawner"
+};
+
+char *math_function[16] = {
+    [BRW_MATH_FUNCTION_INV] = "inv",
+    [BRW_MATH_FUNCTION_LOG] = "log",
+    [BRW_MATH_FUNCTION_EXP] = "exp",
+    [BRW_MATH_FUNCTION_SQRT] = "sqrt",
+    [BRW_MATH_FUNCTION_RSQ] = "rsq",
+    [BRW_MATH_FUNCTION_SIN] = "sin",
+    [BRW_MATH_FUNCTION_COS] = "cos",
+    [BRW_MATH_FUNCTION_SINCOS] = "sincos",
+    [BRW_MATH_FUNCTION_TAN] = "tan",
+    [BRW_MATH_FUNCTION_POW] = "pow",
+    [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER] = "intdivmod",
+    [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT] = "intmod",
+    [BRW_MATH_FUNCTION_INT_DIV_REMAINDER] = "intdiv",
+};
+
+char *math_saturate[2] = {
+    [0] = "",
+    [1] = "sat"
+};
+
+char *math_signed[2] = {
+    [0] = "",
+    [1] = "signed"
+};
+
+char *math_scalar[2] = {
+    [0] = "",
+    [1] = "scalar"
+};
+
+char *math_precision[2] = {
+    [0] = "",
+    [1] = "partial_precision"
+};
+
+char *urb_swizzle[4] = {
+    [BRW_URB_SWIZZLE_NONE] = "",
+    [BRW_URB_SWIZZLE_INTERLEAVE] = "interleave",
+    [BRW_URB_SWIZZLE_TRANSPOSE] = "transpose",
+};
+
+char *urb_allocate[2] = {
+    [0] = "",
+    [1] = "allocate"
+};
+
+char *urb_used[2] = {
+    [0] = "",
+    [1] = "used"
+};
+
+char *urb_complete[2] = {
+    [0] = "",
+    [1] = "complete"
+};
+
+char *sampler_target_format[4] = {
+    [0] = "F",
+    [2] = "UD",
+    [3] = "D"
+};
+
+
+static int column;
+
+static int string (FILE *file, char *string)
+{
+    fputs (string, file);
+    column += strlen (string);
+    return 0;
+}
+
+static int format (FILE *f, char *format, ...)
+{
+    char    buf[1024];
+    va_list	args;
+    va_start (args, format);
+
+    vsnprintf (buf, sizeof (buf) - 1, format, args);
+    string (f, buf);
+    return 0;
+}
+
+static int newline (FILE *f)
+{
+    putc ('\n', f);
+    column = 0;
+    return 0;
+}
+
+static int pad (FILE *f, int c)
+{
+    do
+	string (f, " ");
+    while (column < c);
+    return 0;
+}
+
+static int control (FILE *file, char *name, char *ctrl[], GLuint id, int *space)
+{
+    if (!ctrl[id]) {
+	fprintf (file, "*** invalid %s value %d ",
+		 name, id);
+	return 1;
+    }
+    if (ctrl[id][0])
+    {
+	if (space && *space)
+	    string (file, " ");
+	string (file, ctrl[id]);
+	if (space)
+	    *space = 1;
+    }
+    return 0;
+}
+
+static int print_opcode (FILE *file, int id)
+{
+    if (!opcode[id].name) {
+	format (file, "*** invalid opcode value %d ", id);
+	return 1;
+    }
+    string (file, opcode[id].name);
+    return 0;
+}
+
+static int reg (FILE *file, GLuint _reg_file, GLuint _reg_nr)
+{
+    int	err = 0;
+    if (_reg_file == BRW_ARCHITECTURE_REGISTER_FILE) {
+	switch (_reg_nr & 0xf0) {
+	case BRW_ARF_NULL:
+	    string (file, "null");
+	    return -1;
+	case BRW_ARF_ADDRESS:
+	    format (file, "a%d", _reg_nr & 0x0f);
+	    break;
+	case BRW_ARF_ACCUMULATOR:
+	    format (file, "acc%d", _reg_nr & 0x0f);
+	    break;
+	case BRW_ARF_MASK:
+	    format (file, "mask%d", _reg_nr & 0x0f);
+	    break;
+	case BRW_ARF_MASK_STACK:
+	    format (file, "msd%d", _reg_nr & 0x0f);
+	    break;
+	case BRW_ARF_STATE:
+	    format (file, "sr%d", _reg_nr & 0x0f);
+	    break;
+	case BRW_ARF_CONTROL:
+	    format (file, "cr%d", _reg_nr & 0x0f);
+	    break;
+	case BRW_ARF_NOTIFICATION_COUNT:
+	    format (file, "n%d", _reg_nr & 0x0f);
+	    break;
+	case BRW_ARF_IP:
+	    string (file, "ip");
+	    return -1;
+	    break;
+	default:
+	    format (file, "ARF%d", _reg_nr);
+	    break;
+	}
+    } else {
+	err  |= control (file, "src reg file", reg_file, _reg_file, NULL);
+	format (file, "%d", _reg_nr);
+    }
+    return err;
+}
+
+static int dest (FILE *file, const struct brw_instruction *inst)
+{
+    int	err = 0;
+
+    if (inst->header.access_mode == BRW_ALIGN_1)
+    {
+	if (inst->bits1.da1.dest_address_mode == BRW_ADDRESS_DIRECT)
+	{
+	    err |= reg (file, inst->bits1.da1.dest_reg_file, inst->bits1.da1.dest_reg_nr);
+	    if (err == -1)
+		return 0;
+	    if (inst->bits1.da1.dest_subreg_nr)
+		format (file, ".%d", inst->bits1.da1.dest_subreg_nr);
+	    format (file, "<%d>", inst->bits1.da1.dest_horiz_stride);
+	    err |= control (file, "dest reg encoding", reg_encoding, inst->bits1.da1.dest_reg_type, NULL);
+	}
+	else
+	{
+	    string (file, "g[a0");
+	    if (inst->bits1.ia1.dest_subreg_nr)
+		format (file, ".%d", inst->bits1.ia1.dest_subreg_nr);
+	    if (inst->bits1.ia1.dest_indirect_offset)
+		format (file, " %d", inst->bits1.ia1.dest_indirect_offset);
+	    string (file, "]");
+	    format (file, "<%d>", inst->bits1.ia1.dest_horiz_stride);
+	    err |= control (file, "dest reg encoding", reg_encoding, inst->bits1.ia1.dest_reg_type, NULL);
+	}
+    }
+    else
+    {
+	if (inst->bits1.da16.dest_address_mode == BRW_ADDRESS_DIRECT)
+	{
+	    err |= reg (file, inst->bits1.da16.dest_reg_file, inst->bits1.da16.dest_reg_nr);
+	    if (err == -1)
+		return 0;
+	    if (inst->bits1.da16.dest_subreg_nr)
+		format (file, ".%d", inst->bits1.da16.dest_subreg_nr);
+	    string (file, "<1>");
+	    err |= control (file, "writemask", writemask, inst->bits1.da16.dest_writemask, NULL);
+	    err |= control (file, "dest reg encoding", reg_encoding, inst->bits1.da16.dest_reg_type, NULL);
+	}
+	else
+	{
+	    err = 1;
+	    string (file, "Indirect align16 address mode not supported");
+	}
+    }
+
+    return 0;
+}
+
+static int src_align1_region (FILE *file,
+			      GLuint _vert_stride, GLuint _width, GLuint _horiz_stride)
+{
+    int err = 0;
+    string (file, "<");
+    err |= control (file, "vert stride", vert_stride, _vert_stride, NULL);
+    string (file, ",");
+    err |= control (file, "width", width, _width, NULL);
+    string (file, ",");
+    err |= control (file, "horiz_stride", horiz_stride, _horiz_stride, NULL);
+    string (file, ">");
+    return err;
+}
+
+static int src_da1 (FILE *file, GLuint type, GLuint _reg_file,
+		    GLuint _vert_stride, GLuint _width, GLuint _horiz_stride,
+		    GLuint reg_num, GLuint sub_reg_num, GLuint __abs, GLuint _negate)
+{
+    int err = 0;
+    err |= control (file, "negate", negate, _negate, NULL);
+    err |= control (file, "abs", _abs, __abs, NULL);
+
+    err |= reg (file, _reg_file, reg_num);
+    if (err == -1)
+	return 0;
+    if (sub_reg_num)
+	format (file, ".%d", sub_reg_num);
+    src_align1_region (file, _vert_stride, _width, _horiz_stride);
+    err |= control (file, "src reg encoding", reg_encoding, type, NULL);
+    return err;
+}
+
+static int src_ia1 (FILE *file,
+		    GLuint type,
+		    GLuint _reg_file,
+		    GLint _addr_imm,
+		    GLuint _addr_subreg_nr,
+		    GLuint _negate,
+		    GLuint __abs,
+		    GLuint _addr_mode,
+		    GLuint _horiz_stride,
+		    GLuint _width,
+		    GLuint _vert_stride)
+{
+    int err = 0;
+    err |= control (file, "negate", negate, _negate, NULL);
+    err |= control (file, "abs", _abs, __abs, NULL);
+
+    string (file, "g[a0");
+    if (_addr_subreg_nr)
+	format (file, ".%d", _addr_subreg_nr);
+    if (_addr_imm)
+	format (file, " %d", _addr_imm);
+    string (file, "]");
+    src_align1_region (file, _vert_stride, _width, _horiz_stride);
+    err |= control (file, "src reg encoding", reg_encoding, type, NULL);
+    return err;
+}
+
+static int src_da16 (FILE *file,
+		     GLuint _reg_type,
+		     GLuint _reg_file,
+		     GLuint _vert_stride,
+		     GLuint _reg_nr,
+		     GLuint _subreg_nr,
+		     GLuint __abs,
+		     GLuint _negate,
+		     GLuint swz_x,
+		     GLuint swz_y,
+		     GLuint swz_z,
+		     GLuint swz_w)
+{
+    int err = 0;
+    err |= control (file, "negate", negate, _negate, NULL);
+    err |= control (file, "abs", _abs, __abs, NULL);
+
+    err |= reg (file, _reg_file, _reg_nr);
+    if (err == -1)
+	return 0;
+    if (_subreg_nr)
+	format (file, ".%d", _subreg_nr);
+    string (file, "<");
+    err |= control (file, "vert stride", vert_stride, _vert_stride, NULL);
+    string (file, ",1,1>");
+    err |= control (file, "src da16 reg type", reg_encoding, _reg_type, NULL);
+    /*
+     * Three kinds of swizzle display:
+     *  identity - nothing printed
+     *  1->all	 - print the single channel
+     *  1->1     - print the mapping
+     */
+    if (swz_x == BRW_CHANNEL_X &&
+	swz_y == BRW_CHANNEL_Y &&
+	swz_z == BRW_CHANNEL_Z &&
+	swz_w == BRW_CHANNEL_W)
+    {
+	;
+    }
+    else if (swz_x == swz_y && swz_x == swz_z && swz_x == swz_w)
+    {
+	string (file, ".");
+	err |= control (file, "channel select", chan_sel, swz_x, NULL);
+    }
+    else
+    {
+	string (file, ".");
+	err |= control (file, "channel select", chan_sel, swz_x, NULL);
+	err |= control (file, "channel select", chan_sel, swz_y, NULL);
+	err |= control (file, "channel select", chan_sel, swz_z, NULL);
+	err |= control (file, "channel select", chan_sel, swz_w, NULL);
+    }
+    return err;
+}
+
+
+static int imm (FILE *file, GLuint type, const struct brw_instruction *inst) {
+    switch (type) {
+    case BRW_REGISTER_TYPE_UD:
+	format (file, "0x%08xUD", inst->bits3.ud);
+	break;
+    case BRW_REGISTER_TYPE_D:
+	format (file, "%dD", inst->bits3.d);
+	break;
+    case BRW_REGISTER_TYPE_UW:
+	format (file, "0x%04xUW", (uint16_t) inst->bits3.ud);
+	break;
+    case BRW_REGISTER_TYPE_W:
+	format (file, "%dW", (int16_t) inst->bits3.d);
+	break;
+    case BRW_REGISTER_TYPE_UB:
+	format (file, "0x%02xUB", (int8_t) inst->bits3.ud);
+	break;
+    case BRW_REGISTER_TYPE_VF:
+	format (file, "Vector Float");
+	break;
+    case BRW_REGISTER_TYPE_V:
+	format (file, "0x%08xV", inst->bits3.ud);
+	break;
+    case BRW_REGISTER_TYPE_F:
+	format (file, "%-gF", inst->bits3.f);
+    }
+    return 0;
+}
+
+static int src0 (FILE *file, const struct brw_instruction *inst)
+{
+    if (inst->bits1.da1.src0_reg_file == BRW_IMMEDIATE_VALUE)
+	return imm (file, inst->bits1.da1.src0_reg_type,
+		    inst);
+    else if (inst->header.access_mode == BRW_ALIGN_1)
+    {
+	if (inst->bits2.da1.src0_address_mode == BRW_ADDRESS_DIRECT)
+	{
+	    return src_da1 (file,
+			    inst->bits1.da1.src0_reg_type,
+			    inst->bits1.da1.src0_reg_file,
+			    inst->bits2.da1.src0_vert_stride,
+			    inst->bits2.da1.src0_width,
+			    inst->bits2.da1.src0_horiz_stride,
+			    inst->bits2.da1.src0_reg_nr,
+			    inst->bits2.da1.src0_subreg_nr,
+			    inst->bits2.da1.src0_abs,
+			    inst->bits2.da1.src0_negate);
+	}
+	else
+	{
+	    return src_ia1 (file,
+			    inst->bits1.ia1.src0_reg_type,
+			    inst->bits1.ia1.src0_reg_file,
+			    inst->bits2.ia1.src0_indirect_offset,
+			    inst->bits2.ia1.src0_subreg_nr,
+			    inst->bits2.ia1.src0_negate,
+			    inst->bits2.ia1.src0_abs,
+			    inst->bits2.ia1.src0_address_mode,
+			    inst->bits2.ia1.src0_horiz_stride,
+			    inst->bits2.ia1.src0_width,
+			    inst->bits2.ia1.src0_vert_stride);
+	}
+    }
+    else
+    {
+	if (inst->bits2.da16.src0_address_mode == BRW_ADDRESS_DIRECT)
+	{
+	    return src_da16 (file,
+			     inst->bits1.da16.src0_reg_type,
+			     inst->bits1.da16.src0_reg_file,
+			     inst->bits2.da16.src0_vert_stride,
+			     inst->bits2.da16.src0_reg_nr,
+			     inst->bits2.da16.src0_subreg_nr,
+			     inst->bits2.da16.src0_abs,
+			     inst->bits2.da16.src0_negate,
+			     inst->bits2.da16.src0_swz_x,
+			     inst->bits2.da16.src0_swz_y,
+			     inst->bits2.da16.src0_swz_z,
+			     inst->bits2.da16.src0_swz_w);
+	}
+	else
+	{
+	    string (file, "Indirect align16 address mode not supported");
+	    return 1;
+	}
+    }
+}
+
+static int src1 (FILE *file, const struct brw_instruction *inst)
+{
+    if (inst->bits1.da1.src1_reg_file == BRW_IMMEDIATE_VALUE)
+	return imm (file, inst->bits1.da1.src1_reg_type,
+		    inst);
+    else if (inst->header.access_mode == BRW_ALIGN_1)
+    {
+	if (inst->bits3.da1.src1_address_mode == BRW_ADDRESS_DIRECT)
+	{
+	    return src_da1 (file,
+			    inst->bits1.da1.src1_reg_type,
+			    inst->bits1.da1.src1_reg_file,
+			    inst->bits3.da1.src1_vert_stride,
+			    inst->bits3.da1.src1_width,
+			    inst->bits3.da1.src1_horiz_stride,
+			    inst->bits3.da1.src1_reg_nr,
+			    inst->bits3.da1.src1_subreg_nr,
+			    inst->bits3.da1.src1_abs,
+			    inst->bits3.da1.src1_negate);
+	}
+	else
+	{
+	    return src_ia1 (file,
+			    inst->bits1.ia1.src1_reg_type,
+			    inst->bits1.ia1.src1_reg_file,
+			    inst->bits3.ia1.src1_indirect_offset,
+			    inst->bits3.ia1.src1_subreg_nr,
+			    inst->bits3.ia1.src1_negate,
+			    inst->bits3.ia1.src1_abs,
+			    inst->bits3.ia1.src1_address_mode,
+			    inst->bits3.ia1.src1_horiz_stride,
+			    inst->bits3.ia1.src1_width,
+			    inst->bits3.ia1.src1_vert_stride);
+	}
+    }
+    else
+    {
+	if (inst->bits3.da16.src1_address_mode == BRW_ADDRESS_DIRECT)
+	{
+	    return src_da16 (file,
+			     inst->bits1.da16.src1_reg_type,
+			     inst->bits1.da16.src1_reg_file,
+			     inst->bits3.da16.src1_vert_stride,
+			     inst->bits3.da16.src1_reg_nr,
+			     inst->bits3.da16.src1_subreg_nr,
+			     inst->bits3.da16.src1_abs,
+			     inst->bits3.da16.src1_negate,
+			     inst->bits3.da16.src1_swz_x,
+			     inst->bits3.da16.src1_swz_y,
+			     inst->bits3.da16.src1_swz_z,
+			     inst->bits3.da16.src1_swz_w);
+	}
+	else
+	{
+	    string (file, "Indirect align16 address mode not supported");
+	    return 1;
+	}
+    }
+}
+
+int brw_disasm_insn (FILE *file, const struct brw_instruction *inst)
+{
+    int	err = 0;
+    int space = 0;
+
+    if (inst->header.predicate_control) {
+	string (file, "(");
+	err |= control (file, "predicate inverse", pred_inv, inst->header.predicate_inverse, NULL);
+	string (file, "f0");
+	if (inst->bits2.da1.flag_reg_nr)
+	    format (file, ".%d", inst->bits2.da1.flag_reg_nr);
+	if (inst->header.access_mode == BRW_ALIGN_1)
+	    err |= control (file, "predicate control align1", pred_ctrl_align1,
+			    inst->header.predicate_control, NULL);
+	else
+	    err |= control (file, "predicate control align16", pred_ctrl_align16,
+			    inst->header.predicate_control, NULL);
+	string (file, ") ");
+    }
+
+    err |= print_opcode (file, inst->header.opcode);
+    err |= control (file, "saturate", saturate, inst->header.saturate, NULL);
+    err |= control (file, "debug control", debug_ctrl, inst->header.debug_control, NULL);
+
+    if (inst->header.opcode != BRW_OPCODE_SEND)
+	err |= control (file, "conditional modifier", conditional_modifier,
+			inst->header.destreg__conditionalmod, NULL);
+
+    if (inst->header.opcode != BRW_OPCODE_NOP) {
+	string (file, "(");
+	err |= control (file, "execution size", exec_size, inst->header.execution_size, NULL);
+	string (file, ")");
+    }
+
+    if (inst->header.opcode == BRW_OPCODE_SEND)
+	format (file, " %d", inst->header.destreg__conditionalmod);
+
+    if (opcode[inst->header.opcode].ndst > 0) {
+	pad (file, 16);
+	err |= dest (file, inst);
+    }
+    if (opcode[inst->header.opcode].nsrc > 0) {
+	pad (file, 32);
+	err |= src0 (file, inst);
+    }
+    if (opcode[inst->header.opcode].nsrc > 1) {
+	pad (file, 48);
+	err |= src1 (file, inst);
+    }
+
+    if (inst->header.opcode == BRW_OPCODE_SEND) {
+	newline (file);
+	pad (file, 16);
+	space = 0;
+	err |= control (file, "target function", target_function,
+			inst->bits3.generic.msg_target, &space);
+	switch (inst->bits3.generic.msg_target) {
+	case BRW_MESSAGE_TARGET_MATH:
+	    err |= control (file, "math function", math_function,
+			    inst->bits3.math.function, &space);
+	    err |= control (file, "math saturate", math_saturate,
+			    inst->bits3.math.saturate, &space);
+	    err |= control (file, "math signed", math_signed,
+			    inst->bits3.math.int_type, &space);
+	    err |= control (file, "math scalar", math_scalar,
+			    inst->bits3.math.data_type, &space);
+	    err |= control (file, "math precision", math_precision,
+			    inst->bits3.math.precision, &space);
+	    break;
+	case BRW_MESSAGE_TARGET_SAMPLER:
+	    format (file, " (%d, %d, ",
+		    inst->bits3.sampler.binding_table_index,
+		    inst->bits3.sampler.sampler);
+	    err |= control (file, "sampler target format", sampler_target_format,
+			    inst->bits3.sampler.return_format, NULL);
+	    string (file, ")");
+	    break;
+	case BRW_MESSAGE_TARGET_DATAPORT_WRITE:
+	    format (file, " (%d, %d, %d, %d)",
+		    inst->bits3.dp_write.binding_table_index,
+		    (inst->bits3.dp_write.pixel_scoreboard_clear << 3) |
+		    inst->bits3.dp_write.msg_control,
+		    inst->bits3.dp_write.msg_type,
+		    inst->bits3.dp_write.send_commit_msg);
+	    break;
+	case BRW_MESSAGE_TARGET_URB:
+	    format (file, " %d", inst->bits3.urb.offset);
+	    space = 1;
+	    err |= control (file, "urb swizzle", urb_swizzle,
+			    inst->bits3.urb.swizzle_control, &space);
+	    err |= control (file, "urb allocate", urb_allocate,
+			    inst->bits3.urb.allocate, &space);
+	    err |= control (file, "urb used", urb_used,
+			    inst->bits3.urb.used, &space);
+	    err |= control (file, "urb complete", urb_complete,
+			    inst->bits3.urb.complete, &space);
+	    break;
+	case BRW_MESSAGE_TARGET_THREAD_SPAWNER:
+	    break;
+	default:
+	    format (file, "unsupported target %d", inst->bits3.generic.msg_target);
+	    break;
+	}
+	if (space)
+	    string (file, " ");
+	format (file, "mlen %d",
+		inst->bits3.generic.msg_length);
+	format (file, " rlen %d",
+		inst->bits3.generic.response_length);
+    }
+    pad (file, 64);
+    if (inst->header.opcode != BRW_OPCODE_NOP) {
+	string (file, "{");
+	space = 1;
+	err |= control(file, "access mode", access_mode, inst->header.access_mode, &space);
+	err |= control (file, "mask control", mask_ctrl, inst->header.mask_control, &space);
+	err |= control (file, "dependency control", dep_ctrl, inst->header.dependency_control, &space);
+	err |= control (file, "compression control", compr_ctrl, inst->header.compression_control, &space);
+	err |= control (file, "thread control", thread_ctrl, inst->header.thread_control, &space);
+	if (inst->header.opcode == BRW_OPCODE_SEND)
+	    err |= control (file, "end of thread", end_of_thread,
+			    inst->bits3.generic.end_of_thread, &space);
+	if (space)
+	    string (file, " ");
+	string (file, "}");
+    }
+    string (file, ";");
+    newline (file);
+    return err;
+}
+
+
+int brw_disasm (FILE *file, 
+                const struct brw_instruction *inst,
+                unsigned count)
+{
+   int i, err;
+
+   for (i = 0; i < count; i++) {
+      err = brw_disasm_insn(stderr, &inst[i]);
+      if (err)
+         return err;
+   }
+
+   fprintf(file, "\n");
+   return 0;
+}
+
diff --git a/src/gallium/drivers/i965/brw_disasm.h b/src/gallium/drivers/i965/brw_disasm.h
new file mode 100644
index 0000000..ba5b109
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_disasm.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2008 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef BRW_DISASM_H
+#define BRW_DISASM_H
+
+#include <stdio.h>
+
+struct brw_instruction;
+
+int brw_disasm_insn (FILE *file, const struct brw_instruction *inst);
+int brw_disasm (FILE *file, 
+                const struct brw_instruction *inst,
+                unsigned count);
+
+#endif
+
diff --git a/src/gallium/drivers/i965/brw_draw.c b/src/gallium/drivers/i965/brw_draw.c
new file mode 100644
index 0000000..ea8d39a
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_draw.c
@@ -0,0 +1,289 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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.
+ * 
+ **************************************************************************/
+
+
+#include "util/u_prim.h"
+#include "util/u_upload_mgr.h"
+
+#include "brw_draw.h"
+#include "brw_defines.h"
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_debug.h"
+#include "brw_screen.h"
+
+#include "brw_batchbuffer.h"
+
+
+static uint32_t prim_to_hw_prim[PIPE_PRIM_POLYGON+1] = {
+   _3DPRIM_POINTLIST,
+   _3DPRIM_LINELIST,
+   _3DPRIM_LINELOOP,
+   _3DPRIM_LINESTRIP,
+   _3DPRIM_TRILIST,
+   _3DPRIM_TRISTRIP,
+   _3DPRIM_TRIFAN,
+   _3DPRIM_QUADLIST,
+   _3DPRIM_QUADSTRIP,
+   _3DPRIM_POLYGON
+};
+
+
+
+/* When the primitive changes, set a state bit and re-validate.  Not
+ * the nicest and would rather deal with this by having all the
+ * programs be immune to the active primitive (ie. cope with all
+ * possibilities).  That may not be realistic however.
+ */
+static int brw_set_prim(struct brw_context *brw, unsigned prim )
+{
+
+   if (BRW_DEBUG & DEBUG_PRIMS)
+      debug_printf("PRIM: %s\n", u_prim_name(prim));
+   
+   if (prim != brw->primitive) {
+      unsigned reduced_prim;
+
+      brw->primitive = prim;
+      brw->state.dirty.brw |= BRW_NEW_PRIMITIVE;
+
+      reduced_prim = u_reduced_prim(prim);
+      if (reduced_prim != brw->reduced_primitive) {
+	 brw->reduced_primitive = reduced_prim;
+	 brw->state.dirty.brw |= BRW_NEW_REDUCED_PRIMITIVE;
+      }
+   }
+
+   return prim_to_hw_prim[prim];
+}
+
+
+
+static int brw_emit_prim(struct brw_context *brw,
+			 unsigned start,
+			 unsigned count,
+			 boolean indexed,
+			 uint32_t hw_prim)
+{
+   struct brw_3d_primitive prim_packet;
+   int ret;
+
+   if (BRW_DEBUG & DEBUG_PRIMS)
+      debug_printf("%s start %d count %d indexed %d hw_prim %d\n",
+                   __FUNCTION__, start, count, indexed, hw_prim); 
+
+   prim_packet.header.opcode = CMD_3D_PRIM;
+   prim_packet.header.length = sizeof(prim_packet)/4 - 2;
+   prim_packet.header.pad = 0;
+   prim_packet.header.topology = hw_prim;
+   prim_packet.header.indexed = indexed;
+
+   prim_packet.verts_per_instance = count;
+   prim_packet.start_vert_location = start;
+   if (indexed)
+      prim_packet.start_vert_location += brw->ib.start_vertex_offset;
+   prim_packet.instance_count = 1;
+   prim_packet.start_instance_location = 0;
+   prim_packet.base_vert_location = 0; /* prim->basevertex; XXX: add this to gallium */
+
+
+   /* If we're set to always flush, do it before and after the primitive emit.
+    * We want to catch both missed flushes that hurt instruction/state cache
+    * and missed flushes of the render cache as it heads to other parts of
+    * the besides the draw code.
+    */
+   if (0) {
+      BEGIN_BATCH(1, IGNORE_CLIPRECTS);
+      OUT_BATCH((CMD_MI_FLUSH << 16) | BRW_FLUSH_STATE_CACHE);
+      ADVANCE_BATCH();
+   }
+   if (prim_packet.verts_per_instance) {
+      ret = brw_batchbuffer_data( brw->batch, &prim_packet,
+				  sizeof(prim_packet), LOOP_CLIPRECTS);
+      if (ret)
+	 return ret;
+   }
+   if (0) {
+      BEGIN_BATCH(1, IGNORE_CLIPRECTS);
+      OUT_BATCH((CMD_MI_FLUSH << 16) | BRW_FLUSH_STATE_CACHE);
+      ADVANCE_BATCH();
+   }
+
+   return 0;
+}
+
+
+/* May fail if out of video memory for texture or vbo upload, or on
+ * fallback conditions.
+ */
+static int
+try_draw_range_elements(struct brw_context *brw,
+			struct pipe_buffer *index_buffer,
+			unsigned hw_prim, 
+			unsigned start, unsigned count)
+{
+   int ret;
+
+   ret = brw_validate_state(brw);
+   if (ret)
+      return ret;
+
+   /* Check that we can fit our state in with our existing batchbuffer, or
+    * flush otherwise.
+    */
+   ret = brw->sws->check_aperture_space(brw->sws,
+					brw->state.validated_bos,
+					brw->state.validated_bo_count);
+   if (ret)
+      return ret;
+
+   ret = brw_upload_state(brw);
+   if (ret)
+      return ret;
+   
+   ret = brw_emit_prim(brw, start, count, index_buffer != NULL, hw_prim);
+   if (ret)
+      return ret;
+
+   if (brw->flags.always_flush_batch)
+      brw_context_flush( brw );
+
+   return 0;
+}
+
+
+static void
+brw_draw_range_elements(struct pipe_context *pipe,
+			struct pipe_buffer *index_buffer,
+			unsigned index_size,
+			unsigned min_index,
+			unsigned max_index,
+			unsigned mode, unsigned start, unsigned count)
+{
+   struct brw_context *brw = brw_context(pipe);
+   int ret;
+   uint32_t hw_prim;
+
+   hw_prim = brw_set_prim(brw, mode);
+
+   if (BRW_DEBUG & DEBUG_PRIMS)
+      debug_printf("PRIM: %s start %d count %d index_buffer %p\n",
+                   u_prim_name(mode), start, count, (void *)index_buffer);
+
+   /* Potentially trigger upload of new index buffer.
+    *
+    * XXX: do we need to go through state validation to achieve this?
+    * Could just call upload code directly.
+    */
+   if (brw->curr.index_buffer != index_buffer ||
+       brw->curr.index_size != index_size) {
+      pipe_buffer_reference( &brw->curr.index_buffer, index_buffer );
+      brw->curr.index_size = index_size;
+      brw->state.dirty.mesa |= PIPE_NEW_INDEX_BUFFER;
+   }
+
+   /* XXX: do we really care?
+    */
+   if (brw->curr.min_index != min_index ||
+       brw->curr.max_index != max_index) 
+   { 
+      brw->curr.min_index = min_index;
+      brw->curr.max_index = max_index;
+      brw->state.dirty.mesa |= PIPE_NEW_INDEX_RANGE;
+   }
+
+
+   /* Make a first attempt at drawing:
+    */
+   ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count );
+
+   /* Otherwise, flush and retry:
+    */
+   if (ret != 0) {
+      brw_context_flush( brw );
+      ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count );
+      assert(ret == 0);
+   }
+}
+
+static void
+brw_draw_elements(struct pipe_context *pipe,
+		  struct pipe_buffer *index_buffer,
+		  unsigned index_size,
+		  unsigned mode, 
+		  unsigned start, unsigned count)
+{
+   brw_draw_range_elements( pipe, index_buffer,
+                            index_size,
+                            0, 0xffffffff,
+                            mode, 
+                            start, count );
+}
+
+static void
+brw_draw_arrays(struct pipe_context *pipe, unsigned mode,
+                     unsigned start, unsigned count)
+{
+   brw_draw_elements(pipe, NULL, 0, mode, start, count);
+}
+
+
+
+boolean brw_draw_init( struct brw_context *brw )
+{
+   /* Register our drawing function: 
+    */
+   brw->base.draw_arrays = brw_draw_arrays;
+   brw->base.draw_elements = brw_draw_elements;
+   brw->base.draw_range_elements = brw_draw_range_elements;
+
+   /* Create helpers for uploading data in user buffers:
+    */
+   brw->vb.upload_vertex = u_upload_create( brw->base.screen,
+					    128 * 1024,
+					    64,
+					    PIPE_BUFFER_USAGE_VERTEX );
+   if (brw->vb.upload_vertex == NULL)
+      return FALSE;
+
+   brw->vb.upload_index = u_upload_create( brw->base.screen,
+					   32 * 1024,
+					   64,
+					   PIPE_BUFFER_USAGE_INDEX );
+   if (brw->vb.upload_index == NULL)
+      return FALSE;
+
+   return TRUE;
+}
+
+void brw_draw_cleanup( struct brw_context *brw )
+{
+   u_upload_destroy( brw->vb.upload_vertex );
+   u_upload_destroy( brw->vb.upload_index );
+
+   bo_reference(&brw->ib.bo, NULL);
+}
diff --git a/src/mesa/state_tracker/st_cb_get.h b/src/gallium/drivers/i965/brw_draw.h
similarity index 78%
copy from src/mesa/state_tracker/st_cb_get.h
copy to src/gallium/drivers/i965/brw_draw.h
index 8e9f3e9..8dc5dbc 100644
--- a/src/mesa/state_tracker/st_cb_get.h
+++ b/src/gallium/drivers/i965/brw_draw.h
@@ -1,6 +1,6 @@
-/**************************************************************************
+ /**************************************************************************
  * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -25,13 +25,15 @@
  * 
  **************************************************************************/
 
+#ifndef BRW_DRAW_H
+#define BRW_DRAW_H
 
-#ifndef ST_CB_GET_H
-#define ST_CB_GET_H
+#include "brw_types.h"
 
+struct brw_context;
 
-extern void
-st_init_get_functions(struct dd_function_table *functions);
+boolean brw_draw_init( struct brw_context *brw );
+void brw_draw_cleanup( struct brw_context *brw );
 
 
 #endif
diff --git a/src/gallium/drivers/i965/brw_draw_upload.c b/src/gallium/drivers/i965/brw_draw_upload.c
new file mode 100644
index 0000000..a27da5f
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_draw_upload.c
@@ -0,0 +1,542 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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.
+ * 
+ **************************************************************************/
+
+#include "pipe/p_context.h"
+
+#include "util/u_upload_mgr.h"
+#include "util/u_math.h"
+
+#include "brw_draw.h"
+#include "brw_defines.h"
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_screen.h"
+#include "brw_batchbuffer.h"
+#include "brw_debug.h"
+
+
+
+
+static unsigned brw_translate_surface_format( unsigned id )
+{
+   switch (id) {
+   case PIPE_FORMAT_R64_FLOAT:
+      return BRW_SURFACEFORMAT_R64_FLOAT;
+   case PIPE_FORMAT_R64G64_FLOAT:
+      return BRW_SURFACEFORMAT_R64G64_FLOAT;
+   case PIPE_FORMAT_R64G64B64_FLOAT:
+      return BRW_SURFACEFORMAT_R64G64B64_FLOAT;
+   case PIPE_FORMAT_R64G64B64A64_FLOAT:
+      return BRW_SURFACEFORMAT_R64G64B64A64_FLOAT;
+
+   case PIPE_FORMAT_R32_FLOAT:
+      return BRW_SURFACEFORMAT_R32_FLOAT;
+   case PIPE_FORMAT_R32G32_FLOAT:
+      return BRW_SURFACEFORMAT_R32G32_FLOAT;
+   case PIPE_FORMAT_R32G32B32_FLOAT:
+      return BRW_SURFACEFORMAT_R32G32B32_FLOAT;
+   case PIPE_FORMAT_R32G32B32A32_FLOAT:
+      return BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
+
+   case PIPE_FORMAT_R32_UNORM:
+      return BRW_SURFACEFORMAT_R32_UNORM;
+   case PIPE_FORMAT_R32G32_UNORM:
+      return BRW_SURFACEFORMAT_R32G32_UNORM;
+   case PIPE_FORMAT_R32G32B32_UNORM:
+      return BRW_SURFACEFORMAT_R32G32B32_UNORM;
+   case PIPE_FORMAT_R32G32B32A32_UNORM:
+      return BRW_SURFACEFORMAT_R32G32B32A32_UNORM;
+
+   case PIPE_FORMAT_R32_USCALED:
+      return BRW_SURFACEFORMAT_R32_USCALED;
+   case PIPE_FORMAT_R32G32_USCALED:
+      return BRW_SURFACEFORMAT_R32G32_USCALED;
+   case PIPE_FORMAT_R32G32B32_USCALED:
+      return BRW_SURFACEFORMAT_R32G32B32_USCALED;
+   case PIPE_FORMAT_R32G32B32A32_USCALED:
+      return BRW_SURFACEFORMAT_R32G32B32A32_USCALED;
+
+   case PIPE_FORMAT_R32_SNORM:
+      return BRW_SURFACEFORMAT_R32_SNORM;
+   case PIPE_FORMAT_R32G32_SNORM:
+      return BRW_SURFACEFORMAT_R32G32_SNORM;
+   case PIPE_FORMAT_R32G32B32_SNORM:
+      return BRW_SURFACEFORMAT_R32G32B32_SNORM;
+   case PIPE_FORMAT_R32G32B32A32_SNORM:
+      return BRW_SURFACEFORMAT_R32G32B32A32_SNORM;
+
+   case PIPE_FORMAT_R32_SSCALED:
+      return BRW_SURFACEFORMAT_R32_SSCALED;
+   case PIPE_FORMAT_R32G32_SSCALED:
+      return BRW_SURFACEFORMAT_R32G32_SSCALED;
+   case PIPE_FORMAT_R32G32B32_SSCALED:
+      return BRW_SURFACEFORMAT_R32G32B32_SSCALED;
+   case PIPE_FORMAT_R32G32B32A32_SSCALED:
+      return BRW_SURFACEFORMAT_R32G32B32A32_SSCALED;
+
+   case PIPE_FORMAT_R16_UNORM:
+      return BRW_SURFACEFORMAT_R16_UNORM;
+   case PIPE_FORMAT_R16G16_UNORM:
+      return BRW_SURFACEFORMAT_R16G16_UNORM;
+   case PIPE_FORMAT_R16G16B16_UNORM:
+      return BRW_SURFACEFORMAT_R16G16B16_UNORM;
+   case PIPE_FORMAT_R16G16B16A16_UNORM:
+      return BRW_SURFACEFORMAT_R16G16B16A16_UNORM;
+
+   case PIPE_FORMAT_R16_USCALED:
+      return BRW_SURFACEFORMAT_R16_USCALED;
+   case PIPE_FORMAT_R16G16_USCALED:
+      return BRW_SURFACEFORMAT_R16G16_USCALED;
+   case PIPE_FORMAT_R16G16B16_USCALED:
+      return BRW_SURFACEFORMAT_R16G16B16_USCALED;
+   case PIPE_FORMAT_R16G16B16A16_USCALED:
+      return BRW_SURFACEFORMAT_R16G16B16A16_USCALED;
+
+   case PIPE_FORMAT_R16_SNORM:
+      return BRW_SURFACEFORMAT_R16_SNORM;
+   case PIPE_FORMAT_R16G16_SNORM:
+      return BRW_SURFACEFORMAT_R16G16_SNORM;
+   case PIPE_FORMAT_R16G16B16_SNORM:
+      return BRW_SURFACEFORMAT_R16G16B16_SNORM;
+   case PIPE_FORMAT_R16G16B16A16_SNORM:
+      return BRW_SURFACEFORMAT_R16G16B16A16_SNORM;
+
+   case PIPE_FORMAT_R16_SSCALED:
+      return BRW_SURFACEFORMAT_R16_SSCALED;
+   case PIPE_FORMAT_R16G16_SSCALED:
+      return BRW_SURFACEFORMAT_R16G16_SSCALED;
+   case PIPE_FORMAT_R16G16B16_SSCALED:
+      return BRW_SURFACEFORMAT_R16G16B16_SSCALED;
+   case PIPE_FORMAT_R16G16B16A16_SSCALED:
+      return BRW_SURFACEFORMAT_R16G16B16A16_SSCALED;
+
+   case PIPE_FORMAT_R8_UNORM:
+      return BRW_SURFACEFORMAT_R8_UNORM;
+   case PIPE_FORMAT_R8G8_UNORM:
+      return BRW_SURFACEFORMAT_R8G8_UNORM;
+   case PIPE_FORMAT_R8G8B8_UNORM:
+      return BRW_SURFACEFORMAT_R8G8B8_UNORM;
+   case PIPE_FORMAT_R8G8B8A8_UNORM:
+      return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
+
+   case PIPE_FORMAT_R8_USCALED:
+      return BRW_SURFACEFORMAT_R8_USCALED;
+   case PIPE_FORMAT_R8G8_USCALED:
+      return BRW_SURFACEFORMAT_R8G8_USCALED;
+   case PIPE_FORMAT_R8G8B8_USCALED:
+      return BRW_SURFACEFORMAT_R8G8B8_USCALED;
+   case PIPE_FORMAT_R8G8B8A8_USCALED:
+      return BRW_SURFACEFORMAT_R8G8B8A8_USCALED;
+
+   case PIPE_FORMAT_R8_SNORM:
+      return BRW_SURFACEFORMAT_R8_SNORM;
+   case PIPE_FORMAT_R8G8_SNORM:
+      return BRW_SURFACEFORMAT_R8G8_SNORM;
+   case PIPE_FORMAT_R8G8B8_SNORM:
+      return BRW_SURFACEFORMAT_R8G8B8_SNORM;
+   case PIPE_FORMAT_R8G8B8A8_SNORM:
+      return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
+
+   case PIPE_FORMAT_R8_SSCALED:
+      return BRW_SURFACEFORMAT_R8_SSCALED;
+   case PIPE_FORMAT_R8G8_SSCALED:
+      return BRW_SURFACEFORMAT_R8G8_SSCALED;
+   case PIPE_FORMAT_R8G8B8_SSCALED:
+      return BRW_SURFACEFORMAT_R8G8B8_SSCALED;
+   case PIPE_FORMAT_R8G8B8A8_SSCALED:
+      return BRW_SURFACEFORMAT_R8G8B8A8_SSCALED;
+
+   default:
+      assert(0);
+      return 0;
+   }
+}
+
+static unsigned get_index_type(int type)
+{
+   switch (type) {
+   case 1: return BRW_INDEX_BYTE;
+   case 2: return BRW_INDEX_WORD;
+   case 4: return BRW_INDEX_DWORD;
+   default: assert(0); return 0;
+   }
+}
+
+
+static int brw_prepare_vertices(struct brw_context *brw)
+{
+   unsigned int min_index = brw->curr.min_index;
+   unsigned int max_index = brw->curr.max_index;
+   GLuint i;
+   int ret;
+
+   if (BRW_DEBUG & DEBUG_VERTS)
+      debug_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
+
+
+   for (i = 0; i < brw->curr.num_vertex_buffers; i++) {
+      struct pipe_vertex_buffer *vb = &brw->curr.vertex_buffer[i];
+      struct brw_winsys_buffer *bo;
+      struct pipe_buffer *upload_buf = NULL;
+      unsigned offset;
+      
+      if (BRW_DEBUG & DEBUG_VERTS)
+	 debug_printf("%s vb[%d] user:%d offset:0x%x sz:0x%x stride:0x%x\n",
+		      __FUNCTION__, i,
+		      brw_buffer_is_user_buffer(vb->buffer),
+		      vb->buffer_offset,
+		      vb->buffer->size,
+		      vb->stride);
+
+      if (brw_buffer_is_user_buffer(vb->buffer)) {
+
+	 /* XXX: simplify this.  Stop the state trackers from generating
+	  * zero-stride buffers & have them use additional constants (or
+	  * add support for >1 constant buffer) instead.
+	  */
+	 unsigned size = (vb->stride == 0 ? 
+			  vb->buffer->size - vb->buffer_offset :
+			  MAX2(vb->buffer->size - vb->buffer_offset,
+			       vb->stride * (max_index + 1 - min_index)));
+
+	 ret = u_upload_buffer( brw->vb.upload_vertex, 
+				vb->buffer_offset + min_index * vb->stride,
+				size,
+				vb->buffer,
+				&offset,
+				&upload_buf );
+	 if (ret)
+	    return ret;
+
+	 bo = brw_buffer(upload_buf)->bo;
+	 
+	 assert(offset + size <= bo->size);
+      }
+      else
+      {
+	 offset = vb->buffer_offset;
+	 bo = brw_buffer(vb->buffer)->bo;
+      }
+
+      assert(offset < bo->size);
+      
+      /* Set up post-upload info about this vertex buffer:
+       */
+      brw->vb.vb[i].offset = offset;
+      brw->vb.vb[i].stride = vb->stride;
+      brw->vb.vb[i].vertex_count = (vb->stride == 0 ?
+				    1 :
+				    (bo->size - offset) / vb->stride);
+
+      bo_reference( &brw->vb.vb[i].bo,  bo );
+
+      /* Don't need to retain this reference.  We have a reference on
+       * the underlying winsys buffer:
+       */
+      pipe_buffer_reference( &upload_buf, NULL );
+   }
+
+   brw->vb.nr_vb = i;
+   brw_prepare_query_begin(brw);
+
+   for (i = 0; i < brw->vb.nr_vb; i++) {
+      brw_add_validated_bo(brw, brw->vb.vb[i].bo);
+   }
+
+   return 0;
+}
+
+static int brw_emit_vertex_buffers( struct brw_context *brw )
+{
+   int i;
+
+   /* If the VS doesn't read any inputs (calculating vertex position from
+    * a state variable for some reason, for example), just bail.
+    *
+    * The stale VB state stays in place, but they don't do anything unless
+    * a VE loads from them.
+    */
+   if (brw->vb.nr_vb == 0) {
+      if (BRW_DEBUG & DEBUG_VERTS)
+	 debug_printf("%s: no active vertex buffers\n", __FUNCTION__);
+
+      return 0;
+   }
+
+   /* Emit VB state packets.
+    */
+   BEGIN_BATCH(1 + brw->vb.nr_vb * 4, IGNORE_CLIPRECTS);
+   OUT_BATCH((CMD_VERTEX_BUFFER << 16) |
+	     ((1 + brw->vb.nr_vb * 4) - 2));
+
+   for (i = 0; i < brw->vb.nr_vb; i++) {
+      OUT_BATCH((i << BRW_VB0_INDEX_SHIFT) |
+		BRW_VB0_ACCESS_VERTEXDATA |
+		(brw->vb.vb[i].stride << BRW_VB0_PITCH_SHIFT));
+      OUT_RELOC(brw->vb.vb[i].bo,
+		BRW_USAGE_VERTEX,
+		brw->vb.vb[i].offset);
+      if (BRW_IS_IGDNG(brw)) {
+	 OUT_RELOC(brw->vb.vb[i].bo,
+		   BRW_USAGE_VERTEX,
+		   brw->vb.vb[i].bo->size - 1);
+      } else
+	 OUT_BATCH(brw->vb.vb[i].stride ? brw->vb.vb[i].vertex_count : 0);
+      OUT_BATCH(0); /* Instance data step rate */
+   }
+   ADVANCE_BATCH();
+   return 0;
+}
+
+
+
+
+static int brw_emit_vertex_elements(struct brw_context *brw)
+{
+   GLuint nr = brw->curr.num_vertex_elements;
+   GLuint i;
+
+   brw_emit_query_begin(brw);
+
+   /* If the VS doesn't read any inputs (calculating vertex position from
+    * a state variable for some reason, for example), emit a single pad
+    * VERTEX_ELEMENT struct and bail.
+    *
+    * The stale VB state stays in place, but they don't do anything unless
+    * a VE loads from them.
+    */
+   if (nr == 0) {
+      BEGIN_BATCH(3, IGNORE_CLIPRECTS);
+      OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | 1);
+      OUT_BATCH((0 << BRW_VE0_INDEX_SHIFT) |
+		BRW_VE0_VALID |
+		(BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_VE0_FORMAT_SHIFT) |
+		(0 << BRW_VE0_SRC_OFFSET_SHIFT));
+      OUT_BATCH((BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_0_SHIFT) |
+		(BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) |
+		(BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
+		(BRW_VE1_COMPONENT_STORE_1_FLT << BRW_VE1_COMPONENT_3_SHIFT));
+      ADVANCE_BATCH();
+      return 0;
+   }
+
+   /* Now emit vertex element (VEP) state packets.
+    *
+    */
+   BEGIN_BATCH(1 + nr * 2, IGNORE_CLIPRECTS);
+   OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | ((1 + nr * 2) - 2));
+   for (i = 0; i < nr; i++) {
+      const struct pipe_vertex_element *input = &brw->curr.vertex_element[i];
+      uint32_t format = brw_translate_surface_format( input->src_format );
+      uint32_t comp0 = BRW_VE1_COMPONENT_STORE_SRC;
+      uint32_t comp1 = BRW_VE1_COMPONENT_STORE_SRC;
+      uint32_t comp2 = BRW_VE1_COMPONENT_STORE_SRC;
+      uint32_t comp3 = BRW_VE1_COMPONENT_STORE_SRC;
+
+      switch (input->nr_components) {
+      case 0: comp0 = BRW_VE1_COMPONENT_STORE_0;
+      case 1: comp1 = BRW_VE1_COMPONENT_STORE_0;
+      case 2: comp2 = BRW_VE1_COMPONENT_STORE_0;
+      case 3: comp3 = BRW_VE1_COMPONENT_STORE_1_FLT;
+	 break;
+      }
+
+      OUT_BATCH((input->vertex_buffer_index << BRW_VE0_INDEX_SHIFT) |
+		BRW_VE0_VALID |
+		(format << BRW_VE0_FORMAT_SHIFT) |
+		(input->src_offset << BRW_VE0_SRC_OFFSET_SHIFT));
+
+      if (BRW_IS_IGDNG(brw))
+          OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
+                    (comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
+                    (comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
+                    (comp3 << BRW_VE1_COMPONENT_3_SHIFT));
+      else
+          OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
+                    (comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
+                    (comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
+                    (comp3 << BRW_VE1_COMPONENT_3_SHIFT) |
+                    ((i * 4) << BRW_VE1_DST_OFFSET_SHIFT));
+   }
+   ADVANCE_BATCH();
+   return 0;
+}
+
+
+static int brw_emit_vertices( struct brw_context *brw )
+{
+   int ret;
+
+   ret = brw_emit_vertex_buffers( brw );
+   if (ret)
+      return ret;
+
+   ret = brw_emit_vertex_elements( brw );
+   if (ret)
+      return ret;
+   
+   return 0;
+}
+
+
+const struct brw_tracked_state brw_vertices = {
+   .dirty = {
+      .mesa = (PIPE_NEW_INDEX_RANGE |
+               PIPE_NEW_VERTEX_BUFFER),
+      .brw = BRW_NEW_BATCH,
+      .cache = 0,
+   },
+   .prepare = brw_prepare_vertices,
+   .emit = brw_emit_vertices,
+};
+
+
+static int brw_prepare_indices(struct brw_context *brw)
+{
+   struct pipe_buffer *index_buffer = brw->curr.index_buffer;
+   struct pipe_buffer *upload_buf = NULL;
+   struct brw_winsys_buffer *bo = NULL;
+   GLuint offset;
+   GLuint index_size;
+   GLuint ib_size;
+   int ret;
+
+   if (index_buffer == NULL)
+      return 0;
+
+   if (BRW_DEBUG & DEBUG_VERTS)
+      debug_printf("%s: index_size:%d index_buffer->size:%d\n",
+		   __FUNCTION__,
+		   brw->curr.index_size,
+		   brw->curr.index_buffer->size);
+
+   ib_size = index_buffer->size;
+   index_size = brw->curr.index_size;
+
+   /* Turn userbuffer into a proper hardware buffer?
+    */
+   if (brw_buffer_is_user_buffer(index_buffer)) {
+
+      ret = u_upload_buffer( brw->vb.upload_index,
+			     0,
+			     ib_size,
+			     index_buffer,
+			     &offset,
+			     &upload_buf );
+      if (ret)
+	 return ret;
+
+      bo = brw_buffer(upload_buf)->bo;
+
+      /* XXX: annotate the userbuffer with the upload information so
+       * that successive calls don't get re-uploaded.
+       */
+   }
+   else {
+      bo = brw_buffer(index_buffer)->bo;
+      ib_size = bo->size;
+      offset = 0;
+   }
+
+   /* Use CMD_3D_PRIM's start_vertex_offset to avoid re-uploading the
+    * index buffer state when we're just moving the start index of our
+    * drawing.
+    *
+    * In gallium this will happen in the case where successive draw
+    * calls are made with (distinct?) userbuffers, but the upload_mgr
+    * places the data into a single winsys buffer.
+    * 
+    * This statechange doesn't raise any state flags and is always
+    * just merged into the final draw packet:
+    */
+   if (1) {
+      assert((offset & (index_size - 1)) == 0);
+      brw->ib.start_vertex_offset = offset / index_size;
+   }
+
+   /* These statechanges trigger a new CMD_INDEX_BUFFER packet:
+    */
+   if (brw->ib.bo != bo ||
+       brw->ib.size != ib_size)
+   {
+      bo_reference(&brw->ib.bo, bo);
+      brw->ib.size = ib_size;
+      brw->state.dirty.brw |= BRW_NEW_INDEX_BUFFER;
+   }
+
+   pipe_buffer_reference( &upload_buf, NULL );
+   brw_add_validated_bo(brw, brw->ib.bo);
+   return 0;
+}
+
+const struct brw_tracked_state brw_indices = {
+   .dirty = {
+      .mesa = PIPE_NEW_INDEX_BUFFER,
+      .brw = 0,
+      .cache = 0,
+   },
+   .prepare = brw_prepare_indices,
+};
+
+static int brw_emit_index_buffer(struct brw_context *brw)
+{
+   /* Emit the indexbuffer packet:
+    */
+   if (brw->ib.bo)
+   {
+      struct brw_indexbuffer ib;
+
+      memset(&ib, 0, sizeof(ib));
+
+      ib.header.bits.opcode = CMD_INDEX_BUFFER;
+      ib.header.bits.length = sizeof(ib)/4 - 2;
+      ib.header.bits.index_format = get_index_type(brw->ib.size);
+      ib.header.bits.cut_index_enable = 0;
+
+      BEGIN_BATCH(4, IGNORE_CLIPRECTS);
+      OUT_BATCH( ib.header.dword );
+      OUT_RELOC(brw->ib.bo,
+		BRW_USAGE_VERTEX,
+		brw->ib.offset);
+      OUT_RELOC(brw->ib.bo,
+		BRW_USAGE_VERTEX,
+		brw->ib.offset + brw->ib.size - 1);
+      OUT_BATCH( 0 );
+      ADVANCE_BATCH();
+   }
+
+   return 0;
+}
+
+const struct brw_tracked_state brw_index_buffer = {
+   .dirty = {
+      .mesa = 0,
+      .brw = BRW_NEW_BATCH | BRW_NEW_INDEX_BUFFER,
+      .cache = 0,
+   },
+   .emit = brw_emit_index_buffer,
+};
diff --git a/src/gallium/drivers/i965/brw_eu.c b/src/gallium/drivers/i965/brw_eu.c
new file mode 100644
index 0000000..a8fcb5f
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_eu.c
@@ -0,0 +1,262 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+  
+#include "util/u_memory.h"
+
+#include "brw_context.h"
+#include "brw_defines.h"
+#include "brw_eu.h"
+
+
+
+/* How does predicate control work when execution_size != 8?  Do I
+ * need to test/set for 0xffff when execution_size is 16?
+ */
+void brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value )
+{
+   p->current->header.predicate_control = BRW_PREDICATE_NONE;
+
+   if (value != 0xff) {
+      if (value != p->flag_value) {
+	 brw_push_insn_state(p);
+	 brw_MOV(p, brw_flag_reg(), brw_imm_uw(value));
+	 p->flag_value = value;
+	 brw_pop_insn_state(p);
+      }
+
+      p->current->header.predicate_control = BRW_PREDICATE_NORMAL;
+   }   
+}
+
+void brw_set_predicate_control( struct brw_compile *p, GLuint pc )
+{
+   p->current->header.predicate_control = pc;
+}
+
+void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional )
+{
+   p->current->header.destreg__conditionalmod = conditional;
+}
+
+void brw_set_access_mode( struct brw_compile *p, GLuint access_mode )
+{
+   p->current->header.access_mode = access_mode;
+}
+
+void brw_set_compression_control( struct brw_compile *p, GLboolean compression_control )
+{
+   p->current->header.compression_control = compression_control;
+}
+
+void brw_set_mask_control( struct brw_compile *p, GLuint value )
+{
+   p->current->header.mask_control = value;
+}
+
+void brw_set_saturate( struct brw_compile *p, GLuint value )
+{
+   p->current->header.saturate = value;
+}
+
+void brw_push_insn_state( struct brw_compile *p )
+{
+   assert(p->current != &p->stack[BRW_EU_MAX_INSN_STACK-1]);
+   memcpy(p->current+1, p->current, sizeof(struct brw_instruction));
+   p->current++;   
+}
+
+void brw_pop_insn_state( struct brw_compile *p )
+{
+   assert(p->current != p->stack);
+   p->current--;
+}
+
+
+/***********************************************************************
+ */
+void brw_init_compile( struct brw_context *brw, struct brw_compile *p )
+{
+   p->brw = brw;
+   p->nr_insn = 0;
+   p->current = p->stack;
+   memset(p->current, 0, sizeof(p->current[0]));
+
+   /* Some defaults?
+    */
+   brw_set_mask_control(p, BRW_MASK_ENABLE); /* what does this do? */
+   brw_set_saturate(p, 0);
+   brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+   brw_set_predicate_control_flag_value(p, 0xff); 
+}
+
+
+enum pipe_error brw_get_program( struct brw_compile *p,
+                                 const GLuint **data,
+                                 GLuint *sz )
+{
+   GLuint i;
+
+   for (i = 0; i < 8; i++)
+      brw_NOP(p);
+
+   /* Is the generated program malformed for some reason?
+    */
+   if (p->error)
+      return PIPE_ERROR_BAD_INPUT;
+
+   *sz = p->nr_insn * sizeof(struct brw_instruction);
+   *data = (const GLuint *)p->store;
+   return PIPE_OK;
+}
+
+
+
+/**
+ * Subroutine calls require special attention.
+ * Mesa instructions may be expanded into multiple hardware instructions
+ * so the prog_instruction::BranchTarget field can't be used as an index
+ * into the hardware instructions.
+ *
+ * The BranchTarget field isn't needed, however.  Mesa's GLSL compiler
+ * emits CAL and BGNSUB instructions with labels that can be used to map
+ * subroutine calls to actual subroutine code blocks.
+ *
+ * The structures and function here implement patching of CAL instructions
+ * so they jump to the right subroutine code...
+ */
+
+
+/**
+ * For each OPCODE_BGNSUB we create one of these.
+ */
+struct brw_eu_label
+{
+   GLuint label;     /**< the label number */
+   GLuint position;  /**< the position of the brw instruction for this label */
+   struct brw_eu_label *next;  /**< next in linked list */
+};
+
+
+/**
+ * For each OPCODE_CAL we create one of these.
+ */
+struct brw_eu_call
+{
+   GLuint call_inst_pos;  /**< location of the CAL instruction */
+   GLuint label;
+   struct brw_eu_call *next;  /**< next in linked list */
+};
+
+
+/**
+ * Called for each OPCODE_BGNSUB.
+ */
+void
+brw_save_label(struct brw_compile *c, unsigned l, GLuint position)
+{
+   struct brw_eu_label *label = CALLOC_STRUCT(brw_eu_label);
+   label->label = l;
+   label->position = position;
+   label->next = c->first_label;
+   c->first_label = label;
+}
+
+
+/**
+ * Called for each OPCODE_CAL.
+ */
+void
+brw_save_call(struct brw_compile *c, GLuint label, GLuint call_pos)
+{
+   struct brw_eu_call *call = CALLOC_STRUCT(brw_eu_call);
+   call->call_inst_pos = call_pos;
+   call->label = label;
+   call->next = c->first_call;
+   c->first_call = call;
+}
+
+
+/**
+ * Lookup a label, return label's position/offset.
+ */
+static GLuint
+brw_lookup_label(struct brw_compile *c, unsigned l)
+{
+   const struct brw_eu_label *label;
+   for (label = c->first_label; label; label = label->next) {
+      if (l == label->label) {
+         return label->position;
+      }
+   }
+   abort();  /* should never happen */
+   return ~0;
+}
+
+
+/**
+ * When we're done generating code, this function is called to resolve
+ * subroutine calls.
+ */
+void
+brw_resolve_cals(struct brw_compile *c)
+{
+    const struct brw_eu_call *call;
+
+    for (call = c->first_call; call; call = call->next) {
+        const GLuint sub_loc = brw_lookup_label(c, call->label);
+	struct brw_instruction *brw_call_inst = &c->store[call->call_inst_pos];
+	struct brw_instruction *brw_sub_inst = &c->store[sub_loc];
+	GLint offset = brw_sub_inst - brw_call_inst;
+
+	/* patch brw_inst1 to point to brw_inst2 */
+	brw_set_src1(brw_call_inst, brw_imm_d(offset * 16));
+    }
+
+    /* free linked list of calls */
+    {
+        struct brw_eu_call *call, *next;
+        for (call = c->first_call; call; call = next) {
+	    next = call->next;
+	    FREE(call);
+	}
+	c->first_call = NULL;
+    }
+
+    /* free linked list of labels */
+    {
+        struct brw_eu_label *label, *next;
+	for (label = c->first_label; label; label = next) {
+	    next = label->next;
+	    FREE(label);
+	}
+	c->first_label = NULL;
+    }
+}
diff --git a/src/gallium/drivers/i965/brw_eu.h b/src/gallium/drivers/i965/brw_eu.h
new file mode 100644
index 0000000..af509b2
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_eu.h
@@ -0,0 +1,992 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+   
+
+#ifndef BRW_EU_H
+#define BRW_EU_H
+
+#include "util/u_debug.h"
+#include "pipe/p_defines.h"
+
+#include "brw_structs.h"
+#include "brw_defines.h"
+
+#define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
+#define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
+
+#define BRW_SWIZZLE_NOOP      BRW_SWIZZLE4(0,1,2,3)
+#define BRW_SWIZZLE_XYZW      BRW_SWIZZLE4(0,1,2,3)
+#define BRW_SWIZZLE_XXXX      BRW_SWIZZLE4(0,0,0,0)
+#define BRW_SWIZZLE_XYXY      BRW_SWIZZLE4(0,1,0,1)
+
+#define BRW_WRITEMASK_NONE     0x00
+#define BRW_WRITEMASK_X        0x01
+#define BRW_WRITEMASK_Y        0x02
+#define BRW_WRITEMASK_XY       0x03
+#define BRW_WRITEMASK_Z        0x04
+#define BRW_WRITEMASK_XZ       0x05
+#define BRW_WRITEMASK_YZ       0x06
+#define BRW_WRITEMASK_XYZ      0x07
+#define BRW_WRITEMASK_W        0x08
+#define BRW_WRITEMASK_XW       0x09
+#define BRW_WRITEMASK_YW       0x0A
+#define BRW_WRITEMASK_XYW      0x0B
+#define BRW_WRITEMASK_ZW       0x0C
+#define BRW_WRITEMASK_XZW      0x0D
+#define BRW_WRITEMASK_YZW      0x0E
+#define BRW_WRITEMASK_XYZW     0x0F
+
+
+#define REG_SIZE (8*4)
+
+
+/* These aren't hardware structs, just something useful for us to pass around:
+ *
+ * Align1 operation has a lot of control over input ranges.  Used in
+ * WM programs to implement shaders decomposed into "channel serial"
+ * or "structure of array" form:
+ */
+struct brw_reg
+{
+   GLuint type:4;
+   GLuint file:2;
+   GLuint nr:8;
+   GLuint subnr:5;		/* :1 in align16 */
+   GLuint negate:1;		/* source only */
+   GLuint abs:1;		/* source only */
+   GLuint vstride:4;		/* source only */
+   GLuint width:3;		/* src only, align1 only */
+   GLuint hstride:2;   		/* align1 only */
+   GLuint address_mode:1;	/* relative addressing, hopefully! */
+   GLuint pad0:1;
+
+   union {      
+      struct {
+	 GLuint swizzle:8;		/* src only, align16 only */
+	 GLuint writemask:4;		/* dest only, align16 only */
+	 GLint  indirect_offset:10;	/* relative addressing offset */
+	 GLuint pad1:10;		/* two dwords total */
+      } bits;
+
+      GLfloat f;
+      GLint   d;
+      GLuint ud;
+   } dw1;      
+};
+
+
+struct brw_indirect {
+   GLuint addr_subnr:4;
+   GLint addr_offset:10;
+   GLuint pad:18;
+};
+
+
+struct brw_eu_label;
+struct brw_eu_call;
+
+
+
+#define BRW_EU_MAX_INSN_STACK 5
+#define BRW_EU_MAX_INSN 10000
+
+struct brw_compile {
+   struct brw_instruction store[BRW_EU_MAX_INSN];
+   GLuint nr_insn;
+
+   /* Allow clients to push/pop instruction state:
+    */
+   struct brw_instruction stack[BRW_EU_MAX_INSN_STACK];
+   struct brw_instruction *current;
+
+   GLuint flag_value;
+   GLboolean single_program_flow;
+   struct brw_context *brw;
+
+   struct brw_eu_label *first_label;  /**< linked list of labels */
+   struct brw_eu_call *first_call;    /**< linked list of CALs */
+
+   boolean error;
+};
+
+
+void
+brw_save_label(struct brw_compile *c, unsigned label, GLuint position);
+
+void
+brw_save_call(struct brw_compile *c, unsigned label, GLuint call_pos);
+
+void
+brw_resolve_cals(struct brw_compile *c);
+
+
+
+static INLINE int type_sz( GLuint type )
+{
+   switch( type ) {
+   case BRW_REGISTER_TYPE_UD:
+   case BRW_REGISTER_TYPE_D:
+   case BRW_REGISTER_TYPE_F:
+      return 4;
+   case BRW_REGISTER_TYPE_HF:
+   case BRW_REGISTER_TYPE_UW:
+   case BRW_REGISTER_TYPE_W:
+      return 2;
+   case BRW_REGISTER_TYPE_UB:
+   case BRW_REGISTER_TYPE_B:
+      return 1;
+   default:
+      return 0;
+   }
+}
+
+/**
+ * Construct a brw_reg.
+ * \param file  one of the BRW_x_REGISTER_FILE values
+ * \param nr  register number/index
+ * \param subnr  register sub number
+ * \param type  one of BRW_REGISTER_TYPE_x
+ * \param vstride  one of BRW_VERTICAL_STRIDE_x
+ * \param width  one of BRW_WIDTH_x
+ * \param hstride  one of BRW_HORIZONTAL_STRIDE_x
+ * \param swizzle  one of BRW_SWIZZLE_x
+ * \param writemask  BRW_WRITEMASK_X/Y/Z/W bitfield
+ */
+static INLINE struct brw_reg brw_reg( GLuint file,
+                                      GLuint nr,
+                                      GLuint subnr,
+                                      GLuint type,
+                                      GLuint vstride,
+                                      GLuint width,
+                                      GLuint hstride,
+                                      GLuint swizzle,
+                                      GLuint writemask )
+{
+   struct brw_reg reg;
+   if (type == BRW_GENERAL_REGISTER_FILE)
+      assert(nr < BRW_MAX_GRF);
+   else if (type == BRW_MESSAGE_REGISTER_FILE)
+      assert(nr < BRW_MAX_MRF);
+   else if (type == BRW_ARCHITECTURE_REGISTER_FILE)
+      assert(nr <= BRW_ARF_IP);
+
+   reg.type = type;
+   reg.file = file;
+   reg.nr = nr;
+   reg.subnr = subnr * type_sz(type);
+   reg.negate = 0;
+   reg.abs = 0;
+   reg.vstride = vstride;
+   reg.width = width;
+   reg.hstride = hstride;
+   reg.address_mode = BRW_ADDRESS_DIRECT;
+   reg.pad0 = 0;
+
+   /* Could do better: If the reg is r5.3<0;1,0>, we probably want to
+    * set swizzle and writemask to W, as the lower bits of subnr will
+    * be lost when converted to align16.  This is probably too much to
+    * keep track of as you'd want it adjusted by suboffset(), etc.
+    * Perhaps fix up when converting to align16?
+    */
+   reg.dw1.bits.swizzle = swizzle;
+   reg.dw1.bits.writemask = writemask;
+   reg.dw1.bits.indirect_offset = 0;
+   reg.dw1.bits.pad1 = 0;
+   return reg;
+}
+
+/** Construct float[16] register */
+static INLINE struct brw_reg brw_vec16_reg( GLuint file,
+					      GLuint nr,
+					      GLuint subnr )
+{
+   return brw_reg(file,
+		  nr,
+		  subnr,
+		  BRW_REGISTER_TYPE_F,
+		  BRW_VERTICAL_STRIDE_16,
+		  BRW_WIDTH_16,
+		  BRW_HORIZONTAL_STRIDE_1,
+		  BRW_SWIZZLE_XYZW,
+		  BRW_WRITEMASK_XYZW);
+}
+
+/** Construct float[8] register */
+static INLINE struct brw_reg brw_vec8_reg( GLuint file,
+					     GLuint nr,
+					     GLuint subnr )
+{
+   return brw_reg(file,
+		  nr,
+		  subnr,
+		  BRW_REGISTER_TYPE_F,
+		  BRW_VERTICAL_STRIDE_8,
+		  BRW_WIDTH_8,
+		  BRW_HORIZONTAL_STRIDE_1,
+		  BRW_SWIZZLE_XYZW,
+		  BRW_WRITEMASK_XYZW);
+}
+
+/** Construct float[4] register */
+static INLINE struct brw_reg brw_vec4_reg( GLuint file,
+					      GLuint nr,
+					      GLuint subnr )
+{
+   return brw_reg(file,
+		  nr,
+		  subnr,
+		  BRW_REGISTER_TYPE_F,
+		  BRW_VERTICAL_STRIDE_4,
+		  BRW_WIDTH_4,
+		  BRW_HORIZONTAL_STRIDE_1,
+		  BRW_SWIZZLE_XYZW,
+		  BRW_WRITEMASK_XYZW);
+}
+
+/** Construct float[2] register */
+static INLINE struct brw_reg brw_vec2_reg( GLuint file,
+					      GLuint nr,
+					      GLuint subnr )
+{
+   return brw_reg(file,
+		  nr,
+		  subnr,
+		  BRW_REGISTER_TYPE_F,
+		  BRW_VERTICAL_STRIDE_2,
+		  BRW_WIDTH_2,
+		  BRW_HORIZONTAL_STRIDE_1,
+		  BRW_SWIZZLE_XYXY,
+		  BRW_WRITEMASK_XY);
+}
+
+/** Construct float[1] register */
+static INLINE struct brw_reg brw_vec1_reg( GLuint file,
+					     GLuint nr,
+					     GLuint subnr )
+{
+   return brw_reg(file,
+		  nr,
+		  subnr,
+		  BRW_REGISTER_TYPE_F,
+		  BRW_VERTICAL_STRIDE_0,
+		  BRW_WIDTH_1,
+		  BRW_HORIZONTAL_STRIDE_0,
+		  BRW_SWIZZLE_XXXX,
+		  BRW_WRITEMASK_X);
+}
+
+
+static INLINE struct brw_reg retype( struct brw_reg reg,
+				       GLuint type )
+{
+   reg.type = type;
+   return reg;
+}
+
+static INLINE struct brw_reg suboffset( struct brw_reg reg,
+					  GLuint delta )
+{   
+   reg.subnr += delta * type_sz(reg.type);
+   return reg;
+}
+
+
+static INLINE struct brw_reg offset( struct brw_reg reg,
+				       GLuint delta )
+{
+   reg.nr += delta;
+   return reg;
+}
+
+
+static INLINE struct brw_reg byte_offset( struct brw_reg reg,
+					    GLuint bytes )
+{
+   GLuint newoffset = reg.nr * REG_SIZE + reg.subnr + bytes;
+   reg.nr = newoffset / REG_SIZE;
+   reg.subnr = newoffset % REG_SIZE;
+   return reg;
+}
+   
+
+/** Construct unsigned word[16] register */
+static INLINE struct brw_reg brw_uw16_reg( GLuint file,
+					     GLuint nr,
+					     GLuint subnr )
+{
+   return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
+}
+
+/** Construct unsigned word[8] register */
+static INLINE struct brw_reg brw_uw8_reg( GLuint file,
+					    GLuint nr,
+					    GLuint subnr )
+{
+   return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
+}
+
+/** Construct unsigned word[1] register */
+static INLINE struct brw_reg brw_uw1_reg( GLuint file,
+					    GLuint nr,
+					    GLuint subnr )
+{
+   return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr);
+}
+
+static INLINE struct brw_reg brw_imm_reg( GLuint type )
+{
+   return brw_reg( BRW_IMMEDIATE_VALUE,
+		   0,
+		   0,
+		   type,
+		   BRW_VERTICAL_STRIDE_0,
+		   BRW_WIDTH_1,
+		   BRW_HORIZONTAL_STRIDE_0,
+		   0,
+		   0);      
+}
+
+/** Construct float immediate register */
+static INLINE struct brw_reg brw_imm_f( GLfloat f )
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F);
+   imm.dw1.f = f;
+   return imm;
+}
+
+/** Construct integer immediate register */
+static INLINE struct brw_reg brw_imm_d( GLint d )
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D);
+   imm.dw1.d = d;
+   return imm;
+}
+
+/** Construct uint immediate register */
+static INLINE struct brw_reg brw_imm_ud( GLuint ud )
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD);
+   imm.dw1.ud = ud;
+   return imm;
+}
+
+/** Construct ushort immediate register */
+static INLINE struct brw_reg brw_imm_uw( GLushort uw )
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW);
+   imm.dw1.ud = uw | (uw << 16);
+   return imm;
+}
+
+/** Construct short immediate register */
+static INLINE struct brw_reg brw_imm_w( GLshort w )
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W);
+   imm.dw1.d = w | (w << 16);
+   return imm;
+}
+
+/* brw_imm_b and brw_imm_ub aren't supported by hardware - the type
+ * numbers alias with _V and _VF below:
+ */
+
+/** Construct vector of eight signed half-byte values */
+static INLINE struct brw_reg brw_imm_v( GLuint v )
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V);
+   imm.vstride = BRW_VERTICAL_STRIDE_0;
+   imm.width = BRW_WIDTH_8;
+   imm.hstride = BRW_HORIZONTAL_STRIDE_1;
+   imm.dw1.ud = v;
+   return imm;
+}
+
+/** Construct vector of four 8-bit float values */
+static INLINE struct brw_reg brw_imm_vf( GLuint v )
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
+   imm.vstride = BRW_VERTICAL_STRIDE_0;
+   imm.width = BRW_WIDTH_4;
+   imm.hstride = BRW_HORIZONTAL_STRIDE_1;
+   imm.dw1.ud = v;
+   return imm;
+}
+
+#define VF_ZERO 0x0
+#define VF_ONE  0x30
+#define VF_NEG  (1<<7)
+
+static INLINE struct brw_reg brw_imm_vf4( GLuint v0, 
+					    GLuint v1, 
+					    GLuint v2,
+					    GLuint v3)
+{
+   struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF);
+   imm.vstride = BRW_VERTICAL_STRIDE_0;
+   imm.width = BRW_WIDTH_4;
+   imm.hstride = BRW_HORIZONTAL_STRIDE_1;
+   imm.dw1.ud = ((v0 << 0) |
+		 (v1 << 8) |
+		 (v2 << 16) |
+		 (v3 << 24));
+   return imm;
+}
+
+
+static INLINE struct brw_reg brw_address( struct brw_reg reg )
+{
+   return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr);
+}
+
+/** Construct float[1] general-purpose register */
+static INLINE struct brw_reg brw_vec1_grf( GLuint nr, GLuint subnr )
+{
+   return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
+}
+
+/** Construct float[2] general-purpose register */
+static INLINE struct brw_reg brw_vec2_grf( GLuint nr, GLuint subnr )
+{
+   return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
+}
+
+/** Construct float[4] general-purpose register */
+static INLINE struct brw_reg brw_vec4_grf( GLuint nr, GLuint subnr )
+{
+   return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
+}
+
+/** Construct float[8] general-purpose register */
+static INLINE struct brw_reg brw_vec8_grf( GLuint nr, GLuint subnr )
+{
+   return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
+}
+
+
+static INLINE struct brw_reg brw_uw8_grf( GLuint nr, GLuint subnr )
+{
+   return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
+}
+
+static INLINE struct brw_reg brw_uw16_grf( GLuint nr, GLuint subnr )
+{
+   return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr);
+}
+
+
+/** Construct null register (usually used for setting condition codes) */
+static INLINE struct brw_reg brw_null_reg( void )
+{
+   return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, 
+		       BRW_ARF_NULL, 
+		       0);
+}
+
+static INLINE struct brw_reg brw_address_reg( GLuint subnr )
+{
+   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, 
+		      BRW_ARF_ADDRESS, 
+		      subnr);
+}
+
+/* If/else instructions break in align16 mode if writemask & swizzle
+ * aren't xyzw.  This goes against the convention for other scalar
+ * regs:
+ */
+static INLINE struct brw_reg brw_ip_reg( void )
+{
+   return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE, 
+		  BRW_ARF_IP, 
+		  0,
+		  BRW_REGISTER_TYPE_UD,
+		  BRW_VERTICAL_STRIDE_4, /* ? */
+		  BRW_WIDTH_1,
+		  BRW_HORIZONTAL_STRIDE_0,
+		  BRW_SWIZZLE_XYZW, /* NOTE! */
+		  BRW_WRITEMASK_XYZW); /* NOTE! */
+}
+
+static INLINE struct brw_reg brw_acc_reg( void )
+{
+   return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, 
+		       BRW_ARF_ACCUMULATOR, 
+		       0);
+}
+
+
+static INLINE struct brw_reg brw_flag_reg( void )
+{
+   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
+		      BRW_ARF_FLAG,
+		      0);
+}
+
+
+static INLINE struct brw_reg brw_mask_reg( GLuint subnr )
+{
+   return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE,
+		      BRW_ARF_MASK,
+		      subnr);
+}
+
+static INLINE struct brw_reg brw_message_reg( GLuint nr )
+{
+   assert(nr < BRW_MAX_MRF);
+   return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE,
+		       nr,
+		       0);
+}
+
+
+
+
+/* This is almost always called with a numeric constant argument, so
+ * make things easy to evaluate at compile time:
+ */
+static INLINE GLuint cvt( GLuint val )
+{
+   switch (val) {
+   case 0: return 0;
+   case 1: return 1;
+   case 2: return 2;
+   case 4: return 3;
+   case 8: return 4;
+   case 16: return 5;
+   case 32: return 6;
+   }
+   return 0;
+}
+
+static INLINE struct brw_reg stride( struct brw_reg reg,
+				       GLuint vstride,
+				       GLuint width,
+				       GLuint hstride )
+{
+   reg.vstride = cvt(vstride);
+   reg.width = cvt(width) - 1;
+   reg.hstride = cvt(hstride);
+   return reg;
+}
+
+
+static INLINE struct brw_reg vec16( struct brw_reg reg )
+{
+   return stride(reg, 16,16,1);
+}
+
+static INLINE struct brw_reg vec8( struct brw_reg reg )
+{
+   return stride(reg, 8,8,1);
+}
+
+static INLINE struct brw_reg vec4( struct brw_reg reg )
+{
+   return stride(reg, 4,4,1);
+}
+
+static INLINE struct brw_reg vec2( struct brw_reg reg )
+{
+   return stride(reg, 2,2,1);
+}
+
+static INLINE struct brw_reg vec1( struct brw_reg reg )
+{
+   return stride(reg, 0,1,0);
+}
+
+
+static INLINE struct brw_reg get_element( struct brw_reg reg, GLuint elt )
+{
+   return vec1(suboffset(reg, elt));
+}
+
+static INLINE struct brw_reg get_element_ud( struct brw_reg reg, GLuint elt )
+{
+   return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
+}
+
+
+static INLINE struct brw_reg brw_swizzle( struct brw_reg reg,
+					    GLuint x,
+					    GLuint y, 
+					    GLuint z,
+					    GLuint w)
+{
+   reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
+				       BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
+				       BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
+				       BRW_GET_SWZ(reg.dw1.bits.swizzle, w));
+   return reg;
+}
+
+
+static INLINE struct brw_reg brw_swizzle1( struct brw_reg reg,
+					     GLuint x )
+{
+   return brw_swizzle(reg, x, x, x, x);
+}
+
+static INLINE struct brw_reg brw_writemask( struct brw_reg reg,
+					      GLuint mask )
+{
+   reg.dw1.bits.writemask &= mask;
+   return reg;
+}
+
+static INLINE struct brw_reg brw_set_writemask( struct brw_reg reg,
+						  GLuint mask )
+{
+   reg.dw1.bits.writemask = mask;
+   return reg;
+}
+
+static INLINE struct brw_reg negate( struct brw_reg reg )
+{
+   reg.negate ^= 1;
+   return reg;
+}
+
+static INLINE struct brw_reg brw_abs( struct brw_reg reg )
+{
+   reg.abs = 1;
+   return reg;
+}
+
+/***********************************************************************
+ */
+static INLINE struct brw_reg brw_vec4_indirect( GLuint subnr,
+						  GLint offset )
+{
+   struct brw_reg reg =  brw_vec4_grf(0, 0);
+   reg.subnr = subnr;
+   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
+   reg.dw1.bits.indirect_offset = offset;
+   return reg;
+}
+
+static INLINE struct brw_reg brw_vec1_indirect( GLuint subnr,
+						  GLint offset )
+{
+   struct brw_reg reg =  brw_vec1_grf(0, 0);
+   reg.subnr = subnr;
+   reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER;
+   reg.dw1.bits.indirect_offset = offset;
+   return reg;
+}
+
+static INLINE struct brw_reg deref_4f(struct brw_indirect ptr, GLint offset)
+{
+   return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
+}
+
+static INLINE struct brw_reg deref_1f(struct brw_indirect ptr, GLint offset)
+{
+   return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset);
+}
+
+static INLINE struct brw_reg deref_4b(struct brw_indirect ptr, GLint offset)
+{
+   return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B);
+}
+
+static INLINE struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset)
+{
+   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
+}
+
+static INLINE struct brw_reg deref_1d(struct brw_indirect ptr, GLint offset)
+{
+   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D);
+}
+
+static INLINE struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset)
+{
+   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
+}
+
+static INLINE struct brw_reg get_addr_reg(struct brw_indirect ptr)
+{
+   return brw_address_reg(ptr.addr_subnr);
+}
+
+static INLINE struct brw_indirect brw_indirect_offset( struct brw_indirect ptr, GLint offset )
+{
+   ptr.addr_offset += offset;
+   return ptr;
+}
+
+static INLINE struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offset )
+{
+   struct brw_indirect ptr;
+   ptr.addr_subnr = addr_subnr;
+   ptr.addr_offset = offset;
+   ptr.pad = 0;
+   return ptr;
+}
+
+/** Do two brw_regs refer to the same register? */
+static INLINE GLboolean
+brw_same_reg(struct brw_reg r1, struct brw_reg r2)
+{
+   return r1.file == r2.file && r1.nr == r2.nr;
+}
+
+static INLINE struct brw_instruction *current_insn( struct brw_compile *p)
+{
+   return &p->store[p->nr_insn];
+}
+
+void brw_pop_insn_state( struct brw_compile *p );
+void brw_push_insn_state( struct brw_compile *p );
+void brw_set_mask_control( struct brw_compile *p, GLuint value );
+void brw_set_saturate( struct brw_compile *p, GLuint value );
+void brw_set_access_mode( struct brw_compile *p, GLuint access_mode );
+void brw_set_compression_control( struct brw_compile *p, GLboolean control );
+void brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value );
+void brw_set_predicate_control( struct brw_compile *p, GLuint pc );
+void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional );
+
+void brw_init_compile( struct brw_context *, struct brw_compile *p );
+
+enum pipe_error brw_get_program( struct brw_compile *p, 
+                                 const GLuint **program,
+                                 GLuint *sz );
+
+
+/* Helpers for regular instructions:
+ */
+#define ALU1(OP)					\
+struct brw_instruction *brw_##OP(struct brw_compile *p,	\
+	      struct brw_reg dest,			\
+	      struct brw_reg src0);
+
+#define ALU2(OP)					\
+struct brw_instruction *brw_##OP(struct brw_compile *p,	\
+	      struct brw_reg dest,			\
+	      struct brw_reg src0,			\
+	      struct brw_reg src1);
+
+ALU1(MOV)
+ALU2(SEL)
+ALU1(NOT)
+ALU2(AND)
+ALU2(OR)
+ALU2(XOR)
+ALU2(SHR)
+ALU2(SHL)
+ALU2(RSR)
+ALU2(RSL)
+ALU2(ASR)
+ALU2(JMPI)
+ALU2(ADD)
+ALU2(MUL)
+ALU1(FRC)
+ALU1(RNDD)
+ALU1(RNDZ)
+ALU2(MAC)
+ALU2(MACH)
+ALU1(LZD)
+ALU2(DP4)
+ALU2(DPH)
+ALU2(DP3)
+ALU2(DP2)
+ALU2(LINE)
+
+#undef ALU1
+#undef ALU2
+
+
+
+/* Helpers for SEND instruction:
+ */
+void brw_urb_WRITE(struct brw_compile *p,
+		   struct brw_reg dest,
+		   GLuint msg_reg_nr,
+		   struct brw_reg src0,
+		   GLboolean allocate,
+		   GLboolean used,
+		   GLuint msg_length,
+		   GLuint response_length,
+		   GLboolean eot,
+		   GLboolean writes_complete,
+		   GLuint offset,
+		   GLuint swizzle);
+
+void brw_ff_sync(struct brw_compile *p,
+		   struct brw_reg dest,
+		   GLuint msg_reg_nr,
+		   struct brw_reg src0,
+		   GLboolean allocate,
+		   GLboolean used,
+		   GLuint msg_length,
+		   GLuint response_length,
+		   GLboolean eot,
+		   GLboolean writes_complete,
+		   GLuint offset,
+		   GLuint swizzle);
+
+void brw_fb_WRITE(struct brw_compile *p,
+		   struct brw_reg dest,
+		   GLuint msg_reg_nr,
+		   struct brw_reg src0,
+		   GLuint binding_table_index,
+		   GLuint msg_length,
+		   GLuint response_length,
+		   GLboolean eot);
+
+void brw_SAMPLE(struct brw_compile *p,
+		struct brw_reg dest,
+		GLuint msg_reg_nr,
+		struct brw_reg src0,
+		GLuint binding_table_index,
+		GLuint sampler,
+		GLuint writemask,
+		GLuint msg_type,
+		GLuint response_length,
+		GLuint msg_length,
+		GLboolean eot,
+		GLuint header_present,
+		GLuint simd_mode);
+
+void brw_math_16( struct brw_compile *p,
+		  struct brw_reg dest,
+		  GLuint function,
+		  GLuint saturate,
+		  GLuint msg_reg_nr,
+		  struct brw_reg src,
+		  GLuint precision );
+
+void brw_math( struct brw_compile *p,
+	       struct brw_reg dest,
+	       GLuint function,
+	       GLuint saturate,
+	       GLuint msg_reg_nr,
+	       struct brw_reg src,
+	       GLuint data_type,
+	       GLuint precision );
+
+void brw_dp_READ_16( struct brw_compile *p,
+		     struct brw_reg dest,
+		     GLuint scratch_offset );
+
+void brw_dp_READ_4( struct brw_compile *p,
+                    struct brw_reg dest,
+                    GLboolean relAddr,
+                    GLuint location,
+                    GLuint bind_table_index );
+
+void brw_dp_READ_4_vs( struct brw_compile *p,
+                       struct brw_reg dest,
+                       GLuint oword,
+                       GLboolean relAddr,
+                       struct brw_reg addrReg,
+                       GLuint location,
+                       GLuint bind_table_index );
+
+void brw_dp_WRITE_16( struct brw_compile *p,
+		      struct brw_reg src,
+		      GLuint scratch_offset );
+
+/* If/else/endif.  Works by manipulating the execution flags on each
+ * channel.
+ */
+struct brw_instruction *brw_IF(struct brw_compile *p, 
+			       GLuint execute_size);
+
+struct brw_instruction *brw_ELSE(struct brw_compile *p, 
+				 struct brw_instruction *if_insn);
+
+void brw_ENDIF(struct brw_compile *p, 
+	       struct brw_instruction *if_or_else_insn);
+
+
+/* DO/WHILE loops:
+ */
+struct brw_instruction *brw_DO(struct brw_compile *p,
+			       GLuint execute_size);
+
+struct brw_instruction *brw_WHILE(struct brw_compile *p, 
+	       struct brw_instruction *patch_insn);
+
+struct brw_instruction *brw_BREAK(struct brw_compile *p);
+struct brw_instruction *brw_CONT(struct brw_compile *p);
+/* Forward jumps:
+ */
+void brw_land_fwd_jump(struct brw_compile *p, 
+		       struct brw_instruction *jmp_insn);
+
+
+
+void brw_NOP(struct brw_compile *p);
+
+/* Special case: there is never a destination, execution size will be
+ * taken from src0:
+ */
+void brw_CMP(struct brw_compile *p,
+	     struct brw_reg dest,
+	     GLuint conditional,
+	     struct brw_reg src0,
+	     struct brw_reg src1);
+
+void brw_print_reg( struct brw_reg reg );
+
+
+/*********************************************************************** 
+ * brw_eu_util.c:
+ */
+
+void brw_copy_indirect_to_indirect(struct brw_compile *p,
+				   struct brw_indirect dst_ptr,
+				   struct brw_indirect src_ptr,
+				   GLuint count);
+
+void brw_copy_from_indirect(struct brw_compile *p,
+			    struct brw_reg dst,
+			    struct brw_indirect ptr,
+			    GLuint count);
+
+void brw_copy4(struct brw_compile *p,
+	       struct brw_reg dst,
+	       struct brw_reg src,
+	       GLuint count);
+
+void brw_copy8(struct brw_compile *p,
+	       struct brw_reg dst,
+	       struct brw_reg src,
+	       GLuint count);
+
+void brw_math_invert( struct brw_compile *p, 
+		      struct brw_reg dst,
+		      struct brw_reg src);
+
+void brw_set_src1( struct brw_instruction *insn,
+                          struct brw_reg reg );
+#endif
diff --git a/src/gallium/drivers/i965/brw_eu_debug.c b/src/gallium/drivers/i965/brw_eu_debug.c
new file mode 100644
index 0000000..5989f5a
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_eu_debug.c
@@ -0,0 +1,94 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+ 
+#include "util/u_debug.h"
+
+#include "brw_eu.h"
+
+void brw_print_reg( struct brw_reg hwreg )
+{
+   static const char *file[] = {
+      "arf",
+      "grf",
+      "msg",
+      "imm"
+   };
+
+   static const char *type[] = {
+      "ud",
+      "d",
+      "uw",
+      "w",
+      "ub",
+      "vf",
+      "hf",
+      "f"
+   };
+
+   debug_printf("%s%s", 
+		hwreg.abs ? "abs/" : "",
+		hwreg.negate ? "-" : "");
+     
+   if (hwreg.file == BRW_GENERAL_REGISTER_FILE &&
+       hwreg.nr % 2 == 0 &&
+       hwreg.subnr == 0 &&
+       hwreg.vstride == BRW_VERTICAL_STRIDE_8 &&
+       hwreg.width == BRW_WIDTH_8 &&
+       hwreg.hstride == BRW_HORIZONTAL_STRIDE_1 &&
+       hwreg.type == BRW_REGISTER_TYPE_F) {
+      /* vector register */
+      debug_printf("vec%d", hwreg.nr);
+   }
+   else if (hwreg.file == BRW_GENERAL_REGISTER_FILE &&
+	    hwreg.vstride == BRW_VERTICAL_STRIDE_0 &&
+	    hwreg.width == BRW_WIDTH_1 &&
+	    hwreg.hstride == BRW_HORIZONTAL_STRIDE_0 &&
+	    hwreg.type == BRW_REGISTER_TYPE_F) {      
+      /* "scalar" register */
+      debug_printf("scl%d.%d", hwreg.nr, hwreg.subnr / 4);
+   }
+   else if (hwreg.file == BRW_IMMEDIATE_VALUE) {
+      debug_printf("imm %f", hwreg.dw1.f);
+   }
+   else {
+      debug_printf("%s%d.%d<%d;%d,%d>:%s", 
+		   file[hwreg.file],
+		   hwreg.nr,
+		   hwreg.subnr / type_sz(hwreg.type),
+		   hwreg.vstride ? (1<<(hwreg.vstride-1)) : 0,
+		   1<<hwreg.width,
+		   hwreg.hstride ? (1<<(hwreg.hstride-1)) : 0,		
+		   type[hwreg.type]);
+   }
+}
+
+
+
diff --git a/src/gallium/drivers/i965/brw_eu_emit.c b/src/gallium/drivers/i965/brw_eu_emit.c
new file mode 100644
index 0000000..00d8eac
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_eu_emit.c
@@ -0,0 +1,1433 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+     
+
+#include "brw_context.h"
+#include "brw_defines.h"
+#include "brw_eu.h"
+#include "brw_debug.h"
+#include "brw_disasm.h"
+
+
+
+
+/***********************************************************************
+ * Internal helper for constructing instructions
+ */
+
+static void guess_execution_size( struct brw_instruction *insn,
+				  struct brw_reg reg )
+{
+   if (reg.width == BRW_WIDTH_8 && 
+       insn->header.compression_control == BRW_COMPRESSION_COMPRESSED) 
+      insn->header.execution_size = BRW_EXECUTE_16;
+   else
+      insn->header.execution_size = reg.width;	/* note - definitions are compatible */
+}
+
+
+static void brw_set_dest( struct brw_instruction *insn,
+			  struct brw_reg dest )
+{
+   if (dest.type != BRW_ARCHITECTURE_REGISTER_FILE)
+      assert(dest.nr < 128);
+
+   insn->bits1.da1.dest_reg_file = dest.file;
+   insn->bits1.da1.dest_reg_type = dest.type;
+   insn->bits1.da1.dest_address_mode = dest.address_mode;
+
+   if (dest.address_mode == BRW_ADDRESS_DIRECT) {   
+      insn->bits1.da1.dest_reg_nr = dest.nr;
+
+      if (insn->header.access_mode == BRW_ALIGN_1) {
+	 insn->bits1.da1.dest_subreg_nr = dest.subnr;
+	 if (dest.hstride == BRW_HORIZONTAL_STRIDE_0)
+	    dest.hstride = BRW_HORIZONTAL_STRIDE_1;
+	 insn->bits1.da1.dest_horiz_stride = dest.hstride;
+      }
+      else {
+	 insn->bits1.da16.dest_subreg_nr = dest.subnr / 16;
+	 insn->bits1.da16.dest_writemask = dest.dw1.bits.writemask;
+      }
+   }
+   else {
+      insn->bits1.ia1.dest_subreg_nr = dest.subnr;
+
+      /* These are different sizes in align1 vs align16:
+       */
+      if (insn->header.access_mode == BRW_ALIGN_1) {
+	 insn->bits1.ia1.dest_indirect_offset = dest.dw1.bits.indirect_offset;
+	 if (dest.hstride == BRW_HORIZONTAL_STRIDE_0)
+	    dest.hstride = BRW_HORIZONTAL_STRIDE_1;
+	 insn->bits1.ia1.dest_horiz_stride = dest.hstride;
+      }
+      else {
+	 insn->bits1.ia16.dest_indirect_offset = dest.dw1.bits.indirect_offset;
+      }
+   }
+
+   /* NEW: Set the execution size based on dest.width and
+    * insn->compression_control:
+    */
+   guess_execution_size(insn, dest);
+}
+
+static void brw_set_src0( struct brw_instruction *insn,
+                          struct brw_reg reg )
+{
+   assert(reg.file != BRW_MESSAGE_REGISTER_FILE);
+
+   if (reg.type != BRW_ARCHITECTURE_REGISTER_FILE)
+      assert(reg.nr < 128);
+
+   insn->bits1.da1.src0_reg_file = reg.file;
+   insn->bits1.da1.src0_reg_type = reg.type;
+   insn->bits2.da1.src0_abs = reg.abs;
+   insn->bits2.da1.src0_negate = reg.negate;
+   insn->bits2.da1.src0_address_mode = reg.address_mode;
+
+   if (reg.file == BRW_IMMEDIATE_VALUE) {
+      insn->bits3.ud = reg.dw1.ud;
+   
+      /* Required to set some fields in src1 as well:
+       */
+      insn->bits1.da1.src1_reg_file = 0; /* arf */
+      insn->bits1.da1.src1_reg_type = reg.type;
+   }
+   else 
+   {
+      if (reg.address_mode == BRW_ADDRESS_DIRECT) {
+	 if (insn->header.access_mode == BRW_ALIGN_1) {
+	    insn->bits2.da1.src0_subreg_nr = reg.subnr;
+	    insn->bits2.da1.src0_reg_nr = reg.nr;
+	 }
+	 else {
+	    insn->bits2.da16.src0_subreg_nr = reg.subnr / 16;
+	    insn->bits2.da16.src0_reg_nr = reg.nr;
+	 }
+      }
+      else {
+	 insn->bits2.ia1.src0_subreg_nr = reg.subnr;
+
+	 if (insn->header.access_mode == BRW_ALIGN_1) {
+	    insn->bits2.ia1.src0_indirect_offset = reg.dw1.bits.indirect_offset; 
+	 }
+	 else {
+	    insn->bits2.ia16.src0_subreg_nr = reg.dw1.bits.indirect_offset;
+	 }
+      }
+
+      if (insn->header.access_mode == BRW_ALIGN_1) {
+	 if (reg.width == BRW_WIDTH_1 && 
+	     insn->header.execution_size == BRW_EXECUTE_1) {
+	    insn->bits2.da1.src0_horiz_stride = BRW_HORIZONTAL_STRIDE_0;
+	    insn->bits2.da1.src0_width = BRW_WIDTH_1;
+	    insn->bits2.da1.src0_vert_stride = BRW_VERTICAL_STRIDE_0;
+	 }
+	 else {
+	    insn->bits2.da1.src0_horiz_stride = reg.hstride;
+	    insn->bits2.da1.src0_width = reg.width;
+	    insn->bits2.da1.src0_vert_stride = reg.vstride;
+	 }
+      }
+      else {
+	 insn->bits2.da16.src0_swz_x = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_X);
+	 insn->bits2.da16.src0_swz_y = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Y);
+	 insn->bits2.da16.src0_swz_z = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Z);
+	 insn->bits2.da16.src0_swz_w = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_W);
+
+	 /* This is an oddity of the fact we're using the same
+	  * descriptions for registers in align_16 as align_1:
+	  */
+	 if (reg.vstride == BRW_VERTICAL_STRIDE_8)
+	    insn->bits2.da16.src0_vert_stride = BRW_VERTICAL_STRIDE_4;
+	 else
+	    insn->bits2.da16.src0_vert_stride = reg.vstride;
+      }
+   }
+}
+
+
+void brw_set_src1( struct brw_instruction *insn,
+                   struct brw_reg reg )
+{
+   assert(reg.file != BRW_MESSAGE_REGISTER_FILE);
+
+   assert(reg.nr < 128);
+
+   insn->bits1.da1.src1_reg_file = reg.file;
+   insn->bits1.da1.src1_reg_type = reg.type;
+   insn->bits3.da1.src1_abs = reg.abs;
+   insn->bits3.da1.src1_negate = reg.negate;
+
+   /* Only src1 can be immediate in two-argument instructions.
+    */
+   assert(insn->bits1.da1.src0_reg_file != BRW_IMMEDIATE_VALUE);
+
+   if (reg.file == BRW_IMMEDIATE_VALUE) {
+      insn->bits3.ud = reg.dw1.ud;
+   }
+   else {
+      /* This is a hardware restriction, which may or may not be lifted
+       * in the future:
+       */
+      assert (reg.address_mode == BRW_ADDRESS_DIRECT);
+      /*assert (reg.file == BRW_GENERAL_REGISTER_FILE); */
+
+      if (insn->header.access_mode == BRW_ALIGN_1) {
+	 insn->bits3.da1.src1_subreg_nr = reg.subnr;
+	 insn->bits3.da1.src1_reg_nr = reg.nr;
+      }
+      else {
+	 insn->bits3.da16.src1_subreg_nr = reg.subnr / 16;
+	 insn->bits3.da16.src1_reg_nr = reg.nr;
+      }
+
+      if (insn->header.access_mode == BRW_ALIGN_1) {
+	 if (reg.width == BRW_WIDTH_1 && 
+	     insn->header.execution_size == BRW_EXECUTE_1) {
+	    insn->bits3.da1.src1_horiz_stride = BRW_HORIZONTAL_STRIDE_0;
+	    insn->bits3.da1.src1_width = BRW_WIDTH_1;
+	    insn->bits3.da1.src1_vert_stride = BRW_VERTICAL_STRIDE_0;
+	 }
+	 else {
+	    insn->bits3.da1.src1_horiz_stride = reg.hstride;
+	    insn->bits3.da1.src1_width = reg.width;
+	    insn->bits3.da1.src1_vert_stride = reg.vstride;
+	 }
+      }
+      else {
+	 insn->bits3.da16.src1_swz_x = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_X);
+	 insn->bits3.da16.src1_swz_y = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Y);
+	 insn->bits3.da16.src1_swz_z = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Z);
+	 insn->bits3.da16.src1_swz_w = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_W);
+
+	 /* This is an oddity of the fact we're using the same
+	  * descriptions for registers in align_16 as align_1:
+	  */
+	 if (reg.vstride == BRW_VERTICAL_STRIDE_8)
+	    insn->bits3.da16.src1_vert_stride = BRW_VERTICAL_STRIDE_4;
+	 else
+	    insn->bits3.da16.src1_vert_stride = reg.vstride;
+      }
+   }
+}
+
+
+
+static void brw_set_math_message( struct brw_context *brw,
+				  struct brw_instruction *insn,
+				  GLuint msg_length,
+				  GLuint response_length,
+				  GLuint function,
+				  GLuint integer_type,
+				  GLboolean low_precision,
+				  GLboolean saturate,
+				  GLuint dataType )
+{
+   brw_set_src1(insn, brw_imm_d(0));
+
+   if (BRW_IS_IGDNG(brw)) {
+       insn->bits3.math_igdng.function = function;
+       insn->bits3.math_igdng.int_type = integer_type;
+       insn->bits3.math_igdng.precision = low_precision;
+       insn->bits3.math_igdng.saturate = saturate;
+       insn->bits3.math_igdng.data_type = dataType;
+       insn->bits3.math_igdng.snapshot = 0;
+       insn->bits3.math_igdng.header_present = 0;
+       insn->bits3.math_igdng.response_length = response_length;
+       insn->bits3.math_igdng.msg_length = msg_length;
+       insn->bits3.math_igdng.end_of_thread = 0;
+       insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_MATH;
+       insn->bits2.send_igdng.end_of_thread = 0;
+   } else {
+       insn->bits3.math.function = function;
+       insn->bits3.math.int_type = integer_type;
+       insn->bits3.math.precision = low_precision;
+       insn->bits3.math.saturate = saturate;
+       insn->bits3.math.data_type = dataType;
+       insn->bits3.math.response_length = response_length;
+       insn->bits3.math.msg_length = msg_length;
+       insn->bits3.math.msg_target = BRW_MESSAGE_TARGET_MATH;
+       insn->bits3.math.end_of_thread = 0;
+   }
+}
+
+
+static void brw_set_ff_sync_message( struct brw_context *brw,
+				 struct brw_instruction *insn,
+				 GLboolean allocate,
+				 GLboolean used,
+				 GLuint msg_length,
+				 GLuint response_length,
+				 GLboolean end_of_thread,
+				 GLboolean complete,
+				 GLuint offset,
+				 GLuint swizzle_control )
+{
+	brw_set_src1(insn, brw_imm_d(0));
+
+	insn->bits3.urb_igdng.opcode = 1;
+	insn->bits3.urb_igdng.offset = offset;
+	insn->bits3.urb_igdng.swizzle_control = swizzle_control;
+	insn->bits3.urb_igdng.allocate = allocate;
+	insn->bits3.urb_igdng.used = used;
+	insn->bits3.urb_igdng.complete = complete;
+	insn->bits3.urb_igdng.header_present = 1;
+	insn->bits3.urb_igdng.response_length = response_length;
+	insn->bits3.urb_igdng.msg_length = msg_length;
+	insn->bits3.urb_igdng.end_of_thread = end_of_thread;
+	insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_URB;
+	insn->bits2.send_igdng.end_of_thread = end_of_thread;
+}
+
+static void brw_set_urb_message( struct brw_context *brw,
+				 struct brw_instruction *insn,
+				 GLboolean allocate,
+				 GLboolean used,
+				 GLuint msg_length,
+				 GLuint response_length,
+				 GLboolean end_of_thread,
+				 GLboolean complete,
+				 GLuint offset,
+				 GLuint swizzle_control )
+{
+    brw_set_src1(insn, brw_imm_d(0));
+
+    if (BRW_IS_IGDNG(brw)) {
+        insn->bits3.urb_igdng.opcode = 0;	/* ? */
+        insn->bits3.urb_igdng.offset = offset;
+        insn->bits3.urb_igdng.swizzle_control = swizzle_control;
+        insn->bits3.urb_igdng.allocate = allocate;
+        insn->bits3.urb_igdng.used = used;	/* ? */
+        insn->bits3.urb_igdng.complete = complete;
+        insn->bits3.urb_igdng.header_present = 1;
+        insn->bits3.urb_igdng.response_length = response_length;
+        insn->bits3.urb_igdng.msg_length = msg_length;
+        insn->bits3.urb_igdng.end_of_thread = end_of_thread;
+        insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_URB;
+        insn->bits2.send_igdng.end_of_thread = end_of_thread;
+    } else {
+        insn->bits3.urb.opcode = 0;	/* ? */
+        insn->bits3.urb.offset = offset;
+        insn->bits3.urb.swizzle_control = swizzle_control;
+        insn->bits3.urb.allocate = allocate;
+        insn->bits3.urb.used = used;	/* ? */
+        insn->bits3.urb.complete = complete;
+        insn->bits3.urb.response_length = response_length;
+        insn->bits3.urb.msg_length = msg_length;
+        insn->bits3.urb.msg_target = BRW_MESSAGE_TARGET_URB;
+        insn->bits3.urb.end_of_thread = end_of_thread;
+    }
+}
+
+static void brw_set_dp_write_message( struct brw_context *brw,
+				      struct brw_instruction *insn,
+				      GLuint binding_table_index,
+				      GLuint msg_control,
+				      GLuint msg_type,
+				      GLuint msg_length,
+				      GLuint pixel_scoreboard_clear,
+				      GLuint response_length,
+				      GLuint end_of_thread )
+{
+   brw_set_src1(insn, brw_imm_d(0));
+
+   if (BRW_IS_IGDNG(brw)) {
+       insn->bits3.dp_write_igdng.binding_table_index = binding_table_index;
+       insn->bits3.dp_write_igdng.msg_control = msg_control;
+       insn->bits3.dp_write_igdng.pixel_scoreboard_clear = pixel_scoreboard_clear;
+       insn->bits3.dp_write_igdng.msg_type = msg_type;
+       insn->bits3.dp_write_igdng.send_commit_msg = 0;
+       insn->bits3.dp_write_igdng.header_present = 1;
+       insn->bits3.dp_write_igdng.response_length = response_length;
+       insn->bits3.dp_write_igdng.msg_length = msg_length;
+       insn->bits3.dp_write_igdng.end_of_thread = end_of_thread;
+       insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_DATAPORT_WRITE;
+       insn->bits2.send_igdng.end_of_thread = end_of_thread;
+   } else {
+       insn->bits3.dp_write.binding_table_index = binding_table_index;
+       insn->bits3.dp_write.msg_control = msg_control;
+       insn->bits3.dp_write.pixel_scoreboard_clear = pixel_scoreboard_clear;
+       insn->bits3.dp_write.msg_type = msg_type;
+       insn->bits3.dp_write.send_commit_msg = 0;
+       insn->bits3.dp_write.response_length = response_length;
+       insn->bits3.dp_write.msg_length = msg_length;
+       insn->bits3.dp_write.msg_target = BRW_MESSAGE_TARGET_DATAPORT_WRITE;
+       insn->bits3.dp_write.end_of_thread = end_of_thread;
+   }
+}
+
+static void brw_set_dp_read_message( struct brw_context *brw,
+				      struct brw_instruction *insn,
+				      GLuint binding_table_index,
+				      GLuint msg_control,
+				      GLuint msg_type,
+				      GLuint target_cache,
+				      GLuint msg_length,
+				      GLuint response_length,
+				      GLuint end_of_thread )
+{
+   brw_set_src1(insn, brw_imm_d(0));
+
+   if (BRW_IS_IGDNG(brw)) {
+       insn->bits3.dp_read_igdng.binding_table_index = binding_table_index;
+       insn->bits3.dp_read_igdng.msg_control = msg_control;
+       insn->bits3.dp_read_igdng.msg_type = msg_type;
+       insn->bits3.dp_read_igdng.target_cache = target_cache;
+       insn->bits3.dp_read_igdng.header_present = 1;
+       insn->bits3.dp_read_igdng.response_length = response_length;
+       insn->bits3.dp_read_igdng.msg_length = msg_length;
+       insn->bits3.dp_read_igdng.pad1 = 0;
+       insn->bits3.dp_read_igdng.end_of_thread = end_of_thread;
+       insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_DATAPORT_READ;
+       insn->bits2.send_igdng.end_of_thread = end_of_thread;
+   } else {
+       insn->bits3.dp_read.binding_table_index = binding_table_index; /*0:7*/
+       insn->bits3.dp_read.msg_control = msg_control;  /*8:11*/
+       insn->bits3.dp_read.msg_type = msg_type;  /*12:13*/
+       insn->bits3.dp_read.target_cache = target_cache;  /*14:15*/
+       insn->bits3.dp_read.response_length = response_length;  /*16:19*/
+       insn->bits3.dp_read.msg_length = msg_length;  /*20:23*/
+       insn->bits3.dp_read.msg_target = BRW_MESSAGE_TARGET_DATAPORT_READ; /*24:27*/
+       insn->bits3.dp_read.pad1 = 0;  /*28:30*/
+       insn->bits3.dp_read.end_of_thread = end_of_thread;  /*31*/
+   }
+}
+
+static void brw_set_sampler_message(struct brw_context *brw,
+                                    struct brw_instruction *insn,
+                                    GLuint binding_table_index,
+                                    GLuint sampler,
+                                    GLuint msg_type,
+                                    GLuint response_length,
+                                    GLuint msg_length,
+                                    GLboolean eot,
+                                    GLuint header_present,
+                                    GLuint simd_mode)
+{
+   assert(eot == 0);
+   brw_set_src1(insn, brw_imm_d(0));
+
+   if (BRW_IS_IGDNG(brw)) {
+      insn->bits3.sampler_igdng.binding_table_index = binding_table_index;
+      insn->bits3.sampler_igdng.sampler = sampler;
+      insn->bits3.sampler_igdng.msg_type = msg_type;
+      insn->bits3.sampler_igdng.simd_mode = simd_mode;
+      insn->bits3.sampler_igdng.header_present = header_present;
+      insn->bits3.sampler_igdng.response_length = response_length;
+      insn->bits3.sampler_igdng.msg_length = msg_length;
+      insn->bits3.sampler_igdng.end_of_thread = eot;
+      insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_SAMPLER;
+      insn->bits2.send_igdng.end_of_thread = eot;
+   } else if (BRW_IS_G4X(brw)) {
+      insn->bits3.sampler_g4x.binding_table_index = binding_table_index;
+      insn->bits3.sampler_g4x.sampler = sampler;
+      insn->bits3.sampler_g4x.msg_type = msg_type;
+      insn->bits3.sampler_g4x.response_length = response_length;
+      insn->bits3.sampler_g4x.msg_length = msg_length;
+      insn->bits3.sampler_g4x.end_of_thread = eot;
+      insn->bits3.sampler_g4x.msg_target = BRW_MESSAGE_TARGET_SAMPLER;
+   } else {
+      insn->bits3.sampler.binding_table_index = binding_table_index;
+      insn->bits3.sampler.sampler = sampler;
+      insn->bits3.sampler.msg_type = msg_type;
+      insn->bits3.sampler.return_format = BRW_SAMPLER_RETURN_FORMAT_FLOAT32;
+      insn->bits3.sampler.response_length = response_length;
+      insn->bits3.sampler.msg_length = msg_length;
+      insn->bits3.sampler.end_of_thread = eot;
+      insn->bits3.sampler.msg_target = BRW_MESSAGE_TARGET_SAMPLER;
+   }
+}
+
+
+
+static struct brw_instruction *next_insn( struct brw_compile *p, 
+					  GLuint opcode )
+{
+   struct brw_instruction *insn;
+
+   if (0 && (BRW_DEBUG & DEBUG_DISASSEM))
+   {
+      if (p->nr_insn) 
+         brw_disasm_insn(stderr, &p->store[p->nr_insn-1]);
+   }
+
+   assert(p->nr_insn + 1 < BRW_EU_MAX_INSN);
+
+   insn = &p->store[p->nr_insn++];
+   memcpy(insn, p->current, sizeof(*insn));
+
+   /* Reset this one-shot flag: 
+    */
+
+   if (p->current->header.destreg__conditionalmod) {
+      p->current->header.destreg__conditionalmod = 0;
+      p->current->header.predicate_control = BRW_PREDICATE_NORMAL;
+   }
+
+   insn->header.opcode = opcode;
+   return insn;
+}
+
+
+static struct brw_instruction *brw_alu1( struct brw_compile *p,
+					 GLuint opcode,
+					 struct brw_reg dest,
+					 struct brw_reg src )
+{
+   struct brw_instruction *insn = next_insn(p, opcode);
+   brw_set_dest(insn, dest);
+   brw_set_src0(insn, src);   
+   return insn;
+}
+
+static struct brw_instruction *brw_alu2(struct brw_compile *p,
+					GLuint opcode,
+					struct brw_reg dest,
+					struct brw_reg src0,
+					struct brw_reg src1 )
+{
+   struct brw_instruction *insn = next_insn(p, opcode);   
+   brw_set_dest(insn, dest);
+   brw_set_src0(insn, src0);
+   brw_set_src1(insn, src1);
+   return insn;
+}
+
+
+/***********************************************************************
+ * Convenience routines.
+ */
+#define ALU1(OP)					\
+struct brw_instruction *brw_##OP(struct brw_compile *p,	\
+	      struct brw_reg dest,			\
+	      struct brw_reg src0)   			\
+{							\
+   return brw_alu1(p, BRW_OPCODE_##OP, dest, src0);    	\
+}
+
+#define ALU2(OP)					\
+struct brw_instruction *brw_##OP(struct brw_compile *p,	\
+	      struct brw_reg dest,			\
+	      struct brw_reg src0,			\
+	      struct brw_reg src1)   			\
+{							\
+   return brw_alu2(p, BRW_OPCODE_##OP, dest, src0, src1);	\
+}
+
+
+ALU1(MOV)
+ALU2(SEL)
+ALU1(NOT)
+ALU2(AND)
+ALU2(OR)
+ALU2(XOR)
+ALU2(SHR)
+ALU2(SHL)
+ALU2(RSR)
+ALU2(RSL)
+ALU2(ASR)
+ALU2(ADD)
+ALU2(MUL)
+ALU1(FRC)
+ALU1(RNDD)
+ALU1(RNDZ)
+ALU2(MAC)
+ALU2(MACH)
+ALU1(LZD)
+ALU2(DP4)
+ALU2(DPH)
+ALU2(DP3)
+ALU2(DP2)
+ALU2(LINE)
+
+
+
+
+void brw_NOP(struct brw_compile *p)
+{
+   struct brw_instruction *insn = next_insn(p, BRW_OPCODE_NOP);   
+   brw_set_dest(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
+   brw_set_src0(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
+   brw_set_src1(insn, brw_imm_ud(0x0));
+}
+
+
+
+
+
+/***********************************************************************
+ * Comparisons, if/else/endif
+ */
+
+struct brw_instruction *brw_JMPI(struct brw_compile *p, 
+                                 struct brw_reg dest,
+                                 struct brw_reg src0,
+                                 struct brw_reg src1)
+{
+   struct brw_instruction *insn = brw_alu2(p, BRW_OPCODE_JMPI, dest, src0, src1);
+
+   insn->header.execution_size = 1;
+   insn->header.compression_control = BRW_COMPRESSION_NONE;
+   insn->header.mask_control = BRW_MASK_DISABLE;
+
+   p->current->header.predicate_control = BRW_PREDICATE_NONE;
+
+   return insn;
+}
+
+/* EU takes the value from the flag register and pushes it onto some
+ * sort of a stack (presumably merging with any flag value already on
+ * the stack).  Within an if block, the flags at the top of the stack
+ * control execution on each channel of the unit, eg. on each of the
+ * 16 pixel values in our wm programs.
+ *
+ * When the matching 'else' instruction is reached (presumably by
+ * countdown of the instruction count patched in by our ELSE/ENDIF
+ * functions), the relevent flags are inverted.
+ *
+ * When the matching 'endif' instruction is reached, the flags are
+ * popped off.  If the stack is now empty, normal execution resumes.
+ *
+ * No attempt is made to deal with stack overflow (14 elements?).
+ */
+struct brw_instruction *brw_IF(struct brw_compile *p, GLuint execute_size)
+{
+   struct brw_instruction *insn;
+
+   if (p->single_program_flow) {
+      assert(execute_size == BRW_EXECUTE_1);
+
+      insn = next_insn(p, BRW_OPCODE_ADD);
+      insn->header.predicate_inverse = 1;
+   } else {
+      insn = next_insn(p, BRW_OPCODE_IF);
+   }
+
+   /* Override the defaults for this instruction:
+    */
+   brw_set_dest(insn, brw_ip_reg());
+   brw_set_src0(insn, brw_ip_reg());
+   brw_set_src1(insn, brw_imm_d(0x0));
+
+   insn->header.execution_size = execute_size;
+   insn->header.compression_control = BRW_COMPRESSION_NONE;
+   insn->header.predicate_control = BRW_PREDICATE_NORMAL;
+   insn->header.mask_control = BRW_MASK_ENABLE;
+   if (!p->single_program_flow)
+       insn->header.thread_control = BRW_THREAD_SWITCH;
+
+   p->current->header.predicate_control = BRW_PREDICATE_NONE;
+
+   return insn;
+}
+
+
+struct brw_instruction *brw_ELSE(struct brw_compile *p, 
+				 struct brw_instruction *if_insn)
+{
+   struct brw_instruction *insn;
+   GLuint br = 1;
+
+   if (BRW_IS_IGDNG(p->brw))
+      br = 2;
+
+   if (p->single_program_flow) {
+      insn = next_insn(p, BRW_OPCODE_ADD);
+   } else {
+      insn = next_insn(p, BRW_OPCODE_ELSE);
+   }
+
+   brw_set_dest(insn, brw_ip_reg());
+   brw_set_src0(insn, brw_ip_reg());
+   brw_set_src1(insn, brw_imm_d(0x0));
+
+   insn->header.compression_control = BRW_COMPRESSION_NONE;
+   insn->header.execution_size = if_insn->header.execution_size;
+   insn->header.mask_control = BRW_MASK_ENABLE;
+   if (!p->single_program_flow)
+       insn->header.thread_control = BRW_THREAD_SWITCH;
+
+   /* Patch the if instruction to point at this instruction.
+    */
+   if (p->single_program_flow) {
+      assert(if_insn->header.opcode == BRW_OPCODE_ADD);
+
+      if_insn->bits3.ud = (insn - if_insn + 1) * 16;
+   } else {
+      assert(if_insn->header.opcode == BRW_OPCODE_IF);
+
+      if_insn->bits3.if_else.jump_count = br * (insn - if_insn);
+      if_insn->bits3.if_else.pop_count = 0;
+      if_insn->bits3.if_else.pad0 = 0;
+   }
+
+   return insn;
+}
+
+void brw_ENDIF(struct brw_compile *p, 
+	       struct brw_instruction *patch_insn)
+{
+   GLuint br = 1;
+
+   if (BRW_IS_IGDNG(p->brw))
+      br = 2; 
+ 
+   if (p->single_program_flow) {
+      /* In single program flow mode, there's no need to execute an ENDIF,
+       * since we don't need to do any stack operations, and if we're executing
+       * currently, we want to just continue executing.
+       */
+      struct brw_instruction *next = &p->store[p->nr_insn];
+
+      assert(patch_insn->header.opcode == BRW_OPCODE_ADD);
+
+      patch_insn->bits3.ud = (next - patch_insn) * 16;
+   } else {
+      struct brw_instruction *insn = next_insn(p, BRW_OPCODE_ENDIF);
+
+      brw_set_dest(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
+      brw_set_src0(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD));
+      brw_set_src1(insn, brw_imm_d(0x0));
+
+      insn->header.compression_control = BRW_COMPRESSION_NONE;
+      insn->header.execution_size = patch_insn->header.execution_size;
+      insn->header.mask_control = BRW_MASK_ENABLE;
+      insn->header.thread_control = BRW_THREAD_SWITCH;
+
+      assert(patch_insn->bits3.if_else.jump_count == 0);
+
+      /* Patch the if or else instructions to point at this or the next
+       * instruction respectively.
+       */
+      if (patch_insn->header.opcode == BRW_OPCODE_IF) {
+	 /* Automagically turn it into an IFF:
+	  */
+	 patch_insn->header.opcode = BRW_OPCODE_IFF;
+	 patch_insn->bits3.if_else.jump_count = br * (insn - patch_insn + 1);
+	 patch_insn->bits3.if_else.pop_count = 0;
+	 patch_insn->bits3.if_else.pad0 = 0;
+      } else if (patch_insn->header.opcode == BRW_OPCODE_ELSE) {
+	 patch_insn->bits3.if_else.jump_count = br * (insn - patch_insn + 1);
+	 patch_insn->bits3.if_else.pop_count = 1;
+	 patch_insn->bits3.if_else.pad0 = 0;
+      } else {
+	 assert(0);
+      }
+
+      /* Also pop item off the stack in the endif instruction:
+       */
+      insn->bits3.if_else.jump_count = 0;
+      insn->bits3.if_else.pop_count = 1;
+      insn->bits3.if_else.pad0 = 0;
+   }
+}
+
+struct brw_instruction *brw_BREAK(struct brw_compile *p)
+{
+   struct brw_instruction *insn;
+   insn = next_insn(p, BRW_OPCODE_BREAK);
+   brw_set_dest(insn, brw_ip_reg());
+   brw_set_src0(insn, brw_ip_reg());
+   brw_set_src1(insn, brw_imm_d(0x0));
+   insn->header.compression_control = BRW_COMPRESSION_NONE;
+   insn->header.execution_size = BRW_EXECUTE_8;
+   /* insn->header.mask_control = BRW_MASK_DISABLE; */
+   insn->bits3.if_else.pad0 = 0;
+   return insn;
+}
+
+struct brw_instruction *brw_CONT(struct brw_compile *p)
+{
+   struct brw_instruction *insn;
+   insn = next_insn(p, BRW_OPCODE_CONTINUE);
+   brw_set_dest(insn, brw_ip_reg());
+   brw_set_src0(insn, brw_ip_reg());
+   brw_set_src1(insn, brw_imm_d(0x0));
+   insn->header.compression_control = BRW_COMPRESSION_NONE;
+   insn->header.execution_size = BRW_EXECUTE_8;
+   /* insn->header.mask_control = BRW_MASK_DISABLE; */
+   insn->bits3.if_else.pad0 = 0;
+   return insn;
+}
+
+/* DO/WHILE loop:
+ */
+struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size)
+{
+   if (p->single_program_flow) {
+      return &p->store[p->nr_insn];
+   } else {
+      struct brw_instruction *insn = next_insn(p, BRW_OPCODE_DO);
+
+      /* Override the defaults for this instruction:
+       */
+      brw_set_dest(insn, brw_null_reg());
+      brw_set_src0(insn, brw_null_reg());
+      brw_set_src1(insn, brw_null_reg());
+
+      insn->header.compression_control = BRW_COMPRESSION_NONE;
+      insn->header.execution_size = execute_size;
+      insn->header.predicate_control = BRW_PREDICATE_NONE;
+      /* insn->header.mask_control = BRW_MASK_ENABLE; */
+      /* insn->header.mask_control = BRW_MASK_DISABLE; */
+
+      return insn;
+   }
+}
+
+
+
+struct brw_instruction *brw_WHILE(struct brw_compile *p, 
+                                  struct brw_instruction *do_insn)
+{
+   struct brw_instruction *insn;
+   GLuint br = 1;
+
+   if (BRW_IS_IGDNG(p->brw))
+      br = 2;
+
+   if (p->single_program_flow)
+      insn = next_insn(p, BRW_OPCODE_ADD);
+   else
+      insn = next_insn(p, BRW_OPCODE_WHILE);
+
+   brw_set_dest(insn, brw_ip_reg());
+   brw_set_src0(insn, brw_ip_reg());
+   brw_set_src1(insn, brw_imm_d(0x0));
+
+   insn->header.compression_control = BRW_COMPRESSION_NONE;
+
+   if (p->single_program_flow) {
+      insn->header.execution_size = BRW_EXECUTE_1;
+
+      insn->bits3.d = (do_insn - insn) * 16;
+   } else {
+      insn->header.execution_size = do_insn->header.execution_size;
+
+      assert(do_insn->header.opcode == BRW_OPCODE_DO);
+      insn->bits3.if_else.jump_count = br * (do_insn - insn + 1);
+      insn->bits3.if_else.pop_count = 0;
+      insn->bits3.if_else.pad0 = 0;
+   }
+
+/*    insn->header.mask_control = BRW_MASK_ENABLE; */
+
+   /* insn->header.mask_control = BRW_MASK_DISABLE; */
+   p->current->header.predicate_control = BRW_PREDICATE_NONE;   
+   return insn;
+}
+
+
+/* FORWARD JUMPS:
+ */
+void brw_land_fwd_jump(struct brw_compile *p, 
+		       struct brw_instruction *jmp_insn)
+{
+   struct brw_instruction *landing = &p->store[p->nr_insn];
+   GLuint jmpi = 1;
+
+   if (BRW_IS_IGDNG(p->brw))
+       jmpi = 2;
+
+   assert(jmp_insn->header.opcode == BRW_OPCODE_JMPI);
+   assert(jmp_insn->bits1.da1.src1_reg_file == BRW_IMMEDIATE_VALUE);
+
+   jmp_insn->bits3.ud = jmpi * ((landing - jmp_insn) - 1);
+}
+
+
+
+/* To integrate with the above, it makes sense that the comparison
+ * instruction should populate the flag register.  It might be simpler
+ * just to use the flag reg for most WM tasks?
+ */
+void brw_CMP(struct brw_compile *p,
+	     struct brw_reg dest,
+	     GLuint conditional,
+	     struct brw_reg src0,
+	     struct brw_reg src1)
+{
+   struct brw_instruction *insn = next_insn(p, BRW_OPCODE_CMP);
+
+   insn->header.destreg__conditionalmod = conditional;
+   brw_set_dest(insn, dest);
+   brw_set_src0(insn, src0);
+   brw_set_src1(insn, src1);
+
+/*    guess_execution_size(insn, src0); */
+
+
+   /* Make it so that future instructions will use the computed flag
+    * value until brw_set_predicate_control_flag_value() is called
+    * again.  
+    */
+   if (dest.file == BRW_ARCHITECTURE_REGISTER_FILE &&
+       dest.nr == 0) {
+      p->current->header.predicate_control = BRW_PREDICATE_NORMAL;
+      p->flag_value = 0xff;
+   }
+}
+
+
+
+/***********************************************************************
+ * Helpers for the various SEND message types:
+ */
+
+/** Extended math function, float[8].
+ */
+void brw_math( struct brw_compile *p,
+	       struct brw_reg dest,
+	       GLuint function,
+	       GLuint saturate,
+	       GLuint msg_reg_nr,
+	       struct brw_reg src,
+	       GLuint data_type,
+	       GLuint precision )
+{
+   struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
+   GLuint msg_length = (function == BRW_MATH_FUNCTION_POW) ? 2 : 1; 
+   GLuint response_length = (function == BRW_MATH_FUNCTION_SINCOS) ? 2 : 1; 
+
+   /* Example code doesn't set predicate_control for send
+    * instructions.
+    */
+   insn->header.predicate_control = 0; 
+   insn->header.destreg__conditionalmod = msg_reg_nr;
+
+   brw_set_dest(insn, dest);
+   brw_set_src0(insn, src);
+   brw_set_math_message(p->brw,
+			insn, 
+			msg_length, response_length, 
+			function,
+			BRW_MATH_INTEGER_UNSIGNED,
+			precision,
+			saturate,
+			data_type);
+}
+
+/**
+ * Extended math function, float[16].
+ * Use 2 send instructions.
+ */
+void brw_math_16( struct brw_compile *p,
+		  struct brw_reg dest,
+		  GLuint function,
+		  GLuint saturate,
+		  GLuint msg_reg_nr,
+		  struct brw_reg src,
+		  GLuint precision )
+{
+   struct brw_instruction *insn;
+   GLuint msg_length = (function == BRW_MATH_FUNCTION_POW) ? 2 : 1; 
+   GLuint response_length = (function == BRW_MATH_FUNCTION_SINCOS) ? 2 : 1; 
+
+   /* First instruction:
+    */
+   brw_push_insn_state(p);
+   brw_set_predicate_control_flag_value(p, 0xff);
+   brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+
+   insn = next_insn(p, BRW_OPCODE_SEND);
+   insn->header.destreg__conditionalmod = msg_reg_nr;
+
+   brw_set_dest(insn, dest);
+   brw_set_src0(insn, src);
+   brw_set_math_message(p->brw,
+			insn, 
+			msg_length, response_length, 
+			function,
+			BRW_MATH_INTEGER_UNSIGNED,
+			precision,
+			saturate,
+			BRW_MATH_DATA_VECTOR);
+
+   /* Second instruction:
+    */
+   insn = next_insn(p, BRW_OPCODE_SEND);
+   insn->header.compression_control = BRW_COMPRESSION_2NDHALF;
+   insn->header.destreg__conditionalmod = msg_reg_nr+1;
+
+   brw_set_dest(insn, offset(dest,1));
+   brw_set_src0(insn, src);
+   brw_set_math_message(p->brw, 
+			insn, 
+			msg_length, response_length, 
+			function,
+			BRW_MATH_INTEGER_UNSIGNED,
+			precision,
+			saturate,
+			BRW_MATH_DATA_VECTOR);
+
+   brw_pop_insn_state(p);
+}
+
+
+/**
+ * Write block of 16 dwords/floats to the data port Render Cache scratch buffer.
+ * Scratch offset should be a multiple of 64.
+ * Used for register spilling.
+ */
+void brw_dp_WRITE_16( struct brw_compile *p,
+		      struct brw_reg src,
+		      GLuint scratch_offset )
+{
+   GLuint msg_reg_nr = 1;
+   {
+      brw_push_insn_state(p);
+      brw_set_mask_control(p, BRW_MASK_DISABLE);
+      brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+
+      /* set message header global offset field (reg 0, element 2) */
+      brw_MOV(p,
+	      retype(brw_vec1_grf(0, 2), BRW_REGISTER_TYPE_D),
+	      brw_imm_d(scratch_offset));
+
+      brw_pop_insn_state(p);
+   }
+
+   {
+      GLuint msg_length = 3;
+      struct brw_reg dest = retype(brw_null_reg(), BRW_REGISTER_TYPE_UW);
+      struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
+   
+      insn->header.predicate_control = 0; /* XXX */
+      insn->header.compression_control = BRW_COMPRESSION_NONE; 
+      insn->header.destreg__conditionalmod = msg_reg_nr;
+  
+      brw_set_dest(insn, dest);
+      brw_set_src0(insn, src);
+
+      brw_set_dp_write_message(p->brw,
+			       insn,
+			       255, /* binding table index (255=stateless) */
+			       BRW_DATAPORT_OWORD_BLOCK_4_OWORDS, /* msg_control */
+			       BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE, /* msg_type */
+			       msg_length,
+			       0, /* pixel scoreboard */
+			       0, /* response_length */
+			       0); /* eot */
+   }
+}
+
+
+/**
+ * Read block of 16 dwords/floats from the data port Render Cache scratch buffer.
+ * Scratch offset should be a multiple of 64.
+ * Used for register spilling.
+ */
+void brw_dp_READ_16( struct brw_compile *p,
+		      struct brw_reg dest,
+		      GLuint scratch_offset )
+{
+   GLuint msg_reg_nr = 1;
+   {
+      brw_push_insn_state(p);
+      brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+      brw_set_mask_control(p, BRW_MASK_DISABLE);
+
+      /* set message header global offset field (reg 0, element 2) */
+      brw_MOV(p,
+	      retype(brw_vec1_grf(0, 2), BRW_REGISTER_TYPE_D),
+	      brw_imm_d(scratch_offset));
+
+      brw_pop_insn_state(p);
+   }
+
+   {
+      struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
+   
+      insn->header.predicate_control = 0; /* XXX */
+      insn->header.compression_control = BRW_COMPRESSION_NONE; 
+      insn->header.destreg__conditionalmod = msg_reg_nr;
+  
+      brw_set_dest(insn, dest);	/* UW? */
+      brw_set_src0(insn, retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW));
+
+      brw_set_dp_read_message(p->brw,
+			      insn,
+			      255, /* binding table index (255=stateless) */
+			      3,  /* msg_control (3 means 4 Owords) */
+			      BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
+			      1, /* target cache (render/scratch) */
+			      1, /* msg_length */
+			      2, /* response_length */
+			      0); /* eot */
+   }
+}
+
+
+/**
+ * Read a float[4] vector from the data port Data Cache (const buffer).
+ * Location (in buffer) should be a multiple of 16.
+ * Used for fetching shader constants.
+ * If relAddr is true, we'll do an indirect fetch using the address register.
+ */
+void brw_dp_READ_4( struct brw_compile *p,
+                    struct brw_reg dest,
+                    GLboolean relAddr,
+                    GLuint location,
+                    GLuint bind_table_index )
+{
+   /* XXX: relAddr not implemented */
+   GLuint msg_reg_nr = 1;
+   {
+      struct brw_reg b;
+      brw_push_insn_state(p);
+      brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+      brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+      brw_set_mask_control(p, BRW_MASK_DISABLE);
+
+   /* Setup MRF[1] with location/offset into const buffer */
+      b = brw_message_reg(msg_reg_nr);
+      b = retype(b, BRW_REGISTER_TYPE_UD);
+      /* XXX I think we're setting all the dwords of MRF[1] to 'location'.
+       * when the docs say only dword[2] should be set.  Hmmm.  But it works.
+       */
+      brw_MOV(p, b, brw_imm_ud(location));
+      brw_pop_insn_state(p);
+   }
+
+   {
+      struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
+   
+      insn->header.predicate_control = BRW_PREDICATE_NONE;
+      insn->header.compression_control = BRW_COMPRESSION_NONE; 
+      insn->header.destreg__conditionalmod = msg_reg_nr;
+      insn->header.mask_control = BRW_MASK_DISABLE;
+  
+      /* cast dest to a uword[8] vector */
+      dest = retype(vec8(dest), BRW_REGISTER_TYPE_UW);
+
+      brw_set_dest(insn, dest);
+      brw_set_src0(insn, brw_null_reg());
+
+      brw_set_dp_read_message(p->brw,
+			      insn,
+			      bind_table_index,
+			      0,  /* msg_control (0 means 1 Oword) */
+			      BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
+			      0, /* source cache = data cache */
+			      1, /* msg_length */
+			      1, /* response_length (1 Oword) */
+			      0); /* eot */
+   }
+}
+
+
+/**
+ * Read float[4] constant(s) from VS constant buffer.
+ * For relative addressing, two float[4] constants will be read into 'dest'.
+ * Otherwise, one float[4] constant will be read into the lower half of 'dest'.
+ */
+void brw_dp_READ_4_vs(struct brw_compile *p,
+                      struct brw_reg dest,
+                      GLuint oword,
+                      GLboolean relAddr,
+                      struct brw_reg addrReg,
+                      GLuint location,
+                      GLuint bind_table_index)
+{
+   GLuint msg_reg_nr = 1;
+
+   assert(oword < 2);
+   /*
+   printf("vs const read msg, location %u, msg_reg_nr %d\n",
+          location, msg_reg_nr);
+   */
+
+   /* Setup MRF[1] with location/offset into const buffer */
+   {
+      struct brw_reg b;
+
+      brw_push_insn_state(p);
+      brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+      brw_set_mask_control(p, BRW_MASK_DISABLE);
+      brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+      /*brw_set_access_mode(p, BRW_ALIGN_16);*/
+
+      /* XXX I think we're setting all the dwords of MRF[1] to 'location'.
+       * when the docs say only dword[2] should be set.  Hmmm.  But it works.
+       */
+      b = brw_message_reg(msg_reg_nr);
+      b = retype(b, BRW_REGISTER_TYPE_UD);
+      /*b = get_element_ud(b, 2);*/
+      if (relAddr) {
+         brw_ADD(p, b, addrReg, brw_imm_ud(location));
+      }
+      else {
+         brw_MOV(p, b, brw_imm_ud(location));
+      }
+
+      brw_pop_insn_state(p);
+   }
+
+   {
+      struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
+   
+      insn->header.predicate_control = BRW_PREDICATE_NONE;
+      insn->header.compression_control = BRW_COMPRESSION_NONE; 
+      insn->header.destreg__conditionalmod = msg_reg_nr;
+      insn->header.mask_control = BRW_MASK_DISABLE;
+      /*insn->header.access_mode = BRW_ALIGN_16;*/
+  
+      brw_set_dest(insn, dest);
+      brw_set_src0(insn, brw_null_reg());
+
+      brw_set_dp_read_message(p->brw,
+			      insn,
+			      bind_table_index,
+			      oword,  /* 0 = lower Oword, 1 = upper Oword */
+			      BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
+			      0, /* source cache = data cache */
+			      1, /* msg_length */
+			      1, /* response_length (1 Oword) */
+			      0); /* eot */
+   }
+}
+
+
+
+void brw_fb_WRITE(struct brw_compile *p,
+                  struct brw_reg dest,
+                  GLuint msg_reg_nr,
+                  struct brw_reg src0,
+                  GLuint binding_table_index,
+                  GLuint msg_length,
+                  GLuint response_length,
+                  GLboolean eot)
+{
+   struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
+   
+   insn->header.predicate_control = 0; /* XXX */
+   insn->header.compression_control = BRW_COMPRESSION_NONE; 
+   insn->header.destreg__conditionalmod = msg_reg_nr;
+  
+   brw_set_dest(insn, dest);
+   brw_set_src0(insn, src0);
+   brw_set_dp_write_message(p->brw,
+			    insn,
+			    binding_table_index,
+			    BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE, /* msg_control */
+			    BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE, /* msg_type */
+			    msg_length,
+			    1,	/* pixel scoreboard */
+			    response_length, 
+			    eot);
+}
+
+
+/**
+ * Texture sample instruction.
+ * Note: the msg_type plus msg_length values determine exactly what kind
+ * of sampling operation is performed.  See volume 4, page 161 of docs.
+ */
+void brw_SAMPLE(struct brw_compile *p,
+		struct brw_reg dest,
+		GLuint msg_reg_nr,
+		struct brw_reg src0,
+		GLuint binding_table_index,
+		GLuint sampler,
+		GLuint writemask,
+		GLuint msg_type,
+		GLuint response_length,
+		GLuint msg_length,
+		GLboolean eot,
+		GLuint header_present,
+		GLuint simd_mode)
+{
+   GLboolean need_stall = 0;
+   
+   if (writemask == 0) {
+      /*debug_printf("%s: zero writemask??\n", __FUNCTION__); */
+      return;
+   }
+   
+   /* Hardware doesn't do destination dependency checking on send
+    * instructions properly.  Add a workaround which generates the
+    * dependency by other means.  In practice it seems like this bug
+    * only crops up for texture samples, and only where registers are
+    * written by the send and then written again later without being
+    * read in between.  Luckily for us, we already track that
+    * information and use it to modify the writemask for the
+    * instruction, so that is a guide for whether a workaround is
+    * needed.
+    */
+   if (writemask != BRW_WRITEMASK_XYZW) {
+      GLuint dst_offset = 0;
+      GLuint i, newmask = 0, len = 0;
+
+      for (i = 0; i < 4; i++) {
+	 if (writemask & (1<<i))
+	    break;
+	 dst_offset += 2;
+      }
+      for (; i < 4; i++) {
+	 if (!(writemask & (1<<i)))
+	    break;
+	 newmask |= 1<<i;
+	 len++;
+      }
+
+      if (newmask != writemask) {
+	 need_stall = 1;
+         /* debug_printf("need stall %x %x\n", newmask , writemask); */
+      }
+      else {
+	 struct brw_reg m1 = brw_message_reg(msg_reg_nr);
+	 
+	 newmask = ~newmask & BRW_WRITEMASK_XYZW;
+
+	 brw_push_insn_state(p);
+
+	 brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+	 brw_set_mask_control(p, BRW_MASK_DISABLE);
+
+	 brw_MOV(p, m1, brw_vec8_grf(0,0));	 
+  	 brw_MOV(p, get_element_ud(m1, 2), brw_imm_ud(newmask << 12)); 
+
+	 brw_pop_insn_state(p);
+
+  	 src0 = retype(brw_null_reg(), BRW_REGISTER_TYPE_UW); 
+	 dest = offset(dest, dst_offset);
+	 response_length = len * 2;
+      }
+   }
+
+   {
+      struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
+   
+      insn->header.predicate_control = 0; /* XXX */
+      insn->header.compression_control = BRW_COMPRESSION_NONE;
+      insn->header.destreg__conditionalmod = msg_reg_nr;
+
+      brw_set_dest(insn, dest);
+      brw_set_src0(insn, src0);
+      brw_set_sampler_message(p->brw, insn,
+			      binding_table_index,
+			      sampler,
+			      msg_type,
+			      response_length, 
+			      msg_length,
+			      eot,
+			      header_present,
+			      simd_mode);
+   }
+
+   if (need_stall) {
+      struct brw_reg reg = vec8(offset(dest, response_length-1));
+
+      /*  mov (8) r9.0<1>:f    r9.0<8;8,1>:f    { Align1 }
+       */
+      brw_push_insn_state(p);
+      brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+      brw_MOV(p, reg, reg);	      
+      brw_pop_insn_state(p);
+   }
+
+}
+
+/* All these variables are pretty confusing - we might be better off
+ * using bitmasks and macros for this, in the old style.  Or perhaps
+ * just having the caller instantiate the fields in dword3 itself.
+ */
+void brw_urb_WRITE(struct brw_compile *p,
+		   struct brw_reg dest,
+		   GLuint msg_reg_nr,
+		   struct brw_reg src0,
+		   GLboolean allocate,
+		   GLboolean used,
+		   GLuint msg_length,
+		   GLuint response_length,
+		   GLboolean eot,
+		   GLboolean writes_complete,
+		   GLuint offset,
+		   GLuint swizzle)
+{
+   struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
+
+   assert(msg_length < BRW_MAX_MRF);
+
+   brw_set_dest(insn, dest);
+   brw_set_src0(insn, src0);
+   brw_set_src1(insn, brw_imm_d(0));
+
+   insn->header.destreg__conditionalmod = msg_reg_nr;
+
+   brw_set_urb_message(p->brw,
+		       insn,
+		       allocate,
+		       used,
+		       msg_length,
+		       response_length, 
+		       eot, 
+		       writes_complete, 
+		       offset,
+		       swizzle);
+}
+
+void brw_ff_sync(struct brw_compile *p,
+		   struct brw_reg dest,
+		   GLuint msg_reg_nr,
+		   struct brw_reg src0,
+		   GLboolean allocate,
+		   GLboolean used,
+		   GLuint msg_length,
+		   GLuint response_length,
+		   GLboolean eot,
+		   GLboolean writes_complete,
+		   GLuint offset,
+		   GLuint swizzle)
+{
+   struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
+
+   assert(msg_length < 16);
+
+   brw_set_dest(insn, dest);
+   brw_set_src0(insn, src0);
+   brw_set_src1(insn, brw_imm_d(0));
+
+   insn->header.destreg__conditionalmod = msg_reg_nr;
+
+   brw_set_ff_sync_message(p->brw,
+		       insn,
+		       allocate,
+		       used,
+		       msg_length,
+		       response_length, 
+		       eot, 
+		       writes_complete, 
+		       offset,
+		       swizzle);
+}
diff --git a/src/gallium/drivers/i965/brw_eu_util.c b/src/gallium/drivers/i965/brw_eu_util.c
new file mode 100644
index 0000000..5405cf1
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_eu_util.c
@@ -0,0 +1,126 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+      
+
+#include "brw_context.h"
+#include "brw_defines.h"
+#include "brw_eu.h"
+
+
+void brw_math_invert( struct brw_compile *p, 
+			     struct brw_reg dst,
+			     struct brw_reg src)
+{
+   brw_math( p, 
+	     dst,
+	     BRW_MATH_FUNCTION_INV, 
+	     BRW_MATH_SATURATE_NONE,
+	     0,
+	     src,
+	     BRW_MATH_PRECISION_FULL, 
+	     BRW_MATH_DATA_VECTOR );
+}
+
+
+
+void brw_copy4(struct brw_compile *p,
+	       struct brw_reg dst,
+	       struct brw_reg src,
+	       GLuint count)
+{
+   GLuint i;
+
+   dst = vec4(dst);
+   src = vec4(src);
+
+   for (i = 0; i < count; i++)
+   {
+      GLuint delta = i*32;
+      brw_MOV(p, byte_offset(dst, delta),    byte_offset(src, delta));
+      brw_MOV(p, byte_offset(dst, delta+16), byte_offset(src, delta+16));
+   }
+}
+
+
+void brw_copy8(struct brw_compile *p,
+	       struct brw_reg dst,
+	       struct brw_reg src,
+	       GLuint count)
+{
+   GLuint i;
+
+   dst = vec8(dst);
+   src = vec8(src);
+
+   for (i = 0; i < count; i++)
+   {
+      GLuint delta = i*32;
+      brw_MOV(p, byte_offset(dst, delta),    byte_offset(src, delta));
+   }
+}
+
+
+void brw_copy_indirect_to_indirect(struct brw_compile *p,
+				   struct brw_indirect dst_ptr,
+				   struct brw_indirect src_ptr,
+				   GLuint count)
+{
+   GLuint i;
+
+   for (i = 0; i < count; i++)
+   {
+      GLuint delta = i*32;
+      brw_MOV(p, deref_4f(dst_ptr, delta),    deref_4f(src_ptr, delta));
+      brw_MOV(p, deref_4f(dst_ptr, delta+16), deref_4f(src_ptr, delta+16));
+   }
+}
+
+
+void brw_copy_from_indirect(struct brw_compile *p,
+			    struct brw_reg dst,
+			    struct brw_indirect ptr,
+			    GLuint count)
+{
+   GLuint i;
+
+   dst = vec4(dst);
+
+   for (i = 0; i < count; i++)
+   {
+      GLuint delta = i*32;
+      brw_MOV(p, byte_offset(dst, delta),    deref_4f(ptr, delta));
+      brw_MOV(p, byte_offset(dst, delta+16), deref_4f(ptr, delta+16));
+   }
+}
+
+
+
+
diff --git a/src/gallium/drivers/i965/brw_gs.c b/src/gallium/drivers/i965/brw_gs.c
new file mode 100644
index 0000000..921b201
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_gs.c
@@ -0,0 +1,216 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+      
+#include "brw_batchbuffer.h"
+
+#include "brw_defines.h"
+#include "brw_context.h"
+#include "brw_eu.h"
+#include "brw_util.h"
+#include "brw_state.h"
+#include "brw_gs.h"
+
+
+
+static enum pipe_error compile_gs_prog( struct brw_context *brw,
+                                        struct brw_gs_prog_key *key,
+                                        struct brw_winsys_buffer **bo_out )
+{
+   struct brw_gs_compile c;
+   enum pipe_error ret;
+   const GLuint *program;
+   GLuint program_size;
+
+   memset(&c, 0, sizeof(c));
+   
+   c.key = *key;
+   c.need_ff_sync = BRW_IS_IGDNG(brw);
+   /* Need to locate the two positions present in vertex + header.
+    * These are currently hardcoded:
+    */
+   c.nr_attrs = c.key.nr_attrs;
+
+   if (BRW_IS_IGDNG(brw))
+      c.nr_regs = (c.nr_attrs + 1) / 2 + 3;  /* are vertices packed, or reg-aligned? */
+   else
+      c.nr_regs = (c.nr_attrs + 1) / 2 + 1;  /* are vertices packed, or reg-aligned? */
+
+   c.nr_bytes = c.nr_regs * REG_SIZE;
+
+   
+   /* Begin the compilation:
+    */
+   brw_init_compile(brw, &c.func);
+
+   c.func.single_program_flow = 1;
+
+   /* For some reason the thread is spawned with only 4 channels
+    * unmasked.  
+    */
+   brw_set_mask_control(&c.func, BRW_MASK_DISABLE);
+
+
+   /* Note that primitives which don't require a GS program have
+    * already been weeded out by this stage:
+    */
+   switch (key->primitive) {
+   case PIPE_PRIM_QUADS:
+      brw_gs_quads( &c ); 
+      break;
+   case PIPE_PRIM_QUAD_STRIP:
+      brw_gs_quad_strip( &c );
+      break;
+   case PIPE_PRIM_LINE_LOOP:
+      brw_gs_lines( &c );
+      break;
+   case PIPE_PRIM_LINES:
+      if (key->hint_gs_always)
+	 brw_gs_lines( &c );
+      else {
+	 return PIPE_OK;
+      }
+      break;
+   case PIPE_PRIM_TRIANGLES:
+      if (key->hint_gs_always)
+	 brw_gs_tris( &c );
+      else {
+	 return PIPE_OK;
+      }
+      break;
+   case PIPE_PRIM_POINTS:
+      if (key->hint_gs_always)
+	 brw_gs_points( &c );
+      else {
+	 return PIPE_OK;
+      }
+      break;
+   default:
+      assert(0);
+      return PIPE_ERROR_BAD_INPUT;
+   }
+
+   /* get the program
+    */
+   ret = brw_get_program(&c.func, &program, &program_size);
+   if (ret)
+      return ret;
+
+   /* Upload
+    */
+   ret = brw_upload_cache( &brw->cache, BRW_GS_PROG,
+                           &c.key, sizeof(c.key),
+                           NULL, 0,
+                           program, program_size,
+                           &c.prog_data,
+                           &brw->gs.prog_data,
+                           bo_out );
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+static const unsigned gs_prim[PIPE_PRIM_MAX] = {  
+   PIPE_PRIM_POINTS,
+   PIPE_PRIM_LINES,
+   PIPE_PRIM_LINE_LOOP,
+   PIPE_PRIM_LINES,
+   PIPE_PRIM_TRIANGLES,
+   PIPE_PRIM_TRIANGLES,
+   PIPE_PRIM_TRIANGLES,
+   PIPE_PRIM_QUADS,
+   PIPE_PRIM_QUAD_STRIP,
+   PIPE_PRIM_TRIANGLES
+};
+
+static void populate_key( struct brw_context *brw,
+			  struct brw_gs_prog_key *key )
+{
+   const struct brw_fs_signature *sig = &brw->curr.fragment_shader->signature;
+
+   memset(key, 0, sizeof(*key));
+
+   /* PIPE_NEW_FRAGMENT_SIGNATURE */
+   key->nr_attrs = sig->nr_inputs + 1;
+
+   /* BRW_NEW_PRIMITIVE */
+   key->primitive = gs_prim[brw->primitive];
+
+   key->hint_gs_always = 0;	/* debug code? */
+
+   key->need_gs_prog = (key->hint_gs_always ||
+			brw->primitive == PIPE_PRIM_QUADS ||
+			brw->primitive == PIPE_PRIM_QUAD_STRIP ||
+			brw->primitive == PIPE_PRIM_LINE_LOOP);
+}
+
+/* Calculate interpolants for triangle and line rasterization.
+ */
+static int prepare_gs_prog(struct brw_context *brw)
+{
+   struct brw_gs_prog_key key;
+   enum pipe_error ret;
+
+   /* Populate the key:
+    */
+   populate_key(brw, &key);
+
+   if (brw->gs.prog_active != key.need_gs_prog) {
+      brw->state.dirty.cache |= CACHE_NEW_GS_PROG;
+      brw->gs.prog_active = key.need_gs_prog;
+   }
+
+   if (!brw->gs.prog_active)
+      return PIPE_OK;
+
+   if (brw_search_cache(&brw->cache, BRW_GS_PROG,
+                        &key, sizeof(key),
+                        NULL, 0,
+                        &brw->gs.prog_data,
+                        &brw->gs.prog_bo))
+      return PIPE_OK;
+
+   ret = compile_gs_prog( brw, &key, &brw->gs.prog_bo );
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+
+const struct brw_tracked_state brw_gs_prog = {
+   .dirty = {
+      .mesa  = PIPE_NEW_FRAGMENT_SIGNATURE,
+      .brw   = BRW_NEW_PRIMITIVE,
+      .cache = 0,
+   },
+   .prepare = prepare_gs_prog
+};
diff --git a/src/gallium/drivers/i965/brw_gs.h b/src/gallium/drivers/i965/brw_gs.h
new file mode 100644
index 0000000..6e616dc
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_gs.h
@@ -0,0 +1,76 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+ 
+
+#ifndef BRW_GS_H
+#define BRW_GS_H
+
+
+#include "brw_context.h"
+#include "brw_eu.h"
+
+#define MAX_GS_VERTS (4)	     
+
+struct brw_gs_prog_key {
+   GLuint nr_attrs:8;
+   GLuint primitive:4;
+   GLuint hint_gs_always:1;
+   GLuint need_gs_prog:1;
+   GLuint pad:18;
+};
+
+struct brw_gs_compile {
+   struct brw_compile func;
+   struct brw_gs_prog_key key;
+   struct brw_gs_prog_data prog_data;
+   
+   struct {
+      struct brw_reg R0;
+      struct brw_reg vertex[MAX_GS_VERTS];
+   } reg;
+
+   /* 3 different ways of expressing vertex size:
+    */
+   GLuint nr_attrs;
+   GLuint nr_regs;
+   GLuint nr_bytes;
+   GLboolean need_ff_sync;
+};
+
+#define ATTR_SIZE  (4*4)
+
+void brw_gs_quads( struct brw_gs_compile *c );
+void brw_gs_quad_strip( struct brw_gs_compile *c );
+void brw_gs_tris( struct brw_gs_compile *c );
+void brw_gs_lines( struct brw_gs_compile *c );
+void brw_gs_points( struct brw_gs_compile *c );
+
+#endif
diff --git a/src/gallium/drivers/i965/brw_gs_emit.c b/src/gallium/drivers/i965/brw_gs_emit.c
new file mode 100644
index 0000000..fd8e2ac
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_gs_emit.c
@@ -0,0 +1,181 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+ 
+
+#include "brw_batchbuffer.h"
+
+#include "brw_defines.h"
+#include "brw_context.h"
+#include "brw_eu.h"
+#include "brw_util.h"
+#include "brw_gs.h"
+
+static void brw_gs_alloc_regs( struct brw_gs_compile *c,
+			       GLuint nr_verts )
+{
+   GLuint i = 0,j;
+
+   /* Register usage is static, precompute here:
+    */
+   c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
+
+   /* Payload vertices plus space for more generated vertices:
+    */
+   for (j = 0; j < nr_verts; j++) {
+      c->reg.vertex[j] = brw_vec4_grf(i, 0);
+      i += c->nr_regs;
+   }
+
+   c->prog_data.urb_read_length = c->nr_regs; 
+   c->prog_data.total_grf = i;
+}
+
+
+static void brw_gs_emit_vue(struct brw_gs_compile *c, 
+			    struct brw_reg vert,
+			    GLboolean last,
+			    GLuint header)
+{
+   struct brw_compile *p = &c->func;
+   GLboolean allocate = !last;
+
+   /* Overwrite PrimType and PrimStart in the message header, for
+    * each vertex in turn:
+    */
+   brw_MOV(p, get_element_ud(c->reg.R0, 2), brw_imm_ud(header));
+
+   /* Copy the vertex from vertn into m1..mN+1:
+    */
+   brw_copy8(p, brw_message_reg(1), vert, c->nr_regs);
+
+   /* Send each vertex as a seperate write to the urb.  This is
+    * different to the concept in brw_sf_emit.c, where subsequent
+    * writes are used to build up a single urb entry.  Each of these
+    * writes instantiates a seperate urb entry, and a new one must be
+    * allocated each time.
+    */
+   brw_urb_WRITE(p, 
+		 allocate ? c->reg.R0 : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
+		 0,
+		 c->reg.R0,
+		 allocate,
+		 1,		/* used */
+		 c->nr_regs + 1, /* msg length */
+		 allocate ? 1 : 0, /* response length */
+		 allocate ? 0 : 1, /* eot */
+		 1,		/* writes_complete */
+		 0,		/* urb offset */
+		 BRW_URB_SWIZZLE_NONE);
+}
+
+static void brw_gs_ff_sync(struct brw_gs_compile *c, int num_prim)
+{
+	struct brw_compile *p = &c->func;
+	brw_MOV(p, get_element_ud(c->reg.R0, 1), brw_imm_ud(num_prim));
+	brw_ff_sync(p, 
+				c->reg.R0,
+				0,
+				c->reg.R0,
+				1,	
+				1,		/* used */
+				1,  	/* msg length */
+				1,		/* response length */
+				0,		/* eot */
+				1,		/* write compelete */
+				0,		/* urb offset */
+				BRW_URB_SWIZZLE_NONE);
+}
+
+
+void brw_gs_quads( struct brw_gs_compile *c )
+{
+   brw_gs_alloc_regs(c, 4);
+   
+   /* Use polygons for correct edgeflag behaviour. Note that vertex 3
+    * is the PV for quads, but vertex 0 for polygons:
+    */
+   if (c->need_ff_sync)
+	   brw_gs_ff_sync(c, 1);    
+   brw_gs_emit_vue(c, c->reg.vertex[3], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START));
+   brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2));
+   brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_POLYGON << 2)); 
+   brw_gs_emit_vue(c, c->reg.vertex[2], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END));
+}
+
+void brw_gs_quad_strip( struct brw_gs_compile *c )
+{
+   brw_gs_alloc_regs(c, 4);
+   
+   if (c->need_ff_sync)
+	   brw_gs_ff_sync(c, 1);      
+   brw_gs_emit_vue(c, c->reg.vertex[2], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START));
+   brw_gs_emit_vue(c, c->reg.vertex[3], 0, (_3DPRIM_POLYGON << 2));
+   brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2)); 
+   brw_gs_emit_vue(c, c->reg.vertex[1], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END));
+}
+
+void brw_gs_tris( struct brw_gs_compile *c )
+{
+   brw_gs_alloc_regs(c, 3);
+
+   if (c->need_ff_sync)
+	   brw_gs_ff_sync(c, 1);      
+   brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_TRILIST << 2) | R02_PRIM_START));
+   brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_TRILIST << 2));
+   brw_gs_emit_vue(c, c->reg.vertex[2], 1, ((_3DPRIM_TRILIST << 2) | R02_PRIM_END));
+}
+
+void brw_gs_lines( struct brw_gs_compile *c )
+{
+   brw_gs_alloc_regs(c, 2);
+
+   if (c->need_ff_sync)
+	   brw_gs_ff_sync(c, 1);      
+   brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_LINESTRIP << 2) | R02_PRIM_START));
+   brw_gs_emit_vue(c, c->reg.vertex[1], 1, ((_3DPRIM_LINESTRIP << 2) | R02_PRIM_END));
+}
+
+void brw_gs_points( struct brw_gs_compile *c )
+{
+   brw_gs_alloc_regs(c, 1);
+
+   if (c->need_ff_sync)
+	   brw_gs_ff_sync(c, 1);      
+   brw_gs_emit_vue(c, c->reg.vertex[0], 1, ((_3DPRIM_POINTLIST << 2) | R02_PRIM_START | R02_PRIM_END));
+}
+
+
+
+
+
+
+
+
diff --git a/src/gallium/drivers/i965/brw_gs_state.c b/src/gallium/drivers/i965/brw_gs_state.c
new file mode 100644
index 0000000..b64ec28
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_gs_state.c
@@ -0,0 +1,169 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+ 
+#include "util/u_math.h"
+
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+#include "brw_debug.h"
+
+struct brw_gs_unit_key {
+   unsigned int total_grf;
+   unsigned int urb_entry_read_length;
+
+   unsigned int curbe_offset;
+
+   unsigned int nr_urb_entries, urb_size;
+   GLboolean prog_active;
+};
+
+static void
+gs_unit_populate_key(struct brw_context *brw, struct brw_gs_unit_key *key)
+{
+   memset(key, 0, sizeof(*key));
+
+   /* CACHE_NEW_GS_PROG */
+   key->prog_active = brw->gs.prog_active;
+   if (key->prog_active) {
+      key->total_grf = brw->gs.prog_data->total_grf;
+      key->urb_entry_read_length = brw->gs.prog_data->urb_read_length;
+   } else {
+      key->total_grf = 1;
+      key->urb_entry_read_length = 1;
+   }
+
+   /* BRW_NEW_CURBE_OFFSETS */
+   key->curbe_offset = brw->curbe.clip_start;
+
+   /* BRW_NEW_URB_FENCE */
+   key->nr_urb_entries = brw->urb.nr_gs_entries;
+   key->urb_size = brw->urb.vsize;
+}
+
+static enum pipe_error
+gs_unit_create_from_key(struct brw_context *brw, 
+                        struct brw_gs_unit_key *key,
+                        struct brw_winsys_reloc *reloc,
+                        unsigned nr_reloc,
+                        struct brw_winsys_buffer **bo_out)
+{
+   struct brw_gs_unit_state gs;
+   enum pipe_error ret;
+
+
+   memset(&gs, 0, sizeof(gs));
+
+   /* reloc */
+   gs.thread0.grf_reg_count = align(key->total_grf, 16) / 16 - 1;
+   gs.thread0.kernel_start_pointer = 0;
+
+   gs.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
+   gs.thread1.single_program_flow = 1;
+
+   gs.thread3.dispatch_grf_start_reg = 1;
+   gs.thread3.const_urb_entry_read_offset = 0;
+   gs.thread3.const_urb_entry_read_length = 0;
+   gs.thread3.urb_entry_read_offset = 0;
+   gs.thread3.urb_entry_read_length = key->urb_entry_read_length;
+
+   gs.thread4.nr_urb_entries = key->nr_urb_entries;
+   gs.thread4.urb_entry_allocation_size = key->urb_size - 1;
+
+   if (key->nr_urb_entries >= 8)
+      gs.thread4.max_threads = 1;
+   else
+      gs.thread4.max_threads = 0;
+
+   if (BRW_IS_IGDNG(brw))
+      gs.thread4.rendering_enable = 1;
+
+   if (BRW_DEBUG & DEBUG_STATS)
+      gs.thread4.stats_enable = 1;
+
+   ret = brw_upload_cache(&brw->cache, BRW_GS_UNIT,
+                          key, sizeof(*key),
+                          reloc, nr_reloc,
+                          &gs, sizeof(gs),
+                          NULL, NULL,
+                          bo_out);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+static enum pipe_error prepare_gs_unit(struct brw_context *brw)
+{
+   struct brw_gs_unit_key key;
+   enum pipe_error ret;
+   struct brw_winsys_reloc reloc[1];
+   unsigned nr_reloc = 0;
+   unsigned grf_reg_count;
+
+   gs_unit_populate_key(brw, &key);
+
+   grf_reg_count = (align(key.total_grf, 16) / 16 - 1);
+
+   /* GS program relocation */
+   if (key.prog_active) {
+      make_reloc(&reloc[nr_reloc++],
+                 BRW_USAGE_STATE,
+                 grf_reg_count << 1,
+                 offsetof(struct brw_gs_unit_state, thread0),
+                 brw->gs.prog_bo);
+   }
+
+   if (brw_search_cache(&brw->cache, BRW_GS_UNIT,
+                        &key, sizeof(key),
+                        reloc, nr_reloc,
+                        NULL,
+                        &brw->gs.state_bo))
+      return PIPE_OK;
+
+   ret = gs_unit_create_from_key(brw, &key,
+                                 reloc, nr_reloc,
+                                 &brw->gs.state_bo);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+const struct brw_tracked_state brw_gs_unit = {
+   .dirty = {
+      .mesa  = 0,
+      .brw   = (BRW_NEW_CURBE_OFFSETS |
+		BRW_NEW_URB_FENCE),
+      .cache = CACHE_NEW_GS_PROG
+   },
+   .prepare = prepare_gs_unit,
+};
diff --git a/src/gallium/drivers/i965/brw_misc_state.c b/src/gallium/drivers/i965/brw_misc_state.c
new file mode 100644
index 0000000..e4b2422
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_misc_state.c
@@ -0,0 +1,513 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+ 
+
+
+#include "brw_debug.h"
+#include "brw_batchbuffer.h"
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+#include "brw_screen.h"
+#include "brw_pipe_rast.h"
+
+
+
+
+
+/***********************************************************************
+ * Blend color
+ */
+
+static int upload_blend_constant_color(struct brw_context *brw)
+{
+   BRW_CACHED_BATCH_STRUCT(brw, &brw->curr.bcc);
+   return 0;
+}
+
+
+const struct brw_tracked_state brw_blend_constant_color = {
+   .dirty = {
+      .mesa = PIPE_NEW_BLEND_COLOR,
+      .brw = 0,
+      .cache = 0
+   },
+   .emit = upload_blend_constant_color
+};
+
+/***********************************************************************
+ * Drawing rectangle - framebuffer dimensions
+ */
+static int upload_drawing_rect(struct brw_context *brw)
+{
+   BEGIN_BATCH(4, NO_LOOP_CLIPRECTS);
+   OUT_BATCH(_3DSTATE_DRAWRECT_INFO_I965);
+   OUT_BATCH(0);
+   OUT_BATCH(((brw->curr.fb.width - 1) & 0xffff) |
+	    ((brw->curr.fb.height - 1) << 16));
+   OUT_BATCH(0);
+   ADVANCE_BATCH();
+   return 0;
+}
+
+const struct brw_tracked_state brw_drawing_rect = {
+   .dirty = {
+      .mesa = PIPE_NEW_FRAMEBUFFER_DIMENSIONS,
+      .brw = 0,
+      .cache = 0
+   },
+   .emit = upload_drawing_rect
+};
+
+
+/***********************************************************************
+ * Binding table pointers
+ */
+
+static int prepare_binding_table_pointers(struct brw_context *brw)
+{
+   brw_add_validated_bo(brw, brw->vs.bind_bo);
+   brw_add_validated_bo(brw, brw->wm.bind_bo);
+   return 0;
+}
+
+/**
+ * Upload the binding table pointers, which point each stage's array of surface
+ * state pointers.
+ *
+ * The binding table pointers are relative to the surface state base address,
+ * which is 0.
+ */
+static int upload_binding_table_pointers(struct brw_context *brw)
+{
+   BEGIN_BATCH(6, IGNORE_CLIPRECTS);
+   OUT_BATCH(CMD_BINDING_TABLE_PTRS << 16 | (6 - 2));
+   if (brw->vs.bind_bo != NULL)
+      OUT_RELOC(brw->vs.bind_bo, 
+		BRW_USAGE_SAMPLER,
+		0); /* vs */
+   else
+      OUT_BATCH(0);
+   OUT_BATCH(0); /* gs */
+   OUT_BATCH(0); /* clip */
+   OUT_BATCH(0); /* sf */
+   OUT_RELOC(brw->wm.bind_bo,
+	     BRW_USAGE_SAMPLER,
+	     0); /* wm/ps */
+   ADVANCE_BATCH();
+   return 0;
+}
+
+const struct brw_tracked_state brw_binding_table_pointers = {
+   .dirty = {
+      .mesa = 0,
+      .brw = BRW_NEW_BATCH,
+      .cache = CACHE_NEW_SURF_BIND,
+   },
+   .prepare = prepare_binding_table_pointers,
+   .emit = upload_binding_table_pointers,
+};
+
+
+/**********************************************************************
+ * Upload pointers to the per-stage state.
+ *
+ * The state pointers in this packet are all relative to the general state
+ * base address set by CMD_STATE_BASE_ADDRESS, which is 0.
+ */
+static int upload_pipelined_state_pointers(struct brw_context *brw )
+{
+   BEGIN_BATCH(7, IGNORE_CLIPRECTS);
+   OUT_BATCH(CMD_PIPELINED_STATE_POINTERS << 16 | (7 - 2));
+   OUT_RELOC(brw->vs.state_bo, 
+	     BRW_USAGE_STATE,
+	     0);
+   if (brw->gs.prog_active)
+      OUT_RELOC(brw->gs.state_bo, 
+		BRW_USAGE_STATE,
+		1);
+   else
+      OUT_BATCH(0);
+   OUT_RELOC(brw->clip.state_bo, 
+	     BRW_USAGE_STATE,
+	     1);
+   OUT_RELOC(brw->sf.state_bo,
+	     BRW_USAGE_STATE,
+	     0);
+   OUT_RELOC(brw->wm.state_bo,
+	     BRW_USAGE_STATE,
+	     0);
+   OUT_RELOC(brw->cc.state_bo,
+	     BRW_USAGE_STATE,
+	     0);
+   ADVANCE_BATCH();
+
+   brw->state.dirty.brw |= BRW_NEW_PSP;
+   return 0;
+}
+
+
+static int prepare_psp_urb_cbs(struct brw_context *brw)
+{
+   brw_add_validated_bo(brw, brw->vs.state_bo);
+   brw_add_validated_bo(brw, brw->gs.state_bo);
+   brw_add_validated_bo(brw, brw->clip.state_bo);
+   brw_add_validated_bo(brw, brw->sf.state_bo);
+   brw_add_validated_bo(brw, brw->wm.state_bo);
+   brw_add_validated_bo(brw, brw->cc.state_bo);
+   return 0;
+}
+
+static int upload_psp_urb_cbs(struct brw_context *brw )
+{
+   int ret;
+   
+   ret = upload_pipelined_state_pointers(brw);
+   if (ret)
+      return ret;
+
+   ret = brw_upload_urb_fence(brw);
+   if (ret)
+      return ret;
+
+   ret = brw_upload_cs_urb_state(brw);
+   if (ret)
+      return ret;
+
+   return 0;
+}
+
+const struct brw_tracked_state brw_psp_urb_cbs = {
+   .dirty = {
+      .mesa = 0,
+      .brw = BRW_NEW_URB_FENCE | BRW_NEW_BATCH,
+      .cache = (CACHE_NEW_VS_UNIT | 
+		CACHE_NEW_GS_UNIT | 
+		CACHE_NEW_GS_PROG | 
+		CACHE_NEW_CLIP_UNIT | 
+		CACHE_NEW_SF_UNIT | 
+		CACHE_NEW_WM_UNIT | 
+		CACHE_NEW_CC_UNIT)
+   },
+   .prepare = prepare_psp_urb_cbs,
+   .emit = upload_psp_urb_cbs,
+};
+
+
+/***********************************************************************
+ * Depth buffer 
+ */
+
+static int prepare_depthbuffer(struct brw_context *brw)
+{
+   struct pipe_surface *zsbuf = brw->curr.fb.zsbuf;
+
+   if (zsbuf)
+      brw_add_validated_bo(brw, brw_surface(zsbuf)->bo);
+
+   return 0;
+}
+
+static int emit_depthbuffer(struct brw_context *brw)
+{
+   struct pipe_surface *surface = brw->curr.fb.zsbuf;
+   unsigned int len = (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? 6 : 5;
+
+   if (surface == NULL) {
+      BEGIN_BATCH(len, IGNORE_CLIPRECTS);
+      OUT_BATCH(CMD_DEPTH_BUFFER << 16 | (len - 2));
+      OUT_BATCH((BRW_DEPTHFORMAT_D32_FLOAT << 18) |
+		(BRW_SURFACE_NULL << 29));
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+      OUT_BATCH(0);
+
+      if (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw))
+         OUT_BATCH(0);
+
+      ADVANCE_BATCH();
+   } else {
+      struct brw_winsys_buffer *bo;
+      unsigned int format;
+      unsigned int pitch;
+      unsigned int cpp;
+
+      switch (surface->format) {
+      case PIPE_FORMAT_Z16_UNORM:
+	 format = BRW_DEPTHFORMAT_D16_UNORM;
+	 cpp = 2;
+	 break;
+      case PIPE_FORMAT_X8Z24_UNORM:
+      case PIPE_FORMAT_S8Z24_UNORM:
+	 format = BRW_DEPTHFORMAT_D24_UNORM_S8_UINT;
+	 cpp = 4;
+	 break;
+      case PIPE_FORMAT_Z32_FLOAT:
+	 format = BRW_DEPTHFORMAT_D32_FLOAT;
+	 cpp = 4;
+	 break;
+      default:
+	 assert(0);
+	 return PIPE_ERROR_BAD_INPUT;
+      }
+
+      bo = brw_surface(surface)->bo;
+      pitch = brw_surface(surface)->pitch;
+
+      BEGIN_BATCH(len, IGNORE_CLIPRECTS);
+      OUT_BATCH(CMD_DEPTH_BUFFER << 16 | (len - 2));
+      OUT_BATCH(((pitch * cpp) - 1) |
+		(format << 18) |
+		(BRW_TILEWALK_YMAJOR << 26) |
+		((surface->layout != PIPE_SURFACE_LAYOUT_LINEAR) << 27) |
+		(BRW_SURFACE_2D << 29));
+      OUT_RELOC(bo,
+		BRW_USAGE_DEPTH_BUFFER,
+		surface->offset);
+      OUT_BATCH((BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1) |
+		((pitch - 1) << 6) |
+		((surface->height - 1) << 19));
+      OUT_BATCH(0);
+
+      if (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw))
+         OUT_BATCH(0);
+
+      ADVANCE_BATCH();
+   }
+
+   return 0;
+}
+
+const struct brw_tracked_state brw_depthbuffer = {
+   .dirty = {
+      .mesa = PIPE_NEW_DEPTH_BUFFER,
+      .brw = BRW_NEW_BATCH,
+      .cache = 0,
+   },
+   .prepare = prepare_depthbuffer,
+   .emit = emit_depthbuffer,
+};
+
+
+
+/***********************************************************************
+ * Polygon stipple packet
+ */
+
+static int upload_polygon_stipple(struct brw_context *brw)
+{
+   BRW_CACHED_BATCH_STRUCT(brw, &brw->curr.bps);
+   return 0;
+}
+
+const struct brw_tracked_state brw_polygon_stipple = {
+   .dirty = {
+      .mesa = PIPE_NEW_POLYGON_STIPPLE,
+      .brw = 0,
+      .cache = 0
+   },
+   .emit = upload_polygon_stipple
+};
+
+
+/***********************************************************************
+ * Line stipple packet
+ */
+
+static int upload_line_stipple(struct brw_context *brw)
+{
+   const struct brw_line_stipple *bls = &brw->curr.rast->bls;
+   if (bls->header.opcode) {
+      BRW_CACHED_BATCH_STRUCT(brw, bls);
+   }
+   return 0;
+}
+
+const struct brw_tracked_state brw_line_stipple = {
+   .dirty = {
+      .mesa = PIPE_NEW_RAST,
+      .brw = 0,
+      .cache = 0
+   },
+   .emit = upload_line_stipple
+};
+
+
+/***********************************************************************
+ * Misc invarient state packets
+ */
+
+static int upload_invarient_state( struct brw_context *brw )
+{
+   {
+      /* 0x61040000  Pipeline Select */
+      /*     PipelineSelect            : 0 */
+      struct brw_pipeline_select ps;
+
+      memset(&ps, 0, sizeof(ps));
+      if (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw))
+	 ps.header.opcode = CMD_PIPELINE_SELECT_GM45;
+      else
+	 ps.header.opcode = CMD_PIPELINE_SELECT_965;
+      ps.header.pipeline_select = 0;
+      BRW_BATCH_STRUCT(brw, &ps);
+   }
+
+   {
+      struct brw_global_depth_offset_clamp gdo;
+      memset(&gdo, 0, sizeof(gdo));
+
+      /* Disable depth offset clamping. 
+       */
+      gdo.header.opcode = CMD_GLOBAL_DEPTH_OFFSET_CLAMP;
+      gdo.header.length = sizeof(gdo)/4 - 2;
+      gdo.depth_offset_clamp = 0.0;
+
+      BRW_BATCH_STRUCT(brw, &gdo);
+   }
+
+
+   /* 0x61020000  State Instruction Pointer */
+   {
+      struct brw_system_instruction_pointer sip;
+      memset(&sip, 0, sizeof(sip));
+
+      sip.header.opcode = CMD_STATE_INSN_POINTER;
+      sip.header.length = 0;
+      sip.bits0.pad = 0;
+      sip.bits0.system_instruction_pointer = 0;
+      BRW_BATCH_STRUCT(brw, &sip);
+   }
+
+   /* VF Statistics */
+   {
+      struct brw_vf_statistics vfs;
+      memset(&vfs, 0, sizeof(vfs));
+
+      if (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) 
+	 vfs.opcode = CMD_VF_STATISTICS_GM45;
+      else 
+	 vfs.opcode = CMD_VF_STATISTICS_965;
+
+      if (BRW_DEBUG & DEBUG_STATS)
+	 vfs.statistics_enable = 1; 
+
+      BRW_BATCH_STRUCT(brw, &vfs);
+   }
+   
+   if (!BRW_IS_965(brw))
+   {
+      struct brw_aa_line_parameters balp;
+
+      /* use legacy aa line coverage computation */
+      memset(&balp, 0, sizeof(balp));
+      balp.header.opcode = CMD_AA_LINE_PARAMETERS;
+      balp.header.length = sizeof(balp) / 4 - 2;
+   
+      BRW_BATCH_STRUCT(brw, &balp);
+   }
+
+   {
+      struct brw_polygon_stipple_offset bpso;
+      
+      /* This is invarient state in gallium:
+       */
+      memset(&bpso, 0, sizeof(bpso));
+      bpso.header.opcode = CMD_POLY_STIPPLE_OFFSET;
+      bpso.header.length = sizeof(bpso)/4-2;
+      bpso.bits0.y_offset = 0;
+      bpso.bits0.x_offset = 0;
+
+      BRW_BATCH_STRUCT(brw, &bpso);
+   }
+   
+   return 0;
+}
+
+const struct brw_tracked_state brw_invarient_state = {
+   .dirty = {
+      .mesa = 0,
+      .brw = BRW_NEW_CONTEXT,
+      .cache = 0
+   },
+   .emit = upload_invarient_state
+};
+
+
+/***********************************************************************
+ * State base address 
+ */
+
+/**
+ * Define the base addresses which some state is referenced from.
+ *
+ * This allows us to avoid having to emit relocations in many places for
+ * cached state, and instead emit pointers inside of large, mostly-static
+ * state pools.  This comes at the expense of memory, and more expensive cache
+ * misses.
+ */
+static int upload_state_base_address( struct brw_context *brw )
+{
+   /* Output the structure (brw_state_base_address) directly to the
+    * batchbuffer, so we can emit relocations inline.
+    */
+   if (BRW_IS_IGDNG(brw)) {
+       BEGIN_BATCH(8, IGNORE_CLIPRECTS);
+       OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (8 - 2));
+       OUT_BATCH(1); /* General state base address */
+       OUT_BATCH(1); /* Surface state base address */
+       OUT_BATCH(1); /* Indirect object base address */
+       OUT_BATCH(1); /* Instruction base address */
+       OUT_BATCH(1); /* General state upper bound */
+       OUT_BATCH(1); /* Indirect object upper bound */
+       OUT_BATCH(1); /* Instruction access upper bound */
+       ADVANCE_BATCH();
+   } else {
+       BEGIN_BATCH(6, IGNORE_CLIPRECTS);
+       OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (6 - 2));
+       OUT_BATCH(1); /* General state base address */
+       OUT_BATCH(1); /* Surface state base address */
+       OUT_BATCH(1); /* Indirect object base address */
+       OUT_BATCH(1); /* General state upper bound */
+       OUT_BATCH(1); /* Indirect object upper bound */
+       ADVANCE_BATCH();
+   }
+   return 0;
+}
+
+const struct brw_tracked_state brw_state_base_address = {
+   .dirty = {
+      .mesa = 0,
+      .brw = BRW_NEW_CONTEXT,
+      .cache = 0,
+   },
+   .emit = upload_state_base_address
+};
diff --git a/src/gallium/drivers/i965/brw_pipe_blend.c b/src/gallium/drivers/i965/brw_pipe_blend.c
new file mode 100644
index 0000000..b759a91
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_pipe_blend.c
@@ -0,0 +1,208 @@
+
+#include "util/u_memory.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+
+#include "brw_context.h"
+#include "brw_defines.h"
+#include "brw_debug.h"
+
+static int translate_logicop(unsigned logicop)
+{
+   switch (logicop) {
+   case PIPE_LOGICOP_CLEAR:
+      return BRW_LOGICOPFUNCTION_CLEAR;
+   case PIPE_LOGICOP_AND:
+      return BRW_LOGICOPFUNCTION_AND;
+   case PIPE_LOGICOP_AND_REVERSE:
+      return BRW_LOGICOPFUNCTION_AND_REVERSE;
+   case PIPE_LOGICOP_COPY:
+      return BRW_LOGICOPFUNCTION_COPY;
+   case PIPE_LOGICOP_COPY_INVERTED:
+      return BRW_LOGICOPFUNCTION_COPY_INVERTED;
+   case PIPE_LOGICOP_AND_INVERTED:
+      return BRW_LOGICOPFUNCTION_AND_INVERTED;
+   case PIPE_LOGICOP_NOOP:
+      return BRW_LOGICOPFUNCTION_NOOP;
+   case PIPE_LOGICOP_XOR:
+      return BRW_LOGICOPFUNCTION_XOR;
+   case PIPE_LOGICOP_OR:
+      return BRW_LOGICOPFUNCTION_OR;
+   case PIPE_LOGICOP_OR_INVERTED:
+      return BRW_LOGICOPFUNCTION_OR_INVERTED;
+   case PIPE_LOGICOP_NOR:
+      return BRW_LOGICOPFUNCTION_NOR;
+   case PIPE_LOGICOP_EQUIV:
+      return BRW_LOGICOPFUNCTION_EQUIV;
+   case PIPE_LOGICOP_INVERT:
+      return BRW_LOGICOPFUNCTION_INVERT;
+   case PIPE_LOGICOP_OR_REVERSE:
+      return BRW_LOGICOPFUNCTION_OR_REVERSE;
+   case PIPE_LOGICOP_NAND:
+      return BRW_LOGICOPFUNCTION_NAND;
+   case PIPE_LOGICOP_SET:
+      return BRW_LOGICOPFUNCTION_SET;
+   default:
+      assert(0);
+      return BRW_LOGICOPFUNCTION_SET;
+   }
+}
+
+
+static unsigned translate_blend_equation( unsigned mode )
+{
+   switch (mode) {
+   case PIPE_BLEND_ADD: 
+      return BRW_BLENDFUNCTION_ADD; 
+   case PIPE_BLEND_MIN: 
+      return BRW_BLENDFUNCTION_MIN; 
+   case PIPE_BLEND_MAX: 
+      return BRW_BLENDFUNCTION_MAX; 
+   case PIPE_BLEND_SUBTRACT: 
+      return BRW_BLENDFUNCTION_SUBTRACT; 
+   case PIPE_BLEND_REVERSE_SUBTRACT: 
+      return BRW_BLENDFUNCTION_REVERSE_SUBTRACT; 
+   default: 
+      assert(0);
+      return BRW_BLENDFUNCTION_ADD;
+   }
+}
+
+static unsigned translate_blend_factor( unsigned factor )
+{
+   switch(factor) {
+   case PIPE_BLENDFACTOR_ZERO: 
+      return BRW_BLENDFACTOR_ZERO; 
+   case PIPE_BLENDFACTOR_SRC_ALPHA: 
+      return BRW_BLENDFACTOR_SRC_ALPHA; 
+   case PIPE_BLENDFACTOR_ONE: 
+      return BRW_BLENDFACTOR_ONE; 
+   case PIPE_BLENDFACTOR_SRC_COLOR: 
+      return BRW_BLENDFACTOR_SRC_COLOR; 
+   case PIPE_BLENDFACTOR_INV_SRC_COLOR: 
+      return BRW_BLENDFACTOR_INV_SRC_COLOR; 
+   case PIPE_BLENDFACTOR_DST_COLOR: 
+      return BRW_BLENDFACTOR_DST_COLOR; 
+   case PIPE_BLENDFACTOR_INV_DST_COLOR: 
+      return BRW_BLENDFACTOR_INV_DST_COLOR; 
+   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+      return BRW_BLENDFACTOR_INV_SRC_ALPHA; 
+   case PIPE_BLENDFACTOR_DST_ALPHA: 
+      return BRW_BLENDFACTOR_DST_ALPHA; 
+   case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+      return BRW_BLENDFACTOR_INV_DST_ALPHA; 
+   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: 
+      return BRW_BLENDFACTOR_SRC_ALPHA_SATURATE;
+   case PIPE_BLENDFACTOR_CONST_COLOR:
+      return BRW_BLENDFACTOR_CONST_COLOR; 
+   case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+      return BRW_BLENDFACTOR_INV_CONST_COLOR;
+   case PIPE_BLENDFACTOR_CONST_ALPHA:
+      return BRW_BLENDFACTOR_CONST_ALPHA; 
+   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+      return BRW_BLENDFACTOR_INV_CONST_ALPHA;
+   default:
+      assert(0);
+      return BRW_BLENDFACTOR_ZERO;
+   }   
+}
+
+static void *brw_create_blend_state( struct pipe_context *pipe,
+				     const struct pipe_blend_state *templ )
+{
+   struct brw_blend_state *blend = CALLOC_STRUCT(brw_blend_state);
+   if (blend == NULL)
+      return NULL;
+
+   if (templ->logicop_enable) {
+      blend->cc2.logicop_enable = 1;
+      blend->cc5.logicop_func = translate_logicop(templ->logicop_func);
+   } 
+   else if (templ->blend_enable) {
+      blend->cc6.dest_blend_factor = translate_blend_factor(templ->rgb_dst_factor);
+      blend->cc6.src_blend_factor = translate_blend_factor(templ->rgb_src_factor);
+      blend->cc6.blend_function = translate_blend_equation(templ->rgb_func);
+
+      blend->cc5.ia_dest_blend_factor = translate_blend_factor(templ->alpha_dst_factor);
+      blend->cc5.ia_src_blend_factor = translate_blend_factor(templ->alpha_src_factor);
+      blend->cc5.ia_blend_function = translate_blend_equation(templ->alpha_func);
+
+      blend->cc3.blend_enable = 1;
+      blend->cc3.ia_blend_enable = 
+	 (blend->cc6.dest_blend_factor != blend->cc5.ia_dest_blend_factor ||
+	  blend->cc6.src_blend_factor != blend->cc5.ia_src_blend_factor ||
+	  blend->cc6.blend_function != blend->cc5.ia_blend_function);
+
+      /* Per-surface blend enables, currently just follow global
+       * state:
+       */
+      blend->ss0.color_blend = 1;
+   }
+
+   blend->cc5.dither_enable = templ->dither;
+
+   if (BRW_DEBUG & DEBUG_STATS)
+      blend->cc5.statistics_enable = 1;
+
+   /* Per-surface color mask -- just follow global state:
+    */
+   blend->ss0.writedisable_red   = (templ->colormask & PIPE_MASK_R) ? 0 : 1;
+   blend->ss0.writedisable_green = (templ->colormask & PIPE_MASK_G) ? 0 : 1;
+   blend->ss0.writedisable_blue  = (templ->colormask & PIPE_MASK_B) ? 0 : 1;
+   blend->ss0.writedisable_alpha = (templ->colormask & PIPE_MASK_A) ? 0 : 1;
+
+   return (void *)blend;
+}
+
+static void brw_bind_blend_state(struct pipe_context *pipe,
+				 void *cso)
+{
+   struct brw_context *brw = brw_context(pipe);
+   brw->curr.blend = (const struct brw_blend_state *)cso;
+   brw->state.dirty.mesa |= PIPE_NEW_BLEND;
+}
+
+static void brw_delete_blend_state(struct pipe_context *pipe,
+				  void *cso)
+{
+   struct brw_context *brw = brw_context(pipe);
+   assert((const void *)cso != (const void *)brw->curr.blend);
+   FREE(cso);
+}
+
+
+static void brw_set_blend_color(struct pipe_context *pipe,
+				const struct pipe_blend_color *blend_color)
+{
+   struct brw_context *brw = brw_context(pipe);
+   struct brw_blend_constant_color *bcc = &brw->curr.bcc;
+
+   bcc->blend_constant_color[0] = blend_color->color[0];
+   bcc->blend_constant_color[1] = blend_color->color[1];
+   bcc->blend_constant_color[2] = blend_color->color[2];
+   bcc->blend_constant_color[3] = blend_color->color[3];
+
+   brw->state.dirty.mesa |= PIPE_NEW_BLEND_COLOR;
+}
+
+
+void brw_pipe_blend_init( struct brw_context *brw )
+{
+   brw->base.set_blend_color = brw_set_blend_color;
+   brw->base.create_blend_state = brw_create_blend_state;
+   brw->base.bind_blend_state = brw_bind_blend_state;
+   brw->base.delete_blend_state = brw_delete_blend_state;
+
+   {
+      struct brw_blend_constant_color *bcc = &brw->curr.bcc;
+
+      memset(bcc, 0, sizeof(*bcc));      
+      bcc->header.opcode = CMD_BLEND_CONSTANT_COLOR;
+      bcc->header.length = sizeof(*bcc)/4-2;
+   }
+
+}
+
+void brw_pipe_blend_cleanup( struct brw_context *brw )
+{
+}
diff --git a/src/gallium/drivers/i965/brw_pipe_clear.c b/src/gallium/drivers/i965/brw_pipe_clear.c
new file mode 100644
index 0000000..452e1e8
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_pipe_clear.c
@@ -0,0 +1,218 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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.
+ * 
+ **************************************************************************/
+
+#include "util/u_pack_color.h"
+
+#include "pipe/p_state.h"
+
+#include "brw_batchbuffer.h"
+#include "brw_screen.h"
+#include "brw_context.h"
+
+#define MASK16 0xffff
+#define MASK24 0xffffff
+
+
+/**
+ * Use blitting to clear the renderbuffers named by 'flags'.
+ * Note: we can't use the ctx->DrawBuffer->_ColorDrawBufferIndexes field
+ * since that might include software renderbuffers or renderbuffers
+ * which we're clearing with triangles.
+ * \param mask  bitmask of BUFFER_BIT_* values indicating buffers to clear
+ */
+static enum pipe_error
+try_clear( struct brw_context *brw,
+           struct brw_surface *surface,
+           unsigned value )
+{
+   uint32_t BR13, CMD;
+   int x1 = 0;
+   int y1 = 0;
+   int x2 = surface->base.width;
+   int y2 = surface->base.height;
+   int pitch = surface->pitch;
+   int cpp = surface->cpp;
+
+   if (x2 == 0 || y2 == 0)
+      return 0;
+
+   debug_printf("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
+                __FUNCTION__,
+                (void *)surface->bo, pitch * cpp,
+                surface->base.offset,
+                x1, y1, x2 - x1, y2 - y1);
+
+   BR13 = 0xf0 << 16;
+   CMD = XY_COLOR_BLT_CMD | XY_BLT_WRITE_RGB | XY_BLT_WRITE_ALPHA;
+
+   /* Setup the blit command */
+   if (cpp == 4) {
+      BR13 |= BR13_8888;
+      CMD |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
+   }
+   else {
+      assert(cpp == 2);
+      BR13 |= BR13_565;
+   }
+
+   /* XXX: nasty hack for clearing depth buffers
+    */
+   if (surface->tiling == BRW_TILING_Y) {
+      x2 = pitch;
+   }
+
+   if (surface->tiling == BRW_TILING_X) {
+      CMD |= XY_DST_TILED;
+      pitch /= 4;
+   }
+
+   BR13 |= (pitch * cpp);
+
+   BEGIN_BATCH(6, 0);
+   OUT_BATCH(CMD);
+   OUT_BATCH(BR13);
+   OUT_BATCH((y1 << 16) | x1);
+   OUT_BATCH((y2 << 16) | x2);
+   OUT_RELOC(surface->bo,
+             BRW_USAGE_BLIT_DEST,
+             surface->base.offset);
+   OUT_BATCH(value);
+   ADVANCE_BATCH();
+
+   return 0;
+}
+
+
+
+
+static void color_clear(struct brw_context *brw, 
+                        struct brw_surface *bsurface,
+                        const float *rgba )
+{
+   enum pipe_error ret;
+   union util_color value;
+
+   util_pack_color( rgba, bsurface->base.format, &value );
+
+   if (bsurface->cpp == 2)
+      value.ui |= value.ui << 16;
+
+   ret = try_clear( brw, bsurface, value.ui );
+
+   if (ret != 0) {
+      brw_context_flush( brw );
+      ret = try_clear( brw, bsurface, value.ui );
+      assert( ret == 0 );
+   }
+}
+
+static void zstencil_clear(struct brw_context *brw, 
+                           struct brw_surface *bsurface,
+                           double depth,
+                           unsigned stencil )
+{
+   enum pipe_error ret;
+   unsigned value;
+
+   switch (bsurface->base.format) {
+   case PIPE_FORMAT_X8Z24_UNORM:
+   case PIPE_FORMAT_S8Z24_UNORM:
+      value = ((unsigned)(depth * MASK24) & MASK24);
+      break;
+   case PIPE_FORMAT_Z16_UNORM:
+      value = ((unsigned)(depth * MASK16) & MASK16);
+      break;
+   default:
+      assert(0);
+      return;
+   }
+
+   switch (bsurface->base.format) {
+   case PIPE_FORMAT_X8Z24_UNORM:
+   case PIPE_FORMAT_S8Z24_UNORM:
+      value = value | (stencil << 24);
+      break;
+
+   case PIPE_FORMAT_Z16_UNORM:
+      value = value | (value << 16);
+      break;
+
+   default:
+      break;
+   }
+
+   ret = try_clear( brw, bsurface, value );
+
+   if (ret != 0) {
+      brw_context_flush( brw );
+      ret = try_clear( brw, bsurface, value );
+      assert( ret == 0 );
+   }
+}
+
+
+
+/**
+ * Clear the given surface to the specified value.
+ * No masking, no scissor (clear entire buffer).
+ */
+static void brw_clear(struct pipe_context *pipe, 
+                      unsigned buffers,
+                      const float *rgba,
+                      double depth,
+                      unsigned stencil)
+{
+   struct brw_context *brw = brw_context( pipe );
+   int i;
+
+   if (buffers & PIPE_CLEAR_COLOR) {
+      for (i = 0; i < brw->curr.fb.nr_cbufs; i++) {
+         color_clear( brw, 
+                      brw_surface(brw->curr.fb.cbufs[i]),
+                      rgba );
+      }
+   }
+
+   if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
+      if (brw->curr.fb.zsbuf) {
+         zstencil_clear( brw,
+                         brw_surface(brw->curr.fb.zsbuf),
+                         depth, stencil );
+      }
+   }
+}
+
+
+void brw_pipe_clear_init( struct brw_context *brw )
+{
+   brw->base.clear = brw_clear;
+}
+
+
+void brw_pipe_clear_cleanup( struct brw_context *brw )
+{
+}
diff --git a/src/gallium/drivers/i965/brw_pipe_depth.c b/src/gallium/drivers/i965/brw_pipe_depth.c
new file mode 100644
index 0000000..e010d76
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_pipe_depth.c
@@ -0,0 +1,172 @@
+
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "brw_context.h"
+#include "brw_defines.h"
+
+/* XXX: Fixme - include this to get IZ_ defines
+ */
+#include "brw_wm.h"
+
+static unsigned brw_translate_compare_func(unsigned func)
+{
+   switch (func) {
+   case PIPE_FUNC_NEVER:
+      return BRW_COMPAREFUNCTION_NEVER;
+   case PIPE_FUNC_LESS:
+      return BRW_COMPAREFUNCTION_LESS;
+   case PIPE_FUNC_LEQUAL:
+      return BRW_COMPAREFUNCTION_LEQUAL;
+   case PIPE_FUNC_GREATER:
+      return BRW_COMPAREFUNCTION_GREATER;
+   case PIPE_FUNC_GEQUAL:
+      return BRW_COMPAREFUNCTION_GEQUAL;
+   case PIPE_FUNC_NOTEQUAL:
+      return BRW_COMPAREFUNCTION_NOTEQUAL;
+   case PIPE_FUNC_EQUAL:
+      return BRW_COMPAREFUNCTION_EQUAL;
+   case PIPE_FUNC_ALWAYS:
+      return BRW_COMPAREFUNCTION_ALWAYS;
+   default:
+      assert(0);
+      return BRW_COMPAREFUNCTION_ALWAYS;
+   }
+}
+
+static unsigned translate_stencil_op(unsigned op)
+{
+   switch (op) {
+   case PIPE_STENCIL_OP_KEEP:
+      return BRW_STENCILOP_KEEP;
+   case PIPE_STENCIL_OP_ZERO:
+      return BRW_STENCILOP_ZERO;
+   case PIPE_STENCIL_OP_REPLACE:
+      return BRW_STENCILOP_REPLACE;
+   case PIPE_STENCIL_OP_INCR:
+      return BRW_STENCILOP_INCRSAT;
+   case PIPE_STENCIL_OP_DECR:
+      return BRW_STENCILOP_DECRSAT;
+   case PIPE_STENCIL_OP_INCR_WRAP:
+      return BRW_STENCILOP_INCR;
+   case PIPE_STENCIL_OP_DECR_WRAP:
+      return BRW_STENCILOP_DECR;
+   case PIPE_STENCIL_OP_INVERT:
+      return BRW_STENCILOP_INVERT;
+   default:
+      assert(0);
+      return BRW_STENCILOP_ZERO;
+   }
+}
+
+static void create_bcc_state( struct brw_depth_stencil_state *zstencil,
+			      const struct pipe_depth_stencil_alpha_state *templ )
+{
+   if (templ->stencil[0].enabled) {
+      zstencil->cc0.stencil_enable = 1;
+      zstencil->cc0.stencil_func =
+	 brw_translate_compare_func(templ->stencil[0].func);
+      zstencil->cc0.stencil_fail_op =
+	 translate_stencil_op(templ->stencil[0].fail_op);
+      zstencil->cc0.stencil_pass_depth_fail_op =
+	 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;
+
+      if (templ->stencil[1].enabled) {
+	 zstencil->cc0.bf_stencil_enable = 1;
+	 zstencil->cc0.bf_stencil_func =
+	    brw_translate_compare_func(templ->stencil[1].func);
+	 zstencil->cc0.bf_stencil_fail_op =
+	    translate_stencil_op(templ->stencil[1].fail_op);
+	 zstencil->cc0.bf_stencil_pass_depth_fail_op =
+	    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;
+      }
+
+      zstencil->cc0.stencil_write_enable = (zstencil->cc1.stencil_write_mask ||
+					    zstencil->cc2.bf_stencil_write_mask);
+   }
+
+
+   if (templ->alpha.enabled) {
+      zstencil->cc3.alpha_test = 1;
+      zstencil->cc3.alpha_test_func = brw_translate_compare_func(templ->alpha.func);
+      zstencil->cc3.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8;
+      zstencil->cc7.alpha_ref.ub[0] = float_to_ubyte(templ->alpha.ref_value);
+   }
+
+   if (templ->depth.enabled) {
+      zstencil->cc2.depth_test = 1;
+      zstencil->cc2.depth_test_function = brw_translate_compare_func(templ->depth.func);
+      zstencil->cc2.depth_write_enable = templ->depth.writemask;
+   }
+}
+
+static void create_wm_iz_state( struct brw_depth_stencil_state *zstencil )
+{
+   if (zstencil->cc3.alpha_test)
+      zstencil->iz_lookup |= IZ_PS_KILL_ALPHATEST_BIT;
+
+   if (zstencil->cc2.depth_test)
+      zstencil->iz_lookup |= IZ_DEPTH_TEST_ENABLE_BIT;
+
+   if (zstencil->cc2.depth_write_enable)
+      zstencil->iz_lookup |= IZ_DEPTH_WRITE_ENABLE_BIT;
+
+   if (zstencil->cc0.stencil_enable)
+      zstencil->iz_lookup |= IZ_STENCIL_TEST_ENABLE_BIT;
+
+   if (zstencil->cc0.stencil_write_enable)
+      zstencil->iz_lookup |= IZ_STENCIL_WRITE_ENABLE_BIT;
+
+}
+
+
+static void *
+brw_create_depth_stencil_state( struct pipe_context *pipe,
+				const struct pipe_depth_stencil_alpha_state *templ )
+{
+   struct brw_depth_stencil_state *zstencil = CALLOC_STRUCT(brw_depth_stencil_state);
+
+   create_bcc_state( zstencil, templ );
+   create_wm_iz_state( zstencil );
+
+   return (void *)zstencil;
+}
+
+
+static void brw_bind_depth_stencil_state(struct pipe_context *pipe,
+					 void *cso)
+{
+   struct brw_context *brw = brw_context(pipe);
+   brw->curr.zstencil = (const struct brw_depth_stencil_state *)cso;
+   brw->state.dirty.mesa |= PIPE_NEW_DEPTH_STENCIL_ALPHA;
+}
+
+static void brw_delete_depth_stencil_state(struct pipe_context *pipe,
+					   void *cso)
+{
+   struct brw_context *brw = brw_context(pipe);
+   assert((const void *)cso != (const void *)brw->curr.zstencil);
+   FREE(cso);
+}
+
+
+void brw_pipe_depth_stencil_init( struct brw_context *brw )
+{
+   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;
+}
+
+void brw_pipe_depth_stencil_cleanup( struct brw_context *brw )
+{
+}
diff --git a/src/gallium/drivers/i965/brw_pipe_fb.c b/src/gallium/drivers/i965/brw_pipe_fb.c
new file mode 100644
index 0000000..5d4e502
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_pipe_fb.c
@@ -0,0 +1,84 @@
+#include "util/u_math.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+
+#include "brw_context.h"
+#include "brw_debug.h"
+
+/**
+ * called from intelDrawBuffer()
+ */
+static void brw_set_framebuffer_state( struct pipe_context *pipe, 
+				       const struct pipe_framebuffer_state *fb )
+{
+   struct brw_context *brw = brw_context(pipe);
+   unsigned i;
+
+   /* Dimensions:
+    */
+   if (brw->curr.fb.width != fb->width ||
+       brw->curr.fb.height != fb->height) {
+      brw->curr.fb.width = fb->width;
+      brw->curr.fb.height = fb->height;
+      brw->state.dirty.mesa |= PIPE_NEW_FRAMEBUFFER_DIMENSIONS;
+   }
+   
+   /* Z/Stencil
+    */
+   if (brw->curr.fb.zsbuf != fb->zsbuf) {
+      pipe_surface_reference(&brw->curr.fb.zsbuf, fb->zsbuf);
+      brw->state.dirty.mesa |= PIPE_NEW_DEPTH_BUFFER;
+   }
+
+   /* Color buffers:
+    */
+   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+      if (brw->curr.fb.cbufs[i] != fb->cbufs[i]) {
+	 brw->state.dirty.mesa |= PIPE_NEW_COLOR_BUFFERS;
+	 pipe_surface_reference(&brw->curr.fb.cbufs[i], fb->cbufs[i]);
+      }
+   }
+   
+   if (brw->curr.fb.nr_cbufs != fb->nr_cbufs) {
+      brw->curr.fb.nr_cbufs = MIN2(BRW_MAX_DRAW_BUFFERS, fb->nr_cbufs);
+      brw->state.dirty.mesa |= PIPE_NEW_NR_CBUFS;
+   }
+}
+
+
+static void brw_set_viewport_state( struct pipe_context *pipe,
+				    const struct pipe_viewport_state *viewport )
+{
+   struct brw_context *brw = brw_context(pipe);
+
+   brw->curr.viewport = *viewport;
+   brw->curr.ccv.min_depth = viewport->scale[2] * -1.0 + viewport->translate[2];
+   brw->curr.ccv.max_depth = viewport->scale[2] *  1.0 + viewport->translate[2];
+
+   if (0)
+      debug_printf("%s depth range %f .. %f\n",
+                   __FUNCTION__,
+                   brw->curr.ccv.min_depth,
+                   brw->curr.ccv.max_depth);
+
+   brw->state.dirty.mesa |= PIPE_NEW_VIEWPORT;
+}
+
+
+void brw_pipe_framebuffer_init( struct brw_context *brw )
+{
+   brw->base.set_framebuffer_state = brw_set_framebuffer_state;
+   brw->base.set_viewport_state = brw_set_viewport_state;
+}
+
+void brw_pipe_framebuffer_cleanup( struct brw_context *brw )
+{
+   struct pipe_framebuffer_state *fb = &brw->curr.fb;
+   int i;
+
+   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+      pipe_surface_reference(&fb->cbufs[i], NULL);
+   }
+
+   pipe_surface_reference(&fb->zsbuf, NULL);
+}
diff --git a/src/gallium/drivers/i965/brw_pipe_flush.c b/src/gallium/drivers/i965/brw_pipe_flush.c
new file mode 100644
index 0000000..fdc4814
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_pipe_flush.c
@@ -0,0 +1,83 @@
+
+#include "util/u_upload_mgr.h"
+
+#include "brw_context.h"
+#include "brw_screen.h"
+#include "brw_batchbuffer.h"
+
+
+
+/* All batchbuffer flushes must go through this function.
+ */
+void brw_context_flush( struct brw_context *brw )
+{
+   /*
+    * 
+    */
+   brw_emit_query_end(brw);
+
+   /* Move to the end of the current upload buffer so that we'll force choosing
+    * a new buffer next time.
+    */
+   u_upload_flush( brw->vb.upload_vertex );
+   u_upload_flush( brw->vb.upload_index );
+
+   _brw_batchbuffer_flush( brw->batch, __FILE__, __LINE__ );
+
+   /* Mark all context state as needing to be re-emitted.
+    * This is probably not as severe as on 915, since almost all of our state
+    * is just in referenced buffers.
+    */
+   brw->state.dirty.brw |= BRW_NEW_CONTEXT;
+   brw->state.dirty.mesa |= ~0;
+   brw->state.dirty.brw |= ~0;
+   brw->state.dirty.cache |= ~0;
+
+   brw->curbe.need_new_bo = GL_TRUE;
+}
+
+static void
+brw_flush( struct pipe_context *pipe,
+           unsigned flags, 
+           struct pipe_fence_handle **fence )
+{
+   brw_context_flush( brw_context( pipe ) );
+   if (fence)
+      *fence = NULL;
+}
+
+static unsigned brw_is_buffer_referenced(struct pipe_context *pipe,
+                                  struct pipe_buffer *buffer)
+{
+   struct brw_context *brw = brw_context(pipe);
+   struct brw_screen *bscreen = brw_screen(brw->base.screen);
+
+   return brw_is_buffer_referenced_by_bo( bscreen,
+                                          buffer,
+                                          brw->batch->buf );
+}
+
+static unsigned brw_is_texture_referenced(struct pipe_context *pipe,
+                                   struct pipe_texture *texture,
+                                   unsigned face,
+                                   unsigned level)
+{
+   struct brw_context *brw = brw_context(pipe);
+   struct brw_screen *bscreen = brw_screen(brw->base.screen);
+
+   return brw_is_texture_referenced_by_bo( bscreen,
+                                           texture, face, level,
+                                           brw->batch->buf );
+}
+
+void brw_pipe_flush_init( struct brw_context *brw )
+{
+   brw->base.flush = brw_flush;
+   brw->base.is_buffer_referenced = brw_is_buffer_referenced;
+   brw->base.is_texture_referenced = brw_is_texture_referenced;
+}
+
+
+void brw_pipe_flush_cleanup( struct brw_context *brw )
+{
+}
diff --git a/src/gallium/drivers/i965/brw_pipe_misc.c b/src/gallium/drivers/i965/brw_pipe_misc.c
new file mode 100644
index 0000000..3035907
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_pipe_misc.c
@@ -0,0 +1,54 @@
+
+#include "brw_context.h"
+#include "brw_structs.h"
+#include "brw_defines.h"
+
+static void brw_set_polygon_stipple( struct pipe_context *pipe,
+				     const struct pipe_poly_stipple *stip )
+{
+   struct brw_context *brw = brw_context(pipe);
+   struct brw_polygon_stipple *bps = &brw->curr.bps;
+   GLuint i;
+
+   memset(bps, 0, sizeof *bps);
+   bps->header.opcode = CMD_POLY_STIPPLE_PATTERN;
+   bps->header.length = sizeof *bps/4-2;
+
+   for (i = 0; i < 32; i++)
+      bps->stipple[i] = stip->stipple[i]; /* don't invert */
+
+   brw->state.dirty.mesa |= PIPE_NEW_POLYGON_STIPPLE;
+}
+
+
+static void brw_set_scissor_state( struct pipe_context *pipe,
+                                   const struct pipe_scissor_state *scissor )
+{
+   struct brw_context *brw = brw_context(pipe);
+
+   brw->curr.scissor =  *scissor;
+   brw->state.dirty.mesa |= PIPE_NEW_SCISSOR;
+}
+
+
+static void brw_set_clip_state( struct pipe_context *pipe,
+                                const struct pipe_clip_state *clip )
+{
+   struct brw_context *brw = brw_context(pipe);
+
+   brw->curr.ucp = *clip;
+   brw->state.dirty.mesa |= PIPE_NEW_CLIP;
+}
+
+
+void brw_pipe_misc_init( struct brw_context *brw )
+{
+   brw->base.set_polygon_stipple = brw_set_polygon_stipple;
+   brw->base.set_scissor_state = brw_set_scissor_state;
+   brw->base.set_clip_state = brw_set_clip_state;
+}
+
+
+void brw_pipe_misc_cleanup( struct brw_context *brw )
+{
+}
diff --git a/src/gallium/drivers/i965/brw_pipe_query.c b/src/gallium/drivers/i965/brw_pipe_query.c
new file mode 100644
index 0000000..2eb8626
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_pipe_query.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * 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, sublicense,
+ * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ */
+
+/** @file support for ARB_query_object
+ *
+ * ARB_query_object is implemented by using the PIPE_CONTROL command to stall
+ * execution on the completion of previous depth tests, and write the
+ * current PS_DEPTH_COUNT to a buffer object.
+ *
+ * We use before and after counts when drawing during a query so that
+ * we don't pick up other clients' query data in ours.  To reduce overhead,
+ * a single BO is used to record the query data for all active queries at
+ * once.  This also gives us a simple bound on how much batchbuffer space is
+ * required for handling queries, so that we can be sure that we won't
+ * have to emit a batchbuffer without getting the ending PS_DEPTH_COUNT.
+ */
+#include "util/u_simple_list.h"
+
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_batchbuffer.h"
+#include "brw_reg.h"
+
+/** Waits on the query object's BO and totals the results for this query */
+static boolean
+brw_query_get_result(struct pipe_context *pipe,
+		     struct pipe_query *q,
+		     boolean wait,
+		     uint64_t *result)
+{
+   struct brw_context *brw = brw_context(pipe);
+   struct brw_query_object *query = (struct brw_query_object *)q;
+
+   /* Map and count the pixels from the current query BO */
+   if (query->bo) {
+      int i;
+      uint64_t *map;
+      
+      if (brw->sws->bo_is_busy(query->bo) && !wait)
+	 return FALSE;
+      
+      map = bo_map_read(brw->sws, query->bo);
+      if (map == NULL)
+	 return FALSE;
+      
+      for (i = query->first_index; i <= query->last_index; i++) {
+	 query->result += map[i * 2 + 1] - map[i * 2];
+      }
+
+      brw->sws->bo_unmap(query->bo);
+      bo_reference(&query->bo, NULL);
+   }
+
+   *result = query->result;
+   return TRUE;
+}
+
+static struct pipe_query *
+brw_query_create(struct pipe_context *pipe, unsigned type )
+{
+   struct brw_query_object *query;
+
+   switch (type) {
+   case PIPE_QUERY_OCCLUSION_COUNTER:
+      query = CALLOC_STRUCT( brw_query_object );
+      if (query == NULL)
+	 return NULL;
+      return (struct pipe_query *)query;
+      
+   default:
+      return NULL;
+   }
+}
+
+static void
+brw_query_destroy(struct pipe_context *pipe, struct pipe_query *q)
+{
+   struct brw_query_object *query = (struct brw_query_object *)q;
+
+   bo_reference(&query->bo, NULL);
+   FREE(query);
+}
+
+static void
+brw_query_begin(struct pipe_context *pipe, struct pipe_query *q)
+{
+   struct brw_context *brw = brw_context(pipe);
+   struct brw_query_object *query = (struct brw_query_object *)q;
+
+   /* Reset our driver's tracking of query state. */
+   bo_reference(&query->bo, NULL);
+   query->result = 0;
+   query->first_index = -1;
+   query->last_index = -1;
+
+   insert_at_head(&brw->query.active_head, query);
+   brw->query.stats_wm++;
+   brw->state.dirty.mesa |= PIPE_NEW_QUERY;
+}
+
+static void
+brw_query_end(struct pipe_context *pipe, struct pipe_query *q)
+{
+   struct brw_context *brw = brw_context(pipe);
+   struct brw_query_object *query = (struct brw_query_object *)q;
+
+   /* Flush the batchbuffer in case it has writes to our query BO.
+    * Have later queries write to a new query BO so that further rendering
+    * doesn't delay the collection of our results.
+    */
+   if (query->bo) {
+      brw_emit_query_end(brw);
+      brw_context_flush( brw );
+
+      bo_reference(&brw->query.bo, NULL);
+   }
+
+   remove_from_list(query);
+   brw->query.stats_wm--;
+   brw->state.dirty.mesa |= PIPE_NEW_QUERY;
+}
+
+/***********************************************************************
+ * Internal functions and callbacks to implement queries 
+ */
+
+/** Called to set up the query BO and account for its aperture space */
+enum pipe_error
+brw_prepare_query_begin(struct brw_context *brw)
+{
+   enum pipe_error ret;
+
+   /* Skip if we're not doing any queries. */
+   if (is_empty_list(&brw->query.active_head))
+      return PIPE_OK;
+
+   /* Get a new query BO if we're going to need it. */
+   if (brw->query.bo == NULL ||
+       brw->query.index * 2 + 1 >= 4096 / sizeof(uint64_t)) {
+
+      ret = brw->sws->bo_alloc(brw->sws, BRW_BUFFER_TYPE_QUERY, 4096, 1,
+                               &brw->query.bo);
+      if (ret)
+         return ret;
+
+      brw->query.index = 0;
+   }
+
+   brw_add_validated_bo(brw, brw->query.bo);
+
+   return PIPE_OK;
+}
+
+/** Called just before primitive drawing to get a beginning PS_DEPTH_COUNT. */
+void
+brw_emit_query_begin(struct brw_context *brw)
+{
+   struct brw_query_object *query;
+
+   /* Skip if we're not doing any queries, or we've emitted the start. */
+   if (brw->query.active || is_empty_list(&brw->query.active_head))
+      return;
+
+   BEGIN_BATCH(4, IGNORE_CLIPRECTS);
+   OUT_BATCH(_3DSTATE_PIPE_CONTROL |
+	     PIPE_CONTROL_DEPTH_STALL |
+	     PIPE_CONTROL_WRITE_DEPTH_COUNT);
+   /* This object could be mapped cacheable, but we don't have an exposed
+    * mechanism to support that.  Since it's going uncached, tell GEM that
+    * we're writing to it.  The usual clflush should be all that's required
+    * to pick up the results.
+    */
+   OUT_RELOC(brw->query.bo,
+	     BRW_USAGE_QUERY_RESULT,
+	     PIPE_CONTROL_GLOBAL_GTT_WRITE |
+	     ((brw->query.index * 2) * sizeof(uint64_t)));
+   OUT_BATCH(0);
+   OUT_BATCH(0);
+   ADVANCE_BATCH();
+
+   foreach(query, &brw->query.active_head) {
+      if (query->bo != brw->query.bo) {
+	 uint64_t tmp;
+	 
+	 /* Propogate the results from this buffer to all of the
+	  * active queries, as the bo is going away.
+	  */
+	 if (query->bo != NULL)
+	    brw_query_get_result( &brw->base, 
+				  (struct pipe_query *)query,
+				  FALSE,
+				  &tmp );
+
+	 bo_reference( &query->bo, brw->query.bo );
+	 query->first_index = brw->query.index;
+      }
+      query->last_index = brw->query.index;
+   }
+   brw->query.active = GL_TRUE;
+}
+
+/** Called at batchbuffer flush to get an ending PS_DEPTH_COUNT */
+void
+brw_emit_query_end(struct brw_context *brw)
+{
+   if (!brw->query.active)
+      return;
+
+   BEGIN_BATCH(4, IGNORE_CLIPRECTS);
+   OUT_BATCH(_3DSTATE_PIPE_CONTROL |
+	     PIPE_CONTROL_DEPTH_STALL |
+	     PIPE_CONTROL_WRITE_DEPTH_COUNT);
+   OUT_RELOC(brw->query.bo,
+	     BRW_USAGE_QUERY_RESULT,
+	     PIPE_CONTROL_GLOBAL_GTT_WRITE |
+	     ((brw->query.index * 2 + 1) * sizeof(uint64_t)));
+   OUT_BATCH(0);
+   OUT_BATCH(0);
+   ADVANCE_BATCH();
+
+   brw->query.active = GL_FALSE;
+   brw->query.index++;
+}
+
+void brw_pipe_query_init( struct brw_context *brw )
+{
+   brw->base.create_query = brw_query_create;
+   brw->base.destroy_query = brw_query_destroy;
+   brw->base.begin_query = brw_query_begin;
+   brw->base.end_query = brw_query_end;
+   brw->base.get_query_result = brw_query_get_result;
+}
+
+
+void brw_pipe_query_cleanup( struct brw_context *brw )
+{
+   /* Unreference brw->query.bo ??
+    */
+}
diff --git a/src/gallium/drivers/i965/brw_pipe_rast.c b/src/gallium/drivers/i965/brw_pipe_rast.c
new file mode 100644
index 0000000..2117e91
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_pipe_rast.c
@@ -0,0 +1,161 @@
+
+#include "util/u_memory.h"
+#include "pipe/p_defines.h"
+#include "brw_context.h"
+#include "brw_defines.h"
+#include "brw_pipe_rast.h"
+#include "brw_wm.h"
+
+
+static unsigned translate_fill( unsigned fill )
+{
+   switch (fill) {
+   case PIPE_POLYGON_MODE_FILL:
+      return CLIP_FILL;
+   case PIPE_POLYGON_MODE_LINE:
+      return CLIP_LINE;
+   case PIPE_POLYGON_MODE_POINT:
+      return CLIP_POINT;
+   default:
+      assert(0);
+      return CLIP_FILL;
+   }
+}
+
+
+/* Calculates the key for triangle-mode clipping.  Non-triangle
+ * clipping keys use much less information and are computed on the
+ * fly.
+ */
+static void
+calculate_clip_key_rast( const struct brw_context *brw,
+			 const struct pipe_rasterizer_state *templ,
+			 const struct brw_rasterizer_state *rast,
+			 struct brw_clip_prog_key *key)
+{
+   memset(key, 0, sizeof *key);
+
+   if (brw->chipset.is_igdng)
+       key->clip_mode = BRW_CLIPMODE_KERNEL_CLIP;
+   else
+       key->clip_mode = BRW_CLIPMODE_NORMAL;
+
+   key->do_flat_shading = templ->flatshade;
+
+   if (templ->cull_mode == PIPE_WINDING_BOTH) {
+      key->clip_mode = BRW_CLIPMODE_REJECT_ALL;
+      return;
+   }
+
+   key->fill_ccw = CLIP_CULL;
+   key->fill_cw = CLIP_CULL;
+
+   if (!(templ->cull_mode & PIPE_WINDING_CCW)) {
+      key->fill_ccw = translate_fill(templ->fill_ccw);
+   }
+
+   if (!(templ->cull_mode & PIPE_WINDING_CW)) {
+      key->fill_cw = translate_fill(templ->fill_cw);
+   }
+
+   if (key->fill_cw == CLIP_LINE ||
+       key->fill_ccw == CLIP_LINE ||
+       key->fill_cw == CLIP_POINT ||
+       key->fill_ccw == CLIP_POINT) {
+      key->do_unfilled = 1;
+      key->clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED;
+   }
+
+   key->offset_ccw = templ->offset_ccw;
+   key->offset_cw = templ->offset_cw;
+
+   if (templ->light_twoside && key->fill_cw != CLIP_CULL) 
+      key->copy_bfc_cw = 1;
+   
+   if (templ->light_twoside && key->fill_ccw != CLIP_CULL) 
+      key->copy_bfc_ccw = 1;
+}
+
+
+static void
+calculate_line_stipple_rast( const struct pipe_rasterizer_state *templ,
+			     struct brw_line_stipple *bls )
+{
+   GLfloat tmp = 1.0f / (templ->line_stipple_factor + 1);
+   GLint tmpi = tmp * (1<<13);
+
+   bls->header.opcode = CMD_LINE_STIPPLE_PATTERN;
+   bls->header.length = sizeof(*bls)/4 - 2;
+   bls->bits0.pattern = templ->line_stipple_pattern;
+   bls->bits1.repeat_count = templ->line_stipple_factor + 1;
+   bls->bits1.inverse_repeat_count = tmpi;
+}
+
+static void *brw_create_rasterizer_state( struct pipe_context *pipe,
+					  const struct pipe_rasterizer_state *templ )
+{
+   struct brw_context *brw = brw_context(pipe);
+   struct brw_rasterizer_state *rast;
+
+   rast = CALLOC_STRUCT(brw_rasterizer_state);
+   if (rast == NULL)
+      return NULL;
+
+   rast->templ = *templ;
+
+   calculate_clip_key_rast( brw, templ, rast, &rast->clip_key );
+   
+   if (templ->line_stipple_enable)
+      calculate_line_stipple_rast( templ, &rast->bls );
+
+   /* Caclculate lookup value for WM IZ table.
+    */
+   if (templ->line_smooth) {
+      if (templ->fill_cw == PIPE_POLYGON_MODE_LINE &&
+	  templ->fill_ccw == PIPE_POLYGON_MODE_LINE) {
+	 rast->unfilled_aa_line = AA_ALWAYS;
+      }
+      else if (templ->fill_cw == PIPE_POLYGON_MODE_LINE ||
+	       templ->fill_ccw == PIPE_POLYGON_MODE_LINE) {
+	 rast->unfilled_aa_line = AA_SOMETIMES;
+      }
+      else {
+	 rast->unfilled_aa_line = AA_NEVER;
+      }
+   }
+   else {
+      rast->unfilled_aa_line = AA_NEVER;
+   }
+
+   return (void *)rast;
+}
+
+
+static void brw_bind_rasterizer_state(struct pipe_context *pipe,
+				 void *cso)
+{
+   struct brw_context *brw = brw_context(pipe);
+   brw->curr.rast = (const struct brw_rasterizer_state *)cso;
+   brw->state.dirty.mesa |= PIPE_NEW_RAST;
+}
+
+static void brw_delete_rasterizer_state(struct pipe_context *pipe,
+				  void *cso)
+{
+   struct brw_context *brw = brw_context(pipe);
+   assert((const void *)cso != (const void *)brw->curr.rast);
+   FREE(cso);
+}
+
+
+
+void brw_pipe_rast_init( struct brw_context *brw )
+{
+   brw->base.create_rasterizer_state = brw_create_rasterizer_state;
+   brw->base.bind_rasterizer_state = brw_bind_rasterizer_state;
+   brw->base.delete_rasterizer_state = brw_delete_rasterizer_state;
+}
+
+void brw_pipe_rast_cleanup( struct brw_context *brw )
+{
+}
diff --git a/src/gallium/drivers/i965/brw_pipe_rast.h b/src/gallium/drivers/i965/brw_pipe_rast.h
new file mode 100644
index 0000000..9354f01
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_pipe_rast.h
@@ -0,0 +1,16 @@
+#ifndef BRW_PIPE_RAST_H
+#define BRW_PIPE_RAST_H
+
+#include "brw_clip.h"
+
+struct brw_rasterizer_state {
+   struct pipe_rasterizer_state templ; /* for draw module */
+
+   /* Precalculated hardware state:
+    */
+   struct brw_clip_prog_key clip_key;
+   struct brw_line_stipple bls;
+   unsigned unfilled_aa_line;
+};
+
+#endif
diff --git a/src/gallium/drivers/i965/brw_pipe_sampler.c b/src/gallium/drivers/i965/brw_pipe_sampler.c
new file mode 100644
index 0000000..8171279
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_pipe_sampler.c
@@ -0,0 +1,231 @@
+
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+
+#include "brw_context.h"
+#include "brw_defines.h"
+#include "brw_debug.h"
+
+
+
+/* The brw (and related graphics cores) do not support GL_CLAMP.  The
+ * Intel drivers for "other operating systems" implement GL_CLAMP as
+ * GL_CLAMP_TO_EDGE, so the same is done here.
+ */
+static GLuint translate_wrap_mode( unsigned wrap )
+{
+   switch( wrap ) {
+   case PIPE_TEX_WRAP_REPEAT: 
+      return BRW_TEXCOORDMODE_WRAP;
+
+   case PIPE_TEX_WRAP_CLAMP:
+   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+      return BRW_TEXCOORDMODE_CLAMP;
+      
+   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+      return BRW_TEXCOORDMODE_CLAMP_BORDER;
+
+   case PIPE_TEX_WRAP_MIRROR_REPEAT: 
+      return BRW_TEXCOORDMODE_MIRROR;
+
+   case PIPE_TEX_WRAP_MIRROR_CLAMP: 
+   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 
+   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 
+      return BRW_TEXCOORDMODE_MIRROR_ONCE;
+
+   default: 
+      return BRW_TEXCOORDMODE_WRAP;
+   }
+}
+
+static GLuint translate_img_filter( unsigned filter )
+{
+   switch (filter) {
+   case PIPE_TEX_FILTER_NEAREST:
+      return BRW_MAPFILTER_NEAREST;
+   case PIPE_TEX_FILTER_LINEAR:
+      return BRW_MAPFILTER_LINEAR;
+   default:
+      assert(0);
+      return BRW_MAPFILTER_NEAREST;
+   }
+}
+
+static GLuint translate_mip_filter( unsigned filter )
+{
+   switch (filter) {
+   case PIPE_TEX_MIPFILTER_NONE: 
+      return BRW_MIPFILTER_NONE;
+   case PIPE_TEX_MIPFILTER_NEAREST:
+      return BRW_MIPFILTER_NEAREST;
+   case PIPE_TEX_MIPFILTER_LINEAR:
+      return BRW_MIPFILTER_LINEAR;
+   default:
+      assert(0);
+      return BRW_MIPFILTER_NONE;
+   }
+}
+
+/* XXX: not sure why there are special translations for the shadow tex
+ * compare functions.  In particular ALWAYS is translated to NEVER.
+ * Is this a hardware issue?  Does i965 really suffer from this?
+ */
+static GLuint translate_shadow_compare_func( unsigned func )
+{
+   switch (func) {
+   case PIPE_FUNC_NEVER: 
+       return BRW_COMPAREFUNCTION_ALWAYS;
+   case PIPE_FUNC_LESS: 
+       return BRW_COMPAREFUNCTION_LEQUAL;
+   case PIPE_FUNC_LEQUAL: 
+       return BRW_COMPAREFUNCTION_LESS;
+   case PIPE_FUNC_GREATER: 
+       return BRW_COMPAREFUNCTION_GEQUAL;
+   case PIPE_FUNC_GEQUAL: 
+      return BRW_COMPAREFUNCTION_GREATER;
+   case PIPE_FUNC_NOTEQUAL: 
+      return BRW_COMPAREFUNCTION_EQUAL;
+   case PIPE_FUNC_EQUAL: 
+      return BRW_COMPAREFUNCTION_NOTEQUAL;
+   case PIPE_FUNC_ALWAYS: 
+       return BRW_COMPAREFUNCTION_NEVER;
+   default:
+      assert(0);
+      return BRW_COMPAREFUNCTION_NEVER;
+   }
+}
+
+
+
+
+static void *
+brw_create_sampler_state( struct pipe_context *pipe,
+                          const struct pipe_sampler_state *template )
+{
+   struct brw_sampler *sampler = CALLOC_STRUCT(brw_sampler);
+
+   sampler->ss0.min_filter = translate_img_filter( template->min_img_filter );
+   sampler->ss0.mag_filter = translate_img_filter( template->mag_img_filter );
+   sampler->ss0.mip_filter = translate_mip_filter( template->min_mip_filter );
+
+
+   /* XXX: anisotropy logic slightly changed: 
+    */
+   if (template->max_anisotropy > 1.0) {
+      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->ss1.r_wrap_mode = translate_wrap_mode(template->wrap_r);
+   sampler->ss1.s_wrap_mode = translate_wrap_mode(template->wrap_s);
+   sampler->ss1.t_wrap_mode = translate_wrap_mode(template->wrap_t);
+
+   /* Set LOD bias: 
+    */
+   sampler->ss0.lod_bias = 
+      util_signed_fixed(CLAMP(template->lod_bias, -16, 15), 6);
+
+
+   sampler->ss0.lod_preclamp = 1; /* OpenGL mode */
+   sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */
+
+   /* Set shadow function: 
+    */
+   if (template->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
+
+      /* Shadowing is "enabled" by emitting a particular sampler
+       * message (sample_c).  So need to recompile WM program when
+       * shadow comparison is enabled on each/any texture unit.
+       */
+      sampler->ss0.shadow_function =
+	 translate_shadow_compare_func(template->compare_func);
+   }
+
+   /* Set BaseMipLevel, MaxLOD, MinLOD: 
+    */
+   sampler->ss0.base_level = 
+      util_unsigned_fixed(0, 1);
+
+   sampler->ss1.max_lod = 
+      util_unsigned_fixed(CLAMP(template->max_lod, 0, 13), 6);
+
+   sampler->ss1.min_lod = 
+      util_unsigned_fixed(CLAMP(template->min_lod, 0, 13), 6);
+
+   return (void *)sampler;
+}
+
+static void brw_bind_sampler_state(struct pipe_context *pipe,
+                                   unsigned num, void **sampler)
+{
+   struct brw_context *brw = brw_context(pipe);
+   int i;
+
+   for (i = 0; i < num; i++)
+      brw->curr.sampler[i] = sampler[i];
+
+   for (i = num; i < brw->curr.num_samplers; i++)
+      brw->curr.sampler[i] = NULL;
+
+   brw->curr.num_samplers = num;
+   brw->state.dirty.mesa |= PIPE_NEW_SAMPLERS;
+}
+
+static void brw_delete_sampler_state(struct pipe_context *pipe,
+				  void *cso)
+{
+   FREE(cso);
+}
+
+static void brw_set_sampler_textures(struct pipe_context *pipe,
+				     unsigned num,
+				     struct pipe_texture **texture)
+{
+   struct brw_context *brw = brw_context(pipe);
+   int i;
+
+   for (i = 0; i < num; i++)
+      pipe_texture_reference(&brw->curr.texture[i], texture[i]);
+
+   for (i = num; i < brw->curr.num_textures; i++)
+      pipe_texture_reference(&brw->curr.texture[i], NULL);
+
+   brw->curr.num_textures = num;
+   brw->state.dirty.mesa |= PIPE_NEW_BOUND_TEXTURES;
+}
+
+static void brw_set_vertex_sampler_textures(struct pipe_context *pipe,
+                                            unsigned num,
+                                            struct pipe_texture **texture)
+{
+}
+
+static void brw_bind_vertex_sampler_state(struct pipe_context *pipe,
+                                          unsigned num, void **sampler)
+{
+}
+
+
+void brw_pipe_sampler_init( struct brw_context *brw )
+{
+   brw->base.create_sampler_state = brw_create_sampler_state;
+   brw->base.delete_sampler_state = brw_delete_sampler_state;
+
+   brw->base.set_fragment_sampler_textures = brw_set_sampler_textures;
+   brw->base.bind_fragment_sampler_states = brw_bind_sampler_state;
+
+   brw->base.set_vertex_sampler_textures = brw_set_vertex_sampler_textures;
+   brw->base.bind_vertex_sampler_states = brw_bind_vertex_sampler_state;
+
+}
+void brw_pipe_sampler_cleanup( struct brw_context *brw )
+{
+}
diff --git a/src/gallium/drivers/i965/brw_pipe_shader.c b/src/gallium/drivers/i965/brw_pipe_shader.c
new file mode 100644
index 0000000..bb32d90
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_pipe_shader.c
@@ -0,0 +1,303 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "util/u_memory.h"
+  
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_scan.h"
+
+#include "brw_context.h"
+#include "brw_util.h"
+#include "brw_wm.h"
+
+
+/**
+ * Determine if the given shader uses complex features such as flow
+ * conditionals, loops, subroutines.
+ */
+static GLboolean has_flow_control(const struct tgsi_shader_info *info)
+{
+    return (info->opcode_count[TGSI_OPCODE_ARL] > 0 ||
+	    info->opcode_count[TGSI_OPCODE_IF] > 0 ||
+	    info->opcode_count[TGSI_OPCODE_ENDIF] > 0 || /* redundant - IF */
+	    info->opcode_count[TGSI_OPCODE_CAL] > 0 ||
+	    info->opcode_count[TGSI_OPCODE_BRK] > 0 ||   /* redundant - BGNLOOP */
+	    info->opcode_count[TGSI_OPCODE_RET] > 0 ||   /* redundant - CAL */
+	    info->opcode_count[TGSI_OPCODE_BGNLOOP] > 0);
+}
+
+
+static void scan_immediates(const struct tgsi_token *tokens,
+                            const struct tgsi_shader_info *info,
+                            struct brw_immediate_data *imm)
+{
+   struct tgsi_parse_context parse;
+   boolean done = FALSE;
+
+   imm->nr = 0;
+   imm->data = MALLOC(info->immediate_count * 4 * sizeof(float));
+
+   tgsi_parse_init( &parse, tokens );
+   while (!tgsi_parse_end_of_tokens( &parse ) && !done) {
+      tgsi_parse_token( &parse );
+
+      switch (parse.FullToken.Token.Type) {
+      case TGSI_TOKEN_TYPE_DECLARATION:
+         break;
+
+      case TGSI_TOKEN_TYPE_IMMEDIATE: {
+	 static const float id[4] = {0,0,0,1};
+	 const float *value = &parse.FullToken.FullImmediate.u[0].Float;
+	 unsigned size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
+         unsigned i;
+
+	 for (i = 0; i < size; i++)
+	    imm->data[imm->nr][i] = value[i];
+
+	 for (; i < 4; i++)
+	    imm->data[imm->nr][i] = id[i];
+         
+         imm->nr++;
+	 break;
+      }
+
+      case TGSI_TOKEN_TYPE_INSTRUCTION:
+	 done = 1;
+	 break;
+      }
+   }
+}
+
+
+static void brw_bind_fs_state( struct pipe_context *pipe, void *prog )
+{
+   struct brw_fragment_shader *fs = (struct brw_fragment_shader *)prog;
+   struct brw_context *brw = brw_context(pipe);
+   
+   if (brw->curr.fragment_shader == fs)
+      return;
+
+   if (brw->curr.fragment_shader == NULL ||
+       fs == NULL ||
+       memcmp(&brw->curr.fragment_shader->signature, &fs->signature,
+              brw_fs_signature_size(&fs->signature)) != 0) {
+      brw->state.dirty.mesa |= PIPE_NEW_FRAGMENT_SIGNATURE;
+   }
+
+   brw->curr.fragment_shader = fs;
+   brw->state.dirty.mesa |= PIPE_NEW_FRAGMENT_SHADER;
+}
+
+static void brw_bind_vs_state( struct pipe_context *pipe, void *prog )
+{
+   struct brw_context *brw = brw_context(pipe);
+
+   brw->curr.vertex_shader = (struct brw_vertex_shader *)prog;
+   brw->state.dirty.mesa |= PIPE_NEW_VERTEX_SHADER;
+}
+
+
+
+static void *brw_create_fs_state( struct pipe_context *pipe,
+				  const struct pipe_shader_state *shader )
+{
+   struct brw_context *brw = brw_context(pipe);
+   struct brw_fragment_shader *fs;
+   int i;
+
+   fs = CALLOC_STRUCT(brw_fragment_shader);
+   if (fs == NULL)
+      return NULL;
+
+   /* Duplicate tokens, scan shader
+    */
+   fs->id = brw->program_id++;
+   fs->has_flow_control = has_flow_control(&fs->info);
+
+   fs->tokens = tgsi_dup_tokens(shader->tokens);
+   if (fs->tokens == NULL)
+      goto fail;
+
+   tgsi_scan_shader(fs->tokens, &fs->info);
+   scan_immediates(fs->tokens, &fs->info, &fs->immediates);
+
+   fs->signature.nr_inputs = fs->info.num_inputs;
+   for (i = 0; i < fs->info.num_inputs; i++) {
+      fs->signature.input[i].interp = fs->info.input_interpolate[i];
+      fs->signature.input[i].semantic = fs->info.input_semantic_name[i];
+      fs->signature.input[i].semantic_index = fs->info.input_semantic_index[i];
+   }
+
+   for (i = 0; i < fs->info.num_inputs; i++)
+      if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_POSITION)
+	 fs->uses_depth = 1;
+
+   if (fs->info.uses_kill)
+      fs->iz_lookup |= IZ_PS_KILL_ALPHATEST_BIT;
+
+   if (fs->info.writes_z)
+      fs->iz_lookup |= IZ_PS_COMPUTES_DEPTH_BIT;
+
+   return (void *)fs;
+
+fail:
+   FREE(fs);
+   return NULL;
+}
+
+
+static void *brw_create_vs_state( struct pipe_context *pipe,
+				  const struct pipe_shader_state *shader )
+{
+   struct brw_context *brw = brw_context(pipe);
+   struct brw_vertex_shader *vs;
+   unsigned i;
+
+   vs = CALLOC_STRUCT(brw_vertex_shader);
+   if (vs == NULL)
+      return NULL;
+
+   /* Duplicate tokens, scan shader
+    */
+   vs->tokens = tgsi_dup_tokens(shader->tokens);
+   if (vs->tokens == NULL)
+      goto fail;
+
+   tgsi_scan_shader(vs->tokens, &vs->info);
+   scan_immediates(vs->tokens, &vs->info, &vs->immediates);
+
+   vs->id = brw->program_id++;
+   vs->has_flow_control = has_flow_control(&vs->info);
+
+   vs->output_hpos = BRW_OUTPUT_NOT_PRESENT;
+   vs->output_color0 = BRW_OUTPUT_NOT_PRESENT;
+   vs->output_color1 = BRW_OUTPUT_NOT_PRESENT;
+   vs->output_bfc0 = BRW_OUTPUT_NOT_PRESENT;
+   vs->output_bfc1 = BRW_OUTPUT_NOT_PRESENT;
+   vs->output_edgeflag = BRW_OUTPUT_NOT_PRESENT;
+
+   for (i = 0; i < vs->info.num_outputs; i++) {
+      int index = vs->info.output_semantic_index[i];
+      switch (vs->info.output_semantic_name[i]) {
+      case TGSI_SEMANTIC_POSITION:
+         vs->output_hpos = i;
+         break;
+      case TGSI_SEMANTIC_COLOR:
+         if (index == 0)
+            vs->output_color0 = i;
+         else
+            vs->output_color1 = i;
+         break;
+      case TGSI_SEMANTIC_BCOLOR:
+         if (index == 0)
+            vs->output_bfc0 = i;
+         else
+            vs->output_bfc1 = i;
+         break;
+      case TGSI_SEMANTIC_EDGEFLAG:
+         vs->output_edgeflag = i;
+         break;
+      }
+   }
+
+   
+   /* Done:
+    */
+   return (void *)vs;
+
+fail:
+   FREE(vs);
+   return NULL;
+}
+
+
+static void brw_delete_fs_state( struct pipe_context *pipe, void *prog )
+{
+   struct brw_fragment_shader *fs = (struct brw_fragment_shader *)prog;
+
+   bo_reference(&fs->const_buffer, NULL);
+   FREE( (void *)fs->tokens );
+   FREE( fs );
+}
+
+
+static void brw_delete_vs_state( struct pipe_context *pipe, void *prog )
+{
+   struct brw_fragment_shader *vs = (struct brw_fragment_shader *)prog;
+
+   /* Delete draw shader
+    */
+   FREE( (void *)vs->tokens );
+   FREE( vs );
+}
+
+
+static void brw_set_constant_buffer(struct pipe_context *pipe,
+                                     uint shader, uint index,
+                                     const struct pipe_constant_buffer *buf)
+{
+   struct brw_context *brw = brw_context(pipe);
+
+   assert(index == 0);
+
+   if (shader == PIPE_SHADER_FRAGMENT) {
+      pipe_buffer_reference( &brw->curr.fragment_constants,
+                             buf->buffer );
+
+      brw->state.dirty.mesa |= PIPE_NEW_FRAGMENT_CONSTANTS;
+   }
+   else {
+      pipe_buffer_reference( &brw->curr.vertex_constants,
+                             buf->buffer );
+
+      brw->state.dirty.mesa |= PIPE_NEW_VERTEX_CONSTANTS;
+   }
+}
+
+
+void brw_pipe_shader_init( struct brw_context *brw )
+{
+   brw->base.set_constant_buffer = brw_set_constant_buffer;
+
+   brw->base.create_vs_state = brw_create_vs_state;
+   brw->base.bind_vs_state = brw_bind_vs_state;
+   brw->base.delete_vs_state = brw_delete_vs_state;
+
+   brw->base.create_fs_state = brw_create_fs_state;
+   brw->base.bind_fs_state = brw_bind_fs_state;
+   brw->base.delete_fs_state = brw_delete_fs_state;
+}
+
+void brw_pipe_shader_cleanup( struct brw_context *brw )
+{
+   pipe_buffer_reference( &brw->curr.fragment_constants, NULL );
+   pipe_buffer_reference( &brw->curr.vertex_constants, NULL );
+}
diff --git a/src/gallium/drivers/i965/brw_pipe_vertex.c b/src/gallium/drivers/i965/brw_pipe_vertex.c
new file mode 100644
index 0000000..e3c48e3
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_pipe_vertex.c
@@ -0,0 +1,71 @@
+#include "brw_context.h"
+
+
+static void brw_set_vertex_elements( struct pipe_context *pipe,
+				     unsigned count,
+				     const struct pipe_vertex_element *elements )
+{
+   struct brw_context *brw = brw_context(pipe);
+
+   memcpy(brw->curr.vertex_element, elements, count * sizeof(elements[0]));
+   brw->curr.num_vertex_elements = count;
+
+   brw->state.dirty.mesa |= PIPE_NEW_VERTEX_ELEMENT;
+}
+
+
+static void brw_set_vertex_buffers(struct pipe_context *pipe,
+				   unsigned count,
+				   const struct pipe_vertex_buffer *buffers)
+{
+   struct brw_context *brw = brw_context(pipe);
+   unsigned i;
+
+   /* Check for no change */
+   if (count == brw->curr.num_vertex_buffers &&
+       memcmp(brw->curr.vertex_buffer,
+              buffers,
+              count * sizeof buffers[0]) == 0)
+      return;
+
+   /* Adjust refcounts */
+   for (i = 0; i < count; i++) 
+      pipe_buffer_reference(&brw->curr.vertex_buffer[i].buffer, 
+                            buffers[i].buffer);
+
+   for ( ; i < brw->curr.num_vertex_buffers; i++)
+      pipe_buffer_reference(&brw->curr.vertex_buffer[i].buffer,
+                            NULL);
+
+   /* Copy remaining data */
+   memcpy(brw->curr.vertex_buffer, buffers, count * sizeof buffers[0]);
+   brw->curr.num_vertex_buffers = count;
+
+   brw->state.dirty.mesa |= PIPE_NEW_VERTEX_BUFFER;
+}
+
+
+void 
+brw_pipe_vertex_init( struct brw_context *brw )
+{
+   brw->base.set_vertex_buffers = brw_set_vertex_buffers;
+   brw->base.set_vertex_elements = brw_set_vertex_elements;
+}
+
+
+void 
+brw_pipe_vertex_cleanup( struct brw_context *brw )
+{
+
+   /* Release bound pipe vertex_buffers
+    */
+
+   /* Release some other stuff
+    */
+#if 0
+   for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
+      bo_reference(&brw->vb.inputs[i].bo, NULL);
+      brw->vb.inputs[i].bo = NULL;
+   }
+#endif
+}
diff --git a/src/gallium/drivers/i965/brw_reg.h b/src/gallium/drivers/i965/brw_reg.h
new file mode 100644
index 0000000..a63403b
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_reg.h
@@ -0,0 +1,115 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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.
+ * 
+ **************************************************************************/
+
+#ifndef BRW_REG_H
+#define BRW_REG_H
+
+#define CMD_MI				(0x0 << 29)
+#define CMD_2D				(0x2 << 29)
+#define CMD_3D				(0x3 << 29)
+
+#define MI_NOOP				(CMD_MI | 0)
+#define MI_BATCH_BUFFER_END		(CMD_MI | 0xA << 23)
+#define MI_FLUSH			(CMD_MI | (4 << 23))
+
+#define _3DSTATE_DRAWRECT_INFO_I965	(CMD_3D | (3 << 27) | (1 << 24) | 0x2)
+
+/** @{
+ *
+ * PIPE_CONTROL operation, a combination MI_FLUSH and register write with
+ * additional flushing control.
+ */
+#define _3DSTATE_PIPE_CONTROL		(CMD_3D | (3 << 27) | (2 << 24) | 2)
+#define PIPE_CONTROL_NO_WRITE		(0 << 14)
+#define PIPE_CONTROL_WRITE_IMMEDIATE	(1 << 14)
+#define PIPE_CONTROL_WRITE_DEPTH_COUNT	(2 << 14)
+#define PIPE_CONTROL_WRITE_TIMESTAMP	(3 << 14)
+#define PIPE_CONTROL_DEPTH_STALL	(1 << 13)
+#define PIPE_CONTROL_WRITE_FLUSH	(1 << 12)
+#define PIPE_CONTROL_INSTRUCTION_FLUSH	(1 << 11)
+#define PIPE_CONTROL_INTERRUPT_ENABLE	(1 << 8)
+#define PIPE_CONTROL_PPGTT_WRITE	(0 << 2)
+#define PIPE_CONTROL_GLOBAL_GTT_WRITE	(1 << 2)
+
+/** @} */
+
+#define XY_SETUP_BLT_CMD		(CMD_2D | (0x01 << 22) | 6)
+#define XY_COLOR_BLT_CMD		(CMD_2D | (0x50 << 22) | 4)
+#define XY_SRC_COPY_BLT_CMD             (CMD_2D | (0x53 << 22) | 6)
+
+/* BR00 */
+#define XY_BLT_WRITE_ALPHA	(1 << 21)
+#define XY_BLT_WRITE_RGB	(1 << 20)
+#define XY_SRC_TILED		(1 << 15)
+#define XY_DST_TILED		(1 << 11)
+
+/* BR13 */
+#define BR13_565		(0x1 << 24)
+#define BR13_8888		(0x3 << 24)
+
+#define FENCE_LINEAR 0
+#define FENCE_XMAJOR 1
+#define FENCE_YMAJOR 2
+
+
+
+/* PCI IDs
+ */
+#define PCI_CHIP_I965_G			0x29A2
+#define PCI_CHIP_I965_Q			0x2992
+#define PCI_CHIP_I965_G_1		0x2982
+#define PCI_CHIP_I946_GZ		0x2972
+#define PCI_CHIP_I965_GM                0x2A02
+#define PCI_CHIP_I965_GME               0x2A12
+
+#define PCI_CHIP_GM45_GM                0x2A42
+
+#define PCI_CHIP_IGD_E_G                0x2E02
+#define PCI_CHIP_Q45_G                  0x2E12
+#define PCI_CHIP_G45_G                  0x2E22
+#define PCI_CHIP_G41_G                  0x2E32
+#define PCI_CHIP_B43_G                  0x2E42
+
+#define PCI_CHIP_ILD_G                  0x0042
+#define PCI_CHIP_ILM_G                  0x0046
+
+struct brw_chipset {
+   unsigned pci_id:16;
+   unsigned is_965:1;
+   unsigned is_igdng:1;
+   unsigned is_g4x:1;
+   unsigned pad:13;
+};
+
+
+/* XXX: hacks
+ */
+#define VERT_RESULT_HPOS 0	/* not always true */
+#define VERT_RESULT_PSIZ 10000	/* disabled */
+
+
+#endif
diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c
new file mode 100644
index 0000000..0ecacac
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_screen.c
@@ -0,0 +1,403 @@
+/**************************************************************************
+ * 
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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.
+ * 
+ **************************************************************************/
+
+
+#include "pipe/p_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_string.h"
+
+#include "brw_reg.h"
+#include "brw_context.h"
+#include "brw_screen.h"
+#include "brw_winsys.h"
+#include "brw_debug.h"
+
+#ifdef DEBUG
+static const struct debug_named_value debug_names[] = {
+   { "tex",   DEBUG_TEXTURE},
+   { "state", DEBUG_STATE},
+   { "ioctl", DEBUG_IOCTL},
+   { "blit",  DEBUG_BLIT},
+   { "curbe", DEBUG_CURBE},
+   { "fall",  DEBUG_FALLBACKS},
+   { "verb",  DEBUG_VERBOSE},
+   { "bat",   DEBUG_BATCH},
+   { "pix",   DEBUG_PIXEL},
+   { "wins",  DEBUG_WINSYS},
+   { "min",   DEBUG_MIN_URB},
+   { "dis",   DEBUG_DISASSEM},
+   { "sync",  DEBUG_SYNC},
+   { "prim",  DEBUG_PRIMS },
+   { "vert",  DEBUG_VERTS },
+   { "dma",   DEBUG_DMA },
+   { "san",   DEBUG_SANITY },
+   { "sleep", DEBUG_SLEEP },
+   { "stats", DEBUG_STATS },
+   { "sing",  DEBUG_SINGLE_THREAD },
+   { "thre",  DEBUG_SINGLE_THREAD },
+   { "wm",    DEBUG_WM },
+   { "urb",   DEBUG_URB },
+   { "vs",    DEBUG_VS },
+   { NULL,    0 }
+};
+
+static const struct debug_named_value dump_names[] = {
+   { "asm",   DUMP_ASM},
+   { "state", DUMP_STATE},
+   { "batch", DUMP_BATCH},
+   { NULL, 0 }
+};
+
+int BRW_DEBUG = 0;
+int BRW_DUMP = 0;
+
+#endif
+
+
+/*
+ * Probe functions
+ */
+
+
+static const char *
+brw_get_vendor(struct pipe_screen *screen)
+{
+   return "VMware, Inc.";
+}
+
+static const char *
+brw_get_name(struct pipe_screen *screen)
+{
+   static char buffer[128];
+   const char *chipset;
+
+   switch (brw_screen(screen)->chipset.pci_id) {
+   case PCI_CHIP_I965_G:
+      chipset = "I965_G";
+      break;
+   case PCI_CHIP_I965_Q:
+      chipset = "I965_Q";
+      break;
+   case PCI_CHIP_I965_G_1:
+      chipset = "I965_G_1";
+      break;
+   case PCI_CHIP_I946_GZ:
+      chipset = "I946_GZ";
+      break;
+   case PCI_CHIP_I965_GM:
+      chipset = "I965_GM";
+      break;
+   case PCI_CHIP_I965_GME:
+      chipset = "I965_GME";
+      break;
+   case PCI_CHIP_GM45_GM:
+      chipset = "GM45_GM";
+      break;
+   case PCI_CHIP_IGD_E_G:
+      chipset = "IGD_E_G";
+      break;
+   case PCI_CHIP_Q45_G:
+      chipset = "Q45_G";
+      break;
+   case PCI_CHIP_G45_G:
+      chipset = "G45_G";
+      break;
+   case PCI_CHIP_G41_G:
+      chipset = "G41_G";
+      break;
+   case PCI_CHIP_B43_G:
+      chipset = "B43_G";
+      break;
+   case PCI_CHIP_ILD_G:
+      chipset = "ILD_G";
+      break;
+   case PCI_CHIP_ILM_G:
+      chipset = "ILM_G";
+      break;
+   }
+
+   util_snprintf(buffer, sizeof(buffer), "i965 (chipset: %s)", chipset);
+   return buffer;
+}
+
+static int
+brw_get_param(struct pipe_screen *screen, int param)
+{
+   switch (param) {
+   case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+      return 8;
+   case PIPE_CAP_NPOT_TEXTURES:
+      return 1;
+   case PIPE_CAP_TWO_SIDED_STENCIL:
+      return 1;
+   case PIPE_CAP_GLSL:
+      return 0;
+   case PIPE_CAP_ANISOTROPIC_FILTER:
+      return 0;
+   case PIPE_CAP_POINT_SPRITE:
+      return 0;
+   case PIPE_CAP_MAX_RENDER_TARGETS:
+      return 1;
+   case PIPE_CAP_OCCLUSION_QUERY:
+      return 0;
+   case PIPE_CAP_TEXTURE_SHADOW_MAP:
+      return 1;
+   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+      return 11; /* max 1024x1024 */
+   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+      return 8;  /* max 128x128x128 */
+   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+      return 11; /* max 1024x1024 */
+   default:
+      return 0;
+   }
+}
+
+static float
+brw_get_paramf(struct pipe_screen *screen, int param)
+{
+   switch (param) {
+   case PIPE_CAP_MAX_LINE_WIDTH:
+      /* fall-through */
+   case PIPE_CAP_MAX_LINE_WIDTH_AA:
+      return 7.5;
+
+   case PIPE_CAP_MAX_POINT_WIDTH:
+      /* fall-through */
+   case PIPE_CAP_MAX_POINT_WIDTH_AA:
+      return 255.0;
+
+   case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
+      return 4.0;
+
+   case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
+      return 16.0;
+
+   default:
+      return 0;
+   }
+}
+
+static boolean
+brw_is_format_supported(struct pipe_screen *screen,
+                         enum pipe_format format, 
+                         enum pipe_texture_target target,
+                         unsigned tex_usage, 
+                         unsigned geom_flags)
+{
+   static const enum pipe_format tex_supported[] = {
+      PIPE_FORMAT_L8_UNORM,
+      PIPE_FORMAT_I8_UNORM,
+      PIPE_FORMAT_A8_UNORM,
+      PIPE_FORMAT_L16_UNORM,
+      /*PIPE_FORMAT_I16_UNORM,*/
+      /*PIPE_FORMAT_A16_UNORM,*/
+      PIPE_FORMAT_A8L8_UNORM,
+      PIPE_FORMAT_R5G6B5_UNORM,
+      PIPE_FORMAT_A1R5G5B5_UNORM,
+      PIPE_FORMAT_A4R4G4B4_UNORM,
+      PIPE_FORMAT_X8R8G8B8_UNORM,
+      PIPE_FORMAT_A8R8G8B8_UNORM,
+      /* video */
+      PIPE_FORMAT_YCBCR,
+      PIPE_FORMAT_YCBCR_REV,
+      /* compressed */
+      /*PIPE_FORMAT_FXT1_RGBA,*/
+      PIPE_FORMAT_DXT1_RGB,
+      PIPE_FORMAT_DXT1_RGBA,
+      PIPE_FORMAT_DXT3_RGBA,
+      PIPE_FORMAT_DXT5_RGBA,
+      /* sRGB */
+      PIPE_FORMAT_R8G8B8A8_SRGB,
+      PIPE_FORMAT_A8L8_SRGB,
+      PIPE_FORMAT_L8_SRGB,
+      PIPE_FORMAT_DXT1_SRGB,
+      /* depth */
+      PIPE_FORMAT_Z32_FLOAT,
+      PIPE_FORMAT_X8Z24_UNORM,
+      PIPE_FORMAT_S8Z24_UNORM,
+      PIPE_FORMAT_Z16_UNORM,
+      /* signed */
+      PIPE_FORMAT_R8G8_SNORM,
+      PIPE_FORMAT_R8G8B8A8_SNORM,
+      PIPE_FORMAT_NONE  /* list terminator */
+   };
+   static const enum pipe_format render_supported[] = {
+      PIPE_FORMAT_X8R8G8B8_UNORM,
+      PIPE_FORMAT_A8R8G8B8_UNORM,
+      PIPE_FORMAT_R5G6B5_UNORM,
+      PIPE_FORMAT_NONE  /* list terminator */
+   };
+   static const enum pipe_format depth_supported[] = {
+      PIPE_FORMAT_Z32_FLOAT,
+      PIPE_FORMAT_X8Z24_UNORM,
+      PIPE_FORMAT_S8Z24_UNORM,
+      PIPE_FORMAT_Z16_UNORM,
+      PIPE_FORMAT_NONE  /* list terminator */
+   };
+   const enum pipe_format *list;
+   uint i;
+
+   if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL)
+      list = depth_supported;
+   else if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET)
+      list = render_supported;
+   else
+      list = tex_supported;
+
+   for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) {
+      if (list[i] == format)
+         return TRUE;
+   }
+
+   return FALSE;
+}
+
+
+/*
+ * Fence functions
+ */
+
+
+static void
+brw_fence_reference(struct pipe_screen *screen,
+                     struct pipe_fence_handle **ptr,
+                     struct pipe_fence_handle *fence)
+{
+}
+
+static int
+brw_fence_signalled(struct pipe_screen *screen,
+                     struct pipe_fence_handle *fence,
+                     unsigned flags)
+{
+   return 0;                    /* XXX shouldn't this be a boolean? */
+}
+
+static int
+brw_fence_finish(struct pipe_screen *screen,
+                 struct pipe_fence_handle *fence,
+                 unsigned flags)
+{
+   return 0;
+}
+
+
+/*
+ * Generic functions
+ */
+
+
+static void
+brw_destroy_screen(struct pipe_screen *screen)
+{
+   struct brw_screen *bscreen = brw_screen(screen);
+
+   if (bscreen->sws)
+      bscreen->sws->destroy(bscreen->sws);
+
+   FREE(bscreen);
+}
+
+/**
+ * Create a new brw_screen object
+ */
+struct pipe_screen *
+brw_create_screen(struct brw_winsys_screen *sws, uint pci_id)
+{
+   struct brw_screen *bscreen;
+   struct brw_chipset chipset;
+
+#ifdef DEBUG
+   BRW_DEBUG = debug_get_flags_option("BRW_DEBUG", debug_names, 0);
+   BRW_DEBUG |= debug_get_flags_option("INTEL_DEBUG", debug_names, 0);
+   BRW_DEBUG |= DEBUG_STATS | DEBUG_MIN_URB | DEBUG_WM;
+
+   BRW_DUMP = debug_get_flags_option("BRW_DUMP", dump_names, 0);
+#endif
+
+   memset(&chipset, 0, sizeof chipset);
+
+   chipset.pci_id = pci_id;
+
+   switch (pci_id) {
+   case PCI_CHIP_I965_G:
+   case PCI_CHIP_I965_Q:
+   case PCI_CHIP_I965_G_1:
+   case PCI_CHIP_I946_GZ:
+   case PCI_CHIP_I965_GM:
+   case PCI_CHIP_I965_GME:
+      chipset.is_965 = TRUE;
+      break;
+
+   case PCI_CHIP_GM45_GM:
+   case PCI_CHIP_IGD_E_G:
+   case PCI_CHIP_Q45_G:
+   case PCI_CHIP_G45_G:
+   case PCI_CHIP_G41_G:
+   case PCI_CHIP_B43_G:
+      chipset.is_g4x = TRUE;
+      break;
+
+   case PCI_CHIP_ILD_G:
+   case PCI_CHIP_ILM_G:
+      chipset.is_igdng = TRUE;
+      break;
+
+   default:
+      debug_printf("%s: unknown pci id 0x%x, cannot create screen\n", 
+                   __FUNCTION__, pci_id);
+      return NULL;
+   }
+
+
+   bscreen = CALLOC_STRUCT(brw_screen);
+   if (!bscreen)
+      return NULL;
+
+   bscreen->chipset = chipset;
+   bscreen->sws = sws;
+   bscreen->base.winsys = NULL;
+   bscreen->base.destroy = brw_destroy_screen;
+   bscreen->base.get_name = brw_get_name;
+   bscreen->base.get_vendor = brw_get_vendor;
+   bscreen->base.get_param = brw_get_param;
+   bscreen->base.get_paramf = brw_get_paramf;
+   bscreen->base.is_format_supported = brw_is_format_supported;
+   bscreen->base.fence_reference = brw_fence_reference;
+   bscreen->base.fence_signalled = brw_fence_signalled;
+   bscreen->base.fence_finish = brw_fence_finish;
+
+   brw_screen_tex_init(bscreen);
+   brw_screen_tex_surface_init(bscreen);
+   brw_screen_buffer_init(bscreen);
+
+   bscreen->no_tiling = debug_get_option("BRW_NO_TILING", FALSE) != NULL;
+   
+   
+   return &bscreen->base;
+}
diff --git a/src/gallium/drivers/i965/brw_screen.h b/src/gallium/drivers/i965/brw_screen.h
new file mode 100644
index 0000000..7226d92
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_screen.h
@@ -0,0 +1,199 @@
+/**************************************************************************
+ * 
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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.
+ * 
+ **************************************************************************/
+
+#ifndef BRW_SCREEN_H
+#define BRW_SCREEN_H
+
+#include "pipe/p_state.h"
+#include "pipe/p_screen.h"
+
+#include "brw_reg.h"
+#include "brw_structs.h"
+
+struct brw_winsys_screen;
+
+
+/**
+ * Subclass of pipe_screen
+ */
+struct brw_screen
+{
+   struct pipe_screen base;
+   struct brw_chipset chipset;
+   struct brw_winsys_screen *sws;
+   boolean no_tiling;
+};
+
+/**
+ * Subclass of pipe_transfer
+ */
+struct brw_transfer
+{
+   struct pipe_transfer base;
+
+   unsigned offset;
+};
+
+struct brw_buffer
+{
+   struct pipe_buffer base;
+
+   /* One of either bo or user_buffer will be non-null, depending on
+    * whether this is a hardware or user buffer.
+    */
+   struct brw_winsys_buffer *bo;
+   void *user_buffer;
+
+   /* Mapped pointer??
+    */
+   void *ptr;
+};
+
+
+union brw_surface_id {
+   struct {
+      unsigned face:3;
+      unsigned zslice:13;
+      unsigned level:16;
+   } bits;
+   unsigned value;
+};
+
+
+struct brw_surface
+{
+   struct pipe_surface base;
+   
+   union brw_surface_id id;
+   unsigned cpp;
+   unsigned pitch;
+   unsigned draw_offset;
+   unsigned tiling;
+
+   struct brw_surface_state ss;
+   struct brw_winsys_buffer *bo;
+   struct brw_surface *next, *prev;
+};
+
+
+
+struct brw_texture
+{
+   struct pipe_texture base;
+   struct brw_winsys_buffer *bo;
+   struct brw_surface_state ss;
+
+   unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS];
+   unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
+   unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS];
+
+   boolean compressed;
+   unsigned brw_target;
+   unsigned pitch;
+   unsigned tiling;
+   unsigned cpp;
+   unsigned total_height;
+
+   struct brw_surface views[2];
+};
+
+
+
+/*
+ * Cast wrappers
+ */
+static INLINE struct brw_screen *
+brw_screen(struct pipe_screen *pscreen)
+{
+   return (struct brw_screen *) pscreen;
+}
+
+static INLINE struct brw_transfer *
+brw_transfer(struct pipe_transfer *transfer)
+{
+   return (struct brw_transfer *)transfer;
+}
+
+static INLINE struct brw_surface *
+brw_surface(struct pipe_surface *surface)
+{
+   return (struct brw_surface *)surface;
+}
+
+static INLINE struct brw_buffer *
+brw_buffer(struct pipe_buffer *buffer)
+{
+   return (struct brw_buffer *)buffer;
+}
+
+static INLINE struct brw_texture *
+brw_texture(struct pipe_texture *texture)
+{
+   return (struct brw_texture *)texture;
+}
+
+
+/* Pipe buffer helpers
+ */
+static INLINE boolean
+brw_buffer_is_user_buffer( const struct pipe_buffer *buf )
+{
+   return ((const struct brw_buffer *)buf)->user_buffer != NULL;
+}
+
+unsigned
+brw_surface_pitch( const struct pipe_surface *surface );
+
+/***********************************************************************
+ * Internal functions 
+ */
+GLboolean brw_texture_layout(struct brw_screen *brw_screen,
+			     struct brw_texture *tex );
+
+void brw_update_texture( struct brw_screen *brw_screen,
+			 struct brw_texture *tex );
+
+
+void brw_screen_tex_init( struct brw_screen *brw_screen );
+void brw_screen_tex_surface_init( struct brw_screen *brw_screen );
+
+void brw_screen_buffer_init(struct brw_screen *brw_screen);
+
+
+boolean brw_is_texture_referenced_by_bo( struct brw_screen *brw_screen,
+                                         struct pipe_texture *texture,
+                                         unsigned face, 
+                                         unsigned level,
+                                         struct brw_winsys_buffer *bo );
+
+boolean brw_is_buffer_referenced_by_bo( struct brw_screen *brw_screen,
+                                        struct pipe_buffer *buffer,
+                                        struct brw_winsys_buffer *bo );
+
+
+
+#endif /* BRW_SCREEN_H */
diff --git a/src/gallium/drivers/i965/brw_screen_buffers.c b/src/gallium/drivers/i965/brw_screen_buffers.c
new file mode 100644
index 0000000..d8141a3
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_screen_buffers.c
@@ -0,0 +1,202 @@
+
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_inlines.h"
+
+#include "brw_screen.h"
+#include "brw_winsys.h"
+
+
+
+static void *
+brw_buffer_map_range( struct pipe_screen *screen,
+                      struct pipe_buffer *buffer,
+                      unsigned offset,
+                      unsigned length,
+                      unsigned usage )
+{
+   struct brw_screen *bscreen = brw_screen(screen); 
+   struct brw_winsys_screen *sws = bscreen->sws;
+   struct brw_buffer *buf = brw_buffer( buffer );
+
+   if (buf->user_buffer)
+      return buf->user_buffer;
+
+   return sws->bo_map( buf->bo, 
+                       BRW_DATA_OTHER,
+                       offset,
+                       length,
+                       (usage & PIPE_BUFFER_USAGE_CPU_WRITE) ? TRUE : FALSE,
+                       (usage & PIPE_BUFFER_USAGE_DISCARD) ? TRUE : FALSE,
+                       (usage & PIPE_BUFFER_USAGE_FLUSH_EXPLICIT) ? TRUE : FALSE);
+}
+
+static void *
+brw_buffer_map( struct pipe_screen *screen,
+                struct pipe_buffer *buffer,
+                unsigned usage )
+{
+   struct brw_screen *bscreen = brw_screen(screen); 
+   struct brw_winsys_screen *sws = bscreen->sws;
+   struct brw_buffer *buf = brw_buffer( buffer );
+
+   if (buf->user_buffer)
+      return buf->user_buffer;
+
+   return sws->bo_map( buf->bo, 
+                       BRW_DATA_OTHER,
+                       0,
+                       buf->base.size,
+                       (usage & PIPE_BUFFER_USAGE_CPU_WRITE) ? TRUE : FALSE,
+                       FALSE,
+                       FALSE);
+}
+
+
+static void 
+brw_buffer_flush_mapped_range( struct pipe_screen *screen,
+                               struct pipe_buffer *buffer,
+                               unsigned offset,
+                               unsigned length )
+{
+   struct brw_screen *bscreen = brw_screen(screen); 
+   struct brw_winsys_screen *sws = bscreen->sws;
+   struct brw_buffer *buf = brw_buffer( buffer );
+
+   if (buf->user_buffer)
+      return;
+
+   sws->bo_flush_range( buf->bo, 
+                        offset,
+                        length );
+}
+
+
+static void 
+brw_buffer_unmap( struct pipe_screen *screen,
+                   struct pipe_buffer *buffer )
+{
+   struct brw_screen *bscreen = brw_screen(screen); 
+   struct brw_winsys_screen *sws = bscreen->sws;
+   struct brw_buffer *buf = brw_buffer( buffer );
+   
+   if (buf->bo)
+      sws->bo_unmap(buf->bo);
+}
+
+static void
+brw_buffer_destroy( struct pipe_buffer *buffer )
+{
+   struct brw_buffer *buf = brw_buffer( buffer );
+
+   assert(!p_atomic_read(&buffer->reference.count));
+
+   bo_reference(&buf->bo, NULL);
+   FREE(buf);
+}
+
+
+static struct pipe_buffer *
+brw_buffer_create(struct pipe_screen *screen,
+                   unsigned alignment,
+                   unsigned usage,
+                   unsigned size)
+{
+   struct brw_screen *bscreen = brw_screen(screen);
+   struct brw_winsys_screen *sws = bscreen->sws;
+   struct brw_buffer *buf;
+   unsigned buffer_type;
+   enum pipe_error ret;
+   
+   buf = CALLOC_STRUCT(brw_buffer);
+   if (!buf)
+      return NULL;
+      
+   pipe_reference_init(&buf->base.reference, 1);
+   buf->base.screen = screen;
+   buf->base.alignment = alignment;
+   buf->base.usage = usage;
+   buf->base.size = size;
+
+   switch (usage & (PIPE_BUFFER_USAGE_VERTEX |
+                    PIPE_BUFFER_USAGE_INDEX |
+                    PIPE_BUFFER_USAGE_PIXEL |
+                    PIPE_BUFFER_USAGE_CONSTANT))
+   {
+   case PIPE_BUFFER_USAGE_VERTEX:
+   case PIPE_BUFFER_USAGE_INDEX:
+   case (PIPE_BUFFER_USAGE_VERTEX|PIPE_BUFFER_USAGE_INDEX):
+      buffer_type = BRW_BUFFER_TYPE_VERTEX;
+      break;
+      
+   case PIPE_BUFFER_USAGE_PIXEL:
+      buffer_type = BRW_BUFFER_TYPE_PIXEL;
+      break;
+
+   case PIPE_BUFFER_USAGE_CONSTANT:
+      buffer_type = BRW_BUFFER_TYPE_SHADER_CONSTANTS;
+      break;
+
+   default:
+      buffer_type = BRW_BUFFER_TYPE_GENERIC;
+      break;
+   }
+   
+   ret = sws->bo_alloc( sws, buffer_type,
+                        size, alignment,
+                        &buf->bo );
+   if (ret != PIPE_OK)
+      return NULL;
+      
+   return &buf->base; 
+}
+
+
+static struct pipe_buffer *
+brw_user_buffer_create(struct pipe_screen *screen,
+                       void *ptr,
+                       unsigned bytes)
+{
+   struct brw_buffer *buf;
+   
+   buf = CALLOC_STRUCT(brw_buffer);
+   if (!buf)
+      return NULL;
+      
+   buf->user_buffer = ptr;
+   
+   pipe_reference_init(&buf->base.reference, 1);
+   buf->base.screen = screen;
+   buf->base.alignment = 1;
+   buf->base.usage = 0;
+   buf->base.size = bytes;
+   
+   return &buf->base; 
+}
+
+
+boolean brw_is_buffer_referenced_by_bo( struct brw_screen *brw_screen,
+                                     struct pipe_buffer *buffer,
+                                     struct brw_winsys_buffer *bo )
+{
+   struct brw_buffer *buf = brw_buffer(buffer);
+   if (buf->bo == NULL)
+      return FALSE;
+
+   return brw_screen->sws->bo_references( bo, buf->bo );
+}
+
+   
+void brw_screen_buffer_init(struct brw_screen *brw_screen)
+{
+   brw_screen->base.buffer_create = brw_buffer_create;
+   brw_screen->base.user_buffer_create = brw_user_buffer_create;
+   brw_screen->base.buffer_map = brw_buffer_map;
+   brw_screen->base.buffer_map_range = brw_buffer_map_range;
+   brw_screen->base.buffer_flush_mapped_range = brw_buffer_flush_mapped_range;
+   brw_screen->base.buffer_unmap = brw_buffer_unmap;
+   brw_screen->base.buffer_destroy = brw_buffer_destroy;
+}
diff --git a/src/gallium/drivers/i965/brw_screen_surface.c b/src/gallium/drivers/i965/brw_screen_surface.c
new file mode 100644
index 0000000..e2b9954
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_screen_surface.c
@@ -0,0 +1,262 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "util/u_memory.h"
+#include "util/u_simple_list.h"
+#include "util/u_math.h"
+
+#include "pipe/p_screen.h"
+#include "brw_screen.h"
+#include "brw_defines.h"
+#include "brw_winsys.h"
+
+enum {
+   BRW_VIEW_LINEAR,
+   BRW_VIEW_IN_PLACE
+};
+
+
+static boolean need_linear_view( struct brw_screen *brw_screen,
+				 struct brw_texture *brw_texture,
+				 union brw_surface_id id,
+				 unsigned usage )
+{
+#if 0
+   /* XXX: what about IDGNG?
+    */
+   if (!BRW_IS_G4X(brw->brw_screen->pci_id))
+   {
+      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
+      struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+
+      /* The original gen4 hardware couldn't set up WM surfaces pointing
+       * at an offset within a tile, which can happen when rendering to
+       * anything but the base level of a texture or the +X face/0 depth.
+       * This was fixed with the 4 Series hardware.
+       *
+       * For these original chips, you would have to make the depth and
+       * color destination surfaces include information on the texture
+       * type, LOD, face, and various limits to use them as a destination.
+       *
+       * This is easy in Gallium as surfaces are all backed by
+       * textures, but there's also a nasty requirement that the depth
+       * and the color surfaces all be of the same LOD, which is
+       * harder to get around as we can't look at a surface in
+       * isolation and decide if it's legal.
+       *
+       * Instead, end up being pessimistic and say that for i965,
+       * ... ??
+       */
+      if (brw_tex->tiling != I915_TILING_NONE &&
+	  (brw_tex_image_offset(brw_tex, face, level, zslize) & 4095)) {
+	 if (BRW_DEBUG & DEBUG_VIEW)
+	    debug_printf("%s: need surface view for non-aligned tex image\n",
+			 __FUNCTION__);
+	 return GL_TRUE;
+      }
+   }
+#endif
+
+   /* Tiled 3d textures don't have subsets that look like 2d surfaces:
+    */
+   
+   /* Everything else should be fine to render to in-place:
+    */
+   return GL_FALSE;
+}
+
+/* Look at all texture views and figure out if any of them need to be
+ * back-copied into the texture for sampling
+ */
+void brw_update_texture( struct brw_screen *brw_screen,
+			 struct brw_texture *tex )
+{
+   /* currently nothing to do */
+}
+
+
+/* Create a new surface with linear layout to serve as a render-target
+ * where it would be illegal (perhaps due to tiling constraints) to do
+ * this in-place.
+ * 
+ * Currently not implmented, not sure if it's needed.
+ */
+static struct brw_surface *create_linear_view( struct brw_screen *brw_screen,
+					       struct brw_texture *tex,
+					       union brw_surface_id id,
+					       unsigned usage )
+{
+   return NULL;
+}
+
+
+/* Create a pipe_surface that just points directly into the existing
+ * texture's storage.
+ */
+static struct brw_surface *create_in_place_view( struct brw_screen *brw_screen,
+						  struct brw_texture *tex,
+						  union brw_surface_id id,
+						  unsigned usage )
+{
+   struct brw_surface *surface;
+
+   surface = CALLOC_STRUCT(brw_surface);
+   if (surface == NULL)
+      return NULL;
+
+   pipe_reference_init(&surface->base.reference, 1);
+
+   /* XXX: ignoring render-to-slice-of-3d-texture
+    */
+   assert(id.bits.zslice == 0);
+
+   surface->base.format = tex->base.format;
+   surface->base.width = u_minify(tex->base.width0, id.bits.level);
+   surface->base.height = u_minify(tex->base.height0, id.bits.level);
+   surface->base.offset = tex->image_offset[id.bits.level][id.bits.face];
+   surface->base.usage = usage;
+   surface->base.zslice = id.bits.zslice;
+   surface->base.face = id.bits.face;
+   surface->base.level = id.bits.level;
+   surface->id = id;
+   surface->cpp = tex->cpp;
+   surface->pitch = tex->pitch;
+   surface->tiling = tex->tiling;
+
+   bo_reference( &surface->bo, tex->bo );
+   pipe_texture_reference( &surface->base.texture, &tex->base );
+
+   surface->ss.ss0.surface_format = tex->ss.ss0.surface_format;
+   surface->ss.ss0.surface_type = BRW_SURFACE_2D;
+
+   if (tex->tiling == BRW_TILING_NONE) {
+      surface->ss.ss1.base_addr = surface->base.offset;
+   } else {
+      uint32_t tile_offset = surface->base.offset % 4096;
+
+      surface->ss.ss1.base_addr = surface->base.offset - tile_offset;
+
+      if (brw_screen->chipset.is_g4x) {
+	 if (tex->tiling == BRW_TILING_X) {
+	    /* Note that the low bits of these fields are missing, so
+	     * there's the possibility of getting in trouble.
+	     */
+	    surface->ss.ss5.x_offset = (tile_offset % 512) / tex->cpp / 4;
+	    surface->ss.ss5.y_offset = tile_offset / 512 / 2;
+	 } else {
+	    surface->ss.ss5.x_offset = (tile_offset % 128) / tex->cpp / 4;
+	    surface->ss.ss5.y_offset = tile_offset / 128 / 2;
+	 }
+      }
+      else {
+	 assert(tile_offset == 0);
+      }
+   }
+
+#if 0
+   if (region_bo != NULL)
+      surface->ss.ss1.base_addr += region_bo->offset; /* reloc */
+#endif
+
+   surface->ss.ss2.width = surface->base.width - 1;
+   surface->ss.ss2.height = surface->base.height - 1;
+   surface->ss.ss3.tiled_surface = tex->ss.ss3.tiled_surface;
+   surface->ss.ss3.tile_walk = tex->ss.ss3.tile_walk;
+   surface->ss.ss3.pitch = tex->ss.ss3.pitch;
+
+   return surface;
+}
+
+/* Get a surface which is view into a texture 
+ */
+static struct pipe_surface *brw_get_tex_surface(struct pipe_screen *screen,
+						struct pipe_texture *pt,
+						unsigned face, unsigned level,
+						unsigned zslice,
+						unsigned usage )
+{
+   struct brw_texture *tex = brw_texture(pt);
+   struct brw_screen *bscreen = brw_screen(screen);
+   struct brw_surface *surface;
+   union brw_surface_id id;
+   int type;
+
+   id.bits.face = face;
+   id.bits.level = level;
+   id.bits.zslice = zslice;
+
+   if (need_linear_view(bscreen, tex, id, usage)) 
+      type = BRW_VIEW_LINEAR;
+   else
+      type = BRW_VIEW_IN_PLACE;
+
+   
+   foreach (surface, &tex->views[type]) {
+      if (id.value == surface->id.value)
+	 return &surface->base;
+   }
+
+   switch (type) {
+   case BRW_VIEW_LINEAR:
+      surface = create_linear_view( bscreen, tex, id, usage );
+      break;
+   case BRW_VIEW_IN_PLACE:
+      surface = create_in_place_view( bscreen, tex, id, usage );
+      break;
+   default:
+      return NULL;
+   }
+
+   insert_at_head( &tex->views[type], surface );
+   return &surface->base;
+}
+
+
+static void brw_tex_surface_destroy( struct pipe_surface *surf )
+{
+   struct brw_surface *surface = brw_surface(surf);
+
+   /* Unreference texture, shared buffer:
+    */
+   remove_from_list(surface);
+   bo_reference(&surface->bo, NULL);
+   pipe_texture_reference( &surface->base.texture, NULL );
+
+
+   FREE(surface);
+}
+
+
+void brw_screen_tex_surface_init( struct brw_screen *brw_screen )
+{
+   brw_screen->base.get_tex_surface = brw_get_tex_surface;
+   brw_screen->base.tex_surface_destroy = brw_tex_surface_destroy;
+}
diff --git a/src/gallium/drivers/i965/brw_screen_tex_layout.c b/src/gallium/drivers/i965/brw_screen_tex_layout.c
new file mode 100644
index 0000000..894f4be
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_screen_tex_layout.c
@@ -0,0 +1,414 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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_format.h"
+
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "brw_screen.h"
+#include "brw_debug.h"
+#include "brw_winsys.h"
+
+/* Code to layout images in a mipmap tree for i965.
+ */
+
+static int 
+brw_tex_pitch_align (struct brw_texture *tex,
+		     int pitch)
+{
+   if (!tex->compressed) {
+      int pitch_align;
+
+      switch (tex->tiling) {
+      case BRW_TILING_X:
+	 pitch_align = 512;
+	 break;
+      case BRW_TILING_Y:
+	 pitch_align = 128;
+	 break;
+      default:
+	 /* XXX: Untiled pitch alignment of 64 bytes for now to allow
+	  * render-to-texture to work in all cases. This should
+	  * probably be replaced at some point by some scheme to only
+	  * do this when really necessary, for example standalone
+	  * render target views.
+	  */
+	 pitch_align = 64;
+	 break;
+      }
+
+      pitch = align(pitch * tex->cpp, pitch_align);
+      pitch /= tex->cpp;
+   }
+
+   return pitch;
+}
+
+
+static void 
+brw_tex_alignment_unit(enum pipe_format pf, 
+		       GLuint *w, GLuint *h)
+{
+    switch (pf) {
+    case PIPE_FORMAT_DXT1_RGB:
+    case PIPE_FORMAT_DXT1_RGBA:
+    case PIPE_FORMAT_DXT3_RGBA:
+    case PIPE_FORMAT_DXT5_RGBA:
+    case PIPE_FORMAT_DXT1_SRGB:
+    case PIPE_FORMAT_DXT1_SRGBA:
+    case PIPE_FORMAT_DXT3_SRGBA:
+    case PIPE_FORMAT_DXT5_SRGBA:
+        *w = 4;
+        *h = 4;
+        break;
+
+    default:
+        *w = 4;
+        *h = 2;
+        break;
+    }
+}
+
+
+static void 
+brw_tex_set_level_info(struct brw_texture *tex,
+		       GLuint level,
+		       GLuint nr_images,
+		       GLuint x, GLuint y,
+		       GLuint w, GLuint h, GLuint d)
+{
+
+   if (BRW_DEBUG & DEBUG_TEXTURE)
+      debug_printf("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
+		   level, w, h, d, x, y, tex->level_offset[level]);
+
+   assert(tex->image_offset[level] == NULL);
+   assert(nr_images >= 1);
+
+   tex->level_offset[level] = (x + y * tex->pitch) * tex->cpp;
+   tex->nr_images[level] = nr_images;
+
+   tex->image_offset[level] = MALLOC(nr_images * sizeof(GLuint));
+   tex->image_offset[level][0] = 0;
+}
+
+
+static void
+brw_tex_set_image_offset(struct brw_texture *tex,
+			 GLuint level, GLuint img,
+			 GLuint x, GLuint y, 
+			 GLuint offset)
+{
+   assert((x == 0 && y == 0) || img != 0 || level != 0);
+   assert(img < tex->nr_images[level]);
+
+   if (BRW_DEBUG & DEBUG_TEXTURE)
+      debug_printf("%s level %d img %d pos %d,%d image_offset %x\n",
+		   __FUNCTION__, level, img, x, y, 
+		   tex->image_offset[level][img]);
+
+   tex->image_offset[level][img] = (x + y * tex->pitch) * tex->cpp + offset;
+}
+
+
+
+static void brw_layout_2d( struct brw_texture *tex )
+{
+   GLuint align_h = 2, align_w = 4;
+   GLuint level;
+   GLuint x = 0;
+   GLuint y = 0;
+   GLuint width = tex->base.width0;
+   GLuint height = tex->base.height0;
+
+   tex->pitch = tex->base.width0;
+   brw_tex_alignment_unit(tex->base.format, &align_w, &align_h);
+
+   if (tex->compressed) {
+       tex->pitch = align(tex->base.width0, align_w);
+   }
+
+   /* May need to adjust pitch to accomodate the placement of
+    * the 2nd mipmap.  This occurs when the alignment
+    * constraints of mipmap placement push the right edge of the
+    * 2nd mipmap out past the width of its parent.
+    */
+   if (tex->base.last_level > 0) {
+       GLuint mip1_width;
+
+       if (tex->compressed) {
+          mip1_width = (align(u_minify(tex->base.width0, 1), align_w) + 
+                        align(u_minify(tex->base.width0, 2), align_w));
+       } else {
+          mip1_width = (align(u_minify(tex->base.width0, 1), align_w) + 
+                        u_minify(tex->base.width0, 2));
+       }
+
+       if (mip1_width > tex->pitch) {
+           tex->pitch = mip1_width;
+       }
+   }
+
+   /* Pitch must be a whole number of dwords, even though we
+    * express it in texels.
+    */
+   tex->pitch = brw_tex_pitch_align (tex, tex->pitch);
+   tex->total_height = 0;
+
+   for ( level = 0 ; level <= tex->base.last_level ; level++ ) {
+      GLuint img_height;
+
+      brw_tex_set_level_info(tex, level, 1, x, y, width, height, 1);
+
+      if (tex->compressed)
+	 img_height = MAX2(1, height/4);
+      else
+	 img_height = align(height, align_h);
+
+
+      /* Because the images are packed better, the final offset
+       * might not be the maximal one:
+       */
+      tex->total_height = MAX2(tex->total_height, y + img_height);
+
+      /* Layout_below: step right after second mipmap.
+       */
+      if (level == 1) {
+	 x += align(width, align_w);
+      }
+      else {
+	 y += img_height;
+      }
+
+      width  = u_minify(width, 1);
+      height = u_minify(height, 1);
+   }
+}
+
+
+static boolean 
+brw_layout_cubemap_idgng( struct brw_texture *tex )
+{
+   GLuint align_h = 2, align_w = 4;
+   GLuint level;
+   GLuint x = 0;
+   GLuint y = 0;
+   GLuint width = tex->base.width0;
+   GLuint height = tex->base.height0;
+   GLuint qpitch = 0;
+   GLuint y_pitch = 0;
+
+   tex->pitch = tex->base.width0;
+   brw_tex_alignment_unit(tex->base.format, &align_w, &align_h);
+   y_pitch = align(height, align_h);
+
+   if (tex->compressed) {
+      tex->pitch = align(tex->base.width0, align_w);
+   }
+
+   if (tex->base.last_level != 0) {
+      GLuint mip1_width;
+
+      if (tex->compressed) {
+	 mip1_width = (align(u_minify(tex->base.width0, 1), align_w) +
+		       align(u_minify(tex->base.width0, 2), align_w));
+      } else {
+	 mip1_width = (align(u_minify(tex->base.width0, 1), align_w) +
+		       u_minify(tex->base.width0, 2));
+      }
+
+      if (mip1_width > tex->pitch) {
+	 tex->pitch = mip1_width;
+      }
+   }
+
+   tex->pitch = brw_tex_pitch_align(tex, tex->pitch);
+
+   if (tex->compressed) {
+      qpitch = ((y_pitch + 
+		 align(u_minify(y_pitch, 1), align_h) +
+		 11 * align_h) / 4) * tex->pitch * tex->cpp;
+
+      tex->total_height = ((y_pitch + 
+			    align(u_minify(y_pitch, 1), align_h) + 
+			    11 * align_h) / 4) * 6;
+   } else {
+      qpitch = (y_pitch + 
+		align(u_minify(y_pitch, 1), align_h) + 
+		11 * align_h) * tex->pitch * tex->cpp;
+
+      tex->total_height = (y_pitch +
+			   align(u_minify(y_pitch, 1), align_h) +
+			   11 * align_h) * 6;
+   }
+
+   for (level = 0; level <= tex->base.last_level; level++) {
+      GLuint img_height;
+      GLuint nr_images = 6;
+      GLuint q = 0;
+
+      brw_tex_set_level_info(tex, level, nr_images, x, y, width, height, 1);
+
+      for (q = 0; q < nr_images; q++)
+	 brw_tex_set_image_offset(tex, level, q, x, y, q * qpitch);
+
+      if (tex->compressed)
+	 img_height = MAX2(1, height/4);
+      else
+	 img_height = align(height, align_h);
+
+      if (level == 1) {
+	 x += align(width, align_w);
+      }
+      else {
+	 y += img_height;
+      }
+
+      width  = u_minify(width, 1);
+      height = u_minify(height, 1);
+   }
+
+   return TRUE;
+}
+
+
+static boolean
+brw_layout_3d_cube( struct brw_texture *tex )
+{
+   GLuint width  = tex->base.width0;
+   GLuint height = tex->base.height0;
+   GLuint depth = tex->base.depth0;
+   GLuint pack_x_pitch, pack_x_nr;
+   GLuint pack_y_pitch;
+   GLuint level;
+   GLuint align_h = 2;
+   GLuint align_w = 4;
+
+   tex->total_height = 0;
+   brw_tex_alignment_unit(tex->base.format, &align_w, &align_h);
+
+   if (tex->compressed) {
+      tex->pitch = align(width, align_w);
+      pack_y_pitch = (height + 3) / 4;
+   } else {
+      tex->pitch = brw_tex_pitch_align(tex, tex->base.width0);
+      pack_y_pitch = align(tex->base.height0, align_h);
+   }
+
+   pack_x_pitch = width;
+   pack_x_nr = 1;
+
+   for (level = 0 ; level <= tex->base.last_level ; level++) {
+      GLuint nr_images = tex->base.target == PIPE_TEXTURE_3D ? depth : 6;
+      GLint x = 0;
+      GLint y = 0;
+      GLint q, j;
+
+      brw_tex_set_level_info(tex, level, nr_images,
+				   0, tex->total_height,
+				   width, height, depth);
+
+      for (q = 0; q < nr_images;) {
+	 for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
+	    brw_tex_set_image_offset(tex, level, q, x, y, 0);
+	    x += pack_x_pitch;
+	 }
+
+	 x = 0;
+	 y += pack_y_pitch;
+      }
+
+
+      tex->total_height += y;
+      width  = u_minify(width, 1);
+      height = u_minify(height, 1);
+      depth  = u_minify(depth, 1);
+
+      if (tex->compressed) {
+	 pack_y_pitch = (height + 3) / 4;
+
+	 if (pack_x_pitch > align(width, align_w)) {
+	    pack_x_pitch = align(width, align_w);
+	    pack_x_nr <<= 1;
+	 }
+      } else {
+	 if (pack_x_pitch > 4) {
+	    pack_x_pitch >>= 1;
+	    pack_x_nr <<= 1;
+	    assert(pack_x_pitch * pack_x_nr <= tex->pitch);
+	 }
+
+	 if (pack_y_pitch > 2) {
+	    pack_y_pitch >>= 1;
+	    pack_y_pitch = align(pack_y_pitch, align_h);
+	 }
+      }
+   }
+
+   /* The 965's sampler lays cachelines out according to how accesses
+    * in the texture surfaces run, so they may be "vertical" through
+    * memory.  As a result, the docs say in Surface Padding Requirements:
+    * Sampling Engine Surfaces that two extra rows of padding are required.
+    */
+   if (tex->base.target == PIPE_TEXTURE_CUBE)
+      tex->total_height += 2;
+
+   return TRUE;
+}
+
+
+
+GLboolean brw_texture_layout(struct brw_screen *brw_screen,
+			     struct brw_texture *tex )
+{
+   switch (tex->base.target) {
+   case PIPE_TEXTURE_CUBE:
+      if (brw_screen->chipset.is_igdng)
+	 brw_layout_cubemap_idgng( tex );
+      else
+	 brw_layout_3d_cube( tex );
+      break;
+	    
+   case PIPE_TEXTURE_3D:
+      brw_layout_3d_cube( tex );
+      break;
+
+   default:
+      brw_layout_2d( tex );
+      break;
+   }
+
+   if (BRW_DEBUG & DEBUG_TEXTURE)
+      debug_printf("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
+		   tex->pitch,
+		   tex->total_height,
+		   tex->cpp,
+		   tex->pitch * tex->total_height * tex->cpp );
+
+   return GL_TRUE;
+}
diff --git a/src/gallium/drivers/i965/brw_screen_texture.c b/src/gallium/drivers/i965/brw_screen_texture.c
new file mode 100644
index 0000000..feb9d5f
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_screen_texture.c
@@ -0,0 +1,573 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "util/u_memory.h"
+#include "util/u_simple_list.h"
+#include "util/u_format.h"
+
+#include "brw_screen.h"
+#include "brw_defines.h"
+#include "brw_structs.h"
+#include "brw_winsys.h"
+
+
+
+static GLuint translate_tex_target( unsigned target )
+{
+   switch (target) {
+   case PIPE_TEXTURE_1D: 
+      return BRW_SURFACE_1D;
+
+   case PIPE_TEXTURE_2D: 
+      return BRW_SURFACE_2D;
+
+   case PIPE_TEXTURE_3D: 
+      return BRW_SURFACE_3D;
+
+   case PIPE_TEXTURE_CUBE:
+      return BRW_SURFACE_CUBE;
+
+   default: 
+      assert(0); 
+      return BRW_SURFACE_1D;
+   }
+}
+
+
+static GLuint translate_tex_format( enum pipe_format pf )
+{
+   switch( pf ) {
+   case PIPE_FORMAT_L8_UNORM:
+      return BRW_SURFACEFORMAT_L8_UNORM;
+
+   case PIPE_FORMAT_I8_UNORM:
+      return BRW_SURFACEFORMAT_I8_UNORM;
+
+   case PIPE_FORMAT_A8_UNORM:
+      return BRW_SURFACEFORMAT_A8_UNORM; 
+
+   case PIPE_FORMAT_L16_UNORM:
+      return BRW_SURFACEFORMAT_L16_UNORM;
+
+      /* XXX: Add these to gallium
+   case PIPE_FORMAT_I16_UNORM:
+      return BRW_SURFACEFORMAT_I16_UNORM;
+
+   case PIPE_FORMAT_A16_UNORM:
+      return BRW_SURFACEFORMAT_A16_UNORM; 
+      */
+
+   case PIPE_FORMAT_A8L8_UNORM:
+      return BRW_SURFACEFORMAT_L8A8_UNORM;
+
+   case PIPE_FORMAT_R5G6B5_UNORM:
+      return BRW_SURFACEFORMAT_B5G6R5_UNORM;
+
+   case PIPE_FORMAT_A1R5G5B5_UNORM:
+      return BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
+
+   case PIPE_FORMAT_A4R4G4B4_UNORM:
+      return BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
+
+   case PIPE_FORMAT_X8R8G8B8_UNORM:
+      return BRW_SURFACEFORMAT_R8G8B8X8_UNORM;
+
+   case PIPE_FORMAT_A8R8G8B8_UNORM:
+      return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+
+   /*
+    * Video formats
+    */
+
+   case PIPE_FORMAT_YCBCR_REV:
+      return BRW_SURFACEFORMAT_YCRCB_NORMAL;
+
+   case PIPE_FORMAT_YCBCR:
+      return BRW_SURFACEFORMAT_YCRCB_SWAPUVY;
+
+   /*
+    * Compressed formats.
+    */
+      /* XXX: Add FXT to gallium?
+   case PIPE_FORMAT_FXT1_RGBA:
+      return BRW_SURFACEFORMAT_FXT1;
+      */
+
+   case PIPE_FORMAT_DXT1_RGB:
+       return BRW_SURFACEFORMAT_DXT1_RGB;
+
+   case PIPE_FORMAT_DXT1_RGBA:
+       return BRW_SURFACEFORMAT_BC1_UNORM;
+       
+   case PIPE_FORMAT_DXT3_RGBA:
+       return BRW_SURFACEFORMAT_BC2_UNORM;
+       
+   case PIPE_FORMAT_DXT5_RGBA:
+       return BRW_SURFACEFORMAT_BC3_UNORM;
+
+   /*
+    * sRGB formats
+    */
+
+   case PIPE_FORMAT_R8G8B8A8_SRGB:
+      return BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB;
+
+   case PIPE_FORMAT_A8L8_SRGB:
+      return BRW_SURFACEFORMAT_L8A8_UNORM_SRGB;
+
+   case PIPE_FORMAT_L8_SRGB:
+      return BRW_SURFACEFORMAT_L8_UNORM_SRGB;
+
+   case PIPE_FORMAT_DXT1_SRGB:
+      return BRW_SURFACEFORMAT_BC1_UNORM_SRGB;
+
+   /*
+    * Depth formats
+    */
+
+   case PIPE_FORMAT_Z16_UNORM:
+         return BRW_SURFACEFORMAT_I16_UNORM;
+
+   case PIPE_FORMAT_S8Z24_UNORM:
+   case PIPE_FORMAT_X8Z24_UNORM:
+         return BRW_SURFACEFORMAT_I24X8_UNORM;
+
+   case PIPE_FORMAT_Z32_FLOAT:
+         return BRW_SURFACEFORMAT_I32_FLOAT;
+
+      /* XXX: presumably for bump mapping.  Add this to mesa state
+       * tracker?
+       *
+       * XXX: Add flipped versions of these formats to Gallium.
+       */
+   case PIPE_FORMAT_R8G8_SNORM:
+      return BRW_SURFACEFORMAT_R8G8_SNORM;
+
+   case PIPE_FORMAT_R8G8B8A8_SNORM:
+      return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
+
+   default:
+      return BRW_SURFACEFORMAT_INVALID;
+   }
+}
+
+
+
+
+
+static struct pipe_texture *brw_texture_create( struct pipe_screen *screen,
+						const struct pipe_texture *templ )
+
+{  
+   struct brw_screen *bscreen = brw_screen(screen);
+   struct brw_texture *tex;
+   enum brw_buffer_type buffer_type;
+   enum pipe_error ret;
+   
+   tex = CALLOC_STRUCT(brw_texture);
+   if (tex == NULL)
+      return NULL;
+
+   memcpy(&tex->base, templ, sizeof *templ);
+   pipe_reference_init(&tex->base.reference, 1);
+   tex->base.screen = screen;
+
+   /* XXX: compressed textures need special treatment here
+    */
+   tex->cpp = util_format_get_blocksize(tex->base.format);
+   tex->compressed = util_format_is_compressed(tex->base.format);
+
+   make_empty_list(&tex->views[0]);
+   make_empty_list(&tex->views[1]);
+
+   /* XXX: No tiling with compressed textures??
+    */
+   if (tex->compressed == 0 &&
+       !bscreen->no_tiling) 
+   {
+      if (bscreen->chipset.is_965 &&
+	  util_format_is_depth_or_stencil(templ->format))
+	 tex->tiling = BRW_TILING_Y;
+      else
+	 tex->tiling = BRW_TILING_X;
+   } 
+   else {
+      tex->tiling = BRW_TILING_NONE;
+   }
+
+
+
+
+   if (!brw_texture_layout( bscreen, tex ))
+      goto fail;
+
+   
+   if (templ->tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+                           PIPE_TEXTURE_USAGE_PRIMARY)) {
+      buffer_type = BRW_BUFFER_TYPE_SCANOUT;
+   }
+   else {
+      buffer_type = BRW_BUFFER_TYPE_TEXTURE;
+   }
+
+   ret = bscreen->sws->bo_alloc( bscreen->sws,
+                                 buffer_type,
+                                 tex->pitch * tex->total_height * tex->cpp,
+                                 64,
+                                 &tex->bo );
+   if (ret)
+      goto fail;
+
+   tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
+   tex->ss.ss0.surface_type = translate_tex_target(tex->base.target);
+   tex->ss.ss0.surface_format = translate_tex_format(tex->base.format);
+   assert(tex->ss.ss0.surface_format != BRW_SURFACEFORMAT_INVALID);
+
+   /* This is ok for all textures with channel width 8bit or less:
+    */
+/*    tex->ss.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
+
+
+   /* XXX: what happens when tex->bo->offset changes???
+    */
+   tex->ss.ss1.base_addr = 0; /* reloc */
+   tex->ss.ss2.mip_count = tex->base.last_level;
+   tex->ss.ss2.width = tex->base.width0 - 1;
+   tex->ss.ss2.height = tex->base.height0 - 1;
+
+   switch (tex->tiling) {
+   case BRW_TILING_NONE:
+      tex->ss.ss3.tiled_surface = 0;
+      tex->ss.ss3.tile_walk = 0;
+      break;
+   case BRW_TILING_X:
+      tex->ss.ss3.tiled_surface = 1;
+      tex->ss.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
+      break;
+   case BRW_TILING_Y:
+      tex->ss.ss3.tiled_surface = 1;
+      tex->ss.ss3.tile_walk = BRW_TILEWALK_YMAJOR;
+      break;
+   }
+
+   tex->ss.ss3.pitch = (tex->pitch * tex->cpp) - 1;
+   tex->ss.ss3.depth = tex->base.depth0 - 1;
+
+   tex->ss.ss4.min_lod = 0;
+ 
+   if (tex->base.target == PIPE_TEXTURE_CUBE) {
+      tex->ss.ss0.cube_pos_x = 1;
+      tex->ss.ss0.cube_pos_y = 1;
+      tex->ss.ss0.cube_pos_z = 1;
+      tex->ss.ss0.cube_neg_x = 1;
+      tex->ss.ss0.cube_neg_y = 1;
+      tex->ss.ss0.cube_neg_z = 1;
+   }
+
+   return &tex->base;
+
+fail:
+   bo_reference(&tex->bo, NULL);
+   FREE(tex);
+   return NULL;
+}
+
+static struct pipe_texture *brw_texture_blanket(struct pipe_screen *screen,
+						const struct pipe_texture *templ,
+						const unsigned *stride,
+						struct pipe_buffer *buffer)
+{
+   return NULL;
+}
+
+static void brw_texture_destroy(struct pipe_texture *pt)
+{
+   struct brw_texture *tex = brw_texture(pt);
+   bo_reference(&tex->bo, NULL);
+   FREE(pt);
+}
+
+
+static boolean brw_is_format_supported( struct pipe_screen *screen,
+					enum pipe_format format,
+					enum pipe_texture_target target,
+					unsigned tex_usage, 
+					unsigned geom_flags )
+{
+   return translate_tex_format(format) != BRW_SURFACEFORMAT_INVALID;
+}
+
+
+boolean brw_is_texture_referenced_by_bo( struct brw_screen *brw_screen,
+                                      struct pipe_texture *texture,
+                                      unsigned face, 
+                                      unsigned level,
+                                      struct brw_winsys_buffer *bo )
+{
+   struct brw_texture *tex = brw_texture(texture);
+   struct brw_surface *surf;
+   int i;
+
+   /* XXX: this is subject to false positives if the underlying
+    * texture BO is referenced, we can't tell whether the sub-region
+    * we care about participates in that.
+    */
+   if (brw_screen->sws->bo_references( bo, tex->bo ))
+      return TRUE;
+
+   /* Find any view on this texture for this face/level and see if it
+    * is referenced:
+    */
+   for (i = 0; i < 2; i++) {
+      foreach (surf, &tex->views[i]) {
+         if (surf->bo == tex->bo)
+            continue;
+
+         if (surf->id.bits.face != face ||
+             surf->id.bits.level != level)
+            continue;
+         
+         if (brw_screen->sws->bo_references( bo, surf->bo))
+            return TRUE;
+      }
+   }
+
+   return FALSE;
+}
+
+
+/*
+ * Transfer functions
+ */
+
+static struct pipe_transfer*
+brw_get_tex_transfer(struct pipe_screen *screen,
+                     struct pipe_texture *texture,
+                     unsigned face, unsigned level, unsigned zslice,
+                     enum pipe_transfer_usage usage, unsigned x, unsigned y,
+                     unsigned w, unsigned h)
+{
+   struct brw_texture *tex = brw_texture(texture);
+   struct brw_transfer *trans;
+   unsigned offset;  /* in bytes */
+
+   if (texture->target == PIPE_TEXTURE_CUBE) {
+      offset = tex->image_offset[level][face];
+   } else if (texture->target == PIPE_TEXTURE_3D) {
+      offset = tex->image_offset[level][zslice];
+   } else {
+      offset = tex->image_offset[level][0];
+      assert(face == 0);
+      assert(zslice == 0);
+   }
+
+   trans = CALLOC_STRUCT(brw_transfer);
+   if (trans) {
+      pipe_texture_reference(&trans->base.texture, texture);
+      trans->base.x = x;
+      trans->base.y = y;
+      trans->base.width = w;
+      trans->base.height = h;
+      trans->base.stride = tex->pitch * tex->cpp;
+      trans->offset = offset;
+      trans->base.usage = usage;
+   }
+   return &trans->base;
+}
+
+static void *
+brw_transfer_map(struct pipe_screen *screen,
+                 struct pipe_transfer *transfer)
+{
+   struct brw_texture *tex = brw_texture(transfer->texture);
+   struct brw_winsys_screen *sws = brw_screen(screen)->sws;
+   char *map;
+   unsigned usage = transfer->usage;
+
+   map = sws->bo_map(tex->bo, 
+                     BRW_DATA_OTHER,
+                     0,
+                     tex->bo->size,
+                     (usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE,
+                     (usage & 0) ? TRUE : FALSE,
+                     (usage & 0) ? TRUE : FALSE);
+
+   if (!map)
+      return NULL;
+
+   /* XXX: blocksize and compressed textures
+    */
+   return map + brw_transfer(transfer)->offset +
+      transfer->y /* / transfer->block.height */ * transfer->stride +
+      transfer->x /* / transfer->block.width */ * brw_texture(transfer->texture)->cpp;
+}
+
+static void
+brw_transfer_unmap(struct pipe_screen *screen,
+                   struct pipe_transfer *transfer)
+{
+   struct brw_texture *tex = brw_texture(transfer->texture);
+   struct brw_winsys_screen *sws = brw_screen(screen)->sws;
+
+   sws->bo_unmap(tex->bo);
+}
+
+static void
+brw_tex_transfer_destroy(struct pipe_transfer *trans)
+{
+   pipe_texture_reference(&trans->texture, NULL);
+   FREE(trans);
+}
+
+
+/*
+ * Functions exported to the winsys
+ */
+
+boolean brw_texture_get_winsys_buffer(struct pipe_texture *texture,
+                                      struct brw_winsys_buffer **buffer,
+                                      unsigned *stride)
+{
+   struct brw_texture *tex = brw_texture(texture);
+
+   *buffer = tex->bo;
+   if (stride)
+      *stride = tex->pitch * tex->cpp;
+
+   return TRUE;
+}
+
+struct pipe_texture * 
+brw_texture_blanket_winsys_buffer(struct pipe_screen *screen,
+                                  const struct pipe_texture *templ,
+                                  unsigned pitch,
+				  unsigned tiling,
+                                  struct brw_winsys_buffer *buffer)
+{
+   struct brw_screen *bscreen = brw_screen(screen);
+   struct brw_texture *tex;
+
+   if (templ->target != PIPE_TEXTURE_2D ||
+       templ->last_level != 0 ||
+       templ->depth0 != 1)
+      return NULL;
+
+   if (util_format_is_compressed(templ->format))
+      return NULL;
+
+   tex = CALLOC_STRUCT(brw_texture);
+   if (!tex)
+      return NULL;
+
+   memcpy(&tex->base, templ, sizeof *templ);
+   pipe_reference_init(&tex->base.reference, 1);
+   tex->base.screen = screen;
+
+   /* XXX: cpp vs. blocksize
+    */
+   tex->cpp = util_format_get_blocksize(tex->base.format);
+   tex->tiling = tiling;
+
+   make_empty_list(&tex->views[0]);
+   make_empty_list(&tex->views[1]);
+
+   if (!brw_texture_layout(bscreen, tex))
+      goto fail;
+
+   /* XXX Maybe some more checks? */
+   if ((pitch / tex->cpp) < tex->pitch)
+      goto fail;
+
+   tex->pitch = pitch / tex->cpp;
+
+   tex->bo = buffer;
+
+   /* fix this warning */
+#if 0
+   if (tex->size > buffer->size)
+      goto fail;
+#endif
+
+   tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
+   tex->ss.ss0.surface_type = translate_tex_target(tex->base.target);
+   tex->ss.ss0.surface_format = translate_tex_format(tex->base.format);
+   assert(tex->ss.ss0.surface_format != BRW_SURFACEFORMAT_INVALID);
+
+   /* This is ok for all textures with channel width 8bit or less:
+    */
+/*    tex->ss.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
+
+
+   /* XXX: what happens when tex->bo->offset changes???
+    */
+   tex->ss.ss1.base_addr = 0; /* reloc */
+   tex->ss.ss2.mip_count = tex->base.last_level;
+   tex->ss.ss2.width = tex->base.width0 - 1;
+   tex->ss.ss2.height = tex->base.height0 - 1;
+
+   switch (tex->tiling) {
+   case BRW_TILING_NONE:
+      tex->ss.ss3.tiled_surface = 0;
+      tex->ss.ss3.tile_walk = 0;
+      break;
+   case BRW_TILING_X:
+      tex->ss.ss3.tiled_surface = 1;
+      tex->ss.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
+      break;
+   case BRW_TILING_Y:
+      tex->ss.ss3.tiled_surface = 1;
+      tex->ss.ss3.tile_walk = BRW_TILEWALK_YMAJOR;
+      break;
+   }
+
+   tex->ss.ss3.pitch = (tex->pitch * tex->cpp) - 1;
+   tex->ss.ss3.depth = tex->base.depth0 - 1;
+
+   tex->ss.ss4.min_lod = 0;
+
+   return &tex->base;
+
+fail:
+   FREE(tex);
+   return NULL;
+}
+
+void brw_screen_tex_init( struct brw_screen *brw_screen )
+{
+   brw_screen->base.is_format_supported = brw_is_format_supported;
+   brw_screen->base.texture_create = brw_texture_create;
+   brw_screen->base.texture_destroy = brw_texture_destroy;
+   brw_screen->base.texture_blanket = brw_texture_blanket;
+   brw_screen->base.get_tex_transfer = brw_get_tex_transfer;
+   brw_screen->base.transfer_map = brw_transfer_map;
+   brw_screen->base.transfer_unmap = brw_transfer_unmap;
+   brw_screen->base.tex_transfer_destroy = brw_tex_transfer_destroy;
+}
diff --git a/src/gallium/drivers/i965/brw_sf.c b/src/gallium/drivers/i965/brw_sf.c
new file mode 100644
index 0000000..e1986a9
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_sf.c
@@ -0,0 +1,216 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+  
+#include "pipe/p_state.h"
+
+#include "brw_batchbuffer.h"
+#include "brw_defines.h"
+#include "brw_context.h"
+#include "brw_pipe_rast.h"
+#include "brw_eu.h"
+#include "brw_util.h"
+#include "brw_sf.h"
+#include "brw_state.h"
+
+static enum pipe_error compile_sf_prog( struct brw_context *brw,
+                                        struct brw_sf_prog_key *key,
+                                        struct brw_winsys_buffer **bo_out )
+{
+   enum pipe_error ret;
+   struct brw_sf_compile c;
+   const GLuint *program;
+   GLuint program_size;
+
+   memset(&c, 0, sizeof(c));
+
+   /* Begin the compilation:
+    */
+   brw_init_compile(brw, &c.func);
+
+   c.key = *key;
+   c.nr_attrs = c.key.nr_attrs;
+   c.nr_attr_regs = (c.nr_attrs+1)/2;
+   c.nr_setup_attrs = c.key.nr_attrs;
+   c.nr_setup_regs = (c.nr_setup_attrs+1)/2;
+
+   c.prog_data.urb_read_length = c.nr_attr_regs;
+   c.prog_data.urb_entry_size = c.nr_setup_regs * 2;
+
+   /* Special case when there are no attributes to setup.
+    *
+    * XXX: should be able to set nr_setup_attrs to nr_attrs-1 -- but
+    * breaks vp-tris.c
+    */
+   if (c.nr_attrs - 1 == 0) {
+      c.nr_verts = 0;
+      brw_emit_null_setup( &c );
+   }
+   else {
+      /* Which primitive?  Or all three? 
+       */
+      switch (key->primitive) {
+      case SF_TRIANGLES:
+         c.nr_verts = 3;
+         brw_emit_tri_setup( &c, GL_TRUE );
+         break;
+      case SF_LINES:
+         c.nr_verts = 2;
+         brw_emit_line_setup( &c, GL_TRUE );
+         break;
+      case SF_POINTS:
+         c.nr_verts = 1;
+         if (key->do_point_sprite)
+            brw_emit_point_sprite_setup( &c, GL_TRUE );
+         else
+            brw_emit_point_setup( &c, GL_TRUE );
+         break;
+      case SF_UNFILLED_TRIS:
+         c.nr_verts = 3;
+         brw_emit_anyprim_setup( &c );
+         break;
+      default:
+         assert(0);
+         return PIPE_ERROR_BAD_INPUT;
+      }
+   }
+
+   /* get the program
+    */
+   ret = brw_get_program(&c.func, &program, &program_size);
+   if (ret)
+      return ret;
+
+   /* Upload
+    */
+   ret = brw_upload_cache( &brw->cache, BRW_SF_PROG,
+                           &c.key, sizeof(c.key),
+                           NULL, 0,
+                           program, program_size,
+                           &c.prog_data,
+                           &brw->sf.prog_data,
+                           bo_out);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+/* Calculate interpolants for triangle and line rasterization.
+ */
+static enum pipe_error upload_sf_prog(struct brw_context *brw)
+{
+   const struct brw_fs_signature *sig = &brw->curr.fragment_shader->signature;
+   struct brw_sf_prog_key key;
+   enum pipe_error ret;
+   unsigned i;
+
+   memset(&key, 0, sizeof(key));
+
+   /* Populate the key, noting state dependencies:
+    */
+
+   /* XXX: Add one to account for the position input.
+    */
+   /* PIPE_NEW_FRAGMENT_SIGNATURE */
+   key.nr_attrs = sig->nr_inputs + 1;
+
+
+   /* XXX: why is position required to be linear?  why do we care
+    * about it at all?
+    */
+   key.linear_attrs = 1;        /* position -- but why? */
+
+   for (i = 0; i < sig->nr_inputs; i++) {
+      switch (sig->input[i].interp) {
+      case TGSI_INTERPOLATE_CONSTANT:
+         break;
+      case TGSI_INTERPOLATE_LINEAR:
+         key.linear_attrs |= 1 << (i+1);
+         break;
+      case TGSI_INTERPOLATE_PERSPECTIVE:
+         key.persp_attrs |= 1 << (i+1);
+         break;
+      }
+   }
+
+   /* BRW_NEW_REDUCED_PRIMITIVE */
+   switch (brw->reduced_primitive) {
+   case PIPE_PRIM_TRIANGLES: 
+      /* PIPE_NEW_RAST
+       */
+      if (brw->curr.rast->templ.fill_cw != PIPE_POLYGON_MODE_FILL ||
+	  brw->curr.rast->templ.fill_ccw != PIPE_POLYGON_MODE_FILL)
+	 key.primitive = SF_UNFILLED_TRIS;
+      else
+	 key.primitive = SF_TRIANGLES;
+      break;
+   case PIPE_PRIM_LINES: 
+      key.primitive = SF_LINES; 
+      break;
+   case PIPE_PRIM_POINTS: 
+      key.primitive = SF_POINTS; 
+      break;
+   }
+
+   key.do_point_sprite = brw->curr.rast->templ.point_sprite;
+   key.sprite_origin_lower_left = 0; /* XXX: ctx->Point.SpriteOrigin - fix rast state */
+   key.do_flat_shading = brw->curr.rast->templ.flatshade;
+   key.do_twoside_color = brw->curr.rast->templ.light_twoside;
+
+   if (key.do_twoside_color) {
+      key.frontface_ccw = (brw->curr.rast->templ.front_winding == 
+			   PIPE_WINDING_CCW);
+   }
+
+   if (brw_search_cache(&brw->cache, BRW_SF_PROG,
+                        &key, sizeof(key),
+                        NULL, 0,
+                        &brw->sf.prog_data,
+                        &brw->sf.prog_bo))
+      return PIPE_OK;
+
+   ret = compile_sf_prog( brw, &key, &brw->sf.prog_bo );
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+
+const struct brw_tracked_state brw_sf_prog = {
+   .dirty = {
+      .mesa  = (PIPE_NEW_RAST | PIPE_NEW_FRAGMENT_SIGNATURE),
+      .brw   = (BRW_NEW_REDUCED_PRIMITIVE),
+      .cache = 0
+   },
+   .prepare = upload_sf_prog
+};
+
diff --git a/src/gallium/drivers/i965/brw_sf.h b/src/gallium/drivers/i965/brw_sf.h
new file mode 100644
index 0000000..a895c7d
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_sf.h
@@ -0,0 +1,122 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+   
+
+#ifndef BRW_SF_H
+#define BRW_SF_H
+
+
+#include "brw_context.h"
+#include "brw_eu.h"
+
+
+#define SF_POINTS    0
+#define SF_LINES     1
+#define SF_TRIANGLES 2
+#define SF_UNFILLED_TRIS   3
+
+struct brw_sf_prog_key {
+
+   /* Bitmask of linear and perspective interpolated inputs, 0..nr
+    */
+   GLuint persp_attrs:32;
+   GLuint linear_attrs:32;
+   GLuint point_coord_replace_attrs:32;
+
+   GLuint nr_attrs:8;
+   GLuint primitive:2;
+   GLuint do_twoside_color:1;
+   GLuint do_flat_shading:1;
+   GLuint frontface_ccw:1;
+   GLuint do_point_sprite:1;
+   GLuint sprite_origin_lower_left:1;
+   GLuint pad:17;
+
+   GLuint attr_col0:8;
+   GLuint attr_col1:8;
+   GLuint attr_bfc0:8;
+   GLuint attr_bfc1:8;
+};
+
+struct brw_sf_point_tex {
+   GLboolean CoordReplace;	
+};
+
+struct brw_sf_compile {
+   struct brw_compile func;
+   struct brw_sf_prog_key key;
+   struct brw_sf_prog_data prog_data;
+   
+   struct brw_reg pv;
+   struct brw_reg det;
+   struct brw_reg dx0;
+   struct brw_reg dx2;
+   struct brw_reg dy0;
+   struct brw_reg dy2;
+
+   /* z and 1/w passed in seperately:
+    */
+   struct brw_reg z[3];
+   struct brw_reg inv_w[3];
+   
+   /* The vertices:
+    */
+   struct brw_reg vert[3];
+
+    /* Temporaries, allocated after last vertex reg.
+    */
+   struct brw_reg inv_det;
+   struct brw_reg a1_sub_a0;
+   struct brw_reg a2_sub_a0;
+   struct brw_reg tmp;
+
+   struct brw_reg m1Cx;
+   struct brw_reg m2Cy;
+   struct brw_reg m3C0;
+
+   GLuint nr_verts;
+   GLuint nr_attrs;
+   GLuint nr_attr_regs;
+   GLuint nr_setup_attrs;
+   GLuint nr_setup_regs;
+
+   GLuint point_coord_replace_mask;
+};
+
+ 
+void brw_emit_null_setup( struct brw_sf_compile *c );
+void brw_emit_tri_setup( struct brw_sf_compile *c, GLboolean allocate );
+void brw_emit_line_setup( struct brw_sf_compile *c, GLboolean allocate );
+void brw_emit_point_setup( struct brw_sf_compile *c, GLboolean allocate );
+void brw_emit_point_sprite_setup( struct brw_sf_compile *c, GLboolean allocate );
+void brw_emit_anyprim_setup( struct brw_sf_compile *c );
+
+#endif
diff --git a/src/gallium/drivers/i965/brw_sf_emit.c b/src/gallium/drivers/i965/brw_sf_emit.c
new file mode 100644
index 0000000..3b85725
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_sf_emit.c
@@ -0,0 +1,765 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+   
+
+#include "brw_batchbuffer.h"
+
+#include "brw_defines.h"
+#include "brw_context.h"
+#include "brw_eu.h"
+#include "brw_util.h"
+#include "brw_sf.h"
+
+
+static struct brw_reg get_vert_attr(struct brw_sf_compile *c,
+				    struct brw_reg vert,
+				    GLuint attr)
+{
+   GLuint off = attr / 2;
+   GLuint sub = attr % 2;
+
+   return brw_vec4_grf(vert.nr + off, sub * 4);
+}
+
+
+/*********************************************************************** 
+ * Twoside lighting
+ */
+static void copy_bfc( struct brw_sf_compile *c,
+		      struct brw_reg vert )
+{
+   struct brw_compile *p = &c->func;
+
+   if (c->key.attr_col0 && c->key.attr_bfc0)
+      brw_MOV(p, 
+	      get_vert_attr(c, vert, c->key.attr_col0), 
+	      get_vert_attr(c, vert, c->key.attr_bfc0));
+
+   if (c->key.attr_col1 && c->key.attr_bfc1)
+      brw_MOV(p, 
+	      get_vert_attr(c, vert, c->key.attr_col1), 
+	      get_vert_attr(c, vert, c->key.attr_bfc1));
+}
+
+
+static void do_twoside_color( struct brw_sf_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_instruction *if_insn;
+   GLuint backface_conditional = c->key.frontface_ccw ? BRW_CONDITIONAL_G : BRW_CONDITIONAL_L;
+
+   /* Already done in clip program:
+    */
+   if (c->key.primitive == SF_UNFILLED_TRIS)
+      return;
+
+   /* XXX: What happens if BFC isn't present?  This could only happen
+    * for user-supplied vertex programs, as t_vp_build.c always does
+    * the right thing.
+    */
+   if (!(c->key.attr_col0 && c->key.attr_bfc0) &&
+       !(c->key.attr_col1 && c->key.attr_bfc1))
+      return;
+   
+   /* Need to use BRW_EXECUTE_4 and also do an 4-wide compare in order
+    * to get all channels active inside the IF.  In the clipping code
+    * we run with NoMask, so it's not an option and we can use
+    * BRW_EXECUTE_1 for all comparisions.
+    */
+   brw_push_insn_state(p);
+   brw_CMP(p, vec4(brw_null_reg()), backface_conditional, c->det, brw_imm_f(0));
+   if_insn = brw_IF(p, BRW_EXECUTE_4); 
+   {
+      switch (c->nr_verts) {
+      case 3: copy_bfc(c, c->vert[2]);
+      case 2: copy_bfc(c, c->vert[1]);
+      case 1: copy_bfc(c, c->vert[0]);
+      }
+   }
+   brw_ENDIF(p, if_insn);
+   brw_pop_insn_state(p);
+}
+
+
+
+/***********************************************************************
+ * Flat shading
+ */
+
+#define VERT_RESULT_COLOR_BITS ((1<<VERT_RESULT_COL0) | \
+                                 (1<<VERT_RESULT_COL1))
+
+static void copy_colors( struct brw_sf_compile *c,
+		     struct brw_reg dst,
+		     struct brw_reg src)
+{
+   struct brw_compile *p = &c->func;
+
+   if (c->key.attr_col0)
+      brw_MOV(p, 
+	      get_vert_attr(c, dst, c->key.attr_col0), 
+	      get_vert_attr(c, src, c->key.attr_col0));
+
+   if (c->key.attr_col1)
+      brw_MOV(p, 
+	      get_vert_attr(c, dst, c->key.attr_col1), 
+	      get_vert_attr(c, src, c->key.attr_col1));
+
+}
+
+
+
+/* Need to use a computed jump to copy flatshaded attributes as the
+ * vertices are ordered according to y-coordinate before reaching this
+ * point, so the PV could be anywhere.
+ */
+static void do_flatshade_triangle( struct brw_sf_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg ip = brw_ip_reg();
+   GLuint jmpi = 1;
+   GLuint nr = 0;
+
+   if (c->key.attr_col0)
+      nr++;
+
+   if (c->key.attr_col1)
+      nr++;
+
+   if (nr == 0)
+      return;
+
+   /* Already done in clip program:
+    */
+   if (c->key.primitive == SF_UNFILLED_TRIS)
+      return;
+
+   if (BRW_IS_IGDNG(p->brw))
+       jmpi = 2;
+
+   brw_push_insn_state(p);
+   
+   brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr*2+1)));
+   brw_JMPI(p, ip, ip, c->pv);
+
+   copy_colors(c, c->vert[1], c->vert[0]);
+   copy_colors(c, c->vert[2], c->vert[0]);
+   brw_JMPI(p, ip, ip, brw_imm_d(jmpi*(nr*4+1)));
+
+   copy_colors(c, c->vert[0], c->vert[1]);
+   copy_colors(c, c->vert[2], c->vert[1]);
+   brw_JMPI(p, ip, ip, brw_imm_d(jmpi*nr*2));
+
+   copy_colors(c, c->vert[0], c->vert[2]);
+   copy_colors(c, c->vert[1], c->vert[2]);
+
+   brw_pop_insn_state(p);
+}
+	
+
+static void do_flatshade_line( struct brw_sf_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg ip = brw_ip_reg();
+   GLuint jmpi = 1;
+   GLuint nr = 0;
+
+   if (c->key.attr_col0)
+      nr++;
+
+   if (c->key.attr_col1)
+      nr++;
+
+   if (nr == 0)
+      return;
+
+   /* Already done in clip program: 
+    */
+   if (c->key.primitive == SF_UNFILLED_TRIS)
+      return;
+
+   if (BRW_IS_IGDNG(p->brw))
+       jmpi = 2;
+
+   brw_push_insn_state(p);
+   
+   brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr+1)));
+   brw_JMPI(p, ip, ip, c->pv);
+   copy_colors(c, c->vert[1], c->vert[0]);
+
+   brw_JMPI(p, ip, ip, brw_imm_ud(jmpi*nr));
+   copy_colors(c, c->vert[0], c->vert[1]);
+
+   brw_pop_insn_state(p);
+}
+
+	
+
+/***********************************************************************
+ * Triangle setup.
+ */
+
+
+static void alloc_regs( struct brw_sf_compile *c )
+{
+   GLuint reg, i;
+
+   /* Values computed by fixed function unit:
+    */
+   c->pv  = retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_D);
+   c->det = brw_vec1_grf(1, 2);
+   c->dx0 = brw_vec1_grf(1, 3);
+   c->dx2 = brw_vec1_grf(1, 4);
+   c->dy0 = brw_vec1_grf(1, 5);
+   c->dy2 = brw_vec1_grf(1, 6);
+
+   /* z and 1/w passed in seperately:
+    */
+   c->z[0]     = brw_vec1_grf(2, 0);
+   c->inv_w[0] = brw_vec1_grf(2, 1);
+   c->z[1]     = brw_vec1_grf(2, 2);
+   c->inv_w[1] = brw_vec1_grf(2, 3);
+   c->z[2]     = brw_vec1_grf(2, 4);
+   c->inv_w[2] = brw_vec1_grf(2, 5);
+   
+   /* The vertices:
+    */
+   reg = 3;
+   for (i = 0; i < c->nr_verts; i++) {
+      c->vert[i] = brw_vec8_grf(reg, 0);
+      reg += c->nr_attr_regs;
+   }
+
+   /* Temporaries, allocated after last vertex reg.
+    */
+   c->inv_det = brw_vec1_grf(reg, 0);  reg++;
+   c->a1_sub_a0 = brw_vec8_grf(reg, 0);  reg++;
+   c->a2_sub_a0 = brw_vec8_grf(reg, 0);  reg++;
+   c->tmp = brw_vec8_grf(reg, 0);  reg++;
+
+   /* Note grf allocation:
+    */
+   c->prog_data.total_grf = reg;
+   
+
+   /* Outputs of this program - interpolation coefficients for
+    * rasterization:
+    */
+   c->m1Cx = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 1, 0);
+   c->m2Cy = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 2, 0);
+   c->m3C0 = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 3, 0);
+}
+
+
+static void copy_z_inv_w( struct brw_sf_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   GLuint i;
+
+   brw_push_insn_state(p);
+	
+   /* Copy both scalars with a single MOV:
+    */
+   for (i = 0; i < c->nr_verts; i++)
+      brw_MOV(p, vec2(suboffset(c->vert[i], 2)), vec2(c->z[i]));
+	 
+   brw_pop_insn_state(p);
+}
+
+
+static void invert_det( struct brw_sf_compile *c)
+{
+   /* Looks like we invert all 8 elements just to get 1/det in
+    * position 2 !?!
+    */
+   brw_math(&c->func, 
+	    c->inv_det, 
+	    BRW_MATH_FUNCTION_INV,
+	    BRW_MATH_SATURATE_NONE,
+	    0, 
+	    c->det,
+	    BRW_MATH_DATA_SCALAR,
+	    BRW_MATH_PRECISION_FULL);
+
+}
+
+
+/* Two attributes packed into a wide register.  Figure out if either
+ * or both of them need linear/perspective interpolation.  Constant
+ * regs are left as-is.
+ */
+static GLboolean calculate_masks( struct brw_sf_compile *c,
+				  GLuint reg,
+				  GLushort *pc,
+				  GLushort *pc_persp,
+				  GLushort *pc_linear)
+{
+   GLboolean is_last_attr = (reg == c->nr_setup_regs - 1);
+   GLuint persp_mask = c->key.persp_attrs;
+   GLuint linear_mask = (c->key.persp_attrs | c->key.linear_attrs);
+
+   *pc_persp = 0;
+   *pc_linear = 0;
+   *pc = 0xf;
+      
+   if (persp_mask & (1 << (reg*2))) 
+      *pc_persp = 0xf;
+
+   if (linear_mask & (1 << (reg*2))) 
+      *pc_linear = 0xf;
+
+   /* Maybe only processs one attribute on the final round:
+    */
+   if (reg*2+1 < c->nr_setup_attrs) {
+      *pc |= 0xf0;
+
+      if (persp_mask & (1 << (reg*2+1))) 
+	 *pc_persp |= 0xf0;
+
+      if (linear_mask & (1 << (reg*2+1))) 
+	 *pc_linear |= 0xf0;
+   }
+
+   return is_last_attr;
+}
+
+
+void brw_emit_null_setup( struct brw_sf_compile *c )
+{
+   struct brw_compile *p = &c->func;
+
+   /* m0 is implicitly copied from r0 in the send instruction:
+    */	 
+   brw_urb_WRITE(p, 
+                 brw_null_reg(),
+                 0,
+                 brw_vec8_grf(0, 0), /* r0, will be copied to m0 */
+                 0, 	/* allocate */
+                 1,	/* used */
+                 1, 	/* msg len */
+                 0,	/* response len */
+                 1,	/* eot */
+                 1, 	/* writes complete */
+                 0,	/* offset */
+                 BRW_URB_SWIZZLE_TRANSPOSE); 
+}
+
+void brw_emit_tri_setup( struct brw_sf_compile *c, GLboolean allocate)
+{
+   struct brw_compile *p = &c->func;
+   GLuint i;
+
+   c->nr_verts = 3;
+
+   if (allocate)
+      alloc_regs(c);
+
+   invert_det(c);
+   copy_z_inv_w(c);
+
+   if (c->key.do_twoside_color) 
+      do_twoside_color(c);
+
+   if (c->key.do_flat_shading)
+      do_flatshade_triangle(c);
+      
+   
+   for (i = 0; i < c->nr_setup_regs; i++)
+   {
+      /* Pair of incoming attributes:
+       */
+      struct brw_reg a0 = offset(c->vert[0], i);
+      struct brw_reg a1 = offset(c->vert[1], i);
+      struct brw_reg a2 = offset(c->vert[2], i);
+      GLushort pc, pc_persp, pc_linear;
+      GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
+
+      if (pc_persp)
+      {
+	 brw_set_predicate_control_flag_value(p, pc_persp);
+	 brw_MUL(p, a0, a0, c->inv_w[0]);
+	 brw_MUL(p, a1, a1, c->inv_w[1]);
+	 brw_MUL(p, a2, a2, c->inv_w[2]);
+      }
+      
+      
+      /* Calculate coefficients for interpolated values:
+       */      
+      if (pc_linear)
+      {
+	 brw_set_predicate_control_flag_value(p, pc_linear);
+
+	 brw_ADD(p, c->a1_sub_a0, a1, negate(a0));
+	 brw_ADD(p, c->a2_sub_a0, a2, negate(a0));
+
+	 /* calculate dA/dx
+	  */
+	 brw_MUL(p, brw_null_reg(), c->a1_sub_a0, c->dy2);
+	 brw_MAC(p, c->tmp, c->a2_sub_a0, negate(c->dy0));
+	 brw_MUL(p, c->m1Cx, c->tmp, c->inv_det);
+		
+	 /* calculate dA/dy
+	  */
+	 brw_MUL(p, brw_null_reg(), c->a2_sub_a0, c->dx0);
+	 brw_MAC(p, c->tmp, c->a1_sub_a0, negate(c->dx2));
+	 brw_MUL(p, c->m2Cy, c->tmp, c->inv_det);
+      }
+
+      {
+	 brw_set_predicate_control_flag_value(p, pc); 
+	 /* start point for interpolation
+	  */
+	 brw_MOV(p, c->m3C0, a0);
+      
+	 /* Copy m0..m3 to URB.  m0 is implicitly copied from r0 in
+	  * the send instruction:
+	  */	 
+	 brw_urb_WRITE(p, 
+		       brw_null_reg(),
+		       0,
+		       brw_vec8_grf(0, 0), /* r0, will be copied to m0 */
+		       0, 	/* allocate */
+		       1,	/* used */
+		       4, 	/* msg len */
+		       0,	/* response len */
+		       last,	/* eot */
+		       last, 	/* writes complete */
+		       i*4,	/* offset */
+		       BRW_URB_SWIZZLE_TRANSPOSE); /* XXX: Swizzle control "SF to windower" */
+      }
+   }
+}
+
+
+
+void brw_emit_line_setup( struct brw_sf_compile *c, GLboolean allocate)
+{
+   struct brw_compile *p = &c->func;
+   GLuint i;
+
+
+   c->nr_verts = 2;
+
+   if (allocate)
+      alloc_regs(c);
+
+   invert_det(c);
+   copy_z_inv_w(c);
+
+   if (c->key.do_flat_shading)
+      do_flatshade_line(c);
+
+   for (i = 0; i < c->nr_setup_regs; i++)
+   {
+      /* Pair of incoming attributes:
+       */
+      struct brw_reg a0 = offset(c->vert[0], i);
+      struct brw_reg a1 = offset(c->vert[1], i);
+      GLushort pc, pc_persp, pc_linear;
+      GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
+
+      if (pc_persp)
+      {
+	 brw_set_predicate_control_flag_value(p, pc_persp);
+	 brw_MUL(p, a0, a0, c->inv_w[0]);
+	 brw_MUL(p, a1, a1, c->inv_w[1]);
+      }
+
+      /* Calculate coefficients for position, color:
+       */
+      if (pc_linear) {
+	 brw_set_predicate_control_flag_value(p, pc_linear); 
+
+	 brw_ADD(p, c->a1_sub_a0, a1, negate(a0));
+
+ 	 brw_MUL(p, c->tmp, c->a1_sub_a0, c->dx0); 
+	 brw_MUL(p, c->m1Cx, c->tmp, c->inv_det);
+		
+	 brw_MUL(p, c->tmp, c->a1_sub_a0, c->dy0);
+	 brw_MUL(p, c->m2Cy, c->tmp, c->inv_det);
+      }
+
+      {
+	 brw_set_predicate_control_flag_value(p, pc); 
+
+	 /* start point for interpolation
+	  */
+	 brw_MOV(p, c->m3C0, a0);
+
+	 /* Copy m0..m3 to URB. 
+	  */
+	 brw_urb_WRITE(p, 
+		       brw_null_reg(),
+		       0,
+		       brw_vec8_grf(0, 0),
+		       0, 	/* allocate */
+		       1, 	/* used */
+		       4, 	/* msg len */
+		       0,	/* response len */
+		       last, 	/* eot */
+		       last, 	/* writes complete */
+		       i*4,	/* urb destination offset */
+		       BRW_URB_SWIZZLE_TRANSPOSE); 
+      }
+   } 
+}
+
+void brw_emit_point_sprite_setup( struct brw_sf_compile *c, GLboolean allocate)
+{
+   struct brw_compile *p = &c->func;
+   GLuint i;
+
+   c->nr_verts = 1;
+
+   if (allocate)
+      alloc_regs(c);
+
+   copy_z_inv_w(c);
+
+   for (i = 0; i < c->nr_setup_regs; i++)
+   {
+      /* XXX: only seems to check point_coord_replace_attrs for every
+       * second attribute?!?
+       */
+      boolean coord_replace = !!(c->key.point_coord_replace_attrs & (1<<(2*i)));
+      struct brw_reg a0 = offset(c->vert[0], i);
+      GLushort pc, pc_persp, pc_linear;
+      GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
+            
+      if (pc_persp)
+      {				
+	 if (coord_replace) {
+	    brw_set_predicate_control_flag_value(p, pc_persp);
+	    brw_MUL(p, a0, a0, c->inv_w[0]);
+	 }
+      }
+
+      if (coord_replace) {
+	 /* Caculate 1.0/PointWidth */
+	 brw_math(&c->func,
+		  c->tmp,
+		  BRW_MATH_FUNCTION_INV,
+		  BRW_MATH_SATURATE_NONE,
+		  0,
+		  c->dx0,
+		  BRW_MATH_DATA_SCALAR,
+		  BRW_MATH_PRECISION_FULL);
+
+	 if (c->key.sprite_origin_lower_left) {
+	    brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]);
+	    brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0));
+	    brw_MUL(p, c->m2Cy, c->tmp, negate(c->inv_w[0]));
+	    brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0));
+	 } 
+	 else {
+	    brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]);
+	    brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0));
+	    brw_MUL(p, c->m2Cy, c->tmp, c->inv_w[0]);
+	    brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0));
+	 }
+      } 
+      else {
+	 brw_MOV(p, c->m1Cx, brw_imm_ud(0));
+	 brw_MOV(p, c->m2Cy, brw_imm_ud(0));
+      }
+
+      {
+	 brw_set_predicate_control_flag_value(p, pc); 
+	 if (coord_replace) {
+	    if (c->key.sprite_origin_lower_left) {
+	       brw_MUL(p, c->m3C0, c->inv_w[0], brw_imm_f(1.0));
+	       brw_MOV(p, vec1(suboffset(c->m3C0, 0)), brw_imm_f(0.0));
+	    }
+	    else {
+	       brw_MOV(p, c->m3C0, brw_imm_f(0.0));
+	    }
+	 } 
+	 else {
+	    brw_MOV(p, c->m3C0, a0); /* constant value */
+	 }
+
+	 /* Copy m0..m3 to URB. 
+	  */
+	 brw_urb_WRITE(p, 
+		       brw_null_reg(),
+		       0,
+		       brw_vec8_grf(0, 0),
+		       0, 	/* allocate */
+		       1,	/* used */
+		       4, 	/* msg len */
+		       0,	/* response len */
+		       last, 	/* eot */
+		       last, 	/* writes complete */
+		       i*4,	/* urb destination offset */
+		       BRW_URB_SWIZZLE_TRANSPOSE);
+      }
+   }
+}
+
+/* Points setup - several simplifications as all attributes are
+ * constant across the face of the point (point sprites excluded!)
+ */
+void brw_emit_point_setup( struct brw_sf_compile *c, GLboolean allocate)
+{
+   struct brw_compile *p = &c->func;
+   GLuint i;
+
+   c->nr_verts = 1;
+   
+   if (allocate)
+      alloc_regs(c);
+
+   copy_z_inv_w(c);
+
+   brw_MOV(p, c->m1Cx, brw_imm_ud(0)); /* zero - move out of loop */
+   brw_MOV(p, c->m2Cy, brw_imm_ud(0)); /* zero - move out of loop */
+
+   for (i = 0; i < c->nr_setup_regs; i++)
+   {
+      struct brw_reg a0 = offset(c->vert[0], i);
+      GLushort pc, pc_persp, pc_linear;
+      GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
+            
+      if (pc_persp)
+      {				
+	 /* This seems odd as the values are all constant, but the
+	  * fragment shader will be expecting it:
+	  */
+	 brw_set_predicate_control_flag_value(p, pc_persp);
+	 brw_MUL(p, a0, a0, c->inv_w[0]);
+      }
+
+
+      /* The delta values are always zero, just send the starting
+       * coordinate.  Again, this is to fit in with the interpolation
+       * code in the fragment shader.
+       */
+      {
+	 brw_set_predicate_control_flag_value(p, pc); 
+
+	 brw_MOV(p, c->m3C0, a0); /* constant value */
+
+	 /* Copy m0..m3 to URB. 
+	  */
+	 brw_urb_WRITE(p, 
+		       brw_null_reg(),
+		       0,
+		       brw_vec8_grf(0, 0),
+		       0, 	/* allocate */
+		       1,	/* used */
+		       4, 	/* msg len */
+		       0,	/* response len */
+		       last, 	/* eot */
+		       last, 	/* writes complete */
+		       i*4,	/* urb destination offset */
+		       BRW_URB_SWIZZLE_TRANSPOSE);
+      }
+   }
+}
+
+void brw_emit_anyprim_setup( struct brw_sf_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg ip = brw_ip_reg();
+   struct brw_reg payload_prim = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0);
+   struct brw_reg payload_attr = get_element_ud(brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0), 0); 
+   struct brw_reg primmask;
+   struct brw_instruction *jmp;
+   struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD));
+   
+   GLuint saveflag;
+
+   c->nr_verts = 3;
+   alloc_regs(c);
+
+   primmask = retype(get_element(c->tmp, 0), BRW_REGISTER_TYPE_UD);
+
+   brw_MOV(p, primmask, brw_imm_ud(1));
+   brw_SHL(p, primmask, primmask, payload_prim);
+
+   brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
+   brw_AND(p, v1_null_ud, primmask, brw_imm_ud((1<<_3DPRIM_TRILIST) |
+					       (1<<_3DPRIM_TRISTRIP) |
+					       (1<<_3DPRIM_TRIFAN) |
+					       (1<<_3DPRIM_TRISTRIP_REVERSE) |
+					       (1<<_3DPRIM_POLYGON) |
+					       (1<<_3DPRIM_RECTLIST) |
+					       (1<<_3DPRIM_TRIFAN_NOSTIPPLE)));
+   jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
+   {
+      saveflag = p->flag_value;
+      brw_push_insn_state(p); 
+      brw_emit_tri_setup( c, GL_FALSE );
+      brw_pop_insn_state(p);
+      p->flag_value = saveflag;
+      /* note - thread killed in subroutine, so must
+       * restore the flag which is changed when building
+       * the subroutine. fix #13240
+       */
+   }
+   brw_land_fwd_jump(p, jmp);
+
+   brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
+   brw_AND(p, v1_null_ud, primmask, brw_imm_ud((1<<_3DPRIM_LINELIST) |
+					       (1<<_3DPRIM_LINESTRIP) |
+					       (1<<_3DPRIM_LINELOOP) |
+					       (1<<_3DPRIM_LINESTRIP_CONT) |
+					       (1<<_3DPRIM_LINESTRIP_BF) |
+					       (1<<_3DPRIM_LINESTRIP_CONT_BF)));
+   jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
+   {
+      saveflag = p->flag_value;
+      brw_push_insn_state(p); 
+      brw_emit_line_setup( c, GL_FALSE );
+      brw_pop_insn_state(p);
+      p->flag_value = saveflag;
+      /* note - thread killed in subroutine */
+   }
+   brw_land_fwd_jump(p, jmp); 
+
+   brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
+   brw_AND(p, v1_null_ud, payload_attr, brw_imm_ud(1<<BRW_SPRITE_POINT_ENABLE));
+   jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
+   {
+      saveflag = p->flag_value;
+      brw_push_insn_state(p); 
+      brw_emit_point_sprite_setup( c, GL_FALSE );
+      brw_pop_insn_state(p);
+      p->flag_value = saveflag;
+   }
+   brw_land_fwd_jump(p, jmp); 
+
+   brw_emit_point_setup( c, GL_FALSE );
+}
+
+
+
+
diff --git a/src/gallium/drivers/i965/brw_sf_state.c b/src/gallium/drivers/i965/brw_sf_state.c
new file mode 100644
index 0000000..25dc2b5
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_sf_state.c
@@ -0,0 +1,333 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+   
+#include "util/u_math.h"
+
+#include "pipe/p_state.h"
+
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+#include "brw_debug.h"
+#include "brw_pipe_rast.h"
+
+static enum pipe_error upload_sf_vp(struct brw_context *brw)
+{
+   const struct pipe_viewport_state *vp = &brw->curr.viewport;
+   const struct pipe_scissor_state *scissor = &brw->curr.scissor;
+   struct brw_sf_viewport sfv;
+   enum pipe_error ret;
+
+   memset(&sfv, 0, sizeof(sfv));
+
+   /* PIPE_NEW_VIEWPORT, PIPE_NEW_SCISSOR */
+
+   sfv.viewport.m00 = vp->scale[0];
+   sfv.viewport.m11 = vp->scale[1];
+   sfv.viewport.m22 = vp->scale[2];
+   sfv.viewport.m30 = vp->translate[0];
+   sfv.viewport.m31 = vp->translate[1];
+   sfv.viewport.m32 = vp->translate[2];
+
+   sfv.scissor.xmin = scissor->minx;
+   sfv.scissor.xmax = scissor->maxx - 1; /* ? */
+   sfv.scissor.ymin = scissor->miny;
+   sfv.scissor.ymax = scissor->maxy - 1; /* ? */
+
+   ret = brw_cache_data( &brw->cache, BRW_SF_VP, &sfv, NULL, 0,
+                         &brw->sf.vp_bo );
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+const struct brw_tracked_state brw_sf_vp = {
+   .dirty = {
+      .mesa  = (PIPE_NEW_VIEWPORT | 
+		PIPE_NEW_SCISSOR),
+      .brw   = 0,
+      .cache = 0
+   },
+   .prepare = upload_sf_vp
+};
+
+struct brw_sf_unit_key {
+   unsigned int total_grf;
+   unsigned int urb_entry_read_length;
+   unsigned int nr_urb_entries, urb_size, sfsize;
+   
+   unsigned scissor:1;
+   unsigned line_smooth:1;
+   unsigned point_sprite:1;
+   unsigned point_attenuated:1;
+   unsigned front_face:2;
+   unsigned cull_mode:2;
+   unsigned flatshade_first:1;
+   unsigned gl_rasterization_rules:1;
+   unsigned line_last_pixel_enable:1;
+   float line_width;
+   float point_size;
+};
+
+static void
+sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key)
+{
+   const struct pipe_rasterizer_state *rast = &brw->curr.rast->templ;
+   memset(key, 0, sizeof(*key));
+
+   /* CACHE_NEW_SF_PROG */
+   key->total_grf = brw->sf.prog_data->total_grf;
+   key->urb_entry_read_length = brw->sf.prog_data->urb_read_length;
+
+   /* BRW_NEW_URB_FENCE */
+   key->nr_urb_entries = brw->urb.nr_sf_entries;
+   key->urb_size = brw->urb.vsize;
+   key->sfsize = brw->urb.sfsize;
+
+   /* PIPE_NEW_RAST */
+   key->scissor = rast->scissor;
+   key->front_face = rast->front_winding;
+   key->cull_mode = rast->cull_mode;
+   key->line_smooth = rast->line_smooth;
+   key->line_width = rast->line_width;
+   key->flatshade_first = rast->flatshade_first;
+   key->line_last_pixel_enable = rast->line_last_pixel;
+   key->gl_rasterization_rules = rast->gl_rasterization_rules;
+
+   key->point_sprite = rast->point_sprite;
+   key->point_attenuated = rast->point_size_per_vertex;
+
+   key->point_size = CLAMP(rast->point_size, 
+			   rast->point_size_min, 
+			   rast->point_size_max);
+}
+
+static enum pipe_error
+sf_unit_create_from_key(struct brw_context *brw,
+                        struct brw_sf_unit_key *key,
+                        struct brw_winsys_reloc *reloc,
+                        struct brw_winsys_buffer **bo_out)
+{
+   struct brw_sf_unit_state sf;
+   enum pipe_error ret;
+   int chipset_max_threads;
+   memset(&sf, 0, sizeof(sf));
+
+   sf.thread0.grf_reg_count = align(key->total_grf, 16) / 16 - 1;
+   /* reloc */
+   sf.thread0.kernel_start_pointer = 0;
+
+   sf.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
+
+   sf.thread3.dispatch_grf_start_reg = 3;
+
+   if (BRW_IS_IGDNG(brw))
+       sf.thread3.urb_entry_read_offset = 3;
+   else
+       sf.thread3.urb_entry_read_offset = 1;
+
+   sf.thread3.urb_entry_read_length = key->urb_entry_read_length;
+
+   sf.thread4.nr_urb_entries = key->nr_urb_entries;
+   sf.thread4.urb_entry_allocation_size = key->sfsize - 1;
+
+   /* Each SF thread produces 1 PUE, and there can be up to 24(Pre-IGDNG) or 
+    * 48(IGDNG) threads 
+    */
+   if (BRW_IS_IGDNG(brw))
+      chipset_max_threads = 48;
+   else
+      chipset_max_threads = 24;
+
+   sf.thread4.max_threads = MIN2(chipset_max_threads, key->nr_urb_entries) - 1;
+
+   if (BRW_DEBUG & DEBUG_SINGLE_THREAD)
+      sf.thread4.max_threads = 0;
+
+   if (BRW_DEBUG & DEBUG_STATS)
+      sf.thread4.stats_enable = 1;
+
+   /* CACHE_NEW_SF_VP */
+   /* reloc */
+   sf.sf5.sf_viewport_state_offset = 0;
+
+   sf.sf5.viewport_transform = 1;
+
+   if (key->scissor)
+      sf.sf6.scissor = 1;
+
+   if (key->front_face == PIPE_WINDING_CCW)
+      sf.sf5.front_winding = BRW_FRONTWINDING_CCW;
+   else
+      sf.sf5.front_winding = BRW_FRONTWINDING_CW;
+
+   switch (key->cull_mode) {
+   case PIPE_WINDING_CCW:
+   case PIPE_WINDING_CW:
+      sf.sf6.cull_mode = (key->front_face == key->cull_mode ?
+			  BRW_CULLMODE_FRONT :
+			  BRW_CULLMODE_BACK);
+      break;
+   case PIPE_WINDING_BOTH:
+      sf.sf6.cull_mode = BRW_CULLMODE_BOTH;
+      break;
+   case PIPE_WINDING_NONE:
+      sf.sf6.cull_mode = BRW_CULLMODE_NONE;
+      break;
+   default:
+      assert(0);
+      sf.sf6.cull_mode = BRW_CULLMODE_NONE;
+      break;
+   }
+
+   /* _NEW_LINE */
+   /* XXX use ctx->Const.Min/MaxLineWidth here */
+   sf.sf6.line_width = CLAMP(key->line_width, 1.0, 5.0) * (1<<1);
+
+   sf.sf6.line_endcap_aa_region_width = 1;
+   if (key->line_smooth)
+      sf.sf6.aa_enable = 1;
+   else if (sf.sf6.line_width <= 0x2)
+       sf.sf6.line_width = 0;
+
+   /* XXX: gl_rasterization_rules?  something else?
+    */
+   sf.sf6.point_rast_rule = BRW_RASTRULE_UPPER_RIGHT;
+   sf.sf6.point_rast_rule = BRW_RASTRULE_LOWER_RIGHT;
+   sf.sf6.point_rast_rule = 1;
+
+   /* XXX clamp max depends on AA vs. non-AA */
+
+   /* _NEW_POINT */
+   sf.sf7.sprite_point = key->point_sprite;
+   sf.sf7.point_size = CLAMP(rint(key->point_size), 1, 255) * (1<<3);
+   sf.sf7.use_point_size_state = !key->point_attenuated;
+   sf.sf7.aa_line_distance_mode = 0;
+
+   /* might be BRW_NEW_PRIMITIVE if we have to adjust pv for polygons:
+    */
+   if (!key->flatshade_first) {
+      sf.sf7.trifan_pv = 2;
+      sf.sf7.linestrip_pv = 1;
+      sf.sf7.tristrip_pv = 2;
+   } else {
+      sf.sf7.trifan_pv = 1;
+      sf.sf7.linestrip_pv = 0;
+      sf.sf7.tristrip_pv = 0;
+   }
+
+   sf.sf7.line_last_pixel_enable = key->line_last_pixel_enable;
+
+   /* Set bias for OpenGL rasterization rules:
+    */
+   if (key->gl_rasterization_rules) {
+      sf.sf6.dest_org_vbias = 0x8;
+      sf.sf6.dest_org_hbias = 0x8;
+   }
+   else {
+      sf.sf6.dest_org_vbias = 0x0;
+      sf.sf6.dest_org_hbias = 0x0;
+   }
+
+   ret = brw_upload_cache(&brw->cache, BRW_SF_UNIT,
+                          key, sizeof(*key),
+                          reloc, 2,
+                          &sf, sizeof(sf),
+                          NULL, NULL,
+                          bo_out);
+   if (ret)
+      return ret;
+
+   
+   return PIPE_OK;
+}
+
+static enum pipe_error upload_sf_unit( struct brw_context *brw )
+{
+   struct brw_sf_unit_key key;
+   struct brw_winsys_reloc reloc[2];
+   unsigned total_grf;
+   unsigned viewport_transform;
+   unsigned front_winding;
+   enum pipe_error ret;
+
+   sf_unit_populate_key(brw, &key);
+   
+   /* XXX: cut this crap and pre calculate the key:
+    */
+   total_grf = (align(key.total_grf, 16) / 16 - 1);
+   viewport_transform = 1;
+   front_winding = (key.front_face == PIPE_WINDING_CCW ?
+                    BRW_FRONTWINDING_CCW :
+                    BRW_FRONTWINDING_CW);
+
+   /* Emit SF program relocation */
+   make_reloc(&reloc[0],
+              BRW_USAGE_STATE,
+              total_grf << 1,
+              offsetof(struct brw_sf_unit_state, thread0),
+              brw->sf.prog_bo);
+
+   /* Emit SF viewport relocation */
+   make_reloc(&reloc[1],
+              BRW_USAGE_STATE,
+              front_winding | (viewport_transform << 1),
+              offsetof(struct brw_sf_unit_state, sf5),
+              brw->sf.vp_bo);
+
+
+   if (brw_search_cache(&brw->cache, BRW_SF_UNIT,
+                        &key, sizeof(key),
+                        reloc, 2,
+                        NULL,
+                        &brw->sf.state_bo))
+      return PIPE_OK;
+
+
+   ret = sf_unit_create_from_key(brw, &key,
+                                 reloc,
+                                 &brw->sf.state_bo);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+const struct brw_tracked_state brw_sf_unit = {
+   .dirty = {
+      .mesa  = (PIPE_NEW_RAST),
+      .brw   = BRW_NEW_URB_FENCE,
+      .cache = (CACHE_NEW_SF_VP |
+		CACHE_NEW_SF_PROG)
+   },
+   .prepare = upload_sf_unit,
+};
diff --git a/src/gallium/drivers/i965/brw_state.h b/src/gallium/drivers/i965/brw_state.h
new file mode 100644
index 0000000..d2bbd01
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_state.h
@@ -0,0 +1,174 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+    
+
+#ifndef BRW_STATE_H
+#define BRW_STATE_H
+
+#include "pipe/p_defines.h"
+#include "util/u_memory.h"
+
+#include "brw_context.h"
+
+static INLINE void
+brw_add_validated_bo(struct brw_context *brw, struct brw_winsys_buffer *bo)
+{
+   assert(brw->state.validated_bo_count < Elements(brw->state.validated_bos));
+
+   if (bo != NULL) {
+      bo_reference( &brw->state.validated_bos[brw->state.validated_bo_count++],
+                    bo );
+   }
+}
+
+const struct brw_tracked_state brw_blend_constant_color;
+const struct brw_tracked_state brw_cc_unit;
+const struct brw_tracked_state brw_cc_vp;
+const struct brw_tracked_state brw_clip_prog;
+const struct brw_tracked_state brw_clip_unit;
+const struct brw_tracked_state brw_curbe_buffer;
+const struct brw_tracked_state brw_curbe_offsets;
+const struct brw_tracked_state brw_invarient_state;
+const struct brw_tracked_state brw_gs_prog;
+const struct brw_tracked_state brw_gs_unit;
+const struct brw_tracked_state brw_line_stipple;
+const struct brw_tracked_state brw_aa_line_parameters;
+const struct brw_tracked_state brw_pipelined_state_pointers;
+const struct brw_tracked_state brw_binding_table_pointers;
+const struct brw_tracked_state brw_depthbuffer;
+const struct brw_tracked_state brw_polygon_stipple;
+const struct brw_tracked_state brw_program_parameters;
+const struct brw_tracked_state brw_recalculate_urb_fence;
+const struct brw_tracked_state brw_sf_prog;
+const struct brw_tracked_state brw_sf_unit;
+const struct brw_tracked_state brw_sf_vp;
+const struct brw_tracked_state brw_state_base_address;
+const struct brw_tracked_state brw_urb_fence;
+const struct brw_tracked_state brw_vertex_state;
+const struct brw_tracked_state brw_vs_surfaces;
+const struct brw_tracked_state brw_vs_prog;
+const struct brw_tracked_state brw_vs_unit;
+const struct brw_tracked_state brw_wm_input_sizes;
+const struct brw_tracked_state brw_wm_prog;
+const struct brw_tracked_state brw_wm_samplers;
+const struct brw_tracked_state brw_wm_constant_surface;
+const struct brw_tracked_state brw_wm_surfaces;
+const struct brw_tracked_state brw_wm_unit;
+
+const struct brw_tracked_state brw_psp_urb_cbs;
+
+const struct brw_tracked_state brw_pipe_control;
+
+const struct brw_tracked_state brw_drawing_rect;
+const struct brw_tracked_state brw_indices;
+const struct brw_tracked_state brw_vertices;
+const struct brw_tracked_state brw_index_buffer;
+
+
+/***********************************************************************
+ * brw_state.c
+ */
+int brw_validate_state(struct brw_context *brw);
+int brw_upload_state(struct brw_context *brw);
+void brw_init_state(struct brw_context *brw);
+void brw_destroy_state(struct brw_context *brw);
+
+/***********************************************************************
+ * brw_state_cache.c
+ */
+enum pipe_error brw_cache_data(struct brw_cache *cache,
+                               enum brw_cache_id cache_id,
+                               const void *data,
+                               struct brw_winsys_reloc *relocs,
+                               GLuint nr_relocs,
+                               struct brw_winsys_buffer **bo_out );
+
+enum pipe_error brw_cache_data_sz(struct brw_cache *cache,
+                                  enum brw_cache_id cache_id,
+                                  const void *data,
+                                  GLuint data_size,
+                                  struct brw_winsys_reloc *relocs,
+                                  GLuint nr_relocs,
+                                  struct brw_winsys_buffer **bo_out);
+
+enum pipe_error brw_upload_cache( struct brw_cache *cache,
+                                  enum brw_cache_id cache_id,
+                                  const void *key,
+                                  GLuint key_sz,
+                                  struct brw_winsys_reloc *relocs,
+                                  GLuint nr_relocs,
+                                  const void *data,
+                                  GLuint data_sz,
+                                  const void *aux,
+                                  void *aux_return ,
+                                  struct brw_winsys_buffer **bo_out);
+
+boolean brw_search_cache( struct brw_cache *cache,
+                          enum brw_cache_id cache_id,
+                          const void *key,
+                          GLuint key_size,
+                          struct brw_winsys_reloc *relocs,
+                          GLuint nr_relocs,
+                          void *aux_return,
+                          struct brw_winsys_buffer **bo_out);
+
+void brw_state_cache_check_size( struct brw_context *brw );
+
+void brw_init_caches( struct brw_context *brw );
+void brw_destroy_caches( struct brw_context *brw );
+void brw_state_cache_bo_delete(struct brw_cache *cache, struct brw_winsys_buffer *bo);
+
+/***********************************************************************
+ * brw_state_batch.c
+ */
+#define BRW_BATCH_STRUCT(brw, s) brw_batchbuffer_data( brw->batch, (s), sizeof(*(s)), IGNORE_CLIPRECTS)
+#define BRW_CACHED_BATCH_STRUCT(brw, s) brw_cached_batch_struct( brw, (s), sizeof(*(s)) )
+
+GLboolean brw_cached_batch_struct( struct brw_context *brw,
+				   const void *data,
+				   GLuint sz );
+void brw_destroy_batch_cache( struct brw_context *brw );
+void brw_clear_batch_cache( struct brw_context *brw );
+
+/***********************************************************************
+ * brw_wm_surface_state.c 
+ */
+
+/***********************************************************************
+ * brw_state_debug.c
+ */
+void brw_update_dirty_counts( unsigned mesa,
+			      unsigned brw,
+			      unsigned cache );
+
+
+
+#endif
diff --git a/src/gallium/drivers/i965/brw_state_batch.c b/src/gallium/drivers/i965/brw_state_batch.c
new file mode 100644
index 0000000..7d212e5
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_state_batch.c
@@ -0,0 +1,98 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+     
+
+
+#include "brw_state.h"
+#include "brw_batchbuffer.h"
+
+
+
+/* A facility similar to the data caching code above, which aims to
+ * prevent identical commands being issued repeatedly.
+ */
+GLboolean brw_cached_batch_struct( struct brw_context *brw,
+				   const void *data,
+				   GLuint sz )
+{
+   struct brw_cached_batch_item *item = brw->cached_batch_items;
+   struct header *newheader = (struct header *)data;
+
+   if (brw->flags.always_emit_state) {
+      brw_batchbuffer_data(brw->batch, data, sz, IGNORE_CLIPRECTS);
+      return GL_TRUE;
+   }
+
+   while (item) {
+      if (item->header->opcode == newheader->opcode) {
+	 if (item->sz == sz && memcmp(item->header, newheader, sz) == 0)
+	    return GL_FALSE;
+	 if (item->sz != sz) {
+	    FREE(item->header);
+	    item->header = MALLOC(sz);
+	    item->sz = sz;
+	 }
+	 goto emit;
+      }
+      item = item->next;
+   }
+
+   assert(!item);
+   item = CALLOC_STRUCT(brw_cached_batch_item);
+   item->header = MALLOC(sz);
+   item->sz = sz;
+   item->next = brw->cached_batch_items;
+   brw->cached_batch_items = item;
+
+ emit:
+   memcpy(item->header, newheader, sz);
+   brw_batchbuffer_data(brw->batch, data, sz, IGNORE_CLIPRECTS);
+   return GL_TRUE;
+}
+
+void brw_clear_batch_cache( struct brw_context *brw )
+{
+   struct brw_cached_batch_item *item = brw->cached_batch_items;
+
+   while (item) {
+      struct brw_cached_batch_item *next = item->next;
+      free((void *)item->header);
+      free(item);
+      item = next;
+   }
+
+   brw->cached_batch_items = NULL;
+}
+
+void brw_destroy_batch_cache( struct brw_context *brw )
+{
+   brw_clear_batch_cache(brw);
+}
diff --git a/src/gallium/drivers/i965/brw_state_cache.c b/src/gallium/drivers/i965/brw_state_cache.c
new file mode 100644
index 0000000..16b643c
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_state_cache.c
@@ -0,0 +1,617 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+/** @file brw_state_cache.c
+ *
+ * This file implements a simple static state cache for 965.  The consumers
+ * can query the hash table of state using a cache_id, opaque key data,
+ * and list of buffers that will be used in relocations, and receive the
+ * corresponding state buffer object of state (plus associated auxiliary
+ * data) in return.
+ *
+ * The inner workings are a simple hash table based on a CRC of the key data.
+ * The cache_id and relocation target buffers associated with the state
+ * buffer are included as auxiliary key data, but are not part of the hash
+ * value (this should be fixed, but will likely be fixed instead by making
+ * consumers use structured keys).
+ *
+ * Replacement is not implemented.  Instead, when the cache gets too big, at
+ * a safe point (unlock) we throw out all of the cache data and let it
+ * regenerate for the next rendering operation.
+ *
+ * The reloc structs need to be included as key data, otherwise the
+ * non-unique values stuffed in the offset in key data through
+ * brw_cache_data() may result in successful probe for state buffers
+ * even when the buffer being referenced doesn't match.  The result would be
+ * that the same state cache entry is used twice for different buffers,
+ * only one of the two buffers referenced gets put into the offset, and the
+ * incorrect program is run for the other instance.
+ */
+#include "util/u_memory.h"
+
+#include "brw_debug.h"
+#include "brw_state.h"
+#include "brw_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
+hash_key(const void *key, GLuint key_size,
+         struct brw_winsys_reloc *relocs, GLuint nr_relocs)
+{
+   GLuint *ikey = (GLuint *)key;
+   GLuint hash = 0, i;
+
+   assert(key_size % 4 == 0);
+
+   /* I'm sure this can be improved on:
+    */
+   for (i = 0; i < key_size/4; i++) {
+      hash ^= ikey[i];
+      hash = (hash << 5) | (hash >> 27);
+   }
+
+   /* Include the BO pointers as key data as well */
+   ikey = (GLuint *)relocs;
+   key_size = nr_relocs * sizeof(struct brw_winsys_reloc);
+   for (i = 0; i < key_size/4; i++) {
+      hash ^= ikey[i];
+      hash = (hash << 5) | (hash >> 27);
+   }
+
+   return hash;
+}
+
+
+/**
+ * Marks a new buffer as being chosen for the given cache id.
+ */
+static void
+update_cache_last(struct brw_cache *cache, enum brw_cache_id cache_id,
+		  struct brw_winsys_buffer *bo)
+{
+   if (bo == cache->last_bo[cache_id])
+      return; /* no change */
+
+   bo_reference( &cache->last_bo[cache_id],  bo );
+
+   cache->brw->state.dirty.cache |= 1 << cache_id;
+}
+
+
+static struct brw_cache_item *
+search_cache(struct brw_cache *cache, enum brw_cache_id cache_id,
+	     GLuint hash, const void *key, GLuint key_size,
+	     struct brw_winsys_reloc *relocs, GLuint nr_relocs)
+{
+   struct brw_cache_item *c;
+
+#if 0
+   int bucketcount = 0;
+
+   for (c = cache->items[hash % cache->size]; c; c = c->next)
+      bucketcount++;
+
+   debug_printf("bucket %d/%d = %d/%d items\n", hash % cache->size,
+	   cache->size, bucketcount, cache->n_items);
+#endif
+
+   for (c = cache->items[hash % cache->size]; c; c = c->next) {
+      if (c->cache_id == cache_id &&
+	  c->hash == hash &&
+	  c->key_size == key_size &&
+	  memcmp(c->key, key, key_size) == 0 &&
+	  c->nr_relocs == nr_relocs &&
+	  memcmp(c->relocs, relocs, nr_relocs * sizeof *relocs) == 0)
+	 return c;
+   }
+
+   return NULL;
+}
+
+
+static void
+rehash(struct brw_cache *cache)
+{
+   struct brw_cache_item **items;
+   struct brw_cache_item *c, *next;
+   GLuint size, i;
+
+   size = cache->size * 3;
+   items = (struct brw_cache_item**) CALLOC(size, sizeof(*items));
+
+   for (i = 0; i < cache->size; i++)
+      for (c = cache->items[i]; c; c = next) {
+	 next = c->next;
+	 c->next = items[c->hash % size];
+	 items[c->hash % size] = c;
+      }
+
+   FREE(cache->items);
+   cache->items = items;
+   cache->size = size;
+}
+
+
+/**
+ * Returns the buffer object matching cache_id and key, or NULL.
+ */
+boolean
+brw_search_cache(struct brw_cache *cache,
+                 enum brw_cache_id cache_id,
+                 const void *key,
+                 GLuint key_size,
+                 struct brw_winsys_reloc *relocs, 
+		 GLuint nr_relocs,
+                 void *aux_return,
+                 struct brw_winsys_buffer **bo_out)
+{
+   struct brw_cache_item *item;
+   GLuint hash = hash_key(key, key_size, relocs, nr_relocs);
+
+   item = search_cache(cache, cache_id, hash, key, key_size,
+		       relocs, nr_relocs);
+
+   if (item) {
+      if (aux_return)
+         *(void **)aux_return = (void *)((char *)item->key + item->key_size);
+      
+      update_cache_last(cache, cache_id, item->bo);
+      bo_reference(bo_out, item->bo);
+      return TRUE;
+   }
+   
+   return FALSE;      
+}
+
+
+enum pipe_error
+brw_upload_cache( struct brw_cache *cache,
+		  enum brw_cache_id cache_id,
+		  const void *key,
+		  GLuint key_size,
+		  struct brw_winsys_reloc *relocs,
+		  GLuint nr_relocs,
+		  const void *data,
+		  GLuint data_size,
+		  const void *aux,
+		  void *aux_return,
+                  struct brw_winsys_buffer **bo_out)
+{
+   struct brw_cache_item *item = CALLOC_STRUCT(brw_cache_item);
+   GLuint hash = hash_key(key, key_size, relocs, nr_relocs);
+   GLuint relocs_size = nr_relocs * sizeof relocs[0];
+   GLuint aux_size = cache->aux_size[cache_id];
+   enum pipe_error ret;
+   void *tmp;
+   int i;
+
+   /* Create the buffer object to contain the data.  For now, use a
+    * single buffer type to describe all cached state atoms.  Later,
+    * may want to take advantage of hardware distinctions between
+    * these various entities.
+    */
+   ret = cache->sws->bo_alloc(cache->sws,
+                              cache->buffer_type,
+                              data_size, 1 << 6, 
+                              bo_out);
+   if (ret)
+      return ret;
+
+
+   /* Set up the memory containing the key, aux_data, and relocs */
+   tmp = MALLOC(key_size + aux_size + relocs_size);
+
+   memcpy(tmp, key, key_size);
+   memcpy((char *)tmp + key_size, aux, cache->aux_size[cache_id]);
+   memcpy((char *)tmp + key_size + aux_size, relocs, relocs_size);
+   for (i = 0; i < nr_relocs; i++) {
+      p_atomic_inc(&relocs[i].bo->reference.count);
+   }
+
+   item->cache_id = cache_id;
+   item->key = tmp;
+   item->hash = hash;
+   item->key_size = key_size;
+   item->relocs = (struct brw_winsys_reloc *)((char *)tmp + key_size + aux_size);
+   item->nr_relocs = nr_relocs;
+   bo_reference( &item->bo, *bo_out );
+   item->data_size = data_size;
+
+   if (cache->n_items > cache->size * 1.5)
+      rehash(cache);
+
+   hash %= cache->size;
+   item->next = cache->items[hash];
+   cache->items[hash] = item;
+   cache->n_items++;
+
+   if (aux_return) {
+      assert(cache->aux_size[cache_id]);
+      *(void **)aux_return = (void *)((char *)item->key + item->key_size);
+   }
+
+   if (BRW_DEBUG & DEBUG_STATE)
+      debug_printf("upload %s: %d bytes to cache id %d\n",
+		   cache->name[cache_id],
+		   data_size, cache_id);
+
+   /* Copy data to the buffer */
+   ret = cache->sws->bo_subdata(item->bo, 
+                                cache_id,
+                                0, data_size, data,
+                                relocs, nr_relocs);
+   if (ret)
+      return ret;
+
+   update_cache_last(cache, cache_id, item->bo);
+
+   return PIPE_OK;
+}
+
+
+/**
+ * This doesn't really work with aux data.  Use search/upload instead
+ */
+enum pipe_error
+brw_cache_data_sz(struct brw_cache *cache,
+		  enum brw_cache_id cache_id,
+		  const void *data,
+		  GLuint data_size,
+		  struct brw_winsys_reloc *relocs,
+		  GLuint nr_relocs,
+                  struct brw_winsys_buffer **bo_out)
+{
+   struct brw_cache_item *item;
+   GLuint hash = hash_key(data, data_size, relocs, nr_relocs);
+
+   item = search_cache(cache, cache_id, hash, data, data_size,
+		       relocs, nr_relocs);
+   if (item) {
+      update_cache_last(cache, cache_id, item->bo);
+
+      bo_reference(bo_out, item->bo);
+      return PIPE_OK;
+   }
+
+   return brw_upload_cache(cache, cache_id,
+                           data, data_size,
+                           relocs, nr_relocs,
+                           data, data_size,
+                           NULL, NULL,
+                           bo_out);
+}
+
+
+/**
+ * Wrapper around brw_cache_data_sz using the cache_id's canonical key size.
+ *
+ * If nr_relocs is nonzero, brw_search_cache()/brw_upload_cache() would be
+ * better to use, as the potentially changing offsets in the data-used-as-key
+ * will result in excessive cache misses.
+ * 
+ * XXX: above is no longer true -- can we remove some code?
+ */
+enum pipe_error
+brw_cache_data(struct brw_cache *cache,
+	       enum brw_cache_id cache_id,
+	       const void *data,
+	       struct brw_winsys_reloc *relocs,
+	       GLuint nr_relocs,
+               struct brw_winsys_buffer **bo_out)
+{
+   return brw_cache_data_sz(cache, cache_id, data, cache->key_size[cache_id],
+			    relocs, nr_relocs, bo_out);
+}
+
+
+static void
+brw_init_cache_id(struct brw_cache *cache,
+                  const char *name,
+                  enum brw_cache_id id,
+                  GLuint key_size,
+                  GLuint aux_size)
+{
+   cache->name[id] = strdup(name);
+   cache->key_size[id] = key_size;
+   cache->aux_size[id] = aux_size;
+}
+
+
+static void
+brw_init_general_state_cache(struct brw_context *brw)
+{
+   struct brw_cache *cache = &brw->cache;
+
+   cache->brw = brw;
+   cache->sws = brw->sws;
+
+   cache->buffer_type = BRW_BUFFER_TYPE_GENERAL_STATE;
+
+   cache->size = 7;
+   cache->n_items = 0;
+   cache->items = (struct brw_cache_item **)
+      CALLOC(cache->size, sizeof(struct brw_cache_item));
+
+   brw_init_cache_id(cache,
+		     "CC_VP",
+		     BRW_CC_VP,
+		     sizeof(struct brw_cc_viewport),
+		     0);
+
+   brw_init_cache_id(cache,
+		     "CC_UNIT",
+		     BRW_CC_UNIT,
+		     sizeof(struct brw_cc_unit_state),
+		     0);
+
+   brw_init_cache_id(cache,
+		     "WM_PROG",
+		     BRW_WM_PROG,
+		     sizeof(struct brw_wm_prog_key),
+		     sizeof(struct brw_wm_prog_data));
+
+   brw_init_cache_id(cache,
+		     "SAMPLER_DEFAULT_COLOR",
+		     BRW_SAMPLER_DEFAULT_COLOR,
+		     sizeof(struct brw_sampler_default_color),
+		     0);
+
+   brw_init_cache_id(cache,
+		     "SAMPLER",
+		     BRW_SAMPLER,
+		     0,		/* variable key/data size */
+		     0);
+
+   brw_init_cache_id(cache,
+		     "WM_UNIT",
+		     BRW_WM_UNIT,
+		     sizeof(struct brw_wm_unit_state),
+		     0);
+
+   brw_init_cache_id(cache,
+		     "SF_PROG",
+		     BRW_SF_PROG,
+		     sizeof(struct brw_sf_prog_key),
+		     sizeof(struct brw_sf_prog_data));
+
+   brw_init_cache_id(cache,
+		     "SF_VP",
+		     BRW_SF_VP,
+		     sizeof(struct brw_sf_viewport),
+		     0);
+
+   brw_init_cache_id(cache,
+		     "SF_UNIT",
+		     BRW_SF_UNIT,
+		     sizeof(struct brw_sf_unit_state),
+		     0);
+
+   brw_init_cache_id(cache,
+		     "VS_UNIT",
+		     BRW_VS_UNIT,
+		     sizeof(struct brw_vs_unit_state),
+		     0);
+
+   brw_init_cache_id(cache,
+		     "VS_PROG",
+		     BRW_VS_PROG,
+		     sizeof(struct brw_vs_prog_key),
+		     sizeof(struct brw_vs_prog_data));
+
+   brw_init_cache_id(cache,
+		     "CLIP_UNIT",
+		     BRW_CLIP_UNIT,
+		     sizeof(struct brw_clip_unit_state),
+		     0);
+
+   brw_init_cache_id(cache,
+		     "CLIP_PROG",
+		     BRW_CLIP_PROG,
+		     sizeof(struct brw_clip_prog_key),
+		     sizeof(struct brw_clip_prog_data));
+
+   brw_init_cache_id(cache,
+		     "GS_UNIT",
+		     BRW_GS_UNIT,
+		     sizeof(struct brw_gs_unit_state),
+		     0);
+
+   brw_init_cache_id(cache,
+		     "GS_PROG",
+		     BRW_GS_PROG,
+		     sizeof(struct brw_gs_prog_key),
+		     sizeof(struct brw_gs_prog_data));
+}
+
+
+static void
+brw_init_surface_state_cache(struct brw_context *brw)
+{
+   struct brw_cache *cache = &brw->surface_cache;
+
+   cache->brw = brw;
+   cache->sws = brw->sws;
+
+   cache->buffer_type = BRW_BUFFER_TYPE_SURFACE_STATE;
+
+   cache->size = 7;
+   cache->n_items = 0;
+   cache->items = (struct brw_cache_item **)
+      CALLOC(cache->size, sizeof(struct brw_cache_item));
+
+   brw_init_cache_id(cache,
+		     "SS_SURFACE",
+		     BRW_SS_SURFACE,
+		     sizeof(struct brw_surface_state),
+		     0);
+
+   brw_init_cache_id(cache,
+		     "SS_SURF_BIND",
+		     BRW_SS_SURF_BIND,
+		     0,
+		     0);
+}
+
+
+void
+brw_init_caches(struct brw_context *brw)
+{
+   brw_init_general_state_cache(brw);
+   brw_init_surface_state_cache(brw);
+}
+
+
+static void
+brw_clear_cache(struct brw_context *brw, struct brw_cache *cache)
+{
+   struct brw_cache_item *c, *next;
+   GLuint i;
+
+   if (BRW_DEBUG & DEBUG_STATE)
+      debug_printf("%s\n", __FUNCTION__);
+
+   for (i = 0; i < cache->size; i++) {
+      for (c = cache->items[i]; c; c = next) {
+	 int j;
+
+	 next = c->next;
+
+	 for (j = 0; j < c->nr_relocs; j++)
+	    bo_reference(&c->relocs[j].bo, NULL);
+
+	 bo_reference(&c->bo, NULL);
+	 FREE((void *)c->key);
+	 FREE(c);
+      }
+      cache->items[i] = NULL;
+   }
+
+   cache->n_items = 0;
+
+   if (brw->curbe.last_buf) {
+      FREE(brw->curbe.last_buf);
+      brw->curbe.last_buf = NULL;
+   }
+
+   brw->state.dirty.mesa |= ~0;
+   brw->state.dirty.brw |= ~0;
+   brw->state.dirty.cache |= ~0;
+}
+
+/* Clear all entries from the cache that point to the given bo.
+ *
+ * This lets us release memory for reuse earlier for known-dead buffers,
+ * at the cost of walking the entire hash table.
+ */
+void
+brw_state_cache_bo_delete(struct brw_cache *cache, struct brw_winsys_buffer *bo)
+{
+   struct brw_cache_item **prev;
+   GLuint i;
+
+   if (BRW_DEBUG & DEBUG_STATE)
+      debug_printf("%s\n", __FUNCTION__);
+
+   for (i = 0; i < cache->size; i++) {
+      for (prev = &cache->items[i]; *prev;) {
+	 struct brw_cache_item *c = *prev;
+
+	 if (cache->sws->bo_references(c->bo, bo)) {
+	    int j;
+
+	    *prev = c->next;
+
+	    for (j = 0; j < c->nr_relocs; j++)
+	       bo_reference(&c->relocs[j].bo, NULL);
+
+	    bo_reference(&c->bo, NULL);
+
+	    FREE((void *)c->key);
+	    FREE(c);
+	    cache->n_items--;
+	 } else {
+	    prev = &c->next;
+	 }
+      }
+   }
+}
+
+void
+brw_state_cache_check_size(struct brw_context *brw)
+{
+   if (BRW_DEBUG & DEBUG_STATE)
+      debug_printf("%s (n_items=%d)\n", __FUNCTION__, brw->cache.n_items);
+
+   /* un-tuned guess.  We've got around 20 state objects for a total of around
+    * 32k, so 1000 of them is around 1.5MB.
+    */
+   if (brw->cache.n_items > 1000)
+      brw_clear_cache(brw, &brw->cache);
+
+   if (brw->surface_cache.n_items > 1000)
+      brw_clear_cache(brw, &brw->surface_cache);
+}
+
+
+static void
+brw_destroy_cache(struct brw_context *brw, struct brw_cache *cache)
+{
+   GLuint i;
+
+   if (BRW_DEBUG & DEBUG_STATE)
+      debug_printf("%s\n", __FUNCTION__);
+
+   brw_clear_cache(brw, cache);
+   for (i = 0; i < BRW_MAX_CACHE; i++) {
+      bo_reference(&cache->last_bo[i], NULL);
+      FREE(cache->name[i]);
+   }
+   FREE(cache->items);
+   cache->items = NULL;
+   cache->size = 0;
+}
+
+
+void
+brw_destroy_caches(struct brw_context *brw)
+{
+   brw_destroy_cache(brw, &brw->cache);
+   brw_destroy_cache(brw, &brw->surface_cache);
+}
diff --git a/src/gallium/drivers/i965/brw_state_debug.c b/src/gallium/drivers/i965/brw_state_debug.c
new file mode 100644
index 0000000..049c278
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_state_debug.c
@@ -0,0 +1,153 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "brw_context.h"
+#include "brw_state.h"
+
+
+struct dirty_bit_map {
+   uint32_t bit;
+   char *name;
+   uint32_t count;
+};
+
+#define DEFINE_BIT(name) {name, #name, 0}
+
+static struct dirty_bit_map mesa_bits[] = {
+   DEFINE_BIT(PIPE_NEW_DEPTH_STENCIL_ALPHA),
+   DEFINE_BIT(PIPE_NEW_RAST),
+   DEFINE_BIT(PIPE_NEW_BLEND),
+   DEFINE_BIT(PIPE_NEW_VIEWPORT),
+   DEFINE_BIT(PIPE_NEW_SAMPLERS),
+   DEFINE_BIT(PIPE_NEW_VERTEX_BUFFER),
+   DEFINE_BIT(PIPE_NEW_VERTEX_ELEMENT),
+   DEFINE_BIT(PIPE_NEW_FRAGMENT_SHADER),
+   DEFINE_BIT(PIPE_NEW_VERTEX_SHADER),
+   DEFINE_BIT(PIPE_NEW_FRAGMENT_CONSTANTS),
+   DEFINE_BIT(PIPE_NEW_VERTEX_CONSTANTS),
+   DEFINE_BIT(PIPE_NEW_CLIP),
+   DEFINE_BIT(PIPE_NEW_INDEX_BUFFER),
+   DEFINE_BIT(PIPE_NEW_INDEX_RANGE),
+   DEFINE_BIT(PIPE_NEW_BLEND_COLOR),
+   DEFINE_BIT(PIPE_NEW_POLYGON_STIPPLE),
+   DEFINE_BIT(PIPE_NEW_FRAMEBUFFER_DIMENSIONS),
+   DEFINE_BIT(PIPE_NEW_DEPTH_BUFFER),
+   DEFINE_BIT(PIPE_NEW_COLOR_BUFFERS),
+   DEFINE_BIT(PIPE_NEW_QUERY),
+   DEFINE_BIT(PIPE_NEW_SCISSOR),
+   DEFINE_BIT(PIPE_NEW_BOUND_TEXTURES),
+   DEFINE_BIT(PIPE_NEW_NR_CBUFS),
+   {0, 0, 0}
+};
+
+static struct dirty_bit_map brw_bits[] = {
+   DEFINE_BIT(BRW_NEW_URB_FENCE),
+   DEFINE_BIT(BRW_NEW_FRAGMENT_PROGRAM),
+   DEFINE_BIT(BRW_NEW_VERTEX_PROGRAM),
+   DEFINE_BIT(BRW_NEW_INPUT_DIMENSIONS),
+   DEFINE_BIT(BRW_NEW_CURBE_OFFSETS),
+   DEFINE_BIT(BRW_NEW_REDUCED_PRIMITIVE),
+   DEFINE_BIT(BRW_NEW_PRIMITIVE),
+   DEFINE_BIT(BRW_NEW_CONTEXT),
+   DEFINE_BIT(BRW_NEW_WM_INPUT_DIMENSIONS),
+   DEFINE_BIT(BRW_NEW_PSP),
+   DEFINE_BIT(BRW_NEW_WM_SURFACES),
+   DEFINE_BIT(BRW_NEW_xxx),
+   DEFINE_BIT(BRW_NEW_INDICES),
+   {0, 0, 0}
+};
+
+static struct dirty_bit_map cache_bits[] = {
+   DEFINE_BIT(CACHE_NEW_CC_VP),
+   DEFINE_BIT(CACHE_NEW_CC_UNIT),
+   DEFINE_BIT(CACHE_NEW_WM_PROG),
+   DEFINE_BIT(CACHE_NEW_SAMPLER_DEFAULT_COLOR),
+   DEFINE_BIT(CACHE_NEW_SAMPLER),
+   DEFINE_BIT(CACHE_NEW_WM_UNIT),
+   DEFINE_BIT(CACHE_NEW_SF_PROG),
+   DEFINE_BIT(CACHE_NEW_SF_VP),
+   DEFINE_BIT(CACHE_NEW_SF_UNIT),
+   DEFINE_BIT(CACHE_NEW_VS_UNIT),
+   DEFINE_BIT(CACHE_NEW_VS_PROG),
+   DEFINE_BIT(CACHE_NEW_GS_UNIT),
+   DEFINE_BIT(CACHE_NEW_GS_PROG),
+   DEFINE_BIT(CACHE_NEW_CLIP_VP),
+   DEFINE_BIT(CACHE_NEW_CLIP_UNIT),
+   DEFINE_BIT(CACHE_NEW_CLIP_PROG),
+   DEFINE_BIT(CACHE_NEW_SURFACE),
+   DEFINE_BIT(CACHE_NEW_SURF_BIND),
+   {0, 0, 0}
+};
+
+
+static void
+brw_update_dirty_count(struct dirty_bit_map *bit_map, int32_t bits)
+{
+   int i;
+
+   for (i = 0; i < 32; i++) {
+      if (bit_map[i].bit == 0)
+	 return;
+
+      if (bit_map[i].bit & bits)
+	 bit_map[i].count++;
+   }
+}
+
+static void
+brw_print_dirty_count(struct dirty_bit_map *bit_map, int32_t bits)
+{
+   int i;
+
+   for (i = 0; i < 32; i++) {
+      if (bit_map[i].bit == 0)
+	 return;
+
+      debug_printf("0x%08x: %12d (%s)\n",
+	      bit_map[i].bit, bit_map[i].count, bit_map[i].name);
+   }
+}
+
+void
+brw_update_dirty_counts( unsigned mesa,
+			 unsigned brw,
+			 unsigned cache )
+{
+   static int dirty_count = 0;
+
+   brw_update_dirty_count(mesa_bits, mesa);
+   brw_update_dirty_count(brw_bits, brw);
+   brw_update_dirty_count(cache_bits, cache);
+      if (dirty_count++ % 1000 == 0) {
+	 brw_print_dirty_count(mesa_bits, mesa);
+	 brw_print_dirty_count(brw_bits, brw);
+	 brw_print_dirty_count(cache_bits, cache);
+	 debug_printf("\n");
+      }
+}
diff --git a/src/gallium/drivers/i965/brw_state_upload.c b/src/gallium/drivers/i965/brw_state_upload.c
new file mode 100644
index 0000000..f8b91ef
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_state_upload.c
@@ -0,0 +1,270 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+       
+
+
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_batchbuffer.h"
+#include "brw_debug.h"
+
+const struct brw_tracked_state *atoms[] =
+{
+/*   &brw_wm_input_sizes, */
+   &brw_vs_prog,
+   &brw_gs_prog, 
+   &brw_clip_prog, 
+   &brw_sf_prog,
+   &brw_wm_prog,
+
+   /* Once all the programs are done, we know how large urb entry
+    * sizes need to be and can decide if we need to change the urb
+    * layout.
+    */
+   &brw_curbe_offsets,
+   &brw_recalculate_urb_fence,
+
+   &brw_cc_vp,
+   &brw_cc_unit,
+
+   &brw_vs_surfaces,		/* must do before unit */
+   /*&brw_wm_constant_surface,*/	/* must do before wm surfaces/bind bo */
+   &brw_wm_surfaces,		/* must do before samplers and unit */
+   &brw_wm_samplers,
+
+   &brw_wm_unit,
+   &brw_sf_vp,
+   &brw_sf_unit,
+   &brw_vs_unit,		/* always required, enabled or not */
+   &brw_clip_unit,
+   &brw_gs_unit,  
+
+   /* Command packets:
+    */
+   &brw_invarient_state,
+   &brw_state_base_address,
+
+   &brw_binding_table_pointers,
+   &brw_blend_constant_color,
+
+   &brw_depthbuffer,
+   &brw_polygon_stipple,
+   &brw_line_stipple,
+
+   &brw_psp_urb_cbs,
+
+   &brw_drawing_rect,
+   &brw_indices,
+   &brw_index_buffer,
+   &brw_vertices,
+
+   &brw_curbe_buffer
+};
+
+
+void brw_init_state( struct brw_context *brw )
+{
+   brw_init_caches(brw);
+}
+
+
+void brw_destroy_state( struct brw_context *brw )
+{
+   brw_destroy_caches(brw);
+   brw_destroy_batch_cache(brw);
+}
+
+/***********************************************************************
+ */
+
+static GLboolean check_state( const struct brw_state_flags *a,
+			      const struct brw_state_flags *b )
+{
+   return ((a->mesa & b->mesa) ||
+	   (a->brw & b->brw) ||
+	   (a->cache & b->cache));
+}
+
+static void accumulate_state( struct brw_state_flags *a,
+			      const struct brw_state_flags *b )
+{
+   a->mesa |= b->mesa;
+   a->brw |= b->brw;
+   a->cache |= b->cache;
+}
+
+
+static void xor_states( struct brw_state_flags *result,
+			     const struct brw_state_flags *a,
+			      const struct brw_state_flags *b )
+{
+   result->mesa = a->mesa ^ b->mesa;
+   result->brw = a->brw ^ b->brw;
+   result->cache = a->cache ^ b->cache;
+}
+
+static void
+brw_clear_validated_bos(struct brw_context *brw)
+{
+   int i;
+
+   /* Clear the last round of validated bos */
+   for (i = 0; i < brw->state.validated_bo_count; i++) {
+      bo_reference(&brw->state.validated_bos[i], NULL);
+   }
+   brw->state.validated_bo_count = 0;
+}
+
+
+/***********************************************************************
+ * Emit all state:
+ */
+enum pipe_error brw_validate_state( struct brw_context *brw )
+{
+   struct brw_state_flags *state = &brw->state.dirty;
+   GLuint i;
+   int ret;
+
+   brw_clear_validated_bos(brw);
+   brw_add_validated_bo(brw, brw->batch->buf);
+
+   if (brw->flags.always_emit_state) {
+      state->mesa |= ~0;
+      state->brw |= ~0;
+      state->cache |= ~0;
+   }
+
+   if (state->mesa == 0 &&
+       state->cache == 0 &&
+       state->brw == 0)
+      return 0;
+
+   if (brw->state.dirty.brw & BRW_NEW_CONTEXT)
+      brw_clear_batch_cache(brw);
+
+   /* do prepare stage for all atoms */
+   for (i = 0; i < Elements(atoms); i++) {
+      const struct brw_tracked_state *atom = atoms[i];
+
+      if (check_state(state, &atom->dirty)) {
+         if (atom->prepare) {
+            ret = atom->prepare(brw);
+	    if (ret)
+	       return ret;
+        }
+      }
+   }
+
+   /* Make sure that the textures which are referenced by the current
+    * brw fragment program are actually present/valid.
+    * If this fails, we can experience GPU lock-ups.
+    */
+   {
+      const struct brw_fragment_shader *fp = brw->curr.fragment_shader;
+      if (fp) {
+         assert(fp->info.file_max[TGSI_FILE_SAMPLER] < (int)brw->curr.num_samplers);
+	 /*assert(fp->info.texture_max <= brw->curr.num_textures);*/
+      }
+   }
+
+   return 0;
+}
+
+
+enum pipe_error brw_upload_state(struct brw_context *brw)
+{
+   struct brw_state_flags *state = &brw->state.dirty;
+   int ret;
+   int i;
+
+   brw_clear_validated_bos(brw);
+
+   if (BRW_DEBUG) {
+      /* Debug version which enforces various sanity checks on the
+       * state flags which are generated and checked to help ensure
+       * state atoms are ordered correctly in the list.
+       */
+      struct brw_state_flags examined, prev;      
+      memset(&examined, 0, sizeof(examined));
+      prev = *state;
+
+      for (i = 0; i < Elements(atoms); i++) {
+	 const struct brw_tracked_state *atom = atoms[i];
+	 struct brw_state_flags generated;
+
+	 assert(atom->dirty.mesa ||
+		atom->dirty.brw ||
+		atom->dirty.cache);
+
+	 if (check_state(state, &atom->dirty)) {
+	    if (atom->emit) {
+	       ret = atom->emit( brw );
+	       if (ret)
+		  return ret;
+	    }
+	 }
+
+	 accumulate_state(&examined, &atom->dirty);
+
+	 /* generated = (prev ^ state)
+	  * if (examined & generated)
+	  *     fail;
+	  */
+	 xor_states(&generated, &prev, state);
+	 assert(!check_state(&examined, &generated));
+	 prev = *state;
+      }
+   }
+   else {
+      for (i = 0; i < Elements(atoms); i++) {	 
+	 const struct brw_tracked_state *atom = atoms[i];
+
+	 if (check_state(state, &atom->dirty)) {
+	    if (atom->emit) {
+	       ret = atom->emit( brw );
+	       if (ret)
+		  return ret;
+	    }
+	 }
+      }
+   }
+
+   if (BRW_DEBUG & DEBUG_STATE) {
+      brw_update_dirty_counts( state->mesa, 
+			       state->brw,
+			       state->cache );
+   }
+   
+   /* Clear dirty flags:
+    */
+   memset(state, 0, sizeof(*state));
+   return 0;
+}
diff --git a/src/gallium/drivers/i965/brw_structs.h b/src/gallium/drivers/i965/brw_structs.h
new file mode 100644
index 0000000..bf10bc0
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_structs.h
@@ -0,0 +1,1576 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+        
+
+#ifndef BRW_STRUCTS_H
+#define BRW_STRUCTS_H
+
+#include "brw_types.h"
+
+/** Number of general purpose registers (VS, WM, etc) */
+#define BRW_MAX_GRF 128
+
+/** Number of message register file registers */
+#define BRW_MAX_MRF 16
+
+
+/* Command packets:
+ */
+struct header 
+{
+   GLuint length:16; 
+   GLuint opcode:16; 
+};
+
+
+union header_union
+{
+   struct header bits;
+   GLuint dword;
+};
+
+struct brw_3d_control
+{   
+   struct 
+   {
+      GLuint length:8;
+      GLuint notify_enable:1;
+      GLuint pad:3;
+      GLuint wc_flush_enable:1; 
+      GLuint depth_stall_enable:1; 
+      GLuint operation:2; 
+      GLuint opcode:16; 
+   } header;
+   
+   struct
+   {
+      GLuint pad:2;
+      GLuint dest_addr_type:1; 
+      GLuint dest_addr:29; 
+   } dest;
+   
+   GLuint dword2;   
+   GLuint dword3;   
+};
+
+
+struct brw_3d_primitive
+{
+   struct
+   {
+      GLuint length:8; 
+      GLuint pad:2;
+      GLuint topology:5; 
+      GLuint indexed:1; 
+      GLuint opcode:16; 
+   } header;
+
+   GLuint verts_per_instance;  
+   GLuint start_vert_location;  
+   GLuint instance_count;  
+   GLuint start_instance_location;  
+   GLuint base_vert_location;  
+};
+
+/* These seem to be passed around as function args, so it works out
+ * better to keep them as #defines:
+ */
+#define BRW_FLUSH_READ_CACHE           0x1
+#define BRW_FLUSH_STATE_CACHE          0x2
+#define BRW_INHIBIT_FLUSH_RENDER_CACHE 0x4
+#define BRW_FLUSH_SNAPSHOT_COUNTERS    0x8
+
+struct brw_mi_flush
+{
+   GLuint flags:4;
+   GLuint pad:12;
+   GLuint opcode:16;
+};
+
+struct brw_vf_statistics
+{
+   GLuint statistics_enable:1;
+   GLuint pad:15;
+   GLuint opcode:16;
+};
+
+
+
+struct brw_binding_table_pointers
+{
+   struct header header;
+   GLuint vs; 
+   GLuint gs; 
+   GLuint clp; 
+   GLuint sf; 
+   GLuint wm; 
+};
+
+
+struct brw_blend_constant_color
+{
+   struct header header;
+   GLfloat blend_constant_color[4];  
+};
+
+
+struct brw_depthbuffer
+{
+   union header_union header;
+   
+   union {
+      struct {
+	 GLuint pitch:18; 
+	 GLuint format:3; 
+	 GLuint pad:2;
+	 GLuint software_tiled_rendering_mode:2;
+	 GLuint depth_offset_disable:1; 
+	 GLuint tile_walk:1; 
+	 GLuint tiled_surface:1; 
+	 GLuint pad2:1;
+	 GLuint surface_type:3; 
+      } bits;
+      GLuint dword;
+   } dword1;
+   
+   GLuint dword2_base_addr; 
+ 
+   union {
+      struct {
+	 GLuint pad:1;
+	 GLuint mipmap_layout:1; 
+	 GLuint lod:4; 
+	 GLuint width:13; 
+	 GLuint height:13; 
+      } bits;
+      GLuint dword;
+   } dword3;
+
+   union {
+      struct {
+	 GLuint pad:10;
+	 GLuint min_array_element:11; 
+	 GLuint depth:11; 
+      } bits;
+      GLuint dword;
+   } dword4;
+};
+
+struct brw_depthbuffer_g4x
+{
+   union header_union header;
+   
+   union {
+      struct {
+	 GLuint pitch:18; 
+	 GLuint format:3; 
+	 GLuint pad:2;
+	 GLuint software_tiled_rendering_mode:2;
+	 GLuint depth_offset_disable:1; 
+	 GLuint tile_walk:1; 
+	 GLuint tiled_surface:1; 
+	 GLuint pad2:1;
+	 GLuint surface_type:3; 
+      } bits;
+      GLuint dword;
+   } dword1;
+   
+   GLuint dword2_base_addr; 
+ 
+   union {
+      struct {
+	 GLuint pad:1;
+	 GLuint mipmap_layout:1; 
+	 GLuint lod:4; 
+	 GLuint width:13; 
+	 GLuint height:13; 
+      } bits;
+      GLuint dword;
+   } dword3;
+
+   union {
+      struct {
+	 GLuint pad:10;
+	 GLuint min_array_element:11; 
+	 GLuint depth:11; 
+      } bits;
+      GLuint dword;
+   } dword4;
+
+   union {
+      struct {
+         GLuint xoffset:16;
+         GLuint yoffset:16;
+      } bits;
+      GLuint dword;
+   } dword5;   /* NEW in Integrated Graphics Device */
+};
+
+struct brw_drawrect
+{
+   struct header header;
+   GLuint xmin:16; 
+   GLuint ymin:16; 
+   GLuint xmax:16; 
+   GLuint ymax:16; 
+   GLuint xorg:16;  
+   GLuint yorg:16;  
+};
+
+
+
+
+struct brw_global_depth_offset_clamp
+{
+   struct header header;
+   GLfloat depth_offset_clamp;  
+};
+
+struct brw_indexbuffer
+{   
+   union {
+      struct
+      {
+	 GLuint length:8; 
+	 GLuint index_format:2; 
+	 GLuint cut_index_enable:1; 
+	 GLuint pad:5; 
+	 GLuint opcode:16; 
+      } bits;
+      GLuint dword;
+
+   } header;
+
+   GLuint buffer_start; 
+   GLuint buffer_end; 
+};
+
+/* NEW in Integrated Graphics Device */
+struct brw_aa_line_parameters
+{
+   struct header header;
+
+   struct {
+      GLuint aa_coverage_scope:8;
+      GLuint pad0:8;
+      GLuint aa_coverage_bias:8;
+      GLuint pad1:8;
+   } bits0;
+
+   struct {
+      GLuint aa_coverage_endcap_slope:8;
+      GLuint pad0:8;
+      GLuint aa_coverage_endcap_bias:8;
+      GLuint pad1:8;
+   } bits1;
+};
+
+struct brw_line_stipple
+{   
+   struct header header;
+  
+   struct
+   {
+      GLuint pattern:16; 
+      GLuint pad:16;
+   } bits0;
+   
+   struct
+   {
+      GLuint repeat_count:9; 
+      GLuint pad:7;
+      GLuint inverse_repeat_count:16; 
+   } bits1;
+};
+
+
+struct brw_pipelined_state_pointers
+{
+   struct header header;
+   
+   struct {
+      GLuint pad:5;
+      GLuint offset:27; /* Offset from GENERAL_STATE_BASE */
+   } vs;
+   
+   struct
+   {
+      GLuint enable:1;
+      GLuint pad:4;
+      GLuint offset:27; /* Offset from GENERAL_STATE_BASE */
+   } gs;
+   
+   struct
+   {
+      GLuint enable:1;
+      GLuint pad:4;
+      GLuint offset:27; /* Offset from GENERAL_STATE_BASE */
+   } clp;
+   
+   struct
+   {
+      GLuint pad:5;
+      GLuint offset:27; /* Offset from GENERAL_STATE_BASE */
+   } sf;
+
+   struct
+   {
+      GLuint pad:5;
+      GLuint offset:27; /* Offset from GENERAL_STATE_BASE */
+   } wm;
+   
+   struct
+   {
+      GLuint pad:5;
+      GLuint offset:27; /* Offset from GENERAL_STATE_BASE. KW: check me! */
+   } cc;
+};
+
+
+struct brw_polygon_stipple_offset
+{
+   struct header header;
+
+   struct {
+      GLuint y_offset:5; 
+      GLuint pad:3;
+      GLuint x_offset:5; 
+      GLuint pad0:19;
+   } bits0;
+};
+
+
+
+struct brw_polygon_stipple
+{
+   struct header header;
+   GLuint stipple[32];
+};
+
+
+
+struct brw_pipeline_select
+{
+   struct
+   {
+      GLuint pipeline_select:1;   
+      GLuint pad:15;
+      GLuint opcode:16;   
+   } header;
+};
+
+
+struct brw_pipe_control
+{
+   struct
+   {
+      GLuint length:8;
+      GLuint notify_enable:1;
+      GLuint texture_cache_flush_enable:1;
+      GLuint indirect_state_pointers_disable:1;
+      GLuint instruction_state_cache_flush_enable:1;
+      GLuint write_cache_flush_enable:1;
+      GLuint depth_stall_enable:1;
+      GLuint post_sync_operation:2;
+
+      GLuint opcode:16;
+   } header;
+
+   struct
+   {
+      GLuint pad:2;
+      GLuint dest_addr_type:1;
+      GLuint dest_addr:29;
+   } bits1;
+
+   GLuint data0;
+   GLuint data1;
+};
+
+
+struct brw_urb_fence
+{
+   struct
+   {
+      GLuint length:8;   
+      GLuint vs_realloc:1;   
+      GLuint gs_realloc:1;   
+      GLuint clp_realloc:1;   
+      GLuint sf_realloc:1;   
+      GLuint vfe_realloc:1;   
+      GLuint cs_realloc:1;   
+      GLuint pad:2;
+      GLuint opcode:16;   
+   } header;
+
+   struct
+   {
+      GLuint vs_fence:10;  
+      GLuint gs_fence:10;  
+      GLuint clp_fence:10;  
+      GLuint pad:2;
+   } bits0;
+
+   struct
+   {
+      GLuint sf_fence:10;  
+      GLuint vf_fence:10;  
+      GLuint cs_fence:11;  
+      GLuint pad:1;
+   } bits1;
+};
+
+struct brw_cs_urb_state
+{
+   struct header header;
+
+   struct
+   {
+      GLuint nr_urb_entries:3;   
+      GLuint pad:1;
+      GLuint urb_entry_size:5;   
+      GLuint pad0:23;
+   } bits0;
+};
+
+struct brw_constant_buffer
+{
+   struct
+   {
+      GLuint length:8;   
+      GLuint valid:1;   
+      GLuint pad:7;
+      GLuint opcode:16;   
+   } header;
+
+   struct
+   {
+      GLuint buffer_length:6;   
+      GLuint buffer_address:26;  
+   } bits0;
+};
+
+struct brw_state_base_address
+{
+   struct header header;
+
+   struct
+   {
+      GLuint modify_enable:1;
+      GLuint pad:4;
+      GLuint general_state_address:27;  
+   } bits0;
+
+   struct
+   {
+      GLuint modify_enable:1;
+      GLuint pad:4;
+      GLuint surface_state_address:27;  
+   } bits1;
+
+   struct
+   {
+      GLuint modify_enable:1;
+      GLuint pad:4;
+      GLuint indirect_object_state_address:27;  
+   } bits2;
+
+   struct
+   {
+      GLuint modify_enable:1;
+      GLuint pad:11;
+      GLuint general_state_upper_bound:20;  
+   } bits3;
+
+   struct
+   {
+      GLuint modify_enable:1;
+      GLuint pad:11;
+      GLuint indirect_object_state_upper_bound:20;  
+   } bits4;
+};
+
+struct brw_state_prefetch
+{
+   struct header header;
+
+   struct
+   {
+      GLuint prefetch_count:3;   
+      GLuint pad:3;
+      GLuint prefetch_pointer:26;  
+   } bits0;
+};
+
+struct brw_system_instruction_pointer
+{
+   struct header header;
+
+   struct
+   {
+      GLuint pad:4;
+      GLuint system_instruction_pointer:28;  
+   } bits0;
+};
+
+
+
+
+/* State structs for the various fixed function units:
+ */
+
+
+struct thread0
+{
+   GLuint pad0:1;
+   GLuint grf_reg_count:3; 
+   GLuint pad1:2;
+   GLuint kernel_start_pointer:26; /* Offset from GENERAL_STATE_BASE */
+};
+
+struct thread1
+{
+   GLuint ext_halt_exception_enable:1; 
+   GLuint sw_exception_enable:1; 
+   GLuint mask_stack_exception_enable:1; 
+   GLuint timeout_exception_enable:1; 
+   GLuint illegal_op_exception_enable:1; 
+   GLuint pad0:3;
+   GLuint depth_coef_urb_read_offset:6;	/* WM only */
+   GLuint pad1:2;
+   GLuint floating_point_mode:1; 
+   GLuint thread_priority:1; 
+   GLuint binding_table_entry_count:8; 
+   GLuint pad3:5;
+   GLuint single_program_flow:1; 
+};
+
+struct thread2
+{
+   GLuint per_thread_scratch_space:4; 
+   GLuint pad0:6;
+   GLuint scratch_space_base_pointer:22; 
+};
+
+   
+struct thread3
+{
+   GLuint dispatch_grf_start_reg:4; 
+   GLuint urb_entry_read_offset:6; 
+   GLuint pad0:1;
+   GLuint urb_entry_read_length:6; 
+   GLuint pad1:1;
+   GLuint const_urb_entry_read_offset:6; 
+   GLuint pad2:1;
+   GLuint const_urb_entry_read_length:6; 
+   GLuint pad3:1;
+};
+
+
+
+struct brw_clip_unit_state
+{
+   struct thread0 thread0;
+   struct
+   {
+      GLuint pad0:7;
+      GLuint sw_exception_enable:1;
+      GLuint pad1:3;
+      GLuint mask_stack_exception_enable:1;
+      GLuint pad2:1;
+      GLuint illegal_op_exception_enable:1;
+      GLuint pad3:2;
+      GLuint floating_point_mode:1;
+      GLuint thread_priority:1;
+      GLuint binding_table_entry_count:8;
+      GLuint pad4:5;
+      GLuint single_program_flow:1;
+   } thread1;
+
+   struct thread2 thread2;
+   struct thread3 thread3;
+
+   struct
+   {
+      GLuint pad0:9;
+      GLuint gs_output_stats:1; /* not always */
+      GLuint stats_enable:1; 
+      GLuint nr_urb_entries:7; 
+      GLuint pad1:1;
+      GLuint urb_entry_allocation_size:5; 
+      GLuint pad2:1;
+      GLuint max_threads:5; 	/* may be less */
+      GLuint pad3:2;
+   } thread4;   
+      
+   struct
+   {
+      GLuint pad0:13;
+      GLuint clip_mode:3; 
+      GLuint userclip_enable_flags:8; 
+      GLuint userclip_must_clip:1; 
+      GLuint negative_w_clip_test:1;
+      GLuint guard_band_enable:1; 
+      GLuint viewport_z_clip_enable:1; 
+      GLuint viewport_xy_clip_enable:1; 
+      GLuint vertex_position_space:1; 
+      GLuint api_mode:1; 
+      GLuint pad2:1;
+   } clip5;
+   
+   struct
+   {
+      GLuint pad0:5;
+      GLuint clipper_viewport_state_ptr:27; 
+   } clip6;
+
+   
+   GLfloat viewport_xmin;  
+   GLfloat viewport_xmax;  
+   GLfloat viewport_ymin;  
+   GLfloat viewport_ymax;  
+};
+
+
+
+struct brw_cc_unit_state
+{
+   struct brw_cc0
+   {
+      GLuint pad0:3;
+      GLuint bf_stencil_pass_depth_pass_op:3; 
+      GLuint bf_stencil_pass_depth_fail_op:3; 
+      GLuint bf_stencil_fail_op:3; 
+      GLuint bf_stencil_func:3; 
+      GLuint bf_stencil_enable:1; 
+      GLuint pad1:2;
+      GLuint stencil_write_enable:1; 
+      GLuint stencil_pass_depth_pass_op:3; 
+      GLuint stencil_pass_depth_fail_op:3; 
+      GLuint stencil_fail_op:3; 
+      GLuint stencil_func:3; 
+      GLuint stencil_enable:1; 
+   } cc0;
+
+   
+   struct brw_cc1
+   {
+      GLuint bf_stencil_ref:8; 
+      GLuint stencil_write_mask:8; 
+      GLuint stencil_test_mask:8; 
+      GLuint stencil_ref:8; 
+   } cc1;
+
+   
+   struct brw_cc2
+   {
+      GLuint logicop_enable:1; 
+      GLuint pad0:10;
+      GLuint depth_write_enable:1; 
+      GLuint depth_test_function:3; 
+      GLuint depth_test:1; 
+      GLuint bf_stencil_write_mask:8; 
+      GLuint bf_stencil_test_mask:8; 
+   } cc2;
+
+   
+   struct brw_cc3
+   {
+      GLuint pad0:8;
+      GLuint alpha_test_func:3; 
+      GLuint alpha_test:1; 
+      GLuint blend_enable:1; 
+      GLuint ia_blend_enable:1; 
+      GLuint pad1:1;
+      GLuint alpha_test_format:1;
+      GLuint pad2:16;
+   } cc3;
+   
+   struct brw_cc4
+   {
+      GLuint pad0:5; 
+      GLuint cc_viewport_state_offset:27; /* Offset from GENERAL_STATE_BASE */
+   } cc4;
+   
+   struct brw_cc5
+   {
+      GLuint pad0:2;
+      GLuint ia_dest_blend_factor:5; 
+      GLuint ia_src_blend_factor:5; 
+      GLuint ia_blend_function:3; 
+      GLuint statistics_enable:1; 
+      GLuint logicop_func:4; 
+      GLuint pad1:11;
+      GLuint dither_enable:1; 
+   } cc5;
+
+   struct brw_cc6
+   {
+      GLuint clamp_post_alpha_blend:1; 
+      GLuint clamp_pre_alpha_blend:1; 
+      GLuint clamp_range:2; 
+      GLuint pad0:11;
+      GLuint y_dither_offset:2; 
+      GLuint x_dither_offset:2; 
+      GLuint dest_blend_factor:5; 
+      GLuint src_blend_factor:5; 
+      GLuint blend_function:3; 
+   } cc6;
+
+   struct brw_cc7 {
+      union {
+	 GLfloat f;  
+	 GLubyte ub[4];
+      } alpha_ref;
+   } cc7;
+};
+
+
+
+struct brw_sf_unit_state
+{
+   struct thread0 thread0;
+   struct thread1 thread1;
+   struct thread2 thread2;
+   struct thread3 thread3;
+
+   struct
+   {
+      GLuint pad0:10;
+      GLuint stats_enable:1; 
+      GLuint nr_urb_entries:7; 
+      GLuint pad1:1;
+      GLuint urb_entry_allocation_size:5; 
+      GLuint pad2:1;
+      GLuint max_threads:6; 
+      GLuint pad3:1;
+   } thread4;   
+
+   struct
+   {
+      GLuint front_winding:1; 
+      GLuint viewport_transform:1; 
+      GLuint pad0:3;
+      GLuint sf_viewport_state_offset:27; /* Offset from GENERAL_STATE_BASE */
+   } sf5;
+   
+   struct
+   {
+      GLuint pad0:9;
+      GLuint dest_org_vbias:4; 
+      GLuint dest_org_hbias:4; 
+      GLuint scissor:1; 
+      GLuint disable_2x2_trifilter:1; 
+      GLuint disable_zero_pix_trifilter:1; 
+      GLuint point_rast_rule:2; 
+      GLuint line_endcap_aa_region_width:2; 
+      GLuint line_width:4; 
+      GLuint fast_scissor_disable:1; 
+      GLuint cull_mode:2; 
+      GLuint aa_enable:1; 
+   } sf6;
+
+   struct
+   {
+      GLuint point_size:11; 
+      GLuint use_point_size_state:1; 
+      GLuint subpixel_precision:1; 
+      GLuint sprite_point:1; 
+      GLuint pad0:10;
+      GLuint aa_line_distance_mode:1;
+      GLuint trifan_pv:2; 
+      GLuint linestrip_pv:2; 
+      GLuint tristrip_pv:2; 
+      GLuint line_last_pixel_enable:1; 
+   } sf7;
+
+};
+
+
+struct brw_gs_unit_state
+{
+   struct thread0 thread0;
+   struct thread1 thread1;
+   struct thread2 thread2;
+   struct thread3 thread3;
+
+   struct
+   {
+      GLuint pad0:8;
+      GLuint rendering_enable:1; /* for IGDNG */
+      GLuint pad4:1;
+      GLuint stats_enable:1; 
+      GLuint nr_urb_entries:7; 
+      GLuint pad1:1;
+      GLuint urb_entry_allocation_size:5; 
+      GLuint pad2:1;
+      GLuint max_threads:5; 
+      GLuint pad3:2;
+   } thread4;   
+      
+   struct
+   {
+      GLuint sampler_count:3; 
+      GLuint pad0:2;
+      GLuint sampler_state_pointer:27; 
+   } gs5;
+
+   
+   struct
+   {
+      GLuint max_vp_index:4; 
+      GLuint pad0:12;
+      GLuint svbi_post_inc_value:10;
+      GLuint pad1:1;
+      GLuint svbi_post_inc_enable:1;
+      GLuint svbi_payload:1;
+      GLuint discard_adjaceny:1;
+      GLuint reorder_enable:1; 
+      GLuint pad2:1;
+   } gs6;
+};
+
+
+struct brw_vs_unit_state
+{
+   struct thread0 thread0;
+   struct thread1 thread1;
+   struct thread2 thread2;
+   struct thread3 thread3;
+   
+   struct
+   {
+      GLuint pad0:10;
+      GLuint stats_enable:1; 
+      GLuint nr_urb_entries:7; 
+      GLuint pad1:1;
+      GLuint urb_entry_allocation_size:5; 
+      GLuint pad2:1;
+      GLuint max_threads:6; 
+      GLuint pad3:1;
+   } thread4;   
+
+   struct
+   {
+      GLuint sampler_count:3; 
+      GLuint pad0:2;
+      GLuint sampler_state_pointer:27; 
+   } vs5;
+
+   struct
+   {
+      GLuint vs_enable:1; 
+      GLuint vert_cache_disable:1; 
+      GLuint pad0:30;
+   } vs6;
+};
+
+
+struct brw_wm_unit_state
+{
+   struct thread0 thread0;
+   struct thread1 thread1;
+   struct thread2 thread2;
+   struct thread3 thread3;
+   
+   struct {
+      GLuint stats_enable:1; 
+      GLuint depth_buffer_clear:1;
+      GLuint sampler_count:3; 
+      GLuint sampler_state_pointer:27; 
+   } wm4;
+   
+   struct
+   {
+      GLuint enable_8_pix:1; 
+      GLuint enable_16_pix:1; 
+      GLuint enable_32_pix:1; 
+      GLuint enable_con_32_pix:1;
+      GLuint enable_con_64_pix:1;
+      GLuint pad0:5;
+      GLuint legacy_global_depth_bias:1; 
+      GLuint line_stipple:1; 
+      GLuint depth_offset:1; 
+      GLuint polygon_stipple:1; 
+      GLuint line_aa_region_width:2; 
+      GLuint line_endcap_aa_region_width:2; 
+      GLuint early_depth_test:1; 
+      GLuint thread_dispatch_enable:1; 
+      GLuint program_uses_depth:1; 
+      GLuint program_computes_depth:1; 
+      GLuint program_uses_killpixel:1; 
+      GLuint legacy_line_rast: 1; 
+      GLuint transposed_urb_read_enable:1; 
+      GLuint max_threads:7; 
+   } wm5;
+   
+   GLfloat global_depth_offset_constant;  
+   GLfloat global_depth_offset_scale;   
+   
+   /* for IGDNG only */
+   struct {
+      GLuint pad0:1;
+      GLuint grf_reg_count_1:3; 
+      GLuint pad1:2;
+      GLuint kernel_start_pointer_1:26;
+   } wm8;       
+
+   struct {
+      GLuint pad0:1;
+      GLuint grf_reg_count_2:3; 
+      GLuint pad1:2;
+      GLuint kernel_start_pointer_2:26;
+   } wm9;       
+
+   struct {
+      GLuint pad0:1;
+      GLuint grf_reg_count_3:3; 
+      GLuint pad1:2;
+      GLuint kernel_start_pointer_3:26;
+   } wm10;       
+};
+
+struct brw_sampler_default_color {
+   GLfloat color[4];
+};
+
+struct brw_sampler_state
+{
+   
+   struct brw_ss0
+   {
+      GLuint shadow_function:3; 
+      GLuint lod_bias:11; 
+      GLuint min_filter:3; 
+      GLuint mag_filter:3; 
+      GLuint mip_filter:2; 
+      GLuint base_level:5; 
+      GLuint pad:1;
+      GLuint lod_preclamp:1; 
+      GLuint default_color_mode:1; 
+      GLuint pad0:1;
+      GLuint disable:1; 
+   } ss0;
+
+   struct brw_ss1
+   {
+      GLuint r_wrap_mode:3; 
+      GLuint t_wrap_mode:3; 
+      GLuint s_wrap_mode:3; 
+      GLuint pad:3;
+      GLuint max_lod:10; 
+      GLuint min_lod:10; 
+   } ss1;
+
+   
+   struct brw_ss2
+   {
+      GLuint pad:5;
+      GLuint default_color_pointer:27; 
+   } ss2;
+   
+   struct brw_ss3
+   {
+      GLuint pad:19;
+      GLuint max_aniso:3; 
+      GLuint chroma_key_mode:1; 
+      GLuint chroma_key_index:2; 
+      GLuint chroma_key_enable:1; 
+      GLuint monochrome_filter_width:3; 
+      GLuint monochrome_filter_height:3; 
+   } ss3;
+};
+
+
+struct brw_clipper_viewport
+{
+   GLfloat xmin;  
+   GLfloat xmax;  
+   GLfloat ymin;  
+   GLfloat ymax;  
+};
+
+struct brw_cc_viewport
+{
+   GLfloat min_depth;  
+   GLfloat max_depth;  
+};
+
+struct brw_sf_viewport
+{
+   struct {
+      GLfloat m00;  
+      GLfloat m11;  
+      GLfloat m22;  
+      GLfloat m30;  
+      GLfloat m31;  
+      GLfloat m32;  
+   } viewport;
+
+   /* scissor coordinates are inclusive */
+   struct {
+      GLshort xmin;
+      GLshort ymin;
+      GLshort xmax;
+      GLshort ymax;
+   } scissor;
+};
+
+/* Documented in the subsystem/shared-functions/sampler chapter...
+ */
+struct brw_surface_state
+{
+   struct brw_surf_ss0 {
+      GLuint cube_pos_z:1; 
+      GLuint cube_neg_z:1; 
+      GLuint cube_pos_y:1; 
+      GLuint cube_neg_y:1; 
+      GLuint cube_pos_x:1; 
+      GLuint cube_neg_x:1; 
+      GLuint pad:4;
+      GLuint mipmap_layout_mode:1; 
+      GLuint vert_line_stride_ofs:1; 
+      GLuint vert_line_stride:1; 
+      GLuint color_blend:1; 
+      GLuint writedisable_blue:1; 
+      GLuint writedisable_green:1; 
+      GLuint writedisable_red:1; 
+      GLuint writedisable_alpha:1; 
+      GLuint surface_format:9;     /**< BRW_SURFACEFORMAT_x */
+      GLuint data_return_format:1; 
+      GLuint pad0:1;
+      GLuint surface_type:3;       /**< BRW_SURFACE_1D/2D/3D/CUBE */
+   } ss0;
+   
+   struct brw_surf_ss1 {
+      GLuint base_addr;  
+   } ss1;
+   
+   struct brw_surf_ss2 {
+      GLuint pad:2;
+      GLuint mip_count:4; 
+      GLuint width:13; 
+      GLuint height:13; 
+   } ss2;
+
+   struct brw_surf_ss3 {
+      GLuint tile_walk:1; 
+      GLuint tiled_surface:1; 
+      GLuint pad:1; 
+      GLuint pitch:18; 
+      GLuint depth:11; 
+   } ss3;
+   
+   struct brw_surf_ss4 {
+      GLuint multisample_position_palette_index:3;
+      GLuint pad1:1;
+      GLuint num_multisamples:3;
+      GLuint pad0:1;
+      GLuint render_target_view_extent:9;
+      GLuint min_array_elt:11;
+      GLuint min_lod:4; 
+   } ss4;
+
+   struct brw_surf_ss5 {
+      GLuint pad1:16;
+      GLuint llc_mapping:1;
+      GLuint mlc_mapping:1;
+      GLuint gfdt:1;
+      GLuint gfdt_src:1;
+      GLuint y_offset:4;
+      GLuint pad0:1;
+      GLuint x_offset:7;
+   } ss5;   /* New in G4X */
+
+};
+
+
+
+struct brw_vertex_buffer_state
+{
+   struct {
+      GLuint pitch:11; 
+      GLuint pad:15;
+      GLuint access_type:1; 
+      GLuint vb_index:5; 
+   } vb0;
+   
+   GLuint start_addr; 
+   GLuint max_index;   
+#if 1
+   GLuint instance_data_step_rate; /* not included for sequential/random vertices? */
+#endif
+};
+
+#define BRW_VBP_MAX 17
+
+struct brw_vb_array_state {
+   struct header header;
+   struct brw_vertex_buffer_state vb[BRW_VBP_MAX];
+};
+
+
+struct brw_vertex_element_state
+{
+   struct
+   {
+      GLuint src_offset:11; 
+      GLuint pad:5;
+      GLuint src_format:9; 
+      GLuint pad0:1;
+      GLuint valid:1; 
+      GLuint vertex_buffer_index:5; 
+   } ve0;
+   
+   struct
+   {
+      GLuint dst_offset:8; 
+      GLuint pad:8;
+      GLuint vfcomponent3:4; 
+      GLuint vfcomponent2:4; 
+      GLuint vfcomponent1:4; 
+      GLuint vfcomponent0:4; 
+   } ve1;
+};
+
+#define BRW_VEP_MAX 18
+
+struct brw_vertex_element_packet {
+   struct header header;
+   struct brw_vertex_element_state ve[BRW_VEP_MAX]; /* note: less than _TNL_ATTRIB_MAX */
+};
+
+
+struct brw_urb_immediate {
+   GLuint opcode:4;
+   GLuint offset:6;
+   GLuint swizzle_control:2; 
+   GLuint pad:1;
+   GLuint allocate:1;
+   GLuint used:1;
+   GLuint complete:1;
+   GLuint response_length:4;
+   GLuint msg_length:4;
+   GLuint msg_target:4;
+   GLuint pad1:3;
+   GLuint end_of_thread:1;
+};
+
+/* Instruction format for the execution units:
+ */
+ 
+struct brw_instruction
+{
+   struct 
+   {
+      GLuint opcode:7;
+      GLuint pad:1;
+      GLuint access_mode:1;
+      GLuint mask_control:1;
+      GLuint dependency_control:2;
+      GLuint compression_control:2;
+      GLuint thread_control:2;
+      GLuint predicate_control:4;
+      GLuint predicate_inverse:1;
+      GLuint execution_size:3;
+      GLuint destreg__conditionalmod:4; /* destreg - send, conditionalmod - others */
+      GLuint pad0:2;
+      GLuint debug_control:1;
+      GLuint saturate:1;
+   } header;
+
+   union {
+      struct
+      {
+	 GLuint dest_reg_file:2;
+	 GLuint dest_reg_type:3;
+	 GLuint src0_reg_file:2;
+	 GLuint src0_reg_type:3;
+	 GLuint src1_reg_file:2;
+	 GLuint src1_reg_type:3;
+	 GLuint pad:1;
+	 GLuint dest_subreg_nr:5;
+	 GLuint dest_reg_nr:8;
+	 GLuint dest_horiz_stride:2;
+	 GLuint dest_address_mode:1;
+      } da1;
+
+      struct
+      {
+	 GLuint dest_reg_file:2;
+	 GLuint dest_reg_type:3;
+	 GLuint src0_reg_file:2;
+	 GLuint src0_reg_type:3;
+	 GLuint src1_reg_file:2;        /* 0x00000c00 */
+	 GLuint src1_reg_type:3;        /* 0x00007000 */
+	 GLuint pad:1;
+	 GLint dest_indirect_offset:10;	/* offset against the deref'd address reg */
+	 GLuint dest_subreg_nr:3; /* subnr for the address reg a0.x */
+	 GLuint dest_horiz_stride:2;
+	 GLuint dest_address_mode:1;
+      } ia1;
+
+      struct
+      {
+	 GLuint dest_reg_file:2;
+	 GLuint dest_reg_type:3;
+	 GLuint src0_reg_file:2;
+	 GLuint src0_reg_type:3;
+	 GLuint src1_reg_file:2;
+	 GLuint src1_reg_type:3;
+	 GLuint pad:1;
+	 GLuint dest_writemask:4;
+	 GLuint dest_subreg_nr:1;
+	 GLuint dest_reg_nr:8;
+	 GLuint pad1:2;
+	 GLuint dest_address_mode:1;
+      } da16;
+
+      struct
+      {
+	 GLuint dest_reg_file:2;
+	 GLuint dest_reg_type:3;
+	 GLuint src0_reg_file:2;
+	 GLuint src0_reg_type:3;
+	 GLuint pad0:6;
+	 GLuint dest_writemask:4;
+	 GLint dest_indirect_offset:6;
+	 GLuint dest_subreg_nr:3;
+	 GLuint pad1:2;
+	 GLuint dest_address_mode:1;
+      } ia16;
+   } bits1;
+
+
+   union {
+      struct
+      {
+	 GLuint src0_subreg_nr:5;
+	 GLuint src0_reg_nr:8;
+	 GLuint src0_abs:1;
+	 GLuint src0_negate:1;
+	 GLuint src0_address_mode:1;
+	 GLuint src0_horiz_stride:2;
+	 GLuint src0_width:3;
+	 GLuint src0_vert_stride:4;
+	 GLuint flag_reg_nr:1;
+	 GLuint pad:6;
+      } da1;
+
+      struct
+      {
+	 GLint src0_indirect_offset:10;
+	 GLuint src0_subreg_nr:3;
+	 GLuint src0_abs:1;
+	 GLuint src0_negate:1;
+	 GLuint src0_address_mode:1;
+	 GLuint src0_horiz_stride:2;
+	 GLuint src0_width:3;
+	 GLuint src0_vert_stride:4;
+	 GLuint flag_reg_nr:1;
+	 GLuint pad:6;	
+      } ia1;
+
+      struct
+      {
+	 GLuint src0_swz_x:2;
+	 GLuint src0_swz_y:2;
+	 GLuint src0_subreg_nr:1;
+	 GLuint src0_reg_nr:8;
+	 GLuint src0_abs:1;
+	 GLuint src0_negate:1;
+	 GLuint src0_address_mode:1;
+	 GLuint src0_swz_z:2;
+	 GLuint src0_swz_w:2;
+	 GLuint pad0:1;
+	 GLuint src0_vert_stride:4;
+	 GLuint flag_reg_nr:1;
+	 GLuint pad1:6;
+      } da16;
+
+      struct
+      {
+	 GLuint src0_swz_x:2;
+	 GLuint src0_swz_y:2;
+	 GLint src0_indirect_offset:6;
+	 GLuint src0_subreg_nr:3;
+	 GLuint src0_abs:1;
+	 GLuint src0_negate:1;
+	 GLuint src0_address_mode:1;
+	 GLuint src0_swz_z:2;
+	 GLuint src0_swz_w:2;
+	 GLuint pad0:1;
+	 GLuint src0_vert_stride:4;
+	 GLuint flag_reg_nr:1;
+	 GLuint pad1:6;
+      } ia16;
+
+       struct 
+       {
+           GLuint pad:26;
+           GLuint end_of_thread:1;
+           GLuint pad1:1;
+           GLuint sfid:4;
+       } send_igdng;  /* for IGDNG only */
+
+   } bits2;
+
+   union
+   {
+      struct
+      {
+	 GLuint src1_subreg_nr:5;
+	 GLuint src1_reg_nr:8;
+	 GLuint src1_abs:1;
+	 GLuint src1_negate:1;
+	 GLuint src1_address_mode:1;
+	 GLuint src1_horiz_stride:2;
+	 GLuint src1_width:3;
+	 GLuint src1_vert_stride:4;
+	 GLuint pad0:7;
+      } da1;
+
+      struct
+      {
+	 GLuint src1_swz_x:2;
+	 GLuint src1_swz_y:2;
+	 GLuint src1_subreg_nr:1;
+	 GLuint src1_reg_nr:8;
+	 GLuint src1_abs:1;
+	 GLuint src1_negate:1;
+	 GLuint src1_address_mode:1;
+	 GLuint src1_swz_z:2;
+	 GLuint src1_swz_w:2;
+	 GLuint pad1:1;
+	 GLuint src1_vert_stride:4;
+	 GLuint pad2:7;
+      } da16;
+
+      struct
+      {
+	 GLint  src1_indirect_offset:10;
+	 GLuint src1_subreg_nr:3;
+	 GLuint src1_abs:1;
+	 GLuint src1_negate:1;
+	 GLuint src1_address_mode:1;
+	 GLuint src1_horiz_stride:2;
+	 GLuint src1_width:3;
+	 GLuint src1_vert_stride:4;
+	 GLuint flag_reg_nr:1;
+	 GLuint pad1:6;	
+      } ia1;
+
+      struct
+      {
+	 GLuint src1_swz_x:2;
+	 GLuint src1_swz_y:2;
+	 GLint  src1_indirect_offset:6;
+	 GLuint src1_subreg_nr:3;
+	 GLuint src1_abs:1;
+	 GLuint src1_negate:1;
+	 GLuint pad0:1;
+	 GLuint src1_swz_z:2;
+	 GLuint src1_swz_w:2;
+	 GLuint pad1:1;
+	 GLuint src1_vert_stride:4;
+	 GLuint flag_reg_nr:1;
+	 GLuint pad2:6;
+      } ia16;
+
+
+      struct
+      {
+	 GLint  jump_count:16;	/* note: signed */
+	 GLuint  pop_count:4;
+	 GLuint  pad0:12;
+      } if_else;
+
+      struct {
+	 GLuint function:4;
+	 GLuint int_type:1;
+	 GLuint precision:1;
+	 GLuint saturate:1;
+	 GLuint data_type:1;
+	 GLuint pad0:8;
+	 GLuint response_length:4;
+	 GLuint msg_length:4;
+	 GLuint msg_target:4;
+	 GLuint pad1:3;
+	 GLuint end_of_thread:1;
+      } math;
+
+      struct {
+	 GLuint function:4;
+	 GLuint int_type:1;
+	 GLuint precision:1;
+	 GLuint saturate:1;
+	 GLuint data_type:1;
+	 GLuint snapshot:1;
+	 GLuint pad0:10;
+	 GLuint header_present:1;
+	 GLuint response_length:5;
+	 GLuint msg_length:4;
+	 GLuint pad1:2;
+	 GLuint end_of_thread:1;
+      } math_igdng;
+
+      struct {
+	 GLuint binding_table_index:8;
+	 GLuint sampler:4;
+	 GLuint return_format:2; 
+	 GLuint msg_type:2;   
+	 GLuint response_length:4;
+	 GLuint msg_length:4;
+	 GLuint msg_target:4;
+	 GLuint pad1:3;
+	 GLuint end_of_thread:1;
+      } sampler;
+
+      struct {
+         GLuint binding_table_index:8;
+         GLuint sampler:4;
+         GLuint msg_type:4;
+         GLuint response_length:4;
+         GLuint msg_length:4;
+         GLuint msg_target:4;
+         GLuint pad1:3;
+         GLuint end_of_thread:1;
+      } sampler_g4x;
+
+      struct {
+	 GLuint binding_table_index:8;
+	 GLuint sampler:4;
+	 GLuint msg_type:4;
+	 GLuint simd_mode:2;
+	 GLuint pad0:1;
+	 GLuint header_present:1;
+	 GLuint response_length:5;
+	 GLuint msg_length:4;
+	 GLuint pad1:2;
+	 GLuint end_of_thread:1;
+      } sampler_igdng;
+
+      struct brw_urb_immediate urb;
+
+      struct {
+	 GLuint opcode:4;
+	 GLuint offset:6;
+	 GLuint swizzle_control:2; 
+	 GLuint pad:1;
+	 GLuint allocate:1;
+	 GLuint used:1;
+	 GLuint complete:1;
+	 GLuint pad0:3;
+	 GLuint header_present:1;
+	 GLuint response_length:5;
+	 GLuint msg_length:4;
+	 GLuint pad1:2;
+	 GLuint end_of_thread:1;
+      } urb_igdng;
+
+      struct {
+	 GLuint binding_table_index:8;
+	 GLuint msg_control:4;  
+	 GLuint msg_type:2;  
+	 GLuint target_cache:2;    
+	 GLuint response_length:4;
+	 GLuint msg_length:4;
+	 GLuint msg_target:4;
+	 GLuint pad1:3;
+	 GLuint end_of_thread:1;
+      } dp_read;
+
+      struct {
+	 GLuint binding_table_index:8;
+	 GLuint msg_control:3;  
+	 GLuint msg_type:3;  
+	 GLuint target_cache:2;    
+	 GLuint pad0:3;
+	 GLuint header_present:1;
+	 GLuint response_length:5;
+	 GLuint msg_length:4;
+	 GLuint pad1:2;
+	 GLuint end_of_thread:1;
+      } dp_read_igdng;
+
+      struct {
+	 GLuint binding_table_index:8;
+	 GLuint msg_control:3;
+	 GLuint pixel_scoreboard_clear:1;
+	 GLuint msg_type:3;    
+	 GLuint send_commit_msg:1;
+	 GLuint response_length:4;
+	 GLuint msg_length:4;
+	 GLuint msg_target:4;
+	 GLuint pad1:3;
+	 GLuint end_of_thread:1;
+      } dp_write;
+
+      struct {
+	 GLuint binding_table_index:8;
+	 GLuint msg_control:3;
+	 GLuint pixel_scoreboard_clear:1;
+	 GLuint msg_type:3;    
+	 GLuint send_commit_msg:1;
+	 GLuint pad0:3;
+	 GLuint header_present:1;
+	 GLuint response_length:5;
+	 GLuint msg_length:4;
+	 GLuint pad1:2;
+	 GLuint end_of_thread:1;
+      } dp_write_igdng;
+
+      struct {
+	 GLuint pad:16;
+	 GLuint response_length:4;
+	 GLuint msg_length:4;
+	 GLuint msg_target:4;
+	 GLuint pad1:3;
+	 GLuint end_of_thread:1;
+      } generic;
+
+      struct {
+	 GLuint pad:19;
+	 GLuint header_present:1;
+	 GLuint response_length:5;
+	 GLuint msg_length:4;
+	 GLuint pad1:2;
+	 GLuint end_of_thread:1;
+      } generic_igdng;
+
+      GLint d;
+      GLuint ud;
+      float f;
+   } bits3;
+};
+
+
+#endif
diff --git a/src/gallium/drivers/i965/brw_structs_dump.c b/src/gallium/drivers/i965/brw_structs_dump.c
new file mode 100644
index 0000000..cd40fc6
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_structs_dump.c
@@ -0,0 +1,1247 @@
+/**************************************************************************
+ *
+ * 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 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Dump i965 data structures.
+ *
+ * Generated automatically from brw_structs.h by brw_structs_dump.py.
+ */
+
+#include "util/u_debug.h"
+
+#include "brw_types.h"
+#include "brw_structs.h"
+#include "brw_structs_dump.h"
+
+void
+brw_dump_3d_control(const struct brw_3d_control *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.notify_enable = 0x%x\n", (*ptr).header.notify_enable);
+   debug_printf("\t\t.header.wc_flush_enable = 0x%x\n", (*ptr).header.wc_flush_enable);
+   debug_printf("\t\t.header.depth_stall_enable = 0x%x\n", (*ptr).header.depth_stall_enable);
+   debug_printf("\t\t.header.operation = 0x%x\n", (*ptr).header.operation);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.dest.dest_addr_type = 0x%x\n", (*ptr).dest.dest_addr_type);
+   debug_printf("\t\t.dest.dest_addr = 0x%x\n", (*ptr).dest.dest_addr);
+   debug_printf("\t\t.dword2 = 0x%x\n", (*ptr).dword2);
+   debug_printf("\t\t.dword3 = 0x%x\n", (*ptr).dword3);
+}
+
+void
+brw_dump_3d_primitive(const struct brw_3d_primitive *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.topology = 0x%x\n", (*ptr).header.topology);
+   debug_printf("\t\t.header.indexed = 0x%x\n", (*ptr).header.indexed);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.verts_per_instance = 0x%x\n", (*ptr).verts_per_instance);
+   debug_printf("\t\t.start_vert_location = 0x%x\n", (*ptr).start_vert_location);
+   debug_printf("\t\t.instance_count = 0x%x\n", (*ptr).instance_count);
+   debug_printf("\t\t.start_instance_location = 0x%x\n", (*ptr).start_instance_location);
+   debug_printf("\t\t.base_vert_location = 0x%x\n", (*ptr).base_vert_location);
+}
+
+void
+brw_dump_aa_line_parameters(const struct brw_aa_line_parameters *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.bits0.aa_coverage_scope = 0x%x\n", (*ptr).bits0.aa_coverage_scope);
+   debug_printf("\t\t.bits0.aa_coverage_bias = 0x%x\n", (*ptr).bits0.aa_coverage_bias);
+   debug_printf("\t\t.bits1.aa_coverage_endcap_slope = 0x%x\n", (*ptr).bits1.aa_coverage_endcap_slope);
+   debug_printf("\t\t.bits1.aa_coverage_endcap_bias = 0x%x\n", (*ptr).bits1.aa_coverage_endcap_bias);
+}
+
+void
+brw_dump_binding_table_pointers(const struct brw_binding_table_pointers *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.vs = 0x%x\n", (*ptr).vs);
+   debug_printf("\t\t.gs = 0x%x\n", (*ptr).gs);
+   debug_printf("\t\t.clp = 0x%x\n", (*ptr).clp);
+   debug_printf("\t\t.sf = 0x%x\n", (*ptr).sf);
+   debug_printf("\t\t.wm = 0x%x\n", (*ptr).wm);
+}
+
+void
+brw_dump_blend_constant_color(const struct brw_blend_constant_color *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.blend_constant_color[0] = %f\n", (*ptr).blend_constant_color[0]);
+   debug_printf("\t\t.blend_constant_color[1] = %f\n", (*ptr).blend_constant_color[1]);
+   debug_printf("\t\t.blend_constant_color[2] = %f\n", (*ptr).blend_constant_color[2]);
+   debug_printf("\t\t.blend_constant_color[3] = %f\n", (*ptr).blend_constant_color[3]);
+}
+
+void
+brw_dump_cc0(const struct brw_cc0 *ptr)
+{
+   debug_printf("\t\t.bf_stencil_pass_depth_pass_op = 0x%x\n", (*ptr).bf_stencil_pass_depth_pass_op);
+   debug_printf("\t\t.bf_stencil_pass_depth_fail_op = 0x%x\n", (*ptr).bf_stencil_pass_depth_fail_op);
+   debug_printf("\t\t.bf_stencil_fail_op = 0x%x\n", (*ptr).bf_stencil_fail_op);
+   debug_printf("\t\t.bf_stencil_func = 0x%x\n", (*ptr).bf_stencil_func);
+   debug_printf("\t\t.bf_stencil_enable = 0x%x\n", (*ptr).bf_stencil_enable);
+   debug_printf("\t\t.stencil_write_enable = 0x%x\n", (*ptr).stencil_write_enable);
+   debug_printf("\t\t.stencil_pass_depth_pass_op = 0x%x\n", (*ptr).stencil_pass_depth_pass_op);
+   debug_printf("\t\t.stencil_pass_depth_fail_op = 0x%x\n", (*ptr).stencil_pass_depth_fail_op);
+   debug_printf("\t\t.stencil_fail_op = 0x%x\n", (*ptr).stencil_fail_op);
+   debug_printf("\t\t.stencil_func = 0x%x\n", (*ptr).stencil_func);
+   debug_printf("\t\t.stencil_enable = 0x%x\n", (*ptr).stencil_enable);
+}
+
+void
+brw_dump_cc1(const struct brw_cc1 *ptr)
+{
+   debug_printf("\t\t.bf_stencil_ref = 0x%x\n", (*ptr).bf_stencil_ref);
+   debug_printf("\t\t.stencil_write_mask = 0x%x\n", (*ptr).stencil_write_mask);
+   debug_printf("\t\t.stencil_test_mask = 0x%x\n", (*ptr).stencil_test_mask);
+   debug_printf("\t\t.stencil_ref = 0x%x\n", (*ptr).stencil_ref);
+}
+
+void
+brw_dump_cc2(const struct brw_cc2 *ptr)
+{
+   debug_printf("\t\t.logicop_enable = 0x%x\n", (*ptr).logicop_enable);
+   debug_printf("\t\t.depth_write_enable = 0x%x\n", (*ptr).depth_write_enable);
+   debug_printf("\t\t.depth_test_function = 0x%x\n", (*ptr).depth_test_function);
+   debug_printf("\t\t.depth_test = 0x%x\n", (*ptr).depth_test);
+   debug_printf("\t\t.bf_stencil_write_mask = 0x%x\n", (*ptr).bf_stencil_write_mask);
+   debug_printf("\t\t.bf_stencil_test_mask = 0x%x\n", (*ptr).bf_stencil_test_mask);
+}
+
+void
+brw_dump_cc3(const struct brw_cc3 *ptr)
+{
+   debug_printf("\t\t.alpha_test_func = 0x%x\n", (*ptr).alpha_test_func);
+   debug_printf("\t\t.alpha_test = 0x%x\n", (*ptr).alpha_test);
+   debug_printf("\t\t.blend_enable = 0x%x\n", (*ptr).blend_enable);
+   debug_printf("\t\t.ia_blend_enable = 0x%x\n", (*ptr).ia_blend_enable);
+   debug_printf("\t\t.alpha_test_format = 0x%x\n", (*ptr).alpha_test_format);
+}
+
+void
+brw_dump_cc4(const struct brw_cc4 *ptr)
+{
+   debug_printf("\t\t.cc_viewport_state_offset = 0x%x\n", (*ptr).cc_viewport_state_offset);
+}
+
+void
+brw_dump_cc5(const struct brw_cc5 *ptr)
+{
+   debug_printf("\t\t.ia_dest_blend_factor = 0x%x\n", (*ptr).ia_dest_blend_factor);
+   debug_printf("\t\t.ia_src_blend_factor = 0x%x\n", (*ptr).ia_src_blend_factor);
+   debug_printf("\t\t.ia_blend_function = 0x%x\n", (*ptr).ia_blend_function);
+   debug_printf("\t\t.statistics_enable = 0x%x\n", (*ptr).statistics_enable);
+   debug_printf("\t\t.logicop_func = 0x%x\n", (*ptr).logicop_func);
+   debug_printf("\t\t.dither_enable = 0x%x\n", (*ptr).dither_enable);
+}
+
+void
+brw_dump_cc6(const struct brw_cc6 *ptr)
+{
+   debug_printf("\t\t.clamp_post_alpha_blend = 0x%x\n", (*ptr).clamp_post_alpha_blend);
+   debug_printf("\t\t.clamp_pre_alpha_blend = 0x%x\n", (*ptr).clamp_pre_alpha_blend);
+   debug_printf("\t\t.clamp_range = 0x%x\n", (*ptr).clamp_range);
+   debug_printf("\t\t.y_dither_offset = 0x%x\n", (*ptr).y_dither_offset);
+   debug_printf("\t\t.x_dither_offset = 0x%x\n", (*ptr).x_dither_offset);
+   debug_printf("\t\t.dest_blend_factor = 0x%x\n", (*ptr).dest_blend_factor);
+   debug_printf("\t\t.src_blend_factor = 0x%x\n", (*ptr).src_blend_factor);
+   debug_printf("\t\t.blend_function = 0x%x\n", (*ptr).blend_function);
+}
+
+void
+brw_dump_cc7(const struct brw_cc7 *ptr)
+{
+   debug_printf("\t\t.alpha_ref.f = %f\n", (*ptr).alpha_ref.f);
+   debug_printf("\t\t.alpha_ref.ub[0] = 0x%x\n", (*ptr).alpha_ref.ub[0]);
+   debug_printf("\t\t.alpha_ref.ub[1] = 0x%x\n", (*ptr).alpha_ref.ub[1]);
+   debug_printf("\t\t.alpha_ref.ub[2] = 0x%x\n", (*ptr).alpha_ref.ub[2]);
+   debug_printf("\t\t.alpha_ref.ub[3] = 0x%x\n", (*ptr).alpha_ref.ub[3]);
+}
+
+void
+brw_dump_cc_unit_state(const struct brw_cc_unit_state *ptr)
+{
+   debug_printf("\t\t.cc0.bf_stencil_pass_depth_pass_op = 0x%x\n", (*ptr).cc0.bf_stencil_pass_depth_pass_op);
+   debug_printf("\t\t.cc0.bf_stencil_pass_depth_fail_op = 0x%x\n", (*ptr).cc0.bf_stencil_pass_depth_fail_op);
+   debug_printf("\t\t.cc0.bf_stencil_fail_op = 0x%x\n", (*ptr).cc0.bf_stencil_fail_op);
+   debug_printf("\t\t.cc0.bf_stencil_func = 0x%x\n", (*ptr).cc0.bf_stencil_func);
+   debug_printf("\t\t.cc0.bf_stencil_enable = 0x%x\n", (*ptr).cc0.bf_stencil_enable);
+   debug_printf("\t\t.cc0.stencil_write_enable = 0x%x\n", (*ptr).cc0.stencil_write_enable);
+   debug_printf("\t\t.cc0.stencil_pass_depth_pass_op = 0x%x\n", (*ptr).cc0.stencil_pass_depth_pass_op);
+   debug_printf("\t\t.cc0.stencil_pass_depth_fail_op = 0x%x\n", (*ptr).cc0.stencil_pass_depth_fail_op);
+   debug_printf("\t\t.cc0.stencil_fail_op = 0x%x\n", (*ptr).cc0.stencil_fail_op);
+   debug_printf("\t\t.cc0.stencil_func = 0x%x\n", (*ptr).cc0.stencil_func);
+   debug_printf("\t\t.cc0.stencil_enable = 0x%x\n", (*ptr).cc0.stencil_enable);
+   debug_printf("\t\t.cc1.bf_stencil_ref = 0x%x\n", (*ptr).cc1.bf_stencil_ref);
+   debug_printf("\t\t.cc1.stencil_write_mask = 0x%x\n", (*ptr).cc1.stencil_write_mask);
+   debug_printf("\t\t.cc1.stencil_test_mask = 0x%x\n", (*ptr).cc1.stencil_test_mask);
+   debug_printf("\t\t.cc1.stencil_ref = 0x%x\n", (*ptr).cc1.stencil_ref);
+   debug_printf("\t\t.cc2.logicop_enable = 0x%x\n", (*ptr).cc2.logicop_enable);
+   debug_printf("\t\t.cc2.depth_write_enable = 0x%x\n", (*ptr).cc2.depth_write_enable);
+   debug_printf("\t\t.cc2.depth_test_function = 0x%x\n", (*ptr).cc2.depth_test_function);
+   debug_printf("\t\t.cc2.depth_test = 0x%x\n", (*ptr).cc2.depth_test);
+   debug_printf("\t\t.cc2.bf_stencil_write_mask = 0x%x\n", (*ptr).cc2.bf_stencil_write_mask);
+   debug_printf("\t\t.cc2.bf_stencil_test_mask = 0x%x\n", (*ptr).cc2.bf_stencil_test_mask);
+   debug_printf("\t\t.cc3.alpha_test_func = 0x%x\n", (*ptr).cc3.alpha_test_func);
+   debug_printf("\t\t.cc3.alpha_test = 0x%x\n", (*ptr).cc3.alpha_test);
+   debug_printf("\t\t.cc3.blend_enable = 0x%x\n", (*ptr).cc3.blend_enable);
+   debug_printf("\t\t.cc3.ia_blend_enable = 0x%x\n", (*ptr).cc3.ia_blend_enable);
+   debug_printf("\t\t.cc3.alpha_test_format = 0x%x\n", (*ptr).cc3.alpha_test_format);
+   debug_printf("\t\t.cc4.cc_viewport_state_offset = 0x%x\n", (*ptr).cc4.cc_viewport_state_offset);
+   debug_printf("\t\t.cc5.ia_dest_blend_factor = 0x%x\n", (*ptr).cc5.ia_dest_blend_factor);
+   debug_printf("\t\t.cc5.ia_src_blend_factor = 0x%x\n", (*ptr).cc5.ia_src_blend_factor);
+   debug_printf("\t\t.cc5.ia_blend_function = 0x%x\n", (*ptr).cc5.ia_blend_function);
+   debug_printf("\t\t.cc5.statistics_enable = 0x%x\n", (*ptr).cc5.statistics_enable);
+   debug_printf("\t\t.cc5.logicop_func = 0x%x\n", (*ptr).cc5.logicop_func);
+   debug_printf("\t\t.cc5.dither_enable = 0x%x\n", (*ptr).cc5.dither_enable);
+   debug_printf("\t\t.cc6.clamp_post_alpha_blend = 0x%x\n", (*ptr).cc6.clamp_post_alpha_blend);
+   debug_printf("\t\t.cc6.clamp_pre_alpha_blend = 0x%x\n", (*ptr).cc6.clamp_pre_alpha_blend);
+   debug_printf("\t\t.cc6.clamp_range = 0x%x\n", (*ptr).cc6.clamp_range);
+   debug_printf("\t\t.cc6.y_dither_offset = 0x%x\n", (*ptr).cc6.y_dither_offset);
+   debug_printf("\t\t.cc6.x_dither_offset = 0x%x\n", (*ptr).cc6.x_dither_offset);
+   debug_printf("\t\t.cc6.dest_blend_factor = 0x%x\n", (*ptr).cc6.dest_blend_factor);
+   debug_printf("\t\t.cc6.src_blend_factor = 0x%x\n", (*ptr).cc6.src_blend_factor);
+   debug_printf("\t\t.cc6.blend_function = 0x%x\n", (*ptr).cc6.blend_function);
+   debug_printf("\t\t.cc7.alpha_ref.f = %f\n", (*ptr).cc7.alpha_ref.f);
+   debug_printf("\t\t.cc7.alpha_ref.ub[0] = 0x%x\n", (*ptr).cc7.alpha_ref.ub[0]);
+   debug_printf("\t\t.cc7.alpha_ref.ub[1] = 0x%x\n", (*ptr).cc7.alpha_ref.ub[1]);
+   debug_printf("\t\t.cc7.alpha_ref.ub[2] = 0x%x\n", (*ptr).cc7.alpha_ref.ub[2]);
+   debug_printf("\t\t.cc7.alpha_ref.ub[3] = 0x%x\n", (*ptr).cc7.alpha_ref.ub[3]);
+}
+
+void
+brw_dump_cc_viewport(const struct brw_cc_viewport *ptr)
+{
+   debug_printf("\t\t.min_depth = %f\n", (*ptr).min_depth);
+   debug_printf("\t\t.max_depth = %f\n", (*ptr).max_depth);
+}
+
+void
+brw_dump_clip_unit_state(const struct brw_clip_unit_state *ptr)
+{
+   debug_printf("\t\t.thread0.grf_reg_count = 0x%x\n", (*ptr).thread0.grf_reg_count);
+   debug_printf("\t\t.thread0.kernel_start_pointer = 0x%x\n", (*ptr).thread0.kernel_start_pointer);
+   debug_printf("\t\t.thread1.sw_exception_enable = 0x%x\n", (*ptr).thread1.sw_exception_enable);
+   debug_printf("\t\t.thread1.mask_stack_exception_enable = 0x%x\n", (*ptr).thread1.mask_stack_exception_enable);
+   debug_printf("\t\t.thread1.illegal_op_exception_enable = 0x%x\n", (*ptr).thread1.illegal_op_exception_enable);
+   debug_printf("\t\t.thread1.floating_point_mode = 0x%x\n", (*ptr).thread1.floating_point_mode);
+   debug_printf("\t\t.thread1.thread_priority = 0x%x\n", (*ptr).thread1.thread_priority);
+   debug_printf("\t\t.thread1.binding_table_entry_count = 0x%x\n", (*ptr).thread1.binding_table_entry_count);
+   debug_printf("\t\t.thread1.single_program_flow = 0x%x\n", (*ptr).thread1.single_program_flow);
+   debug_printf("\t\t.thread2.per_thread_scratch_space = 0x%x\n", (*ptr).thread2.per_thread_scratch_space);
+   debug_printf("\t\t.thread2.scratch_space_base_pointer = 0x%x\n", (*ptr).thread2.scratch_space_base_pointer);
+   debug_printf("\t\t.thread3.dispatch_grf_start_reg = 0x%x\n", (*ptr).thread3.dispatch_grf_start_reg);
+   debug_printf("\t\t.thread3.urb_entry_read_offset = 0x%x\n", (*ptr).thread3.urb_entry_read_offset);
+   debug_printf("\t\t.thread3.urb_entry_read_length = 0x%x\n", (*ptr).thread3.urb_entry_read_length);
+   debug_printf("\t\t.thread3.const_urb_entry_read_offset = 0x%x\n", (*ptr).thread3.const_urb_entry_read_offset);
+   debug_printf("\t\t.thread3.const_urb_entry_read_length = 0x%x\n", (*ptr).thread3.const_urb_entry_read_length);
+   debug_printf("\t\t.thread4.gs_output_stats = 0x%x\n", (*ptr).thread4.gs_output_stats);
+   debug_printf("\t\t.thread4.stats_enable = 0x%x\n", (*ptr).thread4.stats_enable);
+   debug_printf("\t\t.thread4.nr_urb_entries = 0x%x\n", (*ptr).thread4.nr_urb_entries);
+   debug_printf("\t\t.thread4.urb_entry_allocation_size = 0x%x\n", (*ptr).thread4.urb_entry_allocation_size);
+   debug_printf("\t\t.thread4.max_threads = 0x%x\n", (*ptr).thread4.max_threads);
+   debug_printf("\t\t.clip5.clip_mode = 0x%x\n", (*ptr).clip5.clip_mode);
+   debug_printf("\t\t.clip5.userclip_enable_flags = 0x%x\n", (*ptr).clip5.userclip_enable_flags);
+   debug_printf("\t\t.clip5.userclip_must_clip = 0x%x\n", (*ptr).clip5.userclip_must_clip);
+   debug_printf("\t\t.clip5.negative_w_clip_test = 0x%x\n", (*ptr).clip5.negative_w_clip_test);
+   debug_printf("\t\t.clip5.guard_band_enable = 0x%x\n", (*ptr).clip5.guard_band_enable);
+   debug_printf("\t\t.clip5.viewport_z_clip_enable = 0x%x\n", (*ptr).clip5.viewport_z_clip_enable);
+   debug_printf("\t\t.clip5.viewport_xy_clip_enable = 0x%x\n", (*ptr).clip5.viewport_xy_clip_enable);
+   debug_printf("\t\t.clip5.vertex_position_space = 0x%x\n", (*ptr).clip5.vertex_position_space);
+   debug_printf("\t\t.clip5.api_mode = 0x%x\n", (*ptr).clip5.api_mode);
+   debug_printf("\t\t.clip6.clipper_viewport_state_ptr = 0x%x\n", (*ptr).clip6.clipper_viewport_state_ptr);
+   debug_printf("\t\t.viewport_xmin = %f\n", (*ptr).viewport_xmin);
+   debug_printf("\t\t.viewport_xmax = %f\n", (*ptr).viewport_xmax);
+   debug_printf("\t\t.viewport_ymin = %f\n", (*ptr).viewport_ymin);
+   debug_printf("\t\t.viewport_ymax = %f\n", (*ptr).viewport_ymax);
+}
+
+void
+brw_dump_clipper_viewport(const struct brw_clipper_viewport *ptr)
+{
+   debug_printf("\t\t.xmin = %f\n", (*ptr).xmin);
+   debug_printf("\t\t.xmax = %f\n", (*ptr).xmax);
+   debug_printf("\t\t.ymin = %f\n", (*ptr).ymin);
+   debug_printf("\t\t.ymax = %f\n", (*ptr).ymax);
+}
+
+void
+brw_dump_constant_buffer(const struct brw_constant_buffer *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.valid = 0x%x\n", (*ptr).header.valid);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.bits0.buffer_length = 0x%x\n", (*ptr).bits0.buffer_length);
+   debug_printf("\t\t.bits0.buffer_address = 0x%x\n", (*ptr).bits0.buffer_address);
+}
+
+void
+brw_dump_cs_urb_state(const struct brw_cs_urb_state *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.bits0.nr_urb_entries = 0x%x\n", (*ptr).bits0.nr_urb_entries);
+   debug_printf("\t\t.bits0.urb_entry_size = 0x%x\n", (*ptr).bits0.urb_entry_size);
+}
+
+void
+brw_dump_depthbuffer(const struct brw_depthbuffer *ptr)
+{
+   debug_printf("\t\t.header.bits.length = 0x%x\n", (*ptr).header.bits.length);
+   debug_printf("\t\t.header.bits.opcode = 0x%x\n", (*ptr).header.bits.opcode);
+   debug_printf("\t\t.dword1.bits.pitch = 0x%x\n", (*ptr).dword1.bits.pitch);
+   debug_printf("\t\t.dword1.bits.format = 0x%x\n", (*ptr).dword1.bits.format);
+   debug_printf("\t\t.dword1.bits.software_tiled_rendering_mode = 0x%x\n", (*ptr).dword1.bits.software_tiled_rendering_mode);
+   debug_printf("\t\t.dword1.bits.depth_offset_disable = 0x%x\n", (*ptr).dword1.bits.depth_offset_disable);
+   debug_printf("\t\t.dword1.bits.tile_walk = 0x%x\n", (*ptr).dword1.bits.tile_walk);
+   debug_printf("\t\t.dword1.bits.tiled_surface = 0x%x\n", (*ptr).dword1.bits.tiled_surface);
+   debug_printf("\t\t.dword1.bits.surface_type = 0x%x\n", (*ptr).dword1.bits.surface_type);
+   debug_printf("\t\t.dword2_base_addr = 0x%x\n", (*ptr).dword2_base_addr);
+   debug_printf("\t\t.dword3.bits.mipmap_layout = 0x%x\n", (*ptr).dword3.bits.mipmap_layout);
+   debug_printf("\t\t.dword3.bits.lod = 0x%x\n", (*ptr).dword3.bits.lod);
+   debug_printf("\t\t.dword3.bits.width = 0x%x\n", (*ptr).dword3.bits.width);
+   debug_printf("\t\t.dword3.bits.height = 0x%x\n", (*ptr).dword3.bits.height);
+   debug_printf("\t\t.dword4.bits.min_array_element = 0x%x\n", (*ptr).dword4.bits.min_array_element);
+   debug_printf("\t\t.dword4.bits.depth = 0x%x\n", (*ptr).dword4.bits.depth);
+}
+
+void
+brw_dump_depthbuffer_g4x(const struct brw_depthbuffer_g4x *ptr)
+{
+   debug_printf("\t\t.header.bits.length = 0x%x\n", (*ptr).header.bits.length);
+   debug_printf("\t\t.header.bits.opcode = 0x%x\n", (*ptr).header.bits.opcode);
+   debug_printf("\t\t.dword1.bits.pitch = 0x%x\n", (*ptr).dword1.bits.pitch);
+   debug_printf("\t\t.dword1.bits.format = 0x%x\n", (*ptr).dword1.bits.format);
+   debug_printf("\t\t.dword1.bits.software_tiled_rendering_mode = 0x%x\n", (*ptr).dword1.bits.software_tiled_rendering_mode);
+   debug_printf("\t\t.dword1.bits.depth_offset_disable = 0x%x\n", (*ptr).dword1.bits.depth_offset_disable);
+   debug_printf("\t\t.dword1.bits.tile_walk = 0x%x\n", (*ptr).dword1.bits.tile_walk);
+   debug_printf("\t\t.dword1.bits.tiled_surface = 0x%x\n", (*ptr).dword1.bits.tiled_surface);
+   debug_printf("\t\t.dword1.bits.surface_type = 0x%x\n", (*ptr).dword1.bits.surface_type);
+   debug_printf("\t\t.dword2_base_addr = 0x%x\n", (*ptr).dword2_base_addr);
+   debug_printf("\t\t.dword3.bits.mipmap_layout = 0x%x\n", (*ptr).dword3.bits.mipmap_layout);
+   debug_printf("\t\t.dword3.bits.lod = 0x%x\n", (*ptr).dword3.bits.lod);
+   debug_printf("\t\t.dword3.bits.width = 0x%x\n", (*ptr).dword3.bits.width);
+   debug_printf("\t\t.dword3.bits.height = 0x%x\n", (*ptr).dword3.bits.height);
+   debug_printf("\t\t.dword4.bits.min_array_element = 0x%x\n", (*ptr).dword4.bits.min_array_element);
+   debug_printf("\t\t.dword4.bits.depth = 0x%x\n", (*ptr).dword4.bits.depth);
+   debug_printf("\t\t.dword5.bits.xoffset = 0x%x\n", (*ptr).dword5.bits.xoffset);
+   debug_printf("\t\t.dword5.bits.yoffset = 0x%x\n", (*ptr).dword5.bits.yoffset);
+}
+
+void
+brw_dump_drawrect(const struct brw_drawrect *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.xmin = 0x%x\n", (*ptr).xmin);
+   debug_printf("\t\t.ymin = 0x%x\n", (*ptr).ymin);
+   debug_printf("\t\t.xmax = 0x%x\n", (*ptr).xmax);
+   debug_printf("\t\t.ymax = 0x%x\n", (*ptr).ymax);
+   debug_printf("\t\t.xorg = 0x%x\n", (*ptr).xorg);
+   debug_printf("\t\t.yorg = 0x%x\n", (*ptr).yorg);
+}
+
+void
+brw_dump_global_depth_offset_clamp(const struct brw_global_depth_offset_clamp *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.depth_offset_clamp = %f\n", (*ptr).depth_offset_clamp);
+}
+
+void
+brw_dump_gs_unit_state(const struct brw_gs_unit_state *ptr)
+{
+   debug_printf("\t\t.thread0.grf_reg_count = 0x%x\n", (*ptr).thread0.grf_reg_count);
+   debug_printf("\t\t.thread0.kernel_start_pointer = 0x%x\n", (*ptr).thread0.kernel_start_pointer);
+   debug_printf("\t\t.thread1.ext_halt_exception_enable = 0x%x\n", (*ptr).thread1.ext_halt_exception_enable);
+   debug_printf("\t\t.thread1.sw_exception_enable = 0x%x\n", (*ptr).thread1.sw_exception_enable);
+   debug_printf("\t\t.thread1.mask_stack_exception_enable = 0x%x\n", (*ptr).thread1.mask_stack_exception_enable);
+   debug_printf("\t\t.thread1.timeout_exception_enable = 0x%x\n", (*ptr).thread1.timeout_exception_enable);
+   debug_printf("\t\t.thread1.illegal_op_exception_enable = 0x%x\n", (*ptr).thread1.illegal_op_exception_enable);
+   debug_printf("\t\t.thread1.depth_coef_urb_read_offset = 0x%x\n", (*ptr).thread1.depth_coef_urb_read_offset);
+   debug_printf("\t\t.thread1.floating_point_mode = 0x%x\n", (*ptr).thread1.floating_point_mode);
+   debug_printf("\t\t.thread1.thread_priority = 0x%x\n", (*ptr).thread1.thread_priority);
+   debug_printf("\t\t.thread1.binding_table_entry_count = 0x%x\n", (*ptr).thread1.binding_table_entry_count);
+   debug_printf("\t\t.thread1.single_program_flow = 0x%x\n", (*ptr).thread1.single_program_flow);
+   debug_printf("\t\t.thread2.per_thread_scratch_space = 0x%x\n", (*ptr).thread2.per_thread_scratch_space);
+   debug_printf("\t\t.thread2.scratch_space_base_pointer = 0x%x\n", (*ptr).thread2.scratch_space_base_pointer);
+   debug_printf("\t\t.thread3.dispatch_grf_start_reg = 0x%x\n", (*ptr).thread3.dispatch_grf_start_reg);
+   debug_printf("\t\t.thread3.urb_entry_read_offset = 0x%x\n", (*ptr).thread3.urb_entry_read_offset);
+   debug_printf("\t\t.thread3.urb_entry_read_length = 0x%x\n", (*ptr).thread3.urb_entry_read_length);
+   debug_printf("\t\t.thread3.const_urb_entry_read_offset = 0x%x\n", (*ptr).thread3.const_urb_entry_read_offset);
+   debug_printf("\t\t.thread3.const_urb_entry_read_length = 0x%x\n", (*ptr).thread3.const_urb_entry_read_length);
+   debug_printf("\t\t.thread4.rendering_enable = 0x%x\n", (*ptr).thread4.rendering_enable);
+   debug_printf("\t\t.thread4.stats_enable = 0x%x\n", (*ptr).thread4.stats_enable);
+   debug_printf("\t\t.thread4.nr_urb_entries = 0x%x\n", (*ptr).thread4.nr_urb_entries);
+   debug_printf("\t\t.thread4.urb_entry_allocation_size = 0x%x\n", (*ptr).thread4.urb_entry_allocation_size);
+   debug_printf("\t\t.thread4.max_threads = 0x%x\n", (*ptr).thread4.max_threads);
+   debug_printf("\t\t.gs5.sampler_count = 0x%x\n", (*ptr).gs5.sampler_count);
+   debug_printf("\t\t.gs5.sampler_state_pointer = 0x%x\n", (*ptr).gs5.sampler_state_pointer);
+   debug_printf("\t\t.gs6.max_vp_index = 0x%x\n", (*ptr).gs6.max_vp_index);
+   debug_printf("\t\t.gs6.svbi_post_inc_value = 0x%x\n", (*ptr).gs6.svbi_post_inc_value);
+   debug_printf("\t\t.gs6.svbi_post_inc_enable = 0x%x\n", (*ptr).gs6.svbi_post_inc_enable);
+   debug_printf("\t\t.gs6.svbi_payload = 0x%x\n", (*ptr).gs6.svbi_payload);
+   debug_printf("\t\t.gs6.discard_adjaceny = 0x%x\n", (*ptr).gs6.discard_adjaceny);
+   debug_printf("\t\t.gs6.reorder_enable = 0x%x\n", (*ptr).gs6.reorder_enable);
+}
+
+void
+brw_dump_indexbuffer(const struct brw_indexbuffer *ptr)
+{
+   debug_printf("\t\t.header.bits.length = 0x%x\n", (*ptr).header.bits.length);
+   debug_printf("\t\t.header.bits.index_format = 0x%x\n", (*ptr).header.bits.index_format);
+   debug_printf("\t\t.header.bits.cut_index_enable = 0x%x\n", (*ptr).header.bits.cut_index_enable);
+   debug_printf("\t\t.header.bits.opcode = 0x%x\n", (*ptr).header.bits.opcode);
+   debug_printf("\t\t.buffer_start = 0x%x\n", (*ptr).buffer_start);
+   debug_printf("\t\t.buffer_end = 0x%x\n", (*ptr).buffer_end);
+}
+
+void
+brw_dump_line_stipple(const struct brw_line_stipple *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.bits0.pattern = 0x%x\n", (*ptr).bits0.pattern);
+   debug_printf("\t\t.bits1.repeat_count = 0x%x\n", (*ptr).bits1.repeat_count);
+   debug_printf("\t\t.bits1.inverse_repeat_count = 0x%x\n", (*ptr).bits1.inverse_repeat_count);
+}
+
+void
+brw_dump_mi_flush(const struct brw_mi_flush *ptr)
+{
+   debug_printf("\t\t.flags = 0x%x\n", (*ptr).flags);
+   debug_printf("\t\t.opcode = 0x%x\n", (*ptr).opcode);
+}
+
+void
+brw_dump_pipe_control(const struct brw_pipe_control *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.notify_enable = 0x%x\n", (*ptr).header.notify_enable);
+   debug_printf("\t\t.header.texture_cache_flush_enable = 0x%x\n", (*ptr).header.texture_cache_flush_enable);
+   debug_printf("\t\t.header.indirect_state_pointers_disable = 0x%x\n", (*ptr).header.indirect_state_pointers_disable);
+   debug_printf("\t\t.header.instruction_state_cache_flush_enable = 0x%x\n", (*ptr).header.instruction_state_cache_flush_enable);
+   debug_printf("\t\t.header.write_cache_flush_enable = 0x%x\n", (*ptr).header.write_cache_flush_enable);
+   debug_printf("\t\t.header.depth_stall_enable = 0x%x\n", (*ptr).header.depth_stall_enable);
+   debug_printf("\t\t.header.post_sync_operation = 0x%x\n", (*ptr).header.post_sync_operation);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.bits1.dest_addr_type = 0x%x\n", (*ptr).bits1.dest_addr_type);
+   debug_printf("\t\t.bits1.dest_addr = 0x%x\n", (*ptr).bits1.dest_addr);
+   debug_printf("\t\t.data0 = 0x%x\n", (*ptr).data0);
+   debug_printf("\t\t.data1 = 0x%x\n", (*ptr).data1);
+}
+
+void
+brw_dump_pipeline_select(const struct brw_pipeline_select *ptr)
+{
+   debug_printf("\t\t.header.pipeline_select = 0x%x\n", (*ptr).header.pipeline_select);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+}
+
+void
+brw_dump_pipelined_state_pointers(const struct brw_pipelined_state_pointers *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.vs.offset = 0x%x\n", (*ptr).vs.offset);
+   debug_printf("\t\t.gs.enable = 0x%x\n", (*ptr).gs.enable);
+   debug_printf("\t\t.gs.offset = 0x%x\n", (*ptr).gs.offset);
+   debug_printf("\t\t.clp.enable = 0x%x\n", (*ptr).clp.enable);
+   debug_printf("\t\t.clp.offset = 0x%x\n", (*ptr).clp.offset);
+   debug_printf("\t\t.sf.offset = 0x%x\n", (*ptr).sf.offset);
+   debug_printf("\t\t.wm.offset = 0x%x\n", (*ptr).wm.offset);
+   debug_printf("\t\t.cc.offset = 0x%x\n", (*ptr).cc.offset);
+}
+
+void
+brw_dump_polygon_stipple(const struct brw_polygon_stipple *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.stipple[0] = 0x%x\n", (*ptr).stipple[0]);
+   debug_printf("\t\t.stipple[1] = 0x%x\n", (*ptr).stipple[1]);
+   debug_printf("\t\t.stipple[2] = 0x%x\n", (*ptr).stipple[2]);
+   debug_printf("\t\t.stipple[3] = 0x%x\n", (*ptr).stipple[3]);
+   debug_printf("\t\t.stipple[4] = 0x%x\n", (*ptr).stipple[4]);
+   debug_printf("\t\t.stipple[5] = 0x%x\n", (*ptr).stipple[5]);
+   debug_printf("\t\t.stipple[6] = 0x%x\n", (*ptr).stipple[6]);
+   debug_printf("\t\t.stipple[7] = 0x%x\n", (*ptr).stipple[7]);
+   debug_printf("\t\t.stipple[8] = 0x%x\n", (*ptr).stipple[8]);
+   debug_printf("\t\t.stipple[9] = 0x%x\n", (*ptr).stipple[9]);
+   debug_printf("\t\t.stipple[10] = 0x%x\n", (*ptr).stipple[10]);
+   debug_printf("\t\t.stipple[11] = 0x%x\n", (*ptr).stipple[11]);
+   debug_printf("\t\t.stipple[12] = 0x%x\n", (*ptr).stipple[12]);
+   debug_printf("\t\t.stipple[13] = 0x%x\n", (*ptr).stipple[13]);
+   debug_printf("\t\t.stipple[14] = 0x%x\n", (*ptr).stipple[14]);
+   debug_printf("\t\t.stipple[15] = 0x%x\n", (*ptr).stipple[15]);
+   debug_printf("\t\t.stipple[16] = 0x%x\n", (*ptr).stipple[16]);
+   debug_printf("\t\t.stipple[17] = 0x%x\n", (*ptr).stipple[17]);
+   debug_printf("\t\t.stipple[18] = 0x%x\n", (*ptr).stipple[18]);
+   debug_printf("\t\t.stipple[19] = 0x%x\n", (*ptr).stipple[19]);
+   debug_printf("\t\t.stipple[20] = 0x%x\n", (*ptr).stipple[20]);
+   debug_printf("\t\t.stipple[21] = 0x%x\n", (*ptr).stipple[21]);
+   debug_printf("\t\t.stipple[22] = 0x%x\n", (*ptr).stipple[22]);
+   debug_printf("\t\t.stipple[23] = 0x%x\n", (*ptr).stipple[23]);
+   debug_printf("\t\t.stipple[24] = 0x%x\n", (*ptr).stipple[24]);
+   debug_printf("\t\t.stipple[25] = 0x%x\n", (*ptr).stipple[25]);
+   debug_printf("\t\t.stipple[26] = 0x%x\n", (*ptr).stipple[26]);
+   debug_printf("\t\t.stipple[27] = 0x%x\n", (*ptr).stipple[27]);
+   debug_printf("\t\t.stipple[28] = 0x%x\n", (*ptr).stipple[28]);
+   debug_printf("\t\t.stipple[29] = 0x%x\n", (*ptr).stipple[29]);
+   debug_printf("\t\t.stipple[30] = 0x%x\n", (*ptr).stipple[30]);
+   debug_printf("\t\t.stipple[31] = 0x%x\n", (*ptr).stipple[31]);
+}
+
+void
+brw_dump_polygon_stipple_offset(const struct brw_polygon_stipple_offset *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.bits0.y_offset = 0x%x\n", (*ptr).bits0.y_offset);
+   debug_printf("\t\t.bits0.x_offset = 0x%x\n", (*ptr).bits0.x_offset);
+}
+
+void
+brw_dump_sampler_default_color(const struct brw_sampler_default_color *ptr)
+{
+   debug_printf("\t\t.color[0] = %f\n", (*ptr).color[0]);
+   debug_printf("\t\t.color[1] = %f\n", (*ptr).color[1]);
+   debug_printf("\t\t.color[2] = %f\n", (*ptr).color[2]);
+   debug_printf("\t\t.color[3] = %f\n", (*ptr).color[3]);
+}
+
+void
+brw_dump_sampler_state(const struct brw_sampler_state *ptr)
+{
+   debug_printf("\t\t.ss0.shadow_function = 0x%x\n", (*ptr).ss0.shadow_function);
+   debug_printf("\t\t.ss0.lod_bias = 0x%x\n", (*ptr).ss0.lod_bias);
+   debug_printf("\t\t.ss0.min_filter = 0x%x\n", (*ptr).ss0.min_filter);
+   debug_printf("\t\t.ss0.mag_filter = 0x%x\n", (*ptr).ss0.mag_filter);
+   debug_printf("\t\t.ss0.mip_filter = 0x%x\n", (*ptr).ss0.mip_filter);
+   debug_printf("\t\t.ss0.base_level = 0x%x\n", (*ptr).ss0.base_level);
+   debug_printf("\t\t.ss0.lod_preclamp = 0x%x\n", (*ptr).ss0.lod_preclamp);
+   debug_printf("\t\t.ss0.default_color_mode = 0x%x\n", (*ptr).ss0.default_color_mode);
+   debug_printf("\t\t.ss0.disable = 0x%x\n", (*ptr).ss0.disable);
+   debug_printf("\t\t.ss1.r_wrap_mode = 0x%x\n", (*ptr).ss1.r_wrap_mode);
+   debug_printf("\t\t.ss1.t_wrap_mode = 0x%x\n", (*ptr).ss1.t_wrap_mode);
+   debug_printf("\t\t.ss1.s_wrap_mode = 0x%x\n", (*ptr).ss1.s_wrap_mode);
+   debug_printf("\t\t.ss1.max_lod = 0x%x\n", (*ptr).ss1.max_lod);
+   debug_printf("\t\t.ss1.min_lod = 0x%x\n", (*ptr).ss1.min_lod);
+   debug_printf("\t\t.ss2.default_color_pointer = 0x%x\n", (*ptr).ss2.default_color_pointer);
+   debug_printf("\t\t.ss3.max_aniso = 0x%x\n", (*ptr).ss3.max_aniso);
+   debug_printf("\t\t.ss3.chroma_key_mode = 0x%x\n", (*ptr).ss3.chroma_key_mode);
+   debug_printf("\t\t.ss3.chroma_key_index = 0x%x\n", (*ptr).ss3.chroma_key_index);
+   debug_printf("\t\t.ss3.chroma_key_enable = 0x%x\n", (*ptr).ss3.chroma_key_enable);
+   debug_printf("\t\t.ss3.monochrome_filter_width = 0x%x\n", (*ptr).ss3.monochrome_filter_width);
+   debug_printf("\t\t.ss3.monochrome_filter_height = 0x%x\n", (*ptr).ss3.monochrome_filter_height);
+}
+
+void
+brw_dump_sf_unit_state(const struct brw_sf_unit_state *ptr)
+{
+   debug_printf("\t\t.thread0.grf_reg_count = 0x%x\n", (*ptr).thread0.grf_reg_count);
+   debug_printf("\t\t.thread0.kernel_start_pointer = 0x%x\n", (*ptr).thread0.kernel_start_pointer);
+   debug_printf("\t\t.thread1.ext_halt_exception_enable = 0x%x\n", (*ptr).thread1.ext_halt_exception_enable);
+   debug_printf("\t\t.thread1.sw_exception_enable = 0x%x\n", (*ptr).thread1.sw_exception_enable);
+   debug_printf("\t\t.thread1.mask_stack_exception_enable = 0x%x\n", (*ptr).thread1.mask_stack_exception_enable);
+   debug_printf("\t\t.thread1.timeout_exception_enable = 0x%x\n", (*ptr).thread1.timeout_exception_enable);
+   debug_printf("\t\t.thread1.illegal_op_exception_enable = 0x%x\n", (*ptr).thread1.illegal_op_exception_enable);
+   debug_printf("\t\t.thread1.depth_coef_urb_read_offset = 0x%x\n", (*ptr).thread1.depth_coef_urb_read_offset);
+   debug_printf("\t\t.thread1.floating_point_mode = 0x%x\n", (*ptr).thread1.floating_point_mode);
+   debug_printf("\t\t.thread1.thread_priority = 0x%x\n", (*ptr).thread1.thread_priority);
+   debug_printf("\t\t.thread1.binding_table_entry_count = 0x%x\n", (*ptr).thread1.binding_table_entry_count);
+   debug_printf("\t\t.thread1.single_program_flow = 0x%x\n", (*ptr).thread1.single_program_flow);
+   debug_printf("\t\t.thread2.per_thread_scratch_space = 0x%x\n", (*ptr).thread2.per_thread_scratch_space);
+   debug_printf("\t\t.thread2.scratch_space_base_pointer = 0x%x\n", (*ptr).thread2.scratch_space_base_pointer);
+   debug_printf("\t\t.thread3.dispatch_grf_start_reg = 0x%x\n", (*ptr).thread3.dispatch_grf_start_reg);
+   debug_printf("\t\t.thread3.urb_entry_read_offset = 0x%x\n", (*ptr).thread3.urb_entry_read_offset);
+   debug_printf("\t\t.thread3.urb_entry_read_length = 0x%x\n", (*ptr).thread3.urb_entry_read_length);
+   debug_printf("\t\t.thread3.const_urb_entry_read_offset = 0x%x\n", (*ptr).thread3.const_urb_entry_read_offset);
+   debug_printf("\t\t.thread3.const_urb_entry_read_length = 0x%x\n", (*ptr).thread3.const_urb_entry_read_length);
+   debug_printf("\t\t.thread4.stats_enable = 0x%x\n", (*ptr).thread4.stats_enable);
+   debug_printf("\t\t.thread4.nr_urb_entries = 0x%x\n", (*ptr).thread4.nr_urb_entries);
+   debug_printf("\t\t.thread4.urb_entry_allocation_size = 0x%x\n", (*ptr).thread4.urb_entry_allocation_size);
+   debug_printf("\t\t.thread4.max_threads = 0x%x\n", (*ptr).thread4.max_threads);
+   debug_printf("\t\t.sf5.front_winding = 0x%x\n", (*ptr).sf5.front_winding);
+   debug_printf("\t\t.sf5.viewport_transform = 0x%x\n", (*ptr).sf5.viewport_transform);
+   debug_printf("\t\t.sf5.sf_viewport_state_offset = 0x%x\n", (*ptr).sf5.sf_viewport_state_offset);
+   debug_printf("\t\t.sf6.dest_org_vbias = 0x%x\n", (*ptr).sf6.dest_org_vbias);
+   debug_printf("\t\t.sf6.dest_org_hbias = 0x%x\n", (*ptr).sf6.dest_org_hbias);
+   debug_printf("\t\t.sf6.scissor = 0x%x\n", (*ptr).sf6.scissor);
+   debug_printf("\t\t.sf6.disable_2x2_trifilter = 0x%x\n", (*ptr).sf6.disable_2x2_trifilter);
+   debug_printf("\t\t.sf6.disable_zero_pix_trifilter = 0x%x\n", (*ptr).sf6.disable_zero_pix_trifilter);
+   debug_printf("\t\t.sf6.point_rast_rule = 0x%x\n", (*ptr).sf6.point_rast_rule);
+   debug_printf("\t\t.sf6.line_endcap_aa_region_width = 0x%x\n", (*ptr).sf6.line_endcap_aa_region_width);
+   debug_printf("\t\t.sf6.line_width = 0x%x\n", (*ptr).sf6.line_width);
+   debug_printf("\t\t.sf6.fast_scissor_disable = 0x%x\n", (*ptr).sf6.fast_scissor_disable);
+   debug_printf("\t\t.sf6.cull_mode = 0x%x\n", (*ptr).sf6.cull_mode);
+   debug_printf("\t\t.sf6.aa_enable = 0x%x\n", (*ptr).sf6.aa_enable);
+   debug_printf("\t\t.sf7.point_size = 0x%x\n", (*ptr).sf7.point_size);
+   debug_printf("\t\t.sf7.use_point_size_state = 0x%x\n", (*ptr).sf7.use_point_size_state);
+   debug_printf("\t\t.sf7.subpixel_precision = 0x%x\n", (*ptr).sf7.subpixel_precision);
+   debug_printf("\t\t.sf7.sprite_point = 0x%x\n", (*ptr).sf7.sprite_point);
+   debug_printf("\t\t.sf7.aa_line_distance_mode = 0x%x\n", (*ptr).sf7.aa_line_distance_mode);
+   debug_printf("\t\t.sf7.trifan_pv = 0x%x\n", (*ptr).sf7.trifan_pv);
+   debug_printf("\t\t.sf7.linestrip_pv = 0x%x\n", (*ptr).sf7.linestrip_pv);
+   debug_printf("\t\t.sf7.tristrip_pv = 0x%x\n", (*ptr).sf7.tristrip_pv);
+   debug_printf("\t\t.sf7.line_last_pixel_enable = 0x%x\n", (*ptr).sf7.line_last_pixel_enable);
+}
+
+void
+brw_dump_sf_viewport(const struct brw_sf_viewport *ptr)
+{
+   debug_printf("\t\t.viewport.m00 = %f\n", (*ptr).viewport.m00);
+   debug_printf("\t\t.viewport.m11 = %f\n", (*ptr).viewport.m11);
+   debug_printf("\t\t.viewport.m22 = %f\n", (*ptr).viewport.m22);
+   debug_printf("\t\t.viewport.m30 = %f\n", (*ptr).viewport.m30);
+   debug_printf("\t\t.viewport.m31 = %f\n", (*ptr).viewport.m31);
+   debug_printf("\t\t.viewport.m32 = %f\n", (*ptr).viewport.m32);
+   debug_printf("\t\t.scissor.xmin = 0x%x\n", (*ptr).scissor.xmin);
+   debug_printf("\t\t.scissor.ymin = 0x%x\n", (*ptr).scissor.ymin);
+   debug_printf("\t\t.scissor.xmax = 0x%x\n", (*ptr).scissor.xmax);
+   debug_printf("\t\t.scissor.ymax = 0x%x\n", (*ptr).scissor.ymax);
+}
+
+void
+brw_dump_ss0(const struct brw_ss0 *ptr)
+{
+   debug_printf("\t\t.shadow_function = 0x%x\n", (*ptr).shadow_function);
+   debug_printf("\t\t.lod_bias = 0x%x\n", (*ptr).lod_bias);
+   debug_printf("\t\t.min_filter = 0x%x\n", (*ptr).min_filter);
+   debug_printf("\t\t.mag_filter = 0x%x\n", (*ptr).mag_filter);
+   debug_printf("\t\t.mip_filter = 0x%x\n", (*ptr).mip_filter);
+   debug_printf("\t\t.base_level = 0x%x\n", (*ptr).base_level);
+   debug_printf("\t\t.lod_preclamp = 0x%x\n", (*ptr).lod_preclamp);
+   debug_printf("\t\t.default_color_mode = 0x%x\n", (*ptr).default_color_mode);
+   debug_printf("\t\t.disable = 0x%x\n", (*ptr).disable);
+}
+
+void
+brw_dump_ss1(const struct brw_ss1 *ptr)
+{
+   debug_printf("\t\t.r_wrap_mode = 0x%x\n", (*ptr).r_wrap_mode);
+   debug_printf("\t\t.t_wrap_mode = 0x%x\n", (*ptr).t_wrap_mode);
+   debug_printf("\t\t.s_wrap_mode = 0x%x\n", (*ptr).s_wrap_mode);
+   debug_printf("\t\t.max_lod = 0x%x\n", (*ptr).max_lod);
+   debug_printf("\t\t.min_lod = 0x%x\n", (*ptr).min_lod);
+}
+
+void
+brw_dump_ss2(const struct brw_ss2 *ptr)
+{
+   debug_printf("\t\t.default_color_pointer = 0x%x\n", (*ptr).default_color_pointer);
+}
+
+void
+brw_dump_ss3(const struct brw_ss3 *ptr)
+{
+   debug_printf("\t\t.max_aniso = 0x%x\n", (*ptr).max_aniso);
+   debug_printf("\t\t.chroma_key_mode = 0x%x\n", (*ptr).chroma_key_mode);
+   debug_printf("\t\t.chroma_key_index = 0x%x\n", (*ptr).chroma_key_index);
+   debug_printf("\t\t.chroma_key_enable = 0x%x\n", (*ptr).chroma_key_enable);
+   debug_printf("\t\t.monochrome_filter_width = 0x%x\n", (*ptr).monochrome_filter_width);
+   debug_printf("\t\t.monochrome_filter_height = 0x%x\n", (*ptr).monochrome_filter_height);
+}
+
+void
+brw_dump_state_base_address(const struct brw_state_base_address *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.bits0.modify_enable = 0x%x\n", (*ptr).bits0.modify_enable);
+   debug_printf("\t\t.bits0.general_state_address = 0x%x\n", (*ptr).bits0.general_state_address);
+   debug_printf("\t\t.bits1.modify_enable = 0x%x\n", (*ptr).bits1.modify_enable);
+   debug_printf("\t\t.bits1.surface_state_address = 0x%x\n", (*ptr).bits1.surface_state_address);
+   debug_printf("\t\t.bits2.modify_enable = 0x%x\n", (*ptr).bits2.modify_enable);
+   debug_printf("\t\t.bits2.indirect_object_state_address = 0x%x\n", (*ptr).bits2.indirect_object_state_address);
+   debug_printf("\t\t.bits3.modify_enable = 0x%x\n", (*ptr).bits3.modify_enable);
+   debug_printf("\t\t.bits3.general_state_upper_bound = 0x%x\n", (*ptr).bits3.general_state_upper_bound);
+   debug_printf("\t\t.bits4.modify_enable = 0x%x\n", (*ptr).bits4.modify_enable);
+   debug_printf("\t\t.bits4.indirect_object_state_upper_bound = 0x%x\n", (*ptr).bits4.indirect_object_state_upper_bound);
+}
+
+void
+brw_dump_state_prefetch(const struct brw_state_prefetch *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.bits0.prefetch_count = 0x%x\n", (*ptr).bits0.prefetch_count);
+   debug_printf("\t\t.bits0.prefetch_pointer = 0x%x\n", (*ptr).bits0.prefetch_pointer);
+}
+
+void
+brw_dump_surf_ss0(const struct brw_surf_ss0 *ptr)
+{
+   debug_printf("\t\t.cube_pos_z = 0x%x\n", (*ptr).cube_pos_z);
+   debug_printf("\t\t.cube_neg_z = 0x%x\n", (*ptr).cube_neg_z);
+   debug_printf("\t\t.cube_pos_y = 0x%x\n", (*ptr).cube_pos_y);
+   debug_printf("\t\t.cube_neg_y = 0x%x\n", (*ptr).cube_neg_y);
+   debug_printf("\t\t.cube_pos_x = 0x%x\n", (*ptr).cube_pos_x);
+   debug_printf("\t\t.cube_neg_x = 0x%x\n", (*ptr).cube_neg_x);
+   debug_printf("\t\t.mipmap_layout_mode = 0x%x\n", (*ptr).mipmap_layout_mode);
+   debug_printf("\t\t.vert_line_stride_ofs = 0x%x\n", (*ptr).vert_line_stride_ofs);
+   debug_printf("\t\t.vert_line_stride = 0x%x\n", (*ptr).vert_line_stride);
+   debug_printf("\t\t.color_blend = 0x%x\n", (*ptr).color_blend);
+   debug_printf("\t\t.writedisable_blue = 0x%x\n", (*ptr).writedisable_blue);
+   debug_printf("\t\t.writedisable_green = 0x%x\n", (*ptr).writedisable_green);
+   debug_printf("\t\t.writedisable_red = 0x%x\n", (*ptr).writedisable_red);
+   debug_printf("\t\t.writedisable_alpha = 0x%x\n", (*ptr).writedisable_alpha);
+   debug_printf("\t\t.surface_format = 0x%x\n", (*ptr).surface_format);
+   debug_printf("\t\t.data_return_format = 0x%x\n", (*ptr).data_return_format);
+   debug_printf("\t\t.surface_type = 0x%x\n", (*ptr).surface_type);
+}
+
+void
+brw_dump_surf_ss1(const struct brw_surf_ss1 *ptr)
+{
+   debug_printf("\t\t.base_addr = 0x%x\n", (*ptr).base_addr);
+}
+
+void
+brw_dump_surf_ss2(const struct brw_surf_ss2 *ptr)
+{
+   debug_printf("\t\t.mip_count = 0x%x\n", (*ptr).mip_count);
+   debug_printf("\t\t.width = 0x%x\n", (*ptr).width);
+   debug_printf("\t\t.height = 0x%x\n", (*ptr).height);
+}
+
+void
+brw_dump_surf_ss3(const struct brw_surf_ss3 *ptr)
+{
+   debug_printf("\t\t.tile_walk = 0x%x\n", (*ptr).tile_walk);
+   debug_printf("\t\t.tiled_surface = 0x%x\n", (*ptr).tiled_surface);
+   debug_printf("\t\t.pitch = 0x%x\n", (*ptr).pitch);
+   debug_printf("\t\t.depth = 0x%x\n", (*ptr).depth);
+}
+
+void
+brw_dump_surf_ss4(const struct brw_surf_ss4 *ptr)
+{
+   debug_printf("\t\t.multisample_position_palette_index = 0x%x\n", (*ptr).multisample_position_palette_index);
+   debug_printf("\t\t.num_multisamples = 0x%x\n", (*ptr).num_multisamples);
+   debug_printf("\t\t.render_target_view_extent = 0x%x\n", (*ptr).render_target_view_extent);
+   debug_printf("\t\t.min_array_elt = 0x%x\n", (*ptr).min_array_elt);
+   debug_printf("\t\t.min_lod = 0x%x\n", (*ptr).min_lod);
+}
+
+void
+brw_dump_surf_ss5(const struct brw_surf_ss5 *ptr)
+{
+   debug_printf("\t\t.llc_mapping = 0x%x\n", (*ptr).llc_mapping);
+   debug_printf("\t\t.mlc_mapping = 0x%x\n", (*ptr).mlc_mapping);
+   debug_printf("\t\t.gfdt = 0x%x\n", (*ptr).gfdt);
+   debug_printf("\t\t.gfdt_src = 0x%x\n", (*ptr).gfdt_src);
+   debug_printf("\t\t.y_offset = 0x%x\n", (*ptr).y_offset);
+   debug_printf("\t\t.x_offset = 0x%x\n", (*ptr).x_offset);
+}
+
+void
+brw_dump_surface_state(const struct brw_surface_state *ptr)
+{
+   debug_printf("\t\t.ss0.cube_pos_z = 0x%x\n", (*ptr).ss0.cube_pos_z);
+   debug_printf("\t\t.ss0.cube_neg_z = 0x%x\n", (*ptr).ss0.cube_neg_z);
+   debug_printf("\t\t.ss0.cube_pos_y = 0x%x\n", (*ptr).ss0.cube_pos_y);
+   debug_printf("\t\t.ss0.cube_neg_y = 0x%x\n", (*ptr).ss0.cube_neg_y);
+   debug_printf("\t\t.ss0.cube_pos_x = 0x%x\n", (*ptr).ss0.cube_pos_x);
+   debug_printf("\t\t.ss0.cube_neg_x = 0x%x\n", (*ptr).ss0.cube_neg_x);
+   debug_printf("\t\t.ss0.mipmap_layout_mode = 0x%x\n", (*ptr).ss0.mipmap_layout_mode);
+   debug_printf("\t\t.ss0.vert_line_stride_ofs = 0x%x\n", (*ptr).ss0.vert_line_stride_ofs);
+   debug_printf("\t\t.ss0.vert_line_stride = 0x%x\n", (*ptr).ss0.vert_line_stride);
+   debug_printf("\t\t.ss0.color_blend = 0x%x\n", (*ptr).ss0.color_blend);
+   debug_printf("\t\t.ss0.writedisable_blue = 0x%x\n", (*ptr).ss0.writedisable_blue);
+   debug_printf("\t\t.ss0.writedisable_green = 0x%x\n", (*ptr).ss0.writedisable_green);
+   debug_printf("\t\t.ss0.writedisable_red = 0x%x\n", (*ptr).ss0.writedisable_red);
+   debug_printf("\t\t.ss0.writedisable_alpha = 0x%x\n", (*ptr).ss0.writedisable_alpha);
+   debug_printf("\t\t.ss0.surface_format = 0x%x\n", (*ptr).ss0.surface_format);
+   debug_printf("\t\t.ss0.data_return_format = 0x%x\n", (*ptr).ss0.data_return_format);
+   debug_printf("\t\t.ss0.surface_type = 0x%x\n", (*ptr).ss0.surface_type);
+   debug_printf("\t\t.ss1.base_addr = 0x%x\n", (*ptr).ss1.base_addr);
+   debug_printf("\t\t.ss2.mip_count = 0x%x\n", (*ptr).ss2.mip_count);
+   debug_printf("\t\t.ss2.width = 0x%x\n", (*ptr).ss2.width);
+   debug_printf("\t\t.ss2.height = 0x%x\n", (*ptr).ss2.height);
+   debug_printf("\t\t.ss3.tile_walk = 0x%x\n", (*ptr).ss3.tile_walk);
+   debug_printf("\t\t.ss3.tiled_surface = 0x%x\n", (*ptr).ss3.tiled_surface);
+   debug_printf("\t\t.ss3.pitch = 0x%x\n", (*ptr).ss3.pitch);
+   debug_printf("\t\t.ss3.depth = 0x%x\n", (*ptr).ss3.depth);
+   debug_printf("\t\t.ss4.multisample_position_palette_index = 0x%x\n", (*ptr).ss4.multisample_position_palette_index);
+   debug_printf("\t\t.ss4.num_multisamples = 0x%x\n", (*ptr).ss4.num_multisamples);
+   debug_printf("\t\t.ss4.render_target_view_extent = 0x%x\n", (*ptr).ss4.render_target_view_extent);
+   debug_printf("\t\t.ss4.min_array_elt = 0x%x\n", (*ptr).ss4.min_array_elt);
+   debug_printf("\t\t.ss4.min_lod = 0x%x\n", (*ptr).ss4.min_lod);
+   debug_printf("\t\t.ss5.llc_mapping = 0x%x\n", (*ptr).ss5.llc_mapping);
+   debug_printf("\t\t.ss5.mlc_mapping = 0x%x\n", (*ptr).ss5.mlc_mapping);
+   debug_printf("\t\t.ss5.gfdt = 0x%x\n", (*ptr).ss5.gfdt);
+   debug_printf("\t\t.ss5.gfdt_src = 0x%x\n", (*ptr).ss5.gfdt_src);
+   debug_printf("\t\t.ss5.y_offset = 0x%x\n", (*ptr).ss5.y_offset);
+   debug_printf("\t\t.ss5.x_offset = 0x%x\n", (*ptr).ss5.x_offset);
+}
+
+void
+brw_dump_system_instruction_pointer(const struct brw_system_instruction_pointer *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.bits0.system_instruction_pointer = 0x%x\n", (*ptr).bits0.system_instruction_pointer);
+}
+
+void
+brw_dump_urb_fence(const struct brw_urb_fence *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.vs_realloc = 0x%x\n", (*ptr).header.vs_realloc);
+   debug_printf("\t\t.header.gs_realloc = 0x%x\n", (*ptr).header.gs_realloc);
+   debug_printf("\t\t.header.clp_realloc = 0x%x\n", (*ptr).header.clp_realloc);
+   debug_printf("\t\t.header.sf_realloc = 0x%x\n", (*ptr).header.sf_realloc);
+   debug_printf("\t\t.header.vfe_realloc = 0x%x\n", (*ptr).header.vfe_realloc);
+   debug_printf("\t\t.header.cs_realloc = 0x%x\n", (*ptr).header.cs_realloc);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.bits0.vs_fence = 0x%x\n", (*ptr).bits0.vs_fence);
+   debug_printf("\t\t.bits0.gs_fence = 0x%x\n", (*ptr).bits0.gs_fence);
+   debug_printf("\t\t.bits0.clp_fence = 0x%x\n", (*ptr).bits0.clp_fence);
+   debug_printf("\t\t.bits1.sf_fence = 0x%x\n", (*ptr).bits1.sf_fence);
+   debug_printf("\t\t.bits1.vf_fence = 0x%x\n", (*ptr).bits1.vf_fence);
+   debug_printf("\t\t.bits1.cs_fence = 0x%x\n", (*ptr).bits1.cs_fence);
+}
+
+void
+brw_dump_urb_immediate(const struct brw_urb_immediate *ptr)
+{
+   debug_printf("\t\t.opcode = 0x%x\n", (*ptr).opcode);
+   debug_printf("\t\t.offset = 0x%x\n", (*ptr).offset);
+   debug_printf("\t\t.swizzle_control = 0x%x\n", (*ptr).swizzle_control);
+   debug_printf("\t\t.allocate = 0x%x\n", (*ptr).allocate);
+   debug_printf("\t\t.used = 0x%x\n", (*ptr).used);
+   debug_printf("\t\t.complete = 0x%x\n", (*ptr).complete);
+   debug_printf("\t\t.response_length = 0x%x\n", (*ptr).response_length);
+   debug_printf("\t\t.msg_length = 0x%x\n", (*ptr).msg_length);
+   debug_printf("\t\t.msg_target = 0x%x\n", (*ptr).msg_target);
+   debug_printf("\t\t.end_of_thread = 0x%x\n", (*ptr).end_of_thread);
+}
+
+void
+brw_dump_vb_array_state(const struct brw_vb_array_state *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.vb[0].vb0.pitch = 0x%x\n", (*ptr).vb[0].vb0.pitch);
+   debug_printf("\t\t.vb[0].vb0.access_type = 0x%x\n", (*ptr).vb[0].vb0.access_type);
+   debug_printf("\t\t.vb[0].vb0.vb_index = 0x%x\n", (*ptr).vb[0].vb0.vb_index);
+   debug_printf("\t\t.vb[0].start_addr = 0x%x\n", (*ptr).vb[0].start_addr);
+   debug_printf("\t\t.vb[0].max_index = 0x%x\n", (*ptr).vb[0].max_index);
+   debug_printf("\t\t.vb[0].instance_data_step_rate = 0x%x\n", (*ptr).vb[0].instance_data_step_rate);
+   debug_printf("\t\t.vb[1].vb0.pitch = 0x%x\n", (*ptr).vb[1].vb0.pitch);
+   debug_printf("\t\t.vb[1].vb0.access_type = 0x%x\n", (*ptr).vb[1].vb0.access_type);
+   debug_printf("\t\t.vb[1].vb0.vb_index = 0x%x\n", (*ptr).vb[1].vb0.vb_index);
+   debug_printf("\t\t.vb[1].start_addr = 0x%x\n", (*ptr).vb[1].start_addr);
+   debug_printf("\t\t.vb[1].max_index = 0x%x\n", (*ptr).vb[1].max_index);
+   debug_printf("\t\t.vb[1].instance_data_step_rate = 0x%x\n", (*ptr).vb[1].instance_data_step_rate);
+   debug_printf("\t\t.vb[2].vb0.pitch = 0x%x\n", (*ptr).vb[2].vb0.pitch);
+   debug_printf("\t\t.vb[2].vb0.access_type = 0x%x\n", (*ptr).vb[2].vb0.access_type);
+   debug_printf("\t\t.vb[2].vb0.vb_index = 0x%x\n", (*ptr).vb[2].vb0.vb_index);
+   debug_printf("\t\t.vb[2].start_addr = 0x%x\n", (*ptr).vb[2].start_addr);
+   debug_printf("\t\t.vb[2].max_index = 0x%x\n", (*ptr).vb[2].max_index);
+   debug_printf("\t\t.vb[2].instance_data_step_rate = 0x%x\n", (*ptr).vb[2].instance_data_step_rate);
+   debug_printf("\t\t.vb[3].vb0.pitch = 0x%x\n", (*ptr).vb[3].vb0.pitch);
+   debug_printf("\t\t.vb[3].vb0.access_type = 0x%x\n", (*ptr).vb[3].vb0.access_type);
+   debug_printf("\t\t.vb[3].vb0.vb_index = 0x%x\n", (*ptr).vb[3].vb0.vb_index);
+   debug_printf("\t\t.vb[3].start_addr = 0x%x\n", (*ptr).vb[3].start_addr);
+   debug_printf("\t\t.vb[3].max_index = 0x%x\n", (*ptr).vb[3].max_index);
+   debug_printf("\t\t.vb[3].instance_data_step_rate = 0x%x\n", (*ptr).vb[3].instance_data_step_rate);
+   debug_printf("\t\t.vb[4].vb0.pitch = 0x%x\n", (*ptr).vb[4].vb0.pitch);
+   debug_printf("\t\t.vb[4].vb0.access_type = 0x%x\n", (*ptr).vb[4].vb0.access_type);
+   debug_printf("\t\t.vb[4].vb0.vb_index = 0x%x\n", (*ptr).vb[4].vb0.vb_index);
+   debug_printf("\t\t.vb[4].start_addr = 0x%x\n", (*ptr).vb[4].start_addr);
+   debug_printf("\t\t.vb[4].max_index = 0x%x\n", (*ptr).vb[4].max_index);
+   debug_printf("\t\t.vb[4].instance_data_step_rate = 0x%x\n", (*ptr).vb[4].instance_data_step_rate);
+   debug_printf("\t\t.vb[5].vb0.pitch = 0x%x\n", (*ptr).vb[5].vb0.pitch);
+   debug_printf("\t\t.vb[5].vb0.access_type = 0x%x\n", (*ptr).vb[5].vb0.access_type);
+   debug_printf("\t\t.vb[5].vb0.vb_index = 0x%x\n", (*ptr).vb[5].vb0.vb_index);
+   debug_printf("\t\t.vb[5].start_addr = 0x%x\n", (*ptr).vb[5].start_addr);
+   debug_printf("\t\t.vb[5].max_index = 0x%x\n", (*ptr).vb[5].max_index);
+   debug_printf("\t\t.vb[5].instance_data_step_rate = 0x%x\n", (*ptr).vb[5].instance_data_step_rate);
+   debug_printf("\t\t.vb[6].vb0.pitch = 0x%x\n", (*ptr).vb[6].vb0.pitch);
+   debug_printf("\t\t.vb[6].vb0.access_type = 0x%x\n", (*ptr).vb[6].vb0.access_type);
+   debug_printf("\t\t.vb[6].vb0.vb_index = 0x%x\n", (*ptr).vb[6].vb0.vb_index);
+   debug_printf("\t\t.vb[6].start_addr = 0x%x\n", (*ptr).vb[6].start_addr);
+   debug_printf("\t\t.vb[6].max_index = 0x%x\n", (*ptr).vb[6].max_index);
+   debug_printf("\t\t.vb[6].instance_data_step_rate = 0x%x\n", (*ptr).vb[6].instance_data_step_rate);
+   debug_printf("\t\t.vb[7].vb0.pitch = 0x%x\n", (*ptr).vb[7].vb0.pitch);
+   debug_printf("\t\t.vb[7].vb0.access_type = 0x%x\n", (*ptr).vb[7].vb0.access_type);
+   debug_printf("\t\t.vb[7].vb0.vb_index = 0x%x\n", (*ptr).vb[7].vb0.vb_index);
+   debug_printf("\t\t.vb[7].start_addr = 0x%x\n", (*ptr).vb[7].start_addr);
+   debug_printf("\t\t.vb[7].max_index = 0x%x\n", (*ptr).vb[7].max_index);
+   debug_printf("\t\t.vb[7].instance_data_step_rate = 0x%x\n", (*ptr).vb[7].instance_data_step_rate);
+   debug_printf("\t\t.vb[8].vb0.pitch = 0x%x\n", (*ptr).vb[8].vb0.pitch);
+   debug_printf("\t\t.vb[8].vb0.access_type = 0x%x\n", (*ptr).vb[8].vb0.access_type);
+   debug_printf("\t\t.vb[8].vb0.vb_index = 0x%x\n", (*ptr).vb[8].vb0.vb_index);
+   debug_printf("\t\t.vb[8].start_addr = 0x%x\n", (*ptr).vb[8].start_addr);
+   debug_printf("\t\t.vb[8].max_index = 0x%x\n", (*ptr).vb[8].max_index);
+   debug_printf("\t\t.vb[8].instance_data_step_rate = 0x%x\n", (*ptr).vb[8].instance_data_step_rate);
+   debug_printf("\t\t.vb[9].vb0.pitch = 0x%x\n", (*ptr).vb[9].vb0.pitch);
+   debug_printf("\t\t.vb[9].vb0.access_type = 0x%x\n", (*ptr).vb[9].vb0.access_type);
+   debug_printf("\t\t.vb[9].vb0.vb_index = 0x%x\n", (*ptr).vb[9].vb0.vb_index);
+   debug_printf("\t\t.vb[9].start_addr = 0x%x\n", (*ptr).vb[9].start_addr);
+   debug_printf("\t\t.vb[9].max_index = 0x%x\n", (*ptr).vb[9].max_index);
+   debug_printf("\t\t.vb[9].instance_data_step_rate = 0x%x\n", (*ptr).vb[9].instance_data_step_rate);
+   debug_printf("\t\t.vb[10].vb0.pitch = 0x%x\n", (*ptr).vb[10].vb0.pitch);
+   debug_printf("\t\t.vb[10].vb0.access_type = 0x%x\n", (*ptr).vb[10].vb0.access_type);
+   debug_printf("\t\t.vb[10].vb0.vb_index = 0x%x\n", (*ptr).vb[10].vb0.vb_index);
+   debug_printf("\t\t.vb[10].start_addr = 0x%x\n", (*ptr).vb[10].start_addr);
+   debug_printf("\t\t.vb[10].max_index = 0x%x\n", (*ptr).vb[10].max_index);
+   debug_printf("\t\t.vb[10].instance_data_step_rate = 0x%x\n", (*ptr).vb[10].instance_data_step_rate);
+   debug_printf("\t\t.vb[11].vb0.pitch = 0x%x\n", (*ptr).vb[11].vb0.pitch);
+   debug_printf("\t\t.vb[11].vb0.access_type = 0x%x\n", (*ptr).vb[11].vb0.access_type);
+   debug_printf("\t\t.vb[11].vb0.vb_index = 0x%x\n", (*ptr).vb[11].vb0.vb_index);
+   debug_printf("\t\t.vb[11].start_addr = 0x%x\n", (*ptr).vb[11].start_addr);
+   debug_printf("\t\t.vb[11].max_index = 0x%x\n", (*ptr).vb[11].max_index);
+   debug_printf("\t\t.vb[11].instance_data_step_rate = 0x%x\n", (*ptr).vb[11].instance_data_step_rate);
+   debug_printf("\t\t.vb[12].vb0.pitch = 0x%x\n", (*ptr).vb[12].vb0.pitch);
+   debug_printf("\t\t.vb[12].vb0.access_type = 0x%x\n", (*ptr).vb[12].vb0.access_type);
+   debug_printf("\t\t.vb[12].vb0.vb_index = 0x%x\n", (*ptr).vb[12].vb0.vb_index);
+   debug_printf("\t\t.vb[12].start_addr = 0x%x\n", (*ptr).vb[12].start_addr);
+   debug_printf("\t\t.vb[12].max_index = 0x%x\n", (*ptr).vb[12].max_index);
+   debug_printf("\t\t.vb[12].instance_data_step_rate = 0x%x\n", (*ptr).vb[12].instance_data_step_rate);
+   debug_printf("\t\t.vb[13].vb0.pitch = 0x%x\n", (*ptr).vb[13].vb0.pitch);
+   debug_printf("\t\t.vb[13].vb0.access_type = 0x%x\n", (*ptr).vb[13].vb0.access_type);
+   debug_printf("\t\t.vb[13].vb0.vb_index = 0x%x\n", (*ptr).vb[13].vb0.vb_index);
+   debug_printf("\t\t.vb[13].start_addr = 0x%x\n", (*ptr).vb[13].start_addr);
+   debug_printf("\t\t.vb[13].max_index = 0x%x\n", (*ptr).vb[13].max_index);
+   debug_printf("\t\t.vb[13].instance_data_step_rate = 0x%x\n", (*ptr).vb[13].instance_data_step_rate);
+   debug_printf("\t\t.vb[14].vb0.pitch = 0x%x\n", (*ptr).vb[14].vb0.pitch);
+   debug_printf("\t\t.vb[14].vb0.access_type = 0x%x\n", (*ptr).vb[14].vb0.access_type);
+   debug_printf("\t\t.vb[14].vb0.vb_index = 0x%x\n", (*ptr).vb[14].vb0.vb_index);
+   debug_printf("\t\t.vb[14].start_addr = 0x%x\n", (*ptr).vb[14].start_addr);
+   debug_printf("\t\t.vb[14].max_index = 0x%x\n", (*ptr).vb[14].max_index);
+   debug_printf("\t\t.vb[14].instance_data_step_rate = 0x%x\n", (*ptr).vb[14].instance_data_step_rate);
+   debug_printf("\t\t.vb[15].vb0.pitch = 0x%x\n", (*ptr).vb[15].vb0.pitch);
+   debug_printf("\t\t.vb[15].vb0.access_type = 0x%x\n", (*ptr).vb[15].vb0.access_type);
+   debug_printf("\t\t.vb[15].vb0.vb_index = 0x%x\n", (*ptr).vb[15].vb0.vb_index);
+   debug_printf("\t\t.vb[15].start_addr = 0x%x\n", (*ptr).vb[15].start_addr);
+   debug_printf("\t\t.vb[15].max_index = 0x%x\n", (*ptr).vb[15].max_index);
+   debug_printf("\t\t.vb[15].instance_data_step_rate = 0x%x\n", (*ptr).vb[15].instance_data_step_rate);
+   debug_printf("\t\t.vb[16].vb0.pitch = 0x%x\n", (*ptr).vb[16].vb0.pitch);
+   debug_printf("\t\t.vb[16].vb0.access_type = 0x%x\n", (*ptr).vb[16].vb0.access_type);
+   debug_printf("\t\t.vb[16].vb0.vb_index = 0x%x\n", (*ptr).vb[16].vb0.vb_index);
+   debug_printf("\t\t.vb[16].start_addr = 0x%x\n", (*ptr).vb[16].start_addr);
+   debug_printf("\t\t.vb[16].max_index = 0x%x\n", (*ptr).vb[16].max_index);
+   debug_printf("\t\t.vb[16].instance_data_step_rate = 0x%x\n", (*ptr).vb[16].instance_data_step_rate);
+}
+
+void
+brw_dump_vertex_buffer_state(const struct brw_vertex_buffer_state *ptr)
+{
+   debug_printf("\t\t.vb0.pitch = 0x%x\n", (*ptr).vb0.pitch);
+   debug_printf("\t\t.vb0.access_type = 0x%x\n", (*ptr).vb0.access_type);
+   debug_printf("\t\t.vb0.vb_index = 0x%x\n", (*ptr).vb0.vb_index);
+   debug_printf("\t\t.start_addr = 0x%x\n", (*ptr).start_addr);
+   debug_printf("\t\t.max_index = 0x%x\n", (*ptr).max_index);
+   debug_printf("\t\t.instance_data_step_rate = 0x%x\n", (*ptr).instance_data_step_rate);
+}
+
+void
+brw_dump_vertex_element_packet(const struct brw_vertex_element_packet *ptr)
+{
+   debug_printf("\t\t.header.length = 0x%x\n", (*ptr).header.length);
+   debug_printf("\t\t.header.opcode = 0x%x\n", (*ptr).header.opcode);
+   debug_printf("\t\t.ve[0].ve0.src_offset = 0x%x\n", (*ptr).ve[0].ve0.src_offset);
+   debug_printf("\t\t.ve[0].ve0.src_format = 0x%x\n", (*ptr).ve[0].ve0.src_format);
+   debug_printf("\t\t.ve[0].ve0.valid = 0x%x\n", (*ptr).ve[0].ve0.valid);
+   debug_printf("\t\t.ve[0].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[0].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[0].ve1.dst_offset = 0x%x\n", (*ptr).ve[0].ve1.dst_offset);
+   debug_printf("\t\t.ve[0].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[0].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[0].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[0].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[0].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[0].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[0].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[0].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[1].ve0.src_offset = 0x%x\n", (*ptr).ve[1].ve0.src_offset);
+   debug_printf("\t\t.ve[1].ve0.src_format = 0x%x\n", (*ptr).ve[1].ve0.src_format);
+   debug_printf("\t\t.ve[1].ve0.valid = 0x%x\n", (*ptr).ve[1].ve0.valid);
+   debug_printf("\t\t.ve[1].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[1].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[1].ve1.dst_offset = 0x%x\n", (*ptr).ve[1].ve1.dst_offset);
+   debug_printf("\t\t.ve[1].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[1].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[1].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[1].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[1].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[1].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[1].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[1].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[2].ve0.src_offset = 0x%x\n", (*ptr).ve[2].ve0.src_offset);
+   debug_printf("\t\t.ve[2].ve0.src_format = 0x%x\n", (*ptr).ve[2].ve0.src_format);
+   debug_printf("\t\t.ve[2].ve0.valid = 0x%x\n", (*ptr).ve[2].ve0.valid);
+   debug_printf("\t\t.ve[2].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[2].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[2].ve1.dst_offset = 0x%x\n", (*ptr).ve[2].ve1.dst_offset);
+   debug_printf("\t\t.ve[2].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[2].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[2].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[2].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[2].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[2].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[2].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[2].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[3].ve0.src_offset = 0x%x\n", (*ptr).ve[3].ve0.src_offset);
+   debug_printf("\t\t.ve[3].ve0.src_format = 0x%x\n", (*ptr).ve[3].ve0.src_format);
+   debug_printf("\t\t.ve[3].ve0.valid = 0x%x\n", (*ptr).ve[3].ve0.valid);
+   debug_printf("\t\t.ve[3].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[3].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[3].ve1.dst_offset = 0x%x\n", (*ptr).ve[3].ve1.dst_offset);
+   debug_printf("\t\t.ve[3].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[3].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[3].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[3].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[3].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[3].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[3].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[3].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[4].ve0.src_offset = 0x%x\n", (*ptr).ve[4].ve0.src_offset);
+   debug_printf("\t\t.ve[4].ve0.src_format = 0x%x\n", (*ptr).ve[4].ve0.src_format);
+   debug_printf("\t\t.ve[4].ve0.valid = 0x%x\n", (*ptr).ve[4].ve0.valid);
+   debug_printf("\t\t.ve[4].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[4].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[4].ve1.dst_offset = 0x%x\n", (*ptr).ve[4].ve1.dst_offset);
+   debug_printf("\t\t.ve[4].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[4].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[4].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[4].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[4].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[4].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[4].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[4].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[5].ve0.src_offset = 0x%x\n", (*ptr).ve[5].ve0.src_offset);
+   debug_printf("\t\t.ve[5].ve0.src_format = 0x%x\n", (*ptr).ve[5].ve0.src_format);
+   debug_printf("\t\t.ve[5].ve0.valid = 0x%x\n", (*ptr).ve[5].ve0.valid);
+   debug_printf("\t\t.ve[5].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[5].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[5].ve1.dst_offset = 0x%x\n", (*ptr).ve[5].ve1.dst_offset);
+   debug_printf("\t\t.ve[5].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[5].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[5].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[5].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[5].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[5].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[5].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[5].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[6].ve0.src_offset = 0x%x\n", (*ptr).ve[6].ve0.src_offset);
+   debug_printf("\t\t.ve[6].ve0.src_format = 0x%x\n", (*ptr).ve[6].ve0.src_format);
+   debug_printf("\t\t.ve[6].ve0.valid = 0x%x\n", (*ptr).ve[6].ve0.valid);
+   debug_printf("\t\t.ve[6].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[6].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[6].ve1.dst_offset = 0x%x\n", (*ptr).ve[6].ve1.dst_offset);
+   debug_printf("\t\t.ve[6].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[6].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[6].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[6].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[6].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[6].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[6].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[6].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[7].ve0.src_offset = 0x%x\n", (*ptr).ve[7].ve0.src_offset);
+   debug_printf("\t\t.ve[7].ve0.src_format = 0x%x\n", (*ptr).ve[7].ve0.src_format);
+   debug_printf("\t\t.ve[7].ve0.valid = 0x%x\n", (*ptr).ve[7].ve0.valid);
+   debug_printf("\t\t.ve[7].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[7].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[7].ve1.dst_offset = 0x%x\n", (*ptr).ve[7].ve1.dst_offset);
+   debug_printf("\t\t.ve[7].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[7].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[7].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[7].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[7].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[7].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[7].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[7].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[8].ve0.src_offset = 0x%x\n", (*ptr).ve[8].ve0.src_offset);
+   debug_printf("\t\t.ve[8].ve0.src_format = 0x%x\n", (*ptr).ve[8].ve0.src_format);
+   debug_printf("\t\t.ve[8].ve0.valid = 0x%x\n", (*ptr).ve[8].ve0.valid);
+   debug_printf("\t\t.ve[8].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[8].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[8].ve1.dst_offset = 0x%x\n", (*ptr).ve[8].ve1.dst_offset);
+   debug_printf("\t\t.ve[8].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[8].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[8].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[8].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[8].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[8].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[8].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[8].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[9].ve0.src_offset = 0x%x\n", (*ptr).ve[9].ve0.src_offset);
+   debug_printf("\t\t.ve[9].ve0.src_format = 0x%x\n", (*ptr).ve[9].ve0.src_format);
+   debug_printf("\t\t.ve[9].ve0.valid = 0x%x\n", (*ptr).ve[9].ve0.valid);
+   debug_printf("\t\t.ve[9].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[9].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[9].ve1.dst_offset = 0x%x\n", (*ptr).ve[9].ve1.dst_offset);
+   debug_printf("\t\t.ve[9].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[9].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[9].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[9].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[9].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[9].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[9].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[9].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[10].ve0.src_offset = 0x%x\n", (*ptr).ve[10].ve0.src_offset);
+   debug_printf("\t\t.ve[10].ve0.src_format = 0x%x\n", (*ptr).ve[10].ve0.src_format);
+   debug_printf("\t\t.ve[10].ve0.valid = 0x%x\n", (*ptr).ve[10].ve0.valid);
+   debug_printf("\t\t.ve[10].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[10].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[10].ve1.dst_offset = 0x%x\n", (*ptr).ve[10].ve1.dst_offset);
+   debug_printf("\t\t.ve[10].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[10].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[10].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[10].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[10].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[10].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[10].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[10].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[11].ve0.src_offset = 0x%x\n", (*ptr).ve[11].ve0.src_offset);
+   debug_printf("\t\t.ve[11].ve0.src_format = 0x%x\n", (*ptr).ve[11].ve0.src_format);
+   debug_printf("\t\t.ve[11].ve0.valid = 0x%x\n", (*ptr).ve[11].ve0.valid);
+   debug_printf("\t\t.ve[11].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[11].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[11].ve1.dst_offset = 0x%x\n", (*ptr).ve[11].ve1.dst_offset);
+   debug_printf("\t\t.ve[11].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[11].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[11].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[11].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[11].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[11].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[11].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[11].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[12].ve0.src_offset = 0x%x\n", (*ptr).ve[12].ve0.src_offset);
+   debug_printf("\t\t.ve[12].ve0.src_format = 0x%x\n", (*ptr).ve[12].ve0.src_format);
+   debug_printf("\t\t.ve[12].ve0.valid = 0x%x\n", (*ptr).ve[12].ve0.valid);
+   debug_printf("\t\t.ve[12].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[12].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[12].ve1.dst_offset = 0x%x\n", (*ptr).ve[12].ve1.dst_offset);
+   debug_printf("\t\t.ve[12].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[12].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[12].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[12].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[12].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[12].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[12].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[12].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[13].ve0.src_offset = 0x%x\n", (*ptr).ve[13].ve0.src_offset);
+   debug_printf("\t\t.ve[13].ve0.src_format = 0x%x\n", (*ptr).ve[13].ve0.src_format);
+   debug_printf("\t\t.ve[13].ve0.valid = 0x%x\n", (*ptr).ve[13].ve0.valid);
+   debug_printf("\t\t.ve[13].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[13].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[13].ve1.dst_offset = 0x%x\n", (*ptr).ve[13].ve1.dst_offset);
+   debug_printf("\t\t.ve[13].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[13].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[13].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[13].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[13].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[13].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[13].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[13].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[14].ve0.src_offset = 0x%x\n", (*ptr).ve[14].ve0.src_offset);
+   debug_printf("\t\t.ve[14].ve0.src_format = 0x%x\n", (*ptr).ve[14].ve0.src_format);
+   debug_printf("\t\t.ve[14].ve0.valid = 0x%x\n", (*ptr).ve[14].ve0.valid);
+   debug_printf("\t\t.ve[14].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[14].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[14].ve1.dst_offset = 0x%x\n", (*ptr).ve[14].ve1.dst_offset);
+   debug_printf("\t\t.ve[14].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[14].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[14].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[14].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[14].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[14].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[14].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[14].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[15].ve0.src_offset = 0x%x\n", (*ptr).ve[15].ve0.src_offset);
+   debug_printf("\t\t.ve[15].ve0.src_format = 0x%x\n", (*ptr).ve[15].ve0.src_format);
+   debug_printf("\t\t.ve[15].ve0.valid = 0x%x\n", (*ptr).ve[15].ve0.valid);
+   debug_printf("\t\t.ve[15].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[15].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[15].ve1.dst_offset = 0x%x\n", (*ptr).ve[15].ve1.dst_offset);
+   debug_printf("\t\t.ve[15].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[15].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[15].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[15].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[15].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[15].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[15].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[15].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[16].ve0.src_offset = 0x%x\n", (*ptr).ve[16].ve0.src_offset);
+   debug_printf("\t\t.ve[16].ve0.src_format = 0x%x\n", (*ptr).ve[16].ve0.src_format);
+   debug_printf("\t\t.ve[16].ve0.valid = 0x%x\n", (*ptr).ve[16].ve0.valid);
+   debug_printf("\t\t.ve[16].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[16].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[16].ve1.dst_offset = 0x%x\n", (*ptr).ve[16].ve1.dst_offset);
+   debug_printf("\t\t.ve[16].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[16].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[16].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[16].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[16].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[16].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[16].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[16].ve1.vfcomponent0);
+   debug_printf("\t\t.ve[17].ve0.src_offset = 0x%x\n", (*ptr).ve[17].ve0.src_offset);
+   debug_printf("\t\t.ve[17].ve0.src_format = 0x%x\n", (*ptr).ve[17].ve0.src_format);
+   debug_printf("\t\t.ve[17].ve0.valid = 0x%x\n", (*ptr).ve[17].ve0.valid);
+   debug_printf("\t\t.ve[17].ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve[17].ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve[17].ve1.dst_offset = 0x%x\n", (*ptr).ve[17].ve1.dst_offset);
+   debug_printf("\t\t.ve[17].ve1.vfcomponent3 = 0x%x\n", (*ptr).ve[17].ve1.vfcomponent3);
+   debug_printf("\t\t.ve[17].ve1.vfcomponent2 = 0x%x\n", (*ptr).ve[17].ve1.vfcomponent2);
+   debug_printf("\t\t.ve[17].ve1.vfcomponent1 = 0x%x\n", (*ptr).ve[17].ve1.vfcomponent1);
+   debug_printf("\t\t.ve[17].ve1.vfcomponent0 = 0x%x\n", (*ptr).ve[17].ve1.vfcomponent0);
+}
+
+void
+brw_dump_vertex_element_state(const struct brw_vertex_element_state *ptr)
+{
+   debug_printf("\t\t.ve0.src_offset = 0x%x\n", (*ptr).ve0.src_offset);
+   debug_printf("\t\t.ve0.src_format = 0x%x\n", (*ptr).ve0.src_format);
+   debug_printf("\t\t.ve0.valid = 0x%x\n", (*ptr).ve0.valid);
+   debug_printf("\t\t.ve0.vertex_buffer_index = 0x%x\n", (*ptr).ve0.vertex_buffer_index);
+   debug_printf("\t\t.ve1.dst_offset = 0x%x\n", (*ptr).ve1.dst_offset);
+   debug_printf("\t\t.ve1.vfcomponent3 = 0x%x\n", (*ptr).ve1.vfcomponent3);
+   debug_printf("\t\t.ve1.vfcomponent2 = 0x%x\n", (*ptr).ve1.vfcomponent2);
+   debug_printf("\t\t.ve1.vfcomponent1 = 0x%x\n", (*ptr).ve1.vfcomponent1);
+   debug_printf("\t\t.ve1.vfcomponent0 = 0x%x\n", (*ptr).ve1.vfcomponent0);
+}
+
+void
+brw_dump_vf_statistics(const struct brw_vf_statistics *ptr)
+{
+   debug_printf("\t\t.statistics_enable = 0x%x\n", (*ptr).statistics_enable);
+   debug_printf("\t\t.opcode = 0x%x\n", (*ptr).opcode);
+}
+
+void
+brw_dump_vs_unit_state(const struct brw_vs_unit_state *ptr)
+{
+   debug_printf("\t\t.thread0.grf_reg_count = 0x%x\n", (*ptr).thread0.grf_reg_count);
+   debug_printf("\t\t.thread0.kernel_start_pointer = 0x%x\n", (*ptr).thread0.kernel_start_pointer);
+   debug_printf("\t\t.thread1.ext_halt_exception_enable = 0x%x\n", (*ptr).thread1.ext_halt_exception_enable);
+   debug_printf("\t\t.thread1.sw_exception_enable = 0x%x\n", (*ptr).thread1.sw_exception_enable);
+   debug_printf("\t\t.thread1.mask_stack_exception_enable = 0x%x\n", (*ptr).thread1.mask_stack_exception_enable);
+   debug_printf("\t\t.thread1.timeout_exception_enable = 0x%x\n", (*ptr).thread1.timeout_exception_enable);
+   debug_printf("\t\t.thread1.illegal_op_exception_enable = 0x%x\n", (*ptr).thread1.illegal_op_exception_enable);
+   debug_printf("\t\t.thread1.depth_coef_urb_read_offset = 0x%x\n", (*ptr).thread1.depth_coef_urb_read_offset);
+   debug_printf("\t\t.thread1.floating_point_mode = 0x%x\n", (*ptr).thread1.floating_point_mode);
+   debug_printf("\t\t.thread1.thread_priority = 0x%x\n", (*ptr).thread1.thread_priority);
+   debug_printf("\t\t.thread1.binding_table_entry_count = 0x%x\n", (*ptr).thread1.binding_table_entry_count);
+   debug_printf("\t\t.thread1.single_program_flow = 0x%x\n", (*ptr).thread1.single_program_flow);
+   debug_printf("\t\t.thread2.per_thread_scratch_space = 0x%x\n", (*ptr).thread2.per_thread_scratch_space);
+   debug_printf("\t\t.thread2.scratch_space_base_pointer = 0x%x\n", (*ptr).thread2.scratch_space_base_pointer);
+   debug_printf("\t\t.thread3.dispatch_grf_start_reg = 0x%x\n", (*ptr).thread3.dispatch_grf_start_reg);
+   debug_printf("\t\t.thread3.urb_entry_read_offset = 0x%x\n", (*ptr).thread3.urb_entry_read_offset);
+   debug_printf("\t\t.thread3.urb_entry_read_length = 0x%x\n", (*ptr).thread3.urb_entry_read_length);
+   debug_printf("\t\t.thread3.const_urb_entry_read_offset = 0x%x\n", (*ptr).thread3.const_urb_entry_read_offset);
+   debug_printf("\t\t.thread3.const_urb_entry_read_length = 0x%x\n", (*ptr).thread3.const_urb_entry_read_length);
+   debug_printf("\t\t.thread4.stats_enable = 0x%x\n", (*ptr).thread4.stats_enable);
+   debug_printf("\t\t.thread4.nr_urb_entries = 0x%x\n", (*ptr).thread4.nr_urb_entries);
+   debug_printf("\t\t.thread4.urb_entry_allocation_size = 0x%x\n", (*ptr).thread4.urb_entry_allocation_size);
+   debug_printf("\t\t.thread4.max_threads = 0x%x\n", (*ptr).thread4.max_threads);
+   debug_printf("\t\t.vs5.sampler_count = 0x%x\n", (*ptr).vs5.sampler_count);
+   debug_printf("\t\t.vs5.sampler_state_pointer = 0x%x\n", (*ptr).vs5.sampler_state_pointer);
+   debug_printf("\t\t.vs6.vs_enable = 0x%x\n", (*ptr).vs6.vs_enable);
+   debug_printf("\t\t.vs6.vert_cache_disable = 0x%x\n", (*ptr).vs6.vert_cache_disable);
+}
+
+void
+brw_dump_wm_unit_state(const struct brw_wm_unit_state *ptr)
+{
+   debug_printf("\t\t.thread0.grf_reg_count = 0x%x\n", (*ptr).thread0.grf_reg_count);
+   debug_printf("\t\t.thread0.kernel_start_pointer = 0x%x\n", (*ptr).thread0.kernel_start_pointer);
+   debug_printf("\t\t.thread1.ext_halt_exception_enable = 0x%x\n", (*ptr).thread1.ext_halt_exception_enable);
+   debug_printf("\t\t.thread1.sw_exception_enable = 0x%x\n", (*ptr).thread1.sw_exception_enable);
+   debug_printf("\t\t.thread1.mask_stack_exception_enable = 0x%x\n", (*ptr).thread1.mask_stack_exception_enable);
+   debug_printf("\t\t.thread1.timeout_exception_enable = 0x%x\n", (*ptr).thread1.timeout_exception_enable);
+   debug_printf("\t\t.thread1.illegal_op_exception_enable = 0x%x\n", (*ptr).thread1.illegal_op_exception_enable);
+   debug_printf("\t\t.thread1.depth_coef_urb_read_offset = 0x%x\n", (*ptr).thread1.depth_coef_urb_read_offset);
+   debug_printf("\t\t.thread1.floating_point_mode = 0x%x\n", (*ptr).thread1.floating_point_mode);
+   debug_printf("\t\t.thread1.thread_priority = 0x%x\n", (*ptr).thread1.thread_priority);
+   debug_printf("\t\t.thread1.binding_table_entry_count = 0x%x\n", (*ptr).thread1.binding_table_entry_count);
+   debug_printf("\t\t.thread1.single_program_flow = 0x%x\n", (*ptr).thread1.single_program_flow);
+   debug_printf("\t\t.thread2.per_thread_scratch_space = 0x%x\n", (*ptr).thread2.per_thread_scratch_space);
+   debug_printf("\t\t.thread2.scratch_space_base_pointer = 0x%x\n", (*ptr).thread2.scratch_space_base_pointer);
+   debug_printf("\t\t.thread3.dispatch_grf_start_reg = 0x%x\n", (*ptr).thread3.dispatch_grf_start_reg);
+   debug_printf("\t\t.thread3.urb_entry_read_offset = 0x%x\n", (*ptr).thread3.urb_entry_read_offset);
+   debug_printf("\t\t.thread3.urb_entry_read_length = 0x%x\n", (*ptr).thread3.urb_entry_read_length);
+   debug_printf("\t\t.thread3.const_urb_entry_read_offset = 0x%x\n", (*ptr).thread3.const_urb_entry_read_offset);
+   debug_printf("\t\t.thread3.const_urb_entry_read_length = 0x%x\n", (*ptr).thread3.const_urb_entry_read_length);
+   debug_printf("\t\t.wm4.stats_enable = 0x%x\n", (*ptr).wm4.stats_enable);
+   debug_printf("\t\t.wm4.depth_buffer_clear = 0x%x\n", (*ptr).wm4.depth_buffer_clear);
+   debug_printf("\t\t.wm4.sampler_count = 0x%x\n", (*ptr).wm4.sampler_count);
+   debug_printf("\t\t.wm4.sampler_state_pointer = 0x%x\n", (*ptr).wm4.sampler_state_pointer);
+   debug_printf("\t\t.wm5.enable_8_pix = 0x%x\n", (*ptr).wm5.enable_8_pix);
+   debug_printf("\t\t.wm5.enable_16_pix = 0x%x\n", (*ptr).wm5.enable_16_pix);
+   debug_printf("\t\t.wm5.enable_32_pix = 0x%x\n", (*ptr).wm5.enable_32_pix);
+   debug_printf("\t\t.wm5.enable_con_32_pix = 0x%x\n", (*ptr).wm5.enable_con_32_pix);
+   debug_printf("\t\t.wm5.enable_con_64_pix = 0x%x\n", (*ptr).wm5.enable_con_64_pix);
+   debug_printf("\t\t.wm5.legacy_global_depth_bias = 0x%x\n", (*ptr).wm5.legacy_global_depth_bias);
+   debug_printf("\t\t.wm5.line_stipple = 0x%x\n", (*ptr).wm5.line_stipple);
+   debug_printf("\t\t.wm5.depth_offset = 0x%x\n", (*ptr).wm5.depth_offset);
+   debug_printf("\t\t.wm5.polygon_stipple = 0x%x\n", (*ptr).wm5.polygon_stipple);
+   debug_printf("\t\t.wm5.line_aa_region_width = 0x%x\n", (*ptr).wm5.line_aa_region_width);
+   debug_printf("\t\t.wm5.line_endcap_aa_region_width = 0x%x\n", (*ptr).wm5.line_endcap_aa_region_width);
+   debug_printf("\t\t.wm5.early_depth_test = 0x%x\n", (*ptr).wm5.early_depth_test);
+   debug_printf("\t\t.wm5.thread_dispatch_enable = 0x%x\n", (*ptr).wm5.thread_dispatch_enable);
+   debug_printf("\t\t.wm5.program_uses_depth = 0x%x\n", (*ptr).wm5.program_uses_depth);
+   debug_printf("\t\t.wm5.program_computes_depth = 0x%x\n", (*ptr).wm5.program_computes_depth);
+   debug_printf("\t\t.wm5.program_uses_killpixel = 0x%x\n", (*ptr).wm5.program_uses_killpixel);
+   debug_printf("\t\t.wm5.legacy_line_rast = 0x%x\n", (*ptr).wm5.legacy_line_rast);
+   debug_printf("\t\t.wm5.transposed_urb_read_enable = 0x%x\n", (*ptr).wm5.transposed_urb_read_enable);
+   debug_printf("\t\t.wm5.max_threads = 0x%x\n", (*ptr).wm5.max_threads);
+   debug_printf("\t\t.global_depth_offset_constant = %f\n", (*ptr).global_depth_offset_constant);
+   debug_printf("\t\t.global_depth_offset_scale = %f\n", (*ptr).global_depth_offset_scale);
+   debug_printf("\t\t.wm8.grf_reg_count_1 = 0x%x\n", (*ptr).wm8.grf_reg_count_1);
+   debug_printf("\t\t.wm8.kernel_start_pointer_1 = 0x%x\n", (*ptr).wm8.kernel_start_pointer_1);
+   debug_printf("\t\t.wm9.grf_reg_count_2 = 0x%x\n", (*ptr).wm9.grf_reg_count_2);
+   debug_printf("\t\t.wm9.kernel_start_pointer_2 = 0x%x\n", (*ptr).wm9.kernel_start_pointer_2);
+   debug_printf("\t\t.wm10.grf_reg_count_3 = 0x%x\n", (*ptr).wm10.grf_reg_count_3);
+   debug_printf("\t\t.wm10.kernel_start_pointer_3 = 0x%x\n", (*ptr).wm10.kernel_start_pointer_3);
+}
+
diff --git a/src/gallium/drivers/i965/brw_structs_dump.h b/src/gallium/drivers/i965/brw_structs_dump.h
new file mode 100644
index 0000000..7c02dbf
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_structs_dump.h
@@ -0,0 +1,276 @@
+/**************************************************************************
+ *
+ * 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 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Dump i965 data structures.
+ *
+ * Generated automatically from brw_structs.h by brw_structs_dump.py.
+ */
+
+#ifndef BRW_STRUCTS_DUMP_H
+#define BRW_STRUCTS_DUMP_H
+
+struct brw_3d_control;
+struct brw_3d_primitive;
+struct brw_aa_line_parameters;
+struct brw_binding_table_pointers;
+struct brw_blend_constant_color;
+struct brw_cc0;
+struct brw_cc1;
+struct brw_cc2;
+struct brw_cc3;
+struct brw_cc4;
+struct brw_cc5;
+struct brw_cc6;
+struct brw_cc7;
+struct brw_cc_unit_state;
+struct brw_cc_viewport;
+struct brw_clip_unit_state;
+struct brw_clipper_viewport;
+struct brw_constant_buffer;
+struct brw_cs_urb_state;
+struct brw_depthbuffer;
+struct brw_depthbuffer_g4x;
+struct brw_drawrect;
+struct brw_global_depth_offset_clamp;
+struct brw_gs_unit_state;
+struct brw_indexbuffer;
+struct brw_line_stipple;
+struct brw_mi_flush;
+struct brw_pipe_control;
+struct brw_pipeline_select;
+struct brw_pipelined_state_pointers;
+struct brw_polygon_stipple;
+struct brw_polygon_stipple_offset;
+struct brw_sampler_default_color;
+struct brw_sampler_state;
+struct brw_sf_unit_state;
+struct brw_sf_viewport;
+struct brw_ss0;
+struct brw_ss1;
+struct brw_ss2;
+struct brw_ss3;
+struct brw_state_base_address;
+struct brw_state_prefetch;
+struct brw_surf_ss0;
+struct brw_surf_ss1;
+struct brw_surf_ss2;
+struct brw_surf_ss3;
+struct brw_surf_ss4;
+struct brw_surf_ss5;
+struct brw_surface_state;
+struct brw_system_instruction_pointer;
+struct brw_urb_fence;
+struct brw_urb_immediate;
+struct brw_vb_array_state;
+struct brw_vertex_buffer_state;
+struct brw_vertex_element_packet;
+struct brw_vertex_element_state;
+struct brw_vf_statistics;
+struct brw_vs_unit_state;
+struct brw_wm_unit_state;
+
+void
+brw_dump_3d_control(const struct brw_3d_control *ptr);
+
+void
+brw_dump_3d_primitive(const struct brw_3d_primitive *ptr);
+
+void
+brw_dump_aa_line_parameters(const struct brw_aa_line_parameters *ptr);
+
+void
+brw_dump_binding_table_pointers(const struct brw_binding_table_pointers *ptr);
+
+void
+brw_dump_blend_constant_color(const struct brw_blend_constant_color *ptr);
+
+void
+brw_dump_cc0(const struct brw_cc0 *ptr);
+
+void
+brw_dump_cc1(const struct brw_cc1 *ptr);
+
+void
+brw_dump_cc2(const struct brw_cc2 *ptr);
+
+void
+brw_dump_cc3(const struct brw_cc3 *ptr);
+
+void
+brw_dump_cc4(const struct brw_cc4 *ptr);
+
+void
+brw_dump_cc5(const struct brw_cc5 *ptr);
+
+void
+brw_dump_cc6(const struct brw_cc6 *ptr);
+
+void
+brw_dump_cc7(const struct brw_cc7 *ptr);
+
+void
+brw_dump_cc_unit_state(const struct brw_cc_unit_state *ptr);
+
+void
+brw_dump_cc_viewport(const struct brw_cc_viewport *ptr);
+
+void
+brw_dump_clip_unit_state(const struct brw_clip_unit_state *ptr);
+
+void
+brw_dump_clipper_viewport(const struct brw_clipper_viewport *ptr);
+
+void
+brw_dump_constant_buffer(const struct brw_constant_buffer *ptr);
+
+void
+brw_dump_cs_urb_state(const struct brw_cs_urb_state *ptr);
+
+void
+brw_dump_depthbuffer(const struct brw_depthbuffer *ptr);
+
+void
+brw_dump_depthbuffer_g4x(const struct brw_depthbuffer_g4x *ptr);
+
+void
+brw_dump_drawrect(const struct brw_drawrect *ptr);
+
+void
+brw_dump_global_depth_offset_clamp(const struct brw_global_depth_offset_clamp *ptr);
+
+void
+brw_dump_gs_unit_state(const struct brw_gs_unit_state *ptr);
+
+void
+brw_dump_indexbuffer(const struct brw_indexbuffer *ptr);
+
+void
+brw_dump_line_stipple(const struct brw_line_stipple *ptr);
+
+void
+brw_dump_mi_flush(const struct brw_mi_flush *ptr);
+
+void
+brw_dump_pipe_control(const struct brw_pipe_control *ptr);
+
+void
+brw_dump_pipeline_select(const struct brw_pipeline_select *ptr);
+
+void
+brw_dump_pipelined_state_pointers(const struct brw_pipelined_state_pointers *ptr);
+
+void
+brw_dump_polygon_stipple(const struct brw_polygon_stipple *ptr);
+
+void
+brw_dump_polygon_stipple_offset(const struct brw_polygon_stipple_offset *ptr);
+
+void
+brw_dump_sampler_default_color(const struct brw_sampler_default_color *ptr);
+
+void
+brw_dump_sampler_state(const struct brw_sampler_state *ptr);
+
+void
+brw_dump_sf_unit_state(const struct brw_sf_unit_state *ptr);
+
+void
+brw_dump_sf_viewport(const struct brw_sf_viewport *ptr);
+
+void
+brw_dump_ss0(const struct brw_ss0 *ptr);
+
+void
+brw_dump_ss1(const struct brw_ss1 *ptr);
+
+void
+brw_dump_ss2(const struct brw_ss2 *ptr);
+
+void
+brw_dump_ss3(const struct brw_ss3 *ptr);
+
+void
+brw_dump_state_base_address(const struct brw_state_base_address *ptr);
+
+void
+brw_dump_state_prefetch(const struct brw_state_prefetch *ptr);
+
+void
+brw_dump_surf_ss0(const struct brw_surf_ss0 *ptr);
+
+void
+brw_dump_surf_ss1(const struct brw_surf_ss1 *ptr);
+
+void
+brw_dump_surf_ss2(const struct brw_surf_ss2 *ptr);
+
+void
+brw_dump_surf_ss3(const struct brw_surf_ss3 *ptr);
+
+void
+brw_dump_surf_ss4(const struct brw_surf_ss4 *ptr);
+
+void
+brw_dump_surf_ss5(const struct brw_surf_ss5 *ptr);
+
+void
+brw_dump_surface_state(const struct brw_surface_state *ptr);
+
+void
+brw_dump_system_instruction_pointer(const struct brw_system_instruction_pointer *ptr);
+
+void
+brw_dump_urb_fence(const struct brw_urb_fence *ptr);
+
+void
+brw_dump_urb_immediate(const struct brw_urb_immediate *ptr);
+
+void
+brw_dump_vb_array_state(const struct brw_vb_array_state *ptr);
+
+void
+brw_dump_vertex_buffer_state(const struct brw_vertex_buffer_state *ptr);
+
+void
+brw_dump_vertex_element_packet(const struct brw_vertex_element_packet *ptr);
+
+void
+brw_dump_vertex_element_state(const struct brw_vertex_element_state *ptr);
+
+void
+brw_dump_vf_statistics(const struct brw_vf_statistics *ptr);
+
+void
+brw_dump_vs_unit_state(const struct brw_vs_unit_state *ptr);
+
+void
+brw_dump_wm_unit_state(const struct brw_wm_unit_state *ptr);
+
+
+#endif /* BRW_STRUCTS_DUMP_H */
diff --git a/src/gallium/drivers/i965/brw_structs_dump.py b/src/gallium/drivers/i965/brw_structs_dump.py
new file mode 100755
index 0000000..6dba49a
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_structs_dump.py
@@ -0,0 +1,291 @@
+#!/usr/bin/env python
+'''
+Generates dumpers for the i965 state strucutures using pygccxml.
+
+Run as 
+
+  PYTHONPATH=/path/to/pygccxml-1.0.0 python brw_structs_dump.py
+
+Jose Fonseca <jfonseca@vmware.com>
+'''
+
+copyright = '''
+/**************************************************************************
+ *
+ * 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 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+ '''
+
+import os
+import sys
+import re
+
+from pygccxml import parser
+from pygccxml import declarations
+
+from pygccxml.declarations import algorithm
+from pygccxml.declarations import decl_visitor
+from pygccxml.declarations import type_traits
+from pygccxml.declarations import type_visitor
+
+
+enums = True
+
+
+def vars_filter(variable):
+    name = variable.name
+    return not re.match('^pad\d*', name) and name != 'dword' 
+
+
+class decl_dumper_t(decl_visitor.decl_visitor_t):
+
+    def __init__(self, stream, instance = '', decl = None):
+        decl_visitor.decl_visitor_t.__init__(self)
+        self.stream = stream
+        self._instance = instance
+        self.decl = decl
+
+    def clone(self):
+        return decl_dumper_t(self.stream, self._instance, self.decl)
+
+    def visit_class(self):
+        class_ = self.decl
+        assert self.decl.class_type in ('struct', 'union')
+
+        for variable in class_.variables(recursive = False):
+            if vars_filter(variable):
+                dump_type(self.stream, self._instance + '.' + variable.name, variable.type)
+
+    def visit_enumeration(self):
+        if enums:
+            self.stream.write('   switch(%s) {\n' % ("(*ptr)" + self._instance,))
+            for name, value in self.decl.values:
+                self.stream.write('   case %s:\n' % (name,))
+                self.stream.write('      debug_printf("\\t\\t%s = %s\\n");\n' % (self._instance, name))
+                self.stream.write('      break;\n')
+            self.stream.write('   default:\n')
+            self.stream.write('      debug_printf("\\t\\t%s = %%i\\n", %s);\n' % (self._instance, "(*ptr)" + self._instance))
+            self.stream.write('      break;\n')
+            self.stream.write('   }\n')
+        else:
+            self.stream.write('   debug_printf("\\t\\t%s = %%i\\n", %s);\n' % (self._instance, "(*ptr)" + self._instance))
+
+
+def dump_decl(stream, instance, decl):
+    dumper = decl_dumper_t(stream, instance, decl)
+    algorithm.apply_visitor(dumper, decl)
+
+
+class type_dumper_t(type_visitor.type_visitor_t):
+
+    def __init__(self, stream, instance, type_):
+        type_visitor.type_visitor_t.__init__(self)
+        self.stream = stream
+        self.instance = instance
+        self.type = type_
+
+    def clone(self):
+        return type_dumper_t(self.instance, self.type)
+
+    def visit_bool(self):
+        self.print_instance('%i')
+        
+    def visit_char(self):
+        #self.print_instance('%i')
+        self.print_instance('0x%x')
+        
+    def visit_unsigned_char(self):
+        #self.print_instance('%u')
+        self.print_instance('0x%x')
+
+    def visit_signed_char(self):
+        #self.print_instance('%i')
+        self.print_instance('0x%x')
+    
+    def visit_wchar(self):
+        self.print_instance('0x%x')
+        
+    def visit_short_int(self):
+        #self.print_instance('%i')
+        self.print_instance('0x%x')
+        
+    def visit_short_unsigned_int(self):
+        #self.print_instance('%u')
+        self.print_instance('0x%x')
+        
+    def visit_int(self):
+        #self.print_instance('%i')
+        self.print_instance('0x%x')
+        
+    def visit_unsigned_int(self):
+        #self.print_instance('%u')
+        self.print_instance('0x%x')
+        
+    def visit_long_int(self):
+        #self.print_instance('%li')
+        self.print_instance('0x%lx')
+        
+    def visit_long_unsigned_int(self):
+        #self.print_instance('%lu')
+        self.print_instance('%0xlx')
+        
+    def visit_long_long_int(self):
+        #self.print_instance('%lli')
+        self.print_instance('%0xllx')
+        
+    def visit_long_long_unsigned_int(self):
+        #self.print_instance('%llu')
+        self.print_instance('0x%llx')
+        
+    def visit_float(self):
+        self.print_instance('%f')
+        
+    def visit_double(self):
+        self.print_instance('%f')
+        
+    def visit_array(self):
+        for i in range(type_traits.array_size(self.type)):
+            dump_type(self.stream, self.instance + '[%i]' % i, type_traits.base_type(self.type))
+
+    def visit_pointer(self):
+        self.print_instance('%p')
+
+    def visit_declarated(self):
+        #stream.write('decl = %r\n' % self.type.decl_string)
+        decl = type_traits.remove_declarated(self.type)
+        dump_decl(self.stream, self.instance, decl)
+
+    def print_instance(self, format):
+        self.stream.write('   debug_printf("\\t\\t%s = %s\\n", %s);\n' % (self.instance, format, "(*ptr)" + self.instance))
+
+
+
+def dump_type(stream, instance, type_):
+    type_ = type_traits.remove_alias(type_)
+    visitor = type_dumper_t(stream, instance, type_)
+    algorithm.apply_visitor(visitor, type_)
+
+
+def dump_struct_interface(stream, class_, suffix = ';'):
+    name = class_.name
+    assert name.startswith('brw_');
+    name = name[:4] + 'dump_' + name[4:]
+    stream.write('void\n')
+    stream.write('%s(const struct %s *ptr)%s\n' % (name, class_.name, suffix))
+
+
+def dump_struct_implementation(stream, decls, class_):
+    dump_struct_interface(stream, class_, suffix = '')
+    stream.write('{\n')
+    dump_decl(stream, '', class_)
+    stream.write('}\n')
+    stream.write('\n')
+
+
+def dump_header(stream):
+    stream.write(copyright.strip() + '\n')
+    stream.write('\n')
+    stream.write('/**\n')
+    stream.write(' * @file\n')
+    stream.write(' * Dump i965 data structures.\n')
+    stream.write(' *\n')
+    stream.write(' * Generated automatically from brw_structs.h by brw_structs_dump.py.\n')
+    stream.write(' */\n')
+    stream.write('\n')
+
+
+def dump_interfaces(decls, global_ns, names):
+    stream = open('brw_structs_dump.h', 'wt')
+    
+    dump_header(stream)
+    
+    stream.write('#ifndef BRW_STRUCTS_DUMP_H\n')
+    stream.write('#define BRW_STRUCTS_DUMP_H\n')
+    stream.write('\n')
+    
+    for name in names:
+        stream.write('struct %s;\n' % (name,))
+    stream.write('\n')
+
+    for name in names:
+        (class_,) = global_ns.classes(name = name)
+        dump_struct_interface(stream, class_)
+        stream.write('\n')
+    stream.write('\n')
+
+    stream.write('#endif /* BRW_STRUCTS_DUMP_H */\n')
+
+
+def dump_implementations(decls, global_ns, names):
+    stream = open('brw_structs_dump.c', 'wt')
+    
+    dump_header(stream)
+
+    stream.write('#include "util/u_debug.h"\n')
+    stream.write('\n')
+    stream.write('#include "brw_types.h"\n')
+    stream.write('#include "brw_structs.h"\n')
+    stream.write('#include "brw_structs_dump.h"\n')
+    stream.write('\n')
+
+    for name in names:
+        (class_,) = global_ns.classes(name = name)
+        dump_struct_implementation(stream, decls, class_)
+
+
+def decl_filter(decl):
+    '''Filter the declarations we're interested in'''
+    name = decl.name
+    return name.startswith('brw_') and name not in ('brw_instruction',) 
+
+
+def main():
+
+    config = parser.config_t(
+        include_paths = [
+            '../../include',
+        ],
+        compiler = 'gcc',
+    )
+
+    headers = [
+        'brw_types.h', 
+        'brw_structs.h', 
+    ]
+
+    decls = parser.parse(headers, config, parser.COMPILATION_MODE.ALL_AT_ONCE)
+    global_ns = declarations.get_global_namespace(decls)
+
+    names = []
+    for class_ in global_ns.classes(decl_filter):
+        names.append(class_.name)
+    names.sort()
+
+    dump_interfaces(decls, global_ns, names)
+    dump_implementations(decls, global_ns, names)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/src/gallium/drivers/i965/brw_swtnl.c b/src/gallium/drivers/i965/brw_swtnl.c
new file mode 100644
index 0000000..464013e
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_swtnl.c
@@ -0,0 +1,95 @@
+
+#include "brw_context.h"
+#include "brw_pipe_rast.h"
+
+
+static GLboolean need_swtnl( struct brw_context *brw )
+{
+   const struct pipe_rasterizer_state *rast = &brw->curr.rast->templ;
+
+   /* If we don't require strict OpenGL conformance, never 
+    * use fallbacks.  If we're forcing fallbacks, always
+    * use fallfacks.
+    */
+   if (brw->flags.no_swtnl)
+      return FALSE;
+
+   if (brw->flags.force_swtnl)
+      return TRUE;
+
+   /* Exceeding hw limits on number of VS inputs?
+    */
+   if (brw->curr.num_vertex_elements == 0 ||
+       brw->curr.num_vertex_elements >= BRW_VEP_MAX) {
+      return TRUE;
+   }
+
+   /* Position array with zero stride?
+    *
+    * XXX: position isn't always at zero...
+    * XXX: eliminate zero-stride arrays
+    */
+   {
+      int ve0_vb = brw->curr.vertex_element[0].vertex_buffer_index;
+      
+      if (brw->curr.vertex_buffer[ve0_vb].stride == 0)
+	 return TRUE;
+   }
+
+   /* XXX: short-circuit
+    */
+   return FALSE;
+
+   if (brw->reduced_primitive == PIPE_PRIM_TRIANGLES) {
+      if (rast->poly_smooth)
+	 return TRUE;
+
+   }
+   
+   if (brw->reduced_primitive == PIPE_PRIM_LINES ||
+       (brw->reduced_primitive == PIPE_PRIM_TRIANGLES &&
+	(rast->fill_cw == PIPE_POLYGON_MODE_LINE ||
+	 rast->fill_ccw == PIPE_POLYGON_MODE_LINE)))
+   {
+      /* BRW hardware will do AA lines, but they are non-conformant it
+       * seems.  TBD whether we keep this fallback:
+       */
+      if (rast->line_smooth)
+	 return TRUE;
+
+      /* XXX: was a fallback in mesa (gs doesn't get enough
+       * information to know when to reset stipple counter), but there
+       * must be a way around it.
+       */
+      if (rast->line_stipple_enable &&
+	  (brw->reduced_primitive == PIPE_PRIM_TRIANGLES ||
+	   brw->primitive == PIPE_PRIM_LINE_LOOP || 
+	   brw->primitive == PIPE_PRIM_LINE_STRIP))
+	 return TRUE;
+   }
+
+   
+   if (brw->reduced_primitive == PIPE_PRIM_POINTS ||
+       (brw->reduced_primitive == PIPE_PRIM_TRIANGLES &&
+	(rast->fill_cw == PIPE_POLYGON_MODE_POINT ||
+	 rast->fill_ccw == PIPE_POLYGON_MODE_POINT)))
+   {
+      if (rast->point_smooth)
+	 return TRUE;
+   }
+
+   /* BRW hardware doesn't handle CLAMP texturing correctly;
+    * brw_wm_sampler_state:translate_wrap_mode() treats CLAMP
+    * as CLAMP_TO_EDGE instead.  If we're using CLAMP, and
+    * we want strict conformance, force the fallback.
+    *
+    * XXX: need a workaround for this.
+    */
+      
+   /* Nothing stopping us from the fast path now */
+   return FALSE;
+}
+
+
+
+
diff --git a/src/gallium/drivers/i965/brw_types.h b/src/gallium/drivers/i965/brw_types.h
new file mode 100644
index 0000000..89e08a5
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_types.h
@@ -0,0 +1,21 @@
+#ifndef BRW_TYPES_H
+#define BRW_TYPES_H
+
+#include "pipe/p_compiler.h"
+
+typedef uint32_t GLuint;
+typedef uint8_t GLubyte;
+typedef uint16_t GLushort;
+typedef int32_t GLint;
+typedef int8_t GLbyte;
+typedef int16_t GLshort;
+typedef float GLfloat;
+
+/* no GLenum, translate all away */
+
+typedef uint8_t GLboolean;
+
+#define GL_FALSE FALSE
+#define GL_TRUE TRUE
+
+#endif
diff --git a/src/gallium/drivers/i965/brw_urb.c b/src/gallium/drivers/i965/brw_urb.c
new file mode 100644
index 0000000..907ec56
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_urb.c
@@ -0,0 +1,263 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+        
+
+
+#include "brw_batchbuffer.h"
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+#include "brw_debug.h"
+
+#define VS 0
+#define GS 1
+#define CLP 2
+#define SF 3
+#define CS 4
+
+/** @file brw_urb.c
+ *
+ * Manages the division of the URB space between the various fixed-function
+ * units.
+ *
+ * See the Thread Initiation Management section of the GEN4 B-Spec, and
+ * the individual *_STATE structures for restrictions on numbers of
+ * entries and threads.
+ */
+
+/*
+ * Generally, a unit requires a min_nr_entries based on how many entries
+ * it produces before the downstream unit gets unblocked and can use and
+ * dereference some of its handles.
+ *
+ * The SF unit preallocates a PUE at the start of thread dispatch, and only
+ * uses that one.  So it requires one entry per thread.
+ *
+ * For CLIP, the SF unit will hold the previous primitive while the
+ * next is getting assembled, meaning that linestrips require 3 CLIP VUEs
+ * (vertices) to ensure continued processing, trifans require 4, and tristrips
+ * require 5.  There can be 1 or 2 threads, and each has the same requirement.
+ *
+ * GS has the same requirement as CLIP, but it never handles tristrips,
+ * so we can lower the minimum to 4 for the POLYGONs (trifans) it produces.
+ * We only run it single-threaded.
+ *
+ * For VS, the number of entries may be 8, 12, 16, or 32 (or 64 on G4X).
+ * Each thread processes 2 preallocated VUEs (vertices) at a time, and they
+ * get streamed down as soon as threads processing earlier vertices get
+ * theirs accepted.
+ *
+ * Each unit will take the number of URB entries we give it (based on the
+ * entry size calculated in brw_vs_emit.c for VUEs, brw_sf_emit.c for PUEs,
+ * and brw_curbe.c for the CURBEs) and decide its maximum number of
+ * threads it can support based on that. in brw_*_state.c.
+ *
+ * XXX: Are the min_entry_size numbers useful?
+ * XXX: Verify min_nr_entries, esp for VS.
+ * XXX: Verify SF min_entry_size.
+ */
+static const struct urb_limits {
+   GLuint min_nr_entries;
+   GLuint preferred_nr_entries;
+   GLuint min_entry_size;
+   GLuint max_entry_size;
+} limits[CS+1] = {
+   { 16, 32, 1, 5 },			/* vs */
+   { 4, 8,  1, 5 },			/* gs */
+   { 5, 10,  1, 5 },			/* clp */
+   { 1, 8,  1, 12 },		        /* sf */
+   { 1, 4,  1, 32 }			/* cs */
+};
+
+
+static GLboolean check_urb_layout( struct brw_context *brw )
+{
+   brw->urb.vs_start = 0;
+   brw->urb.gs_start = brw->urb.nr_vs_entries * brw->urb.vsize;
+   brw->urb.clip_start = brw->urb.gs_start + brw->urb.nr_gs_entries * brw->urb.vsize;
+   brw->urb.sf_start = brw->urb.clip_start + brw->urb.nr_clip_entries * brw->urb.vsize;
+   brw->urb.cs_start = brw->urb.sf_start + brw->urb.nr_sf_entries * brw->urb.sfsize;
+
+   return brw->urb.cs_start + brw->urb.nr_cs_entries * brw->urb.csize <= URB_SIZES(brw);
+}
+
+/* Most minimal update, forces re-emit of URB fence packet after GS
+ * unit turned on/off.
+ */
+static int recalculate_urb_fence( struct brw_context *brw )
+{
+   GLuint csize = brw->curbe.total_size;
+   GLuint vsize = brw->vs.prog_data->urb_entry_size;
+   GLuint sfsize = brw->sf.prog_data->urb_entry_size;
+
+   if (csize < limits[CS].min_entry_size)
+      csize = limits[CS].min_entry_size;
+
+   if (vsize < limits[VS].min_entry_size)
+      vsize = limits[VS].min_entry_size;
+
+   if (sfsize < limits[SF].min_entry_size)
+      sfsize = limits[SF].min_entry_size;
+
+   if (brw->urb.vsize < vsize ||
+       brw->urb.sfsize < sfsize ||
+       brw->urb.csize < csize ||
+       (brw->urb.constrained && (brw->urb.vsize > vsize ||
+				 brw->urb.sfsize > sfsize ||
+				 brw->urb.csize > csize))) {
+      
+
+      brw->urb.csize = csize;
+      brw->urb.sfsize = sfsize;
+      brw->urb.vsize = vsize;
+
+      brw->urb.nr_vs_entries = limits[VS].preferred_nr_entries;	
+      brw->urb.nr_gs_entries = limits[GS].preferred_nr_entries;	
+      brw->urb.nr_clip_entries = limits[CLP].preferred_nr_entries;
+      brw->urb.nr_sf_entries = limits[SF].preferred_nr_entries;	
+      brw->urb.nr_cs_entries = limits[CS].preferred_nr_entries;	
+
+      brw->urb.constrained = 0;
+
+      if (BRW_IS_IGDNG(brw)) {
+         brw->urb.nr_vs_entries = 128;
+         brw->urb.nr_sf_entries = 48;
+         if (check_urb_layout(brw)) {
+            goto done;
+         } else {
+            brw->urb.constrained = 1;
+            brw->urb.nr_vs_entries = limits[VS].preferred_nr_entries;
+            brw->urb.nr_sf_entries = limits[SF].preferred_nr_entries;
+         }
+      } else if (BRW_IS_G4X(brw)) {
+	 brw->urb.nr_vs_entries = 64;
+	 if (check_urb_layout(brw)) {
+	    goto done;
+	 } else {
+	    brw->urb.constrained = 1;
+	    brw->urb.nr_vs_entries = limits[VS].preferred_nr_entries;
+	 }
+      }
+
+      if (BRW_DEBUG & DEBUG_MIN_URB) {
+	 brw->urb.nr_vs_entries = limits[VS].min_nr_entries;	
+	 brw->urb.nr_gs_entries = limits[GS].min_nr_entries;	
+	 brw->urb.nr_clip_entries = limits[CLP].min_nr_entries;
+	 brw->urb.nr_sf_entries = limits[SF].min_nr_entries;	
+	 brw->urb.nr_cs_entries = limits[CS].min_nr_entries;	
+	 brw->urb.constrained = 1;
+      }
+
+      if (!check_urb_layout(brw)) {
+	 brw->urb.nr_vs_entries = limits[VS].min_nr_entries;	
+	 brw->urb.nr_gs_entries = limits[GS].min_nr_entries;	
+	 brw->urb.nr_clip_entries = limits[CLP].min_nr_entries;
+	 brw->urb.nr_sf_entries = limits[SF].min_nr_entries;	
+	 brw->urb.nr_cs_entries = limits[CS].min_nr_entries;	
+
+	 /* Mark us as operating with constrained nr_entries, so that next
+	  * time we recalculate we'll resize the fences in the hope of
+	  * escaping constrained mode and getting back to normal performance.
+	  */
+	 brw->urb.constrained = 1;
+	 
+	 if (!check_urb_layout(brw)) {
+	    /* This is impossible, given the maximal sizes of urb
+	     * entries and the values for minimum nr of entries
+	     * provided above.
+	     */
+	    debug_printf("couldn't calculate URB layout!\n");
+	    exit(1);
+	 }
+	 
+	 if (BRW_DEBUG & (DEBUG_URB|DEBUG_FALLBACKS))
+	    debug_printf("URB CONSTRAINED\n");
+      }
+
+done:
+      if (BRW_DEBUG & DEBUG_URB)
+	 debug_printf("URB fence: %d ..VS.. %d ..GS.. %d ..CLP.. %d ..SF.. %d ..CS.. %d\n",
+		      brw->urb.vs_start,
+		      brw->urb.gs_start,
+		      brw->urb.clip_start,
+		      brw->urb.sf_start,
+		      brw->urb.cs_start, 
+		      URB_SIZES(brw));
+      
+      brw->state.dirty.brw |= BRW_NEW_URB_FENCE;
+   }
+
+   return 0;
+}
+
+
+const struct brw_tracked_state brw_recalculate_urb_fence = {
+   .dirty = {
+      .mesa = 0,
+      .brw = BRW_NEW_CURBE_OFFSETS,
+      .cache = (CACHE_NEW_VS_PROG |
+		CACHE_NEW_SF_PROG)
+   },
+   .prepare = recalculate_urb_fence
+};
+
+
+
+
+
+int brw_upload_urb_fence(struct brw_context *brw)
+{
+   struct brw_urb_fence uf;
+   memset(&uf, 0, sizeof(uf));
+
+   uf.header.opcode = CMD_URB_FENCE;
+   uf.header.length = sizeof(uf)/4-2;
+   uf.header.vs_realloc = 1;
+   uf.header.gs_realloc = 1;
+   uf.header.clp_realloc = 1;
+   uf.header.sf_realloc = 1;
+   uf.header.vfe_realloc = 1;
+   uf.header.cs_realloc = 1;
+
+   /* The ordering below is correct, not the layout in the
+    * instruction.
+    *
+    * There are 256/384 urb reg pairs in total.
+    */
+   uf.bits0.vs_fence  = brw->urb.gs_start;
+   uf.bits0.gs_fence  = brw->urb.clip_start; 
+   uf.bits0.clp_fence = brw->urb.sf_start; 
+   uf.bits1.sf_fence  = brw->urb.cs_start; 
+   uf.bits1.cs_fence  = URB_SIZES(brw);
+
+   BRW_BATCH_STRUCT(brw, &uf);
+   return 0;
+}
diff --git a/src/gallium/drivers/i965/brw_util.c b/src/gallium/drivers/i965/brw_util.c
new file mode 100644
index 0000000..458058d
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_util.c
@@ -0,0 +1,38 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+         
+
+#include "brw_util.h"
+#include "brw_defines.h"
+
+
+
+
diff --git a/src/gallium/drivers/i965/brw_util.h b/src/gallium/drivers/i965/brw_util.h
new file mode 100644
index 0000000..b5f9a36
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_util.h
@@ -0,0 +1,44 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+          
+
+#ifndef BRW_UTIL_H
+#define BRW_UTIL_H
+
+#include "brw_types.h"
+
+extern GLuint brw_count_bits( GLuint val );
+extern GLuint brw_translate_blend_factor( unsigned factor );
+extern GLuint brw_translate_blend_equation( unsigned mode );
+
+
+
+#endif
diff --git a/src/gallium/drivers/i965/brw_vs.c b/src/gallium/drivers/i965/brw_vs.c
new file mode 100644
index 0000000..e3ea5a3
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_vs.c
@@ -0,0 +1,131 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "tgsi/tgsi_dump.h"           
+
+#include "brw_context.h"
+#include "brw_vs.h"
+#include "brw_util.h"
+#include "brw_state.h"
+#include "brw_pipe_rast.h"
+
+
+
+static enum pipe_error do_vs_prog( struct brw_context *brw, 
+                                   struct brw_vertex_shader *vp,
+                                   struct brw_vs_prog_key *key,
+                                   struct brw_winsys_buffer **bo_out)
+{
+   enum pipe_error ret;
+   GLuint program_size;
+   const GLuint *program;
+   struct brw_vs_compile c;
+
+   memset(&c, 0, sizeof(c));
+   memcpy(&c.key, key, sizeof(*key));
+
+   brw_init_compile(brw, &c.func);
+   c.vp = vp;
+
+   c.prog_data.nr_outputs = vp->info.num_outputs;
+   c.prog_data.nr_inputs = vp->info.num_inputs;
+
+   if (1)
+      tgsi_dump(c.vp->tokens, 0);
+
+   /* Emit GEN4 code.
+    */
+   brw_vs_emit(&c);
+
+   /* get the program
+    */
+   ret = brw_get_program(&c.func, &program, &program_size);
+   if (ret)
+      return ret;
+
+   ret = brw_upload_cache( &brw->cache, BRW_VS_PROG,
+                           &c.key, brw_vs_prog_key_size(&c.key),
+                           NULL, 0,
+                           program, program_size,
+                           &c.prog_data,
+                           &brw->vs.prog_data,
+                           bo_out);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+
+static enum pipe_error brw_upload_vs_prog(struct brw_context *brw)
+{
+   struct brw_vs_prog_key key;
+   struct brw_vertex_shader *vp = brw->curr.vertex_shader;
+   struct brw_fs_signature *sig = &brw->curr.fragment_shader->signature;
+   enum pipe_error ret;
+
+   memset(&key, 0, sizeof(key));
+
+   key.program_string_id = vp->id;
+   key.nr_userclip = brw->curr.ucp.nr;
+
+   memcpy(&key.fs_signature, sig, brw_fs_signature_size(sig));
+
+
+   /* Make an early check for the key.
+    */
+   if (brw_search_cache(&brw->cache, BRW_VS_PROG,
+                        &key, brw_vs_prog_key_size(&key),
+                        NULL, 0,
+                        &brw->vs.prog_data,
+                        &brw->vs.prog_bo))
+      return PIPE_OK;
+
+   ret = do_vs_prog(brw, vp, &key, &brw->vs.prog_bo);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+
+/* See brw_vs.c:
+ */
+const struct brw_tracked_state brw_vs_prog = {
+   .dirty = {
+      .mesa  = (PIPE_NEW_CLIP | 
+                PIPE_NEW_RAST |
+                PIPE_NEW_FRAGMENT_SIGNATURE),
+      .brw   = BRW_NEW_VERTEX_PROGRAM,
+      .cache = 0
+   },
+   .prepare = brw_upload_vs_prog
+};
diff --git a/src/gallium/drivers/i965/brw_vs.h b/src/gallium/drivers/i965/brw_vs.h
new file mode 100644
index 0000000..944d88c
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_vs.h
@@ -0,0 +1,106 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+            
+
+#ifndef BRW_VS_H
+#define BRW_VS_H
+
+
+#include "brw_context.h"
+#include "brw_eu.h"
+
+
+struct brw_vs_prog_key {
+   GLuint program_string_id;
+   GLuint nr_userclip:4;
+   GLuint pad:26;
+   struct brw_fs_signature fs_signature;
+};
+
+#define brw_vs_prog_key_size(s) (offsetof(struct brw_vs_prog_key, fs_signature) + \
+                                 brw_fs_signature_size(&(s)->fs_signature))
+
+
+#define MAX_IF_DEPTH 32
+#define MAX_LOOP_DEPTH 32
+
+struct brw_vs_compile {
+   struct brw_compile func;
+   struct brw_vs_prog_key key;
+   struct brw_vs_prog_data prog_data;
+   struct brw_chipset chipset;
+
+   struct brw_vertex_shader *vp;
+
+   GLuint nr_inputs;
+   GLuint nr_outputs;
+   GLuint nr_immediates;
+   GLfloat immediate[128][4];
+
+   GLuint overflow_grf_start;
+   GLuint overflow_count;
+
+   GLuint first_tmp;
+   GLuint last_tmp;
+
+   struct brw_reg r0;
+   struct brw_reg r1;
+   struct brw_reg regs[TGSI_FILE_COUNT][128];
+   struct brw_reg tmp;
+   struct brw_reg stack;
+
+   struct {	
+       GLboolean used_in_src;
+       struct brw_reg reg;
+   } output_regs[128];
+
+   struct brw_reg userplane[6];
+
+   /** we may need up to 3 constants per instruction (if use_const_buffer) */
+   struct {
+      GLint index;
+      struct brw_reg reg;
+   } current_const[3];
+
+   struct brw_instruction *if_inst[MAX_IF_DEPTH];
+   struct brw_instruction *loop_inst[MAX_LOOP_DEPTH];
+   GLuint insn;
+   GLuint if_depth;
+   GLuint loop_depth;
+   GLuint end_offset;
+
+   struct brw_indirect stack_index;
+};
+
+
+void brw_vs_emit( struct brw_vs_compile *c );
+
+#endif
diff --git a/src/gallium/drivers/i965/brw_vs_emit.c b/src/gallium/drivers/i965/brw_vs_emit.c
new file mode 100644
index 0000000..8a16205
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_vs_emit.c
@@ -0,0 +1,1654 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "pipe/p_shader_tokens.h"
+            
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_info.h"
+
+#include "brw_context.h"
+#include "brw_vs.h"
+#include "brw_debug.h"
+#include "brw_disasm.h"
+
+/* Choose one of the 4 vec4's which can be packed into each 16-wide reg.
+ */
+static INLINE struct brw_reg brw_vec4_grf_repeat( GLuint reg, GLuint slot )
+{
+   int nr = reg + slot/2;
+   int subnr = (slot%2) * 4;
+
+   return stride(brw_vec4_grf(nr, subnr), 0, 4, 1);
+}
+
+
+static struct brw_reg get_tmp( struct brw_vs_compile *c )
+{
+   struct brw_reg tmp = brw_vec8_grf(c->last_tmp, 0);
+
+   if (++c->last_tmp > c->prog_data.total_grf)
+      c->prog_data.total_grf = c->last_tmp;
+
+   return tmp;
+}
+
+static void release_tmp( struct brw_vs_compile *c, struct brw_reg tmp )
+{
+   if (tmp.nr == c->last_tmp-1)
+      c->last_tmp--;
+}
+			       
+static void release_tmps( struct brw_vs_compile *c )
+{
+   c->last_tmp = c->first_tmp;
+}
+
+
+static boolean is_position_output( struct brw_vs_compile *c,
+                                   unsigned vs_output )
+{
+   const struct brw_vertex_shader *vs = c->vp;
+   unsigned semantic = vs->info.output_semantic_name[vs_output];
+   unsigned index = vs->info.output_semantic_index[vs_output];
+      
+   return (semantic == TGSI_SEMANTIC_POSITION &&
+           index == 0);
+}
+
+
+static boolean find_output_slot( struct brw_vs_compile *c,
+                                  unsigned vs_output,
+                                  unsigned *fs_input_slot )
+{
+   const struct brw_vertex_shader *vs = c->vp;
+   unsigned semantic = vs->info.output_semantic_name[vs_output];
+   unsigned index = vs->info.output_semantic_index[vs_output];
+   unsigned i;
+
+   for (i = 0; i < c->key.fs_signature.nr_inputs; i++) {
+      if (c->key.fs_signature.input[i].semantic == semantic &&
+          c->key.fs_signature.input[i].semantic_index == index) {
+         *fs_input_slot = i;
+         return TRUE;
+      }
+   }
+
+   return FALSE;
+}
+
+
+/**
+ * Preallocate GRF register before code emit.
+ * Do things as simply as possible.  Allocate and populate all regs
+ * ahead of time.
+ */
+static void brw_vs_alloc_regs( struct brw_vs_compile *c )
+{
+   GLuint i, reg = 0, subreg = 0, mrf;
+   int attributes_in_vue;
+
+   /* Determine whether to use a real constant buffer or use a block
+    * of GRF registers for constants.  The later is faster but only
+    * works if everything fits in the GRF.
+    * XXX this heuristic/check may need some fine tuning...
+    */
+   if (c->vp->info.file_max[TGSI_FILE_CONSTANT] + 1 +
+       c->vp->info.file_max[TGSI_FILE_IMMEDIATE] + 1 +
+       c->vp->info.file_max[TGSI_FILE_TEMPORARY] + 1 + 21 > BRW_MAX_GRF)
+      c->vp->use_const_buffer = GL_TRUE;
+   else {
+      /* XXX: immediates can go elsewhere if necessary:
+       */
+      assert(c->vp->info.file_max[TGSI_FILE_IMMEDIATE] + 1 +
+	     c->vp->info.file_max[TGSI_FILE_TEMPORARY] + 1 + 21 <= BRW_MAX_GRF);
+
+      c->vp->use_const_buffer = GL_FALSE;
+   }
+
+   /*printf("use_const_buffer = %d\n", c->vp->use_const_buffer);*/
+
+   /* r0 -- reserved as usual
+    */
+   c->r0 = brw_vec8_grf(reg, 0);
+   reg++;
+
+   /* User clip planes from curbe: 
+    */
+   if (c->key.nr_userclip) {
+      /* Skip over fixed planes:  Or never read them into vs unit?
+       */
+      subreg += 6;
+
+      for (i = 0; i < c->key.nr_userclip; i++, subreg++) {
+	 c->userplane[i] = 
+            stride( brw_vec4_grf(reg+subreg/2, (subreg%2) * 4), 0, 4, 1);
+      }     
+
+      /* Deal with curbe alignment:
+       */
+      subreg = align(subreg, 2);
+      /*reg += ((6 + c->key.nr_userclip + 3) / 4) * 2;*/
+   }
+
+
+   /* Immediates: always in the curbe.
+    *
+    * XXX: Can try to encode some immediates as brw immediates
+    * XXX: Make sure ureg sets minimal immediate size and respect it
+    * here.
+    */
+   for (i = 0; i < c->vp->info.immediate_count; i++, subreg++) {
+      c->regs[TGSI_FILE_IMMEDIATE][i] = 
+         stride( brw_vec4_grf(reg+subreg/2, (subreg%2) * 4), 0, 4, 1);
+   }
+   c->prog_data.nr_params = c->vp->info.immediate_count * 4;
+
+
+   /* Vertex constant buffer.
+    *
+    * Constants from the buffer can be either cached in the curbe or
+    * loaded as needed from the actual constant buffer.
+    */
+   if (!c->vp->use_const_buffer) {
+      GLuint nr_params = c->vp->info.file_max[TGSI_FILE_CONSTANT] + 1;
+
+      for (i = 0; i < nr_params; i++, subreg++) {
+         c->regs[TGSI_FILE_CONSTANT][i] =
+            stride( brw_vec4_grf(reg+subreg/2, (subreg%2) * 4), 0, 4, 1);
+      }
+
+      c->prog_data.nr_params += nr_params * 4;
+   }
+
+   /* All regs allocated
+    */
+   reg += (subreg + 1) / 2;
+   c->prog_data.curb_read_length = reg - 1;
+
+
+   /* Allocate input regs:  
+    */
+   c->nr_inputs = c->vp->info.num_inputs;
+   for (i = 0; i < c->nr_inputs; i++) {
+      c->regs[TGSI_FILE_INPUT][i] = brw_vec8_grf(reg, 0);
+      reg++;
+   }
+
+   /* If there are no inputs, we'll still be reading one attribute's worth
+    * because it's required -- see urb_read_length setting.
+    */
+   if (c->nr_inputs == 0)
+      reg++;
+
+
+
+   /* Allocate outputs.  The non-position outputs go straight into message regs.
+    */
+   c->nr_outputs = c->prog_data.nr_outputs;
+
+   if (c->chipset.is_igdng)
+      mrf = 8;
+   else
+      mrf = 4;
+
+   
+   if (c->key.fs_signature.nr_inputs > BRW_MAX_MRF) {
+      c->overflow_grf_start = reg;
+      c->overflow_count = c->key.fs_signature.nr_inputs - BRW_MAX_MRF;
+      reg += c->overflow_count;
+   }
+
+   /* XXX: need to access vertex output semantics here:
+    */
+   for (i = 0; i < c->nr_outputs; i++) {
+      unsigned slot;
+
+      /* XXX: Put output position in slot zero always.  Clipper, etc,
+       * need access to this reg.
+       */
+      if (is_position_output(c, i)) {
+	 c->regs[TGSI_FILE_OUTPUT][i] = brw_vec8_grf(reg, 0); /* copy to mrf 0 */
+	 reg++;
+      }
+      else if (find_output_slot(c, i, &slot)) {
+         
+         if (0 /* is_psize_output(c, i) */ ) {
+            /* c->psize_out.grf = reg; */
+            /* c->psize_out.mrf = i; */
+         }
+         
+         /* The first (16-4) outputs can go straight into the message regs.
+          */
+         if (slot + mrf < BRW_MAX_MRF) {
+            c->regs[TGSI_FILE_OUTPUT][i] = brw_message_reg(slot + mrf);
+         }
+         else {
+            int grf = c->overflow_grf_start + slot - BRW_MAX_MRF;
+            c->regs[TGSI_FILE_OUTPUT][i] = brw_vec8_grf(grf, 0);
+         }
+      }
+      else {
+         c->regs[TGSI_FILE_OUTPUT][i] = brw_null_reg();
+      }
+   }     
+
+   /* Allocate program temporaries:
+    */
+   
+   for (i = 0; i < c->vp->info.file_max[TGSI_FILE_TEMPORARY]+1; i++) {
+      c->regs[TGSI_FILE_TEMPORARY][i] = brw_vec8_grf(reg, 0);
+      reg++;
+   }
+
+   /* Address reg(s).  Don't try to use the internal address reg until
+    * deref time.
+    */
+   for (i = 0; i < c->vp->info.file_max[TGSI_FILE_ADDRESS]+1; i++) {
+      c->regs[TGSI_FILE_ADDRESS][i] =  brw_reg(BRW_GENERAL_REGISTER_FILE,
+					     reg,
+					     0,
+					     BRW_REGISTER_TYPE_D,
+					     BRW_VERTICAL_STRIDE_8,
+					     BRW_WIDTH_8,
+					     BRW_HORIZONTAL_STRIDE_1,
+					     BRW_SWIZZLE_XXXX,
+					     BRW_WRITEMASK_X);
+      reg++;
+   }
+
+   if (c->vp->use_const_buffer) {
+      for (i = 0; i < 3; i++) {
+         c->current_const[i].index = -1;
+         c->current_const[i].reg = brw_vec8_grf(reg, 0);
+         reg++;
+      }
+   }
+
+#if 0
+   for (i = 0; i < 128; i++) {
+      if (c->output_regs[i].used_in_src) {
+         c->output_regs[i].reg = brw_vec8_grf(reg, 0);
+         reg++;
+      }
+   }
+#endif
+
+   if (c->vp->has_flow_control) {
+      c->stack =  brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg, 0);
+      reg += 2;
+   }
+
+   /* Some opcodes need an internal temporary:
+    */
+   c->first_tmp = reg;
+   c->last_tmp = reg;		/* for allocation purposes */
+
+   /* Each input reg holds data from two vertices.  The
+    * urb_read_length is the number of registers read from *each*
+    * vertex urb, so is half the amount:
+    */
+   c->prog_data.urb_read_length = (c->nr_inputs + 1) / 2;
+
+   /* Setting this field to 0 leads to undefined behavior according to the
+    * the VS_STATE docs.  Our VUEs will always have at least one attribute
+    * sitting in them, even if it's padding.
+    */
+   if (c->prog_data.urb_read_length == 0)
+      c->prog_data.urb_read_length = 1;
+
+   /* The VS VUEs are shared by VF (outputting our inputs) and VS, so size
+    * them to fit the biggest thing they need to.
+    */
+   attributes_in_vue = MAX2(c->nr_outputs, c->nr_inputs);
+
+   if (c->chipset.is_igdng)
+      c->prog_data.urb_entry_size = (attributes_in_vue + 6 + 3) / 4;
+   else
+      c->prog_data.urb_entry_size = (attributes_in_vue + 2 + 3) / 4;
+
+   c->prog_data.total_grf = reg;
+
+   if (BRW_DEBUG & DEBUG_VS) {
+      debug_printf("%s NumAddrRegs %d\n", __FUNCTION__, 
+		   c->vp->info.file_max[TGSI_FILE_ADDRESS]+1);
+      debug_printf("%s NumTemps %d\n", __FUNCTION__,
+		   c->vp->info.file_max[TGSI_FILE_TEMPORARY]+1);
+      debug_printf("%s reg = %d\n", __FUNCTION__, reg);
+   }
+}
+
+
+/**
+ * If an instruction uses a temp reg both as a src and the dest, we
+ * sometimes need to allocate an intermediate temporary.
+ */
+static void unalias1( struct brw_vs_compile *c,
+		      struct brw_reg dst,
+		      struct brw_reg arg0,
+		      void (*func)( struct brw_vs_compile *,
+				    struct brw_reg,
+				    struct brw_reg ))
+{
+   if (dst.file == arg0.file && dst.nr == arg0.nr) {
+      struct brw_compile *p = &c->func;
+      struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask);
+      func(c, tmp, arg0);
+      brw_MOV(p, dst, tmp);
+      release_tmp(c, tmp);
+   }
+   else {
+      func(c, dst, arg0);
+   }
+}
+
+/**
+ * \sa unalias2
+ * Checkes if 2-operand instruction needs an intermediate temporary.
+ */
+static void unalias2( struct brw_vs_compile *c,
+		      struct brw_reg dst,
+		      struct brw_reg arg0,
+		      struct brw_reg arg1,
+		      void (*func)( struct brw_vs_compile *,
+				    struct brw_reg,
+				    struct brw_reg,
+				    struct brw_reg ))
+{
+   if ((dst.file == arg0.file && dst.nr == arg0.nr) ||
+       (dst.file == arg1.file && dst.nr == arg1.nr)) {
+      struct brw_compile *p = &c->func;
+      struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask);
+      func(c, tmp, arg0, arg1);
+      brw_MOV(p, dst, tmp);
+      release_tmp(c, tmp);
+   }
+   else {
+      func(c, dst, arg0, arg1);
+   }
+}
+
+/**
+ * \sa unalias2
+ * Checkes if 3-operand instruction needs an intermediate temporary.
+ */
+static void unalias3( struct brw_vs_compile *c,
+		      struct brw_reg dst,
+		      struct brw_reg arg0,
+		      struct brw_reg arg1,
+		      struct brw_reg arg2,
+		      void (*func)( struct brw_vs_compile *,
+				    struct brw_reg,
+				    struct brw_reg,
+				    struct brw_reg,
+				    struct brw_reg ))
+{
+   if ((dst.file == arg0.file && dst.nr == arg0.nr) ||
+       (dst.file == arg1.file && dst.nr == arg1.nr) ||
+       (dst.file == arg2.file && dst.nr == arg2.nr)) {
+      struct brw_compile *p = &c->func;
+      struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask);
+      func(c, tmp, arg0, arg1, arg2);
+      brw_MOV(p, dst, tmp);
+      release_tmp(c, tmp);
+   }
+   else {
+      func(c, dst, arg0, arg1, arg2);
+   }
+}
+
+static void emit_sop( struct brw_compile *p,
+                      struct brw_reg dst,
+                      struct brw_reg arg0,
+                      struct brw_reg arg1, 
+		      GLuint cond)
+{
+   brw_MOV(p, dst, brw_imm_f(0.0f));
+   brw_CMP(p, brw_null_reg(), cond, arg0, arg1);
+   brw_MOV(p, dst, brw_imm_f(1.0f));
+   brw_set_predicate_control_flag_value(p, 0xff);
+}
+
+static void emit_seq( struct brw_compile *p,
+                      struct brw_reg dst,
+                      struct brw_reg arg0,
+                      struct brw_reg arg1 )
+{
+   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_EQ);
+}
+
+static void emit_sne( struct brw_compile *p,
+                      struct brw_reg dst,
+                      struct brw_reg arg0,
+                      struct brw_reg arg1 )
+{
+   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_NEQ);
+}
+static void emit_slt( struct brw_compile *p, 
+		      struct brw_reg dst,
+		      struct brw_reg arg0,
+		      struct brw_reg arg1 )
+{
+   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_L);
+}
+
+static void emit_sle( struct brw_compile *p, 
+		      struct brw_reg dst,
+		      struct brw_reg arg0,
+		      struct brw_reg arg1 )
+{
+   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_LE);
+}
+
+static void emit_sgt( struct brw_compile *p, 
+		      struct brw_reg dst,
+		      struct brw_reg arg0,
+		      struct brw_reg arg1 )
+{
+   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_G);
+}
+
+static void emit_sge( struct brw_compile *p, 
+		      struct brw_reg dst,
+		      struct brw_reg arg0,
+		      struct brw_reg arg1 )
+{
+  emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_GE);
+}
+
+static void emit_max( struct brw_compile *p, 
+		      struct brw_reg dst,
+		      struct brw_reg arg0,
+		      struct brw_reg arg1 )
+{
+   brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0, arg1);
+   brw_SEL(p, dst, arg1, arg0);
+   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+}
+
+static void emit_min( struct brw_compile *p, 
+		      struct brw_reg dst,
+		      struct brw_reg arg0,
+		      struct brw_reg arg1 )
+{
+   brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0, arg1);
+   brw_SEL(p, dst, arg0, arg1);
+   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+}
+
+
+static void emit_math1( struct brw_vs_compile *c,
+			GLuint function,
+			struct brw_reg dst,
+			struct brw_reg arg0,
+			GLuint precision)
+{
+   /* There are various odd behaviours with SEND on the simulator.  In
+    * addition there are documented issues with the fact that the GEN4
+    * processor doesn't do dependency control properly on SEND
+    * results.  So, on balance, this kludge to get around failures
+    * with writemasked math results looks like it might be necessary
+    * whether that turns out to be a simulator bug or not:
+    */
+   struct brw_compile *p = &c->func;
+   struct brw_reg tmp = dst;
+   GLboolean need_tmp = (dst.dw1.bits.writemask != 0xf ||
+			 dst.file != BRW_GENERAL_REGISTER_FILE);
+
+   if (need_tmp) 
+      tmp = get_tmp(c);
+
+   brw_math(p, 
+	    tmp,
+	    function,
+	    BRW_MATH_SATURATE_NONE,
+	    2,
+	    arg0,
+	    BRW_MATH_DATA_SCALAR,
+	    precision);
+
+   if (need_tmp) {
+      brw_MOV(p, dst, tmp);
+      release_tmp(c, tmp);
+   }
+}
+
+
+static void emit_math2( struct brw_vs_compile *c, 
+			GLuint function,
+			struct brw_reg dst,
+			struct brw_reg arg0,
+			struct brw_reg arg1,
+			GLuint precision)
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg tmp = dst;
+   GLboolean need_tmp = (dst.dw1.bits.writemask != 0xf ||
+			 dst.file != BRW_GENERAL_REGISTER_FILE);
+
+   if (need_tmp) 
+      tmp = get_tmp(c);
+
+   brw_MOV(p, brw_message_reg(3), arg1);
+   
+   brw_math(p, 
+	    tmp,
+	    function,
+	    BRW_MATH_SATURATE_NONE,
+	    2,
+ 	    arg0,
+	    BRW_MATH_DATA_SCALAR,
+	    precision);
+
+   if (need_tmp) {
+      brw_MOV(p, dst, tmp);
+      release_tmp(c, tmp);
+   }
+}
+
+
+static void emit_exp_noalias( struct brw_vs_compile *c,
+			      struct brw_reg dst,
+			      struct brw_reg arg0 )
+{
+   struct brw_compile *p = &c->func;
+   
+
+   if (dst.dw1.bits.writemask & BRW_WRITEMASK_X) {
+      struct brw_reg tmp = get_tmp(c);
+      struct brw_reg tmp_d = retype(tmp, BRW_REGISTER_TYPE_D);
+
+      /* tmp_d = floor(arg0.x) */
+      brw_RNDD(p, tmp_d, brw_swizzle1(arg0, 0));
+
+      /* result[0] = 2.0 ^ tmp */
+
+      /* Adjust exponent for floating point: 
+       * exp += 127 
+       */
+      brw_ADD(p, brw_writemask(tmp_d, BRW_WRITEMASK_X), tmp_d, brw_imm_d(127));
+
+      /* Install exponent and sign.  
+       * Excess drops off the edge: 
+       */
+      brw_SHL(p, brw_writemask(retype(dst, BRW_REGISTER_TYPE_D), BRW_WRITEMASK_X), 
+	      tmp_d, brw_imm_d(23));
+
+      release_tmp(c, tmp);
+   }
+
+   if (dst.dw1.bits.writemask & BRW_WRITEMASK_Y) {
+      /* result[1] = arg0.x - floor(arg0.x) */
+      brw_FRC(p, brw_writemask(dst, BRW_WRITEMASK_Y), brw_swizzle1(arg0, 0));
+   }
+   
+   if (dst.dw1.bits.writemask & BRW_WRITEMASK_Z) {
+      /* As with the LOG instruction, we might be better off just
+       * doing a taylor expansion here, seeing as we have to do all
+       * the prep work.
+       *
+       * If mathbox partial precision is too low, consider also:
+       * result[3] = result[0] * EXP(result[1])
+       */
+      emit_math1(c, 
+		 BRW_MATH_FUNCTION_EXP, 
+		 brw_writemask(dst, BRW_WRITEMASK_Z),
+		 brw_swizzle1(arg0, 0), 
+		 BRW_MATH_PRECISION_FULL);
+   }  
+
+   if (dst.dw1.bits.writemask & BRW_WRITEMASK_W) {
+      /* result[3] = 1.0; */
+      brw_MOV(p, brw_writemask(dst, BRW_WRITEMASK_W), brw_imm_f(1));
+   }
+}
+
+
+static void emit_log_noalias( struct brw_vs_compile *c,
+			      struct brw_reg dst,
+			      struct brw_reg arg0 )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg tmp = dst;
+   struct brw_reg tmp_ud = retype(tmp, BRW_REGISTER_TYPE_UD);
+   struct brw_reg arg0_ud = retype(arg0, BRW_REGISTER_TYPE_UD);
+   GLboolean need_tmp = (dst.dw1.bits.writemask != 0xf ||
+			 dst.file != BRW_GENERAL_REGISTER_FILE);
+
+   if (need_tmp) {
+      tmp = get_tmp(c);
+      tmp_ud = retype(tmp, BRW_REGISTER_TYPE_UD);
+   }
+   
+   /* Perform mant = frexpf(fabsf(x), &exp), adjust exp and mnt
+    * according to spec:
+    *
+    * These almost look likey they could be joined up, but not really
+    * practical:
+    *
+    * result[0].f = (x.i & ((1<<31)-1) >> 23) - 127
+    * result[1].i = (x.i & ((1<<23)-1)        + (127<<23)
+    */
+   if (dst.dw1.bits.writemask & BRW_WRITEMASK_XZ) {
+      brw_AND(p, 
+	      brw_writemask(tmp_ud, BRW_WRITEMASK_X),
+	      brw_swizzle1(arg0_ud, 0),
+	      brw_imm_ud((1U<<31)-1));
+
+      brw_SHR(p, 
+	      brw_writemask(tmp_ud, BRW_WRITEMASK_X), 
+	      tmp_ud,
+	      brw_imm_ud(23));
+
+      brw_ADD(p, 
+	      brw_writemask(tmp, BRW_WRITEMASK_X), 
+	      retype(tmp_ud, BRW_REGISTER_TYPE_D),	/* does it matter? */
+	      brw_imm_d(-127));
+   }
+
+   if (dst.dw1.bits.writemask & BRW_WRITEMASK_YZ) {
+      brw_AND(p, 
+	      brw_writemask(tmp_ud, BRW_WRITEMASK_Y),
+	      brw_swizzle1(arg0_ud, 0),
+	      brw_imm_ud((1<<23)-1));
+
+      brw_OR(p, 
+	     brw_writemask(tmp_ud, BRW_WRITEMASK_Y), 
+	     tmp_ud,
+	     brw_imm_ud(127<<23));
+   }
+   
+   if (dst.dw1.bits.writemask & BRW_WRITEMASK_Z) {
+      /* result[2] = result[0] + LOG2(result[1]); */
+
+      /* Why bother?  The above is just a hint how to do this with a
+       * taylor series.  Maybe we *should* use a taylor series as by
+       * the time all the above has been done it's almost certainly
+       * quicker than calling the mathbox, even with low precision.
+       * 
+       * Options are:
+       *    - result[0] + mathbox.LOG2(result[1])
+       *    - mathbox.LOG2(arg0.x)
+       *    - result[0] + inline_taylor_approx(result[1])
+       */
+      emit_math1(c, 
+		 BRW_MATH_FUNCTION_LOG, 
+		 brw_writemask(tmp, BRW_WRITEMASK_Z), 
+		 brw_swizzle1(tmp, 1), 
+		 BRW_MATH_PRECISION_FULL);
+      
+      brw_ADD(p, 
+	      brw_writemask(tmp, BRW_WRITEMASK_Z), 
+	      brw_swizzle1(tmp, 2), 
+	      brw_swizzle1(tmp, 0));
+   }  
+
+   if (dst.dw1.bits.writemask & BRW_WRITEMASK_W) {
+      /* result[3] = 1.0; */
+      brw_MOV(p, brw_writemask(tmp, BRW_WRITEMASK_W), brw_imm_f(1));
+   }
+
+   if (need_tmp) {
+      brw_MOV(p, dst, tmp);
+      release_tmp(c, tmp);
+   }
+}
+
+
+/* Need to unalias - consider swizzles:   r0 = DST r0.xxxx r1
+ */
+static void emit_dst_noalias( struct brw_vs_compile *c, 
+			      struct brw_reg dst,
+			      struct brw_reg arg0,
+			      struct brw_reg arg1)
+{
+   struct brw_compile *p = &c->func;
+
+   /* There must be a better way to do this: 
+    */
+   if (dst.dw1.bits.writemask & BRW_WRITEMASK_X)
+      brw_MOV(p, brw_writemask(dst, BRW_WRITEMASK_X), brw_imm_f(1.0));
+   if (dst.dw1.bits.writemask & BRW_WRITEMASK_Y)
+      brw_MUL(p, brw_writemask(dst, BRW_WRITEMASK_Y), arg0, arg1);
+   if (dst.dw1.bits.writemask & BRW_WRITEMASK_Z)
+      brw_MOV(p, brw_writemask(dst, BRW_WRITEMASK_Z), arg0);
+   if (dst.dw1.bits.writemask & BRW_WRITEMASK_W)
+      brw_MOV(p, brw_writemask(dst, BRW_WRITEMASK_W), arg1);
+}
+
+
+static void emit_xpd( struct brw_compile *p,
+		      struct brw_reg dst,
+		      struct brw_reg t,
+		      struct brw_reg u)
+{
+   brw_MUL(p, brw_null_reg(), brw_swizzle(t, 1,2,0,3),  brw_swizzle(u,2,0,1,3));
+   brw_MAC(p, dst,     negate(brw_swizzle(t, 2,0,1,3)), brw_swizzle(u,1,2,0,3));
+}
+
+
+static void emit_lit_noalias( struct brw_vs_compile *c, 
+			      struct brw_reg dst,
+			      struct brw_reg arg0 )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_instruction *if_insn;
+   struct brw_reg tmp = dst;
+   GLboolean need_tmp = (dst.file != BRW_GENERAL_REGISTER_FILE);
+
+   if (need_tmp) 
+      tmp = get_tmp(c);
+   
+   brw_MOV(p, brw_writemask(dst, BRW_WRITEMASK_YZ), brw_imm_f(0)); 
+   brw_MOV(p, brw_writemask(dst, BRW_WRITEMASK_XW), brw_imm_f(1)); 
+
+   /* Need to use BRW_EXECUTE_8 and also do an 8-wide compare in order
+    * to get all channels active inside the IF.  In the clipping code
+    * we run with NoMask, so it's not an option and we can use
+    * BRW_EXECUTE_1 for all comparisions.
+    */
+   brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, brw_swizzle1(arg0,0), brw_imm_f(0));
+   if_insn = brw_IF(p, BRW_EXECUTE_8);
+   {
+      brw_MOV(p, brw_writemask(dst, BRW_WRITEMASK_Y), brw_swizzle1(arg0,0));
+
+      brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, brw_swizzle1(arg0,1), brw_imm_f(0));
+      brw_MOV(p, brw_writemask(tmp, BRW_WRITEMASK_Z),  brw_swizzle1(arg0,1));
+      brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+      emit_math2(c, 
+		 BRW_MATH_FUNCTION_POW, 
+		 brw_writemask(dst, BRW_WRITEMASK_Z),
+		 brw_swizzle1(tmp, 2),
+		 brw_swizzle1(arg0, 3),
+		 BRW_MATH_PRECISION_PARTIAL);      
+   }
+
+   brw_ENDIF(p, if_insn);
+
+   release_tmp(c, tmp);
+}
+
+static void emit_lrp_noalias(struct brw_vs_compile *c,
+			     struct brw_reg dst,
+			     struct brw_reg arg0,
+			     struct brw_reg arg1,
+			     struct brw_reg arg2)
+{
+   struct brw_compile *p = &c->func;
+
+   brw_ADD(p, dst, negate(arg0), brw_imm_f(1.0));
+   brw_MUL(p, brw_null_reg(), dst, arg2);
+   brw_MAC(p, dst, arg0, arg1);
+}
+
+/** 3 or 4-component vector normalization */
+static void emit_nrm( struct brw_vs_compile *c, 
+                      struct brw_reg dst,
+                      struct brw_reg arg0,
+                      int num_comps)
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg tmp = get_tmp(c);
+
+   /* tmp = dot(arg0, arg0) */
+   if (num_comps == 3)
+      brw_DP3(p, tmp, arg0, arg0);
+   else
+      brw_DP4(p, tmp, arg0, arg0);
+
+   /* tmp = 1 / sqrt(tmp) */
+   emit_math1(c, BRW_MATH_FUNCTION_RSQ, tmp, tmp, BRW_MATH_PRECISION_FULL);
+
+   /* dst = arg0 * tmp */
+   brw_MUL(p, dst, arg0, tmp);
+
+   release_tmp(c, tmp);
+}
+
+
+static struct brw_reg
+get_constant(struct brw_vs_compile *c,
+	     GLuint argIndex,
+	     GLuint index,
+	     GLboolean relAddr)
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg const_reg;
+   struct brw_reg const2_reg;
+
+   assert(argIndex < 3);
+
+   if (c->current_const[argIndex].index != index || relAddr) {
+      struct brw_reg addrReg = c->regs[TGSI_FILE_ADDRESS][0];
+
+      c->current_const[argIndex].index = index;
+
+#if 0
+      printf("  fetch const[%d] for arg %d into reg %d\n",
+             src.Index, argIndex, c->current_const[argIndex].reg.nr);
+#endif
+      /* need to fetch the constant now */
+      brw_dp_READ_4_vs(p,
+                       c->current_const[argIndex].reg,/* writeback dest */
+                       0,                             /* oword */
+                       relAddr,                       /* relative indexing? */
+                       addrReg,                       /* address register */
+                       16 * index,               /* byte offset */
+                       SURF_INDEX_VERT_CONST_BUFFER   /* binding table index */
+                       );
+
+      if (relAddr) {
+         /* second read */
+         const2_reg = get_tmp(c);
+
+         /* use upper half of address reg for second read */
+         addrReg = stride(addrReg, 0, 4, 0);
+         addrReg.subnr = 16;
+
+         brw_dp_READ_4_vs(p,
+                          const2_reg,              /* writeback dest */
+                          1,                       /* oword */
+                          relAddr,                 /* relative indexing? */
+                          addrReg,                 /* address register */
+                          16 * index,         /* byte offset */
+                          SURF_INDEX_VERT_CONST_BUFFER
+                          );
+      }
+   }
+
+   const_reg = c->current_const[argIndex].reg;
+
+   if (relAddr) {
+      /* merge the two Owords into the constant register */
+      /* const_reg[7..4] = const2_reg[7..4] */
+      brw_MOV(p,
+              suboffset(stride(const_reg, 0, 4, 1), 4),
+              suboffset(stride(const2_reg, 0, 4, 1), 4));
+      release_tmp(c, const2_reg);
+   }
+   else {
+      /* replicate lower four floats into upper half (to get XYZWXYZW) */
+      const_reg = stride(const_reg, 0, 4, 0);
+      const_reg.subnr = 0;
+   }
+
+   return const_reg;
+}
+
+
+
+/* TODO: relative addressing!
+ */
+static struct brw_reg get_reg( struct brw_vs_compile *c,
+			       enum tgsi_file_type file,
+			       GLuint index )
+{
+   switch (file) {
+   case TGSI_FILE_TEMPORARY:
+   case TGSI_FILE_INPUT:
+   case TGSI_FILE_OUTPUT:
+   case TGSI_FILE_CONSTANT:
+      assert(c->regs[file][index].nr != 0);
+      return c->regs[file][index];
+
+   case TGSI_FILE_ADDRESS:
+      assert(index == 0);
+      return c->regs[file][index];
+
+   case TGSI_FILE_NULL:			/* undef values */
+      return brw_null_reg();
+
+   default:
+      assert(0);
+      return brw_null_reg();
+   }
+}
+
+
+/**
+ * Indirect addressing:  get reg[[arg] + offset].
+ */
+static struct brw_reg deref( struct brw_vs_compile *c,
+			     struct brw_reg arg,
+			     GLint offset)
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg tmp = vec4(get_tmp(c));
+   struct brw_reg addr_reg = c->regs[TGSI_FILE_ADDRESS][0];
+   struct brw_reg vp_address = retype(vec1(addr_reg), BRW_REGISTER_TYPE_UW);
+   GLuint byte_offset = arg.nr * 32 + arg.subnr + offset * 16;
+   struct brw_reg indirect = brw_vec4_indirect(0,0);
+
+   {
+      brw_push_insn_state(p);
+      brw_set_access_mode(p, BRW_ALIGN_1);
+
+      /* This is pretty clunky - load the address register twice and
+       * fetch each 4-dword value in turn.  There must be a way to do
+       * this in a single pass, but I couldn't get it to work.
+       */
+      brw_ADD(p, brw_address_reg(0), vp_address, brw_imm_d(byte_offset));
+      brw_MOV(p, tmp, indirect);
+
+      brw_ADD(p, brw_address_reg(0), suboffset(vp_address, 8), brw_imm_d(byte_offset));
+      brw_MOV(p, suboffset(tmp, 4), indirect);
+
+      brw_pop_insn_state(p);
+   }
+   
+   /* NOTE: tmp not released */
+   return vec8(tmp);
+}
+
+
+/**
+ * Get brw reg corresponding to the instruction's [argIndex] src reg.
+ * TODO: relative addressing!
+ */
+static struct brw_reg
+get_src_reg( struct brw_vs_compile *c,
+	     GLuint argIndex,
+	     GLuint file,
+	     GLint index,
+	     GLboolean relAddr )
+{
+
+   switch (file) {
+   case TGSI_FILE_TEMPORARY:
+   case TGSI_FILE_INPUT:
+   case TGSI_FILE_OUTPUT:
+      if (relAddr) {
+         return deref(c, c->regs[file][0], index);
+      }
+      else {
+         assert(c->regs[file][index].nr != 0);
+         return c->regs[file][index];
+      }
+
+   case TGSI_FILE_IMMEDIATE:
+      return c->regs[file][index];
+
+   case TGSI_FILE_CONSTANT:
+      if (c->vp->use_const_buffer) {
+         return get_constant(c, argIndex, index, relAddr);
+      }
+      else if (relAddr) {
+         return deref(c, c->regs[TGSI_FILE_CONSTANT][0], index);
+      }
+      else {
+         assert(c->regs[TGSI_FILE_CONSTANT][index].nr != 0);
+         return c->regs[TGSI_FILE_CONSTANT][index];
+      }
+   case TGSI_FILE_ADDRESS:
+      assert(index == 0);
+      return c->regs[file][index];
+
+   case TGSI_FILE_NULL:
+      /* this is a normal case since we loop over all three src args */
+      return brw_null_reg();
+
+   default:
+      assert(0);
+      return brw_null_reg();
+   }
+}
+
+
+static void emit_arl( struct brw_vs_compile *c,
+		      struct brw_reg dst,
+		      struct brw_reg arg0 )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg tmp = dst;
+   GLboolean need_tmp = (dst.file != BRW_GENERAL_REGISTER_FILE);
+   
+   if (need_tmp) 
+      tmp = get_tmp(c);
+
+   brw_RNDD(p, tmp, arg0);               /* tmp = round(arg0) */
+   brw_MUL(p, dst, tmp, brw_imm_d(16));  /* dst = tmp * 16 */
+
+   if (need_tmp)
+      release_tmp(c, tmp);
+}
+
+
+/**
+ * Return the brw reg for the given instruction's src argument.
+ */
+static struct brw_reg get_arg( struct brw_vs_compile *c,
+                               const struct tgsi_full_src_register *src,
+                               GLuint argIndex )
+{
+   struct brw_reg reg;
+
+   if (src->Register.File == TGSI_FILE_NULL)
+      return brw_null_reg();
+
+   reg = get_src_reg(c, argIndex,
+		     src->Register.File,
+		     src->Register.Index,
+		     src->Register.Indirect);
+
+   /* Convert 3-bit swizzle to 2-bit.  
+    */
+   reg.dw1.bits.swizzle = BRW_SWIZZLE4(src->Register.SwizzleX,
+				       src->Register.SwizzleY,
+				       src->Register.SwizzleZ,
+				       src->Register.SwizzleW);
+
+   reg.negate = src->Register.Negate ? 1 : 0;   
+
+   /* XXX: abs, absneg
+    */
+
+   return reg;
+}
+
+
+/**
+ * Get brw register for the given program dest register.
+ */
+static struct brw_reg get_dst( struct brw_vs_compile *c,
+			       unsigned file,
+			       unsigned index,
+			       unsigned writemask )
+{
+   struct brw_reg reg;
+
+   switch (file) {
+   case TGSI_FILE_TEMPORARY:
+   case TGSI_FILE_OUTPUT:
+      assert(c->regs[file][index].nr != 0);
+      reg = c->regs[file][index];
+      break;
+   case TGSI_FILE_ADDRESS:
+      assert(index == 0);
+      reg = c->regs[file][index];
+      break;
+   case TGSI_FILE_NULL:
+      /* we may hit this for OPCODE_END, OPCODE_KIL, etc */
+      reg = brw_null_reg();
+      break;
+   default:
+      assert(0);
+      reg = brw_null_reg();
+   }
+
+   reg.dw1.bits.writemask = writemask;
+
+   return reg;
+}
+
+
+
+
+/**
+ * Post-vertex-program processing.  Send the results to the URB.
+ */
+static void emit_vertex_write( struct brw_vs_compile *c)
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg m0 = brw_message_reg(0);
+   struct brw_reg pos = c->regs[TGSI_FILE_OUTPUT][VERT_RESULT_HPOS];
+   struct brw_reg ndc;
+   int eot;
+   int i;
+   GLuint len_vertext_header = 2;
+
+   /* Build ndc coords */
+   ndc = get_tmp(c);
+   /* ndc = 1.0 / pos.w */
+   emit_math1(c, BRW_MATH_FUNCTION_INV, ndc, brw_swizzle1(pos, 3), BRW_MATH_PRECISION_FULL);
+   /* ndc.xyz = pos * ndc */
+   brw_MUL(p, brw_writemask(ndc, BRW_WRITEMASK_XYZ), pos, ndc);
+
+   /* Update the header for point size, user clipping flags, and -ve rhw
+    * workaround.
+    */
+   if (c->prog_data.writes_psiz ||
+       c->key.nr_userclip || 
+       c->chipset.is_965)
+   {
+      struct brw_reg header1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
+      GLuint i;
+
+      brw_MOV(p, header1, brw_imm_ud(0));
+
+      brw_set_access_mode(p, BRW_ALIGN_16);	
+
+      if (c->prog_data.writes_psiz) {
+	 struct brw_reg psiz = c->regs[TGSI_FILE_OUTPUT][VERT_RESULT_PSIZ];
+	 brw_MUL(p, brw_writemask(header1, BRW_WRITEMASK_W), brw_swizzle1(psiz, 0), brw_imm_f(1<<11));
+	 brw_AND(p, brw_writemask(header1, BRW_WRITEMASK_W), header1, brw_imm_ud(0x7ff<<8));
+      }
+
+      for (i = 0; i < c->key.nr_userclip; i++) {
+	 brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
+	 brw_DP4(p, brw_null_reg(), pos, c->userplane[i]);
+	 brw_OR(p, brw_writemask(header1, BRW_WRITEMASK_W), header1, brw_imm_ud(1<<i));
+	 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+      }
+
+      /* i965 clipping workaround: 
+       * 1) Test for -ve rhw
+       * 2) If set, 
+       *      set ndc = (0,0,0,0)
+       *      set ucp[6] = 1
+       *
+       * Later, clipping will detect ucp[6] and ensure the primitive is
+       * clipped against all fixed planes.
+       */
+      if (c->chipset.is_965) {
+	 brw_CMP(p,
+		 vec8(brw_null_reg()),
+		 BRW_CONDITIONAL_L,
+		 brw_swizzle1(ndc, 3),
+		 brw_imm_f(0));
+   
+	 brw_OR(p, brw_writemask(header1, BRW_WRITEMASK_W), header1, brw_imm_ud(1<<6));
+	 brw_MOV(p, ndc, brw_imm_f(0));
+	 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+      }
+
+      brw_set_access_mode(p, BRW_ALIGN_1);	/* why? */
+      brw_MOV(p, retype(brw_message_reg(1), BRW_REGISTER_TYPE_UD), header1);
+      brw_set_access_mode(p, BRW_ALIGN_16);
+
+      release_tmp(c, header1);
+   }
+   else {
+      brw_MOV(p, retype(brw_message_reg(1), BRW_REGISTER_TYPE_UD), brw_imm_ud(0));
+   }
+
+   /* Emit the (interleaved) headers for the two vertices - an 8-reg
+    * of zeros followed by two sets of NDC coordinates:
+    */
+   brw_set_access_mode(p, BRW_ALIGN_1);
+   brw_MOV(p, offset(m0, 2), ndc);
+
+   if (c->chipset.is_igdng) {
+       /* There are 20 DWs (D0-D19) in VUE vertex header on IGDNG */
+       brw_MOV(p, offset(m0, 3), pos); /* a portion of vertex header */
+       /* m4, m5 contain the distances from vertex to the user clip planeXXX. 
+        * Seems it is useless for us.
+        * m6 is used for aligning, so that the remainder of vertex element is 
+        * reg-aligned.
+        */
+       brw_MOV(p, offset(m0, 7), pos); /* the remainder of vertex element */
+       len_vertext_header = 6;
+   } else {
+       brw_MOV(p, offset(m0, 3), pos);
+       len_vertext_header = 2;
+   }
+
+   eot = (c->overflow_count == 0);
+
+   brw_urb_WRITE(p, 
+		 brw_null_reg(), /* dest */
+		 0,		/* starting mrf reg nr */
+		 c->r0,		/* src */
+		 0,		/* allocate */
+		 1,		/* used */
+		 MIN2(c->nr_outputs + 1 + len_vertext_header, (BRW_MAX_MRF-1)), /* msg len */
+		 0,		/* response len */
+		 eot, 		/* eot */
+		 eot, 		/* writes complete */
+		 0, 		/* urb destination offset */
+		 BRW_URB_SWIZZLE_INTERLEAVE);
+
+   /* Not all of the vertex outputs/results fit into the MRF.
+    * Move the overflowed attributes from the GRF to the MRF and
+    * issue another brw_urb_WRITE().
+    */
+   for (i = 0; i < c->overflow_count; i += BRW_MAX_MRF) {
+      unsigned nr = MIN2(c->overflow_count - i, BRW_MAX_MRF);
+      GLuint j;
+
+      eot = (i + nr >= c->overflow_count);
+
+      /* XXX I'm not 100% sure about which MRF regs to use here.  Starting
+       * at mrf[4] atm...
+       */
+      for (j = 0; j < nr; j++) {
+	 brw_MOV(p, brw_message_reg(4+j), 
+                 brw_vec8_grf(c->overflow_grf_start + i + j, 0));
+      }
+
+      brw_urb_WRITE(p,
+                    brw_null_reg(), /* dest */
+                    4,              /* starting mrf reg nr */
+                    c->r0,          /* src */
+                    0,              /* allocate */
+                    1,              /* used */
+                    nr+1,          /* msg len */
+                    0,              /* response len */
+                    eot,            /* eot */
+                    eot,            /* writes complete */
+                    i-1,            /* urb destination offset */
+                    BRW_URB_SWIZZLE_INTERLEAVE);
+   }
+}
+
+
+/**
+ * Called after code generation to resolve subroutine calls and the
+ * END instruction.
+ * \param end_inst  points to brw code for END instruction
+ * \param last_inst  points to last instruction emitted before vertex write
+ */
+static void 
+post_vs_emit( struct brw_vs_compile *c,
+              struct brw_instruction *end_inst,
+              struct brw_instruction *last_inst )
+{
+   GLint offset;
+
+   brw_resolve_cals(&c->func);
+
+   /* patch up the END code to jump past subroutines, etc */
+   offset = last_inst - end_inst;
+   if (offset > 1) {
+      brw_set_src1(end_inst, brw_imm_d(offset * 16));
+   } else {
+      end_inst->header.opcode = BRW_OPCODE_NOP;
+   }
+}
+
+static uint32_t
+get_predicate(const struct tgsi_full_instruction *inst)
+{
+   /* XXX: disabling for now
+    */
+#if 0
+   if (inst->dst.CondMask == COND_TR)
+      return BRW_PREDICATE_NONE;
+
+   /* All of GLSL only produces predicates for COND_NE and one channel per
+    * vector.  Fail badly if someone starts doing something else, as it might
+    * mean infinite looping or something.
+    *
+    * We'd like to support all the condition codes, but our hardware doesn't
+    * quite match the Mesa IR, which is modeled after the NV extensions.  For
+    * those, the instruction may update the condition codes or not, then any
+    * later instruction may use one of those condition codes.  For gen4, the
+    * instruction may update the flags register based on one of the condition
+    * codes output by the instruction, and then further instructions may
+    * predicate on that.  We can probably support this, but it won't
+    * necessarily be easy.
+    */
+/*   assert(inst->dst.CondMask == COND_NE); */
+
+   switch (inst->dst.CondSwizzle) {
+   case SWIZZLE_XXXX:
+      return BRW_PREDICATE_ALIGN16_REPLICATE_X;
+   case SWIZZLE_YYYY:
+      return BRW_PREDICATE_ALIGN16_REPLICATE_Y;
+   case SWIZZLE_ZZZZ:
+      return BRW_PREDICATE_ALIGN16_REPLICATE_Z;
+   case SWIZZLE_WWWW:
+      return BRW_PREDICATE_ALIGN16_REPLICATE_W;
+   default:
+      debug_printf("Unexpected predicate: 0x%08x\n",
+		    inst->dst.CondMask);
+      return BRW_PREDICATE_NORMAL;
+   }
+#else
+   return BRW_PREDICATE_NORMAL;
+#endif
+}
+
+static void emit_insn(struct brw_vs_compile *c,
+		      const struct tgsi_full_instruction *inst)
+{
+   unsigned opcode = inst->Instruction.Opcode;
+   unsigned label = inst->Label.Label;
+   struct brw_compile *p = &c->func;
+   struct brw_reg args[3], dst;
+   GLuint i;
+
+#if 0
+   printf("%d: ", insn);
+   _mesa_print_instruction(inst);
+#endif
+
+   /* Get argument regs.
+    */
+   for (i = 0; i < 3; i++) {
+      args[i] = get_arg(c, &inst->Src[i], i);
+   }
+
+   /* Get dest regs.  Note that it is possible for a reg to be both
+    * dst and arg, given the static allocation of registers.  So
+    * care needs to be taken emitting multi-operation instructions.
+    */ 
+   dst = get_dst(c, 
+		 inst->Dst[0].Register.File,
+		 inst->Dst[0].Register.Index,
+		 inst->Dst[0].Register.WriteMask);
+
+   /* XXX: saturate
+    */
+   if (inst->Instruction.Saturate != TGSI_SAT_NONE) {
+      debug_printf("Unsupported saturate in vertex shader");
+   }
+
+   switch (opcode) {
+   case TGSI_OPCODE_ABS:
+      brw_MOV(p, dst, brw_abs(args[0]));
+      break;
+   case TGSI_OPCODE_ADD:
+      brw_ADD(p, dst, args[0], args[1]);
+      break;
+   case TGSI_OPCODE_COS:
+      emit_math1(c, BRW_MATH_FUNCTION_COS, dst, args[0], BRW_MATH_PRECISION_FULL);
+      break;
+   case TGSI_OPCODE_DP3:
+      brw_DP3(p, dst, args[0], args[1]);
+      break;
+   case TGSI_OPCODE_DP4:
+      brw_DP4(p, dst, args[0], args[1]);
+      break;
+   case TGSI_OPCODE_DPH:
+      brw_DPH(p, dst, args[0], args[1]);
+      break;
+   case TGSI_OPCODE_NRM:
+      emit_nrm(c, dst, args[0], 3);
+      break;
+   case TGSI_OPCODE_NRM4:
+      emit_nrm(c, dst, args[0], 4);
+      break;
+   case TGSI_OPCODE_DST:
+      unalias2(c, dst, args[0], args[1], emit_dst_noalias); 
+      break;
+   case TGSI_OPCODE_EXP:
+      unalias1(c, dst, args[0], emit_exp_noalias);
+      break;
+   case TGSI_OPCODE_EX2:
+      emit_math1(c, BRW_MATH_FUNCTION_EXP, dst, args[0], BRW_MATH_PRECISION_FULL);
+      break;
+   case TGSI_OPCODE_ARL:
+      emit_arl(c, dst, args[0]);
+      break;
+   case TGSI_OPCODE_FLR:
+      brw_RNDD(p, dst, args[0]);
+      break;
+   case TGSI_OPCODE_FRC:
+      brw_FRC(p, dst, args[0]);
+      break;
+   case TGSI_OPCODE_LOG:
+      unalias1(c, dst, args[0], emit_log_noalias);
+      break;
+   case TGSI_OPCODE_LG2:
+      emit_math1(c, BRW_MATH_FUNCTION_LOG, dst, args[0], BRW_MATH_PRECISION_FULL);
+      break;
+   case TGSI_OPCODE_LIT:
+      unalias1(c, dst, args[0], emit_lit_noalias);
+      break;
+   case TGSI_OPCODE_LRP:
+      unalias3(c, dst, args[0], args[1], args[2], emit_lrp_noalias);
+      break;
+   case TGSI_OPCODE_MAD:
+      brw_MOV(p, brw_acc_reg(), args[2]);
+      brw_MAC(p, dst, args[0], args[1]);
+      break;
+   case TGSI_OPCODE_MAX:
+      emit_max(p, dst, args[0], args[1]);
+      break;
+   case TGSI_OPCODE_MIN:
+      emit_min(p, dst, args[0], args[1]);
+      break;
+   case TGSI_OPCODE_MOV:
+      brw_MOV(p, dst, args[0]);
+      break;
+   case TGSI_OPCODE_MUL:
+      brw_MUL(p, dst, args[0], args[1]);
+      break;
+   case TGSI_OPCODE_POW:
+      emit_math2(c, BRW_MATH_FUNCTION_POW, dst, args[0], args[1], BRW_MATH_PRECISION_FULL); 
+      break;
+   case TGSI_OPCODE_RCP:
+      emit_math1(c, BRW_MATH_FUNCTION_INV, dst, args[0], BRW_MATH_PRECISION_FULL);
+      break;
+   case TGSI_OPCODE_RSQ:
+      emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, 
+                 brw_swizzle(args[0], 0,0,0,0), BRW_MATH_PRECISION_FULL);
+      break;
+   case TGSI_OPCODE_SEQ:
+      emit_seq(p, dst, args[0], args[1]);
+      break;
+   case TGSI_OPCODE_SIN:
+      emit_math1(c, BRW_MATH_FUNCTION_SIN, dst, args[0], BRW_MATH_PRECISION_FULL);
+      break;
+   case TGSI_OPCODE_SNE:
+      emit_sne(p, dst, args[0], args[1]);
+      break;
+   case TGSI_OPCODE_SGE:
+      emit_sge(p, dst, args[0], args[1]);
+      break;
+   case TGSI_OPCODE_SGT:
+      emit_sgt(p, dst, args[0], args[1]);
+      break;
+   case TGSI_OPCODE_SLT:
+      emit_slt(p, dst, args[0], args[1]);
+      break;
+   case TGSI_OPCODE_SLE:
+      emit_sle(p, dst, args[0], args[1]);
+      break;
+   case TGSI_OPCODE_SUB:
+      brw_ADD(p, dst, args[0], negate(args[1]));
+      break;
+   case TGSI_OPCODE_TRUNC:
+      /* round toward zero */
+      brw_RNDZ(p, dst, args[0]);
+      break;
+   case TGSI_OPCODE_XPD:
+      emit_xpd(p, dst, args[0], args[1]);
+      break;
+   case TGSI_OPCODE_IF:
+      assert(c->if_depth < MAX_IF_DEPTH);
+      c->if_inst[c->if_depth] = brw_IF(p, BRW_EXECUTE_8);
+      /* Note that brw_IF smashes the predicate_control field. */
+      c->if_inst[c->if_depth]->header.predicate_control = get_predicate(inst);
+      c->if_depth++;
+      break;
+   case TGSI_OPCODE_ELSE:
+      c->if_inst[c->if_depth-1] = brw_ELSE(p, c->if_inst[c->if_depth-1]);
+      break;
+   case TGSI_OPCODE_ENDIF:
+      assert(c->if_depth > 0);
+      brw_ENDIF(p, c->if_inst[--c->if_depth]);
+      break;			
+   case TGSI_OPCODE_BGNLOOP:
+      c->loop_inst[c->loop_depth++] = brw_DO(p, BRW_EXECUTE_8);
+      break;
+   case TGSI_OPCODE_BRK:
+      brw_set_predicate_control(p, get_predicate(inst));
+      brw_BREAK(p);
+      brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+      break;
+   case TGSI_OPCODE_CONT:
+      brw_set_predicate_control(p, get_predicate(inst));
+      brw_CONT(p);
+      brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+      break;
+   case TGSI_OPCODE_ENDLOOP: 
+   {
+      struct brw_instruction *inst0, *inst1;
+      GLuint br = 1;
+
+      c->loop_depth--;
+
+      if (c->chipset.is_igdng)
+	 br = 2;
+
+      inst0 = inst1 = brw_WHILE(p, c->loop_inst[c->loop_depth]);
+      /* patch all the BREAK/CONT instructions from last BEGINLOOP */
+      while (inst0 > c->loop_inst[c->loop_depth]) {
+	 inst0--;
+	 if (inst0->header.opcode == TGSI_OPCODE_BRK) {
+	    inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
+	    inst0->bits3.if_else.pop_count = 0;
+	 }
+	 else if (inst0->header.opcode == TGSI_OPCODE_CONT) {
+	    inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
+	    inst0->bits3.if_else.pop_count = 0;
+	 }
+      }
+   }
+   break;
+   case TGSI_OPCODE_BRA:
+      brw_set_predicate_control(p, get_predicate(inst));
+      brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+      brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+      break;
+   case TGSI_OPCODE_CAL:
+      brw_set_access_mode(p, BRW_ALIGN_1);
+      brw_ADD(p, deref_1d(c->stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
+      brw_set_access_mode(p, BRW_ALIGN_16);
+      brw_ADD(p, get_addr_reg(c->stack_index),
+	      get_addr_reg(c->stack_index), brw_imm_d(4));
+      brw_save_call(p, label, p->nr_insn);
+      brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+      break;
+   case TGSI_OPCODE_RET:
+      brw_ADD(p, get_addr_reg(c->stack_index),
+	      get_addr_reg(c->stack_index), brw_imm_d(-4));
+      brw_set_access_mode(p, BRW_ALIGN_1);
+      brw_MOV(p, brw_ip_reg(), deref_1d(c->stack_index, 0));
+      brw_set_access_mode(p, BRW_ALIGN_16);
+      break;
+   case TGSI_OPCODE_END:	
+      c->end_offset = p->nr_insn;
+      /* this instruction will get patched later to jump past subroutine
+       * code, etc.
+       */
+      brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+      break;
+   case TGSI_OPCODE_BGNSUB:
+      brw_save_label(p, p->nr_insn, p->nr_insn);
+      break;
+   case TGSI_OPCODE_ENDSUB:
+      /* no-op */
+      break;
+   default:
+      debug_printf("Unsupported opcode %i (%s) in vertex shader",
+		   opcode, 
+		   tgsi_get_opcode_name(opcode));
+   }
+
+   /* Set the predication update on the last instruction of the native
+    * instruction sequence.
+    *
+    * This would be problematic if it was set on a math instruction,
+    * but that shouldn't be the case with the current GLSL compiler.
+    */
+#if 0
+   /* XXX: disabled
+    */
+   if (inst->CondUpdate) {
+      struct brw_instruction *hw_insn = &p->store[p->nr_insn - 1];
+
+      assert(hw_insn->header.destreg__conditionalmod == 0);
+      hw_insn->header.destreg__conditionalmod = BRW_CONDITIONAL_NZ;
+   }
+#endif
+
+   release_tmps(c);
+}
+
+
+/* Emit the vertex program instructions here.
+ */
+void brw_vs_emit(struct brw_vs_compile *c)
+{
+   struct brw_compile *p = &c->func;
+   const struct tgsi_token *tokens = c->vp->tokens;
+   struct brw_instruction *end_inst, *last_inst;
+   struct tgsi_parse_context parse;
+   struct tgsi_full_instruction *inst;
+
+   if (BRW_DEBUG & DEBUG_VS)
+      tgsi_dump(c->vp->tokens, 0); 
+
+   c->stack_index = brw_indirect(0, 0);
+
+   brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+   brw_set_access_mode(p, BRW_ALIGN_16);
+   
+
+   /* Static register allocation
+    */
+   brw_vs_alloc_regs(c);
+
+   if (c->vp->has_flow_control) {
+      brw_MOV(p, get_addr_reg(c->stack_index), brw_address(c->stack));
+   }
+
+   /* Instructions
+    */
+   tgsi_parse_init( &parse, tokens );
+   while( !tgsi_parse_end_of_tokens( &parse ) ) {
+      tgsi_parse_token( &parse );
+
+      switch( parse.FullToken.Token.Type ) {
+      case TGSI_TOKEN_TYPE_DECLARATION:
+      case TGSI_TOKEN_TYPE_IMMEDIATE:
+	 break;
+
+      case TGSI_TOKEN_TYPE_INSTRUCTION:
+         inst = &parse.FullToken.FullInstruction;
+	 emit_insn( c, inst );
+         break;
+
+      default:
+         assert( 0 );
+      }
+   }
+   tgsi_parse_free( &parse );
+
+   end_inst = &p->store[c->end_offset];
+   last_inst = &p->store[p->nr_insn];
+
+   /* The END instruction will be patched to jump to this code */
+   emit_vertex_write(c);
+
+   post_vs_emit(c, end_inst, last_inst);
+
+   if (BRW_DEBUG & DEBUG_VS) {
+      debug_printf("vs-native:\n");
+      brw_disasm(stderr, p->store, p->nr_insn);
+   }
+}
diff --git a/src/gallium/drivers/i965/brw_vs_state.c b/src/gallium/drivers/i965/brw_vs_state.c
new file mode 100644
index 0000000..dadbb62
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_vs_state.c
@@ -0,0 +1,201 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+            
+#include "util/u_math.h"
+
+
+#include "brw_debug.h"
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+
+struct brw_vs_unit_key {
+   unsigned int total_grf;
+   unsigned int urb_entry_read_length;
+   unsigned int curb_entry_read_length;
+
+   unsigned int curbe_offset;
+
+   unsigned int nr_urb_entries, urb_size;
+
+   unsigned int nr_surfaces;
+};
+
+static void
+vs_unit_populate_key(struct brw_context *brw, struct brw_vs_unit_key *key)
+{
+   memset(key, 0, sizeof(*key));
+
+   /* CACHE_NEW_VS_PROG */
+   key->total_grf = brw->vs.prog_data->total_grf;
+   key->urb_entry_read_length = brw->vs.prog_data->urb_read_length;
+   key->curb_entry_read_length = brw->vs.prog_data->curb_read_length;
+
+   /* BRW_NEW_URB_FENCE */
+   key->nr_urb_entries = brw->urb.nr_vs_entries;
+   key->urb_size = brw->urb.vsize;
+
+   /* BRW_NEW_NR_VS_SURFACES */
+   key->nr_surfaces = brw->vs.nr_surfaces;
+
+   /* PIPE_NEW_CLIP */
+   if (brw->curr.ucp.nr) {
+      /* Note that we read in the userclip planes as well, hence
+       * clip_start:
+       */
+      key->curbe_offset = brw->curbe.clip_start;
+   }
+   else {
+      key->curbe_offset = brw->curbe.vs_start;
+   }
+}
+
+static enum pipe_error
+vs_unit_create_from_key(struct brw_context *brw, 
+                        struct brw_vs_unit_key *key,
+                        struct brw_winsys_reloc *reloc,
+                        struct brw_winsys_buffer **bo_out)
+{
+   enum pipe_error ret;
+   struct brw_vs_unit_state vs;
+   int chipset_max_threads;
+
+   memset(&vs, 0, sizeof(vs));
+
+   vs.thread0.kernel_start_pointer = 0; /* reloc */
+   vs.thread0.grf_reg_count = align(key->total_grf, 16) / 16 - 1;
+   vs.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
+   /* Choosing multiple program flow means that we may get 2-vertex threads,
+    * which will have the channel mask for dwords 4-7 enabled in the thread,
+    * and those dwords will be written to the second URB handle when we
+    * brw_urb_WRITE() results.
+    */
+   vs.thread1.single_program_flow = 0;
+
+   if (BRW_IS_IGDNG(brw))
+      vs.thread1.binding_table_entry_count = 0; /* hardware requirement */
+   else
+      vs.thread1.binding_table_entry_count = key->nr_surfaces;
+
+   vs.thread3.urb_entry_read_length = key->urb_entry_read_length;
+   vs.thread3.const_urb_entry_read_length = key->curb_entry_read_length;
+   vs.thread3.dispatch_grf_start_reg = 1;
+   vs.thread3.urb_entry_read_offset = 0;
+   vs.thread3.const_urb_entry_read_offset = key->curbe_offset * 2;
+
+   if (BRW_IS_IGDNG(brw))
+       vs.thread4.nr_urb_entries = key->nr_urb_entries >> 2;
+   else
+       vs.thread4.nr_urb_entries = key->nr_urb_entries;
+
+   vs.thread4.urb_entry_allocation_size = key->urb_size - 1;
+
+   if (BRW_IS_IGDNG(brw))
+      chipset_max_threads = 72;
+   else if (BRW_IS_G4X(brw))
+      chipset_max_threads = 32;
+   else
+      chipset_max_threads = 16;
+
+   vs.thread4.max_threads = CLAMP(key->nr_urb_entries / 2,
+				  1, chipset_max_threads) - 1;
+
+   if (BRW_DEBUG & DEBUG_SINGLE_THREAD)
+      vs.thread4.max_threads = 0;
+
+   /* No samplers for ARB_vp programs:
+    */
+   /* It has to be set to 0 for IGDNG
+    */
+   vs.vs5.sampler_count = 0;
+
+   if (BRW_DEBUG & DEBUG_STATS)
+      vs.thread4.stats_enable = 1;
+
+   /* Vertex program always enabled:
+    */
+   vs.vs6.vs_enable = 1;
+
+   ret = brw_upload_cache(&brw->cache, BRW_VS_UNIT,
+                          key, sizeof(*key),
+                          reloc, 1,
+                          &vs, sizeof(vs),
+                          NULL, NULL,
+                          bo_out);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+static int prepare_vs_unit(struct brw_context *brw)
+{
+   struct brw_vs_unit_key key;
+   enum pipe_error ret;
+   struct brw_winsys_reloc reloc[1];
+   unsigned grf_reg_count;
+
+   vs_unit_populate_key(brw, &key);
+
+   grf_reg_count = (align(key.total_grf, 16) / 16 - 1);
+
+   /* Emit VS program relocation */
+   make_reloc(&reloc[0],
+              BRW_USAGE_STATE,
+              grf_reg_count << 1,
+              offsetof(struct brw_vs_unit_state, thread0),
+              brw->vs.prog_bo);
+
+
+   if (brw_search_cache(&brw->cache, BRW_VS_UNIT,
+                        &key, sizeof(key),
+                        reloc, 1,
+                        NULL,
+                        &brw->vs.state_bo))
+      return PIPE_OK;
+
+   ret = vs_unit_create_from_key(brw, &key, reloc, &brw->vs.state_bo);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+const struct brw_tracked_state brw_vs_unit = {
+   .dirty = {
+      .mesa  = (PIPE_NEW_CLIP),
+      .brw   = (BRW_NEW_CURBE_OFFSETS |
+                BRW_NEW_NR_VS_SURFACES |
+		BRW_NEW_URB_FENCE),
+      .cache = CACHE_NEW_VS_PROG
+   },
+   .prepare = prepare_vs_unit,
+};
diff --git a/src/gallium/drivers/i965/brw_vs_surface_state.c b/src/gallium/drivers/i965/brw_vs_surface_state.c
new file mode 100644
index 0000000..177a517
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_vs_surface_state.c
@@ -0,0 +1,232 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+#include "brw_winsys.h"
+
+/* XXX: disabled true constant buffer functionality
+ */
+
+
+/* Creates a new VS constant buffer reflecting the current VS program's
+ * constants, if needed by the VS program.
+ *
+ * Otherwise, constants go through the CURBEs using the brw_constant_buffer
+ * state atom.
+ */
+#if 0
+static struct brw_winsys_buffer *
+brw_vs_update_constant_buffer(struct brw_context *brw)
+{
+   /* XXX: true constant buffers
+    */
+   struct brw_vertex_program *vp =
+      (struct brw_vertex_program *) brw->vertex_program;
+   const struct gl_program_parameter_list *params = vp->program.Base.Parameters;
+   const int size = params->NumParameters * 4 * sizeof(GLfloat);
+   drm_intel_bo *const_buffer;
+
+   /* BRW_NEW_VERTEX_PROGRAM */
+   if (!vp->use_const_buffer)
+      return NULL;
+
+   const_buffer = brw->sws->bo_alloc(brw->sws, 
+				     BRW_BUFFER_TYPE_SHADER_CONSTANTS,
+				     size, 64);
+
+   /* _NEW_PROGRAM_CONSTANTS */
+   brw->sws->bo_subdata(const_buffer, 0, size, params->ParameterValues,
+                        NULL, 0);
+
+   return const_buffer;
+}
+#endif
+
+/**
+ * Update the surface state for a VS constant buffer.
+ *
+ * Sets brw->vs.surf_bo[surf] and brw->vp->const_buffer.
+ */
+#if 0
+static void
+brw_update_vs_constant_surface( struct brw_context *brw,
+                                GLuint surf)
+{
+   struct brw_surface_key key;
+   struct pipe_buffer *cb = brw->curr.vs_constants;
+   enum pipe_error ret;
+
+   assert(surf == 0);
+
+   /* If we're in this state update atom, we need to update VS constants, so
+    * free the old buffer and create a new one for the new contents.
+    */
+   ret = brw_vs_update_constant_buffer(brw, &vp->const_buffer);
+   if (ret)
+      return ret;
+
+   /* If there's no constant buffer, then no surface BO is needed to point at
+    * it.
+    */
+   if (vp->const_buffer == NULL) {
+      bo_reference(brw->vs.surf_bo[surf], NULL);
+      return PIPE_OK;
+   }
+
+   memset(&key, 0, sizeof(key));
+
+   key.format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+   key.bo = vp->const_buffer;
+   key.depthmode = GL_NONE;
+   key.pitch = params->NumParameters;
+   key.width = params->NumParameters;
+   key.height = 1;
+   key.depth = 1;
+   key.cpp = 16;
+
+   /*
+   printf("%s:\n", __FUNCTION__);
+   printf("  width %d  height %d  depth %d  cpp %d  pitch %d\n",
+          key.width, key.height, key.depth, key.cpp, key.pitch);
+   */
+
+   if (brw_search_cache(&brw->surface_cache,
+                        BRW_SS_SURFACE,
+                        &key, sizeof(key),
+                        &key.bo, key.bo ? 1 : 0,
+                        NULL,
+                        &brw->vs.surf_bo[surf]))
+      return PIPE_OK;
+
+   ret = brw_create_constant_surface(brw, &key
+                                     &brw->vs.surf_bo[surf]);
+   if (ret)
+      return ret;
+   
+   return PIPE_OK;
+}
+#endif
+
+
+/**
+ * Constructs the binding table for the VS surface state.
+ */
+static enum pipe_error
+brw_vs_get_binding_table(struct brw_context *brw,
+                         struct brw_winsys_buffer **bo_out)
+{
+#if 0
+   static GLuint data[BRW_VS_MAX_SURF]; /* always zero */
+   struct brw_winsys_reloc reloc[BRW_VS_MAX_SURF];
+   int i;
+
+   /* Emit binding table relocations to surface state */
+   for (i = 0; i < BRW_VS_MAX_SURF; i++) {
+      make_reloc(&reloc[i],
+                 BRW_USAGE_STATE,
+                 0,
+                 i * 4,
+                 brw->vs.surf_bo[i]);
+   }
+   
+   ret = brw_cache_data( &brw->surface_cache, 
+                         BRW_SS_SURF_BIND,
+                         NULL, 0,
+                         reloc, nr_reloc,
+                         data, sizeof data,
+                         NULL, NULL,
+                         bo_out);
+   if (ret)
+      return ret;
+
+   FREE(data);
+   return PIPE_OK;
+#else
+   return PIPE_OK;
+#endif
+}
+
+/**
+ * Vertex shader surfaces (constant buffer).
+ *
+ * This consumes the state updates for the constant buffer needing
+ * to be updated, and produces BRW_NEW_NR_VS_SURFACES for the VS unit and
+ * CACHE_NEW_SURF_BIND for the binding table upload.
+ */
+static enum pipe_error prepare_vs_surfaces(struct brw_context *brw )
+{
+   enum pipe_error ret;
+
+#if 0
+   int i;
+   int nr_surfaces = 0;
+
+   brw_update_vs_constant_surface(ctx, SURF_INDEX_VERT_CONST_BUFFER);
+
+   for (i = 0; i < BRW_VS_MAX_SURF; i++) {
+      if (brw->vs.surf_bo[i] != NULL) {
+	 nr_surfaces = i + 1;
+      }
+   }
+
+   if (brw->vs.nr_surfaces != nr_surfaces) {
+      brw->state.dirty.brw |= BRW_NEW_NR_VS_SURFACES;
+      brw->vs.nr_surfaces = nr_surfaces;
+   }
+#endif
+
+   /* Note that we don't end up updating the bind_bo if we don't have a
+    * surface to be pointing at.  This should be relatively harmless, as it
+    * just slightly increases our working set size.
+    */
+   if (brw->vs.nr_surfaces != 0) {
+      ret = brw_vs_get_binding_table(brw, &brw->vs.bind_bo);
+      if (ret)
+         return ret;
+   }
+
+   return PIPE_OK;
+}
+
+const struct brw_tracked_state brw_vs_surfaces = {
+   .dirty = {
+      .mesa = (PIPE_NEW_VERTEX_CONSTANTS |
+	       PIPE_NEW_VERTEX_SHADER),
+      .brw = 0,
+      .cache = 0
+   },
+   .prepare = prepare_vs_surfaces,
+};
+
+
+
diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h
new file mode 100644
index 0000000..a242e31
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_winsys.h
@@ -0,0 +1,309 @@
+/**************************************************************************
+ *
+ * Copyright © 2009 Jakob Bornecrantz
+ *
+ * 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, sublicense,
+ * 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ **************************************************************************/
+
+#ifndef BRW_WINSYS_H
+#define BRW_WINSYS_H
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_refcnt.h"
+
+struct brw_winsys;
+struct pipe_fence_handle;
+
+/* Not sure why the winsys needs this:
+ */
+#define BRW_BATCH_SIZE (32*1024)
+
+struct brw_winsys_screen;
+
+/* Need a tiny bit of information inside the abstract buffer struct:
+ */
+struct brw_winsys_buffer {
+   struct pipe_reference reference;
+   struct brw_winsys_screen *sws;
+   unsigned size;
+};
+
+
+/* Should be possible to validate usages above against buffer creation
+ * types, below:
+ */
+enum brw_buffer_type
+{
+   BRW_BUFFER_TYPE_TEXTURE,
+   BRW_BUFFER_TYPE_SCANOUT,          /**< a texture used for scanning out from */
+   BRW_BUFFER_TYPE_VERTEX,
+   BRW_BUFFER_TYPE_CURBE,
+   BRW_BUFFER_TYPE_QUERY,
+   BRW_BUFFER_TYPE_SHADER_CONSTANTS,
+   BRW_BUFFER_TYPE_SHADER_SCRATCH,
+   BRW_BUFFER_TYPE_BATCH,
+   BRW_BUFFER_TYPE_GENERAL_STATE,
+   BRW_BUFFER_TYPE_SURFACE_STATE,
+   BRW_BUFFER_TYPE_PIXEL,            /* image uploads, pbo's, etc */
+   BRW_BUFFER_TYPE_GENERIC,          /* unknown */
+   BRW_BUFFER_TYPE_MAX               /* Count of possible values */
+};
+
+
+/* Describe the usage of a particular buffer in a relocation.  The DRM
+ * winsys will translate these back to GEM read/write domain flags.
+ */
+enum brw_buffer_usage {
+   BRW_USAGE_STATE,         /* INSTRUCTION, 0 */
+   BRW_USAGE_QUERY_RESULT,  /* INSTRUCTION, INSTRUCTION */
+   BRW_USAGE_RENDER_TARGET, /* RENDER,      0 */
+   BRW_USAGE_DEPTH_BUFFER,  /* RENDER,      RENDER */
+   BRW_USAGE_BLIT_SOURCE,   /* RENDER,      0 */
+   BRW_USAGE_BLIT_DEST,     /* RENDER,      RENDER */
+   BRW_USAGE_SAMPLER,       /* SAMPLER,     0 */
+   BRW_USAGE_VERTEX,        /* VERTEX,      0 */
+   BRW_USAGE_SCRATCH,       /* 0,           0 */
+   BRW_USAGE_MAX
+};
+
+enum brw_buffer_data_type {
+   BRW_DATA_GS_CC_VP,
+   BRW_DATA_GS_CC_UNIT,
+   BRW_DATA_GS_WM_PROG,
+   BRW_DATA_GS_SAMPLER_DEFAULT_COLOR,
+   BRW_DATA_GS_SAMPLER,
+   BRW_DATA_GS_WM_UNIT,
+   BRW_DATA_GS_SF_PROG,
+   BRW_DATA_GS_SF_VP,
+   BRW_DATA_GS_SF_UNIT,
+   BRW_DATA_GS_VS_UNIT,
+   BRW_DATA_GS_VS_PROG,
+   BRW_DATA_GS_GS_UNIT,
+   BRW_DATA_GS_GS_PROG,
+   BRW_DATA_GS_CLIP_VP,
+   BRW_DATA_GS_CLIP_UNIT,
+   BRW_DATA_GS_CLIP_PROG,
+   BRW_DATA_SS_SURFACE,
+   BRW_DATA_SS_SURF_BIND,
+   BRW_DATA_CONSTANT_BUFFER,
+   BRW_DATA_BATCH_BUFFER,
+   BRW_DATA_OTHER,
+   BRW_DATA_MAX
+};
+
+
+/* Matches the i915_drm definitions:
+ */
+#define BRW_TILING_NONE  0
+#define BRW_TILING_X     1
+#define BRW_TILING_Y     2
+
+
+/* Relocations to be applied with subdata in a call to sws->bo_subdata, below.
+ *
+ * Effectively this encodes:
+ *
+ *    (unsigned *)(subdata + offset) = bo->offset + delta
+ */
+struct brw_winsys_reloc {
+   enum brw_buffer_usage usage; /* debug only */
+   unsigned delta;
+   unsigned offset;
+   struct brw_winsys_buffer *bo;
+};
+
+static INLINE void make_reloc(struct brw_winsys_reloc *reloc,
+                              enum brw_buffer_usage usage,
+                              unsigned delta,
+                              unsigned offset,
+                              struct brw_winsys_buffer *bo)
+{
+   reloc->usage = usage;
+   reloc->delta = delta;
+   reloc->offset = offset;
+   reloc->bo = bo;              /* Note - note taking a reference yet */
+}
+
+
+
+struct brw_winsys_screen {
+
+
+   /**
+    * Buffer functions.
+    */
+
+   /*@{*/
+   /**
+    * Create a buffer.
+    */
+   enum pipe_error (*bo_alloc)(struct brw_winsys_screen *sws,
+                               enum brw_buffer_type type,
+                               unsigned size,
+                               unsigned alignment,
+                               struct brw_winsys_buffer **bo_out);
+
+   /* Destroy a buffer when our refcount goes to zero:
+    */
+   void (*bo_destroy)(struct brw_winsys_buffer *buffer);
+
+   /* delta -- added to b2->offset, and written into buffer
+    * offset -- location above value is written to within buffer
+    */
+   enum pipe_error (*bo_emit_reloc)(struct brw_winsys_buffer *buffer,
+                                    enum brw_buffer_usage usage,
+                                    unsigned delta,
+                                    unsigned offset,
+                                    struct brw_winsys_buffer *b2);
+
+   enum pipe_error (*bo_exec)(struct brw_winsys_buffer *buffer,
+                              unsigned bytes_used);
+
+   enum pipe_error (*bo_subdata)(struct brw_winsys_buffer *buffer,
+                                 enum brw_buffer_data_type data_type,
+                                 size_t offset,
+                                 size_t size,
+                                 const void *data,
+                                 const struct brw_winsys_reloc *reloc,
+                                 unsigned nr_reloc );
+
+   boolean (*bo_is_busy)(struct brw_winsys_buffer *buffer);
+   boolean (*bo_references)(struct brw_winsys_buffer *a,
+                            struct brw_winsys_buffer *b);
+
+   /* XXX: couldn't this be handled by returning true/false on
+    * bo_emit_reloc?
+    */
+   enum pipe_error (*check_aperture_space)(struct brw_winsys_screen *iws,
+                                           struct brw_winsys_buffer **buffers,
+                                           unsigned count);
+
+   /**
+    * Map a buffer.
+    */
+   void *(*bo_map)(struct brw_winsys_buffer *buffer,
+                   enum brw_buffer_data_type data_type,
+                   unsigned offset,
+                   unsigned length,
+                   boolean write,
+                   boolean discard,
+                   boolean flush_explicit);
+
+   void (*bo_flush_range)(struct brw_winsys_buffer *buffer,
+                          unsigned offset,
+                          unsigned length);
+
+   /**
+    * Unmap a buffer.
+    */
+   void (*bo_unmap)(struct brw_winsys_buffer *buffer);
+   /*@}*/
+
+   
+   /* Wait for buffer to go idle.  Similar to map+unmap, but doesn't
+    * mark buffer contents as dirty.
+    */
+   void (*bo_wait_idle)(struct brw_winsys_buffer *buffer);
+   
+   /**
+    * Destroy the winsys.
+    */
+   void (*destroy)(struct brw_winsys_screen *iws);
+};
+
+static INLINE void *
+bo_map_read(struct brw_winsys_screen *sws, struct brw_winsys_buffer *buf)
+{
+   return sws->bo_map( buf,
+                       BRW_DATA_OTHER,
+                       0, buf->size,
+                       FALSE, FALSE, FALSE );
+}
+
+static INLINE void
+bo_reference(struct brw_winsys_buffer **ptr, struct brw_winsys_buffer *buf)
+{
+   struct brw_winsys_buffer *old_buf = *ptr;
+
+   if (pipe_reference(&(*ptr)->reference, &buf->reference))
+      old_buf->sws->bo_destroy(old_buf);
+
+   *ptr = buf;
+}
+
+
+/**
+ * Create brw pipe_screen.
+ */
+struct pipe_screen *brw_create_screen(struct brw_winsys_screen *iws, unsigned pci_id);
+
+/**
+ * Create a brw pipe_context.
+ */
+struct pipe_context *brw_create_context(struct pipe_screen *screen);
+
+/**
+ * Get the brw_winsys buffer backing the texture.
+ *
+ * TODO UGLY
+ */
+struct pipe_texture;
+boolean brw_texture_get_winsys_buffer(struct pipe_texture *texture,
+                                      struct brw_winsys_buffer **buffer,
+                                      unsigned *stride);
+
+/**
+ * Wrap a brw_winsys buffer with a texture blanket.
+ *
+ * TODO UGLY
+ */
+struct pipe_texture * 
+brw_texture_blanket_winsys_buffer(struct pipe_screen *screen,
+                                  const struct pipe_texture *template,
+                                  unsigned pitch,
+				  unsigned tiling,
+                                  struct brw_winsys_buffer *buffer);
+
+
+/*************************************************************************
+ * Cooperative dumping between winsys and driver.  TODO: make this
+ * driver-only by wrapping calls to winsys->bo_subdata().
+ */
+
+#ifdef DEBUG
+extern int BRW_DUMP;
+#else
+#define BRW_DUMP 0
+#endif 
+
+#define DUMP_ASM	        0x1
+#define DUMP_STATE	        0x2
+#define DUMP_BATCH	        0x4
+
+void brw_dump_data( unsigned pci_id,
+		    enum brw_buffer_data_type data_type,
+		    unsigned offset,
+		    const void *data,
+		    size_t size );
+
+
+#endif
diff --git a/src/gallium/drivers/i965/brw_winsys_debug.c b/src/gallium/drivers/i965/brw_winsys_debug.c
new file mode 100644
index 0000000..f8f6a53
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_winsys_debug.c
@@ -0,0 +1,87 @@
+#include "brw_winsys.h"
+#include "brw_disasm.h"
+#include "brw_structs_dump.h"
+#include "brw_structs.h"
+#include "intel_decode.h"
+
+
+void brw_dump_data( unsigned pci_id,
+		    enum brw_buffer_data_type data_type,
+		    unsigned offset,
+		    const void *data,
+		    size_t size )
+{
+   if (BRW_DUMP & DUMP_ASM) {
+      switch (data_type) {
+      case BRW_DATA_GS_WM_PROG:
+      case BRW_DATA_GS_SF_PROG:
+      case BRW_DATA_GS_VS_PROG:
+      case BRW_DATA_GS_GS_PROG:
+      case BRW_DATA_GS_CLIP_PROG:
+         brw_disasm( stderr, data, size / sizeof(struct brw_instruction) );
+         break;
+      default:
+         break;
+      }
+   }
+
+   if (BRW_DUMP & DUMP_STATE) {
+      switch (data_type) {
+      case BRW_DATA_GS_CC_VP:
+         brw_dump_cc_viewport( data );
+         break;
+      case BRW_DATA_GS_CC_UNIT:
+         brw_dump_cc_unit_state( data );
+         break;
+      case BRW_DATA_GS_SAMPLER_DEFAULT_COLOR:
+         brw_dump_sampler_default_color( data );
+         break;
+      case BRW_DATA_GS_SAMPLER:
+         brw_dump_sampler_state( data );
+         break;
+      case BRW_DATA_GS_WM_UNIT:
+         brw_dump_wm_unit_state( data );
+         break;
+      case BRW_DATA_GS_SF_VP:
+         brw_dump_sf_viewport( data );
+         break;
+      case BRW_DATA_GS_SF_UNIT:
+         brw_dump_sf_unit_state( data );
+         break;
+      case BRW_DATA_GS_VS_UNIT:
+         brw_dump_vs_unit_state( data );
+         break;
+      case BRW_DATA_GS_GS_UNIT:
+         brw_dump_gs_unit_state( data );
+         break;
+      case BRW_DATA_GS_CLIP_VP:
+         brw_dump_clipper_viewport( data );
+         break;
+      case BRW_DATA_GS_CLIP_UNIT:
+         brw_dump_clip_unit_state( data );
+         break;
+      case BRW_DATA_SS_SURFACE:
+         brw_dump_surface_state( data );
+         break;
+      case BRW_DATA_SS_SURF_BIND:
+         break;
+      case BRW_DATA_OTHER:
+         break;
+      case BRW_DATA_CONSTANT_BUFFER:
+         break;
+      default:
+         break;
+      }
+   }
+
+   if (BRW_DUMP & DUMP_BATCH) {
+      switch (data_type) {
+      case BRW_DATA_BATCH_BUFFER:
+         intel_decode(data, size / 4, offset, pci_id);
+         break;
+      default:
+         break;
+      }
+   }
+}
+
diff --git a/src/gallium/drivers/i965/brw_wm.c b/src/gallium/drivers/i965/brw_wm.c
new file mode 100644
index 0000000..fdf820a
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_wm.c
@@ -0,0 +1,319 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+#include "tgsi/tgsi_info.h"
+
+#include "brw_context.h"
+#include "brw_screen.h"
+#include "brw_util.h"
+#include "brw_wm.h"
+#include "brw_state.h"
+#include "brw_debug.h"
+#include "brw_pipe_rast.h"
+
+
+/** Return number of src args for given instruction */
+GLuint brw_wm_nr_args( GLuint opcode )
+{
+   switch (opcode) {
+   case WM_FRONTFACING:
+   case WM_PIXELXY:
+      return 0;
+   case WM_CINTERP:
+   case WM_WPOSXY:
+   case WM_DELTAXY:
+      return 1;
+   case WM_LINTERP:
+   case WM_PIXELW:
+      return 2;
+   case WM_FB_WRITE:
+   case WM_PINTERP:
+      return 3;
+   case TGSI_OPCODE_TEX:
+   case TGSI_OPCODE_TXP:
+   case TGSI_OPCODE_TXB:
+   case TGSI_OPCODE_TXD:
+      /* sampler arg is held as a field in the instruction, not in an
+       * actual register:
+       */
+      return tgsi_get_opcode_info(opcode)->num_src - 1;
+
+   default:
+      assert(opcode < MAX_OPCODE);
+      return tgsi_get_opcode_info(opcode)->num_src;
+   }
+}
+
+
+GLuint brw_wm_is_scalar_result( GLuint opcode )
+{
+   switch (opcode) {
+   case TGSI_OPCODE_COS:
+   case TGSI_OPCODE_EX2:
+   case TGSI_OPCODE_LG2:
+   case TGSI_OPCODE_POW:
+   case TGSI_OPCODE_RCP:
+   case TGSI_OPCODE_RSQ:
+   case TGSI_OPCODE_SIN:
+   case TGSI_OPCODE_DP3:
+   case TGSI_OPCODE_DP4:
+   case TGSI_OPCODE_DPH:
+   case TGSI_OPCODE_DST:
+      return 1;
+      
+   default:
+      return 0;
+   }
+}
+
+
+/**
+ * Do GPU code generation for shaders without flow control.  Shaders
+ * without flow control instructions can more readily be analysed for
+ * SSA-style optimizations.
+ */
+static void
+brw_wm_linear_shader_emit(struct brw_context *brw, struct brw_wm_compile *c)
+{
+   /* Augment fragment program.  Add instructions for pre- and
+    * post-fragment-program tasks such as interpolation and fogging.
+    */
+   brw_wm_pass_fp(c);
+
+   /* Translate to intermediate representation.  Build register usage
+    * chains.
+    */
+   brw_wm_pass0(c);
+
+   /* Dead code removal.
+    */
+   brw_wm_pass1(c);
+
+   /* Register allocation.
+    * Divide by two because we operate on 16 pixels at a time and require
+    * two GRF entries for each logical shader register.
+    */
+   c->grf_limit = BRW_WM_MAX_GRF / 2;
+
+   brw_wm_pass2(c);
+
+   /* how many general-purpose registers are used */
+   c->prog_data.total_grf = c->max_wm_grf;
+
+   /* Scratch space is used for register spilling */
+   if (c->last_scratch) {
+      c->prog_data.total_scratch = c->last_scratch + 0x40;
+   }
+   else {
+      c->prog_data.total_scratch = 0;
+   }
+
+   /* Emit GEN4 code.
+    */
+   brw_wm_emit(c);
+}
+
+
+/**
+ * All Mesa program -> GPU code generation goes through this function.
+ * Depending on the instructions used (i.e. flow control instructions)
+ * we'll use one of two code generators.
+ */
+static enum pipe_error do_wm_prog( struct brw_context *brw,
+                                   struct brw_fragment_shader *fp, 
+                                   struct brw_wm_prog_key *key,
+                                   struct brw_winsys_buffer **bo_out)
+{
+   enum pipe_error ret;
+   struct brw_wm_compile *c;
+   const GLuint *program;
+   GLuint program_size;
+
+   if (brw->wm.compile_data == NULL) {
+      brw->wm.compile_data = MALLOC(sizeof(*brw->wm.compile_data));
+      if (!brw->wm.compile_data) 
+         return PIPE_ERROR_OUT_OF_MEMORY;
+   }
+
+   c = brw->wm.compile_data;
+   memset(c, 0, sizeof *c);
+
+   c->key = *key;
+   c->fp = fp;
+   c->env_param = NULL; /*brw->intel.ctx.FragmentProgram.Parameters;*/
+
+   brw_init_compile(brw, &c->func);
+
+   /*
+    * Shader which use GLSL features such as flow control are handled
+    * differently from "simple" shaders.
+    */
+   if (fp->has_flow_control) {
+      c->dispatch_width = 8;
+      /* XXX: GLSL support
+       */
+      exit(1);
+      /* brw_wm_branching_shader_emit(brw, c); */
+   }
+   else {
+      c->dispatch_width = 16;
+      brw_wm_linear_shader_emit(brw, c);
+   }
+
+   if (BRW_DEBUG & DEBUG_WM)
+      debug_printf("\n");
+
+   /* get the program
+    */
+   ret = brw_get_program(&c->func, &program, &program_size);
+   if (ret)
+      return ret;
+
+   ret = brw_upload_cache( &brw->cache, BRW_WM_PROG,
+                           &c->key, sizeof(c->key),
+                           NULL, 0,
+                           program, program_size,
+                           &c->prog_data,
+                           &brw->wm.prog_data,
+                           bo_out );
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+
+
+static void brw_wm_populate_key( struct brw_context *brw,
+				 struct brw_wm_prog_key *key )
+{
+   unsigned lookup, line_aa;
+   unsigned i;
+
+   memset(key, 0, sizeof(*key));
+
+   /* PIPE_NEW_FRAGMENT_SHADER
+    * PIPE_NEW_DEPTH_STENCIL_ALPHA
+    */
+   lookup = (brw->curr.zstencil->iz_lookup |
+	     brw->curr.fragment_shader->iz_lookup);
+
+
+   /* PIPE_NEW_RAST
+    * BRW_NEW_REDUCED_PRIMITIVE 
+    */
+   switch (brw->reduced_primitive) {
+   case PIPE_PRIM_POINTS:
+      line_aa = AA_NEVER;
+      break;
+   case PIPE_PRIM_LINES:
+      line_aa = (brw->curr.rast->templ.line_smooth ? 
+                 AA_ALWAYS : AA_NEVER);
+      break;
+   default:
+      line_aa = brw->curr.rast->unfilled_aa_line;
+      break;
+   }
+	 
+   brw_wm_lookup_iz(line_aa,
+		    lookup,
+		    brw->curr.fragment_shader->uses_depth,
+		    key);
+
+   /* PIPE_NEW_RAST */
+   key->flat_shade = brw->curr.rast->templ.flatshade;
+
+
+   /* PIPE_NEW_BOUND_TEXTURES */
+   for (i = 0; i < brw->curr.num_textures; i++) {
+      const struct brw_texture *tex = brw_texture(brw->curr.texture[i]);
+	 
+      if (tex->base.format == PIPE_FORMAT_YCBCR)
+	 key->yuvtex_mask |= 1 << i;
+
+      if (tex->base.format == PIPE_FORMAT_YCBCR_REV)
+	 key->yuvtex_swap_mask |= 1 << i;
+
+      /* XXX: shadow texture
+       */
+      /* key->shadowtex_mask |= 1<<i; */
+   }
+
+   /* CACHE_NEW_VS_PROG */
+   key->vp_nr_outputs = brw->vs.prog_data->nr_outputs;
+
+   key->nr_cbufs = brw->curr.fb.nr_cbufs;
+
+   key->nr_inputs = brw->curr.fragment_shader->info.num_inputs;
+
+   /* The unique fragment program ID */
+   key->program_string_id = brw->curr.fragment_shader->id;
+}
+
+
+static enum pipe_error brw_prepare_wm_prog(struct brw_context *brw)
+{
+   struct brw_wm_prog_key key;
+   struct brw_fragment_shader *fs = brw->curr.fragment_shader;
+   enum pipe_error ret;
+     
+   brw_wm_populate_key(brw, &key);
+
+   /* Make an early check for the key.
+    */
+   if (brw_search_cache(&brw->cache, BRW_WM_PROG,
+                        &key, sizeof(key),
+                        NULL, 0,
+                        &brw->wm.prog_data,
+                        &brw->wm.prog_bo))
+      return PIPE_OK;
+
+   ret = do_wm_prog(brw, fs, &key, &brw->wm.prog_bo);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+
+const struct brw_tracked_state brw_wm_prog = {
+   .dirty = {
+      .mesa  = (PIPE_NEW_FRAGMENT_SHADER |
+		PIPE_NEW_DEPTH_STENCIL_ALPHA |
+		PIPE_NEW_RAST |
+		PIPE_NEW_NR_CBUFS |
+		PIPE_NEW_BOUND_TEXTURES),
+      .brw   = (BRW_NEW_WM_INPUT_DIMENSIONS |
+		BRW_NEW_REDUCED_PRIMITIVE),
+      .cache = CACHE_NEW_VS_PROG,
+   },
+   .prepare = brw_prepare_wm_prog
+};
+
diff --git a/src/gallium/drivers/i965/brw_wm.h b/src/gallium/drivers/i965/brw_wm.h
new file mode 100644
index 0000000..f1ca9f6
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_wm.h
@@ -0,0 +1,344 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+              
+
+#ifndef BRW_WM_H
+#define BRW_WM_H
+
+#include "brw_context.h"
+#include "brw_eu.h"
+
+#define SATURATE (1<<5)
+
+/* A big lookup table is used to figure out which and how many
+ * additional regs will inserted before the main payload in the WM
+ * program execution.  These mainly relate to depth and stencil
+ * processing and the early-depth-test optimization.
+ */
+#define IZ_PS_KILL_ALPHATEST_BIT    0x1
+#define IZ_PS_COMPUTES_DEPTH_BIT    0x2
+#define IZ_DEPTH_WRITE_ENABLE_BIT   0x4
+#define IZ_DEPTH_TEST_ENABLE_BIT    0x8
+#define IZ_STENCIL_WRITE_ENABLE_BIT 0x10
+#define IZ_STENCIL_TEST_ENABLE_BIT  0x20
+#define IZ_BIT_MAX                  0x40
+
+#define AA_NEVER     0
+#define AA_SOMETIMES 1
+#define AA_ALWAYS    2
+
+struct brw_wm_prog_key {
+   GLuint source_depth_reg:3;
+   GLuint aa_dest_stencil_reg:3;
+   GLuint dest_depth_reg:3;
+   GLuint nr_depth_regs:3;
+   GLuint computes_depth:1;
+   GLuint source_depth_to_render_target:1;
+   GLuint flat_shade:1;
+   GLuint runtime_check_aads_emit:1;
+
+   GLuint shadowtex_mask:16;
+   GLuint yuvtex_mask:16;
+   GLuint yuvtex_swap_mask:16;	/* UV swaped */
+
+   GLuint vp_nr_outputs:6;
+   GLuint nr_inputs:6;
+   GLuint nr_cbufs:3;
+   GLuint has_flow_control:1;
+
+   GLuint program_string_id;
+};
+
+
+/* A bit of a glossary:
+ *
+ * brw_wm_value: A computed value or program input.  Values are
+ * constant, they are created once and are never modified.  When a
+ * fragment program register is written or overwritten, new values are
+ * created fresh, preserving the rule that values are constant.
+ *
+ * brw_wm_ref: A reference to a value.  Wherever a value used is by an
+ * instruction or as a program output, that is tracked with an
+ * instance of this struct.  All references to a value occur after it
+ * is created.  After the last reference, a value is dead and can be
+ * discarded.
+ *
+ * brw_wm_grf: Represents a physical hardware register.  May be either
+ * empty or hold a value.  Register allocation is the process of
+ * assigning values to grf registers.  This occurs in pass2 and the
+ * brw_wm_grf struct is not used before that.
+ *
+ * Fragment program registers: These are time-varying constructs that
+ * are hard to reason about and which we translate away in pass0.  A
+ * single fragment program register element (eg. temp[0].x) will be
+ * translated to one or more brw_wm_value structs, one for each time
+ * that temp[0].x is written to during the program. 
+ */
+
+
+
+/* Used in pass2 to track register allocation.
+ */
+struct brw_wm_grf {
+   struct brw_wm_value *value;
+   GLuint nextuse;
+};
+
+struct brw_wm_value {
+   struct brw_reg hw_reg;	/* emitted to this reg, may not always be there */
+   struct brw_wm_ref *lastuse;
+   struct brw_wm_grf *resident; 
+   GLuint contributes_to_output:1;
+   GLuint spill_slot:16;	/* if non-zero, spill immediately after calculation */
+};
+
+struct brw_wm_ref {
+   struct brw_reg hw_reg;	/* nr filled in in pass2, everything else, pass0 */
+   struct brw_wm_value *value;
+   struct brw_wm_ref *prevuse;
+   GLuint unspill_reg:7;	/* unspill to reg */
+   GLuint emitted:1;
+   GLuint insn:24;
+};
+
+struct brw_wm_instruction {
+   struct brw_wm_value *dst[4];
+   struct brw_wm_ref *src[3][4];
+   GLuint opcode:8;
+   GLuint saturate:1;
+   GLuint writemask:4;
+   GLuint sampler:4;
+   GLuint tex_unit:4;   /* texture/sampler unit for texture instructions */
+   GLuint target:4;     /* TGSI_TEXTURE_x for texture instructions,
+                         * target binding table index for FB_WRITE
+                         */
+   GLuint eot:1;    	/* End of thread indicator for FB_WRITE*/
+};
+
+
+#define BRW_WM_MAX_INSN  2048
+#define BRW_WM_MAX_GRF   128		/* hardware limit */
+#define BRW_WM_MAX_VREG  (BRW_WM_MAX_INSN * 4)
+#define BRW_WM_MAX_REF   (BRW_WM_MAX_INSN * 12)
+#define BRW_WM_MAX_PARAM 256
+#define BRW_WM_MAX_CONST 256
+#define BRW_WM_MAX_KILLS MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS
+#define BRW_WM_MAX_SUBROUTINE 16
+
+
+/* New opcodes to track internal operations required for WM unit.
+ * These are added early so that the registers used can be tracked,
+ * freed and reused like those of other instructions.
+ */
+#define MAX_OPCODE        TGSI_OPCODE_LAST
+#define WM_PIXELXY        (MAX_OPCODE)
+#define WM_DELTAXY        (MAX_OPCODE + 1)
+#define WM_PIXELW         (MAX_OPCODE + 2)
+#define WM_LINTERP        (MAX_OPCODE + 3)
+#define WM_PINTERP        (MAX_OPCODE + 4)
+#define WM_CINTERP        (MAX_OPCODE + 5)
+#define WM_WPOSXY         (MAX_OPCODE + 6)
+#define WM_FB_WRITE       (MAX_OPCODE + 7)
+#define WM_FRONTFACING    (MAX_OPCODE + 8)
+#define MAX_WM_OPCODE     (MAX_OPCODE + 9)
+
+#define BRW_FILE_PAYLOAD   (TGSI_FILE_COUNT)
+#define PAYLOAD_DEPTH      (PIPE_MAX_SHADER_INPUTS) /* ?? */
+
+#define X    0
+#define Y    1
+#define Z    2
+#define W    3
+
+
+struct brw_fp_src {
+   unsigned file:4;
+   unsigned index:16;
+   unsigned swizzle:8;
+   unsigned indirect:1;
+   unsigned negate:1;
+   unsigned abs:1;
+};
+
+struct brw_fp_dst {
+   unsigned file:4;
+   unsigned index:16;
+   unsigned writemask:4;
+   unsigned indirect:1;
+   unsigned saturate:1;
+};
+
+struct brw_fp_instruction {
+   struct brw_fp_dst dst;
+   struct brw_fp_src src[3];
+   unsigned opcode:8;
+   unsigned target:8; /* XXX: special usage for FB_WRITE */
+   unsigned tex_unit:4;
+   unsigned sampler:4;
+   unsigned pad:8;
+};
+
+
+struct brw_wm_compile {
+   struct brw_compile func;
+   struct brw_wm_prog_key key;
+   struct brw_wm_prog_data prog_data;
+
+   struct brw_fragment_shader *fp;
+
+   GLfloat (*env_param)[4];
+
+   enum {
+      START,
+      PASS2_DONE
+   } state;
+
+   /* Initial pass - translate fp instructions to fp instructions,
+    * simplifying and adding instructions for interpolation and
+    * framebuffer writes.
+    */
+   struct {
+      GLfloat v[4];
+      unsigned nr;
+   } immediate[BRW_WM_MAX_CONST+3];
+   GLuint nr_immediates;
+   
+   struct brw_fp_instruction fp_instructions[BRW_WM_MAX_INSN];
+   GLuint nr_fp_insns;
+   GLuint fp_temp;
+   GLuint fp_interp_emitted;
+   GLuint fp_fragcolor_emitted;
+   GLuint fp_first_internal_temp;
+
+   struct brw_fp_src fp_pixel_xy;
+   struct brw_fp_src fp_delta_xy;
+   struct brw_fp_src fp_pixel_w;
+
+
+   /* Subsequent passes using SSA representation:
+    */
+   struct brw_wm_value vreg[BRW_WM_MAX_VREG];
+   GLuint nr_vreg;
+
+   struct brw_wm_value creg[BRW_WM_MAX_PARAM];
+   GLuint nr_creg;
+
+   struct {
+      struct brw_wm_value depth[4]; /* includes r0/r1 */
+      struct brw_wm_value input_interp[PIPE_MAX_SHADER_INPUTS];
+   } payload;
+
+
+   const struct brw_wm_ref *pass0_fp_reg[BRW_FILE_PAYLOAD+1][256][4];
+
+   struct brw_wm_ref undef_ref;
+   struct brw_wm_value undef_value;
+
+   struct brw_wm_ref refs[BRW_WM_MAX_REF];
+   GLuint nr_refs;
+
+   struct brw_wm_instruction instruction[BRW_WM_MAX_INSN];
+   GLuint nr_insns;
+
+   struct brw_wm_grf pass2_grf[BRW_WM_MAX_GRF/2];
+
+   GLuint grf_limit;
+   GLuint max_wm_grf;
+   GLuint last_scratch;
+
+   GLuint cur_inst;  /**< index of current instruction */
+
+   GLboolean out_of_regs;  /**< ran out of GRF registers? */
+
+   /** Mapping from Mesa registers to hardware registers */
+   struct {
+      GLboolean inited;
+      struct brw_reg reg;
+   } wm_regs[BRW_FILE_PAYLOAD+1][256][4];
+
+   GLboolean used_grf[BRW_WM_MAX_GRF];
+   GLuint first_free_grf;
+   struct brw_reg stack;
+   struct brw_reg emit_mask_reg;
+   GLuint tmp_regs[BRW_WM_MAX_GRF];
+   GLuint tmp_index;
+   GLuint tmp_max;
+   GLuint subroutines[BRW_WM_MAX_SUBROUTINE];
+   GLuint dispatch_width;
+
+   /** we may need up to 3 constants per instruction (if use_const_buffer) */
+   struct {
+      GLint index;
+      struct brw_reg reg;
+   } current_const[3];
+
+   GLuint error;
+};
+
+
+GLuint brw_wm_nr_args( GLuint opcode );
+GLuint brw_wm_is_scalar_result( GLuint opcode );
+
+int brw_wm_pass_fp( struct brw_wm_compile *c );
+void brw_wm_pass0( struct brw_wm_compile *c );
+void brw_wm_pass1( struct brw_wm_compile *c );
+void brw_wm_pass2( struct brw_wm_compile *c );
+void brw_wm_emit( struct brw_wm_compile *c );
+
+void brw_wm_print_value( struct brw_wm_compile *c,
+			 struct brw_wm_value *value );
+
+void brw_wm_print_ref( struct brw_wm_compile *c,
+		       struct brw_wm_ref *ref );
+
+void brw_wm_print_insn( struct brw_wm_compile *c,
+			struct brw_wm_instruction *inst );
+
+void brw_wm_print_program( struct brw_wm_compile *c,
+			   const char *stage );
+
+void brw_wm_print_fp_program( struct brw_wm_compile *c,
+                              const char *stage );
+
+void brw_wm_lookup_iz( GLuint line_aa,
+		       GLuint lookup,
+		       GLboolean ps_uses_depth,
+		       struct brw_wm_prog_key *key );
+
+void brw_wm_branching_shader_emit(struct brw_context *brw, struct brw_wm_compile *c);
+
+void emit_ddxy(struct brw_compile *p,
+	       const struct brw_reg *dst,
+	       GLuint mask,
+	       GLboolean is_ddx,
+	       const struct brw_reg *arg0);
+
+#endif
diff --git a/src/gallium/drivers/i965/brw_wm_constant_buffer.c b/src/gallium/drivers/i965/brw_wm_constant_buffer.c
new file mode 100644
index 0000000..6434c6a
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_wm_constant_buffer.c
@@ -0,0 +1,165 @@
+/* XXX: Constant buffers disabled
+ */
+
+
+/**
+ * Create the constant buffer surface.  Vertex/fragment shader constants will be
+ * read from this buffer with Data Port Read instructions/messages.
+ */
+enum pipe_error
+brw_create_constant_surface( struct brw_context *brw,
+                             struct brw_surface_key *key,
+                             struct brw_winsys_buffer **bo_out )
+{
+   const GLint w = key->width - 1;
+   struct brw_winsys_buffer *bo;
+   struct brw_winsys_reloc reloc[1];
+   enum pipe_error ret;
+
+      /* Emit relocation to surface contents */
+   make_reloc(&reloc[0],
+              BRW_USAGE_SAMPLER,
+              0,
+              offsetof(struct brw_surface_state, ss1),
+              key->bo);
+
+   
+   memset(&surf, 0, sizeof(surf));
+
+   surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
+   surf.ss0.surface_type = BRW_SURFACE_BUFFER;
+   surf.ss0.surface_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
+
+   surf.ss1.base_addr = 0; /* reloc */
+
+   surf.ss2.width = w & 0x7f;            /* bits 6:0 of size or width */
+   surf.ss2.height = (w >> 7) & 0x1fff;  /* bits 19:7 of size or width */
+   surf.ss3.depth = (w >> 20) & 0x7f;    /* bits 26:20 of size or width */
+   surf.ss3.pitch = (key->pitch * key->cpp) - 1; /* ignored?? */
+   brw_set_surface_tiling(&surf, key->tiling); /* tiling now allowed */
+ 
+   ret = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
+                          key, sizeof(*key),
+                          reloc, Elements(reloc),
+                          &surf, sizeof(surf),
+                          NULL, NULL,
+                          &bo_out);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+
+
+/**
+ * Update the surface state for a WM constant buffer.
+ * The constant buffer will be (re)allocated here if needed.
+ */
+static enum pipe_error
+brw_update_wm_constant_surface( struct brw_context *brw,
+                                GLuint surf)
+{
+   struct brw_surface_key key;
+   struct brw_fragment_shader *fp = brw->curr.fragment_shader;
+   struct pipe_buffer *cbuf = brw->curr.fragment_constants;
+   int pitch = cbuf->size / (4 * sizeof(float));
+   enum pipe_error ret;
+
+   /* If we're in this state update atom, we need to update WM constants, so
+    * free the old buffer and create a new one for the new contents.
+    */
+   ret = brw_wm_update_constant_buffer(brw, &fp->const_buffer);
+   if (ret)
+      return ret;
+
+   /* If there's no constant buffer, then no surface BO is needed to point at
+    * it.
+    */
+   if (cbuf == NULL) {
+      bo_reference(&brw->wm.surf_bo[surf], NULL);
+      return PIPE_OK;
+   }
+
+   memset(&key, 0, sizeof(key));
+
+   key.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
+   key.ss0.surface_type = BRW_SURFACE_BUFFER;
+   key.ss0.surface_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
+
+   key.bo = brw_buffer(cbuf)->bo;
+
+   key.ss2.width = (pitch-1) & 0x7f;            /* bits 6:0 of size or width */
+   key.ss2.height = ((pitch-1) >> 7) & 0x1fff;  /* bits 19:7 of size or width */
+   key.ss3.depth = ((pitch-1) >> 20) & 0x7f;    /* bits 26:20 of size or width */
+   key.ss3.pitch = (pitch * 4 * sizeof(float)) - 1; /* ignored?? */
+   brw_set_surface_tiling(&surf, key->tiling); /* tiling now allowed */
+
+
+   /*
+   printf("%s:\n", __FUNCTION__);
+   printf("  width %d  height %d  depth %d  cpp %d  pitch %d\n",
+          key.width, key.height, key.depth, key.cpp, key.pitch);
+   */
+
+   if (brw_search_cache(&brw->surface_cache,
+                        BRW_SS_SURFACE,
+                        &key, sizeof(key),
+                        &key.bo, 1,
+                        NULL,
+                        &brw->wm.surf_bo[surf]))
+      return PIPE_OK;
+
+   ret = brw_create_constant_surface(brw, &key, &brw->wm.surf_bo[surf]);
+   if (ret)
+      return ret;
+
+   brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
+   return PIPE_OK;
+}
+
+/**
+ * Updates surface / buffer for fragment shader constant buffer, if
+ * one is required.
+ *
+ * This consumes the state updates for the constant buffer, and produces
+ * BRW_NEW_WM_SURFACES to get picked up by brw_prepare_wm_surfaces for
+ * inclusion in the binding table.
+ */
+static enum pipe_error prepare_wm_constant_surface(struct brw_context *brw )
+{
+   struct brw_fragment_program *fp =
+      (struct brw_fragment_program *) brw->fragment_program;
+   GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER;
+
+   ret = brw_wm_update_constant_buffer(brw,
+                                       &fp->const_buffer);
+   if (ret)
+      return ret;
+
+   /* If there's no constant buffer, then no surface BO is needed to point at
+    * it.
+    */
+   if (fp->const_buffer == 0) {
+      if (brw->wm.surf_bo[surf] != NULL) {
+	 bo_reference(&brw->wm.surf_bo[surf], NULL);
+	 brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
+      }
+      return PIPE_OK;
+   }
+
+   ret = brw_update_wm_constant_surface(ctx, surf);
+   if (ret)
+      return ret;
+
+   return PIPE_OK
+}
+
+const struct brw_tracked_state brw_wm_constant_surface = {
+   .dirty = {
+      .mesa = (_NEW_PROGRAM_CONSTANTS),
+      .brw = (BRW_NEW_FRAGMENT_PROGRAM),
+      .cache = 0
+   },
+   .prepare = prepare_wm_constant_surface,
+};
diff --git a/src/gallium/drivers/i965/brw_wm_debug.c b/src/gallium/drivers/i965/brw_wm_debug.c
new file mode 100644
index 0000000..3d11fa0
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_wm_debug.c
@@ -0,0 +1,256 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "tgsi/tgsi_info.h"
+
+#include "brw_context.h"
+#include "brw_wm.h"
+
+static void print_writemask( unsigned writemask )
+{
+   if (writemask != BRW_WRITEMASK_XYZW)
+      debug_printf(".%s%s%s%s", 
+		   (writemask & BRW_WRITEMASK_X) ? "x" : "",
+		   (writemask & BRW_WRITEMASK_Y) ? "y" : "",
+		   (writemask & BRW_WRITEMASK_Z) ? "z" : "",
+		   (writemask & BRW_WRITEMASK_W) ? "w" : "");
+}
+
+static void print_swizzle( unsigned swizzle )
+{
+   char *swz = "xyzw";
+   if (swizzle != BRW_SWIZZLE_XYZW)
+      debug_printf(".%c%c%c%c", 
+		   swz[BRW_GET_SWZ(swizzle, X)],
+		   swz[BRW_GET_SWZ(swizzle, Y)],
+		   swz[BRW_GET_SWZ(swizzle, Z)],
+		   swz[BRW_GET_SWZ(swizzle, W)]);
+}
+
+static void print_opcode( unsigned opcode )
+{
+   switch (opcode) {
+   case WM_PIXELXY:
+      debug_printf("PIXELXY");
+      break;
+   case WM_DELTAXY:
+      debug_printf("DELTAXY");
+      break;
+   case WM_PIXELW:
+      debug_printf("PIXELW");
+      break;
+   case WM_WPOSXY:
+      debug_printf("WPOSXY");
+      break;
+   case WM_PINTERP:
+      debug_printf("PINTERP");
+      break;
+   case WM_LINTERP:
+      debug_printf("LINTERP");
+      break;
+   case WM_CINTERP:
+      debug_printf("CINTERP");
+      break;
+   case WM_FB_WRITE:
+      debug_printf("FB_WRITE");
+      break;
+   case WM_FRONTFACING:
+      debug_printf("FRONTFACING");
+      break;
+   default:
+      debug_printf("%s", tgsi_get_opcode_info(opcode)->mnemonic);
+      break;
+   }
+}
+
+void brw_wm_print_value( struct brw_wm_compile *c,
+		       struct brw_wm_value *value )
+{
+   assert(value);
+   if (c->state >= PASS2_DONE) 
+      brw_print_reg(value->hw_reg);
+   else if( value == &c->undef_value )
+      debug_printf("undef");
+   else if( value - c->vreg >= 0 &&
+	    value - c->vreg < BRW_WM_MAX_VREG)
+      debug_printf("r%d", value - c->vreg);
+   else if (value - c->creg >= 0 &&
+	    value - c->creg < BRW_WM_MAX_PARAM)
+      debug_printf("c%d", value - c->creg);
+   else if (value - c->payload.input_interp >= 0 &&
+	    value - c->payload.input_interp < PIPE_MAX_SHADER_INPUTS)
+      debug_printf("i%d", value - c->payload.input_interp);
+   else if (value - c->payload.depth >= 0 &&
+	    value - c->payload.depth < PIPE_MAX_SHADER_INPUTS)
+      debug_printf("d%d", value - c->payload.depth);
+   else 
+      debug_printf("?");
+}
+
+void brw_wm_print_ref( struct brw_wm_compile *c,
+		       struct brw_wm_ref *ref )
+{
+   struct brw_reg hw_reg = ref->hw_reg;
+
+   if (ref->unspill_reg)
+      debug_printf("UNSPILL(%x)/", ref->value->spill_slot);
+
+   if (c->state >= PASS2_DONE)
+      brw_print_reg(ref->hw_reg);
+   else {
+      debug_printf("%s", hw_reg.negate ? "-" : "");
+      debug_printf("%s", hw_reg.abs ? "abs/" : "");
+      brw_wm_print_value(c, ref->value);
+      if ((hw_reg.nr&1) || hw_reg.subnr) {
+	 debug_printf("->%d.%d", (hw_reg.nr&1), hw_reg.subnr);
+      }
+   }
+}
+
+void brw_wm_print_insn( struct brw_wm_compile *c,
+			struct brw_wm_instruction *inst )
+{
+   GLuint i, arg;
+   GLuint nr_args = brw_wm_nr_args(inst->opcode);
+
+   debug_printf("[");
+   for (i = 0; i < 4; i++) {
+      if (inst->dst[i]) {
+	 brw_wm_print_value(c, inst->dst[i]);
+	 if (inst->dst[i]->spill_slot)
+	    debug_printf("/SPILL(%x)",inst->dst[i]->spill_slot);
+      }
+      else
+	 debug_printf("#");
+      if (i < 3)      
+	 debug_printf(",");
+   }
+   debug_printf("]");
+   print_writemask(inst->writemask);
+   
+   debug_printf(" = ");
+   print_opcode(inst->opcode);
+  
+   if (inst->saturate)
+      debug_printf("_SAT");
+
+   for (arg = 0; arg < nr_args; arg++) {
+
+      debug_printf(" [");
+
+      for (i = 0; i < 4; i++) {
+	 if (inst->src[arg][i]) {
+	    brw_wm_print_ref(c, inst->src[arg][i]);
+	 }
+	 else
+	    debug_printf("%%");
+
+	 if (i < 3) 
+	    debug_printf(",");
+	 else
+	    debug_printf("]");
+      }
+   }
+   debug_printf("\n");
+}
+
+void brw_wm_print_program( struct brw_wm_compile *c,
+			   const char *stage )
+{
+   GLuint insn;
+
+   debug_printf("%s:\n", stage);
+   for (insn = 0; insn < c->nr_insns; insn++)
+      brw_wm_print_insn(c, &c->instruction[insn]);
+   debug_printf("\n");
+}
+
+static const char *file_strings[TGSI_FILE_COUNT+1] = {
+   "NULL",
+   "CONST",
+   "IN",
+   "OUT",
+   "TEMP",
+   "SAMPLER",
+   "ADDR",
+   "IMM",
+   "LOOP",
+   "PAYLOAD"
+};
+
+static void brw_wm_print_fp_insn( struct brw_wm_compile *c,
+                                  struct brw_fp_instruction *inst )
+{
+   GLuint i;
+   GLuint nr_args = brw_wm_nr_args(inst->opcode);
+
+   print_opcode(inst->opcode);
+   if (inst->dst.saturate)
+      debug_printf("_SAT");
+   debug_printf(" ");
+
+   if (inst->dst.indirect)
+      debug_printf("[");
+
+   debug_printf("%s[%d]",
+                file_strings[inst->dst.file],
+                inst->dst.index );
+   print_writemask(inst->dst.writemask);
+
+   if (inst->dst.indirect)
+      debug_printf("]");
+
+   debug_printf(nr_args ? ", " : "\n");
+   
+   for (i = 0; i < nr_args; i++) {
+      debug_printf("%s%s%s[%d]%s",
+                   inst->src[i].negate ? "-" : "",
+                   inst->src[i].abs ? "ABS(" : "",
+                   file_strings[inst->src[i].file],
+                   inst->src[i].index,
+                   inst->src[i].abs ? ")" : "");
+      print_swizzle(inst->src[i].swizzle);
+      debug_printf("%s", i == nr_args - 1 ? "\n" : ", ");
+   }
+}
+
+
+void brw_wm_print_fp_program( struct brw_wm_compile *c,
+                              const char *stage )
+{
+   GLuint insn;
+
+   debug_printf("%s:\n", stage);
+   for (insn = 0; insn < c->nr_fp_insns; insn++)
+      brw_wm_print_fp_insn(c, &c->fp_instructions[insn]);
+   debug_printf("\n");
+}
+
diff --git a/src/gallium/drivers/i965/brw_wm_emit.c b/src/gallium/drivers/i965/brw_wm_emit.c
new file mode 100644
index 0000000..8f983a6
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_wm_emit.c
@@ -0,0 +1,1521 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "util/u_math.h"
+#include "tgsi/tgsi_info.h"
+
+#include "brw_context.h"
+#include "brw_wm.h"
+#include "brw_debug.h"
+#include "brw_disasm.h"
+
+/* Not quite sure how correct this is - need to understand horiz
+ * vs. vertical strides a little better.
+ */
+static INLINE struct brw_reg sechalf( struct brw_reg reg )
+{
+   if (reg.vstride)
+      reg.nr++;
+   return reg;
+}
+
+/* Payload R0:
+ *
+ * R0.0 -- pixel mask, one bit for each of 4 pixels in 4 quads,
+ *         corresponding to each of the 16 execution channels.
+ * R0.1..8 -- ?
+ * R1.0 -- triangle vertex 0.X
+ * R1.1 -- triangle vertex 0.Y
+ * R1.2 -- quad 0 x,y coords (2 packed uwords)
+ * R1.3 -- quad 1 x,y coords (2 packed uwords)
+ * R1.4 -- quad 2 x,y coords (2 packed uwords)
+ * R1.5 -- quad 3 x,y coords (2 packed uwords)
+ * R1.6 -- ?
+ * R1.7 -- ?
+ * R1.8 -- ?
+ */
+
+
+static void emit_pixel_xy(struct brw_compile *p,
+			  const struct brw_reg *dst,
+			  GLuint mask)
+{
+   struct brw_reg r1 = brw_vec1_grf(1, 0);
+   struct brw_reg r1_uw = retype(r1, BRW_REGISTER_TYPE_UW);
+
+   brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+
+   /* Calculate pixel centers by adding 1 or 0 to each of the
+    * micro-tile coordinates passed in r1.
+    */
+   if (mask & BRW_WRITEMASK_X) {
+      brw_ADD(p,
+	      vec16(retype(dst[0], BRW_REGISTER_TYPE_UW)),
+	      stride(suboffset(r1_uw, 4), 2, 4, 0),
+	      brw_imm_v(0x10101010));
+   }
+
+   if (mask & BRW_WRITEMASK_Y) {
+      brw_ADD(p,
+	      vec16(retype(dst[1], BRW_REGISTER_TYPE_UW)),
+	      stride(suboffset(r1_uw,5), 2, 4, 0),
+	      brw_imm_v(0x11001100));
+   }
+
+   brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
+}
+
+
+
+static void emit_delta_xy(struct brw_compile *p,
+			  const struct brw_reg *dst,
+			  GLuint mask,
+			  const struct brw_reg *arg0)
+{
+   struct brw_reg r1 = brw_vec1_grf(1, 0);
+
+   /* Calc delta X,Y by subtracting origin in r1 from the pixel
+    * centers.
+    */
+   if (mask & BRW_WRITEMASK_X) {
+      brw_ADD(p,
+	      dst[0],
+	      retype(arg0[0], BRW_REGISTER_TYPE_UW),
+	      negate(r1));
+   }
+
+   if (mask & BRW_WRITEMASK_Y) {
+      brw_ADD(p,
+	      dst[1],
+	      retype(arg0[1], BRW_REGISTER_TYPE_UW),
+	      negate(suboffset(r1,1)));
+
+   }
+}
+
+static void emit_wpos_xy(struct brw_wm_compile *c,
+			 const struct brw_reg *dst,
+			 GLuint mask,
+			 const struct brw_reg *arg0)
+{
+   struct brw_compile *p = &c->func;
+
+   if (mask & BRW_WRITEMASK_X) {
+      /* X' = X */
+      brw_MOV(p,
+	      dst[0],
+	      retype(arg0[0], BRW_REGISTER_TYPE_W));
+   }
+
+   /* XXX: is this needed any more, or is this a NOOP?
+    */
+   if (mask & BRW_WRITEMASK_Y) {
+#if 0
+      /* Y' = height - 1 - Y */
+      brw_ADD(p,
+	      dst[1],
+	      negate(retype(arg0[1], BRW_REGISTER_TYPE_W)),
+	      brw_imm_d(c->key.drawable_height - 1));
+#else
+      brw_MOV(p,
+	      dst[0],
+	      retype(arg0[0], BRW_REGISTER_TYPE_W));
+#endif
+   }
+}
+
+
+static void emit_pixel_w( struct brw_compile *p,
+			  const struct brw_reg *dst,
+			  GLuint mask,
+			  const struct brw_reg *arg0,
+			  const struct brw_reg *deltas)
+{
+   /* Don't need this if all you are doing is interpolating color, for
+    * instance.
+    */
+   if (mask & BRW_WRITEMASK_W) {      
+      struct brw_reg interp3 = brw_vec1_grf(arg0[0].nr+1, 4);
+
+      /* Calc 1/w - just linterp wpos[3] optimized by putting the
+       * result straight into a message reg.
+       */
+      brw_LINE(p, brw_null_reg(), interp3, deltas[0]);
+      brw_MAC(p, brw_message_reg(2), suboffset(interp3, 1), deltas[1]);
+
+      /* Calc w */
+      brw_math_16( p, dst[3],
+		   BRW_MATH_FUNCTION_INV,
+		   BRW_MATH_SATURATE_NONE,
+		   2, brw_null_reg(),
+		   BRW_MATH_PRECISION_FULL);
+   }
+}
+
+
+
+static void emit_linterp( struct brw_compile *p, 
+			 const struct brw_reg *dst,
+			 GLuint mask,
+			 const struct brw_reg *arg0,
+			 const struct brw_reg *deltas )
+{
+   struct brw_reg interp[4];
+   GLuint nr = arg0[0].nr;
+   GLuint i;
+
+   interp[0] = brw_vec1_grf(nr, 0);
+   interp[1] = brw_vec1_grf(nr, 4);
+   interp[2] = brw_vec1_grf(nr+1, 0);
+   interp[3] = brw_vec1_grf(nr+1, 4);
+
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {
+	 brw_LINE(p, brw_null_reg(), interp[i], deltas[0]);
+	 brw_MAC(p, dst[i], suboffset(interp[i],1), deltas[1]);
+      }
+   }
+}
+
+
+static void emit_pinterp( struct brw_compile *p, 
+			  const struct brw_reg *dst,
+			  GLuint mask,
+			  const struct brw_reg *arg0,
+			  const struct brw_reg *deltas,
+			  const struct brw_reg *w)
+{
+   struct brw_reg interp[4];
+   GLuint nr = arg0[0].nr;
+   GLuint i;
+
+   interp[0] = brw_vec1_grf(nr, 0);
+   interp[1] = brw_vec1_grf(nr, 4);
+   interp[2] = brw_vec1_grf(nr+1, 0);
+   interp[3] = brw_vec1_grf(nr+1, 4);
+
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {
+	 brw_LINE(p, brw_null_reg(), interp[i], deltas[0]);
+	 brw_MAC(p, dst[i], suboffset(interp[i],1), deltas[1]);
+      }
+   }
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {
+	 brw_MUL(p, dst[i], dst[i], w[3]);
+      }
+   }
+}
+
+
+static void emit_cinterp( struct brw_compile *p, 
+			 const struct brw_reg *dst,
+			 GLuint mask,
+			 const struct brw_reg *arg0 )
+{
+   struct brw_reg interp[4];
+   GLuint nr = arg0[0].nr;
+   GLuint i;
+
+   interp[0] = brw_vec1_grf(nr, 0);
+   interp[1] = brw_vec1_grf(nr, 4);
+   interp[2] = brw_vec1_grf(nr+1, 0);
+   interp[3] = brw_vec1_grf(nr+1, 4);
+
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {
+         brw_MOV(p, dst[i], suboffset(interp[i],3));	/* TODO: optimize away like other moves */
+      }
+   }
+}
+
+/* Sets the destination channels to 1.0 or 0.0 according to glFrontFacing. */
+static void emit_frontfacing( struct brw_compile *p,
+			      const struct brw_reg *dst,
+			      GLuint mask )
+{
+   struct brw_reg r1_6ud = retype(brw_vec1_grf(1, 6), BRW_REGISTER_TYPE_UD);
+   GLuint i;
+
+   if (!(mask & BRW_WRITEMASK_XYZW))
+      return;
+
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {
+	 brw_MOV(p, dst[i], brw_imm_f(0.0));
+      }
+   }
+
+   /* bit 31 is "primitive is back face", so checking < (1 << 31) gives
+    * us front face
+    */
+   brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, r1_6ud, brw_imm_ud(1 << 31));
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {
+	 brw_MOV(p, dst[i], brw_imm_f(1.0));
+      }
+   }
+   brw_set_predicate_control_flag_value(p, 0xff);
+}
+
+/* For OPCODE_DDX and OPCODE_DDY, per channel of output we've got input
+ * looking like:
+ *
+ * arg0: q0.tl q0.tr q0.bl q0.br q1.tl q1.tr q1.bl q1.br
+ *
+ * and we're trying to produce:
+ *
+ *           DDX                     DDY
+ * dst: (q0.tr - q0.tl)     (q0.tl - q0.bl)
+ *      (q0.tr - q0.tl)     (q0.tr - q0.br)
+ *      (q0.br - q0.bl)     (q0.tl - q0.bl)
+ *      (q0.br - q0.bl)     (q0.tr - q0.br)
+ *      (q1.tr - q1.tl)     (q1.tl - q1.bl)
+ *      (q1.tr - q1.tl)     (q1.tr - q1.br)
+ *      (q1.br - q1.bl)     (q1.tl - q1.bl)
+ *      (q1.br - q1.bl)     (q1.tr - q1.br)
+ *
+ * and add two more quads if in 16-pixel dispatch mode.
+ *
+ * For DDX, it ends up being easy: width = 2, horiz=0 gets us the same result
+ * for each pair, and vertstride = 2 jumps us 2 elements after processing a
+ * pair. But for DDY, it's harder, as we want to produce the pairs swizzled
+ * between each other.  We could probably do it like ddx and swizzle the right
+ * order later, but bail for now and just produce
+ * ((q0.tl - q0.bl)x4 (q1.tl - q1.bl)x4)
+ */
+void emit_ddxy(struct brw_compile *p,
+	       const struct brw_reg *dst,
+	       GLuint mask,
+	       GLboolean is_ddx,
+	       const struct brw_reg *arg0)
+{
+   int i;
+   struct brw_reg src0, src1;
+
+   if (mask & SATURATE)
+      brw_set_saturate(p, 1);
+   for (i = 0; i < 4; i++ ) {
+      if (mask & (1<<i)) {
+	 if (is_ddx) {
+	    src0 = brw_reg(arg0[i].file, arg0[i].nr, 1,
+			   BRW_REGISTER_TYPE_F,
+			   BRW_VERTICAL_STRIDE_2,
+			   BRW_WIDTH_2,
+			   BRW_HORIZONTAL_STRIDE_0,
+			   BRW_SWIZZLE_XYZW, BRW_WRITEMASK_XYZW);
+	    src1 = brw_reg(arg0[i].file, arg0[i].nr, 0,
+			   BRW_REGISTER_TYPE_F,
+			   BRW_VERTICAL_STRIDE_2,
+			   BRW_WIDTH_2,
+			   BRW_HORIZONTAL_STRIDE_0,
+			   BRW_SWIZZLE_XYZW, BRW_WRITEMASK_XYZW);
+	 } else {
+	    src0 = brw_reg(arg0[i].file, arg0[i].nr, 0,
+			   BRW_REGISTER_TYPE_F,
+			   BRW_VERTICAL_STRIDE_4,
+			   BRW_WIDTH_4,
+			   BRW_HORIZONTAL_STRIDE_0,
+			   BRW_SWIZZLE_XYZW, BRW_WRITEMASK_XYZW);
+	    src1 = brw_reg(arg0[i].file, arg0[i].nr, 2,
+			   BRW_REGISTER_TYPE_F,
+			   BRW_VERTICAL_STRIDE_4,
+			   BRW_WIDTH_4,
+			   BRW_HORIZONTAL_STRIDE_0,
+			   BRW_SWIZZLE_XYZW, BRW_WRITEMASK_XYZW);
+	 }
+	 brw_ADD(p, dst[i], src0, negate(src1));
+      }
+   }
+   if (mask & SATURATE)
+      brw_set_saturate(p, 0);
+}
+
+static void emit_alu1( struct brw_compile *p, 
+		       struct brw_instruction *(*func)(struct brw_compile *, 
+						       struct brw_reg, 
+						       struct brw_reg),
+		       const struct brw_reg *dst,
+		       GLuint mask,
+		       const struct brw_reg *arg0 )
+{
+   GLuint i;
+
+   if (mask & SATURATE)
+      brw_set_saturate(p, 1);
+
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {
+	 func(p, dst[i], arg0[i]);
+      }
+   }
+
+   if (mask & SATURATE)
+      brw_set_saturate(p, 0);
+}
+
+
+static void emit_alu2( struct brw_compile *p, 
+		       struct brw_instruction *(*func)(struct brw_compile *, 
+						       struct brw_reg, 
+						       struct brw_reg, 
+						       struct brw_reg),
+		       const struct brw_reg *dst,
+		       GLuint mask,
+		       const struct brw_reg *arg0,
+		       const struct brw_reg *arg1 )
+{
+   GLuint i;
+
+   if (mask & SATURATE)
+      brw_set_saturate(p, 1);
+
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {
+	 func(p, dst[i], arg0[i], arg1[i]);
+      }
+   }
+
+   if (mask & SATURATE)
+      brw_set_saturate(p, 0);
+}
+
+
+static void emit_mad( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1,
+		      const struct brw_reg *arg2 )
+{
+   GLuint i;
+
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {
+	 brw_MUL(p, dst[i], arg0[i], arg1[i]);
+
+	 brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
+	 brw_ADD(p, dst[i], dst[i], arg2[i]);
+	 brw_set_saturate(p, 0);
+      }
+   }
+}
+
+static void emit_trunc( struct brw_compile *p,
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0)
+{
+   GLuint i;
+
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {
+	 brw_RNDZ(p, dst[i], arg0[i]);
+      }
+   }
+}
+
+static void emit_lrp( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1,
+		      const struct brw_reg *arg2 )
+{
+   GLuint i;
+
+   /* Uses dst as a temporary:
+    */
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {	
+	 /* Can I use the LINE instruction for this? 
+	  */
+	 brw_ADD(p, dst[i], negate(arg0[i]), brw_imm_f(1.0));
+	 brw_MUL(p, brw_null_reg(), dst[i], arg2[i]);
+
+	 brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
+	 brw_MAC(p, dst[i], arg0[i], arg1[i]);
+	 brw_set_saturate(p, 0);
+      }
+   }
+}
+
+static void emit_sop( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      GLuint cond,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+   GLuint i;
+
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {	
+	 brw_MOV(p, dst[i], brw_imm_f(0));
+	 brw_CMP(p, brw_null_reg(), cond, arg0[i], arg1[i]);
+	 brw_MOV(p, dst[i], brw_imm_f(1.0));
+	 brw_set_predicate_control_flag_value(p, 0xff);
+      }
+   }
+}
+
+static void emit_slt( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+   emit_sop(p, dst, mask, BRW_CONDITIONAL_L, arg0, arg1);
+}
+
+static void emit_sle( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+   emit_sop(p, dst, mask, BRW_CONDITIONAL_LE, arg0, arg1);
+}
+
+static void emit_sgt( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+   emit_sop(p, dst, mask, BRW_CONDITIONAL_G, arg0, arg1);
+}
+
+static void emit_sge( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+   emit_sop(p, dst, mask, BRW_CONDITIONAL_GE, arg0, arg1);
+}
+
+static void emit_seq( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+   emit_sop(p, dst, mask, BRW_CONDITIONAL_EQ, arg0, arg1);
+}
+
+static void emit_sne( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+   emit_sop(p, dst, mask, BRW_CONDITIONAL_NEQ, arg0, arg1);
+}
+
+static void emit_cmp( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1,
+		      const struct brw_reg *arg2 )
+{
+   GLuint i;
+
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {	
+	 brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
+	 brw_MOV(p, dst[i], arg2[i]);
+	 brw_set_saturate(p, 0);
+
+	 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0[i], brw_imm_f(0));
+
+	 brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
+	 brw_MOV(p, dst[i], arg1[i]);
+	 brw_set_saturate(p, 0);
+	 brw_set_predicate_control_flag_value(p, 0xff);
+      }
+   }
+}
+
+static void emit_max( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+   GLuint i;
+
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {	
+	 brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
+	 brw_MOV(p, dst[i], arg0[i]);
+	 brw_set_saturate(p, 0);
+
+	 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0[i], arg1[i]);
+
+	 brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
+	 brw_MOV(p, dst[i], arg1[i]);
+	 brw_set_saturate(p, 0);
+	 brw_set_predicate_control_flag_value(p, 0xff);
+      }
+   }
+}
+
+static void emit_min( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+   GLuint i;
+
+   for (i = 0; i < 4; i++) {
+      if (mask & (1<<i)) {	
+	 brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
+	 brw_MOV(p, dst[i], arg1[i]);
+	 brw_set_saturate(p, 0);
+
+	 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0[i], arg1[i]);
+
+	 brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
+	 brw_MOV(p, dst[i], arg0[i]);
+	 brw_set_saturate(p, 0);
+	 brw_set_predicate_control_flag_value(p, 0xff);
+      }
+   }
+}
+
+
+static void emit_dp3( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+   int dst_chan = ffs(mask & BRW_WRITEMASK_XYZW) - 1;
+
+   if (!(mask & BRW_WRITEMASK_XYZW))
+      return; /* Do not emit dead code */
+
+   assert(util_is_power_of_two(mask & BRW_WRITEMASK_XYZW));
+
+   brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
+   brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]);
+
+   brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
+   brw_MAC(p, dst[dst_chan], arg0[2], arg1[2]);
+   brw_set_saturate(p, 0);
+}
+
+
+static void emit_dp4( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+   int dst_chan = ffs(mask & BRW_WRITEMASK_XYZW) - 1;
+
+   if (!(mask & BRW_WRITEMASK_XYZW))
+      return; /* Do not emit dead code */
+
+   assert(util_is_power_of_two(mask & BRW_WRITEMASK_XYZW));
+
+   brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
+   brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]);
+   brw_MAC(p, brw_null_reg(), arg0[2], arg1[2]);
+
+   brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
+   brw_MAC(p, dst[dst_chan], arg0[3], arg1[3]);
+   brw_set_saturate(p, 0);
+}
+
+
+static void emit_dph( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+   const int dst_chan = ffs(mask & BRW_WRITEMASK_XYZW) - 1;
+
+   if (!(mask & BRW_WRITEMASK_XYZW))
+      return; /* Do not emit dead code */
+
+   assert(util_is_power_of_two(mask & BRW_WRITEMASK_XYZW));
+
+   brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
+   brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]);
+   brw_MAC(p, dst[dst_chan], arg0[2], arg1[2]);
+
+   brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
+   brw_ADD(p, dst[dst_chan], dst[dst_chan], arg1[3]);
+   brw_set_saturate(p, 0);
+}
+
+
+static void emit_xpd( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+   GLuint i;
+
+   assert((mask & BRW_WRITEMASK_W) != BRW_WRITEMASK_W);
+   
+   for (i = 0 ; i < 3; i++) {
+      if (mask & (1<<i)) {
+	 GLuint i2 = (i+2)%3;
+	 GLuint i1 = (i+1)%3;
+
+	 brw_MUL(p, brw_null_reg(), negate(arg0[i2]), arg1[i1]);
+
+	 brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
+	 brw_MAC(p, dst[i], arg0[i1], arg1[i2]);
+	 brw_set_saturate(p, 0);
+      }
+   }
+}
+
+
+static void emit_math1( struct brw_compile *p, 
+			GLuint function,
+			const struct brw_reg *dst,
+			GLuint mask,
+			const struct brw_reg *arg0 )
+{
+   int dst_chan = ffs(mask & BRW_WRITEMASK_XYZW) - 1;
+
+   if (!(mask & BRW_WRITEMASK_XYZW))
+      return; /* Do not emit dead code */
+
+   assert(util_is_power_of_two(mask & BRW_WRITEMASK_XYZW));
+
+   brw_MOV(p, brw_message_reg(2), arg0[0]);
+
+   /* Send two messages to perform all 16 operations:
+    */
+   brw_math_16(p, 
+	       dst[dst_chan],
+	       function,
+	       (mask & SATURATE) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
+	       2,
+	       brw_null_reg(),
+	       BRW_MATH_PRECISION_FULL);
+}
+
+
+static void emit_math2( struct brw_compile *p, 
+			GLuint function,
+			const struct brw_reg *dst,
+			GLuint mask,
+			const struct brw_reg *arg0,
+			const struct brw_reg *arg1)
+{
+   int dst_chan = ffs(mask & BRW_WRITEMASK_XYZW) - 1;
+
+   if (!(mask & BRW_WRITEMASK_XYZW))
+      return; /* Do not emit dead code */
+
+   assert(util_is_power_of_two(mask & BRW_WRITEMASK_XYZW));
+
+   brw_push_insn_state(p);
+
+   brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+   brw_MOV(p, brw_message_reg(2), arg0[0]);
+   brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
+   brw_MOV(p, brw_message_reg(4), sechalf(arg0[0]));
+
+   brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+   brw_MOV(p, brw_message_reg(3), arg1[0]);
+   brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
+   brw_MOV(p, brw_message_reg(5), sechalf(arg1[0]));
+
+   
+   /* Send two messages to perform all 16 operations:
+    */
+   brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+   brw_math(p, 
+	    dst[dst_chan],
+	    function,
+	    (mask & SATURATE) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
+	    2,
+	    brw_null_reg(),
+	    BRW_MATH_DATA_VECTOR,
+	    BRW_MATH_PRECISION_FULL);
+
+   brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
+   brw_math(p, 
+	    offset(dst[dst_chan],1),
+	    function,
+	    (mask & SATURATE) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
+	    4,
+	    brw_null_reg(),
+	    BRW_MATH_DATA_VECTOR,
+	    BRW_MATH_PRECISION_FULL);
+   
+   brw_pop_insn_state(p);
+}
+		     
+
+
+static void emit_tex( struct brw_wm_compile *c,
+		      const struct brw_wm_instruction *inst,
+		      struct brw_reg *dst,
+		      GLuint dst_flags,
+		      struct brw_reg *coord,
+		      GLuint sampler)
+{
+   struct brw_compile *p = &c->func;
+   GLuint msgLength, responseLength;
+   GLuint i, nr;
+   GLuint emit;
+   GLuint msg_type;
+   GLboolean shadow = FALSE;
+
+   /* How many input regs are there?
+    */
+   switch (inst->target) {
+   case TGSI_TEXTURE_1D:
+      emit = BRW_WRITEMASK_X;
+      nr = 1;
+      break;
+   case TGSI_TEXTURE_SHADOW1D:
+      emit = BRW_WRITEMASK_XW;
+      nr = 4;
+      shadow = TRUE;
+      break;
+   case TGSI_TEXTURE_2D:
+      emit = BRW_WRITEMASK_XY;
+      nr = 2;
+      break;
+   case TGSI_TEXTURE_SHADOW2D:
+   case TGSI_TEXTURE_SHADOWRECT:
+      emit = BRW_WRITEMASK_XYW;
+      nr = 4;
+      shadow = TRUE;
+      break;
+   case TGSI_TEXTURE_3D:
+   case TGSI_TEXTURE_CUBE:
+      emit = BRW_WRITEMASK_XYZ;
+      nr = 3;
+      break;
+   default:
+      /* unexpected target */
+      abort();
+   }
+
+   msgLength = 1;
+
+   for (i = 0; i < nr; i++) {
+      static const GLuint swz[4] = {0,1,2,2};
+      if (emit & (1<<i)) 
+	 brw_MOV(p, brw_message_reg(msgLength+1), coord[swz[i]]);
+      else
+	 brw_MOV(p, brw_message_reg(msgLength+1), brw_imm_f(0));
+      msgLength += 2;
+   }
+
+   responseLength = 8;		/* always */
+
+   if (BRW_IS_IGDNG(p->brw)) {
+       if (shadow)
+           msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE_IGDNG;
+       else
+           msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_IGDNG;
+   } else {
+       if (shadow)
+           msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE;
+       else
+           msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE;
+   }
+
+   brw_SAMPLE(p, 
+	      retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW),
+	      1,
+	      retype(c->payload.depth[0].hw_reg, BRW_REGISTER_TYPE_UW),
+              BTI_TEXTURE(inst->tex_unit),
+	      sampler,          /* sampler index */
+	      inst->writemask,
+	      msg_type, 
+	      responseLength,
+	      msgLength,
+	      0,	
+	      1,
+	      BRW_SAMPLER_SIMD_MODE_SIMD16);	
+}
+
+
+static void emit_txb( struct brw_wm_compile *c,
+		      const struct brw_wm_instruction *inst,
+		      struct brw_reg *dst,
+		      GLuint dst_flags,
+		      struct brw_reg *coord,
+		      GLuint sampler )
+{
+   struct brw_compile *p = &c->func;
+   GLuint msgLength;
+   GLuint msg_type;
+   /* Shadow ignored for txb.
+    */
+   switch (inst->target) {
+   case TGSI_TEXTURE_1D:
+   case TGSI_TEXTURE_SHADOW1D:
+      brw_MOV(p, brw_message_reg(2), coord[0]);
+      brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
+      brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
+      break;
+   case TGSI_TEXTURE_2D:
+   case TGSI_TEXTURE_RECT:
+   case TGSI_TEXTURE_SHADOW2D:
+   case TGSI_TEXTURE_SHADOWRECT:
+      brw_MOV(p, brw_message_reg(2), coord[0]);
+      brw_MOV(p, brw_message_reg(4), coord[1]);
+      brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
+      break;
+   case TGSI_TEXTURE_3D:
+   case TGSI_TEXTURE_CUBE:
+      brw_MOV(p, brw_message_reg(2), coord[0]);
+      brw_MOV(p, brw_message_reg(4), coord[1]);
+      brw_MOV(p, brw_message_reg(6), coord[2]);
+      break;
+   default:
+      /* unexpected target */
+      abort();
+   }
+
+   brw_MOV(p, brw_message_reg(8), coord[3]);
+   msgLength = 9;
+
+   if (BRW_IS_IGDNG(p->brw))
+       msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS_IGDNG;
+   else
+       msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
+
+   brw_SAMPLE(p, 
+	      retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW),
+	      1,
+	      retype(c->payload.depth[0].hw_reg, BRW_REGISTER_TYPE_UW),
+              BTI_TEXTURE(inst->tex_unit),
+	      sampler,          /* sampler index */
+	      inst->writemask,
+	      msg_type,
+	      8,		/* responseLength */
+	      msgLength,
+	      0,	
+	      1,
+	      BRW_SAMPLER_SIMD_MODE_SIMD16);	
+}
+
+
+static void emit_lit( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0 )
+{
+   assert((mask & BRW_WRITEMASK_XW) == 0);
+
+   if (mask & BRW_WRITEMASK_Y) {
+      brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
+      brw_MOV(p, dst[1], arg0[0]);
+      brw_set_saturate(p, 0);
+   }
+
+   if (mask & BRW_WRITEMASK_Z) {
+      emit_math2(p, BRW_MATH_FUNCTION_POW,
+		 &dst[2],
+		 BRW_WRITEMASK_X | (mask & SATURATE),
+		 &arg0[1],
+		 &arg0[3]);
+   }
+
+   /* Ordinarily you'd use an iff statement to skip or shortcircuit
+    * some of the POW calculations above, but 16-wide iff statements
+    * seem to lock c1 hardware, so this is a nasty workaround:
+    */
+   brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_LE, arg0[0], brw_imm_f(0));
+   {
+      if (mask & BRW_WRITEMASK_Y) 
+	 brw_MOV(p, dst[1], brw_imm_f(0));
+
+      if (mask & BRW_WRITEMASK_Z) 
+	 brw_MOV(p, dst[2], brw_imm_f(0)); 
+   }
+   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+}
+
+
+/* Kill pixel - set execution mask to zero for those pixels which
+ * fail.
+ */
+static void emit_kil( struct brw_wm_compile *c,
+		      struct brw_reg *arg0)
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg r0uw = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
+   GLuint i;
+   
+   /* XXX - usually won't need 4 compares!
+    */
+   for (i = 0; i < 4; i++) {
+      brw_push_insn_state(p);
+      brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0[i], brw_imm_f(0));   
+      brw_set_predicate_control_flag_value(p, 0xff);
+      brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+      brw_AND(p, r0uw, brw_flag_reg(), r0uw);
+      brw_pop_insn_state(p);
+   }
+}
+
+/* KILLP kills the pixels that are currently executing, not based on a test
+ * of the arguments.
+ */
+static void emit_killp( struct brw_wm_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg r0uw = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
+
+   brw_push_insn_state(p);
+   brw_set_mask_control(p, BRW_MASK_DISABLE);
+   brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); /* IMASK */
+   brw_AND(p, r0uw, c->emit_mask_reg, r0uw);
+   brw_pop_insn_state(p);
+}
+
+static void fire_fb_write( struct brw_wm_compile *c,
+			   GLuint base_reg,
+			   GLuint nr,
+			   GLuint target,
+			   GLuint eot )
+{
+   struct brw_compile *p = &c->func;
+   
+   /* Pass through control information:
+    */
+/*  mov (8) m1.0<1>:ud   r1.0<8;8,1>:ud   { Align1 NoMask } */
+   {
+      brw_push_insn_state(p);
+      brw_set_mask_control(p, BRW_MASK_DISABLE); /* ? */
+      brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+      brw_MOV(p, 
+	       brw_message_reg(base_reg + 1),
+	       brw_vec8_grf(1, 0));
+      brw_pop_insn_state(p);
+   }
+
+   /* Send framebuffer write message: */
+/*  send (16) null.0<1>:uw m0               r0.0<8;8,1>:uw   0x85a04000:ud    { Align1 EOT } */
+   brw_fb_WRITE(p,
+		retype(vec16(brw_null_reg()), BRW_REGISTER_TYPE_UW),
+		base_reg,
+		retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW),
+		target,		
+		nr,
+		0, 
+		eot);
+}
+
+
+static void emit_aa( struct brw_wm_compile *c,
+		     struct brw_reg *arg1,
+		     GLuint reg )
+{
+   struct brw_compile *p = &c->func;
+   GLuint comp = c->key.aa_dest_stencil_reg / 2;
+   GLuint off = c->key.aa_dest_stencil_reg % 2;
+   struct brw_reg aa = offset(arg1[comp], off);
+
+   brw_push_insn_state(p);
+   brw_set_compression_control(p, BRW_COMPRESSION_NONE); /* ?? */
+   brw_MOV(p, brw_message_reg(reg), aa);
+   brw_pop_insn_state(p);
+}
+
+
+/* Post-fragment-program processing.  Send the results to the
+ * framebuffer.
+ * \param arg0  the fragment color
+ * \param arg1  the pass-through depth value
+ * \param arg2  the shader-computed depth value
+ */
+static void emit_fb_write( struct brw_wm_compile *c,
+			   struct brw_reg *arg0,
+			   struct brw_reg *arg1,
+			   struct brw_reg *arg2,
+			   GLuint target,
+			   GLuint eot)
+{
+   struct brw_compile *p = &c->func;
+   GLuint nr = 2;
+   GLuint channel;
+
+   /* Reserve a space for AA - may not be needed:
+    */
+   if (c->key.aa_dest_stencil_reg)
+      nr += 1;
+
+   /* I don't really understand how this achieves the color interleave
+    * (ie RGBARGBA) in the result:  [Do the saturation here]
+    */
+   {
+      brw_push_insn_state(p);
+      
+      for (channel = 0; channel < 4; channel++) {
+	 /*  mov (8) m2.0<1>:ud   r28.0<8;8,1>:ud  { Align1 } */
+	 /*  mov (8) m6.0<1>:ud   r29.0<8;8,1>:ud  { Align1 SecHalf } */
+
+	 brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+	 brw_MOV(p,
+		 brw_message_reg(nr + channel),
+		 arg0[channel]);
+       
+	 brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
+	 brw_MOV(p,
+		 brw_message_reg(nr + channel + 4),
+		 sechalf(arg0[channel]));
+      }
+
+      /* skip over the regs populated above:
+       */
+      nr += 8;
+   
+      brw_pop_insn_state(p);
+   }
+
+   if (c->key.source_depth_to_render_target)
+   {
+      if (c->key.computes_depth) 
+	 brw_MOV(p, brw_message_reg(nr), arg2[2]);
+      else 
+	 brw_MOV(p, brw_message_reg(nr), arg1[1]); /* ? */
+
+      nr += 2;
+   }
+
+   if (c->key.dest_depth_reg)
+   {
+      GLuint comp = c->key.dest_depth_reg / 2;
+      GLuint off = c->key.dest_depth_reg % 2;
+
+      if (off != 0) {
+         brw_push_insn_state(p);
+         brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+
+         brw_MOV(p, brw_message_reg(nr), offset(arg1[comp],1));
+         /* 2nd half? */
+         brw_MOV(p, brw_message_reg(nr+1), arg1[comp+1]);
+         brw_pop_insn_state(p);
+      }
+      else {
+         brw_MOV(p, brw_message_reg(nr), arg1[comp]);
+      }
+      nr += 2;
+   }
+
+   if (!c->key.runtime_check_aads_emit) {
+      if (c->key.aa_dest_stencil_reg)
+	 emit_aa(c, arg1, 2);
+
+      fire_fb_write(c, 0, nr, target, eot);
+   }
+   else {
+      struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD));
+      struct brw_reg ip = brw_ip_reg();
+      struct brw_instruction *jmp;
+      
+      brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+      brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
+      brw_AND(p, 
+	      v1_null_ud, 
+	      get_element_ud(brw_vec8_grf(1,0), 6), 
+	      brw_imm_ud(1<<26)); 
+
+      jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
+      {
+	 emit_aa(c, arg1, 2);
+	 fire_fb_write(c, 0, nr, target, eot);
+	 /* note - thread killed in subroutine */
+      }
+      brw_land_fwd_jump(p, jmp);
+
+      /* ELSE: Shuffle up one register to fill in the hole left for AA:
+       */
+      fire_fb_write(c, 1, nr-1, target, eot);
+   }
+}
+
+
+/**
+ * Move a GPR to scratch memory. 
+ */
+static void emit_spill( struct brw_wm_compile *c,
+			struct brw_reg reg,
+			GLuint slot )
+{
+   struct brw_compile *p = &c->func;
+
+   /*
+     mov (16) m2.0<1>:ud   r2.0<8;8,1>:ud   { Align1 Compr }
+   */
+   brw_MOV(p, brw_message_reg(2), reg);
+
+   /*
+     mov (1) r0.2<1>:d    0x00000080:d     { Align1 NoMask }
+     send (16) null.0<1>:uw m1               r0.0<8;8,1>:uw   0x053003ff:ud    { Align1 }
+   */
+   brw_dp_WRITE_16(p, 
+		   retype(vec16(brw_vec8_grf(0, 0)), BRW_REGISTER_TYPE_UW),
+		   slot);
+}
+
+
+/**
+ * Load a GPR from scratch memory. 
+ */
+static void emit_unspill( struct brw_wm_compile *c,
+			  struct brw_reg reg,
+			  GLuint slot )
+{
+   struct brw_compile *p = &c->func;
+
+   /* Slot 0 is the undef value.
+    */
+   if (slot == 0) {
+      brw_MOV(p, reg, brw_imm_f(0));
+      return;
+   }
+
+   /*
+     mov (1) r0.2<1>:d    0x000000c0:d     { Align1 NoMask }
+     send (16) r110.0<1>:uw m1               r0.0<8;8,1>:uw   0x041243ff:ud    { Align1 }
+   */
+
+   brw_dp_READ_16(p,
+		  retype(vec16(reg), BRW_REGISTER_TYPE_UW),
+		  slot);
+}
+
+
+/**
+ * Retrieve up to 4 GEN4 register pairs for the given wm reg:
+ * Args with unspill_reg != 0 will be loaded from scratch memory.
+ */
+static void get_argument_regs( struct brw_wm_compile *c,
+			       struct brw_wm_ref *arg[],
+			       struct brw_reg *regs )
+{
+   GLuint i;
+
+   for (i = 0; i < 4; i++) {
+      if (arg[i]) {
+	 if (arg[i]->unspill_reg)
+	    emit_unspill(c,
+			 brw_vec8_grf(arg[i]->unspill_reg, 0),
+			 arg[i]->value->spill_slot);
+
+	 regs[i] = arg[i]->hw_reg;
+      }
+      else {
+	 regs[i] = brw_null_reg();
+      }
+   }
+}
+
+
+/**
+ * For values that have a spill_slot!=0, write those regs to scratch memory.
+ */
+static void spill_values( struct brw_wm_compile *c,
+			  struct brw_wm_value *values,
+			  GLuint nr )
+{
+   GLuint i;
+
+   for (i = 0; i < nr; i++)
+      if (values[i].spill_slot) 
+	 emit_spill(c, values[i].hw_reg, values[i].spill_slot);
+}
+
+
+/* Emit the fragment program instructions here.
+ */
+void brw_wm_emit( struct brw_wm_compile *c )
+{
+   struct brw_compile *p = &c->func;
+   GLuint insn;
+
+   brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
+
+   /* Check if any of the payload regs need to be spilled:
+    */
+   spill_values(c, c->payload.depth, 4);
+   spill_values(c, c->creg, c->nr_creg);
+   spill_values(c, c->payload.input_interp, PIPE_MAX_SHADER_INPUTS);
+   
+
+   for (insn = 0; insn < c->nr_insns; insn++) {
+
+      struct brw_wm_instruction *inst = &c->instruction[insn];
+      struct brw_reg args[3][4], dst[4];
+      GLuint i, dst_flags;
+      
+      /* Get argument regs:
+       */
+      for (i = 0; i < 3; i++) 
+	 get_argument_regs(c, inst->src[i], args[i]);
+
+      /* Get dest regs:
+       */
+      for (i = 0; i < 4; i++)
+	 if (inst->dst[i])
+	    dst[i] = inst->dst[i]->hw_reg;
+	 else
+	    dst[i] = brw_null_reg();
+      
+      /* Flags
+       */
+      dst_flags = inst->writemask;
+      if (inst->saturate) 
+	 dst_flags |= SATURATE;
+
+      switch (inst->opcode) {
+	 /* Generated instructions for calculating triangle interpolants:
+	  */
+      case WM_PIXELXY:
+	 emit_pixel_xy(p, dst, dst_flags);
+	 break;
+
+      case WM_DELTAXY:
+	 emit_delta_xy(p, dst, dst_flags, args[0]);
+	 break;
+
+      case WM_WPOSXY:
+	 emit_wpos_xy(c, dst, dst_flags, args[0]);
+	 break;
+
+      case WM_PIXELW:
+	 emit_pixel_w(p, dst, dst_flags, args[0], args[1]);
+	 break;
+
+      case WM_LINTERP:
+	 emit_linterp(p, dst, dst_flags, args[0], args[1]);
+	 break;
+
+      case WM_PINTERP:
+	 emit_pinterp(p, dst, dst_flags, args[0], args[1], args[2]);
+	 break;
+
+      case WM_CINTERP:
+	 emit_cinterp(p, dst, dst_flags, args[0]);
+	 break;
+
+      case WM_FB_WRITE:
+	 emit_fb_write(c, args[0], args[1], args[2], inst->target, inst->eot);
+	 break;
+
+      case WM_FRONTFACING:
+	 emit_frontfacing(p, dst, dst_flags);
+	 break;
+
+	 /* Straightforward arithmetic:
+	  */
+      case TGSI_OPCODE_ADD:
+	 emit_alu2(p, brw_ADD, dst, dst_flags, args[0], args[1]);
+	 break;
+
+      case TGSI_OPCODE_FRC:
+	 emit_alu1(p, brw_FRC, dst, dst_flags, args[0]);
+	 break;
+
+      case TGSI_OPCODE_FLR:
+	 emit_alu1(p, brw_RNDD, dst, dst_flags, args[0]);
+	 break;
+
+      case TGSI_OPCODE_DDX:
+	 emit_ddxy(p, dst, dst_flags, GL_TRUE, args[0]);
+	 break;
+
+      case TGSI_OPCODE_DDY:
+	 emit_ddxy(p, dst, dst_flags, GL_FALSE, args[0]);
+	 break;
+
+      case TGSI_OPCODE_DP3:
+	 emit_dp3(p, dst, dst_flags, args[0], args[1]);
+	 break;
+
+      case TGSI_OPCODE_DP4:
+	 emit_dp4(p, dst, dst_flags, args[0], args[1]);
+	 break;
+
+      case TGSI_OPCODE_DPH:
+	 emit_dph(p, dst, dst_flags, args[0], args[1]);
+	 break;
+
+      case TGSI_OPCODE_TRUNC:
+	 emit_trunc(p, dst, dst_flags, args[0]);
+	 break;
+
+      case TGSI_OPCODE_LRP:
+	 emit_lrp(p, dst, dst_flags, args[0], args[1], args[2]);
+	 break;
+
+      case TGSI_OPCODE_MAD:	
+	 emit_mad(p, dst, dst_flags, args[0], args[1], args[2]);
+	 break;
+
+      case TGSI_OPCODE_MOV:
+	 emit_alu1(p, brw_MOV, dst, dst_flags, args[0]);
+	 break;
+
+      case TGSI_OPCODE_MUL:
+	 emit_alu2(p, brw_MUL, dst, dst_flags, args[0], args[1]);
+	 break;
+
+      case TGSI_OPCODE_XPD:
+	 emit_xpd(p, dst, dst_flags, args[0], args[1]);
+	 break;
+
+	 /* Higher math functions:
+	  */
+      case TGSI_OPCODE_RCP:
+	 emit_math1(p, BRW_MATH_FUNCTION_INV, dst, dst_flags, args[0]);
+	 break;
+
+      case TGSI_OPCODE_RSQ:
+	 emit_math1(p, BRW_MATH_FUNCTION_RSQ, dst, dst_flags, args[0]);
+	 break;
+
+      case TGSI_OPCODE_SIN:
+	 emit_math1(p, BRW_MATH_FUNCTION_SIN, dst, dst_flags, args[0]);
+	 break;
+
+      case TGSI_OPCODE_COS:
+	 emit_math1(p, BRW_MATH_FUNCTION_COS, dst, dst_flags, args[0]);
+	 break;
+
+      case TGSI_OPCODE_EX2:
+	 emit_math1(p, BRW_MATH_FUNCTION_EXP, dst, dst_flags, args[0]);
+	 break;
+
+      case TGSI_OPCODE_LG2:
+	 emit_math1(p, BRW_MATH_FUNCTION_LOG, dst, dst_flags, args[0]);
+	 break;
+
+      case TGSI_OPCODE_SCS:
+	 /* There is an scs math function, but it would need some
+	  * fixup for 16-element execution.
+	  */
+	 if (dst_flags & BRW_WRITEMASK_X)
+	    emit_math1(p, BRW_MATH_FUNCTION_COS, dst, (dst_flags&SATURATE)|BRW_WRITEMASK_X, args[0]);
+	 if (dst_flags & BRW_WRITEMASK_Y)
+	    emit_math1(p, BRW_MATH_FUNCTION_SIN, dst+1, (dst_flags&SATURATE)|BRW_WRITEMASK_X, args[0]);
+	 break;
+
+      case TGSI_OPCODE_POW:
+	 emit_math2(p, BRW_MATH_FUNCTION_POW, dst, dst_flags, args[0], args[1]);
+	 break;
+
+	 /* Comparisons:
+	  */
+      case TGSI_OPCODE_CMP:
+	 emit_cmp(p, dst, dst_flags, args[0], args[1], args[2]);
+	 break;
+
+      case TGSI_OPCODE_MAX:
+	 emit_max(p, dst, dst_flags, args[0], args[1]);
+	 break;
+
+      case TGSI_OPCODE_MIN:
+	 emit_min(p, dst, dst_flags, args[0], args[1]);
+	 break;
+
+      case TGSI_OPCODE_SLT:
+	 emit_slt(p, dst, dst_flags, args[0], args[1]);
+	 break;
+
+      case TGSI_OPCODE_SLE:
+	 emit_sle(p, dst, dst_flags, args[0], args[1]);
+	break;
+      case TGSI_OPCODE_SGT:
+	 emit_sgt(p, dst, dst_flags, args[0], args[1]);
+	break;
+      case TGSI_OPCODE_SGE:
+	 emit_sge(p, dst, dst_flags, args[0], args[1]);
+	 break;
+      case TGSI_OPCODE_SEQ:
+	 emit_seq(p, dst, dst_flags, args[0], args[1]);
+	break;
+      case TGSI_OPCODE_SNE:
+	 emit_sne(p, dst, dst_flags, args[0], args[1]);
+	break;
+
+      case TGSI_OPCODE_LIT:
+	 emit_lit(p, dst, dst_flags, args[0]);
+	 break;
+
+	 /* Texturing operations:
+	  */
+      case TGSI_OPCODE_TEX:
+	 emit_tex(c, inst, dst, dst_flags, args[0], inst->sampler);
+	 break;
+
+      case TGSI_OPCODE_TXB:
+	 emit_txb(c, inst, dst, dst_flags, args[0], inst->sampler);
+	 break;
+
+      case TGSI_OPCODE_KIL:
+	 emit_kil(c, args[0]);
+	 break;
+
+      case TGSI_OPCODE_KILP:
+	 emit_killp(c);
+	 break;
+
+      default:
+	 debug_printf("Unsupported opcode %i (%s) in fragment shader\n",
+		      inst->opcode, 
+		      tgsi_get_opcode_info(inst->opcode)->mnemonic);
+      }
+      
+      for (i = 0; i < 4; i++)
+	if (inst->dst[i] && inst->dst[i]->spill_slot) 
+	   emit_spill(c, 
+		      inst->dst[i]->hw_reg, 
+		      inst->dst[i]->spill_slot);
+   }
+
+   if (BRW_DEBUG & DEBUG_WM) {
+      debug_printf("wm-native:\n");
+      brw_disasm(stderr, p->store, p->nr_insn);
+   }
+}
diff --git a/src/gallium/drivers/i965/brw_wm_fp.c b/src/gallium/drivers/i965/brw_wm_fp.c
new file mode 100644
index 0000000..9c5b527
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_wm_fp.c
@@ -0,0 +1,1224 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+               
+
+#include "pipe/p_shader_tokens.h"
+
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_info.h"
+#include "tgsi/tgsi_util.h"
+
+#include "brw_wm.h"
+#include "brw_util.h"
+#include "brw_debug.h"
+
+
+/***********************************************************************
+ * Source regs
+ */
+
+static struct brw_fp_src src_reg(GLuint file, GLuint idx)
+{
+   struct brw_fp_src reg;
+   reg.file = file;
+   reg.index = idx;
+   reg.swizzle = BRW_SWIZZLE_XYZW;
+   reg.indirect = 0;
+   reg.negate = 0;
+   reg.abs = 0;
+   return reg;
+}
+
+static struct brw_fp_src src_reg_from_dst(struct brw_fp_dst dst)
+{
+   return src_reg(dst.file, dst.index);
+}
+
+static struct brw_fp_src src_undef( void )
+{
+   return src_reg(TGSI_FILE_NULL, 0);
+}
+
+static GLboolean src_is_undef(struct brw_fp_src src)
+{
+   return src.file == TGSI_FILE_NULL;
+}
+
+static struct brw_fp_src src_swizzle( struct brw_fp_src reg, int x, int y, int z, int w )
+{
+   unsigned swz = reg.swizzle;
+
+   reg.swizzle = ( BRW_GET_SWZ(swz, x) << 0 |
+		   BRW_GET_SWZ(swz, y) << 2 |
+		   BRW_GET_SWZ(swz, z) << 4 |
+		   BRW_GET_SWZ(swz, w) << 6 );
+
+   return reg;
+}
+
+static struct brw_fp_src src_scalar( struct brw_fp_src reg, int x )
+{
+   return src_swizzle(reg, x, x, x, x);
+}
+
+static struct brw_fp_src src_abs( struct brw_fp_src src )
+{
+   src.negate = 0;
+   src.abs = 1;
+   return src;
+}
+
+static struct brw_fp_src src_negate( struct brw_fp_src src )
+{
+   src.negate = 1;
+   src.abs = 0;
+   return src;
+}
+
+
+static int match_or_expand_immediate( const float *v,
+                                      unsigned nr,
+                                      float *v2,
+                                      unsigned *nr2,
+                                      unsigned *swizzle )
+{
+   unsigned i, j;
+   
+   *swizzle = 0;
+
+   for (i = 0; i < nr; i++) {
+      boolean found = FALSE;
+
+      for (j = 0; j < *nr2 && !found; j++) {
+         if (v[i] == v2[j]) {
+            *swizzle |= j << (i * 2);
+            found = TRUE;
+         }
+      }
+
+      if (!found) {
+         if (*nr2 >= 4) 
+            return FALSE;
+
+         v2[*nr2] = v[i];
+         *swizzle |= *nr2 << (i * 2);
+         (*nr2)++;
+      }
+   }
+
+   return TRUE;
+}
+
+
+
+/* Internally generated immediates: overkill...
+ */
+static struct brw_fp_src src_imm( struct brw_wm_compile *c, 
+				  const GLfloat *v, 
+				  unsigned nr)
+{
+   unsigned i, j;
+   unsigned swizzle;
+
+   /* Could do a first pass where we examine all existing immediates
+    * without expanding.
+    */
+
+   for (i = 0; i < c->nr_immediates; i++) {
+      if (match_or_expand_immediate( v, 
+                                     nr,
+                                     c->immediate[i].v,
+                                     &c->immediate[i].nr, 
+                                     &swizzle ))
+         goto out;
+   }
+
+   if (c->nr_immediates < Elements(c->immediate)) {
+      i = c->nr_immediates++;
+      if (match_or_expand_immediate( v,
+                                     nr,
+                                     c->immediate[i].v,
+                                     &c->immediate[i].nr, 
+                                     &swizzle ))
+         goto out;
+   }
+
+   c->error = 1;
+   return src_undef();
+
+out:
+   /* Make sure that all referenced elements are from this immediate.
+    * Has the effect of making size-one immediates into scalars.
+    */
+   for (j = nr; j < 4; j++)
+      swizzle |= (swizzle & 0x3) << (j * 2);
+
+   return src_swizzle( src_reg( TGSI_FILE_IMMEDIATE, i ),
+		       BRW_GET_SWZ(swizzle, X),
+		       BRW_GET_SWZ(swizzle, Y),
+		       BRW_GET_SWZ(swizzle, Z),
+		       BRW_GET_SWZ(swizzle, W) );
+}
+
+
+
+static struct brw_fp_src src_imm1f( struct brw_wm_compile *c,
+				    GLfloat f )
+{
+   return src_imm(c, &f, 1);
+}
+
+static struct brw_fp_src src_imm4f( struct brw_wm_compile *c,
+				    GLfloat x,
+				    GLfloat y,
+				    GLfloat z,
+				    GLfloat w)
+{
+   GLfloat f[4] = {x,y,z,w};
+   return src_imm(c, f, 4);
+}
+
+
+
+/***********************************************************************
+ * Dest regs
+ */
+
+static struct brw_fp_dst dst_reg(GLuint file, GLuint idx)
+{
+   struct brw_fp_dst reg;
+   reg.file = file;
+   reg.index = idx;
+   reg.writemask = BRW_WRITEMASK_XYZW;
+   reg.indirect = 0;
+   reg.saturate = 0;
+   return reg;
+}
+
+static struct brw_fp_dst dst_mask( struct brw_fp_dst reg, int mask )
+{
+   reg.writemask &= mask;
+   return reg;
+}
+
+static struct brw_fp_dst dst_undef( void )
+{
+   return dst_reg(TGSI_FILE_NULL, 0);
+}
+
+static boolean dst_is_undef( struct brw_fp_dst dst )
+{
+   return dst.file == TGSI_FILE_NULL;
+}
+
+static struct brw_fp_dst dst_saturate( struct brw_fp_dst reg, boolean flag )
+{
+   reg.saturate = flag;
+   return reg;
+}
+
+static struct brw_fp_dst get_temp( struct brw_wm_compile *c )
+{
+   int bit = ffs( ~c->fp_temp );
+
+   if (!bit) {
+      debug_printf("%s: out of temporaries\n", __FILE__);
+   }
+
+   c->fp_temp |= 1<<(bit-1);
+   return dst_reg(TGSI_FILE_TEMPORARY, c->fp_first_internal_temp+(bit-1));
+}
+
+
+static void release_temp( struct brw_wm_compile *c, struct brw_fp_dst temp )
+{
+   c->fp_temp &= ~(1 << (temp.index - c->fp_first_internal_temp));
+}
+
+
+/***********************************************************************
+ * Instructions 
+ */
+
+static struct brw_fp_instruction *get_fp_inst(struct brw_wm_compile *c)
+{
+   return &c->fp_instructions[c->nr_fp_insns++];
+}
+
+static struct brw_fp_instruction * emit_tex_op(struct brw_wm_compile *c,
+					     GLuint op,
+					     struct brw_fp_dst dest,
+					     GLuint tex_unit,
+					     GLuint target,
+					     GLuint sampler,
+					     struct brw_fp_src src0,
+					     struct brw_fp_src src1,
+					     struct brw_fp_src src2 )
+{
+   struct brw_fp_instruction *inst = get_fp_inst(c);
+
+   if (tex_unit || target)
+      assert(op == TGSI_OPCODE_TXP ||
+             op == TGSI_OPCODE_TXB ||
+             op == TGSI_OPCODE_TEX ||
+             op == WM_FB_WRITE);
+
+   inst->opcode = op;
+   inst->dst = dest;
+   inst->tex_unit = tex_unit;
+   inst->target = target;
+   inst->sampler = sampler;
+   inst->src[0] = src0;
+   inst->src[1] = src1;
+   inst->src[2] = src2;
+
+   return inst;
+}
+   
+
+static INLINE void emit_op3(struct brw_wm_compile *c,
+			    GLuint op,
+			    struct brw_fp_dst dest,
+			    struct brw_fp_src src0,
+			    struct brw_fp_src src1,
+			    struct brw_fp_src src2 )
+{
+   emit_tex_op(c, op, dest, 0, 0, 0, src0, src1, src2);
+}
+
+
+static INLINE void emit_op2(struct brw_wm_compile *c,
+			    GLuint op,
+			    struct brw_fp_dst dest,
+			    struct brw_fp_src src0,
+			    struct brw_fp_src src1)
+{
+   emit_tex_op(c, op, dest, 0, 0, 0, src0, src1, src_undef());
+}
+
+static INLINE void emit_op1(struct brw_wm_compile *c,
+			    GLuint op,
+			    struct brw_fp_dst dest,
+			    struct brw_fp_src src0)
+{
+   emit_tex_op(c, op, dest, 0, 0, 0, src0, src_undef(), src_undef());
+}
+
+static INLINE void emit_op0(struct brw_wm_compile *c,
+			   GLuint op,
+			   struct brw_fp_dst dest)
+{
+   emit_tex_op(c, op, dest, 0, 0, 0, src_undef(), src_undef(), src_undef());
+}
+
+
+
+/* Many opcodes produce the same value across all the result channels.
+ * We'd rather not have to support that splatting in the opcode implementations,
+ * and brw_wm_pass*.c wants to optimize them out by shuffling references around
+ * anyway.  We can easily get both by emitting the opcode to one channel, and
+ * then MOVing it to the others, which brw_wm_pass*.c already understands.
+ */
+static void emit_scalar_insn(struct brw_wm_compile *c,
+			     unsigned opcode,
+			     struct brw_fp_dst dst,
+			     struct brw_fp_src src0,
+			     struct brw_fp_src src1,
+			     struct brw_fp_src src2 )
+{
+   unsigned first_chan = ffs(dst.writemask) - 1;
+   unsigned first_mask = 1 << first_chan;
+
+   if (dst.writemask == 0)
+      return;
+
+   emit_op3( c, opcode,
+	     dst_mask(dst, first_mask),
+	     src0, src1, src2 );
+
+   if (dst.writemask != first_mask) {
+      emit_op1(c, TGSI_OPCODE_MOV,
+	       dst_mask(dst, ~first_mask),
+	       src_scalar(src_reg_from_dst(dst), first_chan));
+   }
+}
+
+
+/***********************************************************************
+ * Special instructions for interpolation and other tasks
+ */
+
+static struct brw_fp_src get_pixel_xy( struct brw_wm_compile *c )
+{
+   if (src_is_undef(c->fp_pixel_xy)) {
+      struct brw_fp_dst pixel_xy = get_temp(c);
+      struct brw_fp_src payload_r0_depth = src_reg(BRW_FILE_PAYLOAD, PAYLOAD_DEPTH);
+      
+      
+      /* Emit the out calculations, and hold onto the results.  Use
+       * two instructions as a temporary is required.
+       */   
+      /* pixel_xy.xy = PIXELXY payload[0];
+       */
+      emit_op1(c,
+	       WM_PIXELXY,
+	       dst_mask(pixel_xy, BRW_WRITEMASK_XY),
+	       payload_r0_depth);
+
+      c->fp_pixel_xy = src_reg_from_dst(pixel_xy);
+   }
+
+   return c->fp_pixel_xy;
+}
+
+static struct brw_fp_src get_delta_xy( struct brw_wm_compile *c )
+{
+   if (src_is_undef(c->fp_delta_xy)) {
+      struct brw_fp_dst delta_xy = get_temp(c);
+      struct brw_fp_src pixel_xy = get_pixel_xy(c);
+      struct brw_fp_src payload_r0_depth = src_reg(BRW_FILE_PAYLOAD, PAYLOAD_DEPTH);
+      
+      /* deltas.xy = DELTAXY pixel_xy, payload[0]
+       */
+      emit_op3(c,
+	      WM_DELTAXY,
+	      dst_mask(delta_xy, BRW_WRITEMASK_XY),
+	      pixel_xy, 
+	      payload_r0_depth,
+	      src_undef());
+      
+      c->fp_delta_xy = src_reg_from_dst(delta_xy);
+   }
+
+   return c->fp_delta_xy;
+}
+
+static struct brw_fp_src get_pixel_w( struct brw_wm_compile *c )
+{
+   if (src_is_undef(c->fp_pixel_w)) {
+      struct brw_fp_dst pixel_w = get_temp(c);
+      struct brw_fp_src deltas = get_delta_xy(c);
+
+      /* XXX: assuming position is always first -- valid? 
+       */
+      struct brw_fp_src interp_wpos = src_reg(BRW_FILE_PAYLOAD, 0);
+
+      /* deltas.xyw = DELTAS2 deltas.xy, payload.interp_wpos.x
+       */
+      emit_op3(c,
+	       WM_PIXELW,
+	       dst_mask(pixel_w, BRW_WRITEMASK_W),
+	       interp_wpos,
+	       deltas, 
+	       src_undef());
+      
+
+      c->fp_pixel_w = src_reg_from_dst(pixel_w);
+   }
+
+   return c->fp_pixel_w;
+}
+
+
+/***********************************************************************
+ * Emit INTERP instructions ahead of first use of each attrib.
+ */
+
+static void emit_interp( struct brw_wm_compile *c,
+			 GLuint idx,
+			 GLuint semantic,
+			 GLuint interp_mode )
+{
+   struct brw_fp_dst dst = dst_reg(TGSI_FILE_INPUT, idx);
+   struct brw_fp_src interp = src_reg(BRW_FILE_PAYLOAD, idx);
+   struct brw_fp_src deltas = get_delta_xy(c);
+
+   /* Need to use PINTERP on attributes which have been
+    * multiplied by 1/W in the SF program, and LINTERP on those
+    * which have not:
+    */
+   switch (semantic) {
+   case TGSI_SEMANTIC_POSITION:
+      /* Have to treat wpos.xy specially:
+       */
+      emit_op1(c,
+	      WM_WPOSXY,
+	      dst_mask(dst, BRW_WRITEMASK_XY),
+	      get_pixel_xy(c));
+      
+      /* TGSI_FILE_INPUT.attr.xyzw = INTERP payload.interp[attr].x, deltas.xyw
+       */
+      emit_op2(c,
+	       WM_LINTERP,
+	       dst_mask(dst, BRW_WRITEMASK_ZW),
+	       interp,
+	       deltas);
+      break;
+
+   case TGSI_SEMANTIC_COLOR:
+      if (c->key.flat_shade) {
+	 emit_op1(c,
+		 WM_CINTERP,
+		 dst,
+		 interp);
+      }
+      else if (interp_mode == TGSI_INTERPOLATE_LINEAR) {
+	 emit_op2(c,
+		  WM_LINTERP,
+		  dst,
+		  interp,
+		  deltas);
+      }
+      else {
+	 emit_op3(c,
+		  WM_PINTERP,
+		  dst,
+		  interp,
+		  deltas,
+		  get_pixel_w(c));
+      }
+
+      break;
+
+   case TGSI_SEMANTIC_FOG:
+      /* Interpolate the fog coordinate */
+      emit_op3(c,
+	      WM_PINTERP,
+	      dst_mask(dst, BRW_WRITEMASK_X),
+	      interp,
+	      deltas,
+	      get_pixel_w(c));
+
+      emit_op1(c,
+	       TGSI_OPCODE_MOV,
+	       dst_mask(dst, BRW_WRITEMASK_YZ),
+	       src_imm1f(c, 0.0));
+
+      emit_op1(c,
+	       TGSI_OPCODE_MOV,
+	       dst_mask(dst, BRW_WRITEMASK_W),
+	       src_imm1f(c, 1.0));
+      break;
+
+   case TGSI_SEMANTIC_FACE:
+      /* XXX review/test this case */
+      emit_op0(c,
+	       WM_FRONTFACING,
+	       dst_mask(dst, BRW_WRITEMASK_X));
+      
+      emit_op1(c,
+	      TGSI_OPCODE_MOV,
+	      dst_mask(dst, BRW_WRITEMASK_YZ),
+	       src_imm1f(c, 0.0));
+
+      emit_op1(c,
+	      TGSI_OPCODE_MOV,
+	      dst_mask(dst, BRW_WRITEMASK_W),
+	       src_imm1f(c, 1.0));
+      break;
+
+   case TGSI_SEMANTIC_PSIZE:
+      /* XXX review/test this case */
+      emit_op3(c,
+	       WM_PINTERP,
+	       dst_mask(dst, BRW_WRITEMASK_XY),
+	       interp,
+	       deltas,
+	       get_pixel_w(c));
+
+      emit_op1(c,
+	      TGSI_OPCODE_MOV,
+	      dst_mask(dst, BRW_WRITEMASK_Z),
+	      src_imm1f(c, 0.0f));
+
+      emit_op1(c,
+	      TGSI_OPCODE_MOV,
+	      dst_mask(dst, BRW_WRITEMASK_W),
+	      src_imm1f(c, 1.0f));
+      break;
+
+   default: 
+      switch (interp_mode) {
+      case TGSI_INTERPOLATE_CONSTANT:
+	 emit_op1(c,
+		  WM_CINTERP,
+		  dst,
+		  interp);
+	 break;
+
+      case TGSI_INTERPOLATE_LINEAR:
+	 emit_op2(c,
+		  WM_LINTERP,
+		  dst,
+		  interp,
+		  deltas);
+	 break;
+
+      case TGSI_INTERPOLATE_PERSPECTIVE:
+	 emit_op3(c,
+		  WM_PINTERP,
+		  dst,
+		  interp,
+		  deltas,
+		  get_pixel_w(c));
+	 break;
+      }
+      break;
+   }
+}
+
+
+/***********************************************************************
+ * Expand various instructions here to simpler forms.  
+ */
+static void precalc_dst( struct brw_wm_compile *c,
+			 struct brw_fp_dst dst,
+			 struct brw_fp_src src0,
+			 struct brw_fp_src src1 )
+{
+   if (dst.writemask & BRW_WRITEMASK_Y) {      
+      /* dst.y = mul src0.y, src1.y
+       */
+      emit_op2(c,
+	       TGSI_OPCODE_MUL,
+	       dst_mask(dst, BRW_WRITEMASK_Y),
+	       src0,
+	       src1);
+   }
+
+   if (dst.writemask & BRW_WRITEMASK_XZ) {
+      /* dst.z = mov src0.zzzz
+       */
+      emit_op1(c,
+	      TGSI_OPCODE_MOV,
+	      dst_mask(dst, BRW_WRITEMASK_Z),
+	      src_scalar(src0, Z));
+
+      /* dst.x = imm1f(1.0)
+       */
+      emit_op1(c,
+	      TGSI_OPCODE_MOV,
+	      dst_saturate(dst_mask(dst, BRW_WRITEMASK_X), 0),
+	      src_imm1f(c, 1.0));
+   }
+   if (dst.writemask & BRW_WRITEMASK_W) {
+      /* dst.w = mov src1.w
+       */
+      emit_op1(c,
+	       TGSI_OPCODE_MOV,
+	       dst_mask(dst, BRW_WRITEMASK_W),
+	       src1);
+   }
+}
+
+
+static void precalc_lit( struct brw_wm_compile *c,
+			 struct brw_fp_dst dst,
+			 struct brw_fp_src src0 )
+{
+   if (dst.writemask & BRW_WRITEMASK_XW) {
+      /* dst.xw = imm(1.0f)
+       */
+      emit_op1(c,
+	       TGSI_OPCODE_MOV,
+	       dst_saturate(dst_mask(dst, BRW_WRITEMASK_XW), 0),
+	       src_imm1f(c, 1.0f));
+   }
+
+   if (dst.writemask & BRW_WRITEMASK_YZ) {
+      emit_op1(c,
+	       TGSI_OPCODE_LIT,
+	       dst_mask(dst, BRW_WRITEMASK_YZ),
+	       src0);
+   }
+}
+
+
+/**
+ * Some TEX instructions require extra code, cube map coordinate
+ * normalization, or coordinate scaling for RECT textures, etc.
+ * This function emits those extra instructions and the TEX
+ * instruction itself.
+ */
+static void precalc_tex( struct brw_wm_compile *c,
+			 struct brw_fp_dst dst,
+			 unsigned target,
+			 unsigned unit,
+			 struct brw_fp_src src0,
+			 struct brw_fp_src sampler )
+{
+   struct brw_fp_src coord = src_undef();
+   struct brw_fp_dst tmp = dst_undef();
+
+   assert(unit < BRW_MAX_TEX_UNIT);
+
+   /* Cubemap: find longest component of coord vector and normalize
+    * it.
+    */
+   if (target == TGSI_TEXTURE_CUBE) {
+      struct brw_fp_src tmpsrc;
+
+      tmp = get_temp(c);
+      tmpsrc = src_reg_from_dst(tmp);
+
+      /* tmp = abs(src0) */
+      emit_op1(c, 
+	       TGSI_OPCODE_MOV,
+	       tmp,
+	       src_abs(src0));
+
+      /* tmp.X = MAX(tmp.X, tmp.Y) */
+      emit_op2(c, TGSI_OPCODE_MAX,
+	       dst_mask(tmp, BRW_WRITEMASK_X),
+	       src_scalar(tmpsrc, X),
+	       src_scalar(tmpsrc, Y));
+
+      /* tmp.X = MAX(tmp.X, tmp.Z) */
+      emit_op2(c, TGSI_OPCODE_MAX,
+	       dst_mask(tmp, BRW_WRITEMASK_X),
+	       tmpsrc,
+	       src_scalar(tmpsrc, Z));
+
+      /* tmp.X = 1 / tmp.X */
+      emit_op1(c, TGSI_OPCODE_RCP,
+	      dst_mask(tmp, BRW_WRITEMASK_X),
+	      tmpsrc);
+
+      /* tmp = src0 * tmp.xxxx */
+      emit_op2(c, TGSI_OPCODE_MUL,
+	       tmp,
+	       src0,
+	       src_scalar(tmpsrc, X));
+
+      coord = tmpsrc;
+   }
+   else if (target == TGSI_TEXTURE_RECT ||
+	    target == TGSI_TEXTURE_SHADOWRECT) {
+      /* XXX: need a mechanism for internally generated constants.
+       */
+      coord = src0;
+   }
+   else {
+      coord = src0;
+   }
+
+   /* Need to emit YUV texture conversions by hand.  Probably need to
+    * do this here - the alternative is in brw_wm_emit.c, but the
+    * conversion requires allocating a temporary variable which we
+    * don't have the facility to do that late in the compilation.
+    */
+   if (c->key.yuvtex_mask & (1 << unit)) {
+      /* convert ycbcr to RGBA */
+      GLboolean  swap_uv = c->key.yuvtex_swap_mask & (1<<unit);
+      struct brw_fp_dst tmp = get_temp(c);
+      struct brw_fp_src tmpsrc = src_reg_from_dst(tmp);
+      struct brw_fp_src C0 = src_imm4f( c,  -.5, -.0625, -.5, 1.164 );
+      struct brw_fp_src C1 = src_imm4f( c, 1.596, -0.813, 2.018, -.391 );
+     
+      /* tmp     = TEX ...
+       */
+      emit_tex_op(c, 
+                  TGSI_OPCODE_TEX,
+                  dst_saturate(tmp, dst.saturate),
+                  unit,
+                  target,
+                  sampler.index,
+                  coord,
+                  src_undef(),
+                  src_undef());
+
+      /* tmp.xyz =  ADD TMP, C0
+       */
+      emit_op2(c, TGSI_OPCODE_ADD,
+	       dst_mask(tmp, BRW_WRITEMASK_XYZ),
+	       tmpsrc,
+	       C0);
+
+      /* YUV.y   = MUL YUV.y, C0.w
+       */
+      emit_op2(c, TGSI_OPCODE_MUL,
+	       dst_mask(tmp, BRW_WRITEMASK_Y),
+	       tmpsrc,
+	       src_scalar(C0, W));
+
+      /* 
+       * if (UV swaped)
+       *     RGB.xyz = MAD YUV.zzx, C1, YUV.y
+       * else
+       *     RGB.xyz = MAD YUV.xxz, C1, YUV.y
+       */
+
+      emit_op3(c, TGSI_OPCODE_MAD,
+	       dst_mask(dst, BRW_WRITEMASK_XYZ),
+	       ( swap_uv ? 
+		 src_swizzle(tmpsrc, Z,Z,X,X) : 
+		 src_swizzle(tmpsrc, X,X,Z,Z)),
+	       C1,
+	       src_scalar(tmpsrc, Y));
+
+      /*  RGB.y   = MAD YUV.z, C1.w, RGB.y
+       */
+      emit_op3(c,
+	       TGSI_OPCODE_MAD,
+	       dst_mask(dst, BRW_WRITEMASK_Y),
+	       src_scalar(tmpsrc, Z),
+	       src_scalar(C1, W),
+	       src_scalar(src_reg_from_dst(dst), Y));
+
+      release_temp(c, tmp);
+   }
+   else {
+      /* ordinary RGBA tex instruction */
+      emit_tex_op(c, 
+                  TGSI_OPCODE_TEX,
+                  dst,
+                  unit,
+                  target,
+                  sampler.index,
+                  coord,
+                  src_undef(),
+                  src_undef());
+   }
+
+   /* XXX: add GL_EXT_texture_swizzle support to gallium -- by
+    * generating shader varients in mesa state tracker.
+    */
+
+   /* Release this temp if we ended up allocating it:
+    */
+   if (!dst_is_undef(tmp))
+      release_temp(c, tmp);
+}
+
+
+/**
+ * Check if the given TXP instruction really needs the divide-by-W step.
+ */
+static GLboolean projtex( struct brw_wm_compile *c,
+			  unsigned target, 
+			  struct brw_fp_src src )
+{
+   /* Only try to detect the simplest cases.  Could detect (later)
+    * cases where we are trying to emit code like RCP {1.0}, MUL x,
+    * {1.0}, and so on.
+    *
+    * More complex cases than this typically only arise from
+    * user-provided fragment programs anyway:
+    */
+   if (target == TGSI_TEXTURE_CUBE)
+      return GL_FALSE;  /* ut2004 gun rendering !?! */
+   
+   if (src.file == TGSI_FILE_INPUT && 
+       BRW_GET_SWZ(src.swizzle, W) == W &&
+       c->fp->info.input_interpolate[src.index] != TGSI_INTERPOLATE_PERSPECTIVE)
+      return GL_FALSE;
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Emit code for TXP.
+ */
+static void precalc_txp( struct brw_wm_compile *c,
+			 struct brw_fp_dst dst,
+			 unsigned target,
+			 unsigned unit,
+			 struct brw_fp_src src0,
+                         struct brw_fp_src sampler )
+{
+   if (projtex(c, target, src0)) {
+      struct brw_fp_dst tmp = get_temp(c);
+
+      /* tmp0.w = RCP inst.arg[0][3]
+       */
+      emit_op1(c,
+	      TGSI_OPCODE_RCP,
+	      dst_mask(tmp, BRW_WRITEMASK_W),
+	      src_scalar(src0, W));
+
+      /* tmp0.xyz =  MUL inst.arg[0], tmp0.wwww
+       */
+      emit_op2(c,
+	       TGSI_OPCODE_MUL,
+	       dst_mask(tmp, BRW_WRITEMASK_XYZ),
+	       src0,
+	       src_scalar(src_reg_from_dst(tmp), W));
+
+      /* dst = TEX tmp0
+       */
+      precalc_tex(c, 
+		  dst,
+		  target,
+		  unit,
+		  src_reg_from_dst(tmp),
+                  sampler );
+
+      release_temp(c, tmp);
+   }
+   else
+   {
+      /* dst = TEX src0
+       */
+      precalc_tex(c, dst, target, unit, src0, sampler);
+   }
+}
+
+
+/* XXX: note this returns a src_reg.
+ */
+static struct brw_fp_src
+find_output_by_semantic( struct brw_wm_compile *c,
+			 unsigned semantic,
+			 unsigned index )
+{
+   const struct tgsi_shader_info *info = &c->fp->info;
+   unsigned i;
+
+   for (i = 0; i < info->num_outputs; i++)
+      if (info->output_semantic_name[i] == semantic &&
+	  info->output_semantic_index[i] == index)
+	 return src_reg( TGSI_FILE_OUTPUT, i );
+
+   /* If not found, return some arbitrary immediate value:
+    *
+    * XXX: this is a good idea but immediates are up generating extra
+    * curbe entries atm, as they would have in the original driver.
+    */
+   return src_reg( TGSI_FILE_OUTPUT, 0 ); /* src_imm1f(c, 1.0); */
+}
+
+
+static void emit_fb_write( struct brw_wm_compile *c )
+{
+   struct brw_fp_src payload_r0_depth = src_reg(BRW_FILE_PAYLOAD, PAYLOAD_DEPTH);
+   struct brw_fp_src outdepth = find_output_by_semantic(c, TGSI_SEMANTIC_POSITION, 0);
+   GLuint i;
+
+
+   outdepth = src_scalar(outdepth, Z);
+
+   for (i = 0 ; i < c->key.nr_cbufs; i++) {
+      struct brw_fp_src outcolor;
+      
+      outcolor = find_output_by_semantic(c, TGSI_SEMANTIC_COLOR, i);
+
+      /* Use emit_tex_op so that we can specify the inst->target
+       * field, which is abused to contain the FB write target and the
+       * EOT marker
+       */
+      emit_tex_op(c, WM_FB_WRITE,
+		  dst_undef(),
+		  (i == c->key.nr_cbufs - 1), /* EOT */
+		  i,
+                  0,            /* no sampler */
+		  outcolor,
+		  payload_r0_depth,
+		  outdepth);
+   }
+}
+
+
+static struct brw_fp_dst translate_dst( struct brw_wm_compile *c,
+					const struct tgsi_full_dst_register *dst,
+					unsigned saturate )
+{
+   struct brw_fp_dst out;
+
+   out.file = dst->Register.File;
+   out.index = dst->Register.Index;
+   out.writemask = dst->Register.WriteMask;
+   out.indirect = dst->Register.Indirect;
+   out.saturate = (saturate == TGSI_SAT_ZERO_ONE);
+   
+   if (out.indirect) {
+      assert(dst->Indirect.File == TGSI_FILE_ADDRESS);
+      assert(dst->Indirect.Index == 0);
+   }
+   
+   return out;
+}
+
+
+static struct brw_fp_src translate_src( struct brw_wm_compile *c,
+					const struct tgsi_full_src_register *src )
+{
+   struct brw_fp_src out;
+
+   out.file = src->Register.File;
+   out.index = src->Register.Index;
+   out.indirect = src->Register.Indirect;
+
+   out.swizzle = ((src->Register.SwizzleX << 0) |
+		  (src->Register.SwizzleY << 2) |
+		  (src->Register.SwizzleZ << 4) |
+		  (src->Register.SwizzleW << 6));
+   
+   switch (tgsi_util_get_full_src_register_sign_mode( src, 0 )) {
+   case TGSI_UTIL_SIGN_CLEAR:
+      out.abs = 1;
+      out.negate = 0;
+      break;
+
+   case TGSI_UTIL_SIGN_SET:
+      out.abs = 1;
+      out.negate = 1;
+      break;
+
+   case TGSI_UTIL_SIGN_TOGGLE:
+      out.abs = 0;
+      out.negate = 1;
+      break;
+
+   case TGSI_UTIL_SIGN_KEEP:
+   default:
+      out.abs = 0;
+      out.negate = 0;
+      break;
+   }
+
+   if (out.indirect) {
+      assert(src->Indirect.File == TGSI_FILE_ADDRESS);
+      assert(src->Indirect.Index == 0);
+   }
+   
+   return out;
+}
+
+
+
+static void emit_insn( struct brw_wm_compile *c,
+		       const struct tgsi_full_instruction *inst )
+{
+   unsigned opcode = inst->Instruction.Opcode;
+   struct brw_fp_dst dst;
+   struct brw_fp_src src[3];
+   int i;
+
+   dst = translate_dst( c, &inst->Dst[0],
+			inst->Instruction.Saturate );
+
+   for (i = 0; i < inst->Instruction.NumSrcRegs; i++)
+      src[i] = translate_src( c, &inst->Src[i] );
+   
+   switch (opcode) {
+   case TGSI_OPCODE_ABS:
+      emit_op1(c, TGSI_OPCODE_MOV,
+	       dst, 
+	       src_abs(src[0]));
+      break;
+
+   case TGSI_OPCODE_SUB: 
+      emit_op2(c, TGSI_OPCODE_ADD,
+	       dst,
+	       src[0],
+	       src_negate(src[1]));
+      break;
+
+   case TGSI_OPCODE_SCS: 
+      emit_op1(c, TGSI_OPCODE_SCS,
+	       dst_mask(dst, BRW_WRITEMASK_XY),
+	       src[0]);
+      break;
+	 
+   case TGSI_OPCODE_DST:
+      precalc_dst(c, dst, src[0], src[1]);
+      break;
+
+   case TGSI_OPCODE_LIT:
+      precalc_lit(c, dst, src[0]);
+      break;
+
+   case TGSI_OPCODE_TEX:
+      precalc_tex(c, dst,
+		  inst->Texture.Texture,
+		  src[1].index,	/* use sampler unit for tex idx */
+		  src[0],       /* coord */
+                  src[1]);      /* sampler */
+      break;
+
+   case TGSI_OPCODE_TXP:
+      precalc_txp(c, dst,
+		  inst->Texture.Texture,
+		  src[1].index,	/* use sampler unit for tex idx */
+		  src[0],       /* coord */
+                  src[1]);      /* sampler */
+      break;
+
+   case TGSI_OPCODE_TXB:
+      /* XXX: TXB not done
+       */
+      precalc_tex(c, dst,
+		  inst->Texture.Texture,
+		  src[1].index,	/* use sampler unit for tex idx*/
+		  src[0],
+                  src[1]);
+      break;
+
+   case TGSI_OPCODE_XPD: 
+      emit_op2(c, TGSI_OPCODE_XPD,
+	       dst_mask(dst, BRW_WRITEMASK_XYZ),
+	       src[0], 
+	       src[1]);
+      break;
+
+   case TGSI_OPCODE_KIL: 
+      emit_op1(c, TGSI_OPCODE_KIL,
+	       dst_mask(dst_undef(), 0),
+	       src[0]);
+      break;
+
+   case TGSI_OPCODE_END:
+      emit_fb_write(c);
+      break;
+   default:
+      if (!c->key.has_flow_control &&
+	  brw_wm_is_scalar_result(opcode))
+	 emit_scalar_insn(c, opcode, dst, src[0], src[1], src[2]);
+      else
+	 emit_op3(c, opcode, dst, src[0], src[1], src[2]);
+      break;
+   }
+}
+
+/**
+ * Initial pass for fragment program code generation.
+ * This function is used by both the GLSL and non-GLSL paths.
+ */
+int brw_wm_pass_fp( struct brw_wm_compile *c )
+{
+   struct brw_fragment_shader *fs = c->fp;
+   struct tgsi_parse_context parse;
+   struct tgsi_full_instruction *inst;
+   struct tgsi_full_declaration *decl;
+   const float *imm;
+   GLuint size;
+   GLuint i;
+
+   if (BRW_DEBUG & DEBUG_WM) {
+      debug_printf("pre-fp:\n");
+      tgsi_dump(fs->tokens, 0); 
+   }
+
+   c->fp_pixel_xy = src_undef();
+   c->fp_delta_xy = src_undef();
+   c->fp_pixel_w = src_undef();
+   c->nr_fp_insns = 0;
+   c->nr_immediates = 0;
+
+
+   /* Loop over all instructions doing assorted simplifications and
+    * transformations.
+    */
+   tgsi_parse_init( &parse, fs->tokens );
+   while( !tgsi_parse_end_of_tokens( &parse ) ) {
+      tgsi_parse_token( &parse );
+
+      switch( parse.FullToken.Token.Type ) {
+      case TGSI_TOKEN_TYPE_DECLARATION:
+	 /* Turn intput declarations into special WM_* instructions.
+	  *
+	  * XXX: For non-branching shaders, consider deferring variable
+	  * initialization as late as possible to minimize register
+	  * usage.  This is how the original BRW driver worked.
+	  *
+	  * In a branching shader, must preamble instructions at decl
+	  * time, as instruction order in the shader does not
+	  * correspond to the order instructions are executed in the
+	  * wild.
+	  *
+	  * This is where special instructions such as WM_CINTERP,
+	  * WM_LINTERP, WM_PINTERP and WM_WPOSXY are emitted to
+	  * compute shader inputs from the payload registers and pixel
+	  * position.
+	  */
+         decl = &parse.FullToken.FullDeclaration;
+         if( decl->Declaration.File == TGSI_FILE_INPUT ) {
+            unsigned first, last, mask;
+            unsigned attrib;
+
+            first = decl->Range.First;
+            last = decl->Range.Last;
+            mask = decl->Declaration.UsageMask;
+
+            for (attrib = first; attrib <= last; attrib++) {
+	       emit_interp(c, 
+			   attrib, 
+			   decl->Semantic.Name,
+			   decl->Declaration.Interpolate );
+            }
+         }
+	 
+         break;
+
+      case TGSI_TOKEN_TYPE_IMMEDIATE:
+	 /* Unlike VS programs we can probably manage fine encoding
+	  * immediate values directly into the emitted EU
+	  * instructions, as we probably only need to reference one
+	  * float value per instruction.  Just save the data for now
+	  * and use directly later.
+	  */
+	 i = c->nr_immediates++;
+	 imm = &parse.FullToken.FullImmediate.u[i].Float;
+	 size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
+
+	 if (c->nr_immediates >= BRW_WM_MAX_CONST)
+	    return PIPE_ERROR_OUT_OF_MEMORY;
+
+	 for (i = 0; i < size; i++)
+	    c->immediate[c->nr_immediates].v[i] = imm[i];
+
+	 for (; i < 4; i++)
+	    c->immediate[c->nr_immediates].v[i] = 0.0;
+
+	 c->immediate[c->nr_immediates].nr = size;
+	 c->nr_immediates++;
+	 break;
+
+      case TGSI_TOKEN_TYPE_INSTRUCTION:
+         inst = &parse.FullToken.FullInstruction;
+	 emit_insn(c, inst);
+	 break;
+      }
+   }
+
+   if (BRW_DEBUG & DEBUG_WM) {
+      brw_wm_print_fp_program( c, "pass_fp" );
+      debug_printf("\n");
+   }
+
+   return c->error;
+}
+
diff --git a/src/gallium/drivers/i965/brw_wm_glsl.c b/src/gallium/drivers/i965/brw_wm_glsl.c
new file mode 100644
index 0000000..3b3afc3
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_wm_glsl.c
@@ -0,0 +1,2032 @@
+#include "util/u_math.h"
+
+
+#include "brw_context.h"
+#include "brw_eu.h"
+#include "brw_wm.h"
+
+
+static struct brw_reg get_dst_reg(struct brw_wm_compile *c,
+                                  const struct brw_fp_instruction *inst,
+                                  GLuint component);
+
+
+static void
+reclaim_temps(struct brw_wm_compile *c);
+
+
+/** Mark GRF register as used. */
+static void
+prealloc_grf(struct brw_wm_compile *c, int r)
+{
+   c->used_grf[r] = GL_TRUE;
+}
+
+
+/** Mark given GRF register as not in use. */
+static void
+release_grf(struct brw_wm_compile *c, int r)
+{
+   /*assert(c->used_grf[r]);*/
+   c->used_grf[r] = GL_FALSE;
+   c->first_free_grf = MIN2(c->first_free_grf, r);
+}
+
+
+/** Return index of a free GRF, mark it as used. */
+static int
+alloc_grf(struct brw_wm_compile *c)
+{
+   GLuint r;
+   for (r = c->first_free_grf; r < BRW_WM_MAX_GRF; r++) {
+      if (!c->used_grf[r]) {
+         c->used_grf[r] = GL_TRUE;
+         c->first_free_grf = r + 1;  /* a guess */
+         return r;
+      }
+   }
+
+   /* no free temps, try to reclaim some */
+   reclaim_temps(c);
+   c->first_free_grf = 0;
+
+   /* try alloc again */
+   for (r = c->first_free_grf; r < BRW_WM_MAX_GRF; r++) {
+      if (!c->used_grf[r]) {
+         c->used_grf[r] = GL_TRUE;
+         c->first_free_grf = r + 1;  /* a guess */
+         return r;
+      }
+   }
+
+   for (r = 0; r < BRW_WM_MAX_GRF; r++) {
+      assert(c->used_grf[r]);
+   }
+
+   /* really, no free GRF regs found */
+   if (!c->out_of_regs) {
+      /* print warning once per compilation */
+      debug_printf("%s: ran out of registers for fragment program", __FUNCTION__);
+      c->out_of_regs = GL_TRUE;
+   }
+
+   return -1;
+}
+
+
+/** Return number of GRF registers used */
+static int
+num_grf_used(const struct brw_wm_compile *c)
+{
+   int r;
+   for (r = BRW_WM_MAX_GRF - 1; r >= 0; r--)
+      if (c->used_grf[r])
+         return r + 1;
+   return 0;
+}
+
+
+
+/**
+ * Record the mapping of a Mesa register to a hardware register.
+ */
+static void set_reg(struct brw_wm_compile *c, int file, int index, 
+	int component, struct brw_reg reg)
+{
+    c->wm_regs[file][index][component].reg = reg;
+    c->wm_regs[file][index][component].inited = GL_TRUE;
+}
+
+static struct brw_reg alloc_tmp(struct brw_wm_compile *c)
+{
+    struct brw_reg reg;
+
+    /* if we need to allocate another temp, grow the tmp_regs[] array */
+    if (c->tmp_index == c->tmp_max) {
+       int r = alloc_grf(c);
+       if (r < 0) {
+          /*printf("Out of temps in %s\n", __FUNCTION__);*/
+          r = 50; /* XXX random register! */
+       }
+       c->tmp_regs[ c->tmp_max++ ] = r;
+    }
+
+    /* form the GRF register */
+    reg = brw_vec8_grf(c->tmp_regs[ c->tmp_index++ ], 0);
+    /*printf("alloc_temp %d\n", reg.nr);*/
+    assert(reg.nr < BRW_WM_MAX_GRF);
+    return reg;
+
+}
+
+/**
+ * Save current temp register info.
+ * There must be a matching call to release_tmps().
+ */
+static int mark_tmps(struct brw_wm_compile *c)
+{
+    return c->tmp_index;
+}
+
+static struct brw_reg lookup_tmp( struct brw_wm_compile *c, int index )
+{
+    return brw_vec8_grf( c->tmp_regs[ index ], 0 );
+}
+
+static void release_tmps(struct brw_wm_compile *c, int mark)
+{
+    c->tmp_index = mark;
+}
+
+/**
+ * Convert Mesa src register to brw register.
+ *
+ * Since we're running in SOA mode each Mesa register corresponds to four
+ * hardware registers.  We allocate the hardware registers as needed here.
+ *
+ * \param file  register file, one of PROGRAM_x
+ * \param index  register number
+ * \param component  src component (X=0, Y=1, Z=2, W=3)
+ * \param nr  not used?!?
+ * \param neg  negate value?
+ * \param abs  take absolute value?
+ */
+static struct brw_reg 
+get_reg(struct brw_wm_compile *c, int file, int index, int component,
+        int nr, GLuint neg, GLuint abs)
+{
+    struct brw_reg reg;
+    switch (file) {
+	case TGSI_FILE_NULL:
+	    return brw_null_reg();	
+
+	case TGSI_FILE_CONSTANT:
+	case TGSI_FILE_TEMPORARY:
+	case TGSI_FILE_INPUT:
+	case TGSI_FILE_OUTPUT:
+	case BRW_FILE_PAYLOAD:
+	    break;
+
+	default:
+	   debug_printf("%s: Unexpected file type\n", __FUNCTION__);
+	   return brw_null_reg();
+    }
+
+    assert(index < 256);
+    assert(component < 4);
+
+    /* see if we've already allocated a HW register for this Mesa register */
+    if (c->wm_regs[file][index][component].inited) {
+       /* yes, re-use */
+       reg = c->wm_regs[file][index][component].reg;
+    }
+    else {
+	/* no, allocate new register */
+       int grf = alloc_grf(c);
+       /*printf("alloc grf %d for reg %d:%d.%d\n", grf, file, index, component);*/
+       if (grf < 0) {
+          /* totally out of temps */
+          grf = 51; /* XXX random register! */
+       }
+
+       reg = brw_vec8_grf(grf, 0);
+       /*printf("Alloc new grf %d for %d.%d\n", reg.nr, index, component);*/
+
+       set_reg(c, file, index, component, reg);
+    }
+
+    if (neg & (1 << component)) {
+	reg = negate(reg);
+    }
+    if (abs)
+	reg = brw_abs(reg);
+    return reg;
+}
+
+
+
+
+/**
+ * Find first/last instruction that references each temporary register.
+ */
+GLboolean
+_mesa_find_temp_intervals(const struct prog_instruction *instructions,
+                          GLuint numInstructions,
+                          GLint intBegin[MAX_PROGRAM_TEMPS],
+                          GLint intEnd[MAX_PROGRAM_TEMPS])
+{
+   struct loop_info
+   {
+      GLuint Start, End;  /**< Start, end instructions of loop */
+   };
+   struct loop_info loopStack[MAX_LOOP_NESTING];
+   GLuint loopStackDepth = 0;
+   GLuint i;
+
+   for (i = 0; i < MAX_PROGRAM_TEMPS; i++){
+      intBegin[i] = intEnd[i] = -1;
+   }
+
+   /* Scan instructions looking for temporary registers */
+   for (i = 0; i < numInstructions; i++) {
+      const struct prog_instruction *inst = instructions + i;
+      if (inst->Opcode == OPCODE_BGNLOOP) {
+         loopStack[loopStackDepth].Start = i;
+         loopStack[loopStackDepth].End = inst->BranchTarget;
+         loopStackDepth++;
+      }
+      else if (inst->Opcode == OPCODE_ENDLOOP) {
+         loopStackDepth--;
+      }
+      else if (inst->Opcode == OPCODE_CAL) {
+         return GL_FALSE;
+      }
+      else {
+         const GLuint numSrc = 3;
+         GLuint j;
+         for (j = 0; j < numSrc; j++) {
+            if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
+               const GLuint index = inst->SrcReg[j].Index;
+               if (inst->SrcReg[j].RelAddr)
+                  return GL_FALSE;
+               update_interval(intBegin, intEnd, index, i);
+               if (loopStackDepth > 0) {
+                  /* extend temp register's interval to end of loop */
+                  GLuint loopEnd = loopStack[loopStackDepth - 1].End;
+                  update_interval(intBegin, intEnd, index, loopEnd);
+               }
+            }
+         }
+         if (inst->DstReg.File == PROGRAM_TEMPORARY) {
+            const GLuint index = inst->DstReg.Index;
+            if (inst->DstReg.RelAddr)
+               return GL_FALSE;
+            update_interval(intBegin, intEnd, index, i);
+            if (loopStackDepth > 0) {
+               /* extend temp register's interval to end of loop */
+               GLuint loopEnd = loopStack[loopStackDepth - 1].End;
+               update_interval(intBegin, intEnd, index, loopEnd);
+            }
+         }
+      }
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * This is called if we run out of GRF registers.  Examine the live intervals
+ * of temp regs in the program and free those which won't be used again.
+ */
+static void
+reclaim_temps(struct brw_wm_compile *c)
+{
+   GLint intBegin[BRW_WM_MAX_TEMPS];
+   GLint intEnd[BRW_WM_MAX_TEMPS];
+   int index;
+
+   /*printf("Reclaim temps:\n");*/
+
+   _mesa_find_temp_intervals(c->fp_instructions, c->nr_fp_insns,
+                             intBegin, intEnd);
+
+   for (index = 0; index < BRW_WM_MAX_TEMPS; index++) {
+      if (intEnd[index] != -1 && intEnd[index] < c->cur_inst) {
+         /* program temp[i] can be freed */
+         int component;
+         /*printf("  temp[%d] is dead\n", index);*/
+         for (component = 0; component < 4; component++) {
+            if (c->wm_regs[TGSI_FILE_TEMPORARY][index][component].inited) {
+               int r = c->wm_regs[TGSI_FILE_TEMPORARY][index][component].reg.nr;
+               release_grf(c, r);
+               /*
+               printf("  Reclaim temp %d, reg %d at inst %d\n",
+                      index, r, c->cur_inst);
+               */
+               c->wm_regs[TGSI_FILE_TEMPORARY][index][component].inited = GL_FALSE;
+            }
+         }
+      }
+   }
+}
+
+
+
+
+/**
+ * Preallocate registers.  This sets up the Mesa to hardware register
+ * mapping for certain registers, such as constants (uniforms/state vars)
+ * and shader inputs.
+ */
+static void prealloc_reg(struct brw_wm_compile *c)
+{
+    int i, j;
+    struct brw_reg reg;
+    int urb_read_length = 0;
+    GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted;
+    GLuint reg_index = 0;
+
+    memset(c->used_grf, GL_FALSE, sizeof(c->used_grf));
+    c->first_free_grf = 0;
+
+    for (i = 0; i < 4; i++) {
+        if (i < c->key.nr_depth_regs) 
+            reg = brw_vec8_grf(i * 2, 0);
+        else
+            reg = brw_vec8_grf(0, 0);
+	set_reg(c, TGSI_FILE_PAYLOAD, PAYLOAD_DEPTH, i, reg);
+    }
+    reg_index += 2 * c->key.nr_depth_regs;
+
+    /* constants */
+    {
+        const GLuint nr_params = c->fp->program.Base.Parameters->NumParameters;
+        const GLuint nr_temps = c->fp->program.Base.NumTemporaries;
+
+        /* use a real constant buffer, or just use a section of the GRF? */
+        /* XXX this heuristic may need adjustment... */
+        if ((nr_params + nr_temps) * 4 + reg_index > 80)
+           c->fp->use_const_buffer = GL_TRUE;
+        else
+           c->fp->use_const_buffer = GL_FALSE;
+        /*printf("WM use_const_buffer = %d\n", c->fp->use_const_buffer);*/
+
+        if (c->fp->use_const_buffer) {
+           /* We'll use a real constant buffer and fetch constants from
+            * it with a dataport read message.
+            */
+
+           /* number of float constants in CURBE */
+           c->prog_data.nr_params = 0;
+        }
+        else {
+           const struct gl_program_parameter_list *plist = 
+              c->fp->program.Base.Parameters;
+           int index = 0;
+
+           /* number of float constants in CURBE */
+           c->prog_data.nr_params = 4 * nr_params;
+
+           /* loop over program constants (float[4]) */
+           for (i = 0; i < nr_params; i++) {
+              /* loop over XYZW channels */
+              for (j = 0; j < 4; j++, index++) {
+                 reg = brw_vec1_grf(reg_index + index / 8, index % 8);
+                 /* Save pointer to parameter/constant value.
+                  * Constants will be copied in prepare_constant_buffer()
+                  */
+                 c->prog_data.param[index] = &plist->ParameterValues[i][j];
+                 set_reg(c, TGSI_FILE_STATE_VAR, i, j, reg);
+              }
+           }
+           /* number of constant regs used (each reg is float[8]) */
+           c->nr_creg = 2 * ((4 * nr_params + 15) / 16);
+           reg_index += c->nr_creg;
+        }
+    }
+
+    /* fragment shader inputs */
+    for (i = 0; i < VERT_RESULT_MAX; i++) {
+       int fp_input;
+
+       if (i >= VERT_RESULT_VAR0)
+	  fp_input = i - VERT_RESULT_VAR0 + FRAG_ATTRIB_VAR0;
+       else if (i <= VERT_RESULT_TEX7)
+	  fp_input = i;
+       else
+	  fp_input = -1;
+
+       if (fp_input >= 0 && inputs & (1 << fp_input)) {
+	  urb_read_length = reg_index;
+	  reg = brw_vec8_grf(reg_index, 0);
+	  for (j = 0; j < 4; j++)
+	     set_reg(c, TGSI_FILE_PAYLOAD, fp_input, j, reg);
+       }
+       if (c->key.nr_vp_outputs > i) {
+	  reg_index += 2;
+       }
+    }
+
+    c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2;
+    c->prog_data.urb_read_length = urb_read_length;
+    c->prog_data.curb_read_length = c->nr_creg;
+    c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, reg_index, 0);
+    reg_index++;
+    c->stack =  brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg_index, 0);
+    reg_index += 2;
+
+    /* mark GRF regs [0..reg_index-1] as in-use */
+    for (i = 0; i < reg_index; i++)
+       prealloc_grf(c, i);
+
+    /* Don't use GRF 126, 127.  Using them seems to lead to GPU lock-ups */
+    prealloc_grf(c, 126);
+    prealloc_grf(c, 127);
+
+    for (i = 0; i < c->nr_fp_insns; i++) {
+	const struct brw_fp_instruction *inst = &c->fp_instructions[i];
+	struct brw_reg dst[4];
+
+	switch (inst->Opcode) {
+	case OPCODE_TEX:
+	case OPCODE_TXB:
+	    /* Allocate the channels of texture results contiguously,
+	     * since they are written out that way by the sampler unit.
+	     */
+	    for (j = 0; j < 4; j++) {
+		dst[j] = get_dst_reg(c, inst, j);
+		if (j != 0)
+		    assert(dst[j].nr == dst[j - 1].nr + 1);
+	    }
+	    break;
+	default:
+	    break;
+	}
+    }
+
+    /* An instruction may reference up to three constants.
+     * They'll be found in these registers.
+     * XXX alloc these on demand!
+     */
+    if (c->fp->use_const_buffer) {
+       for (i = 0; i < 3; i++) {
+          c->current_const[i].index = -1;
+          c->current_const[i].reg = brw_vec8_grf(alloc_grf(c), 0);
+       }
+    }
+#if 0
+    printf("USE CONST BUFFER? %d\n", c->fp->use_const_buffer);
+    printf("AFTER PRE_ALLOC, reg_index = %d\n", reg_index);
+#endif
+}
+
+
+/**
+ * Check if any of the instruction's src registers are constants, uniforms,
+ * or statevars.  If so, fetch any constants that we don't already have in
+ * the three GRF slots.
+ */
+static void fetch_constants(struct brw_wm_compile *c,
+                            const struct brw_fp_instruction *inst)
+{
+   struct brw_compile *p = &c->func;
+   GLuint i;
+
+   /* loop over instruction src regs */
+   for (i = 0; i < 3; i++) {
+      const struct prog_src_register *src = &inst->SrcReg[i];
+      if (src->File == TGSI_FILE_IMMEDIATE ||
+          src->File == TGSI_FILE_CONSTANT) {
+	 c->current_const[i].index = src->Index;
+
+#if 0
+	 printf("  fetch const[%d] for arg %d into reg %d\n",
+		src->Index, i, c->current_const[i].reg.nr);
+#endif
+
+	 /* need to fetch the constant now */
+	 brw_dp_READ_4(p,
+		       c->current_const[i].reg,  /* writeback dest */
+		       src->RelAddr,             /* relative indexing? */
+		       16 * src->Index,          /* byte offset */
+		       SURF_INDEX_FRAG_CONST_BUFFER/* binding table index */
+		       );
+      }
+   }
+}
+
+
+/**
+ * Convert Mesa dst register to brw register.
+ */
+static struct brw_reg get_dst_reg(struct brw_wm_compile *c, 
+                                  const struct brw_fp_instruction *inst,
+                                  GLuint component)
+{
+    const int nr = 1;
+    return get_reg(c, inst->DstReg.File, inst->DstReg.Index, component, nr,
+	    0, 0);
+}
+
+
+static struct brw_reg
+get_src_reg_const(struct brw_wm_compile *c,
+                  const struct brw_fp_instruction *inst,
+                  GLuint srcRegIndex, GLuint component)
+{
+   /* We should have already fetched the constant from the constant
+    * buffer in fetch_constants().  Now we just have to return a
+    * register description that extracts the needed component and
+    * smears it across all eight vector components.
+    */
+   const struct prog_src_register *src = &inst->SrcReg[srcRegIndex];
+   struct brw_reg const_reg;
+
+   assert(component < 4);
+   assert(srcRegIndex < 3);
+   assert(c->current_const[srcRegIndex].index != -1);
+   const_reg = c->current_const[srcRegIndex].reg;
+
+   /* extract desired float from the const_reg, and smear */
+   const_reg = stride(const_reg, 0, 1, 0);
+   const_reg.subnr = component * 4;
+
+   if (src->Negate)
+      const_reg = negate(const_reg);
+   if (src->Abs)
+      const_reg = brw_abs(const_reg);
+
+#if 0
+   printf("  form const[%d].%d for arg %d, reg %d\n",
+          c->current_const[srcRegIndex].index,
+          component,
+          srcRegIndex,
+          const_reg.nr);
+#endif
+
+   return const_reg;
+}
+
+
+/**
+ * Convert Mesa src register to brw register.
+ */
+static struct brw_reg get_src_reg(struct brw_wm_compile *c, 
+                                  const struct brw_fp_instruction *inst,
+                                  GLuint srcRegIndex, GLuint channel)
+{
+    const struct prog_src_register *src = &inst->SrcReg[srcRegIndex];
+    const GLuint nr = 1;
+    const GLuint component = BRW_GET_SWZ(src->Swizzle, channel);
+
+    /* Extended swizzle terms */
+    if (component == SWIZZLE_ZERO) {
+       return brw_imm_f(0.0F);
+    }
+    else if (component == SWIZZLE_ONE) {
+       return brw_imm_f(1.0F);
+    }
+
+    if (c->fp->use_const_buffer &&
+        (src->File == TGSI_FILE_STATE_VAR ||
+         src->File == TGSI_FILE_CONSTANT ||
+         src->File == TGSI_FILE_UNIFORM)) {
+       return get_src_reg_const(c, inst, srcRegIndex, component);
+    }
+    else {
+       /* other type of source register */
+       return get_reg(c, src->File, src->Index, component, nr, 
+                      src->Negate, src->Abs);
+    }
+}
+
+
+/**
+ * Same as \sa get_src_reg() but if the register is a immediate, emit
+ * a brw_reg encoding the immediate.
+ * Note that a brw instruction only allows one src operand to be a immediate.
+ * For instructions with more than one operand, only the second can be a
+ * immediate.  This means that we treat some immediates as constants
+ * (which why TGSI_FILE_IMMEDIATE is checked in fetch_constants()).
+ * 
+ */
+static struct brw_reg get_src_reg_imm(struct brw_wm_compile *c, 
+                                      const struct brw_fp_instruction *inst,
+                                      GLuint srcRegIndex, GLuint channel)
+{
+    const struct prog_src_register *src = &inst->SrcReg[srcRegIndex];
+    if (src->File == TGSI_FILE_IMMEDIATE) {
+       /* an immediate */
+       const int component = BRW_GET_SWZ(src->Swizzle, channel);
+       const GLfloat *param =
+          c->fp->program.Base.Parameters->ParameterValues[src->Index];
+       GLfloat value = param[component];
+       if (src->Negate)
+          value = -value;
+       if (src->Abs)
+          value = FABSF(value);
+#if 0
+       printf("  form immed value %f for chan %d\n", value, channel);
+#endif
+       return brw_imm_f(value);
+    }
+    else {
+       return get_src_reg(c, inst, srcRegIndex, channel);
+    }
+}
+
+
+/**
+ * Subroutines are minimal support for resusable instruction sequences.
+ * They are implemented as simply as possible to minimise overhead: there
+ * is no explicit support for communication between the caller and callee
+ * other than saving the return address in a temporary register, nor is
+ * there any automatic local storage.  This implies that great care is
+ * required before attempting reentrancy or any kind of nested
+ * subroutine invocations.
+ */
+static void invoke_subroutine( struct brw_wm_compile *c,
+			       enum _subroutine subroutine,
+			       void (*emit)( struct brw_wm_compile * ) )
+{
+    struct brw_compile *p = &c->func;
+
+    assert( subroutine < BRW_WM_MAX_SUBROUTINE );
+    
+    if( c->subroutines[ subroutine ] ) {
+	/* subroutine previously emitted: reuse existing instructions */
+
+	int mark = mark_tmps( c );
+	struct brw_reg return_address = retype( alloc_tmp( c ),
+						BRW_REGISTER_TYPE_UD );
+	int here = p->nr_insn;
+	
+	brw_push_insn_state(p);
+	brw_set_mask_control(p, BRW_MASK_DISABLE);
+	brw_ADD( p, return_address, brw_ip_reg(), brw_imm_ud( 2 << 4 ) );
+
+	brw_ADD( p, brw_ip_reg(), brw_ip_reg(),
+		 brw_imm_d( ( c->subroutines[ subroutine ] -
+			      here - 1 ) << 4 ) );
+	brw_pop_insn_state(p);
+
+	release_tmps( c, mark );
+    } else {
+	/* previously unused subroutine: emit, and mark for later reuse */
+	
+	int mark = mark_tmps( c );
+	struct brw_reg return_address = retype( alloc_tmp( c ),
+						BRW_REGISTER_TYPE_UD );
+	struct brw_instruction *calc;
+	int base = p->nr_insn;
+	
+	brw_push_insn_state(p);
+	brw_set_mask_control(p, BRW_MASK_DISABLE);
+	calc = brw_ADD( p, return_address, brw_ip_reg(), brw_imm_ud( 0 ) );
+	brw_pop_insn_state(p);
+	
+	c->subroutines[ subroutine ] = p->nr_insn;
+
+	emit( c );
+	
+	brw_push_insn_state(p);
+	brw_set_mask_control(p, BRW_MASK_DISABLE);
+	brw_MOV( p, brw_ip_reg(), return_address );
+	brw_pop_insn_state(p);
+
+	brw_set_src1( calc, brw_imm_ud( ( p->nr_insn - base ) << 4 ) );
+	
+	release_tmps( c, mark );
+    }
+}
+
+static void emit_trunc( struct brw_wm_compile *c,
+                        const struct brw_fp_instruction *inst)
+{
+    int i;
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    struct brw_reg src, dst;
+	    dst = get_dst_reg(c, inst, i);
+	    src = get_src_reg(c, inst, 0, i);
+	    brw_RNDZ(p, dst, src);
+	}
+    }
+    brw_set_saturate(p, 0);
+}
+
+static void emit_mov( struct brw_wm_compile *c,
+                      const struct brw_fp_instruction *inst)
+{
+    int i;
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    struct brw_reg src, dst;
+	    dst = get_dst_reg(c, inst, i);
+            /* XXX some moves from immediate value don't work reliably!!! */
+            /*src = get_src_reg_imm(c, inst, 0, i);*/
+            src = get_src_reg(c, inst, 0, i);
+	    brw_MOV(p, dst, src);
+	}
+    }
+    brw_set_saturate(p, 0);
+}
+
+static void emit_pixel_xy(struct brw_wm_compile *c,
+                          const struct brw_fp_instruction *inst)
+{
+    struct brw_reg r1 = brw_vec1_grf(1, 0);
+    struct brw_reg r1_uw = retype(r1, BRW_REGISTER_TYPE_UW);
+
+    struct brw_reg dst0, dst1;
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+
+    dst0 = get_dst_reg(c, inst, 0);
+    dst1 = get_dst_reg(c, inst, 1);
+    /* Calculate pixel centers by adding 1 or 0 to each of the
+     * micro-tile coordinates passed in r1.
+     */
+    if (mask & WRITEMASK_X) {
+	brw_ADD(p,
+		vec8(retype(dst0, BRW_REGISTER_TYPE_UW)),
+		stride(suboffset(r1_uw, 4), 2, 4, 0),
+		brw_imm_v(0x10101010));
+    }
+
+    if (mask & WRITEMASK_Y) {
+	brw_ADD(p,
+		vec8(retype(dst1, BRW_REGISTER_TYPE_UW)),
+		stride(suboffset(r1_uw, 5), 2, 4, 0),
+		brw_imm_v(0x11001100));
+    }
+}
+
+static void emit_delta_xy(struct brw_wm_compile *c,
+                          const struct brw_fp_instruction *inst)
+{
+    struct brw_reg r1 = brw_vec1_grf(1, 0);
+    struct brw_reg dst0, dst1, src0, src1;
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+
+    dst0 = get_dst_reg(c, inst, 0);
+    dst1 = get_dst_reg(c, inst, 1);
+    src0 = get_src_reg(c, inst, 0, 0);
+    src1 = get_src_reg(c, inst, 0, 1);
+    /* Calc delta X,Y by subtracting origin in r1 from the pixel
+     * centers.
+     */
+    if (mask & WRITEMASK_X) {
+	brw_ADD(p,
+		dst0,
+		retype(src0, BRW_REGISTER_TYPE_UW),
+		negate(r1));
+    }
+
+    if (mask & WRITEMASK_Y) {
+	brw_ADD(p,
+		dst1,
+		retype(src1, BRW_REGISTER_TYPE_UW),
+		negate(suboffset(r1,1)));
+
+    }
+}
+
+static void fire_fb_write( struct brw_wm_compile *c,
+                           GLuint base_reg,
+                           GLuint nr,
+                           GLuint target,
+                           GLuint eot)
+{
+    struct brw_compile *p = &c->func;
+    /* Pass through control information:
+     */
+    /*  mov (8) m1.0<1>:ud   r1.0<8;8,1>:ud   { Align1 NoMask } */
+    {
+	brw_push_insn_state(p);
+	brw_set_mask_control(p, BRW_MASK_DISABLE); /* ? */
+	brw_MOV(p,
+		brw_message_reg(base_reg + 1),
+		brw_vec8_grf(1, 0));
+	brw_pop_insn_state(p);
+    }
+    /* Send framebuffer write message: */
+    brw_fb_WRITE(p,
+	    retype(vec8(brw_null_reg()), BRW_REGISTER_TYPE_UW),
+	    base_reg,
+	    retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW),
+	    target,              
+	    nr,
+	    0,
+	    eot);
+}
+
+static void emit_fb_write(struct brw_wm_compile *c,
+                          const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    int nr = 2;
+    int channel;
+    GLuint target, eot;
+    struct brw_reg src0;
+
+    /* Reserve a space for AA - may not be needed:
+     */
+    if (c->key.aa_dest_stencil_reg)
+	nr += 1;
+
+    brw_push_insn_state(p);
+    for (channel = 0; channel < 4; channel++) {
+        src0 = get_src_reg(c,  inst, 0, channel);
+        /*  mov (8) m2.0<1>:ud   r28.0<8;8,1>:ud  { Align1 } */
+        /*  mov (8) m6.0<1>:ud   r29.0<8;8,1>:ud  { Align1 SecHalf } */
+        brw_MOV(p, brw_message_reg(nr + channel), src0);
+    }
+    /* skip over the regs populated above: */
+    nr += 8;
+    brw_pop_insn_state(p);
+
+    if (c->key.source_depth_to_render_target) {
+       if (c->key.computes_depth) {
+          src0 = get_src_reg(c, inst, 2, 2);
+          brw_MOV(p, brw_message_reg(nr), src0);
+       }
+       else {
+          src0 = get_src_reg(c, inst, 1, 1);
+          brw_MOV(p, brw_message_reg(nr), src0);
+       }
+
+       nr += 2;
+    }
+
+    if (c->key.dest_depth_reg) {
+        const GLuint comp = c->key.dest_depth_reg / 2;
+        const GLuint off = c->key.dest_depth_reg % 2;
+
+        if (off != 0) {
+            /* XXX this code needs review/testing */
+            struct brw_reg arg1_0 = get_src_reg(c, inst, 1, comp);
+            struct brw_reg arg1_1 = get_src_reg(c, inst, 1, comp+1);
+
+            brw_push_insn_state(p);
+            brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+
+            brw_MOV(p, brw_message_reg(nr), offset(arg1_0, 1));
+            /* 2nd half? */
+            brw_MOV(p, brw_message_reg(nr+1), arg1_1);
+            brw_pop_insn_state(p);
+        }
+        else
+        {
+            struct brw_reg src =  get_src_reg(c, inst, 1, 1);
+            brw_MOV(p, brw_message_reg(nr), src);
+        }
+        nr += 2;
+   }
+
+    target = inst->Aux >> 1;
+    eot = inst->Aux & 1;
+    fire_fb_write(c, 0, nr, target, eot);
+}
+
+static void emit_pixel_w( struct brw_wm_compile *c,
+                          const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    if (mask & WRITEMASK_W) {
+	struct brw_reg dst, src0, delta0, delta1;
+	struct brw_reg interp3;
+
+	dst = get_dst_reg(c, inst, 3);
+	src0 = get_src_reg(c, inst, 0, 0);
+	delta0 = get_src_reg(c, inst, 1, 0);
+	delta1 = get_src_reg(c, inst, 1, 1);
+
+	interp3 = brw_vec1_grf(src0.nr+1, 4);
+	/* Calc 1/w - just linterp wpos[3] optimized by putting the
+	 * result straight into a message reg.
+	 */
+	brw_LINE(p, brw_null_reg(), interp3, delta0);
+	brw_MAC(p, brw_message_reg(2), suboffset(interp3, 1), delta1);
+
+	/* Calc w */
+	brw_math_16( p, dst,
+		BRW_MATH_FUNCTION_INV,
+		BRW_MATH_SATURATE_NONE,
+		2, brw_null_reg(),
+		BRW_MATH_PRECISION_FULL);
+    }
+}
+
+static void emit_linterp(struct brw_wm_compile *c,
+                         const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    struct brw_reg interp[4];
+    struct brw_reg dst, delta0, delta1;
+    struct brw_reg src0;
+    GLuint nr, i;
+
+    src0 = get_src_reg(c, inst, 0, 0);
+    delta0 = get_src_reg(c, inst, 1, 0);
+    delta1 = get_src_reg(c, inst, 1, 1);
+    nr = src0.nr;
+
+    interp[0] = brw_vec1_grf(nr, 0);
+    interp[1] = brw_vec1_grf(nr, 4);
+    interp[2] = brw_vec1_grf(nr+1, 0);
+    interp[3] = brw_vec1_grf(nr+1, 4);
+
+    for(i = 0; i < 4; i++ ) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i);
+	    brw_LINE(p, brw_null_reg(), interp[i], delta0);
+	    brw_MAC(p, dst, suboffset(interp[i],1), delta1);
+	}
+    }
+}
+
+static void emit_cinterp(struct brw_wm_compile *c,
+                         const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+
+    struct brw_reg interp[4];
+    struct brw_reg dst, src0;
+    GLuint nr, i;
+
+    src0 = get_src_reg(c, inst, 0, 0);
+    nr = src0.nr;
+
+    interp[0] = brw_vec1_grf(nr, 0);
+    interp[1] = brw_vec1_grf(nr, 4);
+    interp[2] = brw_vec1_grf(nr+1, 0);
+    interp[3] = brw_vec1_grf(nr+1, 4);
+
+    for(i = 0; i < 4; i++ ) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i);
+	    brw_MOV(p, dst, suboffset(interp[i],3));
+	}
+    }
+}
+
+static void emit_pinterp(struct brw_wm_compile *c,
+                         const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+
+    struct brw_reg interp[4];
+    struct brw_reg dst, delta0, delta1;
+    struct brw_reg src0, w;
+    GLuint nr, i;
+
+    src0 = get_src_reg(c, inst, 0, 0);
+    delta0 = get_src_reg(c, inst, 1, 0);
+    delta1 = get_src_reg(c, inst, 1, 1);
+    w = get_src_reg(c, inst, 2, 3);
+    nr = src0.nr;
+
+    interp[0] = brw_vec1_grf(nr, 0);
+    interp[1] = brw_vec1_grf(nr, 4);
+    interp[2] = brw_vec1_grf(nr+1, 0);
+    interp[3] = brw_vec1_grf(nr+1, 4);
+
+    for(i = 0; i < 4; i++ ) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i);
+	    brw_LINE(p, brw_null_reg(), interp[i], delta0);
+	    brw_MAC(p, dst, suboffset(interp[i],1), 
+		    delta1);
+	    brw_MUL(p, dst, dst, w);
+	}
+    }
+}
+
+/* Sets the destination channels to 1.0 or 0.0 according to glFrontFacing. */
+static void emit_frontfacing(struct brw_wm_compile *c,
+			     const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg r1_6ud = retype(brw_vec1_grf(1, 6), BRW_REGISTER_TYPE_UD);
+    struct brw_reg dst;
+    GLuint mask = inst->DstReg.WriteMask;
+    int i;
+
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i);
+	    brw_MOV(p, dst, brw_imm_f(0.0));
+	}
+    }
+
+    /* bit 31 is "primitive is back face", so checking < (1 << 31) gives
+     * us front face
+     */
+    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, r1_6ud, brw_imm_ud(1 << 31));
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i);
+	    brw_MOV(p, dst, brw_imm_f(1.0));
+	}
+    }
+    brw_set_predicate_control_flag_value(p, 0xff);
+}
+
+static void emit_xpd(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    int i;
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    for (i = 0; i < 4; i++) {
+	GLuint i2 = (i+2)%3;
+	GLuint i1 = (i+1)%3;
+	if (mask & (1<<i)) {
+	    struct brw_reg src0, src1, dst;
+	    dst = get_dst_reg(c, inst, i);
+	    src0 = negate(get_src_reg(c, inst, 0, i2));
+	    src1 = get_src_reg_imm(c, inst, 1, i1);
+	    brw_MUL(p, brw_null_reg(), src0, src1);
+	    src0 = get_src_reg(c, inst, 0, i1);
+	    src1 = get_src_reg_imm(c, inst, 1, i2);
+	    brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+	    brw_MAC(p, dst, src0, src1);
+	    brw_set_saturate(p, 0);
+	}
+    }
+    brw_set_saturate(p, 0);
+}
+
+static void emit_dp3(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    struct brw_reg src0[3], src1[3], dst;
+    int i;
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    int dst_chan = ffs(mask & WRITEMASK_XYZW) - 1;
+
+    if (!(mask & WRITEMASK_XYZW))
+	return;
+
+    assert(is_power_of_two(mask & WRITEMASK_XYZW));
+
+    for (i = 0; i < 3; i++) {
+	src0[i] = get_src_reg(c, inst, 0, i);
+	src1[i] = get_src_reg_imm(c, inst, 1, i);
+    }
+
+    dst = get_dst_reg(c, inst, dst_chan);
+    brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
+    brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    brw_MAC(p, dst, src0[2], src1[2]);
+    brw_set_saturate(p, 0);
+}
+
+static void emit_dp4(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    struct brw_reg src0[4], src1[4], dst;
+    int i;
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    int dst_chan = ffs(mask & WRITEMASK_XYZW) - 1;
+
+    if (!(mask & WRITEMASK_XYZW))
+	return;
+
+    assert(is_power_of_two(mask & WRITEMASK_XYZW));
+
+    for (i = 0; i < 4; i++) {
+	src0[i] = get_src_reg(c, inst, 0, i);
+	src1[i] = get_src_reg_imm(c, inst, 1, i);
+    }
+    dst = get_dst_reg(c, inst, dst_chan);
+    brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
+    brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
+    brw_MAC(p, brw_null_reg(), src0[2], src1[2]);
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    brw_MAC(p, dst, src0[3], src1[3]);
+    brw_set_saturate(p, 0);
+}
+
+static void emit_dph(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    struct brw_reg src0[4], src1[4], dst;
+    int i;
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    int dst_chan = ffs(mask & WRITEMASK_XYZW) - 1;
+
+    if (!(mask & WRITEMASK_XYZW))
+	return;
+
+    assert(is_power_of_two(mask & WRITEMASK_XYZW));
+
+    for (i = 0; i < 4; i++) {
+	src0[i] = get_src_reg(c, inst, 0, i);
+	src1[i] = get_src_reg_imm(c, inst, 1, i);
+    }
+    dst = get_dst_reg(c, inst, dst_chan);
+    brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
+    brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
+    brw_MAC(p, dst, src0[2], src1[2]);
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    brw_ADD(p, dst, dst, src1[3]);
+    brw_set_saturate(p, 0);
+}
+
+/**
+ * Emit a scalar instruction, like RCP, RSQ, LOG, EXP.
+ * Note that the result of the function is smeared across the dest
+ * register's X, Y, Z and W channels (subject to writemasking of course).
+ */
+static void emit_math1(struct brw_wm_compile *c,
+                       const struct brw_fp_instruction *inst, GLuint func)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg src0, dst;
+    GLuint mask = inst->DstReg.WriteMask;
+    int dst_chan = ffs(mask & WRITEMASK_XYZW) - 1;
+
+    if (!(mask & WRITEMASK_XYZW))
+	return;
+
+    assert(is_power_of_two(mask & WRITEMASK_XYZW));
+
+    /* Get first component of source register */
+    dst = get_dst_reg(c, inst, dst_chan);
+    src0 = get_src_reg(c, inst, 0, 0);
+
+    brw_MOV(p, brw_message_reg(2), src0);
+    brw_math(p,
+             dst,
+             func,
+             (inst->SaturateMode != SATURATE_OFF) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
+             2,
+             brw_null_reg(),
+             BRW_MATH_DATA_VECTOR,
+             BRW_MATH_PRECISION_FULL);
+}
+
+static void emit_rcp(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    emit_math1(c, inst, BRW_MATH_FUNCTION_INV);
+}
+
+static void emit_rsq(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    emit_math1(c, inst, BRW_MATH_FUNCTION_RSQ);
+}
+
+static void emit_sin(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    emit_math1(c, inst, BRW_MATH_FUNCTION_SIN);
+}
+
+static void emit_cos(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    emit_math1(c, inst, BRW_MATH_FUNCTION_COS);
+}
+
+static void emit_ex2(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    emit_math1(c, inst, BRW_MATH_FUNCTION_EXP);
+}
+
+static void emit_lg2(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    emit_math1(c, inst, BRW_MATH_FUNCTION_LOG);
+}
+
+static void emit_add(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg src0, src1, dst;
+    GLuint mask = inst->DstReg.WriteMask;
+    int i;
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    for (i = 0 ; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i);
+	    src0 = get_src_reg(c, inst, 0, i);
+	    src1 = get_src_reg_imm(c, inst, 1, i);
+	    brw_ADD(p, dst, src0, src1);
+	}
+    }
+    brw_set_saturate(p, 0);
+}
+
+static void emit_arl(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg src0, addr_reg;
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    addr_reg = brw_uw8_reg(BRW_ARCHITECTURE_REGISTER_FILE, 
+                           BRW_ARF_ADDRESS, 0);
+    src0 = get_src_reg(c, inst, 0, 0); /* channel 0 */
+    brw_MOV(p, addr_reg, src0);
+    brw_set_saturate(p, 0);
+}
+
+
+static void emit_mul(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg src0, src1, dst;
+    GLuint mask = inst->DstReg.WriteMask;
+    int i;
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    for (i = 0 ; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i);
+	    src0 = get_src_reg(c, inst, 0, i);
+	    src1 = get_src_reg_imm(c, inst, 1, i);
+	    brw_MUL(p, dst, src0, src1);
+	}
+    }
+    brw_set_saturate(p, 0);
+}
+
+static void emit_frc(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg src0, dst;
+    GLuint mask = inst->DstReg.WriteMask;
+    int i;
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    for (i = 0 ; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i);
+	    src0 = get_src_reg_imm(c, inst, 0, i);
+	    brw_FRC(p, dst, src0);
+	}
+    }
+    if (inst->SaturateMode != SATURATE_OFF)
+	brw_set_saturate(p, 0);
+}
+
+static void emit_flr(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg src0, dst;
+    GLuint mask = inst->DstReg.WriteMask;
+    int i;
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    for (i = 0 ; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i);
+	    src0 = get_src_reg_imm(c, inst, 0, i);
+	    brw_RNDD(p, dst, src0);
+	}
+    }
+    brw_set_saturate(p, 0);
+}
+
+
+static void emit_min_max(struct brw_wm_compile *c,
+                         const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    const GLuint mask = inst->DstReg.WriteMask;
+    const int mark = mark_tmps(c);
+    int i;
+    brw_push_insn_state(p);
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+            struct brw_reg real_dst = get_dst_reg(c, inst, i);
+	    struct brw_reg src0 = get_src_reg(c, inst, 0, i);
+	    struct brw_reg src1 = get_src_reg(c, inst, 1, i);
+            struct brw_reg dst;
+            /* if dst==src0 or dst==src1 we need to use a temp reg */
+            GLboolean use_temp = brw_same_reg(dst, src0) ||
+                                 brw_same_reg(dst, src1);
+            if (use_temp)
+               dst = alloc_tmp(c);
+            else
+               dst = real_dst;
+
+            /*
+            printf("  Min/max: dst %d  src0 %d  src1 %d\n",
+                   dst.nr, src0.nr, src1.nr);
+            */
+	    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+	    brw_MOV(p, dst, src0);
+	    brw_set_saturate(p, 0);
+
+            if (inst->Opcode == OPCODE_MIN)
+               brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src1, src0);
+            else
+               brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, src1, src0);
+
+	    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+	    brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+	    brw_MOV(p, dst, src1);
+	    brw_set_saturate(p, 0);
+	    brw_set_predicate_control_flag_value(p, 0xff);
+            if (use_temp)
+               brw_MOV(p, real_dst, dst);
+	}
+    }
+    brw_pop_insn_state(p);
+    release_tmps(c, mark);
+}
+
+static void emit_pow(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg dst, src0, src1;
+    GLuint mask = inst->DstReg.WriteMask;
+    int dst_chan = ffs(mask & WRITEMASK_XYZW) - 1;
+
+    if (!(mask & WRITEMASK_XYZW))
+	return;
+
+    assert(is_power_of_two(mask & WRITEMASK_XYZW));
+
+    dst = get_dst_reg(c, inst, dst_chan);
+    src0 = get_src_reg_imm(c, inst, 0, 0);
+    src1 = get_src_reg_imm(c, inst, 1, 0);
+
+    brw_MOV(p, brw_message_reg(2), src0);
+    brw_MOV(p, brw_message_reg(3), src1);
+
+    brw_math(p,
+	    dst,
+	    BRW_MATH_FUNCTION_POW,
+	    (inst->SaturateMode != SATURATE_OFF) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
+	    2,
+	    brw_null_reg(),
+	    BRW_MATH_DATA_VECTOR,
+	    BRW_MATH_PRECISION_FULL);
+}
+
+static void emit_lrp(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    struct brw_reg dst, tmp1, tmp2, src0, src1, src2;
+    int i;
+    int mark = mark_tmps(c);
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i);
+	    src0 = get_src_reg(c, inst, 0, i);
+
+	    src1 = get_src_reg_imm(c, inst, 1, i);
+
+	    if (src1.nr == dst.nr) {
+		tmp1 = alloc_tmp(c);
+		brw_MOV(p, tmp1, src1);
+	    } else
+		tmp1 = src1;
+
+	    src2 = get_src_reg(c, inst, 2, i);
+	    if (src2.nr == dst.nr) {
+		tmp2 = alloc_tmp(c);
+		brw_MOV(p, tmp2, src2);
+	    } else
+		tmp2 = src2;
+
+	    brw_ADD(p, dst, negate(src0), brw_imm_f(1.0));
+	    brw_MUL(p, brw_null_reg(), dst, tmp2);
+	    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+	    brw_MAC(p, dst, src0, tmp1);
+	    brw_set_saturate(p, 0);
+	}
+	release_tmps(c, mark);
+    }
+}
+
+/**
+ * For GLSL shaders, this KIL will be unconditional.
+ * It may be contained inside an IF/ENDIF structure of course.
+ */
+static void emit_kil(struct brw_wm_compile *c)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg depth = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
+    brw_push_insn_state(p);
+    brw_set_mask_control(p, BRW_MASK_DISABLE);
+    brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); //IMASK
+    brw_AND(p, depth, c->emit_mask_reg, depth);
+    brw_pop_insn_state(p);
+}
+
+static void emit_mad(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    struct brw_reg dst, src0, src1, src2;
+    int i;
+
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i);
+	    src0 = get_src_reg(c, inst, 0, i);
+	    src1 = get_src_reg_imm(c, inst, 1, i);
+	    src2 = get_src_reg_imm(c, inst, 2, i);
+	    brw_MUL(p, dst, src0, src1);
+
+	    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+	    brw_ADD(p, dst, dst, src2);
+	    brw_set_saturate(p, 0);
+	}
+    }
+}
+
+static void emit_sop(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst, GLuint cond)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    struct brw_reg dst, src0, src1;
+    int i;
+
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i);
+	    src0 = get_src_reg(c, inst, 0, i);
+	    src1 = get_src_reg_imm(c, inst, 1, i);
+	    brw_push_insn_state(p);
+	    brw_CMP(p, brw_null_reg(), cond, src0, src1);
+	    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+	    brw_MOV(p, dst, brw_imm_f(0.0));
+	    brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+	    brw_MOV(p, dst, brw_imm_f(1.0));
+	    brw_pop_insn_state(p);
+	}
+    }
+}
+
+static void emit_slt(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    emit_sop(c, inst, BRW_CONDITIONAL_L);
+}
+
+static void emit_sle(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    emit_sop(c, inst, BRW_CONDITIONAL_LE);
+}
+
+static void emit_sgt(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    emit_sop(c, inst, BRW_CONDITIONAL_G);
+}
+
+static void emit_sge(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    emit_sop(c, inst, BRW_CONDITIONAL_GE);
+}
+
+static void emit_seq(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    emit_sop(c, inst, BRW_CONDITIONAL_EQ);
+}
+
+static void emit_sne(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    emit_sop(c, inst, BRW_CONDITIONAL_NEQ);
+}
+
+static INLINE struct brw_reg high_words( struct brw_reg reg )
+{
+    return stride( suboffset( retype( reg, BRW_REGISTER_TYPE_W ), 1 ),
+		   0, 8, 2 );
+}
+
+static INLINE struct brw_reg low_words( struct brw_reg reg )
+{
+    return stride( retype( reg, BRW_REGISTER_TYPE_W ), 0, 8, 2 );
+}
+
+static INLINE struct brw_reg even_bytes( struct brw_reg reg )
+{
+    return stride( retype( reg, BRW_REGISTER_TYPE_B ), 0, 16, 2 );
+}
+
+static INLINE struct brw_reg odd_bytes( struct brw_reg reg )
+{
+    return stride( suboffset( retype( reg, BRW_REGISTER_TYPE_B ), 1 ),
+		   0, 16, 2 );
+}
+
+
+    
+static void emit_wpos_xy(struct brw_wm_compile *c,
+                         const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    struct brw_reg src0[2], dst[2];
+
+    dst[0] = get_dst_reg(c, inst, 0);
+    dst[1] = get_dst_reg(c, inst, 1);
+
+    src0[0] = get_src_reg(c, inst, 0, 0);
+    src0[1] = get_src_reg(c, inst, 0, 1);
+
+    /* Calculate the pixel offset from window bottom left into destination
+     * X and Y channels.
+     */
+    if (mask & WRITEMASK_X) {
+	/* X' = X */
+	brw_MOV(p,
+		dst[0],
+		retype(src0[0], BRW_REGISTER_TYPE_W));
+    }
+
+    if (mask & WRITEMASK_Y) {
+	/* Y' = height - 1 - Y */
+	brw_ADD(p,
+		dst[1],
+		negate(retype(src0[1], BRW_REGISTER_TYPE_W)),
+		brw_imm_d(c->key.drawable_height - 1));
+    }
+}
+
+/* TODO
+   BIAS on SIMD8 not working yet...
+ */	
+static void emit_txb(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg dst[4], src[4], payload_reg;
+    /* Note: tex_unit was already looked up through SamplerTextures[] */
+    const GLuint unit = inst->tex_unit;
+    GLuint i;
+    GLuint msg_type;
+
+    assert(unit < BRW_MAX_TEX_UNIT);
+
+    payload_reg = get_reg(c, TGSI_FILE_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
+
+    for (i = 0; i < 4; i++) 
+	dst[i] = get_dst_reg(c, inst, i);
+    for (i = 0; i < 4; i++)
+	src[i] = get_src_reg(c, inst, 0, i);
+
+    switch (inst->tex_target) {
+	case TEXTURE_1D_INDEX:
+	    brw_MOV(p, brw_message_reg(2), src[0]);         /* s coord */
+	    brw_MOV(p, brw_message_reg(3), brw_imm_f(0));   /* t coord */
+	    brw_MOV(p, brw_message_reg(4), brw_imm_f(0));   /* r coord */
+	    break;
+	case TEXTURE_2D_INDEX:
+	case TEXTURE_RECT_INDEX:
+	    brw_MOV(p, brw_message_reg(2), src[0]);
+	    brw_MOV(p, brw_message_reg(3), src[1]);
+	    brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
+	    break;
+	case TEXTURE_3D_INDEX:
+	case TEXTURE_CUBE_INDEX:
+	    brw_MOV(p, brw_message_reg(2), src[0]);
+	    brw_MOV(p, brw_message_reg(3), src[1]);
+	    brw_MOV(p, brw_message_reg(4), src[2]);
+	    break;
+	default:
+            /* invalid target */
+            abort();
+    }
+    brw_MOV(p, brw_message_reg(5), src[3]);          /* bias */
+    brw_MOV(p, brw_message_reg(6), brw_imm_f(0));    /* ref (unused?) */
+
+    if (BRW_IS_IGDNG(p->brw)) {
+        msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_BIAS_IGDNG;
+    } else {
+        /* Does it work well on SIMD8? */
+        msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
+    }
+
+    brw_SAMPLE(p,
+               retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),  /* dest */
+               1,                                           /* msg_reg_nr */
+               retype(payload_reg, BRW_REGISTER_TYPE_UW),   /* src0 */
+               SURF_INDEX_TEXTURE(unit),
+               unit,                                        /* sampler */
+               inst->DstReg.WriteMask,                      /* writemask */
+               msg_type,                                    /* msg_type */
+               4,                                           /* response_length */
+               4,                                           /* msg_length */
+               0,                                           /* eot */
+               1,
+               BRW_SAMPLER_SIMD_MODE_SIMD8);	
+}
+
+
+static void emit_tex(struct brw_wm_compile *c,
+                     const struct brw_fp_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg dst[4], src[4], payload_reg;
+    /* Note: tex_unit was already looked up through SamplerTextures[] */
+    const GLuint unit = inst->tex_unit;
+    GLuint msg_len;
+    GLuint i, nr;
+    GLuint emit;
+    GLboolean shadow = (c->key.shadowtex_mask & (1<<unit)) ? 1 : 0;
+    GLuint msg_type;
+
+    assert(unit < BRW_MAX_TEX_UNIT);
+
+    payload_reg = get_reg(c, TGSI_FILE_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
+
+    for (i = 0; i < 4; i++) 
+	dst[i] = get_dst_reg(c, inst, i);
+    for (i = 0; i < 4; i++)
+	src[i] = get_src_reg(c, inst, 0, i);
+
+    switch (inst->tex_target) {
+	case TEXTURE_1D_INDEX:
+	    emit = WRITEMASK_X;
+	    nr = 1;
+	    break;
+	case TEXTURE_2D_INDEX:
+	case TEXTURE_RECT_INDEX:
+	    emit = WRITEMASK_XY;
+	    nr = 2;
+	    break;
+	case TEXTURE_3D_INDEX:
+	case TEXTURE_CUBE_INDEX:
+	    emit = WRITEMASK_XYZ;
+	    nr = 3;
+	    break;
+	default:
+           /* invalid target */
+           abort();
+    }
+    msg_len = 1;
+
+    /* move/load S, T, R coords */
+    for (i = 0; i < nr; i++) {
+	static const GLuint swz[4] = {0,1,2,2};
+	if (emit & (1<<i))
+	    brw_MOV(p, brw_message_reg(msg_len+1), src[swz[i]]);
+	else
+	    brw_MOV(p, brw_message_reg(msg_len+1), brw_imm_f(0));
+	msg_len += 1;
+    }
+
+    if (shadow) {
+       brw_MOV(p, brw_message_reg(5), brw_imm_f(0));  /* lod / bias */
+       brw_MOV(p, brw_message_reg(6), src[2]);        /* ref value / R coord */
+    }
+
+    if (BRW_IS_IGDNG(p->brw)) {
+        if (shadow)
+            msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_COMPARE_IGDNG;
+        else
+            msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_IGDNG;
+    } else {
+        /* Does it work for shadow on SIMD8 ? */
+        msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE;
+    }
+    
+    brw_SAMPLE(p,
+               retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW), /* dest */
+               1,                                          /* msg_reg_nr */
+               retype(payload_reg, BRW_REGISTER_TYPE_UW),  /* src0 */
+               SURF_INDEX_TEXTURE(unit),
+               unit,                                       /* sampler */
+               inst->DstReg.WriteMask,                     /* writemask */
+               msg_type,                                   /* msg_type */
+               4,                                          /* response_length */
+               shadow ? 6 : 4,                             /* msg_length */
+               0,                                          /* eot */
+               1,
+               BRW_SAMPLER_SIMD_MODE_SIMD8);	
+
+    if (shadow)
+	brw_MOV(p, dst[3], brw_imm_f(1.0));
+}
+
+
+/**
+ * Resolve subroutine calls after code emit is done.
+ */
+static void post_wm_emit( struct brw_wm_compile *c )
+{
+    brw_resolve_cals(&c->func);
+}
+
+static void
+get_argument_regs(struct brw_wm_compile *c,
+		  const struct brw_fp_instruction *inst,
+		  int index,
+		  struct brw_reg *regs,
+		  int mask)
+{
+    int i;
+
+    for (i = 0; i < 4; i++) {
+	if (mask & (1 << i))
+	    regs[i] = get_src_reg(c, inst, index, i);
+    }
+}
+
+static void brw_wm_emit_branching_shader(struct brw_context *brw, struct brw_wm_compile *c)
+{
+#define MAX_IF_DEPTH 32
+#define MAX_LOOP_DEPTH 32
+    struct brw_instruction *if_inst[MAX_IF_DEPTH], *loop_inst[MAX_LOOP_DEPTH];
+    GLuint i, if_depth = 0, loop_depth = 0;
+    struct brw_compile *p = &c->func;
+    struct brw_indirect stack_index = brw_indirect(0, 0);
+
+    c->out_of_regs = GL_FALSE;
+
+    prealloc_reg(c);
+    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+    brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack));
+
+    for (i = 0; i < c->nr_fp_insns; i++) {
+        const struct brw_fp_instruction *inst = &c->fp_instructions[i];
+	int dst_flags;
+	struct brw_reg args[3][4], dst[4];
+	int j;
+
+        c->cur_inst = i;
+
+#if 0
+        debug_printf("Inst %d: ", i);
+        _mesa_print_instruction(inst);
+#endif
+
+        /* fetch any constants that this instruction needs */
+        if (c->fp->use_const_buffer)
+           fetch_constants(c, inst);
+
+	if (inst->CondUpdate)
+	    brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+	else
+	    brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE);
+
+	dst_flags = inst->DstReg.WriteMask;
+	if (inst->SaturateMode == SATURATE_ZERO_ONE)
+	    dst_flags |= SATURATE;
+
+	switch (inst->Opcode) {
+	    case WM_PIXELXY:
+		emit_pixel_xy(c, inst);
+		break;
+	    case WM_DELTAXY: 
+		emit_delta_xy(c, inst);
+		break;
+	    case WM_PIXELW:
+		emit_pixel_w(c, inst);
+		break;	
+	    case WM_LINTERP:
+		emit_linterp(c, inst);
+		break;
+	    case WM_PINTERP:
+		emit_pinterp(c, inst);
+		break;
+	    case WM_CINTERP:
+		emit_cinterp(c, inst);
+		break;
+	    case WM_WPOSXY:
+		emit_wpos_xy(c, inst);
+		break;
+	    case WM_FB_WRITE:
+		emit_fb_write(c, inst);
+		break;
+	    case WM_FRONTFACING:
+		emit_frontfacing(c, inst);
+		break;
+	    case OPCODE_ADD:
+		emit_add(c, inst);
+		break;
+	    case OPCODE_ARL:
+		emit_arl(c, inst);
+		break;
+	    case OPCODE_FRC:
+		emit_frc(c, inst);
+		break;
+	    case OPCODE_FLR:
+		emit_flr(c, inst);
+		break;
+	    case OPCODE_LRP:
+		emit_lrp(c, inst);
+		break;
+	    case OPCODE_TRUNC:
+		emit_trunc(c, inst);
+		break;
+	    case OPCODE_MOV:
+		emit_mov(c, inst);
+		break;
+	    case OPCODE_DP3:
+		emit_dp3(c, inst);
+		break;
+	    case OPCODE_DP4:
+		emit_dp4(c, inst);
+		break;
+	    case OPCODE_XPD:
+		emit_xpd(c, inst);
+		break;
+	    case OPCODE_DPH:
+		emit_dph(c, inst);
+		break;
+	    case OPCODE_RCP:
+		emit_rcp(c, inst);
+		break;
+	    case OPCODE_RSQ:
+		emit_rsq(c, inst);
+		break;
+	    case OPCODE_SIN:
+		emit_sin(c, inst);
+		break;
+	    case OPCODE_COS:
+		emit_cos(c, inst);
+		break;
+	    case OPCODE_EX2:
+		emit_ex2(c, inst);
+		break;
+	    case OPCODE_LG2:
+		emit_lg2(c, inst);
+		break;
+	    case OPCODE_MIN:	
+	    case OPCODE_MAX:	
+		emit_min_max(c, inst);
+		break;
+	    case OPCODE_DDX:
+	    case OPCODE_DDY:
+		for (j = 0; j < 4; j++) {
+		    if (inst->DstReg.WriteMask & (1 << j))
+			dst[j] = get_dst_reg(c, inst, j);
+		    else
+			dst[j] = brw_null_reg();
+		}
+		get_argument_regs(c, inst, 0, args[0], WRITEMASK_XYZW);
+		emit_ddxy(p, dst, dst_flags, (inst->Opcode == OPCODE_DDX),
+			  args[0]);
+                break;
+	    case OPCODE_SLT:
+		emit_slt(c, inst);
+		break;
+	    case OPCODE_SLE:
+		emit_sle(c, inst);
+		break;
+	    case OPCODE_SGT:
+		emit_sgt(c, inst);
+		break;
+	    case OPCODE_SGE:
+		emit_sge(c, inst);
+		break;
+	    case OPCODE_SEQ:
+		emit_seq(c, inst);
+		break;
+	    case OPCODE_SNE:
+		emit_sne(c, inst);
+		break;
+	    case OPCODE_MUL:
+		emit_mul(c, inst);
+		break;
+	    case OPCODE_POW:
+		emit_pow(c, inst);
+		break;
+	    case OPCODE_MAD:
+		emit_mad(c, inst);
+		break;
+	    case OPCODE_TEX:
+		emit_tex(c, inst);
+		break;
+	    case OPCODE_TXB:
+		emit_txb(c, inst);
+		break;
+	    case OPCODE_KIL_NV:
+		emit_kil(c);
+		break;
+	    case OPCODE_IF:
+		assert(if_depth < MAX_IF_DEPTH);
+		if_inst[if_depth++] = brw_IF(p, BRW_EXECUTE_8);
+		break;
+	    case OPCODE_ELSE:
+		if_inst[if_depth-1]  = brw_ELSE(p, if_inst[if_depth-1]);
+		break;
+	    case OPCODE_ENDIF:
+		assert(if_depth > 0);
+		brw_ENDIF(p, if_inst[--if_depth]);
+		break;
+	    case OPCODE_BGNSUB:
+		brw_save_label(p, inst->Comment, p->nr_insn);
+		break;
+	    case OPCODE_ENDSUB:
+		/* no-op */
+		break;
+	    case OPCODE_CAL: 
+		brw_push_insn_state(p);
+		brw_set_mask_control(p, BRW_MASK_DISABLE);
+                brw_set_access_mode(p, BRW_ALIGN_1);
+                brw_ADD(p, deref_1ud(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
+                brw_set_access_mode(p, BRW_ALIGN_16);
+                brw_ADD(p, get_addr_reg(stack_index),
+                         get_addr_reg(stack_index), brw_imm_d(4));
+		brw_save_call(&c->func, inst->label, p->nr_insn);
+                brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+                brw_pop_insn_state(p);
+		break;
+
+	    case OPCODE_RET:
+		brw_push_insn_state(p);
+		brw_set_mask_control(p, BRW_MASK_DISABLE);
+                brw_ADD(p, get_addr_reg(stack_index),
+                        get_addr_reg(stack_index), brw_imm_d(-4));
+                brw_set_access_mode(p, BRW_ALIGN_1);
+                brw_MOV(p, brw_ip_reg(), deref_1ud(stack_index, 0));
+                brw_set_access_mode(p, BRW_ALIGN_16);
+		brw_pop_insn_state(p);
+
+		break;
+	    case OPCODE_BGNLOOP:
+                /* XXX may need to invalidate the current_constant regs */
+		loop_inst[loop_depth++] = brw_DO(p, BRW_EXECUTE_8);
+		break;
+	    case OPCODE_BRK:
+		brw_BREAK(p);
+		brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+		break;
+	    case OPCODE_CONT:
+		brw_CONT(p);
+		brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+		break;
+	    case OPCODE_ENDLOOP: 
+               {
+                  struct brw_instruction *inst0, *inst1;
+                  GLuint br = 1;
+
+                  if (BRW_IS_IGDNG(brw))
+                     br = 2;
+ 
+                  loop_depth--;
+                  inst0 = inst1 = brw_WHILE(p, loop_inst[loop_depth]);
+                  /* patch all the BREAK/CONT instructions from last BGNLOOP */
+                  while (inst0 > loop_inst[loop_depth]) {
+                     inst0--;
+                     if (inst0->header.opcode == BRW_OPCODE_BREAK) {
+			inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
+			inst0->bits3.if_else.pop_count = 0;
+                     }
+                     else if (inst0->header.opcode == BRW_OPCODE_CONTINUE) {
+                        inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
+                        inst0->bits3.if_else.pop_count = 0;
+                     }
+                  }
+               }
+               break;
+	    default:
+		debug_printf("unsupported IR in fragment shader %d\n",
+			inst->Opcode);
+	}
+
+	if (inst->CondUpdate)
+	    brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+	else
+	    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+    }
+    post_wm_emit(c);
+
+    if (BRW_DEBUG & DEBUG_WM) {
+      debug_printf("wm-native:\n");
+      brw_disasm(stderr, p->store, p->nr_insn);
+    }
+}
+
+/**
+ * Do GPU code generation for shaders that use GLSL features such as
+ * flow control.  Other shaders will be compiled with the 
+ */
+void brw_wm_branching_shader_emit(struct brw_context *brw, struct brw_wm_compile *c)
+{
+    if (BRW_DEBUG & DEBUG_WM) {
+       debug_printf("%s:\n", __FUNCTION__);
+    }
+
+    /* initial instruction translation/simplification */
+    brw_wm_pass_fp(c);
+
+    /* actual code generation */
+    brw_wm_emit_branching_shader(brw, c);
+
+    if (BRW_DEBUG & DEBUG_WM) {
+        brw_wm_print_program(c, "brw_wm_branching_shader_emit done");
+    }
+
+    c->prog_data.total_grf = num_grf_used(c);
+    c->prog_data.total_scratch = 0;
+}
diff --git a/src/gallium/drivers/i965/brw_wm_iz.c b/src/gallium/drivers/i965/brw_wm_iz.c
new file mode 100644
index 0000000..6f1e9fc
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_wm_iz.c
@@ -0,0 +1,156 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+                
+
+#include "brw_wm.h"
+
+
+#undef P			/* prompted depth */
+#undef C			/* computed */
+#undef N			/* non-promoted? */
+
+#define P 0
+#define C 1
+#define N 2
+
+const struct {
+   GLuint mode:2;
+   GLuint sd_present:1;
+   GLuint sd_to_rt:1;
+   GLuint dd_present:1;
+   GLuint ds_present:1;
+} wm_iz_table[IZ_BIT_MAX] =
+{
+ { P, 0, 0, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { N, 1, 1, 0, 0 }, 
+ { N, 0, 1, 0, 0 }, 
+ { N, 0, 1, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { C, 0, 1, 1, 0 }, 
+ { C, 0, 1, 1, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { N, 1, 1, 0, 0 }, 
+ { C, 0, 1, 1, 0 }, 
+ { C, 0, 1, 1, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { N, 1, 1, 0, 0 }, 
+ { N, 0, 1, 0, 0 }, 
+ { N, 0, 1, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { C, 0, 1, 1, 0 }, 
+ { C, 0, 1, 1, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { N, 1, 1, 0, 0 }, 
+ { C, 0, 1, 1, 0 }, 
+ { C, 0, 1, 1, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { N, 1, 1, 0, 1 }, 
+ { N, 0, 1, 0, 1 }, 
+ { N, 0, 1, 0, 1 }, 
+ { P, 0, 0, 0, 0 }, 
+ { P, 0, 0, 0, 0 }, 
+ { C, 0, 1, 1, 1 }, 
+ { C, 0, 1, 1, 1 }, 
+ { P, 0, 0, 0, 0 }, 
+ { N, 1, 1, 0, 1 }, 
+ { C, 0, 1, 1, 1 }, 
+ { C, 0, 1, 1, 1 }, 
+ { P, 0, 0, 0, 0 }, 
+ { C, 0, 0, 0, 1 }, 
+ { P, 0, 0, 0, 0 }, 
+ { C, 0, 1, 0, 1 }, 
+ { P, 0, 0, 0, 0 }, 
+ { C, 1, 1, 0, 1 }, 
+ { C, 0, 1, 0, 1 }, 
+ { C, 0, 1, 0, 1 }, 
+ { P, 0, 0, 0, 0 }, 
+ { C, 1, 1, 1, 1 }, 
+ { C, 0, 1, 1, 1 }, 
+ { C, 0, 1, 1, 1 }, 
+ { P, 0, 0, 0, 0 }, 
+ { C, 1, 1, 1, 1 }, 
+ { C, 0, 1, 1, 1 }, 
+ { C, 0, 1, 1, 1 } 
+};
+
+/**
+ * \param line_aa  AA_NEVER, AA_ALWAYS or AA_SOMETIMES
+ * \param lookup  bitmask of IZ_* flags
+ */
+void brw_wm_lookup_iz( GLuint line_aa,
+		       GLuint lookup,
+		       GLboolean ps_uses_depth,
+		       struct brw_wm_prog_key *key )
+{
+   GLuint reg = 2;
+
+   assert (lookup < IZ_BIT_MAX);
+      
+   if (lookup & IZ_PS_COMPUTES_DEPTH_BIT)
+      key->computes_depth = 1;
+
+   if (wm_iz_table[lookup].sd_present || ps_uses_depth) {
+      key->source_depth_reg = reg;
+      reg += 2;
+   }
+
+   if (wm_iz_table[lookup].sd_to_rt)
+      key->source_depth_to_render_target = 1;
+
+   if (wm_iz_table[lookup].ds_present || line_aa != AA_NEVER) {
+      key->aa_dest_stencil_reg = reg;
+      key->runtime_check_aads_emit = (!wm_iz_table[lookup].ds_present &&
+				      line_aa == AA_SOMETIMES);
+      reg++;
+   }
+
+   if (wm_iz_table[lookup].dd_present) {
+      key->dest_depth_reg = reg;
+      reg+=2;
+   }
+
+   key->nr_depth_regs = (reg+1)/2;
+}
+
diff --git a/src/gallium/drivers/i965/brw_wm_pass0.c b/src/gallium/drivers/i965/brw_wm_pass0.c
new file mode 100644
index 0000000..0bacad2
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_wm_pass0.c
@@ -0,0 +1,366 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "brw_debug.h"
+#include "brw_wm.h"
+
+
+
+/***********************************************************************
+ */
+
+static struct brw_wm_ref *get_ref( struct brw_wm_compile *c )
+{
+   assert(c->nr_refs < BRW_WM_MAX_REF);
+   return &c->refs[c->nr_refs++];
+}
+
+static struct brw_wm_value *get_value( struct brw_wm_compile *c)
+{
+   assert(c->nr_refs < BRW_WM_MAX_VREG);
+   return &c->vreg[c->nr_vreg++];
+}
+
+/** return pointer to a newly allocated instruction */
+static struct brw_wm_instruction *get_instruction( struct brw_wm_compile *c )
+{
+   assert(c->nr_insns < BRW_WM_MAX_INSN);
+   return &c->instruction[c->nr_insns++];
+}
+
+/***********************************************************************
+ */
+
+/** Init the "undef" register */
+static void pass0_init_undef( struct brw_wm_compile *c)
+{
+   struct brw_wm_ref *ref = &c->undef_ref;
+   ref->value = &c->undef_value;
+   ref->hw_reg = brw_vec8_grf(0, 0);
+   ref->insn = 0;
+   ref->prevuse = NULL;
+}
+
+/** Set a FP register to a value */
+static void pass0_set_fpreg_value( struct brw_wm_compile *c,
+				   GLuint file,
+				   GLuint idx,
+				   GLuint component,
+				   struct brw_wm_value *value )
+{
+   struct brw_wm_ref *ref = get_ref(c);
+   ref->value = value;
+   ref->hw_reg = brw_vec8_grf(0, 0);
+   ref->insn = 0;
+   ref->prevuse = NULL;
+   c->pass0_fp_reg[file][idx][component] = ref;
+}
+
+/** Set a FP register to a ref */
+static void pass0_set_fpreg_ref( struct brw_wm_compile *c,
+				 GLuint file,
+				 GLuint idx,
+				 GLuint component,
+				 const struct brw_wm_ref *src_ref )
+{
+   c->pass0_fp_reg[file][idx][component] = src_ref;
+}
+
+static const struct brw_wm_ref *get_param_ref( struct brw_wm_compile *c, 
+					       unsigned idx,
+                                               unsigned component)
+{
+   GLuint i = idx * 4 + component;
+   
+   if (i >= BRW_WM_MAX_PARAM) {
+      debug_printf("%s: out of params\n", __FUNCTION__);
+      c->prog_data.error = 1;
+      return NULL;
+   }
+   else {
+      struct brw_wm_ref *ref = get_ref(c);
+
+      c->nr_creg = MAX2(c->nr_creg, (i+16)/16);
+
+      /* Push the offsets into hw_reg.  These will be added to the
+       * real register numbers once one is allocated in pass2.
+       */
+      ref->hw_reg = brw_vec1_grf((i&8)?1:0, i%8);
+      ref->value = &c->creg[i/16];
+      ref->insn = 0;
+      ref->prevuse = NULL;
+
+      return ref;
+   }
+}
+
+
+
+
+/* Lookup our internal registers
+ */
+static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
+					       GLuint file,
+					       GLuint idx,
+					       GLuint component )
+{
+   const struct brw_wm_ref *ref = c->pass0_fp_reg[file][idx][component];
+
+   if (!ref) {
+      switch (file) {
+      case TGSI_FILE_INPUT:
+      case TGSI_FILE_TEMPORARY:
+      case TGSI_FILE_OUTPUT:
+      case BRW_FILE_PAYLOAD:
+	 /* should already be done?? */
+	 break;
+
+      case TGSI_FILE_CONSTANT:
+	 ref = get_param_ref(c, 
+                             c->fp->info.immediate_count + idx,
+                             component);
+	 break;
+
+      case TGSI_FILE_IMMEDIATE:
+	 ref = get_param_ref(c, 
+                             idx,
+                             component);
+	 break;
+
+      default:
+	 assert(0);
+	 break;
+      }
+
+      c->pass0_fp_reg[file][idx][component] = ref;
+   }
+
+   if (!ref)
+      ref = &c->undef_ref;
+
+   return ref;
+}
+
+
+
+/***********************************************************************
+ * Straight translation to internal instruction format
+ */
+
+static void pass0_set_dst( struct brw_wm_compile *c,
+			   struct brw_wm_instruction *out,
+			   const struct brw_fp_instruction *inst,
+			   GLuint writemask )
+{
+   const struct brw_fp_dst dst = inst->dst;
+   GLuint i;
+
+   for (i = 0; i < 4; i++) {
+      if (writemask & (1<<i)) {
+	 out->dst[i] = get_value(c);
+	 pass0_set_fpreg_value(c, dst.file, dst.index, i, out->dst[i]);
+      }
+   }
+
+   out->writemask = writemask;
+}
+
+
+static const struct brw_wm_ref *get_fp_src_reg_ref( struct brw_wm_compile *c,
+						    struct brw_fp_src src,
+						    GLuint i )
+{
+   return pass0_get_reg(c, src.file, src.index, BRW_GET_SWZ(src.swizzle,i));
+}
+
+
+static struct brw_wm_ref *get_new_ref( struct brw_wm_compile *c,
+				       struct brw_fp_src src,
+				       GLuint i,
+				       struct brw_wm_instruction *insn)
+{
+   const struct brw_wm_ref *ref = get_fp_src_reg_ref(c, src, i);
+   struct brw_wm_ref *newref = get_ref(c);
+
+   newref->value = ref->value;
+   newref->hw_reg = ref->hw_reg;
+
+   if (insn) {
+      newref->insn = insn - c->instruction;
+      newref->prevuse = newref->value->lastuse;
+      newref->value->lastuse = newref;
+   }
+
+   if (src.negate)
+      newref->hw_reg.negate ^= 1;
+
+   if (src.abs) {
+      newref->hw_reg.negate = 0;
+      newref->hw_reg.abs = 1;
+   }
+
+   return newref;
+}
+
+
+static void
+translate_insn(struct brw_wm_compile *c,
+               const struct brw_fp_instruction *inst)
+{
+   struct brw_wm_instruction *out = get_instruction(c);
+   GLuint writemask = inst->dst.writemask;
+   GLuint nr_args = brw_wm_nr_args(inst->opcode);
+   GLuint i, j;
+
+   /* Copy some data out of the instruction
+    */
+   out->opcode = inst->opcode;
+   out->saturate = inst->dst.saturate;
+   out->tex_unit = inst->tex_unit;
+   out->target = inst->target;
+
+   /* Nasty hack:
+    */
+   out->eot = (inst->opcode == WM_FB_WRITE &&
+               inst->tex_unit != 0);
+
+
+   /* Args:
+    */
+   for (i = 0; i < nr_args; i++) {
+      for (j = 0; j < 4; j++) {
+	 out->src[i][j] = get_new_ref(c, inst->src[i], j, out);
+      }
+   }
+
+   /* Dst:
+    */
+   pass0_set_dst(c, out, inst, writemask);
+}
+
+
+
+/***********************************************************************
+ * Optimize moves and swizzles away:
+ */ 
+static void pass0_precalc_mov( struct brw_wm_compile *c,
+			       const struct brw_fp_instruction *inst )
+{
+   const struct brw_fp_dst dst = inst->dst;
+   GLuint writemask = dst.writemask;
+   struct brw_wm_ref *refs[4];
+   GLuint i;
+
+   /* Get the effect of a MOV by manipulating our register table:
+    * First get all refs, then assign refs.  This ensures that "in-place"
+    * swizzles such as:
+    *   MOV t, t.xxyx
+    * are handled correctly.  Previously, these two steps were done in
+    * one loop and the above case was incorrectly handled.
+    */
+   for (i = 0; i < 4; i++) {
+      refs[i] = get_new_ref(c, inst->src[0], i, NULL);
+   }
+   for (i = 0; i < 4; i++) {
+      if (writemask & (1 << i)) {	    
+         pass0_set_fpreg_ref( c, dst.file, dst.index, i, refs[i]);
+      }
+   }
+}
+
+
+/* Initialize payload "registers".
+ */
+static void pass0_init_payload( struct brw_wm_compile *c )
+{
+   GLuint i;
+
+   for (i = 0; i < 4; i++) {
+      GLuint j = i >= c->key.nr_depth_regs ? 0 : i;
+      pass0_set_fpreg_value( c, BRW_FILE_PAYLOAD, PAYLOAD_DEPTH, i, 
+			     &c->payload.depth[j] );
+   }
+
+   for (i = 0; i < c->key.nr_inputs; i++)
+      pass0_set_fpreg_value( c, BRW_FILE_PAYLOAD, i, 0, 
+			     &c->payload.input_interp[i] );      
+}
+
+
+/***********************************************************************
+ * PASS 0
+ *
+ * Work forwards to give each calculated value a unique number.  Where
+ * an instruction produces duplicate values (eg DP3), all are given
+ * the same number.
+ *
+ * Translate away swizzling and eliminate non-saturating moves.
+ *
+ * Translate instructions from our fp_instruction structs to our
+ * internal brw_wm_instruction representation.
+ */
+void brw_wm_pass0( struct brw_wm_compile *c )
+{
+   GLuint insn;
+
+   c->nr_vreg = 0;
+   c->nr_insns = 0;
+
+   pass0_init_undef(c);
+   pass0_init_payload(c);
+
+   for (insn = 0; insn < c->nr_fp_insns; insn++) {
+      const struct brw_fp_instruction *inst = &c->fp_instructions[insn];
+
+      /* Optimize away moves, otherwise emit translated instruction:
+       */      
+      switch (inst->opcode) {
+      case TGSI_OPCODE_MOV: 
+	 if (!inst->dst.saturate) {
+	    pass0_precalc_mov(c, inst);
+	 }
+	 else {
+	    translate_insn(c, inst);
+	 }
+	 break;
+      default:
+	 translate_insn(c, inst);
+	 break;
+      }
+   }
+ 
+   if (BRW_DEBUG & DEBUG_WM) {
+      brw_wm_print_program(c, "pass0");
+   }
+}
diff --git a/src/gallium/drivers/i965/brw_wm_pass1.c b/src/gallium/drivers/i965/brw_wm_pass1.c
new file mode 100644
index 0000000..005747f
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_wm_pass1.c
@@ -0,0 +1,292 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+                  
+
+#include "brw_wm.h"
+#include "brw_debug.h"
+
+
+static GLuint get_tracked_mask(struct brw_wm_compile *c,
+			       struct brw_wm_instruction *inst)
+{
+   GLuint i;
+   for (i = 0; i < 4; i++) {
+      if (inst->writemask & (1<<i)) {
+	 if (!inst->dst[i]->contributes_to_output) {
+	    inst->writemask &= ~(1<<i);
+	    inst->dst[i] = 0;
+	 }
+      }
+   }
+
+   return inst->writemask;
+}
+
+/* Remove a reference from a value's usage chain.
+ */
+static void unlink_ref(struct brw_wm_ref *ref)
+{
+   struct brw_wm_value *value = ref->value;
+
+   if (ref == value->lastuse) {
+      value->lastuse = ref->prevuse;
+   }
+   else {
+      struct brw_wm_ref *i = value->lastuse;
+      while (i->prevuse != ref) i = i->prevuse;
+      i->prevuse = ref->prevuse;
+   }
+}
+
+static void track_arg(struct brw_wm_compile *c,
+		      struct brw_wm_instruction *inst,
+		      GLuint arg,
+		      GLuint readmask)
+{
+   GLuint i;
+
+   for (i = 0; i < 4; i++) {
+      struct brw_wm_ref *ref = inst->src[arg][i];
+      if (ref) {
+	 if (readmask & (1<<i)) {
+	    ref->value->contributes_to_output = 1;
+         }
+	 else {
+	    unlink_ref(ref);
+	    inst->src[arg][i] = NULL;
+	 }
+      }
+   }
+}
+
+static GLuint get_texcoord_mask( GLuint tex_idx )
+{
+   switch (tex_idx) {
+   case TGSI_TEXTURE_1D:
+      return BRW_WRITEMASK_X;
+   case TGSI_TEXTURE_2D:
+   case TGSI_TEXTURE_RECT:
+      return BRW_WRITEMASK_XY;
+   case TGSI_TEXTURE_3D:
+      return BRW_WRITEMASK_XYZ;
+   case TGSI_TEXTURE_CUBE:
+      return BRW_WRITEMASK_XYZ;
+
+   case TGSI_TEXTURE_SHADOW1D:
+      return BRW_WRITEMASK_XZ;
+   case TGSI_TEXTURE_SHADOW2D:
+   case TGSI_TEXTURE_SHADOWRECT:
+      return BRW_WRITEMASK_XYZ;
+   default: 
+      assert(0);
+      return 0;
+   }
+}
+
+
+/* Step two: Basically this is dead code elimination.  
+ *
+ * Iterate backwards over instructions, noting which values
+ * contribute to the final result.  Adjust writemasks to only
+ * calculate these values.
+ */
+void brw_wm_pass1( struct brw_wm_compile *c )
+{
+   GLint insn;
+
+   for (insn = c->nr_insns-1; insn >= 0; insn--) {
+      struct brw_wm_instruction *inst = &c->instruction[insn];
+      GLuint writemask;
+      GLuint read0, read1, read2;
+
+      if (inst->opcode == TGSI_OPCODE_KIL) {
+	 track_arg(c, inst, 0, BRW_WRITEMASK_XYZW); /* All args contribute to final */
+	 continue;
+      }
+
+      if (inst->opcode == WM_FB_WRITE) {
+	 track_arg(c, inst, 0, BRW_WRITEMASK_XYZW); 
+	 track_arg(c, inst, 1, BRW_WRITEMASK_XYZW); 
+	 if (c->key.source_depth_to_render_target &&
+	     c->key.computes_depth)
+	    track_arg(c, inst, 2, BRW_WRITEMASK_Z); 
+	 else
+	    track_arg(c, inst, 2, 0); 
+	 continue;
+      }
+
+      /* Lookup all the registers which were written by this
+       * instruction and get a mask of those that contribute to the output:
+       */
+      writemask = get_tracked_mask(c, inst);
+      if (!writemask) {
+	 GLuint arg;
+	 for (arg = 0; arg < 3; arg++)
+	    track_arg(c, inst, arg, 0);
+	 continue;
+      }
+
+      read0 = 0;
+      read1 = 0;
+      read2 = 0;
+
+      /* Mark all inputs which contribute to the marked outputs:
+       */
+      switch (inst->opcode) {
+      case TGSI_OPCODE_ABS:
+      case TGSI_OPCODE_FLR:
+      case TGSI_OPCODE_FRC:
+      case TGSI_OPCODE_MOV:
+      case TGSI_OPCODE_TRUNC:
+	 read0 = writemask;
+	 break;
+
+      case TGSI_OPCODE_SUB:
+      case TGSI_OPCODE_SLT:
+      case TGSI_OPCODE_SLE:
+      case TGSI_OPCODE_SGE:
+      case TGSI_OPCODE_SGT:
+      case TGSI_OPCODE_SEQ:
+      case TGSI_OPCODE_SNE:
+      case TGSI_OPCODE_ADD:
+      case TGSI_OPCODE_MAX:
+      case TGSI_OPCODE_MIN:
+      case TGSI_OPCODE_MUL:
+	 read0 = writemask;
+	 read1 = writemask;
+	 break;
+
+      case TGSI_OPCODE_DDX:
+      case TGSI_OPCODE_DDY:
+	 read0 = writemask;
+	 break;
+
+      case TGSI_OPCODE_MAD:	
+      case TGSI_OPCODE_CMP:
+      case TGSI_OPCODE_LRP:
+	 read0 = writemask;
+	 read1 = writemask;	
+	 read2 = writemask;	
+	 break;
+
+      case TGSI_OPCODE_XPD: 
+	 if (writemask & BRW_WRITEMASK_X) read0 |= BRW_WRITEMASK_YZ;	 
+	 if (writemask & BRW_WRITEMASK_Y) read0 |= BRW_WRITEMASK_XZ;	 
+	 if (writemask & BRW_WRITEMASK_Z) read0 |= BRW_WRITEMASK_XY;
+	 read1 = read0;
+	 break;
+
+      case TGSI_OPCODE_COS:
+      case TGSI_OPCODE_EX2:
+      case TGSI_OPCODE_LG2:
+      case TGSI_OPCODE_RCP:
+      case TGSI_OPCODE_RSQ:
+      case TGSI_OPCODE_SIN:
+      case TGSI_OPCODE_SCS:
+      case WM_CINTERP:
+      case WM_PIXELXY:
+	 read0 = BRW_WRITEMASK_X;
+	 break;
+
+      case TGSI_OPCODE_POW:
+	 read0 = BRW_WRITEMASK_X;
+	 read1 = BRW_WRITEMASK_X;
+	 break;
+
+      case TGSI_OPCODE_TEX:
+      case TGSI_OPCODE_TXP:
+	 read0 = get_texcoord_mask(inst->target);
+	 break;
+
+      case TGSI_OPCODE_TXB:
+	 read0 = get_texcoord_mask(inst->target) | BRW_WRITEMASK_W;
+	 break;
+
+      case WM_WPOSXY:
+	 read0 = writemask & BRW_WRITEMASK_XY;
+	 break;
+
+      case WM_DELTAXY:
+	 read0 = writemask & BRW_WRITEMASK_XY;
+	 read1 = BRW_WRITEMASK_X;
+	 break;
+
+      case WM_PIXELW:
+	 read0 = BRW_WRITEMASK_X;
+	 read1 = BRW_WRITEMASK_XY;
+	 break;
+
+      case WM_LINTERP:
+	 read0 = BRW_WRITEMASK_X;
+	 read1 = BRW_WRITEMASK_XY;
+	 break;
+
+      case WM_PINTERP:
+	 read0 = BRW_WRITEMASK_X; /* interpolant */
+	 read1 = BRW_WRITEMASK_XY; /* deltas */
+	 read2 = BRW_WRITEMASK_W; /* pixel w */
+	 break;
+
+      case TGSI_OPCODE_DP3:	
+	 read0 = BRW_WRITEMASK_XYZ;
+	 read1 = BRW_WRITEMASK_XYZ;
+	 break;
+
+      case TGSI_OPCODE_DPH:
+	 read0 = BRW_WRITEMASK_XYZ;
+	 read1 = BRW_WRITEMASK_XYZW;
+	 break;
+
+      case TGSI_OPCODE_DP4:
+	 read0 = BRW_WRITEMASK_XYZW;
+	 read1 = BRW_WRITEMASK_XYZW;
+	 break;
+
+      case TGSI_OPCODE_LIT: 
+	 read0 = BRW_WRITEMASK_XYW;
+	 break;
+
+      case TGSI_OPCODE_DST:
+      case WM_FRONTFACING:
+      case TGSI_OPCODE_KILP:
+      default:
+	 break;
+      }
+
+      track_arg(c, inst, 0, read0);
+      track_arg(c, inst, 1, read1);
+      track_arg(c, inst, 2, read2);
+   }
+
+   if (BRW_DEBUG & DEBUG_WM) {
+      brw_wm_print_program(c, "pass1");
+   }
+}
diff --git a/src/gallium/drivers/i965/brw_wm_pass2.c b/src/gallium/drivers/i965/brw_wm_pass2.c
new file mode 100644
index 0000000..19248b4
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_wm_pass2.c
@@ -0,0 +1,334 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+                   
+
+#include "brw_debug.h"
+#include "brw_wm.h"
+
+
+/* Use these to force spilling so that that functionality can be
+ * tested with known-good examples rather than having to construct new
+ * tests.
+ */
+#define TEST_PAYLOAD_SPILLS 0
+#define TEST_DST_SPILLS 0
+
+static void spill_value(struct brw_wm_compile *c,
+			struct brw_wm_value *value);
+
+static void prealloc_reg(struct brw_wm_compile *c,
+			 struct brw_wm_value *value,
+			 GLuint reg)
+{
+   if (value->lastuse) {
+      /* Set nextuse to zero, it will be corrected by
+       * update_register_usage().
+       */
+      c->pass2_grf[reg].value = value;
+      c->pass2_grf[reg].nextuse = 0;
+
+      value->resident = &c->pass2_grf[reg];
+      value->hw_reg = brw_vec8_grf(reg*2, 0);
+
+      if (TEST_PAYLOAD_SPILLS)
+	 spill_value(c, value);
+   }
+}
+
+
+/* Initialize all the register values.  Do the initial setup
+ * calculations for interpolants.
+ */
+static void init_registers( struct brw_wm_compile *c )
+{
+   GLuint reg = 0;
+   GLuint j;
+
+   for (j = 0; j < c->grf_limit; j++) 
+      c->pass2_grf[j].nextuse = BRW_WM_MAX_INSN;
+
+   /* Pre-allocate incoming payload regs:
+    */
+   for (j = 0; j < c->key.nr_depth_regs; j++) 
+      prealloc_reg(c, &c->payload.depth[j], reg++);
+
+   for (j = 0; j < c->nr_creg; j++) 
+      prealloc_reg(c, &c->creg[j], reg++);
+
+   reg++;                       /* XXX: skip over position output */
+
+   /* XXX: currently just hope the VS outputs line up with FS inputs:
+    */
+   for (j = 0; j < c->key.nr_inputs; j++)
+      prealloc_reg(c, &c->payload.input_interp[j], reg++);
+
+   c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2;
+   c->prog_data.urb_read_length = (c->key.nr_inputs + 1) * 2;
+   c->prog_data.curb_read_length = c->nr_creg * 2;
+
+   /* Note this allocation:
+    */
+   c->max_wm_grf = reg * 2;
+}
+
+
+/* Update the nextuse value for each register in our file.
+ */
+static void update_register_usage(struct brw_wm_compile *c,
+				  GLuint thisinsn)
+{
+   GLuint i;
+
+   for (i = 1; i < c->grf_limit; i++) {
+      struct brw_wm_grf *grf = &c->pass2_grf[i];
+
+      /* Only search those which can change:
+       */
+      if (grf->nextuse < thisinsn) {
+	 const struct brw_wm_ref *ref = grf->value->lastuse;
+
+	 /* Has last use of value been passed?
+	  */
+	 if (ref->insn < thisinsn) {
+	    grf->value->resident = 0;
+	    grf->value = 0;
+	    grf->nextuse = BRW_WM_MAX_INSN;
+	 }
+	 else {
+	    /* Else loop through chain to update:
+	     */
+	    while (ref->prevuse && ref->prevuse->insn >= thisinsn)
+	       ref = ref->prevuse;
+
+	    grf->nextuse = ref->insn;
+	 }
+      }
+   }
+}
+
+
+static void spill_value(struct brw_wm_compile *c,
+			struct brw_wm_value *value)
+{	
+   /* Allocate a spill slot.  Note that allocations start from 0x40 -
+    * the first slot is reserved to mean "undef" in brw_wm_emit.c
+    */
+   if (!value->spill_slot) {
+      c->last_scratch += 0x40;	
+      value->spill_slot = c->last_scratch;
+   }
+
+   /* The spill will be done in brw_wm_emit.c immediately after the
+    * value is calculated, so we can just take this reg without any
+    * further work.
+    */
+   value->resident->value = NULL;
+   value->resident->nextuse = BRW_WM_MAX_INSN;
+   value->resident = NULL;
+}
+
+
+
+/* Search for contiguous region with the most distant nearest
+ * member.  Free regs count as very distant.
+ *
+ * TODO: implement spill-to-reg so that we can rearrange discontigous
+ * free regs and then spill the oldest non-free regs in sequence.
+ * This would mean inserting instructions in this pass.
+ */
+static GLuint search_contiguous_regs(struct brw_wm_compile *c,
+				     GLuint nr,
+				     GLuint thisinsn)
+{
+   struct brw_wm_grf *grf = c->pass2_grf;
+   GLuint furthest = 0;
+   GLuint reg = 0;
+   GLuint i, j;
+
+   /* Start search at 1: r0 is special and can't be used or spilled.
+    */
+   for (i = 1; i < c->grf_limit && furthest < BRW_WM_MAX_INSN; i++) {
+      GLuint group_nextuse = BRW_WM_MAX_INSN;
+
+      for (j = 0; j < nr; j++) {
+	 if (grf[i+j].nextuse < group_nextuse)
+	    group_nextuse = grf[i+j].nextuse;
+      }
+
+      if (group_nextuse > furthest) {
+	 furthest = group_nextuse;
+	 reg = i;
+      }
+   }
+
+   assert(furthest != thisinsn);
+
+   /* Any non-empty regs will need to be spilled:
+    */
+   for (j = 0; j < nr; j++) 
+      if (grf[reg+j].value)
+	 spill_value(c, grf[reg+j].value);
+
+   return reg;
+}
+
+
+static void alloc_contiguous_dest(struct brw_wm_compile *c, 
+				  struct brw_wm_value *dst[],
+				  GLuint nr,
+				  GLuint thisinsn)
+{
+   GLuint reg = search_contiguous_regs(c, nr, thisinsn);
+   GLuint i;
+
+   for (i = 0; i < nr; i++) {
+      if (!dst[i]) {
+	 /* Need to grab a dummy value in TEX case.  Don't introduce
+	  * it into the tracking scheme.
+	  */
+	 dst[i] = &c->vreg[c->nr_vreg++];
+      }
+      else {
+	 assert(!dst[i]->resident);
+	 assert(c->pass2_grf[reg+i].nextuse != thisinsn);
+
+	 c->pass2_grf[reg+i].value = dst[i];
+	 c->pass2_grf[reg+i].nextuse = thisinsn;
+
+	 dst[i]->resident = &c->pass2_grf[reg+i];
+      }
+
+      dst[i]->hw_reg = brw_vec8_grf((reg+i)*2, 0);
+   }
+
+   if ((reg+nr)*2 > c->max_wm_grf)
+      c->max_wm_grf = (reg+nr) * 2;
+}
+
+
+static void load_args(struct brw_wm_compile *c, 
+		      struct brw_wm_instruction *inst)
+{
+   GLuint thisinsn = inst - c->instruction;
+   GLuint i,j;
+
+   for (i = 0; i < 3; i++) {
+      for (j = 0; j < 4; j++) {
+	 struct brw_wm_ref *ref = inst->src[i][j];
+
+	 if (ref) {
+	    if (!ref->value->resident) {
+	       /* Need to bring the value in from scratch space.  The code for
+		* this will be done in brw_wm_emit.c, here we just do the
+		* register allocation and mark the ref as requiring a fill.
+		*/
+	       GLuint reg = search_contiguous_regs(c, 1, thisinsn);
+
+	       c->pass2_grf[reg].value = ref->value;
+	       c->pass2_grf[reg].nextuse = thisinsn;
+
+	       ref->value->resident = &c->pass2_grf[reg];
+
+	       /* Note that a fill is required:
+		*/
+	       ref->unspill_reg = reg*2;
+	    }
+
+	    /* Adjust the hw_reg to point at the value's current location:
+	     */
+	    assert(ref->value == ref->value->resident->value);
+	    ref->hw_reg.nr += (ref->value->resident - c->pass2_grf) * 2;
+	 }
+      }
+   }
+}
+
+
+
+/* Step 3: Work forwards once again.  Perform register allocations,
+ * taking into account instructions like TEX which require contiguous
+ * result registers.  Where necessary spill registers to scratch space
+ * and reload later.
+ */
+void brw_wm_pass2( struct brw_wm_compile *c )
+{
+   GLuint insn;
+   GLuint i;
+
+   init_registers(c);
+
+   for (insn = 0; insn < c->nr_insns; insn++) {
+      struct brw_wm_instruction *inst = &c->instruction[insn];
+
+      /* Update registers' nextuse values:
+       */
+      update_register_usage(c, insn);
+
+      /* May need to unspill some args.
+       */
+      load_args(c, inst);
+
+      /* Allocate registers to hold results:
+       */
+      switch (inst->opcode) {
+      case TGSI_OPCODE_TEX:
+      case TGSI_OPCODE_TXB:
+      case TGSI_OPCODE_TXP:
+	 alloc_contiguous_dest(c, inst->dst, 4, insn);
+	 break;
+
+      default:
+	 for (i = 0; i < 4; i++) {
+	    if (inst->writemask & (1<<i)) {
+	       assert(inst->dst[i]);
+	       alloc_contiguous_dest(c, &inst->dst[i], 1, insn);
+	    }
+	 }
+	 break;
+      }
+
+      if (TEST_DST_SPILLS && inst->opcode != WM_PIXELXY) {
+	 for (i = 0; i < 4; i++)	
+	    if (inst->dst[i])
+	       spill_value(c, inst->dst[i]);
+      }
+   }
+
+   if (BRW_DEBUG & DEBUG_WM) {
+      brw_wm_print_program(c, "pass2");
+   }
+
+   c->state = PASS2_DONE;
+
+   if (BRW_DEBUG & DEBUG_WM) {
+       brw_wm_print_program(c, "pass2/done");
+   }
+}
diff --git a/src/gallium/drivers/i965/brw_wm_sampler_state.c b/src/gallium/drivers/i965/brw_wm_sampler_state.c
new file mode 100644
index 0000000..a8bc31c
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_wm_sampler_state.c
@@ -0,0 +1,229 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+                   
+#include "util/u_math.h"
+#include "util/u_format.h"
+
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+#include "brw_screen.h"
+
+
+/* Samplers aren't strictly wm state from the hardware's perspective,
+ * but that is the only situation in which we use them in this driver.
+ */
+
+
+
+static enum pipe_error
+upload_default_color( struct brw_context *brw,
+		      const GLfloat *color,
+                      struct brw_winsys_buffer **bo_out )
+{
+   struct brw_sampler_default_color sdc;
+   enum pipe_error ret;
+
+   COPY_4V(sdc.color, color); 
+   
+   ret = brw_cache_data( &brw->cache, BRW_SAMPLER_DEFAULT_COLOR, &sdc,
+                         NULL, 0, bo_out );
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+
+struct wm_sampler_key {
+   int sampler_count;
+   struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT];
+};
+
+
+/** Sets up the cache key for sampler state for all texture units */
+static void
+brw_wm_sampler_populate_key(struct brw_context *brw,
+			    struct wm_sampler_key *key)
+{
+   int i;
+
+   memset(key, 0, sizeof(*key));
+
+   key->sampler_count = MIN2(brw->curr.num_textures,
+			    brw->curr.num_samplers);
+
+   for (i = 0; i < key->sampler_count; i++) {
+      const struct brw_texture *tex = brw_texture(brw->curr.texture[i]);
+      const struct brw_sampler *sampler = brw->curr.sampler[i];
+      struct brw_sampler_state *entry = &key->sampler[i];
+
+      entry->ss0 = sampler->ss0;
+      entry->ss1 = sampler->ss1;
+      entry->ss2.default_color_pointer = 0; /* reloc */
+      entry->ss3 = sampler->ss3;
+
+      /* Cube-maps on 965 and later must use the same wrap mode for all 3
+       * coordinate dimensions.  Futher, only CUBE and CLAMP are valid.
+       */
+      if (tex->base.target == PIPE_TEXTURE_CUBE) {
+	 if (FALSE &&
+	     (sampler->ss0.min_filter != BRW_MAPFILTER_NEAREST || 
+	      sampler->ss0.mag_filter != BRW_MAPFILTER_NEAREST)) {
+	    entry->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CUBE;
+	    entry->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CUBE;
+	    entry->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CUBE;
+	 } else {
+	    entry->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+	    entry->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+	    entry->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+	 }
+      } else if (tex->base.target == PIPE_TEXTURE_1D) {
+	 /* There's a bug in 1D texture sampling - it actually pays
+	  * attention to the wrap_t value, though it should not.
+	  * Override the wrap_t value here to GL_REPEAT to keep
+	  * any nonexistent border pixels from floating in.
+	  */
+	 entry->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
+      }
+   }
+}
+
+
+static enum pipe_error
+brw_wm_sampler_update_default_colors(struct brw_context *brw)
+{
+   enum pipe_error ret;
+   int nr = MIN2(brw->curr.num_textures,
+		 brw->curr.num_samplers);
+   int i;
+
+   for (i = 0; i < nr; i++) {
+      const struct brw_texture *tex = brw_texture(brw->curr.texture[i]);
+      const struct brw_sampler *sampler = brw->curr.sampler[i];
+      const float *bc;
+
+      if (util_format_is_depth_or_stencil(tex->base.format)) {
+	 float bordercolor[4] = {
+	    sampler->border_color[0],
+	    sampler->border_color[0],
+	    sampler->border_color[0],
+	    sampler->border_color[0]
+	 };
+         
+         bc = bordercolor;
+      }
+      else {
+         bc = sampler->border_color;
+      }
+
+      /* GL specs that border color for depth textures is taken from the
+       * R channel, while the hardware uses A.  Spam R into all the
+       * channels for safety.
+       */
+      ret = upload_default_color(brw, 
+                                 bc,
+                                 &brw->wm.sdc_bo[i]);
+      if (ret) 
+         return ret;
+   }
+
+   return PIPE_OK;
+}
+
+
+
+/* All samplers must be uploaded in a single contiguous array.  
+ */
+static int upload_wm_samplers( struct brw_context *brw )
+{
+   struct wm_sampler_key key;
+   struct brw_winsys_reloc reloc[BRW_MAX_TEX_UNIT];
+   enum pipe_error ret;
+   int i;
+
+   brw_wm_sampler_update_default_colors(brw);
+   brw_wm_sampler_populate_key(brw, &key);
+
+   if (brw->wm.sampler_count != key.sampler_count) {
+      brw->wm.sampler_count = key.sampler_count;
+      brw->state.dirty.cache |= CACHE_NEW_SAMPLER;
+   }
+
+   if (brw->wm.sampler_count == 0) {
+      bo_reference(&brw->wm.sampler_bo, NULL);
+      return PIPE_OK;
+   }
+
+   /* Emit SDC relocations */
+   for (i = 0; i < key.sampler_count; i++) {
+      make_reloc( &reloc[i],
+                  BRW_USAGE_SAMPLER,
+                  0,
+                  i * sizeof(struct brw_sampler_state) +
+                  offsetof(struct brw_sampler_state, ss2),
+                  brw->wm.sdc_bo[i]);
+   }
+
+
+   if (brw_search_cache(&brw->cache, BRW_SAMPLER,
+                        &key, sizeof(key),
+                        reloc, key.sampler_count,
+                        NULL,
+                        &brw->wm.sampler_bo))
+      return PIPE_OK;
+
+   /* If we didnt find it in the cache, compute the state and put it in the
+    * cache.
+    */
+   ret = brw_upload_cache(&brw->cache, BRW_SAMPLER,
+                          &key, sizeof(key),
+                          reloc, key.sampler_count,
+                          &key.sampler, sizeof(key.sampler),
+                          NULL, NULL,
+                          &brw->wm.sampler_bo);
+   if (ret)
+      return ret;
+
+
+   return 0;
+}
+
+const struct brw_tracked_state brw_wm_samplers = {
+   .dirty = {
+      .mesa = PIPE_NEW_BOUND_TEXTURES | PIPE_NEW_SAMPLERS,
+      .brw = 0,
+      .cache = 0
+   },
+   .prepare = upload_wm_samplers,
+};
+
+
diff --git a/src/gallium/drivers/i965/brw_wm_state.c b/src/gallium/drivers/i965/brw_wm_state.c
new file mode 100644
index 0000000..ee970ac
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_wm_state.c
@@ -0,0 +1,339 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+                   
+#include "util/u_math.h"
+
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+#include "brw_wm.h"
+#include "brw_debug.h"
+#include "brw_pipe_rast.h"
+
+/***********************************************************************
+ * WM unit - fragment programs and rasterization
+ */
+
+struct brw_wm_unit_key {
+   unsigned int total_grf, total_scratch;
+   unsigned int urb_entry_read_length;
+   unsigned int curb_entry_read_length;
+   unsigned int dispatch_grf_start_reg;
+
+   unsigned int curbe_offset;
+   unsigned int urb_size;
+
+   unsigned int max_threads;
+
+   unsigned int nr_surfaces, sampler_count;
+   GLboolean uses_depth, computes_depth, uses_kill, has_flow_control;
+   GLboolean polygon_stipple, stats_wm, line_stipple, offset_enable;
+   GLfloat offset_units, offset_factor;
+};
+
+static void
+wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key)
+{
+   const struct brw_fragment_shader *fp = brw->curr.fragment_shader;
+
+   memset(key, 0, sizeof(*key));
+
+   if (BRW_DEBUG & DEBUG_SINGLE_THREAD)
+      key->max_threads = 1;
+   else {
+      /* WM maximum threads is number of EUs times number of threads per EU. */
+      if (BRW_IS_IGDNG(brw))
+         key->max_threads = 12 * 6;
+      else if (BRW_IS_G4X(brw))
+	 key->max_threads = 10 * 5;
+      else
+	 key->max_threads = 8 * 4;
+   }
+
+   /* CACHE_NEW_WM_PROG */
+   key->total_grf = brw->wm.prog_data->total_grf;
+   key->urb_entry_read_length = brw->wm.prog_data->urb_read_length;
+   key->curb_entry_read_length = brw->wm.prog_data->curb_read_length;
+   key->dispatch_grf_start_reg = brw->wm.prog_data->first_curbe_grf;
+   key->total_scratch = align(brw->wm.prog_data->total_scratch, 1024);
+
+   /* BRW_NEW_URB_FENCE */
+   key->urb_size = brw->urb.vsize;
+
+   /* BRW_NEW_CURBE_OFFSETS */
+   key->curbe_offset = brw->curbe.wm_start;
+
+   /* BRW_NEW_NR_SURFACEs */
+   key->nr_surfaces = brw->wm.nr_surfaces;
+
+   /* CACHE_NEW_SAMPLER */
+   key->sampler_count = brw->wm.sampler_count;
+
+   /* PIPE_NEW_RAST */
+   key->polygon_stipple = brw->curr.rast->templ.poly_stipple_enable;
+
+   /* PIPE_NEW_FRAGMENT_PROGRAM */
+   key->uses_depth = fp->uses_depth;
+   key->computes_depth = fp->info.writes_z;
+
+   /* PIPE_NEW_DEPTH_BUFFER
+    *
+    * Override for NULL depthbuffer case, required by the Pixel Shader Computed
+    * Depth field.
+    */
+   if (brw->curr.fb.zsbuf == NULL)
+      key->computes_depth = 0;
+
+   /* PIPE_NEW_DEPTH_STENCIL_ALPHA */
+   key->uses_kill = (fp->info.uses_kill || 
+		     brw->curr.zstencil->cc3.alpha_test);
+
+   key->has_flow_control = fp->has_flow_control;
+
+   /* temporary sanity check assertion */
+   assert(fp->has_flow_control == 0);
+
+   /* PIPE_NEW_QUERY */
+   key->stats_wm = (brw->query.stats_wm != 0);
+
+   /* PIPE_NEW_RAST */
+   key->line_stipple = brw->curr.rast->templ.line_stipple_enable;
+
+
+   key->offset_enable = (brw->curr.rast->templ.offset_cw ||
+			 brw->curr.rast->templ.offset_ccw);
+
+   key->offset_units = brw->curr.rast->templ.offset_units;
+   key->offset_factor = brw->curr.rast->templ.offset_scale;
+}
+
+/**
+ * Setup wm hardware state.  See page 225 of Volume 2
+ */
+static enum pipe_error
+wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key,
+			struct brw_winsys_reloc *reloc,
+                        unsigned nr_reloc,
+                        struct brw_winsys_buffer **bo_out)
+{
+   struct brw_wm_unit_state wm;
+   enum pipe_error ret;
+
+   memset(&wm, 0, sizeof(wm));
+
+   wm.thread0.grf_reg_count = align(key->total_grf, 16) / 16 - 1;
+   wm.thread0.kernel_start_pointer = 0; /* reloc */
+   wm.thread1.depth_coef_urb_read_offset = 1;
+   wm.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
+
+   if (BRW_IS_IGDNG(brw))
+      wm.thread1.binding_table_entry_count = 0; /* hardware requirement */
+   else
+      wm.thread1.binding_table_entry_count = key->nr_surfaces;
+
+   if (key->total_scratch != 0) {
+      wm.thread2.scratch_space_base_pointer = 0; /* reloc */
+      wm.thread2.per_thread_scratch_space = key->total_scratch / 1024 - 1;
+   } else {
+      wm.thread2.scratch_space_base_pointer = 0;
+      wm.thread2.per_thread_scratch_space = 0;
+   }
+
+   wm.thread3.dispatch_grf_start_reg = key->dispatch_grf_start_reg;
+   wm.thread3.urb_entry_read_length = key->urb_entry_read_length;
+   wm.thread3.urb_entry_read_offset = 0;
+   wm.thread3.const_urb_entry_read_length = key->curb_entry_read_length;
+   wm.thread3.const_urb_entry_read_offset = key->curbe_offset * 2;
+
+   if (BRW_IS_IGDNG(brw)) 
+      wm.wm4.sampler_count = 0; /* hardware requirement */
+   else
+      wm.wm4.sampler_count = (key->sampler_count + 1) / 4;
+
+   /* reloc */
+   wm.wm4.sampler_state_pointer = 0;
+
+   wm.wm5.program_uses_depth = key->uses_depth;
+   wm.wm5.program_computes_depth = key->computes_depth;
+   wm.wm5.program_uses_killpixel = key->uses_kill;
+
+   if (key->has_flow_control)
+      wm.wm5.enable_8_pix = 1;
+   else
+      wm.wm5.enable_16_pix = 1;
+
+   wm.wm5.max_threads = key->max_threads - 1;
+   wm.wm5.thread_dispatch_enable = 1;	/* AKA: color_write */
+   wm.wm5.legacy_line_rast = 0;
+   wm.wm5.legacy_global_depth_bias = 0;
+   wm.wm5.early_depth_test = 1;	        /* never need to disable */
+   wm.wm5.line_aa_region_width = 0;
+   wm.wm5.line_endcap_aa_region_width = 1;
+
+   wm.wm5.polygon_stipple = key->polygon_stipple;
+
+   if (key->offset_enable) {
+      wm.wm5.depth_offset = 1;
+      /* Something wierd going on with legacy_global_depth_bias,
+       * offset_constant, scaling and MRD.  This value passes glean
+       * but gives some odd results elsewere (eg. the
+       * quad-offset-units test).
+       */
+      wm.global_depth_offset_constant = key->offset_units * 2;
+
+      /* This is the only value that passes glean:
+       */
+      wm.global_depth_offset_scale = key->offset_factor;
+   }
+
+   wm.wm5.line_stipple = key->line_stipple;
+
+   if ((BRW_DEBUG & DEBUG_STATS) || key->stats_wm)
+      wm.wm4.stats_enable = 1;
+
+   ret = brw_upload_cache(&brw->cache, BRW_WM_UNIT,
+                          key, sizeof(*key),
+                          reloc, nr_reloc,
+                          &wm, sizeof(wm),
+                          NULL, NULL,
+                          bo_out);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+
+static enum pipe_error upload_wm_unit( struct brw_context *brw )
+{
+   struct brw_wm_unit_key key;
+   struct brw_winsys_reloc reloc[3];
+   unsigned nr_reloc = 0;
+   enum pipe_error ret;
+   unsigned grf_reg_count;
+   unsigned per_thread_scratch_space;
+   unsigned stats_enable;
+   unsigned sampler_count;
+
+   wm_unit_populate_key(brw, &key);
+
+
+   /* Allocate the necessary scratch space if we haven't already.  Don't
+    * bother reducing the allocation later, since we use scratch so
+    * rarely.
+    */
+   assert(key.total_scratch <= 12 * 1024);
+   if (key.total_scratch) {
+      GLuint total = key.total_scratch * key.max_threads;
+
+      /* Do we need a new buffer:
+       */
+      if (brw->wm.scratch_bo && total > brw->wm.scratch_bo->size) 
+	 bo_reference(&brw->wm.scratch_bo, NULL);
+
+      if (brw->wm.scratch_bo == NULL) {
+	 ret = brw->sws->bo_alloc(brw->sws,
+                                  BRW_BUFFER_TYPE_SHADER_SCRATCH,
+                                  total,
+                                  4096,
+                                  &brw->wm.scratch_bo);
+         if (ret)
+            return ret;
+      }
+   }
+
+
+   /* XXX: temporary:
+    */
+   grf_reg_count = (align(key.total_grf, 16) / 16 - 1);
+   per_thread_scratch_space = key.total_scratch / 1024 - 1;
+   stats_enable = (BRW_DEBUG & DEBUG_STATS) || key.stats_wm;
+   sampler_count = BRW_IS_IGDNG(brw) ? 0 :(key.sampler_count + 1) / 4;
+
+   /* Emit WM program relocation */
+   make_reloc(&reloc[nr_reloc++],
+              BRW_USAGE_STATE,
+              grf_reg_count << 1,
+              offsetof(struct brw_wm_unit_state, thread0),
+              brw->wm.prog_bo);
+
+   /* Emit scratch space relocation */
+   if (key.total_scratch != 0) {
+      make_reloc(&reloc[nr_reloc++],
+                 BRW_USAGE_SCRATCH,
+                 per_thread_scratch_space,
+                 offsetof(struct brw_wm_unit_state, thread2),
+                 brw->wm.scratch_bo);
+   }
+
+   /* Emit sampler state relocation */
+   if (key.sampler_count != 0) {
+      make_reloc(&reloc[nr_reloc++],
+                 BRW_USAGE_STATE,
+                 stats_enable | (sampler_count << 2),
+                 offsetof(struct brw_wm_unit_state, wm4),
+                 brw->wm.sampler_bo);
+   }
+
+
+   if (brw_search_cache(&brw->cache, BRW_WM_UNIT,
+                        &key, sizeof(key),
+                        reloc, nr_reloc,
+                        NULL,
+                        &brw->wm.state_bo))
+      return PIPE_OK;
+
+   ret = wm_unit_create_from_key(brw, &key, 
+                                 reloc, nr_reloc,
+                                 &brw->wm.state_bo);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+const struct brw_tracked_state brw_wm_unit = {
+   .dirty = {
+      .mesa = (PIPE_NEW_FRAGMENT_SHADER |
+	       PIPE_NEW_DEPTH_BUFFER |
+	       PIPE_NEW_RAST | 
+	       PIPE_NEW_DEPTH_STENCIL_ALPHA |
+	       PIPE_NEW_QUERY),
+
+      .brw = (BRW_NEW_CURBE_OFFSETS |
+	      BRW_NEW_NR_WM_SURFACES),
+
+      .cache = (CACHE_NEW_WM_PROG |
+		CACHE_NEW_SAMPLER)
+   },
+   .prepare = upload_wm_unit,
+};
+
diff --git a/src/gallium/drivers/i965/brw_wm_surface_state.c b/src/gallium/drivers/i965/brw_wm_surface_state.c
new file mode 100644
index 0000000..f92b819
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_wm_surface_state.c
@@ -0,0 +1,294 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+ 
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ 
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  */
+                   
+#include "pipe/p_format.h"
+
+#include "brw_batchbuffer.h"
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+#include "brw_screen.h"
+
+
+
+
+static enum pipe_error
+brw_update_texture_surface( struct brw_context *brw,
+			    struct brw_texture *tex,
+                            struct brw_winsys_buffer **bo_out)
+{
+   struct brw_winsys_reloc reloc[1];
+   enum pipe_error ret;
+
+   /* Emit relocation to surface contents */
+   make_reloc(&reloc[0],
+              BRW_USAGE_SAMPLER,
+              0,
+              offsetof(struct brw_surface_state, ss1),
+              tex->bo);
+
+   if (brw_search_cache(&brw->surface_cache,
+                        BRW_SS_SURFACE,
+                        &tex->ss, sizeof tex->ss,
+                        reloc, Elements(reloc),
+                        NULL,
+                        bo_out))
+      return PIPE_OK;
+
+   ret = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
+                          &tex->ss, sizeof tex->ss,
+                          reloc, Elements(reloc),
+                          &tex->ss, sizeof tex->ss,
+                          NULL, NULL,
+                          bo_out);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+
+
+
+
+
+
+
+/**
+ * Sets up a surface state structure to point at the given region.
+ * While it is only used for the front/back buffer currently, it should be
+ * usable for further buffers when doing ARB_draw_buffer support.
+ */
+static enum pipe_error
+brw_update_render_surface(struct brw_context *brw,
+                          struct brw_surface *surface,
+                          struct brw_winsys_buffer **bo_out)
+{
+   struct brw_surf_ss0 blend_ss0 = brw->curr.blend->ss0;
+   struct brw_surface_state ss;
+   struct brw_winsys_reloc reloc[1];
+   enum pipe_error ret;
+
+   /* XXX: we will only be rendering to this surface:
+    */
+   make_reloc(&reloc[0],
+              BRW_USAGE_RENDER_TARGET,
+              0,
+              offsetof(struct brw_surface_state, ss1),
+              surface->bo);
+
+   /* Surfaces are potentially shared between contexts, so can't
+    * scribble the in-place ss0 value in the surface.
+    */
+   memcpy(&ss, &surface->ss, sizeof ss);
+
+   ss.ss0.color_blend        = blend_ss0.color_blend;
+   ss.ss0.writedisable_blue  = blend_ss0.writedisable_blue;
+   ss.ss0.writedisable_green = blend_ss0.writedisable_green;
+   ss.ss0.writedisable_red   = blend_ss0.writedisable_red;
+   ss.ss0.writedisable_alpha = blend_ss0.writedisable_alpha;
+
+   if (brw_search_cache(&brw->surface_cache,
+                        BRW_SS_SURFACE,
+                        &ss, sizeof(ss),
+                        reloc, Elements(reloc),
+                        NULL,
+                        bo_out))
+      return PIPE_OK;
+       
+   ret = brw_upload_cache(&brw->surface_cache,
+                          BRW_SS_SURFACE,
+                          &ss, sizeof ss,
+                          reloc, Elements(reloc),
+                          &ss, sizeof ss,
+                          NULL, NULL,
+                          bo_out);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+
+/**
+ * Constructs the binding table for the WM surface state, which maps unit
+ * numbers to surface state objects.
+ */
+static enum pipe_error
+brw_wm_get_binding_table(struct brw_context *brw,
+                         struct brw_winsys_buffer **bo_out )
+{
+   enum pipe_error ret;
+   struct brw_winsys_reloc reloc[BRW_WM_MAX_SURF];
+   uint32_t data[BRW_WM_MAX_SURF];
+   GLuint nr_relocs = 0;
+   GLuint data_size = brw->wm.nr_surfaces * sizeof data[0];
+   int i;
+
+   assert(brw->wm.nr_surfaces <= BRW_WM_MAX_SURF);
+   assert(brw->wm.nr_surfaces > 0);
+
+   /* Emit binding table relocations to surface state 
+    */
+   for (i = 0; i < brw->wm.nr_surfaces; i++) {
+      if (brw->wm.surf_bo[i]) {
+         make_reloc(&reloc[nr_relocs++],
+                    BRW_USAGE_STATE,
+                    0,
+                    i * sizeof(GLuint),
+                    brw->wm.surf_bo[i]);
+      }
+   }
+
+   /* Note there is no key for this search beyond the values in the
+    * relocation array:
+    */
+   if (brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND,
+                        NULL, 0,
+                        reloc, nr_relocs,
+                        NULL,
+                        bo_out))
+      return PIPE_OK;
+
+   /* Upload zero data, will all be overwitten with relocation
+    * offsets:
+    */
+   for (i = 0; i < brw->wm.nr_surfaces; i++)
+      data[i] = 0;
+
+   ret = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND,
+                           NULL, 0,
+                           reloc, nr_relocs,
+                           data, data_size,
+                           NULL, NULL,
+                           bo_out);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+static enum pipe_error prepare_wm_surfaces(struct brw_context *brw )
+{
+   enum pipe_error ret;
+   int nr_surfaces = 0;
+   GLuint i;
+
+   /* PIPE_NEW_COLOR_BUFFERS | PIPE_NEW_BLEND
+    *
+    * Update surfaces for drawing buffers.  Mixes in colormask and
+    * blend state.
+    *
+    * XXX: no color buffer case
+    */
+   for (i = 0; i < brw->curr.fb.nr_cbufs; i++) {
+      ret = brw_update_render_surface(brw, 
+                                      brw_surface(brw->curr.fb.cbufs[i]), 
+                                      &brw->wm.surf_bo[BTI_COLOR_BUF(i)]);
+      if (ret)
+         return ret;
+      
+      nr_surfaces = BTI_COLOR_BUF(i) + 1;
+   }
+
+
+
+   /* PIPE_NEW_FRAGMENT_CONSTANTS
+    */
+#if 0
+   if (brw->curr.fragment_constants) {
+      ret = brw_update_fragment_constant_surface(
+         brw, 
+         brw->curr.fragment_constants, 
+         &brw->wm.surf_bo[BTI_FRAGMENT_CONSTANTS]);
+
+      if (ret)
+         return ret;
+
+      nr_surfaces = BTI_FRAGMENT_CONSTANTS + 1;
+   }
+   else {
+      bo_reference(&brw->wm.surf_bo[SURF_FRAG_CONSTANTS], NULL);      
+   }
+#endif
+
+
+   /* PIPE_NEW_TEXTURE 
+    */
+   for (i = 0; i < brw->curr.num_textures; i++) {
+      ret = brw_update_texture_surface(brw, 
+                                       brw_texture(brw->curr.texture[i]),
+                                       &brw->wm.surf_bo[BTI_TEXTURE(i)]);
+      if (ret)
+         return ret;
+
+      nr_surfaces = BTI_TEXTURE(i) + 1;
+   }
+
+   /* Clear any inactive entries:
+    */
+   for (i = brw->curr.fb.nr_cbufs; i < BRW_MAX_DRAW_BUFFERS; i++) 
+      bo_reference(&brw->wm.surf_bo[BTI_COLOR_BUF(i)], NULL);
+
+   if (!brw->curr.fragment_constants)
+      bo_reference(&brw->wm.surf_bo[BTI_FRAGMENT_CONSTANTS], NULL);      
+
+   /* XXX: no pipe_max_textures define?? */
+   for (i = brw->curr.num_textures; i < PIPE_MAX_SAMPLERS; i++)
+      bo_reference(&brw->wm.surf_bo[BTI_TEXTURE(i)], NULL);
+
+   if (brw->wm.nr_surfaces != nr_surfaces) {
+      brw->wm.nr_surfaces = nr_surfaces;
+      brw->state.dirty.brw |= BRW_NEW_NR_WM_SURFACES;
+   }
+
+   ret = brw_wm_get_binding_table(brw, &brw->wm.bind_bo);
+   if (ret)
+      return ret;
+
+   return PIPE_OK;
+}
+
+const struct brw_tracked_state brw_wm_surfaces = {
+   .dirty = {
+      .mesa = (PIPE_NEW_COLOR_BUFFERS |
+               PIPE_NEW_BOUND_TEXTURES |
+               PIPE_NEW_FRAGMENT_CONSTANTS |
+	       PIPE_NEW_BLEND),
+      .brw = (BRW_NEW_CONTEXT |
+	      BRW_NEW_WM_SURFACES),
+      .cache = 0
+   },
+   .prepare = prepare_wm_surfaces,
+};
+
+
+
diff --git a/src/gallium/drivers/i965/intel_decode.c b/src/gallium/drivers/i965/intel_decode.c
new file mode 100644
index 0000000..3166958
--- /dev/null
+++ b/src/gallium/drivers/i965/intel_decode.c
@@ -0,0 +1,1790 @@
+/* -*- c-basic-offset: 4 -*- */
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * 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, sublicense,
+ * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ */
+
+/** @file intel_decode.c
+ * This file contains code to print out batchbuffer contents in a
+ * human-readable format.
+ *
+ * The current version only supports i915 packets, and only pretty-prints a
+ * subset of them.  The intention is for it to make just a best attempt to
+ * decode, but never crash in the process.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "intel_decode.h"
+
+/*#include "intel_chipset.h"*/
+#define IS_965(x) 1             /* XXX */
+#define IS_9XX(x) 1             /* XXX */
+
+#define BUFFER_FAIL(_count, _len, _name) do {			\
+    fprintf(out, "Buffer size too small in %s (%d < %d)\n",	\
+	    (_name), (_count), (_len));				\
+    (*failures)++;						\
+    return count;						\
+} while (0)
+
+static FILE *out;
+static uint32_t saved_s2 = 0, saved_s4 = 0;
+static char saved_s2_set = 0, saved_s4_set = 0;
+
+static float
+int_as_float(uint32_t intval)
+{
+    union intfloat {
+	uint32_t i;
+	float f;
+    } uval;
+
+    uval.i = intval;
+    return uval.f;
+}
+
+static void
+instr_out(const uint32_t *data, uint32_t hw_offset, unsigned int index,
+	  char *fmt, ...)
+{
+    va_list va;
+
+    fprintf(out, "0x%08x: 0x%08x:%s ", hw_offset + index * 4, data[index],
+	    index == 0 ? "" : "  ");
+    va_start(va, fmt);
+    vfprintf(out, fmt, va);
+    va_end(va);
+}
+
+
+static int
+decode_mi(const uint32_t *data, int count, uint32_t hw_offset, int *failures)
+{
+    unsigned int opcode;
+
+    struct {
+	uint32_t opcode;
+	int len_mask;
+	int min_len;
+	int max_len;
+	char *name;
+    } opcodes_mi[] = {
+	{ 0x08, 0, 1, 1, "MI_ARB_ON_OFF" },
+	{ 0x0a, 0, 1, 1, "MI_BATCH_BUFFER_END" },
+	{ 0x31, 0x3f, 2, 2, "MI_BATCH_BUFFER_START" },
+	{ 0x14, 0x3f, 3, 3, "MI_DISPLAY_BUFFER_INFO" },
+	{ 0x04, 0, 1, 1, "MI_FLUSH" },
+	{ 0x22, 0, 3, 3, "MI_LOAD_REGISTER_IMM" },
+	{ 0x13, 0x3f, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" },
+	{ 0x12, 0x3f, 2, 2, "MI_LOAD_SCAN_LINES_INCL" },
+	{ 0x00, 0, 1, 1, "MI_NOOP" },
+	{ 0x11, 0x3f, 2, 2, "MI_OVERLAY_FLIP" },
+	{ 0x07, 0, 1, 1, "MI_REPORT_HEAD" },
+	{ 0x18, 0x3f, 2, 2, "MI_SET_CONTEXT" },
+	{ 0x20, 0x3f, 3, 4, "MI_STORE_DATA_IMM" },
+	{ 0x21, 0x3f, 3, 4, "MI_STORE_DATA_INDEX" },
+	{ 0x24, 0x3f, 3, 3, "MI_STORE_REGISTER_MEM" },
+	{ 0x02, 0, 1, 1, "MI_USER_INTERRUPT" },
+	{ 0x03, 0, 1, 1, "MI_WAIT_FOR_EVENT" },
+    };
+
+
+    for (opcode = 0; opcode < sizeof(opcodes_mi) / sizeof(opcodes_mi[0]);
+	 opcode++) {
+	if ((data[0] & 0x1f800000) >> 23 == opcodes_mi[opcode].opcode) {
+	    unsigned int len = 1, i;
+
+	    instr_out(data, hw_offset, 0, "%s\n", opcodes_mi[opcode].name);
+	    if (opcodes_mi[opcode].max_len > 1) {
+		len = (data[0] & opcodes_mi[opcode].len_mask) + 2;
+		if (len < opcodes_mi[opcode].min_len ||
+		    len > opcodes_mi[opcode].max_len)
+		{
+		    fprintf(out, "Bad length (%d) in %s, [%d, %d]\n",
+			    len, opcodes_mi[opcode].name,
+			    opcodes_mi[opcode].min_len,
+			    opcodes_mi[opcode].max_len);
+		}
+	    }
+
+	    for (i = 1; i < len; i++) {
+		if (i >= count)
+		    BUFFER_FAIL(count, len, opcodes_mi[opcode].name);
+		instr_out(data, hw_offset, i, "dword %d\n", i);
+	    }
+
+	    return len;
+	}
+    }
+
+    instr_out(data, hw_offset, 0, "MI UNKNOWN\n");
+    (*failures)++;
+    return 1;
+}
+
+static int
+decode_2d(const uint32_t *data, int count, uint32_t hw_offset, int *failures)
+{
+    unsigned int opcode, len;
+    char *format = NULL;
+
+    struct {
+	uint32_t opcode;
+	int min_len;
+	int max_len;
+	char *name;
+    } opcodes_2d[] = {
+	{ 0x40, 5, 5, "COLOR_BLT" },
+	{ 0x43, 6, 6, "SRC_COPY_BLT" },
+	{ 0x01, 8, 8, "XY_SETUP_BLT" },
+	{ 0x11, 9, 9, "XY_SETUP_MONO_PATTERN_SL_BLT" },
+	{ 0x03, 3, 3, "XY_SETUP_CLIP_BLT" },
+	{ 0x24, 2, 2, "XY_PIXEL_BLT" },
+	{ 0x25, 3, 3, "XY_SCANLINES_BLT" },
+	{ 0x26, 4, 4, "Y_TEXT_BLT" },
+	{ 0x31, 5, 134, "XY_TEXT_IMMEDIATE_BLT" },
+	{ 0x50, 6, 6, "XY_COLOR_BLT" },
+	{ 0x51, 6, 6, "XY_PAT_BLT" },
+	{ 0x76, 8, 8, "XY_PAT_CHROMA_BLT" },
+	{ 0x72, 7, 135, "XY_PAT_BLT_IMMEDIATE" },
+	{ 0x77, 9, 137, "XY_PAT_CHROMA_BLT_IMMEDIATE" },
+	{ 0x52, 9, 9, "XY_MONO_PAT_BLT" },
+	{ 0x59, 7, 7, "XY_MONO_PAT_FIXED_BLT" },
+	{ 0x53, 8, 8, "XY_SRC_COPY_BLT" },
+	{ 0x54, 8, 8, "XY_MONO_SRC_COPY_BLT" },
+	{ 0x71, 9, 137, "XY_MONO_SRC_COPY_IMMEDIATE_BLT" },
+	{ 0x55, 9, 9, "XY_FULL_BLT" },
+	{ 0x55, 9, 137, "XY_FULL_IMMEDIATE_PATTERN_BLT" },
+	{ 0x56, 9, 9, "XY_FULL_MONO_SRC_BLT" },
+	{ 0x75, 10, 138, "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT" },
+	{ 0x57, 12, 12, "XY_FULL_MONO_PATTERN_BLT" },
+	{ 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" },
+    };
+
+    switch ((data[0] & 0x1fc00000) >> 22) {
+    case 0x50:
+	instr_out(data, hw_offset, 0,
+		  "XY_COLOR_BLT (rgb %sabled, alpha %sabled, dst tile %d)\n",
+		  (data[0] & (1 << 20)) ? "en" : "dis",
+		  (data[0] & (1 << 21)) ? "en" : "dis",
+		  (data[0] >> 11) & 1);
+
+	len = (data[0] & 0x000000ff) + 2;
+	if (len != 6)
+	    fprintf(out, "Bad count in XY_COLOR_BLT\n");
+	if (count < 6)
+	    BUFFER_FAIL(count, len, "XY_COLOR_BLT");
+
+	switch ((data[1] >> 24) & 0x3) {
+	case 0:
+	    format="8";
+	    break;
+	case 1:
+	    format="565";
+	    break;
+	case 2:
+	    format="1555";
+	    break;
+	case 3:
+	    format="8888";
+	    break;
+	}
+
+	instr_out(data, hw_offset, 1, "format %s, pitch %d, "
+		  "clipping %sabled\n", format,
+		  (short)(data[1] & 0xffff),
+		  data[1] & (1 << 30) ? "en" : "dis");
+	instr_out(data, hw_offset, 2, "(%d,%d)\n",
+		  data[2] & 0xffff, data[2] >> 16);
+	instr_out(data, hw_offset, 3, "(%d,%d)\n",
+		  data[3] & 0xffff, data[3] >> 16);
+	instr_out(data, hw_offset, 4, "offset 0x%08x\n", data[4]);
+	instr_out(data, hw_offset, 5, "color\n");
+	return len;
+    case 0x53:
+	instr_out(data, hw_offset, 0,
+		  "XY_SRC_COPY_BLT (rgb %sabled, alpha %sabled, "
+		  "src tile %d, dst tile %d)\n",
+		  (data[0] & (1 << 20)) ? "en" : "dis",
+		  (data[0] & (1 << 21)) ? "en" : "dis",
+		  (data[0] >> 15) & 1,
+		  (data[0] >> 11) & 1);
+
+	len = (data[0] & 0x000000ff) + 2;
+	if (len != 8)
+	    fprintf(out, "Bad count in XY_SRC_COPY_BLT\n");
+	if (count < 8)
+	    BUFFER_FAIL(count, len, "XY_SRC_COPY_BLT");
+
+	switch ((data[1] >> 24) & 0x3) {
+	case 0:
+	    format="8";
+	    break;
+	case 1:
+	    format="565";
+	    break;
+	case 2:
+	    format="1555";
+	    break;
+	case 3:
+	    format="8888";
+	    break;
+	}
+
+	instr_out(data, hw_offset, 1, "format %s, dst pitch %d, "
+		  "clipping %sabled\n", format,
+		  (short)(data[1] & 0xffff),
+		  data[1] & (1 << 30) ? "en" : "dis");
+	instr_out(data, hw_offset, 2, "dst (%d,%d)\n",
+		  data[2] & 0xffff, data[2] >> 16);
+	instr_out(data, hw_offset, 3, "dst (%d,%d)\n",
+		  data[3] & 0xffff, data[3] >> 16);
+	instr_out(data, hw_offset, 4, "dst offset 0x%08x\n", data[4]);
+	instr_out(data, hw_offset, 5, "src (%d,%d)\n",
+		  data[5] & 0xffff, data[5] >> 16);
+	instr_out(data, hw_offset, 6, "src pitch %d\n",
+		  (short)(data[6] & 0xffff));
+	instr_out(data, hw_offset, 7, "src offset 0x%08x\n", data[7]);
+	return len;
+    }
+
+    for (opcode = 0; opcode < sizeof(opcodes_2d) / sizeof(opcodes_2d[0]);
+	 opcode++) {
+	if ((data[0] & 0x1fc00000) >> 22 == opcodes_2d[opcode].opcode) {
+	    unsigned int i;
+
+	    len = 1;
+	    instr_out(data, hw_offset, 0, "%s\n", opcodes_2d[opcode].name);
+	    if (opcodes_2d[opcode].max_len > 1) {
+		len = (data[0] & 0x000000ff) + 2;
+		if (len < opcodes_2d[opcode].min_len ||
+		    len > opcodes_2d[opcode].max_len)
+		{
+		    fprintf(out, "Bad count in %s\n", opcodes_2d[opcode].name);
+		}
+	    }
+
+	    for (i = 1; i < len; i++) {
+		if (i >= count)
+		    BUFFER_FAIL(count, len, opcodes_2d[opcode].name);
+		instr_out(data, hw_offset, i, "dword %d\n", i);
+	    }
+
+	    return len;
+	}
+    }
+
+    instr_out(data, hw_offset, 0, "2D UNKNOWN\n");
+    (*failures)++;
+    return 1;
+}
+
+static int
+decode_3d_1c(const uint32_t *data, int count, uint32_t hw_offset, int *failures)
+{
+    switch ((data[0] & 0x00f80000) >> 19) {
+    case 0x11:
+	instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISALBE\n");
+	return 1;
+    case 0x10:
+	instr_out(data, hw_offset, 0, "3DSTATE_SCISSOR_ENABLE\n");
+	return 1;
+    case 0x01:
+	instr_out(data, hw_offset, 0, "3DSTATE_MAP_COORD_SET_I830\n");
+	return 1;
+    case 0x0a:
+	instr_out(data, hw_offset, 0, "3DSTATE_MAP_CUBE_I830\n");
+	return 1;
+    case 0x05:
+	instr_out(data, hw_offset, 0, "3DSTATE_MAP_TEX_STREAM_I830\n");
+	return 1;
+    }
+
+    instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
+    (*failures)++;
+    return 1;
+}
+
+/** Sets the string dstname to describe the destination of the PS instruction */
+static void
+i915_get_instruction_dst(const uint32_t *data, int i, char *dstname, int do_mask)
+{
+    uint32_t a0 = data[i];
+    int dst_nr = (a0 >> 14) & 0xf;
+    char dstmask[8];
+    char *sat;
+
+    if (do_mask) {
+	if (((a0 >> 10) & 0xf) == 0xf) {
+	    dstmask[0] = 0;
+	} else {
+	    int dstmask_index = 0;
+
+	    dstmask[dstmask_index++] = '.';
+	    if (a0 & (1 << 10))
+		dstmask[dstmask_index++] = 'x';
+	    if (a0 & (1 << 11))
+		dstmask[dstmask_index++] = 'y';
+	    if (a0 & (1 << 12))
+		dstmask[dstmask_index++] = 'z';
+	    if (a0 & (1 << 13))
+		dstmask[dstmask_index++] = 'w';
+	    dstmask[dstmask_index++] = 0;
+	}
+
+	if (a0 & (1 << 22))
+	    sat = ".sat";
+	else
+	    sat = "";
+    } else {
+	dstmask[0] = 0;
+	sat = "";
+    }
+
+    switch ((a0 >> 19) & 0x7) {
+    case 0:
+	if (dst_nr > 15)
+	    fprintf(out, "bad destination reg R%d\n", dst_nr);
+	sprintf(dstname, "R%d%s%s", dst_nr, dstmask, sat);
+	break;
+    case 4:
+	if (dst_nr > 0)
+	    fprintf(out, "bad destination reg oC%d\n", dst_nr);
+	sprintf(dstname, "oC%s%s", dstmask, sat);
+	break;
+    case 5:
+	if (dst_nr > 0)
+	    fprintf(out, "bad destination reg oD%d\n", dst_nr);
+	sprintf(dstname, "oD%s%s",  dstmask, sat);
+	break;
+    case 6:
+	if (dst_nr > 2)
+	    fprintf(out, "bad destination reg U%d\n", dst_nr);
+	sprintf(dstname, "U%d%s%s", dst_nr, dstmask, sat);
+	break;
+    default:
+	sprintf(dstname, "RESERVED");
+	break;
+    }
+}
+
+static char *
+i915_get_channel_swizzle(uint32_t select)
+{
+    switch (select & 0x7) {
+    case 0:
+	return (select & 8) ? "-x" : "x";
+    case 1:
+	return (select & 8) ? "-y" : "y";
+    case 2:
+	return (select & 8) ? "-z" : "z";
+    case 3:
+	return (select & 8) ? "-w" : "w";
+    case 4:
+	return (select & 8) ? "-0" : "0";
+    case 5:
+	return (select & 8) ? "-1" : "1";
+    default:
+	return (select & 8) ? "-bad" : "bad";
+    }
+}
+
+static void
+i915_get_instruction_src_name(uint32_t src_type, uint32_t src_nr, char *name)
+{
+    switch (src_type) {
+    case 0:
+	sprintf(name, "R%d", src_nr);
+	if (src_nr > 15)
+	    fprintf(out, "bad src reg %s\n", name);
+	break;
+    case 1:
+	if (src_nr < 8)
+	    sprintf(name, "T%d", src_nr);
+	else if (src_nr == 8)
+	    sprintf(name, "DIFFUSE");
+	else if (src_nr == 9)
+	    sprintf(name, "SPECULAR");
+	else if (src_nr == 10)
+	    sprintf(name, "FOG");
+	else {
+	    fprintf(out, "bad src reg T%d\n", src_nr);
+	    sprintf(name, "RESERVED");
+	}
+	break;
+    case 2:
+	sprintf(name, "C%d", src_nr);
+	if (src_nr > 31)
+	    fprintf(out, "bad src reg %s\n", name);
+	break;
+    case 4:
+	sprintf(name, "oC");
+	if (src_nr > 0)
+	    fprintf(out, "bad src reg oC%d\n", src_nr);
+	break;
+    case 5:
+	sprintf(name, "oD");
+	if (src_nr > 0)
+	    fprintf(out, "bad src reg oD%d\n", src_nr);
+	break;
+    case 6:
+	sprintf(name, "U%d", src_nr);
+	if (src_nr > 2)
+	    fprintf(out, "bad src reg %s\n", name);
+	break;
+    default:
+	fprintf(out, "bad src reg type %d\n", src_type);
+	sprintf(name, "RESERVED");
+	break;
+    }
+}
+
+static void
+i915_get_instruction_src0(const uint32_t *data, int i, char *srcname)
+{
+    uint32_t a0 = data[i];
+    uint32_t a1 = data[i + 1];
+    int src_nr = (a0 >> 2) & 0x1f;
+    char *swizzle_x = i915_get_channel_swizzle((a1 >> 28) & 0xf);
+    char *swizzle_y = i915_get_channel_swizzle((a1 >> 24) & 0xf);
+    char *swizzle_z = i915_get_channel_swizzle((a1 >> 20) & 0xf);
+    char *swizzle_w = i915_get_channel_swizzle((a1 >> 16) & 0xf);
+    char swizzle[100];
+
+    i915_get_instruction_src_name((a0 >> 7) & 0x7, src_nr, srcname);
+    sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w);
+    if (strcmp(swizzle, ".xyzw") != 0)
+	strcat(srcname, swizzle);
+}
+
+static void
+i915_get_instruction_src1(const uint32_t *data, int i, char *srcname)
+{
+    uint32_t a1 = data[i + 1];
+    uint32_t a2 = data[i + 2];
+    int src_nr = (a1 >> 8) & 0x1f;
+    char *swizzle_x = i915_get_channel_swizzle((a1 >> 4) & 0xf);
+    char *swizzle_y = i915_get_channel_swizzle((a1 >> 0) & 0xf);
+    char *swizzle_z = i915_get_channel_swizzle((a2 >> 28) & 0xf);
+    char *swizzle_w = i915_get_channel_swizzle((a2 >> 24) & 0xf);
+    char swizzle[100];
+
+    i915_get_instruction_src_name((a1 >> 13) & 0x7, src_nr, srcname);
+    sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w);
+    if (strcmp(swizzle, ".xyzw") != 0)
+	strcat(srcname, swizzle);
+}
+
+static void
+i915_get_instruction_src2(const uint32_t *data, int i, char *srcname)
+{
+    uint32_t a2 = data[i + 2];
+    int src_nr = (a2 >> 16) & 0x1f;
+    char *swizzle_x = i915_get_channel_swizzle((a2 >> 12) & 0xf);
+    char *swizzle_y = i915_get_channel_swizzle((a2 >> 8) & 0xf);
+    char *swizzle_z = i915_get_channel_swizzle((a2 >> 4) & 0xf);
+    char *swizzle_w = i915_get_channel_swizzle((a2 >> 0) & 0xf);
+    char swizzle[100];
+
+    i915_get_instruction_src_name((a2 >> 21) & 0x7, src_nr, srcname);
+    sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w);
+    if (strcmp(swizzle, ".xyzw") != 0)
+	strcat(srcname, swizzle);
+}
+
+static void
+i915_get_instruction_addr(uint32_t src_type, uint32_t src_nr, char *name)
+{
+    switch (src_type) {
+    case 0:
+	sprintf(name, "R%d", src_nr);
+	if (src_nr > 15)
+	    fprintf(out, "bad src reg %s\n", name);
+	break;
+    case 1:
+	if (src_nr < 8)
+	    sprintf(name, "T%d", src_nr);
+	else if (src_nr == 8)
+	    sprintf(name, "DIFFUSE");
+	else if (src_nr == 9)
+	    sprintf(name, "SPECULAR");
+	else if (src_nr == 10)
+	    sprintf(name, "FOG");
+	else {
+	    fprintf(out, "bad src reg T%d\n", src_nr);
+	    sprintf(name, "RESERVED");
+	}
+	break;
+    case 4:
+	sprintf(name, "oC");
+	if (src_nr > 0)
+	    fprintf(out, "bad src reg oC%d\n", src_nr);
+	break;
+    case 5:
+	sprintf(name, "oD");
+	if (src_nr > 0)
+	    fprintf(out, "bad src reg oD%d\n", src_nr);
+	break;
+    default:
+	fprintf(out, "bad src reg type %d\n", src_type);
+	sprintf(name, "RESERVED");
+	break;
+    }
+}
+
+static void
+i915_decode_alu1(const uint32_t *data, uint32_t hw_offset,
+		 int i, char *instr_prefix, char *op_name)
+{
+    char dst[100], src0[100];
+
+    i915_get_instruction_dst(data, i, dst, 1);
+    i915_get_instruction_src0(data, i, src0);
+
+    instr_out(data, hw_offset, i++, "%s: %s %s, %s\n", instr_prefix,
+	      op_name, dst, src0);
+    instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+    instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+}
+
+static void
+i915_decode_alu2(const uint32_t *data, uint32_t hw_offset,
+		 int i, char *instr_prefix, char *op_name)
+{
+    char dst[100], src0[100], src1[100];
+
+    i915_get_instruction_dst(data, i, dst, 1);
+    i915_get_instruction_src0(data, i, src0);
+    i915_get_instruction_src1(data, i, src1);
+
+    instr_out(data, hw_offset, i++, "%s: %s %s, %s, %s\n", instr_prefix,
+	      op_name, dst, src0, src1);
+    instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+    instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+}
+
+static void
+i915_decode_alu3(const uint32_t *data, uint32_t hw_offset,
+		 int i, char *instr_prefix, char *op_name)
+{
+    char dst[100], src0[100], src1[100], src2[100];
+
+    i915_get_instruction_dst(data, i, dst, 1);
+    i915_get_instruction_src0(data, i, src0);
+    i915_get_instruction_src1(data, i, src1);
+    i915_get_instruction_src2(data, i, src2);
+
+    instr_out(data, hw_offset, i++, "%s: %s %s, %s, %s, %s\n", instr_prefix,
+	      op_name, dst, src0, src1, src2);
+    instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+    instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+}
+
+static void
+i915_decode_tex(const uint32_t *data, uint32_t hw_offset, int i, char *instr_prefix,
+		char *tex_name)
+{
+    uint32_t t0 = data[i];
+    uint32_t t1 = data[i + 1];
+    char dst_name[100];
+    char addr_name[100];
+    int sampler_nr;
+
+    i915_get_instruction_dst(data, i, dst_name, 0);
+    i915_get_instruction_addr((t1 >> 24) & 0x7,
+			      (t1 >> 17) & 0xf,
+			      addr_name);
+    sampler_nr = t0 & 0xf;
+
+    instr_out(data, hw_offset, i++, "%s: %s %s, S%d, %s\n", instr_prefix,
+	      tex_name, dst_name, sampler_nr, addr_name);
+    instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+    instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+}
+
+static void
+i915_decode_dcl(const uint32_t *data, uint32_t hw_offset, int i, char *instr_prefix)
+{
+    uint32_t d0 = data[i];
+    char *sampletype;
+    int dcl_nr = (d0 >> 14) & 0xf;
+    char *dcl_x = d0 & (1 << 10) ? "x" : "";
+    char *dcl_y = d0 & (1 << 11) ? "y" : "";
+    char *dcl_z = d0 & (1 << 12) ? "z" : "";
+    char *dcl_w = d0 & (1 << 13) ? "w" : "";
+    char dcl_mask[10];
+
+    switch ((d0 >> 19) & 0x3) {
+    case 1:
+	sprintf(dcl_mask, ".%s%s%s%s", dcl_x, dcl_y, dcl_z, dcl_w);
+	if (strcmp(dcl_mask, ".") == 0)
+	    fprintf(out, "bad (empty) dcl mask\n");
+
+	if (dcl_nr > 10)
+	    fprintf(out, "bad T%d dcl register number\n", dcl_nr);
+	if (dcl_nr < 8) {
+	    if (strcmp(dcl_mask, ".x") != 0 &&
+		strcmp(dcl_mask, ".xy") != 0 &&
+		strcmp(dcl_mask, ".xz") != 0 &&
+		strcmp(dcl_mask, ".w") != 0 &&
+		strcmp(dcl_mask, ".xyzw") != 0) {
+		fprintf(out, "bad T%d.%s dcl mask\n", dcl_nr, dcl_mask);
+	    }
+	    instr_out(data, hw_offset, i++, "%s: DCL T%d%s\n", instr_prefix,
+		      dcl_nr, dcl_mask);
+	} else {
+	    if (strcmp(dcl_mask, ".xz") == 0)
+		fprintf(out, "errataed bad dcl mask %s\n", dcl_mask);
+	    else if (strcmp(dcl_mask, ".xw") == 0)
+		fprintf(out, "errataed bad dcl mask %s\n", dcl_mask);
+	    else if (strcmp(dcl_mask, ".xzw") == 0)
+		fprintf(out, "errataed bad dcl mask %s\n", dcl_mask);
+
+	    if (dcl_nr == 8) {
+		instr_out(data, hw_offset, i++, "%s: DCL DIFFUSE%s\n", instr_prefix,
+			  dcl_mask);
+	    } else if (dcl_nr == 9) {
+		instr_out(data, hw_offset, i++, "%s: DCL SPECULAR%s\n", instr_prefix,
+			  dcl_mask);
+	    } else if (dcl_nr == 10) {
+		instr_out(data, hw_offset, i++, "%s: DCL FOG%s\n", instr_prefix,
+			  dcl_mask);
+	    }
+	}
+	instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+	instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+	break;
+    case 3:
+	switch ((d0 >> 22) & 0x3) {
+	case 0:
+	    sampletype = "2D";
+	    break;
+	case 1:
+	    sampletype = "CUBE";
+	    break;
+	case 2:
+	    sampletype = "3D";
+	    break;
+	default:
+	    sampletype = "RESERVED";
+	    break;
+	}
+	if (dcl_nr > 15)
+	    fprintf(out, "bad S%d dcl register number\n", dcl_nr);
+	instr_out(data, hw_offset, i++, "%s: DCL S%d %s\n", instr_prefix,
+		  dcl_nr, sampletype);
+	instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+	instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+	break;
+    default:
+	instr_out(data, hw_offset, i++, "%s: DCL RESERVED%d\n", instr_prefix, dcl_nr);
+	instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+	instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+    }
+}
+
+static void
+i915_decode_instruction(const uint32_t *data, uint32_t hw_offset,
+			int i, char *instr_prefix)
+{
+    switch ((data[i] >> 24) & 0x1f) {
+    case 0x0:
+	instr_out(data, hw_offset, i++, "%s: NOP\n", instr_prefix);
+	instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+	instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+	break;
+    case 0x01:
+	i915_decode_alu2(data, hw_offset, i, instr_prefix, "ADD");
+	break;
+    case 0x02:
+	i915_decode_alu1(data, hw_offset, i, instr_prefix, "MOV");
+	break;
+    case 0x03:
+	i915_decode_alu2(data, hw_offset, i, instr_prefix, "MUL");
+	break;
+    case 0x04:
+	i915_decode_alu3(data, hw_offset, i, instr_prefix, "MAD");
+	break;
+    case 0x05:
+	i915_decode_alu3(data, hw_offset, i, instr_prefix, "DP2ADD");
+	break;
+    case 0x06:
+	i915_decode_alu2(data, hw_offset, i, instr_prefix, "DP3");
+	break;
+    case 0x07:
+	i915_decode_alu2(data, hw_offset, i, instr_prefix, "DP4");
+	break;
+    case 0x08:
+	i915_decode_alu1(data, hw_offset, i, instr_prefix, "FRC");
+	break;
+    case 0x09:
+	i915_decode_alu1(data, hw_offset, i, instr_prefix, "RCP");
+	break;
+    case 0x0a:
+	i915_decode_alu1(data, hw_offset, i, instr_prefix, "RSQ");
+	break;
+    case 0x0b:
+	i915_decode_alu1(data, hw_offset, i, instr_prefix, "EXP");
+	break;
+    case 0x0c:
+	i915_decode_alu1(data, hw_offset, i, instr_prefix, "LOG");
+	break;
+    case 0x0d:
+	i915_decode_alu2(data, hw_offset, i, instr_prefix, "CMP");
+	break;
+    case 0x0e:
+	i915_decode_alu2(data, hw_offset, i, instr_prefix, "MIN");
+	break;
+    case 0x0f:
+	i915_decode_alu2(data, hw_offset, i, instr_prefix, "MAX");
+	break;
+    case 0x10:
+	i915_decode_alu1(data, hw_offset, i, instr_prefix, "FLR");
+	break;
+    case 0x11:
+	i915_decode_alu1(data, hw_offset, i, instr_prefix, "MOD");
+	break;
+    case 0x12:
+	i915_decode_alu1(data, hw_offset, i, instr_prefix, "TRC");
+	break;
+    case 0x13:
+	i915_decode_alu2(data, hw_offset, i, instr_prefix, "SGE");
+	break;
+    case 0x14:
+	i915_decode_alu2(data, hw_offset, i, instr_prefix, "SLT");
+	break;
+    case 0x15:
+	i915_decode_tex(data, hw_offset, i, instr_prefix, "TEXLD");
+	break;
+    case 0x16:
+	i915_decode_tex(data, hw_offset, i, instr_prefix, "TEXLDP");
+	break;
+    case 0x17:
+	i915_decode_tex(data, hw_offset, i, instr_prefix, "TEXLDB");
+	break;
+    case 0x19:
+	i915_decode_dcl(data, hw_offset, i, instr_prefix);
+	break;
+    default:
+	instr_out(data, hw_offset, i++, "%s: unknown\n", instr_prefix);
+	instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+	instr_out(data, hw_offset, i++, "%s\n", instr_prefix);
+	break;
+    }
+}
+
+static int
+decode_3d_1d(const uint32_t *data, int count, uint32_t hw_offset, int *failures, int i830)
+{
+    unsigned int len, i, c, opcode, word, map, sampler, instr;
+    char *format;
+
+    struct {
+	uint32_t opcode;
+	int i830_only;
+	int min_len;
+	int max_len;
+	char *name;
+    } opcodes_3d_1d[] = {
+	{ 0x8e, 0, 3, 3, "3DSTATE_BUFFER_INFO" },
+	{ 0x86, 0, 4, 4, "3DSTATE_CHROMA_KEY" },
+	{ 0x9c, 0, 1, 1, "3DSTATE_CLEAR_PARAMETERS" },
+	{ 0x88, 0, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" },
+	{ 0x99, 0, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" },
+	{ 0x9a, 0, 2, 2, "3DSTATE_DEFAULT_SPECULAR" },
+	{ 0x98, 0, 2, 2, "3DSTATE_DEFAULT_Z" },
+	{ 0x97, 0, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" },
+	{ 0x85, 0, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" },
+	{ 0x80, 0, 5, 5, "3DSTATE_DRAWING_RECTANGLE" },
+	{ 0x8e, 0, 3, 3, "3DSTATE_BUFFER_INFO" },
+	{ 0x9d, 0, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" },
+	{ 0x9e, 0, 4, 4, "3DSTATE_MONO_FILTER" },
+	{ 0x89, 0, 4, 4, "3DSTATE_FOG_MODE" },
+	{ 0x8f, 0, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" },
+	{ 0x81, 0, 3, 3, "3DSTATE_SCISSOR_RECTANGLE" },
+	{ 0x83, 0, 2, 2, "3DSTATE_SPAN_STIPPLE" },
+	{ 0x8c, 1, 2, 2, "3DSTATE_MAP_COORD_TRANSFORM_I830" },
+	{ 0x8b, 1, 2, 2, "3DSTATE_MAP_VERTEX_TRANSFORM_I830" },
+	{ 0x8d, 1, 3, 3, "3DSTATE_W_STATE_I830" },
+	{ 0x01, 1, 2, 2, "3DSTATE_COLOR_FACTOR_I830" },
+	{ 0x02, 1, 2, 2, "3DSTATE_MAP_COORD_SETBIND_I830" },
+    };
+
+    switch ((data[0] & 0x00ff0000) >> 16) {
+    case 0x07:
+	/* This instruction is unusual.  A 0 length means just 1 DWORD instead of
+	 * 2.  The 0 length is specified in one place to be unsupported, but
+	 * stated to be required in another, and 0 length LOAD_INDIRECTs appear
+	 * to cause no harm at least.
+	 */
+	instr_out(data, hw_offset, 0, "3DSTATE_LOAD_INDIRECT\n");
+	len = (data[0] & 0x000000ff) + 1;
+	i = 1;
+	if (data[0] & (0x01 << 8)) {
+	    if (i + 2 >= count)
+		BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
+	    instr_out(data, hw_offset, i++, "SIS.0\n");
+	    instr_out(data, hw_offset, i++, "SIS.1\n");
+	}
+	if (data[0] & (0x02 << 8)) {
+	    if (i + 1 >= count)
+		BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
+	    instr_out(data, hw_offset, i++, "DIS.0\n");
+	}
+	if (data[0] & (0x04 << 8)) {
+	    if (i + 2 >= count)
+		BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
+	    instr_out(data, hw_offset, i++, "SSB.0\n");
+	    instr_out(data, hw_offset, i++, "SSB.1\n");
+	}
+	if (data[0] & (0x08 << 8)) {
+	    if (i + 2 >= count)
+		BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
+	    instr_out(data, hw_offset, i++, "MSB.0\n");
+	    instr_out(data, hw_offset, i++, "MSB.1\n");
+	}
+	if (data[0] & (0x10 << 8)) {
+	    if (i + 2 >= count)
+		BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
+	    instr_out(data, hw_offset, i++, "PSP.0\n");
+	    instr_out(data, hw_offset, i++, "PSP.1\n");
+	}
+	if (data[0] & (0x20 << 8)) {
+	    if (i + 2 >= count)
+		BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT");
+	    instr_out(data, hw_offset, i++, "PSC.0\n");
+	    instr_out(data, hw_offset, i++, "PSC.1\n");
+	}
+	if (len != i) {
+	    fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n");
+	    (*failures)++;
+	    return len;
+	}
+	return len;
+    case 0x04:
+	instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n");
+	len = (data[0] & 0x0000000f) + 2;
+	i = 1;
+	for (word = 0; word <= 7; word++) {
+	    if (data[0] & (1 << (4 + word))) {
+		if (i >= count)
+		    BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1");
+
+		/* save vertex state for decode */
+		if (word == 2) {
+		    saved_s2_set = 1;
+		    saved_s2 = data[i];
+		}
+		if (word == 4) {
+		    saved_s4_set = 1;
+		    saved_s4 = data[i];
+		}
+
+		instr_out(data, hw_offset, i++, "S%d\n", word);
+	    }
+	}
+	if (len != i) {
+	    fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n");
+	    (*failures)++;
+	}
+	return len;
+    case 0x00:
+	instr_out(data, hw_offset, 0, "3DSTATE_MAP_STATE\n");
+	len = (data[0] & 0x0000003f) + 2;
+	instr_out(data, hw_offset, 1, "mask\n");
+
+	i = 2;
+	for (map = 0; map <= 15; map++) {
+	    if (data[1] & (1 << map)) {
+		if (i + 3 >= count)
+		    BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE");
+		instr_out(data, hw_offset, i++, "map %d MS2\n", map);
+		instr_out(data, hw_offset, i++, "map %d MS3\n", map);
+		instr_out(data, hw_offset, i++, "map %d MS4\n", map);
+	    }
+	}
+	if (len != i) {
+	    fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n");
+	    (*failures)++;
+	    return len;
+	}
+	return len;
+    case 0x06:
+	instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n");
+	len = (data[0] & 0x000000ff) + 2;
+
+	i = 2;
+	for (c = 0; c <= 31; c++) {
+	    if (data[1] & (1 << c)) {
+		if (i + 4 >= count)
+		    BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_CONSTANTS");
+		instr_out(data, hw_offset, i, "C%d.X = %f\n",
+			  c, int_as_float(data[i]));
+		i++;
+		instr_out(data, hw_offset, i, "C%d.Y = %f\n",
+			  c, int_as_float(data[i]));
+		i++;
+		instr_out(data, hw_offset, i, "C%d.Z = %f\n",
+			  c, int_as_float(data[i]));
+		i++;
+		instr_out(data, hw_offset, i, "C%d.W = %f\n",
+			  c, int_as_float(data[i]));
+		i++;
+	    }
+	}
+	if (len != i) {
+	    fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_CONSTANTS\n");
+	    (*failures)++;
+	}
+	return len;
+    case 0x05:
+	instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n");
+	len = (data[0] & 0x000000ff) + 2;
+	if ((len - 1) % 3 != 0 || len > 370) {
+	    fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_PROGRAM\n");
+	    (*failures)++;
+	}
+	i = 1;
+	for (instr = 0; instr < (len - 1) / 3; instr++) {
+	    char instr_prefix[10];
+
+	    if (i + 3 >= count)
+		BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_PROGRAM");
+	    sprintf(instr_prefix, "PS%03d", instr);
+	    i915_decode_instruction(data, hw_offset, i, instr_prefix);
+	    i += 3;
+	}
+	return len;
+    case 0x01:
+	if (i830)
+	    break;
+	instr_out(data, hw_offset, 0, "3DSTATE_SAMPLER_STATE\n");
+	instr_out(data, hw_offset, 1, "mask\n");
+	len = (data[0] & 0x0000003f) + 2;
+	i = 2;
+	for (sampler = 0; sampler <= 15; sampler++) {
+	    if (data[1] & (1 << sampler)) {
+		if (i + 3 >= count)
+		    BUFFER_FAIL(count, len, "3DSTATE_SAMPLER_STATE");
+		instr_out(data, hw_offset, i++, "sampler %d SS2\n",
+			  sampler);
+		instr_out(data, hw_offset, i++, "sampler %d SS3\n",
+			  sampler);
+		instr_out(data, hw_offset, i++, "sampler %d SS4\n",
+			  sampler);
+	    }
+	}
+	if (len != i) {
+	    fprintf(out, "Bad count in 3DSTATE_SAMPLER_STATE\n");
+	    (*failures)++;
+	}
+	return len;
+    case 0x85:
+	len = (data[0] & 0x0000000f) + 2;
+
+	if (len != 2)
+	    fprintf(out, "Bad count in 3DSTATE_DEST_BUFFER_VARIABLES\n");
+	if (count < 2)
+	    BUFFER_FAIL(count, len, "3DSTATE_DEST_BUFFER_VARIABLES");
+
+	instr_out(data, hw_offset, 0,
+		  "3DSTATE_DEST_BUFFER_VARIABLES\n");
+
+	switch ((data[1] >> 8) & 0xf) {
+	case 0x0: format = "g8"; break;
+	case 0x1: format = "x1r5g5b5"; break;
+	case 0x2: format = "r5g6b5"; break;
+	case 0x3: format = "a8r8g8b8"; break;
+	case 0x4: format = "ycrcb_swapy"; break;
+	case 0x5: format = "ycrcb_normal"; break;
+	case 0x6: format = "ycrcb_swapuv"; break;
+	case 0x7: format = "ycrcb_swapuvy"; break;
+	case 0x8: format = "a4r4g4b4"; break;
+	case 0x9: format = "a1r5g5b5"; break;
+	case 0xa: format = "a2r10g10b10"; break;
+	default: format = "BAD"; break;
+	}
+	instr_out(data, hw_offset, 1, "%s format, early Z %sabled\n",
+		  format,
+		  (data[1] & (1 << 31)) ? "en" : "dis");
+	return len;
+    }
+
+    for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]);
+	 opcode++)
+    {
+	if (opcodes_3d_1d[opcode].i830_only && !i830)
+	    continue;
+
+	if (((data[0] & 0x00ff0000) >> 16) == opcodes_3d_1d[opcode].opcode) {
+	    len = 1;
+
+	    instr_out(data, hw_offset, 0, "%s\n", opcodes_3d_1d[opcode].name);
+	    if (opcodes_3d_1d[opcode].max_len > 1) {
+		len = (data[0] & 0x0000ffff) + 2;
+		if (len < opcodes_3d_1d[opcode].min_len ||
+		    len > opcodes_3d_1d[opcode].max_len)
+		{
+		    fprintf(out, "Bad count in %s\n",
+			    opcodes_3d_1d[opcode].name);
+		    (*failures)++;
+		}
+	    }
+
+	    for (i = 1; i < len; i++) {
+		if (i >= count)
+		    BUFFER_FAIL(count, len,  opcodes_3d_1d[opcode].name);
+		instr_out(data, hw_offset, i, "dword %d\n", i);
+	    }
+
+	    return len;
+	}
+    }
+
+    instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
+    (*failures)++;
+    return 1;
+}
+
+static int
+decode_3d_primitive(const uint32_t *data, int count, uint32_t hw_offset,
+		    int *failures)
+{
+    char immediate = (data[0] & (1 << 23)) == 0;
+    unsigned int len, i;
+    char *primtype;
+
+    switch ((data[0] >> 18) & 0xf) {
+    case 0x0: primtype = "TRILIST"; break;
+    case 0x1: primtype = "TRISTRIP"; break;
+    case 0x2: primtype = "TRISTRIP_REVERSE"; break;
+    case 0x3: primtype = "TRIFAN"; break;
+    case 0x4: primtype = "POLYGON"; break;
+    case 0x5: primtype = "LINELIST"; break;
+    case 0x6: primtype = "LINESTRIP"; break;
+    case 0x7: primtype = "RECTLIST"; break;
+    case 0x8: primtype = "POINTLIST"; break;
+    case 0x9: primtype = "DIB"; break;
+    case 0xa: primtype = "CLEAR_RECT"; break;
+    default: primtype = "unknown"; break;
+    }
+
+    /* XXX: 3DPRIM_DIB not supported */
+    if (immediate) {
+	len = (data[0] & 0x0003ffff) + 2;
+	instr_out(data, hw_offset, 0, "3DPRIMITIVE inline %s\n", primtype);
+	if (count < len)
+	    BUFFER_FAIL(count, len,  "3DPRIMITIVE inline");
+	if (!saved_s2_set || !saved_s4_set) {
+	    fprintf(out, "unknown vertex format\n");
+	    for (i = 1; i < len; i++) {
+		instr_out(data, hw_offset, i,
+			  "           vertex data (%f float)\n",
+			  int_as_float(data[i]));
+	    }
+	} else {
+	    unsigned int vertex = 0;
+	    for (i = 1; i < len;) {
+		unsigned int tc;
+
+#define VERTEX_OUT(fmt, ...) do {					\
+    if (i < len)							\
+	instr_out(data, hw_offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \
+    else								\
+	fprintf(out, " missing data in V%d\n", vertex);			\
+    i++;								\
+} while (0)
+
+		VERTEX_OUT("X = %f", int_as_float(data[i]));
+		VERTEX_OUT("Y = %f", int_as_float(data[i]));
+	        switch (saved_s4 >> 6 & 0x7) {
+		case 0x1:
+		    VERTEX_OUT("Z = %f", int_as_float(data[i]));
+		    break;
+		case 0x2:
+		    VERTEX_OUT("Z = %f", int_as_float(data[i]));
+		    VERTEX_OUT("W = %f", int_as_float(data[i]));
+		    break;
+		case 0x3:
+		    break;
+		case 0x4:
+		    VERTEX_OUT("W = %f", int_as_float(data[i]));
+		    break;
+		default:
+		    fprintf(out, "bad S4 position mask\n");
+		}
+
+		if (saved_s4 & (1 << 10)) {
+		    VERTEX_OUT("color = (A=0x%02x, R=0x%02x, G=0x%02x, "
+			       "B=0x%02x)",
+			       data[i] >> 24,
+			       (data[i] >> 16) & 0xff,
+			       (data[i] >> 8) & 0xff,
+			       data[i] & 0xff);
+		}
+		if (saved_s4 & (1 << 11)) {
+		    VERTEX_OUT("spec = (A=0x%02x, R=0x%02x, G=0x%02x, "
+			       "B=0x%02x)",
+			       data[i] >> 24,
+			       (data[i] >> 16) & 0xff,
+			       (data[i] >> 8) & 0xff,
+			       data[i] & 0xff);
+		}
+		if (saved_s4 & (1 << 12))
+		    VERTEX_OUT("width = 0x%08x)", data[i]);
+
+		for (tc = 0; tc <= 7; tc++) {
+		    switch ((saved_s2 >> (tc * 4)) & 0xf) {
+		    case 0x0:
+			VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i]));
+			VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i]));
+			break;
+		    case 0x1:
+			VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i]));
+			VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i]));
+			VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i]));
+			break;
+		    case 0x2:
+			VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i]));
+			VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i]));
+			VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i]));
+			VERTEX_OUT("T%d.W = %f", tc, int_as_float(data[i]));
+			break;
+		    case 0x3:
+			VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i]));
+			break;
+		    case 0x4:
+			VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]);
+			break;
+		    case 0x5:
+			VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]);
+			VERTEX_OUT("T%d.ZW = 0x%08x half-float", tc, data[i]);
+			break;
+		    case 0xf:
+			break;
+		    default:
+			fprintf(out, "bad S2.T%d format\n", tc);
+		    }
+		}
+		vertex++;
+	    }
+	}
+    } else {
+	/* indirect vertices */
+	len = data[0] & 0x0000ffff; /* index count */
+	if (data[0] & (1 << 17)) {
+	    /* random vertex access */
+	    if (count < (len + 1) / 2 + 1) {
+		BUFFER_FAIL(count, (len + 1) / 2 + 1,
+			    "3DPRIMITIVE random indirect");
+	    }
+	    instr_out(data, hw_offset, 0,
+		      "3DPRIMITIVE random indirect %s (%d)\n", primtype, len);
+	    if (len == 0) {
+		/* vertex indices continue until 0xffff is found */
+		for (i = 1; i < count; i++) {
+		    if ((data[i] & 0xffff) == 0xffff) {
+			instr_out(data, hw_offset, i,
+				  "            indices: (terminator)\n");
+			return i;
+		    } else if ((data[i] >> 16) == 0xffff) {
+			instr_out(data, hw_offset, i,
+				  "            indices: 0x%04x, "
+				  "(terminator)\n",
+				  data[i] & 0xffff);
+			return i;
+		    } else {
+			instr_out(data, hw_offset, i,
+				  "            indices: 0x%04x, 0x%04x\n",
+				  data[i] & 0xffff, data[i] >> 16);
+		    }
+		}
+		fprintf(out,
+			"3DPRIMITIVE: no terminator found in index buffer\n");
+		(*failures)++;
+		return count;
+	    } else {
+		/* fixed size vertex index buffer */
+		for (i = 0; i < len; i += 2) {
+		    if (i * 2 == len - 1) {
+			instr_out(data, hw_offset, i,
+				  "            indices: 0x%04x\n",
+				  data[i] & 0xffff);
+		    } else {
+			instr_out(data, hw_offset, i,
+				  "            indices: 0x%04x, 0x%04x\n",
+				  data[i] & 0xffff, data[i] >> 16);
+		    }
+		}
+	    }
+	    return (len + 1) / 2 + 1;
+	} else {
+	    /* sequential vertex access */
+	    if (count < 2)
+		BUFFER_FAIL(count, 2, "3DPRIMITIVE seq indirect");
+	    instr_out(data, hw_offset, 0,
+		      "3DPRIMITIVE sequential indirect %s, %d starting from "
+		      "%d\n", primtype, len, data[1] & 0xffff);
+	    instr_out(data, hw_offset, 1, "           start\n");
+	    return 2;
+	}
+    }
+
+    return len;
+}
+
+static int
+decode_3d(const uint32_t *data, int count, uint32_t hw_offset, int *failures)
+{
+    unsigned int opcode;
+
+    struct {
+	uint32_t opcode;
+	int min_len;
+	int max_len;
+	char *name;
+    } opcodes_3d[] = {
+	{ 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" },
+	{ 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" },
+	{ 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" },
+	{ 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" },
+	{ 0x15, 1, 1, "3DSTATE_FOG_COLOR" },
+	{ 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" },
+	{ 0x0d, 1, 1, "3DSTATE_MODES_4" },
+	{ 0x0c, 1, 1, "3DSTATE_MODES_5" },
+	{ 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" },
+    };
+
+    switch ((data[0] & 0x1f000000) >> 24) {
+    case 0x1f:
+	return decode_3d_primitive(data, count, hw_offset, failures);
+    case 0x1d:
+	return decode_3d_1d(data, count, hw_offset, failures, 0);
+    case 0x1c:
+	return decode_3d_1c(data, count, hw_offset, failures);
+    }
+
+    for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]);
+	 opcode++) {
+	if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) {
+	    unsigned int len = 1, i;
+
+	    instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name);
+	    if (opcodes_3d[opcode].max_len > 1) {
+		len = (data[0] & 0xff) + 2;
+		if (len < opcodes_3d[opcode].min_len ||
+		    len > opcodes_3d[opcode].max_len)
+		{
+		    fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name);
+		}
+	    }
+
+	    for (i = 1; i < len; i++) {
+		if (i >= count)
+		    BUFFER_FAIL(count, len, opcodes_3d[opcode].name);
+		instr_out(data, hw_offset, i, "dword %d\n", i);
+	    }
+	    return len;
+	}
+    }
+
+    instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
+    (*failures)++;
+    return 1;
+}
+
+static const char *
+get_965_surfacetype(unsigned int surfacetype)
+{
+    switch (surfacetype) {
+    case 0: return "1D";
+    case 1: return "2D";
+    case 2: return "3D";
+    case 3: return "CUBE";
+    case 4: return "BUFFER";
+    case 7: return "NULL";
+    default: return "unknown";
+    }
+}
+
+static const char *
+get_965_depthformat(unsigned int depthformat)
+{
+    switch (depthformat) {
+    case 0: return "s8_z24float";
+    case 1: return "z32float";
+    case 2: return "z24s8";
+    case 5: return "z16";
+    default: return "unknown";
+    }
+}
+
+static const char *
+get_965_element_component(uint32_t data, int component)
+{
+    uint32_t component_control = (data >> (16 + (3 - component) * 4)) & 0x7;
+
+    switch (component_control) {
+    case 0:
+	return "nostore";
+    case 1:
+	switch (component) {
+	case 0: return "X";
+	case 1: return "Y";
+	case 2: return "Z";
+	case 3: return "W";
+	default: return "fail";
+	}
+    case 2:
+	return "0.0";
+    case 3:
+	return "1.0";
+    case 4:
+	return "0x1";
+    case 5:
+	return "VID";
+    default:
+	return "fail";
+    }
+}
+
+static const char *
+get_965_prim_type(uint32_t data)
+{
+    uint32_t primtype = (data >> 10) & 0x1f;
+
+    switch (primtype) {
+    case 0x01: return "point list";
+    case 0x02: return "line list";
+    case 0x03: return "line strip";
+    case 0x04: return "tri list";
+    case 0x05: return "tri strip";
+    case 0x06: return "tri fan";
+    case 0x07: return "quad list";
+    case 0x08: return "quad strip";
+    case 0x09: return "line list adj";
+    case 0x0a: return "line strip adj";
+    case 0x0b: return "tri list adj";
+    case 0x0c: return "tri strip adj";
+    case 0x0d: return "tri strip reverse";
+    case 0x0e: return "polygon";
+    case 0x0f: return "rect list";
+    case 0x10: return "line loop";
+    case 0x11: return "point list bf";
+    case 0x12: return "line strip cont";
+    case 0x13: return "line strip bf";
+    case 0x14: return "line strip cont bf";
+    case 0x15: return "tri fan no stipple";
+    default: return "fail";
+    }
+}
+
+static int
+decode_3d_965(const uint32_t *data, int count, uint32_t hw_offset, int *failures)
+{
+    unsigned int opcode, len;
+    int i;
+
+    struct {
+	uint32_t opcode;
+	int min_len;
+	int max_len;
+	char *name;
+    } opcodes_3d[] = {
+	{ 0x6000, 3, 3, "URB_FENCE" },
+	{ 0x6001, 2, 2, "CS_URB_STATE" },
+	{ 0x6002, 2, 2, "CONSTANT_BUFFER" },
+	{ 0x6101, 6, 6, "STATE_BASE_ADDRESS" },
+	{ 0x6102, 2, 2 , "STATE_SIP" },
+	{ 0x6104, 1, 1, "3DSTATE_PIPELINE_SELECT" },
+	{ 0x680b, 1, 1, "3DSTATE_VF_STATISTICS" },
+	{ 0x6904, 1, 1, "3DSTATE_PIPELINE_SELECT" },
+	{ 0x7800, 7, 7, "3DSTATE_PIPELINED_POINTERS" },
+	{ 0x7801, 6, 6, "3DSTATE_BINDING_TABLE_POINTERS" },
+	{ 0x780b, 1, 1, "3DSTATE_VF_STATISTICS" },
+	{ 0x7808, 5, 257, "3DSTATE_VERTEX_BUFFERS" },
+	{ 0x7809, 3, 256, "3DSTATE_VERTEX_ELEMENTS" },
+	{ 0x780a, 3, 3, "3DSTATE_INDEX_BUFFER" },
+	{ 0x7900, 4, 4, "3DSTATE_DRAWING_RECTANGLE" },
+	{ 0x7901, 5, 5, "3DSTATE_CONSTANT_COLOR" },
+	{ 0x7905, 5, 7, "3DSTATE_DEPTH_BUFFER" },
+	{ 0x7906, 2, 2, "3DSTATE_POLY_STIPPLE_OFFSET" },
+	{ 0x7907, 33, 33, "3DSTATE_POLY_STIPPLE_PATTERN" },
+	{ 0x7908, 3, 3, "3DSTATE_LINE_STIPPLE" },
+	{ 0x7909, 2, 2, "3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP" },
+	{ 0x790a, 3, 3, "3DSTATE_AA_LINE_PARAMETERS" },
+	{ 0x7b00, 6, 6, "3DPRIMITIVE" },
+    };
+
+    len = (data[0] & 0x0000ffff) + 2;
+
+    switch ((data[0] & 0xffff0000) >> 16) {
+    case 0x6101:
+	if (len != 6)
+	    fprintf(out, "Bad count in STATE_BASE_ADDRESS\n");
+	if (count < 6)
+	    BUFFER_FAIL(count, len, "STATE_BASE_ADDRESS");
+
+	instr_out(data, hw_offset, 0,
+		  "STATE_BASE_ADDRESS\n");
+
+	if (data[1] & 1) {
+	    instr_out(data, hw_offset, 1, "General state at 0x%08x\n",
+		      data[1] & ~1);
+	} else
+	    instr_out(data, hw_offset, 1, "General state not updated\n");
+
+	if (data[2] & 1) {
+	    instr_out(data, hw_offset, 2, "Surface state at 0x%08x\n",
+		      data[2] & ~1);
+	} else
+	    instr_out(data, hw_offset, 2, "Surface state not updated\n");
+
+	if (data[3] & 1) {
+	    instr_out(data, hw_offset, 3, "Indirect state at 0x%08x\n",
+		      data[3] & ~1);
+	} else
+	    instr_out(data, hw_offset, 3, "Indirect state not updated\n");
+
+	if (data[4] & 1) {
+	    instr_out(data, hw_offset, 4, "General state upper bound 0x%08x\n",
+		      data[4] & ~1);
+	} else
+	    instr_out(data, hw_offset, 4, "General state not updated\n");
+
+	if (data[5] & 1) {
+	    instr_out(data, hw_offset, 5, "Indirect state upper bound 0x%08x\n",
+		      data[5] & ~1);
+	} else
+	    instr_out(data, hw_offset, 5, "Indirect state not updated\n");
+
+	return len;
+    case 0x7800:
+	if (len != 7)
+	    fprintf(out, "Bad count in 3DSTATE_PIPELINED_POINTERS\n");
+	if (count < 7)
+	    BUFFER_FAIL(count, len, "3DSTATE_PIPELINED_POINTERS");
+
+	instr_out(data, hw_offset, 0,
+		  "3DSTATE_PIPELINED_POINTERS\n");
+	instr_out(data, hw_offset, 1, "VS state\n");
+	instr_out(data, hw_offset, 2, "GS state\n");
+	instr_out(data, hw_offset, 3, "Clip state\n");
+	instr_out(data, hw_offset, 4, "SF state\n");
+	instr_out(data, hw_offset, 5, "WM state\n");
+	instr_out(data, hw_offset, 6, "CC state\n");
+	return len;
+    case 0x7801:
+	if (len != 6)
+	    fprintf(out, "Bad count in 3DSTATE_BINDING_TABLE_POINTERS\n");
+	if (count < 6)
+	    BUFFER_FAIL(count, len, "3DSTATE_BINDING_TABLE_POINTERS");
+
+	instr_out(data, hw_offset, 0,
+		  "3DSTATE_BINDING_TABLE_POINTERS\n");
+	instr_out(data, hw_offset, 1, "VS binding table\n");
+	instr_out(data, hw_offset, 2, "GS binding table\n");
+	instr_out(data, hw_offset, 3, "Clip binding table\n");
+	instr_out(data, hw_offset, 4, "SF binding table\n");
+	instr_out(data, hw_offset, 5, "WM binding table\n");
+
+	return len;
+
+    case 0x7808:
+	len = (data[0] & 0xff) + 2;
+	if ((len - 1) % 4 != 0)
+	    fprintf(out, "Bad count in 3DSTATE_VERTEX_BUFFERS\n");
+	if (count < len)
+	    BUFFER_FAIL(count, len, "3DSTATE_VERTEX_BUFFERS");
+	instr_out(data, hw_offset, 0, "3DSTATE_VERTEX_BUFFERS\n");
+
+	for (i = 1; i < len;) {
+	    instr_out(data, hw_offset, i, "buffer %d: %s, pitch %db\n",
+		      data[i] >> 27,
+		      data[i] & (1 << 26) ? "random" : "sequential",
+		      data[i] & 0x07ff);
+	    i++;
+	    instr_out(data, hw_offset, i++, "buffer address\n");
+	    instr_out(data, hw_offset, i++, "max index\n");
+	    instr_out(data, hw_offset, i++, "mbz\n");
+	}
+	return len;
+
+    case 0x7809:
+	len = (data[0] & 0xff) + 2;
+	if ((len + 1) % 2 != 0)
+	    fprintf(out, "Bad count in 3DSTATE_VERTEX_ELEMENTS\n");
+	if (count < len)
+	    BUFFER_FAIL(count, len, "3DSTATE_VERTEX_ELEMENTS");
+	instr_out(data, hw_offset, 0, "3DSTATE_VERTEX_ELEMENTS\n");
+
+	for (i = 1; i < len;) {
+	    instr_out(data, hw_offset, i, "buffer %d: %svalid, type 0x%04x, "
+		      "src offset 0x%04x bytes\n",
+		      data[i] >> 27,
+		      data[i] & (1 << 26) ? "" : "in",
+		      (data[i] >> 16) & 0x1ff,
+		      data[i] & 0x07ff);
+	    i++;
+	    instr_out(data, hw_offset, i, "(%s, %s, %s, %s), "
+		      "dst offset 0x%02x bytes\n",
+		      get_965_element_component(data[i], 0),
+		      get_965_element_component(data[i], 1),
+		      get_965_element_component(data[i], 2),
+		      get_965_element_component(data[i], 3),
+		      (data[i] & 0xff) * 4);
+	    i++;
+	}
+	return len;
+
+    case 0x780a:
+	len = (data[0] & 0xff) + 2;
+	if (len != 3)
+	    fprintf(out, "Bad count in 3DSTATE_INDEX_BUFFER\n");
+	if (count < len)
+	    BUFFER_FAIL(count, len, "3DSTATE_INDEX_BUFFER");
+	instr_out(data, hw_offset, 0, "3DSTATE_INDEX_BUFFER\n");
+	instr_out(data, hw_offset, 1, "beginning buffer address\n");
+	instr_out(data, hw_offset, 2, "ending buffer address\n");
+	return len;
+
+    case 0x7900:
+	if (len != 4)
+	    fprintf(out, "Bad count in 3DSTATE_DRAWING_RECTANGLE\n");
+	if (count < 4)
+	    BUFFER_FAIL(count, len, "3DSTATE_DRAWING_RECTANGLE");
+
+	instr_out(data, hw_offset, 0,
+		  "3DSTATE_DRAWING_RECTANGLE\n");
+	instr_out(data, hw_offset, 1, "top left: %d,%d\n",
+		  data[1] & 0xffff,
+		  (data[1] >> 16) & 0xffff);
+	instr_out(data, hw_offset, 2, "bottom right: %d,%d\n",
+		  data[2] & 0xffff,
+		  (data[2] >> 16) & 0xffff);
+	instr_out(data, hw_offset, 3, "origin: %d,%d\n",
+		  (int)data[3] & 0xffff,
+		  ((int)data[3] >> 16) & 0xffff);
+
+	return len;
+
+    case 0x7905:
+	if (len != 5 && len != 6)
+	    fprintf(out, "Bad count in 3DSTATE_DEPTH_BUFFER\n");
+	if (count < len)
+	    BUFFER_FAIL(count, len, "3DSTATE_DEPTH_BUFFER");
+
+	instr_out(data, hw_offset, 0,
+		  "3DSTATE_DEPTH_BUFFER\n");
+	instr_out(data, hw_offset, 1, "%s, %s, pitch = %d bytes, %stiled\n",
+		  get_965_surfacetype(data[1] >> 29),
+		  get_965_depthformat((data[1] >> 18) & 0x7),
+		  (data[1] & 0x0001ffff) + 1,
+		  data[1] & (1 << 27) ? "" : "not ");
+	instr_out(data, hw_offset, 2, "depth offset\n");
+	instr_out(data, hw_offset, 3, "%dx%d\n",
+		  ((data[3] & 0x0007ffc0) >> 6) + 1,
+		  ((data[3] & 0xfff80000) >> 19) + 1);
+	instr_out(data, hw_offset, 4, "volume depth\n");
+	if (len == 6)
+	    instr_out(data, hw_offset, 5, "\n");
+
+	return len;
+
+    case 0x7b00:
+	len = (data[0] & 0xff) + 2;
+	if (len != 6)
+	    fprintf(out, "Bad count in 3DPRIMITIVE\n");
+	if (count < len)
+	    BUFFER_FAIL(count, len, "3DPRIMITIVE");
+
+	instr_out(data, hw_offset, 0,
+		  "3DPRIMITIVE: %s %s\n",
+		  get_965_prim_type(data[0]),
+		  (data[0] & (1 << 15)) ? "random" : "sequential");
+	instr_out(data, hw_offset, 1, "vertex count\n");
+	instr_out(data, hw_offset, 2, "start vertex\n");
+	instr_out(data, hw_offset, 3, "instance count\n");
+	instr_out(data, hw_offset, 4, "start instance\n");
+	instr_out(data, hw_offset, 5, "index bias\n");
+	return len;
+    }
+
+    for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]);
+	 opcode++) {
+	if ((data[0] & 0xffff0000) >> 16 == opcodes_3d[opcode].opcode) {
+	    unsigned int i;
+	    len = 1;
+
+	    instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name);
+	    if (opcodes_3d[opcode].max_len > 1) {
+		len = (data[0] & 0xff) + 2;
+		if (len < opcodes_3d[opcode].min_len ||
+		    len > opcodes_3d[opcode].max_len)
+		{
+		    fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name);
+		}
+	    }
+
+	    for (i = 1; i < len; i++) {
+		if (i >= count)
+		    BUFFER_FAIL(count, len, opcodes_3d[opcode].name);
+		instr_out(data, hw_offset, i, "dword %d\n", i);
+	    }
+	    return len;
+	}
+    }
+
+    instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
+    (*failures)++;
+    return 1;
+}
+
+static int
+decode_3d_i830(const uint32_t *data, int count, uint32_t hw_offset, int *failures)
+{
+    unsigned int opcode;
+
+    struct {
+	uint32_t opcode;
+	int min_len;
+	int max_len;
+	char *name;
+    } opcodes_3d[] = {
+	{ 0x02, 1, 1, "3DSTATE_MODES_3" },
+	{ 0x03, 1, 1, "3DSTATE_ENABLES_1"},
+	{ 0x04, 1, 1, "3DSTATE_ENABLES_2"},
+	{ 0x05, 1, 1, "3DSTATE_VFT0"},
+	{ 0x06, 1, 1, "3DSTATE_AA"},
+	{ 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" },
+	{ 0x08, 1, 1, "3DSTATE_MODES_1" },
+	{ 0x09, 1, 1, "3DSTATE_STENCIL_TEST" },
+	{ 0x0a, 1, 1, "3DSTATE_VFT1"},
+	{ 0x0b, 1, 1, "3DSTATE_INDPT_ALPHA_BLEND" },
+	{ 0x0c, 1, 1, "3DSTATE_MODES_5" },
+	{ 0x0d, 1, 1, "3DSTATE_MAP_BLEND_OP" },
+	{ 0x0e, 1, 1, "3DSTATE_MAP_BLEND_ARG" },
+	{ 0x0f, 1, 1, "3DSTATE_MODES_2" },
+	{ 0x15, 1, 1, "3DSTATE_FOG_COLOR" },
+	{ 0x16, 1, 1, "3DSTATE_MODES_4" },
+    };
+
+    switch ((data[0] & 0x1f000000) >> 24) {
+    case 0x1f:
+	return decode_3d_primitive(data, count, hw_offset, failures);
+    case 0x1d:
+	return decode_3d_1d(data, count, hw_offset, failures, 1);
+    case 0x1c:
+	return decode_3d_1c(data, count, hw_offset, failures);
+    }
+
+    for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]);
+	 opcode++) {
+	if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) {
+	    unsigned int len = 1, i;
+
+	    instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name);
+	    if (opcodes_3d[opcode].max_len > 1) {
+		len = (data[0] & 0xff) + 2;
+		if (len < opcodes_3d[opcode].min_len ||
+		    len > opcodes_3d[opcode].max_len)
+		{
+		    fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name);
+		}
+	    }
+
+	    for (i = 1; i < len; i++) {
+		if (i >= count)
+		    BUFFER_FAIL(count, len, opcodes_3d[opcode].name);
+		instr_out(data, hw_offset, i, "dword %d\n", i);
+	    }
+	    return len;
+	}
+    }
+
+    instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
+    (*failures)++;
+    return 1;
+}
+
+/**
+ * Decodes an i830-i915 batch buffer, writing the output to stdout.
+ *
+ * \param data batch buffer contents
+ * \param count number of DWORDs to decode in the batch buffer
+ * \param hw_offset hardware address for the buffer
+ */
+int
+intel_decode(const uint32_t *data, int count, uint32_t hw_offset, uint32_t devid)
+{
+    int index = 0;
+    int failures = 0;
+
+    out = stderr;
+
+    while (index < count) {
+	switch ((data[index] & 0xe0000000) >> 29) {
+	case 0x0:
+	    index += decode_mi(data + index, count - index,
+			       hw_offset + index * 4, &failures);
+	    break;
+	case 0x2:
+	    index += decode_2d(data + index, count - index,
+			       hw_offset + index * 4, &failures);
+	    break;
+	case 0x3:
+	    if (IS_965(devid)) {
+		index += decode_3d_965(data + index, count - index,
+				       hw_offset + index * 4, &failures);
+	    } else if (IS_9XX(devid)) {
+		index += decode_3d(data + index, count - index,
+				   hw_offset + index * 4, &failures);
+	    } else {
+		index += decode_3d_i830(data + index, count - index,
+					hw_offset + index * 4, &failures);
+	    }
+	    break;
+	default:
+	    instr_out(data, hw_offset, index, "UNKNOWN\n");
+	    failures++;
+	    index++;
+	    break;
+	}
+	fflush(out);
+    }
+
+    return failures;
+}
+
+void intel_decode_context_reset(void)
+{
+    saved_s2_set = 0;
+    saved_s4_set = 1;
+}
+
diff --git a/src/gallium/drivers/i965/intel_decode.h b/src/gallium/drivers/i965/intel_decode.h
new file mode 100644
index 0000000..7683097
--- /dev/null
+++ b/src/gallium/drivers/i965/intel_decode.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * 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, sublicense,
+ * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ */
+
+int intel_decode(const uint32_t *data, int count, uint32_t hw_offset, uint32_t devid);
+void intel_decode_context_reset(void);
diff --git a/src/gallium/drivers/i965/intel_structs.h b/src/gallium/drivers/i965/intel_structs.h
new file mode 100644
index 0000000..522e3bd
--- /dev/null
+++ b/src/gallium/drivers/i965/intel_structs.h
@@ -0,0 +1,132 @@
+#ifndef INTEL_STRUCTS_H
+#define INTEL_STRUCTS_H
+
+struct br0 {
+   GLuint length:8;
+   GLuint pad0:3;
+   GLuint dst_tiled:1;
+   GLuint pad1:8;
+   GLuint write_rgb:1;
+   GLuint write_alpha:1;
+   GLuint opcode:7;
+   GLuint client:3;
+};
+
+   
+struct br13 {
+   GLint dest_pitch:16;
+   GLuint rop:8;
+   GLuint color_depth:2;
+   GLuint pad1:3;
+   GLuint mono_source_transparency:1;
+   GLuint clipping_enable:1;
+   GLuint pad0:1;
+};
+
+
+
+/* This is an attempt to move some of the 2D interaction in this
+ * driver to using structs for packets rather than a bunch of #defines
+ * and dwords.
+ */
+struct xy_color_blit {
+   struct br0 br0;
+   struct br13 br13;
+
+   struct {
+      GLuint dest_x1:16;
+      GLuint dest_y1:16;
+   } dw2;
+
+   struct {
+      GLuint dest_x2:16;
+      GLuint dest_y2:16;
+   } dw3;
+   
+   GLuint dest_base_addr;
+   GLuint color;
+};
+
+struct xy_src_copy_blit {
+   struct br0 br0;
+   struct br13 br13;
+
+   struct {
+      GLuint dest_x1:16;
+      GLuint dest_y1:16;
+   } dw2;
+
+   struct {
+      GLuint dest_x2:16;
+      GLuint dest_y2:16;
+   } dw3;
+   
+   GLuint dest_base_addr;
+
+   struct {
+      GLuint src_x1:16;
+      GLuint src_y1:16;
+   } dw5;
+
+   struct {
+      GLint src_pitch:16;
+      GLuint pad:16;
+   } dw6;
+   
+   GLuint src_base_addr;
+};
+
+struct xy_setup_blit {
+   struct br0 br0;
+   struct br13 br13;
+
+   struct {
+      GLuint clip_x1:16;
+      GLuint clip_y1:16;
+   } dw2;
+
+   struct {
+      GLuint clip_x2:16;
+      GLuint clip_y2:16;
+   } dw3;
+      
+   GLuint dest_base_addr;
+   GLuint background_color;
+   GLuint foreground_color;
+   GLuint pattern_base_addr;
+};
+
+
+struct xy_text_immediate_blit {
+   struct {
+      GLuint length:8;
+      GLuint pad2:3;
+      GLuint dst_tiled:1;
+      GLuint pad1:4;
+      GLuint byte_packed:1;
+      GLuint pad0:5;
+      GLuint opcode:7;
+      GLuint client:3;
+   } dw0;
+
+   struct {
+      GLuint dest_x1:16;
+      GLuint dest_y1:16;
+   } dw1;
+
+   struct {
+      GLuint dest_x2:16;
+      GLuint dest_y2:16;
+   } dw2;   
+
+   /* Src bitmap data follows as inline dwords.
+    */
+};
+
+
+#define CLIENT_2D 0x2
+#define OPCODE_XY_SETUP_BLT 0x1
+#define OPCODE_XY_COLOR_BLT 0x50
+#define OPCODE_XY_TEXT_IMMEDIATE_BLT 0x31
+
+#endif
diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c
index 4e70008..9f5b4e6 100644
--- a/src/gallium/drivers/identity/id_context.c
+++ b/src/gallium/drivers/identity/id_context.c
@@ -46,17 +46,6 @@
 }
 
 static void
-identity_set_edgeflags(struct pipe_context *_pipe,
-                       const unsigned *bitfield)
-{
-   struct identity_context *id_pipe = identity_context(_pipe);
-   struct pipe_context *pipe = id_pipe->pipe;
-
-   pipe->set_edgeflags(pipe,
-                       bitfield);
-}
-
-static boolean
 identity_draw_arrays(struct pipe_context *_pipe,
                      unsigned prim,
                      unsigned start,
@@ -65,13 +54,13 @@
    struct identity_context *id_pipe = identity_context(_pipe);
    struct pipe_context *pipe = id_pipe->pipe;
 
-   return pipe->draw_arrays(pipe,
-                            prim,
-                            start,
-                            count);
+   pipe->draw_arrays(pipe,
+                     prim,
+                     start,
+                     count);
 }
 
-static boolean
+static void
 identity_draw_elements(struct pipe_context *_pipe,
                        struct pipe_buffer *_indexBuffer,
                        unsigned indexSize,
@@ -84,15 +73,15 @@
    struct pipe_context *pipe = id_pipe->pipe;
    struct pipe_buffer *indexBuffer = id_buffer->buffer;
 
-   return pipe->draw_elements(pipe,
-                              indexBuffer,
-                              indexSize,
-                              prim,
-                              start,
-                              count);
+   pipe->draw_elements(pipe,
+                       indexBuffer,
+                       indexSize,
+                       prim,
+                       start,
+                       count);
 }
 
-static boolean
+static void
 identity_draw_range_elements(struct pipe_context *_pipe,
                              struct pipe_buffer *_indexBuffer,
                              unsigned indexSize,
@@ -107,14 +96,14 @@
    struct pipe_context *pipe = id_pipe->pipe;
    struct pipe_buffer *indexBuffer = id_buffer->buffer;
 
-   return pipe->draw_range_elements(pipe,
-                                    indexBuffer,
-                                    indexSize,
-                                    minIndex,
-                                    maxIndex,
-                                    mode,
-                                    start,
-                                    count);
+   pipe->draw_range_elements(pipe,
+                             indexBuffer,
+                             indexSize,
+                             minIndex,
+                             maxIndex,
+                             mode,
+                             start,
+                             count);
 }
 
 static struct pipe_query *
@@ -221,16 +210,29 @@
 }
 
 static void
-identity_bind_sampler_states(struct pipe_context *_pipe,
-                             unsigned num,
-                             void **samplers)
+identity_bind_fragment_sampler_states(struct pipe_context *_pipe,
+                                      unsigned num_samplers,
+                                      void **samplers)
 {
    struct identity_context *id_pipe = identity_context(_pipe);
    struct pipe_context *pipe = id_pipe->pipe;
 
-   pipe->bind_sampler_states(pipe,
-                             num,
-                             samplers);
+   pipe->bind_fragment_sampler_states(pipe,
+                                      num_samplers,
+                                      samplers);
+}
+
+static void
+identity_bind_vertex_sampler_states(struct pipe_context *_pipe,
+                                    unsigned num_samplers,
+                                    void **samplers)
+{
+   struct identity_context *id_pipe = identity_context(_pipe);
+   struct pipe_context *pipe = id_pipe->pipe;
+
+   pipe->bind_vertex_sampler_states(pipe,
+                                    num_samplers,
+                                    samplers);
 }
 
 static void
@@ -480,9 +482,9 @@
 }
 
 static void
-identity_set_sampler_textures(struct pipe_context *_pipe,
-                              unsigned num_textures,
-                              struct pipe_texture **_textures)
+identity_set_fragment_sampler_textures(struct pipe_context *_pipe,
+                                       unsigned num_textures,
+                                       struct pipe_texture **_textures)
 {
    struct identity_context *id_pipe = identity_context(_pipe);
    struct pipe_context *pipe = id_pipe->pipe;
@@ -499,9 +501,34 @@
       textures = unwrapped_textures;
    }
 
-   pipe->set_sampler_textures(pipe,
-                              num_textures,
-                              textures);
+   pipe->set_fragment_sampler_textures(pipe,
+                                       num_textures,
+                                       textures);
+}
+
+static void
+identity_set_vertex_sampler_textures(struct pipe_context *_pipe,
+                                     unsigned num_textures,
+                                     struct pipe_texture **_textures)
+{
+   struct identity_context *id_pipe = identity_context(_pipe);
+   struct pipe_context *pipe = id_pipe->pipe;
+   struct pipe_texture *unwrapped_textures[PIPE_MAX_VERTEX_SAMPLERS];
+   struct pipe_texture **textures = NULL;
+   unsigned i;
+
+   if (_textures) {
+      for (i = 0; i < num_textures; i++)
+         unwrapped_textures[i] = identity_texture_unwrap(_textures[i]);
+      for (; i < PIPE_MAX_VERTEX_SAMPLERS; i++)
+         unwrapped_textures[i] = NULL;
+
+      textures = unwrapped_textures;
+   }
+
+   pipe->set_vertex_sampler_textures(pipe,
+                                     num_textures,
+                                     textures);
 }
 
 static void
@@ -669,7 +696,6 @@
    id_pipe->base.draw = NULL;
 
    id_pipe->base.destroy = identity_destroy;
-   id_pipe->base.set_edgeflags = identity_set_edgeflags;
    id_pipe->base.draw_arrays = identity_draw_arrays;
    id_pipe->base.draw_elements = identity_draw_elements;
    id_pipe->base.draw_range_elements = identity_draw_range_elements;
@@ -682,7 +708,8 @@
    id_pipe->base.bind_blend_state = identity_bind_blend_state;
    id_pipe->base.delete_blend_state = identity_delete_blend_state;
    id_pipe->base.create_sampler_state = identity_create_sampler_state;
-   id_pipe->base.bind_sampler_states = identity_bind_sampler_states;
+   id_pipe->base.bind_fragment_sampler_states = identity_bind_fragment_sampler_states;
+   id_pipe->base.bind_vertex_sampler_states = identity_bind_vertex_sampler_states;
    id_pipe->base.delete_sampler_state = identity_delete_sampler_state;
    id_pipe->base.create_rasterizer_state = identity_create_rasterizer_state;
    id_pipe->base.bind_rasterizer_state = identity_bind_rasterizer_state;
@@ -703,7 +730,8 @@
    id_pipe->base.set_polygon_stipple = identity_set_polygon_stipple;
    id_pipe->base.set_scissor_state = identity_set_scissor_state;
    id_pipe->base.set_viewport_state = identity_set_viewport_state;
-   id_pipe->base.set_sampler_textures = identity_set_sampler_textures;
+   id_pipe->base.set_fragment_sampler_textures = identity_set_fragment_sampler_textures;
+   id_pipe->base.set_vertex_sampler_textures = identity_set_vertex_sampler_textures;
    id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers;
    id_pipe->base.set_vertex_elements = identity_set_vertex_elements;
    id_pipe->base.surface_copy = identity_surface_copy;
diff --git a/src/gallium/drivers/identity/id_objects.c b/src/gallium/drivers/identity/id_objects.c
index e893e59..bc9bc71 100644
--- a/src/gallium/drivers/identity/id_objects.c
+++ b/src/gallium/drivers/identity/id_objects.c
@@ -180,3 +180,42 @@
    screen->tex_transfer_destroy(id_transfer->transfer);
    FREE(id_transfer);
 }
+
+struct pipe_video_surface *
+identity_video_surface_create(struct identity_screen *id_screen,
+                              struct pipe_video_surface *video_surface)
+{
+   struct identity_video_surface *id_video_surface;
+
+   if (!video_surface) {
+      goto error;
+   }
+
+   assert(video_surface->screen == id_screen->screen);
+
+   id_video_surface = CALLOC_STRUCT(identity_video_surface);
+   if (!id_video_surface) {
+      goto error;
+   }
+
+   memcpy(&id_video_surface->base,
+          video_surface,
+          sizeof(struct pipe_video_surface));
+
+   pipe_reference_init(&id_video_surface->base.reference, 1);
+   id_video_surface->base.screen = &id_screen->base;
+   id_video_surface->video_surface = video_surface;
+
+   return &id_video_surface->base;
+
+error:
+   pipe_video_surface_reference(&video_surface, NULL);
+   return NULL;
+}
+
+void
+identity_video_surface_destroy(struct identity_video_surface *id_video_surface)
+{
+   pipe_video_surface_reference(&id_video_surface->video_surface, NULL);
+   FREE(id_video_surface);
+}
diff --git a/src/gallium/drivers/identity/id_objects.h b/src/gallium/drivers/identity/id_objects.h
index ce58faa..77cc719 100644
--- a/src/gallium/drivers/identity/id_objects.h
+++ b/src/gallium/drivers/identity/id_objects.h
@@ -31,6 +31,7 @@
 
 #include "pipe/p_compiler.h"
 #include "pipe/p_state.h"
+#include "pipe/p_video_state.h"
 
 #include "id_screen.h"
 
@@ -67,6 +68,14 @@
 };
 
 
+struct identity_video_surface
+{
+   struct pipe_video_surface base;
+
+   struct pipe_video_surface *video_surface;
+};
+
+
 static INLINE struct identity_buffer *
 identity_buffer(struct pipe_buffer *_buffer)
 {
@@ -103,6 +112,15 @@
    return (struct identity_transfer *)_transfer;
 }
 
+static INLINE struct identity_video_surface *
+identity_video_surface(struct pipe_video_surface *_video_surface)
+{
+   if (!_video_surface) {
+      return NULL;
+   }
+   (void)identity_screen(_video_surface->screen);
+   return (struct identity_video_surface *)_video_surface;
+}
 
 static INLINE struct pipe_buffer *
 identity_buffer_unwrap(struct pipe_buffer *_buffer)
@@ -165,5 +183,12 @@
 void
 identity_transfer_destroy(struct identity_transfer *id_transfer);
 
+struct pipe_video_surface *
+identity_video_surface_create(struct identity_screen *id_screen,
+                              struct pipe_video_surface *video_surface);
+
+void
+identity_video_surface_destroy(struct identity_video_surface *id_video_surface);
+
 
 #endif /* ID_OBJECTS_H */
diff --git a/src/gallium/drivers/identity/id_public.h b/src/gallium/drivers/identity/id_public.h
index cac14cf..3d2862e 100644
--- a/src/gallium/drivers/identity/id_public.h
+++ b/src/gallium/drivers/identity/id_public.h
@@ -37,4 +37,4 @@
 struct pipe_context *
 identity_context_create(struct pipe_screen *screen, struct pipe_context *pipe);
 
-#endif /* PT_PUBLIC_H */
+#endif /* ID_PUBLIC_H */
diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c
index 2643963..53eae3e 100644
--- a/src/gallium/drivers/identity/id_screen.c
+++ b/src/gallium/drivers/identity/id_screen.c
@@ -379,6 +379,33 @@
    identity_buffer_destroy(identity_buffer(_buffer));
 }
 
+static struct pipe_video_surface *
+identity_screen_video_surface_create(struct pipe_screen *_screen,
+                                     enum pipe_video_chroma_format chroma_format,
+                                     unsigned width,
+                                     unsigned height)
+{
+   struct identity_screen *id_screen = identity_screen(_screen);
+   struct pipe_screen *screen = id_screen->screen;
+   struct pipe_video_surface *result;
+
+   result = screen->video_surface_create(screen,
+                                         chroma_format,
+                                         width,
+                                         height);
+
+   if (result) {
+      return identity_video_surface_create(id_screen, result);
+   }
+   return NULL;
+}
+
+static void
+identity_screen_video_surface_destroy(struct pipe_video_surface *_vsfc)
+{
+   identity_video_surface_destroy(identity_video_surface(_vsfc));
+}
+
 static void
 identity_screen_flush_frontbuffer(struct pipe_screen *_screen,
                                   struct pipe_surface *_surface,
@@ -472,6 +499,12 @@
    if (screen->buffer_unmap)
       id_screen->base.buffer_unmap = identity_screen_buffer_unmap;
    id_screen->base.buffer_destroy = identity_screen_buffer_destroy;
+   if (screen->video_surface_create) {
+      id_screen->base.video_surface_create = identity_screen_video_surface_create;
+   }
+   if (screen->video_surface_destroy) {
+      id_screen->base.video_surface_destroy = identity_screen_video_surface_destroy;
+   }
    id_screen->base.flush_frontbuffer = identity_screen_flush_frontbuffer;
    id_screen->base.fence_reference = identity_screen_fence_reference;
    id_screen->base.fence_signalled = identity_screen_fence_signalled;
diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile
index e038a52..7c6e460 100644
--- a/src/gallium/drivers/llvmpipe/Makefile
+++ b/src/gallium/drivers/llvmpipe/Makefile
@@ -50,7 +50,6 @@
 	lp_state_vs.c \
 	lp_surface.c \
 	lp_tex_cache.c \
-	lp_tex_sample_c.c \
 	lp_tex_sample_llvm.c \
 	lp_texture.c \
 	lp_tile_cache.c \
diff --git a/src/gallium/drivers/llvmpipe/README b/src/gallium/drivers/llvmpipe/README
index 89d0883..72d9f39 100644
--- a/src/gallium/drivers/llvmpipe/README
+++ b/src/gallium/drivers/llvmpipe/README
@@ -51,47 +51,42 @@
 
  - Linux
  
- - udis86, http://udis86.sourceforge.net/ . Use my repository, which decodes
-   opcodes not yet supported by upstream.
+ - A x86 or amd64 processor.  64bit mode is preferred.
  
-     git clone git://people.freedesktop.org/~jrfonseca/udis86
+   Support for sse2 is strongly encouraged.  Support for ssse3, and sse4.1 will
+   yield the most efficient code.  The less features the CPU has the more
+   likely is that you ran into underperforming, buggy, or incomplete code.  
+   
+   See /proc/cpuinfo to know what your CPU supports.
+ 
+ - LLVM 2.6.
+ 
+   For Linux, on a recent Debian based distribution do:
+ 
+     aptitude install llvm-dev
+
+   For Windows download pre-built MSVC 9.0 or MinGW binaries from
+   http://people.freedesktop.org/~jrfonseca/llvm/ and set the LLVM environment
+   variable to the extracted path.
+
+ - scons (optional)
+
+ - udis86, http://udis86.sourceforge.net/ (optional):
+ 
+     git clone git://udis86.git.sourceforge.net/gitroot/udis86/udis86
      cd udis86
+     ./autogen.sh
      ./configure --with-pic
      make
      sudo make install
  
- - LLVM 2.5. On Debian based distributions do:
- 
-     aptitude install llvm-dev
-
-   There is a typo in one of the llvm-dev 2.5 headers, that causes compilation
-   errors in the debug build:
-
-     --- /usr/include/llvm-c/Core.h.orig	2009-08-10 15:38:54.000000000 +0100
-     +++ /usr/include/llvm-c/Core.h	2009-08-10 15:38:25.000000000 +0100
-     @@ -831,7 +831,7 @@
-        template<typename T>
-        inline T **unwrap(LLVMValueRef *Vals, unsigned Length) {
-          #if DEBUG
-     -    for (LLVMValueRef *I = Vals, E = Vals + Length; I != E; ++I)
-     +    for (LLVMValueRef *I = Vals, *E = Vals + Length; I != E; ++I)
-            cast<T>(*I);
-          #endif
-          return reinterpret_cast<T**>(Vals);
- 
- - A x86 or amd64 processor with support for sse2, sse3, and sse4.1 SIMD
-   instructions. This is necessary because we emit several SSE intrinsics for
-   convenience. See /proc/cpuinfo to know what your CPU supports.
- 
- - scons
-
 
 Building
 ========
 
-To build everything invoke scons as:
+To build everything on Linux invoke scons as:
 
-  scons debug=yes statetrackers=mesa drivers=llvmpipe winsys=xlib dri=false -k
+  scons debug=yes statetrackers=mesa drivers=trace,llvmpipe winsys=xlib dri=false
 
 Alternatively, you can build it with GNU make, if you prefer, by invoking it as
 
@@ -99,12 +94,15 @@
 
 but the rest of these instructions assume that scons is used.
 
+For windows is everything the except except the winsys:
+
+  scons debug=yes statetrackers=mesa drivers=trace,llvmpipe winsys=gdi dri=false
 
 Using
 =====
 
-Building will create a drop-in alternative for libGL.so. To use it set the
-environment variables:
+On Linux, building will create a drop-in alternative for libGL.so. To use it
+set the environment variables:
 
   export LD_LIBRARY_PATH=$PWD/build/linux-x86_64-debug/lib:$LD_LIBRARY_PATH
 
@@ -115,6 +113,11 @@
 For performance evaluation pass debug=no to scons, and use the corresponding
 lib directory without the "-debug" suffix.
 
+On Windows, building will create a drop-in alternative for opengl32.dll. To use
+it put it in the same directory as the application. It can also be used by
+replacing the native ICD driver, but it's quite an advanced usage, so if you
+need to ask, don't even try it.
+
 
 Unit testing
 ============
diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript
index 3bd2e70..6bb545a 100644
--- a/src/gallium/drivers/llvmpipe/SConscript
+++ b/src/gallium/drivers/llvmpipe/SConscript
@@ -9,6 +9,8 @@
 
 env.Tool('udis86')
 
+env.Append(CPPPATH = ['.'])
+
 env.CodeGenerate(
 	target = 'lp_tile_soa.c',
 	script = 'lp_tile_soa.py',
@@ -64,7 +66,6 @@
 		'lp_state_vs.c',
 		'lp_surface.c',
 		'lp_tex_cache.c',
-		'lp_tex_sample_c.c',
 		'lp_tex_sample_llvm.c',
 		'lp_texture.c',
 		'lp_tile_cache.c',
@@ -74,21 +75,19 @@
 
 env = env.Clone()
 
-env.Prepend(LIBS = [llvmpipe] + auxiliaries)
+env.Prepend(LIBS = [llvmpipe] + gallium)
 
-env.Program(
-    target = 'lp_test_format',
-    source = ['lp_test_format.c', 'lp_test_main.c'],
-)
+tests = [
+    'format',
+    'blend',
+    'conv',
+]
 
-env.Program(
-    target = 'lp_test_blend',
-    source = ['lp_test_blend.c', 'lp_test_main.c'],
-)
-
-env.Program(
-    target = 'lp_test_conv',
-    source = ['lp_test_conv.c', 'lp_test_main.c'],
-)
+for test in tests:
+    target = env.Program(
+        target = 'lp_test_' + test,
+        source = ['lp_test_' + test + '.c', 'lp_test_main.c'],
+    )
+    env.InstallProgram(target)
 
 Export('llvmpipe')
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.c b/src/gallium/drivers/llvmpipe/lp_bld_arit.c
index 9c59677..eea6b5d 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_arit.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.c
@@ -629,7 +629,8 @@
    if(type.floating) {
       /* Mask out the sign bit */
       LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
-      LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long)1 << type.width) - 1);
+      unsigned long absMask = ~(1 << (type.width - 1));
+      LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long) absMask));
       a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
       a = LLVMBuildAnd(bld->builder, a, mask, "");
       a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
@@ -1083,7 +1084,7 @@
              LLVMValueRef x)
 {
    /* log(2) */
-   LLVMValueRef log2 = lp_build_const_scalar(bld->type, 1.4426950408889634);
+   LLVMValueRef log2 = lp_build_const_scalar(bld->type, 0.69314718055994529);
 
    return lp_build_mul(bld, log2, lp_build_exp2(bld, x));
 }
@@ -1095,7 +1096,7 @@
 
 /**
  * Generate polynomial.
- * Ex:  x^2 * coeffs[0] + x * coeffs[1] + coeffs[2].
+ * Ex:  coeffs[0] + x * coeffs[1] + x^2 * coeffs[2].
  */
 static LLVMValueRef
 lp_build_polynomial(struct lp_build_context *bld,
@@ -1285,13 +1286,13 @@
       /* mant = (float) mantissa(x) */
       mant = LLVMBuildAnd(bld->builder, i, mantmask, "");
       mant = LLVMBuildOr(bld->builder, mant, one, "");
-      mant = LLVMBuildSIToFP(bld->builder, mant, vec_type, "");
+      mant = LLVMBuildBitCast(bld->builder, mant, vec_type, "");
 
       logmant = lp_build_polynomial(bld, mant, lp_build_log2_polynomial,
                                     Elements(lp_build_log2_polynomial));
 
       /* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/
-      logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildMul(bld->builder, mant, bld->one, ""), "");
+      logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildSub(bld->builder, mant, bld->one, ""), "");
 
       res = LLVMBuildAdd(bld->builder, logmant, logexp, "");
    }
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
index d14f468..ced7b9c 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
@@ -142,7 +142,7 @@
 
 enum lp_build_blend_swizzle {
    LP_BUILD_BLEND_SWIZZLE_RGBA = 0,
-   LP_BUILD_BLEND_SWIZZLE_AAAA = 1,
+   LP_BUILD_BLEND_SWIZZLE_AAAA = 1
 };
 
 
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_debug.c b/src/gallium/drivers/llvmpipe/lp_bld_debug.c
index 59d8f49..39dfc51 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_debug.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_debug.c
@@ -77,10 +77,10 @@
    while (ud_disassemble(&ud_obj)) {
 
 #ifdef PIPE_ARCH_X86
-      debug_printf("%08lx: ", (unsigned long)ud_insn_off(&ud_obj));
+      debug_printf("0x%08lx:\t", (unsigned long)ud_insn_off(&ud_obj));
 #endif
 #ifdef PIPE_ARCH_X86_64
-      debug_printf("%016llx: ", (unsigned long long)ud_insn_off(&ud_obj));
+      debug_printf("0x%016llx:\t", (unsigned long long)ud_insn_off(&ud_obj));
 #endif
 
 #if 0
@@ -115,9 +115,16 @@
          }
       }
 
-      if (ud_insn_off(&ud_obj) >= max_jmp_pc && ud_obj.mnemonic == UD_Iret)
+      if ((ud_insn_off(&ud_obj) >= max_jmp_pc && ud_obj.mnemonic == UD_Iret) ||
+           ud_obj.mnemonic == UD_Iinvalid)
          break;
    }
+
+#if 0
+   /* Print GDB command, useful to verify udis86 output */
+   debug_printf("disassemble %p %p\n", func, (void*)(uintptr_t)ud_obj.pc);
+#endif
+
    debug_printf("\n");
 #else
    (void)func;
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.c b/src/gallium/drivers/llvmpipe/lp_bld_depth.c
index 98ec1cb..d438c0e 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_depth.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.c
@@ -90,7 +90,7 @@
 
    if(format_desc->channel[swizzle].type == UTIL_FORMAT_TYPE_FLOAT) {
       type.floating = TRUE;
-      assert(swizzle = 0);
+      assert(swizzle == 0);
       assert(format_desc->channel[swizzle].size == format_desc->block.bits);
    }
    else if(format_desc->channel[swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED) {
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_flow.c b/src/gallium/drivers/llvmpipe/lp_bld_flow.c
index dcc25fb..25c10af 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_flow.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_flow.c
@@ -47,7 +47,7 @@
  */
 enum lp_build_flow_construct_kind {
    lP_BUILD_FLOW_SCOPE,
-   LP_BUILD_FLOW_SKIP,
+   LP_BUILD_FLOW_SKIP
 };
 
 
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c b/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c
index 5836e01..10e82f1 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c
@@ -130,7 +130,7 @@
 
    shifted = LLVMBuildLShr(builder, packed, LLVMConstVector(shifts, 4), "");
    masked = LLVMBuildAnd(builder, shifted, LLVMConstVector(masks, 4), "");
-   // UIToFP can't be expressed in SSE2
+   /* UIToFP can't be expressed in SSE2 */
    casted = LLVMBuildSIToFP(builder, masked, LLVMVectorType(LLVMFloatType(), 4), "");
 
    if (normalized)
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.c b/src/gallium/drivers/llvmpipe/lp_bld_interp.c
index 818c0e9..49dab8a 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_interp.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.c
@@ -303,8 +303,8 @@
             unsigned first, last, mask;
             unsigned attrib;
 
-            first = decl->DeclarationRange.First;
-            last = decl->DeclarationRange.Last;
+            first = decl->Range.First;
+            last = decl->Range.Last;
             mask = decl->Declaration.UsageMask;
 
             for( attrib = first; attrib <= last; ++attrib ) {
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_misc.cpp b/src/gallium/drivers/llvmpipe/lp_bld_misc.cpp
index c9acaf1..6e79438 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_misc.cpp
+++ b/src/gallium/drivers/llvmpipe/lp_bld_misc.cpp
@@ -26,8 +26,6 @@
  **************************************************************************/
 
 
-#include "llvm/Config/config.h"
-
 #include "pipe/p_config.h"
 
 #include "lp_bld_misc.h"
@@ -50,13 +48,28 @@
 extern "C" int X86TargetMachineModule;
 
 
-void
+int
 LLVMInitializeNativeTarget(void)
 {
 #if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
-   X86TargetMachineModule = 1;			
+   X86TargetMachineModule = 1;
 #endif
+   return 0;
 }
 
 
 #endif
+
+
+/* 
+ * Hack to allow the linking of release LLVM static libraries on a debug build.
+ *
+ * See also:
+ * - http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/7234ea2b-0042-42ed-b4e2-5d8644dfb57d
+ */
+#if defined(_MSC_VER) && defined(_DEBUG)
+#include <crtdefs.h>
+extern "C" {
+   _CRTIMP void __cdecl _invalid_parameter_noinfo(void) {}
+}
+#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_misc.h b/src/gallium/drivers/llvmpipe/lp_bld_misc.h
index 51a84c5..0e787e0 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_misc.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_misc.h
@@ -30,17 +30,23 @@
 #define LP_BLD_MISC_H
 
 
+#include "llvm/Config/config.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 
+#ifndef LLVM_NATIVE_ARCH
+
 void
 LLVMLinkInJIT(void);
 
-void
+int
 LLVMInitializeNativeTarget(void);
 
+#endif /* !LLVM_NATIVE_ARCH */
+
 
 #ifdef __cplusplus
 }
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_sample.c b/src/gallium/drivers/llvmpipe/lp_bld_sample.c
index 4d272be..9003e10 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_sample.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_sample.c
@@ -59,9 +59,9 @@
 
    state->format            = texture->format;
    state->target            = texture->target;
-   state->pot_width         = util_is_pot(texture->width[0]);
-   state->pot_height        = util_is_pot(texture->height[0]);
-   state->pot_depth         = util_is_pot(texture->depth[0]);
+   state->pot_width         = util_is_pot(texture->width0);
+   state->pot_height        = util_is_pot(texture->height0);
+   state->pot_depth         = util_is_pot(texture->depth0);
 
    state->wrap_s            = sampler->wrap_s;
    state->wrap_t            = sampler->wrap_t;
@@ -69,8 +69,8 @@
    state->min_img_filter    = sampler->min_img_filter;
    state->min_mip_filter    = sampler->min_mip_filter;
    state->mag_img_filter    = sampler->mag_img_filter;
-   if(sampler->compare_mode) {
-      state->compare_mode      = sampler->compare_mode;
+   state->compare_mode      = sampler->compare_mode;
+   if(sampler->compare_mode != PIPE_TEX_COMPARE_NONE) {
       state->compare_func      = sampler->compare_func;
    }
    state->normalized_coords = sampler->normalized_coords;
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c
index 47b68b7..5ee8d55 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c
@@ -488,7 +488,7 @@
    LLVMValueRef res;
    unsigned chan;
 
-   if(!bld->static_state->compare_mode)
+   if(bld->static_state->compare_mode == PIPE_TEX_COMPARE_NONE)
       return;
 
    /* TODO: Compare before swizzling, to avoid redundant computations */
@@ -577,7 +577,6 @@
       lp_build_sample_2d_nearest_soa(&bld, s, t, width, height, stride, data_ptr, texel);
       break;
    case PIPE_TEX_FILTER_LINEAR:
-   case PIPE_TEX_FILTER_ANISO:
       if(lp_format_is_rgba8(bld.format_desc))
          lp_build_sample_2d_linear_aos(&bld, s, t, width, height, stride, data_ptr, texel);
       else
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
index 64027de..fb1eda4 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
@@ -64,7 +64,7 @@
    for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++)
 
 #define IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
-   ((INST)->FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN)))
+   ((INST)->Dst[0].Register.WriteMask & (1 << (CHAN)))
 
 #define IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
    if (IS_DST0_CHANNEL_ENABLED( INST, CHAN ))
@@ -157,7 +157,7 @@
    unsigned index,
    const unsigned chan_index )
 {
-   const struct tgsi_full_src_register *reg = &inst->FullSrcRegisters[index];
+   const struct tgsi_full_src_register *reg = &inst->Src[index];
    unsigned swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index );
    LLVMValueRef res;
 
@@ -167,9 +167,9 @@
    case TGSI_SWIZZLE_Z:
    case TGSI_SWIZZLE_W:
 
-      switch (reg->SrcRegister.File) {
+      switch (reg->Register.File) {
       case TGSI_FILE_CONSTANT: {
-         LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), reg->SrcRegister.Index*4 + swizzle, 0);
+         LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), reg->Register.Index*4 + swizzle, 0);
          LLVMValueRef scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr, &index, 1, "");
          LLVMValueRef scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
          res = lp_build_broadcast_scalar(&bld->base, scalar);
@@ -177,17 +177,17 @@
       }
 
       case TGSI_FILE_IMMEDIATE:
-         res = bld->immediates[reg->SrcRegister.Index][swizzle];
+         res = bld->immediates[reg->Register.Index][swizzle];
          assert(res);
          break;
 
       case TGSI_FILE_INPUT:
-         res = bld->inputs[reg->SrcRegister.Index][swizzle];
+         res = bld->inputs[reg->Register.Index][swizzle];
          assert(res);
          break;
 
       case TGSI_FILE_TEMPORARY:
-         res = bld->temps[reg->SrcRegister.Index][swizzle];
+         res = bld->temps[reg->Register.Index][swizzle];
          if(!res)
             return bld->base.undef;
          break;
@@ -267,7 +267,7 @@
    unsigned chan_index,
    LLVMValueRef value)
 {
-   const struct tgsi_full_dst_register *reg = &inst->FullDstRegisters[index];
+   const struct tgsi_full_dst_register *reg = &inst->Dst[index];
 
    switch( inst->Instruction.Saturate ) {
    case TGSI_SAT_NONE:
@@ -287,13 +287,13 @@
       assert(0);
    }
 
-   switch( reg->DstRegister.File ) {
+   switch( reg->Register.File ) {
    case TGSI_FILE_OUTPUT:
-      bld->outputs[reg->DstRegister.Index][chan_index] = value;
+      bld->outputs[reg->Register.Index][chan_index] = value;
       break;
 
    case TGSI_FILE_TEMPORARY:
-      bld->temps[reg->DstRegister.Index][chan_index] = value;
+      bld->temps[reg->Register.Index][chan_index] = value;
       break;
 
    case TGSI_FILE_ADDRESS:
@@ -319,14 +319,14 @@
           boolean projected,
           LLVMValueRef *texel)
 {
-   const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index;
+   const uint unit = inst->Src[1].Register.Index;
    LLVMValueRef lodbias;
-   LLVMValueRef oow;
+   LLVMValueRef oow = NULL;
    LLVMValueRef coords[3];
    unsigned num_coords;
    unsigned i;
 
-   switch (inst->InstructionExtTexture.Texture) {
+   switch (inst->Texture.Texture) {
    case TGSI_TEXTURE_1D:
       num_coords = 1;
       break;
@@ -361,6 +361,9 @@
       if (projected)
          coords[i] = lp_build_mul(&bld->base, coords[i], oow);
    }
+   for (i = num_coords; i < 3; i++) {
+      coords[i] = bld->base.undef;
+   }
 
    bld->sampler->emit_fetch_texel(bld->sampler,
                                   bld->base.builder,
@@ -375,7 +378,7 @@
    struct lp_build_tgsi_soa_context *bld,
    const struct tgsi_full_instruction *inst )
 {
-   const struct tgsi_full_src_register *reg = &inst->FullSrcRegisters[0];
+   const struct tgsi_full_src_register *reg = &inst->Src[0];
    LLVMValueRef terms[NUM_CHANNELS];
    LLVMValueRef mask;
    unsigned chan_index;
@@ -423,15 +426,15 @@
 {
    uint i;
    for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
-      const struct tgsi_full_src_register *reg = &inst->FullSrcRegisters[i];
-      if (reg->SrcRegister.File == TGSI_FILE_TEMPORARY &&
-          reg->SrcRegister.Indirect)
+      const struct tgsi_full_src_register *reg = &inst->Src[i];
+      if (reg->Register.File == TGSI_FILE_TEMPORARY &&
+          reg->Register.Indirect)
          return TRUE;
    }
    for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
-      const struct tgsi_full_dst_register *reg = &inst->FullDstRegisters[i];
-      if (reg->DstRegister.File == TGSI_FILE_TEMPORARY &&
-          reg->DstRegister.Indirect)
+      const struct tgsi_full_dst_register *reg = &inst->Dst[i];
+      if (reg->Register.File == TGSI_FILE_TEMPORARY &&
+          reg->Register.Indirect)
          return TRUE;
    }
    return FALSE;
@@ -446,7 +449,12 @@
 {
    unsigned chan_index;
    LLVMValueRef src0, src1, src2;
-   LLVMValueRef tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+   LLVMValueRef tmp0, tmp1, tmp2;
+   LLVMValueRef tmp3 = NULL;
+   LLVMValueRef tmp4 = NULL;
+   LLVMValueRef tmp5 = NULL;
+   LLVMValueRef tmp6 = NULL;
+   LLVMValueRef tmp7 = NULL;
    LLVMValueRef res;
    LLVMValueRef dst0[NUM_CHANNELS];
 
@@ -560,9 +568,9 @@
       if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
           IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
           IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z )) {
-         LLVMValueRef *p_floor_log2;
-         LLVMValueRef *p_exp;
-         LLVMValueRef *p_log2;
+         LLVMValueRef *p_floor_log2 = NULL;
+         LLVMValueRef *p_exp = NULL;
+         LLVMValueRef *p_log2 = NULL;
 
          src0 = emit_fetch( bld, inst, 0, CHAN_X );
          src0 = lp_build_abs( &bld->base, src0 );
@@ -763,7 +771,7 @@
       FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
          src0 = emit_fetch( bld, inst, 0, chan_index );
          tmp0 = lp_build_floor(&bld->base, src0);
-         tmp0 = lp_build_sub(&bld->base, tmp0, src0);
+         tmp0 = lp_build_sub(&bld->base, src0, tmp0);
          dst0[chan_index] = tmp0;
       }
       break;
@@ -1310,7 +1318,7 @@
       return 0;
       break;
 
-   case TGSI_OPCODE_SHR:
+   case TGSI_OPCODE_ISHR:
       /* deprecated? */
       assert(0);
       return 0;
diff --git a/src/gallium/drivers/llvmpipe/lp_clear.c b/src/gallium/drivers/llvmpipe/lp_clear.c
index bdcff94..08d9f2e 100644
--- a/src/gallium/drivers/llvmpipe/lp_clear.c
+++ b/src/gallium/drivers/llvmpipe/lp_clear.c
@@ -50,6 +50,7 @@
                double depth, unsigned stencil)
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+   union util_color uc;
    unsigned cv;
    uint i;
 
@@ -64,8 +65,8 @@
       for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) {
          struct pipe_surface *ps = llvmpipe->framebuffer.cbufs[i];
 
-         util_pack_color(rgba, ps->format, &cv);
-         lp_tile_cache_clear(llvmpipe->cbuf_cache[i], rgba, cv);
+         util_pack_color(rgba, ps->format, &uc);
+         lp_tile_cache_clear(llvmpipe->cbuf_cache[i], rgba, uc.ui);
       }
       llvmpipe->dirty_render_cache = TRUE;
    }
diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c
index 57e71f3..1cc3c92 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.c
+++ b/src/gallium/drivers/llvmpipe/lp_context.c
@@ -118,6 +118,11 @@
       pipe_texture_reference(&llvmpipe->texture[i], NULL);
    }
 
+   for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+      lp_destroy_tex_tile_cache(llvmpipe->vertex_tex_cache[i]);
+      pipe_texture_reference(&llvmpipe->vertex_textures[i], NULL);
+   }
+
    for (i = 0; i < Elements(llvmpipe->constants); i++) {
       if (llvmpipe->constants[i].buffer) {
          pipe_buffer_reference(&llvmpipe->constants[i].buffer, NULL);
@@ -135,6 +140,7 @@
    struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
    unsigned i;
 
+   /* check if any of the bound drawing surfaces are this texture */
    if(llvmpipe->dirty_render_cache) {
       for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) {
          if(llvmpipe->framebuffer.cbufs[i] && 
@@ -145,6 +151,18 @@
          llvmpipe->framebuffer.zsbuf->texture == texture)
          return PIPE_REFERENCED_FOR_WRITE;
    }
+
+   /* check if any of the tex_cache textures are this texture */
+   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+      if (llvmpipe->tex_cache[i] &&
+            llvmpipe->tex_cache[i]->texture == texture)
+         return PIPE_REFERENCED_FOR_READ;
+   }
+   for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+      if (llvmpipe->vertex_tex_cache[i] &&
+          llvmpipe->vertex_tex_cache[i]->texture == texture)
+         return PIPE_REFERENCED_FOR_READ;
+   }
    
    return PIPE_UNREFERENCED;
 }
@@ -180,7 +198,8 @@
    llvmpipe->pipe.delete_blend_state = llvmpipe_delete_blend_state;
 
    llvmpipe->pipe.create_sampler_state = llvmpipe_create_sampler_state;
-   llvmpipe->pipe.bind_sampler_states  = llvmpipe_bind_sampler_states;
+   llvmpipe->pipe.bind_fragment_sampler_states  = llvmpipe_bind_sampler_states;
+   llvmpipe->pipe.bind_vertex_sampler_states  = llvmpipe_bind_vertex_sampler_states;
    llvmpipe->pipe.delete_sampler_state = llvmpipe_delete_sampler_state;
 
    llvmpipe->pipe.create_depth_stencil_alpha_state = llvmpipe_create_depth_stencil_state;
@@ -205,7 +224,8 @@
    llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state;
    llvmpipe->pipe.set_polygon_stipple = llvmpipe_set_polygon_stipple;
    llvmpipe->pipe.set_scissor_state = llvmpipe_set_scissor_state;
-   llvmpipe->pipe.set_sampler_textures = llvmpipe_set_sampler_textures;
+   llvmpipe->pipe.set_fragment_sampler_textures = llvmpipe_set_sampler_textures;
+   llvmpipe->pipe.set_vertex_sampler_textures = llvmpipe_set_vertex_sampler_textures;
    llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state;
 
    llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
@@ -214,8 +234,6 @@
    llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays;
    llvmpipe->pipe.draw_elements = llvmpipe_draw_elements;
    llvmpipe->pipe.draw_range_elements = llvmpipe_draw_range_elements;
-   llvmpipe->pipe.set_edgeflags = llvmpipe_set_edgeflags;
-
 
    llvmpipe->pipe.clear = llvmpipe_clear;
    llvmpipe->pipe.flush = llvmpipe_flush;
@@ -234,24 +252,10 @@
 
    for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
       llvmpipe->tex_cache[i] = lp_create_tex_tile_cache( screen );
+   for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++)
+      llvmpipe->vertex_tex_cache[i] = lp_create_tex_tile_cache(screen);
 
 
-   /* vertex shader samplers */
-   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
-      llvmpipe->tgsi.vert_samplers[i].base.get_samples = lp_get_samples;
-      llvmpipe->tgsi.vert_samplers[i].processor = TGSI_PROCESSOR_VERTEX;
-      llvmpipe->tgsi.vert_samplers[i].cache = llvmpipe->tex_cache[i];
-      llvmpipe->tgsi.vert_samplers_list[i] = &llvmpipe->tgsi.vert_samplers[i];
-   }
-
-   /* fragment shader samplers */
-   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
-      llvmpipe->tgsi.frag_samplers[i].base.get_samples = lp_get_samples;
-      llvmpipe->tgsi.frag_samplers[i].processor = TGSI_PROCESSOR_FRAGMENT;
-      llvmpipe->tgsi.frag_samplers[i].cache = llvmpipe->tex_cache[i];
-      llvmpipe->tgsi.frag_samplers_list[i] = &llvmpipe->tgsi.frag_samplers[i];
-   }
-
    /*
     * Create drawing context and plug our rendering stage into it.
     */
@@ -259,10 +263,7 @@
    if (!llvmpipe->draw) 
       goto fail;
 
-   draw_texture_samplers(llvmpipe->draw,
-                         PIPE_MAX_SAMPLERS,
-                         (struct tgsi_sampler **)
-                            llvmpipe->tgsi.vert_samplers_list);
+   /* FIXME: devise alternative to draw_texture_samplers */
 
    if (debug_get_bool_option( "LP_NO_RAST", FALSE ))
       llvmpipe->no_rast = TRUE;
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index 3ad95d0..6411797 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -55,6 +55,7 @@
    /** Constant state objects */
    const struct pipe_blend_state *blend;
    const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
+   struct pipe_sampler_state *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS];
    const struct pipe_depth_stencil_alpha_state *depth_stencil;
    const struct pipe_rasterizer_state *rasterizer;
    struct lp_fragment_shader *fs;
@@ -68,12 +69,15 @@
    struct pipe_poly_stipple poly_stipple;
    struct pipe_scissor_state scissor;
    struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
+   struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
    struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
 
    unsigned num_samplers;
    unsigned num_textures;
+   unsigned num_vertex_samplers;
+   unsigned num_vertex_textures;
    unsigned num_vertex_elements;
    unsigned num_vertex_buffers;
 
@@ -111,14 +115,6 @@
 
    unsigned line_stipple_counter;
 
-   /** TGSI exec things */
-   struct {
-      struct lp_shader_sampler vert_samplers[PIPE_MAX_SAMPLERS];
-      struct lp_shader_sampler *vert_samplers_list[PIPE_MAX_SAMPLERS];
-      struct lp_shader_sampler frag_samplers[PIPE_MAX_SAMPLERS];
-      struct lp_shader_sampler *frag_samplers_list[PIPE_MAX_SAMPLERS];
-   } tgsi;
-
    /** The primitive drawing context */
    struct draw_context *draw;
 
@@ -136,6 +132,7 @@
 
    unsigned tex_timestamp;
    struct llvmpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
+   struct llvmpipe_tex_tile_cache *vertex_tex_cache[PIPE_MAX_VERTEX_SAMPLERS];
 
    unsigned no_rast : 1;
 
diff --git a/src/mesa/state_tracker/st_cb_get.h b/src/gallium/drivers/llvmpipe/lp_debug.h
similarity index 62%
copy from src/mesa/state_tracker/st_cb_get.h
copy to src/gallium/drivers/llvmpipe/lp_debug.h
index 8e9f3e9..74b2757 100644
--- a/src/mesa/state_tracker/st_cb_get.h
+++ b/src/gallium/drivers/llvmpipe/lp_debug.h
@@ -1,6 +1,6 @@
 /**************************************************************************
  * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -26,12 +26,46 @@
  **************************************************************************/
 
 
-#ifndef ST_CB_GET_H
-#define ST_CB_GET_H
+#ifndef LP_DEBUG_H
+#define LP_DEBUG_H
 
+#include "pipe/p_compiler.h"
+#include "util/u_debug.h"
 
 extern void
-st_init_get_functions(struct dd_function_table *functions);
+st_print_current(void);
 
 
+#define DEBUG_PIPE      0x1
+#define DEBUG_TGSI      0x2
+#define DEBUG_TEX       0x4
+#define DEBUG_ASM       0x8
+#define DEBUG_SETUP     0x10
+#define DEBUG_RAST      0x20
+#define DEBUG_QUERY     0x40
+#define DEBUG_SCREEN    0x80
+#define DEBUG_JIT       0x100
+
+#ifdef DEBUG
+extern int LP_DEBUG;
+#else
+#define LP_DEBUG 0
 #endif
+
+void st_debug_init( void );
+
+static INLINE void
+LP_DBG( unsigned flag, const char *fmt, ... )
+{
+    if (LP_DEBUG & flag)
+    {
+        va_list args;
+
+        va_start( args, fmt );
+        debug_vprintf( fmt, args );
+        va_end( args );
+    }
+}
+
+
+#endif /* LP_DEBUG_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
index 0aa13a1..c152b44 100644
--- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
+++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
@@ -45,11 +45,11 @@
 
 
 
-boolean
+void
 llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
                      unsigned start, unsigned count)
 {
-   return llvmpipe_draw_elements(pipe, NULL, 0, mode, start, count);
+   llvmpipe_draw_elements(pipe, NULL, 0, mode, start, count);
 }
 
 
@@ -58,7 +58,7 @@
  * Basically, map the vertex buffers (and drawing surfaces), then hand off
  * the drawing to the 'draw' module.
  */
-boolean
+void
 llvmpipe_draw_range_elements(struct pipe_context *pipe,
                              struct pipe_buffer *indexBuffer,
                              unsigned indexSize,
@@ -103,7 +103,7 @@
    draw_arrays(draw, mode, start, count);
 
    /*
-    * unmap vertex/index buffers - will cause draw module to flush
+    * unmap vertex/index buffers
     */
    for (i = 0; i < lp->num_vertex_buffers; i++) {
       draw_set_mapped_vertex_buffer(draw, i, NULL);
@@ -112,31 +112,28 @@
       draw_set_mapped_element_buffer(draw, 0, NULL);
    }
 
+   /*
+    * TODO: Flush only when a user vertex/index buffer is present
+    * (or even better, modify draw module to do this
+    * internally when this condition is seen?)
+    */
+   draw_flush(draw);
 
    /* Note: leave drawing surfaces mapped */
 
    lp->dirty_render_cache = TRUE;
-   
-   return TRUE;
 }
 
 
-boolean
+void
 llvmpipe_draw_elements(struct pipe_context *pipe,
                        struct pipe_buffer *indexBuffer,
                        unsigned indexSize,
                        unsigned mode, unsigned start, unsigned count)
 {
-   return llvmpipe_draw_range_elements( pipe, indexBuffer,
-                                        indexSize,
-                                        0, 0xffffffff,
-                                        mode, start, count );
+   llvmpipe_draw_range_elements( pipe, indexBuffer,
+                                 indexSize,
+                                 0, 0xffffffff,
+                                 mode, start, count );
 }
 
-
-void
-llvmpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags)
-{
-   struct llvmpipe_context *lp = llvmpipe_context(pipe);
-   draw_set_edgeflags(lp->draw, edgeflags);
-}
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index 13535dd..4ef0783 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -79,25 +79,22 @@
 
    /* struct lp_jit_context */
    {
-      LLVMTypeRef elem_types[5];
+      LLVMTypeRef elem_types[4];
       LLVMTypeRef context_type;
 
       elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* constants */
-      elem_types[1] = LLVMPointerType(LLVMInt8Type(), 0);  /* samplers */
-      elem_types[2] = LLVMFloatType();                     /* alpha_ref_value */
-      elem_types[3] = LLVMPointerType(LLVMInt8Type(), 0);  /* blend_color */
-      elem_types[4] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */
+      elem_types[1] = LLVMFloatType();                     /* alpha_ref_value */
+      elem_types[2] = LLVMPointerType(LLVMInt8Type(), 0);  /* blend_color */
+      elem_types[3] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */
 
       context_type = LLVMStructType(elem_types, Elements(elem_types), 0);
 
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, constants,
                              screen->target, context_type, 0);
-      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, samplers,
-                             screen->target, context_type, 1);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, alpha_ref_value,
-                             screen->target, context_type, 2);
+                             screen->target, context_type, 1);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color,
-                             screen->target, context_type, 3);
+                             screen->target, context_type, 2);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, textures,
                              screen->target, context_type,
                              LP_JIT_CONTEXT_TEXTURES_INDEX);
@@ -109,24 +106,6 @@
       screen->context_ptr_type = LLVMPointerType(context_type, 0);
    }
 
-   /* fetch_texel
-    */
-   {
-      LLVMTypeRef ret_type;
-      LLVMTypeRef arg_types[3];
-      LLVMValueRef fetch_texel;
-
-      ret_type = LLVMVoidType();
-      arg_types[0] = LLVMPointerType(LLVMInt8Type(), 0);  /* samplers */
-      arg_types[1] = LLVMInt32Type();                     /* unit */
-      arg_types[2] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0); /* store */
-
-      fetch_texel = lp_declare_intrinsic(screen->module, "fetch_texel",
-                                         ret_type, arg_types, Elements(arg_types));
-
-      LLVMAddGlobalMapping(screen->engine, fetch_texel, lp_fetch_texel_soa);
-   }
-
 #ifdef DEBUG
    LLVMDumpModule(screen->module);
 #endif
@@ -154,6 +133,7 @@
 #if 0
    /* For simulating less capable machines */
    util_cpu_caps.has_sse3 = 0;
+   util_cpu_caps.has_ssse3 = 0;
    util_cpu_caps.has_sse4_1 = 0;
 #endif
 
@@ -167,7 +147,7 @@
    if (LLVMCreateJITCompiler(&screen->engine, screen->provider, 1, &error)) {
       _debug_printf("%s\n", error);
       LLVMDisposeMessage(error);
-      abort();
+      assert(0);
    }
 
    screen->target = LLVMGetExecutionEngineTargetData(screen->engine);
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index 58f716e..277b690 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -41,7 +41,6 @@
 #include "pipe/p_state.h"
 
 
-struct tgsi_sampler;
 struct llvmpipe_screen;
 
 
@@ -78,8 +77,6 @@
 {
    const float *constants;
 
-   struct tgsi_sampler **samplers;
-
    float alpha_ref_value;
 
    /* FIXME: store (also?) in floats */
@@ -92,16 +89,13 @@
 #define lp_jit_context_constants(_builder, _ptr) \
    lp_build_struct_get(_builder, _ptr, 0, "constants")
 
-#define lp_jit_context_samplers(_builder, _ptr) \
-   lp_build_struct_get(_builder, _ptr, 1, "samplers")
-
 #define lp_jit_context_alpha_ref_value(_builder, _ptr) \
-   lp_build_struct_get(_builder, _ptr, 2, "alpha_ref_value")
+   lp_build_struct_get(_builder, _ptr, 1, "alpha_ref_value")
 
 #define lp_jit_context_blend_color(_builder, _ptr) \
-   lp_build_struct_get(_builder, _ptr, 3, "blend_color")
+   lp_build_struct_get(_builder, _ptr, 2, "blend_color")
 
-#define LP_JIT_CONTEXT_TEXTURES_INDEX 4
+#define LP_JIT_CONTEXT_TEXTURES_INDEX 3
 
 #define lp_jit_context_textures(_builder, _ptr) \
    lp_build_struct_get_ptr(_builder, _ptr, LP_JIT_CONTEXT_TEXTURES_INDEX, "textures")
@@ -118,12 +112,6 @@
                     void *color,
                     void *depth);
 
-void PIPE_CDECL
-lp_fetch_texel_soa( struct tgsi_sampler **samplers,
-                    uint32_t unit,
-                    float *store );
-
-
 void
 lp_jit_screen_cleanup(struct llvmpipe_screen *screen);
 
diff --git a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c
index 4abff4e..e8e2e25 100644
--- a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c
+++ b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c
@@ -128,6 +128,7 @@
 {
    struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
    assert( cvbr->vertex_buffer_size >= (max_index+1) * cvbr->vertex_size );
+   (void) cvbr;
    /* do nothing */
 }
 
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 0518927..9b47415 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -27,6 +27,7 @@
 
 
 #include "util/u_memory.h"
+#include "util/u_format.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_screen.h"
 
@@ -35,6 +36,24 @@
 #include "lp_winsys.h"
 #include "lp_jit.h"
 #include "lp_screen.h"
+#include "lp_debug.h"
+
+#ifdef DEBUG
+int LP_DEBUG = 0;
+
+static const struct debug_named_value lp_debug_flags[] = {
+   { "pipe",   DEBUG_PIPE },
+   { "tgsi",   DEBUG_TGSI },
+   { "tex",    DEBUG_TEX },
+   { "asm",    DEBUG_ASM },
+   { "setup",  DEBUG_SETUP },
+   { "rast",   DEBUG_RAST },
+   { "query",  DEBUG_QUERY },
+   { "screen", DEBUG_SCREEN },
+   { "jit",    DEBUG_JIT },
+   {NULL, 0}
+};
+#endif
 
 
 static const char *
@@ -58,7 +77,9 @@
    case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
       return PIPE_MAX_SAMPLERS;
    case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
-      return PIPE_MAX_SAMPLERS;
+      return PIPE_MAX_VERTEX_SAMPLERS;
+   case PIPE_CAP_MAX_COMBINED_SAMPLERS:
+      return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS;
    case PIPE_CAP_NPOT_TEXTURES:
       return 1;
    case PIPE_CAP_TWO_SIDED_STENCIL:
@@ -131,17 +152,17 @@
 {
    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
    struct llvmpipe_winsys *winsys = screen->winsys;
+   const struct util_format_description *format_desc;
+
+   format_desc = util_format_description(format);
+   if(!format_desc)
+      return FALSE;
 
    assert(target == PIPE_TEXTURE_1D ||
           target == PIPE_TEXTURE_2D ||
           target == PIPE_TEXTURE_3D ||
           target == PIPE_TEXTURE_CUBE);
 
-   if(format == PIPE_FORMAT_Z16_UNORM)
-      return FALSE;
-   if(format == PIPE_FORMAT_S8_UNORM)
-      return FALSE;
-
    switch(format) {
    case PIPE_FORMAT_DXT1_RGB:
    case PIPE_FORMAT_DXT1_RGBA:
@@ -152,8 +173,51 @@
       break;
    }
 
-   if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
-      return winsys->is_displaytarget_format_supported(winsys, format);
+   if(tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
+      if(format_desc->block.width != 1 ||
+         format_desc->block.height != 1)
+         return FALSE;
+
+      if(format_desc->layout != UTIL_FORMAT_LAYOUT_SCALAR &&
+         format_desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
+         format_desc->layout != UTIL_FORMAT_LAYOUT_ARRAY)
+         return FALSE;
+
+      if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB &&
+         format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB)
+         return FALSE;
+   }
+
+   if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+      if(!winsys->is_displaytarget_format_supported(winsys, format))
+         return FALSE;
+   }
+
+   if(tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
+      if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
+         return FALSE;
+
+      /* FIXME: Temporary restriction. See lp_state_fs.c. */
+      if(format_desc->block.bits != 32)
+         return FALSE;
+   }
+
+   /* FIXME: Temporary restrictions. See lp_bld_sample_soa.c */
+   if(tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) {
+      if(format_desc->block.width != 1 ||
+         format_desc->block.height != 1)
+         return FALSE;
+
+      if(format_desc->layout != UTIL_FORMAT_LAYOUT_SCALAR &&
+         format_desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
+         format_desc->layout != UTIL_FORMAT_LAYOUT_ARRAY)
+         return FALSE;
+
+      if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB &&
+         format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB &&
+         format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
+         return FALSE;
+   }
 
    return TRUE;
 }
@@ -213,6 +277,10 @@
 {
    struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
 
+#ifdef DEBUG
+   LP_DEBUG = debug_get_flags_option("LP_DEBUG", lp_debug_flags, 0 );
+#endif
+
    if (!screen)
       return NULL;
 
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index ffcbc9a..b18f17c 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -41,6 +41,7 @@
 #include "draw/draw_vertex.h"
 #include "pipe/p_shader_tokens.h"
 #include "pipe/p_thread.h"
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "lp_bld_debug.h"
@@ -166,7 +167,7 @@
       assert((y % 2) == 0);
       depth = llvmpipe->zsbuf_map +
               y*llvmpipe->zsbuf_transfer->stride +
-              2*x*llvmpipe->zsbuf_transfer->block.size;
+              2*x*util_format_get_blocksize(llvmpipe->zsbuf_transfer->texture->format);
    }
    else
       depth = NULL;
diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h
index 7b26ce6..7020da1 100644
--- a/src/gallium/drivers/llvmpipe/lp_state.h
+++ b/src/gallium/drivers/llvmpipe/lp_state.h
@@ -56,7 +56,6 @@
 #define LP_NEW_QUERY         0x4000
 
 
-struct tgsi_sampler;
 struct vertex_info;
 struct pipe_context;
 struct llvmpipe_context;
@@ -126,6 +125,10 @@
 llvmpipe_create_sampler_state(struct pipe_context *,
                               const struct pipe_sampler_state *);
 void llvmpipe_bind_sampler_states(struct pipe_context *, unsigned, void **);
+void
+llvmpipe_bind_vertex_sampler_states(struct pipe_context *,
+                                    unsigned num_samplers,
+                                    void **samplers);
 void llvmpipe_delete_sampler_state(struct pipe_context *, void *);
 
 void *
@@ -172,6 +175,11 @@
                                     unsigned num,
                                     struct pipe_texture ** );
 
+void
+llvmpipe_set_vertex_sampler_textures(struct pipe_context *,
+                                     unsigned num_textures,
+                                     struct pipe_texture **);
+
 void llvmpipe_set_viewport_state( struct pipe_context *,
                                   const struct pipe_viewport_state * );
 
@@ -188,14 +196,14 @@
 void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe );
 
 
-boolean llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
+void llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
 			     unsigned start, unsigned count);
 
-boolean llvmpipe_draw_elements(struct pipe_context *pipe,
+void llvmpipe_draw_elements(struct pipe_context *pipe,
 			       struct pipe_buffer *indexBuffer,
 			       unsigned indexSize,
 			       unsigned mode, unsigned start, unsigned count);
-boolean
+void
 llvmpipe_draw_range_elements(struct pipe_context *pipe,
                              struct pipe_buffer *indexBuffer,
                              unsigned indexSize,
@@ -204,10 +212,6 @@
                              unsigned mode, unsigned start, unsigned count);
 
 void
-llvmpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags);
-
-
-void
 llvmpipe_map_transfers(struct llvmpipe_context *lp);
 
 void
diff --git a/src/gallium/drivers/llvmpipe/lp_state_blend.c b/src/gallium/drivers/llvmpipe/lp_state_blend.c
index 3f03bd0..a94cd05 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_blend.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_blend.c
@@ -34,6 +34,7 @@
 #include "util/u_memory.h"
 #include "util/u_math.h"
 #include "util/u_debug_dump.h"
+#include "draw/draw_context.h"
 #include "lp_screen.h"
 #include "lp_context.h"
 #include "lp_state.h"
@@ -51,6 +52,11 @@
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
 
+   if (llvmpipe->blend == blend)
+      return;
+
+   draw_flush(llvmpipe->draw);
+
    llvmpipe->blend = blend;
 
    llvmpipe->dirty |= LP_NEW_BLEND;
@@ -69,6 +75,11 @@
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
    unsigned i, j;
 
+   if(memcmp(&llvmpipe->blend_color, blend_color, sizeof *blend_color) == 0)
+      return;
+
+   draw_flush(llvmpipe->draw);
+
    memcpy(&llvmpipe->blend_color, blend_color, sizeof *blend_color);
 
    if(!llvmpipe->jit_context.blend_color)
@@ -76,7 +87,7 @@
    for (i = 0; i < 4; ++i) {
       uint8_t c = float_to_ubyte(blend_color->color[i]);
       for (j = 0; j < 16; ++j)
-         llvmpipe->jit_context.blend_color[i*4 + j] = c;
+         llvmpipe->jit_context.blend_color[i*16 + j] = c;
    }
 }
 
@@ -99,7 +110,12 @@
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
 
-   llvmpipe->depth_stencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil;
+   if (llvmpipe->depth_stencil == depth_stencil)
+      return;
+
+   draw_flush(llvmpipe->draw);
+
+   llvmpipe->depth_stencil = depth_stencil;
 
    if(llvmpipe->depth_stencil)
       llvmpipe->jit_context.alpha_ref_value = llvmpipe->depth_stencil->alpha.ref_value;
diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c
index c753b18..6c1ef6b 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_derived.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c
@@ -66,7 +66,7 @@
       /* compute vertex layout now */
       const struct lp_fragment_shader *lpfs = llvmpipe->fs;
       struct vertex_info *vinfo_vbuf = &llvmpipe->vertex_info_vbuf;
-      const uint num = draw_num_vs_outputs(llvmpipe->draw);
+      const uint num = draw_current_shader_outputs(llvmpipe->draw);
       uint i;
 
       /* Tell draw_vbuf to simply emit the whole post-xform vertex
@@ -116,13 +116,13 @@
          }
 
          /* this includes texcoords and varying vars */
-         src = draw_find_vs_output(llvmpipe->draw,
+         src = draw_find_shader_output(llvmpipe->draw,
                                    lpfs->info.input_semantic_name[i],
                                    lpfs->info.input_semantic_index[i]);
          draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src);
       }
 
-      llvmpipe->psize_slot = draw_find_vs_output(llvmpipe->draw,
+      llvmpipe->psize_slot = draw_find_shader_output(llvmpipe->draw,
                                                  TGSI_SEMANTIC_PSIZE, 0);
       if (llvmpipe->psize_slot > 0) {
          draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
@@ -192,32 +192,6 @@
 }
 
 
-static void
-update_tgsi_samplers( struct llvmpipe_context *llvmpipe )
-{
-   unsigned i;
-
-   /* vertex shader samplers */
-   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
-      llvmpipe->tgsi.vert_samplers[i].sampler = llvmpipe->sampler[i];
-      llvmpipe->tgsi.vert_samplers[i].texture = llvmpipe->texture[i];
-      llvmpipe->tgsi.frag_samplers[i].base.get_samples = lp_get_samples;
-   }
-
-   /* fragment shader samplers */
-   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
-      llvmpipe->tgsi.frag_samplers[i].sampler = llvmpipe->sampler[i];
-      llvmpipe->tgsi.frag_samplers[i].texture = llvmpipe->texture[i];
-      llvmpipe->tgsi.frag_samplers[i].base.get_samples = lp_get_samples;
-   }
-
-   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
-      lp_tex_tile_cache_validate_texture( llvmpipe->tex_cache[i] );
-   }
-
-   llvmpipe->jit_context.samplers = (struct tgsi_sampler **)llvmpipe->tgsi.frag_samplers_list;
-}
-
 /* Hopefully this will remain quite simple, otherwise need to pull in
  * something like the state tracker mechanism.
  */
@@ -233,8 +207,9 @@
    }
       
    if (llvmpipe->dirty & (LP_NEW_SAMPLER |
-                          LP_NEW_TEXTURE))
-      update_tgsi_samplers( llvmpipe );
+                          LP_NEW_TEXTURE)) {
+      /* TODO */
+   }
 
    if (llvmpipe->dirty & (LP_NEW_RASTERIZER |
                           LP_NEW_FS |
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 2e9aa9f..b73ca2d 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -87,6 +87,7 @@
 #include "lp_state.h"
 #include "lp_quad.h"
 #include "lp_tex_sample.h"
+#include "lp_debug.h"
 
 
 static const unsigned char quad_offset_x[4] = {0, 1, 0, 1};
@@ -148,6 +149,20 @@
    format_desc = util_format_description(key->zsbuf_format);
    assert(format_desc);
 
+   /*
+    * Depths are expected to be between 0 and 1, even if they are stored in
+    * floats. Setting these bits here will ensure that the lp_build_conv() call
+    * below won't try to unnecessarily clamp the incoming values.
+    */
+   if(src_type.floating) {
+      src_type.sign = FALSE;
+      src_type.norm = TRUE;
+   }
+   else {
+      assert(!src_type.sign);
+      assert(src_type.norm);
+   }
+
    /* Pick the depth type. */
    dst_type = lp_depth_type(format_desc, src_type.width*src_type.length);
 
@@ -155,14 +170,11 @@
    assert(dst_type.width == src_type.width);
    assert(dst_type.length == src_type.length);
 
-#if 1
-   src = lp_build_clamped_float_to_unsigned_norm(builder,
-                                                 src_type,
-                                                 dst_type.width,
-                                                 src);
-#else
    lp_build_conv(builder, src_type, dst_type, &src, 1, &src, 1);
-#endif
+
+   dst_ptr = LLVMBuildBitCast(builder,
+                              dst_ptr,
+                              LLVMPointerType(lp_build_vec_type(dst_type), 0), "");
 
    lp_build_depth_test(builder,
                        &key->depth,
@@ -397,59 +409,58 @@
    unsigned i;
    unsigned chan;
 
-#ifdef DEBUG
-   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.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.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.blend_enable) {
-      debug_printf("blend.rgb_func = %s\n",   debug_dump_blend_func  (key->blend.rgb_func, TRUE));
-      debug_printf("rgb_src_factor = %s\n",   debug_dump_blend_factor(key->blend.rgb_src_factor, TRUE));
-      debug_printf("rgb_dst_factor = %s\n",   debug_dump_blend_factor(key->blend.rgb_dst_factor, TRUE));
-      debug_printf("alpha_func = %s\n",       debug_dump_blend_func  (key->blend.alpha_func, TRUE));
-      debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_src_factor, TRUE));
-      debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_dst_factor, TRUE));
-   }
-   debug_printf("blend.colormask = 0x%x\n", key->blend.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));
-         debug_printf("  .target = %s\n",
-                      debug_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));
-         debug_printf("  .min_img_filter = %s\n",
-                      debug_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));
-         debug_printf("  .mag_img_filter = %s\n",
-                      debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE));
-         if(key->sampler[i].compare_mode)
-            debug_printf("  .compare_mode = %s\n", debug_dump_func(key->sampler[i].compare_func, TRUE));
-         debug_printf("  .normalized_coords = %u\n", key->sampler[i].normalized_coords);
-         debug_printf("  .prefilter = %u\n", key->sampler[i].prefilter);
+   if (LP_DEBUG & DEBUG_JIT) {
+      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.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.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.blend_enable) {
+         debug_printf("blend.rgb_func = %s\n",   debug_dump_blend_func  (key->blend.rgb_func, TRUE));
+         debug_printf("rgb_src_factor = %s\n",   debug_dump_blend_factor(key->blend.rgb_src_factor, TRUE));
+         debug_printf("rgb_dst_factor = %s\n",   debug_dump_blend_factor(key->blend.rgb_dst_factor, TRUE));
+         debug_printf("alpha_func = %s\n",       debug_dump_blend_func  (key->blend.alpha_func, TRUE));
+         debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_src_factor, TRUE));
+         debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_dst_factor, TRUE));
+      }
+      debug_printf("blend.colormask = 0x%x\n", key->blend.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));
+            debug_printf("  .target = %s\n",
+                         debug_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));
+            debug_printf("  .min_img_filter = %s\n",
+                         debug_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));
+            debug_printf("  .mag_img_filter = %s\n",
+                         debug_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("  .normalized_coords = %u\n", key->sampler[i].normalized_coords);
+            debug_printf("  .prefilter = %u\n", key->sampler[i].prefilter);
+         }
       }
    }
 
-#endif
-
    variant = CALLOC_STRUCT(lp_fragment_shader_variant);
    if(!variant)
       return NULL;
@@ -539,13 +550,8 @@
                             a0_ptr, dadx_ptr, dady_ptr,
                             x0, y0, 2, 0);
 
-#if 0
-   /* C texture sampling */
-   sampler = lp_c_sampler_soa_create(context_ptr);
-#else
    /* code generated texture sampling */
    sampler = lp_llvm_sampler_soa_create(key->sampler, context_ptr);
-#endif
 
    for(i = 0; i < num_fs; ++i) {
       LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
@@ -588,8 +594,8 @@
    }
 
    lp_build_conv_mask(builder, fs_type, blend_type,
-                               fs_mask, num_fs,
-                               &blend_mask, 1);
+                      fs_mask, num_fs,
+                      &blend_mask, 1);
 
    /*
     * Blending.
@@ -611,23 +617,24 @@
     * Translate the LLVM IR into machine code.
     */
 
+#ifdef DEBUG
    if(LLVMVerifyFunction(variant->function, LLVMPrintMessageAction)) {
       LLVMDumpValue(variant->function);
-      abort();
+      assert(0);
    }
+#endif
 
    LLVMRunFunctionPassManager(screen->pass, variant->function);
 
-#ifdef DEBUG
-   LLVMDumpValue(variant->function);
-   debug_printf("\n");
-#endif
+   if (LP_DEBUG & DEBUG_JIT) {
+      LLVMDumpValue(variant->function);
+      debug_printf("\n");
+   }
 
    variant->jit_function = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, variant->function);
 
-#ifdef DEBUG
-   lp_disassemble(variant->jit_function);
-#endif
+   if (LP_DEBUG & DEBUG_ASM)
+      lp_disassemble(variant->jit_function);
 
    variant->next = shader->variants;
    shader->variants = variant;
@@ -661,7 +668,12 @@
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
 
-   llvmpipe->fs = (struct lp_fragment_shader *) fs;
+   if (llvmpipe->fs == fs)
+      return;
+
+   draw_flush(llvmpipe->draw);
+
+   llvmpipe->fs = fs;
 
    llvmpipe->dirty |= LP_NEW_FS;
 }
@@ -676,6 +688,7 @@
    struct lp_fragment_shader_variant *variant;
 
    assert(fs != llvmpipe->fs);
+   (void) llvmpipe;
 
    variant = shader->variants;
    while(variant) {
@@ -711,8 +724,7 @@
    assert(shader < PIPE_SHADER_TYPES);
    assert(index == 0);
 
-   if(shader == PIPE_SHADER_VERTEX)
-      draw_flush(llvmpipe->draw);
+   draw_flush(llvmpipe->draw);
 
    /* note: reference counting */
    pipe_buffer_reference(&llvmpipe->constants[shader].buffer, buffer);
@@ -722,7 +734,8 @@
    }
 
    if(shader == PIPE_SHADER_VERTEX) {
-      draw_set_mapped_constant_buffer(llvmpipe->draw, data, size);
+      draw_set_mapped_constant_buffer(llvmpipe->draw, PIPE_SHADER_VERTEX,
+                                      data, size);
    }
 
    llvmpipe->dirty |= LP_NEW_CONSTANTS;
diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
index 4561c6b..aa3b5a3 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
@@ -41,14 +41,17 @@
 }
 
 void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe,
-                                    void *setup)
+                                    void *rasterizer)
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
 
-   /* pass-through to draw module */
-   draw_set_rasterizer_state(llvmpipe->draw, setup);
+   if (llvmpipe->rasterizer == rasterizer)
+      return;
 
-   llvmpipe->rasterizer = (struct pipe_rasterizer_state *)setup;
+   /* pass-through to draw module */
+   draw_set_rasterizer_state(llvmpipe->draw, rasterizer);
+
+   llvmpipe->rasterizer = rasterizer;
 
    llvmpipe->dirty |= LP_NEW_RASTERIZER;
 }
diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
index c69d90c..d382f9c 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
@@ -78,6 +78,34 @@
 
 
 void
+llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
+                                    unsigned num_samplers,
+                                    void **samplers)
+{
+   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+   unsigned i;
+
+   assert(num_samplers <= PIPE_MAX_VERTEX_SAMPLERS);
+
+   /* Check for no-op */
+   if (num_samplers == llvmpipe->num_vertex_samplers &&
+       !memcmp(llvmpipe->vertex_samplers, samplers, num_samplers * sizeof(void *)))
+      return;
+
+   draw_flush(llvmpipe->draw);
+
+   for (i = 0; i < num_samplers; ++i)
+      llvmpipe->vertex_samplers[i] = samplers[i];
+   for (i = num_samplers; i < PIPE_MAX_VERTEX_SAMPLERS; ++i)
+      llvmpipe->vertex_samplers[i] = NULL;
+
+   llvmpipe->num_vertex_samplers = num_samplers;
+
+   llvmpipe->dirty |= LP_NEW_SAMPLER;
+}
+
+
+void
 llvmpipe_set_sampler_textures(struct pipe_context *pipe,
                               unsigned num, struct pipe_texture **texture)
 {
@@ -102,8 +130,8 @@
       if(tex) {
          struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex);
          struct lp_jit_texture *jit_tex = &llvmpipe->jit_context.textures[i];
-         jit_tex->width = tex->width[0];
-         jit_tex->height = tex->height[0];
+         jit_tex->width = tex->width0;
+         jit_tex->height = tex->height0;
          jit_tex->stride = lp_tex->stride[0];
          if(!lp_tex->dt)
             jit_tex->data = lp_tex->data;
@@ -117,6 +145,37 @@
 
 
 void
+llvmpipe_set_vertex_sampler_textures(struct pipe_context *pipe,
+                                     unsigned num_textures,
+                                     struct pipe_texture **textures)
+{
+   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+   uint i;
+
+   assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS);
+
+   /* Check for no-op */
+   if (num_textures == llvmpipe->num_vertex_textures &&
+       !memcmp(llvmpipe->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) {
+      return;
+   }
+
+   draw_flush(llvmpipe->draw);
+
+   for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+      struct pipe_texture *tex = i < num_textures ? textures[i] : NULL;
+
+      pipe_texture_reference(&llvmpipe->vertex_textures[i], tex);
+      lp_tex_tile_cache_set_texture(llvmpipe->vertex_tex_cache[i], tex);
+   }
+
+   llvmpipe->num_vertex_textures = num_textures;
+
+   llvmpipe->dirty |= LP_NEW_TEXTURE;
+}
+
+
+void
 llvmpipe_delete_sampler_state(struct pipe_context *pipe,
                               void *sampler)
 {
diff --git a/src/gallium/drivers/llvmpipe/lp_state_surface.c b/src/gallium/drivers/llvmpipe/lp_state_surface.c
index c06ce8b..e37ff04 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_surface.c
@@ -35,6 +35,8 @@
 
 #include "draw/draw_context.h"
 
+#include "util/u_format.h"
+
 
 /**
  * XXX this might get moved someday
@@ -49,6 +51,8 @@
    struct llvmpipe_context *lp = llvmpipe_context(pipe);
    uint i;
 
+   draw_flush(lp->draw);
+
    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
       /* check if changing cbuf */
       if (lp->framebuffer.cbufs[i] != fb->cbufs[i]) {
@@ -88,8 +92,9 @@
       if (lp->framebuffer.zsbuf) {
          int depth_bits;
          double mrd;
-         depth_bits = pf_get_component_bits(lp->framebuffer.zsbuf->format,
-                                            PIPE_FORMAT_COMP_Z);
+         depth_bits = util_format_get_component_bits(lp->framebuffer.zsbuf->format,
+                                                     UTIL_FORMAT_COLORSPACE_ZS,
+                                                     0);
          if (depth_bits > 16) {
             mrd = 0.0000001;
          }
diff --git a/src/gallium/drivers/llvmpipe/lp_state_vs.c b/src/gallium/drivers/llvmpipe/lp_state_vs.c
index 15c3029..884e387 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_vs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_vs.c
@@ -70,14 +70,18 @@
 
 
 void
-llvmpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
+llvmpipe_bind_vs_state(struct pipe_context *pipe, void *_vs)
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+   const struct lp_vertex_shader *vs = (const struct lp_vertex_shader *)_vs;
 
-   llvmpipe->vs = (const struct lp_vertex_shader *)vs;
+   if (llvmpipe->vs == vs)
+      return;
 
-   draw_bind_vertex_shader(llvmpipe->draw,
-                           (llvmpipe->vs ? llvmpipe->vs->draw_data : NULL));
+   draw_bind_vertex_shader(llvmpipe->draw, 
+                           vs ? vs->draw_data : NULL);
+
+   llvmpipe->vs = vs;
 
    llvmpipe->dirty |= LP_NEW_VS;
 }
@@ -92,5 +96,6 @@
       (struct lp_vertex_shader *)vs;
 
    draw_delete_vertex_shader(llvmpipe->draw, state->draw_data);
+   FREE( (void *)state->shader.tokens );
    FREE( state );
 }
diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c
index 149fec1..29fff91 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_blend.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c
@@ -462,6 +462,7 @@
 }
 
 
+ALIGN_STACK
 static boolean
 test_one(unsigned verbose,
          FILE *fp,
@@ -530,11 +531,11 @@
    success = TRUE;
    for(i = 0; i < n && success; ++i) {
       if(mode == AoS) {
-         uint8_t src[LP_NATIVE_VECTOR_WIDTH/8];
-         uint8_t dst[LP_NATIVE_VECTOR_WIDTH/8];
-         uint8_t con[LP_NATIVE_VECTOR_WIDTH/8];
-         uint8_t res[LP_NATIVE_VECTOR_WIDTH/8];
-         uint8_t ref[LP_NATIVE_VECTOR_WIDTH/8];
+         ALIGN16_ATTRIB uint8_t src[LP_NATIVE_VECTOR_WIDTH/8];
+         ALIGN16_ATTRIB uint8_t dst[LP_NATIVE_VECTOR_WIDTH/8];
+         ALIGN16_ATTRIB uint8_t con[LP_NATIVE_VECTOR_WIDTH/8];
+         ALIGN16_ATTRIB uint8_t res[LP_NATIVE_VECTOR_WIDTH/8];
+         ALIGN16_ATTRIB uint8_t ref[LP_NATIVE_VECTOR_WIDTH/8];
          int64_t start_counter = 0;
          int64_t end_counter = 0;
 
@@ -595,11 +596,11 @@
 
       if(mode == SoA) {
          const unsigned stride = type.length*type.width/8;
-         uint8_t src[4*LP_NATIVE_VECTOR_WIDTH/8];
-         uint8_t dst[4*LP_NATIVE_VECTOR_WIDTH/8];
-         uint8_t con[4*LP_NATIVE_VECTOR_WIDTH/8];
-         uint8_t res[4*LP_NATIVE_VECTOR_WIDTH/8];
-         uint8_t ref[4*LP_NATIVE_VECTOR_WIDTH/8];
+         ALIGN16_ATTRIB uint8_t src[4*LP_NATIVE_VECTOR_WIDTH/8];
+         ALIGN16_ATTRIB uint8_t dst[4*LP_NATIVE_VECTOR_WIDTH/8];
+         ALIGN16_ATTRIB uint8_t con[4*LP_NATIVE_VECTOR_WIDTH/8];
+         ALIGN16_ATTRIB uint8_t res[4*LP_NATIVE_VECTOR_WIDTH/8];
+         ALIGN16_ATTRIB uint8_t ref[4*LP_NATIVE_VECTOR_WIDTH/8];
          int64_t start_counter = 0;
          int64_t end_counter = 0;
          boolean mismatch;
diff --git a/src/gallium/drivers/llvmpipe/lp_test_conv.c b/src/gallium/drivers/llvmpipe/lp_test_conv.c
index ac2a6d0..faddfb9 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_conv.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_conv.c
@@ -142,6 +142,7 @@
 }
 
 
+ALIGN_STACK
 static boolean
 test_one(unsigned verbose,
          FILE *fp,
@@ -229,8 +230,8 @@
    for(i = 0; i < n && success; ++i) {
       unsigned src_stride = src_type.length*src_type.width/8;
       unsigned dst_stride = dst_type.length*dst_type.width/8;
-      uint8_t src[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
-      uint8_t dst[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
+      ALIGN16_ATTRIB uint8_t src[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
+      ALIGN16_ATTRIB uint8_t dst[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
       double fref[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
       uint8_t ref[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
       int64_t start_counter = 0;
@@ -329,7 +330,7 @@
          fprintf(stderr, "conv.bc written\n");
          fprintf(stderr, "Invoke as \"llc -o - conv.bc\"\n");
          firsttime = FALSE;
-         //abort();
+         /* abort(); */
       }
    }
 
diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c
index b2403ad..23ea9eb 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_format.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_format.c
@@ -199,6 +199,7 @@
 }
 
 
+ALIGN_STACK
 static boolean
 test_format(unsigned verbose, FILE *fp, const struct pixel_test_case *test)
 {
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_cache.c b/src/gallium/drivers/llvmpipe/lp_tex_cache.c
index 773e848..a6d9a2c 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_cache.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_cache.c
@@ -36,6 +36,7 @@
 #include "util/u_memory.h"
 #include "util/u_tile.h"
 #include "util/u_format.h"
+#include "util/u_math.h"
 #include "lp_context.h"
 #include "lp_surface.h"
 #include "lp_texture.h"
@@ -154,7 +155,6 @@
       if (lpt->timestamp != tc->timestamp) {
          /* texture was modified, invalidate all cached tiles */
          uint i;
-         debug_printf("INV %d %d\n", tc->timestamp, lpt->timestamp);
          for (i = 0; i < NUM_ENTRIES; i++) {
             tc->entries[i].addr.bits.invalid = 1;
          }
@@ -270,8 +270,8 @@
                                      addr.bits.level, 
                                      addr.bits.z, 
                                      PIPE_TRANSFER_READ, 0, 0,
-                                     tc->texture->width[addr.bits.level],
-                                     tc->texture->height[addr.bits.level]);
+                                     u_minify(tc->texture->width0, addr.bits.level),
+                                     u_minify(tc->texture->height0, addr.bits.level));
 
          tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans);
 
@@ -290,7 +290,7 @@
             assert(0);
          }
 
-         util_format_read_4ub(tc->tex_trans->format,
+         util_format_read_4ub(tc->tex_trans->texture->format,
                               (uint8_t *)tile->color, sizeof tile->color[0],
                               tc->tex_trans_map, tc->tex_trans->stride,
                               x, y, w, h);
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_cache.h b/src/gallium/drivers/llvmpipe/lp_tex_cache.h
index 9fa6c36..05fded7 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_cache.h
+++ b/src/gallium/drivers/llvmpipe/lp_tex_cache.h
@@ -115,7 +115,7 @@
 lp_find_cached_tex_tile(struct llvmpipe_tex_tile_cache *tc,
                         union tex_tile_address addr );
 
-static INLINE const union tex_tile_address
+static INLINE union tex_tile_address
 tex_tile_address( unsigned x,
                   unsigned y,
                   unsigned z,
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.h b/src/gallium/drivers/llvmpipe/lp_tex_sample.h
index 9ad1bde..cb59a94 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample.h
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.h
@@ -31,64 +31,11 @@
 
 #include <llvm-c/Core.h>
 
-#include "tgsi/tgsi_exec.h"
 
-
-struct llvmpipe_tex_tile_cache;
 struct lp_sampler_static_state;
 
 
 /**
- * Subclass of tgsi_sampler
- */
-struct lp_shader_sampler
-{
-   struct tgsi_sampler base;  /**< base class */
-
-   unsigned processor;
-
-   /* For lp_get_samples_2d_linear_POT:
-    */
-   unsigned xpot;
-   unsigned ypot;
-   unsigned level;
-
-   const struct pipe_texture *texture;
-   const struct pipe_sampler_state *sampler;
-
-   struct llvmpipe_tex_tile_cache *cache;
-};
-
-
-
-static INLINE struct lp_shader_sampler *
-lp_shader_sampler(const struct tgsi_sampler *sampler)
-{
-   return (struct lp_shader_sampler *) sampler;
-}
-
-
-
-extern void
-lp_get_samples(struct tgsi_sampler *tgsi_sampler,
-               const float s[QUAD_SIZE],
-               const float t[QUAD_SIZE],
-               const float p[QUAD_SIZE],
-               float lodbias,
-               float rgba[NUM_CHANNELS][QUAD_SIZE]);
-
-
-/**
- * Texture sampling code generator that just calls lp_get_samples C function
- * for the actual sampling computation.
- *
- * @param context_ptr LLVM value with the pointer to the struct lp_jit_context.
- */
-struct lp_build_sampler_soa *
-lp_c_sampler_soa_create(LLVMValueRef context_ptr);
-
-
-/**
  * Pure-LLVM texture sampling code generator.
  *
  * @param context_ptr LLVM value with the pointer to the struct lp_jit_context.
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c
deleted file mode 100644
index a1365a0..0000000
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c
+++ /dev/null
@@ -1,1713 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * Copyright 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.
- * 
- **************************************************************************/
-
-/**
- * Texture sampling
- *
- * Authors:
- *   Brian Paul
- */
-
-#include "lp_context.h"
-#include "lp_quad.h"
-#include "lp_surface.h"
-#include "lp_texture.h"
-#include "lp_tex_sample.h"
-#include "lp_tex_cache.h"
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_shader_tokens.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-
-
-
-/*
- * Note, the FRAC macro has to work perfectly.  Otherwise you'll sometimes
- * see 1-pixel bands of improperly weighted linear-filtered textures.
- * The tests/texwrap.c demo is a good test.
- * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0.
- * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x).
- */
-#define FRAC(f)  ((f) - util_ifloor(f))
-
-
-/**
- * Linear interpolation macro
- */
-static INLINE float
-lerp(float a, float v0, float v1)
-{
-   return v0 + a * (v1 - v0);
-}
-
-
-/**
- * Do 2D/biliner interpolation of float values.
- * v00, v10, v01 and v11 are typically four texture samples in a square/box.
- * a and b are the horizontal and vertical interpolants.
- * It's important that this function is inlined when compiled with
- * optimization!  If we find that's not true on some systems, convert
- * to a macro.
- */
-static INLINE float
-lerp_2d(float a, float b,
-        float v00, float v10, float v01, float v11)
-{
-   const float temp0 = lerp(a, v00, v10);
-   const float temp1 = lerp(a, v01, v11);
-   return lerp(b, temp0, temp1);
-}
-
-
-/**
- * As above, but 3D interpolation of 8 values.
- */
-static INLINE float
-lerp_3d(float a, float b, float c,
-        float v000, float v100, float v010, float v110,
-        float v001, float v101, float v011, float v111)
-{
-   const float temp0 = lerp_2d(a, b, v000, v100, v010, v110);
-   const float temp1 = lerp_2d(a, b, v001, v101, v011, v111);
-   return lerp(c, temp0, temp1);
-}
-
-
-
-/**
- * If A is a signed integer, A % B doesn't give the right value for A < 0
- * (in terms of texture repeat).  Just casting to unsigned fixes that.
- */
-#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B))
-
-
-/**
- * Apply texture coord wrapping mode and return integer texture indexes
- * for a vector of four texcoords (S or T or P).
- * \param wrapMode  PIPE_TEX_WRAP_x
- * \param s  the incoming texcoords
- * \param size  the texture image size
- * \param icoord  returns the integer texcoords
- * \return  integer texture index
- */
-static INLINE void
-nearest_texcoord_4(unsigned wrapMode, const float s[4], unsigned size,
-                   int icoord[4])
-{
-   uint ch;
-   switch (wrapMode) {
-   case PIPE_TEX_WRAP_REPEAT:
-      /* s limited to [0,1) */
-      /* i limited to [0,size-1] */
-      for (ch = 0; ch < 4; ch++) {
-         int i = util_ifloor(s[ch] * size);
-         icoord[ch] = REMAINDER(i, size);
-      }
-      return;
-   case PIPE_TEX_WRAP_CLAMP:
-      /* s limited to [0,1] */
-      /* i limited to [0,size-1] */
-      for (ch = 0; ch < 4; ch++) {
-         if (s[ch] <= 0.0F)
-            icoord[ch] = 0;
-         else if (s[ch] >= 1.0F)
-            icoord[ch] = size - 1;
-         else
-            icoord[ch] = util_ifloor(s[ch] * size);
-      }
-      return;
-   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
-      {
-         /* s limited to [min,max] */
-         /* i limited to [0, size-1] */
-         const float min = 1.0F / (2.0F * size);
-         const float max = 1.0F - min;
-         for (ch = 0; ch < 4; ch++) {
-            if (s[ch] < min)
-               icoord[ch] = 0;
-            else if (s[ch] > max)
-               icoord[ch] = size - 1;
-            else
-               icoord[ch] = util_ifloor(s[ch] * size);
-         }
-      }
-      return;
-   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
-      {
-         /* s limited to [min,max] */
-         /* i limited to [-1, size] */
-         const float min = -1.0F / (2.0F * size);
-         const float max = 1.0F - min;
-         for (ch = 0; ch < 4; ch++) {
-            if (s[ch] <= min)
-               icoord[ch] = -1;
-            else if (s[ch] >= max)
-               icoord[ch] = size;
-            else
-               icoord[ch] = util_ifloor(s[ch] * size);
-         }
-      }
-      return;
-   case PIPE_TEX_WRAP_MIRROR_REPEAT:
-      {
-         const float min = 1.0F / (2.0F * size);
-         const float max = 1.0F - min;
-         for (ch = 0; ch < 4; ch++) {
-            const int flr = util_ifloor(s[ch]);
-            float u;
-            if (flr & 1)
-               u = 1.0F - (s[ch] - (float) flr);
-            else
-               u = s[ch] - (float) flr;
-            if (u < min)
-               icoord[ch] = 0;
-            else if (u > max)
-               icoord[ch] = size - 1;
-            else
-               icoord[ch] = util_ifloor(u * size);
-         }
-      }
-      return;
-   case PIPE_TEX_WRAP_MIRROR_CLAMP:
-      for (ch = 0; ch < 4; ch++) {
-         /* s limited to [0,1] */
-         /* i limited to [0,size-1] */
-         const float u = fabsf(s[ch]);
-         if (u <= 0.0F)
-            icoord[ch] = 0;
-         else if (u >= 1.0F)
-            icoord[ch] = size - 1;
-         else
-            icoord[ch] = util_ifloor(u * size);
-      }
-      return;
-   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
-      {
-         /* s limited to [min,max] */
-         /* i limited to [0, size-1] */
-         const float min = 1.0F / (2.0F * size);
-         const float max = 1.0F - min;
-         for (ch = 0; ch < 4; ch++) {
-            const float u = fabsf(s[ch]);
-            if (u < min)
-               icoord[ch] = 0;
-            else if (u > max)
-               icoord[ch] = size - 1;
-            else
-               icoord[ch] = util_ifloor(u * size);
-         }
-      }
-      return;
-   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
-      {
-         /* s limited to [min,max] */
-         /* i limited to [0, size-1] */
-         const float min = -1.0F / (2.0F * size);
-         const float max = 1.0F - min;
-         for (ch = 0; ch < 4; ch++) {
-            const float u = fabsf(s[ch]);
-            if (u < min)
-               icoord[ch] = -1;
-            else if (u > max)
-               icoord[ch] = size;
-            else
-               icoord[ch] = util_ifloor(u * size);
-         }
-      }
-      return;
-   default:
-      assert(0);
-   }
-}
-
-
-/**
- * Used to compute texel locations for linear sampling for four texcoords.
- * \param wrapMode  PIPE_TEX_WRAP_x
- * \param s  the texcoords
- * \param size  the texture image size
- * \param icoord0  returns first texture indexes
- * \param icoord1  returns second texture indexes (usually icoord0 + 1)
- * \param w  returns blend factor/weight between texture indexes
- * \param icoord  returns the computed integer texture coords
- */
-static INLINE void
-linear_texcoord_4(unsigned wrapMode, const float s[4], unsigned size,
-                  int icoord0[4], int icoord1[4], float w[4])
-{
-   uint ch;
-
-   switch (wrapMode) {
-   case PIPE_TEX_WRAP_REPEAT:
-      for (ch = 0; ch < 4; ch++) {
-         float u = s[ch] * size - 0.5F;
-         icoord0[ch] = REMAINDER(util_ifloor(u), size);
-         icoord1[ch] = REMAINDER(icoord0[ch] + 1, size);
-         w[ch] = FRAC(u);
-      }
-      break;;
-   case PIPE_TEX_WRAP_CLAMP:
-      for (ch = 0; ch < 4; ch++) {
-         float u = CLAMP(s[ch], 0.0F, 1.0F);
-         u = u * size - 0.5f;
-         icoord0[ch] = util_ifloor(u);
-         icoord1[ch] = icoord0[ch] + 1;
-         w[ch] = FRAC(u);
-      }
-      break;;
-   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
-      for (ch = 0; ch < 4; ch++) {
-         float u = CLAMP(s[ch], 0.0F, 1.0F);
-         u = u * size - 0.5f;
-         icoord0[ch] = util_ifloor(u);
-         icoord1[ch] = icoord0[ch] + 1;
-         if (icoord0[ch] < 0)
-            icoord0[ch] = 0;
-         if (icoord1[ch] >= (int) size)
-            icoord1[ch] = size - 1;
-         w[ch] = FRAC(u);
-      }
-      break;;
-   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
-      {
-         const float min = -1.0F / (2.0F * size);
-         const float max = 1.0F - min;
-         for (ch = 0; ch < 4; ch++) {
-            float u = CLAMP(s[ch], min, max);
-            u = u * size - 0.5f;
-            icoord0[ch] = util_ifloor(u);
-            icoord1[ch] = icoord0[ch] + 1;
-            w[ch] = FRAC(u);
-         }
-      }
-      break;;
-   case PIPE_TEX_WRAP_MIRROR_REPEAT:
-      for (ch = 0; ch < 4; ch++) {
-         const int flr = util_ifloor(s[ch]);
-         float u;
-         if (flr & 1)
-            u = 1.0F - (s[ch] - (float) flr);
-         else
-            u = s[ch] - (float) flr;
-         u = u * size - 0.5F;
-         icoord0[ch] = util_ifloor(u);
-         icoord1[ch] = icoord0[ch] + 1;
-         if (icoord0[ch] < 0)
-            icoord0[ch] = 0;
-         if (icoord1[ch] >= (int) size)
-            icoord1[ch] = size - 1;
-         w[ch] = FRAC(u);
-      }
-      break;;
-   case PIPE_TEX_WRAP_MIRROR_CLAMP:
-      for (ch = 0; ch < 4; ch++) {
-         float u = fabsf(s[ch]);
-         if (u >= 1.0F)
-            u = (float) size;
-         else
-            u *= size;
-         u -= 0.5F;
-         icoord0[ch] = util_ifloor(u);
-         icoord1[ch] = icoord0[ch] + 1;
-         w[ch] = FRAC(u);
-      }
-      break;;
-   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
-      for (ch = 0; ch < 4; ch++) {
-         float u = fabsf(s[ch]);
-         if (u >= 1.0F)
-            u = (float) size;
-         else
-            u *= size;
-         u -= 0.5F;
-         icoord0[ch] = util_ifloor(u);
-         icoord1[ch] = icoord0[ch] + 1;
-         if (icoord0[ch] < 0)
-            icoord0[ch] = 0;
-         if (icoord1[ch] >= (int) size)
-            icoord1[ch] = size - 1;
-         w[ch] = FRAC(u);
-      }
-      break;;
-   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
-      {
-         const float min = -1.0F / (2.0F * size);
-         const float max = 1.0F - min;
-         for (ch = 0; ch < 4; ch++) {
-            float u = fabsf(s[ch]);
-            if (u <= min)
-               u = min * size;
-            else if (u >= max)
-               u = max * size;
-            else
-               u *= size;
-            u -= 0.5F;
-            icoord0[ch] = util_ifloor(u);
-            icoord1[ch] = icoord0[ch] + 1;
-            w[ch] = FRAC(u);
-         }
-      }
-      break;;
-   default:
-      assert(0);
-   }
-}
-
-
-/**
- * For RECT textures / unnormalized texcoords
- * Only a subset of wrap modes supported.
- */
-static INLINE void
-nearest_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size,
-                          int icoord[4])
-{
-   uint ch;
-   switch (wrapMode) {
-   case PIPE_TEX_WRAP_CLAMP:
-      for (ch = 0; ch < 4; ch++) {
-         int i = util_ifloor(s[ch]);
-         icoord[ch]= CLAMP(i, 0, (int) size-1);
-      }
-      return;
-   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
-      /* fall-through */
-   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
-      for (ch = 0; ch < 4; ch++) {
-         icoord[ch]= util_ifloor( CLAMP(s[ch], 0.5F, (float) size - 0.5F) );
-      }
-      return;
-   default:
-      assert(0);
-   }
-}
-
-
-/**
- * For RECT textures / unnormalized texcoords.
- * Only a subset of wrap modes supported.
- */
-static INLINE void
-linear_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size,
-                         int icoord0[4], int icoord1[4], float w[4])
-{
-   uint ch;
-   switch (wrapMode) {
-   case PIPE_TEX_WRAP_CLAMP:
-      for (ch = 0; ch < 4; ch++) {
-         /* Not exactly what the spec says, but it matches NVIDIA output */
-         float u = CLAMP(s[ch] - 0.5F, 0.0f, (float) size - 1.0f);
-         icoord0[ch] = util_ifloor(u);
-         icoord1[ch] = icoord0[ch] + 1;
-         w[ch] = FRAC(u);
-      }
-      return;
-   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
-      /* fall-through */
-   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
-      for (ch = 0; ch < 4; ch++) {
-         float u = CLAMP(s[ch], 0.5F, (float) size - 0.5F);
-         u -= 0.5F;
-         icoord0[ch] = util_ifloor(u);
-         icoord1[ch] = icoord0[ch] + 1;
-         if (icoord1[ch] > (int) size - 1)
-            icoord1[ch] = size - 1;
-         w[ch] = FRAC(u);
-      }
-      break;
-   default:
-      assert(0);
-   }
-}
-
-
-static unsigned
-choose_cube_face(float rx, float ry, float rz, float *newS, float *newT)
-{
-   /*
-      major axis
-      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
-       -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry
-       +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
-       -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
-   */
-   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;
-      }
-   }
-
-   *newS = ( sc / ma + 1.0F ) * 0.5F;
-   *newT = ( tc / ma + 1.0F ) * 0.5F;
-
-   return face;
-}
-
-
-/**
- * Examine the quad's texture coordinates to compute the partial
- * derivatives w.r.t X and Y, then compute lambda (level of detail).
- *
- * This is only done for fragment shaders, not vertex shaders.
- */
-static float
-compute_lambda(struct tgsi_sampler *tgsi_sampler,
-               const float s[QUAD_SIZE],
-               const float t[QUAD_SIZE],
-               const float p[QUAD_SIZE],
-               float lodbias)
-{
-   const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
-   const struct pipe_texture *texture = samp->texture;
-   const struct pipe_sampler_state *sampler = samp->sampler;
-   float rho, lambda;
-
-   if (samp->processor == TGSI_PROCESSOR_VERTEX)
-      return lodbias;
-
-   assert(sampler->normalized_coords);
-
-   assert(s);
-   {
-      float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT];
-      float dsdy = s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT];
-      dsdx = fabsf(dsdx);
-      dsdy = fabsf(dsdy);
-      rho = MAX2(dsdx, dsdy) * texture->width[0];
-   }
-   if (t) {
-      float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT];
-      float dtdy = t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT];
-      float max;
-      dtdx = fabsf(dtdx);
-      dtdy = fabsf(dtdy);
-      max = MAX2(dtdx, dtdy) * texture->height[0];
-      rho = MAX2(rho, max);
-   }
-   if (p) {
-      float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT];
-      float dpdy = p[QUAD_TOP_LEFT]     - p[QUAD_BOTTOM_LEFT];
-      float max;
-      dpdx = fabsf(dpdx);
-      dpdy = fabsf(dpdy);
-      max = MAX2(dpdx, dpdy) * texture->depth[0];
-      rho = MAX2(rho, max);
-   }
-
-   lambda = util_fast_log2(rho);
-   lambda += lodbias + sampler->lod_bias;
-   lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod);
-
-   return lambda;
-}
-
-
-/**
- * Do several things here:
- * 1. Compute lambda from the texcoords, if needed
- * 2. Determine if we're minifying or magnifying
- * 3. If minifying, choose mipmap levels
- * 4. Return image filter to use within mipmap images
- * \param level0  Returns first mipmap level to sample from
- * \param level1  Returns second mipmap level to sample from
- * \param levelBlend  Returns blend factor between levels, in [0,1]
- * \param imgFilter  Returns either the min or mag filter, depending on lambda
- */
-static void
-choose_mipmap_levels(struct tgsi_sampler *tgsi_sampler,
-                     const float s[QUAD_SIZE],
-                     const float t[QUAD_SIZE],
-                     const float p[QUAD_SIZE],
-                     float lodbias,
-                     unsigned *level0, unsigned *level1, float *levelBlend,
-                     unsigned *imgFilter)
-{
-   const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
-   const struct pipe_texture *texture = samp->texture;
-   const struct pipe_sampler_state *sampler = samp->sampler;
-
-   if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
-      /* no mipmap selection needed */
-      *level0 = *level1 = CLAMP((int) sampler->min_lod,
-                                0, (int) texture->last_level);
-
-      if (sampler->min_img_filter != sampler->mag_img_filter) {
-         /* non-mipmapped texture, but still need to determine if doing
-          * minification or magnification.
-          */
-         float lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias);
-         if (lambda <= 0.0) {
-            *imgFilter = sampler->mag_img_filter;
-         }
-         else {
-            *imgFilter = sampler->min_img_filter;
-         }
-      }
-      else {
-         *imgFilter = sampler->mag_img_filter;
-      }
-   }
-   else {
-      float lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias);
-
-      if (lambda <= 0.0) { /* XXX threshold depends on the filter */
-         /* magnifying */
-         *imgFilter = sampler->mag_img_filter;
-         *level0 = *level1 = 0;
-      }
-      else {
-         /* minifying */
-         *imgFilter = sampler->min_img_filter;
-
-         /* choose mipmap level(s) and compute the blend factor between them */
-         if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
-            /* Nearest mipmap level */
-            const int lvl = (int) (lambda + 0.5);
-            *level0 =
-            *level1 = CLAMP(lvl, 0, (int) texture->last_level);
-         }
-         else {
-            /* Linear interpolation between mipmap levels */
-            const int lvl = (int) lambda;
-            *level0 = CLAMP(lvl,     0, (int) texture->last_level);
-            *level1 = CLAMP(lvl + 1, 0, (int) texture->last_level);
-            *levelBlend = FRAC(lambda);  /* blending weight between levels */
-         }
-      }
-   }
-}
-
-
-/**
- * Get a texel from a texture, using the texture tile cache.
- *
- * \param face  the cube face in 0..5
- * \param level  the mipmap level
- * \param x  the x coord of texel within 2D image
- * \param y  the y coord of texel within 2D image
- * \param z  which slice of a 3D texture
- * \param rgba  the quad to put the texel/color into
- * \param j  which element of the rgba quad to write to
- *
- * XXX maybe move this into lp_tile_cache.c and merge with the
- * lp_get_cached_tile_tex() function.  Also, get 4 texels instead of 1...
- */
-static void
-get_texel_quad_2d(const struct tgsi_sampler *tgsi_sampler,
-                  unsigned face, unsigned level, int x, int y, 
-                  const uint8_t *out[4])
-{
-   const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
-
-   const struct llvmpipe_cached_tex_tile *tile
-      = lp_get_cached_tex_tile(samp->cache,
-                               tex_tile_address(x, y, 0, face, level));
-
-   y %= TEX_TILE_SIZE;
-   x %= TEX_TILE_SIZE;
-      
-   out[0] = &tile->color[y  ][x  ][0];
-   out[1] = &tile->color[y  ][x+1][0];
-   out[2] = &tile->color[y+1][x  ][0];
-   out[3] = &tile->color[y+1][x+1][0];
-}
-
-static INLINE const uint8_t *
-get_texel_2d_ptr(const struct tgsi_sampler *tgsi_sampler,
-                 unsigned face, unsigned level, int x, int y)
-{
-   const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
-
-   const struct llvmpipe_cached_tex_tile *tile
-      = lp_get_cached_tex_tile(samp->cache,
-                               tex_tile_address(x, y, 0, face, level));
-
-   y %= TEX_TILE_SIZE;
-   x %= TEX_TILE_SIZE;
-
-   return &tile->color[y][x][0];
-}
-
-
-static void
-get_texel_quad_2d_mt(const struct tgsi_sampler *tgsi_sampler,
-                     unsigned face, unsigned level, 
-                     int x0, int y0, 
-                     int x1, int y1,
-                     const uint8_t *out[4])
-{
-   unsigned i;
-
-   for (i = 0; i < 4; i++) {
-      unsigned tx = (i & 1) ? x1 : x0;
-      unsigned ty = (i >> 1) ? y1 : y0;
-
-      out[i] = get_texel_2d_ptr( tgsi_sampler, face, level, tx, ty );
-   }
-}
-
-static void
-get_texel(const struct tgsi_sampler *tgsi_sampler,
-                 unsigned face, unsigned level, int x, int y, int z,
-                 float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j)
-{
-   const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
-   const struct pipe_texture *texture = samp->texture;
-   const struct pipe_sampler_state *sampler = samp->sampler;
-
-   if (x < 0 || x >= (int) texture->width[level] ||
-       y < 0 || y >= (int) texture->height[level] ||
-       z < 0 || z >= (int) texture->depth[level]) {
-      rgba[0][j] = sampler->border_color[0];
-      rgba[1][j] = sampler->border_color[1];
-      rgba[2][j] = sampler->border_color[2];
-      rgba[3][j] = sampler->border_color[3];
-   }
-   else {
-      const unsigned tx = x % TEX_TILE_SIZE;
-      const unsigned ty = y % TEX_TILE_SIZE;
-      const struct llvmpipe_cached_tex_tile *tile;
-
-      tile = lp_get_cached_tex_tile(samp->cache,
-                                    tex_tile_address(x, y, z, face, level));
-
-      rgba[0][j] = ubyte_to_float(tile->color[ty][tx][0]);
-      rgba[1][j] = ubyte_to_float(tile->color[ty][tx][1]);
-      rgba[2][j] = ubyte_to_float(tile->color[ty][tx][2]);
-      rgba[3][j] = ubyte_to_float(tile->color[ty][tx][3]);
-      if (0)
-      {
-         debug_printf("Get texel %f %f %f %f from %s\n",
-                      rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j],
-                      pf_name(texture->format));
-      }
-   }
-}
-
-
-/**
- * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
- * When we sampled the depth texture, the depth value was put into all
- * RGBA channels.  We look at the red channel here.
- * \param rgba  quad of (depth) texel values
- * \param p  texture 'P' components for four pixels in quad
- * \param j  which pixel in the quad to test [0..3]
- */
-static INLINE void
-shadow_compare(const struct pipe_sampler_state *sampler,
-               float rgba[NUM_CHANNELS][QUAD_SIZE],
-               const float p[QUAD_SIZE],
-               uint j)
-{
-   int k;
-   switch (sampler->compare_func) {
-   case PIPE_FUNC_LESS:
-      k = p[j] < rgba[0][j];
-      break;
-   case PIPE_FUNC_LEQUAL:
-      k = p[j] <= rgba[0][j];
-      break;
-   case PIPE_FUNC_GREATER:
-      k = p[j] > rgba[0][j];
-      break;
-   case PIPE_FUNC_GEQUAL:
-      k = p[j] >= rgba[0][j];
-      break;
-   case PIPE_FUNC_EQUAL:
-      k = p[j] == rgba[0][j];
-      break;
-   case PIPE_FUNC_NOTEQUAL:
-      k = p[j] != rgba[0][j];
-      break;
-   case PIPE_FUNC_ALWAYS:
-      k = 1;
-      break;
-   case PIPE_FUNC_NEVER:
-      k = 0;
-      break;
-   default:
-      k = 0;
-      assert(0);
-      break;
-   }
-
-   /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */
-   rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k;
-   rgba[3][j] = 1.0F;
-}
-
-
-/**
- * As above, but do four z/texture comparisons.
- */
-static INLINE void
-shadow_compare4(const struct pipe_sampler_state *sampler,
-                float rgba[NUM_CHANNELS][QUAD_SIZE],
-                const float p[QUAD_SIZE])
-{
-   int j, k0, k1, k2, k3;
-   float val;
-
-   /* compare four texcoords vs. four texture samples */
-   switch (sampler->compare_func) {
-   case PIPE_FUNC_LESS:
-      k0 = p[0] < rgba[0][0];
-      k1 = p[1] < rgba[0][1];
-      k2 = p[2] < rgba[0][2];
-      k3 = p[3] < rgba[0][3];
-      break;
-   case PIPE_FUNC_LEQUAL:
-      k0 = p[0] <= rgba[0][0];
-      k1 = p[1] <= rgba[0][1];
-      k2 = p[2] <= rgba[0][2];
-      k3 = p[3] <= rgba[0][3];
-      break;
-   case PIPE_FUNC_GREATER:
-      k0 = p[0] > rgba[0][0];
-      k1 = p[1] > rgba[0][1];
-      k2 = p[2] > rgba[0][2];
-      k3 = p[3] > rgba[0][3];
-      break;
-   case PIPE_FUNC_GEQUAL:
-      k0 = p[0] >= rgba[0][0];
-      k1 = p[1] >= rgba[0][1];
-      k2 = p[2] >= rgba[0][2];
-      k3 = p[3] >= rgba[0][3];
-      break;
-   case PIPE_FUNC_EQUAL:
-      k0 = p[0] == rgba[0][0];
-      k1 = p[1] == rgba[0][1];
-      k2 = p[2] == rgba[0][2];
-      k3 = p[3] == rgba[0][3];
-      break;
-   case PIPE_FUNC_NOTEQUAL:
-      k0 = p[0] != rgba[0][0];
-      k1 = p[1] != rgba[0][1];
-      k2 = p[2] != rgba[0][2];
-      k3 = p[3] != rgba[0][3];
-      break;
-   case PIPE_FUNC_ALWAYS:
-      k0 = k1 = k2 = k3 = 1;
-      break;
-   case PIPE_FUNC_NEVER:
-      k0 = k1 = k2 = k3 = 0;
-      break;
-   default:
-      k0 = k1 = k2 = k3 = 0;
-      assert(0);
-      break;
-   }
-
-   /* convert four pass/fail values to an intensity in [0,1] */
-   val = 0.25F * (k0 + k1 + k2 + k3);
-
-   /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */
-   for (j = 0; j < 4; j++) {
-      rgba[0][j] = rgba[1][j] = rgba[2][j] = val;
-      rgba[3][j] = 1.0F;
-   }
-}
-
-
-
-static void
-lp_get_samples_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler,
-                                    const float s[QUAD_SIZE],
-                                    const float t[QUAD_SIZE],
-                                    const float p[QUAD_SIZE],
-                                    float lodbias,
-                                    float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
-   const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
-   unsigned  j;
-   unsigned level = samp->level;
-   unsigned xpot = 1 << (samp->xpot - level);
-   unsigned ypot = 1 << (samp->ypot - level);
-   unsigned xmax = (xpot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, xpot) - 1; */
-   unsigned ymax = (ypot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, ypot) - 1; */
-      
-   for (j = 0; j < QUAD_SIZE; j++) {
-      int c;
-
-      float u = s[j] * xpot - 0.5F;
-      float v = t[j] * ypot - 0.5F;
-
-      int uflr = util_ifloor(u);
-      int vflr = util_ifloor(v);
-
-      float xw = u - (float)uflr;
-      float yw = v - (float)vflr;
-
-      int x0 = uflr & (xpot - 1);
-      int y0 = vflr & (ypot - 1);
-
-      const uint8_t *tx[4];
-      
-
-      /* Can we fetch all four at once:
-       */
-      if (x0 < xmax && y0 < ymax)
-      {
-         get_texel_quad_2d(tgsi_sampler, 0, level, x0, y0, tx);
-      }
-      else 
-      {
-         unsigned x1 = (x0 + 1) & (xpot - 1);
-         unsigned y1 = (y0 + 1) & (ypot - 1);
-         get_texel_quad_2d_mt(tgsi_sampler, 0, level, 
-                              x0, y0, x1, y1, tx);
-      }
-
-
-      /* interpolate R, G, B, A */
-      for (c = 0; c < 4; c++) {
-         rgba[c][j] = lerp_2d(xw, yw, 
-                              ubyte_to_float(tx[0][c]), ubyte_to_float(tx[1][c]),
-                              ubyte_to_float(tx[2][c]), ubyte_to_float(tx[3][c]));
-      }
-   }
-}
-
-
-static void
-lp_get_samples_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler,
-                                     const float s[QUAD_SIZE],
-                                     const float t[QUAD_SIZE],
-                                     const float p[QUAD_SIZE],
-                                     float lodbias,
-                                     float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
-   const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
-   unsigned  j;
-   unsigned level = samp->level;
-   unsigned xpot = 1 << (samp->xpot - level);
-   unsigned ypot = 1 << (samp->ypot - level);
-
-   for (j = 0; j < QUAD_SIZE; j++) {
-      int c;
-
-      float u = s[j] * xpot;
-      float v = t[j] * ypot;
-
-      int uflr = util_ifloor(u);
-      int vflr = util_ifloor(v);
-
-      int x0 = uflr & (xpot - 1);
-      int y0 = vflr & (ypot - 1);
-
-      const uint8_t *out = get_texel_2d_ptr(tgsi_sampler, 0, level, x0, y0);
-
-      for (c = 0; c < 4; c++) {
-         rgba[c][j] = ubyte_to_float(out[c]);
-      }
-   }
-}
-
-
-static void
-lp_get_samples_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler,
-                                     const float s[QUAD_SIZE],
-                                     const float t[QUAD_SIZE],
-                                     const float p[QUAD_SIZE],
-                                     float lodbias,
-                                     float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
-   const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
-   unsigned  j;
-   unsigned level = samp->level;
-   unsigned xpot = 1 << (samp->xpot - level);
-   unsigned ypot = 1 << (samp->ypot - level);
-
-   for (j = 0; j < QUAD_SIZE; j++) {
-      int c;
-
-      float u = s[j] * xpot;
-      float v = t[j] * ypot;
-
-      int x0, y0;
-      const uint8_t *out;
-
-      x0 = util_ifloor(u);
-      if (x0 < 0) 
-         x0 = 0;
-      else if (x0 > xpot - 1)
-         x0 = xpot - 1;
-
-      y0 = util_ifloor(v);
-      if (y0 < 0) 
-         y0 = 0;
-      else if (y0 > ypot - 1)
-         y0 = ypot - 1;
-      
-      out = get_texel_2d_ptr(tgsi_sampler, 0, level, x0, y0);
-
-      for (c = 0; c < 4; c++) {
-         rgba[c][j] = ubyte_to_float(out[c]);
-      }
-   }
-}
-
-
-static void
-lp_get_samples_2d_linear_mip_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler,
-                                               const float s[QUAD_SIZE],
-                                               const float t[QUAD_SIZE],
-                                               const float p[QUAD_SIZE],
-                                               float lodbias,
-                                               float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
-   struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
-   const struct pipe_texture *texture = samp->texture;
-   int level0;
-   float lambda;
-
-   lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias);
-   level0 = (int)lambda;
-
-   if (lambda < 0.0) { 
-      samp->level = 0;
-      lp_get_samples_2d_linear_repeat_POT( tgsi_sampler,
-                                           s, t, p, 0, rgba );
-   }
-   else if (level0 >= texture->last_level) {
-      samp->level = texture->last_level;
-      lp_get_samples_2d_linear_repeat_POT( tgsi_sampler,
-                                           s, t, p, 0, rgba );
-   }
-   else {
-      float levelBlend = lambda - level0;
-      float rgba0[4][4];
-      float rgba1[4][4];
-      int c,j;
-
-      samp->level = level0;
-      lp_get_samples_2d_linear_repeat_POT( tgsi_sampler,
-                                           s, t, p, 0, rgba0 );
-
-      samp->level = level0+1;
-      lp_get_samples_2d_linear_repeat_POT( tgsi_sampler,
-                                           s, t, p, 0, rgba1 );
-
-      for (j = 0; j < QUAD_SIZE; j++) {
-         for (c = 0; c < 4; c++) {
-            rgba[c][j] = lerp(levelBlend, rgba0[c][j], rgba1[c][j]);
-         }
-      }
-   }
-}
-
-/**
- * Common code for sampling 1D/2D/cube textures.
- * Could probably extend for 3D...
- */
-static void
-lp_get_samples_2d_common(struct tgsi_sampler *tgsi_sampler,
-                         const float s[QUAD_SIZE],
-                         const float t[QUAD_SIZE],
-                         const float p[QUAD_SIZE],
-                         float lodbias,
-                         float rgba[NUM_CHANNELS][QUAD_SIZE],
-                         const unsigned faces[4])
-{
-   const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
-   const struct pipe_texture *texture = samp->texture;
-   const struct pipe_sampler_state *sampler = samp->sampler;
-   unsigned level0, level1, j, imgFilter;
-   int width, height;
-   float levelBlend;
-
-   choose_mipmap_levels(tgsi_sampler, s, t, p, 
-                        lodbias,
-                        &level0, &level1, &levelBlend, &imgFilter);
-
-   assert(sampler->normalized_coords);
-
-   width = texture->width[level0];
-   height = texture->height[level0];
-
-   assert(width > 0);
-
-   switch (imgFilter) {
-   case PIPE_TEX_FILTER_NEAREST:
-      {
-         int x[4], y[4];
-         nearest_texcoord_4(sampler->wrap_s, s, width, x);
-         nearest_texcoord_4(sampler->wrap_t, t, height, y);
-
-         for (j = 0; j < QUAD_SIZE; j++) {
-            get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j);
-            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
-               shadow_compare(sampler, rgba, p, j);
-            }
-
-            if (level0 != level1) {
-               /* get texels from second mipmap level and blend */
-               float rgba2[4][4];
-               unsigned c;
-               x[j] /= 2;
-               y[j] /= 2;
-               get_texel(tgsi_sampler, faces[j], level1, x[j], y[j], 0,
-                         rgba2, j);
-               if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
-                  shadow_compare(sampler, rgba2, p, j);
-               }
-
-               for (c = 0; c < NUM_CHANNELS; c++) {
-                  rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
-               }
-            }
-         }
-      }
-      break;
-   case PIPE_TEX_FILTER_LINEAR:
-   case PIPE_TEX_FILTER_ANISO:
-      {
-         int x0[4], y0[4], x1[4], y1[4];
-         float xw[4], yw[4]; /* weights */
-
-         linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw);
-         linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw);
-
-         for (j = 0; j < QUAD_SIZE; j++) {
-            float tx[4][4]; /* texels */
-            int c;
-            get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0);
-            get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1);
-            get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2);
-            get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3);
-            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
-               shadow_compare4(sampler, tx, p);
-            }
-
-            /* interpolate R, G, B, A */
-            for (c = 0; c < 4; c++) {
-               rgba[c][j] = lerp_2d(xw[j], yw[j],
-                                    tx[c][0], tx[c][1],
-                                    tx[c][2], tx[c][3]);
-            }
-
-            if (level0 != level1) {
-               /* get texels from second mipmap level and blend */
-               float rgba2[4][4];
-
-               /* XXX: This is incorrect -- will often end up with (x0
-                *  == x1 && y0 == y1), meaning that we fetch the same
-                *  texel four times and linearly interpolate between
-                *  identical values.  The correct approach would be to
-                *  call linear_texcoord again for the second level.
-                */
-               x0[j] /= 2;
-               y0[j] /= 2;
-               x1[j] /= 2;
-               y1[j] /= 2;
-               get_texel(tgsi_sampler, faces[j], level1, x0[j], y0[j], 0, tx, 0);
-               get_texel(tgsi_sampler, faces[j], level1, x1[j], y0[j], 0, tx, 1);
-               get_texel(tgsi_sampler, faces[j], level1, x0[j], y1[j], 0, tx, 2);
-               get_texel(tgsi_sampler, faces[j], level1, x1[j], y1[j], 0, tx, 3);
-               if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
-                  shadow_compare4(sampler, tx, p);
-               }
-
-               /* interpolate R, G, B, A */
-               for (c = 0; c < 4; c++) {
-                  rgba2[c][j] = lerp_2d(xw[j], yw[j],
-                                        tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
-               }
-
-               for (c = 0; c < NUM_CHANNELS; c++) {
-                  rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
-               }
-            }
-         }
-      }
-      break;
-   default:
-      assert(0);
-   }
-}
-
-
-static INLINE void
-lp_get_samples_1d(struct tgsi_sampler *sampler,
-                  const float s[QUAD_SIZE],
-                  const float t[QUAD_SIZE],
-                  const float p[QUAD_SIZE],
-                  float lodbias,
-                  float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
-   static const unsigned faces[4] = {0, 0, 0, 0};
-   static const float tzero[4] = {0, 0, 0, 0};
-   lp_get_samples_2d_common(sampler, s, tzero, NULL,
-                            lodbias, rgba, faces);
-}
-
-
-static INLINE void
-lp_get_samples_2d(struct tgsi_sampler *sampler,
-                  const float s[QUAD_SIZE],
-                  const float t[QUAD_SIZE],
-                  const float p[QUAD_SIZE],
-                  float lodbias,
-                  float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
-   static const unsigned faces[4] = {0, 0, 0, 0};
-   lp_get_samples_2d_common(sampler, s, t, p,
-                            lodbias, rgba, faces);
-}
-
-
-static INLINE void
-lp_get_samples_3d(struct tgsi_sampler *tgsi_sampler,
-                  const float s[QUAD_SIZE],
-                  const float t[QUAD_SIZE],
-                  const float p[QUAD_SIZE],
-                  float lodbias,
-                  float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
-   const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
-   const struct pipe_texture *texture = samp->texture;
-   const struct pipe_sampler_state *sampler = samp->sampler;
-   /* get/map pipe_surfaces corresponding to 3D tex slices */
-   unsigned level0, level1, j, imgFilter;
-   int width, height, depth;
-   float levelBlend;
-   const uint face = 0;
-
-   choose_mipmap_levels(tgsi_sampler, s, t, p, 
-                        lodbias,
-                        &level0, &level1, &levelBlend, &imgFilter);
-
-   assert(sampler->normalized_coords);
-
-   width = texture->width[level0];
-   height = texture->height[level0];
-   depth = texture->depth[level0];
-
-   assert(width > 0);
-   assert(height > 0);
-   assert(depth > 0);
-
-   switch (imgFilter) {
-   case PIPE_TEX_FILTER_NEAREST:
-      {
-         int x[4], y[4], z[4];
-         nearest_texcoord_4(sampler->wrap_s, s, width, x);
-         nearest_texcoord_4(sampler->wrap_t, t, height, y);
-         nearest_texcoord_4(sampler->wrap_r, p, depth, z);
-         for (j = 0; j < QUAD_SIZE; j++) {
-            get_texel(tgsi_sampler, face, level0, x[j], y[j], z[j], rgba, j);
-            if (level0 != level1) {
-               /* get texels from second mipmap level and blend */
-               float rgba2[4][4];
-               unsigned c;
-               x[j] /= 2;
-               y[j] /= 2;
-               z[j] /= 2;
-               get_texel(tgsi_sampler, face, level1, x[j], y[j], z[j], rgba2, j);
-               for (c = 0; c < NUM_CHANNELS; c++) {
-                  rgba[c][j] = lerp(levelBlend, rgba2[c][j], rgba[c][j]);
-               }
-            }
-         }
-      }
-      break;
-   case PIPE_TEX_FILTER_LINEAR:
-   case PIPE_TEX_FILTER_ANISO:
-      {
-         int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4];
-         float xw[4], yw[4], zw[4]; /* interpolation weights */
-         linear_texcoord_4(sampler->wrap_s, s, width,  x0, x1, xw);
-         linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw);
-         linear_texcoord_4(sampler->wrap_r, p, depth,  z0, z1, zw);
-
-         for (j = 0; j < QUAD_SIZE; j++) {
-            int c;
-            float tx0[4][4], tx1[4][4];
-            get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z0[j], tx0, 0);
-            get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z0[j], tx0, 1);
-            get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z0[j], tx0, 2);
-            get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z0[j], tx0, 3);
-            get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z1[j], tx1, 0);
-            get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z1[j], tx1, 1);
-            get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z1[j], tx1, 2);
-            get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z1[j], tx1, 3);
-
-            /* interpolate R, G, B, A */
-            for (c = 0; c < 4; c++) {
-               rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j],
-                                    tx0[c][0], tx0[c][1],
-                                    tx0[c][2], tx0[c][3],
-                                    tx1[c][0], tx1[c][1],
-                                    tx1[c][2], tx1[c][3]);
-            }
-
-            if (level0 != level1) {
-               /* get texels from second mipmap level and blend */
-               float rgba2[4][4];
-               x0[j] /= 2;
-               y0[j] /= 2;
-               z0[j] /= 2;
-               x1[j] /= 2;
-               y1[j] /= 2;
-               z1[j] /= 2;
-               get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z0[j], tx0, 0);
-               get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z0[j], tx0, 1);
-               get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z0[j], tx0, 2);
-               get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z0[j], tx0, 3);
-               get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z1[j], tx1, 0);
-               get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z1[j], tx1, 1);
-               get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z1[j], tx1, 2);
-               get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z1[j], tx1, 3);
-
-               /* interpolate R, G, B, A */
-               for (c = 0; c < 4; c++) {
-                  rgba2[c][j] = lerp_3d(xw[j], yw[j], zw[j],
-                                        tx0[c][0], tx0[c][1],
-                                        tx0[c][2], tx0[c][3],
-                                        tx1[c][0], tx1[c][1],
-                                        tx1[c][2], tx1[c][3]);
-               }
-
-               /* blend mipmap levels */
-               for (c = 0; c < NUM_CHANNELS; c++) {
-                  rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
-               }
-            }
-         }
-      }
-      break;
-   default:
-      assert(0);
-   }
-}
-
-
-static void
-lp_get_samples_cube(struct tgsi_sampler *sampler,
-                    const float s[QUAD_SIZE],
-                    const float t[QUAD_SIZE],
-                    const float p[QUAD_SIZE],
-                    float lodbias,
-                    float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
-   unsigned faces[QUAD_SIZE], j;
-   float ssss[4], tttt[4];
-   for (j = 0; j < QUAD_SIZE; j++) {
-      faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j);
-   }
-   lp_get_samples_2d_common(sampler, ssss, tttt, NULL,
-                            lodbias, rgba, faces);
-}
-
-
-static void
-lp_get_samples_rect(struct tgsi_sampler *tgsi_sampler,
-                    const float s[QUAD_SIZE],
-                    const float t[QUAD_SIZE],
-                    const float p[QUAD_SIZE],
-                    float lodbias,
-                    float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
-   const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
-   const struct pipe_texture *texture = samp->texture;
-   const struct pipe_sampler_state *sampler = samp->sampler;
-   const uint face = 0;
-   unsigned level0, level1, j, imgFilter;
-   int width, height;
-   float levelBlend;
-
-   choose_mipmap_levels(tgsi_sampler, s, t, p, 
-                        lodbias,
-                        &level0, &level1, &levelBlend, &imgFilter);
-
-   /* texture RECTS cannot be mipmapped */
-   assert(level0 == level1);
-
-   width = texture->width[level0];
-   height = texture->height[level0];
-
-   assert(width > 0);
-
-   switch (imgFilter) {
-   case PIPE_TEX_FILTER_NEAREST:
-      {
-         int x[4], y[4];
-         nearest_texcoord_unnorm_4(sampler->wrap_s, s, width, x);
-         nearest_texcoord_unnorm_4(sampler->wrap_t, t, height, y);
-         for (j = 0; j < QUAD_SIZE; j++) {
-            get_texel(tgsi_sampler, face, level0, x[j], y[j], 0, rgba, j);
-            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
-               shadow_compare(sampler, rgba, p, j);
-            }
-         }
-      }
-      break;
-   case PIPE_TEX_FILTER_LINEAR:
-   case PIPE_TEX_FILTER_ANISO:
-      {
-         int x0[4], y0[4], x1[4], y1[4];
-         float xw[4], yw[4]; /* weights */
-         linear_texcoord_unnorm_4(sampler->wrap_s, s, width,  x0, x1, xw);
-         linear_texcoord_unnorm_4(sampler->wrap_t, t, height, y0, y1, yw);
-         for (j = 0; j < QUAD_SIZE; j++) {
-            float tx[4][4]; /* texels */
-            int c;
-            get_texel(tgsi_sampler, face, level0, x0[j], y0[j], 0, tx, 0);
-            get_texel(tgsi_sampler, face, level0, x1[j], y0[j], 0, tx, 1);
-            get_texel(tgsi_sampler, face, level0, x0[j], y1[j], 0, tx, 2);
-            get_texel(tgsi_sampler, face, level0, x1[j], y1[j], 0, tx, 3);
-            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
-               shadow_compare4(sampler, tx, p);
-            }
-            for (c = 0; c < 4; c++) {
-               rgba[c][j] = lerp_2d(xw[j], yw[j],
-                                    tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
-            }
-         }
-      }
-      break;
-   default:
-      assert(0);
-   }
-}
-
-
-/**
- * Error condition handler
- */
-static INLINE void
-lp_get_samples_null(struct tgsi_sampler *tgsi_sampler,
-                    const float s[QUAD_SIZE],
-                    const float t[QUAD_SIZE],
-                    const float p[QUAD_SIZE],
-                    float lodbias,
-                    float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
-   int i,j;
-
-   for (i = 0; i < 4; i++)
-      for (j = 0; j < 4; j++)
-         rgba[i][j] = 1.0;
-}
-
-/**
- * Called via tgsi_sampler::get_samples() when using a sampler for the
- * first time.  Determine the actual sampler function, link it in and
- * call it.
- */
-void
-lp_get_samples(struct tgsi_sampler *tgsi_sampler,
-               const float s[QUAD_SIZE],
-               const float t[QUAD_SIZE],
-               const float p[QUAD_SIZE],
-               float lodbias,
-               float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
-   struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
-   const struct pipe_texture *texture = samp->texture;
-   const struct pipe_sampler_state *sampler = samp->sampler;
-
-   /* Default to the 'undefined' case:
-    */
-   tgsi_sampler->get_samples = lp_get_samples_null;
-
-   if (!texture) {
-      assert(0);                /* is this legal?? */
-      goto out;
-   }
-
-   if (!sampler->normalized_coords) {
-      assert (texture->target == PIPE_TEXTURE_2D);
-      tgsi_sampler->get_samples = lp_get_samples_rect;
-      goto out;
-   }
-
-   switch (texture->target) {
-   case PIPE_TEXTURE_1D:
-      tgsi_sampler->get_samples = lp_get_samples_1d;
-      break;
-   case PIPE_TEXTURE_2D:
-      tgsi_sampler->get_samples = lp_get_samples_2d;
-      break;
-   case PIPE_TEXTURE_3D:
-      tgsi_sampler->get_samples = lp_get_samples_3d;
-      break;
-   case PIPE_TEXTURE_CUBE:
-      tgsi_sampler->get_samples = lp_get_samples_cube;
-      break;
-   default:
-      assert(0);
-      break;
-   }
-
-   /* Do this elsewhere: 
-    */
-   samp->xpot = util_unsigned_logbase2( samp->texture->width[0] );
-   samp->ypot = util_unsigned_logbase2( samp->texture->height[0] );
-
-   /* Try to hook in a faster sampler.  Ultimately we'll have to
-    * code-generate these.  Luckily most of this looks like it is
-    * orthogonal state within the sampler.
-    */
-   if (texture->target == PIPE_TEXTURE_2D &&
-       sampler->min_img_filter == sampler->mag_img_filter &&
-       sampler->wrap_s == sampler->wrap_t &&
-       sampler->compare_mode == FALSE &&
-       sampler->normalized_coords) 
-   {
-      if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
-         samp->level = CLAMP((int) sampler->min_lod,
-                             0, (int) texture->last_level);
-
-         if (sampler->wrap_s == PIPE_TEX_WRAP_REPEAT) {
-            switch (sampler->min_img_filter) {
-            case PIPE_TEX_FILTER_NEAREST:
-               tgsi_sampler->get_samples = lp_get_samples_2d_nearest_repeat_POT;
-               break;
-            case PIPE_TEX_FILTER_LINEAR:
-               tgsi_sampler->get_samples = lp_get_samples_2d_linear_repeat_POT;
-               break;
-            default:
-               break;
-            }
-         } 
-         else if (sampler->wrap_s == PIPE_TEX_WRAP_CLAMP) {
-            switch (sampler->min_img_filter) {
-            case PIPE_TEX_FILTER_NEAREST:
-               tgsi_sampler->get_samples = lp_get_samples_2d_nearest_clamp_POT;
-               break;
-            default:
-               break;
-            }
-         }
-      }
-      else if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
-         if (sampler->wrap_s == PIPE_TEX_WRAP_REPEAT) {
-            switch (sampler->min_img_filter) {
-            case PIPE_TEX_FILTER_LINEAR:
-               tgsi_sampler->get_samples = lp_get_samples_2d_linear_mip_linear_repeat_POT;
-               break;
-            default:
-               break;
-            }
-         } 
-      }
-   }
-   else if (0) {
-      _debug_printf("target %d/%d min_mip %d/%d min_img %d/%d wrap %d/%d compare %d/%d norm %d/%d\n",
-                    texture->target, PIPE_TEXTURE_2D,
-                    sampler->min_mip_filter, PIPE_TEX_MIPFILTER_NONE,
-                    sampler->min_img_filter, sampler->mag_img_filter,
-                    sampler->wrap_s, sampler->wrap_t,
-                    sampler->compare_mode, FALSE,
-                    sampler->normalized_coords, TRUE);
-   }
-
-out:
-   tgsi_sampler->get_samples( tgsi_sampler, s, t, p, lodbias, rgba );
-}
-
-
-void PIPE_CDECL
-lp_fetch_texel_soa( struct tgsi_sampler **samplers,
-                    uint32_t unit,
-                    float *store )
-{
-   struct tgsi_sampler *sampler = samplers[unit];
-
-#if 0
-   uint j;
-
-   debug_printf("%s sampler: %p (%p) store: %p\n",
-                __FUNCTION__,
-                sampler, *sampler,
-                store );
-
-   debug_printf("lodbias %f\n", store[12]);
-
-   for (j = 0; j < 4; j++)
-      debug_printf("sample %d texcoord %f %f\n",
-                   j,
-                   store[0+j],
-                   store[4+j]);
-#endif
-
-   {
-      float rgba[NUM_CHANNELS][QUAD_SIZE];
-      sampler->get_samples(sampler,
-                           &store[0],
-                           &store[4],
-                           &store[8],
-                           0.0f, /*store[12],  lodbias */
-                           rgba);
-      memcpy(store, rgba, sizeof rgba);
-   }
-
-#if 0
-   for (j = 0; j < 4; j++)
-      debug_printf("sample %d result %f %f %f %f\n",
-                   j,
-                   store[0+j],
-                   store[4+j],
-                   store[8+j],
-                   store[12+j]);
-#endif
-}
-
-
-#include "lp_bld_type.h"
-#include "lp_bld_intr.h"
-#include "lp_bld_tgsi.h"
-
-
-struct lp_c_sampler_soa
-{
-   struct lp_build_sampler_soa base;
-
-   LLVMValueRef context_ptr;
-
-   LLVMValueRef samplers_ptr;
-
-   /** Coords/texels store */
-   LLVMValueRef store_ptr;
-};
-
-
-static void
-lp_c_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
-{
-   FREE(sampler);
-}
-
-
-static void
-lp_c_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *_sampler,
-                                  LLVMBuilderRef builder,
-                                  struct lp_type type,
-                                  unsigned unit,
-                                  unsigned num_coords,
-                                  const LLVMValueRef *coords,
-                                  LLVMValueRef lodbias,
-                                  LLVMValueRef *texel)
-{
-   struct lp_c_sampler_soa *sampler = (struct lp_c_sampler_soa *)_sampler;
-   LLVMTypeRef vec_type = LLVMTypeOf(coords[0]);
-   LLVMValueRef args[3];
-   unsigned i;
-
-   if(!sampler->samplers_ptr)
-      sampler->samplers_ptr = lp_jit_context_samplers(builder, sampler->context_ptr);
-
-   if(!sampler->store_ptr)
-      sampler->store_ptr = LLVMBuildArrayAlloca(builder,
-                                            vec_type,
-                                            LLVMConstInt(LLVMInt32Type(), 4, 0),
-                                            "texel_store");
-
-   for (i = 0; i < num_coords; i++) {
-      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
-      LLVMValueRef coord_ptr = LLVMBuildGEP(builder, sampler->store_ptr, &index, 1, "");
-      LLVMBuildStore(builder, coords[i], coord_ptr);
-   }
-
-   args[0] = sampler->samplers_ptr;
-   args[1] = LLVMConstInt(LLVMInt32Type(), unit, 0);
-   args[2] = sampler->store_ptr;
-
-   lp_build_intrinsic(builder, "fetch_texel", LLVMVoidType(), args, 3);
-
-   for (i = 0; i < NUM_CHANNELS; ++i) {
-      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
-      LLVMValueRef texel_ptr = LLVMBuildGEP(builder, sampler->store_ptr, &index, 1, "");
-      texel[i] = LLVMBuildLoad(builder, texel_ptr, "");
-   }
-}
-
-
-struct lp_build_sampler_soa *
-lp_c_sampler_soa_create(LLVMValueRef context_ptr)
-{
-   struct lp_c_sampler_soa *sampler;
-
-   sampler = CALLOC_STRUCT(lp_c_sampler_soa);
-   if(!sampler)
-      return NULL;
-
-   sampler->base.destroy = lp_c_sampler_soa_destroy;
-   sampler->base.emit_fetch_texel = lp_c_sampler_soa_emit_fetch_texel;
-   sampler->context_ptr = context_ptr;
-
-   return &sampler->base;
-}
-
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index a00f249..2c13502 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -34,6 +34,8 @@
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
 #include "pipe/internal/p_winsys_screen.h"
+
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 
@@ -48,7 +50,6 @@
 /* Simple, maximally packed layout.
  */
 
-
 /* Conventional allocation path for non-display textures:
  */
 static boolean
@@ -57,29 +58,21 @@
 {
    struct pipe_texture *pt = &lpt->base;
    unsigned level;
-   unsigned width = pt->width[0];
-   unsigned height = pt->height[0];
-   unsigned depth = pt->depth[0];
+   unsigned width = pt->width0;
+   unsigned height = pt->height0;
+   unsigned depth = pt->depth0;
 
    unsigned buffer_size = 0;
 
-   pf_get_block(lpt->base.format, &lpt->base.block);
-
    for (level = 0; level <= pt->last_level; level++) {
       unsigned nblocksx, nblocksy;
 
-      pt->width[level] = width;
-      pt->height[level] = height;
-      pt->depth[level] = depth;
-      pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width);  
-      pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height);
-
       /* Allocate storage for whole quads. This is particularly important
        * for depth surfaces, which are currently stored in a swizzled format. */
-      nblocksx = pf_get_nblocksx(&pt->block, align(width, 2));
-      nblocksy = pf_get_nblocksy(&pt->block, align(height, 2));
+      nblocksx = util_format_get_nblocksx(pt->format, align(width, 2));
+      nblocksy = util_format_get_nblocksy(pt->format, align(height, 2));
 
-      lpt->stride[level] = align(nblocksx*pt->block.size, 16);
+      lpt->stride[level] = align(nblocksx * util_format_get_blocksize(pt->format), 16);
 
       lpt->level_offset[level] = buffer_size;
 
@@ -87,9 +80,9 @@
                       ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
                       lpt->stride[level]);
 
-      width  = minify(width);
-      height = minify(height);
-      depth = minify(depth);
+      width  = u_minify(width, 1);
+      height = u_minify(height, 1);
+      depth = u_minify(depth, 1);
    }
 
    lpt->data = align_malloc(buffer_size, 16);
@@ -103,14 +96,10 @@
 {
    struct llvmpipe_winsys *winsys = screen->winsys;
 
-   pf_get_block(lpt->base.format, &lpt->base.block);
-   lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width[0]);  
-   lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height[0]);  
-
    lpt->dt = winsys->displaytarget_create(winsys,
                                           lpt->base.format,
-                                          lpt->base.width[0],
-                                          lpt->base.height[0],
+                                          lpt->base.width0,
+                                          lpt->base.height0,
                                           16,
                                           &lpt->stride[0] );
 
@@ -172,7 +161,7 @@
    /* Only supports one type */
    if (base->target != PIPE_TEXTURE_2D ||
        base->last_level != 0 ||
-       base->depth[0] != 1) {
+       base->depth0 != 1) {
       return NULL;
    }
 
@@ -183,8 +172,6 @@
    lpt->base = *base;
    pipe_reference_init(&lpt->base.reference, 1);
    lpt->base.screen = screen;
-   lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width[0]);  
-   lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height[0]);  
    lpt->stride[0] = stride[0];
 
    pipe_buffer_reference(&lpt->buffer, buffer);
@@ -229,8 +216,8 @@
       pipe_reference_init(&ps->reference, 1);
       pipe_texture_reference(&ps->texture, pt);
       ps->format = pt->format;
-      ps->width = pt->width[level];
-      ps->height = pt->height[level];
+      ps->width = u_minify(pt->width0, level);
+      ps->height = u_minify(pt->height0, level);
       ps->offset = lpt->level_offset[level];
       ps->usage = usage;
 
@@ -258,11 +245,17 @@
       ps->level = level;
       ps->zslice = zslice;
 
+      /* XXX shouldn't that rather be
+         tex_height = align(ps->height, 2);
+         to account for alignment done in llvmpipe_texture_layout ?
+      */
       if (pt->target == PIPE_TEXTURE_CUBE) {
-         ps->offset += face * pt->nblocksy[level] * lpt->stride[level];
+         unsigned tex_height = ps->height;
+         ps->offset += face * util_format_get_nblocksy(pt->format, tex_height) * lpt->stride[level];
       }
       else if (pt->target == PIPE_TEXTURE_3D) {
-         ps->offset += zslice * pt->nblocksy[level] * lpt->stride[level];
+         unsigned tex_height = ps->height;
+         ps->offset += zslice * util_format_get_nblocksy(pt->format, tex_height) * lpt->stride[level];
       }
       else {
          assert(face == 0);
@@ -303,14 +296,10 @@
    if (lpt) {
       struct pipe_transfer *pt = &lpt->base;
       pipe_texture_reference(&pt->texture, texture);
-      pt->format = texture->format;
-      pt->block = texture->block;
       pt->x = x;
       pt->y = y;
       pt->width = w;
       pt->height = h;
-      pt->nblocksx = texture->nblocksx[level];
-      pt->nblocksy = texture->nblocksy[level];
       pt->stride = lptex->stride[level];
       pt->usage = usage;
       pt->face = face;
@@ -319,11 +308,17 @@
 
       lpt->offset = lptex->level_offset[level];
 
+      /* XXX shouldn't that rather be
+         tex_height = align(u_minify(texture->height0, level), 2)
+         to account for alignment done in llvmpipe_texture_layout ?
+      */
       if (texture->target == PIPE_TEXTURE_CUBE) {
-         lpt->offset += face * pt->nblocksy * pt->stride;
+         unsigned tex_height = u_minify(texture->height0, level);
+         lpt->offset += face *  util_format_get_nblocksy(texture->format, tex_height) * pt->stride;
       }
       else if (texture->target == PIPE_TEXTURE_3D) {
-         lpt->offset += zslice * pt->nblocksy * pt->stride;
+         unsigned tex_height = u_minify(texture->height0, level);
+         lpt->offset += zslice * util_format_get_nblocksy(texture->format, tex_height) * pt->stride;
       }
       else {
          assert(face == 0);
@@ -355,9 +350,11 @@
    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
    ubyte *map, *xfer_map;
    struct llvmpipe_texture *lpt;
+   enum pipe_format format;
 
    assert(transfer->texture);
    lpt = llvmpipe_texture(transfer->texture);
+   format = lpt->base.format;
 
    if(lpt->dt) {
       struct llvmpipe_winsys *winsys = screen->winsys;
@@ -382,8 +379,8 @@
    }
    
    xfer_map = map + llvmpipe_transfer(transfer)->offset +
-      transfer->y / transfer->block.height * transfer->stride +
-      transfer->x / transfer->block.width * transfer->block.size;
+      transfer->y / util_format_get_blockheight(format) * transfer->stride +
+      transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
    /*printf("map = %p  xfer map = %p\n", map, xfer_map);*/
    return xfer_map;
 }
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.c b/src/gallium/drivers/llvmpipe/lp_tile_cache.c
index ec3e002..7a1ecf5 100644
--- a/src/gallium/drivers/llvmpipe/lp_tile_cache.c
+++ b/src/gallium/drivers/llvmpipe/lp_tile_cache.c
@@ -252,13 +252,13 @@
                case LP_TILE_STATUS_CLEAR:
                   /* Actually clear the tiles which were flagged as being in a
                    * clear state. */
-                  util_fill_rect(tc->transfer_map, &pt->block, pt->stride,
+                  util_fill_rect(tc->transfer_map, pt->texture->format, pt->stride,
                                  x, y, w, h,
                                  tc->clear_val);
                   break;
 
                case LP_TILE_STATUS_DEFINED:
-                  lp_tile_write_4ub(pt->format,
+                  lp_tile_write_4ub(pt->texture->format,
                                     tile->color,
                                     tc->transfer_map, pt->stride,
                                     x, y, w, h);
@@ -291,6 +291,11 @@
    assert(tc->surface);
    assert(tc->transfer);
 
+   if(!tc->transfer_map)
+      lp_tile_cache_map_transfers(tc);
+
+   assert(tc->transfer_map);
+
    switch(tile->status) {
    case LP_TILE_STATUS_CLEAR:
       /* don't get tile from framebuffer, just clear it */
@@ -306,7 +311,7 @@
       y &= ~(TILE_SIZE - 1);
 
       if (!pipe_clip_tile(x, y, &w, &h, tc->transfer))
-         lp_tile_read_4ub(pt->format,
+         lp_tile_read_4ub(pt->texture->format,
                           tile->color,
                           tc->transfer_map, tc->transfer->stride,
                           x, y, w, h);
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_soa.h b/src/gallium/drivers/llvmpipe/lp_tile_soa.h
index 040b018..19d00b5 100644
--- a/src/gallium/drivers/llvmpipe/lp_tile_soa.h
+++ b/src/gallium/drivers/llvmpipe/lp_tile_soa.h
@@ -29,7 +29,7 @@
 #define LP_TILE_SOA_H
 
 #include "pipe/p_compiler.h"
-#include "tgsi/tgsi_exec.h" // for NUM_CHANNELS
+#include "tgsi/tgsi_exec.h" /* for NUM_CHANNELS */
 
 
 #ifdef __cplusplus
diff --git a/src/gallium/drivers/llvmpipe/lp_winsys.h b/src/gallium/drivers/llvmpipe/lp_winsys.h
index 595481c..74b472b 100644
--- a/src/gallium/drivers/llvmpipe/lp_winsys.h
+++ b/src/gallium/drivers/llvmpipe/lp_winsys.h
@@ -35,7 +35,7 @@
 #define LP_WINSYS_H
 
 
-#include "pipe/p_compiler.h" // for boolean
+#include "pipe/p_compiler.h" /* for boolean */
 #include "pipe/p_format.h"
 
 
diff --git a/src/gallium/drivers/nouveau/nouveau_push.h b/src/gallium/drivers/nouveau/nouveau_push.h
deleted file mode 100644
index 9c23508..0000000
--- a/src/gallium/drivers/nouveau/nouveau_push.h
+++ /dev/null
@@ -1,93 +0,0 @@
-#ifndef __NOUVEAU_PUSH_H__
-#define __NOUVEAU_PUSH_H__
-
-#include "nouveau/nouveau_winsys.h"
-
-#ifndef NOUVEAU_PUSH_CONTEXT
-#error undefined push context
-#endif
-
-#define OUT_RING(data) do {                                                    \
-	NOUVEAU_PUSH_CONTEXT(pc);                                              \
-	(*pc->base.channel->pushbuf->cur++) = (data);                          \
-} while(0)
-
-#define OUT_RINGp(src,size) do {                                               \
-	NOUVEAU_PUSH_CONTEXT(pc);                                              \
-	memcpy(pc->base.channel->pushbuf->cur, (src), (size) * 4);             \
-	pc->base.channel->pushbuf->cur += (size);                              \
-} while(0)
-
-#define OUT_RINGf(data) do {                                                   \
-	union { float v; uint32_t u; } c;                                      \
-	c.v = (data);                                                          \
-	OUT_RING(c.u);                                                         \
-} while(0)
-
-#define BEGIN_RING(obj,mthd,size) do {                                         \
-	NOUVEAU_PUSH_CONTEXT(pc);                                              \
-	struct nouveau_channel *chan = pc->base.channel;                       \
-	if (chan->pushbuf->remaining < ((size) + 1))                           \
-		nouveau_pushbuf_flush(chan, ((size) + 1));                     \
-	OUT_RING((pc->obj->subc << 13) | ((size) << 18) | (mthd));             \
-	chan->pushbuf->remaining -= ((size) + 1);                              \
-} while(0)
-
-#define BEGIN_RING_NI(obj,mthd,size) do {                                      \
-	BEGIN_RING(obj, (mthd) | 0x40000000, (size));                          \
-} while(0)
-
-static inline void
-DO_FIRE_RING(struct nouveau_channel *chan, struct pipe_fence_handle **fence)
-{
-	nouveau_pushbuf_flush(chan, 0);
-	if (fence)
-		*fence = NULL;
-}
-
-#define FIRE_RING(fence) do {                                                  \
-	NOUVEAU_PUSH_CONTEXT(pc);                                              \
-	DO_FIRE_RING(pc->base.channel, fence);                                 \
-} while(0)
-
-#define OUT_RELOC(bo,data,flags,vor,tor) do {                                  \
-	NOUVEAU_PUSH_CONTEXT(pc);                                              \
-	struct nouveau_channel *chan = pc->base.channel;                       \
-	nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, nouveau_bo(bo), \
-				   (data), 0, (flags), (vor), (tor));          \
-} while(0)
-
-/* Raw data + flags depending on FB/TT buffer */
-#define OUT_RELOCd(bo,data,flags,vor,tor) do {                                 \
-	OUT_RELOC((bo), (data), (flags) | NOUVEAU_BO_OR, (vor), (tor));        \
-} while(0)
-
-/* FB/TT object handle */
-#define OUT_RELOCo(bo,flags) do {                                              \
-	OUT_RELOC((bo), 0, (flags) | NOUVEAU_BO_OR,                            \
-		  pc->base.channel->vram->handle,                              \
-		  pc->base.channel->gart->handle);                             \
-} while(0)
-
-/* Low 32-bits of offset */
-#define OUT_RELOCl(bo,delta,flags) do {                                        \
-	OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_LOW, 0, 0);              \
-} while(0)
-
-/* High 32-bits of offset */
-#define OUT_RELOCh(bo,delta,flags) do {                                        \
-	OUT_RELOC((bo), (delta), (flags) | NOUVEAU_BO_HIGH, 0, 0);             \
-} while(0)
-
-/* A reloc which'll recombine into a NV_DMA_METHOD packet header */
-#define OUT_RELOCm(bo, flags, obj, mthd, size) do {                            \
-	NOUVEAU_PUSH_CONTEXT(pc);                                              \
-	struct nouveau_channel *chan = pc->base.channel;                       \
-	if (chan->pushbuf->remaining < ((size) + 1))                           \
-		nouveau_pushbuf_flush(chan, ((size) + 1));                     \
-	OUT_RELOCd((bo), (pc->obj->subc << 13) | ((size) << 18) | (mthd),      \
-		   (flags), 0, 0);                                             \
-	chan->pushbuf->remaining -= ((size) + 1);                              \
-} while(0)
-
-#endif
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index e4cf91c..7ebc94e 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -31,7 +31,7 @@
 		       unsigned alignment, unsigned usage, unsigned size)
 {
 	struct pipe_buffer *pb;
-	
+
 	pb = CALLOC(1, sizeof(struct pipe_buffer)+sizeof(struct nouveau_bo *));
 	if (!pb) {
 		nouveau_bo_ref(NULL, &bo);
@@ -127,8 +127,18 @@
 		      unsigned usage)
 {
 	struct nouveau_bo *bo = nouveau_bo(pb);
+	struct nouveau_screen *nscreen = nouveau_screen(pscreen);
 	int ret;
 
+	if (nscreen->pre_pipebuffer_map_callback) {
+		ret = nscreen->pre_pipebuffer_map_callback(pscreen, pb, usage);
+		if (ret) {
+			debug_printf("pre_pipebuffer_map_callback failed %d\n",
+				ret);
+			return NULL;
+		}
+	}
+
 	ret = nouveau_bo_map(bo, nouveau_screen_map_flags(usage));
 	if (ret) {
 		debug_printf("map failed: %d\n", ret);
@@ -143,11 +153,22 @@
 			    unsigned offset, unsigned length, unsigned usage)
 {
 	struct nouveau_bo *bo = nouveau_bo(pb);
+	struct nouveau_screen *nscreen = nouveau_screen(pscreen);
 	uint32_t flags = nouveau_screen_map_flags(usage);
 	int ret;
 
+	if (nscreen->pre_pipebuffer_map_callback) {
+		ret = nscreen->pre_pipebuffer_map_callback(pscreen, pb, usage);
+		if (ret) {
+			debug_printf("pre_pipebuffer_map_callback failed %d\n",
+				ret);
+			return NULL;
+		}
+	}
+
 	ret = nouveau_bo_map_range(bo, offset, length, flags);
 	if (ret) {
+		nouveau_bo_unmap(bo);
 		if (!(flags & NOUVEAU_BO_NOWAIT) || ret != -EBUSY)
 			debug_printf("map_range failed: %d\n", ret);
 		return NULL;
@@ -239,5 +260,6 @@
 void
 nouveau_screen_fini(struct nouveau_screen *screen)
 {
+	nouveau_channel_free(&screen->channel);
 }
 
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h
index ebfc67a..a7927d8 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -5,6 +5,9 @@
 	struct pipe_screen base;
 	struct nouveau_device *device;
 	struct nouveau_channel *channel;
+
+	int (*pre_pipebuffer_map_callback) (struct pipe_screen *pscreen,
+		struct pipe_buffer *pb, unsigned usage);
 };
 
 static inline struct nouveau_screen *
diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h
index b595405..e844f6a 100644
--- a/src/gallium/drivers/nouveau/nouveau_stateobj.h
+++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h
@@ -3,41 +3,95 @@
 
 #include "util/u_debug.h"
 
+#ifdef DEBUG
+#define DEBUG_NOUVEAU_STATEOBJ
+#endif /* DEBUG */
+
 struct nouveau_stateobj_reloc {
 	struct nouveau_bo *bo;
 
-	unsigned offset;
-	unsigned packet;
+	struct nouveau_grobj *gr;
+	uint32_t push_offset;
+	uint32_t mthd;
 
-	unsigned data;
+	uint32_t data;
 	unsigned flags;
 	unsigned vor;
 	unsigned tor;
 };
 
+struct nouveau_stateobj_start {
+	struct nouveau_grobj *gr;
+	uint32_t mthd;
+	uint32_t size;
+	unsigned offset;
+};
+
 struct nouveau_stateobj {
 	struct pipe_reference reference;
 
-	unsigned *push;
+	struct nouveau_stateobj_start *start;
 	struct nouveau_stateobj_reloc *reloc;
 
-	unsigned *cur;
-	unsigned cur_packet;
+	/* Common memory pool for data. */
+	uint32_t *pool;
+	unsigned pool_cur;
+
+#ifdef DEBUG_NOUVEAU_STATEOBJ
+	unsigned start_alloc;
+	unsigned reloc_alloc;
+	unsigned pool_alloc;
+#endif  /* DEBUG_NOUVEAU_STATEOBJ */
+
+	unsigned total; /* includes begin_ring */
+	unsigned cur; /* excludes begin_ring, offset from "cur_start" */
+	unsigned cur_start;
 	unsigned cur_reloc;
 };
 
+static INLINE void
+so_dump(struct nouveau_stateobj *so)
+{
+	unsigned i, nr, total = 0;
+
+	for (i = 0; i < so->cur_start; i++) {
+		if (so->start[i].gr->subc > -1)
+			debug_printf("+0x%04x: 0x%08x\n", total++,
+				(so->start[i].size << 18) | (so->start[i].gr->subc << 13)
+				| so->start[i].mthd);
+		else
+			debug_printf("+0x%04x: 0x%08x\n", total++,
+				(so->start[i].size << 18) | so->start[i].mthd);
+		for (nr = 0; nr < so->start[i].size; nr++, total++)
+			debug_printf("+0x%04x: 0x%08x\n", total,
+				so->pool[so->start[i].offset + nr]);
+	}
+}
+
 static INLINE struct nouveau_stateobj *
-so_new(unsigned push, unsigned reloc)
+so_new(unsigned start, unsigned push, unsigned reloc)
 {
 	struct nouveau_stateobj *so;
 
 	so = MALLOC(sizeof(struct nouveau_stateobj));
 	pipe_reference_init(&so->reference, 1);
-	so->push = MALLOC(sizeof(unsigned) * push);
-	so->reloc = MALLOC(sizeof(struct nouveau_stateobj_reloc) * reloc);
+	so->total = so->cur = so->cur_start = so->cur_reloc = 0;
 
-	so->cur = so->push;
-	so->cur_reloc = so->cur_packet = 0;
+#ifdef DEBUG_NOUVEAU_STATEOBJ
+	so->start_alloc = start;
+	so->reloc_alloc = reloc;
+	so->pool_alloc = push;
+#endif /* DEBUG_NOUVEAU_STATEOBJ */
+
+	so->start = MALLOC(start * sizeof(struct nouveau_stateobj_start));
+	so->reloc = MALLOC(reloc * sizeof(struct nouveau_stateobj_reloc));
+	so->pool = MALLOC(push * sizeof(uint32_t));
+	so->pool_cur = 0;
+
+	if (!so->start || !so->reloc || !so->pool) {
+		debug_printf("malloc failed\n");
+		assert(0);
+	}
 
 	return so;
 }
@@ -48,62 +102,128 @@
 	struct nouveau_stateobj *so = *pso;
 	int i;
 
-        if (pipe_reference((struct pipe_reference**)pso, &ref->reference)) {
-		free(so->push);
+	if (pipe_reference(&(*pso)->reference, &ref->reference)) {
+		FREE(so->start);
 		for (i = 0; i < so->cur_reloc; i++)
 			nouveau_bo_ref(NULL, &so->reloc[i].bo);
-		free(so->reloc);
-		free(so);
+		FREE(so->reloc);
+		FREE(so->pool);
+		FREE(so);
 	}
+	*pso = ref;
 }
 
 static INLINE void
-so_data(struct nouveau_stateobj *so, unsigned data)
+so_data(struct nouveau_stateobj *so, uint32_t data)
 {
-	(*so->cur++) = (data);
-	so->cur_packet += 4;
+#ifdef DEBUG_NOUVEAU_STATEOBJ
+	if (so->cur >= so->start[so->cur_start - 1].size) {
+		debug_printf("exceeding specified size\n");
+		assert(0);
+	}
+#endif /* DEBUG_NOUVEAU_STATEOBJ */
+
+	so->pool[so->start[so->cur_start - 1].offset + so->cur++] = data;
 }
 
 static INLINE void
-so_datap(struct nouveau_stateobj *so, unsigned *data, unsigned size)
+so_datap(struct nouveau_stateobj *so, uint32_t *data, unsigned size)
 {
-	so->cur_packet += (4 * size);
+#ifdef DEBUG_NOUVEAU_STATEOBJ
+	if ((so->cur + size) > so->start[so->cur_start - 1].size) {
+		debug_printf("exceeding specified size\n");
+		assert(0);
+	}
+#endif /* DEBUG_NOUVEAU_STATEOBJ */
+
 	while (size--)
-		(*so->cur++) = (*data++);
+		so->pool[so->start[so->cur_start - 1].offset + so->cur++] =
+			*data++;
 }
 
 static INLINE void
 so_method(struct nouveau_stateobj *so, struct nouveau_grobj *gr,
 	  unsigned mthd, unsigned size)
 {
-	so->cur_packet = (gr->subc << 13) | (1 << 18) | (mthd - 4);
-	so_data(so, (gr->subc << 13) | (size << 18) | mthd);
+	struct nouveau_stateobj_start *start;
+
+#ifdef DEBUG_NOUVEAU_STATEOBJ
+	if (so->start_alloc <= so->cur_start) {
+		debug_printf("exceeding num_start size\n");
+		assert(0);
+	} else
+#endif /* DEBUG_NOUVEAU_STATEOBJ */
+		start = so->start;
+
+#ifdef DEBUG_NOUVEAU_STATEOBJ
+	if (so->cur_start > 0 && start[so->cur_start - 1].size > so->cur) {
+		debug_printf("previous so_method was not filled\n");
+		assert(0);
+	}
+#endif /* DEBUG_NOUVEAU_STATEOBJ */
+
+	so->start = start;
+	start[so->cur_start].gr = gr;
+	start[so->cur_start].mthd = mthd;
+	start[so->cur_start].size = size;
+
+#ifdef DEBUG_NOUVEAU_STATEOBJ
+	if (so->pool_alloc < (size + so->pool_cur)) {
+		debug_printf("exceeding num_pool size\n");
+		assert(0);
+	}
+#endif /* DEBUG_NOUVEAU_STATEOBJ */
+
+	start[so->cur_start].offset = so->pool_cur;
+	so->pool_cur += size;
+
+	so->cur_start++;
+	/* The 1 is for *this* begin_ring. */
+	so->total += so->cur + 1;
+	so->cur = 0;
 }
 
 static INLINE void
 so_reloc(struct nouveau_stateobj *so, struct nouveau_bo *bo,
 	 unsigned data, unsigned flags, unsigned vor, unsigned tor)
 {
-	struct nouveau_stateobj_reloc *r = &so->reloc[so->cur_reloc++];
-	
-	r->bo = NULL;
-	nouveau_bo_ref(bo, &r->bo);
-	r->offset = so->cur - so->push;
-	r->packet = so->cur_packet;
-	r->data = data;
-	r->flags = flags;
-	r->vor = vor;
-	r->tor = tor;
+	struct nouveau_stateobj_reloc *r;
+
+#ifdef DEBUG_NOUVEAU_STATEOBJ
+	if (so->reloc_alloc <= so->cur_reloc) {
+		debug_printf("exceeding num_reloc size\n");
+		assert(0);
+	} else
+#endif /* DEBUG_NOUVEAU_STATEOBJ */
+		r = so->reloc;
+
+	so->reloc = r;
+	r[so->cur_reloc].bo = NULL;
+	nouveau_bo_ref(bo, &(r[so->cur_reloc].bo));
+	r[so->cur_reloc].gr = so->start[so->cur_start-1].gr;
+	r[so->cur_reloc].push_offset = so->total + so->cur;
+	r[so->cur_reloc].data = data;
+	r[so->cur_reloc].flags = flags;
+	r[so->cur_reloc].mthd = so->start[so->cur_start-1].mthd +
+							(so->cur << 2);
+	r[so->cur_reloc].vor = vor;
+	r[so->cur_reloc].tor = tor;
+
 	so_data(so, data);
+	so->cur_reloc++;
 }
 
-static INLINE void
-so_dump(struct nouveau_stateobj *so)
+/* Determine if this buffer object is referenced by this state object. */
+static INLINE boolean
+so_bo_is_reloc(struct nouveau_stateobj *so, struct nouveau_bo *bo)
 {
-	unsigned i, nr = so->cur - so->push;
+	int i;
 
-	for (i = 0; i < nr; i++)
-		debug_printf("+0x%04x: 0x%08x\n", i, so->push[i]);
+	for (i = 0; i < so->cur_reloc; i++)
+		if (so->reloc[i].bo == bo)
+			return true;
+
+	return false;
 }
 
 static INLINE void
@@ -111,48 +231,95 @@
 {
 	struct nouveau_pushbuf *pb = chan->pushbuf;
 	unsigned nr, i;
+	int ret = 0;
 
-	nr = so->cur - so->push;
-	if (pb->remaining < nr)
-		nouveau_pushbuf_flush(chan, nr);
-	pb->remaining -= nr;
+#ifdef DEBUG_NOUVEAU_STATEOBJ
+	if (so->start[so->cur_start - 1].size > so->cur) {
+		debug_printf("emit: previous so_method was not filled\n");
+		assert(0);
+	}
+#endif /* DEBUG_NOUVEAU_STATEOBJ */
 
-	memcpy(pb->cur, so->push, nr * 4);
+	/* We cannot update total in case we so_emit again. */
+	nr = so->total + so->cur;
+
+	/* This will flush if we need space.
+	 * We don't actually need the marker.
+	 */
+	if ((ret = nouveau_pushbuf_marker_emit(chan, nr, so->cur_reloc))) {
+		debug_printf("so_emit failed marker emit with error %d\n", ret);
+		assert(0);
+	}
+
+	/* Submit data. This will ensure proper binding of objects. */
+	for (i = 0; i < so->cur_start; i++) {
+		BEGIN_RING(chan, so->start[i].gr, so->start[i].mthd, so->start[i].size);
+		OUT_RINGp(chan, &(so->pool[so->start[i].offset]), so->start[i].size);
+	}
+
 	for (i = 0; i < so->cur_reloc; i++) {
 		struct nouveau_stateobj_reloc *r = &so->reloc[i];
 
-		nouveau_pushbuf_emit_reloc(chan, pb->cur + r->offset,
-					   r->bo, r->data, 0, r->flags,
-					   r->vor, r->tor);
+		if ((ret = nouveau_pushbuf_emit_reloc(chan, pb->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);
+			assert(0);
+		}
 	}
-	pb->cur += nr;
 }
 
 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;
 
 	if (!so)
 		return;
 
-	i = so->cur_reloc << 1;
-	if (pb->remaining < i)
-		nouveau_pushbuf_flush(chan, i);
-	pb->remaining -= i;
-
+	/* If we need to flush in flush notify, then we have a problem anyway. */
 	for (i = 0; i < so->cur_reloc; i++) {
 		struct nouveau_stateobj_reloc *r = &so->reloc[i];
 
-		nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo, r->packet, 0,
-					   (r->flags & (NOUVEAU_BO_VRAM |
-							NOUVEAU_BO_GART |
-							NOUVEAU_BO_RDWR)) |
-					   NOUVEAU_BO_DUMMY, 0, 0);
-		nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo, r->data, 0,
-					   r->flags | NOUVEAU_BO_DUMMY,
-					   r->vor, r->tor);
+#ifdef DEBUG_NOUVEAU_STATEOBJ
+		if (r->mthd & 0x40000000) {
+			debug_printf("error: NI mthd 0x%08X\n", r->mthd);
+			continue;
+		}
+#endif /* DEBUG_NOUVEAU_STATEOBJ */
+
+		/* The object needs to be bound and the system must know the
+		 * subchannel is being used. Otherwise it will discard it.
+		 */
+		if (gr != r->gr) {
+			BEGIN_RING(chan, r->gr, 0x100, 1);
+			OUT_RING(chan, 0);
+			gr = r->gr;
+		}
+
+		/* Some relocs really don't like to be hammered,
+		 * NOUVEAU_BO_DUMMY makes sure it only
+		 * happens when needed.
+		 */
+		ret = OUT_RELOC(chan, r->bo, (r->gr->subc << 13) | (1<< 18) |
+			r->mthd, (r->flags & (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART
+				| NOUVEAU_BO_RDWR)) | NOUVEAU_BO_DUMMY, 0, 0);
+		if (ret) {
+			debug_printf("OUT_RELOC failed %d\n", ret);
+			assert(0);
+		}
+
+		ret = OUT_RELOC(chan, r->bo, r->data, r->flags |
+			NOUVEAU_BO_DUMMY, r->vor, r->tor);
+		if (ret) {
+			debug_printf("OUT_RELOC failed %d\n", ret);
+			assert(0);
+		}
+
+		pb->remaining -= 2;
 	}
 }
 
diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h
index 42c77e5..4c3e08a 100644
--- a/src/gallium/drivers/nouveau/nouveau_winsys.h
+++ b/src/gallium/drivers/nouveau/nouveau_winsys.h
@@ -23,6 +23,9 @@
 #define NOUVEAU_BUFFER_USAGE_ZETA     (1 << 17)
 #define NOUVEAU_BUFFER_USAGE_TRANSFER (1 << 18)
 
+/* use along with GPU_WRITE for 2D-only writes */
+#define NOUVEAU_BUFFER_USAGE_NO_RENDER (1 << 19)
+
 extern struct pipe_screen *
 nv04_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
 
diff --git a/src/gallium/drivers/nv04/nv04_context.c b/src/gallium/drivers/nv04/nv04_context.c
index 10d984a..edd9685 100644
--- a/src/gallium/drivers/nv04/nv04_context.c
+++ b/src/gallium/drivers/nv04/nv04_context.c
@@ -10,10 +10,14 @@
 	   struct pipe_fence_handle **fence)
 {
 	struct nv04_context *nv04 = nv04_context(pipe);
+	struct nv04_screen *screen = nv04->screen;
+	struct nouveau_channel *chan = screen->base.channel;
 
 	draw_flush(nv04->draw);
 
-	FIRE_RING(fence);
+	FIRE_RING(chan);
+	if (fence)
+		*fence = NULL;
 }
 
 static void
@@ -27,40 +31,39 @@
 	FREE(nv04);
 }
 
-static void
-nv04_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
-{
-}
-
 static boolean
 nv04_init_hwctx(struct nv04_context *nv04)
 {
+	struct nv04_screen *screen = nv04->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *fahrenheit = screen->fahrenheit;
+
 	// requires a valid handle
-//	BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_NOTIFY, 1);
+//	BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_NOTIFY, 1);
 //	OUT_RING(0);
-	BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_NOP, 1);
-	OUT_RING(0);
+	BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_NOP, 1);
+	OUT_RING(chan, 0);
 
-	BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1);
-	OUT_RING(0x40182800);
+	BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1);
+	OUT_RING(chan, 0x40182800);
 //	OUT_RING(1<<20/*no cull*/);
-	BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1);
+	BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_BLEND, 1);
 //	OUT_RING(0x24|(1<<6)|(1<<8));
-	OUT_RING(0x120001a4);
-	BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_FORMAT, 1);
-	OUT_RING(0x332213a1);
-	BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_FILTER, 1);
-	OUT_RING(0x11001010);
-	BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_COLORKEY, 1);
-	OUT_RING(0x0);
-//	BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 1);
+	OUT_RING(chan, 0x120001a4);
+	BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FORMAT, 1);
+	OUT_RING(chan, 0x332213a1);
+	BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FILTER, 1);
+	OUT_RING(chan, 0x11001010);
+	BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_COLORKEY, 1);
+	OUT_RING(chan, 0x0);
+//	BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_OFFSET, 1);
 //	OUT_RING(SCREEN_OFFSET);
-	BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_FOGCOLOR, 1);
-	OUT_RING(0xff000000);
+	BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FOGCOLOR, 1);
+	OUT_RING(chan, 0xff000000);
 
 
 
-	FIRE_RING (NULL);
+	FIRE_RING (chan);
 	return TRUE;
 }
 
@@ -83,7 +86,6 @@
 	nv04->pipe.winsys = ws;
 	nv04->pipe.screen = pscreen;
 	nv04->pipe.destroy = nv04_destroy;
-	nv04->pipe.set_edgeflags = nv04_set_edgeflags;
 	nv04->pipe.draw_arrays = nv04_draw_arrays;
 	nv04->pipe.draw_elements = nv04_draw_elements;
 	nv04->pipe.clear = nv04_clear;
diff --git a/src/gallium/drivers/nv04/nv04_context.h b/src/gallium/drivers/nv04/nv04_context.h
index 55326c7..fe3b527 100644
--- a/src/gallium/drivers/nv04/nv04_context.h
+++ b/src/gallium/drivers/nv04/nv04_context.h
@@ -15,10 +15,6 @@
 #include "nouveau/nouveau_gldefs.h"
 #include "nouveau/nouveau_context.h"
 
-#define NOUVEAU_PUSH_CONTEXT(ctx)                                              \
-	struct nv04_screen *ctx = nv04->screen
-#include "nouveau/nouveau_push.h"
-
 #include "nv04_state.h"
 
 #define NOUVEAU_ERR(fmt, args...) \
@@ -141,9 +137,9 @@
 extern void nv04_state_tex_update(struct nv04_context *nv04);
 
 /* nv04_vbo.c */
-extern boolean nv04_draw_arrays(struct pipe_context *, unsigned mode,
+extern void nv04_draw_arrays(struct pipe_context *, unsigned mode,
 				unsigned start, unsigned count);
-extern boolean nv04_draw_elements( struct pipe_context *pipe,
+extern void nv04_draw_elements( struct pipe_context *pipe,
                     struct pipe_buffer *indexBuffer,
                     unsigned indexSize,
                     unsigned prim, unsigned start, unsigned count);
diff --git a/src/gallium/drivers/nv04/nv04_fragtex.c b/src/gallium/drivers/nv04/nv04_fragtex.c
index 21f990f..c152b52 100644
--- a/src/gallium/drivers/nv04/nv04_fragtex.c
+++ b/src/gallium/drivers/nv04/nv04_fragtex.c
@@ -4,7 +4,7 @@
 #define _(m,tf)                                                                \
 {                                                                              \
   PIPE_FORMAT_##m,                                                             \
-  NV04_DX5_TEXTURED_TRIANGLE_FORMAT_COLOR_##tf,                                               \
+  NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_##tf,                                               \
 }
 
 struct nv04_texture_format {
@@ -53,14 +53,14 @@
 		return;
 	}
 
-	nv04->fragtex.format = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_ZOH_CORNER 
-		| NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_FOH_CORNER
+	nv04->fragtex.format = NV04_TEXTURED_TRIANGLE_FORMAT_ORIGIN_ZOH_CORNER
+		| NV04_TEXTURED_TRIANGLE_FORMAT_ORIGIN_FOH_CORNER
 		| nv04_fragtex_format(pt->format)
-		| ( (pt->last_level + 1) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_MIPMAP_LEVELS_SHIFT )
-		| ( log2i(pt->width[0]) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_U_SHIFT )
-		| ( log2i(pt->height[0]) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_V_SHIFT )
-		| NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE
-		| NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_CLAMP_TO_EDGE
+		| ( (pt->last_level + 1) << NV04_TEXTURED_TRIANGLE_FORMAT_MIPMAP_LEVELS_SHIFT )
+		| ( log2i(pt->width0) << NV04_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_U_SHIFT )
+		| ( log2i(pt->height0) << NV04_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_V_SHIFT )
+		| NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE
+		| NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_CLAMP_TO_EDGE
 		;
 }
 
diff --git a/src/gallium/drivers/nv04/nv04_miptree.c b/src/gallium/drivers/nv04/nv04_miptree.c
index 93f752f..e0a6948 100644
--- a/src/gallium/drivers/nv04/nv04_miptree.c
+++ b/src/gallium/drivers/nv04/nv04_miptree.c
@@ -1,6 +1,7 @@
 #include "pipe/p_state.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
+#include "util/u_math.h"
 
 #include "nv04_context.h"
 #include "nv04_screen.h"
@@ -9,31 +10,22 @@
 nv04_miptree_layout(struct nv04_miptree *nv04mt)
 {
 	struct pipe_texture *pt = &nv04mt->base;
-	uint width = pt->width[0], height = pt->height[0];
 	uint offset = 0;
 	int nr_faces, l;
 
 	nr_faces = 1;
 
 	for (l = 0; l <= pt->last_level; l++) {
-		pt->width[l] = width;
-		pt->height[l] = height;
-
-		pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width);
-		pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height);
-		
-		nv04mt->level[l].pitch = pt->width[0];
+		nv04mt->level[l].pitch = pt->width0;
 		nv04mt->level[l].pitch = (nv04mt->level[l].pitch + 63) & ~63;
-
-		width  = MAX2(1, width  >> 1);
-		height = MAX2(1, height >> 1);
 	}
 
 	for (l = 0; l <= pt->last_level; l++) {
-
 		nv04mt->level[l].image_offset = 
 			CALLOC(nr_faces, sizeof(unsigned));
-		offset += nv04mt->level[l].pitch * pt->height[l];
+		/* XXX guess was obviously missing */
+		nv04mt->level[l].image_offset[0] = offset;
+		offset += nv04mt->level[l].pitch * u_minify(pt->height0, l);
 	}
 
 	nv04mt->total_size = offset;
@@ -63,7 +55,7 @@
 		FREE(mt);
 		return NULL;
 	}
-	
+	mt->bo = nouveau_bo(mt->buffer);
 	return &mt->base;
 }
 
@@ -75,7 +67,7 @@
 
 	/* Only supports 2D, non-mipmapped textures for the moment */
 	if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 ||
-	    pt->depth[0] != 1)
+	    pt->depth0 != 1)
 		return NULL;
 
 	mt = CALLOC_STRUCT(nv04_miptree);
@@ -89,6 +81,7 @@
 	mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
 
 	pipe_buffer_reference(&mt->buffer, pb);
+	mt->bo = nouveau_bo(mt->buffer);
 	return &mt->base;
 }
 
@@ -120,8 +113,8 @@
 		return NULL;
 	pipe_texture_reference(&ns->base.texture, pt);
 	ns->base.format = pt->format;
-	ns->base.width = pt->width[level];
-	ns->base.height = pt->height[level];
+	ns->base.width = u_minify(pt->width0, level);
+	ns->base.height = u_minify(pt->height0, level);
 	ns->base.usage = flags;
 	pipe_reference_init(&ns->base.reference, 1);
 	ns->base.face = face;
@@ -129,7 +122,7 @@
 	ns->base.zslice = zslice;
 	ns->pitch = nv04mt->level[level].pitch;
 
-	ns->base.offset = nv04mt->level[level].image_offset;
+	ns->base.offset = nv04mt->level[level].image_offset[0];
 
 	return &ns->base;
 }
diff --git a/src/gallium/drivers/nv04/nv04_prim_vbuf.c b/src/gallium/drivers/nv04/nv04_prim_vbuf.c
index f645823..0b795ea 100644
--- a/src/gallium/drivers/nv04/nv04_prim_vbuf.c
+++ b/src/gallium/drivers/nv04/nv04_prim_vbuf.c
@@ -93,33 +93,45 @@
 
 static INLINE void nv04_2triangles(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5)
 {
-	BEGIN_RING(fahrenheit,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xA),49);
-	OUT_RINGp(buffer + VERTEX_SIZE * v0,8);
-	OUT_RINGp(buffer + VERTEX_SIZE * v1,8);
-	OUT_RINGp(buffer + VERTEX_SIZE * v2,8);
-	OUT_RINGp(buffer + VERTEX_SIZE * v3,8);
-	OUT_RINGp(buffer + VERTEX_SIZE * v4,8);
-	OUT_RINGp(buffer + VERTEX_SIZE * v5,8);
-	OUT_RING(0xFEDCBA);
+	struct nv04_screen *screen = nv04->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *fahrenheit = screen->fahrenheit;
+
+	BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0xA), 49);
+	OUT_RINGp(chan, buffer + VERTEX_SIZE * v0,8);
+	OUT_RINGp(chan, buffer + VERTEX_SIZE * v1,8);
+	OUT_RINGp(chan, buffer + VERTEX_SIZE * v2,8);
+	OUT_RINGp(chan, buffer + VERTEX_SIZE * v3,8);
+	OUT_RINGp(chan, buffer + VERTEX_SIZE * v4,8);
+	OUT_RINGp(chan, buffer + VERTEX_SIZE * v5,8);
+	OUT_RING(chan, 0xFEDCBA);
 }
 
 static INLINE void nv04_1triangle(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2)
 {
-	BEGIN_RING(fahrenheit,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xD),25);
-	OUT_RINGp(buffer + VERTEX_SIZE * v0,8);
-	OUT_RINGp(buffer + VERTEX_SIZE * v1,8);
-	OUT_RINGp(buffer + VERTEX_SIZE * v2,8);
-	OUT_RING(0xFED);
+	struct nv04_screen *screen = nv04->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *fahrenheit = screen->fahrenheit;
+
+	BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0xD), 25);
+	OUT_RINGp(chan, buffer + VERTEX_SIZE * v0,8);
+	OUT_RINGp(chan, buffer + VERTEX_SIZE * v1,8);
+	OUT_RINGp(chan, buffer + VERTEX_SIZE * v2,8);
+	OUT_RING(chan, 0xFED);
 }
 
 static INLINE void nv04_1quad(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2, ushort v3)
 {
-	BEGIN_RING(fahrenheit,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xC),33);
-	OUT_RINGp(buffer + VERTEX_SIZE * v0,8);
-	OUT_RINGp(buffer + VERTEX_SIZE * v1,8);
-	OUT_RINGp(buffer + VERTEX_SIZE * v2,8);
-	OUT_RINGp(buffer + VERTEX_SIZE * v3,8);
-	OUT_RING(0xFECEDC);
+	struct nv04_screen *screen = nv04->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *fahrenheit = screen->fahrenheit;
+
+	BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0xC), 33);
+	OUT_RINGp(chan, buffer + VERTEX_SIZE * v0,8);
+	OUT_RINGp(chan, buffer + VERTEX_SIZE * v1,8);
+	OUT_RINGp(chan, buffer + VERTEX_SIZE * v2,8);
+	OUT_RINGp(chan, buffer + VERTEX_SIZE * v3,8);
+	OUT_RING(chan, 0xFECEDC);
 }
 
 static void nv04_vbuf_render_triangles_elts(struct nv04_vbuf_render * render, const ushort * indices, uint nr_indices)
@@ -156,7 +168,10 @@
 {
 	const uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC};
 	unsigned char* buffer = render->buffer;
-	struct nv04_context* nv04 = render->nv04;
+	struct nv04_context *nv04 = render->nv04;
+	struct nv04_screen *screen = nv04->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *fahrenheit = screen->fahrenheit;
 	int i,j;
 
 	for(i = 0; i<nr_indices; i+=14) 
@@ -166,15 +181,15 @@
 		if (numvert<3)
 			break;
 
-		BEGIN_RING( fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0), numvert*8 );
+		BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0), numvert*8);
 		for(j = 0; j<numvert; j++)
-			OUT_RINGp( buffer + VERTEX_SIZE * indices [i+j], 8 );
+			OUT_RINGp(chan, buffer + VERTEX_SIZE * indices [i+j], 8 );
 
-		BEGIN_RING_NI( fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE(0), (numtri+1)/2 );
+		BEGIN_RING_NI(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_DRAWPRIMITIVE(0), (numtri+1)/2 );
 		for(j = 0; j<numtri/2; j++ )
-			OUT_RING(striptbl[j]);
+			OUT_RING(chan, striptbl[j]);
 		if (numtri%2)
-			OUT_RING(striptbl[numtri/2]&0xFFF);
+			OUT_RING(chan, striptbl[numtri/2]&0xFFF);
 	}
 }
 
@@ -182,11 +197,14 @@
 {
 	const uint32_t fantbl[]={0x320210,0x540430,0x760650,0x980870,0xBA0A90,0xDC0CB0,0xFE0ED0};
 	unsigned char* buffer = render->buffer;
-	struct nv04_context* nv04 = render->nv04;
+	struct nv04_context *nv04 = render->nv04;
+	struct nv04_screen *screen = nv04->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *fahrenheit = screen->fahrenheit;
 	int i,j;
 
-	BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0), 8);
-	OUT_RINGp(buffer + VERTEX_SIZE * indices[0], 8);
+	BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0), 8);
+	OUT_RINGp(chan, buffer + VERTEX_SIZE * indices[0], 8);
 
 	for(i = 1; i<nr_indices; i+=14)
 	{
@@ -195,16 +213,16 @@
 		if (numvert < 3)
 			break;
 
-		BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x1), numvert*8);
+		BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0x1), numvert*8);
 
 		for(j=0;j<numvert;j++)
-			OUT_RINGp( buffer + VERTEX_SIZE * indices[ i+j ], 8 );
+			OUT_RINGp(chan, buffer + VERTEX_SIZE * indices[ i+j ], 8 );
 
-		BEGIN_RING_NI(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE(0), (numtri+1)/2);
+		BEGIN_RING_NI(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_DRAWPRIMITIVE(0), (numtri+1)/2);
 		for(j = 0; j<numtri/2; j++)
-			OUT_RING(fantbl[j]);
+			OUT_RING(chan, fantbl[j]);
 		if (numtri%2)
-			OUT_RING(fantbl[numtri/2]&0xFFF);
+			OUT_RING(chan, fantbl[numtri/2]&0xFFF);
 	}
 }
 
diff --git a/src/gallium/drivers/nv04/nv04_screen.c b/src/gallium/drivers/nv04/nv04_screen.c
index 170ce3e..7c5b6e8 100644
--- a/src/gallium/drivers/nv04/nv04_screen.c
+++ b/src/gallium/drivers/nv04/nv04_screen.c
@@ -119,6 +119,8 @@
 	nouveau_grobj_free(&screen->fahrenheit);
 	nv04_surface_2d_takedown(&screen->eng2d);
 
+	nouveau_screen_fini(&screen->base);
+
 	FREE(pscreen);
 }
 
@@ -163,10 +165,10 @@
 		fahrenheit_class = 0;
 		sub3d_class = 0;
 	} else if (dev->chipset >= 0x10) {
-		fahrenheit_class = NV10_DX5_TEXTURED_TRIANGLE;
+		fahrenheit_class = NV10_TEXTURED_TRIANGLE;
 		sub3d_class = NV10_CONTEXT_SURFACES_3D;
 	} else {
-		fahrenheit_class=NV04_DX5_TEXTURED_TRIANGLE;
+		fahrenheit_class=NV04_TEXTURED_TRIANGLE;
 		sub3d_class = NV04_CONTEXT_SURFACES_3D;
 	}
 
diff --git a/src/gallium/drivers/nv04/nv04_state.c b/src/gallium/drivers/nv04/nv04_state.c
index d356ebd..e3dc4c5 100644
--- a/src/gallium/drivers/nv04/nv04_state.c
+++ b/src/gallium/drivers/nv04/nv04_state.c
@@ -50,28 +50,28 @@
 
 	switch (wrap) {
 	case PIPE_TEX_WRAP_REPEAT:
-		ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT;
+		ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT;
 		break;
 	case PIPE_TEX_WRAP_MIRROR_REPEAT:
-		ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_MIRRORED_REPEAT;
+		ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_MIRRORED_REPEAT;
 		break;
 	case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
-		ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE;
+		ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE;
 		break;
 	case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
-		ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_BORDER;
+		ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_BORDER;
 		break;
 	case PIPE_TEX_WRAP_CLAMP:
-		ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP;
+		ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP;
 		break;
 	case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
 	case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
 	case PIPE_TEX_WRAP_MIRROR_CLAMP:
 	default:
 		NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
-		ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP;
+		ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP;
 	}
-	return ret >> NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT;
+	return ret >> NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT;
 }
 
 static void *
@@ -84,20 +84,20 @@
 
 	ss = MALLOC(sizeof(struct nv04_sampler_state));
 
-	ss->format = ((wrap_mode(cso->wrap_s) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT) |
-		    (wrap_mode(cso->wrap_t) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_SHIFT));
+	ss->format = ((wrap_mode(cso->wrap_s) << NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT) |
+		    (wrap_mode(cso->wrap_t) << NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_SHIFT));
 
 	if (cso->max_anisotropy > 1.0) {
-		filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MINIFY_ENABLE | NV04_DX5_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MAGNIFY_ENABLE;
+		filter |= NV04_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MINIFY_ENABLE | NV04_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MAGNIFY_ENABLE;
 	}
 
 	switch (cso->mag_img_filter) {
 	case PIPE_TEX_FILTER_LINEAR:
-		filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MAGNIFY_LINEAR;
+		filter |= NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_LINEAR;
 		break;
 	case PIPE_TEX_FILTER_NEAREST:
 	default:
-		filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST;
+		filter |= NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST;
 		break;
 	}
 
@@ -105,14 +105,14 @@
 	case PIPE_TEX_FILTER_LINEAR:
 		switch (cso->min_mip_filter) {
 		case PIPE_TEX_MIPFILTER_NEAREST:
-			filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST;
+			filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST;
 			break;
 		case PIPE_TEX_MIPFILTER_LINEAR:
-			filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR;
+			filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR;
 			break;
 		case PIPE_TEX_MIPFILTER_NONE:
 		default:
-			filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR;
+			filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR;
 			break;
 		}
 		break;
@@ -120,14 +120,14 @@
 	default:
 		switch (cso->min_mip_filter) {
 		case PIPE_TEX_MIPFILTER_NEAREST:
-			filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST;
+			filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST;
 		break;
 		case PIPE_TEX_MIPFILTER_LINEAR:
-			filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR;
+			filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR;
 			break;
 		case PIPE_TEX_MIPFILTER_NONE:
 		default:
-			filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST;
+			filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST;
 			break;
 		}
 		break;
@@ -181,7 +181,7 @@
 	 */
 	rs = MALLOC(sizeof(struct nv04_rasterizer_state));
 
-	rs->blend = cso->flatshade ? NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT : NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD;
+	rs->blend = cso->flatshade ? NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT : NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD;
 
 	return (void *)rs;
 }
@@ -229,16 +229,16 @@
 	hw = MALLOC(sizeof(struct nv04_depth_stencil_alpha_state));
 
 	hw->control = float_to_ubyte(cso->alpha.ref_value);
-	hw->control |= ( nv04_compare_func(cso->alpha.func) << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_FUNC_SHIFT );
-	hw->control |= cso->alpha.enabled ? NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_TEST_ENABLE : 0;
-	hw->control |= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ORIGIN;
-	hw->control |= cso->depth.enabled ? (1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE_SHIFT) : 0;
-	hw->control |= ( nv04_compare_func(cso->depth.func)<< NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_FUNC_SHIFT );
-	hw->control |= 1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_SHIFT; // no culling, handled by the draw module
-	hw->control |= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE;
-	hw->control |= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_PERSPECTIVE_ENABLE;
-	hw->control |= cso->depth.writemask ? (1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_WRITE_ENABLE_SHIFT) : 0;
-	hw->control |= 1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_FORMAT_SHIFT; // integer zbuffer format
+	hw->control |= ( nv04_compare_func(cso->alpha.func) << NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_FUNC_SHIFT );
+	hw->control |= cso->alpha.enabled ? NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE : 0;
+	hw->control |= NV04_TEXTURED_TRIANGLE_CONTROL_ORIGIN;
+	hw->control |= cso->depth.enabled ? NV04_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE : 0;
+	hw->control |= ( nv04_compare_func(cso->depth.func)<< NV04_TEXTURED_TRIANGLE_CONTROL_Z_FUNC_SHIFT );
+	hw->control |= 1 << NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_SHIFT; // no culling, handled by the draw module
+	hw->control |= NV04_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE;
+	hw->control |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_PERSPECTIVE_ENABLE;
+	hw->control |= cso->depth.writemask ? NV04_TEXTURED_TRIANGLE_CONTROL_Z_WRITE : 0;
+	hw->control |= 1 << NV04_TEXTURED_TRIANGLE_CONTROL_Z_FORMAT_SHIFT; // integer zbuffer format
 
 	return (void *)hw;
 }
@@ -377,7 +377,7 @@
 /*	struct nv04_context *nv04 = nv04_context(pipe);
 
 	// XXX
-	BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_SCISSOR_HORIZ, 2);
+	BEGIN_RING(fahrenheit, NV04_TEXTURED_TRIANGLE_SCISSOR_HORIZ, 2);
 	OUT_RING  (((s->maxx - s->minx) << 16) | s->minx);
 	OUT_RING  (((s->maxy - s->miny) << 16) | s->miny);*/
 }
@@ -425,9 +425,9 @@
 	nv04->pipe.delete_blend_state = nv04_blend_state_delete;
 
 	nv04->pipe.create_sampler_state = nv04_sampler_state_create;
-	nv04->pipe.bind_sampler_states = nv04_sampler_state_bind;
+	nv04->pipe.bind_fragment_sampler_states = nv04_sampler_state_bind;
 	nv04->pipe.delete_sampler_state = nv04_sampler_state_delete;
-	nv04->pipe.set_sampler_textures = nv04_set_sampler_texture;
+	nv04->pipe.set_fragment_sampler_textures = nv04_set_sampler_texture;
 
 	nv04->pipe.create_rasterizer_state = nv04_rasterizer_state_create;
 	nv04->pipe.bind_rasterizer_state = nv04_rasterizer_state_bind;
diff --git a/src/gallium/drivers/nv04/nv04_state.h b/src/gallium/drivers/nv04/nv04_state.h
index 399f750..81d1d2e 100644
--- a/src/gallium/drivers/nv04/nv04_state.h
+++ b/src/gallium/drivers/nv04/nv04_state.h
@@ -31,6 +31,7 @@
 
 struct nv04_miptree {
 	struct pipe_texture base;
+	struct nouveau_bo *bo;
 
 	struct pipe_buffer *buffer;
 	uint total_size;
diff --git a/src/gallium/drivers/nv04/nv04_state_emit.c b/src/gallium/drivers/nv04/nv04_state_emit.c
index eb2c1c5..b8d6dc5 100644
--- a/src/gallium/drivers/nv04/nv04_state_emit.c
+++ b/src/gallium/drivers/nv04/nv04_state_emit.c
@@ -57,13 +57,19 @@
 static void nv04_emit_control(struct nv04_context* nv04)
 {
 	uint32_t control = nv04->dsa->control;
+	struct nv04_screen *screen = nv04->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *fahrenheit = screen->fahrenheit;
 
-	BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1);
-	OUT_RING(control);
+	BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1);
+	OUT_RING(chan, control);
 }
 
 static void nv04_emit_blend(struct nv04_context* nv04)
 {
+	struct nv04_screen *screen = nv04->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *fahrenheit = screen->fahrenheit;
 	uint32_t blend;
 
 	blend=0x4; // texture MODULATE_ALPHA
@@ -75,19 +81,23 @@
 	blend|=(nv04_blend_func(nv04->blend->b_src)<<24);
 	blend|=(nv04_blend_func(nv04->blend->b_dst)<<28);
 
-	BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1);
-	OUT_RING(blend);
+	BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_BLEND, 1);
+	OUT_RING(chan, blend);
 }
 
 static void nv04_emit_sampler(struct nv04_context *nv04, int unit)
 {
 	struct nv04_miptree *nv04mt = nv04->tex_miptree[unit];
 	struct pipe_texture *pt = &nv04mt->base;
+	struct nv04_screen *screen = nv04->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *fahrenheit = screen->fahrenheit;
+	struct nouveau_bo *bo = nouveau_bo(nv04mt->buffer);
 
-	BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 3);
-	OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
-	OUT_RELOCd(nv04mt->buffer, (nv04->fragtex.format | nv04->sampler[unit]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
-	OUT_RING(nv04->sampler[unit]->filter);
+	BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_OFFSET, 3);
+	OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+	OUT_RELOCd(chan, bo, (nv04->fragtex.format | nv04->sampler[unit]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
+	OUT_RING(chan, nv04->sampler[unit]->filter);
 }
 
 static void nv04_state_emit_framebuffer(struct nv04_context* nv04)
@@ -97,6 +107,10 @@
 	uint32_t rt_format, w, h;
 	int colour_format = 0, zeta_format = 0;
 	struct nv04_miptree *nv04mt = 0;
+	struct nv04_screen *screen = nv04->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *context_surfaces_3d = screen->context_surfaces_3d;
+	struct nouveau_bo *bo;
 
 	w = fb->cbufs[0]->width;
 	h = fb->cbufs[0]->height;
@@ -128,24 +142,29 @@
 		assert(0);
 	}
 
-	BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_FORMAT, 1);
-	OUT_RING(rt_format);
+	BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_FORMAT, 1);
+	OUT_RING(chan, rt_format);
 
 	nv04mt = (struct nv04_miptree *)rt->base.texture;
+	bo = nouveau_bo(nv04mt->buffer);
 	/* FIXME pitches have to be aligned ! */
-	BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
-	OUT_RING(rt->pitch|(zeta->pitch<<16));
-	OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+	BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
+	OUT_RING(chan, rt->pitch|(zeta->pitch<<16));
+	OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
 	if (fb->zsbuf) {
 		nv04mt = (struct nv04_miptree *)zeta->base.texture;
-		BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
-		OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+		BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
+		OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
 	}
 }
 
 void
 nv04_emit_hw_state(struct nv04_context *nv04)
 {
+	struct nv04_screen *screen = nv04->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *fahrenheit = screen->fahrenheit;
+	struct nouveau_grobj *context_surfaces_3d = screen->context_surfaces_3d;
 	int i;
 
 	if (nv04->dirty & NV04_NEW_VERTPROG) {
@@ -163,8 +182,8 @@
 	if (nv04->dirty & NV04_NEW_CONTROL) {
 		nv04->dirty &= ~NV04_NEW_CONTROL;
 
-		BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1);
-		OUT_RING(nv04->dsa->control);
+		BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1);
+		OUT_RING(chan, nv04->dsa->control);
 	}
 
 	if (nv04->dirty & NV04_NEW_BLEND) {
@@ -205,12 +224,12 @@
 	unsigned rt_pitch = ((struct nv04_surface *)nv04->rt)->pitch;
 	unsigned zeta_pitch = ((struct nv04_surface *)nv04->zeta)->pitch;
 
-	BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
-	OUT_RING(rt_pitch|(zeta_pitch<<16));
-	OUT_RELOCl(nv04->rt, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+	BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
+	OUT_RING(chan, rt_pitch|(zeta_pitch<<16));
+	OUT_RELOCl(chan, nouveau_bo(nv04->rt), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
 	if (nv04->zeta) {
-		BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
-		OUT_RELOCl(nv04->zeta, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+		BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
+		OUT_RELOCl(chan, nouveau_bo(nv04->zeta), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
 	}
 
 	/* Texture images */
@@ -218,9 +237,10 @@
 		if (!(nv04->fp_samplers & (1 << i)))
 			continue;
 		struct nv04_miptree *nv04mt = nv04->tex_miptree[i];
-		BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 2);
-		OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
-		OUT_RELOCd(nv04mt->buffer, (nv04->fragtex.format | nv04->sampler[i]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
+		struct nouveau_bo *bo = nouveau_bo(nv04mt->buffer);
+		BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_OFFSET, 2);
+		OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+		OUT_RELOCd(chan, bo, (nv04->fragtex.format | nv04->sampler[i]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
 	}
 }
 
diff --git a/src/gallium/drivers/nv04/nv04_surface_2d.c b/src/gallium/drivers/nv04/nv04_surface_2d.c
index 8be134b..b24a9ce 100644
--- a/src/gallium/drivers/nv04/nv04_surface_2d.c
+++ b/src/gallium/drivers/nv04/nv04_surface_2d.c
@@ -1,5 +1,6 @@
 #include "pipe/p_context.h"
 #include "pipe/p_format.h"
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 
@@ -76,7 +77,7 @@
 }
 
 static INLINE unsigned
-nv04_swizzle_bits(unsigned x, unsigned y)
+nv04_swizzle_bits_square(unsigned x, unsigned y)
 {
 	unsigned u = (x & 0x001) << 0 |
 	             (x & 0x002) << 1 |
@@ -106,6 +107,15 @@
 	return v | u;
 }
 
+/* rectangular swizzled textures are linear concatenations of swizzled square tiles */
+static INLINE unsigned
+nv04_swizzle_bits(unsigned x, unsigned y, unsigned w, unsigned h)
+{
+	unsigned s = MIN2(w, h);
+	unsigned m = s - 1;
+	return (((x | y) & ~m) * s) | nv04_swizzle_bits_square(x & m, y & m);
+}
+
 static int
 nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx,
 			  struct pipe_surface *dst, int dx, int dy,
@@ -133,6 +143,9 @@
 	assert(sub_w == w || util_is_pot(sub_w));
 	assert(sub_h == h || util_is_pot(sub_h));
 
+	MARK_RING (chan, 8 + ((w+sub_w)/sub_w)*((h+sub_h)/sub_h)*17, 2 +
+			 ((w+sub_w)/sub_w)*((h+sub_h)/sub_h)*2);
+
 	BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1);
 	OUT_RELOCo(chan, dst_bo,
 	                 NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
@@ -154,20 +167,19 @@
 	  for (x = 0; x < w; x += sub_w) {
 	    sub_w = MIN2(sub_w, w - x);
 
-	    /* Must be 64-byte aligned */
-	    assert(!((dst->offset + nv04_swizzle_bits(dx+x, dy+y) * dst->texture->block.size) & 63));
+	    assert(!(dst->offset & 63));
 
 	    BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_OFFSET, 1);
-	    OUT_RELOCl(chan, dst_bo, dst->offset + nv04_swizzle_bits(dx+x, dy+y) * dst->texture->block.size,
+	    OUT_RELOCl(chan, dst_bo, dst->offset,
                              NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
 
 	    BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9);
 	    OUT_RING  (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE);
 	    OUT_RING  (chan, nv04_scaled_image_format(src->format));
 	    OUT_RING  (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
-	    OUT_RING  (chan, 0);
+	    OUT_RING  (chan, (x + dx) | ((y + dy) << NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT_Y_SHIFT));
 	    OUT_RING  (chan, sub_h << NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE_H_SHIFT | sub_w);
-	    OUT_RING  (chan, 0);
+	    OUT_RING  (chan, (x + dx) | ((y + dy) << NV04_SCALED_IMAGE_FROM_MEMORY_OUT_POINT_Y_SHIFT));
 	    OUT_RING  (chan, sub_h << NV04_SCALED_IMAGE_FROM_MEMORY_OUT_SIZE_H_SHIFT | sub_w);
 	    OUT_RING  (chan, 1 << 20);
 	    OUT_RING  (chan, 1 << 20);
@@ -177,7 +189,7 @@
 	    OUT_RING  (chan, src_pitch |
 			     NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER |
 			     NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE);
-	    OUT_RELOCl(chan, src_bo, src->offset + (sy+y) * src_pitch + (sx+x) * src->texture->block.size,
+	    OUT_RELOCl(chan, src_bo, src->offset + (sy+y) * src_pitch + (sx+x) * util_format_get_blocksize(src->texture->format),
                              NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
 	    OUT_RING  (chan, 0);
 	  }
@@ -198,11 +210,11 @@
 	unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
 	unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
 	unsigned dst_offset = dst->offset + dy * dst_pitch +
-	                      dx * dst->texture->block.size;
+	                      dx * util_format_get_blocksize(dst->texture->format);
 	unsigned src_offset = src->offset + sy * src_pitch +
-	                      sx * src->texture->block.size;
+	                      sx * util_format_get_blocksize(src->texture->format);
 
-	WAIT_RING (chan, 3 + ((h / 2047) + 1) * 9);
+	MARK_RING (chan, 3 + ((h / 2047) + 1) * 9, 2 + ((h / 2047) + 1) * 2);
 	BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2);
 	OUT_RELOCo(chan, src_bo,
 		   NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
@@ -219,7 +231,7 @@
 			   NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR);
 		OUT_RING  (chan, src_pitch);
 		OUT_RING  (chan, dst_pitch);
-		OUT_RING  (chan, w * src->texture->block.size);
+		OUT_RING  (chan, w * util_format_get_blocksize(src->texture->format));
 		OUT_RING  (chan, count);
 		OUT_RING  (chan, 0x0101);
 		OUT_RING  (chan, 0);
@@ -250,7 +262,7 @@
 	if (format < 0)
 		return 1;
 
-	WAIT_RING (chan, 12);
+	MARK_RING (chan, 12, 4);
 	BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
 	OUT_RELOCo(chan, src_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
 	OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
@@ -315,7 +327,7 @@
 	gdirect_format = nv04_rect_format(dst->format);
 	assert(gdirect_format >= 0);
 
-	WAIT_RING (chan, 16);
+	MARK_RING (chan, 16, 4);
 	BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
 	OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
 	OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
@@ -487,3 +499,49 @@
 	ctx->fill = nv04_surface_fill;
 	return ctx;
 }
+
+struct nv04_surface*
+nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d* eng2d, struct nv04_surface* ns)
+{
+	int temp_flags;
+
+	// printf("creating temp, flags is %i!\n", flags);
+
+	if(ns->base.usage & PIPE_BUFFER_USAGE_DISCARD)
+	{
+		temp_flags = ns->base.usage | PIPE_BUFFER_USAGE_GPU_READ;
+		ns->base.usage = PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER | PIPE_BUFFER_USAGE_DISCARD;
+	}
+	else
+	{
+		temp_flags = ns->base.usage | PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE;
+		ns->base.usage = PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER | PIPE_BUFFER_USAGE_GPU_READ;
+	}
+
+	struct nv40_screen* screen = (struct nv40_screen*)pscreen;
+	ns->base.usage = PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE;
+
+	struct pipe_texture templ;
+	memset(&templ, 0, sizeof(templ));
+	templ.format = ns->base.texture->format;
+	templ.target = PIPE_TEXTURE_2D;
+	templ.width0 = ns->base.width;
+	templ.height0 = ns->base.height;
+	templ.depth0 = 1;
+	templ.last_level = 0;
+
+	// TODO: this is probably wrong and we should specifically handle multisampling somehow once it is implemented
+	templ.nr_samples = ns->base.texture->nr_samples;
+
+	templ.tex_usage = ns->base.texture->tex_usage | PIPE_TEXTURE_USAGE_RENDER_TARGET;
+
+	struct pipe_texture* temp_tex = pscreen->texture_create(pscreen, &templ);
+	struct nv04_surface* temp_ns = (struct nv04_surface*)pscreen->get_tex_surface(pscreen, temp_tex, 0, 0, 0, temp_flags);
+	temp_ns->backing = ns;
+
+	if(ns->base.usage & PIPE_BUFFER_USAGE_GPU_READ)
+		eng2d->copy(eng2d, &temp_ns->backing->base, 0, 0, &ns->base, 0, 0, ns->base.width, ns->base.height);
+
+	return temp_ns;
+}
+
diff --git a/src/gallium/drivers/nv04/nv04_surface_2d.h b/src/gallium/drivers/nv04/nv04_surface_2d.h
index 02b3f56..ce696a1 100644
--- a/src/gallium/drivers/nv04/nv04_surface_2d.h
+++ b/src/gallium/drivers/nv04/nv04_surface_2d.h
@@ -4,6 +4,7 @@
 struct nv04_surface {
 	struct pipe_surface base;
 	unsigned pitch;
+	struct nv04_surface* backing;
 };
 
 struct nv04_surface_2d {
@@ -30,4 +31,7 @@
 void
 nv04_surface_2d_takedown(struct nv04_surface_2d **);
 
+struct nv04_surface*
+nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d* eng2d, struct nv04_surface* ns);
+
 #endif
diff --git a/src/gallium/drivers/nv04/nv04_transfer.c b/src/gallium/drivers/nv04/nv04_transfer.c
index 6618660..2dd2e14 100644
--- a/src/gallium/drivers/nv04/nv04_transfer.c
+++ b/src/gallium/drivers/nv04/nv04_transfer.c
@@ -1,7 +1,9 @@
 #include <pipe/p_state.h>
 #include <pipe/p_defines.h>
 #include <pipe/p_inlines.h>
+#include <util/u_format.h>
 #include <util/u_memory.h>
+#include <util/u_math.h>
 #include <nouveau/nouveau_winsys.h>
 #include "nv04_context.h"
 #include "nv04_screen.h"
@@ -10,22 +12,19 @@
 struct nv04_transfer {
 	struct pipe_transfer base;
 	struct pipe_surface *surface;
-	bool direct;
+	boolean direct;
 };
 
 static void
-nv04_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
+nv04_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height,
                              struct pipe_texture *template)
 {
 	memset(template, 0, sizeof(struct pipe_texture));
 	template->target = pt->target;
 	template->format = pt->format;
-	template->width[0] = pt->width[level];
-	template->height[0] = pt->height[level];
-	template->depth[0] = 1;
-	template->block = pt->block;
-	template->nblocksx[0] = pt->nblocksx[level];
-	template->nblocksy[0] = pt->nblocksx[level];
+	template->width0 = width;
+	template->height0 = height;
+	template->depth0 = 1;
 	template->last_level = 0;
 	template->nr_samples = pt->nr_samples;
 
@@ -48,14 +47,10 @@
 		return NULL;
 
 	pipe_texture_reference(&tx->base.texture, pt);
-	tx->base.format = pt->format;
 	tx->base.x = x;
 	tx->base.y = y;
 	tx->base.width = w;
 	tx->base.height = h;
-	tx->base.block = pt->block;
-	tx->base.nblocksx = pt->nblocksx[level];
-	tx->base.nblocksy = pt->nblocksy[level];
 	tx->base.stride = mt->level[level].pitch;
 	tx->base.usage = usage;
 	tx->base.face = face;
@@ -76,7 +71,7 @@
 
 	tx->direct = false;
 
-	nv04_compatible_transfer_tex(pt, level, &tx_tex_template);
+	nv04_compatible_transfer_tex(pt, w, h, &tx_tex_template);
 
 	tx_tex = pscreen->texture_create(pscreen, &tx_tex_template);
 	if (!tx_tex)
@@ -85,6 +80,8 @@
 		return NULL;
 	}
 
+	tx->base.stride = ((struct nv04_miptree*)tx_tex)->level[0].pitch;
+
 	tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
 	                                       face, level, zslice,
 	                                       pipe_transfer_buffer_flags(&tx->base));
@@ -110,8 +107,8 @@
 		/* TODO: Check if SIFM can un-swizzle */
 		nvscreen->eng2d->copy(nvscreen->eng2d,
 		                      tx->surface, 0, 0,
-		                      src, 0, 0,
-		                      src->width, src->height);
+		                      src, x, y,
+		                      w, h);
 
 		pipe_surface_reference(&src, NULL);
 	}
@@ -135,9 +132,9 @@
 
 		/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
 		nvscreen->eng2d->copy(nvscreen->eng2d,
-		                      dst, 0, 0,
+		                      dst, tx->base.x, tx->base.y,
 		                      tx->surface, 0, 0,
-		                      dst->width, dst->height);
+		                      tx->base.width, tx->base.height);
 
 		pipe_surface_reference(&dst, NULL);
 	}
@@ -156,8 +153,10 @@
 	void *map = pipe_buffer_map(pscreen, mt->buffer,
 	                            pipe_transfer_buffer_flags(ptx));
 
-	return map + ns->base.offset +
-	       ptx->y * ns->pitch + ptx->x * ptx->block.size;
+	if(!tx->direct)
+		return map + ns->base.offset;
+	else
+		return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format);
 }
 
 static void
diff --git a/src/gallium/drivers/nv04/nv04_vbo.c b/src/gallium/drivers/nv04/nv04_vbo.c
index e316781..3484771 100644
--- a/src/gallium/drivers/nv04/nv04_vbo.c
+++ b/src/gallium/drivers/nv04/nv04_vbo.c
@@ -9,7 +9,7 @@
 #include "nouveau/nouveau_channel.h"
 #include "nouveau/nouveau_pushbuf.h"
 
-boolean nv04_draw_elements( struct pipe_context *pipe,
+void nv04_draw_elements( struct pipe_context *pipe,
                     struct pipe_buffer *indexBuffer,
                     unsigned indexSize,
                     unsigned prim, unsigned start, unsigned count)
@@ -45,7 +45,7 @@
 		draw_set_mapped_element_buffer(draw, 0, NULL);
 	}
 
-	draw_set_mapped_constant_buffer(draw,
+	draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX,
 					nv04->constbuf[PIPE_SHADER_VERTEX],
 					nv04->constbuf_nr[PIPE_SHADER_VERTEX]);
 
@@ -65,15 +65,13 @@
 		pipe_buffer_unmap(pscreen, indexBuffer);
 		draw_set_mapped_element_buffer(draw, 0, NULL);
 	}
-
-	return TRUE;
 }
 
-boolean nv04_draw_arrays( struct pipe_context *pipe,
-				 unsigned prim, unsigned start, unsigned count)
+void nv04_draw_arrays( struct pipe_context *pipe,
+                       unsigned prim, unsigned start, unsigned count)
 {
 	printf("coucou in draw arrays\n");
-	return nv04_draw_elements(pipe, NULL, 0, prim, start, count);
+	nv04_draw_elements(pipe, NULL, 0, prim, start, count);
 }
 
 
diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c
index 933176f..1ecb73d 100644
--- a/src/gallium/drivers/nv10/nv10_context.c
+++ b/src/gallium/drivers/nv10/nv10_context.c
@@ -10,10 +10,14 @@
 	   struct pipe_fence_handle **fence)
 {
 	struct nv10_context *nv10 = nv10_context(pipe);
+	struct nv10_screen *screen = nv10->screen;
+	struct nouveau_channel *chan = screen->base.channel;
 
 	draw_flush(nv10->draw);
 
-	FIRE_RING(fence);
+	FIRE_RING(chan);
+	if (fence)
+		*fence = NULL;
 }
 
 static void
@@ -31,230 +35,226 @@
 {
 	struct nv10_screen *screen = nv10->screen;
 	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *celsius = screen->celsius;
 	int i;
 	float projectionmatrix[16];
 
-	BEGIN_RING(celsius, NV10TCL_DMA_NOTIFY, 1);
-	OUT_RING  (screen->sync->handle);
-	BEGIN_RING(celsius, NV10TCL_DMA_IN_MEMORY0, 2);
-	OUT_RING  (chan->vram->handle);
-	OUT_RING  (chan->gart->handle);
-	BEGIN_RING(celsius, NV10TCL_DMA_IN_MEMORY2, 2);
-	OUT_RING  (chan->vram->handle);
-	OUT_RING  (chan->vram->handle);
+	BEGIN_RING(chan, celsius, NV10TCL_DMA_NOTIFY, 1);
+	OUT_RING  (chan, screen->sync->handle);
+	BEGIN_RING(chan, celsius, NV10TCL_DMA_IN_MEMORY0, 2);
+	OUT_RING  (chan, chan->vram->handle);
+	OUT_RING  (chan, chan->gart->handle);
+	BEGIN_RING(chan, celsius, NV10TCL_DMA_IN_MEMORY2, 2);
+	OUT_RING  (chan, chan->vram->handle);
+	OUT_RING  (chan, chan->vram->handle);
 
-	BEGIN_RING(celsius, NV10TCL_NOP, 1);
-	OUT_RING  (0);
+	BEGIN_RING(chan, celsius, NV10TCL_NOP, 1);
+	OUT_RING  (chan, 0);
 
-	BEGIN_RING(celsius, NV10TCL_RT_HORIZ, 2);
-	OUT_RING  (0);
-	OUT_RING  (0);
+	BEGIN_RING(chan, celsius, NV10TCL_RT_HORIZ, 2);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
 
-	BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1);
-	OUT_RING  ((0x7ff<<16)|0x800);
-	BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1);
-	OUT_RING  ((0x7ff<<16)|0x800);
+	BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1);
+	OUT_RING  (chan, (0x7ff<<16)|0x800);
+	BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1);
+	OUT_RING  (chan, (0x7ff<<16)|0x800);
 
 	for (i=1;i<8;i++) {
-		BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(i), 1);
-		OUT_RING  (0);
-		BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_VERT(i), 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(i), 1);
+		OUT_RING  (chan, 0);
+		BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(i), 1);
+		OUT_RING  (chan, 0);
 	}
 
-	BEGIN_RING(celsius, 0x290, 1);
-	OUT_RING  ((0x10<<16)|1);
-	BEGIN_RING(celsius, 0x3f4, 1);
-	OUT_RING  (0);
+	BEGIN_RING(chan, celsius, 0x290, 1);
+	OUT_RING  (chan, (0x10<<16)|1);
+	BEGIN_RING(chan, celsius, 0x3f4, 1);
+	OUT_RING  (chan, 0);
 
-	BEGIN_RING(celsius, NV10TCL_NOP, 1);
-	OUT_RING  (0);
+	BEGIN_RING(chan, celsius, NV10TCL_NOP, 1);
+	OUT_RING  (chan, 0);
 
 	if (nv10->screen->celsius->grclass != NV10TCL) {
 		/* For nv11, nv17 */
-		BEGIN_RING(celsius, 0x120, 3);
-		OUT_RING  (0);
-		OUT_RING  (1);
-		OUT_RING  (2);
+		BEGIN_RING(chan, celsius, 0x120, 3);
+		OUT_RING  (chan, 0);
+		OUT_RING  (chan, 1);
+		OUT_RING  (chan, 2);
 
-		BEGIN_RING(celsius, NV10TCL_NOP, 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, celsius, NV10TCL_NOP, 1);
+		OUT_RING  (chan, 0);
 	}
 
-	BEGIN_RING(celsius, NV10TCL_NOP, 1);
-	OUT_RING  (0);
+	BEGIN_RING(chan, celsius, NV10TCL_NOP, 1);
+	OUT_RING  (chan, 0);
 
 	/* Set state */
-	BEGIN_RING(celsius, NV10TCL_FOG_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_FUNC, 2);
-	OUT_RING  (0x207);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_TX_ENABLE(0), 2);
-	OUT_RING  (0);
-	OUT_RING  (0);
+	BEGIN_RING(chan, celsius, NV10TCL_FOG_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_FUNC, 2);
+	OUT_RING  (chan, 0x207);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(0), 2);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
 
-	BEGIN_RING(celsius, NV10TCL_RC_IN_ALPHA(0), 12);
-	OUT_RING  (0x30141010);
-	OUT_RING  (0);
-	OUT_RING  (0x20040000);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	OUT_RING  (0x00000c00);
-	OUT_RING  (0);
-	OUT_RING  (0x00000c00);
-	OUT_RING  (0x18000000);
-	OUT_RING  (0x300e0300);
-	OUT_RING  (0x0c091c80);
+	BEGIN_RING(chan, celsius, NV10TCL_RC_IN_ALPHA(0), 12);
+	OUT_RING  (chan, 0x30141010);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0x20040000);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0x00000c00);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0x00000c00);
+	OUT_RING  (chan, 0x18000000);
+	OUT_RING  (chan, 0x300e0300);
+	OUT_RING  (chan, 0x0c091c80);
 
-	BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 2);
-	OUT_RING  (1);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_VERTEX_WEIGHT_ENABLE, 2);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_SRC, 4);
-	OUT_RING  (1);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	OUT_RING  (0x8006);
-	BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 8);
-	OUT_RING  (0xff);
-	OUT_RING  (0x207);
-	OUT_RING  (0);
-	OUT_RING  (0xff);
-	OUT_RING  (0x1e00);
-	OUT_RING  (0x1e00);
-	OUT_RING  (0x1e00);
-	OUT_RING  (0x1d01);
-	BEGIN_RING(celsius, NV10TCL_NORMALIZE_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_FOG_ENABLE, 2);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_LIGHT_MODEL, 1);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_COLOR_CONTROL, 1);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_ENABLED_LIGHTS, 1);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_DEPTH_FUNC, 1);
-	OUT_RING  (0x201);
-	BEGIN_RING(celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_DEPTH_TEST_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_POINT_SIZE, 1);
-	OUT_RING  (8);
-	BEGIN_RING(celsius, NV10TCL_POINT_PARAMETERS_ENABLE, 2);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_LINE_WIDTH, 1);
-	OUT_RING  (8);
-	BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_POLYGON_MODE_FRONT, 2);
-	OUT_RING  (0x1b02);
-	OUT_RING  (0x1b02);
-	BEGIN_RING(celsius, NV10TCL_CULL_FACE, 2);
-	OUT_RING  (0x405);
-	OUT_RING  (0x901);
-	BEGIN_RING(celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_CULL_FACE_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_TX_GEN_S(0), 8);
+	BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_DITHER_ENABLE, 2);
+	OUT_RING  (chan, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_VERTEX_WEIGHT_ENABLE, 2);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_SRC, 4);
+	OUT_RING  (chan, 1);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0x8006);
+	BEGIN_RING(chan, celsius, NV10TCL_STENCIL_MASK, 8);
+	OUT_RING  (chan, 0xff);
+	OUT_RING  (chan, 0x207);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0xff);
+	OUT_RING  (chan, 0x1e00);
+	OUT_RING  (chan, 0x1e00);
+	OUT_RING  (chan, 0x1e00);
+	OUT_RING  (chan, 0x1d01);
+	BEGIN_RING(chan, celsius, NV10TCL_NORMALIZE_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_FOG_ENABLE, 2);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_LIGHT_MODEL, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_COLOR_CONTROL, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_ENABLED_LIGHTS, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_DEPTH_FUNC, 1);
+	OUT_RING  (chan, 0x201);
+	BEGIN_RING(chan, celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_DEPTH_TEST_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_POINT_SIZE, 1);
+	OUT_RING  (chan, 8);
+	BEGIN_RING(chan, celsius, NV10TCL_POINT_PARAMETERS_ENABLE, 2);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_LINE_WIDTH, 1);
+	OUT_RING  (chan, 8);
+	BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_POLYGON_MODE_FRONT, 2);
+	OUT_RING  (chan, 0x1b02);
+	OUT_RING  (chan, 0x1b02);
+	BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE, 2);
+	OUT_RING  (chan, 0x405);
+	OUT_RING  (chan, 0x901);
+	BEGIN_RING(chan, celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_TX_GEN_S(0), 8);
 	for (i=0;i<8;i++) {
-		OUT_RING  (0);
+		OUT_RING  (chan, 0);
 	}
-	BEGIN_RING(celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3);
-	OUT_RING  (0x3fc00000);	/* -1.50 */
-	OUT_RING  (0xbdb8aa0a);	/* -0.09 */
-	OUT_RING  (0);		/*  0.00 */
+	BEGIN_RING(chan, celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3);
+	OUT_RING  (chan, 0x3fc00000);	/* -1.50 */
+	OUT_RING  (chan, 0xbdb8aa0a);	/* -0.09 */
+	OUT_RING  (chan, 0);		/*  0.00 */
 
-	BEGIN_RING(celsius, NV10TCL_NOP, 1);
-	OUT_RING  (0);
+	BEGIN_RING(chan, celsius, NV10TCL_NOP, 1);
+	OUT_RING  (chan, 0);
 
-	BEGIN_RING(celsius, NV10TCL_FOG_MODE, 2);
-	OUT_RING  (0x802);
-	OUT_RING  (2);
+	BEGIN_RING(chan, celsius, NV10TCL_FOG_MODE, 2);
+	OUT_RING  (chan, 0x802);
+	OUT_RING  (chan, 2);
 	/* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when
 	 * using texturing, except when using the texture matrix
 	 */
-	BEGIN_RING(celsius, NV10TCL_VIEW_MATRIX_ENABLE, 1);
-	OUT_RING  (6);
-	BEGIN_RING(celsius, NV10TCL_COLOR_MASK, 1);
-	OUT_RING  (0x01010101);
+	BEGIN_RING(chan, celsius, NV10TCL_VIEW_MATRIX_ENABLE, 1);
+	OUT_RING  (chan, 6);
+	BEGIN_RING(chan, celsius, NV10TCL_COLOR_MASK, 1);
+	OUT_RING  (chan, 0x01010101);
 
 	/* Set vertex component */
-	BEGIN_RING(celsius, NV10TCL_VERTEX_COL_4F_R, 4);
-	OUT_RINGf (1.0);
-	OUT_RINGf (1.0);
-	OUT_RINGf (1.0);
-	OUT_RINGf (1.0);
-	BEGIN_RING(celsius, NV10TCL_VERTEX_COL2_3F_R, 3);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	BEGIN_RING(celsius, NV10TCL_VERTEX_NOR_3F_X, 3);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	OUT_RINGf (1.0);
-	BEGIN_RING(celsius, NV10TCL_VERTEX_TX0_4F_S, 4);
-	OUT_RINGf (0.0);
-	OUT_RINGf (0.0);
-	OUT_RINGf (0.0);
-	OUT_RINGf (1.0);
-	BEGIN_RING(celsius, NV10TCL_VERTEX_TX1_4F_S, 4);
-	OUT_RINGf (0.0);
-	OUT_RINGf (0.0);
-	OUT_RINGf (0.0);
-	OUT_RINGf (1.0);
-	BEGIN_RING(celsius, NV10TCL_VERTEX_FOG_1F, 1);
-	OUT_RINGf (0.0);
-	BEGIN_RING(celsius, NV10TCL_EDGEFLAG_ENABLE, 1);
-	OUT_RING  (1);
+	BEGIN_RING(chan, celsius, NV10TCL_VERTEX_COL_4F_R, 4);
+	OUT_RINGf (chan, 1.0);
+	OUT_RINGf (chan, 1.0);
+	OUT_RINGf (chan, 1.0);
+	OUT_RINGf (chan, 1.0);
+	BEGIN_RING(chan, celsius, NV10TCL_VERTEX_COL2_3F_R, 3);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, celsius, NV10TCL_VERTEX_NOR_3F_X, 3);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	OUT_RINGf (chan, 1.0);
+	BEGIN_RING(chan, celsius, NV10TCL_VERTEX_TX0_4F_S, 4);
+	OUT_RINGf (chan, 0.0);
+	OUT_RINGf (chan, 0.0);
+	OUT_RINGf (chan, 0.0);
+	OUT_RINGf (chan, 1.0);
+	BEGIN_RING(chan, celsius, NV10TCL_VERTEX_TX1_4F_S, 4);
+	OUT_RINGf (chan, 0.0);
+	OUT_RINGf (chan, 0.0);
+	OUT_RINGf (chan, 0.0);
+	OUT_RINGf (chan, 1.0);
+	BEGIN_RING(chan, celsius, NV10TCL_VERTEX_FOG_1F, 1);
+	OUT_RINGf (chan, 0.0);
+	BEGIN_RING(chan, celsius, NV10TCL_EDGEFLAG_ENABLE, 1);
+	OUT_RING  (chan, 1);
 
 	memset(projectionmatrix, 0, sizeof(projectionmatrix));
-	BEGIN_RING(celsius, NV10TCL_PROJECTION_MATRIX(0), 16);
+	BEGIN_RING(chan, celsius, NV10TCL_PROJECTION_MATRIX(0), 16);
 	projectionmatrix[0*4+0] = 1.0;
 	projectionmatrix[1*4+1] = 1.0;
 	projectionmatrix[2*4+2] = 1.0;
 	projectionmatrix[3*4+3] = 1.0;
 	for (i=0;i<16;i++) {
-		OUT_RINGf  (projectionmatrix[i]);
+		OUT_RINGf  (chan, projectionmatrix[i]);
 	}
 
-	BEGIN_RING(celsius, NV10TCL_DEPTH_RANGE_NEAR, 2);
-	OUT_RING  (0.0);
-	OUT_RINGf  (16777216.0);
+	BEGIN_RING(chan, celsius, NV10TCL_DEPTH_RANGE_NEAR, 2);
+	OUT_RING  (chan, 0.0);
+	OUT_RINGf  (chan, 16777216.0);
 
-	BEGIN_RING(celsius, NV10TCL_VIEWPORT_SCALE_X, 4);
-	OUT_RINGf  (-2048.0);
-	OUT_RINGf  (-2048.0);
-	OUT_RINGf  (16777215.0 * 0.5);
-	OUT_RING  (0);
+	BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_TRANSLATE_X, 4);
+	OUT_RINGf  (chan, -2048.0);
+	OUT_RINGf  (chan, -2048.0);
+	OUT_RINGf  (chan, 16777215.0 * 0.5);
+	OUT_RING  (chan, 0);
 
-	FIRE_RING (NULL);
-}
-
-static void
-nv10_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
-{
+	FIRE_RING (chan);
 }
 
 struct pipe_context *
@@ -276,7 +276,6 @@
 	nv10->pipe.winsys = ws;
 	nv10->pipe.screen = pscreen;
 	nv10->pipe.destroy = nv10_destroy;
-	nv10->pipe.set_edgeflags = nv10_set_edgeflags;
 	nv10->pipe.draw_arrays = nv10_draw_arrays;
 	nv10->pipe.draw_elements = nv10_draw_elements;
 	nv10->pipe.clear = nv10_clear;
diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h
index 36a6aa7..ab4b825 100644
--- a/src/gallium/drivers/nv10/nv10_context.h
+++ b/src/gallium/drivers/nv10/nv10_context.h
@@ -15,10 +15,6 @@
 #include "nouveau/nouveau_gldefs.h"
 #include "nouveau/nouveau_context.h"
 
-#define NOUVEAU_PUSH_CONTEXT(ctx)                                              \
-	struct nv10_screen *ctx = nv10->screen
-#include "nouveau/nouveau_push.h"
-
 #include "nv10_state.h"
 
 #define NOUVEAU_ERR(fmt, args...) \
@@ -144,9 +140,9 @@
 extern void nv10_state_tex_update(struct nv10_context *nv10);
 
 /* nv10_vbo.c */
-extern boolean nv10_draw_arrays(struct pipe_context *, unsigned mode,
+extern void nv10_draw_arrays(struct pipe_context *, unsigned mode,
 				unsigned start, unsigned count);
-extern boolean nv10_draw_elements( struct pipe_context *pipe,
+extern void nv10_draw_elements( struct pipe_context *pipe,
                     struct pipe_buffer *indexBuffer,
                     unsigned indexSize,
                     unsigned prim, unsigned start, unsigned count);
diff --git a/src/gallium/drivers/nv10/nv10_fragtex.c b/src/gallium/drivers/nv10/nv10_fragtex.c
index 27f2f87..c1f7ccb 100644
--- a/src/gallium/drivers/nv10/nv10_fragtex.c
+++ b/src/gallium/drivers/nv10/nv10_fragtex.c
@@ -52,6 +52,9 @@
 	struct nv10_miptree *nv10mt = nv10->tex_miptree[unit];
 	struct pipe_texture *pt = &nv10mt->base;
 	struct nv10_texture_format *tf;
+	struct nv10_screen *screen = nv10->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *celsius = screen->celsius;
 	uint32_t txf, txs, txp;
 
 	tf = nv10_fragtex_format(pt->format);
@@ -62,9 +65,9 @@
 
 	txf  = tf->format << 8;
 	txf |= (pt->last_level + 1) << 16;
-	txf |= log2i(pt->width[0]) << 20;
-	txf |= log2i(pt->height[0]) << 24;
-	txf |= log2i(pt->depth[0]) << 28;
+	txf |= log2i(pt->width0) << 20;
+	txf |= log2i(pt->height0) << 24;
+	txf |= log2i(pt->depth0) << 28;
 	txf |= 8;
 
 	switch (pt->target) {
@@ -82,15 +85,15 @@
 		return;
 	}
 
-	BEGIN_RING(celsius, NV10TCL_TX_OFFSET(unit), 8);
-	OUT_RELOCl(nv10mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
-	OUT_RELOCd(nv10mt->buffer,txf,NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
-	OUT_RING  (ps->wrap);
-	OUT_RING  (0x40000000); /* enable */
-	OUT_RING  (txs);
-	OUT_RING  (ps->filt | 0x2000 /* magic */);
-	OUT_RING  ((pt->width[0] << 16) | pt->height[0]);
-	OUT_RING  (ps->bcol);
+	BEGIN_RING(chan, celsius, NV10TCL_TX_OFFSET(unit), 8);
+	OUT_RELOCl(chan, nouveau_bo(nv10mt->buffer), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+	OUT_RELOCd(chan, nouveau_bo(nv10mt->buffer),txf,NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
+	OUT_RING  (chan, ps->wrap);
+	OUT_RING  (chan, 0x40000000); /* enable */
+	OUT_RING  (chan, txs);
+	OUT_RING  (chan, ps->filt | 0x2000 /* magic */);
+	OUT_RING  (chan, (pt->width0 << 16) | pt->height0);
+	OUT_RING  (chan, ps->bcol);
 #endif
 }
 
@@ -99,6 +102,9 @@
 {
 #if 0
 	struct nv10_fragment_program *fp = nv10->fragprog.active;
+	struct nv10_screen *screen = nv10->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *celsius = screen->celsius;
 	unsigned samplers, unit;
 
 	samplers = nv10->fp_samplers & ~fp->samplers;
@@ -106,8 +112,8 @@
 		unit = ffs(samplers) - 1;
 		samplers &= ~(1 << unit);
 
-		BEGIN_RING(celsius, NV10TCL_TX_ENABLE(unit), 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(unit), 1);
+		OUT_RING  (chan, 0);
 	}
 
 	samplers = nv10->dirty_samplers & fp->samplers;
diff --git a/src/gallium/drivers/nv10/nv10_miptree.c b/src/gallium/drivers/nv10/nv10_miptree.c
index 34e3c2e..908482a 100644
--- a/src/gallium/drivers/nv10/nv10_miptree.c
+++ b/src/gallium/drivers/nv10/nv10_miptree.c
@@ -1,6 +1,8 @@
 #include "pipe/p_state.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
 
 #include "nv10_context.h"
 #include "nv10_screen.h"
@@ -10,7 +12,7 @@
 {
 	struct pipe_texture *pt = &nv10mt->base;
 	boolean swizzled = FALSE;
-	uint width = pt->width[0], height = pt->height[0];
+	uint width = pt->width0;
 	uint offset = 0;
 	int nr_faces, l, f;
 
@@ -21,29 +23,23 @@
 	}
 	
 	for (l = 0; l <= pt->last_level; l++) {
-		pt->width[l] = width;
-		pt->height[l] = height;
-		pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width);
-		pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height);
-
 		if (swizzled)
-			nv10mt->level[l].pitch = pt->nblocksx[l] * pt->block.size;
+			nv10mt->level[l].pitch = util_format_get_stride(pt->format, width);
 		else
-			nv10mt->level[l].pitch = pt->nblocksx[0] * pt->block.size;
+			nv10mt->level[l].pitch = util_format_get_stride(pt->format, pt->width0);
 		nv10mt->level[l].pitch = (nv10mt->level[l].pitch + 63) & ~63;
 
 		nv10mt->level[l].image_offset =
 			CALLOC(nr_faces, sizeof(unsigned));
 
-		width  = MAX2(1, width  >> 1);
-		height = MAX2(1, height >> 1);
+		width  = u_minify(width, 1);
 
 	}
 
 	for (f = 0; f < nr_faces; f++) {
 		for (l = 0; l <= pt->last_level; l++) {
 			nv10mt->level[l].image_offset[f] = offset;
-			offset += nv10mt->level[l].pitch * pt->height[l];
+			offset += nv10mt->level[l].pitch * u_minify(pt->height0, l);
 		}
 	}
 
@@ -58,7 +54,7 @@
 
 	/* Only supports 2D, non-mipmapped textures for the moment */
 	if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 ||
-	    pt->depth[0] != 1)
+	    pt->depth0 != 1)
 		return NULL;
 
 	mt = CALLOC_STRUCT(nv10_miptree);
@@ -72,6 +68,7 @@
 	mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
 
 	pipe_buffer_reference(&mt->buffer, pb);
+	mt->bo = nouveau_bo(mt->buffer);
 	return &mt->base;
 }
 
@@ -95,6 +92,7 @@
 		FREE(mt);
 		return NULL;
 	}
+	mt->bo = nouveau_bo(mt->buffer);
 	
 	return &mt->base;
 }
@@ -133,8 +131,8 @@
 		return NULL;
 	pipe_texture_reference(&ns->base.texture, pt);
 	ns->base.format = pt->format;
-	ns->base.width = pt->width[level];
-	ns->base.height = pt->height[level];
+	ns->base.width = u_minify(pt->width0, level);
+	ns->base.height = u_minify(pt->height0, level);
 	ns->base.usage = flags;
 	pipe_reference_init(&ns->base.reference, 1);
 	ns->base.face = face;
diff --git a/src/gallium/drivers/nv10/nv10_prim_vbuf.c b/src/gallium/drivers/nv10/nv10_prim_vbuf.c
index 1806d5f..c5dbe43 100644
--- a/src/gallium/drivers/nv10/nv10_prim_vbuf.c
+++ b/src/gallium/drivers/nv10/nv10_prim_vbuf.c
@@ -67,12 +67,15 @@
 
 void nv10_vtxbuf_bind( struct nv10_context* nv10 )
 {
+	struct nv10_screen *screen = nv10->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *celsius = screen->celsius;
 	int i;
 	for(i = 0; i < 8; i++) {
-		BEGIN_RING(celsius, NV10TCL_VERTEX_ARRAY_ATTRIB_OFFSET(i), 1);
-		OUT_RING(0/*nv10->vtxbuf*/);
-		BEGIN_RING(celsius, NV10TCL_VERTEX_ARRAY_ATTRIB_FORMAT(i) ,1);
-		OUT_RING(0/*XXX*/);
+		BEGIN_RING(chan, celsius, NV10TCL_VTXBUF_ADDRESS(i), 1);
+		OUT_RING(chan, 0/*nv10->vtxbuf*/);
+		BEGIN_RING(chan, celsius, NV10TCL_VTXFMT(i), 1);
+		OUT_RING(chan, 0/*XXX*/);
 	}
 }
 
@@ -163,19 +166,22 @@
 {
 	struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
 	struct nv10_context *nv10 = nv10_render->nv10;
+	struct nv10_screen *screen = nv10->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *celsius = screen->celsius;
 	int push, i;
 
 	nv10_emit_hw_state(nv10);
 
-	BEGIN_RING(celsius, NV10TCL_VERTEX_ARRAY_OFFSET_POS, 1);
-	OUT_RELOCl(nv10_render->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+	BEGIN_RING(chan, celsius, NV10TCL_VERTEX_ARRAY_OFFSET_POS, 1);
+	OUT_RELOCl(chan, nouveau_bo(nv10_render->buffer), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
 
-	BEGIN_RING(celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1);
-	OUT_RING(nv10_render->hwprim);
+	BEGIN_RING(chan, celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1);
+	OUT_RING(chan, nv10_render->hwprim);
 
 	if (nr_indices & 1) {
-		BEGIN_RING(celsius, NV10TCL_VB_ELEMENT_U32, 1);
-		OUT_RING  (indices[0]);
+		BEGIN_RING(chan, celsius, NV10TCL_VB_ELEMENT_U32, 1);
+		OUT_RING  (chan, indices[0]);
 		indices++; nr_indices--;
 	}
 
@@ -183,16 +189,16 @@
 		// XXX too big/small ? check the size
 		push = MIN2(nr_indices, 1200 * 2);
 
-		BEGIN_RING_NI(celsius, NV10TCL_VB_ELEMENT_U16, push >> 1);
+		BEGIN_RING_NI(chan, celsius, NV10TCL_VB_ELEMENT_U16, push >> 1);
 		for (i = 0; i < push; i+=2)
-			OUT_RING((indices[i+1] << 16) | indices[i]);
+			OUT_RING(chan, (indices[i+1] << 16) | indices[i]);
 
 		nr_indices -= push;
 		indices  += push;
 	}
 
-	BEGIN_RING(celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1);
-	OUT_RING  (0);
+	BEGIN_RING(chan, celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1);
+	OUT_RING  (chan, 0);
 }
 
 
diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c
index ee5901e..69a6dab 100644
--- a/src/gallium/drivers/nv10/nv10_screen.c
+++ b/src/gallium/drivers/nv10/nv10_screen.c
@@ -115,6 +115,9 @@
 
 	nouveau_notifier_free(&screen->sync);
 	nouveau_grobj_free(&screen->celsius);
+	nv04_surface_2d_takedown(&screen->eng2d);
+
+	nouveau_screen_fini(&screen->base);
 
 	FREE(pscreen);
 }
@@ -177,7 +180,6 @@
 		NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
 		return FALSE;
 	}
-	BIND_RING(chan, screen->celsius, 7);
 
 	/* 2D engine setup */
 	screen->eng2d = nv04_surface_2d_init(&screen->base);
diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c
index 9b38219..ffc6be3 100644
--- a/src/gallium/drivers/nv10/nv10_state.c
+++ b/src/gallium/drivers/nv10/nv10_state.c
@@ -553,9 +553,9 @@
 	nv10->pipe.delete_blend_state = nv10_blend_state_delete;
 
 	nv10->pipe.create_sampler_state = nv10_sampler_state_create;
-	nv10->pipe.bind_sampler_states = nv10_sampler_state_bind;
+	nv10->pipe.bind_fragment_sampler_states = nv10_sampler_state_bind;
 	nv10->pipe.delete_sampler_state = nv10_sampler_state_delete;
-	nv10->pipe.set_sampler_textures = nv10_set_sampler_texture;
+	nv10->pipe.set_fragment_sampler_textures = nv10_set_sampler_texture;
 
 	nv10->pipe.create_rasterizer_state = nv10_rasterizer_state_create;
 	nv10->pipe.bind_rasterizer_state = nv10_rasterizer_state_bind;
diff --git a/src/gallium/drivers/nv10/nv10_state.h b/src/gallium/drivers/nv10/nv10_state.h
index 3a3fd0d..2524ac0 100644
--- a/src/gallium/drivers/nv10/nv10_state.h
+++ b/src/gallium/drivers/nv10/nv10_state.h
@@ -126,6 +126,7 @@
 
 struct nv10_miptree {
 	struct pipe_texture base;
+	struct nouveau_bo *bo;
 
 	struct pipe_buffer *buffer;
 	uint total_size;
diff --git a/src/gallium/drivers/nv10/nv10_state_emit.c b/src/gallium/drivers/nv10/nv10_state_emit.c
index 2577ab7..30a596c 100644
--- a/src/gallium/drivers/nv10/nv10_state_emit.c
+++ b/src/gallium/drivers/nv10/nv10_state_emit.c
@@ -4,25 +4,32 @@
 static void nv10_state_emit_blend(struct nv10_context* nv10)
 {
 	struct nv10_blend_state *b = nv10->blend;
+	struct nv10_screen *screen = nv10->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *celsius = screen->celsius;
 
-	BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 1);
-	OUT_RING  (b->d_enable);
+	BEGIN_RING(chan, celsius, NV10TCL_DITHER_ENABLE, 1);
+	OUT_RING  (chan, b->d_enable);
 
-	BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 3);
-	OUT_RING  (b->b_enable);
-	OUT_RING  (b->b_srcfunc);
-	OUT_RING  (b->b_dstfunc);
+	BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_ENABLE, 3);
+	OUT_RING  (chan, b->b_enable);
+	OUT_RING  (chan, b->b_srcfunc);
+	OUT_RING  (chan, b->b_dstfunc);
 
-	BEGIN_RING(celsius, NV10TCL_COLOR_MASK, 1);
-	OUT_RING  (b->c_mask);
+	BEGIN_RING(chan, celsius, NV10TCL_COLOR_MASK, 1);
+	OUT_RING  (chan, b->c_mask);
 }
 
 static void nv10_state_emit_blend_color(struct nv10_context* nv10)
 {
 	struct pipe_blend_color *c = nv10->blend_color;
+	struct nv10_screen *screen = nv10->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *celsius = screen->celsius;
 
-	BEGIN_RING(celsius, NV10TCL_BLEND_COLOR, 1);
-	OUT_RING  ((float_to_ubyte(c->color[3]) << 24)|
+	BEGIN_RING(chan, celsius, NV10TCL_BLEND_COLOR, 1);
+	OUT_RING  (chan,
+		   (float_to_ubyte(c->color[3]) << 24)|
 		   (float_to_ubyte(c->color[0]) << 16)|
 		   (float_to_ubyte(c->color[1]) << 8) |
 		   (float_to_ubyte(c->color[2]) << 0));
@@ -31,60 +38,66 @@
 static void nv10_state_emit_rast(struct nv10_context* nv10)
 {
 	struct nv10_rasterizer_state *r = nv10->rast;
+	struct nv10_screen *screen = nv10->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *celsius = screen->celsius;
 
-	BEGIN_RING(celsius, NV10TCL_SHADE_MODEL, 2);
-	OUT_RING  (r->shade_model);
-	OUT_RING  (r->line_width);
+	BEGIN_RING(chan, celsius, NV10TCL_SHADE_MODEL, 2);
+	OUT_RING  (chan, r->shade_model);
+	OUT_RING  (chan, r->line_width);
 
 
-	BEGIN_RING(celsius, NV10TCL_POINT_SIZE, 1);
-	OUT_RING  (r->point_size);
+	BEGIN_RING(chan, celsius, NV10TCL_POINT_SIZE, 1);
+	OUT_RING  (chan, r->point_size);
 
-	BEGIN_RING(celsius, NV10TCL_POLYGON_MODE_FRONT, 2);
-	OUT_RING  (r->poly_mode_front);
-	OUT_RING  (r->poly_mode_back);
+	BEGIN_RING(chan, celsius, NV10TCL_POLYGON_MODE_FRONT, 2);
+	OUT_RING  (chan, r->poly_mode_front);
+	OUT_RING  (chan, r->poly_mode_back);
 
 
-	BEGIN_RING(celsius, NV10TCL_CULL_FACE, 2);
-	OUT_RING  (r->cull_face);
-	OUT_RING  (r->front_face);
+	BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE, 2);
+	OUT_RING  (chan, r->cull_face);
+	OUT_RING  (chan, r->front_face);
 
-	BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 2);
-	OUT_RING  (r->line_smooth_en);
-	OUT_RING  (r->poly_smooth_en);
+	BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 2);
+	OUT_RING  (chan, r->line_smooth_en);
+	OUT_RING  (chan, r->poly_smooth_en);
 
-	BEGIN_RING(celsius, NV10TCL_CULL_FACE_ENABLE, 1);
-	OUT_RING  (r->cull_face_en);
+	BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE_ENABLE, 1);
+	OUT_RING  (chan, r->cull_face_en);
 }
 
 static void nv10_state_emit_dsa(struct nv10_context* nv10)
 {
 	struct nv10_depth_stencil_alpha_state *d = nv10->dsa;
+	struct nv10_screen *screen = nv10->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *celsius = screen->celsius;
 
-	BEGIN_RING(celsius, NV10TCL_DEPTH_FUNC, 1);
-	OUT_RING (d->depth.func);
+	BEGIN_RING(chan, celsius, NV10TCL_DEPTH_FUNC, 1);
+	OUT_RING (chan, d->depth.func);
 
-	BEGIN_RING(celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1);
-	OUT_RING (d->depth.write_enable);
+	BEGIN_RING(chan, celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1);
+	OUT_RING (chan, d->depth.write_enable);
 
-	BEGIN_RING(celsius, NV10TCL_DEPTH_TEST_ENABLE, 1);
-	OUT_RING (d->depth.test_enable);
+	BEGIN_RING(chan, celsius, NV10TCL_DEPTH_TEST_ENABLE, 1);
+	OUT_RING (chan, d->depth.test_enable);
 
 #if 0
-	BEGIN_RING(celsius, NV10TCL_STENCIL_ENABLE, 1);
-	OUT_RING (d->stencil.enable);
-	BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 7);
-	OUT_RINGp ((uint32_t *)&(d->stencil.wmask), 7);
+	BEGIN_RING(chan, celsius, NV10TCL_STENCIL_ENABLE, 1);
+	OUT_RING (chan, d->stencil.enable);
+	BEGIN_RING(chan, celsius, NV10TCL_STENCIL_MASK, 7);
+	OUT_RINGp (chan, (uint32_t *)&(d->stencil.wmask), 7);
 #endif
 
-	BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1);
-	OUT_RING (d->alpha.enabled);
+	BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1);
+	OUT_RING (chan, d->alpha.enabled);
 
-	BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_FUNC, 1);
-	OUT_RING (d->alpha.func);
+	BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_FUNC, 1);
+	OUT_RING (chan, d->alpha.func);
 
-	BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_REF, 1);
-	OUT_RING (d->alpha.ref);
+	BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_REF, 1);
+	OUT_RING (chan, d->alpha.ref);
 }
 
 static void nv10_state_emit_viewport(struct nv10_context* nv10)
@@ -108,6 +121,10 @@
 	int colour_format = 0, zeta_format = 0;
         struct nv10_miptree *nv10mt = 0;
 
+	struct nv10_screen *screen = nv10->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *celsius = screen->celsius;
+
 	w = fb->cbufs[0]->width;
 	h = fb->cbufs[0]->height;
 	colour_format = fb->cbufs[0]->format;
@@ -144,11 +161,11 @@
 	}
 
 	if (zeta) {
-		BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1);
-		OUT_RING  (rt->pitch | (zeta->pitch << 16));
+		BEGIN_RING(chan, celsius, NV10TCL_RT_PITCH, 1);
+		OUT_RING  (chan, rt->pitch | (zeta->pitch << 16));
 	} else {
-		BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1);
-		OUT_RING  (rt->pitch | (rt->pitch << 16));
+		BEGIN_RING(chan, celsius, NV10TCL_RT_PITCH, 1);
+		OUT_RING  (chan, rt->pitch | (rt->pitch << 16));
 	}
 
 	nv10mt = (struct nv10_miptree *)rt->base.texture;
@@ -160,13 +177,13 @@
 		nv10->zeta = nv10mt->buffer;
 	}
 
-	BEGIN_RING(celsius, NV10TCL_RT_HORIZ, 3);
-	OUT_RING  ((w << 16) | 0);
-	OUT_RING  ((h << 16) | 0);
-	OUT_RING  (rt_format);
-	BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 2);
-	OUT_RING  (((w - 1) << 16) | 0 | 0x08000800);
-	OUT_RING  (((h - 1) << 16) | 0 | 0x08000800);
+	BEGIN_RING(chan, celsius, NV10TCL_RT_HORIZ, 3);
+	OUT_RING  (chan, (w << 16) | 0);
+	OUT_RING  (chan, (h << 16) | 0);
+	OUT_RING  (chan, rt_format);
+	BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 2);
+	OUT_RING  (chan, ((w - 1) << 16) | 0 | 0x08000800);
+	OUT_RING  (chan, ((h - 1) << 16) | 0 | 0x08000800);
 }
 
 static void nv10_vertex_layout(struct nv10_context *nv10)
@@ -201,6 +218,10 @@
 void
 nv10_emit_hw_state(struct nv10_context *nv10)
 {
+	struct nv10_screen *screen = nv10->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *celsius = screen->celsius;
+	struct nouveau_bo *rt_bo;
 	int i;
 
 	if (nv10->dirty & NV10_NEW_VERTPROG) {
@@ -269,38 +290,41 @@
 	 */
 
 	/* Render target */
+	rt_bo = nouveau_bo(nv10->rt[0]);
 // XXX figre out who's who for NV10TCL_DMA_* and fill accordingly
-//	BEGIN_RING(celsius, NV10TCL_DMA_COLOR0, 1);
-//	OUT_RELOCo(nv10->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-	BEGIN_RING(celsius, NV10TCL_COLOR_OFFSET, 1);
-	OUT_RELOCl(nv10->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+//	BEGIN_RING(chan, celsius, NV10TCL_DMA_COLOR0, 1);
+//	OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+	BEGIN_RING(chan, celsius, NV10TCL_COLOR_OFFSET, 1);
+	OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
 
 	if (nv10->zeta) {
+		struct nouveau_bo *zeta_bo = nouveau_bo(nv10->zeta);
 // XXX
-//		BEGIN_RING(celsius, NV10TCL_DMA_ZETA, 1);
-//		OUT_RELOCo(nv10->zeta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-		BEGIN_RING(celsius, NV10TCL_ZETA_OFFSET, 1);
-		OUT_RELOCl(nv10->zeta, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+//		BEGIN_RING(chan, celsius, NV10TCL_DMA_ZETA, 1);
+//		OUT_RELOCo(chan, zeta_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+		BEGIN_RING(chan, celsius, NV10TCL_ZETA_OFFSET, 1);
+		OUT_RELOCl(chan, zeta_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
 		/* XXX for when we allocate LMA on nv17 */
-/*		BEGIN_RING(celsius, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1);
-		OUT_RELOCl(nv10->zeta + lma_offset);*/
+/*		BEGIN_RING(chan, celsius, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1);
+		OUT_RELOCl(chan, nouveau_bo(nv10->zeta + lma_offset));*/
 	}
 
 	/* Vertex buffer */
-	BEGIN_RING(celsius, NV10TCL_DMA_VTXBUF0, 1);
-	OUT_RELOCo(nv10->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-	BEGIN_RING(celsius, NV10TCL_COLOR_OFFSET, 1);
-	OUT_RELOCl(nv10->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+	BEGIN_RING(chan, celsius, NV10TCL_DMA_VTXBUF0, 1);
+	OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+	BEGIN_RING(chan, celsius, NV10TCL_COLOR_OFFSET, 1);
+	OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
 
 	/* Texture images */
 	for (i = 0; i < 2; i++) {
 		if (!(nv10->fp_samplers & (1 << i)))
 			continue;
-		BEGIN_RING(celsius, NV10TCL_TX_OFFSET(i), 1);
-		OUT_RELOCl(nv10->tex[i].buffer, 0, NOUVEAU_BO_VRAM |
+		struct nouveau_bo *bo = nouveau_bo(nv10->tex[i].buffer);
+		BEGIN_RING(chan, celsius, NV10TCL_TX_OFFSET(i), 1);
+		OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM |
 			   NOUVEAU_BO_GART | NOUVEAU_BO_RD);
-		BEGIN_RING(celsius, NV10TCL_TX_FORMAT(i), 1);
-		OUT_RELOCd(nv10->tex[i].buffer, nv10->tex[i].format,
+		BEGIN_RING(chan, celsius, NV10TCL_TX_FORMAT(i), 1);
+		OUT_RELOCd(chan, bo, nv10->tex[i].format,
 			   NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
 			   NOUVEAU_BO_OR, NV10TCL_TX_FORMAT_DMA0,
 			   NV10TCL_TX_FORMAT_DMA1);
diff --git a/src/gallium/drivers/nv10/nv10_transfer.c b/src/gallium/drivers/nv10/nv10_transfer.c
index 8feb85e..eb04af9 100644
--- a/src/gallium/drivers/nv10/nv10_transfer.c
+++ b/src/gallium/drivers/nv10/nv10_transfer.c
@@ -1,7 +1,9 @@
 #include <pipe/p_state.h>
 #include <pipe/p_defines.h>
 #include <pipe/p_inlines.h>
+#include <util/u_format.h>
 #include <util/u_memory.h>
+#include <util/u_math.h>
 #include <nouveau/nouveau_winsys.h>
 #include "nv10_context.h"
 #include "nv10_screen.h"
@@ -10,22 +12,19 @@
 struct nv10_transfer {
 	struct pipe_transfer base;
 	struct pipe_surface *surface;
-	bool direct;
+	boolean direct;
 };
 
 static void
-nv10_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
+nv10_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height,
                              struct pipe_texture *template)
 {
 	memset(template, 0, sizeof(struct pipe_texture));
 	template->target = pt->target;
 	template->format = pt->format;
-	template->width[0] = pt->width[level];
-	template->height[0] = pt->height[level];
-	template->depth[0] = 1;
-	template->block = pt->block;
-	template->nblocksx[0] = pt->nblocksx[level];
-	template->nblocksy[0] = pt->nblocksx[level];
+	template->width0 = width;
+	template->height0 = height;
+	template->depth0 = 1;
 	template->last_level = 0;
 	template->nr_samples = pt->nr_samples;
 
@@ -48,14 +47,10 @@
 		return NULL;
 
 	pipe_texture_reference(&tx->base.texture, pt);
-	tx->base.format = pt->format;
 	tx->base.x = x;
 	tx->base.y = y;
 	tx->base.width = w;
 	tx->base.height = h;
-	tx->base.block = pt->block;
-	tx->base.nblocksx = pt->nblocksx[level];
-	tx->base.nblocksy = pt->nblocksy[level];
 	tx->base.stride = mt->level[level].pitch;
 	tx->base.usage = usage;
 	tx->base.face = face;
@@ -76,7 +71,7 @@
 
 	tx->direct = false;
 
-	nv10_compatible_transfer_tex(pt, level, &tx_tex_template);
+	nv10_compatible_transfer_tex(pt, w, h, &tx_tex_template);
 
 	tx_tex = pscreen->texture_create(pscreen, &tx_tex_template);
 	if (!tx_tex)
@@ -85,6 +80,8 @@
 		return NULL;
 	}
 
+	tx->base.stride = ((struct nv10_miptree*)tx_tex)->level[0].pitch;
+
 	tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
 	                                       face, level, zslice,
 	                                       pipe_transfer_buffer_flags(&tx->base));
@@ -110,8 +107,8 @@
 		/* TODO: Check if SIFM can un-swizzle */
 		nvscreen->eng2d->copy(nvscreen->eng2d,
 		                      tx->surface, 0, 0,
-		                      src, 0, 0,
-		                      src->width, src->height);
+		                      src, x, y,
+		                      w, h);
 
 		pipe_surface_reference(&src, NULL);
 	}
@@ -135,9 +132,9 @@
 
 		/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
 		nvscreen->eng2d->copy(nvscreen->eng2d,
-		                      dst, 0, 0,
+		                      dst, tx->base.x, tx->base.y,
 		                      tx->surface, 0, 0,
-		                      dst->width, dst->height);
+		                      tx->base.width, tx->base.height);
 
 		pipe_surface_reference(&dst, NULL);
 	}
@@ -156,8 +153,10 @@
 	void *map = pipe_buffer_map(pscreen, mt->buffer,
 	                            pipe_transfer_buffer_flags(ptx));
 
-	return map + ns->base.offset +
-	       ptx->y * ns->pitch + ptx->x * ptx->block.size;
+	if(!tx->direct)
+		return map + ns->base.offset;
+	else
+		return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format);
 }
 
 static void
diff --git a/src/gallium/drivers/nv10/nv10_vbo.c b/src/gallium/drivers/nv10/nv10_vbo.c
index 441a4f7..9180c72 100644
--- a/src/gallium/drivers/nv10/nv10_vbo.c
+++ b/src/gallium/drivers/nv10/nv10_vbo.c
@@ -9,7 +9,7 @@
 #include "nouveau/nouveau_channel.h"
 #include "nouveau/nouveau_pushbuf.h"
 
-boolean nv10_draw_elements( struct pipe_context *pipe,
+void nv10_draw_elements( struct pipe_context *pipe,
                     struct pipe_buffer *indexBuffer,
                     unsigned indexSize,
                     unsigned prim, unsigned start, unsigned count)
@@ -45,6 +45,7 @@
 	}
 
 	draw_set_mapped_constant_buffer(draw,
+                                        PIPE_SHADER_VERTEX,
 					nv10->constbuf[PIPE_SHADER_VERTEX],
 					nv10->constbuf_nr[PIPE_SHADER_VERTEX]);
 
@@ -64,14 +65,12 @@
 		pipe_buffer_unmap(pscreen, indexBuffer);
 		draw_set_mapped_element_buffer(draw, 0, NULL);
 	}
-
-	return TRUE;
 }
 
-boolean nv10_draw_arrays( struct pipe_context *pipe,
-				 unsigned prim, unsigned start, unsigned count)
+void nv10_draw_arrays( struct pipe_context *pipe,
+                       unsigned prim, unsigned start, unsigned count)
 {
-	return nv10_draw_elements(pipe, NULL, 0, prim, start, count);
+	nv10_draw_elements(pipe, NULL, 0, prim, start, count);
 }
 
 
diff --git a/src/gallium/drivers/nv20/nv20_context.c b/src/gallium/drivers/nv20/nv20_context.c
index 9a48739..5b80af2 100644
--- a/src/gallium/drivers/nv20/nv20_context.c
+++ b/src/gallium/drivers/nv20/nv20_context.c
@@ -10,10 +10,14 @@
 	   struct pipe_fence_handle **fence)
 {
 	struct nv20_context *nv20 = nv20_context(pipe);
+	struct nv20_screen *screen = nv20->screen;
+	struct nouveau_channel *chan = screen->base.channel;
 
 	draw_flush(nv20->draw);
 
-	FIRE_RING(fence);
+	FIRE_RING(chan);
+	if (fence)
+		*fence = NULL;
 }
 
 static void
@@ -31,353 +35,352 @@
 {
 	struct nv20_screen *screen = nv20->screen;
 	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *kelvin = screen->kelvin;
 	int i;
 	float projectionmatrix[16];
-	const boolean is_nv25tcl = (nv20->screen->kelvin->grclass == NV25TCL);
+	const boolean is_nv25tcl = (kelvin->grclass == NV25TCL);
 
-	BEGIN_RING(kelvin, NV20TCL_DMA_NOTIFY, 1);
-	OUT_RING  (screen->sync->handle);
-	BEGIN_RING(kelvin, NV20TCL_DMA_TEXTURE0, 2);
-	OUT_RING  (chan->vram->handle);
-	OUT_RING  (chan->gart->handle); /* TEXTURE1 */
-	BEGIN_RING(kelvin, NV20TCL_DMA_COLOR, 2);
-	OUT_RING  (chan->vram->handle);
-	OUT_RING  (chan->vram->handle); /* ZETA */
+	BEGIN_RING(chan, kelvin, NV20TCL_DMA_NOTIFY, 1);
+	OUT_RING  (chan, screen->sync->handle);
+	BEGIN_RING(chan, kelvin, NV20TCL_DMA_TEXTURE0, 2);
+	OUT_RING  (chan, chan->vram->handle);
+	OUT_RING  (chan, chan->gart->handle); /* TEXTURE1 */
+	BEGIN_RING(chan, kelvin, NV20TCL_DMA_COLOR, 2);
+	OUT_RING  (chan, chan->vram->handle);
+	OUT_RING  (chan, chan->vram->handle); /* ZETA */
 
-	BEGIN_RING(kelvin, NV20TCL_DMA_QUERY, 1);
-	OUT_RING  (0); /* renouveau: beef0351, unique */
+	BEGIN_RING(chan, kelvin, NV20TCL_DMA_QUERY, 1);
+	OUT_RING  (chan, 0); /* renouveau: beef0351, unique */
 
-	BEGIN_RING(kelvin, NV20TCL_RT_HORIZ, 2);
-	OUT_RING  (0);
-	OUT_RING  (0);
+	BEGIN_RING(chan, kelvin, NV20TCL_RT_HORIZ, 2);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
 
-	BEGIN_RING(kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 1);
-	OUT_RING  ((0xfff << 16) | 0x0);
-	BEGIN_RING(kelvin, NV20TCL_VIEWPORT_CLIP_VERT(0), 1);
-	OUT_RING  ((0xfff << 16) | 0x0);
+	BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 1);
+	OUT_RING  (chan, (0xfff << 16) | 0x0);
+	BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_VERT(0), 1);
+	OUT_RING  (chan, (0xfff << 16) | 0x0);
 
 	for (i = 1; i < NV20TCL_VIEWPORT_CLIP_HORIZ__SIZE; i++) {
-		BEGIN_RING(kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(i), 1);
-		OUT_RING  (0);
-		BEGIN_RING(kelvin, NV20TCL_VIEWPORT_CLIP_VERT(i), 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(i), 1);
+		OUT_RING  (chan, 0);
+		BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_VERT(i), 1);
+		OUT_RING  (chan, 0);
 	}
 
-	BEGIN_RING(kelvin, NV20TCL_VIEWPORT_CLIP_MODE, 1);
-	OUT_RING  (0);
+	BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_MODE, 1);
+	OUT_RING  (chan, 0);
 
-	BEGIN_RING(kelvin, 0x17e0, 3);
-	OUT_RINGf (0.0);
-	OUT_RINGf (0.0);
-	OUT_RINGf (1.0);
+	BEGIN_RING(chan, kelvin, 0x17e0, 3);
+	OUT_RINGf (chan, 0.0);
+	OUT_RINGf (chan, 0.0);
+	OUT_RINGf (chan, 1.0);
 
 	if (is_nv25tcl) {
-		BEGIN_RING(kelvin, NV20TCL_TX_RCOMP, 1);
-		OUT_RING  (NV20TCL_TX_RCOMP_LEQUAL | 0xdb0);
+		BEGIN_RING(chan, kelvin, NV20TCL_TX_RCOMP, 1);
+		OUT_RING  (chan, NV20TCL_TX_RCOMP_LEQUAL | 0xdb0);
 	} else {
-		BEGIN_RING(kelvin, 0x1e68, 1);
-		OUT_RING  (0x4b800000); /* 16777216.000000 */
-		BEGIN_RING(kelvin, NV20TCL_TX_RCOMP, 1);
-		OUT_RING  (NV20TCL_TX_RCOMP_LEQUAL);
+		BEGIN_RING(chan, kelvin, 0x1e68, 1);
+		OUT_RING  (chan, 0x4b800000); /* 16777216.000000 */
+		BEGIN_RING(chan, kelvin, NV20TCL_TX_RCOMP, 1);
+		OUT_RING  (chan, NV20TCL_TX_RCOMP_LEQUAL);
 	}
 
-	BEGIN_RING(kelvin, 0x290, 1);
-	OUT_RING  ((0x10 << 16) | 1);
-	BEGIN_RING(kelvin, 0x9fc, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, 0x1d80, 1);
-	OUT_RING  (1);
-	BEGIN_RING(kelvin, 0x9f8, 1);
-	OUT_RING  (4);
-	BEGIN_RING(kelvin, 0x17ec, 3);
-	OUT_RINGf (0.0);
-	OUT_RINGf (1.0);
-	OUT_RINGf (0.0);
+	BEGIN_RING(chan, kelvin, 0x290, 1);
+	OUT_RING  (chan, (0x10 << 16) | 1);
+	BEGIN_RING(chan, kelvin, 0x9fc, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, 0x1d80, 1);
+	OUT_RING  (chan, 1);
+	BEGIN_RING(chan, kelvin, 0x9f8, 1);
+	OUT_RING  (chan, 4);
+	BEGIN_RING(chan, kelvin, 0x17ec, 3);
+	OUT_RINGf (chan, 0.0);
+	OUT_RINGf (chan, 1.0);
+	OUT_RINGf (chan, 0.0);
 
 	if (is_nv25tcl) {
-		BEGIN_RING(kelvin, 0x1d88, 1);
-		OUT_RING  (3);
+		BEGIN_RING(chan, kelvin, 0x1d88, 1);
+		OUT_RING  (chan, 3);
 
-		BEGIN_RING(kelvin, NV25TCL_DMA_IN_MEMORY9, 1);
-		OUT_RING  (chan->vram->handle);
-		BEGIN_RING(kelvin, NV25TCL_DMA_IN_MEMORY8, 1);
-		OUT_RING  (chan->vram->handle);
+		BEGIN_RING(chan, kelvin, NV25TCL_DMA_IN_MEMORY9, 1);
+		OUT_RING  (chan, chan->vram->handle);
+		BEGIN_RING(chan, kelvin, NV25TCL_DMA_IN_MEMORY8, 1);
+		OUT_RING  (chan, chan->vram->handle);
 	}
-	BEGIN_RING(kelvin, NV20TCL_DMA_FENCE, 1);
-	OUT_RING  (0);	/* renouveau: beef1e10 */
+	BEGIN_RING(chan, kelvin, NV20TCL_DMA_FENCE, 1);
+	OUT_RING  (chan, 0);	/* renouveau: beef1e10 */
 
-	BEGIN_RING(kelvin, 0x1e98, 1);
-	OUT_RING  (0);
+	BEGIN_RING(chan, kelvin, 0x1e98, 1);
+	OUT_RING  (chan, 0);
 #if 0
 	if (is_nv25tcl) {
-		BEGIN_RING(NvSub3D, NV25TCL_DMA_IN_MEMORY4, 2);
-		OUT_RING  (NvDmaTT);	/* renouveau: beef0202 */
-		OUT_RING  (NvDmaFB);	/* renouveau: beef0201 */
+		BEGIN_RING(chan, NvSub3D, NV25TCL_DMA_IN_MEMORY4, 2);
+		OUT_RING  (chan, NvDmaTT);	/* renouveau: beef0202 */
+		OUT_RING  (chan, NvDmaFB);	/* renouveau: beef0201 */
 
-		BEGIN_RING(NvSub3D, NV20TCL_DMA_TEXTURE1, 1);
-		OUT_RING  (NvDmaTT);	/* renouveau: beef0202 */
+		BEGIN_RING(chan, NvSub3D, NV20TCL_DMA_TEXTURE1, 1);
+		OUT_RING  (chan, NvDmaTT);	/* renouveau: beef0202 */
 	}
 #endif
-	BEGIN_RING(kelvin, NV20TCL_NOTIFY, 1);
-	OUT_RING  (0);
+	BEGIN_RING(chan, kelvin, NV20TCL_NOTIFY, 1);
+	OUT_RING  (chan, 0);
 
-	BEGIN_RING(kelvin, 0x120, 3);
-	OUT_RING  (0);
-	OUT_RING  (1);
-	OUT_RING  (2);
+	BEGIN_RING(chan, kelvin, 0x120, 3);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 1);
+	OUT_RING  (chan, 2);
 
 /* error: ILLEGAL_MTHD, PROTECTION_FAULT
-	BEGIN_RING(kelvin, NV20TCL_VIEWPORT_TRANSLATE_X, 4);
-	OUT_RINGf (0.0);
-	OUT_RINGf (512.0);
-	OUT_RINGf (0.0);
-	OUT_RINGf (0.0);
+	BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_TRANSLATE_X, 4);
+	OUT_RINGf (chan, 0.0);
+	OUT_RINGf (chan, 512.0);
+	OUT_RINGf (chan, 0.0);
+	OUT_RINGf (chan, 0.0);
 */
 
 	if (is_nv25tcl) {
-		BEGIN_RING(kelvin, 0x022c, 2);
-		OUT_RING  (0x280);
-		OUT_RING  (0x07d28000);
+		BEGIN_RING(chan, kelvin, 0x022c, 2);
+		OUT_RING  (chan, 0x280);
+		OUT_RING  (chan, 0x07d28000);
 	}
 
 /* * illegal method, protection fault
-	BEGIN_RING(NvSub3D, 0x1c2c, 1);
-	OUT_RING  (0); */
+	BEGIN_RING(chan, NvSub3D, 0x1c2c, 1);
+	OUT_RING  (chan, 0); */
 
 	if (is_nv25tcl) {
-		BEGIN_RING(kelvin, 0x1da4, 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, kelvin, 0x1da4, 1);
+		OUT_RING  (chan, 0);
 	}
 
 /* * crashes with illegal method, protection fault
-	BEGIN_RING(NvSub3D, 0x1c18, 1);
-	OUT_RING  (0x200); */
+	BEGIN_RING(chan, NvSub3D, 0x1c18, 1);
+	OUT_RING  (chan, 0x200); */
 
-	BEGIN_RING(kelvin, NV20TCL_RT_HORIZ, 2);
-	OUT_RING  ((0 << 16) | 0);
-	OUT_RING  ((0 << 16) | 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_RT_HORIZ, 2);
+	OUT_RING  (chan, (0 << 16) | 0);
+	OUT_RING  (chan, (0 << 16) | 0);
 
 	/* *** Set state *** */
 
-	BEGIN_RING(kelvin, NV20TCL_ALPHA_FUNC_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_ALPHA_FUNC_FUNC, 2);
-	OUT_RING  (NV20TCL_ALPHA_FUNC_FUNC_ALWAYS);
-	OUT_RING  (0);			/* NV20TCL_ALPHA_FUNC_REF */
+	BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_FUNC, 2);
+	OUT_RING  (chan, NV20TCL_ALPHA_FUNC_FUNC_ALWAYS);
+	OUT_RING  (chan, 0);			/* NV20TCL_ALPHA_FUNC_REF */
 
 	for (i = 0; i < NV20TCL_TX_ENABLE__SIZE; ++i) {
-		BEGIN_RING(kelvin, NV20TCL_TX_ENABLE(i), 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, kelvin, NV20TCL_TX_ENABLE(i), 1);
+		OUT_RING  (chan, 0);
 	}
-	BEGIN_RING(kelvin, NV20TCL_TX_SHADER_OP, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_TX_SHADER_CULL_MODE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_RC_IN_ALPHA(0), 4);
-	OUT_RING  (0x30d410d0);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_RC_OUT_RGB(0), 4);
-	OUT_RING  (0x00000c00);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_RC_ENABLE, 1);
-	OUT_RING  (0x00011101);
-	BEGIN_RING(kelvin, NV20TCL_RC_FINAL0, 2);
-	OUT_RING  (0x130e0300);
-	OUT_RING  (0x0c091c80);
-	BEGIN_RING(kelvin, NV20TCL_RC_OUT_ALPHA(0), 4);
-	OUT_RING  (0x00000c00);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_RC_IN_RGB(0), 4);
-	OUT_RING  (0x20c400c0);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_RC_COLOR0, 2);
-	OUT_RING  (0);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_RC_CONSTANT_COLOR0(0), 4);
-	OUT_RING  (0x035125a0);
-	OUT_RING  (0);
-	OUT_RING  (0x40002000);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_MULTISAMPLE_CONTROL, 1);
-	OUT_RING  (0xffff0000);
+	BEGIN_RING(chan, kelvin, NV20TCL_TX_SHADER_OP, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_TX_SHADER_CULL_MODE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_RC_IN_ALPHA(0), 4);
+	OUT_RING  (chan, 0x30d410d0);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_RC_OUT_RGB(0), 4);
+	OUT_RING  (chan, 0x00000c00);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_RC_ENABLE, 1);
+	OUT_RING  (chan, 0x00011101);
+	BEGIN_RING(chan, kelvin, NV20TCL_RC_FINAL0, 2);
+	OUT_RING  (chan, 0x130e0300);
+	OUT_RING  (chan, 0x0c091c80);
+	BEGIN_RING(chan, kelvin, NV20TCL_RC_OUT_ALPHA(0), 4);
+	OUT_RING  (chan, 0x00000c00);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_RC_IN_RGB(0), 4);
+	OUT_RING  (chan, 0x20c400c0);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_RC_COLOR0, 2);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_RC_CONSTANT_COLOR0(0), 4);
+	OUT_RING  (chan, 0x035125a0);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0x40002000);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_MULTISAMPLE_CONTROL, 1);
+	OUT_RING  (chan, 0xffff0000);
 
-	BEGIN_RING(kelvin, NV20TCL_BLEND_FUNC_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_DITHER_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_STENCIL_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_BLEND_FUNC_SRC, 4);
-	OUT_RING  (NV20TCL_BLEND_FUNC_SRC_ONE);
-	OUT_RING  (NV20TCL_BLEND_FUNC_DST_ZERO);
-	OUT_RING  (0);			/* NV20TCL_BLEND_COLOR */
-	OUT_RING  (NV20TCL_BLEND_EQUATION_FUNC_ADD);
-	BEGIN_RING(kelvin, NV20TCL_STENCIL_MASK, 7);
-	OUT_RING  (0xff);
-	OUT_RING  (NV20TCL_STENCIL_FUNC_FUNC_ALWAYS);
-	OUT_RING  (0);			/* NV20TCL_STENCIL_FUNC_REF */
-	OUT_RING  (0xff);		/* NV20TCL_STENCIL_FUNC_MASK */
-	OUT_RING  (NV20TCL_STENCIL_OP_FAIL_KEEP);
-	OUT_RING  (NV20TCL_STENCIL_OP_ZFAIL_KEEP);
-	OUT_RING  (NV20TCL_STENCIL_OP_ZPASS_KEEP);
+	BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_DITHER_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_STENCIL_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_SRC, 4);
+	OUT_RING  (chan, NV20TCL_BLEND_FUNC_SRC_ONE);
+	OUT_RING  (chan, NV20TCL_BLEND_FUNC_DST_ZERO);
+	OUT_RING  (chan, 0);			/* NV20TCL_BLEND_COLOR */
+	OUT_RING  (chan, NV20TCL_BLEND_EQUATION_FUNC_ADD);
+	BEGIN_RING(chan, kelvin, NV20TCL_STENCIL_MASK, 7);
+	OUT_RING  (chan, 0xff);
+	OUT_RING  (chan, NV20TCL_STENCIL_FUNC_FUNC_ALWAYS);
+	OUT_RING  (chan, 0);			/* NV20TCL_STENCIL_FUNC_REF */
+	OUT_RING  (chan, 0xff);		/* NV20TCL_STENCIL_FUNC_MASK */
+	OUT_RING  (chan, NV20TCL_STENCIL_OP_FAIL_KEEP);
+	OUT_RING  (chan, NV20TCL_STENCIL_OP_ZFAIL_KEEP);
+	OUT_RING  (chan, NV20TCL_STENCIL_OP_ZPASS_KEEP);
 
-	BEGIN_RING(kelvin, NV20TCL_COLOR_LOGIC_OP_ENABLE, 2);
-	OUT_RING  (0);
-	OUT_RING  (NV20TCL_COLOR_LOGIC_OP_OP_COPY);
-	BEGIN_RING(kelvin, 0x17cc, 1);
-	OUT_RING  (0);
+	BEGIN_RING(chan, kelvin, NV20TCL_COLOR_LOGIC_OP_ENABLE, 2);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, NV20TCL_COLOR_LOGIC_OP_OP_COPY);
+	BEGIN_RING(chan, kelvin, 0x17cc, 1);
+	OUT_RING  (chan, 0);
 	if (is_nv25tcl) {
-		BEGIN_RING(kelvin, 0x1d84, 1);
-		OUT_RING  (1);
+		BEGIN_RING(chan, kelvin, 0x1d84, 1);
+		OUT_RING  (chan, 1);
 	}
-	BEGIN_RING(kelvin, NV20TCL_LIGHTING_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_LIGHT_CONTROL, 1);
-	OUT_RING  (0x00020000);
-	BEGIN_RING(kelvin, NV20TCL_SEPARATE_SPECULAR_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_LIGHT_MODEL_TWO_SIDE_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_ENABLED_LIGHTS, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_NORMALIZE_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_POLYGON_STIPPLE_PATTERN(0),
+	BEGIN_RING(chan, kelvin, NV20TCL_LIGHTING_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_CONTROL, 1);
+	OUT_RING  (chan, 0x00020000);
+	BEGIN_RING(chan, kelvin, NV20TCL_SEPARATE_SPECULAR_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_MODEL_TWO_SIDE_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_ENABLED_LIGHTS, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_NORMALIZE_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_STIPPLE_PATTERN(0),
 					NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE);
 	for (i = 0; i < NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE; ++i) {
-		OUT_RING(0xffffffff);
+		OUT_RING(chan, 0xffffffff);
 	}
 
-	BEGIN_RING(kelvin, NV20TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
-	OUT_RING  (0);
-	OUT_RING  (0);		/* NV20TCL.POLYGON_OFFSET_LINE_ENABLE */
-	OUT_RING  (0);		/* NV20TCL.POLYGON_OFFSET_FILL_ENABLE */
-	BEGIN_RING(kelvin, NV20TCL_DEPTH_FUNC, 1);
-	OUT_RING  (NV20TCL_DEPTH_FUNC_LESS);
-	BEGIN_RING(kelvin, NV20TCL_DEPTH_WRITE_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_DEPTH_TEST_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_POLYGON_OFFSET_FACTOR, 2);
-	OUT_RINGf (0.0);
-	OUT_RINGf (0.0);	/* NV20TCL.POLYGON_OFFSET_UNITS */
-	BEGIN_RING(kelvin, NV20TCL_DEPTH_UNK17D8, 1);
-	OUT_RING  (1);
+	BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);		/* NV20TCL.POLYGON_OFFSET_LINE_ENABLE */
+	OUT_RING  (chan, 0);		/* NV20TCL.POLYGON_OFFSET_FILL_ENABLE */
+	BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_FUNC, 1);
+	OUT_RING  (chan, NV20TCL_DEPTH_FUNC_LESS);
+	BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_WRITE_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_TEST_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_OFFSET_FACTOR, 2);
+	OUT_RINGf (chan, 0.0);
+	OUT_RINGf (chan, 0.0);	/* NV20TCL.POLYGON_OFFSET_UNITS */
+	BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_UNK17D8, 1);
+	OUT_RING  (chan, 1);
 	if (!is_nv25tcl) {
-		BEGIN_RING(kelvin, 0x1d84, 1);
-		OUT_RING  (3);
+		BEGIN_RING(chan, kelvin, 0x1d84, 1);
+		OUT_RING  (chan, 3);
 	}
-	BEGIN_RING(kelvin, NV20TCL_POINT_SIZE, 1);
+	BEGIN_RING(chan, kelvin, NV20TCL_POINT_SIZE, 1);
 	if (!is_nv25tcl) {
-		OUT_RING  (8);
+		OUT_RING  (chan, 8);
 	} else {
-		OUT_RINGf (1.0);
+		OUT_RINGf (chan, 1.0);
 	}
 	if (!is_nv25tcl) {
-		BEGIN_RING(kelvin, NV20TCL_POINT_PARAMETERS_ENABLE, 2);
-		OUT_RING  (0);
-		OUT_RING  (0);		/* NV20TCL.POINT_SMOOTH_ENABLE */
+		BEGIN_RING(chan, kelvin, NV20TCL_POINT_PARAMETERS_ENABLE, 2);
+		OUT_RING  (chan, 0);
+		OUT_RING  (chan, 0);		/* NV20TCL.POINT_SMOOTH_ENABLE */
 	} else {
-		BEGIN_RING(kelvin, NV20TCL_POINT_PARAMETERS_ENABLE, 1);
-		OUT_RING  (0);
-		BEGIN_RING(kelvin, 0x0a1c, 1);
-		OUT_RING  (0x800);
+		BEGIN_RING(chan, kelvin, NV20TCL_POINT_PARAMETERS_ENABLE, 1);
+		OUT_RING  (chan, 0);
+		BEGIN_RING(chan, kelvin, 0x0a1c, 1);
+		OUT_RING  (chan, 0x800);
 	}
-	BEGIN_RING(kelvin, NV20TCL_LINE_WIDTH, 1);
-	OUT_RING  (8);
-	BEGIN_RING(kelvin, NV20TCL_LINE_SMOOTH_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_POLYGON_MODE_FRONT, 2);
-	OUT_RING  (NV20TCL_POLYGON_MODE_FRONT_FILL);
-	OUT_RING  (NV20TCL_POLYGON_MODE_BACK_FILL);
-	BEGIN_RING(kelvin, NV20TCL_CULL_FACE, 2);
-	OUT_RING  (NV20TCL_CULL_FACE_BACK);
-	OUT_RING  (NV20TCL_FRONT_FACE_CCW);
-	BEGIN_RING(kelvin, NV20TCL_POLYGON_SMOOTH_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_CULL_FACE_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_SHADE_MODEL, 1);
-	OUT_RING  (NV20TCL_SHADE_MODEL_SMOOTH);
-	BEGIN_RING(kelvin, NV20TCL_POLYGON_STIPPLE_ENABLE, 1);
-	OUT_RING  (0);
-	BEGIN_RING(kelvin, NV20TCL_TX_GEN_S(0), 4 * NV20TCL_TX_GEN_S__SIZE);
+	BEGIN_RING(chan, kelvin, NV20TCL_LINE_WIDTH, 1);
+	OUT_RING  (chan, 8);
+	BEGIN_RING(chan, kelvin, NV20TCL_LINE_SMOOTH_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_MODE_FRONT, 2);
+	OUT_RING  (chan, NV20TCL_POLYGON_MODE_FRONT_FILL);
+	OUT_RING  (chan, NV20TCL_POLYGON_MODE_BACK_FILL);
+	BEGIN_RING(chan, kelvin, NV20TCL_CULL_FACE, 2);
+	OUT_RING  (chan, NV20TCL_CULL_FACE_BACK);
+	OUT_RING  (chan, NV20TCL_FRONT_FACE_CCW);
+	BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_SMOOTH_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_CULL_FACE_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_SHADE_MODEL, 1);
+	OUT_RING  (chan, NV20TCL_SHADE_MODEL_SMOOTH);
+	BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_STIPPLE_ENABLE, 1);
+	OUT_RING  (chan, 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_TX_GEN_S(0), 4 * NV20TCL_TX_GEN_S__SIZE);
 	for (i=0; i < 4 * NV20TCL_TX_GEN_S__SIZE; ++i) {
-		OUT_RING(0);
+		OUT_RING(chan, 0);
 	}
-	BEGIN_RING(kelvin, NV20TCL_FOG_EQUATION_CONSTANT, 3);
-	OUT_RINGf (1.5);
-	OUT_RINGf (-0.090168);		/* NV20TCL.FOG_EQUATION_LINEAR */
-	OUT_RINGf (0.0);		/* NV20TCL.FOG_EQUATION_QUADRATIC */
-	BEGIN_RING(kelvin, NV20TCL_FOG_MODE, 2);
-	OUT_RING  (NV20TCL_FOG_MODE_EXP_2);
-	OUT_RING  (NV20TCL_FOG_COORD_DIST_COORD_FOG);
-	BEGIN_RING(kelvin, NV20TCL_FOG_ENABLE, 2);
-	OUT_RING  (0);
-	OUT_RING  (0);			/* NV20TCL.FOG_COLOR */
-	BEGIN_RING(kelvin, NV20TCL_ENGINE, 1);
-	OUT_RING  (NV20TCL_ENGINE_FIXED);
+	BEGIN_RING(chan, kelvin, NV20TCL_FOG_EQUATION_CONSTANT, 3);
+	OUT_RINGf (chan, 1.5);
+	OUT_RINGf (chan, -0.090168);		/* NV20TCL.FOG_EQUATION_LINEAR */
+	OUT_RINGf (chan, 0.0);		/* NV20TCL.FOG_EQUATION_QUADRATIC */
+	BEGIN_RING(chan, kelvin, NV20TCL_FOG_MODE, 2);
+	OUT_RING  (chan, NV20TCL_FOG_MODE_EXP_SIGNED);
+	OUT_RING  (chan, NV20TCL_FOG_COORD_FOG);
+	BEGIN_RING(chan, kelvin, NV20TCL_FOG_ENABLE, 2);
+	OUT_RING  (chan, 0);
+	OUT_RING  (chan, 0);			/* NV20TCL.FOG_COLOR */
+	BEGIN_RING(chan, kelvin, NV20TCL_ENGINE, 1);
+	OUT_RING  (chan, NV20TCL_ENGINE_FIXED);
 
 	for (i = 0; i < NV20TCL_TX_MATRIX_ENABLE__SIZE; ++i) {
-		BEGIN_RING(kelvin, NV20TCL_TX_MATRIX_ENABLE(i), 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, kelvin, NV20TCL_TX_MATRIX_ENABLE(i), 1);
+		OUT_RING  (chan, 0);
 	}
 
-	BEGIN_RING(kelvin, NV20TCL_VTX_ATTR_4F_X(1), 4 * 15);
-	OUT_RINGf(1.0); OUT_RINGf(0.0); OUT_RINGf(0.0); OUT_RINGf(1.0);
-	OUT_RINGf(0.0); OUT_RINGf(0.0); OUT_RINGf(1.0); OUT_RINGf(1.0);
-	OUT_RINGf(1.0); OUT_RINGf(1.0); OUT_RINGf(1.0); OUT_RINGf(1.0);
+	BEGIN_RING(chan, kelvin, NV20TCL_VTX_ATTR_4F_X(1), 4 * 15);
+	OUT_RINGf(chan, 1.0); OUT_RINGf(chan, 0.0); OUT_RINGf(chan, 0.0); OUT_RINGf(chan, 1.0);
+	OUT_RINGf(chan, 0.0); OUT_RINGf(chan, 0.0); OUT_RINGf(chan, 1.0); OUT_RINGf(chan, 1.0);
+	OUT_RINGf(chan, 1.0); OUT_RINGf(chan, 1.0); OUT_RINGf(chan, 1.0); OUT_RINGf(chan, 1.0);
 	for (i = 4; i < 16; ++i) {
-		OUT_RINGf(0.0); OUT_RINGf(0.0); OUT_RINGf(0.0);	OUT_RINGf(1.0);
+		OUT_RINGf(chan, 0.0);
+		OUT_RINGf(chan, 0.0);
+		OUT_RINGf(chan, 0.0);
+		OUT_RINGf(chan, 1.0);
 	}
 
-	BEGIN_RING(kelvin, NV20TCL_EDGEFLAG_ENABLE, 1);
-	OUT_RING  (1);
-	BEGIN_RING(kelvin, NV20TCL_COLOR_MASK, 1);
-	OUT_RING (0x00010101);
-	BEGIN_RING(kelvin, NV20TCL_CLEAR_VALUE, 1);
-	OUT_RING (0);
+	BEGIN_RING(chan, kelvin, NV20TCL_EDGEFLAG_ENABLE, 1);
+	OUT_RING  (chan, 1);
+	BEGIN_RING(chan, kelvin, NV20TCL_COLOR_MASK, 1);
+	OUT_RING (chan, 0x00010101);
+	BEGIN_RING(chan, kelvin, NV20TCL_CLEAR_VALUE, 1);
+	OUT_RING (chan, 0);
 
 	memset(projectionmatrix, 0, sizeof(projectionmatrix));
 	projectionmatrix[0*4+0] = 1.0;
 	projectionmatrix[1*4+1] = 1.0;
 	projectionmatrix[2*4+2] = 16777215.0;
 	projectionmatrix[3*4+3] = 1.0;
-	BEGIN_RING(kelvin, NV20TCL_PROJECTION_MATRIX(0), 16);
+	BEGIN_RING(chan, kelvin, NV20TCL_PROJECTION_MATRIX(0), 16);
 	for (i = 0; i < 16; i++) {
-		OUT_RINGf  (projectionmatrix[i]);
+		OUT_RINGf  (chan, projectionmatrix[i]);
 	}
 
-	BEGIN_RING(kelvin, NV20TCL_DEPTH_RANGE_NEAR, 2);
-	OUT_RINGf (0.0);
-	OUT_RINGf (16777216.0); /* [0, 1] scaled approx to [0, 2^24] */
+	BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_RANGE_NEAR, 2);
+	OUT_RINGf (chan, 0.0);
+	OUT_RINGf (chan, 16777216.0); /* [0, 1] scaled approx to [0, 2^24] */
 
-	BEGIN_RING(kelvin, NV20TCL_VIEWPORT_SCALE0_X, 4);
-	OUT_RINGf (0.0); /* x-offset, w/2 + 1.031250 */
-	OUT_RINGf (0.0); /* y-offset, h/2 + 0.030762 */
-	OUT_RINGf (0.0);
-	OUT_RINGf (16777215.0);
+	BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_TRANSLATE_X, 4);
+	OUT_RINGf (chan, 0.0); /* x-offset, w/2 + 1.031250 */
+	OUT_RINGf (chan, 0.0); /* y-offset, h/2 + 0.030762 */
+	OUT_RINGf (chan, 0.0);
+	OUT_RINGf (chan, 16777215.0);
 
-	BEGIN_RING(kelvin, NV20TCL_VIEWPORT_SCALE1_X, 4);
-	OUT_RINGf (0.0); /* no effect?, w/2 */
-	OUT_RINGf (0.0); /* no effect?, h/2 */
-	OUT_RINGf (16777215.0 * 0.5);
-	OUT_RINGf (65535.0);
+	BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_SCALE_X, 4);
+	OUT_RINGf (chan, 0.0); /* no effect?, w/2 */
+	OUT_RINGf (chan, 0.0); /* no effect?, h/2 */
+	OUT_RINGf (chan, 16777215.0 * 0.5);
+	OUT_RINGf (chan, 65535.0);
 
-	FIRE_RING (NULL);
-}
-
-static void
-nv20_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
-{
+	FIRE_RING (chan);
 }
 
 struct pipe_context *
@@ -399,7 +402,6 @@
 	nv20->pipe.winsys = ws;
 	nv20->pipe.screen = pscreen;
 	nv20->pipe.destroy = nv20_destroy;
-	nv20->pipe.set_edgeflags = nv20_set_edgeflags;
 	nv20->pipe.draw_arrays = nv20_draw_arrays;
 	nv20->pipe.draw_elements = nv20_draw_elements;
 	nv20->pipe.clear = nv20_clear;
diff --git a/src/gallium/drivers/nv20/nv20_context.h b/src/gallium/drivers/nv20/nv20_context.h
index a4eaa95..c7dfada 100644
--- a/src/gallium/drivers/nv20/nv20_context.h
+++ b/src/gallium/drivers/nv20/nv20_context.h
@@ -15,10 +15,6 @@
 #include "nouveau/nouveau_gldefs.h"
 #include "nouveau/nouveau_context.h"
 
-#define NOUVEAU_PUSH_CONTEXT(ctx)                                              \
-	struct nv20_screen *ctx = nv20->screen
-#include "nouveau/nouveau_push.h"
-
 #include "nv20_state.h"
 
 #define NOUVEAU_ERR(fmt, args...) \
@@ -143,9 +139,9 @@
 extern void nv20_state_tex_update(struct nv20_context *nv20);
 
 /* nv20_vbo.c */
-extern boolean nv20_draw_arrays(struct pipe_context *, unsigned mode,
+extern void nv20_draw_arrays(struct pipe_context *, unsigned mode,
 				unsigned start, unsigned count);
-extern boolean nv20_draw_elements( struct pipe_context *pipe,
+extern void nv20_draw_elements( struct pipe_context *pipe,
                     struct pipe_buffer *indexBuffer,
                     unsigned indexSize,
                     unsigned prim, unsigned start, unsigned count);
diff --git a/src/gallium/drivers/nv20/nv20_fragtex.c b/src/gallium/drivers/nv20/nv20_fragtex.c
index 495a7be..dedbec7 100644
--- a/src/gallium/drivers/nv20/nv20_fragtex.c
+++ b/src/gallium/drivers/nv20/nv20_fragtex.c
@@ -52,6 +52,9 @@
 	struct nv20_miptree *nv20mt = nv20->tex_miptree[unit];
 	struct pipe_texture *pt = &nv20mt->base;
 	struct nv20_texture_format *tf;
+	struct nv20_screen *screen = nv20->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *kelvin = screen->kelvin;
 	uint32_t txf, txs, txp;
 
 	tf = nv20_fragtex_format(pt->format);
@@ -62,9 +65,9 @@
 
 	txf  = tf->format << 8;
 	txf |= (pt->last_level + 1) << 16;
-	txf |= log2i(pt->width[0]) << 20;
-	txf |= log2i(pt->height[0]) << 24;
-	txf |= log2i(pt->depth[0]) << 28;
+	txf |= log2i(pt->width0) << 20;
+	txf |= log2i(pt->height0) << 24;
+	txf |= log2i(pt->depth0) << 28;
 	txf |= 8;
 
 	switch (pt->target) {
@@ -82,15 +85,15 @@
 		return;
 	}
 
-	BEGIN_RING(kelvin, NV10TCL_TX_OFFSET(unit), 8);
-	OUT_RELOCl(nv20mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
-	OUT_RELOCd(nv20mt->buffer,txf,NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
-	OUT_RING  (ps->wrap);
-	OUT_RING  (0x40000000); /* enable */
-	OUT_RING  (txs);
-	OUT_RING  (ps->filt | 0x2000 /* magic */);
-	OUT_RING  ((pt->width[0] << 16) | pt->height[0]);
-	OUT_RING  (ps->bcol);
+	BEGIN_RING(chan, kelvin, NV10TCL_TX_OFFSET(unit), 8);
+	OUT_RELOCl(chan, nouveau_bo(nv20mt->buffer), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+	OUT_RELOCd(chan, nouveau_bo(nv20mt->buffer),txf,NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
+	OUT_RING  (chan, ps->wrap);
+	OUT_RING  (chan, 0x40000000); /* enable */
+	OUT_RING  (chan, txs);
+	OUT_RING  (chan, ps->filt | 0x2000 /* magic */);
+	OUT_RING  (chan, (pt->width0 << 16) | pt->height0);
+	OUT_RING  (chan, ps->bcol);
 #endif
 }
 
@@ -99,6 +102,9 @@
 {
 #if 0
 	struct nv20_fragment_program *fp = nv20->fragprog.active;
+	struct nv20_screen *screen = nv20->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *kelvin = screen->kelvin;
 	unsigned samplers, unit;
 
 	samplers = nv20->fp_samplers & ~fp->samplers;
@@ -106,8 +112,8 @@
 		unit = ffs(samplers) - 1;
 		samplers &= ~(1 << unit);
 
-		BEGIN_RING(kelvin, NV10TCL_TX_ENABLE(unit), 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, kelvin, NV10TCL_TX_ENABLE(unit), 1);
+		OUT_RING  (chan, 0);
 	}
 
 	samplers = nv20->dirty_samplers & fp->samplers;
diff --git a/src/gallium/drivers/nv20/nv20_miptree.c b/src/gallium/drivers/nv20/nv20_miptree.c
index 185fbf5..8f7538e 100644
--- a/src/gallium/drivers/nv20/nv20_miptree.c
+++ b/src/gallium/drivers/nv20/nv20_miptree.c
@@ -1,15 +1,18 @@
 #include "pipe/p_state.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
 
 #include "nv20_context.h"
 #include "nv20_screen.h"
+#include "../nv04/nv04_surface_2d.h"
 
 static void
 nv20_miptree_layout(struct nv20_miptree *nv20mt)
 {
 	struct pipe_texture *pt = &nv20mt->base;
-	uint width = pt->width[0], height = pt->height[0];
+	uint width = pt->width0;
 	uint offset = 0;
 	int nr_faces, l, f;
 	uint wide_pitch = pt->tex_usage & (PIPE_TEXTURE_USAGE_SAMPLER |
@@ -25,21 +28,15 @@
 	}
 	
 	for (l = 0; l <= pt->last_level; l++) {
-		pt->width[l] = width;
-		pt->height[l] = height;
-		pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width);
-		pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height);
-
 		if (wide_pitch && (pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR))
-			nv20mt->level[l].pitch = align(pt->width[0] * pt->block.size, 64);
+			nv20mt->level[l].pitch = align(util_format_get_stride(pt->format, pt->width0), 64);
 		else
-			nv20mt->level[l].pitch = pt->width[l] * pt->block.size;
+			nv20mt->level[l].pitch = util_format_get_stride(pt->format, width);
 
 		nv20mt->level[l].image_offset =
 			CALLOC(nr_faces, sizeof(unsigned));
 
-		width  = MAX2(1, width  >> 1);
-		height = MAX2(1, height >> 1);
+		width  = u_minify(width, 1);
 	}
 
 	for (f = 0; f < nr_faces; f++) {
@@ -47,14 +44,14 @@
 			nv20mt->level[l].image_offset[f] = offset;
 
 			if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) &&
-			    pt->width[l + 1] > 1 && pt->height[l + 1] > 1)
-				offset += align(nv20mt->level[l].pitch * pt->height[l], 64);
+			    u_minify(pt->width0, l + 1) > 1 && u_minify(pt->height0, l + 1) > 1)
+				offset += align(nv20mt->level[l].pitch * u_minify(pt->height0, l), 64);
 			else
-				offset += nv20mt->level[l].pitch * pt->height[l];
+				offset += nv20mt->level[l].pitch * u_minify(pt->height0, l);
 		}
 
 		nv20mt->level[l].image_offset[f] = offset;
-		offset += nv20mt->level[l].pitch * pt->height[l];
+		offset += nv20mt->level[l].pitch * u_minify(pt->height0, l);
 	}
 
 	nv20mt->total_size = offset;
@@ -68,7 +65,7 @@
 
 	/* Only supports 2D, non-mipmapped textures for the moment */
 	if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 ||
-	    pt->depth[0] != 1)
+	    pt->depth0 != 1)
 		return NULL;
 
 	mt = CALLOC_STRUCT(nv20_miptree);
@@ -82,6 +79,7 @@
 	mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
 
 	pipe_buffer_reference(&mt->buffer, pb);
+	mt->bo = nouveau_bo(mt->buffer);
 	return &mt->base;
 }
 
@@ -100,8 +98,8 @@
 	mt->base.screen = screen;
 
 	/* Swizzled textures must be POT */
-	if (pt->width[0] & (pt->width[0] - 1) ||
-	    pt->height[0] & (pt->height[0] - 1))
+	if (pt->width0 & (pt->width0 - 1) ||
+	    pt->height0 & (pt->height0 - 1))
 		mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
 	else
 	if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY |
@@ -130,6 +128,12 @@
 	if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC)
 		buf_usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE;
 
+	/* apparently we can't render to swizzled surfaces smaller than 64 bytes, so make them linear.
+	 * If the user did not ask for a render target, they can still render to it, but it will cost them an extra copy.
+	 * This also happens for small mipmaps of large textures. */
+	if (pt->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET && util_format_get_stride(pt->format, pt->width0) < 64)
+		mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
+
 	nv20_miptree_layout(mt);
 
 	mt->buffer = screen->buffer_create(screen, 256, buf_usage, mt->total_size);
@@ -137,6 +141,7 @@
 		FREE(mt);
 		return NULL;
 	}
+	mt->bo = nouveau_bo(mt->buffer);
 	
 	return &mt->base;
 }
@@ -167,8 +172,8 @@
 		return NULL;
 	pipe_texture_reference(&ns->base.texture, pt);
 	ns->base.format = pt->format;
-	ns->base.width = pt->width[level];
-	ns->base.height = pt->height[level];
+	ns->base.width = u_minify(pt->width0, level);
+	ns->base.height = u_minify(pt->height0, level);
 	ns->base.usage = flags;
 	pipe_reference_init(&ns->base.reference, 1);
 	ns->base.face = face;
@@ -185,12 +190,27 @@
 		ns->base.offset = nv20mt->level[level].image_offset[0];
 	}
 
+	/* create a linear temporary that we can render into if necessary.
+	 * Note that ns->pitch is always a multiple of 64 for linear surfaces and swizzled surfaces are POT, so
+	 * ns->pitch & 63 is equivalent to (ns->pitch < 64 && swizzled)*/
+	if((ns->pitch & 63) && (ns->base.usage & (PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER)) == PIPE_BUFFER_USAGE_GPU_WRITE)
+		return &nv04_surface_wrap_for_render(screen, ((struct nv20_screen*)screen)->eng2d, ns)->base;
+
 	return &ns->base;
 }
 
 static void
 nv20_miptree_surface_destroy(struct pipe_surface *ps)
 {
+	struct nv04_surface* ns = (struct nv04_surface*)ps;
+	if(ns->backing)
+	{
+		struct nv20_screen* screen = (struct nv20_screen*)ps->texture->screen;
+		if(ns->backing->base.usage & PIPE_BUFFER_USAGE_GPU_WRITE)
+			screen->eng2d->copy(screen->eng2d, &ns->backing->base, 0, 0, ps, 0, 0, ns->base.width, ns->base.height);
+		nv20_miptree_surface_destroy(&ns->backing->base);
+	}
+	
 	pipe_texture_reference(&ps->texture, NULL);
 	FREE(ps);
 }
diff --git a/src/gallium/drivers/nv20/nv20_prim_vbuf.c b/src/gallium/drivers/nv20/nv20_prim_vbuf.c
index ddfcdb8..2e14567 100644
--- a/src/gallium/drivers/nv20/nv20_prim_vbuf.c
+++ b/src/gallium/drivers/nv20/nv20_prim_vbuf.c
@@ -81,12 +81,15 @@
 void nv20_vtxbuf_bind( struct nv20_context* nv20 )
 {
 #if 0
+	struct nv20_screen *screen = nv20->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *kelvin = screen->kelvin;
 	int i;
 	for(i = 0; i < NV20TCL_VTXBUF_ADDRESS__SIZE; i++) {
-		BEGIN_RING(kelvin, NV20TCL_VTXBUF_ADDRESS(i), 1);
-		OUT_RING(0/*nv20->vtxbuf*/);
-		BEGIN_RING(kelvin, NV20TCL_VTXFMT(i) ,1);
-		OUT_RING(0/*XXX*/);
+		BEGIN_RING(chan, kelvin, NV20TCL_VTXBUF_ADDRESS(i), 1);
+		OUT_RING(chan, 0/*nv20->vtxbuf*/);
+		BEGIN_RING(chan, kelvin, NV20TCL_VTXFMT(i) ,1);
+		OUT_RING(chan, 0/*XXX*/);
 	}
 #endif
 }
@@ -202,6 +205,9 @@
 static unsigned
 nv20__emit_format(struct nv20_context *nv20, enum attrib_emit type, int hwattr)
 {
+	struct nv20_screen *screen = nv20->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *kelvin = screen->kelvin;
 	uint32_t hwfmt = 0;
 	unsigned fields;
 
@@ -231,8 +237,8 @@
 		return 0;
 	}
 
-	BEGIN_RING(kelvin, NV20TCL_VTXFMT(hwattr), 1);
-	OUT_RING(hwfmt);
+	BEGIN_RING(chan, kelvin, NV20TCL_VTXFMT(hwattr), 1);
+	OUT_RING(chan, hwfmt);
 	return fields;
 }
 
@@ -262,6 +268,9 @@
 		uint nr_indices)
 {
 	struct nv20_context *nv20 = nv20_render->nv20;
+	struct nv20_screen *screen = nv20->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *kelvin = screen->kelvin;
 	struct vertex_info *vinfo = &nv20->vertex_info;
 	unsigned nr_fields;
 	int max_push;
@@ -270,29 +279,29 @@
 
 	nr_fields = nv20__emit_vertex_array_format(nv20);
 
-	BEGIN_RING(kelvin, NV20TCL_VERTEX_BEGIN_END, 1);
-	OUT_RING(nv20_render->hwprim);
+	BEGIN_RING(chan, kelvin, NV20TCL_VERTEX_BEGIN_END, 1);
+	OUT_RING(chan, nv20_render->hwprim);
 
 	max_push = 1200 / nr_fields;
 	while (nr_indices) {
 		int i;
 		int push = MIN2(nr_indices, max_push);
 
-		BEGIN_RING_NI(kelvin, NV20TCL_VERTEX_DATA, push * nr_fields);
+		BEGIN_RING_NI(chan, kelvin, NV20TCL_VERTEX_DATA, push * nr_fields);
 		for (i = 0; i < push; i++) {
 			/* XXX: fixme to handle other than floats? */
 			int f = nr_fields;
 			float *attrv = (float*)&data[indices[i] * vsz];
 			while (f-- > 0)
-				OUT_RINGf(*attrv++);
+				OUT_RINGf(chan, *attrv++);
 		}
 
 		nr_indices -= push;
 		indices += push;
 	}
 
-	BEGIN_RING(kelvin, NV20TCL_VERTEX_BEGIN_END, 1);
-	OUT_RING(NV20TCL_VERTEX_BEGIN_END_STOP);
+	BEGIN_RING(chan, kelvin, NV20TCL_VERTEX_BEGIN_END, 1);
+	OUT_RING(chan, NV20TCL_VERTEX_BEGIN_END_STOP);
 }
 
 static void
@@ -301,20 +310,23 @@
 		uint nr_indices)
 {
 	struct nv20_context *nv20 = nv20_render->nv20;
+	struct nv20_screen *screen = nv20->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *kelvin = screen->kelvin;
 	int push, i;
 
 	NOUVEAU_ERR("nv20__draw_pbuffer: this path is broken.\n");
 
-	BEGIN_RING(kelvin, NV10TCL_VERTEX_ARRAY_OFFSET_POS, 1);
-	OUT_RELOCl(nv20_render->pbuffer, 0,
+	BEGIN_RING(chan, kelvin, NV10TCL_VERTEX_ARRAY_OFFSET_POS, 1);
+	OUT_RELOCl(chan, nouveau_bo(nv20_render->pbuffer), 0,
 			NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
 
-	BEGIN_RING(kelvin, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1);
-	OUT_RING(nv20_render->hwprim);
+	BEGIN_RING(chan, kelvin, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1);
+	OUT_RING(chan, nv20_render->hwprim);
 
 	if (nr_indices & 1) {
-		BEGIN_RING(kelvin, NV10TCL_VB_ELEMENT_U32, 1);
-		OUT_RING  (indices[0]);
+		BEGIN_RING(chan, kelvin, NV10TCL_VB_ELEMENT_U32, 1);
+		OUT_RING  (chan, indices[0]);
 		indices++; nr_indices--;
 	}
 
@@ -322,16 +334,16 @@
 		// XXX too big/small ? check the size
 		push = MIN2(nr_indices, 1200 * 2);
 
-		BEGIN_RING_NI(kelvin, NV10TCL_VB_ELEMENT_U16, push >> 1);
+		BEGIN_RING_NI(chan, kelvin, NV10TCL_VB_ELEMENT_U16, push >> 1);
 		for (i = 0; i < push; i+=2)
-			OUT_RING((indices[i+1] << 16) | indices[i]);
+			OUT_RING(chan, (indices[i+1] << 16) | indices[i]);
 
 		nr_indices -= push;
 		indices  += push;
 	}
 
-	BEGIN_RING(kelvin, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1);
-	OUT_RING  (0);
+	BEGIN_RING(chan, kelvin, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1);
+	OUT_RING  (chan, 0);
 }
 
 static void
diff --git a/src/gallium/drivers/nv20/nv20_screen.c b/src/gallium/drivers/nv20/nv20_screen.c
index 4eeacd1..d091335 100644
--- a/src/gallium/drivers/nv20/nv20_screen.c
+++ b/src/gallium/drivers/nv20/nv20_screen.c
@@ -115,6 +115,9 @@
 
 	nouveau_notifier_free(&screen->sync);
 	nouveau_grobj_free(&screen->kelvin);
+	nv04_surface_2d_takedown(&screen->eng2d);
+
+	nouveau_screen_fini(&screen->base);
 
 	FREE(pscreen);
 }
@@ -173,7 +176,6 @@
 		NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
 		return FALSE;
 	}
-	BIND_RING(chan, screen->kelvin, 7);
 
 	/* 2D engine setup */
 	screen->eng2d = nv04_surface_2d_init(&screen->base);
diff --git a/src/gallium/drivers/nv20/nv20_state.c b/src/gallium/drivers/nv20/nv20_state.c
index ed40849..3a82e63 100644
--- a/src/gallium/drivers/nv20/nv20_state.c
+++ b/src/gallium/drivers/nv20/nv20_state.c
@@ -546,9 +546,9 @@
 	nv20->pipe.delete_blend_state = nv20_blend_state_delete;
 
 	nv20->pipe.create_sampler_state = nv20_sampler_state_create;
-	nv20->pipe.bind_sampler_states = nv20_sampler_state_bind;
+	nv20->pipe.bind_fragment_sampler_states = nv20_sampler_state_bind;
 	nv20->pipe.delete_sampler_state = nv20_sampler_state_delete;
-	nv20->pipe.set_sampler_textures = nv20_set_sampler_texture;
+	nv20->pipe.set_fragment_sampler_textures = nv20_set_sampler_texture;
 
 	nv20->pipe.create_rasterizer_state = nv20_rasterizer_state_create;
 	nv20->pipe.bind_rasterizer_state = nv20_rasterizer_state_bind;
diff --git a/src/gallium/drivers/nv20/nv20_state.h b/src/gallium/drivers/nv20/nv20_state.h
index 34f402f..dde4106 100644
--- a/src/gallium/drivers/nv20/nv20_state.h
+++ b/src/gallium/drivers/nv20/nv20_state.h
@@ -126,6 +126,7 @@
 
 struct nv20_miptree {
 	struct pipe_texture base;
+	struct nouveau_bo *bo;
 
 	struct pipe_buffer *buffer;
 	uint total_size;
diff --git a/src/gallium/drivers/nv20/nv20_state_emit.c b/src/gallium/drivers/nv20/nv20_state_emit.c
index 0122b1c..6bbd1fd 100644
--- a/src/gallium/drivers/nv20/nv20_state_emit.c
+++ b/src/gallium/drivers/nv20/nv20_state_emit.c
@@ -5,27 +5,34 @@
 static void nv20_state_emit_blend(struct nv20_context* nv20)
 {
 	struct nv20_blend_state *b = nv20->blend;
+	struct nv20_screen *screen = nv20->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *kelvin = screen->kelvin;
 
-	BEGIN_RING(kelvin, NV20TCL_DITHER_ENABLE, 1);
-	OUT_RING  (b->d_enable);
+	BEGIN_RING(chan, kelvin, NV20TCL_DITHER_ENABLE, 1);
+	OUT_RING  (chan, b->d_enable);
 
-	BEGIN_RING(kelvin, NV20TCL_BLEND_FUNC_ENABLE, 1);
-	OUT_RING  (b->b_enable);
+	BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_ENABLE, 1);
+	OUT_RING  (chan, b->b_enable);
 
-	BEGIN_RING(kelvin, NV20TCL_BLEND_FUNC_SRC, 2);
-	OUT_RING  (b->b_srcfunc);
-	OUT_RING  (b->b_dstfunc);
+	BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_SRC, 2);
+	OUT_RING  (chan, b->b_srcfunc);
+	OUT_RING  (chan, b->b_dstfunc);
 
-	BEGIN_RING(kelvin, NV20TCL_COLOR_MASK, 1);
-	OUT_RING  (b->c_mask);
+	BEGIN_RING(chan, kelvin, NV20TCL_COLOR_MASK, 1);
+	OUT_RING  (chan, b->c_mask);
 }
 
 static void nv20_state_emit_blend_color(struct nv20_context* nv20)
 {
 	struct pipe_blend_color *c = nv20->blend_color;
+	struct nv20_screen *screen = nv20->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *kelvin = screen->kelvin;
 
-	BEGIN_RING(kelvin, NV20TCL_BLEND_COLOR, 1);
-	OUT_RING  ((float_to_ubyte(c->color[3]) << 24)|
+	BEGIN_RING(chan, kelvin, NV20TCL_BLEND_COLOR, 1);
+	OUT_RING  (chan,
+		   (float_to_ubyte(c->color[3]) << 24)|
 		   (float_to_ubyte(c->color[0]) << 16)|
 		   (float_to_ubyte(c->color[1]) << 8) |
 		   (float_to_ubyte(c->color[2]) << 0));
@@ -34,63 +41,69 @@
 static void nv20_state_emit_rast(struct nv20_context* nv20)
 {
 	struct nv20_rasterizer_state *r = nv20->rast;
+	struct nv20_screen *screen = nv20->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *kelvin = screen->kelvin;
 
-	BEGIN_RING(kelvin, NV20TCL_SHADE_MODEL, 2);
-	OUT_RING  (r->shade_model);
-	OUT_RING  (r->line_width);
+	BEGIN_RING(chan, kelvin, NV20TCL_SHADE_MODEL, 2);
+	OUT_RING  (chan, r->shade_model);
+	OUT_RING  (chan, r->line_width);
 
 
-	BEGIN_RING(kelvin, NV20TCL_POINT_SIZE, 1);
-	OUT_RING  (r->point_size);
+	BEGIN_RING(chan, kelvin, NV20TCL_POINT_SIZE, 1);
+	OUT_RING  (chan, r->point_size);
 
-	BEGIN_RING(kelvin, NV20TCL_POLYGON_MODE_FRONT, 2);
-	OUT_RING  (r->poly_mode_front);
-	OUT_RING  (r->poly_mode_back);
+	BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_MODE_FRONT, 2);
+	OUT_RING  (chan, r->poly_mode_front);
+	OUT_RING  (chan, r->poly_mode_back);
 
 
-	BEGIN_RING(kelvin, NV20TCL_CULL_FACE, 2);
-	OUT_RING  (r->cull_face);
-	OUT_RING  (r->front_face);
+	BEGIN_RING(chan, kelvin, NV20TCL_CULL_FACE, 2);
+	OUT_RING  (chan, r->cull_face);
+	OUT_RING  (chan, r->front_face);
 
-	BEGIN_RING(kelvin, NV20TCL_LINE_SMOOTH_ENABLE, 2);
-	OUT_RING  (r->line_smooth_en);
-	OUT_RING  (r->poly_smooth_en);
+	BEGIN_RING(chan, kelvin, NV20TCL_LINE_SMOOTH_ENABLE, 2);
+	OUT_RING  (chan, r->line_smooth_en);
+	OUT_RING  (chan, r->poly_smooth_en);
 
-	BEGIN_RING(kelvin, NV20TCL_CULL_FACE_ENABLE, 1);
-	OUT_RING  (r->cull_face_en);
+	BEGIN_RING(chan, kelvin, NV20TCL_CULL_FACE_ENABLE, 1);
+	OUT_RING  (chan, r->cull_face_en);
 }
 
 static void nv20_state_emit_dsa(struct nv20_context* nv20)
 {
 	struct nv20_depth_stencil_alpha_state *d = nv20->dsa;
+	struct nv20_screen *screen = nv20->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *kelvin = screen->kelvin;
 
-	BEGIN_RING(kelvin, NV20TCL_DEPTH_FUNC, 1);
-	OUT_RING (d->depth.func);
+	BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_FUNC, 1);
+	OUT_RING (chan, d->depth.func);
 
-	BEGIN_RING(kelvin, NV20TCL_DEPTH_WRITE_ENABLE, 1);
-	OUT_RING (d->depth.write_enable);
+	BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_WRITE_ENABLE, 1);
+	OUT_RING (chan, d->depth.write_enable);
 
-	BEGIN_RING(kelvin, NV20TCL_DEPTH_TEST_ENABLE, 1);
-	OUT_RING (d->depth.test_enable);
+	BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_TEST_ENABLE, 1);
+	OUT_RING (chan, d->depth.test_enable);
 
-	BEGIN_RING(kelvin, NV20TCL_DEPTH_UNK17D8, 1);
-	OUT_RING (1);
+	BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_UNK17D8, 1);
+	OUT_RING (chan, 1);
 
 #if 0
-	BEGIN_RING(kelvin, NV20TCL_STENCIL_ENABLE, 1);
-	OUT_RING (d->stencil.enable);
-	BEGIN_RING(kelvin, NV20TCL_STENCIL_MASK, 7);
-	OUT_RINGp ((uint32_t *)&(d->stencil.wmask), 7);
+	BEGIN_RING(chan, kelvin, NV20TCL_STENCIL_ENABLE, 1);
+	OUT_RING (chan, d->stencil.enable);
+	BEGIN_RING(chan, kelvin, NV20TCL_STENCIL_MASK, 7);
+	OUT_RINGp (chan, (uint32_t *)&(d->stencil.wmask), 7);
 #endif
 
-	BEGIN_RING(kelvin, NV20TCL_ALPHA_FUNC_ENABLE, 1);
-	OUT_RING (d->alpha.enabled);
+	BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_ENABLE, 1);
+	OUT_RING (chan, d->alpha.enabled);
 
-	BEGIN_RING(kelvin, NV20TCL_ALPHA_FUNC_FUNC, 1);
-	OUT_RING (d->alpha.func);
+	BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_FUNC, 1);
+	OUT_RING (chan, d->alpha.func);
 
-	BEGIN_RING(kelvin, NV20TCL_ALPHA_FUNC_REF, 1);
-	OUT_RING (d->alpha.ref);
+	BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_REF, 1);
+	OUT_RING (chan, d->alpha.ref);
 }
 
 static void nv20_state_emit_viewport(struct nv20_context* nv20)
@@ -101,9 +114,13 @@
 {
 	/* NV20TCL_SCISSOR_* is probably a software method */
 /*	struct pipe_scissor_state *s = nv20->scissor;
-	BEGIN_RING(kelvin, NV20TCL_SCISSOR_HORIZ, 2);
-	OUT_RING  (((s->maxx - s->minx) << 16) | s->minx);
-	OUT_RING  (((s->maxy - s->miny) << 16) | s->miny);*/
+	struct nv20_screen *screen = nv20->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *kelvin = screen->kelvin;
+
+	BEGIN_RING(chan, kelvin, NV20TCL_SCISSOR_HORIZ, 2);
+	OUT_RING  (chan, ((s->maxx - s->minx) << 16) | s->minx);
+	OUT_RING  (chan, ((s->maxy - s->miny) << 16) | s->miny);*/
 }
 
 static void nv20_state_emit_framebuffer(struct nv20_context* nv20)
@@ -113,6 +130,9 @@
 	uint32_t rt_format, w, h;
 	int colour_format = 0, zeta_format = 0;
 	struct nv20_miptree *nv20mt = 0;
+	struct nv20_screen *screen = nv20->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *kelvin = screen->kelvin;
 
 	w = fb->cbufs[0]->width;
 	h = fb->cbufs[0]->height;
@@ -150,11 +170,11 @@
 	}
 
 	if (zeta) {
-		BEGIN_RING(kelvin, NV20TCL_RT_PITCH, 1);
-		OUT_RING  (rt->pitch | (zeta->pitch << 16));
+		BEGIN_RING(chan, kelvin, NV20TCL_RT_PITCH, 1);
+		OUT_RING  (chan, rt->pitch | (zeta->pitch << 16));
 	} else {
-		BEGIN_RING(kelvin, NV20TCL_RT_PITCH, 1);
-		OUT_RING  (rt->pitch | (rt->pitch << 16));
+		BEGIN_RING(chan, kelvin, NV20TCL_RT_PITCH, 1);
+		OUT_RING  (chan, rt->pitch | (rt->pitch << 16));
 	}
 
 	nv20mt = (struct nv20_miptree *)rt->base.texture;
@@ -166,13 +186,13 @@
 		nv20->zeta = nv20mt->buffer;
 	}
 
-	BEGIN_RING(kelvin, NV20TCL_RT_HORIZ, 3);
-	OUT_RING  ((w << 16) | 0);
-	OUT_RING  ((h << 16) | 0); /*NV20TCL_RT_VERT */
-	OUT_RING  (rt_format); /* NV20TCL_RT_FORMAT */
-	BEGIN_RING(kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 2);
-	OUT_RING  (((w - 1) << 16) | 0);
-	OUT_RING  (((h - 1) << 16) | 0);
+	BEGIN_RING(chan, kelvin, NV20TCL_RT_HORIZ, 3);
+	OUT_RING  (chan, (w << 16) | 0);
+	OUT_RING  (chan, (h << 16) | 0); /*NV20TCL_RT_VERT */
+	OUT_RING  (chan, rt_format); /* NV20TCL_RT_FORMAT */
+	BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 2);
+	OUT_RING  (chan, ((w - 1) << 16) | 0);
+	OUT_RING  (chan, ((h - 1) << 16) | 0);
 }
 
 static void nv20_vertex_layout(struct nv20_context *nv20)
@@ -228,7 +248,7 @@
 	}
 
 	/* always do position */ {
-		src = draw_find_vs_output(dc, TGSI_SEMANTIC_POSITION, 0);
+		src = draw_find_shader_output(dc, TGSI_SEMANTIC_POSITION, 0);
 		draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR, src);
 		vinfo->hwfmt[0] |= (1 << 0);
 	}
@@ -237,19 +257,19 @@
 	for (i = 4; i < 6; i++) {
 		if (!generics[i])
 			continue;
-		src = draw_find_vs_output(dc, TGSI_SEMANTIC_GENERIC, i);
+		src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i);
 		draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
 		vinfo->hwfmt[0] |= (1 << (i - 3));
 	}
 
 	if (colors[0]) {
-		src = draw_find_vs_output(dc, TGSI_SEMANTIC_COLOR, 0);
+		src = draw_find_shader_output(dc, TGSI_SEMANTIC_COLOR, 0);
 		draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
 		vinfo->hwfmt[0] |= (1 << 3);
 	}
 
 	if (colors[1]) {
-		src = draw_find_vs_output(dc, TGSI_SEMANTIC_COLOR, 1);
+		src = draw_find_shader_output(dc, TGSI_SEMANTIC_COLOR, 1);
 		draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
 		vinfo->hwfmt[0] |= (1 << 4);
 	}
@@ -258,7 +278,7 @@
 	for (i = 6; i < 10; i++) {
 		if (!generics[i])
 			continue;
-		src = draw_find_vs_output(dc, TGSI_SEMANTIC_GENERIC, i);
+		src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i);
 		draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
 		vinfo->hwfmt[0] |= (1 << (i - 1));
 	}
@@ -267,7 +287,7 @@
 	for (i = 0; i < 4; i++) {
 		if (!generics[i])
 			continue;
-		src = draw_find_vs_output(dc, TGSI_SEMANTIC_GENERIC, i);
+		src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i);
 		draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
 		vinfo->hwfmt[0] |= (1 << (i + 9));
 	}
@@ -276,13 +296,13 @@
 	for (i = 10; i < 12; i++) {
 		if (!generics[i])
 			continue;
-		src = draw_find_vs_output(dc, TGSI_SEMANTIC_GENERIC, i);
+		src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i);
 		draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
 		vinfo->hwfmt[0] |= (1 << (i + 3));
 	}
 
 	if (fog) {
-		src = draw_find_vs_output(dc, TGSI_SEMANTIC_FOG, 0);
+		src = draw_find_shader_output(dc, TGSI_SEMANTIC_FOG, 0);
 		draw_emit_vertex_attr(vinfo, EMIT_1F, INTERP_PERSPECTIVE, src);
 		vinfo->hwfmt[0] |= (1 << 15);
 	}
@@ -293,6 +313,10 @@
 void
 nv20_emit_hw_state(struct nv20_context *nv20)
 {
+	struct nv20_screen *screen = nv20->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *kelvin = screen->kelvin;
+	struct nouveau_bo *rt_bo;
 	int i;
 
 	if (nv20->dirty & NV20_NEW_VERTPROG) {
@@ -361,36 +385,39 @@
 	 */
 
 	/* Render target */
-	BEGIN_RING(kelvin, NV20TCL_DMA_COLOR, 1);
-	OUT_RELOCo(nv20->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-	BEGIN_RING(kelvin, NV20TCL_COLOR_OFFSET, 1);
-	OUT_RELOCl(nv20->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+	rt_bo = nouveau_bo(nv20->rt[0]);
+	BEGIN_RING(chan, kelvin, NV20TCL_DMA_COLOR, 1);
+	OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+	BEGIN_RING(chan, kelvin, NV20TCL_COLOR_OFFSET, 1);
+	OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
 
 	if (nv20->zeta) {
-		BEGIN_RING(kelvin, NV20TCL_DMA_ZETA, 1);
-		OUT_RELOCo(nv20->zeta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-		BEGIN_RING(kelvin, NV20TCL_ZETA_OFFSET, 1);
-		OUT_RELOCl(nv20->zeta, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+		struct nouveau_bo *zeta_bo = nouveau_bo(nv20->zeta);
+		BEGIN_RING(chan, kelvin, NV20TCL_DMA_ZETA, 1);
+		OUT_RELOCo(chan, zeta_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+		BEGIN_RING(chan, kelvin, NV20TCL_ZETA_OFFSET, 1);
+		OUT_RELOCl(chan, zeta_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
 		/* XXX for when we allocate LMA on nv17 */
-/*		BEGIN_RING(kelvin, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1);
-		OUT_RELOCl(nv20->zeta + lma_offset);*/
+/*		BEGIN_RING(chan, kelvin, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1);
+		OUT_RELOCl(chan, nouveau_bo(nv20->zeta + lma_offset));*/
 	}
 
 	/* Vertex buffer */
-	BEGIN_RING(kelvin, NV20TCL_DMA_VTXBUF0, 1);
-	OUT_RELOCo(nv20->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-	BEGIN_RING(kelvin, NV20TCL_COLOR_OFFSET, 1);
-	OUT_RELOCl(nv20->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+	BEGIN_RING(chan, kelvin, NV20TCL_DMA_VTXBUF0, 1);
+	OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+	BEGIN_RING(chan, kelvin, NV20TCL_COLOR_OFFSET, 1);
+	OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
 
 	/* Texture images */
 	for (i = 0; i < 2; i++) {
 		if (!(nv20->fp_samplers & (1 << i)))
 			continue;
-		BEGIN_RING(kelvin, NV20TCL_TX_OFFSET(i), 1);
-		OUT_RELOCl(nv20->tex[i].buffer, 0, NOUVEAU_BO_VRAM |
+		struct nouveau_bo *bo = nouveau_bo(nv20->tex[i].buffer);
+		BEGIN_RING(chan, kelvin, NV20TCL_TX_OFFSET(i), 1);
+		OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM |
 			   NOUVEAU_BO_GART | NOUVEAU_BO_RD);
-		BEGIN_RING(kelvin, NV20TCL_TX_FORMAT(i), 1);
-		OUT_RELOCd(nv20->tex[i].buffer, nv20->tex[i].format,
+		BEGIN_RING(chan, kelvin, NV20TCL_TX_FORMAT(i), 1);
+		OUT_RELOCd(chan, bo, nv20->tex[i].format,
 			   NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
 			   NOUVEAU_BO_OR, NV20TCL_TX_FORMAT_DMA0,
 			   NV20TCL_TX_FORMAT_DMA1);
diff --git a/src/gallium/drivers/nv20/nv20_transfer.c b/src/gallium/drivers/nv20/nv20_transfer.c
index 81b4f1a..699773e 100644
--- a/src/gallium/drivers/nv20/nv20_transfer.c
+++ b/src/gallium/drivers/nv20/nv20_transfer.c
@@ -1,7 +1,9 @@
 #include <pipe/p_state.h>
 #include <pipe/p_defines.h>
 #include <pipe/p_inlines.h>
+#include <util/u_format.h>
 #include <util/u_memory.h>
+#include <util/u_math.h>
 #include <nouveau/nouveau_winsys.h>
 #include "nv20_context.h"
 #include "nv20_screen.h"
@@ -10,22 +12,19 @@
 struct nv20_transfer {
 	struct pipe_transfer base;
 	struct pipe_surface *surface;
-	bool direct;
+	boolean direct;
 };
 
 static void
-nv20_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
+nv20_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height,
                              struct pipe_texture *template)
 {
 	memset(template, 0, sizeof(struct pipe_texture));
 	template->target = pt->target;
 	template->format = pt->format;
-	template->width[0] = pt->width[level];
-	template->height[0] = pt->height[level];
-	template->depth[0] = 1;
-	template->block = pt->block;
-	template->nblocksx[0] = pt->nblocksx[level];
-	template->nblocksy[0] = pt->nblocksx[level];
+	template->width0 = width;
+	template->height0 = height;
+	template->depth0 = 1;
 	template->last_level = 0;
 	template->nr_samples = pt->nr_samples;
 
@@ -48,14 +47,10 @@
 		return NULL;
 
 	pipe_texture_reference(&tx->base.texture, pt);
-	tx->base.format = pt->format;
 	tx->base.x = x;
 	tx->base.y = y;
 	tx->base.width = w;
 	tx->base.height = h;
-	tx->base.block = pt->block;
-	tx->base.nblocksx = pt->nblocksx[level];
-	tx->base.nblocksy = pt->nblocksy[level];
 	tx->base.stride = mt->level[level].pitch;
 	tx->base.usage = usage;
 	tx->base.face = face;
@@ -76,7 +71,7 @@
 
 	tx->direct = false;
 
-	nv20_compatible_transfer_tex(pt, level, &tx_tex_template);
+	nv20_compatible_transfer_tex(pt, w, h, &tx_tex_template);
 
 	tx_tex = pscreen->texture_create(pscreen, &tx_tex_template);
 	if (!tx_tex)
@@ -85,6 +80,8 @@
 		return NULL;
 	}
 
+	tx->base.stride = ((struct nv20_miptree*)tx_tex)->level[0].pitch;
+
 	tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
 	                                       face, level, zslice,
 	                                       pipe_transfer_buffer_flags(&tx->base));
@@ -110,8 +107,8 @@
 		/* TODO: Check if SIFM can un-swizzle */
 		nvscreen->eng2d->copy(nvscreen->eng2d,
 		                      tx->surface, 0, 0,
-		                      src, 0, 0,
-		                      src->width, src->height);
+		                      src, x, y,
+		                      w, h);
 
 		pipe_surface_reference(&src, NULL);
 	}
@@ -131,13 +128,13 @@
 
 		dst = pscreen->get_tex_surface(pscreen, ptx->texture,
 	                                       ptx->face, ptx->level, ptx->zslice,
-	                                       PIPE_BUFFER_USAGE_GPU_WRITE);
+	                                       PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER);
 
 		/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
 		nvscreen->eng2d->copy(nvscreen->eng2d,
-		                      dst, 0, 0,
+		                      dst, tx->base.x, tx->base.y,
 		                      tx->surface, 0, 0,
-		                      dst->width, dst->height);
+		                      tx->base.width, tx->base.height);
 
 		pipe_surface_reference(&dst, NULL);
 	}
@@ -156,8 +153,10 @@
 	void *map = pipe_buffer_map(pscreen, mt->buffer,
 	                            pipe_transfer_buffer_flags(ptx));
 
-	return map + ns->base.offset +
-	       ptx->y * ns->pitch + ptx->x * ptx->block.size;
+	if(!tx->direct)
+		return map + ns->base.offset;
+	else
+		return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format);
 }
 
 static void
diff --git a/src/gallium/drivers/nv20/nv20_vbo.c b/src/gallium/drivers/nv20/nv20_vbo.c
index 84d7db6..52991a0 100644
--- a/src/gallium/drivers/nv20/nv20_vbo.c
+++ b/src/gallium/drivers/nv20/nv20_vbo.c
@@ -9,7 +9,7 @@
 #include "nouveau/nouveau_channel.h"
 #include "nouveau/nouveau_pushbuf.h"
 
-boolean nv20_draw_elements( struct pipe_context *pipe,
+void nv20_draw_elements( struct pipe_context *pipe,
                     struct pipe_buffer *indexBuffer,
                     unsigned indexSize,
                     unsigned prim, unsigned start, unsigned count)
@@ -45,7 +45,7 @@
 		draw_set_mapped_element_buffer(draw, 0, NULL);
 	}
 
-	draw_set_mapped_constant_buffer(draw,
+	draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX,
 					nv20->constbuf[PIPE_SHADER_VERTEX],
 					nv20->constbuf_nr[PIPE_SHADER_VERTEX]);
 
@@ -67,13 +67,12 @@
 	}
 
 	draw_flush(nv20->draw);
-	return TRUE;
 }
 
-boolean nv20_draw_arrays( struct pipe_context *pipe,
+void nv20_draw_arrays( struct pipe_context *pipe,
 				 unsigned prim, unsigned start, unsigned count)
 {
-	return nv20_draw_elements(pipe, NULL, 0, prim, start, count);
+	nv20_draw_elements(pipe, NULL, 0, prim, start, count);
 }
 
 
diff --git a/src/gallium/drivers/nv20/nv20_vertprog.c b/src/gallium/drivers/nv20/nv20_vertprog.c
index 388245e..7886c2a 100644
--- a/src/gallium/drivers/nv20/nv20_vertprog.c
+++ b/src/gallium/drivers/nv20/nv20_vertprog.c
@@ -253,32 +253,32 @@
 tgsi_src(struct nv20_vpc *vpc, const struct tgsi_full_src_register *fsrc) {
 	struct nv20_sreg src;
 
-	switch (fsrc->SrcRegister.File) {
+	switch (fsrc->Register.File) {
 	case TGSI_FILE_INPUT:
-		src = nv20_sr(NV30SR_INPUT, fsrc->SrcRegister.Index);
+		src = nv20_sr(NV30SR_INPUT, fsrc->Register.Index);
 		break;
 	case TGSI_FILE_CONSTANT:
-		src = constant(vpc, fsrc->SrcRegister.Index, 0, 0, 0, 0);
+		src = constant(vpc, fsrc->Register.Index, 0, 0, 0, 0);
 		break;
 	case TGSI_FILE_IMMEDIATE:
-		src = vpc->imm[fsrc->SrcRegister.Index];
+		src = vpc->imm[fsrc->Register.Index];
 		break;
 	case TGSI_FILE_TEMPORARY:
-		if (vpc->high_temp < fsrc->SrcRegister.Index)
-			vpc->high_temp = fsrc->SrcRegister.Index;
-		src = nv20_sr(NV30SR_TEMP, fsrc->SrcRegister.Index);
+		if (vpc->high_temp < fsrc->Register.Index)
+			vpc->high_temp = fsrc->Register.Index;
+		src = nv20_sr(NV30SR_TEMP, fsrc->Register.Index);
 		break;
 	default:
 		NOUVEAU_ERR("bad src file\n");
 		break;
 	}
 
-	src.abs = fsrc->SrcRegisterExtMod.Absolute;
-	src.negate = fsrc->SrcRegister.Negate;
-	src.swz[0] = fsrc->SrcRegister.SwizzleX;
-	src.swz[1] = fsrc->SrcRegister.SwizzleY;
-	src.swz[2] = fsrc->SrcRegister.SwizzleZ;
-	src.swz[3] = fsrc->SrcRegister.SwizzleW;
+	src.abs = fsrc->Register.Absolute;
+	src.negate = fsrc->Register.Negate;
+	src.swz[0] = fsrc->Register.SwizzleX;
+	src.swz[1] = fsrc->Register.SwizzleY;
+	src.swz[2] = fsrc->Register.SwizzleZ;
+	src.swz[3] = fsrc->Register.SwizzleW;
 	return src;
 }
 
@@ -286,14 +286,14 @@
 tgsi_dst(struct nv20_vpc *vpc, const struct tgsi_full_dst_register *fdst) {
 	struct nv20_sreg dst;
 
-	switch (fdst->DstRegister.File) {
+	switch (fdst->Register.File) {
 	case TGSI_FILE_OUTPUT:
 		dst = nv20_sr(NV30SR_OUTPUT,
-			      vpc->output_map[fdst->DstRegister.Index]);
+			      vpc->output_map[fdst->Register.Index]);
 
 		break;
 	case TGSI_FILE_TEMPORARY:
-		dst = nv20_sr(NV30SR_TEMP, fdst->DstRegister.Index);
+		dst = nv20_sr(NV30SR_TEMP, fdst->Register.Index);
 		if (vpc->high_temp < dst.index)
 			vpc->high_temp = dst.index;
 		break;
@@ -334,8 +334,8 @@
 	for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
 		const struct tgsi_full_src_register *fsrc;
 
-		fsrc = &finst->FullSrcRegisters[i];
-		if (fsrc->SrcRegister.File == TGSI_FILE_TEMPORARY) {
+		fsrc = &finst->Src[i];
+		if (fsrc->Register.File == TGSI_FILE_TEMPORARY) {
 			src[i] = tgsi_src(vpc, fsrc);
 		}
 	}
@@ -343,11 +343,11 @@
 	for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
 		const struct tgsi_full_src_register *fsrc;
 
-		fsrc = &finst->FullSrcRegisters[i];
-		switch (fsrc->SrcRegister.File) {
+		fsrc = &finst->Src[i];
+		switch (fsrc->Register.File) {
 		case TGSI_FILE_INPUT:
-			if (ai == -1 || ai == fsrc->SrcRegister.Index) {
-				ai = fsrc->SrcRegister.Index;
+			if (ai == -1 || ai == fsrc->Register.Index) {
+				ai = fsrc->Register.Index;
 				src[i] = tgsi_src(vpc, fsrc);
 			} else {
 				src[i] = temp(vpc);
@@ -360,8 +360,8 @@
 		 */
 		case TGSI_FILE_CONSTANT:
 		case TGSI_FILE_IMMEDIATE:
-			if (ci == -1 || ci == fsrc->SrcRegister.Index) {
-				ci = fsrc->SrcRegister.Index;
+			if (ci == -1 || ci == fsrc->Register.Index) {
+				ci = fsrc->Register.Index;
 				src[i] = tgsi_src(vpc, fsrc);
 			} else {
 				src[i] = temp(vpc);
@@ -378,8 +378,8 @@
 		}
 	}
 
-	dst  = tgsi_dst(vpc, &finst->FullDstRegisters[0]);
-	mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask);
+	dst  = tgsi_dst(vpc, &finst->Dst[0]);
+	mask = tgsi_mask(finst->Dst[0].Register.WriteMask);
 
 	switch (finst->Instruction.Opcode) {
 	case TGSI_OPCODE_ABS:
@@ -490,15 +490,15 @@
 {
 	int hw;
 
-	switch (fdec->Semantic.SemanticName) {
+	switch (fdec->Semantic.Name) {
 	case TGSI_SEMANTIC_POSITION:
 		hw = NV30_VP_INST_DEST_POS;
 		break;
 	case TGSI_SEMANTIC_COLOR:
-		if (fdec->Semantic.SemanticIndex == 0) {
+		if (fdec->Semantic.Index == 0) {
 			hw = NV30_VP_INST_DEST_COL0;
 		} else
-		if (fdec->Semantic.SemanticIndex == 1) {
+		if (fdec->Semantic.Index == 1) {
 			hw = NV30_VP_INST_DEST_COL1;
 		} else {
 			NOUVEAU_ERR("bad colour semantic index\n");
@@ -506,10 +506,10 @@
 		}
 		break;
 	case TGSI_SEMANTIC_BCOLOR:
-		if (fdec->Semantic.SemanticIndex == 0) {
+		if (fdec->Semantic.Index == 0) {
 			hw = NV30_VP_INST_DEST_BFC0;
 		} else
-		if (fdec->Semantic.SemanticIndex == 1) {
+		if (fdec->Semantic.Index == 1) {
 			hw = NV30_VP_INST_DEST_BFC1;
 		} else {
 			NOUVEAU_ERR("bad bcolour semantic index\n");
@@ -523,19 +523,22 @@
 		hw = NV30_VP_INST_DEST_PSZ;
 		break;
 	case TGSI_SEMANTIC_GENERIC:
-		if (fdec->Semantic.SemanticIndex <= 7) {
-			hw = NV30_VP_INST_DEST_TC(fdec->Semantic.SemanticIndex);
+		if (fdec->Semantic.Index <= 7) {
+			hw = NV30_VP_INST_DEST_TC(fdec->Semantic.Index);
 		} else {
 			NOUVEAU_ERR("bad generic semantic index\n");
 			return FALSE;
 		}
 		break;
+	case TGSI_SEMANTIC_EDGEFLAG:
+		NOUVEAU_ERR("cannot handle edgeflag output\n");
+		return FALSE;
 	default:
 		NOUVEAU_ERR("bad output semantic\n");
 		return FALSE;
 	}
 
-	vpc->output_map[fdec->DeclarationRange.First] = hw;
+	vpc->output_map[fdec->Range.First] = hw;
 	return TRUE;
 }
 
diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c
index d8300fd..54572e9 100644
--- a/src/gallium/drivers/nv30/nv30_context.c
+++ b/src/gallium/drivers/nv30/nv30_context.c
@@ -10,21 +10,32 @@
 	   struct pipe_fence_handle **fence)
 {
 	struct nv30_context *nv30 = nv30_context(pipe);
+	struct nv30_screen *screen = nv30->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *rankine = screen->rankine;
 
 	if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
-		BEGIN_RING(rankine, 0x1fd8, 1);
-		OUT_RING  (2);
-		BEGIN_RING(rankine, 0x1fd8, 1);
-		OUT_RING  (1);
+		BEGIN_RING(chan, rankine, 0x1fd8, 1);
+		OUT_RING  (chan, 2);
+		BEGIN_RING(chan, rankine, 0x1fd8, 1);
+		OUT_RING  (chan, 1);
 	}
 
-	FIRE_RING(fence);
+	FIRE_RING(chan);
+	if (fence)
+		*fence = NULL;
 }
 
 static void
 nv30_destroy(struct pipe_context *pipe)
 {
 	struct nv30_context *nv30 = nv30_context(pipe);
+	unsigned i;
+
+	for (i = 0; i < NV30_STATE_MAX; i++) {
+		if (nv30->state.hw[i])
+			so_ref(NULL, &nv30->state.hw[i]);
+	}
 
 	if (nv30->draw)
 		draw_destroy(nv30->draw);
@@ -58,6 +69,9 @@
 	nv30->pipe.is_texture_referenced = nouveau_is_texture_referenced;
 	nv30->pipe.is_buffer_referenced = nouveau_is_buffer_referenced;
 
+	screen->base.channel->user_private = nv30;
+	screen->base.channel->flush_notify = nv30_state_flush_notify;
+
 	nv30_init_query_functions(nv30);
 	nv30_init_surface_functions(nv30);
 	nv30_init_state_functions(nv30);
diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h
index 8d49366..e594492 100644
--- a/src/gallium/drivers/nv30/nv30_context.h
+++ b/src/gallium/drivers/nv30/nv30_context.h
@@ -14,10 +14,6 @@
 #include "nouveau/nouveau_winsys.h"
 #include "nouveau/nouveau_gldefs.h"
 #include "nouveau/nouveau_context.h"
-
-#define NOUVEAU_PUSH_CONTEXT(ctx)                                              \
-	struct nv30_screen *ctx = nv30->screen
-#include "nouveau/nouveau_push.h"
 #include "nouveau/nouveau_stateobj.h"
 
 #include "nv30_state.h"
@@ -144,7 +140,6 @@
 	unsigned vtxbuf_nr;
 	struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
 	unsigned vtxelt_nr;
-	const unsigned *edgeflags;
 };
 
 static INLINE struct nv30_context *
@@ -184,6 +179,7 @@
 /* nv30_state.c and friends */
 extern boolean nv30_state_validate(struct nv30_context *nv30);
 extern void nv30_state_emit(struct nv30_context *nv30);
+extern void nv30_state_flush_notify(struct nouveau_channel *chan);
 extern struct nv30_state_entry nv30_state_rasterizer;
 extern struct nv30_state_entry nv30_state_scissor;
 extern struct nv30_state_entry nv30_state_stipple;
@@ -198,9 +194,9 @@
 extern struct nv30_state_entry nv30_state_vbo;
 
 /* nv30_vbo.c */
-extern boolean nv30_draw_arrays(struct pipe_context *, unsigned mode,
+extern void nv30_draw_arrays(struct pipe_context *, unsigned mode,
 				unsigned start, unsigned count);
-extern boolean nv30_draw_elements(struct pipe_context *pipe,
+extern void nv30_draw_elements(struct pipe_context *pipe,
 				  struct pipe_buffer *indexBuffer,
 				  unsigned indexSize,
 				  unsigned mode, unsigned start,
diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c
index cc03854..2d565cb 100644
--- a/src/gallium/drivers/nv30/nv30_fragprog.c
+++ b/src/gallium/drivers/nv30/nv30_fragprog.c
@@ -4,6 +4,7 @@
 #include "pipe/p_inlines.h"
 
 #include "pipe/p_shader_tokens.h"
+#include "tgsi/tgsi_dump.h"
 #include "tgsi/tgsi_parse.h"
 #include "tgsi/tgsi_util.h"
 
@@ -131,7 +132,7 @@
 				sizeof(uint32_t) * 4);
 		}
 
-		sr |= (NV30_FP_REG_TYPE_CONST << NV30_FP_REG_TYPE_SHIFT);	
+		sr |= (NV30_FP_REG_TYPE_CONST << NV30_FP_REG_TYPE_SHIFT);
 		break;
 	case NV30SR_NONE:
 		sr |= (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT);
@@ -236,20 +237,20 @@
 {
 	struct nv30_sreg src;
 
-	switch (fsrc->SrcRegister.File) {
+	switch (fsrc->Register.File) {
 	case TGSI_FILE_INPUT:
 		src = nv30_sr(NV30SR_INPUT,
-			      fpc->attrib_map[fsrc->SrcRegister.Index]);
+			      fpc->attrib_map[fsrc->Register.Index]);
 		break;
 	case TGSI_FILE_CONSTANT:
-		src = constant(fpc, fsrc->SrcRegister.Index, NULL);
+		src = constant(fpc, fsrc->Register.Index, NULL);
 		break;
 	case TGSI_FILE_IMMEDIATE:
-		assert(fsrc->SrcRegister.Index < fpc->nr_imm);
-		src = fpc->imm[fsrc->SrcRegister.Index];
+		assert(fsrc->Register.Index < fpc->nr_imm);
+		src = fpc->imm[fsrc->Register.Index];
 		break;
 	case TGSI_FILE_TEMPORARY:
-		src = nv30_sr(NV30SR_TEMP, fsrc->SrcRegister.Index + 1);
+		src = nv30_sr(NV30SR_TEMP, fsrc->Register.Index + 1);
 		if (fpc->high_temp < src.index)
 			fpc->high_temp = src.index;
 		break;
@@ -257,7 +258,7 @@
 	 * Luckily fragprog results are just temp regs..
 	 */
 	case TGSI_FILE_OUTPUT:
-		if (fsrc->SrcRegister.Index == fpc->colour_id)
+		if (fsrc->Register.Index == fpc->colour_id)
 			return nv30_sr(NV30SR_OUTPUT, 0);
 		else
 			return nv30_sr(NV30SR_OUTPUT, 1);
@@ -267,12 +268,12 @@
 		break;
 	}
 
-	src.abs = fsrc->SrcRegisterExtMod.Absolute;
-	src.negate = fsrc->SrcRegister.Negate;
-	src.swz[0] = fsrc->SrcRegister.SwizzleX;
-	src.swz[1] = fsrc->SrcRegister.SwizzleY;
-	src.swz[2] = fsrc->SrcRegister.SwizzleZ;
-	src.swz[3] = fsrc->SrcRegister.SwizzleW;
+	src.abs = fsrc->Register.Absolute;
+	src.negate = fsrc->Register.Negate;
+	src.swz[0] = fsrc->Register.SwizzleX;
+	src.swz[1] = fsrc->Register.SwizzleY;
+	src.swz[2] = fsrc->Register.SwizzleZ;
+	src.swz[3] = fsrc->Register.SwizzleW;
 	return src;
 }
 
@@ -280,22 +281,22 @@
 tgsi_dst(struct nv30_fpc *fpc, const struct tgsi_full_dst_register *fdst) {
 	int idx;
 
-	switch (fdst->DstRegister.File) {
+	switch (fdst->Register.File) {
 	case TGSI_FILE_OUTPUT:
-		if (fdst->DstRegister.Index == fpc->colour_id)
+		if (fdst->Register.Index == fpc->colour_id)
 			return nv30_sr(NV30SR_OUTPUT, 0);
 		else
 			return nv30_sr(NV30SR_OUTPUT, 1);
 		break;
 	case TGSI_FILE_TEMPORARY:
-		idx = fdst->DstRegister.Index + 1;
+		idx = fdst->Register.Index + 1;
 		if (fpc->high_temp < idx)
 			fpc->high_temp = idx;
 		return nv30_sr(NV30SR_TEMP, idx);
 	case TGSI_FILE_NULL:
 		return nv30_sr(NV30SR_NONE, 0);
 	default:
-		NOUVEAU_ERR("bad dst file %d\n", fdst->DstRegister.File);
+		NOUVEAU_ERR("bad dst file %d\n", fdst->Register.File);
 		return nv30_sr(NV30SR_NONE, 0);
 	}
 }
@@ -362,8 +363,8 @@
 	for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
 		const struct tgsi_full_src_register *fsrc;
 
-		fsrc = &finst->FullSrcRegisters[i];
-		if (fsrc->SrcRegister.File == TGSI_FILE_TEMPORARY) {
+		fsrc = &finst->Src[i];
+		if (fsrc->Register.File == TGSI_FILE_TEMPORARY) {
 			src[i] = tgsi_src(fpc, fsrc);
 		}
 	}
@@ -371,9 +372,9 @@
 	for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
 		const struct tgsi_full_src_register *fsrc;
 
-		fsrc = &finst->FullSrcRegisters[i];
+		fsrc = &finst->Src[i];
 
-		switch (fsrc->SrcRegister.File) {
+		switch (fsrc->Register.File) {
 		case TGSI_FILE_INPUT:
 		case TGSI_FILE_CONSTANT:
 		case TGSI_FILE_TEMPORARY:
@@ -384,14 +385,14 @@
 			break;
 		}
 
-		switch (fsrc->SrcRegister.File) {
+		switch (fsrc->Register.File) {
 		case TGSI_FILE_INPUT:
-			if (ai == -1 || ai == fsrc->SrcRegister.Index) {
-				ai = fsrc->SrcRegister.Index;
+			if (ai == -1 || ai == fsrc->Register.Index) {
+				ai = fsrc->Register.Index;
 				src[i] = tgsi_src(fpc, fsrc);
 			} else {
 				NOUVEAU_MSG("extra src attr %d\n",
-					 fsrc->SrcRegister.Index);
+					 fsrc->Register.Index);
 				src[i] = temp(fpc);
 				arith(fpc, 0, MOV, src[i], MASK_ALL,
 				      tgsi_src(fpc, fsrc), none, none);
@@ -399,8 +400,8 @@
 			break;
 		case TGSI_FILE_CONSTANT:
 		case TGSI_FILE_IMMEDIATE:
-			if (ci == -1 || ci == fsrc->SrcRegister.Index) {
-				ci = fsrc->SrcRegister.Index;
+			if (ci == -1 || ci == fsrc->Register.Index) {
+				ci = fsrc->Register.Index;
 				src[i] = tgsi_src(fpc, fsrc);
 			} else {
 				src[i] = temp(fpc);
@@ -412,7 +413,7 @@
 			/* handled above */
 			break;
 		case TGSI_FILE_SAMPLER:
-			unit = fsrc->SrcRegister.Index;
+			unit = fsrc->Register.Index;
 			break;
 		case TGSI_FILE_OUTPUT:
 			break;
@@ -422,8 +423,8 @@
 		}
 	}
 
-	dst  = tgsi_dst(fpc, &finst->FullDstRegisters[0]);
-	mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask);
+	dst  = tgsi_dst(fpc, &finst->Dst[0]);
+	mask = tgsi_mask(finst->Dst[0].Register.WriteMask);
 	sat  = (finst->Instruction.Saturate == TGSI_SAT_ZERO_ONE);
 
 	switch (finst->Instruction.Opcode) {
@@ -434,10 +435,11 @@
 		arith(fpc, sat, ADD, dst, mask, src[0], src[1], none);
 		break;
 	case TGSI_OPCODE_CMP:
-		tmp = temp(fpc);
-		arith(fpc, sat, MOV, dst, mask, src[2], none, none);
+		tmp = nv30_sr(NV30SR_NONE, 0);
 		tmp.cc_update = 1;
 		arith(fpc, 0, MOV, tmp, 0xf, src[0], none, none);
+		dst.cc_test = NV30_VP_INST_COND_GE;
+		arith(fpc, sat, MOV, dst, mask, src[2], none, none);
 		dst.cc_test = NV30_VP_INST_COND_LT;
 		arith(fpc, sat, MOV, dst, mask, src[1], none, none);
 		break;
@@ -516,13 +518,28 @@
 		arith(fpc, sat, RSQ, dst, mask, abs(swz(src[0], X, X, X, X)), none, none);
 		break;
 	case TGSI_OPCODE_SCS:
-		if (mask & MASK_X) {
-			arith(fpc, sat, COS, dst, MASK_X,
-			      swz(src[0], X, X, X, X), none, none);
+		/* avoid overwriting the source */
+		if(src[0].swz[SWZ_X] != SWZ_X)
+		{
+			if (mask & MASK_X) {
+				arith(fpc, sat, COS, dst, MASK_X,
+				      swz(src[0], X, X, X, X), none, none);
+			}
+			if (mask & MASK_Y) {
+				arith(fpc, sat, SIN, dst, MASK_Y,
+				      swz(src[0], X, X, X, X), none, none);
+			}
 		}
-		if (mask & MASK_Y) {
-			arith(fpc, sat, SIN, dst, MASK_Y,
-			      swz(src[0], X, X, X, X), none, none);
+		else
+		{
+			if (mask & MASK_Y) {
+				arith(fpc, sat, SIN, dst, MASK_Y,
+				      swz(src[0], X, X, X, X), none, none);
+			}
+			if (mask & MASK_X) {
+				arith(fpc, sat, COS, dst, MASK_X,
+				      swz(src[0], X, X, X, X), none, none);
+			}
 		}
 		break;
 	case TGSI_OPCODE_SIN:
@@ -571,15 +588,15 @@
 {
 	int hw;
 
-	switch (fdec->Semantic.SemanticName) {
+	switch (fdec->Semantic.Name) {
 	case TGSI_SEMANTIC_POSITION:
 		hw = NV30_FP_OP_INPUT_SRC_POSITION;
 		break;
 	case TGSI_SEMANTIC_COLOR:
-		if (fdec->Semantic.SemanticIndex == 0) {
+		if (fdec->Semantic.Index == 0) {
 			hw = NV30_FP_OP_INPUT_SRC_COL0;
 		} else
-		if (fdec->Semantic.SemanticIndex == 1) {
+		if (fdec->Semantic.Index == 1) {
 			hw = NV30_FP_OP_INPUT_SRC_COL1;
 		} else {
 			NOUVEAU_ERR("bad colour semantic index\n");
@@ -590,9 +607,9 @@
 		hw = NV30_FP_OP_INPUT_SRC_FOGC;
 		break;
 	case TGSI_SEMANTIC_GENERIC:
-		if (fdec->Semantic.SemanticIndex <= 7) {
+		if (fdec->Semantic.Index <= 7) {
 			hw = NV30_FP_OP_INPUT_SRC_TC(fdec->Semantic.
-						     SemanticIndex);
+						     Index);
 		} else {
 			NOUVEAU_ERR("bad generic semantic index\n");
 			return FALSE;
@@ -603,7 +620,7 @@
 		return FALSE;
 	}
 
-	fpc->attrib_map[fdec->DeclarationRange.First] = hw;
+	fpc->attrib_map[fdec->Range.First] = hw;
 	return TRUE;
 }
 
@@ -611,12 +628,12 @@
 nv30_fragprog_parse_decl_output(struct nv30_fpc *fpc,
 				const struct tgsi_full_declaration *fdec)
 {
-	switch (fdec->Semantic.SemanticName) {
+	switch (fdec->Semantic.Name) {
 	case TGSI_SEMANTIC_POSITION:
-		fpc->depth_id = fdec->DeclarationRange.First;
+		fpc->depth_id = fdec->Range.First;
 		break;
 	case TGSI_SEMANTIC_COLOR:
-		fpc->colour_id = fdec->DeclarationRange.First;
+		fpc->colour_id = fdec->Range.First;
 		break;
 	default:
 		NOUVEAU_ERR("bad output semantic\n");
@@ -652,9 +669,9 @@
 					goto out_err;
 				break;
 			/*case TGSI_FILE_TEMPORARY:
-				if (fdec->DeclarationRange.Last > high_temp) {
+				if (fdec->Range.Last > high_temp) {
 					high_temp =
-						fdec->DeclarationRange.Last;
+						fdec->Range.Last;
 				}
 				break;*/
 			default:
@@ -666,7 +683,7 @@
 		{
 			struct tgsi_full_immediate *imm;
 			float vals[4];
-			
+
 			imm = &p.FullToken.FullImmediate;
 			assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32);
 			assert(fpc->nr_imm < MAX_IMM);
@@ -754,7 +771,7 @@
 	fp->insn[fpc->inst_offset + 1] = 0x00000000;
 	fp->insn[fpc->inst_offset + 2] = 0x00000000;
 	fp->insn[fpc->inst_offset + 3] = 0x00000000;
-	
+
 	fp->translated = TRUE;
 	fp->on_hw = FALSE;
 out_err:
@@ -820,7 +837,7 @@
 	fp->buffer = pscreen->buffer_create(pscreen, 0x100, 0, fp->insn_len * 4);
 	nv30_fragprog_upload(nv30, fp);
 
-	so = so_new(8, 1);
+	so = so_new(4, 4, 1);
 	so_method(so, nv30->screen->rankine, NV34TCL_FP_ACTIVE_PROGRAM, 1);
 	so_reloc (so, nouveau_bo(fp->buffer), 0, NOUVEAU_BO_VRAM |
 		      NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW |
@@ -838,7 +855,7 @@
 update_constants:
 	if (fp->nr_consts) {
 		float *map;
-		
+
 		map = pipe_buffer_map(pscreen, constbuf,
 				      PIPE_BUFFER_USAGE_CPU_READ);
 		for (i = 0; i < fp->nr_consts; i++) {
@@ -869,6 +886,12 @@
 nv30_fragprog_destroy(struct nv30_context *nv30,
 		      struct nv30_fragment_program *fp)
 {
+	if (fp->buffer)
+		pipe_buffer_reference(&fp->buffer, NULL);
+
+	if (fp->so)
+		so_ref(NULL, &fp->so);
+
 	if (fp->insn_len)
 		FREE(fp->insn);
 }
diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c
index dca760c..9893567 100644
--- a/src/gallium/drivers/nv30/nv30_fragtex.c
+++ b/src/gallium/drivers/nv30/nv30_fragtex.c
@@ -74,9 +74,9 @@
 
 	txf  = tf->format;
 	txf |= ((pt->last_level>0) ? NV34TCL_TX_FORMAT_MIPMAP : 0);
-	txf |= log2i(pt->width[0]) << NV34TCL_TX_FORMAT_BASE_SIZE_U_SHIFT;
-	txf |= log2i(pt->height[0]) << NV34TCL_TX_FORMAT_BASE_SIZE_V_SHIFT;
-	txf |= log2i(pt->depth[0]) << NV34TCL_TX_FORMAT_BASE_SIZE_W_SHIFT;
+	txf |= log2i(pt->width0) << NV34TCL_TX_FORMAT_BASE_SIZE_U_SHIFT;
+	txf |= log2i(pt->height0) << NV34TCL_TX_FORMAT_BASE_SIZE_V_SHIFT;
+	txf |= log2i(pt->depth0) << NV34TCL_TX_FORMAT_BASE_SIZE_W_SHIFT;
 	txf |= NV34TCL_TX_FORMAT_NO_BORDER | 0x10000;
 
 	switch (pt->target) {
@@ -106,7 +106,7 @@
 
 	txs = tf->swizzle;
 
-	so = so_new(16, 2);
+	so = so_new(1, 8, 2);
 	so_method(so, nv30->screen->rankine, NV34TCL_TX_OFFSET(unit), 8);
 	so_reloc (so, bo, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0);
 	so_reloc (so, bo, txf, tex_flags | NOUVEAU_BO_OR,
@@ -115,8 +115,8 @@
 	so_data  (so, NV34TCL_TX_ENABLE_ENABLE | ps->en);
 	so_data  (so, txs);
 	so_data  (so, ps->filt | 0x2000 /*voodoo*/);
-	so_data  (so, (pt->width[0] << NV34TCL_TX_NPOT_SIZE_W_SHIFT) |
-		       pt->height[0]);
+	so_data  (so, (pt->width0 << NV34TCL_TX_NPOT_SIZE_W_SHIFT) |
+		       pt->height0);
 	so_data  (so, ps->bcol);
 
 	return so;
@@ -135,7 +135,7 @@
 		unit = ffs(samplers) - 1;
 		samplers &= ~(1 << unit);
 
-		so = so_new(2, 0);
+		so = so_new(1, 1, 0);
 		so_method(so, nv30->screen->rankine, NV34TCL_TX_ENABLE(unit), 1);
 		so_data  (so, 0);
 		so_ref(so, &nv30->state.hw[NV30_STATE_FRAGTEX0 + unit]);
diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c
index 280696d..8fbba38 100644
--- a/src/gallium/drivers/nv30/nv30_miptree.c
+++ b/src/gallium/drivers/nv30/nv30_miptree.c
@@ -1,14 +1,17 @@
 #include "pipe/p_state.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
 
 #include "nv30_context.h"
+#include "../nv04/nv04_surface_2d.h"
 
 static void
 nv30_miptree_layout(struct nv30_miptree *nv30mt)
 {
 	struct pipe_texture *pt = &nv30mt->base;
-	uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0];
+	uint width = pt->width0;
 	uint offset = 0;
 	int nr_faces, l, f;
 	uint wide_pitch = pt->tex_usage & (PIPE_TEXTURE_USAGE_SAMPLER |
@@ -21,29 +24,21 @@
 		nr_faces = 6;
 	} else
 	if (pt->target == PIPE_TEXTURE_3D) {
-		nr_faces = pt->depth[0];
+		nr_faces = pt->depth0;
 	} else {
 		nr_faces = 1;
 	}
 
 	for (l = 0; l <= pt->last_level; l++) {
-		pt->width[l] = width;
-		pt->height[l] = height;
-		pt->depth[l] = depth;
-		pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width);
-		pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height);
-
 		if (wide_pitch && (pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR))
-			nv30mt->level[l].pitch = align(pt->width[0] * pt->block.size, 64);
+			nv30mt->level[l].pitch = align(util_format_get_stride(pt->format, pt->width0), 64);
 		else
-			nv30mt->level[l].pitch = pt->width[l] * pt->block.size;
+			nv30mt->level[l].pitch = util_format_get_stride(pt->format, width);
 
 		nv30mt->level[l].image_offset =
 			CALLOC(nr_faces, sizeof(unsigned));
 
-		width  = MAX2(1, width  >> 1);
-		height = MAX2(1, height >> 1);
-		depth  = MAX2(1, depth  >> 1);
+		width  = u_minify(width, 1);
 	}
 
 	for (f = 0; f < nr_faces; f++) {
@@ -51,14 +46,14 @@
 			nv30mt->level[l].image_offset[f] = offset;
 
 			if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) &&
-			    pt->width[l + 1] > 1 && pt->height[l + 1] > 1)
-				offset += align(nv30mt->level[l].pitch * pt->height[l], 64);
+			    u_minify(pt->width0, l + 1) > 1 && u_minify(pt->height0, l + 1) > 1)
+				offset += align(nv30mt->level[l].pitch * u_minify(pt->height0, l), 64);
 			else
-				offset += nv30mt->level[l].pitch * pt->height[l];
+				offset += nv30mt->level[l].pitch * u_minify(pt->height0, l);
 		}
 
 		nv30mt->level[l].image_offset[f] = offset;
-		offset += nv30mt->level[l].pitch * pt->height[l];
+		offset += nv30mt->level[l].pitch * u_minify(pt->height0, l);
 	}
 
 	nv30mt->total_size = offset;
@@ -79,8 +74,8 @@
 	mt->base.screen = pscreen;
 
 	/* Swizzled textures must be POT */
-	if (pt->width[0] & (pt->width[0] - 1) ||
-	    pt->height[0] & (pt->height[0] - 1))
+	if (pt->width0 & (pt->width0 - 1) ||
+	    pt->height0 & (pt->height0 - 1))
 		mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
 	else
 	if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY |
@@ -114,6 +109,12 @@
 	if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC)
 		buf_usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE;
 
+	/* apparently we can't render to swizzled surfaces smaller than 64 bytes, so make them linear.
+	 * If the user did not ask for a render target, they can still render to it, but it will cost them an extra copy.
+	 * This also happens for small mipmaps of large textures. */
+	if (pt->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET && util_format_get_stride(pt->format, pt->width0) < 64)
+		mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
+
 	nv30_miptree_layout(mt);
 
 	mt->buffer = pscreen->buffer_create(pscreen, 256, buf_usage,
@@ -122,6 +123,7 @@
 		FREE(mt);
 		return NULL;
 	}
+	mt->bo = nouveau_bo(mt->buffer);
 
 	return &mt->base;
 }
@@ -134,7 +136,7 @@
 
 	/* Only supports 2D, non-mipmapped textures for the moment */
 	if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 ||
-	    pt->depth[0] != 1)
+	    pt->depth0 != 1)
 		return NULL;
 
 	mt = CALLOC_STRUCT(nv30_miptree);
@@ -151,6 +153,7 @@
 	mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
 
 	pipe_buffer_reference(&mt->buffer, pb);
+	mt->bo = nouveau_bo(mt->buffer);
 	return &mt->base;
 }
 
@@ -182,8 +185,8 @@
 		return NULL;
 	pipe_texture_reference(&ns->base.texture, pt);
 	ns->base.format = pt->format;
-	ns->base.width = pt->width[level];
-	ns->base.height = pt->height[level];
+	ns->base.width = u_minify(pt->width0, level);
+	ns->base.height = u_minify(pt->height0, level);
 	ns->base.usage = flags;
 	pipe_reference_init(&ns->base.reference, 1);
 	ns->base.face = face;
@@ -200,12 +203,27 @@
 		ns->base.offset = nv30mt->level[level].image_offset[0];
 	}
 
+	/* create a linear temporary that we can render into if necessary.
+	 * Note that ns->pitch is always a multiple of 64 for linear surfaces and swizzled surfaces are POT, so
+	 * ns->pitch & 63 is equivalent to (ns->pitch < 64 && swizzled)*/
+	if((ns->pitch & 63) && (ns->base.usage & (PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER)) == PIPE_BUFFER_USAGE_GPU_WRITE)
+		return &nv04_surface_wrap_for_render(pscreen, ((struct nv30_screen*)pscreen)->eng2d, ns)->base;
+
 	return &ns->base;
 }
 
 static void
 nv30_miptree_surface_del(struct pipe_surface *ps)
 {
+	struct nv04_surface* ns = (struct nv04_surface*)ps;
+	if(ns->backing)
+	{
+		struct nv30_screen* screen = (struct nv30_screen*)ps->texture->screen;
+		if(ns->backing->base.usage & PIPE_BUFFER_USAGE_GPU_WRITE)
+			screen->eng2d->copy(screen->eng2d, &ns->backing->base, 0, 0, ps, 0, 0, ns->base.width, ns->base.height);
+		nv30_miptree_surface_del(&ns->backing->base);
+	}
+
 	pipe_texture_reference(&ps->texture, NULL);
 	FREE(ps);
 }
diff --git a/src/gallium/drivers/nv30/nv30_query.c b/src/gallium/drivers/nv30/nv30_query.c
index 1d1c8a4..e27e9cc 100644
--- a/src/gallium/drivers/nv30/nv30_query.c
+++ b/src/gallium/drivers/nv30/nv30_query.c
@@ -41,6 +41,9 @@
 {
 	struct nv30_context *nv30 = nv30_context(pipe);
 	struct nv30_query *q = nv30_query(pq);
+	struct nv30_screen *screen = nv30->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *rankine = screen->rankine;
 
 	assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
 
@@ -57,10 +60,10 @@
 		assert(0);
 	nouveau_notifier_reset(nv30->screen->query, q->object->start);
 
-	BEGIN_RING(rankine, NV34TCL_QUERY_RESET, 1);
-	OUT_RING  (1);
-	BEGIN_RING(rankine, NV34TCL_QUERY_UNK17CC, 1);
-	OUT_RING  (1);
+	BEGIN_RING(chan, rankine, NV34TCL_QUERY_RESET, 1);
+	OUT_RING  (chan, 1);
+	BEGIN_RING(chan, rankine, NV34TCL_QUERY_UNK17CC, 1);
+	OUT_RING  (chan, 1);
 
 	q->ready = FALSE;
 }
@@ -69,12 +72,15 @@
 nv30_query_end(struct pipe_context *pipe, struct pipe_query *pq)
 {
 	struct nv30_context *nv30 = nv30_context(pipe);
+	struct nv30_screen *screen = nv30->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *rankine = screen->rankine;
 	struct nv30_query *q = nv30_query(pq);
 
-	BEGIN_RING(rankine, NV34TCL_QUERY_GET, 1);
-	OUT_RING  ((0x01 << NV34TCL_QUERY_GET_UNK24_SHIFT) |
+	BEGIN_RING(chan, rankine, NV34TCL_QUERY_GET, 1);
+	OUT_RING  (chan, (0x01 << NV34TCL_QUERY_GET_UNK24_SHIFT) |
 		   ((q->object->start * 32) << NV34TCL_QUERY_GET_OFFSET_SHIFT));
-	FIRE_RING(NULL);
+	FIRE_RING(chan);
 }
 
 static boolean
diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
index 221ae1b..9ed4817 100644
--- a/src/gallium/drivers/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nv30/nv30_screen.c
@@ -116,7 +116,10 @@
 		case PIPE_FORMAT_Z24X8_UNORM:
 			return TRUE;
 		case PIPE_FORMAT_Z16_UNORM:
-			return (front->format == PIPE_FORMAT_R5G6B5_UNORM);
+			if (front) {
+				return (front->format == PIPE_FORMAT_R5G6B5_UNORM);
+			}
+			return TRUE;
 		default:
 			break;
 		}
@@ -153,6 +156,12 @@
 nv30_screen_destroy(struct pipe_screen *pscreen)
 {
 	struct nv30_screen *screen = nv30_screen(pscreen);
+	unsigned i;
+
+	for (i = 0; i < NV30_STATE_MAX; i++) {
+		if (screen->state[i])
+			so_ref(NULL, &screen->state[i]);
+	}
 
 	nouveau_resource_free(&screen->vp_exec_heap);
 	nouveau_resource_free(&screen->vp_data_heap);
@@ -160,6 +169,9 @@
 	nouveau_notifier_free(&screen->query);
 	nouveau_notifier_free(&screen->sync);
 	nouveau_grobj_free(&screen->rankine);
+	nv04_surface_2d_takedown(&screen->eng2d);
+
+	nouveau_screen_fini(&screen->base);
 
 	FREE(pscreen);
 }
@@ -221,7 +233,6 @@
 		NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
 		return FALSE;
 	}
-	BIND_RING(chan, screen->rankine, 7);
 
 	/* 2D engine setup */
 	screen->eng2d = nv04_surface_2d_init(&screen->base);
@@ -258,7 +269,7 @@
 	}
 
 	/* Static rankine initialisation */
-	so = so_new(128, 0);
+	so = so_new(36, 60, 0);
 	so_method(so, screen->rankine, NV34TCL_DMA_NOTIFY, 1);
 	so_data  (so, screen->sync->handle);
 	so_method(so, screen->rankine, NV34TCL_DMA_TEXTURE0, 2);
diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c
index b91e972..a80dfb0 100644
--- a/src/gallium/drivers/nv30/nv30_state.c
+++ b/src/gallium/drivers/nv30/nv30_state.c
@@ -14,7 +14,7 @@
 	struct nv30_context *nv30 = nv30_context(pipe);
 	struct nouveau_grobj *rankine = nv30->screen->rankine;
 	struct nv30_blend_state *bso = CALLOC(1, sizeof(*bso));
-	struct nouveau_stateobj *so = so_new(16, 0);
+	struct nouveau_stateobj *so = so_new(5, 8, 0);
 
 	if (cso->blend_enable) {
 		so_method(so, rankine, NV34TCL_BLEND_FUNC_ENABLE, 3);
@@ -300,7 +300,7 @@
 {
 	struct nv30_context *nv30 = nv30_context(pipe);
 	struct nv30_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso));
-	struct nouveau_stateobj *so = so_new(32, 0);
+	struct nouveau_stateobj *so = so_new(9, 19, 0);
 	struct nouveau_grobj *rankine = nv30->screen->rankine;
 
 	/*XXX: ignored:
@@ -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(32, 0);
+	struct nouveau_stateobj *so = so_new(5, 21, 0);
 	struct nouveau_grobj *rankine = nv30->screen->rankine;
 
 	so_method(so, rankine, NV34TCL_DEPTH_FUNC, 3);
@@ -672,16 +672,6 @@
 	/*nv30->draw_dirty |= NV30_NEW_ARRAYS;*/
 }
 
-static void
-nv30_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
-{
-	struct nv30_context *nv30 = nv30_context(pipe);
-
-	nv30->edgeflags = bitfield;
-	nv30->dirty |= NV30_NEW_ARRAYS;
-	/*nv30->draw_dirty |= NV30_NEW_ARRAYS;*/
-}
-
 void
 nv30_init_state_functions(struct nv30_context *nv30)
 {
@@ -690,9 +680,9 @@
 	nv30->pipe.delete_blend_state = nv30_blend_state_delete;
 
 	nv30->pipe.create_sampler_state = nv30_sampler_state_create;
-	nv30->pipe.bind_sampler_states = nv30_sampler_state_bind;
+	nv30->pipe.bind_fragment_sampler_states = nv30_sampler_state_bind;
 	nv30->pipe.delete_sampler_state = nv30_sampler_state_delete;
-	nv30->pipe.set_sampler_textures = nv30_set_sampler_texture;
+	nv30->pipe.set_fragment_sampler_textures = nv30_set_sampler_texture;
 
 	nv30->pipe.create_rasterizer_state = nv30_rasterizer_state_create;
 	nv30->pipe.bind_rasterizer_state = nv30_rasterizer_state_bind;
@@ -721,7 +711,6 @@
 	nv30->pipe.set_scissor_state = nv30_set_scissor_state;
 	nv30->pipe.set_viewport_state = nv30_set_viewport_state;
 
-	nv30->pipe.set_edgeflags = nv30_set_edgeflags;
 	nv30->pipe.set_vertex_buffers = nv30_set_vertex_buffers;
 	nv30->pipe.set_vertex_elements = nv30_set_vertex_elements;
 }
diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h
index e6f23bf..e42e872 100644
--- a/src/gallium/drivers/nv30/nv30_state.h
+++ b/src/gallium/drivers/nv30/nv30_state.h
@@ -72,6 +72,7 @@
 
 struct nv30_miptree {
 	struct pipe_texture base;
+	struct nouveau_bo *bo;
 
 	struct pipe_buffer *buffer;
 	uint total_size;
diff --git a/src/gallium/drivers/nv30/nv30_state_blend.c b/src/gallium/drivers/nv30/nv30_state_blend.c
index 64cf9ae..c36d58c 100644
--- a/src/gallium/drivers/nv30/nv30_state_blend.c
+++ b/src/gallium/drivers/nv30/nv30_state_blend.c
@@ -18,7 +18,7 @@
 static boolean
 nv30_state_blend_colour_validate(struct nv30_context *nv30)
 {
-	struct nouveau_stateobj *so = so_new(2, 0);
+	struct nouveau_stateobj *so = so_new(1, 1, 0);
 	struct pipe_blend_color *bcol = &nv30->blend_colour;
 
 	so_method(so, nv30->screen->rankine, NV34TCL_BLEND_COLOR, 1);
diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c
index 621b884..ac52d94 100644
--- a/src/gallium/drivers/nv30/nv30_state_emit.c
+++ b/src/gallium/drivers/nv30/nv30_state_emit.c
@@ -41,7 +41,7 @@
 	struct nouveau_channel *chan = nv30->screen->base.channel;
 	struct nv30_state *state = &nv30->state;
 	struct nv30_screen *screen = nv30->screen;
-	unsigned i, samplers;
+	unsigned i;
 	uint64_t states;
 
 	if (nv30->pctx_id != screen->cur_pctx) {
@@ -63,6 +63,14 @@
 	}
 
 	state->dirty = 0;
+}
+
+void
+nv30_state_flush_notify(struct nouveau_channel *chan)
+{
+	struct nv30_context *nv30 = chan->user_private;
+	struct nv30_state *state = &nv30->state;
+	unsigned i, samplers;
 
 	so_emit_reloc_markers(chan, state->hw[NV30_STATE_FB]);
 	for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
diff --git a/src/gallium/drivers/nv30/nv30_state_fb.c b/src/gallium/drivers/nv30/nv30_state_fb.c
index 6f6d174..2ed2ea5 100644
--- a/src/gallium/drivers/nv30/nv30_state_fb.c
+++ b/src/gallium/drivers/nv30/nv30_state_fb.c
@@ -10,7 +10,7 @@
 	struct nv04_surface *rt[2], *zeta = NULL;
 	uint32_t rt_enable = 0, rt_format = 0;
 	int i, colour_format = 0, zeta_format = 0, depth_only = 0;
-	struct nouveau_stateobj *so = so_new(64, 10);
+	struct nouveau_stateobj *so = so_new(12, 18, 10);
 	unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM;
 	unsigned w = fb->width;
 	unsigned h = fb->height;
diff --git a/src/gallium/drivers/nv30/nv30_state_scissor.c b/src/gallium/drivers/nv30/nv30_state_scissor.c
index 3ac7a84..ba61a9e 100644
--- a/src/gallium/drivers/nv30/nv30_state_scissor.c
+++ b/src/gallium/drivers/nv30/nv30_state_scissor.c
@@ -12,7 +12,7 @@
 		return FALSE;
 	nv30->state.scissor_enabled = rast->scissor;
 
-	so = so_new(3, 0);
+	so = so_new(1, 2, 0);
 	so_method(so, nv30->screen->rankine, NV34TCL_SCISSOR_HORIZ, 2);
 	if (nv30->state.scissor_enabled) {
 		so_data  (so, ((s->maxx - s->minx) << 16) | s->minx);
diff --git a/src/gallium/drivers/nv30/nv30_state_stipple.c b/src/gallium/drivers/nv30/nv30_state_stipple.c
index d0c791a..ed520a4 100644
--- a/src/gallium/drivers/nv30/nv30_state_stipple.c
+++ b/src/gallium/drivers/nv30/nv30_state_stipple.c
@@ -14,14 +14,14 @@
 	if (rast->poly_stipple_enable) {
 		unsigned i;
 
-		so = so_new(35, 0);
+		so = so_new(2, 33, 0);
 		so_method(so, rankine, NV34TCL_POLYGON_STIPPLE_ENABLE, 1);
 		so_data  (so, 1);
 		so_method(so, rankine, NV34TCL_POLYGON_STIPPLE_PATTERN(0), 32);
 		for (i = 0; i < 32; i++)
 			so_data(so, nv30->stipple[i]);
 	} else {
-		so = so_new(2, 0);
+		so = so_new(1, 1, 0);
 		so_method(so, rankine, NV34TCL_POLYGON_STIPPLE_ENABLE, 1);
 		so_data  (so, 0);
 	}
diff --git a/src/gallium/drivers/nv30/nv30_state_viewport.c b/src/gallium/drivers/nv30/nv30_state_viewport.c
index c3eb413..2d77812 100644
--- a/src/gallium/drivers/nv30/nv30_state_viewport.c
+++ b/src/gallium/drivers/nv30/nv30_state_viewport.c
@@ -19,7 +19,7 @@
 		return FALSE;
 	nv30->state.viewport_bypass = bypass;
 
-	so = so_new(11, 0);
+	so = so_new(3, 10, 0);
 	if (!bypass) {
 		so_method(so, nv30->screen->rankine,
 			  NV34TCL_VIEWPORT_TRANSLATE_X, 8);
diff --git a/src/gallium/drivers/nv30/nv30_transfer.c b/src/gallium/drivers/nv30/nv30_transfer.c
index 98011de..6559899 100644
--- a/src/gallium/drivers/nv30/nv30_transfer.c
+++ b/src/gallium/drivers/nv30/nv30_transfer.c
@@ -1,7 +1,9 @@
 #include <pipe/p_state.h>
 #include <pipe/p_defines.h>
 #include <pipe/p_inlines.h>
+#include <util/u_format.h>
 #include <util/u_memory.h>
+#include <util/u_math.h>
 #include <nouveau/nouveau_winsys.h>
 #include "nv30_context.h"
 #include "nv30_screen.h"
@@ -10,22 +12,19 @@
 struct nv30_transfer {
 	struct pipe_transfer base;
 	struct pipe_surface *surface;
-	bool direct;
+	boolean direct;
 };
 
 static void
-nv30_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
+nv30_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height,
                              struct pipe_texture *template)
 {
 	memset(template, 0, sizeof(struct pipe_texture));
 	template->target = pt->target;
 	template->format = pt->format;
-	template->width[0] = pt->width[level];
-	template->height[0] = pt->height[level];
-	template->depth[0] = 1;
-	template->block = pt->block;
-	template->nblocksx[0] = pt->nblocksx[level];
-	template->nblocksy[0] = pt->nblocksx[level];
+	template->width0 = width;
+	template->height0 = height;
+	template->depth0 = 1;
 	template->last_level = 0;
 	template->nr_samples = pt->nr_samples;
 
@@ -48,14 +47,10 @@
 		return NULL;
 
 	pipe_texture_reference(&tx->base.texture, pt);
-	tx->base.format = pt->format;
 	tx->base.x = x;
 	tx->base.y = y;
 	tx->base.width = w;
 	tx->base.height = h;
-	tx->base.block = pt->block;
-	tx->base.nblocksx = pt->nblocksx[level];
-	tx->base.nblocksy = pt->nblocksy[level];
 	tx->base.stride = mt->level[level].pitch;
 	tx->base.usage = usage;
 	tx->base.face = face;
@@ -76,7 +71,7 @@
 
 	tx->direct = false;
 
-	nv30_compatible_transfer_tex(pt, level, &tx_tex_template);
+	nv30_compatible_transfer_tex(pt, w, h, &tx_tex_template);
 
 	tx_tex = pscreen->texture_create(pscreen, &tx_tex_template);
 	if (!tx_tex)
@@ -85,6 +80,8 @@
 		return NULL;
 	}
 
+	tx->base.stride = ((struct nv30_miptree*)tx_tex)->level[0].pitch;
+
 	tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
 	                                       0, 0, 0,
 	                                       pipe_transfer_buffer_flags(&tx->base));
@@ -110,8 +107,8 @@
 		/* TODO: Check if SIFM can un-swizzle */
 		nvscreen->eng2d->copy(nvscreen->eng2d,
 		                      tx->surface, 0, 0,
-		                      src, 0, 0,
-		                      src->width, src->height);
+		                      src, x, y,
+		                      w, h);
 
 		pipe_surface_reference(&src, NULL);
 	}
@@ -131,13 +128,13 @@
 
 		dst = pscreen->get_tex_surface(pscreen, ptx->texture,
 	                                       ptx->face, ptx->level, ptx->zslice,
-	                                       PIPE_BUFFER_USAGE_GPU_WRITE);
+	                                       PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER);
 
 		/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
 		nvscreen->eng2d->copy(nvscreen->eng2d,
-		                      dst, 0, 0,
+		                      dst, tx->base.x, tx->base.y,
 		                      tx->surface, 0, 0,
-		                      dst->width, dst->height);
+		                      tx->base.width, tx->base.height);
 
 		pipe_surface_reference(&dst, NULL);
 	}
@@ -156,8 +153,10 @@
 	void *map = pipe_buffer_map(pscreen, mt->buffer,
 	                            pipe_transfer_buffer_flags(ptx));
 
-	return map + ns->base.offset +
-	       ptx->y * ns->pitch + ptx->x * ptx->block.size;
+	if(!tx->direct)
+		return map + ns->base.offset;
+	else
+		return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format);
 }
 
 static void
diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c
index 189656e..1c5db03 100644
--- a/src/gallium/drivers/nv30/nv30_vbo.c
+++ b/src/gallium/drivers/nv30/nv30_vbo.c
@@ -163,19 +163,21 @@
 	return TRUE;
 }
 
-boolean
+void
 nv30_draw_arrays(struct pipe_context *pipe,
 		 unsigned mode, unsigned start, unsigned count)
 {
 	struct nv30_context *nv30 = nv30_context(pipe);
-	struct nouveau_channel *chan = nv30->screen->base.channel;
+	struct nv30_screen *screen = nv30->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *rankine = screen->rankine;
 	unsigned restart = 0;
 
 	nv30_vbo_set_idxbuf(nv30, NULL, 0);
 	if (FORCE_SWTNL || !nv30_state_validate(nv30)) {
 		/*return nv30_draw_elements_swtnl(pipe, NULL, 0,
 						mode, start, count);*/
-		return FALSE;
+		return;
 	}
 
 	while (count) {
@@ -186,17 +188,17 @@
 		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256,
 					mode, start, count, &restart);
 		if (!vc) {
-			FIRE_RING(NULL);
+			FIRE_RING(chan);
 			continue;
 		}
 
-		BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1);
-		OUT_RING  (nvgl_primitive(mode));
+		BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+		OUT_RING  (chan, nvgl_primitive(mode));
 
 		nr = (vc & 0xff);
 		if (nr) {
-			BEGIN_RING(rankine, NV34TCL_VB_VERTEX_BATCH, 1);
-			OUT_RING  (((nr - 1) << 24) | start);
+			BEGIN_RING(chan, rankine, NV34TCL_VB_VERTEX_BATCH, 1);
+			OUT_RING  (chan, ((nr - 1) << 24) | start);
 			start += nr;
 		}
 
@@ -206,15 +208,15 @@
 
 			nr -= push;
 
-			BEGIN_RING_NI(rankine, NV34TCL_VB_VERTEX_BATCH, push);
+			BEGIN_RING_NI(chan, rankine, NV34TCL_VB_VERTEX_BATCH, push);
 			while (push--) {
-				OUT_RING(((0x100 - 1) << 24) | start);
+				OUT_RING(chan, ((0x100 - 1) << 24) | start);
 				start += 0x100;
 			}
 		}
 
-		BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+		OUT_RING  (chan, 0);
 
 		count -= vc;
 		start = restart;
@@ -228,7 +230,9 @@
 nv30_draw_elements_u08(struct nv30_context *nv30, void *ib,
 		       unsigned mode, unsigned start, unsigned count)
 {
-	struct nouveau_channel *chan = nv30->screen->base.channel;
+	struct nv30_screen *screen = nv30->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *rankine = screen->rankine;
 
 	while (count) {
 		uint8_t *elts = (uint8_t *)ib + start;
@@ -239,17 +243,17 @@
 		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2,
 					mode, start, count, &restart);
 		if (vc == 0) {
-			FIRE_RING(NULL);
+			FIRE_RING(chan);
 			continue;
 		}
 		count -= vc;
 
-		BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1);
-		OUT_RING  (nvgl_primitive(mode));
+		BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+		OUT_RING  (chan, nvgl_primitive(mode));
 
 		if (vc & 1) {
-			BEGIN_RING(rankine, NV34TCL_VB_ELEMENT_U32, 1);
-			OUT_RING  (elts[0]);
+			BEGIN_RING(chan, rankine, NV34TCL_VB_ELEMENT_U32, 1);
+			OUT_RING  (chan, elts[0]);
 			elts++; vc--;
 		}
 
@@ -258,16 +262,16 @@
 
 			push = MIN2(vc, 2047 * 2);
 
-			BEGIN_RING_NI(rankine, NV34TCL_VB_ELEMENT_U16, push >> 1);
+			BEGIN_RING_NI(chan, rankine, NV34TCL_VB_ELEMENT_U16, push >> 1);
 			for (i = 0; i < push; i+=2)
-				OUT_RING((elts[i+1] << 16) | elts[i]);
+				OUT_RING(chan, (elts[i+1] << 16) | elts[i]);
 
 			vc -= push;
 			elts += push;
 		}
 
-		BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+		OUT_RING  (chan, 0);
 
 		start = restart;
 	}
@@ -277,7 +281,9 @@
 nv30_draw_elements_u16(struct nv30_context *nv30, void *ib,
 		       unsigned mode, unsigned start, unsigned count)
 {
-	struct nouveau_channel *chan = nv30->screen->base.channel;
+	struct nv30_screen *screen = nv30->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *rankine = screen->rankine;
 
 	while (count) {
 		uint16_t *elts = (uint16_t *)ib + start;
@@ -288,17 +294,17 @@
 		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2,
 					mode, start, count, &restart);
 		if (vc == 0) {
-			FIRE_RING(NULL);
+			FIRE_RING(chan);
 			continue;
 		}
 		count -= vc;
 
-		BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1);
-		OUT_RING  (nvgl_primitive(mode));
+		BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+		OUT_RING  (chan, nvgl_primitive(mode));
 
 		if (vc & 1) {
-			BEGIN_RING(rankine, NV34TCL_VB_ELEMENT_U32, 1);
-			OUT_RING  (elts[0]);
+			BEGIN_RING(chan, rankine, NV34TCL_VB_ELEMENT_U32, 1);
+			OUT_RING  (chan, elts[0]);
 			elts++; vc--;
 		}
 
@@ -307,16 +313,16 @@
 
 			push = MIN2(vc, 2047 * 2);
 
-			BEGIN_RING_NI(rankine, NV34TCL_VB_ELEMENT_U16, push >> 1);
+			BEGIN_RING_NI(chan, rankine, NV34TCL_VB_ELEMENT_U16, push >> 1);
 			for (i = 0; i < push; i+=2)
-				OUT_RING((elts[i+1] << 16) | elts[i]);
+				OUT_RING(chan, (elts[i+1] << 16) | elts[i]);
 
 			vc -= push;
 			elts += push;
 		}
 
-		BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+		OUT_RING  (chan, 0);
 
 		start = restart;
 	}
@@ -326,7 +332,9 @@
 nv30_draw_elements_u32(struct nv30_context *nv30, void *ib,
 		       unsigned mode, unsigned start, unsigned count)
 {
-	struct nouveau_channel *chan = nv30->screen->base.channel;
+	struct nv30_screen *screen = nv30->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *rankine = screen->rankine;
 
 	while (count) {
 		uint32_t *elts = (uint32_t *)ib + start;
@@ -337,32 +345,32 @@
 		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 5, 1,
 					mode, start, count, &restart);
 		if (vc == 0) {
-			FIRE_RING(NULL);
+			FIRE_RING(chan);
 			continue;
 		}
 		count -= vc;
 
-		BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1);
-		OUT_RING  (nvgl_primitive(mode));
+		BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+		OUT_RING  (chan, nvgl_primitive(mode));
 
 		while (vc) {
 			push = MIN2(vc, 2047);
 
-			BEGIN_RING_NI(rankine, NV34TCL_VB_ELEMENT_U32, push);
-			OUT_RINGp    (elts, push);
+			BEGIN_RING_NI(chan, rankine, NV34TCL_VB_ELEMENT_U32, push);
+			OUT_RINGp    (chan, elts, push);
 
 			vc -= push;
 			elts += push;
 		}
 
-		BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+		OUT_RING  (chan, 0);
 
 		start = restart;
 	}
 }
 
-static boolean
+static void
 nv30_draw_elements_inline(struct pipe_context *pipe,
 			  struct pipe_buffer *ib, unsigned ib_size,
 			  unsigned mode, unsigned start, unsigned count)
@@ -393,15 +401,16 @@
 	}
 
 	pipe_buffer_unmap(pscreen, ib);
-	return TRUE;
 }
 
-static boolean
+static void
 nv30_draw_elements_vbo(struct pipe_context *pipe,
 		       unsigned mode, unsigned start, unsigned count)
 {
 	struct nv30_context *nv30 = nv30_context(pipe);
-	struct nouveau_channel *chan = nv30->screen->base.channel;
+	struct nv30_screen *screen = nv30->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *rankine = screen->rankine;
 	unsigned restart = 0;
 
 	while (count) {
@@ -412,17 +421,17 @@
 		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256,
 					mode, start, count, &restart);
 		if (!vc) {
-			FIRE_RING(NULL);
+			FIRE_RING(chan);
 			continue;
 		}
 		
-		BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1);
-		OUT_RING  (nvgl_primitive(mode));
+		BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+		OUT_RING  (chan, nvgl_primitive(mode));
 
 		nr = (vc & 0xff);
 		if (nr) {
-			BEGIN_RING(rankine, NV34TCL_VB_INDEX_BATCH, 1);
-			OUT_RING  (((nr - 1) << 24) | start);
+			BEGIN_RING(chan, rankine, NV34TCL_VB_INDEX_BATCH, 1);
+			OUT_RING  (chan, ((nr - 1) << 24) | start);
 			start += nr;
 		}
 
@@ -432,24 +441,22 @@
 
 			nr -= push;
 
-			BEGIN_RING_NI(rankine, NV34TCL_VB_INDEX_BATCH, push);
+			BEGIN_RING_NI(chan, rankine, NV34TCL_VB_INDEX_BATCH, push);
 			while (push--) {
-				OUT_RING(((0x100 - 1) << 24) | start);
+				OUT_RING(chan, ((0x100 - 1) << 24) | start);
 				start += 0x100;
 			}
 		}
 
-		BEGIN_RING(rankine, NV34TCL_VERTEX_BEGIN_END, 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+		OUT_RING  (chan, 0);
 
 		count -= vc;
 		start = restart;
 	}
-
-	return TRUE;
 }
 
-boolean
+void
 nv30_draw_elements(struct pipe_context *pipe,
 		   struct pipe_buffer *indexBuffer, unsigned indexSize,
 		   unsigned mode, unsigned start, unsigned count)
@@ -461,7 +468,7 @@
 	if (FORCE_SWTNL || !nv30_state_validate(nv30)) {
 		/*return nv30_draw_elements_swtnl(pipe, NULL, 0,
 						mode, start, count);*/
-		return FALSE;	
+		return;	
 	}
 
 	if (idxbuf) {
@@ -472,7 +479,6 @@
 	}
 
 	pipe->flush(pipe, 0, NULL);
-	return TRUE;
 }
 
 static boolean
@@ -485,14 +491,9 @@
 	unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
 	int hw;
 
-	if (nv30->edgeflags) {
-		/*nv30->fallback_swtnl |= NV30_NEW_ARRAYS;*/
-		return FALSE;
-	}
-
-	vtxbuf = so_new(20, 18);
+	vtxbuf = so_new(3, 17, 18);
 	so_method(vtxbuf, rankine, NV34TCL_VTXBUF_ADDRESS(0), nv30->vtxelt_nr);
-	vtxfmt = so_new(17, 0);
+	vtxfmt = so_new(1, 16, 0);
 	so_method(vtxfmt, rankine, NV34TCL_VTXFMT(0), nv30->vtxelt_nr);
 
 	for (hw = 0; hw < nv30->vtxelt_nr; hw++) {
@@ -505,7 +506,7 @@
 
 		if (!vb->stride) {
 			if (!sattr)
-				sattr = so_new(16 * 5, 0);
+				sattr = so_new(16, 16 * 4, 0);
 
 			if (nv30_vbo_static_attrib(nv30, sattr, hw, ve, vb)) {
 				so_data(vtxbuf, 0);
diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c
index 14a5c02..e77a5be 100644
--- a/src/gallium/drivers/nv30/nv30_vertprog.c
+++ b/src/gallium/drivers/nv30/nv30_vertprog.c
@@ -253,32 +253,32 @@
 tgsi_src(struct nv30_vpc *vpc, const struct tgsi_full_src_register *fsrc) {
 	struct nv30_sreg src;
 
-	switch (fsrc->SrcRegister.File) {
+	switch (fsrc->Register.File) {
 	case TGSI_FILE_INPUT:
-		src = nv30_sr(NV30SR_INPUT, fsrc->SrcRegister.Index);
+		src = nv30_sr(NV30SR_INPUT, fsrc->Register.Index);
 		break;
 	case TGSI_FILE_CONSTANT:
-		src = constant(vpc, fsrc->SrcRegister.Index, 0, 0, 0, 0);
+		src = constant(vpc, fsrc->Register.Index, 0, 0, 0, 0);
 		break;
 	case TGSI_FILE_IMMEDIATE:
-		src = vpc->imm[fsrc->SrcRegister.Index];
+		src = vpc->imm[fsrc->Register.Index];
 		break;
 	case TGSI_FILE_TEMPORARY:
-		if (vpc->high_temp < fsrc->SrcRegister.Index)
-			vpc->high_temp = fsrc->SrcRegister.Index;
-		src = nv30_sr(NV30SR_TEMP, fsrc->SrcRegister.Index);
+		if (vpc->high_temp < fsrc->Register.Index)
+			vpc->high_temp = fsrc->Register.Index;
+		src = nv30_sr(NV30SR_TEMP, fsrc->Register.Index);
 		break;
 	default:
 		NOUVEAU_ERR("bad src file\n");
 		break;
 	}
 
-	src.abs = fsrc->SrcRegisterExtMod.Absolute;
-	src.negate = fsrc->SrcRegister.Negate;
-	src.swz[0] = fsrc->SrcRegister.SwizzleX;
-	src.swz[1] = fsrc->SrcRegister.SwizzleY;
-	src.swz[2] = fsrc->SrcRegister.SwizzleZ;
-	src.swz[3] = fsrc->SrcRegister.SwizzleW;
+	src.abs = fsrc->Register.Absolute;
+	src.negate = fsrc->Register.Negate;
+	src.swz[0] = fsrc->Register.SwizzleX;
+	src.swz[1] = fsrc->Register.SwizzleY;
+	src.swz[2] = fsrc->Register.SwizzleZ;
+	src.swz[3] = fsrc->Register.SwizzleW;
 	return src;
 }
 
@@ -286,14 +286,14 @@
 tgsi_dst(struct nv30_vpc *vpc, const struct tgsi_full_dst_register *fdst) {
 	struct nv30_sreg dst;
 
-	switch (fdst->DstRegister.File) {
+	switch (fdst->Register.File) {
 	case TGSI_FILE_OUTPUT:
 		dst = nv30_sr(NV30SR_OUTPUT,
-			      vpc->output_map[fdst->DstRegister.Index]);
+			      vpc->output_map[fdst->Register.Index]);
 
 		break;
 	case TGSI_FILE_TEMPORARY:
-		dst = nv30_sr(NV30SR_TEMP, fdst->DstRegister.Index);
+		dst = nv30_sr(NV30SR_TEMP, fdst->Register.Index);
 		if (vpc->high_temp < dst.index)
 			vpc->high_temp = dst.index;
 		break;
@@ -334,8 +334,8 @@
 	for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
 		const struct tgsi_full_src_register *fsrc;
 
-		fsrc = &finst->FullSrcRegisters[i];
-		if (fsrc->SrcRegister.File == TGSI_FILE_TEMPORARY) {
+		fsrc = &finst->Src[i];
+		if (fsrc->Register.File == TGSI_FILE_TEMPORARY) {
 			src[i] = tgsi_src(vpc, fsrc);
 		}
 	}
@@ -343,11 +343,11 @@
 	for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
 		const struct tgsi_full_src_register *fsrc;
 
-		fsrc = &finst->FullSrcRegisters[i];
-		switch (fsrc->SrcRegister.File) {
+		fsrc = &finst->Src[i];
+		switch (fsrc->Register.File) {
 		case TGSI_FILE_INPUT:
-			if (ai == -1 || ai == fsrc->SrcRegister.Index) {
-				ai = fsrc->SrcRegister.Index;
+			if (ai == -1 || ai == fsrc->Register.Index) {
+				ai = fsrc->Register.Index;
 				src[i] = tgsi_src(vpc, fsrc);
 			} else {
 				src[i] = temp(vpc);
@@ -360,8 +360,8 @@
 		 */
 		case TGSI_FILE_CONSTANT:
 		case TGSI_FILE_IMMEDIATE:
-			if (ci == -1 || ci == fsrc->SrcRegister.Index) {
-				ci = fsrc->SrcRegister.Index;
+			if (ci == -1 || ci == fsrc->Register.Index) {
+				ci = fsrc->Register.Index;
 				src[i] = tgsi_src(vpc, fsrc);
 			} else {
 				src[i] = temp(vpc);
@@ -378,8 +378,8 @@
 		}
 	}
 
-	dst  = tgsi_dst(vpc, &finst->FullDstRegisters[0]);
-	mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask);
+	dst  = tgsi_dst(vpc, &finst->Dst[0]);
+	mask = tgsi_mask(finst->Dst[0].Register.WriteMask);
 
 	switch (finst->Instruction.Opcode) {
 	case TGSI_OPCODE_ABS:
@@ -490,15 +490,15 @@
 {
 	int hw;
 
-	switch (fdec->Semantic.SemanticName) {
+	switch (fdec->Semantic.Name) {
 	case TGSI_SEMANTIC_POSITION:
 		hw = NV30_VP_INST_DEST_POS;
 		break;
 	case TGSI_SEMANTIC_COLOR:
-		if (fdec->Semantic.SemanticIndex == 0) {
+		if (fdec->Semantic.Index == 0) {
 			hw = NV30_VP_INST_DEST_COL0;
 		} else
-		if (fdec->Semantic.SemanticIndex == 1) {
+		if (fdec->Semantic.Index == 1) {
 			hw = NV30_VP_INST_DEST_COL1;
 		} else {
 			NOUVEAU_ERR("bad colour semantic index\n");
@@ -506,10 +506,10 @@
 		}
 		break;
 	case TGSI_SEMANTIC_BCOLOR:
-		if (fdec->Semantic.SemanticIndex == 0) {
+		if (fdec->Semantic.Index == 0) {
 			hw = NV30_VP_INST_DEST_BFC0;
 		} else
-		if (fdec->Semantic.SemanticIndex == 1) {
+		if (fdec->Semantic.Index == 1) {
 			hw = NV30_VP_INST_DEST_BFC1;
 		} else {
 			NOUVEAU_ERR("bad bcolour semantic index\n");
@@ -523,19 +523,22 @@
 		hw = NV30_VP_INST_DEST_PSZ;
 		break;
 	case TGSI_SEMANTIC_GENERIC:
-		if (fdec->Semantic.SemanticIndex <= 7) {
-			hw = NV30_VP_INST_DEST_TC(fdec->Semantic.SemanticIndex);
+		if (fdec->Semantic.Index <= 7) {
+			hw = NV30_VP_INST_DEST_TC(fdec->Semantic.Index);
 		} else {
 			NOUVEAU_ERR("bad generic semantic index\n");
 			return FALSE;
 		}
 		break;
+	case TGSI_SEMANTIC_EDGEFLAG:
+		NOUVEAU_ERR("cannot handle edgeflag output\n");
+		return FALSE;
 	default:
 		NOUVEAU_ERR("bad output semantic\n");
 		return FALSE;
 	}
 
-	vpc->output_map[fdec->DeclarationRange.First] = hw;
+	vpc->output_map[fdec->Range.First] = hw;
 	return TRUE;
 }
 
@@ -647,7 +650,9 @@
 nv30_vertprog_validate(struct nv30_context *nv30)
 { 
 	struct pipe_screen *pscreen = nv30->pipe.screen;
-	struct nouveau_grobj *rankine = nv30->screen->rankine;
+	struct nv30_screen *screen = nv30->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *rankine = screen->rankine;
 	struct nv30_vertex_program *vp;
 	struct pipe_buffer *constbuf;
 	boolean upload_code = FALSE, upload_data = FALSE;
@@ -681,7 +686,7 @@
 				assert(0);
 		}
 
-		so = so_new(2, 0);
+		so = so_new(1, 1, 0);
 		so_method(so, rankine, NV34TCL_VP_START_FROM_ID, 1);
 		so_data  (so, vp->exec->start);
 		so_ref(so, &vp->so);
@@ -767,9 +772,9 @@
 				       4 * sizeof(float));
 			}
 
-			BEGIN_RING(rankine, NV34TCL_VP_UPLOAD_CONST_ID, 5);
-			OUT_RING  (i + vp->data->start);
-			OUT_RINGp ((uint32_t *)vpd->value, 4);
+			BEGIN_RING(chan, rankine, NV34TCL_VP_UPLOAD_CONST_ID, 5);
+			OUT_RING  (chan, i + vp->data->start);
+			OUT_RINGp (chan, (uint32_t *)vpd->value, 4);
 		}
 
 		if (constbuf)
@@ -785,11 +790,11 @@
 				vp->insns[i].data[2], vp->insns[i].data[3]);
 		}
 #endif
-		BEGIN_RING(rankine, NV34TCL_VP_UPLOAD_FROM_ID, 1);
-		OUT_RING  (vp->exec->start);
+		BEGIN_RING(chan, rankine, NV34TCL_VP_UPLOAD_FROM_ID, 1);
+		OUT_RING  (chan, vp->exec->start);
 		for (i = 0; i < vp->nr_insns; i++) {
-			BEGIN_RING(rankine, NV34TCL_VP_UPLOAD_INST(0), 4);
-			OUT_RINGp (vp->insns[i].data, 4);
+			BEGIN_RING(chan, rankine, NV34TCL_VP_UPLOAD_INST(0), 4);
+			OUT_RINGp (chan, vp->insns[i].data, 4);
 		}
 	}
 
diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c
index 7f00827..f79ae4d 100644
--- a/src/gallium/drivers/nv40/nv40_context.c
+++ b/src/gallium/drivers/nv40/nv40_context.c
@@ -10,21 +10,32 @@
 	   struct pipe_fence_handle **fence)
 {
 	struct nv40_context *nv40 = nv40_context(pipe);
+	struct nv40_screen *screen = nv40->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *curie = screen->curie;
 
 	if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
-		BEGIN_RING(curie, 0x1fd8, 1);
-		OUT_RING  (2);
-		BEGIN_RING(curie, 0x1fd8, 1);
-		OUT_RING  (1);
+		BEGIN_RING(chan, curie, 0x1fd8, 1);
+		OUT_RING  (chan, 2);
+		BEGIN_RING(chan, curie, 0x1fd8, 1);
+		OUT_RING  (chan, 1);
 	}
 
-	FIRE_RING(fence);
+	FIRE_RING(chan);
+	if (fence)
+		*fence = NULL;
 }
 
 static void
 nv40_destroy(struct pipe_context *pipe)
 {
 	struct nv40_context *nv40 = nv40_context(pipe);
+	unsigned i;
+
+	for (i = 0; i < NV40_STATE_MAX; i++) {
+		if (nv40->state.hw[i])
+			so_ref(NULL, &nv40->state.hw[i]);
+	}
 
 	if (nv40->draw)
 		draw_destroy(nv40->draw);
@@ -58,6 +69,9 @@
 	nv40->pipe.is_texture_referenced = nouveau_is_texture_referenced;
 	nv40->pipe.is_buffer_referenced = nouveau_is_buffer_referenced;
 
+	screen->base.channel->user_private = nv40;
+	screen->base.channel->flush_notify = nv40_state_flush_notify;
+
 	nv40_init_query_functions(nv40);
 	nv40_init_surface_functions(nv40);
 	nv40_init_state_functions(nv40);
diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h
index a3d5941..e219bb5 100644
--- a/src/gallium/drivers/nv40/nv40_context.h
+++ b/src/gallium/drivers/nv40/nv40_context.h
@@ -14,10 +14,6 @@
 #include "nouveau/nouveau_winsys.h"
 #include "nouveau/nouveau_gldefs.h"
 #include "nouveau/nouveau_context.h"
-
-#define NOUVEAU_PUSH_CONTEXT(ctx)                                              \
-	struct nv40_screen *ctx = nv40->screen
-#include "nouveau/nouveau_push.h"
 #include "nouveau/nouveau_stateobj.h"
 
 #include "nv40_state.h"
@@ -159,7 +155,6 @@
 	unsigned vtxbuf_nr;
 	struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
 	unsigned vtxelt_nr;
-	const unsigned *edgeflags;
 };
 
 static INLINE struct nv40_context *
@@ -184,7 +179,7 @@
 
 /* nv40_draw.c */
 extern struct draw_stage *nv40_draw_render_stage(struct nv40_context *nv40);
-extern boolean nv40_draw_elements_swtnl(struct pipe_context *pipe,
+extern void nv40_draw_elements_swtnl(struct pipe_context *pipe,
 					struct pipe_buffer *idxbuf,
 					unsigned ib_size, unsigned mode,
 					unsigned start, unsigned count);
@@ -204,6 +199,7 @@
 extern boolean nv40_state_validate(struct nv40_context *nv40);
 extern boolean nv40_state_validate_swtnl(struct nv40_context *nv40);
 extern void nv40_state_emit(struct nv40_context *nv40);
+extern void nv40_state_flush_notify(struct nouveau_channel *chan);
 extern struct nv40_state_entry nv40_state_rasterizer;
 extern struct nv40_state_entry nv40_state_scissor;
 extern struct nv40_state_entry nv40_state_stipple;
@@ -219,9 +215,9 @@
 extern struct nv40_state_entry nv40_state_vtxfmt;
 
 /* nv40_vbo.c */
-extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode,
+extern void nv40_draw_arrays(struct pipe_context *, unsigned mode,
 				unsigned start, unsigned count);
-extern boolean nv40_draw_elements(struct pipe_context *pipe,
+extern void nv40_draw_elements(struct pipe_context *pipe,
 				  struct pipe_buffer *indexBuffer,
 				  unsigned indexSize,
 				  unsigned mode, unsigned start,
diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c
index b2f19ecb..d826f8c 100644
--- a/src/gallium/drivers/nv40/nv40_draw.c
+++ b/src/gallium/drivers/nv40/nv40_draw.c
@@ -31,6 +31,9 @@
 static INLINE void
 nv40_render_vertex(struct nv40_context *nv40, const struct vertex_header *v)
 {
+	struct nv40_screen *screen = nv40->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *curie = screen->curie;
 	unsigned i;
 
 	for (i = 0; i < nv40->swtnl.nr_attribs; i++) {
@@ -41,30 +44,30 @@
 		case EMIT_OMIT:
 			break;
 		case EMIT_1F:
-			BEGIN_RING(curie, NV40TCL_VTX_ATTR_1F(hw), 1);
-			OUT_RING  (fui(v->data[idx][0]));
+			BEGIN_RING(chan, curie, NV40TCL_VTX_ATTR_1F(hw), 1);
+			OUT_RING  (chan, fui(v->data[idx][0]));
 			break;
 		case EMIT_2F:
-			BEGIN_RING(curie, NV40TCL_VTX_ATTR_2F_X(hw), 2);
-			OUT_RING  (fui(v->data[idx][0]));
-			OUT_RING  (fui(v->data[idx][1]));
+			BEGIN_RING(chan, curie, NV40TCL_VTX_ATTR_2F_X(hw), 2);
+			OUT_RING  (chan, fui(v->data[idx][0]));
+			OUT_RING  (chan, fui(v->data[idx][1]));
 			break;
 		case EMIT_3F:
-			BEGIN_RING(curie, NV40TCL_VTX_ATTR_3F_X(hw), 3);
-			OUT_RING  (fui(v->data[idx][0]));
-			OUT_RING  (fui(v->data[idx][1]));
-			OUT_RING  (fui(v->data[idx][2]));
+			BEGIN_RING(chan, curie, NV40TCL_VTX_ATTR_3F_X(hw), 3);
+			OUT_RING  (chan, fui(v->data[idx][0]));
+			OUT_RING  (chan, fui(v->data[idx][1]));
+			OUT_RING  (chan, fui(v->data[idx][2]));
 			break;
 		case EMIT_4F:
-			BEGIN_RING(curie, NV40TCL_VTX_ATTR_4F_X(hw), 4);
-			OUT_RING  (fui(v->data[idx][0]));
-			OUT_RING  (fui(v->data[idx][1]));
-			OUT_RING  (fui(v->data[idx][2]));
-			OUT_RING  (fui(v->data[idx][3]));
+			BEGIN_RING(chan, curie, NV40TCL_VTX_ATTR_4F_X(hw), 4);
+			OUT_RING  (chan, fui(v->data[idx][0]));
+			OUT_RING  (chan, fui(v->data[idx][1]));
+			OUT_RING  (chan, fui(v->data[idx][2]));
+			OUT_RING  (chan, fui(v->data[idx][3]));
 			break;
 		case EMIT_4UB:
-			BEGIN_RING(curie, NV40TCL_VTX_ATTR_4UB(hw), 1);
-			OUT_RING  (pack_ub4(float_to_ubyte(v->data[idx][0]),
+			BEGIN_RING(chan, curie, NV40TCL_VTX_ATTR_4UB(hw), 1);
+			OUT_RING  (chan, pack_ub4(float_to_ubyte(v->data[idx][0]),
 					    float_to_ubyte(v->data[idx][1]),
 					    float_to_ubyte(v->data[idx][2]),
 					    float_to_ubyte(v->data[idx][3])));
@@ -82,7 +85,11 @@
 {
 	struct nv40_render_stage *rs = nv40_render_stage(stage);
 	struct nv40_context *nv40 = rs->nv40;
-	struct nouveau_pushbuf *pb = nv40->screen->base.channel->pushbuf;
+
+	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 */
@@ -91,19 +98,19 @@
 			NOUVEAU_ERR("AIII, missed flush\n");
 			assert(0);
 		}
-		FIRE_RING(NULL);
+		FIRE_RING(chan);
 		nv40_state_emit(nv40);
 	}
 
 	/* Switch primitive modes if necessary */
 	if (rs->prim != mode) {
 		if (rs->prim != NV40TCL_BEGIN_END_STOP) {
-			BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
-			OUT_RING  (NV40TCL_BEGIN_END_STOP);	
+			BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
+			OUT_RING  (chan, NV40TCL_BEGIN_END_STOP);
 		}
 
-		BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
-		OUT_RING  (mode);
+		BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
+		OUT_RING  (chan, mode);
 		rs->prim = mode;
 	}
 
@@ -115,8 +122,8 @@
 	 * off the primitive now.
 	 */
 	if (pb->remaining < ((count * 20) + 6)) {
-		BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
-		OUT_RING  (NV40TCL_BEGIN_END_STOP);
+		BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
+		OUT_RING  (chan, NV40TCL_BEGIN_END_STOP);
 		rs->prim = NV40TCL_BEGIN_END_STOP;
 	}
 }
@@ -144,10 +151,13 @@
 {
 	struct nv40_render_stage *rs = nv40_render_stage(draw);
 	struct nv40_context *nv40 = rs->nv40;
+	struct nv40_screen *screen = nv40->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *curie = screen->curie;
 
 	if (rs->prim != NV40TCL_BEGIN_END_STOP) {
-		BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
-		OUT_RING  (NV40TCL_BEGIN_END_STOP);
+		BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
+		OUT_RING  (chan, NV40TCL_BEGIN_END_STOP);
 		rs->prim = NV40TCL_BEGIN_END_STOP;
 	}
 }
@@ -226,7 +236,7 @@
 	return &render->stage;
 }
 
-boolean
+void
 nv40_draw_elements_swtnl(struct pipe_context *pipe,
 			 struct pipe_buffer *idxbuf, unsigned idxbuf_size,
 			 unsigned mode, unsigned start, unsigned count)
@@ -237,7 +247,7 @@
 	void *map;
 
 	if (!nv40_state_validate_swtnl(nv40))
-		return FALSE;
+		return;
 	nv40->state.dirty &= ~(1ULL << NV40_STATE_VTXBUF);
 	nv40_state_emit(nv40);
 
@@ -261,7 +271,8 @@
 		map = pipe_buffer_map(pscreen,
 				      nv40->constbuf[PIPE_SHADER_VERTEX],
 				      PIPE_BUFFER_USAGE_CPU_READ);
-		draw_set_mapped_constant_buffer(nv40->draw, map, nr);
+		draw_set_mapped_constant_buffer(nv40->draw, PIPE_SHADER_VERTEX,
+                                                map, nr);
 	}
 
 	draw_arrays(nv40->draw, mode, start, count);
@@ -277,15 +288,13 @@
 
 	draw_flush(nv40->draw);
 	pipe->flush(pipe, 0, NULL);
-
-	return TRUE;
 }
 
 static INLINE void
 emit_attrib(struct nv40_context *nv40, unsigned hw, unsigned emit,
 	    unsigned semantic, unsigned index)
 {
-	unsigned draw_out = draw_find_vs_output(nv40->draw, semantic, index);
+	unsigned draw_out = draw_find_shader_output(nv40->draw, semantic, index);
 	unsigned a = nv40->swtnl.nr_attribs++;
 
 	nv40->swtnl.hw[a] = hw;
diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c
index 9927750..1237066 100644
--- a/src/gallium/drivers/nv40/nv40_fragprog.c
+++ b/src/gallium/drivers/nv40/nv40_fragprog.c
@@ -149,7 +149,7 @@
 				sizeof(uint32_t) * 4);
 		}
 
-		sr |= (NV40_FP_REG_TYPE_CONST << NV40_FP_REG_TYPE_SHIFT);	
+		sr |= (NV40_FP_REG_TYPE_CONST << NV40_FP_REG_TYPE_SHIFT);
 		break;
 	case NV40SR_NONE:
 		sr |= (NV40_FP_REG_TYPE_INPUT << NV40_FP_REG_TYPE_SHIFT);
@@ -255,50 +255,50 @@
 {
 	struct nv40_sreg src;
 
-	switch (fsrc->SrcRegister.File) {
+	switch (fsrc->Register.File) {
 	case TGSI_FILE_INPUT:
 		src = nv40_sr(NV40SR_INPUT,
-			      fpc->attrib_map[fsrc->SrcRegister.Index]);
+			      fpc->attrib_map[fsrc->Register.Index]);
 		break;
 	case TGSI_FILE_CONSTANT:
-		src = constant(fpc, fsrc->SrcRegister.Index, NULL);
+		src = constant(fpc, fsrc->Register.Index, NULL);
 		break;
 	case TGSI_FILE_IMMEDIATE:
-		assert(fsrc->SrcRegister.Index < fpc->nr_imm);
-		src = fpc->imm[fsrc->SrcRegister.Index];
+		assert(fsrc->Register.Index < fpc->nr_imm);
+		src = fpc->imm[fsrc->Register.Index];
 		break;
 	case TGSI_FILE_TEMPORARY:
-		src = fpc->r_temp[fsrc->SrcRegister.Index];
+		src = fpc->r_temp[fsrc->Register.Index];
 		break;
 	/* NV40 fragprog result regs are just temps, so this is simple */
 	case TGSI_FILE_OUTPUT:
-		src = fpc->r_result[fsrc->SrcRegister.Index];
+		src = fpc->r_result[fsrc->Register.Index];
 		break;
 	default:
 		NOUVEAU_ERR("bad src file\n");
 		break;
 	}
 
-	src.abs = fsrc->SrcRegisterExtMod.Absolute;
-	src.negate = fsrc->SrcRegister.Negate;
-	src.swz[0] = fsrc->SrcRegister.SwizzleX;
-	src.swz[1] = fsrc->SrcRegister.SwizzleY;
-	src.swz[2] = fsrc->SrcRegister.SwizzleZ;
-	src.swz[3] = fsrc->SrcRegister.SwizzleW;
+	src.abs = fsrc->Register.Absolute;
+	src.negate = fsrc->Register.Negate;
+	src.swz[0] = fsrc->Register.SwizzleX;
+	src.swz[1] = fsrc->Register.SwizzleY;
+	src.swz[2] = fsrc->Register.SwizzleZ;
+	src.swz[3] = fsrc->Register.SwizzleW;
 	return src;
 }
 
 static INLINE struct nv40_sreg
 tgsi_dst(struct nv40_fpc *fpc, const struct tgsi_full_dst_register *fdst) {
-	switch (fdst->DstRegister.File) {
+	switch (fdst->Register.File) {
 	case TGSI_FILE_OUTPUT:
-		return fpc->r_result[fdst->DstRegister.Index];
+		return fpc->r_result[fdst->Register.Index];
 	case TGSI_FILE_TEMPORARY:
-		return fpc->r_temp[fdst->DstRegister.Index];
+		return fpc->r_temp[fdst->Register.Index];
 	case TGSI_FILE_NULL:
 		return nv40_sr(NV40SR_NONE, 0);
 	default:
-		NOUVEAU_ERR("bad dst file %d\n", fdst->DstRegister.File);
+		NOUVEAU_ERR("bad dst file %d\n", fdst->Register.File);
 		return nv40_sr(NV40SR_NONE, 0);
 	}
 }
@@ -364,8 +364,8 @@
 	for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
 		const struct tgsi_full_src_register *fsrc;
 
-		fsrc = &finst->FullSrcRegisters[i];
-		if (fsrc->SrcRegister.File == TGSI_FILE_TEMPORARY) {
+		fsrc = &finst->Src[i];
+		if (fsrc->Register.File == TGSI_FILE_TEMPORARY) {
 			src[i] = tgsi_src(fpc, fsrc);
 		}
 	}
@@ -373,9 +373,9 @@
 	for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
 		const struct tgsi_full_src_register *fsrc;
 
-		fsrc = &finst->FullSrcRegisters[i];
+		fsrc = &finst->Src[i];
 
-		switch (fsrc->SrcRegister.File) {
+		switch (fsrc->Register.File) {
 		case TGSI_FILE_INPUT:
 		case TGSI_FILE_CONSTANT:
 		case TGSI_FILE_TEMPORARY:
@@ -386,10 +386,10 @@
 			break;
 		}
 
-		switch (fsrc->SrcRegister.File) {
+		switch (fsrc->Register.File) {
 		case TGSI_FILE_INPUT:
-			if (ai == -1 || ai == fsrc->SrcRegister.Index) {
-				ai = fsrc->SrcRegister.Index;
+			if (ai == -1 || ai == fsrc->Register.Index) {
+				ai = fsrc->Register.Index;
 				src[i] = tgsi_src(fpc, fsrc);
 			} else {
 				src[i] = temp(fpc);
@@ -399,8 +399,8 @@
 			break;
 		case TGSI_FILE_CONSTANT:
 			if ((ci == -1 && ii == -1) ||
-			    ci == fsrc->SrcRegister.Index) {
-				ci = fsrc->SrcRegister.Index;
+			    ci == fsrc->Register.Index) {
+				ci = fsrc->Register.Index;
 				src[i] = tgsi_src(fpc, fsrc);
 			} else {
 				src[i] = temp(fpc);
@@ -410,8 +410,8 @@
 			break;
 		case TGSI_FILE_IMMEDIATE:
 			if ((ci == -1 && ii == -1) ||
-			    ii == fsrc->SrcRegister.Index) {
-				ii = fsrc->SrcRegister.Index;
+			    ii == fsrc->Register.Index) {
+				ii = fsrc->Register.Index;
 				src[i] = tgsi_src(fpc, fsrc);
 			} else {
 				src[i] = temp(fpc);
@@ -423,7 +423,7 @@
 			/* handled above */
 			break;
 		case TGSI_FILE_SAMPLER:
-			unit = fsrc->SrcRegister.Index;
+			unit = fsrc->Register.Index;
 			break;
 		case TGSI_FILE_OUTPUT:
 			break;
@@ -433,8 +433,8 @@
 		}
 	}
 
-	dst  = tgsi_dst(fpc, &finst->FullDstRegisters[0]);
-	mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask);
+	dst  = tgsi_dst(fpc, &finst->Dst[0]);
+	mask = tgsi_mask(finst->Dst[0].Register.WriteMask);
 	sat  = (finst->Instruction.Saturate == TGSI_SAT_ZERO_ONE);
 
 	switch (finst->Instruction.Opcode) {
@@ -445,10 +445,11 @@
 		arith(fpc, sat, ADD, dst, mask, src[0], src[1], none);
 		break;
 	case TGSI_OPCODE_CMP:
-		tmp = temp(fpc);
-		arith(fpc, sat, MOV, dst, mask, src[2], none, none);
+		tmp = nv40_sr(NV40SR_NONE, 0);
 		tmp.cc_update = 1;
 		arith(fpc, 0, MOV, tmp, 0xf, src[0], none, none);
+		dst.cc_test = NV40_VP_INST_COND_GE;
+		arith(fpc, sat, MOV, dst, mask, src[2], none, none);
 		dst.cc_test = NV40_VP_INST_COND_LT;
 		arith(fpc, sat, MOV, dst, mask, src[1], none, none);
 		break;
@@ -573,13 +574,28 @@
 		      neg(swz(tmp, X, X, X, X)), none, none);
 		break;
 	case TGSI_OPCODE_SCS:
-		if (mask & MASK_X) {
-			arith(fpc, sat, COS, dst, MASK_X,
-			      swz(src[0], X, X, X, X), none, none);
+		/* avoid overwriting the source */
+		if(src[0].swz[SWZ_X] != SWZ_X)
+		{
+			if (mask & MASK_X) {
+				arith(fpc, sat, COS, dst, MASK_X,
+				      swz(src[0], X, X, X, X), none, none);
+			}
+			if (mask & MASK_Y) {
+				arith(fpc, sat, SIN, dst, MASK_Y,
+				      swz(src[0], X, X, X, X), none, none);
+			}
 		}
-		if (mask & MASK_Y) {
-			arith(fpc, sat, SIN, dst, MASK_Y,
-			      swz(src[0], X, X, X, X), none, none);
+		else
+		{
+			if (mask & MASK_Y) {
+				arith(fpc, sat, SIN, dst, MASK_Y,
+				      swz(src[0], X, X, X, X), none, none);
+			}
+			if (mask & MASK_X) {
+				arith(fpc, sat, COS, dst, MASK_X,
+				      swz(src[0], X, X, X, X), none, none);
+			}
 		}
 		break;
 	case TGSI_OPCODE_SEQ:
@@ -644,15 +660,15 @@
 {
 	int hw;
 
-	switch (fdec->Semantic.SemanticName) {
+	switch (fdec->Semantic.Name) {
 	case TGSI_SEMANTIC_POSITION:
 		hw = NV40_FP_OP_INPUT_SRC_POSITION;
 		break;
 	case TGSI_SEMANTIC_COLOR:
-		if (fdec->Semantic.SemanticIndex == 0) {
+		if (fdec->Semantic.Index == 0) {
 			hw = NV40_FP_OP_INPUT_SRC_COL0;
 		} else
-		if (fdec->Semantic.SemanticIndex == 1) {
+		if (fdec->Semantic.Index == 1) {
 			hw = NV40_FP_OP_INPUT_SRC_COL1;
 		} else {
 			NOUVEAU_ERR("bad colour semantic index\n");
@@ -663,9 +679,9 @@
 		hw = NV40_FP_OP_INPUT_SRC_FOGC;
 		break;
 	case TGSI_SEMANTIC_GENERIC:
-		if (fdec->Semantic.SemanticIndex <= 7) {
+		if (fdec->Semantic.Index <= 7) {
 			hw = NV40_FP_OP_INPUT_SRC_TC(fdec->Semantic.
-						     SemanticIndex);
+						     Index);
 		} else {
 			NOUVEAU_ERR("bad generic semantic index\n");
 			return FALSE;
@@ -676,7 +692,7 @@
 		return FALSE;
 	}
 
-	fpc->attrib_map[fdec->DeclarationRange.First] = hw;
+	fpc->attrib_map[fdec->Range.First] = hw;
 	return TRUE;
 }
 
@@ -684,15 +700,15 @@
 nv40_fragprog_parse_decl_output(struct nv40_fpc *fpc,
 				const struct tgsi_full_declaration *fdec)
 {
-	unsigned idx = fdec->DeclarationRange.First;
+	unsigned idx = fdec->Range.First;
 	unsigned hw;
 
-	switch (fdec->Semantic.SemanticName) {
+	switch (fdec->Semantic.Name) {
 	case TGSI_SEMANTIC_POSITION:
 		hw = 1;
 		break;
 	case TGSI_SEMANTIC_COLOR:
-		switch (fdec->Semantic.SemanticIndex) {
+		switch (fdec->Semantic.Index) {
 		case 0: hw = 0; break;
 		case 1: hw = 2; break;
 		case 2: hw = 3; break;
@@ -738,9 +754,9 @@
 					goto out_err;
 				break;
 			case TGSI_FILE_TEMPORARY:
-				if (fdec->DeclarationRange.Last > high_temp) {
+				if (fdec->Range.Last > high_temp) {
 					high_temp =
-						fdec->DeclarationRange.Last;
+						fdec->Range.Last;
 				}
 				break;
 			default:
@@ -752,7 +768,7 @@
 		{
 			struct tgsi_full_immediate *imm;
 			float vals[4];
-			
+
 			imm = &p.FullToken.FullImmediate;
 			assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32);
 			assert(fpc->nr_imm < MAX_IMM);
@@ -836,7 +852,7 @@
 	fp->insn[fpc->inst_offset + 1] = 0x00000000;
 	fp->insn[fpc->inst_offset + 2] = 0x00000000;
 	fp->insn[fpc->inst_offset + 3] = 0x00000000;
-	
+
 	fp->translated = TRUE;
 out_err:
 	tgsi_parse_free(&parse);
@@ -903,7 +919,7 @@
 	fp->buffer = pscreen->buffer_create(pscreen, 0x100, 0, fp->insn_len * 4);
 	nv40_fragprog_upload(nv40, fp);
 
-	so = so_new(4, 1);
+	so = so_new(2, 2, 1);
 	so_method(so, nv40->screen->curie, NV40TCL_FP_ADDRESS, 1);
 	so_reloc (so, nouveau_bo(fp->buffer), 0, NOUVEAU_BO_VRAM |
 		      NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW |
@@ -917,7 +933,7 @@
 update_constants:
 	if (fp->nr_consts) {
 		float *map;
-		
+
 		map = pipe_buffer_map(pscreen, constbuf,
 				      PIPE_BUFFER_USAGE_CPU_READ);
 		for (i = 0; i < fp->nr_consts; i++) {
@@ -948,6 +964,12 @@
 nv40_fragprog_destroy(struct nv40_context *nv40,
 		      struct nv40_fragment_program *fp)
 {
+	if (fp->buffer)
+		pipe_buffer_reference(&fp->buffer, NULL);
+
+	if (fp->so)
+		so_ref(NULL, &fp->so);
+
 	if (fp->insn_len)
 		FREE(fp->insn);
 }
diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c
index e2ec575..aad9198 100644
--- a/src/gallium/drivers/nv40/nv40_fragtex.c
+++ b/src/gallium/drivers/nv40/nv40_fragtex.c
@@ -108,7 +108,7 @@
 
 	txs = tf->swizzle;
 
-	so = so_new(16, 2);
+	so = so_new(2, 9, 2);
 	so_method(so, nv40->screen->curie, NV40TCL_TEX_OFFSET(unit), 8);
 	so_reloc (so, bo, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0);
 	so_reloc (so, bo, txf, tex_flags | NOUVEAU_BO_OR,
@@ -117,11 +117,11 @@
 	so_data  (so, NV40TCL_TEX_ENABLE_ENABLE | ps->en);
 	so_data  (so, txs);
 	so_data  (so, ps->filt | tf->sign | 0x2000 /*voodoo*/);
-	so_data  (so, (pt->width[0] << NV40TCL_TEX_SIZE0_W_SHIFT) |
-		       pt->height[0]);
+	so_data  (so, (pt->width0 << NV40TCL_TEX_SIZE0_W_SHIFT) |
+		       pt->height0);
 	so_data  (so, ps->bcol);
 	so_method(so, nv40->screen->curie, NV40TCL_TEX_SIZE1(unit), 1);
-	so_data  (so, (pt->depth[0] << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp);
+	so_data  (so, (pt->depth0 << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp);
 
 	return so;
 }
@@ -139,7 +139,7 @@
 		unit = ffs(samplers) - 1;
 		samplers &= ~(1 << unit);
 
-		so = so_new(2, 0);
+		so = so_new(1, 1, 0);
 		so_method(so, nv40->screen->curie, NV40TCL_TEX_ENABLE(unit), 1);
 		so_data  (so, 0);
 		so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]);
diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c
index 465dd3b..89bd155 100644
--- a/src/gallium/drivers/nv40/nv40_miptree.c
+++ b/src/gallium/drivers/nv40/nv40_miptree.c
@@ -1,14 +1,19 @@
 #include "pipe/p_state.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
 
 #include "nv40_context.h"
+#include "../nv04/nv04_surface_2d.h"
+
+
 
 static void
 nv40_miptree_layout(struct nv40_miptree *mt)
 {
 	struct pipe_texture *pt = &mt->base;
-	uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0];
+	uint width = pt->width0;
 	uint offset = 0;
 	int nr_faces, l, f;
 	uint wide_pitch = pt->tex_usage & (PIPE_TEXTURE_USAGE_SAMPLER |
@@ -21,29 +26,21 @@
 		nr_faces = 6;
 	} else
 	if (pt->target == PIPE_TEXTURE_3D) {
-		nr_faces = pt->depth[0];
+		nr_faces = pt->depth0;
 	} else {
 		nr_faces = 1;
 	}
 
 	for (l = 0; l <= pt->last_level; l++) {
-		pt->width[l] = width;
-		pt->height[l] = height;
-		pt->depth[l] = depth;
-		pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width);
-		pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height);
-
 		if (wide_pitch && (pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR))
-			mt->level[l].pitch = align(pt->width[0] * pt->block.size, 64);
+			mt->level[l].pitch = align(util_format_get_stride(pt->format, pt->width0), 64);
 		else
-			mt->level[l].pitch = pt->width[l] * pt->block.size;
+			mt->level[l].pitch = util_format_get_stride(pt->format, width);
 
 		mt->level[l].image_offset =
 			CALLOC(nr_faces, sizeof(unsigned));
 
-		width  = MAX2(1, width  >> 1);
-		height = MAX2(1, height >> 1);
-		depth  = MAX2(1, depth  >> 1);
+		width  = u_minify(width, 1);
 	}
 
 	for (f = 0; f < nr_faces; f++) {
@@ -51,14 +48,14 @@
 			mt->level[l].image_offset[f] = offset;
 
 			if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) &&
-			    pt->width[l + 1] > 1 && pt->height[l + 1] > 1)
-				offset += align(mt->level[l].pitch * pt->height[l], 64);
+			    u_minify(pt->width0, l + 1) > 1 && u_minify(pt->height0, l + 1) > 1)
+				offset += align(mt->level[l].pitch * u_minify(pt->height0, l), 64);
 			else
-				offset += mt->level[l].pitch * pt->height[l];
+				offset += mt->level[l].pitch * u_minify(pt->height0, l);
 		}
 
 		mt->level[l].image_offset[f] = offset;
-		offset += mt->level[l].pitch * pt->height[l];
+		offset += mt->level[l].pitch * u_minify(pt->height0, l);
 	}
 
 	mt->total_size = offset;
@@ -79,8 +76,8 @@
 	mt->base.screen = pscreen;
 
 	/* Swizzled textures must be POT */
-	if (pt->width[0] & (pt->width[0] - 1) ||
-	    pt->height[0] & (pt->height[0] - 1))
+	if (pt->width0 & (pt->width0 - 1) ||
+	    pt->height0 & (pt->height0 - 1))
 		mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
 	else
 	if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY |
@@ -109,6 +106,12 @@
 	if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC)
 		buf_usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE;
 
+	/* apparently we can't render to swizzled surfaces smaller than 64 bytes, so make them linear.
+	 * If the user did not ask for a render target, they can still render to it, but it will cost them an extra copy.
+	 * This also happens for small mipmaps of large textures. */
+	if (pt->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET && util_format_get_stride(pt->format, pt->width0) < 64)
+		mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
+
 	nv40_miptree_layout(mt);
 
 	mt->buffer = pscreen->buffer_create(pscreen, 256, buf_usage, mt->total_size);
@@ -116,7 +119,7 @@
 		FREE(mt);
 		return NULL;
 	}
-
+	mt->bo = nouveau_bo(mt->buffer);
 	return &mt->base;
 }
 
@@ -128,7 +131,7 @@
 
 	/* Only supports 2D, non-mipmapped textures for the moment */
 	if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 ||
-	    pt->depth[0] != 1)
+	    pt->depth0 != 1)
 		return NULL;
 
 	mt = CALLOC_STRUCT(nv40_miptree);
@@ -145,6 +148,7 @@
 	mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
 
 	pipe_buffer_reference(&mt->buffer, pb);
+	mt->bo = nouveau_bo(mt->buffer);
 	return &mt->base;
 }
 
@@ -176,8 +180,8 @@
 		return NULL;
 	pipe_texture_reference(&ns->base.texture, pt);
 	ns->base.format = pt->format;
-	ns->base.width = pt->width[level];
-	ns->base.height = pt->height[level];
+	ns->base.width = u_minify(pt->width0, level);
+	ns->base.height = u_minify(pt->height0, level);
 	ns->base.usage = flags;
 	pipe_reference_init(&ns->base.reference, 1);
 	ns->base.face = face;
@@ -194,12 +198,27 @@
 		ns->base.offset = mt->level[level].image_offset[0];
 	}
 
+	/* create a linear temporary that we can render into if necessary.
+	 * Note that ns->pitch is always a multiple of 64 for linear surfaces and swizzled surfaces are POT, so
+	 * ns->pitch & 63 is equivalent to (ns->pitch < 64 && swizzled)*/
+	if((ns->pitch & 63) && (ns->base.usage & (PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER)) == PIPE_BUFFER_USAGE_GPU_WRITE)
+		return &nv04_surface_wrap_for_render(pscreen, ((struct nv40_screen*)pscreen)->eng2d, ns)->base;
+
 	return &ns->base;
 }
 
 static void
 nv40_miptree_surface_del(struct pipe_surface *ps)
 {
+	struct nv04_surface* ns = (struct nv04_surface*)ps;
+	if(ns->backing)
+	{
+		struct nv40_screen* screen = (struct nv40_screen*)ps->texture->screen;
+		if(ns->backing->base.usage & PIPE_BUFFER_USAGE_GPU_WRITE)
+			screen->eng2d->copy(screen->eng2d, &ns->backing->base, 0, 0, ps, 0, 0, ns->base.width, ns->base.height);
+		nv40_miptree_surface_del(&ns->backing->base);
+	}
+
 	pipe_texture_reference(&ps->texture, NULL);
 	FREE(ps);
 }
diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c
index 7874aed..8ed4a67 100644
--- a/src/gallium/drivers/nv40/nv40_query.c
+++ b/src/gallium/drivers/nv40/nv40_query.c
@@ -41,6 +41,9 @@
 {
 	struct nv40_context *nv40 = nv40_context(pipe);
 	struct nv40_query *q = nv40_query(pq);
+	struct nv40_screen *screen = nv40->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *curie = screen->curie;
 
 	assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
 
@@ -57,10 +60,10 @@
 		assert(0);
 	nouveau_notifier_reset(nv40->screen->query, q->object->start);
 
-	BEGIN_RING(curie, NV40TCL_QUERY_RESET, 1);
-	OUT_RING  (1);
-	BEGIN_RING(curie, NV40TCL_QUERY_UNK17CC, 1);
-	OUT_RING  (1);
+	BEGIN_RING(chan, curie, NV40TCL_QUERY_RESET, 1);
+	OUT_RING  (chan, 1);
+	BEGIN_RING(chan, curie, NV40TCL_QUERY_UNK17CC, 1);
+	OUT_RING  (chan, 1);
 
 	q->ready = FALSE;
 }
@@ -70,11 +73,14 @@
 {
 	struct nv40_context *nv40 = nv40_context(pipe);
 	struct nv40_query *q = nv40_query(pq);
+	struct nv40_screen *screen = nv40->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *curie = screen->curie;
 
-	BEGIN_RING(curie, NV40TCL_QUERY_GET, 1);
-	OUT_RING  ((0x01 << NV40TCL_QUERY_GET_UNK24_SHIFT) |
+	BEGIN_RING(chan, curie, NV40TCL_QUERY_GET, 1);
+	OUT_RING  (chan, (0x01 << NV40TCL_QUERY_GET_UNK24_SHIFT) |
 		   ((q->object->start * 32) << NV40TCL_QUERY_GET_OFFSET_SHIFT));
-	FIRE_RING(NULL);
+	FIRE_RING(chan);
 }
 
 static boolean
diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c
index bd13dfd..9e55e5a 100644
--- a/src/gallium/drivers/nv40/nv40_screen.c
+++ b/src/gallium/drivers/nv40/nv40_screen.c
@@ -140,6 +140,12 @@
 nv40_screen_destroy(struct pipe_screen *pscreen)
 {
 	struct nv40_screen *screen = nv40_screen(pscreen);
+	unsigned i;
+
+	for (i = 0; i < NV40_STATE_MAX; i++) {
+		if (screen->state[i])
+			so_ref(NULL, &screen->state[i]);
+	}
 
 	nouveau_resource_free(&screen->vp_exec_heap);
 	nouveau_resource_free(&screen->vp_data_heap);
@@ -147,6 +153,7 @@
 	nouveau_notifier_free(&screen->query);
 	nouveau_notifier_free(&screen->sync);
 	nouveau_grobj_free(&screen->curie);
+	nv04_surface_2d_takedown(&screen->eng2d);
 
 	nouveau_screen_fini(&screen->base);
 
@@ -208,7 +215,6 @@
 		NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
 		return FALSE;
 	}
-	BIND_RING(chan, screen->curie, 7);
 
 	/* 2D engine setup */
 	screen->eng2d = nv04_surface_2d_init(&screen->base);
@@ -245,7 +251,7 @@
 	}
 
 	/* Static curie initialisation */
-	so = so_new(128, 0);
+	so = so_new(16, 25, 0);
 	so_method(so, screen->curie, NV40TCL_DMA_NOTIFY, 1);
 	so_data  (so, screen->sync->handle);
 	so_method(so, screen->curie, NV40TCL_DMA_TEXTURE0, 2);
diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c
index c3ee4d2..ed0ca9e 100644
--- a/src/gallium/drivers/nv40/nv40_state.c
+++ b/src/gallium/drivers/nv40/nv40_state.c
@@ -16,7 +16,7 @@
 	struct nv40_context *nv40 = nv40_context(pipe);
 	struct nouveau_grobj *curie = nv40->screen->curie;
 	struct nv40_blend_state *bso = CALLOC(1, sizeof(*bso));
-	struct nouveau_stateobj *so = so_new(16, 0);
+	struct nouveau_stateobj *so = so_new(5, 8, 0);
 
 	if (cso->blend_enable) {
 		so_method(so, curie, NV40TCL_BLEND_ENABLE, 3);
@@ -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(32, 0);
+	struct nouveau_stateobj *so = so_new(8, 18, 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(32, 0);
+	struct nouveau_stateobj *so = so_new(4, 21, 0);
 	struct nouveau_grobj *curie = nv40->screen->curie;
 
 	so_method(so, curie, NV40TCL_DEPTH_FUNC, 3);
@@ -687,16 +687,6 @@
 	nv40->draw_dirty |= NV40_NEW_ARRAYS;
 }
 
-static void
-nv40_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
-{
-	struct nv40_context *nv40 = nv40_context(pipe);
-
-	nv40->edgeflags = bitfield;
-	nv40->dirty |= NV40_NEW_ARRAYS;
-	nv40->draw_dirty |= NV40_NEW_ARRAYS;
-}
-
 void
 nv40_init_state_functions(struct nv40_context *nv40)
 {
@@ -705,9 +695,9 @@
 	nv40->pipe.delete_blend_state = nv40_blend_state_delete;
 
 	nv40->pipe.create_sampler_state = nv40_sampler_state_create;
-	nv40->pipe.bind_sampler_states = nv40_sampler_state_bind;
+	nv40->pipe.bind_fragment_sampler_states = nv40_sampler_state_bind;
 	nv40->pipe.delete_sampler_state = nv40_sampler_state_delete;
-	nv40->pipe.set_sampler_textures = nv40_set_sampler_texture;
+	nv40->pipe.set_fragment_sampler_textures = nv40_set_sampler_texture;
 
 	nv40->pipe.create_rasterizer_state = nv40_rasterizer_state_create;
 	nv40->pipe.bind_rasterizer_state = nv40_rasterizer_state_bind;
@@ -736,7 +726,6 @@
 	nv40->pipe.set_scissor_state = nv40_set_scissor_state;
 	nv40->pipe.set_viewport_state = nv40_set_viewport_state;
 
-	nv40->pipe.set_edgeflags = nv40_set_edgeflags;
 	nv40->pipe.set_vertex_buffers = nv40_set_vertex_buffers;
 	nv40->pipe.set_vertex_elements = nv40_set_vertex_elements;
 }
diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h
index 8a9d8c8..192074e 100644
--- a/src/gallium/drivers/nv40/nv40_state.h
+++ b/src/gallium/drivers/nv40/nv40_state.h
@@ -75,6 +75,7 @@
 
 struct nv40_miptree {
 	struct pipe_texture base;
+	struct nouveau_bo *bo;
 
 	struct pipe_buffer *buffer;
 	uint total_size;
diff --git a/src/gallium/drivers/nv40/nv40_state_blend.c b/src/gallium/drivers/nv40/nv40_state_blend.c
index 8cd05ce..3ff00a3 100644
--- a/src/gallium/drivers/nv40/nv40_state_blend.c
+++ b/src/gallium/drivers/nv40/nv40_state_blend.c
@@ -18,7 +18,7 @@
 static boolean
 nv40_state_blend_colour_validate(struct nv40_context *nv40)
 {
-	struct nouveau_stateobj *so = so_new(2, 0);
+	struct nouveau_stateobj *so = so_new(1, 1, 0);
 	struct pipe_blend_color *bcol = &nv40->blend_colour;
 
 	so_method(so, nv40->screen->curie, NV40TCL_BLEND_COLOR, 1);
diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c
index 1986929..13fe854 100644
--- a/src/gallium/drivers/nv40/nv40_state_emit.c
+++ b/src/gallium/drivers/nv40/nv40_state_emit.c
@@ -54,10 +54,11 @@
 void
 nv40_state_emit(struct nv40_context *nv40)
 {
-	struct nouveau_channel *chan = nv40->screen->base.channel;
 	struct nv40_state *state = &nv40->state;
 	struct nv40_screen *screen = nv40->screen;
-	unsigned i, samplers;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *curie = screen->curie;
+	unsigned i;
 	uint64_t states;
 
 	if (nv40->pctx_id != screen->cur_pctx) {
@@ -80,13 +81,21 @@
 
 	if (state->dirty & ((1ULL << NV40_STATE_FRAGPROG) |
 			    (1ULL << NV40_STATE_FRAGTEX0))) {
-		BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1);
-		OUT_RING  (2);
-		BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1);
-		OUT_RING  (1);
+		BEGIN_RING(chan, curie, NV40TCL_TEX_CACHE_CTL, 1);
+		OUT_RING  (chan, 2);
+		BEGIN_RING(chan, curie, NV40TCL_TEX_CACHE_CTL, 1);
+		OUT_RING  (chan, 1);
 	}
 
 	state->dirty = 0;
+}
+
+void
+nv40_state_flush_notify(struct nouveau_channel *chan)
+{
+	struct nv40_context *nv40 = chan->user_private;
+	struct nv40_state *state = &nv40->state;
+	unsigned i, samplers;
 
 	so_emit_reloc_markers(chan, state->hw[NV40_STATE_FB]);
 	for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
@@ -160,7 +169,6 @@
 		draw_set_viewport_state(draw, &nv40->viewport);
 
 	if (nv40->draw_dirty & NV40_NEW_ARRAYS) {
-		draw_set_edgeflags(draw, nv40->edgeflags);
 		draw_set_vertex_buffers(draw, nv40->vtxbuf_nr, nv40->vtxbuf);
 		draw_set_vertex_elements(draw, nv40->vtxelt_nr, nv40->vtxelt);	
 	}
diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c
index 1c7a7cd..a58fe9d 100644
--- a/src/gallium/drivers/nv40/nv40_state_fb.c
+++ b/src/gallium/drivers/nv40/nv40_state_fb.c
@@ -19,7 +19,7 @@
 	struct nv04_surface *rt[4], *zeta;
 	uint32_t rt_enable, rt_format;
 	int i, colour_format = 0, zeta_format = 0;
-	struct nouveau_stateobj *so = so_new(64, 10);
+	struct nouveau_stateobj *so = so_new(18, 24, 10);
 	unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM;
 	unsigned w = fb->width;
 	unsigned h = fb->height;
diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c
index cf58d33..753a505 100644
--- a/src/gallium/drivers/nv40/nv40_state_scissor.c
+++ b/src/gallium/drivers/nv40/nv40_state_scissor.c
@@ -12,7 +12,7 @@
 		return FALSE;
 	nv40->state.scissor_enabled = rast->scissor;
 
-	so = so_new(3, 0);
+	so = so_new(1, 2, 0);
 	so_method(so, nv40->screen->curie, NV40TCL_SCISSOR_HORIZ, 2);
 	if (nv40->state.scissor_enabled) {
 		so_data  (so, ((s->maxx - s->minx) << 16) | s->minx);
diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c
index b51024a..2b371eb 100644
--- a/src/gallium/drivers/nv40/nv40_state_stipple.c
+++ b/src/gallium/drivers/nv40/nv40_state_stipple.c
@@ -14,14 +14,14 @@
 	if (rast->poly_stipple_enable) {
 		unsigned i;
 
-		so = so_new(35, 0);
+		so = so_new(2, 33, 0);
 		so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1);
 		so_data  (so, 1);
 		so_method(so, curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32);
 		for (i = 0; i < 32; i++)
 			so_data(so, nv40->stipple[i]);
 	} else {
-		so = so_new(2, 0);
+		so = so_new(1, 1, 0);
 		so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1);
 		so_data  (so, 0);
 	}
diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c
index 665d2d5..9919ba1 100644
--- a/src/gallium/drivers/nv40/nv40_state_viewport.c
+++ b/src/gallium/drivers/nv40/nv40_state_viewport.c
@@ -19,7 +19,7 @@
 		return FALSE;
 	nv40->state.viewport_bypass = bypass;
 
-	so = so_new(11, 0);
+	so = so_new(2, 9, 0);
 	if (!bypass) {
 		so_method(so, nv40->screen->curie,
 			  NV40TCL_VIEWPORT_TRANSLATE_X, 8);
diff --git a/src/gallium/drivers/nv40/nv40_transfer.c b/src/gallium/drivers/nv40/nv40_transfer.c
index 92caee6..791ee68 100644
--- a/src/gallium/drivers/nv40/nv40_transfer.c
+++ b/src/gallium/drivers/nv40/nv40_transfer.c
@@ -1,7 +1,9 @@
 #include <pipe/p_state.h>
 #include <pipe/p_defines.h>
 #include <pipe/p_inlines.h>
+#include <util/u_format.h>
 #include <util/u_memory.h>
+#include <util/u_math.h>
 #include <nouveau/nouveau_winsys.h>
 #include "nv40_context.h"
 #include "nv40_screen.h"
@@ -10,22 +12,19 @@
 struct nv40_transfer {
 	struct pipe_transfer base;
 	struct pipe_surface *surface;
-	bool direct;
+	boolean direct;
 };
 
 static void
-nv40_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
+nv40_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height,
                              struct pipe_texture *template)
 {
 	memset(template, 0, sizeof(struct pipe_texture));
 	template->target = pt->target;
 	template->format = pt->format;
-	template->width[0] = pt->width[level];
-	template->height[0] = pt->height[level];
-	template->depth[0] = 1;
-	template->block = pt->block;
-	template->nblocksx[0] = pt->nblocksx[level];
-	template->nblocksy[0] = pt->nblocksx[level];
+	template->width0 = width;
+	template->height0 = height;
+	template->depth0 = 1;
 	template->last_level = 0;
 	template->nr_samples = pt->nr_samples;
 
@@ -48,14 +47,10 @@
 		return NULL;
 
 	pipe_texture_reference(&tx->base.texture, pt);
-	tx->base.format = pt->format;
 	tx->base.x = x;
 	tx->base.y = y;
 	tx->base.width = w;
 	tx->base.height = h;
-	tx->base.block = pt->block;
-	tx->base.nblocksx = pt->nblocksx[level];
-	tx->base.nblocksy = pt->nblocksy[level];
 	tx->base.stride = mt->level[level].pitch;
 	tx->base.usage = usage;
 	tx->base.face = face;
@@ -76,7 +71,7 @@
 
 	tx->direct = false;
 
-	nv40_compatible_transfer_tex(pt, level, &tx_tex_template);
+	nv40_compatible_transfer_tex(pt, w, h, &tx_tex_template);
 
 	tx_tex = pscreen->texture_create(pscreen, &tx_tex_template);
 	if (!tx_tex)
@@ -85,6 +80,8 @@
 		return NULL;
 	}
 
+	tx->base.stride = ((struct nv40_miptree*)tx_tex)->level[0].pitch;
+
 	tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
 	                                       0, 0, 0,
 	                                       pipe_transfer_buffer_flags(&tx->base));
@@ -110,8 +107,8 @@
 		/* TODO: Check if SIFM can un-swizzle */
 		nvscreen->eng2d->copy(nvscreen->eng2d,
 		                      tx->surface, 0, 0,
-		                      src, 0, 0,
-		                      src->width, src->height);
+		                      src, x, y,
+		                      w, h);
 
 		pipe_surface_reference(&src, NULL);
 	}
@@ -131,13 +128,13 @@
 
 		dst = pscreen->get_tex_surface(pscreen, ptx->texture,
 	                                       ptx->face, ptx->level, ptx->zslice,
-	                                       PIPE_BUFFER_USAGE_GPU_WRITE);
+	                                       PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER);
 
 		/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
 		nvscreen->eng2d->copy(nvscreen->eng2d,
-		                      dst, 0, 0,
+		                      dst, tx->base.x, tx->base.y,
 		                      tx->surface, 0, 0,
-		                      dst->width, dst->height);
+		                      tx->base.width, tx->base.height);
 
 		pipe_surface_reference(&dst, NULL);
 	}
@@ -156,8 +153,10 @@
 	void *map = pipe_buffer_map(pscreen, mt->buffer,
 	                            pipe_transfer_buffer_flags(ptx));
 
-	return map + ns->base.offset +
-	       ptx->y * ns->pitch + ptx->x * ptx->block.size;
+	if(!tx->direct)
+		return map + ns->base.offset;
+	else
+		return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format);
 }
 
 static void
diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c
index b2753b8..a777898 100644
--- a/src/gallium/drivers/nv40/nv40_vbo.c
+++ b/src/gallium/drivers/nv40/nv40_vbo.c
@@ -164,18 +164,21 @@
 	return TRUE;
 }
 
-boolean
+void
 nv40_draw_arrays(struct pipe_context *pipe,
 		 unsigned mode, unsigned start, unsigned count)
 {
 	struct nv40_context *nv40 = nv40_context(pipe);
-	struct nouveau_channel *chan = nv40->screen->base.channel;
+	struct nv40_screen *screen = nv40->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *curie = screen->curie;
 	unsigned restart;
 
 	nv40_vbo_set_idxbuf(nv40, NULL, 0);
 	if (FORCE_SWTNL || !nv40_state_validate(nv40)) {
-		return nv40_draw_elements_swtnl(pipe, NULL, 0,
-						mode, start, count);
+		nv40_draw_elements_swtnl(pipe, NULL, 0,
+                                         mode, start, count);
+                return;
 	}
 
 	while (count) {
@@ -186,17 +189,17 @@
 		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256,
 					mode, start, count, &restart);
 		if (!vc) {
-			FIRE_RING(NULL);
+			FIRE_RING(chan);
 			continue;
 		}
 
-		BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
-		OUT_RING  (nvgl_primitive(mode));
+		BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
+		OUT_RING  (chan, nvgl_primitive(mode));
 
 		nr = (vc & 0xff);
 		if (nr) {
-			BEGIN_RING(curie, NV40TCL_VB_VERTEX_BATCH, 1);
-			OUT_RING  (((nr - 1) << 24) | start);
+			BEGIN_RING(chan, curie, NV40TCL_VB_VERTEX_BATCH, 1);
+			OUT_RING  (chan, ((nr - 1) << 24) | start);
 			start += nr;
 		}
 
@@ -206,29 +209,30 @@
 
 			nr -= push;
 
-			BEGIN_RING_NI(curie, NV40TCL_VB_VERTEX_BATCH, push);
+			BEGIN_RING_NI(chan, curie, NV40TCL_VB_VERTEX_BATCH, push);
 			while (push--) {
-				OUT_RING(((0x100 - 1) << 24) | start);
+				OUT_RING(chan, ((0x100 - 1) << 24) | start);
 				start += 0x100;
 			}
 		}
 
-		BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
+		OUT_RING  (chan, 0);
 
 		count -= vc;
 		start = restart;
 	}
 
 	pipe->flush(pipe, 0, NULL);
-	return TRUE;
 }
 
 static INLINE void
 nv40_draw_elements_u08(struct nv40_context *nv40, void *ib,
 		       unsigned mode, unsigned start, unsigned count)
 {
-	struct nouveau_channel *chan = nv40->screen->base.channel;
+	struct nv40_screen *screen = nv40->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *curie = screen->curie;
 
 	while (count) {
 		uint8_t *elts = (uint8_t *)ib + start;
@@ -239,17 +243,17 @@
 		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2,
 					mode, start, count, &restart);
 		if (vc == 0) {
-			FIRE_RING(NULL);
+			FIRE_RING(chan);
 			continue;
 		}
 		count -= vc;
 
-		BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
-		OUT_RING  (nvgl_primitive(mode));
+		BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
+		OUT_RING  (chan, nvgl_primitive(mode));
 
 		if (vc & 1) {
-			BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1);
-			OUT_RING  (elts[0]);
+			BEGIN_RING(chan, curie, NV40TCL_VB_ELEMENT_U32, 1);
+			OUT_RING  (chan, elts[0]);
 			elts++; vc--;
 		}
 
@@ -258,16 +262,16 @@
 
 			push = MIN2(vc, 2047 * 2);
 
-			BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U16, push >> 1);
+			BEGIN_RING_NI(chan, curie, NV40TCL_VB_ELEMENT_U16, push >> 1);
 			for (i = 0; i < push; i+=2)
-				OUT_RING((elts[i+1] << 16) | elts[i]);
+				OUT_RING(chan, (elts[i+1] << 16) | elts[i]);
 
 			vc -= push;
 			elts += push;
 		}
 
-		BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
+		OUT_RING  (chan, 0);
 
 		start = restart;
 	}
@@ -277,7 +281,9 @@
 nv40_draw_elements_u16(struct nv40_context *nv40, void *ib,
 		       unsigned mode, unsigned start, unsigned count)
 {
-	struct nouveau_channel *chan = nv40->screen->base.channel;
+	struct nv40_screen *screen = nv40->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *curie = screen->curie;
 
 	while (count) {
 		uint16_t *elts = (uint16_t *)ib + start;
@@ -288,17 +294,17 @@
 		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2,
 					mode, start, count, &restart);
 		if (vc == 0) {
-			FIRE_RING(NULL);
+			FIRE_RING(chan);
 			continue;
 		}
 		count -= vc;
 
-		BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
-		OUT_RING  (nvgl_primitive(mode));
+		BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
+		OUT_RING  (chan, nvgl_primitive(mode));
 
 		if (vc & 1) {
-			BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1);
-			OUT_RING  (elts[0]);
+			BEGIN_RING(chan, curie, NV40TCL_VB_ELEMENT_U32, 1);
+			OUT_RING  (chan, elts[0]);
 			elts++; vc--;
 		}
 
@@ -307,16 +313,16 @@
 
 			push = MIN2(vc, 2047 * 2);
 
-			BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U16, push >> 1);
+			BEGIN_RING_NI(chan, curie, NV40TCL_VB_ELEMENT_U16, push >> 1);
 			for (i = 0; i < push; i+=2)
-				OUT_RING((elts[i+1] << 16) | elts[i]);
+				OUT_RING(chan, (elts[i+1] << 16) | elts[i]);
 
 			vc -= push;
 			elts += push;
 		}
 
-		BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
+		OUT_RING  (chan, 0);
 
 		start = restart;
 	}
@@ -326,7 +332,9 @@
 nv40_draw_elements_u32(struct nv40_context *nv40, void *ib,
 		       unsigned mode, unsigned start, unsigned count)
 {
-	struct nouveau_channel *chan = nv40->screen->base.channel;
+	struct nv40_screen *screen = nv40->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *curie = screen->curie;
 
 	while (count) {
 		uint32_t *elts = (uint32_t *)ib + start;
@@ -337,32 +345,32 @@
 		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 5, 1,
 					mode, start, count, &restart);
 		if (vc == 0) {
-			FIRE_RING(NULL);
+			FIRE_RING(chan);
 			continue;
 		}
 		count -= vc;
 
-		BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
-		OUT_RING  (nvgl_primitive(mode));
+		BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
+		OUT_RING  (chan, nvgl_primitive(mode));
 
 		while (vc) {
 			push = MIN2(vc, 2047);
 
-			BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U32, push);
-			OUT_RINGp    (elts, push);
+			BEGIN_RING_NI(chan, curie, NV40TCL_VB_ELEMENT_U32, push);
+			OUT_RINGp    (chan, elts, push);
 
 			vc -= push;
 			elts += push;
 		}
 
-		BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
+		OUT_RING  (chan, 0);
 
 		start = restart;
 	}
 }
 
-static boolean
+static void
 nv40_draw_elements_inline(struct pipe_context *pipe,
 			  struct pipe_buffer *ib, unsigned ib_size,
 			  unsigned mode, unsigned start, unsigned count)
@@ -393,15 +401,16 @@
 	}
 
 	pipe_buffer_unmap(pscreen, ib);
-	return TRUE;
 }
 
-static boolean
+static void
 nv40_draw_elements_vbo(struct pipe_context *pipe,
 		       unsigned mode, unsigned start, unsigned count)
 {
 	struct nv40_context *nv40 = nv40_context(pipe);
-	struct nouveau_channel *chan = nv40->screen->base.channel;
+	struct nv40_screen *screen = nv40->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *curie = screen->curie;
 	unsigned restart;
 
 	while (count) {
@@ -412,17 +421,17 @@
 		vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256,
 					mode, start, count, &restart);
 		if (!vc) {
-			FIRE_RING(NULL);
+			FIRE_RING(chan);
 			continue;
 		}
 		
-		BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
-		OUT_RING  (nvgl_primitive(mode));
+		BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
+		OUT_RING  (chan, nvgl_primitive(mode));
 
 		nr = (vc & 0xff);
 		if (nr) {
-			BEGIN_RING(curie, NV40TCL_VB_INDEX_BATCH, 1);
-			OUT_RING  (((nr - 1) << 24) | start);
+			BEGIN_RING(chan, curie, NV40TCL_VB_INDEX_BATCH, 1);
+			OUT_RING  (chan, ((nr - 1) << 24) | start);
 			start += nr;
 		}
 
@@ -432,24 +441,22 @@
 
 			nr -= push;
 
-			BEGIN_RING_NI(curie, NV40TCL_VB_INDEX_BATCH, push);
+			BEGIN_RING_NI(chan, curie, NV40TCL_VB_INDEX_BATCH, push);
 			while (push--) {
-				OUT_RING(((0x100 - 1) << 24) | start);
+				OUT_RING(chan, ((0x100 - 1) << 24) | start);
 				start += 0x100;
 			}
 		}
 
-		BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
-		OUT_RING  (0);
+		BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
+		OUT_RING  (chan, 0);
 
 		count -= vc;
 		start = restart;
 	}
-
-	return TRUE;
 }
 
-boolean
+void
 nv40_draw_elements(struct pipe_context *pipe,
 		   struct pipe_buffer *indexBuffer, unsigned indexSize,
 		   unsigned mode, unsigned start, unsigned count)
@@ -459,8 +466,9 @@
 
 	idxbuf = nv40_vbo_set_idxbuf(nv40, indexBuffer, indexSize);
 	if (FORCE_SWTNL || !nv40_state_validate(nv40)) {
-		return nv40_draw_elements_swtnl(pipe, NULL, 0,
-						mode, start, count);
+		nv40_draw_elements_swtnl(pipe, NULL, 0,
+                                         mode, start, count);
+                return;
 	}
 
 	if (idxbuf) {
@@ -471,7 +479,6 @@
 	}
 
 	pipe->flush(pipe, 0, NULL);
-	return TRUE;
 }
 
 static boolean
@@ -484,14 +491,9 @@
 	unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
 	int hw;
 
-	if (nv40->edgeflags) {
-		nv40->fallback_swtnl |= NV40_NEW_ARRAYS;
-		return FALSE;
-	}
-
-	vtxbuf = so_new(20, 18);
+	vtxbuf = so_new(3, 17, 18);
 	so_method(vtxbuf, curie, NV40TCL_VTXBUF_ADDRESS(0), nv40->vtxelt_nr);
-	vtxfmt = so_new(17, 0);
+	vtxfmt = so_new(1, 16, 0);
 	so_method(vtxfmt, curie, NV40TCL_VTXFMT(0), nv40->vtxelt_nr);
 
 	for (hw = 0; hw < nv40->vtxelt_nr; hw++) {
@@ -504,7 +506,7 @@
 
 		if (!vb->stride) {
 			if (!sattr)
-				sattr = so_new(16 * 5, 0);
+				sattr = so_new(16, 16 * 4, 0);
 
 			if (nv40_vbo_static_attrib(nv40, sattr, hw, ve, vb)) {
 				so_data(vtxbuf, 0);
diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c
index 31dae24..8d80fca 100644
--- a/src/gallium/drivers/nv40/nv40_vertprog.c
+++ b/src/gallium/drivers/nv40/nv40_vertprog.c
@@ -295,30 +295,30 @@
 tgsi_src(struct nv40_vpc *vpc, const struct tgsi_full_src_register *fsrc) {
 	struct nv40_sreg src;
 
-	switch (fsrc->SrcRegister.File) {
+	switch (fsrc->Register.File) {
 	case TGSI_FILE_INPUT:
-		src = nv40_sr(NV40SR_INPUT, fsrc->SrcRegister.Index);
+		src = nv40_sr(NV40SR_INPUT, fsrc->Register.Index);
 		break;
 	case TGSI_FILE_CONSTANT:
-		src = constant(vpc, fsrc->SrcRegister.Index, 0, 0, 0, 0);
+		src = constant(vpc, fsrc->Register.Index, 0, 0, 0, 0);
 		break;
 	case TGSI_FILE_IMMEDIATE:
-		src = vpc->imm[fsrc->SrcRegister.Index];
+		src = vpc->imm[fsrc->Register.Index];
 		break;
 	case TGSI_FILE_TEMPORARY:
-		src = vpc->r_temp[fsrc->SrcRegister.Index];
+		src = vpc->r_temp[fsrc->Register.Index];
 		break;
 	default:
 		NOUVEAU_ERR("bad src file\n");
 		break;
 	}
 
-	src.abs = fsrc->SrcRegisterExtMod.Absolute;
-	src.negate = fsrc->SrcRegister.Negate;
-	src.swz[0] = fsrc->SrcRegister.SwizzleX;
-	src.swz[1] = fsrc->SrcRegister.SwizzleY;
-	src.swz[2] = fsrc->SrcRegister.SwizzleZ;
-	src.swz[3] = fsrc->SrcRegister.SwizzleW;
+	src.abs = fsrc->Register.Absolute;
+	src.negate = fsrc->Register.Negate;
+	src.swz[0] = fsrc->Register.SwizzleX;
+	src.swz[1] = fsrc->Register.SwizzleY;
+	src.swz[2] = fsrc->Register.SwizzleZ;
+	src.swz[3] = fsrc->Register.SwizzleW;
 	return src;
 }
 
@@ -326,15 +326,15 @@
 tgsi_dst(struct nv40_vpc *vpc, const struct tgsi_full_dst_register *fdst) {
 	struct nv40_sreg dst;
 
-	switch (fdst->DstRegister.File) {
+	switch (fdst->Register.File) {
 	case TGSI_FILE_OUTPUT:
-		dst = vpc->r_result[fdst->DstRegister.Index];
+		dst = vpc->r_result[fdst->Register.Index];
 		break;
 	case TGSI_FILE_TEMPORARY:
-		dst = vpc->r_temp[fdst->DstRegister.Index];
+		dst = vpc->r_temp[fdst->Register.Index];
 		break;
 	case TGSI_FILE_ADDRESS:
-		dst = vpc->r_address[fdst->DstRegister.Index];
+		dst = vpc->r_address[fdst->Register.Index];
 		break;
 	default:
 		NOUVEAU_ERR("bad dst file\n");
@@ -405,8 +405,8 @@
 	for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
 		const struct tgsi_full_src_register *fsrc;
 
-		fsrc = &finst->FullSrcRegisters[i];
-		if (fsrc->SrcRegister.File == TGSI_FILE_TEMPORARY) {
+		fsrc = &finst->Src[i];
+		if (fsrc->Register.File == TGSI_FILE_TEMPORARY) {
 			src[i] = tgsi_src(vpc, fsrc);
 		}
 	}
@@ -414,9 +414,9 @@
 	for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
 		const struct tgsi_full_src_register *fsrc;
 
-		fsrc = &finst->FullSrcRegisters[i];
+		fsrc = &finst->Src[i];
 
-		switch (fsrc->SrcRegister.File) {
+		switch (fsrc->Register.File) {
 		case TGSI_FILE_INPUT:
 		case TGSI_FILE_CONSTANT:
 		case TGSI_FILE_TEMPORARY:
@@ -427,10 +427,10 @@
 			break;
 		}
 
-		switch (fsrc->SrcRegister.File) {
+		switch (fsrc->Register.File) {
 		case TGSI_FILE_INPUT:
-			if (ai == -1 || ai == fsrc->SrcRegister.Index) {
-				ai = fsrc->SrcRegister.Index;
+			if (ai == -1 || ai == fsrc->Register.Index) {
+				ai = fsrc->Register.Index;
 				src[i] = tgsi_src(vpc, fsrc);
 			} else {
 				src[i] = temp(vpc);
@@ -440,8 +440,8 @@
 			break;
 		case TGSI_FILE_CONSTANT:
 			if ((ci == -1 && ii == -1) ||
-			    ci == fsrc->SrcRegister.Index) {
-				ci = fsrc->SrcRegister.Index;
+			    ci == fsrc->Register.Index) {
+				ci = fsrc->Register.Index;
 				src[i] = tgsi_src(vpc, fsrc);
 			} else {
 				src[i] = temp(vpc);
@@ -451,8 +451,8 @@
 			break;
 		case TGSI_FILE_IMMEDIATE:
 			if ((ci == -1 && ii == -1) ||
-			    ii == fsrc->SrcRegister.Index) {
-				ii = fsrc->SrcRegister.Index;
+			    ii == fsrc->Register.Index) {
+				ii = fsrc->Register.Index;
 				src[i] = tgsi_src(vpc, fsrc);
 			} else {
 				src[i] = temp(vpc);
@@ -469,8 +469,8 @@
 		}
 	}
 
-	dst  = tgsi_dst(vpc, &finst->FullDstRegisters[0]);
-	mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask);
+	dst  = tgsi_dst(vpc, &finst->Dst[0]);
+	mask = tgsi_mask(finst->Dst[0].Register.WriteMask);
 
 	switch (finst->Instruction.Opcode) {
 	case TGSI_OPCODE_ABS:
@@ -577,19 +577,19 @@
 nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc,
 				const struct tgsi_full_declaration *fdec)
 {
-	unsigned idx = fdec->DeclarationRange.First;
+	unsigned idx = fdec->Range.First;
 	int hw;
 
-	switch (fdec->Semantic.SemanticName) {
+	switch (fdec->Semantic.Name) {
 	case TGSI_SEMANTIC_POSITION:
 		hw = NV40_VP_INST_DEST_POS;
 		vpc->hpos_idx = idx;
 		break;
 	case TGSI_SEMANTIC_COLOR:
-		if (fdec->Semantic.SemanticIndex == 0) {
+		if (fdec->Semantic.Index == 0) {
 			hw = NV40_VP_INST_DEST_COL0;
 		} else
-		if (fdec->Semantic.SemanticIndex == 1) {
+		if (fdec->Semantic.Index == 1) {
 			hw = NV40_VP_INST_DEST_COL1;
 		} else {
 			NOUVEAU_ERR("bad colour semantic index\n");
@@ -597,10 +597,10 @@
 		}
 		break;
 	case TGSI_SEMANTIC_BCOLOR:
-		if (fdec->Semantic.SemanticIndex == 0) {
+		if (fdec->Semantic.Index == 0) {
 			hw = NV40_VP_INST_DEST_BFC0;
 		} else
-		if (fdec->Semantic.SemanticIndex == 1) {
+		if (fdec->Semantic.Index == 1) {
 			hw = NV40_VP_INST_DEST_BFC1;
 		} else {
 			NOUVEAU_ERR("bad bcolour semantic index\n");
@@ -614,13 +614,17 @@
 		hw = NV40_VP_INST_DEST_PSZ;
 		break;
 	case TGSI_SEMANTIC_GENERIC:
-		if (fdec->Semantic.SemanticIndex <= 7) {
-			hw = NV40_VP_INST_DEST_TC(fdec->Semantic.SemanticIndex);
+		if (fdec->Semantic.Index <= 7) {
+			hw = NV40_VP_INST_DEST_TC(fdec->Semantic.Index);
 		} else {
 			NOUVEAU_ERR("bad generic semantic index\n");
 			return FALSE;
 		}
 		break;
+	case TGSI_SEMANTIC_EDGEFLAG:
+		/* not really an error just a fallback */
+		NOUVEAU_ERR("cannot handle edgeflag output\n");
+		return FALSE;
 	default:
 		NOUVEAU_ERR("bad output semantic\n");
 		return FALSE;
@@ -652,16 +656,16 @@
 			fdec = &p.FullToken.FullDeclaration;
 			switch (fdec->Declaration.File) {
 			case TGSI_FILE_TEMPORARY:
-				if (fdec->DeclarationRange.Last > high_temp) {
+				if (fdec->Range.Last > high_temp) {
 					high_temp =
-						fdec->DeclarationRange.Last;
+						fdec->Range.Last;
 				}
 				break;
 #if 0 /* this would be nice.. except gallium doesn't track it */
 			case TGSI_FILE_ADDRESS:
-				if (fdec->DeclarationRange.Last > high_addr) {
+				if (fdec->Range.Last > high_addr) {
 					high_addr =
-						fdec->DeclarationRange.Last;
+						fdec->Range.Last;
 				}
 				break;
 #endif
@@ -681,11 +685,11 @@
 			const struct tgsi_full_dst_register *fdst;
 
 			finst = &p.FullToken.FullInstruction;
-			fdst = &finst->FullDstRegisters[0];
+			fdst = &finst->Dst[0];
 
-			if (fdst->DstRegister.File == TGSI_FILE_ADDRESS) {
-				if (fdst->DstRegister.Index > high_addr)
-					high_addr = fdst->DstRegister.Index;
+			if (fdst->Register.File == TGSI_FILE_ADDRESS) {
+				if (fdst->Register.Index > high_addr)
+					high_addr = fdst->Register.Index;
 			}
 		
 		}
@@ -830,7 +834,9 @@
 nv40_vertprog_validate(struct nv40_context *nv40)
 { 
 	struct pipe_screen *pscreen = nv40->pipe.screen;
-	struct nouveau_grobj *curie = nv40->screen->curie;
+	struct nv40_screen *screen = nv40->screen;
+	struct nouveau_channel *chan = screen->base.channel;
+	struct nouveau_grobj *curie = screen->curie;
 	struct nv40_vertex_program *vp;
 	struct pipe_buffer *constbuf;
 	boolean upload_code = FALSE, upload_data = FALSE;
@@ -880,7 +886,7 @@
 				assert(0);
 		}
 
-		so = so_new(7, 0);
+		so = so_new(3, 4, 0);
 		so_method(so, curie, NV40TCL_VP_START_FROM_ID, 1);
 		so_data  (so, vp->exec->start);
 		so_method(so, curie, NV40TCL_VP_ATTRIB_EN, 2);
@@ -970,9 +976,9 @@
 				       4 * sizeof(float));
 			}
 
-			BEGIN_RING(curie, NV40TCL_VP_UPLOAD_CONST_ID, 5);
-			OUT_RING  (i + vp->data->start);
-			OUT_RINGp ((uint32_t *)vpd->value, 4);
+			BEGIN_RING(chan, curie, NV40TCL_VP_UPLOAD_CONST_ID, 5);
+			OUT_RING  (chan, i + vp->data->start);
+			OUT_RINGp (chan, (uint32_t *)vpd->value, 4);
 		}
 
 		if (constbuf)
@@ -989,11 +995,11 @@
 			NOUVEAU_MSG("VP %d: 0x%08x\n", i, vp->insns[i].data[3]);
 		}
 #endif
-		BEGIN_RING(curie, NV40TCL_VP_UPLOAD_FROM_ID, 1);
-		OUT_RING  (vp->exec->start);
+		BEGIN_RING(chan, curie, NV40TCL_VP_UPLOAD_FROM_ID, 1);
+		OUT_RING  (chan, vp->exec->start);
 		for (i = 0; i < vp->nr_insns; i++) {
-			BEGIN_RING(curie, NV40TCL_VP_UPLOAD_INST(0), 4);
-			OUT_RINGp (vp->insns[i].data, 4);
+			BEGIN_RING(chan, curie, NV40TCL_VP_UPLOAD_INST(0), 4);
+			OUT_RINGp (chan, vp->insns[i].data, 4);
 		}
 	}
 
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 219e7a7..5997456 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -43,16 +43,44 @@
 {
 	struct nv50_context *nv50 = nv50_context(pipe);
 
+        if (nv50->state.fb)
+		so_ref(NULL, &nv50->state.fb);
+	if (nv50->state.blend)
+		so_ref(NULL, &nv50->state.blend);
+	if (nv50->state.blend_colour)
+		so_ref(NULL, &nv50->state.blend_colour);
+	if (nv50->state.zsa)
+		so_ref(NULL, &nv50->state.zsa);
+	if (nv50->state.rast)
+		so_ref(NULL, &nv50->state.rast);
+	if (nv50->state.stipple)
+		so_ref(NULL, &nv50->state.stipple);
+	if (nv50->state.scissor)
+		so_ref(NULL, &nv50->state.scissor);
+	if (nv50->state.viewport)
+		so_ref(NULL, &nv50->state.viewport);
+	if (nv50->state.tsc_upload)
+		so_ref(NULL, &nv50->state.tsc_upload);
+	if (nv50->state.tic_upload)
+		so_ref(NULL, &nv50->state.tic_upload);
+	if (nv50->state.vertprog)
+		so_ref(NULL, &nv50->state.vertprog);
+	if (nv50->state.fragprog)
+		so_ref(NULL, &nv50->state.fragprog);
+	if (nv50->state.programs)
+		so_ref(NULL, &nv50->state.programs);
+	if (nv50->state.vtxfmt)
+		so_ref(NULL, &nv50->state.vtxfmt);
+	if (nv50->state.vtxbuf)
+		so_ref(NULL, &nv50->state.vtxbuf);
+	if (nv50->state.vtxattr)
+		so_ref(NULL, &nv50->state.vtxattr);
+
 	draw_destroy(nv50->draw);
 	FREE(nv50);
 }
 
 
-static void
-nv50_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
-{
-}
-
 struct pipe_context *
 nv50_create(struct pipe_screen *pscreen, unsigned pctx_id)
 {
@@ -71,7 +99,6 @@
 
 	nv50->pipe.destroy = nv50_destroy;
 
-	nv50->pipe.set_edgeflags = nv50_set_edgeflags;
 	nv50->pipe.draw_arrays = nv50_draw_arrays;
 	nv50->pipe.draw_elements = nv50_draw_elements;
 	nv50->pipe.clear = nv50_clear;
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 4b0f062..cbd4c3f 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -65,7 +65,7 @@
 };
 
 struct nv50_sampler_stateobj {
-	bool normalized;
+	boolean normalized;
 	unsigned tsc[8];
 };
 
@@ -126,7 +126,7 @@
 	unsigned viewport_bypass;
 	struct nouveau_stateobj *tsc_upload;
 	struct nouveau_stateobj *tic_upload;
-	unsigned miptree_nr;
+	unsigned miptree_nr[PIPE_SHADER_TYPES];
 	struct nouveau_stateobj *vertprog;
 	struct nouveau_stateobj *fragprog;
 	struct nouveau_stateobj *programs;
@@ -162,10 +162,10 @@
 	unsigned vtxbuf_nr;
 	struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
 	unsigned vtxelt_nr;
-	struct nv50_sampler_stateobj *sampler[PIPE_MAX_SAMPLERS];
-	unsigned sampler_nr;
-	struct nv50_miptree *miptree[PIPE_MAX_SAMPLERS];
-	unsigned miptree_nr;
+	struct nv50_sampler_stateobj *sampler[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
+	unsigned sampler_nr[PIPE_SHADER_TYPES];
+	struct nv50_miptree *miptree[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
+	unsigned miptree_nr[PIPE_SHADER_TYPES];
 
 	uint16_t vbo_fifo;
 };
@@ -191,9 +191,9 @@
 extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *nv50);
 
 /* nv50_vbo.c */
-extern boolean nv50_draw_arrays(struct pipe_context *, unsigned mode,
+extern void nv50_draw_arrays(struct pipe_context *, unsigned mode,
 				unsigned start, unsigned count);
-extern boolean nv50_draw_elements(struct pipe_context *pipe,
+extern void nv50_draw_elements(struct pipe_context *pipe,
 				  struct pipe_buffer *indexBuffer,
 				  unsigned indexSize,
 				  unsigned mode, unsigned start,
@@ -218,7 +218,7 @@
 extern void nv50_so_init_sifc(struct nv50_context *nv50,
 			      struct nouveau_stateobj *so,
 			      struct nouveau_bo *bo, unsigned reloc,
-			      unsigned size);
+			      unsigned offset, unsigned size);
 
 /* nv50_tex.c */
 extern void nv50_tex_validate(struct nv50_context *);
diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c
index 9c20c5c..3f1edf0 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -23,6 +23,7 @@
 #include "pipe/p_state.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
 
 #include "nv50_context.h"
 
@@ -55,14 +56,28 @@
 	return tile_mode | 0x10;
 }
 
+static INLINE unsigned
+get_zslice_offset(unsigned tile_mode, unsigned z, unsigned pitch, unsigned nb_h)
+{
+	unsigned tile_h = get_tile_height(tile_mode);
+	unsigned tile_d = get_tile_depth(tile_mode);
+
+	/* pitch_2d == to next slice within this volume-tile */
+	/* pitch_3d == size (in bytes) of a volume-tile */
+	unsigned pitch_2d = tile_h * 64;
+	unsigned pitch_3d = tile_d * align(nb_h, tile_h) * pitch;
+
+	return (z % tile_d) * pitch_2d + (z / tile_d) * pitch_3d;
+}
+
 static struct pipe_texture *
 nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
 {
 	struct nouveau_device *dev = nouveau_screen(pscreen)->device;
 	struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
 	struct pipe_texture *pt = &mt->base.base;
-	unsigned width = tmp->width[0], height = tmp->height[0];
-	unsigned depth = tmp->depth[0], image_alignment;
+	unsigned width = tmp->width0, height = tmp->height0;
+	unsigned depth = tmp->depth0, image_alignment;
 	uint32_t tile_flags;
 	int ret, i, l;
 
@@ -91,20 +106,15 @@
 
 	for (l = 0; l <= pt->last_level; l++) {
 		struct nv50_miptree_level *lvl = &mt->level[l];
-
-		pt->width[l] = width;
-		pt->height[l] = height;
-		pt->depth[l] = depth;
-		pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width);
-		pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height);
+		unsigned nblocksy = util_format_get_nblocksy(pt->format, height);
 
 		lvl->image_offset = CALLOC(mt->image_nr, sizeof(int));
-		lvl->pitch = align(pt->nblocksx[l] * pt->block.size, 64);
-		lvl->tile_mode = get_tile_mode(pt->nblocksy[l], depth);
+		lvl->pitch = align(util_format_get_stride(pt->format, width), 64);
+		lvl->tile_mode = get_tile_mode(nblocksy, depth);
 
-		width = MAX2(1, width >> 1);
-		height = MAX2(1, height >> 1);
-		depth = MAX2(1, depth >> 1);
+		width = u_minify(width, 1);
+		height = u_minify(height, 1);
+		depth = u_minify(depth, 1);
 	}
 
 	image_alignment  = get_tile_height(mt->level[0].tile_mode) * 64;
@@ -121,8 +131,8 @@
 			unsigned tile_d = get_tile_depth(lvl->tile_mode);
 
 			size  = lvl->pitch;
-			size *= align(pt->nblocksy[l], tile_h);
-			size *= align(pt->depth[l], tile_d);
+			size *= align(util_format_get_nblocksy(pt->format, u_minify(pt->height0, l)), tile_h);
+			size *= align(u_minify(pt->depth0, l), tile_d);
 
 			lvl->image_offset[i] = mt->total_size;
 
@@ -135,6 +145,8 @@
 				  mt->level[0].tile_mode, tile_flags,
 				  &mt->base.bo);
 	if (ret) {
+		for (l = 0; l < pt->last_level; ++l)
+			FREE(mt->level[l].image_offset);
 		FREE(mt);
 		return NULL;
 	}
@@ -151,7 +163,7 @@
 
 	/* Only supports 2D, non-mipmapped textures for the moment */
 	if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 ||
-	    pt->depth[0] != 1)
+	    pt->depth0 != 1)
 		return NULL;
 
 	mt = CALLOC_STRUCT(nv50_miptree);
@@ -174,6 +186,10 @@
 nv50_miptree_destroy(struct pipe_texture *pt)
 {
 	struct nv50_miptree *mt = nv50_miptree(pt);
+	unsigned l;
+
+	for (l = 0; l < pt->last_level; ++l)
+		FREE(mt->level[l].image_offset);
 
 	nouveau_bo_ref(NULL, &mt->base.bo);
 	FREE(mt);
@@ -187,23 +203,18 @@
 	struct nv50_miptree *mt = nv50_miptree(pt);
 	struct nv50_miptree_level *lvl = &mt->level[level];
 	struct pipe_surface *ps;
-	int img;
+	unsigned img = 0;
 
 	if (pt->target == PIPE_TEXTURE_CUBE)
 		img = face;
-	else
-	if (pt->target == PIPE_TEXTURE_3D)
-		img = zslice;
-	else
-		img = 0;
 
 	ps = CALLOC_STRUCT(pipe_surface);
 	if (!ps)
 		return NULL;
 	pipe_texture_reference(&ps->texture, pt);
 	ps->format = pt->format;
-	ps->width = pt->width[level];
-	ps->height = pt->height[level];
+	ps->width = u_minify(pt->width0, level);
+	ps->height = u_minify(pt->height0, level);
 	ps->usage = flags;
 	pipe_reference_init(&ps->reference, 1);
 	ps->face = face;
@@ -211,6 +222,12 @@
 	ps->zslice = zslice;
 	ps->offset = lvl->image_offset[img];
 
+	if (pt->target == PIPE_TEXTURE_3D) {
+		unsigned nb_h = util_format_get_nblocksy(pt->format, ps->height);
+		ps->offset += get_zslice_offset(lvl->tile_mode, zslice,
+						lvl->pitch, nb_h);
+	}
+
 	return ps;
 }
 
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index bf50982..e16fa47 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -96,11 +96,23 @@
 
 #define NV50_MOD_NEG 1
 #define NV50_MOD_ABS 2
+#define NV50_MOD_NEG_ABS (NV50_MOD_NEG | NV50_MOD_ABS)
 #define NV50_MOD_SAT 4
+#define NV50_MOD_I32 8
 
-/* arbitrary limits */
-#define MAX_IF_DEPTH 4
-#define MAX_LOOP_DEPTH 4
+/* NV50_MOD_I32 is used to indicate integer mode for neg/abs */
+
+/* STACK: Conditionals and loops have to use the (per warp) stack.
+ * Stack entries consist of an entry type (divergent path, join at),
+ * a mask indicating the active threads of the warp, and an address.
+ * MPs can store 12 stack entries internally, if we need more (and
+ * we probably do), we have to create a stack buffer in VRAM.
+ */
+/* impose low limits for now */
+#define NV50_MAX_COND_NESTING 4
+#define NV50_MAX_LOOP_NESTING 3
+
+#define JOIN_ON(e) e; pc->p->exec_tail->inst[1] |= 2
 
 struct nv50_pc {
 	struct nv50_program *p;
@@ -119,35 +131,44 @@
 	struct nv50_reg *param;
 	int param_nr;
 	struct nv50_reg *immd;
-	float *immd_buf;
+	uint32_t *immd_buf;
 	int immd_nr;
 	struct nv50_reg **addr;
 	int addr_nr;
+	uint8_t addr_alloc; /* set bit indicates used for TGSI_FILE_ADDRESS */
 
 	struct nv50_reg *temp_temp[16];
+	struct nv50_program_exec *temp_temp_exec[16];
 	unsigned temp_temp_nr;
 
 	/* broadcast and destination replacement regs */
 	struct nv50_reg *r_brdc;
 	struct nv50_reg *r_dst[4];
 
+	struct nv50_reg reg_instances[16];
+	unsigned reg_instance_nr;
+
 	unsigned interp_mode[32];
 	/* perspective interpolation registers */
 	struct nv50_reg *iv_p;
 	struct nv50_reg *iv_c;
 
-	struct nv50_program_exec *if_cond;
-	struct nv50_program_exec *if_insn[MAX_IF_DEPTH];
-	struct nv50_program_exec *br_join[MAX_IF_DEPTH];
-	struct nv50_program_exec *br_loop[MAX_LOOP_DEPTH]; /* for BRK branch */
+	struct nv50_program_exec *if_insn[NV50_MAX_COND_NESTING];
+	struct nv50_program_exec *if_join[NV50_MAX_COND_NESTING];
+	struct nv50_program_exec *loop_brka[NV50_MAX_LOOP_NESTING];
 	int if_lvl, loop_lvl;
-	unsigned loop_pos[MAX_LOOP_DEPTH];
+	unsigned loop_pos[NV50_MAX_LOOP_NESTING];
+
+	unsigned *insn_pos; /* actual program offset of each TGSI insn */
+	boolean in_subroutine;
 
 	/* current instruction and total number of insns */
 	unsigned insn_cur;
 	unsigned insn_nr;
 
 	boolean allow32;
+
+	uint8_t edgeflag_out;
 };
 
 static INLINE void
@@ -176,8 +197,7 @@
 
 	/* remove records of temporary address register values */
 	for (i = 0; i < NV50_SU_MAX_ADDR; ++i)
-		if (pc->r_addr[i].index < 0)
-			pc->r_addr[i].rhw = -1;
+		pc->r_addr[i].rhw = -1;
 }
 
 static void
@@ -226,7 +246,23 @@
 		}
 	}
 
-	assert(0);
+	NOUVEAU_ERR("out of registers\n");
+	abort();
+}
+
+static INLINE struct nv50_reg *
+reg_instance(struct nv50_pc *pc, struct nv50_reg *reg)
+{
+	struct nv50_reg *ri;
+
+	assert(pc->reg_instance_nr < 16);
+	ri = &pc->reg_instances[pc->reg_instance_nr++];
+	if (reg) {
+		alloc_reg(pc, reg);
+		*ri = *reg;
+		reg->mod = 0;
+	}
+	return ri;
 }
 
 /* XXX: For shaders that aren't executed linearly (e.g. shaders that
@@ -251,26 +287,11 @@
 		}
 	}
 
-	assert(0);
+	NOUVEAU_ERR("out of registers\n");
+	abort();
 	return NULL;
 }
 
-/* Assign the hw of the discarded temporary register src
- * to the tgsi register dst and free src.
- */
-static void
-assimilate_temp(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
-{
-	assert(src->index == -1 && src->hw != -1);
-
-	if (dst->hw != -1)
-		pc->r_temp[dst->hw] = NULL;
-	pc->r_temp[src->hw] = dst;
-	dst->hw = src->hw;
-
-	FREE(src);
-}
-
 /* release the hardware resource held by r */
 static void
 release_hw(struct nv50_pc *pc, struct nv50_reg *r)
@@ -329,38 +350,53 @@
 }
 
 static struct nv50_reg *
-temp_temp(struct nv50_pc *pc)
+temp_temp(struct nv50_pc *pc, struct nv50_program_exec *e)
 {
 	if (pc->temp_temp_nr >= 16)
 		assert(0);
 
 	pc->temp_temp[pc->temp_temp_nr] = alloc_temp(pc, NULL);
+	pc->temp_temp_exec[pc->temp_temp_nr] = e;
 	return pc->temp_temp[pc->temp_temp_nr++];
 }
 
+/* This *must* be called for all nv50_program_exec that have been
+ * given as argument to temp_temp, or the temps will be leaked !
+ */
 static void
-kill_temp_temp(struct nv50_pc *pc)
+kill_temp_temp(struct nv50_pc *pc, struct nv50_program_exec *e)
 {
 	int i;
-	
+
 	for (i = 0; i < pc->temp_temp_nr; i++)
-		free_temp(pc, pc->temp_temp[i]);
-	pc->temp_temp_nr = 0;
+		if (pc->temp_temp_exec[i] == e)
+			free_temp(pc, pc->temp_temp[i]);
+	if (!e)
+		pc->temp_temp_nr = 0;
 }
 
 static int
-ctor_immd(struct nv50_pc *pc, float x, float y, float z, float w)
+ctor_immd_4u32(struct nv50_pc *pc,
+	       uint32_t x, uint32_t y, uint32_t z, uint32_t w)
 {
-	pc->immd_buf = REALLOC(pc->immd_buf, (pc->immd_nr * 4 * sizeof(float)),
-			       (pc->immd_nr + 1) * 4 * sizeof(float));
+	unsigned size = pc->immd_nr * 4 * sizeof(uint32_t);
+
+	pc->immd_buf = REALLOC(pc->immd_buf, size, size + 4 * sizeof(uint32_t));
+
 	pc->immd_buf[(pc->immd_nr * 4) + 0] = x;
 	pc->immd_buf[(pc->immd_nr * 4) + 1] = y;
 	pc->immd_buf[(pc->immd_nr * 4) + 2] = z;
 	pc->immd_buf[(pc->immd_nr * 4) + 3] = w;
-	
+
 	return pc->immd_nr++;
 }
 
+static INLINE int
+ctor_immd_4f32(struct nv50_pc *pc, float x, float y, float z, float w)
+{
+	return ctor_immd_4u32(pc, fui(x), fui(y), fui(z), fui(w));
+}
+
 static struct nv50_reg *
 alloc_immd(struct nv50_pc *pc, float f)
 {
@@ -368,11 +404,11 @@
 	unsigned hw;
 
 	for (hw = 0; hw < pc->immd_nr * 4; hw++)
-		if (pc->immd_buf[hw] == f)
+		if (pc->immd_buf[hw] == fui(f))
 			break;
 
 	if (hw == pc->immd_nr * 4)
-		hw = ctor_immd(pc, f, -f, 0.5 * f, 0) * 4;
+		hw = ctor_immd_4f32(pc, f, -f, 0.5 * f, 0) * 4;
 
 	ctor_reg(r, P_IMMD, -1, hw);
 	return r;
@@ -398,6 +434,8 @@
 		p->exec_head = e;
 	p->exec_tail = e;
 	p->exec_size += (e->inst[0] & 1) ? 2 : 1;
+
+	kill_temp_temp(pc, e);
 }
 
 static INLINE void set_long(struct nv50_pc *, struct nv50_program_exec *);
@@ -418,10 +456,19 @@
 	return FALSE;
 }
 
+static boolean
+is_join(struct nv50_program_exec *e)
+{
+	if (is_long(e) && (e->inst[1] & 3) == 2)
+		return TRUE;
+	return FALSE;
+}
+
 static INLINE void
 set_pred(struct nv50_pc *pc, unsigned pred, unsigned idx,
 	 struct nv50_program_exec *e)
 {
+	assert(!is_immd(e));
 	set_long(pc, e);
 	e->inst[1] &= ~((0x1f << 7) | (0x3 << 12));
 	e->inst[1] |= (pred << 7) | (idx << 12);
@@ -464,22 +511,15 @@
 static INLINE void
 set_immd(struct nv50_pc *pc, struct nv50_reg *imm, struct nv50_program_exec *e)
 {
-	unsigned val;
-	float f = pc->immd_buf[imm->hw];
-
-	if (imm->mod & NV50_MOD_ABS)
-		f = fabsf(f);
-	val = fui((imm->mod & NV50_MOD_NEG) ? -f : f);
-
 	set_long(pc, e);
-	/*XXX: can't be predicated - bits overlap.. catch cases where both
-	 *     are required and avoid them. */
+	/* XXX: can't be predicated - bits overlap; cases where both
+	 * are required should be avoided by using pc->allow32 */
 	set_pred(pc, 0, 0, e);
 	set_pred_wr(pc, 0, 0, e);
 
 	e->inst[1] |= 0x00000002 | 0x00000001;
-	e->inst[0] |= (val & 0x3f) << 16;
-	e->inst[1] |= (val >> 6) << 2;
+	e->inst[0] |= (pc->immd_buf[imm->hw] & 0x3f) << 16;
+	e->inst[1] |= (pc->immd_buf[imm->hw] >> 6) << 2;
 }
 
 static INLINE void
@@ -511,21 +551,24 @@
 static struct nv50_reg *
 alloc_addr(struct nv50_pc *pc, struct nv50_reg *ref)
 {
-	int i;
 	struct nv50_reg *a_tgsi = NULL, *a = NULL;
+	int i;
+	uint8_t avail = ~pc->addr_alloc;
 
 	if (!ref) {
-		/* allocate for TGSI address reg */
-		for (i = 0; i < NV50_SU_MAX_ADDR; ++i) {
-			if (pc->r_addr[i].index >= 0)
-				continue;
-			if (pc->r_addr[i].rhw >= 0 &&
-			    pc->r_addr[i].acc == pc->insn_cur)
-				continue;
+		/* allocate for TGSI_FILE_ADDRESS */
+		while (avail) {
+			i = ffs(avail) - 1;
 
-			pc->r_addr[i].rhw = -1;
-			pc->r_addr[i].index = i;
-			return &pc->r_addr[i];
+			if (pc->r_addr[i].rhw < 0 ||
+			    pc->r_addr[i].acc != pc->insn_cur) {
+				pc->addr_alloc |= (1 << i);
+
+				pc->r_addr[i].rhw = -1;
+				pc->r_addr[i].index = i;
+				return &pc->r_addr[i];
+			}
+			avail &= ~(1 << i);
 		}
 		assert(0);
 		return NULL;
@@ -533,15 +576,16 @@
 
 	/* Allocate and set an address reg so we can access 'ref'.
 	 *
-	 * If and r_addr has index < 0, it is not reserved for TGSI,
-	 * and index will be the negative of the TGSI addr index the
-	 * value in rhw is relative to, or -256 if rhw is an offset
-	 * from 0. If rhw < 0, the reg has not been initialized.
+	 * If and r_addr->index will be -1 or the hw index the value
+	 * value in rhw is relative to. If rhw < 0, the reg has not
+	 * been initialized or is in use for TGSI_FILE_ADDRESS.
 	 */
-	for (i = NV50_SU_MAX_ADDR - 1; i >= 0; --i) {
-		if (pc->r_addr[i].index >= 0) /* occupied for TGSI */
-			continue;
-		if (pc->r_addr[i].rhw < 0) { /* unused */
+	while (avail) { /* only consider regs that are not TGSI */
+		i = ffs(avail) - 1;
+		avail &= ~(1 << i);
+
+		if ((!a || a->rhw >= 0) && pc->r_addr[i].rhw < 0) {
+			/* prefer an usused reg with low hw index */
 			a = &pc->r_addr[i];
 			continue;
 		}
@@ -551,8 +595,8 @@
 		if (ref->hw - pc->r_addr[i].rhw >= 128)
 			continue;
 
-		if ((ref->acc >= 0 && pc->r_addr[i].index == -256) ||
-		    (ref->acc < 0 && -pc->r_addr[i].index == ref->index)) {
+		if ((ref->acc >= 0 && pc->r_addr[i].index < 0) ||
+		    (ref->acc < 0 && pc->r_addr[i].index == ref->index)) {
 			pc->r_addr[i].acc = pc->insn_cur;
 			return &pc->r_addr[i];
 		}
@@ -566,7 +610,7 @@
 
 	a->rhw = ref->hw & ~0x7f;
 	a->acc = pc->insn_cur;
-	a->index = a_tgsi ? -ref->index : -256;
+	a->index = a_tgsi ? ref->index : -1;
 	return a;
 }
 
@@ -624,6 +668,7 @@
 	e->inst[1] |= (((src->type == P_IMMD) ? 0 : 1) << 22);
 }
 
+/* Never apply nv50_reg::mod in emit_mov, or carefully check the code !!! */
 static void
 emit_mov(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
 {
@@ -644,7 +689,7 @@
 	if (src->type == P_IMMD || src->type == P_CONST) {
 		set_long(pc, e);
 		set_data(pc, src, 0x7f, 9, e);
-		e->inst[1] |= 0x20000000; /* src0 const? */
+		e->inst[1] |= 0x20000000; /* mov from c[] */
 	} else {
 		if (src->type == P_ATTR) {
 			set_long(pc, e);
@@ -659,9 +704,9 @@
 
 	if (is_long(e) && !is_immd(e)) {
 		e->inst[1] |= 0x04000000; /* 32-bit */
-		e->inst[1] |= 0x0000c000; /* "subsubop" 0x3 */
+		e->inst[1] |= 0x0000c000; /* 32-bit c[] load / lane mask 0:1 */
 		if (!(e->inst[1] & 0x20000000))
-			e->inst[1] |= 0x00030000; /* "subsubop" 0xf */
+			e->inst[1] |= 0x00030000; /* lane mask 2:3 */
 	} else
 		e->inst[0] |= 0x00008000;
 
@@ -676,6 +721,45 @@
 	FREE(imm);
 }
 
+/* Assign the hw of the discarded temporary register src
+ * to the tgsi register dst and free src.
+ */
+static void
+assimilate_temp(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
+{
+	assert(src->index == -1 && src->hw != -1);
+
+	if (pc->if_lvl || pc->loop_lvl ||
+	    (dst->type != P_TEMP) ||
+	    (src->hw < pc->result_nr * 4 &&
+	     pc->p->type == PIPE_SHADER_FRAGMENT) ||
+	    pc->p->info.opcode_count[TGSI_OPCODE_CAL] ||
+	    pc->p->info.opcode_count[TGSI_OPCODE_BRA]) {
+
+		emit_mov(pc, dst, src);
+		free_temp(pc, src);
+		return;
+	}
+
+	if (dst->hw != -1)
+		pc->r_temp[dst->hw] = NULL;
+	pc->r_temp[src->hw] = dst;
+	dst->hw = src->hw;
+
+	FREE(src);
+}
+
+static void
+emit_nop(struct nv50_pc *pc)
+{
+	struct nv50_program_exec *e = exec(pc);
+
+	e->inst[0] = 0xf0000000;
+	set_long(pc, e);
+	e->inst[1] = 0xe0000000;
+	emit(pc, e);
+}
+
 static boolean
 check_swap_src_0_1(struct nv50_pc *pc,
 		   struct nv50_reg **s0, struct nv50_reg **s1)
@@ -707,7 +791,7 @@
 	struct nv50_reg *temp;
 
 	if (src->type != P_TEMP) {
-		temp = temp_temp(pc);
+		temp = temp_temp(pc, e);
 		emit_mov(pc, temp, src);
 		src = temp;
 	}
@@ -726,7 +810,7 @@
 		e->inst[1] |= 0x00200000;
 	} else
 	if (src->type == P_CONST || src->type == P_IMMD) {
-		struct nv50_reg *temp = temp_temp(pc);
+		struct nv50_reg *temp = temp_temp(pc, e);
 
 		emit_mov(pc, temp, src);
 		src = temp;
@@ -742,7 +826,7 @@
 set_src_1(struct nv50_pc *pc, struct nv50_reg *src, struct nv50_program_exec *e)
 {
 	if (src->type == P_ATTR) {
-		struct nv50_reg *temp = temp_temp(pc);
+		struct nv50_reg *temp = temp_temp(pc, e);
 
 		emit_mov(pc, temp, src);
 		src = temp;
@@ -750,7 +834,7 @@
 	if (src->type == P_CONST || src->type == P_IMMD) {
 		assert(!(e->inst[0] & 0x00800000));
 		if (e->inst[0] & 0x01000000) {
-			struct nv50_reg *temp = temp_temp(pc);
+			struct nv50_reg *temp = temp_temp(pc, e);
 
 			emit_mov(pc, temp, src);
 			src = temp;
@@ -772,7 +856,7 @@
 	set_long(pc, e);
 
 	if (src->type == P_ATTR) {
-		struct nv50_reg *temp = temp_temp(pc);
+		struct nv50_reg *temp = temp_temp(pc, e);
 
 		emit_mov(pc, temp, src);
 		src = temp;
@@ -780,7 +864,7 @@
 	if (src->type == P_CONST || src->type == P_IMMD) {
 		assert(!(e->inst[0] & 0x01000000));
 		if (e->inst[0] & 0x00800000) {
-			struct nv50_reg *temp = temp_temp(pc);
+			struct nv50_reg *temp = temp_temp(pc, e);
 
 			emit_mov(pc, temp, src);
 			src = temp;
@@ -795,6 +879,53 @@
 }
 
 static void
+set_half_src(struct nv50_pc *pc, struct nv50_reg *src, int lh,
+	     struct nv50_program_exec *e, int pos)
+{
+	struct nv50_reg *r = src;
+
+	alloc_reg(pc, r);
+	if (r->type != P_TEMP) {
+		r = temp_temp(pc, e);
+		emit_mov(pc, r, src);
+	}
+
+	if (r->hw > (NV50_SU_MAX_TEMP / 2)) {
+		NOUVEAU_ERR("out of low GPRs\n");
+		abort();
+	}
+
+	e->inst[pos / 32] |= ((src->hw * 2) + lh) << (pos % 32);
+}
+
+static void
+emit_mov_from_pred(struct nv50_pc *pc, struct nv50_reg *dst, int pred)
+{
+	struct nv50_program_exec *e = exec(pc);
+
+	assert(dst->type == P_TEMP);
+	e->inst[1] = 0x20000000 | (pred << 12);
+	set_long(pc, e);
+	set_dst(pc, dst, e);
+
+	emit(pc, e);
+}
+
+static void
+emit_mov_to_pred(struct nv50_pc *pc, int pred, struct nv50_reg *src)
+{
+	struct nv50_program_exec *e = exec(pc);
+
+	e->inst[0] = 0x000001fc;
+	e->inst[1] = 0xa0000008;
+	set_long(pc, e);
+	set_pred_wr(pc, 1, pred, e);
+	set_src_0_restricted(pc, src, e);
+
+	emit(pc, e);
+}
+
+static void
 emit_mul(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0,
 	 struct nv50_reg *src1)
 {
@@ -809,7 +940,7 @@
 	set_dst(pc, dst, e);
 	set_src_0(pc, src0, e);
 	if (src1->type == P_IMMD && !is_long(e)) {
-		if (src0->mod & NV50_MOD_NEG)
+		if (src0->mod ^ src1->mod)
 			e->inst[0] |= 0x00008000;
 		set_immd(pc, src1, e);
 	} else {
@@ -871,6 +1002,13 @@
 	emit(pc, e);
 }
 
+#define NV50_MAX_F32 0x880
+#define NV50_MAX_S32 0x08c
+#define NV50_MAX_U32 0x084
+#define NV50_MIN_F32 0x8a0
+#define NV50_MIN_S32 0x0ac
+#define NV50_MIN_U32 0x0a4
+
 static void
 emit_minmax(struct nv50_pc *pc, unsigned sub, struct nv50_reg *dst,
 	    struct nv50_reg *src0, struct nv50_reg *src1)
@@ -878,8 +1016,8 @@
 	struct nv50_program_exec *e = exec(pc);
 
 	set_long(pc, e);
-	e->inst[0] |= 0xb0000000;
-	e->inst[1] |= (sub << 29);
+	e->inst[0] |= 0x30000000 | ((sub & 0x800) << 20);
+	e->inst[1] |= (sub << 24);
 
 	check_swap_src_0_1(pc, &src0, &src1);
 	set_dst(pc, dst, e);
@@ -898,7 +1036,6 @@
 emit_sub(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0,
 	 struct nv50_reg *src1)
 {
-	assert(src0 != src1);
 	src1->mod ^= NV50_MOD_NEG;
 	emit_add(pc, dst, src0, src1);
 	src1->mod ^= NV50_MOD_NEG;
@@ -921,6 +1058,8 @@
 	    op != TGSI_OPCODE_XOR)
 		assert(!"invalid bit op");
 
+	assert(!(src0->mod | src1->mod));
+
 	if (src1->type == P_IMMD && src0->type == P_TEMP && pc->allow32) {
 		set_immd(pc, src1, e);
 		if (op == TGSI_OPCODE_OR)
@@ -942,6 +1081,69 @@
 }
 
 static void
+emit_not(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
+{
+	struct nv50_program_exec *e = exec(pc);
+
+	e->inst[0] = 0xd0000000;
+	e->inst[1] = 0x0402c000;
+	set_long(pc, e);
+	set_dst(pc, dst, e);
+	set_src_1(pc, src, e);
+
+	emit(pc, e);
+}
+
+static void
+emit_shift(struct nv50_pc *pc, struct nv50_reg *dst,
+	   struct nv50_reg *src0, struct nv50_reg *src1, unsigned dir)
+{
+	struct nv50_program_exec *e = exec(pc);
+
+	e->inst[0] = 0x30000000;
+	e->inst[1] = 0xc4000000;
+
+	set_long(pc, e);
+	set_dst(pc, dst, e);
+	set_src_0(pc, src0, e);
+
+	if (src1->type == P_IMMD) {
+		e->inst[1] |= (1 << 20);
+		e->inst[0] |= (pc->immd_buf[src1->hw] & 0x7f) << 16;
+	} else
+		set_src_1(pc, src1, e);
+
+	if (dir != TGSI_OPCODE_SHL)
+		e->inst[1] |= (1 << 29);
+
+	if (dir == TGSI_OPCODE_ISHR)
+		e->inst[1] |= (1 << 27);
+
+	emit(pc, e);
+}
+
+static void
+emit_shl_imm(struct nv50_pc *pc, struct nv50_reg *dst,
+	     struct nv50_reg *src, int s)
+{
+	struct nv50_program_exec *e = exec(pc);
+
+	e->inst[0] = 0x30000000;
+	e->inst[1] = 0xc4100000;
+	if (s < 0) {
+		e->inst[1] |= 1 << 29;
+		s = -s;
+	}
+	e->inst[1] |= ((s & 0x7f) << 16);
+
+	set_long(pc, e);
+	set_dst(pc, dst, e);
+	set_src_0(pc, src, e);
+
+	emit(pc, e);
+}
+
+static void
 emit_mad(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0,
 	 struct nv50_reg *src1, struct nv50_reg *src2)
 {
@@ -967,12 +1169,19 @@
 emit_msb(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0,
 	 struct nv50_reg *src1, struct nv50_reg *src2)
 {
-	assert(src2 != src0 && src2 != src1);
 	src2->mod ^= NV50_MOD_NEG;
 	emit_mad(pc, dst, src0, src1, src2);
 	src2->mod ^= NV50_MOD_NEG;
 }
 
+#define NV50_FLOP_RCP 0
+#define NV50_FLOP_RSQ 2
+#define NV50_FLOP_LG2 3
+#define NV50_FLOP_SIN 4
+#define NV50_FLOP_COS 5
+#define NV50_FLOP_EX2 6
+
+/* rcp, rsqrt, lg2 support neg and abs */
 static void
 emit_flop(struct nv50_pc *pc, unsigned sub,
 	  struct nv50_reg *dst, struct nv50_reg *src)
@@ -980,17 +1189,20 @@
 	struct nv50_program_exec *e = exec(pc);
 
 	e->inst[0] |= 0x90000000;
-	if (sub) {
+	if (sub || src->mod) {
 		set_long(pc, e);
 		e->inst[1] |= (sub << 29);
 	}
 
 	set_dst(pc, dst, e);
+	set_src_0_restricted(pc, src, e);
 
-	if (sub == 0 || sub == 2)
-		set_src_0_restricted(pc, src, e);
-	else
-		set_src_0(pc, src, e);
+	assert(!src->mod || sub < 4);
+
+	if (src->mod & NV50_MOD_NEG)
+		e->inst[1] |= 0x04000000;
+	if (src->mod & NV50_MOD_ABS)
+		e->inst[1] |= 0x00100000;
 
 	emit(pc, e);
 }
@@ -1007,6 +1219,11 @@
 	set_long(pc, e);
 	e->inst[1] |= (6 << 29) | 0x00004000;
 
+	if (src->mod & NV50_MOD_NEG)
+		e->inst[1] |= 0x04000000;
+	if (src->mod & NV50_MOD_ABS)
+		e->inst[1] |= 0x00100000;
+
 	emit(pc, e);
 }
 
@@ -1022,39 +1239,49 @@
 	set_long(pc, e);
 	e->inst[1] |= (6 << 29);
 
+	if (src->mod & NV50_MOD_NEG)
+		e->inst[1] |= 0x04000000;
+	if (src->mod & NV50_MOD_ABS)
+		e->inst[1] |= 0x00100000;
+
 	emit(pc, e);
 }
 
-#define CVTOP_RN	0x01
-#define CVTOP_FLOOR	0x03
-#define CVTOP_CEIL	0x05
-#define CVTOP_TRUNC	0x07
-#define CVTOP_SAT	0x08
-#define CVTOP_ABS	0x10
+#define CVT_RN    (0x00 << 16)
+#define CVT_FLOOR (0x02 << 16)
+#define CVT_CEIL  (0x04 << 16)
+#define CVT_TRUNC (0x06 << 16)
+#define CVT_SAT   (0x08 << 16)
+#define CVT_ABS   (0x10 << 16)
 
-/* 0x04 == 32 bit dst */
-/* 0x40 == dst is float */
-/* 0x80 == src is float */
-#define CVT_F32_F32 0xc4
-#define CVT_F32_S32 0x44
-#define CVT_S32_F32 0x8c
-#define CVT_S32_S32 0x0c
-#define CVT_NEG     0x20
-#define CVT_RI      0x08
+#define CVT_X32_X32 0x04004000
+#define CVT_X32_S32 0x04014000
+#define CVT_F32_F32 ((0xc0 << 24) | CVT_X32_X32)
+#define CVT_S32_F32 ((0x88 << 24) | CVT_X32_X32)
+#define CVT_U32_F32 ((0x80 << 24) | CVT_X32_X32)
+#define CVT_F32_S32 ((0x40 << 24) | CVT_X32_S32)
+#define CVT_F32_U32 ((0x40 << 24) | CVT_X32_X32)
+#define CVT_S32_S32 ((0x08 << 24) | CVT_X32_S32)
+#define CVT_S32_U32 ((0x08 << 24) | CVT_X32_X32)
+#define CVT_U32_S32 ((0x00 << 24) | CVT_X32_S32)
+
+#define CVT_NEG 0x20000000
+#define CVT_RI  0x08000000
 
 static void
 emit_cvt(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src,
-	 int wp, unsigned cvn, unsigned fmt)
+	 int wp, uint32_t cvn)
 {
 	struct nv50_program_exec *e;
 
 	e = exec(pc);
-	set_long(pc, e);
 
-	e->inst[0] |= 0xa0000000;
-	e->inst[1] |= 0x00004000; /* 32 bit src */
-	e->inst[1] |= (cvn << 16);
-	e->inst[1] |= (fmt << 24);
+	if (src->mod & NV50_MOD_NEG) cvn |= CVT_NEG;
+	if (src->mod & NV50_MOD_ABS) cvn |= CVT_ABS;
+
+	e->inst[0] = 0xa0000000;
+	e->inst[1] = cvn;
+	set_long(pc, e);
 	set_src_0(pc, src, e);
 
 	if (wp >= 0)
@@ -1079,10 +1306,12 @@
  *  0x6 = GE
  *  0x7 = set condition code ? (used before bra.lt/le/gt/ge)
  *  0x8 = unordered bit (allows NaN)
+ *
+ *  mode = 0x04 (u32), 0x0c (s32), 0x80 (f32)
  */
 static void
 emit_set(struct nv50_pc *pc, unsigned ccode, struct nv50_reg *dst, int wp,
-	 struct nv50_reg *src0, struct nv50_reg *src1)
+	 struct nv50_reg *src0, struct nv50_reg *src1, uint8_t mode)
 {
 	static const unsigned cc_swapped[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
 
@@ -1097,16 +1326,10 @@
 	if (dst && dst->type != P_TEMP)
 		dst = alloc_temp(pc, NULL);
 
-	/* set.u32 */
 	set_long(pc, e);
-	e->inst[0] |= 0xb0000000;
+	e->inst[0] |= 0x30000000 | (mode << 24);
 	e->inst[1] |= 0x60000000 | (ccode << 14);
 
-	/* XXX: decuda will disasm as .u16 and use .lo/.hi regs, but
-	 * that doesn't seem to match what the hw actually does
-	e->inst[1] |= 0x04000000; << breaks things, u32 by default ?
-	 */
-
 	if (wp >= 0)
 		set_pred_wr(pc, 1, wp, e);
 	if (dst)
@@ -1120,35 +1343,147 @@
 	set_src_1(pc, src1, e);
 
 	emit(pc, e);
-	pc->if_cond = pc->p->exec_tail; /* record for OPCODE_IF */
 
-	/* cvt.f32.u32/s32 (?) if we didn't only write the predicate */
-	if (rdst)
-		emit_cvt(pc, rdst, dst, -1, CVTOP_ABS | CVTOP_RN, CVT_F32_S32);
+	if (rdst && mode == 0x80) /* convert to float ? */
+		emit_cvt(pc, rdst, dst, -1, CVT_ABS | CVT_F32_S32);
 	if (rdst && rdst != dst)
 		free_temp(pc, dst);
 }
 
-static INLINE unsigned
-map_tgsi_setop_cc(unsigned op)
+static INLINE void
+map_tgsi_setop_hw(unsigned op, uint8_t *cc, uint8_t *ty)
 {
 	switch (op) {
-	case TGSI_OPCODE_SLT: return 0x1;
-	case TGSI_OPCODE_SGE: return 0x6;
-	case TGSI_OPCODE_SEQ: return 0x2;
-	case TGSI_OPCODE_SGT: return 0x4;
-	case TGSI_OPCODE_SLE: return 0x3;
-	case TGSI_OPCODE_SNE: return 0xd;
+	case TGSI_OPCODE_SLT: *cc = 0x1; *ty = 0x80; break;
+	case TGSI_OPCODE_SGE: *cc = 0x6; *ty = 0x80; break;
+	case TGSI_OPCODE_SEQ: *cc = 0x2; *ty = 0x80; break;
+	case TGSI_OPCODE_SGT: *cc = 0x4; *ty = 0x80; break;
+	case TGSI_OPCODE_SLE: *cc = 0x3; *ty = 0x80; break;
+	case TGSI_OPCODE_SNE: *cc = 0xd; *ty = 0x80; break;
+
+	case TGSI_OPCODE_ISLT: *cc = 0x1; *ty = 0x0c; break;
+	case TGSI_OPCODE_ISGE: *cc = 0x6; *ty = 0x0c; break;
+	case TGSI_OPCODE_USEQ: *cc = 0x2; *ty = 0x04; break;
+	case TGSI_OPCODE_USGE: *cc = 0x6; *ty = 0x04; break;
+	case TGSI_OPCODE_USLT: *cc = 0x1; *ty = 0x04; break;
+	case TGSI_OPCODE_USNE: *cc = 0x5; *ty = 0x04; break;
 	default:
 		assert(0);
-		return 0;
+		return;
 	}
 }
 
+static void
+emit_add_b32(struct nv50_pc *pc, struct nv50_reg *dst,
+	     struct nv50_reg *src0, struct nv50_reg *rsrc1)
+{
+	struct nv50_program_exec *e = exec(pc);
+	struct nv50_reg *src1;
+
+	e->inst[0] = 0x20000000;
+
+	alloc_reg(pc, rsrc1);
+	check_swap_src_0_1(pc, &src0, &rsrc1);
+
+	src1 = rsrc1;
+	if (src0->mod & rsrc1->mod & NV50_MOD_NEG) {
+		src1 = temp_temp(pc, e);
+		emit_cvt(pc, src1, rsrc1, -1, CVT_S32_S32);
+	}
+
+	if (!pc->allow32 || src1->hw > 63 ||
+	    (src1->type != P_TEMP && src1->type != P_IMMD))
+		set_long(pc, e);
+
+	set_dst(pc, dst, e);
+	set_src_0(pc, src0, e);
+
+	if (is_long(e)) {
+		e->inst[1] |= 1 << 26;
+		set_src_2(pc, src1, e);
+	} else {
+		e->inst[0] |= 0x8000;
+		if (src1->type == P_IMMD)
+			set_immd(pc, src1, e);
+		else
+			set_src_1(pc, src1, e);
+	}
+
+	if (src0->mod & NV50_MOD_NEG)
+		e->inst[0] |= 1 << 28;
+	else
+	if (src1->mod & NV50_MOD_NEG)
+		e->inst[0] |= 1 << 22;
+
+	emit(pc, e);
+}
+
+static void
+emit_mad_u16(struct nv50_pc *pc, struct nv50_reg *dst,
+	     struct nv50_reg *src0, int lh_0, struct nv50_reg *src1, int lh_1,
+	     struct nv50_reg *src2)
+{
+	struct nv50_program_exec *e = exec(pc);
+
+	e->inst[0] = 0x60000000;
+	if (!pc->allow32)
+		set_long(pc, e);
+	set_dst(pc, dst, e);
+
+	set_half_src(pc, src0, lh_0, e, 9);
+	set_half_src(pc, src1, lh_1, e, 16);
+	alloc_reg(pc, src2);
+	if (is_long(e) || (src2->type != P_TEMP) || (src2->hw != dst->hw))
+		set_src_2(pc, src2, e);
+
+	emit(pc, e);
+}
+
+static void
+emit_mul_u16(struct nv50_pc *pc, struct nv50_reg *dst,
+	     struct nv50_reg *src0, int lh_0, struct nv50_reg *src1, int lh_1)
+{
+	struct nv50_program_exec *e = exec(pc);
+
+	e->inst[0] = 0x40000000;
+	set_long(pc, e);
+	set_dst(pc, dst, e);
+
+	set_half_src(pc, src0, lh_0, e, 9);
+	set_half_src(pc, src1, lh_1, e, 16);
+
+	emit(pc, e);
+}
+
+static void
+emit_sad(struct nv50_pc *pc, struct nv50_reg *dst,
+	 struct nv50_reg *src0, struct nv50_reg *src1, struct nv50_reg *src2)
+{
+	struct nv50_program_exec *e = exec(pc);
+
+	e->inst[0] = 0x50000000;
+	if (!pc->allow32)
+		set_long(pc, e);
+	check_swap_src_0_1(pc, &src0, &src1);
+	set_dst(pc, dst, e);
+	set_src_0(pc, src0, e);
+	set_src_1(pc, src1, e);
+	alloc_reg(pc, src2);
+	if (is_long(e) || (src2->type != dst->type) || (src2->hw != dst->hw))
+		set_src_2(pc, src2, e);
+
+	if (is_long(e))
+		e->inst[1] |= 0x0c << 24;
+	else
+		e->inst[0] |= 0x81 << 8;
+
+	emit(pc, e);
+}
+
 static INLINE void
 emit_flr(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
 {
-	emit_cvt(pc, dst, src, -1, CVTOP_FLOOR, CVT_F32_F32 | CVT_RI);
+	emit_cvt(pc, dst, src, -1, CVT_FLOOR | CVT_F32_F32 | CVT_RI);
 }
 
 static void
@@ -1157,24 +1492,18 @@
 {
 	struct nv50_reg *temp = alloc_temp(pc, NULL);
 
-	emit_flop(pc, 3, temp, v);
+	emit_flop(pc, NV50_FLOP_LG2, temp, v);
 	emit_mul(pc, temp, temp, e);
 	emit_preex2(pc, temp, temp);
-	emit_flop(pc, 6, dst, temp);
+	emit_flop(pc, NV50_FLOP_EX2, dst, temp);
 
 	free_temp(pc, temp);
 }
 
 static INLINE void
-emit_abs(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
-{
-	emit_cvt(pc, dst, src, -1, CVTOP_ABS, CVT_F32_F32);
-}
-
-static INLINE void
 emit_sat(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
 {
-	emit_cvt(pc, dst, src, -1, CVTOP_SAT, CVT_F32_F32);
+	emit_cvt(pc, dst, src, -1, CVT_SAT | CVT_F32_F32);
 }
 
 static void
@@ -1192,18 +1521,18 @@
 
 	if (mask & (3 << 1)) {
 		tmp[0] = alloc_temp(pc, NULL);
-		emit_minmax(pc, 4, tmp[0], src[0], zero);
+		emit_minmax(pc, NV50_MAX_F32, tmp[0], src[0], zero);
 	}
 
 	if (mask & (1 << 2)) {
 		set_pred_wr(pc, 1, 0, pc->p->exec_tail);
 
-		tmp[1] = temp_temp(pc);
-		emit_minmax(pc, 4, tmp[1], src[1], zero);
+		tmp[1] = temp_temp(pc, NULL);
+		emit_minmax(pc, NV50_MAX_F32, tmp[1], src[1], zero);
 
-		tmp[3] = temp_temp(pc);
-		emit_minmax(pc, 4, tmp[3], src[3], neg128);
-		emit_minmax(pc, 5, tmp[3], tmp[3], pos128);
+		tmp[3] = temp_temp(pc, NULL);
+		emit_minmax(pc, NV50_MAX_F32, tmp[3], src[3], neg128);
+		emit_minmax(pc, NV50_MIN_F32, tmp[3], tmp[3], pos128);
 
 		emit_pow(pc, dst[2], tmp[1], tmp[3]);
 		emit_mov(pc, dst[2], zero);
@@ -1231,35 +1560,115 @@
 	FREE(one);
 }
 
-static INLINE void
-emit_neg(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
-{
-	emit_cvt(pc, dst, src, -1, CVTOP_RN, CVT_F32_F32 | CVT_NEG);
-}
-
 static void
 emit_kil(struct nv50_pc *pc, struct nv50_reg *src)
 {
 	struct nv50_program_exec *e;
 	const int r_pred = 1;
-	unsigned cvn = CVT_F32_F32;
 
-	if (src->mod & NV50_MOD_NEG)
-		cvn |= CVT_NEG;
-	/* write predicate reg */
-	emit_cvt(pc, NULL, src, r_pred, CVTOP_RN, cvn);
-
-	/* conditional discard */
 	e = exec(pc);
-	e->inst[0] = 0x00000002;
-	set_long(pc, e);
-	set_pred(pc, 0x1 /* LT */, r_pred, e);
+	e->inst[0] = 0x00000002; /* discard */
+	set_long(pc, e); /* sets cond code to ALWAYS */
+
+	if (src) {
+		set_pred(pc, 0x1 /* cc = LT */, r_pred, e);
+		/* write to predicate reg */
+		emit_cvt(pc, NULL, src, r_pred, CVT_F32_F32);
+	}
+
 	emit(pc, e);
 }
 
+static struct nv50_program_exec *
+emit_control_flow(struct nv50_pc *pc, unsigned op, int pred, unsigned cc)
+{
+	struct nv50_program_exec *e = exec(pc);
+
+	e->inst[0] = (op << 28) | 2;
+	set_long(pc, e);
+	if (pred >= 0)
+		set_pred(pc, cc, pred, e);
+
+	emit(pc, e);
+	return e;
+}
+
+static INLINE struct nv50_program_exec *
+emit_breakaddr(struct nv50_pc *pc)
+{
+	return emit_control_flow(pc, 0x4, -1, 0);
+}
+
+static INLINE void
+emit_break(struct nv50_pc *pc, int pred, unsigned cc)
+{
+	emit_control_flow(pc, 0x5, pred, cc);
+}
+
+static INLINE struct nv50_program_exec *
+emit_joinat(struct nv50_pc *pc)
+{
+	return emit_control_flow(pc, 0xa, -1, 0);
+}
+
+static INLINE struct nv50_program_exec *
+emit_branch(struct nv50_pc *pc, int pred, unsigned cc)
+{
+	return emit_control_flow(pc, 0x1, pred, cc);
+}
+
+static INLINE struct nv50_program_exec *
+emit_call(struct nv50_pc *pc, int pred, unsigned cc)
+{
+	return emit_control_flow(pc, 0x2, pred, cc);
+}
+
+static INLINE void
+emit_ret(struct nv50_pc *pc, int pred, unsigned cc)
+{
+	emit_control_flow(pc, 0x3, pred, cc);
+}
+
+#define QOP_ADD 0
+#define QOP_SUBR 1
+#define QOP_SUB 2
+#define QOP_MOV_SRC1 3
+
+/* For a quad of threads / top left, top right, bottom left, bottom right
+ * pixels, do a different operation, and take src0 from a specific thread.
+ */
+static void
+emit_quadop(struct nv50_pc *pc, struct nv50_reg *dst, int wp, int lane_src0,
+	    struct nv50_reg *src0, struct nv50_reg *src1, ubyte qop)
+{
+       struct nv50_program_exec *e = exec(pc);
+
+       e->inst[0] = 0xc0000000;
+       e->inst[1] = 0x80000000;
+       set_long(pc, e);
+       e->inst[0] |= lane_src0 << 16;
+       set_src_0(pc, src0, e);
+       set_src_2(pc, src1, e);
+
+       if (wp >= 0)
+	       set_pred_wr(pc, 1, wp, e);
+
+       if (dst)
+	       set_dst(pc, dst, e);
+       else {
+	       e->inst[0] |= 0x000001fc;
+	       e->inst[1] |= 0x00000008;
+       }
+
+       e->inst[0] |= (qop & 3) << 20;
+       e->inst[1] |= (qop >> 2) << 22;
+
+       emit(pc, e);
+}
+
 static void
 load_cube_tex_coords(struct nv50_pc *pc, struct nv50_reg *t[4],
-		     struct nv50_reg **src, boolean proj)
+		     struct nv50_reg **src, unsigned arg, boolean proj)
 {
 	int mod[3] = { src[0]->mod, src[1]->mod, src[2]->mod };
 
@@ -1267,8 +1676,8 @@
 	src[1]->mod |= NV50_MOD_ABS;
 	src[2]->mod |= NV50_MOD_ABS;
 
-	emit_minmax(pc, 4, t[2], src[0], src[1]);
-	emit_minmax(pc, 4, t[2], src[2], t[2]);
+	emit_minmax(pc, NV50_MAX_F32, t[2], src[0], src[1]);
+	emit_minmax(pc, NV50_MAX_F32, t[2], src[2], t[2]);
 
 	src[0]->mod = mod[0];
 	src[1]->mod = mod[1];
@@ -1276,7 +1685,11 @@
 
 	if (proj && 0 /* looks more correct without this */)
 		emit_mul(pc, t[2], t[2], src[3]);
-	emit_flop(pc, 0, t[2], t[2]);
+	else
+	if (arg == 4) /* there is no textureProj(samplerCubeShadow) */
+		emit_mov(pc, t[3], src[3]);
+
+	emit_flop(pc, NV50_FLOP_RCP, t[2], t[2]);
 
 	emit_mul(pc, t[0], src[0], t[2]);
 	emit_mul(pc, t[1], src[1], t[2]);
@@ -1284,89 +1697,221 @@
 }
 
 static void
-emit_tex(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask,
-	 struct nv50_reg **src, unsigned unit, unsigned type, boolean proj)
+load_proj_tex_coords(struct nv50_pc *pc, struct nv50_reg *t[4],
+		     struct nv50_reg **src, unsigned dim, unsigned arg)
 {
-	struct nv50_reg *t[4];
-	struct nv50_program_exec *e;
+	unsigned c, mode;
 
-	unsigned c, mode, dim;
+	if (src[0]->type == P_TEMP && src[0]->rhw != -1) {
+		mode = pc->interp_mode[src[0]->index] | INTERP_PERSPECTIVE;
 
+		t[3]->rhw = src[3]->rhw;
+		emit_interp(pc, t[3], NULL, (mode & INTERP_CENTROID));
+		emit_flop(pc, NV50_FLOP_RCP, t[3], t[3]);
+
+		for (c = 0; c < dim; ++c) {
+			t[c]->rhw = src[c]->rhw;
+			emit_interp(pc, t[c], t[3], mode);
+		}
+		if (arg != dim) { /* depth reference value */
+			t[dim]->rhw = src[2]->rhw;
+			emit_interp(pc, t[dim], t[3], mode);
+		}
+	} else {
+		/* XXX: for some reason the blob sometimes uses MAD
+		 * (mad f32 $rX $rY $rZ neg $r63)
+		 */
+		emit_flop(pc, NV50_FLOP_RCP, t[3], src[3]);
+		for (c = 0; c < dim; ++c)
+			emit_mul(pc, t[c], src[c], t[3]);
+		if (arg != dim) /* depth reference value */
+			emit_mul(pc, t[dim], src[2], t[3]);
+	}
+}
+
+static INLINE void
+get_tex_dim(unsigned type, unsigned *dim, unsigned *arg)
+{
 	switch (type) {
 	case TGSI_TEXTURE_1D:
-		dim = 1;
+		*arg = *dim = 1;
+		break;
+	case TGSI_TEXTURE_SHADOW1D:
+		*dim = 1;
+		*arg = 2;
 		break;
 	case TGSI_TEXTURE_UNKNOWN:
 	case TGSI_TEXTURE_2D:
-	case TGSI_TEXTURE_SHADOW1D: /* XXX: x, z */
 	case TGSI_TEXTURE_RECT:
-		dim = 2;
+		*arg = *dim = 2;
+		break;
+	case TGSI_TEXTURE_SHADOW2D:
+	case TGSI_TEXTURE_SHADOWRECT:
+		*dim = 2;
+		*arg = 3;
 		break;
 	case TGSI_TEXTURE_3D:
 	case TGSI_TEXTURE_CUBE:
-	case TGSI_TEXTURE_SHADOW2D:
-	case TGSI_TEXTURE_SHADOWRECT: /* XXX */
-		dim = 3;
+		*dim = *arg = 3;
 		break;
 	default:
 		assert(0);
 		break;
 	}
+}
 
-	/* some cards need t[0]'s hw index to be a multiple of 4 */
-	alloc_temp4(pc, t, 0);
+/* We shouldn't execute TEXLOD if any of the pixels in a quad have
+ * different LOD values, so branch off groups of equal LOD.
+ */
+static void
+emit_texlod_sequence(struct nv50_pc *pc, struct nv50_reg *tlod,
+		     struct nv50_reg *src, struct nv50_program_exec *tex)
+{
+	struct nv50_program_exec *join_at;
+	unsigned i, target = pc->p->exec_size + 9 * 2;
 
-	if (type == TGSI_TEXTURE_CUBE) {
-		load_cube_tex_coords(pc, t, src, proj);
-	} else
-	if (proj) {
-		if (src[0]->type == P_TEMP && src[0]->rhw != -1) {
-			mode = pc->interp_mode[src[0]->index];
+	if (pc->p->type != PIPE_SHADER_FRAGMENT) {
+		emit(pc, tex);
+		return;
+	}
+	pc->allow32 = FALSE;
 
-			t[3]->rhw = src[3]->rhw;
-			emit_interp(pc, t[3], NULL, (mode & INTERP_CENTROID));
-			emit_flop(pc, 0, t[3], t[3]);
+	/* Subtract lod of each pixel from lod of top left pixel, jump
+	 * texlod insn if result is 0, then repeat for 2 other pixels.
+	 */
+	join_at = emit_joinat(pc);
+	emit_quadop(pc, NULL, 0, 0, tlod, tlod, 0x55);
+	emit_branch(pc, 0, 2)->param.index = target;
 
-			for (c = 0; c < dim; c++) {
-				t[c]->rhw = src[c]->rhw;
-				emit_interp(pc, t[c], t[3],
-					    (mode | INTERP_PERSPECTIVE));
-			}
-		} else {
-			emit_flop(pc, 0, t[3], src[3]);
-			for (c = 0; c < dim; c++)
-				emit_mul(pc, t[c], src[c], t[3]);
-
-			/* XXX: for some reason the blob sometimes uses MAD:
-			 * emit_mad(pc, t[c], src[0][c], t[3], t[3])
-			 * pc->p->exec_tail->inst[1] |= 0x080fc000;
-			 */
-		}
-	} else {
-		for (c = 0; c < dim; c++)
-			emit_mov(pc, t[c], src[c]);
+	for (i = 1; i < 4; ++i) {
+		emit_quadop(pc, NULL, 0, i, tlod, tlod, 0x55);
+		emit_branch(pc, 0, 2)->param.index = target;
 	}
 
-	e = exec(pc);
-	set_long(pc, e);
-	e->inst[0] |= 0xf0000000;
-	e->inst[1] |= 0x00000004;
-	set_dst(pc, t[0], e);
-	e->inst[0] |= (unit << 9);
+	emit_mov(pc, tlod, src); /* target */
+	emit(pc, tex); /* texlod */
 
-	if (dim == 2)
-		e->inst[0] |= 0x00400000;
-	else
-	if (dim == 3) {
-		e->inst[0] |= 0x00800000;
-		if (type == TGSI_TEXTURE_CUBE)
-			e->inst[0] |= 0x08000000;
+	join_at->param.index = target + 2 * 2;
+	JOIN_ON(emit_nop(pc)); /* join _after_ tex */
+}
+
+static void
+emit_texbias_sequence(struct nv50_pc *pc, struct nv50_reg *t[4], unsigned arg,
+		      struct nv50_program_exec *tex)
+{
+	struct nv50_program_exec *e;
+	struct nv50_reg imm_1248, *t123[4][4], *r_bits = alloc_temp(pc, NULL);
+	int r_pred = 0;
+	unsigned n, c, i, cc[4] = { 0x0a, 0x13, 0x11, 0x10 };
+
+	pc->allow32 = FALSE;
+	ctor_reg(&imm_1248, P_IMMD, -1, ctor_immd_4u32(pc, 1, 2, 4, 8) * 4);
+
+	/* Subtract bias value of thread i from bias values of each thread,
+	 * store result in r_pred, and set bit i in r_bits if result was 0.
+	 */
+	assert(arg < 4);
+	for (i = 0; i < 4; ++i, ++imm_1248.hw) {
+		emit_quadop(pc, NULL, r_pred, i, t[arg], t[arg], 0x55);
+		emit_mov(pc, r_bits, &imm_1248);
+		set_pred(pc, 2, r_pred, pc->p->exec_tail);
+	}
+	emit_mov_to_pred(pc, r_pred, r_bits);
+
+	/* The lanes of a quad are now grouped by the bit in r_pred they have
+	 * set. Put the input values for TEX into a new register set for each
+	 * group and execute TEX only for a specific group.
+	 * We cannot use the same register set for each group because we need
+	 * the derivatives, which are implicitly calculated, to be correct.
+	 */
+	for (i = 1; i < 4; ++i) {
+		alloc_temp4(pc, t123[i], 0);
+
+		for (c = 0; c <= arg; ++c)
+			emit_mov(pc, t123[i][c], t[c]);
+
+		*(e = exec(pc)) = *(tex);
+		e->inst[0] &= ~0x01fc;
+		set_dst(pc, t123[i][0], e);
+		set_pred(pc, cc[i], r_pred, e);
+		emit(pc, e);
+	}
+	/* finally TEX on the original regs (where we kept the input) */
+	set_pred(pc, cc[0], r_pred, tex);
+	emit(pc, tex);
+
+	/* put the 3 * n other results into regs for lane 0 */
+	n = popcnt4(((e->inst[0] >> 25) & 0x3) | ((e->inst[1] >> 12) & 0xc));
+	for (i = 1; i < 4; ++i) {
+		for (c = 0; c < n; ++c) {
+			emit_mov(pc, t[c], t123[i][c]);
+			set_pred(pc, cc[i], r_pred, pc->p->exec_tail);
+		}
+		free_temp4(pc, t123[i]);
+	}
+
+	emit_nop(pc);
+	free_temp(pc, r_bits);
+}
+
+static void
+emit_tex(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask,
+	 struct nv50_reg **src, unsigned unit, unsigned type,
+	 boolean proj, int bias_lod)
+{
+	struct nv50_reg *t[4];
+	struct nv50_program_exec *e;
+	unsigned c, dim, arg;
+
+	/* t[i] must be within a single 128 bit super-reg */
+	alloc_temp4(pc, t, 0);
+
+	e = exec(pc);
+	e->inst[0] = 0xf0000000;
+	set_long(pc, e);
+	set_dst(pc, t[0], e);
+
+	/* TIC and TSC binding indices (TSC is ignored as TSC_LINKED = TRUE): */
+	e->inst[0] |= (unit << 9) /* | (unit << 17) */;
+
+	/* live flag (don't set if TEX results affect input to another TEX): */
+	/* e->inst[0] |= 0x00000004; */
+
+	get_tex_dim(type, &dim, &arg);
+
+	if (type == TGSI_TEXTURE_CUBE) {
+		e->inst[0] |= 0x08000000;
+		load_cube_tex_coords(pc, t, src, arg, proj);
+	} else
+	if (proj)
+		load_proj_tex_coords(pc, t, src, dim, arg);
+	else {
+		for (c = 0; c < dim; c++)
+			emit_mov(pc, t[c], src[c]);
+		if (arg != dim) /* depth reference value (always src.z here) */
+			emit_mov(pc, t[dim], src[2]);
 	}
 
 	e->inst[0] |= (mask & 0x3) << 25;
 	e->inst[1] |= (mask & 0xc) << 12;
 
-	emit(pc, e);
+	if (!bias_lod) {
+		e->inst[0] |= (arg - 1) << 22;
+		emit(pc, e);
+	} else
+	if (bias_lod < 0) {
+		assert(pc->p->type == PIPE_SHADER_FRAGMENT);
+		e->inst[0] |= arg << 22;
+		e->inst[1] |= 0x20000000; /* texbias */
+		emit_mov(pc, t[arg], src[3]);
+		emit_texbias_sequence(pc, t, arg, e);
+	} else {
+		e->inst[0] |= arg << 22;
+		e->inst[1] |= 0x40000000; /* texlod */
+		emit_mov(pc, t[arg], src[3]);
+		emit_texlod_sequence(pc, t[arg], src[3], e);
+	}
+
 #if 1
 	c = 0;
 	if (mask & 1) emit_mov(pc, dst[0], t[c++]);
@@ -1389,46 +1934,14 @@
 }
 
 static void
-emit_branch(struct nv50_pc *pc, int pred, unsigned cc,
-	    struct nv50_program_exec **join)
-{
-	struct nv50_program_exec *e = exec(pc);
-
-	if (join) {
-		set_long(pc, e);
-		e->inst[0] |= 0xa0000002;
-		emit(pc, e);
-		*join = e;
-		e = exec(pc);
-	}
-
-	set_long(pc, e);
-	e->inst[0] |= 0x10000002;
-	if (pred >= 0)
-		set_pred(pc, cc, pred, e);
-	emit(pc, e);
-}
-
-static void
-emit_nop(struct nv50_pc *pc)
-{
-	struct nv50_program_exec *e = exec(pc);
-
-	e->inst[0] = 0xf0000000;
-	set_long(pc, e);
-	e->inst[1] = 0xe0000000;
-	emit(pc, e);
-}
-
-static void
 emit_ddx(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
 {
 	struct nv50_program_exec *e = exec(pc);
 
 	assert(src->type == P_TEMP);
 
-	e->inst[0] = 0xc0140000;
-	e->inst[1] = 0x89800000;
+	e->inst[0] = (src->mod & NV50_MOD_NEG) ? 0xc0240000 : 0xc0140000;
+	e->inst[1] = (src->mod & NV50_MOD_NEG) ? 0x86400000 : 0x89800000;
 	set_long(pc, e);
 	set_dst(pc, dst, e);
 	set_src_0(pc, src, e);
@@ -1444,11 +1957,8 @@
 
 	assert(src->type == P_TEMP);
 
-	if (!(src->mod & NV50_MOD_NEG)) /* ! double negation */
-		emit_neg(pc, src, src);
-
-	e->inst[0] = 0xc0150000;
-	e->inst[1] = 0x8a400000;
+	e->inst[0] = (src->mod & NV50_MOD_NEG) ? 0xc0250000 : 0xc0150000;
+	e->inst[1] = (src->mod & NV50_MOD_NEG) ? 0x85800000 : 0x8a400000;
 	set_long(pc, e);
 	set_dst(pc, dst, e);
 	set_src_0(pc, src, e);
@@ -1470,6 +1980,21 @@
 		q = 0x0403c000;
 		m = 0xffff7fff;
 		break;
+	case 0x2:
+	case 0x3:
+		/* ADD, SUB, SUBR b32 */
+		m = ~(0x8000 | (127 << 16));
+		q = ((e->inst[0] & (~m)) >> 2) | (1 << 26);
+		break;
+	case 0x5:
+		/* SAD */
+		m = ~(0x81 << 8);
+		q = (0x0c << 24) | ((e->inst[0] & (0x7f << 2)) << 12);
+		break;
+	case 0x6:
+		/* MAD u16 */
+		q = (e->inst[0] & (0x7f << 2)) << 12;
+		break;
 	case 0x8:
 		/* INTERP (move centroid, perspective and flat bits) */
 		m = ~0x03000100;
@@ -1506,50 +2031,65 @@
 }
 
 /* Some operations support an optional negation flag. */
-static boolean
-negate_supported(const struct tgsi_full_instruction *insn, int i)
+static int
+get_supported_mods(const struct tgsi_full_instruction *insn, int i)
 {
-	int s;
-
 	switch (insn->Instruction.Opcode) {
+	case TGSI_OPCODE_ADD:
+	case TGSI_OPCODE_COS:
+	case TGSI_OPCODE_DDX:
 	case TGSI_OPCODE_DDY:
 	case TGSI_OPCODE_DP3:
 	case TGSI_OPCODE_DP4:
-	case TGSI_OPCODE_MUL:
+	case TGSI_OPCODE_EX2:
 	case TGSI_OPCODE_KIL:
-	case TGSI_OPCODE_ADD:
-	case TGSI_OPCODE_SUB:
+	case TGSI_OPCODE_LG2:
 	case TGSI_OPCODE_MAD:
-		break;
+	case TGSI_OPCODE_MUL:
 	case TGSI_OPCODE_POW:
-		if (i == 1)
-			break;
-		return FALSE;
+	case TGSI_OPCODE_RCP:
+	case TGSI_OPCODE_RSQ: /* ignored, RSQ = rsqrt(abs(src.x)) */
+	case TGSI_OPCODE_SCS:
+	case TGSI_OPCODE_SIN:
+	case TGSI_OPCODE_SUB:
+		return NV50_MOD_NEG;
+	case TGSI_OPCODE_MAX:
+	case TGSI_OPCODE_MIN:
+	case TGSI_OPCODE_INEG: /* tgsi src sign toggle/set would be stupid */
+		return NV50_MOD_ABS;
+	case TGSI_OPCODE_CEIL:
+	case TGSI_OPCODE_FLR:
+	case TGSI_OPCODE_TRUNC:
+		return NV50_MOD_NEG | NV50_MOD_ABS;
+	case TGSI_OPCODE_F2I:
+	case TGSI_OPCODE_F2U:
+	case TGSI_OPCODE_I2F:
+	case TGSI_OPCODE_U2F:
+		return NV50_MOD_NEG | NV50_MOD_ABS | NV50_MOD_I32;
+	case TGSI_OPCODE_UADD:
+		return NV50_MOD_NEG | NV50_MOD_I32;
+	case TGSI_OPCODE_SAD:
+	case TGSI_OPCODE_SHL:
+	case TGSI_OPCODE_IMAX:
+	case TGSI_OPCODE_IMIN:
+	case TGSI_OPCODE_ISHR:
+	case TGSI_OPCODE_NOT:
+	case TGSI_OPCODE_UMAD:
+	case TGSI_OPCODE_UMAX:
+	case TGSI_OPCODE_UMIN:
+	case TGSI_OPCODE_UMUL:
+	case TGSI_OPCODE_USHR:
+		return NV50_MOD_I32;
 	default:
-		return FALSE;
+		return 0;
 	}
-
-	/* Watch out for possible multiple uses of an nv50_reg, we
-	 * can't use nv50_reg::neg in these cases.
-	 */
-	for (s = 0; s < insn->Instruction.NumSrcRegs; ++s) {
-		if (s == i)
-			continue;
-		if ((insn->FullSrcRegisters[s].SrcRegister.Index ==
-		     insn->FullSrcRegisters[i].SrcRegister.Index) &&
-		    (insn->FullSrcRegisters[s].SrcRegister.File ==
-		     insn->FullSrcRegisters[i].SrcRegister.File))
-			return FALSE;
-	}
-
-	return TRUE;
 }
 
 /* Return a read mask for source registers deduced from opcode & write mask. */
 static unsigned
 nv50_tgsi_src_mask(const struct tgsi_full_instruction *insn, int c)
 {
-	unsigned x, mask = insn->FullDstRegisters[0].DstRegister.WriteMask;
+	unsigned x, mask = insn->Dst[0].Register.WriteMask;
 
 	switch (insn->Instruction.Opcode) {
 	case TGSI_OPCODE_COS:
@@ -1564,30 +2104,40 @@
 	case TGSI_OPCODE_DST:
 		return mask & (c ? 0xa : 0x6);
 	case TGSI_OPCODE_EX2:
+	case TGSI_OPCODE_EXP:
 	case TGSI_OPCODE_LG2:
+	case TGSI_OPCODE_LOG:
 	case TGSI_OPCODE_POW:
 	case TGSI_OPCODE_RCP:
 	case TGSI_OPCODE_RSQ:
 	case TGSI_OPCODE_SCS:
 		return 0x1;
+	case TGSI_OPCODE_IF:
+		return 0x1;
 	case TGSI_OPCODE_LIT:
 		return 0xb;
 	case TGSI_OPCODE_TEX:
+	case TGSI_OPCODE_TXB:
+	case TGSI_OPCODE_TXL:
 	case TGSI_OPCODE_TXP:
 	{
-		const struct tgsi_instruction_ext_texture *tex;
+		const struct tgsi_instruction_texture *tex;
 
-		assert(insn->Instruction.Extended);
-		tex = &insn->InstructionExtTexture;
+		assert(insn->Instruction.Texture);
+		tex = &insn->Texture;
 
 		mask = 0x7;
-		if (insn->Instruction.Opcode == TGSI_OPCODE_TXP)
-			mask |= 0x8;
+		if (insn->Instruction.Opcode != TGSI_OPCODE_TEX &&
+		    insn->Instruction.Opcode != TGSI_OPCODE_TXD)
+			mask |= 0x8; /* bias, lod or proj */
 
 		switch (tex->Texture) {
 		case TGSI_TEXTURE_1D:
 			mask &= 0x9;
 			break;
+		case TGSI_TEXTURE_SHADOW1D:
+			mask &= 0x5;
+			break;
 		case TGSI_TEXTURE_2D:
 			mask &= 0xb;
 			break;
@@ -1612,17 +2162,17 @@
 static struct nv50_reg *
 tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst)
 {
-	switch (dst->DstRegister.File) {
+	switch (dst->Register.File) {
 	case TGSI_FILE_TEMPORARY:
-		return &pc->temp[dst->DstRegister.Index * 4 + c];
+		return &pc->temp[dst->Register.Index * 4 + c];
 	case TGSI_FILE_OUTPUT:
-		return &pc->result[dst->DstRegister.Index * 4 + c];
+		return &pc->result[dst->Register.Index * 4 + c];
 	case TGSI_FILE_ADDRESS:
 	{
-		struct nv50_reg *r = pc->addr[dst->DstRegister.Index * 4 + c];
+		struct nv50_reg *r = pc->addr[dst->Register.Index * 4 + c];
 		if (!r) {
 			r = alloc_addr(pc, NULL);
-			pc->addr[dst->DstRegister.Index * 4 + c] = r;
+			pc->addr[dst->Register.Index * 4 + c] = r;
 		}
 		assert(r);
 		return r;
@@ -1638,14 +2188,14 @@
 
 static struct nv50_reg *
 tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src,
-	 boolean neg)
+	 int mod)
 {
 	struct nv50_reg *r = NULL;
-	struct nv50_reg *temp;
-	unsigned sgn, c, swz;
+	struct nv50_reg *temp = NULL;
+	unsigned sgn, c, swz, cvn;
 
-	if (src->SrcRegister.File != TGSI_FILE_CONSTANT)
-		assert(!src->SrcRegister.Indirect);
+	if (src->Register.File != TGSI_FILE_CONSTANT)
+		assert(!src->Register.Indirect);
 
 	sgn = tgsi_util_get_full_src_register_sign_mode(src, chan);
 
@@ -1655,36 +2205,36 @@
 	case TGSI_SWIZZLE_Y:
 	case TGSI_SWIZZLE_Z:
 	case TGSI_SWIZZLE_W:
-		switch (src->SrcRegister.File) {
+		switch (src->Register.File) {
 		case TGSI_FILE_INPUT:
-			r = &pc->attr[src->SrcRegister.Index * 4 + c];
+			r = &pc->attr[src->Register.Index * 4 + c];
 			break;
 		case TGSI_FILE_TEMPORARY:
-			r = &pc->temp[src->SrcRegister.Index * 4 + c];
+			r = &pc->temp[src->Register.Index * 4 + c];
 			break;
 		case TGSI_FILE_CONSTANT:
-			if (!src->SrcRegister.Indirect) {
-				r = &pc->param[src->SrcRegister.Index * 4 + c];
+			if (!src->Register.Indirect) {
+				r = &pc->param[src->Register.Index * 4 + c];
 				break;
 			}
 			/* Indicate indirection by setting r->acc < 0 and
 			 * use the index field to select the address reg.
 			 */
-			r = MALLOC_STRUCT(nv50_reg);
+			r = reg_instance(pc, NULL);
 			swz = tgsi_util_get_src_register_swizzle(
-						 &src->SrcRegisterInd, 0);
+						 &src->Indirect, 0);
 			ctor_reg(r, P_CONST,
-				 src->SrcRegisterInd.Index * 4 + swz,
-				 src->SrcRegister.Index * 4 + c);
+				 src->Indirect.Index * 4 + swz,
+				 src->Register.Index * 4 + c);
 			r->acc = -1;
 			break;
 		case TGSI_FILE_IMMEDIATE:
-			r = &pc->immd[src->SrcRegister.Index * 4 + c];
+			r = &pc->immd[src->Register.Index * 4 + c];
 			break;
 		case TGSI_FILE_SAMPLER:
-			break;
+			return NULL;
 		case TGSI_FILE_ADDRESS:
-			r = pc->addr[src->SrcRegister.Index * 4 + c];
+			r = pc->addr[src->Register.Index * 4 + c];
 			assert(r);
 			break;
 		default:
@@ -1697,33 +2247,34 @@
 		break;
 	}
 
+	cvn = (mod & NV50_MOD_I32) ? CVT_S32_S32 : CVT_F32_F32;
+
 	switch (sgn) {
-	case TGSI_UTIL_SIGN_KEEP:
-		break;
 	case TGSI_UTIL_SIGN_CLEAR:
-		temp = temp_temp(pc);
-		emit_abs(pc, temp, r);
-		r = temp;
-		break;
-	case TGSI_UTIL_SIGN_TOGGLE:
-		if (neg)
-			r->mod = NV50_MOD_NEG;
-		else {
-			temp = temp_temp(pc);
-			emit_neg(pc, temp, r);
-			r = temp;
-		}
+		r->mod = NV50_MOD_ABS;
 		break;
 	case TGSI_UTIL_SIGN_SET:
-		temp = temp_temp(pc);
-		emit_cvt(pc, temp, r, -1, CVTOP_ABS, CVT_F32_F32 | CVT_NEG);
-		r = temp;
+		r->mod = NV50_MOD_NEG_ABS;
+		break;
+	case TGSI_UTIL_SIGN_TOGGLE:
+		r->mod = NV50_MOD_NEG;
 		break;
 	default:
-		assert(0);
+		assert(!r->mod && sgn == TGSI_UTIL_SIGN_KEEP);
 		break;
 	}
 
+	if ((r->mod & mod) != r->mod) {
+		temp = temp_temp(pc, NULL);
+		emit_cvt(pc, temp, r, -1, cvn);
+		r->mod = 0;
+		r = temp;
+	} else
+		r->mod |= mod & NV50_MOD_I32;
+
+	assert(r);
+	if (r->acc >= 0 && r != temp)
+		return reg_instance(pc, r); /* will clear r->mod */
 	return r;
 }
 
@@ -1776,9 +2327,13 @@
 			assert(0);
 			return 0x0;
 		}
+	case TGSI_OPCODE_EXP:
+	case TGSI_OPCODE_LOG:
 	case TGSI_OPCODE_LIT:
 	case TGSI_OPCODE_SCS:
 	case TGSI_OPCODE_TEX:
+	case TGSI_OPCODE_TXB:
+	case TGSI_OPCODE_TXL:
 	case TGSI_OPCODE_TXP:
 		/* these take care of dangerous swizzles themselves */
 		return 0x0;
@@ -1814,34 +2369,51 @@
 
 	if (pc->if_insn[lvl]->next != pc->p->exec_tail)
 		return FALSE;
+	if (is_immd(pc->p->exec_tail))
+		return FALSE;
 
 	/* if ccode == 'true', the BRA is from an ELSE and the predicate
 	 * reg may no longer be valid, since we currently always use $p0
 	 */
 	if (has_pred(pc->if_insn[lvl], 0xf))
 		return FALSE;
-	assert(pc->if_insn[lvl] && pc->br_join[lvl]);
+	assert(pc->if_insn[lvl] && pc->if_join[lvl]);
 
-	/* We'll use the exec allocated for JOIN_AT (as we can't easily
-	 * update prev's next); if exec_tail is BRK, update the pointer.
+	/* We'll use the exec allocated for JOIN_AT (we can't easily
+	 * access nv50_program_exec's prev).
 	 */
-	if (pc->loop_lvl && pc->br_loop[pc->loop_lvl - 1] == pc->p->exec_tail)
-		pc->br_loop[pc->loop_lvl - 1] = pc->br_join[lvl];
-
 	pc->p->exec_size -= 4; /* remove JOIN_AT and BRA */
 
-	*pc->br_join[lvl] = *pc->p->exec_tail;
+	*pc->if_join[lvl] = *pc->p->exec_tail;
 
 	FREE(pc->if_insn[lvl]);
 	FREE(pc->p->exec_tail);
 
-	pc->p->exec_tail = pc->br_join[lvl];
+	pc->p->exec_tail = pc->if_join[lvl];
 	pc->p->exec_tail->next = NULL;
 	set_pred(pc, 0xd, 0, pc->p->exec_tail);
 
 	return TRUE;
 }
 
+static void
+nv50_fp_move_results(struct nv50_pc *pc)
+{
+	struct nv50_reg reg;
+	unsigned i;
+
+	ctor_reg(&reg, P_TEMP, -1, -1);
+
+	for (i = 0; i < pc->result_nr * 4; ++i) {
+		if (pc->result[i].rhw < 0 || pc->result[i].hw < 0)
+			continue;
+		if (pc->result[i].rhw != pc->result[i].hw) {
+			reg.hw = pc->result[i].rhw;
+			emit_mov(pc, &reg, &pc->result[i]);
+		}
+	}
+}
+
 static boolean
 nv50_program_tx_insn(struct nv50_pc *pc,
 		     const struct tgsi_full_instruction *inst)
@@ -1850,38 +2422,38 @@
 	unsigned mask, sat, unit;
 	int i, c;
 
-	mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
+	mask = inst->Dst[0].Register.WriteMask;
 	sat = inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE;
 
 	memset(src, 0, sizeof(src));
 
 	for (c = 0; c < 4; c++) {
 		if ((mask & (1 << c)) && !pc->r_dst[c])
-			dst[c] = tgsi_dst(pc, c, &inst->FullDstRegisters[0]);
+			dst[c] = tgsi_dst(pc, c, &inst->Dst[0]);
 		else
 			dst[c] = pc->r_dst[c];
 		rdst[c] = dst[c];
 	}
 
 	for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
-		const struct tgsi_full_src_register *fs = &inst->FullSrcRegisters[i];
+		const struct tgsi_full_src_register *fs = &inst->Src[i];
 		unsigned src_mask;
-		boolean neg_supp;
+		int mod_supp;
 
 		src_mask = nv50_tgsi_src_mask(inst, i);
-		neg_supp = negate_supported(inst, i);
+		mod_supp = get_supported_mods(inst, i);
 
-		if (fs->SrcRegister.File == TGSI_FILE_SAMPLER)
-			unit = fs->SrcRegister.Index;
+		if (fs->Register.File == TGSI_FILE_SAMPLER)
+			unit = fs->Register.Index;
 
 		for (c = 0; c < 4; c++)
 			if (src_mask & (1 << c))
-				src[i][c] = tgsi_src(pc, c, fs, neg_supp);
+				src[i][c] = tgsi_src(pc, c, fs, mod_supp);
 	}
 
 	brdc = temp = pc->r_brdc;
 	if (brdc && brdc->type != P_TEMP) {
-		temp = temp_temp(pc);
+		temp = temp_temp(pc, NULL);
 		if (sat)
 			brdc = temp;
 	} else
@@ -1890,7 +2462,7 @@
 			if (!(mask & (1 << c)) || dst[c]->type == P_TEMP)
 				continue;
 			/* rdst[c] = dst[c]; */ /* done above */
-			dst[c] = temp_temp(pc);
+			dst[c] = temp_temp(pc, NULL);
 		}
 	}
 
@@ -1901,7 +2473,8 @@
 		for (c = 0; c < 4; c++) {
 			if (!(mask & (1 << c)))
 				continue;
-			emit_abs(pc, dst[c], src[0][c]);
+			emit_cvt(pc, dst[c], src[0][c], -1,
+				 CVT_ABS | CVT_F32_F32);
 		}
 		break;
 	case TGSI_OPCODE_ADD:
@@ -1923,25 +2496,37 @@
 		break;
 	case TGSI_OPCODE_ARL:
 		assert(src[0][0]);
-		temp = temp_temp(pc);
-		emit_cvt(pc, temp, src[0][0], -1, CVTOP_FLOOR, CVT_S32_F32);
+		temp = temp_temp(pc, NULL);
+		emit_cvt(pc, temp, src[0][0], -1, CVT_FLOOR | CVT_S32_F32);
 		emit_arl(pc, dst[0], temp, 4);
 		break;
 	case TGSI_OPCODE_BGNLOOP:
+		pc->loop_brka[pc->loop_lvl] = emit_breakaddr(pc);
 		pc->loop_pos[pc->loop_lvl++] = pc->p->exec_size;
 		terminate_mbb(pc);
 		break;
+	case TGSI_OPCODE_BGNSUB:
+		assert(!pc->in_subroutine);
+		pc->in_subroutine = TRUE;
+		/* probably not necessary, but align to 8 byte boundary */
+		if (!is_long(pc->p->exec_tail))
+			convert_to_long(pc, pc->p->exec_tail);
+		break;
 	case TGSI_OPCODE_BRK:
-		emit_branch(pc, -1, 0, NULL);
 		assert(pc->loop_lvl > 0);
-		pc->br_loop[pc->loop_lvl - 1] = pc->p->exec_tail;
+		emit_break(pc, -1, 0);
+		break;
+	case TGSI_OPCODE_CAL:
+		assert(inst->Label.Label < pc->insn_nr);
+		emit_call(pc, -1, 0)->param.index = inst->Label.Label;
+		/* replaced by actual offset in nv50_program_fixup_insns */
 		break;
 	case TGSI_OPCODE_CEIL:
 		for (c = 0; c < 4; c++) {
 			if (!(mask & (1 << c)))
 				continue;
 			emit_cvt(pc, dst[c], src[0][c], -1,
-				 CVTOP_CEIL, CVT_F32_F32 | CVT_RI);
+				 CVT_CEIL | CVT_F32_F32 | CVT_RI);
 		}
 		break;
 	case TGSI_OPCODE_CMP:
@@ -1949,24 +2534,29 @@
 		for (c = 0; c < 4; c++) {
 			if (!(mask & (1 << c)))
 				continue;
-			emit_cvt(pc, NULL, src[0][c], 1, CVTOP_RN, CVT_F32_F32);
+			emit_cvt(pc, NULL, src[0][c], 1, CVT_F32_F32);
 			emit_mov(pc, dst[c], src[1][c]);
 			set_pred(pc, 0x1, 1, pc->p->exec_tail); /* @SF */
 			emit_mov(pc, dst[c], src[2][c]);
 			set_pred(pc, 0x6, 1, pc->p->exec_tail); /* @NSF */
 		}
 		break;
+	case TGSI_OPCODE_CONT:
+		assert(pc->loop_lvl > 0);
+		emit_branch(pc, -1, 0)->param.index =
+			pc->loop_pos[pc->loop_lvl - 1];
+		break;
 	case TGSI_OPCODE_COS:
 		if (mask & 8) {
 			emit_precossin(pc, temp, src[0][3]);
-			emit_flop(pc, 5, dst[3], temp);
+			emit_flop(pc, NV50_FLOP_COS, dst[3], temp);
 			if (!(mask &= 7))
 				break;
 			if (temp == dst[3])
-				temp = brdc = temp_temp(pc);
+				temp = brdc = temp_temp(pc, NULL);
 		}
 		emit_precossin(pc, temp, src[0][0]);
-		emit_flop(pc, 5, brdc, temp);
+		emit_flop(pc, NV50_FLOP_COS, brdc, temp);
 		break;
 	case TGSI_OPCODE_DDX:
 		for (c = 0; c < 4; c++) {
@@ -2010,7 +2600,7 @@
 			emit_mov_immdval(pc, dst[0], 1.0f);
 		break;
 	case TGSI_OPCODE_ELSE:
-		emit_branch(pc, -1, 0, NULL);
+		emit_branch(pc, -1, 0);
 		pc->if_insn[--pc->if_lvl]->param.index = pc->p->exec_size;
 		pc->if_insn[pc->if_lvl++] = pc->p->exec_tail;
 		terminate_mbb(pc);
@@ -2022,26 +2612,72 @@
 		if (nv50_kill_branch(pc) == TRUE)
 			break;
 
-		if (pc->br_join[pc->if_lvl]) {
-			pc->br_join[pc->if_lvl]->param.index = pc->p->exec_size;
-			pc->br_join[pc->if_lvl] = NULL;
+		if (pc->if_join[pc->if_lvl]) {
+			pc->if_join[pc->if_lvl]->param.index = pc->p->exec_size;
+			pc->if_join[pc->if_lvl] = NULL;
 		}
 		terminate_mbb(pc);
 		/* emit a NOP as join point, we could set it on the next
 		 * one, but would have to make sure it is long and !immd
 		 */
-		emit_nop(pc);
-		pc->p->exec_tail->inst[1] |= 2;
+		JOIN_ON(emit_nop(pc));
 		break;
 	case TGSI_OPCODE_ENDLOOP:
-		emit_branch(pc, -1, 0, NULL);
-		pc->p->exec_tail->param.index = pc->loop_pos[--pc->loop_lvl];
-		pc->br_loop[pc->loop_lvl]->param.index = pc->p->exec_size;
+		emit_branch(pc, -1, 0)->param.index =
+			pc->loop_pos[--pc->loop_lvl];
+		pc->loop_brka[pc->loop_lvl]->param.index = pc->p->exec_size;
 		terminate_mbb(pc);
 		break;
+	case TGSI_OPCODE_ENDSUB:
+		assert(pc->in_subroutine);
+		pc->in_subroutine = FALSE;
+		break;
 	case TGSI_OPCODE_EX2:
 		emit_preex2(pc, temp, src[0][0]);
-		emit_flop(pc, 6, brdc, temp);
+		emit_flop(pc, NV50_FLOP_EX2, brdc, temp);
+		break;
+	case TGSI_OPCODE_EXP:
+	{
+		struct nv50_reg *t[2];
+
+		assert(!temp);
+		t[0] = temp_temp(pc, NULL);
+		t[1] = temp_temp(pc, NULL);
+
+		if (mask & 0x6)
+			emit_mov(pc, t[0], src[0][0]);
+		if (mask & 0x3)
+			emit_flr(pc, t[1], src[0][0]);
+
+		if (mask & (1 << 1))
+			emit_sub(pc, dst[1], t[0], t[1]);
+		if (mask & (1 << 0)) {
+			emit_preex2(pc, t[1], t[1]);
+			emit_flop(pc, NV50_FLOP_EX2, dst[0], t[1]);
+		}
+		if (mask & (1 << 2)) {
+			emit_preex2(pc, t[0], t[0]);
+			emit_flop(pc, NV50_FLOP_EX2, dst[2], t[0]);
+		}
+		if (mask & (1 << 3))
+			emit_mov_immdval(pc, dst[3], 1.0f);
+	}
+		break;
+	case TGSI_OPCODE_F2I:
+		for (c = 0; c < 4; c++) {
+			if (!(mask & (1 << c)))
+				continue;
+			emit_cvt(pc, dst[c], src[0][c], -1,
+				 CVT_TRUNC | CVT_S32_F32);
+		}
+		break;
+	case TGSI_OPCODE_F2U:
+		for (c = 0; c < 4; c++) {
+			if (!(mask & (1 << c)))
+				continue;
+			emit_cvt(pc, dst[c], src[0][c], -1,
+				 CVT_TRUNC | CVT_U32_F32);
+		}
 		break;
 	case TGSI_OPCODE_FLR:
 		for (c = 0; c < 4; c++) {
@@ -2051,7 +2687,7 @@
 		}
 		break;
 	case TGSI_OPCODE_FRC:
-		temp = temp_temp(pc);
+		temp = temp_temp(pc, NULL);
 		for (c = 0; c < 4; c++) {
 			if (!(mask & (1 << c)))
 				continue;
@@ -2059,30 +2695,88 @@
 			emit_sub(pc, dst[c], src[0][c], temp);
 		}
 		break;
+	case TGSI_OPCODE_I2F:
+		for (c = 0; c < 4; c++) {
+			if (!(mask & (1 << c)))
+				continue;
+			emit_cvt(pc, dst[c], src[0][c], -1, CVT_F32_S32);
+		}
+		break;
 	case TGSI_OPCODE_IF:
-		/* emitting a join_at may not be necessary */
-		assert(pc->if_lvl < MAX_IF_DEPTH);
-		/* set_pred_wr(pc, 1, 0, pc->if_cond); */
-		emit_cvt(pc, NULL, src[0][0], 0, CVTOP_ABS | CVTOP_RN,
-			 CVT_F32_F32);
-		emit_branch(pc, 0, 2, &pc->br_join[pc->if_lvl]);
-		pc->if_insn[pc->if_lvl++] = pc->p->exec_tail;
+		assert(pc->if_lvl < NV50_MAX_COND_NESTING);
+		emit_cvt(pc, NULL, src[0][0], 0, CVT_ABS | CVT_F32_F32);
+		pc->if_join[pc->if_lvl] = emit_joinat(pc);
+		pc->if_insn[pc->if_lvl++] = emit_branch(pc, 0, 2);;
 		terminate_mbb(pc);
 		break;
+	case TGSI_OPCODE_IMAX:
+		for (c = 0; c < 4; c++) {
+			if (!(mask & (1 << c)))
+				continue;
+			emit_minmax(pc, 0x08c, dst[c], src[0][c], src[1][c]);
+		}
+		break;
+	case TGSI_OPCODE_IMIN:
+		for (c = 0; c < 4; c++) {
+			if (!(mask & (1 << c)))
+				continue;
+			emit_minmax(pc, 0x0ac, dst[c], src[0][c], src[1][c]);
+		}
+		break;
+	case TGSI_OPCODE_INEG:
+		for (c = 0; c < 4; c++) {
+			if (!(mask & (1 << c)))
+				continue;
+			emit_cvt(pc, dst[c], src[0][c], -1,
+				 CVT_S32_S32 | CVT_NEG);
+		}
+		break;
 	case TGSI_OPCODE_KIL:
+		assert(src[0][0] && src[0][1] && src[0][2] && src[0][3]);
 		emit_kil(pc, src[0][0]);
 		emit_kil(pc, src[0][1]);
 		emit_kil(pc, src[0][2]);
 		emit_kil(pc, src[0][3]);
 		break;
+	case TGSI_OPCODE_KILP:
+		emit_kil(pc, NULL);
+		break;
 	case TGSI_OPCODE_LIT:
 		emit_lit(pc, &dst[0], mask, &src[0][0]);
 		break;
 	case TGSI_OPCODE_LG2:
-		emit_flop(pc, 3, brdc, src[0][0]);
+		emit_flop(pc, NV50_FLOP_LG2, brdc, src[0][0]);
+		break;
+	case TGSI_OPCODE_LOG:
+	{
+		struct nv50_reg *t[2];
+
+		t[0] = temp_temp(pc, NULL);
+		if (mask & (1 << 1))
+			t[1] = temp_temp(pc, NULL);
+		else
+			t[1] = t[0];
+
+		emit_cvt(pc, t[0], src[0][0], -1, CVT_ABS | CVT_F32_F32);
+		emit_flop(pc, NV50_FLOP_LG2, t[1], t[0]);
+		if (mask & (1 << 2))
+			emit_mov(pc, dst[2], t[1]);
+		emit_flr(pc, t[1], t[1]);
+		if (mask & (1 << 0))
+			emit_mov(pc, dst[0], t[1]);
+		if (mask & (1 << 1)) {
+			t[1]->mod = NV50_MOD_NEG;
+			emit_preex2(pc, t[1], t[1]);
+			t[1]->mod = 0;
+			emit_flop(pc, NV50_FLOP_EX2, t[1], t[1]);
+			emit_mul(pc, dst[1], t[0], t[1]);
+		}
+		if (mask & (1 << 3))
+			emit_mov_immdval(pc, dst[3], 1.0f);
+	}
 		break;
 	case TGSI_OPCODE_LRP:
-		temp = temp_temp(pc);
+		temp = temp_temp(pc, NULL);
 		for (c = 0; c < 4; c++) {
 			if (!(mask & (1 << c)))
 				continue;
@@ -2101,14 +2795,14 @@
 		for (c = 0; c < 4; c++) {
 			if (!(mask & (1 << c)))
 				continue;
-			emit_minmax(pc, 4, dst[c], src[0][c], src[1][c]);
+			emit_minmax(pc, 0x880, dst[c], src[0][c], src[1][c]);
 		}
 		break;
 	case TGSI_OPCODE_MIN:
 		for (c = 0; c < 4; c++) {
 			if (!(mask & (1 << c)))
 				continue;
-			emit_minmax(pc, 5, dst[c], src[0][c], src[1][c]);
+			emit_minmax(pc, 0x8a0, dst[c], src[0][c], src[1][c]);
 		}
 		break;
 	case TGSI_OPCODE_MOV:
@@ -2125,39 +2819,73 @@
 			emit_mul(pc, dst[c], src[0][c], src[1][c]);
 		}
 		break;
+	case TGSI_OPCODE_NOT:
+		for (c = 0; c < 4; c++) {
+			if (!(mask & (1 << c)))
+				continue;
+			emit_not(pc, dst[c], src[0][c]);
+		}
+		break;
 	case TGSI_OPCODE_POW:
 		emit_pow(pc, brdc, src[0][0], src[1][0]);
 		break;
 	case TGSI_OPCODE_RCP:
-		emit_flop(pc, 0, brdc, src[0][0]);
+		if (!sat && popcnt4(mask) == 1)
+			brdc = dst[ffs(mask) - 1];
+		emit_flop(pc, NV50_FLOP_RCP, brdc, src[0][0]);
+		break;
+	case TGSI_OPCODE_RET:
+		if (pc->p->type == PIPE_SHADER_FRAGMENT && !pc->in_subroutine)
+			nv50_fp_move_results(pc);
+		emit_ret(pc, -1, 0);
 		break;
 	case TGSI_OPCODE_RSQ:
-		emit_flop(pc, 2, brdc, src[0][0]);
+		if (!sat && popcnt4(mask) == 1)
+			brdc = dst[ffs(mask) - 1];
+		src[0][0]->mod |= NV50_MOD_ABS;
+		emit_flop(pc, NV50_FLOP_RSQ, brdc, src[0][0]);
+		break;
+	case TGSI_OPCODE_SAD:
+		for (c = 0; c < 4; c++) {
+			if (!(mask & (1 << c)))
+				continue;
+			emit_sad(pc, dst[c], src[0][c], src[1][c], src[2][c]);
+		}
 		break;
 	case TGSI_OPCODE_SCS:
-		temp = temp_temp(pc);
+		temp = temp_temp(pc, NULL);
 		if (mask & 3)
 			emit_precossin(pc, temp, src[0][0]);
 		if (mask & (1 << 0))
-			emit_flop(pc, 5, dst[0], temp);
+			emit_flop(pc, NV50_FLOP_COS, dst[0], temp);
 		if (mask & (1 << 1))
-			emit_flop(pc, 4, dst[1], temp);
+			emit_flop(pc, NV50_FLOP_SIN, dst[1], temp);
 		if (mask & (1 << 2))
 			emit_mov_immdval(pc, dst[2], 0.0);
 		if (mask & (1 << 3))
 			emit_mov_immdval(pc, dst[3], 1.0);
 		break;
+	case TGSI_OPCODE_SHL:
+	case TGSI_OPCODE_ISHR:
+	case TGSI_OPCODE_USHR:
+		for (c = 0; c < 4; c++) {
+			if (!(mask & (1 << c)))
+				continue;
+			emit_shift(pc, dst[c], src[0][c], src[1][c],
+				   inst->Instruction.Opcode);
+		}
+		break;
 	case TGSI_OPCODE_SIN:
 		if (mask & 8) {
 			emit_precossin(pc, temp, src[0][3]);
-			emit_flop(pc, 4, dst[3], temp);
+			emit_flop(pc, NV50_FLOP_SIN, dst[3], temp);
 			if (!(mask &= 7))
 				break;
 			if (temp == dst[3])
-				temp = brdc = temp_temp(pc);
+				temp = brdc = temp_temp(pc, NULL);
 		}
 		emit_precossin(pc, temp, src[0][0]);
-		emit_flop(pc, 4, brdc, temp);
+		emit_flop(pc, NV50_FLOP_SIN, brdc, temp);
 		break;
 	case TGSI_OPCODE_SLT:
 	case TGSI_OPCODE_SGE:
@@ -2165,12 +2893,23 @@
 	case TGSI_OPCODE_SGT:
 	case TGSI_OPCODE_SLE:
 	case TGSI_OPCODE_SNE:
-		i = map_tgsi_setop_cc(inst->Instruction.Opcode);
+	case TGSI_OPCODE_ISLT:
+	case TGSI_OPCODE_ISGE:
+	case TGSI_OPCODE_USEQ:
+	case TGSI_OPCODE_USGE:
+	case TGSI_OPCODE_USLT:
+	case TGSI_OPCODE_USNE:
+	{
+		uint8_t cc, ty;
+
+		map_tgsi_setop_hw(inst->Instruction.Opcode, &cc, &ty);
+
 		for (c = 0; c < 4; c++) {
 			if (!(mask & (1 << c)))
 				continue;
-			emit_set(pc, i, dst[c], -1, src[0][c], src[1][c]);
+			emit_set(pc, cc, dst[c], -1, src[0][c], src[1][c], ty);
 		}
+	}
 		break;
 	case TGSI_OPCODE_SUB:
 		for (c = 0; c < 4; c++) {
@@ -2181,22 +2920,91 @@
 		break;
 	case TGSI_OPCODE_TEX:
 		emit_tex(pc, dst, mask, src[0], unit,
-			 inst->InstructionExtTexture.Texture, FALSE);
+			 inst->Texture.Texture, FALSE, 0);
+		break;
+	case TGSI_OPCODE_TXB:
+		emit_tex(pc, dst, mask, src[0], unit,
+			 inst->Texture.Texture, FALSE, -1);
+		break;
+	case TGSI_OPCODE_TXL:
+		emit_tex(pc, dst, mask, src[0], unit,
+			 inst->Texture.Texture, FALSE, 1);
 		break;
 	case TGSI_OPCODE_TXP:
 		emit_tex(pc, dst, mask, src[0], unit,
-			 inst->InstructionExtTexture.Texture, TRUE);
+			 inst->Texture.Texture, TRUE, 0);
 		break;
 	case TGSI_OPCODE_TRUNC:
 		for (c = 0; c < 4; c++) {
 			if (!(mask & (1 << c)))
 				continue;
 			emit_cvt(pc, dst[c], src[0][c], -1,
-				 CVTOP_TRUNC, CVT_F32_F32 | CVT_RI);
+				 CVT_TRUNC | CVT_F32_F32 | CVT_RI);
 		}
 		break;
+	case TGSI_OPCODE_U2F:
+		for (c = 0; c < 4; c++) {
+			if (!(mask & (1 << c)))
+				continue;
+			emit_cvt(pc, dst[c], src[0][c], -1, CVT_F32_U32);
+		}
+		break;
+	case TGSI_OPCODE_UADD:
+		for (c = 0; c < 4; c++) {
+			if (!(mask & (1 << c)))
+				continue;
+			emit_add_b32(pc, dst[c], src[0][c], src[1][c]);
+		}
+		break;
+	case TGSI_OPCODE_UMAX:
+		for (c = 0; c < 4; c++) {
+			if (!(mask & (1 << c)))
+				continue;
+			emit_minmax(pc, 0x084, dst[c], src[0][c], src[1][c]);
+		}
+		break;
+	case TGSI_OPCODE_UMIN:
+		for (c = 0; c < 4; c++) {
+			if (!(mask & (1 << c)))
+				continue;
+			emit_minmax(pc, 0x0a4, dst[c], src[0][c], src[1][c]);
+		}
+		break;
+	case TGSI_OPCODE_UMAD:
+	{
+		assert(!temp);
+		temp = temp_temp(pc, NULL);
+		for (c = 0; c < 4; c++) {
+			if (!(mask & (1 << c)))
+				continue;
+			emit_mul_u16(pc, temp, src[0][c], 0, src[1][c], 1);
+			emit_mad_u16(pc, temp, src[0][c], 1, src[1][c], 0,
+				     temp);
+			emit_shl_imm(pc, temp, temp, 16);
+			emit_mad_u16(pc, temp, src[0][c], 0, src[1][c], 0,
+				     temp);
+			emit_add_b32(pc, dst[c], temp, src[2][c]);
+		}
+	}
+		break;
+	case TGSI_OPCODE_UMUL:
+	{
+		assert(!temp);
+		temp = temp_temp(pc, NULL);
+		for (c = 0; c < 4; c++) {
+			if (!(mask & (1 << c)))
+				continue;
+			emit_mul_u16(pc, temp, src[0][c], 0, src[1][c], 1);
+			emit_mad_u16(pc, temp, src[0][c], 1, src[1][c], 0,
+				     temp);
+			emit_shl_imm(pc, temp, temp, 16);
+			emit_mad_u16(pc, dst[c], src[0][c], 0, src[1][c], 0,
+				     temp);
+		}
+	}
+		break;
 	case TGSI_OPCODE_XPD:
-		temp = temp_temp(pc);
+		temp = temp_temp(pc, NULL);
 		if (mask & (1 << 0)) {
 			emit_mul(pc, temp, src[0][2], src[1][1]);
 			emit_msb(pc, dst[0], src[0][1], src[1][2], temp);
@@ -2213,6 +3021,17 @@
 			emit_mov_immdval(pc, dst[3], 1.0);
 		break;
 	case TGSI_OPCODE_END:
+		if (pc->p->type == PIPE_SHADER_FRAGMENT)
+			nv50_fp_move_results(pc);
+
+		/* last insn must be long so it can have the exit bit set */
+		if (!is_long(pc->p->exec_tail))
+			convert_to_long(pc, pc->p->exec_tail);
+		else
+		if (is_immd(pc->p->exec_tail) || is_join(pc->p->exec_tail))
+			emit_nop(pc);
+
+		pc->p->exec_tail->inst[1] |= 1; /* set exit bit */
 		break;
 	default:
 		NOUVEAU_ERR("invalid opcode %d\n", inst->Instruction.Opcode);
@@ -2239,39 +3058,34 @@
 		}
 	}
 
-	for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
-		for (c = 0; c < 4; c++) {
-			if (!src[i][c])
-				continue;
-			src[i][c]->mod = 0;
-			if (src[i][c]->index == -1 && src[i][c]->type == P_IMMD)
-				FREE(src[i][c]);
-			else
-			if (src[i][c]->acc < 0 && src[i][c]->type == P_CONST)
-				FREE(src[i][c]); /* indirect constant */
-		}
-	}
+	kill_temp_temp(pc, NULL);
+	pc->reg_instance_nr = 0;
 
-	kill_temp_temp(pc);
 	return TRUE;
 }
 
 static void
 prep_inspect_insn(struct nv50_pc *pc, const struct tgsi_full_instruction *insn)
 {
-	struct nv50_reg *reg = NULL;
+	struct nv50_reg *r, *reg = NULL;
 	const struct tgsi_full_src_register *src;
 	const struct tgsi_dst_register *dst;
 	unsigned i, c, k, mask;
 
-	dst = &insn->FullDstRegisters[0].DstRegister;
+	dst = &insn->Dst[0].Register;
 	mask = dst->WriteMask;
 
         if (dst->File == TGSI_FILE_TEMPORARY)
-                reg = pc->temp;
+		reg = pc->temp;
         else
-        if (dst->File == TGSI_FILE_OUTPUT)
-                reg = pc->result;
+	if (dst->File == TGSI_FILE_OUTPUT) {
+		reg = pc->result;
+
+		if (insn->Instruction.Opcode == TGSI_OPCODE_MOV &&
+		    dst->Index == pc->edgeflag_out &&
+		    insn->Src[0].Register.File == TGSI_FILE_INPUT)
+			pc->p->cfg.edgeflag_in = insn->Src[0].Register.Index;
+	}
 
 	if (reg) {
 		for (c = 0; c < 4; c++) {
@@ -2282,12 +3096,12 @@
 	}
 
 	for (i = 0; i < insn->Instruction.NumSrcRegs; i++) {
-		src = &insn->FullSrcRegisters[i];
+		src = &insn->Src[i];
 
-		if (src->SrcRegister.File == TGSI_FILE_TEMPORARY)
+		if (src->Register.File == TGSI_FILE_TEMPORARY)
 			reg = pc->temp;
 		else
-		if (src->SrcRegister.File == TGSI_FILE_INPUT)
+		if (src->Register.File == TGSI_FILE_INPUT)
 			reg = pc->attr;
 		else
 			continue;
@@ -2299,7 +3113,15 @@
 				continue;
 			k = tgsi_util_get_full_src_register_swizzle(src, c);
 
-			reg[src->SrcRegister.Index * 4 + k].acc = pc->insn_nr;
+			r = &reg[src->Register.Index * 4 + k];
+
+			/* If used before written, pre-allocate the reg,
+			 * lest we overwrite results from a subroutine.
+			 */
+			if (!r->acc && r->type == P_TEMP)
+				alloc_reg(pc, r);
+
+			r->acc = pc->insn_nr;
 		}
 	}
 }
@@ -2359,13 +3181,13 @@
 tgsi_broadcast_dst(struct nv50_pc *pc,
 		   const struct tgsi_full_dst_register *fd, unsigned mask)
 {
-	if (fd->DstRegister.File == TGSI_FILE_TEMPORARY) {
-		int c = ffs(~mask & fd->DstRegister.WriteMask);
+	if (fd->Register.File == TGSI_FILE_TEMPORARY) {
+		int c = ffs(~mask & fd->Register.WriteMask);
 		if (c)
 			return tgsi_dst(pc, c - 1, fd);
 	} else {
-		int c = ffs(fd->DstRegister.WriteMask) - 1;
-		if ((1 << c) == fd->DstRegister.WriteMask)
+		int c = ffs(fd->Register.WriteMask) - 1;
+		if ((1 << c) == fd->Register.WriteMask)
 			return tgsi_dst(pc, c, fd);
 	}
 
@@ -2379,7 +3201,7 @@
 nv50_tgsi_scan_swizzle(const struct tgsi_full_instruction *insn,
 		       unsigned rdep[4])
 {
-	const struct tgsi_full_dst_register *fd = &insn->FullDstRegisters[0];
+	const struct tgsi_full_dst_register *fd = &insn->Dst[0];
 	const struct tgsi_full_src_register *fs;
 	unsigned i, deqs = 0;
 
@@ -2388,11 +3210,11 @@
 
 	for (i = 0; i < insn->Instruction.NumSrcRegs; i++) {
 		unsigned chn, mask = nv50_tgsi_src_mask(insn, i);
-		boolean neg_supp = negate_supported(insn, i);
+		int ms = get_supported_mods(insn, i);
 
-		fs = &insn->FullSrcRegisters[i];
-		if (fs->SrcRegister.File != fd->DstRegister.File ||
-		    fs->SrcRegister.Index != fd->DstRegister.Index)
+		fs = &insn->Src[i];
+		if (fs->Register.File != fd->Register.File ||
+		    fs->Register.Index != fd->Register.Index)
 			continue;
 
 		for (chn = 0; chn < 4; ++chn) {
@@ -2403,13 +3225,15 @@
 			c = tgsi_util_get_full_src_register_swizzle(fs, chn);
 			s = tgsi_util_get_full_src_register_sign_mode(fs, chn);
 
-			if (!(fd->DstRegister.WriteMask & (1 << c)))
+			if (!(fd->Register.WriteMask & (1 << c)))
 				continue;
 
-			/* no danger if src is copied to TEMP first */
-			if ((s != TGSI_UTIL_SIGN_KEEP) &&
-			    (s != TGSI_UTIL_SIGN_TOGGLE || !neg_supp))
-				continue;
+			if (s == TGSI_UTIL_SIGN_TOGGLE && !(ms & NV50_MOD_NEG))
+					continue;
+			if (s == TGSI_UTIL_SIGN_CLEAR && !(ms & NV50_MOD_ABS))
+					continue;
+			if ((s == TGSI_UTIL_SIGN_SET) && ((ms & 3) != 3))
+					continue;
 
 			rdep[c] |= nv50_tgsi_dst_revdep(
 				insn->Instruction.Opcode, i, chn);
@@ -2427,18 +3251,18 @@
 	const struct tgsi_full_dst_register *fd;
 	unsigned i, deqs, rdep[4], m[4];
 
-	fd = &tok->FullInstruction.FullDstRegisters[0];
+	fd = &tok->FullInstruction.Dst[0];
 	deqs = nv50_tgsi_scan_swizzle(&insn, rdep);
 
 	if (is_scalar_op(insn.Instruction.Opcode)) {
 		pc->r_brdc = tgsi_broadcast_dst(pc, fd, deqs);
 		if (!pc->r_brdc)
-			pc->r_brdc = temp_temp(pc);
+			pc->r_brdc = temp_temp(pc, NULL);
 		return nv50_program_tx_insn(pc, &insn);
 	}
 	pc->r_brdc = NULL;
 
-	if (!deqs)
+	if (!deqs || (!rdep[0] && !rdep[1] && !rdep[2] && !rdep[3]))
 		return nv50_program_tx_insn(pc, &insn);
 
 	deqs = nv50_revdep_reorder(m, rdep);
@@ -2446,10 +3270,10 @@
 	for (i = 0; i < 4; ++i) {
 		assert(pc->r_dst[m[i]] == NULL);
 
-		insn.FullDstRegisters[0].DstRegister.WriteMask =
-			fd->DstRegister.WriteMask & (1 << m[i]);
+		insn.Dst[0].Register.WriteMask =
+			fd->Register.WriteMask & (1 << m[i]);
 
-		if (!insn.FullDstRegisters[0].DstRegister.WriteMask)
+		if (!insn.Dst[0].Register.WriteMask)
 			continue;
 
 		if (deqs & (1 << i))
@@ -2489,7 +3313,7 @@
 		iv->rhw = popcnt4(pc->p->cfg.regs[1] >> 24) - 1;
 
 		emit_interp(pc, iv, NULL, mode & INTERP_CENTROID);
-		emit_flop(pc, 0, iv, iv);
+		emit_flop(pc, NV50_FLOP_RCP, iv, iv);
 
 		/* XXX: when loading interpolants dynamically, move these
 		 * to the program head, or make sure it can't be skipped.
@@ -2535,10 +3359,10 @@
 			const struct tgsi_full_immediate *imm =
 				&tp.FullToken.FullImmediate;
 
-			ctor_immd(pc, imm->u[0].Float,
-				      imm->u[1].Float,
-				      imm->u[2].Float,
-				      imm->u[3].Float);
+			ctor_immd_4f32(pc, imm->u[0].Float,
+				       imm->u[1].Float,
+				       imm->u[2].Float,
+				       imm->u[3].Float);
 		}
 			break;
 		case TGSI_TOKEN_TYPE_DECLARATION:
@@ -2547,8 +3371,8 @@
 			unsigned si, last, first, mode;
 
 			d = &tp.FullToken.FullDeclaration;
-			first = d->DeclarationRange.First;
-			last = d->DeclarationRange.Last;
+			first = d->Range.First;
+			last = d->Range.Last;
 
 			switch (d->Declaration.File) {
 			case TGSI_FILE_TEMPORARY:
@@ -2558,8 +3382,8 @@
 				    p->type == PIPE_SHADER_FRAGMENT)
 					break;
 
-				si = d->Semantic.SemanticIndex;
-				switch (d->Semantic.SemanticName) {
+				si = d->Semantic.Index;
+				switch (d->Semantic.Name) {
 				case TGSI_SEMANTIC_BCOLOR:
 					p->cfg.two_side[si].hw = first;
 					if (p->cfg.io_nr > first)
@@ -2570,6 +3394,9 @@
 					if (p->cfg.io_nr > first)
 						p->cfg.io_nr = first;
 					break;
+				case TGSI_SEMANTIC_EDGEFLAG:
+					pc->edgeflag_out = first;
+					break;
 					/*
 				case TGSI_SEMANTIC_CLIP_DISTANCE:
 					p->cfg.clpd = MIN2(p->cfg.clpd, first);
@@ -2637,7 +3464,7 @@
 
 		for (i = 0, rid = 0; i < pc->result_nr; ++i) {
 			p->cfg.io[i].hw = rid;
-			p->cfg.io[i].id_vp = i;
+			p->cfg.io[i].id = i;
 
 			for (c = 0; c < 4; ++c) {
 				int n = i * 4 + c;
@@ -2669,14 +3496,12 @@
 		 * the lower hardware IDs, so sort them:
 		 */
 		for (i = 0; i < pc->attr_nr; i++) {
-			if (pc->interp_mode[i] == INTERP_FLAT) {
-				p->cfg.io[m].id_vp = i + base;
-				p->cfg.io[m++].id_fp = i;
-			} else {
+			if (pc->interp_mode[i] == INTERP_FLAT)
+				p->cfg.io[m++].id = i;
+			else {
 				if (!(pc->interp_mode[i] & INTERP_PERSPECTIVE))
 					p->cfg.io[n].linear = TRUE;
-				p->cfg.io[n].id_vp = i + base;
-				p->cfg.io[n++].id_fp = i;
+				p->cfg.io[n++].id = i;
 			}
 		}
 
@@ -2688,7 +3513,7 @@
 
 		for (n = 0; n < pc->attr_nr; ++n) {
 			p->cfg.io[n].hw = rid = aid;
-			i = p->cfg.io[n].id_fp;
+			i = p->cfg.io[n].id;
 
 			if (p->info.input_semantic_name[n] ==
 			    TGSI_SEMANTIC_FACE) {
@@ -2728,8 +3553,8 @@
 		for (i = 0; i < pc->attr_nr; i++) {
 			ubyte si, sn;
 
-			sn = p->info.input_semantic_name[p->cfg.io[i].id_fp];
-			si = p->info.input_semantic_index[p->cfg.io[i].id_fp];
+			sn = p->info.input_semantic_name[p->cfg.io[i].id];
+			si = p->info.input_semantic_index[p->cfg.io[i].id];
 
 			if (sn == TGSI_SEMANTIC_COLOR) {
 				p->cfg.two_side[si] = p->cfg.io[i];
@@ -2820,6 +3645,8 @@
 	p->cfg.two_side[0].hw = 0x40;
 	p->cfg.two_side[1].hw = 0x40;
 
+	p->cfg.edgeflag_in = pc->edgeflag_out = 0xff;
+
 	switch (p->type) {
 	case PIPE_SHADER_VERTEX:
 		p->cfg.psiz = 0x40;
@@ -2894,27 +3721,9 @@
 }
 
 static void
-nv50_fp_move_results(struct nv50_pc *pc)
-{
-	struct nv50_reg reg;
-	unsigned i;
-
-	ctor_reg(&reg, P_TEMP, -1, -1);
-
-	for (i = 0; i < pc->result_nr * 4; ++i) {
-		if (pc->result[i].rhw < 0 || pc->result[i].hw < 0)
-			continue;
-		if (pc->result[i].rhw != pc->result[i].hw) {
-			reg.hw = pc->result[i].rhw;
-			emit_mov(pc, &reg, &pc->result[i]);
-		}
-	}
-}
-
-static void
 nv50_program_fixup_insns(struct nv50_pc *pc)
 {
-	struct nv50_program_exec *e, *prev = NULL, **bra_list;
+	struct nv50_program_exec *e, **bra_list;
 	unsigned i, n, pos;
 
 	bra_list = CALLOC(pc->p->exec_size, sizeof(struct nv50_program_exec *));
@@ -2934,27 +3743,24 @@
 			for (i = 0; i < n; ++i)
 				if (bra_list[i]->param.index >= pos)
 					bra_list[i]->param.index += 1;
+			for (i = 0; i < pc->insn_nr; ++i)
+				if (pc->insn_pos[i] >= pos)
+					pc->insn_pos[i] += 1;
 			convert_to_long(pc, e);
 			++pos;
 		}
-		if (e->next)
-			prev = e;
 	}
 
-	assert(!is_immd(pc->p->exec_head));
-	assert(!is_immd(pc->p->exec_tail));
-
-	/* last instruction must be long so it can have the end bit set */
-	if (!is_long(pc->p->exec_tail)) {
-		convert_to_long(pc, pc->p->exec_tail);
-		if (prev)
-			convert_to_long(pc, prev);
-	}
-	assert(!(pc->p->exec_tail->inst[1] & 2));
-	/* set the end-bit */
-	pc->p->exec_tail->inst[1] |= 1;
-
 	FREE(bra_list);
+
+	if (!pc->p->info.opcode_count[TGSI_OPCODE_CAL])
+		return;
+
+	/* fill in CALL offsets */
+	for (e = pc->p->exec_head; e; e = e->next) {
+		if ((e->inst[0] & 2) && (e->inst[0] >> 28) == 0x2)
+			e->param.index = pc->insn_pos[e->param.index];
+	}
 }
 
 static boolean
@@ -2976,19 +3782,20 @@
 	if (ret == FALSE)
 		goto out_cleanup;
 
+	pc->insn_pos = MALLOC(pc->insn_nr * sizeof(unsigned));
+
 	tgsi_parse_init(&parse, pc->p->pipe.tokens);
 	while (!tgsi_parse_end_of_tokens(&parse)) {
 		const union tgsi_full_token *tok = &parse.FullToken;
 
-		/* don't allow half insn/immd on first and last instruction */
+		/* previously allow32 was FALSE for first & last instruction */
 		pc->allow32 = TRUE;
-		if (pc->insn_cur == 0 || pc->insn_cur + 2 == pc->insn_nr)
-			pc->allow32 = FALSE;
 
 		tgsi_parse_token(&parse);
 
 		switch (tok->Token.Type) {
 		case TGSI_TOKEN_TYPE_INSTRUCTION:
+			pc->insn_pos[pc->insn_cur] = pc->p->exec_size;
 			++pc->insn_cur;
 			ret = nv50_tgsi_insn(pc, tok);
 			if (ret == FALSE)
@@ -2999,9 +3806,6 @@
 		}
 	}
 
-	if (pc->p->type == PIPE_SHADER_FRAGMENT)
-		nv50_fp_move_results(pc);
-
 	nv50_program_fixup_insns(pc);
 
 	p->param_nr = pc->param_nr * 4;
@@ -3025,7 +3829,7 @@
 }
 
 static void
-nv50_program_upload_data(struct nv50_context *nv50, float *map,
+nv50_program_upload_data(struct nv50_context *nv50, uint32_t *map,
 			unsigned start, unsigned count, unsigned cbuf)
 {
 	struct nouveau_channel *chan = nv50->screen->base.channel;
@@ -3073,8 +3877,8 @@
 
 	if (p->param_nr) {
 		unsigned cb;
-		float *map = pipe_buffer_map(pscreen, nv50->constbuf[p->type],
-					     PIPE_BUFFER_USAGE_CPU_READ);
+		uint32_t *map = pipe_buffer_map(pscreen, nv50->constbuf[p->type],
+						PIPE_BUFFER_USAGE_CPU_READ);
 
 		if (p->type == PIPE_SHADER_VERTEX)
 			cb = NV50_CB_PVP;
@@ -3173,7 +3977,7 @@
 	nv50_program_validate_data(nv50, p);
 	nv50_program_validate_code(nv50, p);
 
-	so = so_new(13, 2);
+	so = so_new(5, 8, 2);
 	so_method(so, tesla, NV50TCL_VP_ADDRESS_HIGH, 2);
 	so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
 		      NOUVEAU_BO_HIGH, 0, 0);
@@ -3209,7 +4013,7 @@
 	nv50_program_validate_data(nv50, p);
 	nv50_program_validate_code(nv50, p);
 
-	so = so_new(64, 2);
+	so = so_new(6, 7, 2);
 	so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2);
 	so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
 		      NOUVEAU_BO_HIGH, 0, 0);
@@ -3219,7 +4023,7 @@
 	so_data  (so, p->cfg.high_temp);
 	so_method(so, tesla, NV50TCL_FP_RESULT_COUNT, 1);
 	so_data  (so, p->cfg.high_result);
-	so_method(so, tesla, NV50TCL_FP_CTRL_UNK19A8, 1);
+	so_method(so, tesla, NV50TCL_FP_CONTROL, 1);
 	so_data  (so, p->cfg.regs[2]);
 	so_method(so, tesla, NV50TCL_FP_CTRL_UNK196C, 1);
 	so_data  (so, p->cfg.regs[3]);
@@ -3229,22 +4033,23 @@
 	so_ref(NULL, &so);
 }
 
-static void
+static uint32_t
 nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned base)
 {
 	struct nv50_program *fp = nv50->fragprog;
 	struct nv50_program *vp = nv50->vertprog;
 	unsigned i, c, m = base;
+	uint32_t origin = 0x00000010;
 
-	/* XXX: This can't work correctly in all cases yet, we either
-	 * have to create TGSI_SEMANTIC_PNTC or sprite_coord_mode has
-	 * to be per FP input instead of per VP output
+	/* XXX: this might not work correctly in all cases yet - we'll
+	 * just assume that an FP generic input that is not written in
+	 * the VP is PointCoord.
 	 */
 	memset(pntc, 0, 8 * sizeof(uint32_t));
 
 	for (i = 0; i < fp->cfg.io_nr; i++) {
 		uint8_t sn, si;
-		uint8_t j = fp->cfg.io[i].id_vp, k = fp->cfg.io[i].id_fp;
+		uint8_t j, k = fp->cfg.io[i].id;
 		unsigned n = popcnt4(fp->cfg.io[i].mask);
 
 		if (fp->info.input_semantic_name[k] != TGSI_SEMANTIC_GENERIC) {
@@ -3252,17 +4057,25 @@
 			continue;
 		}
 
-		sn = vp->info.input_semantic_name[j];
-		si = vp->info.input_semantic_index[j];
+		for (j = 0; j < vp->info.num_outputs; ++j) {
+			sn = vp->info.output_semantic_name[j];
+			si = vp->info.output_semantic_index[j];
 
-		if (j < fp->cfg.io_nr && sn == TGSI_SEMANTIC_GENERIC) {
+			if (sn == fp->info.input_semantic_name[k] &&
+			    si == fp->info.input_semantic_index[k])
+				break;
+		}
+
+		if (j < vp->info.num_outputs) {
 			ubyte mode =
 				nv50->rasterizer->pipe.sprite_coord_mode[si];
 
 			if (mode == PIPE_SPRITE_COORD_NONE) {
 				m += n;
 				continue;
-			}
+			} else
+			if (mode == PIPE_SPRITE_COORD_LOWER_LEFT)
+				origin = 0;
 		}
 
 		/* this is either PointCoord or replaced by sprite coords */
@@ -3273,6 +4086,7 @@
 			++m;
 		}
 	}
+	return origin;
 }
 
 static int
@@ -3343,20 +4157,24 @@
 	reg[0] += m - 4; /* adjust FFC0 id */
 	reg[4] |= m << 8; /* set mid where 'normal' FP inputs start */
 
-	i = 0;
-	if (fp->info.input_semantic_name[0] == TGSI_SEMANTIC_POSITION)
-		i = 1;
-	for (; i < fp->cfg.io_nr; i++) {
-		ubyte sn = fp->info.input_semantic_name[fp->cfg.io[i].id_fp];
-		ubyte si = fp->info.input_semantic_index[fp->cfg.io[i].id_fp];
+	for (i = 0; i < fp->cfg.io_nr; i++) {
+		ubyte sn = fp->info.input_semantic_name[fp->cfg.io[i].id];
+		ubyte si = fp->info.input_semantic_index[fp->cfg.io[i].id];
 
-		n = fp->cfg.io[i].id_vp;
-		if (n >= vp->cfg.io_nr ||
-		    vp->info.output_semantic_name[n] != sn ||
-		    vp->info.output_semantic_index[n] != si)
-			vpo = &dummy;
-		else
-			vpo = &vp->cfg.io[n];
+		/* position must be mapped first */
+		assert(i == 0 || sn != TGSI_SEMANTIC_POSITION);
+
+		/* maybe even remove these from cfg.io */
+		if (sn == TGSI_SEMANTIC_POSITION || sn == TGSI_SEMANTIC_FACE)
+			continue;
+
+		/* VP outputs and vp->cfg.io are in the same order */
+		for (n = 0; n < vp->info.num_outputs; ++n) {
+			if (vp->info.output_semantic_name[n] == sn &&
+			    vp->info.output_semantic_index[n] == si)
+				break;
+		}
+		vpo = (n < vp->info.num_outputs) ? &vp->cfg.io[n] : &dummy;
 
 		m = nv50_sreg4_map(map, m, lin, &fp->cfg.io[i], vpo);
 	}
@@ -3367,7 +4185,7 @@
 	}
 
 	/* now fill the stateobj */
-	so = so_new(64, 0);
+	so = so_new(7, 57, 0);
 
 	n = (m + 3) / 4;
 	so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 1);
@@ -3381,11 +4199,13 @@
 	so_method(so, tesla, NV50TCL_FP_INTERPOLANT_CTRL, 1);
 	so_data  (so, reg[4]);
 
-	so_method(so, tesla, 0x1540, 4);
+	so_method(so, tesla, NV50TCL_NOPERSPECTIVE_BITMAP(0), 4);
 	so_datap (so, lin, 4);
 
 	if (nv50->rasterizer->pipe.point_sprite) {
-		nv50_pntc_replace(nv50, pcrd, (reg[4] >> 8) & 0xff);
+		so_method(so, tesla, NV50TCL_POINT_SPRITE_CTRL, 1);
+		so_data  (so,
+			  nv50_pntc_replace(nv50, pcrd, (reg[4] >> 8) & 0xff));
 
 		so_method(so, tesla, NV50TCL_POINT_COORD_REPLACE_MAP(0), 8);
 		so_datap (so, pcrd, 8);
diff --git a/src/gallium/drivers/nv50/nv50_program.h b/src/gallium/drivers/nv50/nv50_program.h
index d78dee0..461fec1 100644
--- a/src/gallium/drivers/nv50/nv50_program.h
+++ b/src/gallium/drivers/nv50/nv50_program.h
@@ -17,8 +17,7 @@
 
 struct nv50_sreg4 {
 	uint8_t hw;
-	uint8_t id_vp;
-	uint8_t id_fp;
+	uint8_t id; /* tgsi index, nv50 needs them sorted: flat ones last */
 
 	uint8_t mask;
 	boolean linear;
@@ -38,7 +37,7 @@
 
 	struct nouveau_bo *bo;
 
-	float *immd;
+	uint32_t *immd;
 	unsigned immd_nr;
 	unsigned param_nr;
 
@@ -59,6 +58,7 @@
 		/* VP only */
 		uint8_t clpd, clpd_nr;
 		uint8_t psiz;
+		uint8_t edgeflag_in;
 	} cfg;
 };
 
diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c
index 5305c93..5a4ab35 100644
--- a/src/gallium/drivers/nv50/nv50_query.c
+++ b/src/gallium/drivers/nv50/nv50_query.c
@@ -77,9 +77,9 @@
 	struct nouveau_grobj *tesla = nv50->screen->tesla;
 	struct nv50_query *q = nv50_query(pq);
 
-	BEGIN_RING(chan, tesla, 0x1530, 1);
+	BEGIN_RING(chan, tesla, NV50TCL_SAMPLECNT_RESET, 1);
 	OUT_RING  (chan, 1);
-	BEGIN_RING(chan, tesla, 0x1514, 1);
+	BEGIN_RING(chan, tesla, NV50TCL_SAMPLECNT_ENABLE, 1);
 	OUT_RING  (chan, 1);
 
 	q->ready = FALSE;
@@ -93,7 +93,7 @@
 	struct nouveau_grobj *tesla = nv50->screen->tesla;
 	struct nv50_query *q = nv50_query(pq);
 
-	WAIT_RING (chan, 5);
+	MARK_RING (chan, 5, 2); /* flush on lack of space or relocs */
 	BEGIN_RING(chan, tesla, NV50TCL_QUERY_ADDRESS_HIGH, 4);
 	OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
 	OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
@@ -111,7 +111,7 @@
 
 	if (!q->ready) {
 		ret = nouveau_bo_map(q->bo, NOUVEAU_BO_RD |
-				     wait ? 0 : NOUVEAU_BO_NOWAIT);
+				     (wait ? 0 : NOUVEAU_BO_NOWAIT));
 		if (ret)
 			return false;
 		q->result = ((uint32_t *)q->bo->map)[1];
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index c8d0f1e..28e2b35 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -76,6 +76,7 @@
 		case PIPE_FORMAT_DXT3_RGBA:
 		case PIPE_FORMAT_DXT5_RGBA:
 		case PIPE_FORMAT_Z24S8_UNORM:
+		case PIPE_FORMAT_S8Z24_UNORM:
 		case PIPE_FORMAT_Z32_FLOAT:
 		case PIPE_FORMAT_R16G16B16A16_SNORM:
 		case PIPE_FORMAT_R16G16B16A16_UNORM:
@@ -97,6 +98,10 @@
 	switch (param) {
 	case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
 		return 32;
+	case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
+		return 32;
+	case PIPE_CAP_MAX_COMBINED_SAMPLERS:
+		return 64;
 	case PIPE_CAP_NPOT_TEXTURES:
 		return 1;
 	case PIPE_CAP_TWO_SIDED_STENCIL:
@@ -122,10 +127,8 @@
 	case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
 	case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
 		return 1;
-	case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
-		return 0;
 	case PIPE_CAP_TGSI_CONT_SUPPORTED:
-		return 0;
+		return 1;
 	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
 		return 1;
 	case NOUVEAU_CAP_HW_VTXBUF:
@@ -162,6 +165,21 @@
 nv50_screen_destroy(struct pipe_screen *pscreen)
 {
 	struct nv50_screen *screen = nv50_screen(pscreen);
+	unsigned i;
+
+	for (i = 0; i < 2; i++) {
+		if (screen->constbuf_parm[i])
+			nouveau_bo_ref(NULL, &screen->constbuf_parm[i]);
+	}
+
+	if (screen->constbuf_misc[0])
+		nouveau_bo_ref(NULL, &screen->constbuf_misc[0]);
+	if (screen->tic)
+		nouveau_bo_ref(NULL, &screen->tic);
+	if (screen->tsc)
+		nouveau_bo_ref(NULL, &screen->tsc);
+	if (screen->static_init)
+		so_ref(NULL, &screen->static_init);
 
 	nouveau_notifier_free(&screen->sync);
 	nouveau_grobj_free(&screen->tesla);
@@ -171,6 +189,28 @@
 	FREE(screen);
 }
 
+static int
+nv50_pre_pipebuffer_map(struct pipe_screen *pscreen, struct pipe_buffer *pb,
+	unsigned usage)
+{
+	struct nv50_screen *screen = nv50_screen(pscreen);
+	struct nv50_context *ctx = screen->cur_ctx;
+
+	if (!(pb->usage & PIPE_BUFFER_USAGE_VERTEX))
+		return 0;
+
+	/* Our vtxbuf got mapped, it can no longer be considered part of current
+	 * state, remove it to avoid emitting reloc markers.
+	 */
+	if (ctx && ctx->state.vtxbuf && so_bo_is_reloc(ctx->state.vtxbuf,
+			nouveau_bo(pb))) {
+		so_ref(NULL, &ctx->state.vtxbuf);
+		ctx->dirty |= NV50_NEW_ARRAYS;
+	}
+
+	return 0;
+}
+
 struct pipe_screen *
 nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 {
@@ -198,6 +238,7 @@
 	pscreen->get_param = nv50_screen_get_param;
 	pscreen->get_paramf = nv50_screen_get_paramf;
 	pscreen->is_format_supported = nv50_screen_is_format_supported;
+	screen->base.pre_pipebuffer_map_callback = nv50_pre_pipebuffer_map;
 
 	nv50_screen_init_miptree_functions(pscreen);
 	nv50_transfer_init_screen_functions(pscreen);
@@ -210,7 +251,6 @@
 		nv50_screen_destroy(pscreen);
 		return NULL;
 	}
-	BIND_RING(chan, screen->m2mf, 1);
 
 	/* 2D object */
 	ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d);
@@ -219,7 +259,6 @@
 		nv50_screen_destroy(pscreen);
 		return NULL;
 	}
-	BIND_RING(chan, screen->eng2d, 2);
 
 	/* 3D object */
 	switch (chipset & 0xf0) {
@@ -228,8 +267,7 @@
 		break;
 	case 0x80:
 	case 0x90:
-		/* this stupid name should be corrected. */
-		tesla_class = NV54TCL;
+		tesla_class = NV84TCL;
 		break;
 	case 0xa0:
 		switch (chipset) {
@@ -239,7 +277,7 @@
 			tesla_class = NVA0TCL;
 			break;
 		default:
-			tesla_class = 0x8597;
+			tesla_class = NVA8TCL;
 			break;
 		}
 		break;
@@ -256,7 +294,6 @@
 		nv50_screen_destroy(pscreen);
 		return NULL;
 	}
-	BIND_RING(chan, screen->tesla, 3);
 
 	/* Sync notifier */
 	ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
@@ -267,7 +304,7 @@
 	}
 
 	/* Static M2MF init */
-	so = so_new(32, 0);
+	so = so_new(1, 3, 0);
 	so_method(so, screen->m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3);
 	so_data  (so, screen->sync->handle);
 	so_data  (so, chan->vram->handle);
@@ -276,7 +313,7 @@
 	so_ref (NULL, &so);
 
 	/* Static 2D init */
-	so = so_new(64, 0);
+	so = so_new(4, 7, 0);
 	so_method(so, screen->eng2d, NV50_2D_DMA_NOTIFY, 4);
 	so_data  (so, screen->sync->handle);
 	so_data  (so, chan->vram->handle);
@@ -284,7 +321,7 @@
 	so_data  (so, chan->vram->handle);
 	so_method(so, screen->eng2d, NV50_2D_OPERATION, 1);
 	so_data  (so, NV50_2D_OPERATION_SRCCOPY);
-	so_method(so, screen->eng2d, 0x0290, 1);
+	so_method(so, screen->eng2d, NV50_2D_CLIP_ENABLE, 1);
 	so_data  (so, 0);
 	so_method(so, screen->eng2d, 0x0888, 1);
 	so_data  (so, 1);
@@ -292,31 +329,35 @@
 	so_ref(NULL, &so);
 
 	/* Static tesla init */
-	so = so_new(256, 20);
+	so = so_new(40, 84, 20);
 
-	so_method(so, screen->tesla, 0x1558, 1);
-	so_data  (so, 1);
+	so_method(so, screen->tesla, NV50TCL_COND_MODE, 1);
+	so_data  (so, NV50TCL_COND_MODE_ALWAYS);
 	so_method(so, screen->tesla, NV50TCL_DMA_NOTIFY, 1);
 	so_data  (so, screen->sync->handle);
-	so_method(so, screen->tesla, NV50TCL_DMA_UNK0(0),
-				     NV50TCL_DMA_UNK0__SIZE);
-	for (i = 0; i < NV50TCL_DMA_UNK0__SIZE; i++)
+	so_method(so, screen->tesla, NV50TCL_DMA_ZETA, 11);
+	for (i = 0; i < 11; i++)
 		so_data(so, chan->vram->handle);
-	so_method(so, screen->tesla, NV50TCL_DMA_UNK1(0),
-				     NV50TCL_DMA_UNK1__SIZE);
-	for (i = 0; i < NV50TCL_DMA_UNK1__SIZE; i++)
+	so_method(so, screen->tesla, NV50TCL_DMA_COLOR(0),
+				     NV50TCL_DMA_COLOR__SIZE);
+	for (i = 0; i < NV50TCL_DMA_COLOR__SIZE; i++)
 		so_data(so, chan->vram->handle);
-	so_method(so, screen->tesla, 0x121c, 1);
+	so_method(so, screen->tesla, NV50TCL_RT_CONTROL, 1);
 	so_data  (so, 1);
 
-	/* try to activate all/more lanes (threads) in a warp */
+	/* activate all 32 lanes (threads) in a warp */
+	so_method(so, screen->tesla, NV50TCL_WARP_HALVES, 1);
+	so_data  (so, 0x2);
 	so_method(so, screen->tesla, 0x1400, 1);
 	so_data  (so, 0xf);
 
-	so_method(so, screen->tesla, 0x13bc, 1);
+	/* max TIC (bits 4:8) & TSC (ignored) bindings, per program type */
+	so_method(so, screen->tesla, NV50TCL_TEX_LIMITS(0), 1);
+	so_data  (so, 0x54);
+	so_method(so, screen->tesla, NV50TCL_TEX_LIMITS(2), 1);
 	so_data  (so, 0x54);
 	/* origin is top left (set to 1 for bottom left) */
-	so_method(so, screen->tesla, 0x13ac, 1);
+	so_method(so, screen->tesla, NV50TCL_Y_ORIGIN_BOTTOM, 1);
 	so_data  (so, 0);
 	so_method(so, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1);
 	so_data  (so, 8);
@@ -352,7 +393,7 @@
 	//  B = buffer ID (maybe more than 1 byte)
 	//  N = CB index used in shader instruction
 	//  P = program type (0 = VP, 2 = GP, 3 = FP)
-	so_method(so, screen->tesla, 0x1694, 1);
+	so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
 	so_data  (so, 0x000BBNP1);
 	*/
 
@@ -385,7 +426,8 @@
 	so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
 	so_data  (so, 0x00000131 | (NV50_CB_PFP << 12));
 
-	ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 64*8*4, &screen->tic);
+	ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, PIPE_SHADER_TYPES*32*32,
+			     &screen->tic);
 	if (ret) {
 		nv50_screen_destroy(pscreen);
 		return NULL;
@@ -396,9 +438,10 @@
 		  NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
 	so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
 		  NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
-	so_data  (so, 0x000007ff);
+	so_data  (so, PIPE_SHADER_TYPES * 32 - 1);
 
-	ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 64*8*4, &screen->tsc);
+	ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, PIPE_SHADER_TYPES*32*32,
+			     &screen->tsc);
 	if (ret) {
 		nv50_screen_destroy(pscreen);
 		return NULL;
@@ -409,27 +452,31 @@
 		  NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
 	so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
 		  NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
-	so_data  (so, 0x00000000);
+	so_data  (so, 0x00000000); /* ignored if TSC_LINKED (0x1234) = 1 */
 
 
 	/* Vertex array limits - max them out */
 	for (i = 0; i < 16; i++) {
-		so_method(so, screen->tesla, NV50TCL_UNK1080_OFFSET_HIGH(i), 2);
+		so_method(so, screen->tesla, NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2);
 		so_data  (so, 0x000000ff);
 		so_data  (so, 0xffffffff);
 	}
 
-	so_method(so, screen->tesla, NV50TCL_DEPTH_RANGE_NEAR, 2);
+	so_method(so, screen->tesla, NV50TCL_DEPTH_RANGE_NEAR(0), 2);
 	so_data  (so, fui(0.0));
 	so_data  (so, fui(1.0));
 
-	so_method(so, screen->tesla, 0x1234, 1);
+	/* no dynamic combination of TIC & TSC entries => only BIND_TIC used */
+	so_method(so, screen->tesla, NV50TCL_LINKED_TSC, 1);
 	so_data  (so, 1);
 
 	/* activate first scissor rectangle */
-	so_method(so, screen->tesla, NV50TCL_SCISSOR_ENABLE, 1);
+	so_method(so, screen->tesla, NV50TCL_SCISSOR_ENABLE(0), 1);
 	so_data  (so, 1);
 
+	so_method(so, screen->tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
+	so_data  (so, 1); /* default edgeflag to TRUE */
+
 	so_emit(chan, so);
 	so_ref (so, &screen->static_init);
 	so_ref (NULL, &so);
diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h
index 61e24a5..a038a4e 100644
--- a/src/gallium/drivers/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nv50/nv50_screen.h
@@ -2,6 +2,7 @@
 #define __NV50_SCREEN_H__
 
 #include "nouveau/nouveau_screen.h"
+#include "nv50_context.h"
 
 struct nv50_screen {
 	struct nouveau_screen base;
@@ -9,6 +10,7 @@
 	struct nouveau_winsys *nvws;
 
 	unsigned cur_pctx;
+	struct nv50_context *cur_ctx;
 
 	struct nouveau_grobj *tesla;
 	struct nouveau_grobj *eng2d;
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index ffaa5e2..1f67df8 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -35,7 +35,7 @@
 nv50_blend_state_create(struct pipe_context *pipe,
 			const struct pipe_blend_state *cso)
 {
-	struct nouveau_stateobj *so = so_new(64, 0);
+	struct nouveau_stateobj *so = so_new(5, 24, 0);
 	struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
 	struct nv50_blend_stateobj *bso = CALLOC_STRUCT(nv50_blend_stateobj);
 	unsigned cmask = 0, i;
@@ -146,7 +146,6 @@
 		  (wrap_mode(cso->wrap_r) << 6));
 
 	switch (cso->mag_img_filter) {
-	case PIPE_TEX_FILTER_ANISO:
 	case PIPE_TEX_FILTER_LINEAR:
 		tsc[1] |= NV50TSC_1_1_MAGF_LINEAR;
 		break;
@@ -157,7 +156,6 @@
 	}
 
 	switch (cso->min_img_filter) {
-	case PIPE_TEX_FILTER_ANISO:
 	case PIPE_TEX_FILTER_LINEAR:
 		tsc[1] |= NV50TSC_1_1_MINF_LINEAR;
 		break;
@@ -196,8 +194,9 @@
 	}
 
 	if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
-		tsc[0] |= (1 << 8);
-		tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7);
+		/* XXX: must be deactivated for non-shadow textures */
+		tsc[0] |= (1 << 9);
+		tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7) << 10;
 	}
 
 	limit = CLAMP(cso->lod_bias, -16.0, 15.0);
@@ -215,46 +214,71 @@
 	return (void *)sso;
 }
 
-static void
-nv50_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
+static INLINE void
+nv50_sampler_state_bind(struct pipe_context *pipe, unsigned type,
+			unsigned nr, void **sampler)
 {
 	struct nv50_context *nv50 = nv50_context(pipe);
-	int i;
 
-	nv50->sampler_nr = nr;
-	for (i = 0; i < nv50->sampler_nr; i++)
-		nv50->sampler[i] = sampler[i];
+	memcpy(nv50->sampler[type], sampler, nr * sizeof(void *));
 
+	nv50->sampler_nr[type] = nr;
 	nv50->dirty |= NV50_NEW_SAMPLER;
 }
 
 static void
+nv50_vp_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **s)
+{
+	nv50_sampler_state_bind(pipe, PIPE_SHADER_VERTEX, nr, s);
+}
+
+static void
+nv50_fp_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **s)
+{
+	nv50_sampler_state_bind(pipe, PIPE_SHADER_FRAGMENT, nr, s);
+}
+
+static void
 nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
 {
 	FREE(hwcso);
 }
 
-static void
-nv50_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
-			 struct pipe_texture **pt)
+static INLINE void
+nv50_set_sampler_texture(struct pipe_context *pipe, unsigned type,
+			 unsigned nr, struct pipe_texture **pt)
 {
 	struct nv50_context *nv50 = nv50_context(pipe);
-	int i;
+	unsigned i;
 
 	for (i = 0; i < nr; i++)
-		pipe_texture_reference((void *)&nv50->miptree[i], pt[i]);
-	for (i = nr; i < nv50->miptree_nr; i++)
-		pipe_texture_reference((void *)&nv50->miptree[i], NULL);
+		pipe_texture_reference((void *)&nv50->miptree[type][i], pt[i]);
+	for (i = nr; i < nv50->miptree_nr[type]; i++)
+		pipe_texture_reference((void *)&nv50->miptree[type][i], NULL);
 
-	nv50->miptree_nr = nr;
+	nv50->miptree_nr[type] = nr;
 	nv50->dirty |= NV50_NEW_TEXTURE;
 }
 
+static void
+nv50_set_vp_sampler_textures(struct pipe_context *pipe,
+			     unsigned nr, struct pipe_texture **pt)
+{
+	nv50_set_sampler_texture(pipe, PIPE_SHADER_VERTEX, nr, pt);
+}
+
+static void
+nv50_set_fp_sampler_textures(struct pipe_context *pipe,
+			     unsigned nr, struct pipe_texture **pt)
+{
+	nv50_set_sampler_texture(pipe, PIPE_SHADER_FRAGMENT, nr, pt);
+}
+
 static void *
 nv50_rasterizer_state_create(struct pipe_context *pipe,
 			     const struct pipe_rasterizer_state *cso)
 {
-	struct nouveau_stateobj *so = so_new(64, 0);
+	struct nouveau_stateobj *so = so_new(15, 21, 0);
 	struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
 	struct nv50_rasterizer_stateobj *rso =
 		CALLOC_STRUCT(nv50_rasterizer_stateobj);
@@ -269,7 +293,7 @@
 	so_method(so, tesla, NV50TCL_SHADE_MODEL, 1);
 	so_data  (so, cso->flatshade ? NV50TCL_SHADE_MODEL_FLAT :
 				       NV50TCL_SHADE_MODEL_SMOOTH);
-	so_method(so, tesla, 0x1684, 1);
+	so_method(so, tesla, NV50TCL_PROVOKING_VERTEX_LAST, 1);
 	so_data  (so, cso->flatshade_first ? 0 : 1);
 
 	so_method(so, tesla, NV50TCL_VERTEX_TWO_SIDE_ENABLE, 1);
@@ -366,7 +390,7 @@
 		so_method(so, tesla, NV50TCL_POLYGON_OFFSET_FACTOR, 1);
 		so_data  (so, fui(cso->offset_scale));
 		so_method(so, tesla, NV50TCL_POLYGON_OFFSET_UNITS, 1);
-		so_data  (so, fui(cso->offset_units));
+		so_data  (so, fui(cso->offset_units * 2.0f));
 	}
 
 	rso->pipe = *cso;
@@ -399,7 +423,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(64, 0);
+	struct nouveau_stateobj *so = so_new(8, 22, 0);
 
 	so_method(so, tesla, NV50TCL_DEPTH_WRITE_ENABLE, 1);
 	so_data  (so, cso->depth.writemask ? 1 : 0);
@@ -413,9 +437,8 @@
 		so_data  (so, 0);
 	}
 
-	/* XXX: keep hex values until header is updated (names reversed) */
 	if (cso->stencil[0].enabled) {
-		so_method(so, tesla, 0x1380, 8);
+		so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 8);
 		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));
@@ -425,23 +448,23 @@
 		so_data  (so, cso->stencil[0].writemask);
 		so_data  (so, cso->stencil[0].valuemask);
 	} else {
-		so_method(so, tesla, 0x1380, 1);
+		so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 1);
 		so_data  (so, 0);
 	}
 
 	if (cso->stencil[1].enabled) {
-		so_method(so, tesla, 0x1594, 5);
+		so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 5);
 		so_data  (so, 1);
 		so_data  (so, nvgl_stencil_op(cso->stencil[1].fail_op));
 		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, 0x0f54, 3);
+		so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 3);
 		so_data  (so, cso->stencil[1].ref_value);
 		so_data  (so, cso->stencil[1].writemask);
 		so_data  (so, cso->stencil[1].valuemask);
 	} else {
-		so_method(so, tesla, 0x1594, 1);
+		so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 1);
 		so_data  (so, 0);
 	}
 
@@ -648,9 +671,11 @@
 	nv50->pipe.delete_blend_state = nv50_blend_state_delete;
 
 	nv50->pipe.create_sampler_state = nv50_sampler_state_create;
-	nv50->pipe.bind_sampler_states = nv50_sampler_state_bind;
 	nv50->pipe.delete_sampler_state = nv50_sampler_state_delete;
-	nv50->pipe.set_sampler_textures = nv50_set_sampler_texture;
+	nv50->pipe.bind_fragment_sampler_states = nv50_fp_sampler_state_bind;
+	nv50->pipe.bind_vertex_sampler_states   = nv50_vp_sampler_state_bind;
+	nv50->pipe.set_fragment_sampler_textures = nv50_set_fp_sampler_textures;
+	nv50->pipe.set_vertex_sampler_textures   = nv50_set_vp_sampler_textures;
 
 	nv50->pipe.create_rasterizer_state = nv50_rasterizer_state_create;
 	nv50->pipe.bind_rasterizer_state = nv50_rasterizer_state_bind;
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index a13d64b..f83232f 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -33,17 +33,18 @@
 nv50_state_validate_fb(struct nv50_context *nv50)
 {
 	struct nouveau_grobj *tesla = nv50->screen->tesla;
-	struct nouveau_stateobj *so = so_new(128, 18);
+	struct nouveau_stateobj *so = so_new(32, 79, 18);
 	struct pipe_framebuffer_state *fb = &nv50->framebuffer;
 	unsigned i, w, h, gw = 0;
 
-	/* Set nr of active RTs. Don't know what 0xfac6880 does, but
-	 * at least 0x880 was required to draw to more than 1 RT.
-	 * In some special cases, 0xfac6880 is not used, we probably
-	 * don't hit any of these though.
+	/* Set nr of active RTs and select RT for each colour output.
+	 * FP result 0 always goes to RT[0], bits 4 - 6 are ignored.
+	 * Ambiguous assignment results in no rendering (no DATA_ERROR).
 	 */
-	so_method(so, tesla, 0x121c, 1);
-	so_data  (so, 0x0fac6880 | fb->nr_cbufs);
+	so_method(so, tesla, NV50TCL_RT_CONTROL, 1);
+	so_data  (so, fb->nr_cbufs |
+		  (0 <<  4) | (1 <<  7) | (2 << 10) | (3 << 13) |
+		  (4 << 16) | (5 << 19) | (6 << 22) | (7 << 25));
 
 	for (i = 0; i < fb->nr_cbufs; i++) {
 		struct pipe_texture *pt = fb->cbufs[i]->texture;
@@ -86,7 +87,7 @@
 				level[fb->cbufs[i]->level].tile_mode << 4);
 		so_data(so, 0x00000000);
 
-		so_method(so, tesla, 0x1224, 1);
+		so_method(so, tesla, NV50TCL_RT_ARRAY_MODE, 1);
 		so_data  (so, 1);
 	}
 
@@ -123,22 +124,22 @@
 				level[fb->zsbuf->level].tile_mode << 4);
 		so_data(so, 0x00000000);
 
-		so_method(so, tesla, 0x1538, 1);
+		so_method(so, tesla, NV50TCL_ZETA_ENABLE, 1);
 		so_data  (so, 1);
 		so_method(so, tesla, NV50TCL_ZETA_HORIZ, 3);
 		so_data  (so, fb->zsbuf->width);
 		so_data  (so, fb->zsbuf->height);
 		so_data  (so, 0x00010001);
 	} else {
-		so_method(so, tesla, 0x1538, 1);
+		so_method(so, tesla, NV50TCL_ZETA_ENABLE, 1);
 		so_data  (so, 0);
 	}
 
-	so_method(so, tesla, NV50TCL_VIEWPORT_HORIZ, 2);
+	so_method(so, tesla, NV50TCL_VIEWPORT_HORIZ(0), 2);
 	so_data  (so, w << 16);
 	so_data  (so, h << 16);
 	/* set window lower left corner */
-	so_method(so, tesla, NV50TCL_WINDOW_LEFT, 2);
+	so_method(so, tesla, NV50TCL_WINDOW_OFFSET_X, 2);
 	so_data  (so, 0);
 	so_data  (so, 0);
 	/* set screen scissor rectangle */
@@ -155,11 +156,38 @@
 }
 
 static void
+nv50_validate_samplers(struct nv50_context *nv50, struct nouveau_stateobj *so,
+		       unsigned p)
+{
+	struct nouveau_grobj *eng2d = nv50->screen->eng2d;
+	unsigned i, j, dw = nv50->sampler_nr[p] * 8;
+
+	if (!dw)
+		return;
+	nv50_so_init_sifc(nv50, so, nv50->screen->tsc, NOUVEAU_BO_VRAM,
+			  p * (32 * 8 * 4), dw * 4);
+
+	so_method(so, eng2d, NV50_2D_SIFC_DATA | (2 << 29), dw);
+
+	for (i = 0; i < nv50->sampler_nr[p]; ++i) {
+		if (nv50->sampler[p][i])
+			so_datap(so, nv50->sampler[p][i]->tsc, 8);
+		else {
+			for (j = 0; j < 8; ++j) /* you get punished */
+				so_data(so, 0); /* ... for leaving holes */
+		}
+	}
+}
+
+static void
 nv50_state_emit(struct nv50_context *nv50)
 {
 	struct nv50_screen *screen = nv50->screen;
 	struct nouveau_channel *chan = screen->base.channel;
 
+	/* I don't want to copy headers from the winsys. */
+	screen->cur_ctx = nv50;
+
 	if (nv50->pctx_id != screen->cur_pctx) {
 		if (nv50->state.fb)
 			nv50->state.dirty |= NV50_NEW_FRAMEBUFFER;
@@ -200,7 +228,8 @@
 		so_emit(chan, nv50->state.vertprog);
 	if (nv50->state.dirty & NV50_NEW_FRAGPROG)
 		so_emit(chan, nv50->state.fragprog);
-	if (nv50->state.dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG))
+	if (nv50->state.dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
+				 NV50_NEW_RASTERIZER))
 		so_emit(chan, nv50->state.programs);
 	if (nv50->state.dirty & NV50_NEW_RASTERIZER)
 		so_emit(chan, nv50->state.rast);
@@ -244,7 +273,6 @@
 nv50_state_validate(struct nv50_context *nv50)
 {
 	struct nouveau_grobj *tesla = nv50->screen->tesla;
-	struct nouveau_grobj *eng2d = nv50->screen->eng2d;
 	struct nouveau_stateobj *so;
 	unsigned i;
 
@@ -263,14 +291,15 @@
 	if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB))
 		nv50_fragprog_validate(nv50);
 
-	if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG))
+	if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
+			   NV50_NEW_RASTERIZER))
 		nv50_linkage_validate(nv50);
 
 	if (nv50->dirty & NV50_NEW_RASTERIZER)
 		so_ref(nv50->rasterizer->so, &nv50->state.rast);
 
 	if (nv50->dirty & NV50_NEW_BLEND_COLOUR) {
-		so = so_new(5, 0);
+		so = so_new(1, 4, 0);
 		so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 4);
 		so_data  (so, fui(nv50->blend_colour.color[0]));
 		so_data  (so, fui(nv50->blend_colour.color[1]));
@@ -281,10 +310,10 @@
 	}
 
 	if (nv50->dirty & NV50_NEW_STIPPLE) {
-		so = so_new(33, 0);
+		so = so_new(1, 32, 0);
 		so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32);
 		for (i = 0; i < 32; i++)
-			so_data(so, nv50->stipple.stipple[i]);
+			so_data(so, util_bswap32(nv50->stipple.stipple[i]));
 		so_ref(so, &nv50->state.stipple);
 		so_ref(NULL, &so);
 	}
@@ -298,8 +327,8 @@
 			goto scissor_uptodate;
 		nv50->state.scissor_enabled = rast->scissor;
 
-		so = so_new(3, 0);
-		so_method(so, tesla, NV50TCL_SCISSOR_HORIZ, 2);
+		so = so_new(1, 2, 0);
+		so_method(so, tesla, NV50TCL_SCISSOR_HORIZ(0), 2);
 		if (nv50->state.scissor_enabled) {
 			so_data(so, (s->maxx << 16) | s->minx);
 			so_data(so, (s->maxy << 16) | s->miny);
@@ -327,13 +356,13 @@
 			goto viewport_uptodate;
 		nv50->state.viewport_bypass = bypass;
 
-		so = so_new(14, 0);
+		so = so_new(5, 9, 0);
 		if (!bypass) {
-			so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE(0), 3);
+			so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3);
 			so_data  (so, fui(nv50->viewport.translate[0]));
 			so_data  (so, fui(nv50->viewport.translate[1]));
 			so_data  (so, fui(nv50->viewport.translate[2]));
-			so_method(so, tesla, NV50TCL_VIEWPORT_SCALE(0), 3);
+			so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3);
 			so_data  (so, fui(nv50->viewport.scale[0]));
 			so_data  (so, fui(nv50->viewport.scale[1]));
 			so_data  (so, fui(nv50->viewport.scale[2]));
@@ -366,22 +395,17 @@
 viewport_uptodate:
 
 	if (nv50->dirty & NV50_NEW_SAMPLER) {
-		unsigned i;
+		unsigned nr = 0;
 
-		so = so_new(nv50->sampler_nr * 9 + 23 + 4, 2);
+		for (i = 0; i < PIPE_SHADER_TYPES; ++i)
+			nr += nv50->sampler_nr[i];
 
-		nv50_so_init_sifc(nv50, so, nv50->screen->tsc, NOUVEAU_BO_VRAM,
-				  nv50->sampler_nr * 8 * 4);
+		so = so_new(1+ 5 * PIPE_SHADER_TYPES, 1+ 19 * PIPE_SHADER_TYPES
+					+ nr * 8, PIPE_SHADER_TYPES * 2);
 
-		for (i = 0; i < nv50->sampler_nr; i++) {
-			if (!nv50->sampler[i])
-				continue;
-			so_method(so, eng2d, NV50_2D_SIFC_DATA | (2 << 29), 8);
-			so_datap (so, nv50->sampler[i]->tsc, 8);
-		}
+		nv50_validate_samplers(nv50, so, PIPE_SHADER_VERTEX);
+		nv50_validate_samplers(nv50, so, PIPE_SHADER_FRAGMENT);
 
-		so_method(so, tesla, 0x1440, 1); /* sync SIFC */
-		so_data  (so, 0);
 		so_method(so, tesla, 0x1334, 1); /* flush TSC */
 		so_data  (so, 0);
 
@@ -404,10 +428,13 @@
 
 void nv50_so_init_sifc(struct nv50_context *nv50,
 		       struct nouveau_stateobj *so,
-		       struct nouveau_bo *bo, unsigned reloc, unsigned size)
+		       struct nouveau_bo *bo, unsigned reloc,
+		       unsigned offset, unsigned size)
 {
 	struct nouveau_grobj *eng2d = nv50->screen->eng2d;
 
+	reloc |= NOUVEAU_BO_WR;
+
 	so_method(so, eng2d, NV50_2D_DST_FORMAT, 2);
 	so_data  (so, NV50_2D_DST_FORMAT_R8_UNORM);
 	so_data  (so, 1);
@@ -415,9 +442,9 @@
 	so_data  (so, 262144);
 	so_data  (so, 65536);
 	so_data  (so, 1);
-	so_reloc (so, bo, 0, reloc | NOUVEAU_BO_WR | NOUVEAU_BO_HIGH, 0, 0);
-	so_reloc (so, bo, 0, reloc | NOUVEAU_BO_WR | NOUVEAU_BO_LOW, 0, 0);
-	so_method(so, eng2d, NV50_2D_SIFC_UNK0800, 2);
+	so_reloc (so, bo, offset, reloc | NOUVEAU_BO_HIGH, 0, 0);
+	so_reloc (so, bo, offset, reloc | NOUVEAU_BO_LOW, 0, 0);
+	so_method(so, eng2d, NV50_2D_SIFC_BITMAP_ENABLE, 2);
 	so_data  (so, 0);
 	so_data  (so, NV50_2D_SIFC_FORMAT_R8_UNORM);
 	so_method(so, eng2d, NV50_2D_SIFC_WIDTH, 10);
diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
index 6bf6f77..6378132 100644
--- a/src/gallium/drivers/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nv50/nv50_surface.c
@@ -62,6 +62,7 @@
  		return 1;
 
  	if (!bo->tile_flags) {
+		MARK_RING (chan, 9, 2); /* flush on lack of space or relocs */
  		BEGIN_RING(chan, eng2d, mthd, 2);
  		OUT_RING  (chan, format);
  		OUT_RING  (chan, 1);
@@ -72,6 +73,7 @@
  		OUT_RELOCh(chan, bo, ps->offset, flags);
  		OUT_RELOCl(chan, bo, ps->offset, flags);
  	} else {
+		MARK_RING (chan, 11, 2); /* flush on lack of space or relocs */
  		BEGIN_RING(chan, eng2d, mthd, 5);
  		OUT_RING  (chan, format);
  		OUT_RING  (chan, 0);
@@ -174,11 +176,11 @@
 	if (ret)
 		return;
 
-	BEGIN_RING(chan, eng2d, 0x0580, 3);
-	OUT_RING  (chan, 4);
+	BEGIN_RING(chan, eng2d, NV50_2D_DRAW_SHAPE, 3);
+	OUT_RING  (chan, NV50_2D_DRAW_SHAPE_RECTANGLES);
 	OUT_RING  (chan, format);
 	OUT_RING  (chan, value);
-	BEGIN_RING(chan, eng2d, NV50_2D_RECT_X1, 4);
+	BEGIN_RING(chan, eng2d, NV50_2D_DRAW_POINT32_X(0), 4);
 	OUT_RING  (chan, destx);
 	OUT_RING  (chan, desty);
 	OUT_RING  (chan, width);
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index 2813f54..bef548b 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -25,6 +25,8 @@
 
 #include "nouveau/nouveau_stateobj.h"
 
+#include "util/u_format.h"
+
 #define _MIXED(pf, t0, t1, t2, t3, cr, cg, cb, ca, f)		\
 {                                                       	\
 	PIPE_FORMAT_##pf,					\
@@ -68,6 +70,7 @@
 	_(DXT5_RGBA, UNORM, C0, C1, C2, C3, DXT5),
 
 	_MIXED(Z24S8_UNORM, UINT, UNORM, UINT, UINT, C1, C1, C1, ONE, 24_8),
+	_MIXED(S8Z24_UNORM, UNORM, UINT, UINT, UINT, C0, C0, C0, ONE, 8_24),
 
 	_(R16G16B16A16_SNORM, UNORM, C0, C1, C2, C3, 16_16_16_16),
 	_(R16G16B16A16_UNORM, SNORM, C0, C1, C2, C3, 16_16_16_16),
@@ -85,10 +88,11 @@
 
 static int
 nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so,
-		   struct nv50_miptree *mt, int unit)
+		   struct nv50_miptree *mt, int unit, unsigned p)
 {
 	unsigned i;
 	uint32_t mode;
+	const struct util_format_description *desc;
 
 	for (i = 0; i < NV50_TEX_FORMAT_LIST_SIZE; i++)
 		if (nv50_tex_format_list[i].pf == mt->base.base.format)
@@ -96,7 +100,7 @@
 	if (i == NV50_TEX_FORMAT_LIST_SIZE)
                 return 1;
 
-	if (nv50->sampler[unit]->normalized)
+	if (nv50->sampler[p][unit]->normalized)
 		mode = 0x50001000 | (1 << 31);
 	else {
 		mode = 0x50001000 | (7 << 14);
@@ -106,7 +110,10 @@
 	mode |= ((mt->base.bo->tile_mode & 0x0f) << 22) |
 		((mt->base.bo->tile_mode & 0xf0) << 21);
 
-	if (pf_type(mt->base.base.format) == PIPE_FORMAT_TYPE_SRGB)
+	desc = util_format_description(mt->base.base.format);
+	assert(desc);
+
+	if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
 		mode |= 0x0400;
 
 	switch (mt->base.base.target) {
@@ -131,57 +138,89 @@
 		 NOUVEAU_BO_RD, 0, 0);
 	so_data (so, mode);
 	so_data (so, 0x00300000);
-	so_data (so, mt->base.base.width[0] | (1 << 31));
+	so_data (so, mt->base.base.width0 | (1 << 31));
 	so_data (so, (mt->base.base.last_level << 28) |
-		 (mt->base.base.depth[0] << 16) | mt->base.base.height[0]);
+		 (mt->base.base.depth0 << 16) | mt->base.base.height0);
 	so_data (so, 0x03000000);
 	so_data (so, mt->base.base.last_level << 4);
 
 	return 0;
 }
 
+#ifndef NV50TCL_BIND_TIC
+#define NV50TCL_BIND_TIC(n) (0x1448 + 8 * n)
+#endif
+
+static boolean
+nv50_validate_textures(struct nv50_context *nv50, struct nouveau_stateobj *so,
+		       unsigned p)
+{
+	static const unsigned p_remap[PIPE_SHADER_TYPES] = { 0, 2 };
+
+	struct nouveau_grobj *eng2d = nv50->screen->eng2d;
+	struct nouveau_grobj *tesla = nv50->screen->tesla;
+	unsigned unit, j, p_hw = p_remap[p];
+
+	nv50_so_init_sifc(nv50, so, nv50->screen->tic, NOUVEAU_BO_VRAM,
+			  p * (32 * 8 * 4), nv50->miptree_nr[p] * 8 * 4);
+
+	for (unit = 0; unit < nv50->miptree_nr[p]; ++unit) {
+		struct nv50_miptree *mt = nv50->miptree[p][unit];
+
+		so_method(so, eng2d, NV50_2D_SIFC_DATA | (2 << 29), 8);
+		if (mt) {
+			if (nv50_tex_construct(nv50, so, mt, unit, p))
+				return FALSE;
+			/* Set TEX insn $t src binding $unit in program type p
+			 * to TIC, TSC entry (32 * p + unit), mark valid (1).
+			 */
+			so_method(so, tesla, NV50TCL_BIND_TIC(p_hw), 1);
+			so_data  (so, ((32 * p + unit) << 9) | (unit << 1) | 1);
+		} else {
+			for (j = 0; j < 8; ++j)
+				so_data(so, 0);
+			so_method(so, tesla, NV50TCL_BIND_TIC(p_hw), 1);
+			so_data  (so, (unit << 1) | 0);
+		}
+	}
+
+	for (; unit < nv50->state.miptree_nr[p]; unit++) {
+		/* Make other bindings invalid. */
+		so_method(so, tesla, NV50TCL_BIND_TIC(p_hw), 1);
+		so_data  (so, (unit << 1) | 0);
+	}
+
+	nv50->state.miptree_nr[p] = nv50->miptree_nr[p];
+	return TRUE;
+}
+
 void
 nv50_tex_validate(struct nv50_context *nv50)
 {
-	struct nouveau_grobj *eng2d = nv50->screen->eng2d;
-	struct nouveau_grobj *tesla = nv50->screen->tesla;
 	struct nouveau_stateobj *so;
-	unsigned i, unit, push;
+	struct nouveau_grobj *tesla = nv50->screen->tesla;
+	unsigned p, start, push, nrlc;
 
-	push = MAX2(nv50->miptree_nr, nv50->state.miptree_nr) * 2 + 23 + 6;
-	so = so_new(nv50->miptree_nr * 9 + push, nv50->miptree_nr * 2 + 2);
-
-	nv50_so_init_sifc(nv50, so, nv50->screen->tic, NOUVEAU_BO_VRAM,
-			  nv50->miptree_nr * 8 * 4);
-
-	for (i = 0, unit = 0; unit < nv50->miptree_nr; ++unit) {
-		struct nv50_miptree *mt = nv50->miptree[unit];
-
-		if (!mt)
-			continue;
-
-		so_method(so, eng2d, NV50_2D_SIFC_DATA | (2 << 29), 8);
-		if (nv50_tex_construct(nv50, so, mt, unit)) {
-			NOUVEAU_ERR("failed tex validate\n");
-			so_ref(NULL, &so);
-			return;
-		}
-
-		so_method(so, tesla, NV50TCL_SET_SAMPLER_TEX, 1);
-		so_data  (so, (i++ << NV50TCL_SET_SAMPLER_TEX_TIC_SHIFT) |
-			  (unit << NV50TCL_SET_SAMPLER_TEX_SAMPLER_SHIFT) |
-			  NV50TCL_SET_SAMPLER_TEX_VALID);
+	for (nrlc = 0, start = 0, push = 0, p = 0; p < PIPE_SHADER_TYPES; ++p) {
+		start += MAX2(nv50->miptree_nr[p], nv50->state.miptree_nr[p]);
+		push += MAX2(nv50->miptree_nr[p], nv50->state.miptree_nr[p]);
+		nrlc += nv50->miptree_nr[p];
 	}
+	start = start * 2 + 4 * PIPE_SHADER_TYPES + 2;
+	push = push * 9 + 19 * PIPE_SHADER_TYPES + 2;
+	nrlc = nrlc * 2 + 2 * PIPE_SHADER_TYPES;
 
-	for (; unit < nv50->state.miptree_nr; unit++) {
-		so_method(so, tesla, NV50TCL_SET_SAMPLER_TEX, 1);
-		so_data  (so,
-			  (unit << NV50TCL_SET_SAMPLER_TEX_SAMPLER_SHIFT) | 0);
+	so = so_new(start, push, nrlc);
+
+	if (nv50_validate_textures(nv50, so, PIPE_SHADER_VERTEX) == FALSE ||
+	    nv50_validate_textures(nv50, so, PIPE_SHADER_FRAGMENT) == FALSE) {
+		so_ref(NULL, &so);
+
+		NOUVEAU_ERR("failed tex validate\n");
+		return;
 	}
 
 	/* not sure if the following really do what I think: */
-	so_method(so, tesla, 0x1440, 1); /* sync SIFC */
-	so_data  (so, 0);
 	so_method(so, tesla, 0x1330, 1); /* flush TIC */
 	so_data  (so, 0);
 	so_method(so, tesla, 0x1338, 1); /* flush texture caches */
@@ -189,6 +228,4 @@
 
 	so_ref(so, &nv50->state.tic_upload);
 	so_ref(NULL, &so);
-	nv50->state.miptree_nr = nv50->miptree_nr;
 }
-
diff --git a/src/gallium/drivers/nv50/nv50_texture.h b/src/gallium/drivers/nv50/nv50_texture.h
index d531e61..b870302 100644
--- a/src/gallium/drivers/nv50/nv50_texture.h
+++ b/src/gallium/drivers/nv50/nv50_texture.h
@@ -82,6 +82,7 @@
 #define NV50TIC_0_0_FMT_RGTC1                                     0x00000027
 #define NV50TIC_0_0_FMT_RGTC2                                     0x00000028
 #define NV50TIC_0_0_FMT_24_8                                      0x00000029
+#define NV50TIC_0_0_FMT_8_24                                      0x0000002a
 #define NV50TIC_0_0_FMT_32_DEPTH                                  0x0000002f
 #define NV50TIC_0_0_FMT_32_8                                      0x00000030
 
diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c
index ea61357..a2f1db2 100644
--- a/src/gallium/drivers/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nv50/nv50_transfer.c
@@ -1,6 +1,8 @@
 
 #include "pipe/p_context.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
 
 #include "nv50_context.h"
 
@@ -15,16 +17,19 @@
 	int level_depth;
 	int level_x;
 	int level_y;
+	int level_z;
+	unsigned nblocksx;
+	unsigned nblocksy;
 };
 
 static void
 nv50_transfer_rect_m2mf(struct pipe_screen *pscreen,
 			struct nouveau_bo *src_bo, unsigned src_offset,
 			int src_pitch, unsigned src_tile_mode,
-			int sx, int sy, int sw, int sh, int sd,
+			int sx, int sy, int sz, int sw, int sh, int sd,
 			struct nouveau_bo *dst_bo, unsigned dst_offset,
 			int dst_pitch, unsigned dst_tile_mode,
-			int dx, int dy, int dw, int dh, int dd,
+			int dx, int dy, int dz, int dw, int dh, int dd,
 			int cpp, int width, int height,
 			unsigned src_reloc, unsigned dst_reloc)
 {
@@ -42,7 +47,7 @@
 			NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN, 1);
 		OUT_RING  (chan, 1);
 		BEGIN_RING(chan, m2mf,
-			NV50_MEMORY_TO_MEMORY_FORMAT_PITCH_IN, 1);
+			NV04_MEMORY_TO_MEMORY_FORMAT_PITCH_IN, 1);
 		OUT_RING  (chan, src_pitch);
 		src_offset += (sy * src_pitch) + (sx * cpp);
 	} else {
@@ -53,7 +58,7 @@
 		OUT_RING  (chan, sw * cpp);
 		OUT_RING  (chan, sh);
 		OUT_RING  (chan, sd);
-		OUT_RING  (chan, 0);
+		OUT_RING  (chan, sz); /* copying only 1 zslice per call */
 	}
 
 	if (!dst_bo->tile_flags) {
@@ -61,7 +66,7 @@
 			NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT, 1);
 		OUT_RING  (chan, 1);
 		BEGIN_RING(chan, m2mf,
-			NV50_MEMORY_TO_MEMORY_FORMAT_PITCH_OUT, 1);
+			NV04_MEMORY_TO_MEMORY_FORMAT_PITCH_OUT, 1);
 		OUT_RING  (chan, dst_pitch);
 		dst_offset += (dy * dst_pitch) + (dx * cpp);
 	} else {
@@ -72,19 +77,19 @@
 		OUT_RING  (chan, dw * cpp);
 		OUT_RING  (chan, dh);
 		OUT_RING  (chan, dd);
-		OUT_RING  (chan, 0);
+		OUT_RING  (chan, dz); /* copying only 1 zslice per call */
 	}
 
 	while (height) {
 		int line_count = height > 2047 ? 2047 : height;
 
-		WAIT_RING (chan, 15);
+		MARK_RING (chan, 15, 4); /* flush on lack of space or relocs */
 		BEGIN_RING(chan, m2mf,
 			NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH, 2);
 		OUT_RELOCh(chan, src_bo, src_offset, src_reloc);
 		OUT_RELOCh(chan, dst_bo, dst_offset, dst_reloc);
 		BEGIN_RING(chan, m2mf,
-			NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 2);
+			NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 2);
 		OUT_RELOCl(chan, src_bo, src_offset, src_reloc);
 		OUT_RELOCl(chan, dst_bo, dst_offset, dst_reloc);
 		if (src_bo->tile_flags) {
@@ -102,7 +107,7 @@
 			dst_offset += (line_count * dst_pitch);
 		}
 		BEGIN_RING(chan, m2mf,
-			NV50_MEMORY_TO_MEMORY_FORMAT_LINE_LENGTH_IN, 4);
+			NV04_MEMORY_TO_MEMORY_FORMAT_LINE_LENGTH_IN, 4);
 		OUT_RING  (chan, width * cpp);
 		OUT_RING  (chan, line_count);
 		OUT_RING  (chan, 0x00000101);
@@ -115,20 +120,6 @@
 	}
 }
 
-static INLINE unsigned
-get_zslice_offset(unsigned tile_mode, unsigned z, unsigned pitch, unsigned ny)
-{
-	unsigned tile_h = get_tile_height(tile_mode);
-	unsigned tile_d = get_tile_depth(tile_mode);
-
-	/* pitch_2d == to next slice within this volume-tile */
-	/* pitch_3d == to next slice in next 2D array of blocks */
-	unsigned pitch_2d = tile_h * 64;
-	unsigned pitch_3d = tile_d * align(ny, tile_h) * pitch;
-
-	return (z % tile_d) * pitch_2d + (z / tile_d) * pitch_3d;
-}
-
 static struct pipe_transfer *
 nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
 		  unsigned face, unsigned level, unsigned zslice,
@@ -150,56 +141,43 @@
 		return NULL;
 
 	pipe_texture_reference(&tx->base.texture, pt);
-	tx->base.format = pt->format;
+	tx->nblocksx = util_format_get_nblocksx(pt->format, u_minify(pt->width0, level));
+	tx->nblocksy = util_format_get_nblocksy(pt->format, u_minify(pt->height0, level));
 	tx->base.width = w;
 	tx->base.height = h;
-	tx->base.block = pt->block;
-	if (!pt->nblocksx[level]) {
-		tx->base.nblocksx = pf_get_nblocksx(&pt->block,
-						    pt->width[level]);
-		tx->base.nblocksy = pf_get_nblocksy(&pt->block,
-						    pt->height[level]);
-	} else {
-		tx->base.nblocksx = pt->nblocksx[level];
-		tx->base.nblocksy = pt->nblocksy[level];
-	}
-	tx->base.stride = tx->base.nblocksx * pt->block.size;
+	tx->base.stride = tx->nblocksx * util_format_get_blocksize(pt->format);
 	tx->base.usage = usage;
 
 	tx->level_pitch = lvl->pitch;
-	tx->level_width = mt->base.base.width[level];
-	tx->level_height = mt->base.base.height[level];
-	tx->level_depth = mt->base.base.depth[level];
+	tx->level_width = u_minify(mt->base.base.width0, level);
+	tx->level_height = u_minify(mt->base.base.height0, level);
+	tx->level_depth = u_minify(mt->base.base.depth0, level);
 	tx->level_offset = lvl->image_offset[image];
 	tx->level_tiling = lvl->tile_mode;
-	tx->level_x = pf_get_nblocksx(&tx->base.block, x);
-	tx->level_y = pf_get_nblocksy(&tx->base.block, y);
+	tx->level_z = zslice;
+	tx->level_x = util_format_get_nblocksx(pt->format, x);
+	tx->level_y = util_format_get_nblocksy(pt->format, y);
 	ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
-			     tx->base.nblocksy * tx->base.stride, &tx->bo);
+			     tx->nblocksy * tx->base.stride, &tx->bo);
 	if (ret) {
 		FREE(tx);
 		return NULL;
 	}
 
-	if (pt->target == PIPE_TEXTURE_3D)
-		tx->level_offset += get_zslice_offset(lvl->tile_mode, zslice,
-						      lvl->pitch,
-						      tx->base.nblocksy);
-
 	if (usage & PIPE_TRANSFER_READ) {
-		nx = pf_get_nblocksx(&tx->base.block, tx->base.width);
-		ny = pf_get_nblocksy(&tx->base.block, tx->base.height);
+		nx = util_format_get_nblocksx(pt->format, tx->base.width);
+		ny = util_format_get_nblocksy(pt->format, tx->base.height);
 
 		nv50_transfer_rect_m2mf(pscreen, mt->base.bo, tx->level_offset,
 					tx->level_pitch, tx->level_tiling,
-					x, y,
-					tx->base.nblocksx, tx->base.nblocksy,
+					x, y, zslice,
+					tx->nblocksx, tx->nblocksy,
 					tx->level_depth,
 					tx->bo, 0,
 					tx->base.stride, tx->bo->tile_mode,
-					0, 0,
-					tx->base.nblocksx, tx->base.nblocksy, 1,
-					tx->base.block.size, nx, ny,
+					0, 0, 0,
+					tx->nblocksx, tx->nblocksy, 1,
+					util_format_get_blocksize(pt->format), nx, ny,
 					NOUVEAU_BO_VRAM | NOUVEAU_BO_GART,
 					NOUVEAU_BO_GART);
 	}
@@ -212,23 +190,24 @@
 {
 	struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
 	struct nv50_miptree *mt = nv50_miptree(ptx->texture);
+	struct pipe_texture *pt = ptx->texture;
 
-	unsigned nx = pf_get_nblocksx(&tx->base.block, tx->base.width);
-	unsigned ny = pf_get_nblocksy(&tx->base.block, tx->base.height);
+	unsigned nx = util_format_get_nblocksx(pt->format, tx->base.width);
+	unsigned ny = util_format_get_nblocksy(pt->format, tx->base.height);
 
 	if (ptx->usage & PIPE_TRANSFER_WRITE) {
-		struct pipe_screen *pscreen = ptx->texture->screen;
+		struct pipe_screen *pscreen = pt->screen;
 
 		nv50_transfer_rect_m2mf(pscreen, tx->bo, 0,
 					tx->base.stride, tx->bo->tile_mode,
-					0, 0,
-					tx->base.nblocksx, tx->base.nblocksy, 1,
+					0, 0, 0,
+					tx->nblocksx, tx->nblocksy, 1,
 					mt->base.bo, tx->level_offset,
 					tx->level_pitch, tx->level_tiling,
-					tx->level_x, tx->level_y,
-					tx->base.nblocksx, tx->base.nblocksy,
+					tx->level_x, tx->level_y, tx->level_z,
+					tx->nblocksx, tx->nblocksy,
 					tx->level_depth,
-					tx->base.block.size, nx, ny,
+					util_format_get_blocksize(pt->format), nx, ny,
 					NOUVEAU_BO_GART, NOUVEAU_BO_VRAM |
 					NOUVEAU_BO_GART);
 	}
@@ -287,7 +266,7 @@
 
 	reloc |= NOUVEAU_BO_WR;
 
-	WAIT_RING (chan, 32);
+	MARK_RING (chan, 32, 2); /* flush on lack of space or relocs */
 
 	if (bo->tile_flags) {
 		BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 5);
@@ -312,7 +291,7 @@
 
 	/* NV50_2D_OPERATION_SRCCOPY assumed already set */
 
-	BEGIN_RING(chan, eng2d, NV50_2D_SIFC_UNK0800, 2);
+	BEGIN_RING(chan, eng2d, NV50_2D_SIFC_BITMAP_ENABLE, 2);
 	OUT_RING  (chan, 0);
 	OUT_RING  (chan, src_format);
 	BEGIN_RING(chan, eng2d, NV50_2D_SIFC_WIDTH, 10);
@@ -355,6 +334,6 @@
 		src += src_pitch;
 	}
 
-	BEGIN_RING(chan, tesla, 0x1440, 1);
+	BEGIN_RING(chan, tesla, NV50TCL_CODE_CB_FLUSH, 1);
 	OUT_RING  (chan, 0);
 }
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index db54380..f2e510f 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -24,6 +24,8 @@
 #include "pipe/p_state.h"
 #include "pipe/p_inlines.h"
 
+#include "util/u_format.h"
+
 #include "nv50_context.h"
 
 static boolean
@@ -62,18 +64,25 @@
 }
 
 static INLINE uint32_t
-nv50_vbo_type_to_hw(unsigned type)
+nv50_vbo_type_to_hw(enum pipe_format format)
 {
-	switch (type) {
-	case PIPE_FORMAT_TYPE_FLOAT:
+	const struct util_format_description *desc;
+
+	desc = util_format_description(format);
+	assert(desc);
+
+	switch (desc->channel[0].type) {
+	case UTIL_FORMAT_TYPE_FLOAT:
 		return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT;
-	case PIPE_FORMAT_TYPE_UNORM:
-		return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UNORM;
-	case PIPE_FORMAT_TYPE_SNORM:
-		return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SNORM;
-	case PIPE_FORMAT_TYPE_USCALED:
+	case UTIL_FORMAT_TYPE_UNSIGNED:
+		if (desc->channel[0].normalized) {
+			return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UNORM;
+		}
 		return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_USCALED;
-	case PIPE_FORMAT_TYPE_SSCALED:
+	case UTIL_FORMAT_TYPE_SIGNED:
+		if (desc->channel[0].normalized) {
+			return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SNORM;
+		}
 		return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SSCALED;
 	/*
 	case PIPE_FORMAT_TYPE_UINT:
@@ -90,19 +99,19 @@
 {
 	static const uint32_t hw_values[] = {
 		0, 0, 0, 0,
-		NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_8,
-		NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_8_8,
-		NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_8_8_8,
-		NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_8_8_8_8,
-		NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_16,
-		NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_16_16,
-		NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_16_16_16,
-		NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_16_16_16_16,
+		NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_8,
+		NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_8_8,
+		NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_8_8_8,
+		NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_8_8_8_8,
+		NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_16,
+		NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_16_16,
+		NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_16_16_16,
+		NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_16_16_16_16,
 		0, 0, 0, 0,
-		NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_32,
-		NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_32_32,
-		NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_32_32_32,
-		NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_32_32_32_32 };
+		NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_32,
+		NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_32_32,
+		NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_32_32_32,
+		NV50TCL_VERTEX_ARRAY_ATTRIB_FORMAT_32_32_32_32 };
 
 	/* we'd also have R11G11B10 and R10G10B10A2 */
 
@@ -120,9 +129,15 @@
 {
 	uint32_t hw_type, hw_size;
 	enum pipe_format pf = ve->src_format;
-	unsigned size = pf_size_x(pf) << pf_exp2(pf);
+	const struct util_format_description *desc;
+	unsigned size;
 
-	hw_type = nv50_vbo_type_to_hw(pf_type(pf));
+	desc = util_format_description(pf);
+	assert(desc);
+
+	size = util_format_get_component_bits(pf, UTIL_FORMAT_COLORSPACE_RGB, 0);
+
+	hw_type = nv50_vbo_type_to_hw(pf);
 	hw_size = nv50_vbo_size_to_hw(size, ve->nr_components);
 
 	if (!hw_type || !hw_size) {
@@ -131,13 +146,13 @@
 		return 0x24e80000;
 	}
 
-	if (pf_swizzle_x(pf) == 2) /* BGRA */
+	if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_Z) /* BGRA */
 		hw_size |= (1 << 31); /* no real swizzle bits :-( */
 
 	return (hw_type | hw_size);
 }
 
-boolean
+void
 nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
 		 unsigned count)
 {
@@ -167,7 +182,9 @@
 	BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
 	OUT_RING  (chan, 0);
 
-	return ret;
+        /* XXX: not sure what to do if ret != TRUE: flush and retry?
+         */
+        assert(ret);
 }
 
 static INLINE boolean
@@ -183,7 +200,7 @@
 		return nv50_push_elements_u08(nv50, map, count);
 
 	if (count & 1) {
-		BEGIN_RING(chan, tesla, 0x15e8, 1);
+		BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32, 1);
 		OUT_RING  (chan, map[0]);
 		map++;
 		count--;
@@ -193,7 +210,7 @@
 		unsigned nr = count > 2046 ? 2046 : count;
 		int i;
 
-		BEGIN_RING(chan, tesla, 0x400015f0, nr >> 1);
+		BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x40000000, nr >> 1);
 		for (i = 0; i < nr; i += 2)
 			OUT_RING  (chan, (map[i + 1] << 16) | map[i]);
 
@@ -216,7 +233,7 @@
 		return nv50_push_elements_u16(nv50, map, count);
 
 	if (count & 1) {
-		BEGIN_RING(chan, tesla, 0x15e8, 1);
+		BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32, 1);
 		OUT_RING  (chan, map[0]);
 		map++;
 		count--;
@@ -226,7 +243,7 @@
 		unsigned nr = count > 2046 ? 2046 : count;
 		int i;
 
-		BEGIN_RING(chan, tesla, 0x400015f0, nr >> 1);
+		BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x40000000, nr >> 1);
 		for (i = 0; i < nr; i += 2)
 			OUT_RING  (chan, (map[i + 1] << 16) | map[i]);
 
@@ -251,7 +268,7 @@
 	while (count) {
 		unsigned nr = count > 2047 ? 2047 : count;
 
-		BEGIN_RING(chan, tesla, 0x400015e8, nr);
+		BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x40000000, nr);
 		OUT_RINGp (chan, map, nr);
 
 		count -= nr;
@@ -260,7 +277,7 @@
 	return TRUE;
 }
 
-boolean
+void
 nv50_draw_elements(struct pipe_context *pipe,
 		   struct pipe_buffer *indexBuffer, unsigned indexSize,
 		   unsigned mode, unsigned start, unsigned count)
@@ -302,8 +319,10 @@
 	OUT_RING  (chan, 0);
 
 	pipe_buffer_unmap(pscreen, indexBuffer);
-
-	return ret;
+        
+        /* XXX: what to do if ret != TRUE?  Flush and retry?
+         */
+	assert(ret);
 }
 
 static INLINE boolean
@@ -319,9 +338,13 @@
 	float *v;
 	int ret;
 	enum pipe_format pf = ve->src_format;
+	const struct util_format_description *desc;
 
-	if ((pf_type(pf) != PIPE_FORMAT_TYPE_FLOAT) ||
-	    (pf_size_x(pf) << pf_exp2(pf)) != 32)
+	desc = util_format_description(pf);
+	assert(desc);
+
+	if ((desc->channel[0].type != UTIL_FORMAT_TYPE_FLOAT) ||
+	    util_format_get_component_bits(pf, UTIL_FORMAT_COLORSPACE_RGB, 0) != 32)
 		return FALSE;
 
 	ret = nouveau_bo_map(bo, NOUVEAU_BO_RD);
@@ -331,7 +354,7 @@
 
 	so = *pso;
 	if (!so)
-		*pso = so = so_new(nv50->vtxelt_nr * 5, 0);
+		*pso = so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 4, 0);
 
 	switch (ve->nr_components) {
 	case 4:
@@ -353,6 +376,10 @@
 		so_data  (so, fui(v[1]));
 		break;
 	case 1:
+		if (attrib == nv50->vertprog->cfg.edgeflag_in) {
+			so_method(so, tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
+			so_data  (so, v[0] ? 1 : 0);
+		}
 		so_method(so, tesla, NV50TCL_VTX_ATTR_1F(attrib), 1);
 		so_data  (so, fui(v[0]));
 		break;
@@ -382,11 +409,14 @@
 		    !(nv50->vtxbuf[i].buffer->usage & PIPE_BUFFER_USAGE_VERTEX))
 			nv50->vbo_fifo = 0xffff;
 
+	if (nv50->vertprog->cfg.edgeflag_in < 16)
+		nv50->vbo_fifo = 0xffff; /* vertprog can't set edgeflag */
+
 	n_ve = MAX2(nv50->vtxelt_nr, nv50->state.vtxelt_nr);
 
 	vtxattr = NULL;
-	vtxbuf = so_new(n_ve * 7, nv50->vtxelt_nr * 4);
-	vtxfmt = so_new(n_ve + 1, 0);
+	vtxbuf = so_new(n_ve * 2, n_ve * 5, nv50->vtxelt_nr * 4);
+	vtxfmt = so_new(1, n_ve, 0);
 	so_method(vtxfmt, tesla, NV50TCL_VERTEX_ARRAY_ATTRIB(0), n_ve);
 
 	for (i = 0; i < nv50->vtxelt_nr; i++) {
@@ -426,7 +456,7 @@
 			  NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
 
 		/* vertex array limits */
-		so_method(vtxbuf, tesla, 0x1080 + (i * 8), 2);
+		so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2);
 		so_reloc (vtxbuf, bo, vb->buffer->size - 1,
 			  NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
 			  NOUVEAU_BO_HIGH, 0, 0);
@@ -460,6 +490,9 @@
 	unsigned nr_ve;
 	unsigned vtx_dwords;
 	unsigned vtx_max;
+
+	float edgeflag;
+	unsigned ve_edgeflag;
 };
 
 static INLINE void
@@ -603,13 +636,17 @@
 	if (nv50_map_vbufs(nv50) == FALSE)
 		return FALSE;
 
+	emit->ve_edgeflag = nv50->vertprog->cfg.edgeflag_in;
+
+	emit->edgeflag = 0.5f;
 	emit->nr_ve = 0;
 	emit->vtx_dwords = 0;
 
 	for (i = 0; i < nv50->vtxelt_nr; ++i) {
 		struct pipe_vertex_element *ve;
 		struct pipe_vertex_buffer *vb;
-		unsigned n, type, size;
+		unsigned n, size;
+		const struct util_format_description *desc;
 
 		ve = &nv50->vtxelt[i];
 		vb = &nv50->vtxbuf[ve->vertex_buffer_index];
@@ -621,8 +658,11 @@
 		emit->map[n] = nouveau_bo(vb->buffer)->map +
 			(start * vb->stride + ve->src_offset);
 
-		type = pf_type(ve->src_format);
-		size = pf_size_x(ve->src_format) << pf_exp2(ve->src_format);
+		desc = util_format_description(ve->src_format);
+		assert(desc);
+
+		size = util_format_get_component_bits(
+			ve->src_format, UTIL_FORMAT_COLORSPACE_RGB, 0);
 
 		assert(ve->nr_components > 0 && ve->nr_components <= 4);
 
@@ -664,10 +704,31 @@
 	}
 
 	emit->vtx_max = 512 / emit->vtx_dwords;
+	if (emit->ve_edgeflag < 16)
+		emit->vtx_max = 1;
 
 	return TRUE;
 }
 
+static INLINE void
+set_edgeflag(struct nouveau_channel *chan,
+	     struct nouveau_grobj *tesla,
+	     struct nv50_vbo_emitctx *emit, uint32_t index)
+{
+	unsigned i = emit->ve_edgeflag;
+
+	if (i < 16) {
+		float f = *((float *)(emit->map[i] + index * emit->stride[i]));
+
+		if (emit->edgeflag != f) {
+			emit->edgeflag = f;
+
+			BEGIN_RING(chan, tesla, 0x15e4, 1);
+			OUT_RING  (chan, f ? 1 : 0);
+		}
+	}
+}
+
 static boolean
 nv50_push_arrays(struct nv50_context *nv50, unsigned start, unsigned count)
 {
@@ -682,6 +743,8 @@
 		unsigned i, dw, nr = MIN2(count, emit.vtx_max);
 	        dw = nr * emit.vtx_dwords;
 
+		set_edgeflag(chan, tesla, &emit, 0); /* nr will be 1 */
+
 		BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw);
 		for (i = 0; i < nr; ++i)
 			emit_vtx_next(chan, &emit);
@@ -707,6 +770,8 @@
 		unsigned i, dw, nr = MIN2(count, emit.vtx_max);
 	        dw = nr * emit.vtx_dwords;
 
+		set_edgeflag(chan, tesla, &emit, *map);
+
 		BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw);
 		for (i = 0; i < nr; ++i)
 			emit_vtx(chan, &emit, *map++);
@@ -732,6 +797,8 @@
 		unsigned i, dw, nr = MIN2(count, emit.vtx_max);
 	        dw = nr * emit.vtx_dwords;
 
+		set_edgeflag(chan, tesla, &emit, *map);
+
 		BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw);
 		for (i = 0; i < nr; ++i)
 			emit_vtx(chan, &emit, *map++);
@@ -757,6 +824,8 @@
 		unsigned i, dw, nr = MIN2(count, emit.vtx_max);
 	        dw = nr * emit.vtx_dwords;
 
+		set_edgeflag(chan, tesla, &emit, *map);
+
 		BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw);
 		for (i = 0; i < nr; ++i)
 			emit_vtx(chan, &emit, *map++);
diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile
index f73d80d..afddcb1 100644
--- a/src/gallium/drivers/r300/Makefile
+++ b/src/gallium/drivers/r300/Makefile
@@ -4,8 +4,8 @@
 LIBNAME = r300
 
 C_SOURCES = \
+	r300_blit.c \
 	r300_chipset.c \
-	r300_clear.c \
 	r300_context.c \
 	r300_debug.c \
 	r300_emit.c \
@@ -22,7 +22,8 @@
 	r300_tgsi_to_rc.c
 
 LIBRARY_INCLUDES = \
-	-I$(TOP)/src/mesa/drivers/dri/r300/compiler
+	-I$(TOP)/src/mesa/drivers/dri/r300/compiler \
+	-I$(TOP)/src/gallium/winsys/drm/radeon/core
 
 COMPILER_ARCHIVE = $(TOP)/src/mesa/drivers/dri/r300/compiler/libr300compiler.a
 
@@ -34,4 +35,4 @@
 .PHONY : $(COMPILER_ARCHIVE)
 
 $(COMPILER_ARCHIVE):
-	cd $(TOP)/src/mesa/drivers/dri/r300/compiler; make
+	$(MAKE) -C $(TOP)/src/mesa/drivers/dri/r300/compiler
diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript
index 9798904..183aa17 100644
--- a/src/gallium/drivers/r300/SConscript
+++ b/src/gallium/drivers/r300/SConscript
@@ -4,13 +4,18 @@
 
 env = env.Clone()
 # add the paths for r300compiler
-env.Append(CPPPATH = ['#/src/mesa/drivers/dri/r300/compiler', '#/include', '#/src/mesa'])
+env.Append(CPPPATH = [
+    '#/src/mesa/drivers/dri/r300/compiler', 
+    '#/src/gallium/winsys/drm/radeon/core',
+    '#/include', 
+    '#/src/mesa',
+])
 
 r300 = env.ConvenienceLibrary(
     target = 'r300',
     source = [
+        'r300_blit.c',
         'r300_chipset.c',
-        'r300_clear.c',
         'r300_context.c',
         'r300_debug.c',
         'r300_emit.c',
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
new file mode 100644
index 0000000..c14414f
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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 "r300_blit.h"
+#include "r300_context.h"
+
+#include "util/u_rect.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_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);
+}
+
+/* Clear currently bound buffers. */
+void r300_clear(struct pipe_context* pipe,
+                unsigned buffers,
+                const float* rgba,
+                double depth,
+                unsigned stencil)
+{
+    /* XXX Implement fastfill.
+     *
+     * If fastfill is enabled, a few facts should be considered:
+     *
+     * 1) Zbuffer must be micro-tiled and whole microtiles must be
+     *    written.
+     *
+     * 2) ZB_DEPTHCLEARVALUE is used to clear a zbuffer and Z Mask must be
+     *    equal to 0.
+     *
+     * 3) RB3D_COLOR_CLEAR_VALUE is used to clear a colorbuffer and
+     *    RB3D_COLOR_CHANNEL_MASK must be equal to 0.
+     *
+     * 4) ZB_CB_CLEAR can be used to make the ZB units help in clearing
+     *    the colorbuffer. The color clear value is supplied through both
+     *    RB3D_COLOR_CLEAR_VALUE and ZB_DEPTHCLEARVALUE, and the colorbuffer
+     *    must be set in ZB_DEPTHOFFSET and ZB_DEPTHPITCH in addition to
+     *    RB3D_COLOROFFSET and RB3D_COLORPITCH. It's obvious that the zbuffer
+     *    will not be cleared and multiple render targets cannot be cleared
+     *    this way either.
+     *
+     * 5) For 16-bit integer buffering, compression causes a hung with one or
+     *    two samples and should not be used.
+     *
+     * 6) Fastfill must not be used if reading of compressed Z data is disabled
+     *    and writing of compressed Z data is enabled (RD/WR_COMP_ENABLE),
+     *    i.e. it cannot be used to compress the zbuffer.
+     *    (what the hell does that mean and how does it fit in clearing
+     *    the buffers?)
+     *
+     * - Marek
+     */
+
+    struct r300_context* r300 = r300_context(pipe);
+
+    r300_blitter_save_states(r300);
+
+    util_blitter_clear(r300->blitter,
+                       r300->framebuffer_state.width,
+                       r300->framebuffer_state.height,
+                       r300->framebuffer_state.nr_cbufs,
+                       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)
+{
+    struct r300_context* r300 = r300_context(pipe);
+
+    /* Yeah we have to save all those states to ensure this blitter operation
+     * is really transparent. The states will be restored by the blitter once
+     * copying is done. */
+    r300_blitter_save_states(r300);
+    util_blitter_save_framebuffer(r300->blitter, &r300->framebuffer_state);
+
+    util_blitter_save_fragment_sampler_states(
+        r300->blitter, r300->sampler_count, (void**)r300->sampler_states);
+
+    util_blitter_save_fragment_sampler_textures(
+        r300->blitter, r300->texture_count,
+        (struct pipe_texture**)r300->textures);
+
+    /* Do a copy */
+    util_blitter_copy(r300->blitter,
+                      dst, dstx, dsty, src, srcx, srcy, width, height, TRUE);
+}
+
+/* Fill a region of a surface with a constant value. */
+void r300_surface_fill(struct pipe_context* pipe,
+                       struct pipe_surface* dst,
+                       unsigned dstx, unsigned dsty,
+                       unsigned width, unsigned height,
+                       unsigned value)
+{
+    struct r300_context* r300 = r300_context(pipe);
+
+    r300_blitter_save_states(r300);
+    util_blitter_save_framebuffer(r300->blitter, &r300->framebuffer_state);
+
+    util_blitter_fill(r300->blitter,
+                      dst, dstx, dsty, width, height, value);
+}
diff --git a/src/gallium/drivers/r300/r300_clear.h b/src/gallium/drivers/r300/r300_blit.h
similarity index 65%
rename from src/gallium/drivers/r300/r300_clear.h
rename to src/gallium/drivers/r300/r300_blit.h
index b8fcdf2..029e4f9 100644
--- a/src/gallium/drivers/r300/r300_clear.h
+++ b/src/gallium/drivers/r300/r300_blit.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2008 Marek Olšák <maraeo@gmail.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -20,10 +20,11 @@
  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
 
-#ifndef R300_CLEAR_H
-#define R300_CLEAR_H
+#ifndef R300_BLIT_H
+#define R300_BLIT_H
 
 struct pipe_context;
+struct pipe_surface;
 
 void r300_clear(struct pipe_context* pipe,
                 unsigned buffers,
@@ -31,4 +32,17 @@
                 double depth,
                 unsigned stencil);
 
-#endif /* R300_CLEAR_H */
+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);
+
+void r300_surface_fill(struct pipe_context* pipe,
+                       struct pipe_surface* dst,
+                       unsigned dstx, unsigned dsty,
+                       unsigned width, unsigned height,
+                       unsigned value);
+
+#endif /* R300_BLIT_H */
diff --git a/src/gallium/drivers/r300/r300_clear.c b/src/gallium/drivers/r300/r300_clear.c
deleted file mode 100644
index 02d6d50..0000000
--- a/src/gallium/drivers/r300/r300_clear.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
- *
- * 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
- * on 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
- * THE AUTHOR(S) AND/OR THEIR 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 "r300_clear.h"
-#include "r300_context.h"
-
-#include "util/u_clear.h"
-
-/* Clears currently bound buffers. */
-void r300_clear(struct pipe_context* pipe,
-                unsigned buffers,
-                const float* rgba,
-                double depth,
-                unsigned stencil)
-{
-    /* XXX we can and should do one clear if both color and zs are set */
-    util_clear(pipe, &r300_context(pipe)->framebuffer_state,
-            buffers, rgba, depth, stencil);
-}
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index f974147..af95bbe 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -28,14 +28,16 @@
 #include "util/u_memory.h"
 #include "util/u_simple_list.h"
 
-#include "r300_clear.h"
+#include "r300_blit.h"
 #include "r300_context.h"
+#include "r300_emit.h"
 #include "r300_flush.h"
 #include "r300_query.h"
 #include "r300_render.h"
 #include "r300_screen.h"
 #include "r300_state_derived.h"
 #include "r300_state_invariant.h"
+#include "r300_texture.h"
 #include "r300_winsys.h"
 
 static enum pipe_error r300_clear_hash_table(void* key, void* value,
@@ -51,6 +53,8 @@
     struct r300_context* r300 = r300_context(context);
     struct r300_query* query, * temp;
 
+    util_blitter_destroy(r300->blitter);
+
     util_hash_table_foreach(r300->shader_hash_table, r300_clear_hash_table,
         NULL);
     util_hash_table_destroy(r300->shader_hash_table);
@@ -66,10 +70,13 @@
         FREE(query);
     }
 
-    FREE(r300->blend_color_state);
+    FREE(r300->blend_color_state.state);
+    FREE(r300->clip_state.state);
     FREE(r300->rs_block);
-    FREE(r300->scissor_state);
-    FREE(r300->viewport_state);
+    FREE(r300->scissor_state.state);
+    FREE(r300->vertex_info);
+    FREE(r300->viewport_state.state);
+    FREE(r300->ztop_state.state);
     FREE(r300);
 }
 
@@ -89,8 +96,11 @@
 r300_is_buffer_referenced(struct pipe_context *pipe,
                           struct pipe_buffer *buf)
 {
-    /* XXX */
-    return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+    /* This only checks to see whether actual hardware buffers are
+     * referenced. Since we use managed BOs and transfers, it's actually not
+     * possible for pipe_buffers to ever reference the actual hardware, so
+     * buffers are never referenced. */
+    return 0;
 }
 
 static void r300_flush_cb(void *data)
@@ -100,17 +110,37 @@
     cs_context_copy->context.flush(&cs_context_copy->context, 0, NULL);
 }
 
+#define R300_INIT_ATOM(name) \
+    r300->name##_state.state = NULL; \
+    r300->name##_state.emit = r300_emit_##name##_state; \
+    r300->name##_state.dirty = FALSE; \
+    insert_at_tail(&r300->atom_list, &r300->name##_state);
+
+static void r300_setup_atoms(struct r300_context* r300)
+{
+    make_empty_list(&r300->atom_list);
+    R300_INIT_ATOM(ztop);
+    R300_INIT_ATOM(blend);
+    R300_INIT_ATOM(blend_color);
+    R300_INIT_ATOM(clip);
+    R300_INIT_ATOM(dsa);
+    R300_INIT_ATOM(rs);
+    R300_INIT_ATOM(scissor);
+    R300_INIT_ATOM(viewport);
+}
+
 struct pipe_context* r300_create_context(struct pipe_screen* screen,
-                                         struct r300_winsys* r300_winsys)
+                                         struct radeon_winsys* radeon_winsys)
 {
     struct r300_context* r300 = CALLOC_STRUCT(r300_context);
+    struct r300_screen* r300screen = r300_screen(screen);
 
     if (!r300)
         return NULL;
 
-    r300->winsys = r300_winsys;
+    r300->winsys = radeon_winsys;
 
-    r300->context.winsys = (struct pipe_winsys*)r300_winsys;
+    r300->context.winsys = (struct pipe_winsys*)radeon_winsys;
     r300->context.screen = screen;
 
     r300_init_debug(r300);
@@ -118,10 +148,28 @@
     r300->context.destroy = r300_destroy_context;
 
     r300->context.clear = r300_clear;
+    r300->context.surface_copy = r300_surface_copy;
+    r300->context.surface_fill = r300_surface_fill;
 
-    r300->context.draw_arrays = r300_draw_arrays;
-    r300->context.draw_elements = r300_draw_elements;
-    r300->context.draw_range_elements = r300_swtcl_draw_range_elements;
+    if (r300screen->caps->has_tcl) {
+        r300->context.draw_arrays = r300_draw_arrays;
+        r300->context.draw_elements = r300_draw_elements;
+        r300->context.draw_range_elements = r300_draw_range_elements;
+    } else {
+        r300->context.draw_arrays = r300_swtcl_draw_arrays;
+        r300->context.draw_elements = r300_draw_elements;
+        r300->context.draw_range_elements = r300_swtcl_draw_range_elements;
+
+        /* Create a Draw. This is used for SW TCL. */
+        r300->draw = draw_create();
+        /* Enable our renderer. */
+        draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300));
+        /* Enable Draw's clipping. */
+        draw_set_driver_clipping(r300->draw, FALSE);
+        /* Force Draw to never do viewport transform, since we can do
+         * transform in hardware, always. */
+        draw_set_viewport_state(r300->draw, &r300_viewport_identity);
+    }
 
     r300->context.is_texture_referenced = r300_is_texture_referenced;
     r300->context.is_buffer_referenced = r300_is_buffer_referenced;
@@ -129,24 +177,20 @@
     r300->shader_hash_table = util_hash_table_create(r300_shader_key_hash,
         r300_shader_key_compare);
 
-    r300->blend_color_state = CALLOC_STRUCT(r300_blend_color_state);
-    r300->rs_block = CALLOC_STRUCT(r300_rs_block);
-    r300->scissor_state = CALLOC_STRUCT(r300_scissor_state);
-    r300->viewport_state = CALLOC_STRUCT(r300_viewport_state);
+    r300_setup_atoms(r300);
 
-    /* Create a Draw. This is used for vert collation and SW TCL. */
-    r300->draw = draw_create();
-    /* Enable our renderer. */
-    draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300));
-    /* Disable Draw's clipping if TCL is present. */
-    draw_set_driver_clipping(r300->draw, r300_screen(screen)->caps->has_tcl);
-    /* Force Draw to never do viewport transform, since (again) we can do
-     * transform in hardware, always. */
-    draw_set_viewport_state(r300->draw, &r300_viewport_identity);
+    r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state);
+    r300->clip_state.state = CALLOC_STRUCT(pipe_clip_state);
+    r300->rs_block = CALLOC_STRUCT(r300_rs_block);
+    r300->scissor_state.state = CALLOC_STRUCT(r300_scissor_state);
+    r300->vertex_info = CALLOC_STRUCT(r300_vertex_info);
+    r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state);
+    r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state);
 
     /* Open up the OQ BO. */
     r300->oqbo = screen->buffer_create(screen, 4096,
             PIPE_BUFFER_USAGE_VERTEX, 4096);
+    make_empty_list(&r300->query_list);
 
     r300_init_flush_functions(r300);
 
@@ -161,6 +205,8 @@
     r300->winsys->set_flush_cb(r300->winsys, r300_flush_cb, r300);
     r300->dirty_state = R300_NEW_KITCHEN_SINK;
     r300->dirty_hw++;
-    make_empty_list(&r300->query_list);
+
+    r300->blitter = util_blitter_create(&r300->context);
+
     return &r300->context;
 }
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 850e5a4..5937f0e 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -25,12 +25,23 @@
 
 #include "draw/draw_vertex.h"
 
+#include "util/u_blitter.h"
+
 #include "pipe/p_context.h"
 #include "pipe/p_inlines.h"
 
+struct r300_context;
+
 struct r300_fragment_shader;
 struct r300_vertex_shader;
 
+struct r300_atom {
+    struct r300_atom *prev, *next;
+    void* state;
+    void (*emit)(struct r300_context*, void*);
+    boolean dirty;
+};
+
 struct r300_blend_state {
     uint32_t blend_control;       /* R300_RB3D_CBLEND: 0x4e04 */
     uint32_t alpha_blend_control; /* R300_RB3D_ABLEND: 0x4e08 */
@@ -60,11 +71,6 @@
     /* Draw-specific rasterizer state */
     struct pipe_rasterizer_state rs;
 
-    /* Whether or not to enable the VTE. This is referenced at the very
-     * last moment during emission of VTE state, to decide whether or not
-     * the VTE should be used for transformation. */
-    boolean enable_vte;
-
     uint32_t vap_control_status;    /* R300_VAP_CNTL_STATUS: 0x2140 */
     uint32_t point_size;            /* R300_GA_POINT_SIZE: 0x421c */
     uint32_t point_minmax;          /* R300_GA_POINT_MINMAX: 0x4230 */
@@ -89,14 +95,25 @@
 };
 
 struct r300_sampler_state {
+    struct pipe_sampler_state state;
+
     uint32_t filter0;      /* R300_TX_FILTER0: 0x4400 */
     uint32_t filter1;      /* R300_TX_FILTER1: 0x4440 */
     uint32_t border_color; /* R300_TX_BORDER_COLOR: 0x45c0 */
+
+    /* Min/max LOD must be clamped to [0, last_level], thus
+     * it's dependent on a currently bound texture */
+    unsigned min_lod, max_lod;
+};
+
+struct r300_scissor_regs {
+    uint32_t top_left;     /* R300_SC_SCISSORS_TL: 0x43e0 */
+    uint32_t bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */
 };
 
 struct r300_scissor_state {
-    uint32_t scissor_top_left;     /* R300_SC_SCISSORS_TL: 0x43e0 */
-    uint32_t scissor_bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */
+    struct r300_scissor_regs framebuffer;
+    struct r300_scissor_regs scissor;
 };
 
 struct r300_texture_state {
@@ -119,24 +136,17 @@
     uint32_t z_buffer_top;      /* R300_ZB_ZTOP: 0x4f14 */
 };
 
-#define R300_NEW_BLEND           0x00000001
-#define R300_NEW_BLEND_COLOR     0x00000002
-#define R300_NEW_CLIP            0x00000004
-#define R300_NEW_DSA             0x00000008
 #define R300_NEW_FRAMEBUFFERS    0x00000010
 #define R300_NEW_FRAGMENT_SHADER 0x00000020
 #define R300_NEW_FRAGMENT_SHADER_CONSTANTS    0x00000040
-#define R300_NEW_RASTERIZER      0x00000080
 #define R300_NEW_RS_BLOCK        0x00000100
 #define R300_NEW_SAMPLER         0x00000200
 #define R300_ANY_NEW_SAMPLERS    0x0001fe00
-#define R300_NEW_SCISSOR         0x00020000
 #define R300_NEW_TEXTURE         0x00040000
 #define R300_ANY_NEW_TEXTURES    0x03fc0000
 #define R300_NEW_VERTEX_FORMAT   0x04000000
 #define R300_NEW_VERTEX_SHADER   0x08000000
 #define R300_NEW_VERTEX_SHADER_CONSTANTS    0x10000000
-#define R300_NEW_VIEWPORT        0x20000000
 #define R300_NEW_QUERY           0x40000000
 #define R300_NEW_KITCHEN_SINK    0x7fffffff
 
@@ -216,18 +226,14 @@
     struct r300_texture_state state;
 };
 
-struct r300_vertex_format {
+struct r300_vertex_info {
     /* Parent class */
     struct vertex_info vinfo;
+
     /* R300_VAP_PROG_STREAK_CNTL_[0-7] */
     uint32_t vap_prog_stream_cntl[8];
     /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
     uint32_t vap_prog_stream_cntl_ext[8];
-    /* Map of vertex attributes into PVS memory for HW TCL,
-     * or GA memory for SW TCL. */
-    int vs_tab[16];
-    /* Map of rasterizer attributes from GB through RS to US. */
-    int fs_tab[16];
 };
 
 extern struct pipe_viewport_state r300_viewport_identity;
@@ -237,9 +243,11 @@
     struct pipe_context context;
 
     /* The interface to the windowing system, etc. */
-    struct r300_winsys* winsys;
+    struct radeon_winsys* winsys;
     /* Draw module. Used mostly for SW TCL. */
     struct draw_context* draw;
+    /* Accelerated blit support. */
+    struct blitter_context* blitter;
 
     /* Vertex buffer for rendering. */
     struct pipe_buffer* vbo;
@@ -256,52 +264,57 @@
      * depends on the combination of both currently loaded shaders. */
     struct util_hash_table* shader_hash_table;
     /* Vertex formatting information. */
-    struct r300_vertex_format* vertex_info;
+    struct r300_vertex_info* vertex_info;
 
     /* Various CSO state objects. */
+    /* Beginning of atom list. */
+    struct r300_atom atom_list;
     /* Blend state. */
-    struct r300_blend_state* blend_state;
+    struct r300_atom blend_state;
     /* Blend color state. */
-    struct r300_blend_color_state* blend_color_state;
+    struct r300_atom blend_color_state;
     /* User clip planes. */
-    struct pipe_clip_state clip_state;
+    struct r300_atom clip_state;
     /* Shader constants. */
     struct r300_constant_buffer shader_constants[PIPE_SHADER_TYPES];
     /* Depth, stencil, and alpha state. */
-    struct r300_dsa_state* dsa_state;
+    struct r300_atom dsa_state;
     /* Fragment shader. */
     struct r300_fragment_shader* fs;
     /* Framebuffer state. We currently don't need our own version of this. */
     struct pipe_framebuffer_state framebuffer_state;
     /* Rasterizer state. */
-    struct r300_rs_state* rs_state;
+    struct r300_atom rs_state;
     /* RS block state. */
     struct r300_rs_block* rs_block;
     /* Sampler states. */
     struct r300_sampler_state* sampler_states[8];
     int sampler_count;
     /* Scissor state. */
-    struct r300_scissor_state* scissor_state;
+    struct r300_atom scissor_state;
     /* Texture states. */
     struct r300_texture* textures[8];
     int texture_count;
-    /* Vertex buffers for Gallium. */
-    struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
-    int vertex_buffer_count;
-    /* Vertex elements for Gallium. */
-    struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS];
-    int vertex_element_count;
     /* Vertex shader. */
     struct r300_vertex_shader* vs;
     /* Viewport state. */
-    struct r300_viewport_state* viewport_state;
+    struct r300_atom viewport_state;
     /* ZTOP state. */
-    struct r300_ztop_state ztop_state;
+    struct r300_atom ztop_state;
+
+    /* Vertex buffers for Gallium. */
+    struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+    int vertex_buffer_count;
+    /* Vertex elements for Gallium. */
+    struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
+    int vertex_element_count;
 
     /* Bitmask of dirty state objects. */
     uint32_t dirty_state;
     /* Flag indicating whether or not the HW is dirty. */
     uint32_t dirty_hw;
+    /* Whether the TCL engine should be in bypass mode. */
+    boolean tcl_bypass;
 
     /** Combination of DBG_xxx flags */
     unsigned debug;
diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h
index 883f0a0..d142fee 100644
--- a/src/gallium/drivers/r300/r300_cs.h
+++ b/src/gallium/drivers/r300/r300_cs.h
@@ -26,7 +26,8 @@
 #include "util/u_math.h"
 
 #include "r300_reg.h"
-#include "r300_winsys.h"
+
+#include "radeon_winsys.h"
 
 /* Yes, I know macros are ugly. However, they are much prettier than the code
  * that they neatly hide away, and don't have the cost of function setup,so
@@ -34,8 +35,8 @@
 
 #define MAX_CS_SIZE 64 * 1024 / 4
 
-#define VERY_VERBOSE_CS 0
-#define VERY_VERBOSE_REGISTERS 0
+#define VERY_VERBOSE_CS 1
+#define VERY_VERBOSE_REGISTERS 1
 
 /* XXX stolen from radeon_drm.h */
 #define RADEON_GEM_DOMAIN_CPU  0x1
@@ -50,11 +51,11 @@
 
 #define CS_LOCALS(context) \
     struct r300_context* const cs_context_copy = (context); \
-    struct r300_winsys* cs_winsys = cs_context_copy->winsys; \
+    struct radeon_winsys* cs_winsys = cs_context_copy->winsys; \
     int cs_count = 0;
 
 #define CHECK_CS(size) \
-    cs_winsys->check_cs(cs_winsys, (size))
+    assert(cs_winsys->check_cs(cs_winsys, (size)))
 
 #define BEGIN_CS(size) do { \
     CHECK_CS(size); \
@@ -114,6 +115,15 @@
     cs_count -= 3; \
 } while (0)
 
+#define OUT_CS_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \
+    DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, " \
+            "domains (%d, %d, %d)\n", \
+        bo, rd, wd, flags); \
+    assert(bo); \
+    cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \
+    cs_count -= 2; \
+} while (0)
+
 #define END_CS do { \
     if (VERY_VERBOSE_CS) { \
         DBG(cs_context_copy, DBG_CS, "r300: END_CS in %s (%s:%d)\n", __FUNCTION__, \
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 69ce596..0e5533c 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -1,5 +1,6 @@
 /*
  * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -22,7 +23,9 @@
 
 /* r300_emit: Functions for emitting state. */
 
+#include "util/u_format.h"
 #include "util/u_math.h"
+#include "util/u_simple_list.h"
 
 #include "r300_context.h"
 #include "r300_cs.h"
@@ -34,23 +37,30 @@
 #include "r300_texture.h"
 #include "r300_vs.h"
 
-void r300_emit_blend_state(struct r300_context* r300,
-                           struct r300_blend_state* blend)
+void r300_emit_blend_state(struct r300_context* r300, void* state)
 {
+    struct r300_blend_state* blend = (struct r300_blend_state*)state;
     CS_LOCALS(r300);
     BEGIN_CS(8);
-    OUT_CS_REG_SEQ(R300_RB3D_CBLEND, 3);
-    OUT_CS(blend->blend_control);
-    OUT_CS(blend->alpha_blend_control);
-    OUT_CS(blend->color_channel_mask);
     OUT_CS_REG(R300_RB3D_ROPCNTL, blend->rop);
+    OUT_CS_REG_SEQ(R300_RB3D_CBLEND, 3);
+    if (r300->framebuffer_state.nr_cbufs) {
+        OUT_CS(blend->blend_control);
+        OUT_CS(blend->alpha_blend_control);
+        OUT_CS(blend->color_channel_mask);
+    } else {
+        OUT_CS(0);
+        OUT_CS(0);
+        OUT_CS(0);
+        /* XXX also disable fastfill here once it's supported */
+    }
     OUT_CS_REG(R300_RB3D_DITHER_CTL, blend->dither);
     END_CS;
 }
 
-void r300_emit_blend_color_state(struct r300_context* r300,
-                                 struct r300_blend_color_state* bc)
+void r300_emit_blend_color_state(struct r300_context* r300, void* state)
 {
+    struct r300_blend_color_state* bc = (struct r300_blend_color_state*)state;
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
     CS_LOCALS(r300);
 
@@ -67,9 +77,9 @@
     }
 }
 
-void r300_emit_clip_state(struct r300_context* r300,
-                          struct pipe_clip_state* clip)
+void r300_emit_clip_state(struct r300_context* r300, void* state)
 {
+    struct pipe_clip_state* clip = (struct pipe_clip_state*)state;
     int i;
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
     CS_LOCALS(r300);
@@ -97,13 +107,13 @@
 
 }
 
-void r300_emit_dsa_state(struct r300_context* r300,
-                           struct r300_dsa_state* dsa)
+void r300_emit_dsa_state(struct r300_context* r300, void* state)
 {
+    struct r300_dsa_state* dsa = (struct r300_dsa_state*)state;
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
     CS_LOCALS(r300);
 
-    BEGIN_CS(r300screen->caps->is_r500 ? 10 : 8);
+    BEGIN_CS(r300screen->caps->is_r500 ? 8 : 6);
     OUT_CS_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function);
 
     /* not needed since we use the 8bit alpha ref */
@@ -112,10 +122,16 @@
     }*/
 
     OUT_CS_REG_SEQ(R300_ZB_CNTL, 3);
-    OUT_CS(dsa->z_buffer_control);
-    OUT_CS(dsa->z_stencil_control);
+
+    if (r300->framebuffer_state.zsbuf) {
+        OUT_CS(dsa->z_buffer_control);
+        OUT_CS(dsa->z_stencil_control);
+    } else {
+        OUT_CS(0);
+        OUT_CS(0);
+    }
+
     OUT_CS(dsa->stencil_ref_mask);
-    OUT_CS_REG(R300_ZB_ZTOP, r300->ztop_state.z_buffer_top);
 
     /* XXX it seems r3xx doesn't support STENCILREFMASK_BF */
     if (r300screen->caps->is_r500) {
@@ -129,7 +145,11 @@
     struct rc_constant * constant,
     struct r300_constant_buffer * externals)
 {
-    static const float zero[4] = { 0.0, 0.0, 0.0, 0.0 };
+    struct r300_viewport_state* viewport =
+        (struct r300_viewport_state*)r300->viewport_state.state;
+    static float vec[4] = { 0.0, 0.0, 0.0, 1.0 };
+    struct pipe_texture *tex;
+
     switch(constant->Type) {
         case RC_CONSTANT_EXTERNAL:
             return externals->constants[constant->u.External];
@@ -137,11 +157,58 @@
         case RC_CONSTANT_IMMEDIATE:
             return constant->u.Immediate;
 
+        case RC_CONSTANT_STATE:
+            switch (constant->u.State[0]) {
+                /* Factor for converting rectangle coords to
+                 * normalized coords. Should only show up on non-r500. */
+                case RC_STATE_R300_TEXRECT_FACTOR:
+                    tex = &r300->textures[constant->u.State[1]]->tex;
+                    vec[0] = 1.0 / tex->width0;
+                    vec[1] = 1.0 / tex->height0;
+                    break;
+
+                /* Texture compare-fail value. */
+                /* XXX Since Gallium doesn't support GL_ARB_shadow_ambient,
+                 * this is always (0,0,0,0), right? */
+                case RC_STATE_SHADOW_AMBIENT:
+                    vec[3] = 0;
+                    break;
+
+                case RC_STATE_R300_VIEWPORT_SCALE:
+                    if (r300->tcl_bypass) {
+                        vec[0] = 1;
+                        vec[1] = 1;
+                        vec[2] = 1;
+                    } else {
+                        vec[0] = viewport->xscale;
+                        vec[1] = viewport->yscale;
+                        vec[2] = viewport->zscale;
+                    }
+                    break;
+
+                case RC_STATE_R300_VIEWPORT_OFFSET:
+                    if (!r300->tcl_bypass) {
+                        vec[0] = viewport->xoffset;
+                        vec[1] = viewport->yoffset;
+                        vec[2] = viewport->zoffset;
+                    }
+                    break;
+
+                default:
+                    debug_printf("r300: Implementation error: "
+                        "Unknown RC_CONSTANT type %d\n", constant->u.State[0]);
+            }
+            break;
+
         default:
-            debug_printf("r300: Implementation error: Unhandled constant type %i\n",
-                constant->Type);
-            return zero;
+            debug_printf("r300: Implementation error: "
+                "Unhandled constant type %d\n", constant->Type);
     }
+
+    /* This should either be (0, 0, 0, 1), which should be a relatively safe
+     * RGBA or STRQ value, or it could be one of the RC_CONSTANT_STATE
+     * state factors. */
+    return vec;
 }
 
 /* Convert a normal single-precision float into the 7.16 format
@@ -245,6 +312,22 @@
     END_CS;
 }
 
+static void r300_emit_fragment_depth_config(struct r300_context* r300,
+                                            struct r300_fragment_shader* fs)
+{
+    CS_LOCALS(r300);
+
+    BEGIN_CS(4);
+    if (r300_fragment_shader_writes_depth(fs)) {
+        OUT_CS_REG(R300_FG_DEPTH_SRC, R300_FG_DEPTH_SRC_SHADER);
+        OUT_CS_REG(R300_US_W_FMT, R300_W_FMT_W24 | R300_W_SRC_US);
+    } else {
+        OUT_CS_REG(R300_FG_DEPTH_SRC, R300_FG_DEPTH_SRC_SCAN);
+        OUT_CS_REG(R300_US_W_FMT, R300_W_FMT_W0 | R300_W_SRC_US);
+    }
+    END_CS;
+}
+
 void r500_emit_fragment_program_code(struct r300_context* r300,
                                      struct rX00_fragment_program_code* generic_code)
 {
@@ -254,7 +337,7 @@
 
     BEGIN_CS(13 +
              ((code->inst_end + 1) * 6));
-    OUT_CS_REG(R500_US_CONFIG, 0);
+    OUT_CS_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
     OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx);
     OUT_CS_REG(R500_US_CODE_RANGE,
                R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(code->inst_end));
@@ -308,7 +391,13 @@
     int i;
     CS_LOCALS(r300);
 
-    BEGIN_CS((10 * fb->nr_cbufs) + (fb->zsbuf ? 10 : 0) + 4);
+    /* Shouldn't fail unless there is a bug in the state tracker. */
+    assert(fb->nr_cbufs <= 4);
+
+    BEGIN_CS((10 * fb->nr_cbufs) + (2 * (4 - fb->nr_cbufs)) +
+             (fb->zsbuf ? 10 : 0) + 6);
+
+    /* Flush and free renderbuffer caches. */
     OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT,
         R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS |
         R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D);
@@ -316,6 +405,10 @@
         R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
         R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
 
+    /* Set the number of colorbuffers. */
+    OUT_CS_REG(R300_RB3D_CCTL, R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs));
+
+    /* Set up colorbuffers. */
     for (i = 0; i < fb->nr_cbufs; i++) {
         surf = fb->cbufs[i];
         tex = (struct r300_texture*)surf->texture;
@@ -333,6 +426,12 @@
             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;
         tex = (struct r300_texture*)surf->texture;
@@ -360,8 +459,6 @@
     if (!query)
 	return;
 
-    /* XXX This will almost certainly not return good results
-     * for overlapping queries. */
     BEGIN_CS(4);
     if (caps->family == CHIP_FAMILY_RV530) {
         OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
@@ -479,8 +576,9 @@
         r300_emit_query_finish(r300, query);
 }
 
-void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs)
+void r300_emit_rs_state(struct r300_context* r300, void* state)
 {
+    struct r300_rs_state* rs = (struct r300_rs_state*)state;
     CS_LOCALS(r300);
 
     BEGIN_CS(22);
@@ -510,6 +608,8 @@
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
     CS_LOCALS(r300);
 
+    DBG(r300, DBG_DRAW, "r300: RS emit:\n");
+
     BEGIN_CS(21);
     if (r300screen->caps->is_r500) {
         OUT_CS_REG_SEQ(R500_RS_IP_0, 8);
@@ -518,7 +618,7 @@
     }
     for (i = 0; i < 8; i++) {
         OUT_CS(rs->ip[i]);
-        /* debug_printf("ip %d: 0x%08x\n", i, rs->ip[i]); */
+        DBG(r300, DBG_DRAW, "    : ip %d: 0x%08x\n", i, rs->ip[i]);
     }
 
     OUT_CS_REG_SEQ(R300_RS_COUNT, 2);
@@ -532,33 +632,46 @@
     }
     for (i = 0; i < 8; i++) {
         OUT_CS(rs->inst[i]);
-        /* debug_printf("inst %d: 0x%08x\n", i, rs->inst[i]); */
+        DBG(r300, DBG_DRAW, "    : inst %d: 0x%08x\n", i, rs->inst[i]);
     }
 
-    /* debug_printf("count: 0x%08x inst_count: 0x%08x\n", rs->count,
-     *        rs->inst_count); */
+    DBG(r300, DBG_DRAW, "    : count: 0x%08x inst_count: 0x%08x\n",
+        rs->count, rs->inst_count);
 
     END_CS;
 }
 
-void r300_emit_scissor_state(struct r300_context* r300,
-                             struct r300_scissor_state* scissor)
+static void r300_emit_scissor_regs(struct r300_context* r300,
+                                   struct r300_scissor_regs* scissor)
 {
     CS_LOCALS(r300);
 
     BEGIN_CS(3);
     OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2);
-    OUT_CS(scissor->scissor_top_left);
-    OUT_CS(scissor->scissor_bottom_right);
+    OUT_CS(scissor->top_left);
+    OUT_CS(scissor->bottom_right);
     END_CS;
 }
 
+void r300_emit_scissor_state(struct r300_context* r300, void* state)
+{
+    struct r300_scissor_state* scissor = (struct r300_scissor_state*)state;
+    /* XXX argfl! */
+    if (((struct r300_rs_state*)r300->rs_state.state)->rs.scissor) {
+        r300_emit_scissor_regs(r300, &scissor->scissor);
+    } else {
+        r300_emit_scissor_regs(r300, &scissor->framebuffer);
+    }
+}
+
 void r300_emit_texture(struct r300_context* r300,
                        struct r300_sampler_state* sampler,
                        struct r300_texture* tex,
                        unsigned offset)
 {
     uint32_t filter0 = sampler->filter0;
+    uint32_t format0 = tex->state.format0;
+    unsigned min_level, max_level;
     CS_LOCALS(r300);
 
     /* to emulate 1D textures through 2D ones correctly */
@@ -567,13 +680,20 @@
         filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE);
     }
 
+    /* determine min/max levels */
+    /* the MAX_MIP level is the largest (finest) one */
+    max_level = MIN2(sampler->max_lod, tex->tex.last_level);
+    min_level = MIN2(sampler->min_lod, max_level);
+    format0 |= R300_TX_NUM_LEVELS(max_level);
+    filter0 |= R300_TX_MAX_MIP_LEVEL(min_level);
+
     BEGIN_CS(16);
     OUT_CS_REG(R300_TX_FILTER0_0 + (offset * 4), filter0 |
         (offset << 28));
     OUT_CS_REG(R300_TX_FILTER1_0 + (offset * 4), sampler->filter1);
     OUT_CS_REG(R300_TX_BORDER_COLOR_0 + (offset * 4), sampler->border_color);
 
-    OUT_CS_REG(R300_TX_FORMAT0_0 + (offset * 4), tex->state.format0);
+    OUT_CS_REG(R300_TX_FORMAT0_0 + (offset * 4), format0);
     OUT_CS_REG(R300_TX_FORMAT1_0 + (offset * 4), tex->state.format1);
     OUT_CS_REG(R300_TX_FORMAT2_0 + (offset * 4), tex->state.format2);
     OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (offset * 4), 1);
@@ -582,7 +702,70 @@
     END_CS;
 }
 
-void r300_emit_vertex_buffer(struct r300_context* r300)
+static boolean r300_validate_aos(struct r300_context *r300)
+{
+    struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
+    struct pipe_vertex_element *velem = r300->vertex_element;
+    int i;
+
+    /* Check if formats and strides are aligned to the size of DWORD. */
+    for (i = 0; i < r300->vertex_element_count; i++) {
+        if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 ||
+            util_format_get_blocksize(velem[i].src_format) % 4 != 0) {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+void r300_emit_aos(struct r300_context* r300, unsigned offset)
+{
+    struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer;
+    struct pipe_vertex_element *velem = r300->vertex_element;
+    int i;
+    unsigned size1, size2, aos_count = r300->vertex_element_count;
+    unsigned packet_size = (aos_count * 3 + 1) / 2;
+    CS_LOCALS(r300);
+
+    /* XXX Move this checking to a more approriate place. */
+    if (!r300_validate_aos(r300)) {
+        /* XXX We should fallback using Draw. */
+        assert(0);
+    }
+
+    BEGIN_CS(2 + packet_size + aos_count * 2);
+    OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
+    OUT_CS(aos_count);
+
+    for (i = 0; i < aos_count - 1; i += 2) {
+        vb1 = &vbuf[velem[i].vertex_buffer_index];
+        vb2 = &vbuf[velem[i+1].vertex_buffer_index];
+        size1 = util_format_get_blocksize(velem[i].src_format);
+        size2 = util_format_get_blocksize(velem[i+1].src_format);
+
+        OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) |
+               R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(vb2->stride));
+        OUT_CS(vb1->buffer_offset + velem[i].src_offset   + offset * vb1->stride);
+        OUT_CS(vb2->buffer_offset + velem[i+1].src_offset + offset * vb2->stride);
+    }
+
+    if (aos_count & 1) {
+        vb1 = &vbuf[velem[i].vertex_buffer_index];
+        size1 = util_format_get_blocksize(velem[i].src_format);
+
+        OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride));
+        OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride);
+    }
+
+    for (i = 0; i < aos_count; i++) {
+        OUT_CS_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer,
+                               RADEON_GEM_DOMAIN_GTT, 0, 0);
+    }
+    END_CS;
+}
+
+#if 0
+void r300_emit_draw_packet(struct r300_context* r300)
 {
     CS_LOCALS(r300);
 
@@ -605,12 +788,15 @@
     OUT_CS_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
     END_CS;
 }
+#endif
 
 void r300_emit_vertex_format_state(struct r300_context* r300)
 {
     int i;
     CS_LOCALS(r300);
 
+    DBG(r300, DBG_DRAW, "r300: VAP/PSC emit:\n");
+
     BEGIN_CS(26);
     OUT_CS_REG(R300_VAP_VTX_SIZE, r300->vertex_info->vinfo.size);
 
@@ -620,32 +806,42 @@
     OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
     OUT_CS(r300->vertex_info->vinfo.hwfmt[2]);
     OUT_CS(r300->vertex_info->vinfo.hwfmt[3]);
-    /* for (i = 0; i < 4; i++) {
-     *    debug_printf("hwfmt%d: 0x%08x\n", i,
-     *            r300->vertex_info->vinfo.hwfmt[i]);
-     * } */
+    for (i = 0; i < 4; i++) {
+       DBG(r300, DBG_DRAW, "    : hwfmt%d: 0x%08x\n", i,
+               r300->vertex_info->vinfo.hwfmt[i]);
+    }
 
     OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, 8);
     for (i = 0; i < 8; i++) {
         OUT_CS(r300->vertex_info->vap_prog_stream_cntl[i]);
-        /* debug_printf("prog_stream_cntl%d: 0x%08x\n", i,
-         *        r300->vertex_info->vap_prog_stream_cntl[i]); */
+        DBG(r300, DBG_DRAW, "    : prog_stream_cntl%d: 0x%08x\n", i,
+               r300->vertex_info->vap_prog_stream_cntl[i]);
     }
     OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, 8);
     for (i = 0; i < 8; i++) {
         OUT_CS(r300->vertex_info->vap_prog_stream_cntl_ext[i]);
-        /* debug_printf("prog_stream_cntl_ext%d: 0x%08x\n", i,
-         *        r300->vertex_info->vap_prog_stream_cntl_ext[i]); */
+        DBG(r300, DBG_DRAW, "    : prog_stream_cntl_ext%d: 0x%08x\n", i,
+               r300->vertex_info->vap_prog_stream_cntl_ext[i]);
     }
     END_CS;
 }
 
+
 void r300_emit_vertex_program_code(struct r300_context* r300,
                                    struct r300_vertex_program_code* code)
 {
     int i;
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
     unsigned instruction_count = code->length / 4;
+
+    int vtx_mem_size = r300screen->caps->is_r500 ? 128 : 72;
+    int input_count = MAX2(util_bitcount(code->InputsRead), 1);
+    int output_count = MAX2(util_bitcount(code->OutputsWritten), 1);
+    int temp_count = MAX2(code->num_temporaries, 1);
+    int pvs_num_slots = MIN3(vtx_mem_size / input_count,
+                             vtx_mem_size / output_count, 10);
+    int pvs_num_controllers = MIN2(vtx_mem_size / temp_count, 6);
+
     CS_LOCALS(r300);
 
     if (!r300screen->caps->has_tcl) {
@@ -658,8 +854,7 @@
     /* R300_VAP_PVS_CODE_CNTL_0
      * R300_VAP_PVS_CONST_CNTL
      * R300_VAP_PVS_CODE_CNTL_1
-     * See the r5xx docs for instructions on how to use these.
-     * XXX these could be optimized to select better values... */
+     * See the r5xx docs for instructions on how to use these. */
     OUT_CS_REG_SEQ(R300_VAP_PVS_CODE_CNTL_0, 3);
     OUT_CS(R300_PVS_FIRST_INST(0) |
             R300_PVS_XYZW_VALID_INST(instruction_count - 1) |
@@ -672,10 +867,11 @@
     for (i = 0; i < code->length; i++)
         OUT_CS(code->body.d[i]);
 
-    OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(10) |
-            R300_PVS_NUM_CNTLRS(5) |
+    OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(pvs_num_slots) |
+            R300_PVS_NUM_CNTLRS(pvs_num_controllers) |
             R300_PVS_NUM_FPUS(r300screen->caps->num_vert_fpus) |
-            R300_PVS_VF_MAX_VTX_NUM(12));
+            R300_PVS_VF_MAX_VTX_NUM(12) |
+            (r300screen->caps->is_r500 ? R500_TCL_STATE_OPTIMIZATION : 0));
     END_CS;
 }
 
@@ -718,25 +914,57 @@
     END_CS;
 }
 
-void r300_emit_viewport_state(struct r300_context* r300,
-                              struct r300_viewport_state* viewport)
+void r300_emit_viewport_state(struct r300_context* r300, void* state)
 {
+    struct r300_viewport_state* viewport = (struct r300_viewport_state*)state;
     CS_LOCALS(r300);
 
-    BEGIN_CS(9);
-    OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6);
-    OUT_CS_32F(viewport->xscale);
-    OUT_CS_32F(viewport->xoffset);
-    OUT_CS_32F(viewport->yscale);
-    OUT_CS_32F(viewport->yoffset);
-    OUT_CS_32F(viewport->zscale);
-    OUT_CS_32F(viewport->zoffset);
-
-    if (r300->rs_state->enable_vte) {
-        OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control);
-    } else {
+    if (r300->tcl_bypass) {
+        BEGIN_CS(2);
         OUT_CS_REG(R300_VAP_VTE_CNTL, 0);
+        END_CS;
+    } else {
+        BEGIN_CS(9);
+        OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6);
+        OUT_CS_32F(viewport->xscale);
+        OUT_CS_32F(viewport->xoffset);
+        OUT_CS_32F(viewport->yscale);
+        OUT_CS_32F(viewport->yoffset);
+        OUT_CS_32F(viewport->zscale);
+        OUT_CS_32F(viewport->zoffset);
+        OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control);
+        END_CS;
     }
+}
+
+void r300_emit_texture_count(struct r300_context* r300)
+{
+    uint32_t tx_enable = 0;
+    int i;
+    CS_LOCALS(r300);
+
+    /* Notice that texture_count and sampler_count are just sizes
+     * of the respective arrays. We still have to check for the individual
+     * elements. */
+    for (i = 0; i < MIN2(r300->sampler_count, r300->texture_count); i++) {
+        if (r300->textures[i]) {
+            tx_enable |= 1 << i;
+        }
+    }
+
+    BEGIN_CS(2);
+    OUT_CS_REG(R300_TX_ENABLE, tx_enable);
+    END_CS;
+
+}
+
+void r300_emit_ztop_state(struct r300_context* r300, void* state)
+{
+    struct r300_ztop_state* ztop = (struct r300_ztop_state*)state;
+    CS_LOCALS(r300);
+
+    BEGIN_CS(2);
+    OUT_CS_REG(R300_ZB_ZTOP, ztop->z_buffer_top);
     END_CS;
 }
 
@@ -744,9 +972,8 @@
 {
     CS_LOCALS(r300);
 
-    BEGIN_CS(4);
+    BEGIN_CS(2);
     OUT_CS_REG(R300_TX_INVALTAGS, 0);
-    OUT_CS_REG(R300_TX_ENABLE, (1 << r300->texture_count) - 1);
     END_CS;
 }
 
@@ -764,19 +991,21 @@
 {
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
     struct r300_texture* tex;
+    struct r300_atom* atom;
     int i, dirty_tex = 0;
     boolean invalid = FALSE;
 
-    if (!(r300->dirty_state)) {
-        return;
+    /* Check size of CS. */
+    /* Make sure we have at least 8*1024 spare dwords. */
+    /* XXX It would be nice to know the number of dwords we really need to
+     * XXX emit. */
+    if (!r300->winsys->check_cs(r300->winsys, 8*1024)) {
+        r300->context.flush(&r300->context, 0, NULL);
     }
 
-    r300_update_derived_state(r300);
-
     /* Clean out BOs. */
     r300->winsys->reset_bos(r300->winsys);
 
-    /* XXX check size */
 validate:
     /* Color buffers... */
     for (i = 0; i < r300->framebuffer_state.nr_cbufs; i++) {
@@ -823,7 +1052,7 @@
             goto validate;
         }
     } else {
-        debug_printf("No VBO while emitting dirty state!\n");
+        /* debug_printf("No VBO while emitting dirty state!\n"); */
     }
     if (!r300->winsys->validate(r300->winsys)) {
         r300->context.flush(&r300->context, 0, NULL);
@@ -841,40 +1070,30 @@
         r300->dirty_state &= ~R300_NEW_QUERY;
     }
 
-    if (r300->dirty_state & R300_NEW_BLEND) {
-        r300_emit_blend_state(r300, r300->blend_state);
-        r300->dirty_state &= ~R300_NEW_BLEND;
-    }
-
-    if (r300->dirty_state & R300_NEW_BLEND_COLOR) {
-        r300_emit_blend_color_state(r300, r300->blend_color_state);
-        r300->dirty_state &= ~R300_NEW_BLEND_COLOR;
-    }
-
-    if (r300->dirty_state & R300_NEW_CLIP) {
-        r300_emit_clip_state(r300, &r300->clip_state);
-        r300->dirty_state &= ~R300_NEW_CLIP;
-    }
-
-    if (r300->dirty_state & R300_NEW_DSA) {
-        r300_emit_dsa_state(r300, r300->dsa_state);
-        r300->dirty_state &= ~R300_NEW_DSA;
+    foreach(atom, &r300->atom_list) {
+        if (atom->dirty) {
+            atom->emit(r300, atom->state);
+            atom->dirty = FALSE;
+        }
     }
 
     if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) {
+        r300_emit_fragment_depth_config(r300, r300->fs);
         if (r300screen->caps->is_r500) {
-            r500_emit_fragment_program_code(r300, &r300->fs->code);
+            r500_emit_fragment_program_code(r300, &r300->fs->shader->code);
         } else {
-            r300_emit_fragment_program_code(r300, &r300->fs->code);
+            r300_emit_fragment_program_code(r300, &r300->fs->shader->code);
         }
         r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER;
     }
 
     if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER_CONSTANTS) {
         if (r300screen->caps->is_r500) {
-            r500_emit_fs_constant_buffer(r300, &r300->fs->code.constants);
+            r500_emit_fs_constant_buffer(r300,
+                                         &r300->fs->shader->code.constants);
         } else {
-            r300_emit_fs_constant_buffer(r300, &r300->fs->code.constants);
+            r300_emit_fs_constant_buffer(r300,
+                                         &r300->fs->shader->code.constants);
         }
         r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS;
     }
@@ -884,24 +1103,16 @@
         r300->dirty_state &= ~R300_NEW_FRAMEBUFFERS;
     }
 
-    if (r300->dirty_state & R300_NEW_RASTERIZER) {
-        r300_emit_rs_state(r300, r300->rs_state);
-        r300->dirty_state &= ~R300_NEW_RASTERIZER;
-    }
-
     if (r300->dirty_state & R300_NEW_RS_BLOCK) {
         r300_emit_rs_block_state(r300, r300->rs_block);
         r300->dirty_state &= ~R300_NEW_RS_BLOCK;
     }
 
-    if (r300->dirty_state & R300_NEW_SCISSOR) {
-        r300_emit_scissor_state(r300, r300->scissor_state);
-        r300->dirty_state &= ~R300_NEW_SCISSOR;
-    }
-
     /* Samplers and textures are tracked separately but emitted together. */
     if (r300->dirty_state &
             (R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES)) {
+        r300_emit_texture_count(r300);
+
         for (i = 0; i < MIN2(r300->sampler_count, r300->texture_count); i++) {
   	    if (r300->dirty_state &
 		((R300_NEW_SAMPLER << i) | (R300_NEW_TEXTURE << i))) {
@@ -918,11 +1129,6 @@
         r300->dirty_state &= ~(R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES);
     }
 
-    if (r300->dirty_state & R300_NEW_VIEWPORT) {
-        r300_emit_viewport_state(r300, r300->viewport_state);
-        r300->dirty_state &= ~R300_NEW_VIEWPORT;
-    }
-
     if (dirty_tex) {
         r300_flush_textures(r300);
     }
@@ -951,7 +1157,7 @@
     */
 
     /* Finally, emit the VBO. */
-    r300_emit_vertex_buffer(r300);
+    /* r300_emit_vertex_buffer(r300); */
 
     r300->dirty_hw++;
 }
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index 6befca7..05a6bfe 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -29,17 +29,15 @@
 struct rX00_fragment_program_code;
 struct r300_vertex_program_code;
 
-void r300_emit_blend_state(struct r300_context* r300,
-                           struct r300_blend_state* blend);
+void r300_emit_aos(struct r300_context* r300, unsigned offset);
 
-void r300_emit_blend_color_state(struct r300_context* r300,
-                                 struct r300_blend_color_state* bc);
+void r300_emit_blend_state(struct r300_context* r300, void* state);
 
-void r300_emit_clip_state(struct r300_context* r300,
-                          struct pipe_clip_state* clip);
+void r300_emit_blend_color_state(struct r300_context* r300, void* state);
 
-void r300_emit_dsa_state(struct r300_context* r300,
-                         struct r300_dsa_state* dsa);
+void r300_emit_clip_state(struct r300_context* r300, void* state);
+
+void r300_emit_dsa_state(struct r300_context* r300, void* state);
 
 void r300_emit_fragment_program_code(struct r300_context* r300,
                                      struct rX00_fragment_program_code* generic_code);
@@ -61,13 +59,12 @@
 
 void r300_emit_query_end(struct r300_context* r300);
 
-void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs);
+void r300_emit_rs_state(struct r300_context* r300, void* state);
 
 void r300_emit_rs_block_state(struct r300_context* r300,
                               struct r300_rs_block* rs);
 
-void r300_emit_scissor_state(struct r300_context* r300,
-                             struct r300_scissor_state* scissor);
+void r300_emit_scissor_state(struct r300_context* r300, void* state);
 
 void r300_emit_texture(struct r300_context* r300,
                        struct r300_sampler_state* sampler,
@@ -87,8 +84,11 @@
 void r300_emit_vertex_shader(struct r300_context* r300,
                              struct r300_vertex_shader* vs);
 
-void r300_emit_viewport_state(struct r300_context* r300,
-                              struct r300_viewport_state* viewport);
+void r300_emit_viewport_state(struct r300_context* r300, void* state);
+
+void r300_emit_texture_count(struct r300_context* r300);
+
+void r300_emit_ztop_state(struct r300_context* r300, void* state);
 
 void r300_flush_textures(struct r300_context* r300);
 
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index 29ddc84..60ea9c1 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -1,6 +1,7 @@
 /*
  * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
  *                Joakim Sindholt <opensource@zhasha.com>
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -21,6 +22,9 @@
  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
 
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
 #include "tgsi/tgsi_dump.h"
 
 #include "r300_context.h"
@@ -31,6 +35,45 @@
 #include "radeon_code.h"
 #include "radeon_compiler.h"
 
+/* Convert info about FS input semantics to r300_shader_semantics. */
+void r300_shader_read_fs_inputs(struct tgsi_shader_info* info,
+                                struct r300_shader_semantics* fs_inputs)
+{
+    int i;
+    unsigned index;
+
+    r300_shader_semantics_reset(fs_inputs);
+
+    for (i = 0; i < info->num_inputs; i++) {
+        index = info->input_semantic_index[i];
+
+        switch (info->input_semantic_name[i]) {
+            case TGSI_SEMANTIC_COLOR:
+                assert(index <= ATTR_COLOR_COUNT);
+                fs_inputs->color[index] = i;
+                break;
+
+            case TGSI_SEMANTIC_GENERIC:
+                assert(index <= ATTR_GENERIC_COUNT);
+                fs_inputs->generic[index] = i;
+                break;
+
+            case TGSI_SEMANTIC_FOG:
+                assert(index == 0);
+                fs_inputs->fog = i;
+                break;
+
+            case TGSI_SEMANTIC_POSITION:
+                assert(index == 0);
+                fs_inputs->wpos = i;
+                break;
+
+            default:
+                assert(0);
+        }
+    }
+}
+
 static void find_output_registers(struct r300_fragment_program_compiler * compiler,
                                   struct r300_fragment_shader * fs)
 {
@@ -58,61 +101,69 @@
     void (*allocate)(void * data, unsigned input, unsigned hwreg),
     void * mydata)
 {
-    struct tgsi_shader_info* info = &((struct r300_fragment_shader*)c->UserData)->info;
-    int total_colors = 0;
-    int colors = 0;
-    int total_generic = 0;
-    int generic = 0;
-    int i;
+    struct r300_shader_semantics* inputs =
+        (struct r300_shader_semantics*)c->UserData;
+    int i, reg = 0;
 
-    for (i = 0; i < info->num_inputs; i++) {
-        switch (info->input_semantic_name[i]) {
-            case TGSI_SEMANTIC_COLOR:
-                total_colors++;
-                break;
-            case TGSI_SEMANTIC_FOG:
-            case TGSI_SEMANTIC_GENERIC:
-                total_generic++;
-                break;
+    /* Allocate input registers. */
+    for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+        if (inputs->color[i] != ATTR_UNUSED) {
+            allocate(mydata, inputs->color[i], reg++);
         }
     }
+    for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
+        if (inputs->generic[i] != ATTR_UNUSED) {
+            allocate(mydata, inputs->generic[i], reg++);
+        }
+    }
+    if (inputs->fog != ATTR_UNUSED) {
+        allocate(mydata, inputs->fog, reg++);
+    }
+    if (inputs->wpos != ATTR_UNUSED) {
+        allocate(mydata, inputs->wpos, reg++);
+    }
+}
 
-    for(i = 0; i < info->num_inputs; i++) {
-        switch (info->input_semantic_name[i]) {
-            case TGSI_SEMANTIC_COLOR:
-                allocate(mydata, i, colors);
-                colors++;
-                break;
-            case TGSI_SEMANTIC_FOG:
-            case TGSI_SEMANTIC_GENERIC:
-                allocate(mydata, i, total_colors + generic);
-                generic++;
-                break;
+static void get_compare_state(
+    struct r300_context* r300,
+    struct r300_fragment_program_external_state* state,
+    unsigned shadow_samplers)
+{
+    memset(state, 0, sizeof(*state));
+
+    for (int i = 0; i < r300->sampler_count; i++) {
+        struct r300_sampler_state* s = r300->sampler_states[i];
+
+        if (s && s->state.compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
+            /* XXX Gallium doesn't provide us with any information regarding
+             * this mode, so we are screwed. I'm setting 0 = LUMINANCE. */
+            state->unit[i].depth_texture_mode = 0;
+
+            /* Fortunately, no need to translate this. */
+            state->unit[i].texture_compare_func = s->state.compare_func;
         }
     }
 }
 
-void r300_translate_fragment_shader(struct r300_context* r300,
-                                    struct r300_fragment_shader* fs)
+static void r300_translate_fragment_shader(
+    struct r300_context* r300,
+    struct r300_fragment_shader_code* shader)
 {
+    struct r300_fragment_shader* fs = r300->fs;
     struct r300_fragment_program_compiler compiler;
     struct tgsi_to_rc ttr;
+    int wpos = fs->inputs.wpos;
 
+    /* Setup the compiler. */
     memset(&compiler, 0, sizeof(compiler));
     rc_init(&compiler.Base);
     compiler.Base.Debug = DBG_ON(r300, DBG_FP);
 
-    compiler.code = &fs->code;
+    compiler.code = &shader->code;
+    compiler.state = shader->compare_state;
     compiler.is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
     compiler.AllocateHwInputs = &allocate_hardware_inputs;
-    compiler.UserData = fs;
-
-    /* TODO: Program compilation depends on texture compare modes,
-     * which are sampler state. Therefore, programs need to be recompiled
-     * depending on this state as in the classic Mesa driver.
-     *
-     * This is not yet handled correctly.
-     */
+    compiler.UserData = &fs->inputs;
 
     find_output_registers(&compiler, fs);
 
@@ -127,15 +178,76 @@
 
     r300_tgsi_to_rc(&ttr, fs->state.tokens);
 
+    fs->shadow_samplers = compiler.Base.Program.ShadowSamplers;
+
+    /**
+     * Transform the program to support WPOS.
+     *
+     * Introduce a small fragment at the start of the program that will be
+     * the only code that directly reads the WPOS input.
+     * All other code pieces that reference that input will be rewritten
+     * to read from a newly allocated temporary. */
+    if (wpos != ATTR_UNUSED) {
+        /* Moving the input to some other reg is not really necessary. */
+        rc_transform_fragment_wpos(&compiler.Base, wpos, wpos, TRUE);
+    }
+
     /* Invoke the compiler */
     r3xx_compile_fragment_program(&compiler);
     if (compiler.Base.Error) {
         /* XXX failover maybe? */
         DBG(r300, DBG_FP, "r300: Error compiling fragment program: %s\n",
             compiler.Base.ErrorMsg);
+        assert(0);
     }
 
     /* And, finally... */
     rc_destroy(&compiler.Base);
-    fs->translated = TRUE;
+}
+
+boolean r300_pick_fragment_shader(struct r300_context* r300)
+{
+    struct r300_fragment_shader* fs = r300->fs;
+    struct r300_fragment_program_external_state state;
+    struct r300_fragment_shader_code* ptr;
+
+    if (!fs->first) {
+        /* Build the fragment shader for the first time. */
+        fs->first = fs->shader = CALLOC_STRUCT(r300_fragment_shader_code);
+
+        /* BTW shadow samplers will be known after the first translation,
+         * therefore we set ~0, which means it should look at all sampler
+         * states. This choice doesn't have any impact on the correctness. */
+        get_compare_state(r300, &fs->shader->compare_state, ~0);
+        r300_translate_fragment_shader(r300, fs->shader);
+        return TRUE;
+
+    } else if (fs->shadow_samplers) {
+        get_compare_state(r300, &state, fs->shadow_samplers);
+
+        /* Check if the currently-bound shader has been compiled
+         * with the texture-compare state we need. */
+        if (memcmp(&fs->shader->compare_state, &state, sizeof(state)) != 0) {
+            /* Search for the right shader. */
+            ptr = fs->first;
+            while (ptr) {
+                if (memcmp(&ptr->compare_state, &state, sizeof(state)) == 0) {
+                    fs->shader = ptr;
+                    return TRUE;
+                }
+                ptr = ptr->next;
+            }
+
+            /* Not found, gotta compile a new one. */
+            ptr = CALLOC_STRUCT(r300_fragment_shader_code);
+            ptr->next = fs->first;
+            fs->first = fs->shader = ptr;
+
+            ptr->compare_state = state;
+            r300_translate_fragment_shader(r300, ptr);
+            return TRUE;
+        }
+    }
+
+    return FALSE;
 }
diff --git a/src/gallium/drivers/r300/r300_fs.h b/src/gallium/drivers/r300/r300_fs.h
index e831c30..40ce874 100644
--- a/src/gallium/drivers/r300/r300_fs.h
+++ b/src/gallium/drivers/r300/r300_fs.h
@@ -1,6 +1,7 @@
 /*
  * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
  *                Joakim Sindholt <opensource@zhasha.com>
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -25,31 +26,46 @@
 #define R300_FS_H
 
 #include "pipe/p_state.h"
-
 #include "tgsi/tgsi_scan.h"
-
 #include "radeon_code.h"
+#include "r300_shader_semantics.h"
+
+struct r300_fragment_shader_code {
+    struct r300_fragment_program_external_state compare_state;
+    struct rX00_fragment_program_code code;
+
+    struct r300_fragment_shader_code* next;
+};
 
 struct r300_fragment_shader {
     /* Parent class */
     struct pipe_shader_state state;
+
     struct tgsi_shader_info info;
+    struct r300_shader_semantics inputs;
 
-    /* Has this shader been translated yet? */
-    boolean translated;
+    /* Bits 0-15: TRUE if it's a shadow sampler, FALSE otherwise. */
+    unsigned shadow_samplers;
 
-    /* Compiled code */
-    struct rX00_fragment_program_code code;
+    /* Currently-bound fragment shader. */
+    struct r300_fragment_shader_code* shader;
+
+    /* List of the same shaders compiled with different texture-compare
+     * states. */
+    struct r300_fragment_shader_code* first;
 };
 
+void r300_shader_read_fs_inputs(struct tgsi_shader_info* info,
+                                struct r300_shader_semantics* fs_inputs);
 
-void r300_translate_fragment_shader(struct r300_context* r300,
-                                    struct r300_fragment_shader* fs);
+/* Return TRUE if the shader was switched and should be re-emitted. */
+boolean r300_pick_fragment_shader(struct r300_context* r300);
 
-static inline boolean r300_fragment_shader_writes_depth(struct r300_fragment_shader *fs)
+static INLINE boolean r300_fragment_shader_writes_depth(struct r300_fragment_shader *fs)
 {
     if (!fs)
-	return FALSE;
-    return (fs->code.writes_depth) ? TRUE : FALSE;
+        return FALSE;
+    return (fs->shader->code.writes_depth) ? TRUE : FALSE;
 }
+
 #endif /* R300_FS_H */
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
index 1e4d3f5..034bfc1 100644
--- a/src/gallium/drivers/r300/r300_reg.h
+++ b/src/gallium/drivers/r300/r300_reg.h
@@ -661,20 +661,20 @@
 #	define R300_GB_SUPER_TILE_B		(1 << 15)
 #	define R300_GB_SUBPIXEL_1_12		(0 << 16)
 #	define R300_GB_SUBPIXEL_1_16		(1 << 16)
-#	define GB_TILE_CONFIG_QUADS_PER_RAS_4   (0 << 17)
-#	define GB_TILE_CONFIG_QUADS_PER_RAS_8   (1 << 17)
-#	define GB_TILE_CONFIG_QUADS_PER_RAS_16  (2 << 17)
-#	define GB_TILE_CONFIG_QUADS_PER_RAS_32  (3 << 17)
-#	define GB_TILE_CONFIG_BB_SCAN_INTERCEPT (0 << 19)
-#	define GB_TILE_CONFIG_BB_SCAN_BOUND_BOX (1 << 19)
-#	define GB_TILE_CONFIG_ALT_SCAN_EN_LR    (0 << 20)
-#	define GB_TILE_CONFIG_ALT_SCAN_EN_LRL   (1 << 20)
-#	define GB_TILE_CONFIG_ALT_OFFSET        (0 << 21)
-#	define GB_TILE_CONFIG_SUBPRECISION      (0 << 22)
-#	define GB_TILE_CONFIG_ALT_TILING_DEF    (0 << 23)
-#	define GB_TILE_CONFIG_ALT_TILING_3_2    (1 << 23)
-#	define GB_TILE_CONFIG_Z_EXTENDED_24_1   (0 << 24)
-#	define GB_TILE_CONFIG_Z_EXTENDED_S25_1  (1 << 24)
+#	define R300_GB_TILE_CONFIG_QUADS_PER_RAS_4   (0 << 17)
+#	define R300_GB_TILE_CONFIG_QUADS_PER_RAS_8   (1 << 17)
+#	define R300_GB_TILE_CONFIG_QUADS_PER_RAS_16  (2 << 17)
+#	define R300_GB_TILE_CONFIG_QUADS_PER_RAS_32  (3 << 17)
+#	define R300_GB_TILE_CONFIG_BB_SCAN_INTERCEPT (0 << 19)
+#	define R300_GB_TILE_CONFIG_BB_SCAN_BOUND_BOX (1 << 19)
+#	define R300_GB_TILE_CONFIG_ALT_SCAN_EN_LR    (0 << 20)
+#	define R300_GB_TILE_CONFIG_ALT_SCAN_EN_LRL   (1 << 20)
+#	define R300_GB_TILE_CONFIG_ALT_OFFSET        (0 << 21)
+#	define R300_GB_TILE_CONFIG_SUBPRECISION      (0 << 22)
+#	define R300_GB_TILE_CONFIG_ALT_TILING_DEF    (0 << 23)
+#	define R300_GB_TILE_CONFIG_ALT_TILING_3_2    (1 << 23)
+#	define R300_GB_TILE_CONFIG_Z_EXTENDED_24_1   (0 << 24)
+#	define R300_GB_TILE_CONFIG_Z_EXTENDED_S25_1  (1 << 24)
 
 /* Specifies the sizes of the various FIFO`s in the sc/rs/us. This register must be the first one written */
 #define R300_GB_FIFO_SIZE	0x4024
@@ -700,9 +700,9 @@
 #	define R300_OFIFO_HIGHWATER_SHIFT	22	/* two bits only */
 #	define R300_CUBE_FIFO_HIGHWATER_COL_SHIFT	24
 
-#define GB_Z_PEQ_CONFIG                          0x4028
-#	define GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_4_4    (0 << 0)
-#	define GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8    (1 << 0)
+#define R300_GB_Z_PEQ_CONFIG                          0x4028
+#	define R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_4_4    (0 << 0)
+#	define R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8    (1 << 0)
 
 /* Specifies various polygon specific selects (fog, depth, perspective). */
 #define R300_GB_SELECT                           0x401c
@@ -725,39 +725,39 @@
 
 /* Specifies the graphics pipeline configuration for antialiasing. */
 #define R300_GB_AA_CONFIG                         0x4020
-#	define GB_AA_CONFIG_AA_DISABLE           (0 << 0)
-#	define GB_AA_CONFIG_AA_ENABLE            (1 << 0)
-#	define GB_AA_CONFIG_NUM_AA_SUBSAMPLES_2  (0 << 1)
-#	define GB_AA_CONFIG_NUM_AA_SUBSAMPLES_3  (1 << 1)
-#	define GB_AA_CONFIG_NUM_AA_SUBSAMPLES_4  (2 << 1)
-#	define GB_AA_CONFIG_NUM_AA_SUBSAMPLES_6  (3 << 1)
+#	define R300_GB_AA_CONFIG_AA_DISABLE           (0 << 0)
+#	define R300_GB_AA_CONFIG_AA_ENABLE            (1 << 0)
+#	define R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_2  (0 << 1)
+#	define R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_3  (1 << 1)
+#	define R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_4  (2 << 1)
+#	define R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_6  (3 << 1)
 
 /* Selects which of 4 pipes are active. */
-#define GB_PIPE_SELECT                           0x402c
-#	define GB_PIPE_SELECT_PIPE0_ID_SHIFT  0
-#	define GB_PIPE_SELECT_PIPE1_ID_SHIFT  2
-#	define GB_PIPE_SELECT_PIPE2_ID_SHIFT  4
-#	define GB_PIPE_SELECT_PIPE3_ID_SHIFT  6
-#	define GB_PIPE_SELECT_PIPE_MASK_SHIFT 8
-#	define GB_PIPE_SELECT_MAX_PIPE        12
-#	define GB_PIPE_SELECT_BAD_PIPES       14
-#	define GB_PIPE_SELECT_CONFIG_PIPES    18
+#define R300_GB_PIPE_SELECT                           0x402c
+#	define R300_GB_PIPE_SELECT_PIPE0_ID_SHIFT  0
+#	define R300_GB_PIPE_SELECT_PIPE1_ID_SHIFT  2
+#	define R300_GB_PIPE_SELECT_PIPE2_ID_SHIFT  4
+#	define R300_GB_PIPE_SELECT_PIPE3_ID_SHIFT  6
+#	define R300_GB_PIPE_SELECT_PIPE_MASK_SHIFT 8
+#	define R300_GB_PIPE_SELECT_MAX_PIPE        12
+#	define R300_GB_PIPE_SELECT_BAD_PIPES       14
+#	define R300_GB_PIPE_SELECT_CONFIG_PIPES    18
 
 
 /* Specifies the sizes of the various FIFO`s in the sc/rs. */
-#define GB_FIFO_SIZE1                            0x4070
+#define R300_GB_FIFO_SIZE1                            0x4070
 /* High water mark for SC input fifo */
-#	define GB_FIFO_SIZE1_SC_HIGHWATER_IFIFO_SHIFT 0
-#	define GB_FIFO_SIZE1_SC_HIGHWATER_IFIFO_MASK  0x0000003f
+#	define R300_GB_FIFO_SIZE1_SC_HIGHWATER_IFIFO_SHIFT 0
+#	define R300_GB_FIFO_SIZE1_SC_HIGHWATER_IFIFO_MASK  0x0000003f
 /* High water mark for SC input fifo (B) */
-#	define GB_FIFO_SIZE1_SC_HIGHWATER_BFIFO_SHIFT 6
-#	define GB_FIFO_SIZE1_SC_HIGHWATER_BFIFO_MASK  0x00000fc0
+#	define R300_GB_FIFO_SIZE1_SC_HIGHWATER_BFIFO_SHIFT 6
+#	define R300_GB_FIFO_SIZE1_SC_HIGHWATER_BFIFO_MASK  0x00000fc0
 /* High water mark for RS colors' fifo */
-#	define GB_FIFO_SIZE1_SC_HIGHWATER_COL_SHIFT   12
-#	define GB_FIFO_SIZE1_SC_HIGHWATER_COL_MASK    0x0003f000
+#	define R300_GB_FIFO_SIZE1_SC_HIGHWATER_COL_SHIFT   12
+#	define R300_GB_FIFO_SIZE1_SC_HIGHWATER_COL_MASK    0x0003f000
 /* High water mark for RS textures' fifo */
-#	define GB_FIFO_SIZE1_SC_HIGHWATER_TEX_SHIFT   18
-#	define GB_FIFO_SIZE1_SC_HIGHWATER_TEX_MASK    0x00fc0000
+#	define R300_GB_FIFO_SIZE1_SC_HIGHWATER_TEX_SHIFT   18
+#	define R300_GB_FIFO_SIZE1_SC_HIGHWATER_TEX_MASK    0x00fc0000
 
 /* This table specifies the source location and format for up to 16 texture
  * addresses (i[0]:i[15]) and four colors (c[0]:c[3])
@@ -1293,7 +1293,7 @@
 #        define R500_RS_INST_TEX_ID(x)                  ((x) << 0)
 #define R500_RS_INST_TEX_CN_WRITE			(1 << 4)
 #define R500_RS_INST_TEX_ADDR_SHIFT			5
-#        define R500_RS_INST_TEX_ADDR(x)                ((x) << 0)
+#        define R500_RS_INST_TEX_ADDR(x)                ((x) << 5)
 #define R500_RS_INST_COL_ID_SHIFT			12
 #        define R500_RS_INST_COL_ID(x)                  ((x) << 12)
 #define R500_RS_INST_COL_CN_NO_WRITE			(0 << 16)
@@ -1463,6 +1463,8 @@
 #	define R300_TX_MIN_FILTER_MIP_NEAREST    (1 << 13)
 #	define R300_TX_MIN_FILTER_MIP_LINEAR     (2 << 13)
 #	define R300_TX_MIN_FILTER_MIP_MASK       (3 << 13)
+#       define R300_TX_MAX_MIP_LEVEL_SHIFT       17
+#       define R300_TX_MAX_MIP_LEVEL_MASK        (0xf << 17)
 #	define R300_TX_MAX_ANISO_1_TO_1          (0 << 21)
 #	define R300_TX_MAX_ANISO_2_TO_1          (1 << 21)
 #	define R300_TX_MAX_ANISO_4_TO_1          (2 << 21)
@@ -1471,6 +1473,7 @@
 #	define R300_TX_MAX_ANISO_MASK            (7 << 21)
 #       define R300_TX_WRAP_S(x)                 ((x) << 0)
 #       define R300_TX_WRAP_T(x)                 ((x) << 3)
+#       define R300_TX_MAX_MIP_LEVEL(x)          ((x) << 17)
 
 #define R300_TX_FILTER1_0                      0x4440
 #	define R300_CHROMA_KEY_MODE_DISABLE    0
@@ -1500,8 +1503,6 @@
 #       define R300_TX_HEIGHTMASK_MASK           (2047 << 11)
 #	define R300_TX_DEPTHMASK_SHIFT           22
 #	define R300_TX_DEPTHMASK_MASK            (0xf << 22)
-#       define R300_TX_MAX_MIP_LEVEL_SHIFT       26
-#       define R300_TX_MAX_MIP_LEVEL_MASK        (0xf << 26)
 #       define R300_TX_SIZE_PROJECTED            (1 << 30)
 #       define R300_TX_PITCH_EN                  (1 << 31)
 #       define R300_TX_WIDTH(x)                  ((x) << 0)
@@ -1884,6 +1885,7 @@
 #       define R300_RGB_ADDR0(x)                ((x) << 0)
 #       define R300_RGB_ADDR1(x)                ((x) << 6)
 #       define R300_RGB_ADDR2(x)                ((x) << 12)
+#       define R300_RGB_TARGET(x)               ((x) << 29)
 
 #define R300_US_ALU_ALPHA_ADDR_0                 0x47C0
 #       define R300_ALU_SRC0A_SHIFT             0
@@ -1901,9 +1903,10 @@
 #       define R300_ALU_DSTA_REG                (1 << 23)
 #       define R300_ALU_DSTA_OUTPUT             (1 << 24)
 #		define R300_ALU_DSTA_DEPTH              (1 << 27)
-#       define R300_ALPHA_ADDR0(x)                ((x) << 0)
-#       define R300_ALPHA_ADDR1(x)                ((x) << 6)
-#       define R300_ALPHA_ADDR2(x)                ((x) << 12)
+#       define R300_ALPHA_ADDR0(x)              ((x) << 0)
+#       define R300_ALPHA_ADDR1(x)              ((x) << 6)
+#       define R300_ALPHA_ADDR2(x)              ((x) << 12)
+#       define R300_ALPHA_TARGET(x)             ((x) << 25)
 
 #define R300_US_ALU_RGB_INST_0                   0x48C0
 #       define R300_ALU_ARGC_SRC0C_XYZ          0
@@ -2142,6 +2145,7 @@
 
 /* Unpipelined. */
 #define R300_RB3D_CCTL                      0x4e00
+#	define R300_RB3D_CCTL_NUM_MULTIWRITES(x)       (MAX2(((x)-1), 0) << 5)
 #	define R300_RB3D_CCTL_NUM_MULTIWRITES_1_BUFFER                (0 << 5)
 #	define R300_RB3D_CCTL_NUM_MULTIWRITES_2_BUFFERS               (1 << 5)
 #	define R300_RB3D_CCTL_NUM_MULTIWRITES_3_BUFFERS               (2 << 5)
@@ -2182,6 +2186,8 @@
 #       define R300_DISCARD_SRC_PIXELS_SRC_ALPHA_1     (4 << 3)
 #       define R300_DISCARD_SRC_PIXELS_SRC_COLOR_1     (5 << 3)
 #       define R300_DISCARD_SRC_PIXELS_SRC_ALPHA_COLOR_1     (6 << 3)
+#       define R500_SRC_ALPHA_0_NO_READ                (1 << 30)
+#       define R500_SRC_ALPHA_1_NO_READ                (1 << 31)
 
 /* the following are shared between CBLEND and ABLEND */
 #       define R300_FCN_MASK                         (3  << 12)
@@ -2634,7 +2640,7 @@
 	VE_COND_MUX_GTE			= 25,
 	VE_SET_GREATER_THAN		= 26,
 	VE_SET_EQUAL			= 27,
-	VE_SET_NOT_EQUAL		= 28,
+	VE_SET_NOT_EQUAL		= 28
 };
 
 enum {
@@ -2668,20 +2674,20 @@
 	ME_PRED_SET_CLR			= 25,
 	ME_PRED_SET_INV			= 26,
 	ME_PRED_SET_POP			= 27,
-	ME_PRED_SET_RESTORE		= 28,
+	ME_PRED_SET_RESTORE		= 28
 };
 
 enum {
 	/* R3XX */
 	PVS_MACRO_OP_2CLK_MADD		= 0,
-	PVS_MACRO_OP_2CLK_M2X_ADD	= 1,
+	PVS_MACRO_OP_2CLK_M2X_ADD	= 1
 };
 
 enum {
 	PVS_SRC_REG_TEMPORARY		= 0,	/* Intermediate Storage */
 	PVS_SRC_REG_INPUT		= 1,	/* Input Vertex Storage */
 	PVS_SRC_REG_CONSTANT		= 2,	/* Constant State Storage */
-	PVS_SRC_REG_ALT_TEMPORARY	= 3,	/* Alternate Intermediate Storage */
+	PVS_SRC_REG_ALT_TEMPORARY	= 3	/* Alternate Intermediate Storage */
 };
 
 enum {
@@ -2690,7 +2696,7 @@
 	PVS_DST_REG_OUT			= 2,	/* Output Memory. Used for all outputs */
 	PVS_DST_REG_OUT_REPL_X		= 3,	/* Output Memory & Replicate X to all channels */
 	PVS_DST_REG_ALT_TEMPORARY	= 4,	/* Alternate Intermediate Storage */
-	PVS_DST_REG_INPUT		= 5,	/* Output Memory & Replicate X to all channels */
+	PVS_DST_REG_INPUT		= 5	/* Output Memory & Replicate X to all channels */
 };
 
 enum {
@@ -2699,7 +2705,7 @@
 	PVS_SRC_SELECT_Z		= 2,	/* Select Z Component */
 	PVS_SRC_SELECT_W		= 3,	/* Select W Component */
 	PVS_SRC_SELECT_FORCE_0		= 4,	/* Force Component to 0.0 */
-	PVS_SRC_SELECT_FORCE_1		= 5,	/* Force Component to 1.0 */
+	PVS_SRC_SELECT_FORCE_1		= 5	/* Force Component to 1.0 */
 };
 
 /* PVS Opcode & Destination Operand Description */
@@ -2738,7 +2744,7 @@
 	PVS_DST_ADDR_SEL_MASK		= 0x3,
 	PVS_DST_ADDR_SEL_SHIFT		= 29,
 	PVS_DST_ADDR_MODE_0_MASK	= 0x1,
-	PVS_DST_ADDR_MODE_0_SHIFT	= 31,
+	PVS_DST_ADDR_MODE_0_SHIFT	= 31
 };
 
 /* PVS Source Operand Description */
@@ -2773,7 +2779,7 @@
 	PVS_SRC_ADDR_SEL_MASK		= 0x3,
 	PVS_SRC_ADDR_SEL_SHIFT		= 29,
 	PVS_SRC_ADDR_MODE_1_MASK	= 0x0,
-	PVS_SRC_ADDR_MODE_1_SHIFT	= 32,
+	PVS_SRC_ADDR_MODE_1_SHIFT	= 32
 };
 
 /*\}*/
@@ -3290,6 +3296,11 @@
  */
 #define R300_PACKET3_3D_LOAD_VBPNTR         0x00002F00
 
+#   define R300_VBPNTR_SIZE0(x)    ((x) >> 2)
+#   define R300_VBPNTR_STRIDE0(x)  (((x) >> 2) << 8)
+#   define R300_VBPNTR_SIZE1(x)    (((x) >> 2) << 16)
+#   define R300_VBPNTR_STRIDE1(x)  (((x) >> 2) << 24)
+
 #define R300_PACKET3_INDX_BUFFER            0x00003300
 #    define R300_INDX_BUFFER_DST_SHIFT          0
 #    define R300_INDX_BUFFER_SKIP_SHIFT         16
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index c36350d..ee43421 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -20,6 +20,9 @@
  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
 
+/* r300_render: Vertex and index buffer primitive emission. Contains both
+ * HW TCL fastpath rendering, and SW TCL Draw-assisted rendering. */
+
 #include "draw/draw_context.h"
 #include "draw/draw_vbuf.h"
 
@@ -38,7 +41,7 @@
 /* r300_render: Vertex and index buffer primitive emission. */
 #define R300_MAX_VBO_SIZE  (1024 * 1024)
 
-static uint32_t r300_translate_primitive(unsigned prim)
+uint32_t r300_translate_primitive(unsigned prim)
 {
     switch (prim) {
         case PIPE_PRIM_POINTS:
@@ -66,8 +69,146 @@
     }
 }
 
+static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300,
+                                            unsigned mode)
+{
+    struct r300_rs_state* rs = (struct r300_rs_state*)r300->rs_state.state;
+    uint32_t color_control = rs->color_control;
+
+    /* By default (see r300_state.c:r300_create_rs_state) color_control is
+     * initialized to provoking the first vertex.
+     *
+     * Triangle fans must be reduced to the second vertex, not the first, in
+     * Gallium flatshade-first mode, as per the GL spec.
+     * (http://www.opengl.org/registry/specs/ARB/provoking_vertex.txt)
+     *
+     * Quads never provoke correctly in flatshade-first mode. The first
+     * vertex is never considered as provoking, so only the second, third,
+     * and fourth vertices can be selected, and both "third" and "last" modes
+     * select the fourth vertex. This is probably due to D3D lacking quads.
+     *
+     * Similarly, polygons reduce to the first, not the last, vertex, when in
+     * "last" mode, and all other modes start from the second vertex.
+     *
+     * ~ C.
+     */
+
+    if (rs->rs.flatshade_first) {
+        switch (mode) {
+            case PIPE_PRIM_TRIANGLE_FAN:
+                color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_SECOND;
+                break;
+            case PIPE_PRIM_QUADS:
+            case PIPE_PRIM_QUAD_STRIP:
+            case PIPE_PRIM_POLYGON:
+                color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
+                break;
+            default:
+                color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_FIRST;
+                break;
+        }
+    } else {
+        color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
+    }
+
+    return color_control;
+}
+
+static void r300_emit_draw_arrays(struct r300_context *r300,
+                                  unsigned mode,
+                                  unsigned count)
+{
+    CS_LOCALS(r300);
+
+    BEGIN_CS(8);
+    OUT_CS_REG(R300_GA_COLOR_CONTROL,
+            r300_provoking_vertex_fixes(r300, mode));
+    OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0);
+    OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1);
+    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
+    OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
+           r300_translate_primitive(mode));
+    END_CS;
+}
+
+static void r300_emit_draw_elements(struct r300_context *r300,
+                                    struct pipe_buffer* indexBuffer,
+                                    unsigned indexSize,
+                                    unsigned minIndex,
+                                    unsigned maxIndex,
+                                    unsigned mode,
+                                    unsigned start,
+                                    unsigned count)
+{
+    uint32_t count_dwords;
+    uint32_t offset_dwords = indexSize * start / sizeof(uint32_t);
+    CS_LOCALS(r300);
+
+    /* XXX most of these are stupid */
+    assert(indexSize == 4 || indexSize == 2);
+    assert((start * indexSize)  % 4 == 0);
+    assert(offset_dwords == 0);
+
+    BEGIN_CS(14);
+    OUT_CS_REG(R300_GA_COLOR_CONTROL,
+            r300_provoking_vertex_fixes(r300, mode));
+    OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, minIndex);
+    OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, maxIndex);
+    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0);
+    if (indexSize == 4) {
+        count_dwords = count + start;
+        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
+               R300_VAP_VF_CNTL__INDEX_SIZE_32bit |
+               r300_translate_primitive(mode));
+    } else {
+        count_dwords = (count + start + 1) / 2;
+        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
+               r300_translate_primitive(mode));
+    }
+
+    /* INDX_BUFFER is a truly special packet3.
+     * Unlike most other packet3, where the offset is after the count,
+     * the order is reversed, so the relocation ends up carrying the
+     * size of the indexbuf instead of the offset.
+     *
+     * XXX Fix offset
+     */
+    OUT_CS_PKT3(R300_PACKET3_INDX_BUFFER, 2);
+    OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) |
+           (0 << R300_INDX_BUFFER_SKIP_SHIFT));
+    OUT_CS(offset_dwords);
+    OUT_CS_RELOC(indexBuffer, count_dwords,
+        RADEON_GEM_DOMAIN_GTT, 0, 0);
+
+    END_CS;
+}
+
+
+static boolean r300_setup_vertex_buffers(struct r300_context *r300)
+{
+    struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
+    struct pipe_vertex_element *velem = r300->vertex_element;
+
+validate:
+    for (int i = 0; i < r300->vertex_element_count; i++) {
+        if (!r300->winsys->add_buffer(r300->winsys,
+                vbuf[velem[i].vertex_buffer_index].buffer,
+            RADEON_GEM_DOMAIN_GTT, 0)) {
+            r300->context.flush(&r300->context, 0, NULL);
+            goto validate;
+        }
+    }
+
+    if (!r300->winsys->validate(r300->winsys)) {
+        r300->context.flush(&r300->context, 0, NULL);
+        return r300->winsys->validate(r300->winsys);
+    }
+
+    return TRUE;
+}
+
 /* This is the fast-path drawing & emission for HW TCL. */
-boolean r300_draw_range_elements(struct pipe_context* pipe,
+void r300_draw_range_elements(struct pipe_context* pipe,
                                  struct pipe_buffer* indexBuffer,
                                  unsigned indexSize,
                                  unsigned minIndex,
@@ -77,105 +218,78 @@
                                  unsigned count)
 {
     struct r300_context* r300 = r300_context(pipe);
-    uint32_t prim = r300_translate_primitive(mode);
-    struct pipe_vertex_buffer* aos = r300->vertex_buffers;
-    unsigned aos_count = r300->vertex_buffer_count;
-    short* indices;
-    unsigned packet_size;
-    unsigned i;
-    bool invalid = FALSE;
-    
-    CS_LOCALS(r300);
 
     if (!u_trim_pipe_prim(mode, &count)) {
-        return FALSE;
+        return;
     }
 
-validate:
-    for (i = 0; i < aos_count; i++) {
-        if (!r300->winsys->add_buffer(r300->winsys, aos[i].buffer,
-                    RADEON_GEM_DOMAIN_GTT, 0)) {
-            pipe->flush(pipe, 0, NULL);
-            goto validate;
-        }
+    if (count > 65535) {
+       /* XXX: use aux/indices functions to split this into smaller
+        * primitives.
+        */
+        return;
     }
+
+    r300_update_derived_state(r300);
+
+    if (!r300_setup_vertex_buffers(r300)) {
+        return;
+    }
+
+    if (!r300->winsys->add_buffer(r300->winsys, indexBuffer,
+                                  RADEON_GEM_DOMAIN_GTT, 0)) {
+        return;
+    }
+
     if (!r300->winsys->validate(r300->winsys)) {
-        pipe->flush(pipe, 0, NULL);
-        if (invalid) {
-            /* Well, hell. */
-            debug_printf("r300: Stuck in validation loop, gonna quit now.");
-            exit(1);
-        }
-        invalid = TRUE;
-        goto validate;
+        return;
     }
 
     r300_emit_dirty_state(r300);
 
-    packet_size = (aos_count >> 1) * 3 + (aos_count & 1) * 2;
+    r300_emit_aos(r300, 0);
 
-    BEGIN_CS(3 + packet_size + (aos_count * 2));
-    OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
-    OUT_CS(aos_count);
-    for (i = 0; i < aos_count - 1; i += 2) {
-        OUT_CS(aos[i].stride |
-            (aos[i].stride << 8) |
-            (aos[i + 1].stride << 16) |
-            (aos[i + 1].stride << 24));
-        OUT_CS(aos[i].buffer_offset + start * 4 * aos[i].stride);
-        OUT_CS(aos[i + 1].buffer_offset + start * 4 * aos[i + 1].stride);
-    }
-    if (aos_count & 1) {
-        OUT_CS(aos[i].stride | (aos[i].stride << 8));
-        OUT_CS(aos[i].buffer_offset + start * 4 * aos[i].stride);
-    }
-    for (i = 0; i < aos_count; i++) {
-        OUT_CS_RELOC(aos[i].buffer, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
-    }
-    END_CS;
-
-    if (indexBuffer) {
-        indices = (short*)pipe_buffer_map(pipe->screen, indexBuffer,
-                                          PIPE_BUFFER_USAGE_CPU_READ);
-
-        /* Set the starting point. */
-        indices += start;
-
-        BEGIN_CS(2 + (count+1)/2);
-        OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count + 1)/2);
-        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | prim);
-        for (i = 0; i < count - 1; i += 2) {
-            OUT_CS(indices[i + 1] << 16 | indices[i]);
-        }
-        if (count % 2) {
-            OUT_CS(indices[count - 1]);
-        }
-        END_CS;
-    } else {
-        BEGIN_CS(2);
-        OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
-        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
-               prim);
-        END_CS;
-    }
-
-    return TRUE;
+    r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, maxIndex,
+                            mode, start, count);
 }
 
 /* Simple helpers for context setup. Should probably be moved to util. */
-boolean r300_draw_elements(struct pipe_context* pipe,
-                           struct pipe_buffer* indexBuffer,
-                           unsigned indexSize, unsigned mode,
-                           unsigned start, unsigned count)
+void r300_draw_elements(struct pipe_context* pipe,
+                        struct pipe_buffer* indexBuffer,
+                        unsigned indexSize, unsigned mode,
+                        unsigned start, unsigned count)
 {
-    return pipe->draw_range_elements(pipe, indexBuffer, indexSize, 0, ~0,
-                                     mode, start, count);
+   pipe->draw_range_elements(pipe, indexBuffer, indexSize, 0, ~0,
+                             mode, start, count);
 }
 
-boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
+void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
                          unsigned start, unsigned count)
 {
-    return pipe->draw_elements(pipe, NULL, 0, mode, start, count);
+    struct r300_context* r300 = r300_context(pipe);
+
+    if (!u_trim_pipe_prim(mode, &count)) {
+        return;
+    }
+
+    if (count > 65535) {
+        /* XXX: driver needs to handle this -- use the functions in
+         * aux/indices to split this into several smaller primitives.
+         */
+        return;
+    }
+
+    r300_update_derived_state(r300);
+
+    if (!r300_setup_vertex_buffers(r300)) {
+        return;
+    }
+
+    r300_emit_dirty_state(r300);
+
+    r300_emit_aos(r300, start);
+
+    r300_emit_draw_arrays(r300, mode, count);
 }
 
 /****************************************************************************
@@ -183,8 +297,44 @@
  * keep these functions separated so that they are easier to locate. ~C.    *
  ***************************************************************************/
 
-/* Draw-based drawing for SW TCL chipsets. */
-boolean r300_swtcl_draw_range_elements(struct pipe_context* pipe,
+/* SW TCL arrays, using Draw. */
+void r300_swtcl_draw_arrays(struct pipe_context* pipe,
+                               unsigned mode,
+                               unsigned start,
+                               unsigned count)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    int i;
+
+    if (!u_trim_pipe_prim(mode, &count)) {
+        return;
+    }
+
+    for (i = 0; i < r300->vertex_buffer_count; i++) {
+        void* buf = pipe_buffer_map(pipe->screen,
+                                    r300->vertex_buffer[i].buffer,
+                                    PIPE_BUFFER_USAGE_CPU_READ);
+        draw_set_mapped_vertex_buffer(r300->draw, i, buf);
+    }
+
+    draw_set_mapped_element_buffer(r300->draw, 0, NULL);
+
+    draw_set_mapped_constant_buffer(r300->draw,
+				    PIPE_SHADER_VERTEX,
+				    r300->shader_constants[PIPE_SHADER_VERTEX].constants,
+				    r300->shader_constants[PIPE_SHADER_VERTEX].count *
+                (sizeof(float) * 4));
+
+    draw_arrays(r300->draw, mode, start, count);
+
+    for (i = 0; i < r300->vertex_buffer_count; i++) {
+        pipe_buffer_unmap(pipe->screen, r300->vertex_buffer[i].buffer);
+        draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
+    }
+}
+
+/* SW TCL elements, using Draw. */
+void r300_swtcl_draw_range_elements(struct pipe_context* pipe,
                                        struct pipe_buffer* indexBuffer,
                                        unsigned indexSize,
                                        unsigned minIndex,
@@ -195,28 +345,26 @@
 {
     struct r300_context* r300 = r300_context(pipe);
     int i;
+    void* indices;
 
     if (!u_trim_pipe_prim(mode, &count)) {
-        return FALSE;
+        return;
     }
 
     for (i = 0; i < r300->vertex_buffer_count; i++) {
         void* buf = pipe_buffer_map(pipe->screen,
-                                    r300->vertex_buffers[i].buffer,
+                                    r300->vertex_buffer[i].buffer,
                                     PIPE_BUFFER_USAGE_CPU_READ);
         draw_set_mapped_vertex_buffer(r300->draw, i, buf);
     }
 
-    if (indexBuffer) {
-        void* indices = pipe_buffer_map(pipe->screen, indexBuffer,
-                                        PIPE_BUFFER_USAGE_CPU_READ);
-        draw_set_mapped_element_buffer_range(r300->draw, indexSize,
-                                             minIndex, maxIndex, indices);
-    } else {
-        draw_set_mapped_element_buffer(r300->draw, 0, NULL);
-    }
+    indices = pipe_buffer_map(pipe->screen, indexBuffer,
+                              PIPE_BUFFER_USAGE_CPU_READ);
+    draw_set_mapped_element_buffer_range(r300->draw, indexSize,
+                                         minIndex, maxIndex, indices);
 
     draw_set_mapped_constant_buffer(r300->draw,
+				    PIPE_SHADER_VERTEX,
             r300->shader_constants[PIPE_SHADER_VERTEX].constants,
             r300->shader_constants[PIPE_SHADER_VERTEX].count *
                 (sizeof(float) * 4));
@@ -224,17 +372,13 @@
     draw_arrays(r300->draw, mode, start, count);
 
     for (i = 0; i < r300->vertex_buffer_count; i++) {
-        pipe_buffer_unmap(pipe->screen, r300->vertex_buffers[i].buffer);
+        pipe_buffer_unmap(pipe->screen, r300->vertex_buffer[i].buffer);
         draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
     }
 
-    if (indexBuffer) {
-        pipe_buffer_unmap(pipe->screen, indexBuffer);
-        draw_set_mapped_element_buffer_range(r300->draw, 0, start,
-                                             start + count - 1, NULL);
-    }
-
-    return TRUE;
+    pipe_buffer_unmap(pipe->screen, indexBuffer);
+    draw_set_mapped_element_buffer_range(r300->draw, 0, start,
+                                         start + count - 1, NULL);
 }
 
 /* Object for rendering using Draw. */
@@ -310,7 +454,7 @@
     r300render->vbo_ptr = pipe_buffer_map(screen, r300render->vbo,
                                           PIPE_BUFFER_USAGE_CPU_WRITE);
 
-    return (r300render->vbo_ptr + r300render->vbo_offset);
+    return ((uint8_t*)r300render->vbo_ptr + r300render->vbo_offset);
 }
 
 static void r300_render_unmap_vertices(struct vbuf_render* render,
diff --git a/src/gallium/drivers/r300/r300_render.h b/src/gallium/drivers/r300/r300_render.h
index 3d8f47b..27b5e6a 100644
--- a/src/gallium/drivers/r300/r300_render.h
+++ b/src/gallium/drivers/r300/r300_render.h
@@ -23,30 +23,37 @@
 #ifndef R300_RENDER_H
 #define R300_RENDER_H
 
-boolean r300_draw_range_elements(struct pipe_context* pipe,
-                                 struct pipe_buffer* indexBuffer,
-                                 unsigned indexSize,
-                                 unsigned minIndex,
-                                 unsigned maxIndex,
-                                 unsigned mode,
-                                 unsigned start,
-                                 unsigned count);
+uint32_t r300_translate_primitive(unsigned prim);
 
-boolean r300_draw_elements(struct pipe_context* pipe,
-                           struct pipe_buffer* indexBuffer,
-                           unsigned indexSize, unsigned mode,
-                           unsigned start, unsigned count);
+void r300_draw_range_elements(struct pipe_context* pipe,
+                              struct pipe_buffer* indexBuffer,
+                              unsigned indexSize,
+                              unsigned minIndex,
+                              unsigned maxIndex,
+                              unsigned mode,
+                              unsigned start,
+                              unsigned count);
 
-boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
-                         unsigned start, unsigned count);
+void r300_draw_elements(struct pipe_context* pipe,
+                        struct pipe_buffer* indexBuffer,
+                        unsigned indexSize, unsigned mode,
+                        unsigned start, unsigned count);
 
-boolean r300_swtcl_draw_range_elements(struct pipe_context* pipe,
-                                       struct pipe_buffer* indexBuffer,
-                                       unsigned indexSize,
-                                       unsigned minIndex,
-                                       unsigned maxIndex,
-                                       unsigned mode,
-                                       unsigned start,
-                                       unsigned count);
+void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
+                      unsigned start, unsigned count);
+
+void r300_swtcl_draw_arrays(struct pipe_context* pipe,
+                            unsigned mode,
+                            unsigned start,
+                            unsigned count);
+
+void r300_swtcl_draw_range_elements(struct pipe_context* pipe,
+                                    struct pipe_buffer* indexBuffer,
+                                    unsigned indexSize,
+                                    unsigned minIndex,
+                                    unsigned maxIndex,
+                                    unsigned mode,
+                                    unsigned start,
+                                    unsigned count);
 
 #endif /* R300_RENDER_H */
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 390b630..287664b 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -21,13 +21,15 @@
  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
 
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
 #include "util/u_memory.h"
 #include "util/u_simple_screen.h"
 
 #include "r300_context.h"
 #include "r300_screen.h"
 #include "r300_texture.h"
-#include "r300_winsys.h"
+
+#include "radeon_winsys.h"
 
 /* Return the identifier behind whom the brave coders responsible for this
  * amalgamation of code, sweat, and duct tape, routinely obscure their names.
@@ -81,6 +83,7 @@
 
     switch (param) {
         case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+        case PIPE_CAP_MAX_COMBINED_SAMPLERS:
             /* XXX I'm told this goes up to 16 */
             return 8;
         case PIPE_CAP_NPOT_TEXTURES:
@@ -140,6 +143,12 @@
             return 0;
         case PIPE_CAP_BLEND_EQUATION_SEPARATE:
             return 1;
+        case PIPE_CAP_SM3:
+            if (r300screen->caps->is_r500) {
+                return 1;
+            } else {
+                return 0;
+            }
         default:
             debug_printf("r300: Implementation error: Bad param %d\n",
                 param);
@@ -219,12 +228,18 @@
 
         /* Z buffer or texture */
         case PIPE_FORMAT_Z16_UNORM:
+            retval = usage &
+                (PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
+                 PIPE_TEXTURE_USAGE_SAMPLER);
+            break;
+
+        /* 24bit Z buffer can only be used as a texture on R500. */
         case PIPE_FORMAT_Z24X8_UNORM:
         /* Z buffer with stencil or texture */
         case PIPE_FORMAT_Z24S8_UNORM:
             retval = usage &
                 (PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
-                 PIPE_TEXTURE_USAGE_SAMPLER);
+                 (is_r500 ? PIPE_TEXTURE_USAGE_SAMPLER : 0));
             break;
 
         /* Definitely unsupported formats. */
@@ -311,14 +326,10 @@
     trans = CALLOC_STRUCT(r300_transfer);
     if (trans) {
         pipe_texture_reference(&trans->transfer.texture, texture);
-        trans->transfer.format = texture->format;
         trans->transfer.x = x;
         trans->transfer.y = y;
         trans->transfer.width = w;
         trans->transfer.height = h;
-        trans->transfer.block = texture->block;
-        trans->transfer.nblocksx = texture->nblocksx[level];
-        trans->transfer.nblocksy = texture->nblocksy[level];
         trans->transfer.stride = r300_texture_get_stride(tex, level);
         trans->transfer.usage = usage;
 
@@ -344,6 +355,7 @@
 {
     struct r300_texture* tex = (struct r300_texture*)transfer->texture;
     char* map;
+    enum pipe_format format = tex->tex.format;
 
     map = pipe_buffer_map(screen, tex->buffer,
                           pipe_transfer_buffer_flags(transfer));
@@ -353,8 +365,8 @@
     }
 
     return map + r300_transfer(transfer)->offset +
-        transfer->y / transfer->block.height * transfer->stride +
-        transfer->x / transfer->block.width * transfer->block.size;
+        transfer->y / util_format_get_blockheight(format) * transfer->stride +
+        transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
 }
 
 static void r300_transfer_unmap(struct pipe_screen* screen,
@@ -372,7 +384,7 @@
     FREE(r300screen);
 }
 
-struct pipe_screen* r300_create_screen(struct r300_winsys* r300_winsys)
+struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys)
 {
     struct r300_screen* r300screen = CALLOC_STRUCT(r300_screen);
     struct r300_capabilities* caps = CALLOC_STRUCT(r300_capabilities);
@@ -380,14 +392,14 @@
     if (!r300screen || !caps)
         return NULL;
 
-    caps->pci_id = r300_winsys->pci_id;
-    caps->num_frag_pipes = r300_winsys->gb_pipes;
-    caps->num_z_pipes = r300_winsys->z_pipes;
+    caps->pci_id = radeon_winsys->pci_id;
+    caps->num_frag_pipes = radeon_winsys->gb_pipes;
+    caps->num_z_pipes = radeon_winsys->z_pipes;
 
     r300_parse_chipset(caps);
 
     r300screen->caps = caps;
-    r300screen->screen.winsys = (struct pipe_winsys*)r300_winsys;
+    r300screen->screen.winsys = (struct pipe_winsys*)radeon_winsys;
     r300screen->screen.destroy = r300_destroy_screen;
     r300screen->screen.get_name = r300_get_name;
     r300screen->screen.get_vendor = r300_get_vendor;
diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h
index 41df31f..2217988 100644
--- a/src/gallium/drivers/r300/r300_screen.h
+++ b/src/gallium/drivers/r300/r300_screen.h
@@ -27,6 +27,8 @@
 
 #include "r300_chipset.h"
 
+struct radeon_winsys;
+
 struct r300_screen {
     /* Parent class */
     struct pipe_screen screen;
@@ -56,6 +58,6 @@
 }
 
 /* Creates a new r300 screen. */
-struct pipe_screen* r300_create_screen(struct r300_winsys* r300_winsys);
+struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys);
 
 #endif /* R300_SCREEN_H */
diff --git a/src/gallium/drivers/r300/r300_shader_semantics.h b/src/gallium/drivers/r300/r300_shader_semantics.h
new file mode 100644
index 0000000..6796841
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_shader_semantics.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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. */
+
+#ifndef R300_SHADER_SEMANTICS_H
+#define R300_SHADER_SEMANTICS_H
+
+#define ATTR_UNUSED             (-1)
+#define ATTR_COLOR_COUNT        2
+#define ATTR_GENERIC_COUNT      16
+
+/* This structure contains information about what attributes are written by VS
+ * or read by FS. (but not both) It's much easier to work with than
+ * tgsi_shader_info.
+ *
+ * The variables contain indices to tgsi_shader_info semantics and those
+ * indices are nothing else than input/output register numbers. */
+struct r300_shader_semantics {
+    int pos;
+    int psize;
+    int color[ATTR_COLOR_COUNT];
+    int bcolor[ATTR_COLOR_COUNT];
+    int generic[ATTR_GENERIC_COUNT];
+    int fog;
+    int wpos;
+};
+
+static INLINE void r300_shader_semantics_reset(
+    struct r300_shader_semantics* info)
+{
+    int i;
+
+    info->pos = ATTR_UNUSED;
+    info->psize = ATTR_UNUSED;
+    info->fog = ATTR_UNUSED;
+    info->wpos = ATTR_UNUSED;
+
+    for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+        info->color[i] = ATTR_UNUSED;
+        info->bcolor[i] = ATTR_UNUSED;
+    }
+
+    for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
+        info->generic[i] = ATTR_UNUSED;
+    }
+}
+
+#endif
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 658a8cb..78764dd 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -1,5 +1,6 @@
 /*
  * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -41,6 +42,120 @@
 /* r300_state: Functions used to intialize state context by translating
  * Gallium state objects into semi-native r300 state objects. */
 
+static boolean blend_discard_if_src_alpha_0(unsigned srcRGB, unsigned srcA,
+                                            unsigned dstRGB, unsigned dstA)
+{
+    /* If the blend equation is ADD or REVERSE_SUBTRACT,
+     * SRC_ALPHA == 0, and the following state is set, the colorbuffer
+     * will not be changed.
+     * Notice that the dst factors are the src factors inverted. */
+    return (srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA ||
+            srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE ||
+            srcRGB == PIPE_BLENDFACTOR_ZERO) &&
+           (srcA == PIPE_BLENDFACTOR_SRC_COLOR ||
+            srcA == PIPE_BLENDFACTOR_SRC_ALPHA ||
+            srcA == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE ||
+            srcA == PIPE_BLENDFACTOR_ZERO) &&
+           (dstRGB == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||
+            dstRGB == PIPE_BLENDFACTOR_ONE) &&
+           (dstA == PIPE_BLENDFACTOR_INV_SRC_COLOR ||
+            dstA == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||
+            dstA == PIPE_BLENDFACTOR_ONE);
+}
+
+static boolean blend_discard_if_src_alpha_1(unsigned srcRGB, unsigned srcA,
+                                            unsigned dstRGB, unsigned dstA)
+{
+    /* If the blend equation is ADD or REVERSE_SUBTRACT,
+     * SRC_ALPHA == 1, and the following state is set, the colorbuffer
+     * will not be changed.
+     * Notice that the dst factors are the src factors inverted. */
+    return (srcRGB == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||
+            srcRGB == PIPE_BLENDFACTOR_ZERO) &&
+           (srcA == PIPE_BLENDFACTOR_INV_SRC_COLOR ||
+            srcA == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||
+            srcA == PIPE_BLENDFACTOR_ZERO) &&
+           (dstRGB == PIPE_BLENDFACTOR_SRC_ALPHA ||
+            dstRGB == PIPE_BLENDFACTOR_ONE) &&
+           (dstA == PIPE_BLENDFACTOR_SRC_COLOR ||
+            dstA == PIPE_BLENDFACTOR_SRC_ALPHA ||
+            dstA == PIPE_BLENDFACTOR_ONE);
+}
+
+static boolean blend_discard_if_src_color_0(unsigned srcRGB, unsigned srcA,
+                                            unsigned dstRGB, unsigned dstA)
+{
+    /* If the blend equation is ADD or REVERSE_SUBTRACT,
+     * SRC_COLOR == (0,0,0), and the following state is set, the colorbuffer
+     * will not be changed.
+     * Notice that the dst factors are the src factors inverted. */
+    return (srcRGB == PIPE_BLENDFACTOR_SRC_COLOR ||
+            srcRGB == PIPE_BLENDFACTOR_ZERO) &&
+           (srcA == PIPE_BLENDFACTOR_ZERO) &&
+           (dstRGB == PIPE_BLENDFACTOR_INV_SRC_COLOR ||
+            dstRGB == PIPE_BLENDFACTOR_ONE) &&
+           (dstA == PIPE_BLENDFACTOR_ONE);
+}
+
+static boolean blend_discard_if_src_color_1(unsigned srcRGB, unsigned srcA,
+                                            unsigned dstRGB, unsigned dstA)
+{
+    /* If the blend equation is ADD or REVERSE_SUBTRACT,
+     * SRC_COLOR == (1,1,1), and the following state is set, the colorbuffer
+     * will not be changed.
+     * Notice that the dst factors are the src factors inverted. */
+    return (srcRGB == PIPE_BLENDFACTOR_INV_SRC_COLOR ||
+            srcRGB == PIPE_BLENDFACTOR_ZERO) &&
+           (srcA == PIPE_BLENDFACTOR_ZERO) &&
+           (dstRGB == PIPE_BLENDFACTOR_SRC_COLOR ||
+            dstRGB == PIPE_BLENDFACTOR_ONE) &&
+           (dstA == PIPE_BLENDFACTOR_ONE);
+}
+
+static boolean blend_discard_if_src_alpha_color_0(unsigned srcRGB, unsigned srcA,
+                                                  unsigned dstRGB, unsigned dstA)
+{
+    /* If the blend equation is ADD or REVERSE_SUBTRACT,
+     * SRC_ALPHA_COLOR == (0,0,0,0), and the following state is set,
+     * the colorbuffer will not be changed.
+     * Notice that the dst factors are the src factors inverted. */
+    return (srcRGB == PIPE_BLENDFACTOR_SRC_COLOR ||
+            srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA ||
+            srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE ||
+            srcRGB == PIPE_BLENDFACTOR_ZERO) &&
+           (srcA == PIPE_BLENDFACTOR_SRC_COLOR ||
+            srcA == PIPE_BLENDFACTOR_SRC_ALPHA ||
+            srcA == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE ||
+            srcA == PIPE_BLENDFACTOR_ZERO) &&
+           (dstRGB == PIPE_BLENDFACTOR_INV_SRC_COLOR ||
+            dstRGB == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||
+            dstRGB == PIPE_BLENDFACTOR_ONE) &&
+           (dstA == PIPE_BLENDFACTOR_INV_SRC_COLOR ||
+            dstA == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||
+            dstA == PIPE_BLENDFACTOR_ONE);
+}
+
+static boolean blend_discard_if_src_alpha_color_1(unsigned srcRGB, unsigned srcA,
+                                                  unsigned dstRGB, unsigned dstA)
+{
+    /* If the blend equation is ADD or REVERSE_SUBTRACT,
+     * SRC_ALPHA_COLOR == (1,1,1,1), and the following state is set,
+     * the colorbuffer will not be changed.
+     * Notice that the dst factors are the src factors inverted. */
+    return (srcRGB == PIPE_BLENDFACTOR_INV_SRC_COLOR ||
+            srcRGB == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||
+            srcRGB == PIPE_BLENDFACTOR_ZERO) &&
+           (srcA == PIPE_BLENDFACTOR_INV_SRC_COLOR ||
+            srcA == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||
+            srcA == PIPE_BLENDFACTOR_ZERO) &&
+           (dstRGB == PIPE_BLENDFACTOR_SRC_COLOR ||
+            dstRGB == PIPE_BLENDFACTOR_SRC_ALPHA ||
+            dstRGB == PIPE_BLENDFACTOR_ONE) &&
+           (dstA == PIPE_BLENDFACTOR_SRC_COLOR ||
+            dstA == PIPE_BLENDFACTOR_SRC_ALPHA ||
+            dstA == PIPE_BLENDFACTOR_ONE);
+}
+
 /* Create a new blend state based on the CSO blend state.
  *
  * This encompasses alpha blending, logic/raster ops, and blend dithering. */
@@ -66,7 +181,11 @@
             ( r300_translate_blend_factor(srcRGB) << R300_SRC_BLEND_SHIFT) |
             ( r300_translate_blend_factor(dstRGB) << R300_DST_BLEND_SHIFT);
 
-        /* optimization: some operations do not require the destination color */
+        /* Optimization: some operations do not require the destination color.
+         *
+         * When SRC_ALPHA_SATURATE is used, colorbuffer reads must be enabled,
+         * otherwise blending gives incorrect results. It seems to be
+         * a hardware bug. */
         if (eqRGB == PIPE_BLEND_MIN || eqA == PIPE_BLEND_MIN ||
             eqRGB == PIPE_BLEND_MAX || eqA == PIPE_BLEND_MAX ||
             dstRGB != PIPE_BLENDFACTOR_ZERO ||
@@ -78,11 +197,81 @@
             srcA == PIPE_BLENDFACTOR_DST_COLOR ||
             srcA == PIPE_BLENDFACTOR_DST_ALPHA ||
             srcA == PIPE_BLENDFACTOR_INV_DST_COLOR ||
-            srcA == PIPE_BLENDFACTOR_INV_DST_ALPHA)
+            srcA == PIPE_BLENDFACTOR_INV_DST_ALPHA ||
+            srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE) {
+            /* Enable reading from the colorbuffer. */
             blend->blend_control |= R300_READ_ENABLE;
 
-        /* XXX implement the optimization with DISCARD_SRC_PIXELS*/
-        /* XXX implement the optimization with SRC_ALPHA_?_NO_READ */
+            if (r300_screen(r300_context(pipe)->context.screen)->caps->is_r500) {
+                /* Optimization: Depending on incoming pixels, we can
+                 * conditionally disable the reading in hardware... */
+                if (eqRGB != PIPE_BLEND_MIN && eqA != PIPE_BLEND_MIN &&
+                    eqRGB != PIPE_BLEND_MAX && eqA != PIPE_BLEND_MAX) {
+                    /* Disable reading if SRC_ALPHA == 0. */
+                    if ((dstRGB == PIPE_BLENDFACTOR_SRC_ALPHA ||
+                         dstRGB == PIPE_BLENDFACTOR_ZERO) &&
+                        (dstA == PIPE_BLENDFACTOR_SRC_COLOR ||
+                         dstA == PIPE_BLENDFACTOR_SRC_ALPHA ||
+                         dstA == PIPE_BLENDFACTOR_ZERO)) {
+                         blend->blend_control |= R500_SRC_ALPHA_0_NO_READ;
+                    }
+
+                    /* Disable reading if SRC_ALPHA == 1. */
+                    if ((dstRGB == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||
+                         dstRGB == PIPE_BLENDFACTOR_ZERO) &&
+                        (dstA == PIPE_BLENDFACTOR_INV_SRC_COLOR ||
+                         dstA == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||
+                         dstA == PIPE_BLENDFACTOR_ZERO)) {
+                         blend->blend_control |= R500_SRC_ALPHA_1_NO_READ;
+                    }
+                }
+            }
+        }
+
+        /* Optimization: discard pixels which don't change the colorbuffer.
+         *
+         * The code below is non-trivial and some math is involved.
+         *
+         * Discarding pixels must be disabled when FP16 AA is enabled.
+         * This is a hardware bug. Also, this implementation wouldn't work
+         * with FP blending enabled and equation clamping disabled.
+         *
+         * Equations other than ADD are rarely used and therefore won't be
+         * optimized. */
+        if ((eqRGB == PIPE_BLEND_ADD || eqRGB == PIPE_BLEND_REVERSE_SUBTRACT) &&
+            (eqA == PIPE_BLEND_ADD || eqA == PIPE_BLEND_REVERSE_SUBTRACT)) {
+            /* ADD: X+Y
+             * REVERSE_SUBTRACT: Y-X
+             *
+             * The idea is:
+             * If X = src*srcFactor = 0 and Y = dst*dstFactor = 1,
+             * then CB will not be changed.
+             *
+             * Given the srcFactor and dstFactor variables, we can derive
+             * what src and dst should be equal to and discard appropriate
+             * pixels.
+             */
+            if (blend_discard_if_src_alpha_0(srcRGB, srcA, dstRGB, dstA)) {
+                blend->blend_control |= R300_DISCARD_SRC_PIXELS_SRC_ALPHA_0;
+            } else if (blend_discard_if_src_alpha_1(srcRGB, srcA,
+                                                    dstRGB, dstA)) {
+                blend->blend_control |= R300_DISCARD_SRC_PIXELS_SRC_ALPHA_1;
+            } else if (blend_discard_if_src_color_0(srcRGB, srcA,
+                                                    dstRGB, dstA)) {
+                blend->blend_control |= R300_DISCARD_SRC_PIXELS_SRC_COLOR_0;
+            } else if (blend_discard_if_src_color_1(srcRGB, srcA,
+                                                    dstRGB, dstA)) {
+                blend->blend_control |= R300_DISCARD_SRC_PIXELS_SRC_COLOR_1;
+            } else if (blend_discard_if_src_alpha_color_0(srcRGB, srcA,
+                                                          dstRGB, dstA)) {
+                blend->blend_control |=
+                    R300_DISCARD_SRC_PIXELS_SRC_ALPHA_COLOR_0;
+            } else if (blend_discard_if_src_alpha_color_1(srcRGB, srcA,
+                                                          dstRGB, dstA)) {
+                blend->blend_control |=
+                    R300_DISCARD_SRC_PIXELS_SRC_ALPHA_COLOR_1;
+            }
+        }
 
         /* separate alpha */
         if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) {
@@ -128,8 +317,8 @@
 {
     struct r300_context* r300 = r300_context(pipe);
 
-    r300->blend_state = (struct r300_blend_state*)state;
-    r300->dirty_state |= R300_NEW_BLEND;
+    r300->blend_state.state = state;
+    r300->blend_state.dirty = TRUE;
 }
 
 /* Free blend state. */
@@ -151,19 +340,22 @@
                                  const struct pipe_blend_color* color)
 {
     struct r300_context* r300 = r300_context(pipe);
+    struct r300_blend_color_state* state =
+        (struct r300_blend_color_state*)r300->blend_color_state.state;
+    union util_color uc;
 
-    util_pack_color(color->color, PIPE_FORMAT_A8R8G8B8_UNORM,
-            &r300->blend_color_state->blend_color);
+    util_pack_color(color->color, PIPE_FORMAT_A8R8G8B8_UNORM, &uc);
+    state->blend_color = uc.ui;
 
     /* XXX if FP16 blending is enabled, we should use the FP16 format */
-    r300->blend_color_state->blend_color_red_alpha =
+    state->blend_color_red_alpha =
         float_to_fixed10(color->color[0]) |
         (float_to_fixed10(color->color[3]) << 16);
-    r300->blend_color_state->blend_color_green_blue =
+    state->blend_color_green_blue =
         float_to_fixed10(color->color[2]) |
         (float_to_fixed10(color->color[1]) << 16);
 
-    r300->dirty_state |= R300_NEW_BLEND_COLOR;
+    r300->blend_color_state.dirty = TRUE;
 }
 
 static void r300_set_clip_state(struct pipe_context* pipe,
@@ -172,8 +364,8 @@
     struct r300_context* r300 = r300_context(pipe);
 
     if (r300_screen(pipe->screen)->caps->has_tcl) {
-        r300->clip_state = *state;
-        r300->dirty_state |= R300_NEW_CLIP;
+        memcpy(r300->clip_state.state, state, sizeof(struct pipe_clip_state));
+        r300->clip_state.dirty = TRUE;
     } else {
         draw_flush(r300->draw);
         draw_set_clip_state(r300->draw, state);
@@ -271,8 +463,8 @@
 {
     struct r300_context* r300 = r300_context(pipe);
 
-    r300->dsa_state = (struct r300_dsa_state*)state;
-    r300->dirty_state |= R300_NEW_DSA;
+    r300->dsa_state.state = state;
+    r300->dsa_state.dirty = TRUE;
 }
 
 /* Free DSA state. */
@@ -282,11 +474,26 @@
     FREE(state);
 }
 
-static void r300_set_edgeflags(struct pipe_context* pipe,
-                               const unsigned* bitfield)
+static void r300_set_scissor_regs(const struct pipe_scissor_state* state,
+                                  struct r300_scissor_regs *scissor,
+                                  boolean is_r500)
 {
-    /* XXX you know it's bad when i915 has this blank too */
-    /* XXX and even worse, I have no idea WTF the bitfield is */
+    if (is_r500) {
+        scissor->top_left =
+            (state->minx << R300_SCISSORS_X_SHIFT) |
+            (state->miny << R300_SCISSORS_Y_SHIFT);
+        scissor->bottom_right =
+            ((state->maxx - 1) << R300_SCISSORS_X_SHIFT) |
+            ((state->maxy - 1) << R300_SCISSORS_Y_SHIFT);
+    } else {
+        /* Offset of 1440 in non-R500 chipsets. */
+        scissor->top_left =
+            ((state->minx + 1440) << R300_SCISSORS_X_SHIFT) |
+            ((state->miny + 1440) << R300_SCISSORS_Y_SHIFT);
+        scissor->bottom_right =
+            (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) |
+            (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT);
+    }
 }
 
 static void
@@ -294,6 +501,9 @@
                                const struct pipe_framebuffer_state* state)
 {
     struct r300_context* r300 = r300_context(pipe);
+    struct r300_scissor_state* scissor =
+        (struct r300_scissor_state*)r300->scissor_state.state;
+    struct pipe_scissor_state pscissor;
 
     if (r300->draw) {
         draw_flush(r300->draw);
@@ -301,7 +511,19 @@
 
     r300->framebuffer_state = *state;
 
+    /* XXX Arg. This is silly. */
+    pscissor.minx = pscissor.miny = 0;
+    pscissor.maxx = state->width;
+    pscissor.maxy = state->height;
+    r300_set_scissor_regs(&pscissor, &scissor->framebuffer,
+                          r300_screen(r300->context.screen)->caps->is_r500);
+
+    /* Don't rely on the order of states being set for the first time. */
     r300->dirty_state |= R300_NEW_FRAMEBUFFERS;
+
+    r300->blend_state.dirty = TRUE;
+    r300->dsa_state.dirty = TRUE;
+    r300->scissor_state.dirty = TRUE;
 }
 
 /* Create fragment shader state. */
@@ -317,6 +539,7 @@
     fs->state.tokens = tgsi_dup_tokens(shader->tokens);
 
     tgsi_scan_shader(shader->tokens, &fs->info);
+    r300_shader_read_fs_inputs(&fs->info, &fs->inputs);
 
     return (void*)fs;
 }
@@ -330,11 +553,14 @@
     if (fs == NULL) {
         r300->fs = NULL;
         return;
-    } else if (!fs->translated) {
-        r300_translate_fragment_shader(r300, fs);
     }
 
     r300->fs = fs;
+    r300_pick_fragment_shader(r300);
+
+    if (r300->vs && r300_vertex_shader_setup_wpos(r300)) {
+        r300->dirty_state |= R300_NEW_VERTEX_FORMAT;
+    }
 
     r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS;
 }
@@ -343,7 +569,14 @@
 static void r300_delete_fs_state(struct pipe_context* pipe, void* shader)
 {
     struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;
-    rc_constants_destroy(&fs->code.constants);
+    struct r300_fragment_shader_code *tmp, *ptr = fs->first;
+
+    while (ptr) {
+        tmp = ptr;
+        ptr = ptr->next;
+        rc_constants_destroy(&tmp->code.constants);
+        FREE(tmp);
+    }
     FREE((void*)fs->state.tokens);
     FREE(shader);
 }
@@ -369,8 +602,6 @@
     /* Copy rasterizer state for Draw. */
     rs->rs = *state;
 
-    rs->enable_vte = !state->bypass_vs_clip_and_viewport;
-
 #ifdef PIPE_ARCH_LITTLE_ENDIAN
     rs->vap_control_status = R300_VC_NO_SWAP;
 #else
@@ -382,8 +613,6 @@
     if (state->bypass_vs_clip_and_viewport ||
             !r300_screen(pipe->screen)->caps->has_tcl) {
         rs->vap_control_status |= R300_VAP_TCL_BYPASS;
-    } else {
-        rs->rs.bypass_vs_clip_and_viewport = TRUE;
     }
 
     rs->point_size = pack_float_16_6x(state->point_size) |
@@ -474,10 +703,6 @@
         rs->color_control = R300_SHADE_MODEL_SMOOTH;
     }
 
-    if (!state->flatshade_first) {
-        rs->color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
-    }
-
     return (void*)rs;
 }
 
@@ -492,12 +717,19 @@
         draw_set_rasterizer_state(r300->draw, &rs->rs);
     }
 
-    r300->rs_state = rs;
+    r300->tcl_bypass = rs->rs.bypass_vs_clip_and_viewport;
+
+    r300->rs_state.state = rs;
+    r300->rs_state.dirty = TRUE;
+    /* XXX Why is this still needed, dammit!? */
+    r300->scissor_state.dirty = TRUE;
+    r300->viewport_state.dirty = TRUE;
+
     /* XXX Clean these up when we move to atom emits */
-    r300->dirty_state |= R300_NEW_RASTERIZER;
     r300->dirty_state |= R300_NEW_RS_BLOCK;
-    r300->dirty_state |= R300_NEW_SCISSOR;
-    r300->dirty_state |= R300_NEW_VIEWPORT;
+    if (r300->fs && r300->fs->inputs.wpos != ATTR_UNUSED) {
+        r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+    }
 }
 
 /* Free rasterizer state. */
@@ -513,6 +745,9 @@
     struct r300_context* r300 = r300_context(pipe);
     struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state);
     int lod_bias;
+    union util_color uc;
+
+    sampler->state = *state;
 
     sampler->filter0 |=
         (r300_translate_wrap(state->wrap_s) << R300_TX_WRAP_S_SHIFT) |
@@ -521,7 +756,13 @@
 
     sampler->filter0 |= r300_translate_tex_filters(state->min_img_filter,
                                                    state->mag_img_filter,
-                                                   state->min_mip_filter);
+                                                   state->min_mip_filter,
+                                                   state->max_anisotropy > 1.0);
+
+    /* Unfortunately, r300-r500 don't support floating-point mipmap lods. */
+    /* We must pass these to the emit function to clamp them properly. */
+    sampler->min_lod = MAX2((unsigned)state->min_lod, 0);
+    sampler->max_lod = MAX2((unsigned)ceilf(state->max_lod), 0);
 
     lod_bias = CLAMP((int)(state->lod_bias * 32), -(1 << 9), (1 << 9) - 1);
 
@@ -529,8 +770,8 @@
 
     sampler->filter1 |= r300_anisotropy(state->max_anisotropy);
 
-    util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM,
-                    &sampler->border_color);
+    util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM, &uc);
+    sampler->border_color = uc.ui;
 
     /* R500-specific fixups and optimizations */
     if (r300_screen(r300->context.screen)->caps->is_r500) {
@@ -559,6 +800,20 @@
     }
 
     r300->sampler_count = count;
+
+    /* Pick a fragment shader based on the texture compare state. */
+    if (r300->fs && (r300->dirty_state & R300_ANY_NEW_SAMPLERS)) {
+        if (r300_pick_fragment_shader(r300)) {
+            r300->dirty_state |= R300_NEW_FRAGMENT_SHADER |
+                                 R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+        }
+    }
+}
+
+static void r300_lacks_vertex_textures(struct pipe_context* pipe,
+                                       unsigned count,
+                                       void** states)
+{
 }
 
 static void r300_delete_sampler_state(struct pipe_context* pipe, void* state)
@@ -571,18 +826,26 @@
                                       struct pipe_texture** texture)
 {
     struct r300_context* r300 = r300_context(pipe);
+    boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
     int i;
 
     /* XXX magic num */
     if (count > 8) {
         return;
     }
-
+    
     for (i = 0; i < count; i++) {
         if (r300->textures[i] != (struct r300_texture*)texture[i]) {
             pipe_texture_reference((struct pipe_texture**)&r300->textures[i],
                 texture[i]);
             r300->dirty_state |= (R300_NEW_TEXTURE << i);
+
+            /* R300-specific - set the texrect factor in a fragment shader */
+            if (!is_r500 && r300->textures[i]->is_npot) {
+                /* XXX It would be nice to re-emit just 1 constant,
+                 * XXX not all of them */
+                r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+            }
         }
     }
 
@@ -601,61 +864,54 @@
                                    const struct pipe_scissor_state* state)
 {
     struct r300_context* r300 = r300_context(pipe);
+    struct r300_scissor_state* scissor =
+        (struct r300_scissor_state*)r300->scissor_state.state;
 
-    if (r300_screen(r300->context.screen)->caps->is_r500) {
-        r300->scissor_state->scissor_top_left =
-            (state->minx << R300_SCISSORS_X_SHIFT) |
-            (state->miny << R300_SCISSORS_Y_SHIFT);
-        r300->scissor_state->scissor_bottom_right =
-            ((state->maxx - 1) << R300_SCISSORS_X_SHIFT) |
-            ((state->maxy - 1) << R300_SCISSORS_Y_SHIFT);
-    } else {
-        /* Offset of 1440 in non-R500 chipsets. */
-        r300->scissor_state->scissor_top_left =
-            ((state->minx + 1440) << R300_SCISSORS_X_SHIFT) |
-            ((state->miny + 1440) << R300_SCISSORS_Y_SHIFT);
-        r300->scissor_state->scissor_bottom_right =
-            (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) |
-            (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT);
-    }
+    r300_set_scissor_regs(state, &scissor->scissor,
+                          r300_screen(r300->context.screen)->caps->is_r500);
 
-    r300->dirty_state |= R300_NEW_SCISSOR;
+    r300->scissor_state.dirty = TRUE;
 }
 
 static void r300_set_viewport_state(struct pipe_context* pipe,
                                     const struct pipe_viewport_state* state)
 {
     struct r300_context* r300 = r300_context(pipe);
+    struct r300_viewport_state* viewport =
+        (struct r300_viewport_state*)r300->viewport_state.state;
 
     /* Do the transform in HW. */
-    r300->viewport_state->vte_control = R300_VTX_W0_FMT;
+    viewport->vte_control = R300_VTX_W0_FMT;
 
     if (state->scale[0] != 1.0f) {
-        r300->viewport_state->xscale = state->scale[0];
-        r300->viewport_state->vte_control |= R300_VPORT_X_SCALE_ENA;
+        viewport->xscale = state->scale[0];
+        viewport->vte_control |= R300_VPORT_X_SCALE_ENA;
     }
     if (state->scale[1] != 1.0f) {
-        r300->viewport_state->yscale = state->scale[1];
-        r300->viewport_state->vte_control |= R300_VPORT_Y_SCALE_ENA;
+        viewport->yscale = state->scale[1];
+        viewport->vte_control |= R300_VPORT_Y_SCALE_ENA;
     }
     if (state->scale[2] != 1.0f) {
-        r300->viewport_state->zscale = state->scale[2];
-        r300->viewport_state->vte_control |= R300_VPORT_Z_SCALE_ENA;
+        viewport->zscale = state->scale[2];
+        viewport->vte_control |= R300_VPORT_Z_SCALE_ENA;
     }
     if (state->translate[0] != 0.0f) {
-        r300->viewport_state->xoffset = state->translate[0];
-        r300->viewport_state->vte_control |= R300_VPORT_X_OFFSET_ENA;
+        viewport->xoffset = state->translate[0];
+        viewport->vte_control |= R300_VPORT_X_OFFSET_ENA;
     }
     if (state->translate[1] != 0.0f) {
-        r300->viewport_state->yoffset = state->translate[1];
-        r300->viewport_state->vte_control |= R300_VPORT_Y_OFFSET_ENA;
+        viewport->yoffset = state->translate[1];
+        viewport->vte_control |= R300_VPORT_Y_OFFSET_ENA;
     }
     if (state->translate[2] != 0.0f) {
-        r300->viewport_state->zoffset = state->translate[2];
-        r300->viewport_state->vte_control |= R300_VPORT_Z_OFFSET_ENA;
+        viewport->zoffset = state->translate[2];
+        viewport->vte_control |= R300_VPORT_Z_OFFSET_ENA;
     }
 
-    r300->dirty_state |= R300_NEW_VIEWPORT;
+    r300->viewport_state.dirty = TRUE;
+    if (r300->fs && r300->fs->inputs.wpos != ATTR_UNUSED) {
+        r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+    }
 }
 
 static void r300_set_vertex_buffers(struct pipe_context* pipe,
@@ -664,15 +920,16 @@
 {
     struct r300_context* r300 = r300_context(pipe);
 
-    memcpy(r300->vertex_buffers, buffers,
+    memcpy(r300->vertex_buffer, buffers,
         sizeof(struct pipe_vertex_buffer) * count);
-
     r300->vertex_buffer_count = count;
 
     if (r300->draw) {
         draw_flush(r300->draw);
         draw_set_vertex_buffers(r300->draw, count, buffers);
     }
+
+    r300->dirty_state |= R300_NEW_VERTEX_FORMAT;
 }
 
 static void r300_set_vertex_elements(struct pipe_context* pipe,
@@ -681,9 +938,9 @@
 {
     struct r300_context* r300 = r300_context(pipe);
 
-    memcpy(r300->vertex_elements, elements,
-        sizeof(struct pipe_vertex_element) * count);
-
+    memcpy(r300->vertex_element,
+           elements,
+           sizeof(struct pipe_vertex_element) * count);
     r300->vertex_element_count = count;
 
     if (r300->draw) {
@@ -705,9 +962,6 @@
 
         tgsi_scan_shader(shader->tokens, &vs->info);
 
-        /* Appease Draw. */
-        vs->draw = draw_create_vertex_shader(r300->draw, shader);
-
         return (void*)vs;
     } else {
         return draw_create_vertex_shader(r300->draw, shader);
@@ -718,8 +972,6 @@
 {
     struct r300_context* r300 = r300_context(pipe);
 
-    draw_flush(r300->draw);
-
     if (r300_screen(pipe->screen)->caps->has_tcl) {
         struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
 
@@ -730,10 +982,16 @@
             r300_translate_vertex_shader(r300, vs);
         }
 
-        draw_bind_vertex_shader(r300->draw, vs->draw);
         r300->vs = vs;
-        r300->dirty_state |= R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS;
+        if (r300->fs) {
+            r300_vertex_shader_setup_wpos(r300);
+        }
+
+        r300->dirty_state |=
+            R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS |
+            R300_NEW_VERTEX_FORMAT;
     } else {
+        draw_flush(r300->draw);
         draw_bind_vertex_shader(r300->draw,
                 (struct draw_vertex_shader*)shader);
     }
@@ -747,7 +1005,6 @@
         struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
 
         rc_constants_destroy(&vs->code.constants);
-        draw_delete_vertex_shader(r300->draw, vs->draw);
         FREE((void*)vs->state.tokens);
         FREE(shader);
     } else {
@@ -797,8 +1054,6 @@
     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_edgeflags = r300_set_edgeflags;
-
     r300->context.set_framebuffer_state = r300_set_framebuffer_state;
 
     r300->context.create_fs_state = r300_create_fs_state;
@@ -812,10 +1067,11 @@
     r300->context.delete_rasterizer_state = r300_delete_rs_state;
 
     r300->context.create_sampler_state = r300_create_sampler_state;
-    r300->context.bind_sampler_states = r300_bind_sampler_states;
+    r300->context.bind_fragment_sampler_states = r300_bind_sampler_states;
+    r300->context.bind_vertex_sampler_states = r300_lacks_vertex_textures;
     r300->context.delete_sampler_state = r300_delete_sampler_state;
 
-    r300->context.set_sampler_textures = r300_set_sampler_textures;
+    r300->context.set_fragment_sampler_textures = r300_set_sampler_textures;
 
     r300->context.set_scissor_state = r300_set_scissor_state;
 
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 7d000e9..1928464 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -1,5 +1,6 @@
 /*
  * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -28,6 +29,7 @@
 #include "r300_context.h"
 #include "r300_fs.h"
 #include "r300_screen.h"
+#include "r300_shader_semantics.h"
 #include "r300_state_derived.h"
 #include "r300_state_inlines.h"
 #include "r300_vs.h"
@@ -47,8 +49,8 @@
 
 unsigned r300_shader_key_hash(void* key) {
     struct r300_shader_key* shader_key = (struct r300_shader_key*)key;
-    unsigned vs = (unsigned)shader_key->vs;
-    unsigned fs = (unsigned)shader_key->fs;
+    unsigned vs = (intptr_t)shader_key->vs;
+    unsigned fs = (intptr_t)shader_key->fs;
 
     return (vs << 16) | (fs & 0xffff);
 }
@@ -61,200 +63,152 @@
         (shader_key1->fs == shader_key2->fs);
 }
 
-/* Set up the vs_tab and routes. */
-static void r300_vs_tab_routes(struct r300_context* r300,
-                               struct r300_vertex_format* vformat)
+static void r300_draw_emit_attrib(struct r300_context* r300,
+                                  enum attrib_emit emit,
+                                  enum interp_mode interp,
+                                  int index)
 {
-    struct r300_screen* r300screen = r300_screen(r300->context.screen);
-    struct vertex_info* vinfo = &vformat->vinfo;
-    int* tab = vformat->vs_tab;
-    boolean pos = FALSE, psize = FALSE, fog = FALSE;
-    int i, texs = 0, cols = 0;
-    struct tgsi_shader_info* info;
+    struct tgsi_shader_info* info = &r300->vs->info;
+    int output;
 
-    if (r300screen->caps->has_tcl) {
-        /* Use vertex shader to determine required routes. */
-        info = &r300->vs->info;
+    output = draw_find_shader_output(r300->draw,
+                                     info->output_semantic_name[index],
+                                     info->output_semantic_index[index]);
+    draw_emit_vertex_attr(&r300->vertex_info->vinfo, emit, interp, output);
+}
+
+static void r300_draw_emit_all_attribs(struct r300_context* r300)
+{
+    struct r300_shader_semantics* vs_outputs = &r300->vs->outputs;
+    int i, gen_count;
+
+    /* Position. */
+    if (vs_outputs->pos != ATTR_UNUSED) {
+        r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
+                              vs_outputs->pos);
     } else {
-        /* Use fragment shader to determine required routes. */
-        info = &r300->fs->info;
+        assert(0);
     }
 
-    assert(info->num_inputs <= 16);
+    /* Point size. */
+    if (vs_outputs->psize != ATTR_UNUSED) {
+        r300_draw_emit_attrib(r300, EMIT_1F_PSIZE, INTERP_POS,
+                              vs_outputs->psize);
+    }
 
-    if (!r300screen->caps->has_tcl || !r300->rs_state->enable_vte)
-    {
-        for (i = 0; i < info->num_inputs; i++) {
-            switch (r300->vs->code.inputs[i]) {
-                case TGSI_SEMANTIC_POSITION:
-                    pos = TRUE;
-                    tab[i] = 0;
-                    break;
-                case TGSI_SEMANTIC_COLOR:
-                    tab[i] = 2 + cols;
-                    cols++;
-                    break;
-                case TGSI_SEMANTIC_PSIZE:
-                    assert(psize == FALSE);
-                    psize = TRUE;
-                    tab[i] = 15;
-                    break;
-                case TGSI_SEMANTIC_FOG:
-                    assert(fog == FALSE);
-                    fog = TRUE;
-                    /* Fall through */
-                case TGSI_SEMANTIC_GENERIC:
-                    tab[i] = 6 + texs;
-                    texs++;
-                    break;
-                default:
-                    debug_printf("r300: Unknown vertex input %d\n",
-                        info->input_semantic_name[i]);
-                    break;
-            }
+    /* Colors. */
+    for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+        if (vs_outputs->color[i] != ATTR_UNUSED) {
+            r300_draw_emit_attrib(r300, EMIT_4F, INTERP_LINEAR,
+                                  vs_outputs->color[i]);
         }
     }
-    else
-    {
-        /* Just copy vert attribs over as-is. */
-        for (i = 0; i < info->num_inputs; i++) {
-            tab[i] = i;
-        }
 
-        for (i = 0; i < info->num_outputs; i++) {
-            switch (info->output_semantic_name[i]) {
-                case TGSI_SEMANTIC_POSITION:
-                    pos = TRUE;
-                    break;
-                case TGSI_SEMANTIC_COLOR:
-                    cols++;
-                    break;
-                case TGSI_SEMANTIC_PSIZE:
-                    psize = TRUE;
-                    break;
-                case TGSI_SEMANTIC_FOG:
-                    fog = TRUE;
-                    /* Fall through */
-                case TGSI_SEMANTIC_GENERIC:
-                    texs++;
-                    break;
-                default:
-                    debug_printf("r300: Unknown vertex output %d\n",
-                        info->output_semantic_name[i]);
-                    break;
-            }
+    /* XXX Back-face colors. */
+
+    /* Texture coordinates. */
+    gen_count = 0;
+    for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
+        if (vs_outputs->generic[i] != ATTR_UNUSED) {
+            r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
+                                  vs_outputs->generic[i]);
+            gen_count++;
         }
     }
 
+    /* Fog coordinates. */
+    if (vs_outputs->fog != ATTR_UNUSED) {
+        r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
+                              vs_outputs->fog);
+        gen_count++;
+    }
+
     /* XXX magic */
-    assert(texs <= 8);
-
-    /* Do the actual vertex_info setup.
-     *
-     * vertex_info has four uints of hardware-specific data in it.
-     * vinfo.hwfmt[0] is R300_VAP_VTX_STATE_CNTL
-     * vinfo.hwfmt[1] is R300_VAP_VSM_VTX_ASSM
-     * vinfo.hwfmt[2] is R300_VAP_OUTPUT_VTX_FMT_0
-     * vinfo.hwfmt[3] is R300_VAP_OUTPUT_VTX_FMT_1 */
-
-    vinfo->hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */
-
-    /* We need to add vertex position attribute only for SW TCL case,
-     * for HW TCL case it could be generated by vertex shader */
-    if (!pos && !r300screen->caps->has_tcl) {
-        debug_printf("r300: Forcing vertex position attribute emit...\n");
-        /* Make room for the position attribute
-         * at the beginning of the tab. */
-        for (i = 15; i > 0; i--) {
-            tab[i] = tab[i-1];
-        }
-        tab[0] = 0;
-    }
-    draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE,
-        draw_find_vs_output(r300->draw, TGSI_SEMANTIC_POSITION, 0));
-    vinfo->hwfmt[1] |= R300_INPUT_CNTL_POS;
-    vinfo->hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
-
-    if (psize) {
-        draw_emit_vertex_attr(vinfo, EMIT_1F_PSIZE, INTERP_POS,
-            draw_find_vs_output(r300->draw, TGSI_SEMANTIC_PSIZE, 0));
-        vinfo->hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
-    }
-
-    for (i = 0; i < cols; i++) {
-        draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR,
-            draw_find_vs_output(r300->draw, TGSI_SEMANTIC_COLOR, i));
-        vinfo->hwfmt[1] |= R300_INPUT_CNTL_COLOR;
-        vinfo->hwfmt[2] |= (R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i);
-    }
-
-    /* Init i right here, increment it if fog is enabled.
-     * This gets around a double-increment problem. */
-    i = 0;
-
-    if (fog) {
-        i++;
-        draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE,
-            draw_find_vs_output(r300->draw, TGSI_SEMANTIC_FOG, 0));
-        vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);
-        vinfo->hwfmt[3] |= (4 << (3 * i));
-    }
-
-    for (; i < texs; i++) {
-        draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE,
-            draw_find_vs_output(r300->draw, TGSI_SEMANTIC_GENERIC, i));
-        vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);
-        vinfo->hwfmt[3] |= (4 << (3 * i));
-    }
-
-    /* Handle the case where the vertex shader will be generating some of
-     * the attribs based on its inputs. */
-    if (r300screen->caps->has_tcl &&
-            info->num_inputs < info->num_outputs) {
-        vinfo->num_attribs = info->num_inputs;
-    }
-
-    draw_compute_vertex_size(vinfo);
+    assert(gen_count <= 8);
 }
 
 /* Update the PSC tables. */
-static void r300_vertex_psc(struct r300_context* r300,
-                            struct r300_vertex_format* vformat)
+static void r300_vertex_psc(struct r300_context* r300)
 {
-    struct r300_screen* r300screen = r300_screen(r300->context.screen);
+    struct r300_vertex_info *vformat = r300->vertex_info;
+    uint16_t type, swizzle;
+    enum pipe_format format;
+    unsigned i;
+    int identity[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+    int* stream_tab;
+
+    /* If TCL is bypassed, map vertex streams to equivalent VS output
+     * locations. */
+    if (r300->tcl_bypass) {
+        stream_tab = r300->vs->stream_loc_notcl;
+    } else {
+        stream_tab = identity;
+    }
+
+    /* Vertex shaders have no semantics on their inputs,
+     * so PSC should just route stuff based on the vertex elements,
+     * and not on attrib information. */
+    DBG(r300, DBG_DRAW, "r300: vs expects %d attribs, routing %d elements"
+            " in psc\n",
+            r300->vs->info.num_inputs,
+            r300->vertex_element_count);
+
+    for (i = 0; i < r300->vertex_element_count; i++) {
+        format = r300->vertex_element[i].src_format;
+
+        type = r300_translate_vertex_data_type(format) |
+            (stream_tab[i] << R300_DST_VEC_LOC_SHIFT);
+        swizzle = r300_translate_vertex_data_swizzle(format);
+
+        if (i & 1) {
+            vformat->vap_prog_stream_cntl[i >> 1] |= type << 16;
+            vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
+        } else {
+            vformat->vap_prog_stream_cntl[i >> 1] |= type;
+            vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
+        }
+    }
+
+    assert(i <= 15);
+
+    /* Set the last vector in the PSC. */
+    if (i) {
+        i -= 1;
+    }
+    vformat->vap_prog_stream_cntl[i >> 1] |=
+        (R300_LAST_VEC << (i & 1 ? 16 : 0));
+}
+
+/* Update the PSC tables for SW TCL, using Draw. */
+static void r300_swtcl_vertex_psc(struct r300_context* r300)
+{
+    struct r300_vertex_info *vformat = r300->vertex_info;
     struct vertex_info* vinfo = &vformat->vinfo;
-    int* tab = vformat->vs_tab;
     uint16_t type, swizzle;
     enum pipe_format format;
     unsigned i, attrib_count;
+    int* vs_output_tab = r300->vs->stream_loc_notcl;
 
-    /* Vertex shaders have no semantics on their inputs,
-     * so PSC should just route stuff based on their info,
-     * and not on attrib information. */
-    if (r300screen->caps->has_tcl) {
-        attrib_count = r300->vs->info.num_inputs;
-        DBG(r300, DBG_DRAW, "r300: routing %d attribs in psc for vs\n",
-                attrib_count);
-    } else {
-        attrib_count = vinfo->num_attribs;
-        DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count);
-        for (i = 0; i < attrib_count; i++) {
-            DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d,"
-                   " tab %d\n", vinfo->attrib[i].src_index,
-                   vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
-                   tab[i]);
-        }
+    /* For each Draw attribute, route it to the fragment shader according
+     * to the vs_output_tab. */
+    attrib_count = vinfo->num_attribs;
+    DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count);
+    for (i = 0; i < attrib_count; i++) {
+        DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d,"
+               " vs_output_tab %d\n", vinfo->attrib[i].src_index,
+               vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
+               vs_output_tab[i]);
     }
 
     for (i = 0; i < attrib_count; i++) {
         /* Make sure we have a proper destination for our attribute. */
-        assert(tab[i] != -1);
+        assert(vs_output_tab[i] != -1);
 
         format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
 
         /* Obtain the type of data in this attribute. */
         type = r300_translate_vertex_data_type(format) |
-            tab[i] << R300_DST_VEC_LOC_SHIFT;
+            vs_output_tab[i] << R300_DST_VEC_LOC_SHIFT;
 
         /* Obtain the swizzle for this attribute. Note that the default
          * swizzle in the hardware is not XYZW! */
@@ -263,12 +217,10 @@
         /* Add the attribute to the PSC table. */
         if (i & 1) {
             vformat->vap_prog_stream_cntl[i >> 1] |= type << 16;
-
             vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
         } else {
-            vformat->vap_prog_stream_cntl[i >> 1] |= type <<  0;
-
-            vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 0;
+            vformat->vap_prog_stream_cntl[i >> 1] |= type;
+            vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
         }
     }
 
@@ -280,188 +232,216 @@
         (R300_LAST_VEC << (i & 1 ? 16 : 0));
 }
 
-/* Set up the mappings from GB to US, for RS block. */
-static void r300_update_fs_tab(struct r300_context* r300,
-                               struct r300_vertex_format* vformat)
+static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr,
+                        boolean swizzle_0001)
 {
-    struct tgsi_shader_info* info = &r300->fs->info;
-    int i, cols = 0, texs = 0, cols_emitted = 0;
-    int* tab = vformat->fs_tab;
-
-    for (i = 0; i < 16; i++) {
-        tab[i] = -1;
+    rs->ip[id] |= R300_RS_COL_PTR(ptr);
+    if (swizzle_0001) {
+        rs->ip[id] |= R300_RS_COL_FMT(R300_RS_COL_FMT_0001);
+    } else {
+        rs->ip[id] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
     }
-
-    assert(info->num_inputs <= 16);
-    for (i = 0; i < info->num_inputs; i++) {
-        switch (info->input_semantic_name[i]) {
-            case TGSI_SEMANTIC_COLOR:
-                tab[i] = INTERP_LINEAR;
-                cols++;
-                break;
-            case TGSI_SEMANTIC_POSITION:
-            case TGSI_SEMANTIC_PSIZE:
-                debug_printf("r300: Implementation error: Can't use "
-                        "pos attribs in fragshader yet!\n");
-                /* Pass through for now */
-            case TGSI_SEMANTIC_FOG:
-            case TGSI_SEMANTIC_GENERIC:
-                tab[i] = INTERP_PERSPECTIVE;
-                break;
-            default:
-                debug_printf("r300: Unknown vertex input %d\n",
-                    info->input_semantic_name[i]);
-                break;
-        }
-    }
-
-    /* Now that we know where everything is... */
-    DBG(r300, DBG_DRAW, "r300: fp input count: %d\n", info->num_inputs);
-    for (i = 0; i < info->num_inputs; i++) {
-        switch (tab[i]) {
-            case INTERP_LINEAR:
-                DBG(r300, DBG_DRAW, "r300: attrib: "
-                        "stack offset %d, color,    tab %d\n",
-                        i, cols_emitted);
-                tab[i] = cols_emitted;
-                cols_emitted++;
-                break;
-            case INTERP_PERSPECTIVE:
-                DBG(r300, DBG_DRAW, "r300: attrib: "
-                        "stack offset %d, texcoord, tab %d\n",
-                        i, cols + texs);
-                tab[i] = cols + texs;
-                texs++;
-                break;
-            case -1:
-                debug_printf("r300: Implementation error: Bad fp interp!\n");
-            default:
-                break;
-        }
-    }
-
+    rs->inst[id] |= R300_RS_INST_COL_ID(id);
 }
 
-/* Set up the RS block. This is the part of the chipset that actually does
- * the rasterization of vertices into fragments. This is also the part of the
- * chipset that locks up if any part of it is even slightly wrong. */
-static void r300_update_rs_block(struct r300_context* r300,
-                                 struct r300_rs_block* rs)
+static void r300_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset)
 {
-    struct tgsi_shader_info* info = &r300->fs->info;
-    int col_count = 0, fp_offset = 0, i, tex_count = 0;
-    int rs_tex_comp = 0;
+    rs->inst[id] |= R300_RS_INST_COL_CN_WRITE |
+                    R300_RS_INST_COL_ADDR(fp_offset);
+}
+
+static void r300_rs_tex(struct r300_rs_block* rs, int id, int ptr,
+                        boolean swizzle_X001)
+{
+    if (swizzle_X001) {
+        rs->ip[id] |= R300_RS_TEX_PTR(ptr*4) |
+                      R300_RS_SEL_S(R300_RS_SEL_C0) |
+                      R300_RS_SEL_T(R300_RS_SEL_K0) |
+                      R300_RS_SEL_R(R300_RS_SEL_K0) |
+                      R300_RS_SEL_Q(R300_RS_SEL_K1);
+    } else {
+        rs->ip[id] |= R300_RS_TEX_PTR(ptr*4) |
+                      R300_RS_SEL_S(R300_RS_SEL_C0) |
+                      R300_RS_SEL_T(R300_RS_SEL_C1) |
+                      R300_RS_SEL_R(R300_RS_SEL_C2) |
+                      R300_RS_SEL_Q(R300_RS_SEL_C3);
+    }
+    rs->inst[id] |= R300_RS_INST_TEX_ID(id);
+}
+
+static void r300_rs_tex_write(struct r300_rs_block* rs, int id, int fp_offset)
+{
+    rs->inst[id] |= R300_RS_INST_TEX_CN_WRITE |
+                    R300_RS_INST_TEX_ADDR(fp_offset);
+}
+
+static void r500_rs_col(struct r300_rs_block* rs, int id, int ptr,
+                        boolean swizzle_0001)
+{
+    rs->ip[id] |= R500_RS_COL_PTR(ptr);
+    if (swizzle_0001) {
+        rs->ip[id] |= R500_RS_COL_FMT(R300_RS_COL_FMT_0001);
+    } else {
+        rs->ip[id] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
+    }
+    rs->inst[id] |= R500_RS_INST_COL_ID(id);
+}
+
+static void r500_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset)
+{
+    rs->inst[id] |= R500_RS_INST_COL_CN_WRITE |
+                    R500_RS_INST_COL_ADDR(fp_offset);
+}
+
+static void r500_rs_tex(struct r300_rs_block* rs, int id, int ptr,
+                        boolean swizzle_X001)
+{
+    int rs_tex_comp = ptr*4;
+
+    if (swizzle_X001) {
+        rs->ip[id] |= R500_RS_SEL_S(rs_tex_comp) |
+                      R500_RS_SEL_T(R500_RS_IP_PTR_K0) |
+                      R500_RS_SEL_R(R500_RS_IP_PTR_K0) |
+                      R500_RS_SEL_Q(R500_RS_IP_PTR_K1);
+    } else {
+        rs->ip[id] |= R500_RS_SEL_S(rs_tex_comp) |
+                      R500_RS_SEL_T(rs_tex_comp + 1) |
+                      R500_RS_SEL_R(rs_tex_comp + 2) |
+                      R500_RS_SEL_Q(rs_tex_comp + 3);
+    }
+    rs->inst[id] |= R500_RS_INST_TEX_ID(id);
+}
+
+static void r500_rs_tex_write(struct r300_rs_block* rs, int id, int fp_offset)
+{
+    rs->inst[id] |= R500_RS_INST_TEX_CN_WRITE |
+                    R500_RS_INST_TEX_ADDR(fp_offset);
+}
+
+/* Set up the RS block.
+ *
+ * This is the part of the chipset that actually does the rasterization
+ * of vertices into fragments. This is also the part of the chipset that
+ * locks up if any part of it is even slightly wrong. */
+static void r300_update_rs_block(struct r300_context* r300,
+                                 struct r300_shader_semantics* vs_outputs,
+                                 struct r300_shader_semantics* fs_inputs)
+{
+    struct r300_rs_block* rs = r300->rs_block;
+    int i, col_count = 0, tex_count = 0, fp_offset = 0;
+    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);
+    void (*rX00_rs_tex_write)(struct r300_rs_block*, int, int);
+    boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED ||
+                              vs_outputs->bcolor[1] != ATTR_UNUSED;
 
     if (r300_screen(r300->context.screen)->caps->is_r500) {
-        for (i = 0; i < info->num_inputs; i++) {
-            switch (info->input_semantic_name[i]) {
-                case TGSI_SEMANTIC_COLOR:
-                    rs->ip[col_count] |=
-                        R500_RS_COL_PTR(col_count) |
-                        R500_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
-                    col_count++;
-                    break;
-                case TGSI_SEMANTIC_GENERIC:
-                    rs->ip[tex_count] |=
-                        R500_RS_SEL_S(rs_tex_comp) |
-                        R500_RS_SEL_T(rs_tex_comp + 1) |
-                        R500_RS_SEL_R(rs_tex_comp + 2) |
-                        R500_RS_SEL_Q(rs_tex_comp + 3);
-                    tex_count++;
-                    rs_tex_comp += 4;
-                    break;
-                default:
-                    break;
-            }
-        }
-
-        /* Rasterize at least one color, or bad things happen. */
-        if ((col_count == 0) && (tex_count == 0)) {
-            rs->ip[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_0001);
-            col_count++;
-        }
-
-        for (i = 0; i < tex_count; i++) {
-            rs->inst[i] |= R500_RS_INST_TEX_ID(i) |
-                R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_offset);
-            fp_offset++;
-        }
-
-        for (i = 0; i < col_count; i++) {
-            rs->inst[i] |= R500_RS_INST_COL_ID(i) |
-                R500_RS_INST_COL_CN_WRITE | R500_RS_INST_COL_ADDR(fp_offset);
-            fp_offset++;
-        }
+        rX00_rs_col       = r500_rs_col;
+        rX00_rs_col_write = r500_rs_col_write;
+        rX00_rs_tex       = r500_rs_tex;
+        rX00_rs_tex_write = r500_rs_tex_write;
     } else {
-        for (i = 0; i < info->num_inputs; i++) {
-            switch (info->input_semantic_name[i]) {
-                case TGSI_SEMANTIC_COLOR:
-                    rs->ip[col_count] |=
-                        R300_RS_COL_PTR(col_count) |
-                        R300_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
-                    col_count++;
-                    break;
-                case TGSI_SEMANTIC_GENERIC:
-                    rs->ip[tex_count] |=
-                        R300_RS_TEX_PTR(rs_tex_comp) |
-                        R300_RS_SEL_S(R300_RS_SEL_C0) |
-                        R300_RS_SEL_T(R300_RS_SEL_C1) |
-                        R300_RS_SEL_R(R300_RS_SEL_C2) |
-                        R300_RS_SEL_Q(R300_RS_SEL_C3);
-                    tex_count++;
-                    rs_tex_comp+=4;
-                    break;
-                default:
-                    break;
+        rX00_rs_col       = r300_rs_col;
+        rX00_rs_col_write = r300_rs_col_write;
+        rX00_rs_tex       = r300_rs_tex;
+        rX00_rs_tex_write = r300_rs_tex_write;
+    }
+
+    /* Rasterize colors. */
+    for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+        if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used) {
+            /* Always rasterize if it's written by the VS,
+             * otherwise it locks up. */
+            rX00_rs_col(rs, col_count, i, FALSE);
+
+            /* Write it to the FS input register if it's used by the FS. */
+            if (fs_inputs->color[i] != ATTR_UNUSED) {
+                rX00_rs_col_write(rs, col_count, fp_offset);
+                fp_offset++;
+            }
+            col_count++;
+        } else {
+            /* Skip the FS input register, leave it uninitialized. */
+            /* If we try to set it to (0,0,0,1), it will lock up. */
+            if (fs_inputs->color[i] != ATTR_UNUSED) {
+                fp_offset++;
             }
         }
+    }
 
-        if (col_count == 0) {
-            rs->ip[0] |= R300_RS_COL_FMT(R300_RS_COL_FMT_0001);
+    /* Rasterize texture coordinates. */
+    for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
+        if (vs_outputs->generic[i] != ATTR_UNUSED) {
+            /* Always rasterize if it's written by the VS,
+             * otherwise it locks up. */
+            rX00_rs_tex(rs, tex_count, tex_count, FALSE);
+
+            /* Write it to the FS input register if it's used by the FS. */
+            if (fs_inputs->generic[i] != ATTR_UNUSED) {
+                rX00_rs_tex_write(rs, tex_count, fp_offset);
+                fp_offset++;
+            }
+            tex_count++;
+        } else {
+            /* Skip the FS input register, leave it uninitialized. */
+            /* If we try to set it to (0,0,0,1), it will lock up. */
+            if (fs_inputs->generic[i] != ATTR_UNUSED) {
+                fp_offset++;
+            }
         }
+    }
 
-        if (tex_count == 0) {
-            rs->ip[0] |=
-                R300_RS_SEL_S(R300_RS_SEL_K0) |
-                R300_RS_SEL_T(R300_RS_SEL_K0) |
-                R300_RS_SEL_R(R300_RS_SEL_K0) |
-                R300_RS_SEL_Q(R300_RS_SEL_K1);
-        }
+    /* Rasterize fog coordinates. */
+    if (vs_outputs->fog != ATTR_UNUSED) {
+        /* Always rasterize if it's written by the VS,
+         * otherwise it locks up. */
+        rX00_rs_tex(rs, tex_count, tex_count, TRUE);
 
-        /* Rasterize at least one color, or bad things happen. */
-        if ((col_count == 0) && (tex_count == 0)) {
-            col_count++;
-        }
-
-        for (i = 0; i < tex_count; i++) {
-            rs->inst[i] |= R300_RS_INST_TEX_ID(i) |
-                R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_offset);
+        /* Write it to the FS input register if it's used by the FS. */
+        if (fs_inputs->fog != ATTR_UNUSED) {
+            rX00_rs_tex_write(rs, tex_count, fp_offset);
             fp_offset++;
         }
-
-        for (i = 0; i < col_count; i++) {
-            rs->inst[i] |= R300_RS_INST_COL_ID(i) |
-                R300_RS_INST_COL_CN_WRITE | R300_RS_INST_COL_ADDR(fp_offset);
+        tex_count++;
+    } else {
+        /* Skip the FS input register, leave it uninitialized. */
+        /* If we try to set it to (0,0,0,1), it will lock up. */
+        if (fs_inputs->fog != ATTR_UNUSED) {
             fp_offset++;
         }
     }
 
-    rs->count = (rs_tex_comp) | (col_count << R300_IC_COUNT_SHIFT) |
+    /* Rasterize WPOS. */
+    /* If the FS doesn't need it, it's not written by the VS. */
+    if (fs_inputs->wpos != ATTR_UNUSED) {
+        rX00_rs_tex(rs, tex_count, tex_count, FALSE);
+        rX00_rs_tex_write(rs, tex_count, fp_offset);
+
+        fp_offset++;
+        tex_count++;
+    }
+
+    /* Rasterize at least one color, or bad things happen. */
+    if (col_count == 0 && tex_count == 0) {
+        rX00_rs_col(rs, 0, 0, TRUE);
+        col_count++;
+    }
+
+    rs->count = (tex_count*4) | (col_count << R300_IC_COUNT_SHIFT) |
         R300_HIRES_EN;
 
-    rs->inst_count = MAX2(MAX2(col_count - 1, tex_count - 1), 0);
+    rs->inst_count = MAX3(col_count - 1, tex_count - 1, 0);
 }
 
 /* Update the vertex format. */
 static void r300_update_derived_shader_state(struct r300_context* r300)
 {
-    struct r300_shader_key* key;
-    struct r300_vertex_format* vformat;
-    struct r300_rs_block* rs_block;
-    struct r300_shader_derived_value* value;
-    int i;
+    struct r300_screen* r300screen = r300_screen(r300->context.screen);
 
     /*
+    struct r300_shader_key* key;
+    struct r300_shader_derived_value* value;
     key = CALLOC_STRUCT(r300_shader_key);
     key->vs = r300->vs;
     key->fs = r300->fs;
@@ -485,32 +465,51 @@
             (void*)key, (void*)value);
     } */
 
-    /* XXX This will be refactored ASAP. */
-    vformat = CALLOC_STRUCT(r300_vertex_format);
-    rs_block = CALLOC_STRUCT(r300_rs_block);
+    /* Reset structures */
+    memset(r300->rs_block, 0, sizeof(struct r300_rs_block));
+    memset(r300->vertex_info, 0, sizeof(struct r300_vertex_info));
+    memcpy(r300->vertex_info->vinfo.hwfmt, r300->vs->hwfmt, sizeof(uint)*4);
 
-    for (i = 0; i < 16; i++) {
-        vformat->vs_tab[i] = -1;
-        vformat->fs_tab[i] = -1;
+    r300_update_rs_block(r300, &r300->vs->outputs, &r300->fs->inputs);
+
+    if (r300screen->caps->has_tcl) {
+        r300_vertex_psc(r300);
+    } else {
+        r300_draw_emit_all_attribs(r300);
+        draw_compute_vertex_size(&r300->vertex_info->vinfo);
+        r300_swtcl_vertex_psc(r300);
     }
 
-    r300_vs_tab_routes(r300, vformat);
-    r300_vertex_psc(r300, vformat);
-    r300_update_fs_tab(r300, vformat);
+    r300->dirty_state |= R300_NEW_RS_BLOCK;
+}
 
-    r300_update_rs_block(r300, rs_block);
+static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa)
+{
+    /* We are interested only in the cases when a new depth or stencil value
+     * can be written and changed. */
 
-    FREE(r300->vertex_info);
-    FREE(r300->rs_block);
+    /* We might optionally check for [Z func: never] and inspect the stencil
+     * state in a similar fashion, but it's not terribly important. */
+    return (dsa->z_buffer_control & R300_Z_WRITE_ENABLE) ||
+           (dsa->stencil_ref_mask & R300_STENCILWRITEMASK_MASK) ||
+           ((dsa->z_buffer_control & R500_STENCIL_REFMASK_FRONT_BACK) &&
+            (dsa->stencil_ref_bf & R300_STENCILWRITEMASK_MASK));
+}
 
-    r300->vertex_info = vformat;
-    r300->rs_block = rs_block;
-    r300->dirty_state |= (R300_NEW_VERTEX_FORMAT | R300_NEW_RS_BLOCK);
+static boolean r300_dsa_alpha_test_enabled(struct r300_dsa_state* dsa)
+{
+    /* We are interested only in the cases when alpha testing can kill
+     * a fragment. */
+    uint32_t af = dsa->alpha_function;
+
+    return (af & R300_FG_ALPHA_FUNC_ENABLE) &&
+           (af & R300_FG_ALPHA_FUNC_ALWAYS) != R300_FG_ALPHA_FUNC_ALWAYS;
 }
 
 static void r300_update_ztop(struct r300_context* r300)
 {
-    r300->ztop_state.z_buffer_top = R300_ZTOP_ENABLE;
+    struct r300_ztop_state* ztop_state =
+        (struct r300_ztop_state*)r300->ztop_state.state;
 
     /* This is important enough that I felt it warranted a comment.
      *
@@ -524,32 +523,45 @@
      * The docs claim that for the first three cases, if no ZS writes happen,
      * then ZTOP can be used.
      *
+     * (3) will never apply since we do not support chroma-keyed operations.
+     * (4) will need to be re-examined (and this comment updated) if/when
+     * Hyper-Z becomes supported.
+     *
      * Additionally, the following conditions require disabled ZTOP:
-     * ~) Depth writes in fragment shader
-     * ~) Outstanding occlusion queries
+     * 5) Depth writes in fragment shader
+     * 6) Outstanding occlusion queries
+     *
+     * This register causes stalls all the way from SC to CB when changed,
+     * but it is buffered on-chip so it does not hurt to write it if it has
+     * not changed.
      *
      * ~C.
      */
-    if (r300->dsa_state->alpha_function) {
-        r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE;
-    } else if (r300->fs->info.uses_kill) {
-        r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE;
-    } else if (r300_fragment_shader_writes_depth(r300->fs)) {
-        r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE;
-    } else if (r300->query_current) {
-        r300->ztop_state.z_buffer_top = R300_ZTOP_DISABLE;
+
+    /* ZS writes */
+    if (r300_dsa_writes_depth_stencil(r300->dsa_state.state) &&
+           (r300_dsa_alpha_test_enabled(r300->dsa_state.state) ||/* (1) */
+            r300->fs->info.uses_kill)) {                         /* (2) */
+        ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
+    } else if (r300_fragment_shader_writes_depth(r300->fs)) {    /* (5) */
+        ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
+    } else if (r300->query_current) {                            /* (6) */
+        ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
+    } else {
+        ztop_state->z_buffer_top = R300_ZTOP_ENABLE;
     }
+
+    r300->ztop_state.dirty = TRUE;
 }
 
 void r300_update_derived_state(struct r300_context* r300)
 {
+    /* XXX */
     if (r300->dirty_state &
-        (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER)) {
+        (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER |
+         R300_NEW_VERTEX_FORMAT) || r300->rs_state.dirty) {
         r300_update_derived_shader_state(r300);
     }
 
-    if (r300->dirty_state &
-            (R300_NEW_DSA | R300_NEW_FRAGMENT_SHADER | R300_NEW_QUERY)) {
-        r300_update_ztop(r300);
-    }
+    r300_update_ztop(r300);
 }
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index 52b9650..35be00e 100644
--- a/src/gallium/drivers/r300/r300_state_inlines.h
+++ b/src/gallium/drivers/r300/r300_state_inlines.h
@@ -28,6 +28,8 @@
 
 #include "pipe/p_format.h"
 
+#include "util/u_format.h"
+
 #include "r300_reg.h"
 
 /* Some maths. These should probably find their way to u_math, if needed. */
@@ -191,6 +193,42 @@
     return 0;
 }
 
+static INLINE uint32_t
+r300_translate_polygon_mode_front(unsigned mode) {
+    switch (mode)
+    {
+        case PIPE_POLYGON_MODE_FILL:
+            return R300_GA_POLY_MODE_FRONT_PTYPE_TRI;
+        case PIPE_POLYGON_MODE_LINE:
+            return R300_GA_POLY_MODE_FRONT_PTYPE_LINE;
+        case PIPE_POLYGON_MODE_POINT:
+            return R300_GA_POLY_MODE_FRONT_PTYPE_POINT;
+
+        default:
+            debug_printf("r300: Bad polygon mode %i in %s\n", mode,
+                __FUNCTION__);
+            return R300_GA_POLY_MODE_FRONT_PTYPE_TRI;
+    }
+}
+
+static INLINE uint32_t
+r300_translate_polygon_mode_back(unsigned mode) {
+    switch (mode)
+    {
+        case PIPE_POLYGON_MODE_FILL:
+            return R300_GA_POLY_MODE_BACK_PTYPE_TRI;
+        case PIPE_POLYGON_MODE_LINE:
+            return R300_GA_POLY_MODE_BACK_PTYPE_LINE;
+        case PIPE_POLYGON_MODE_POINT:
+            return R300_GA_POLY_MODE_BACK_PTYPE_POINT;
+
+        default:
+            debug_printf("r300: Bad polygon mode %i in %s\n", mode,
+                __FUNCTION__);
+            return R300_GA_POLY_MODE_BACK_PTYPE_TRI;
+    }
+}
+
 /* Texture sampler state. */
 
 static INLINE uint32_t r300_translate_wrap(int wrap)
@@ -219,38 +257,37 @@
     }
 }
 
-static INLINE uint32_t r300_translate_tex_filters(int min, int mag, int mip)
+static INLINE uint32_t r300_translate_tex_filters(int min, int mag, int mip,
+                                                  int is_anisotropic)
 {
     uint32_t retval = 0;
-    switch (min) {
+    if (is_anisotropic)
+        retval |= R300_TX_MIN_FILTER_ANISO | R300_TX_MAG_FILTER_ANISO;
+    else {
+        switch (min) {
         case PIPE_TEX_FILTER_NEAREST:
             retval |= R300_TX_MIN_FILTER_NEAREST;
             break;
         case PIPE_TEX_FILTER_LINEAR:
             retval |= R300_TX_MIN_FILTER_LINEAR;
             break;
-        case PIPE_TEX_FILTER_ANISO:
-            retval |= R300_TX_MIN_FILTER_ANISO;
-            break;
         default:
             debug_printf("r300: Unknown texture filter %d\n", min);
             assert(0);
             break;
-    }
-    switch (mag) {
+        }
+        switch (mag) {
         case PIPE_TEX_FILTER_NEAREST:
             retval |= R300_TX_MAG_FILTER_NEAREST;
             break;
         case PIPE_TEX_FILTER_LINEAR:
             retval |= R300_TX_MAG_FILTER_LINEAR;
             break;
-        case PIPE_TEX_FILTER_ANISO:
-            retval |= R300_TX_MAG_FILTER_ANISO;
-            break;
         default:
             debug_printf("r300: Unknown texture filter %d\n", mag);
             assert(0);
             break;
+        }
     }
     switch (mip) {
         case PIPE_TEX_MIPFILTER_NONE:
@@ -407,20 +444,22 @@
 static INLINE unsigned pf_component_count(enum pipe_format format) {
     unsigned count = 0;
 
-    if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS) {
-        return count;
-    }
-
-    if (pf_size_x(format)) {
+    if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0)) {
         count++;
     }
-    if (pf_size_y(format)) {
+    if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1)) {
         count++;
     }
-    if (pf_size_z(format)) {
+    if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2)) {
         count++;
     }
-    if (pf_size_w(format)) {
+    if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3)) {
+        count++;
+    }
+    if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0)) {
+        count++;
+    }
+    if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) {
         count++;
     }
 
@@ -431,38 +470,40 @@
 static INLINE uint16_t
 r300_translate_vertex_data_type(enum pipe_format format) {
     uint32_t result = 0;
+    const struct util_format_description *desc;
     unsigned components = pf_component_count(format);
 
-    if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS) {
-        debug_printf("r300: Bad format %s in %s\n", pf_name(format),
-            __FUNCTION__);
-        return 0;
+    desc = util_format_description(format);
+
+    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__);
+        assert(0);
     }
 
-    switch (pf_type(format)) {
+    switch (desc->channel[0].type) {
         /* Half-floats, floats, doubles */
-        case PIPE_FORMAT_TYPE_FLOAT:
-            switch (pf_size_x(format)) {
-                case 4:
+        case UTIL_FORMAT_TYPE_FLOAT:
+            switch (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0)) {
+                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__);
                     assert(0);
             }
             break;
-        /* Normalized unsigned ints */
-        case PIPE_FORMAT_TYPE_UNORM:
-        /* Normalized signed ints */
-        case PIPE_FORMAT_TYPE_SNORM:
-        /* Non-normalized unsigned ints */
-        case PIPE_FORMAT_TYPE_USCALED:
-        /* Non-normalized signed ints */
-        case PIPE_FORMAT_TYPE_SSCALED:
-            switch (pf_size_x(format)) {
-                case 1:
+        /* Unsigned ints */
+        case UTIL_FORMAT_TYPE_UNSIGNED:
+        /* Signed ints */
+        case UTIL_FORMAT_TYPE_SIGNED:
+            switch (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0)) {
+                case 8:
                     result = R300_DATA_TYPE_BYTE;
                     break;
-                case 2:
+                case 16:
                     if (components > 2) {
                         result = R300_DATA_TYPE_SHORT_4;
                     } else {
@@ -470,19 +511,24 @@
                     }
                     break;
                 default:
+                    debug_printf("r300: Bad format %s in %s:%d\n",
+                        pf_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);
             }
             break;
         default:
+            debug_printf("r300: Bad format %s in %s:%d\n",
+                pf_name(format), __FUNCTION__, __LINE__);
             assert(0);
     }
 
-    if (pf_type(format) == PIPE_FORMAT_TYPE_SSCALED) {
+    if (desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED) {
         result |= R300_SIGNED;
-    } else if (pf_type(format) == PIPE_FORMAT_TYPE_UNORM) {
+    }
+    if (desc->channel[0].normalized) {
         result |= R300_NORMALIZE;
-    } else if (pf_type(format) == PIPE_FORMAT_TYPE_SNORM) {
-        result |= (R300_SIGNED | R300_NORMALIZE);
     }
 
     return result;
@@ -490,54 +536,22 @@
 
 static INLINE uint16_t
 r300_translate_vertex_data_swizzle(enum pipe_format format) {
+    const struct util_format_description *desc = util_format_description(format);
 
-    if (pf_layout(format) != PIPE_FORMAT_LAYOUT_RGBAZS) {
-        debug_printf("r300: Bad format %s in %s\n", pf_name(format),
-            __FUNCTION__);
+    assert(format);
+
+    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__);
         return 0;
     }
 
-    return ((pf_swizzle_x(format) << R300_SWIZZLE_SELECT_X_SHIFT) |
-        (pf_swizzle_y(format) << R300_SWIZZLE_SELECT_Y_SHIFT) |
-        (pf_swizzle_z(format) << R300_SWIZZLE_SELECT_Z_SHIFT) |
-        (pf_swizzle_w(format) << R300_SWIZZLE_SELECT_W_SHIFT) |
+    return ((desc->swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) |
+        (desc->swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) |
+        (desc->swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) |
+        (desc->swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT) |
         (0xf << R300_WRITE_ENA_SHIFT));
 }
 
-static INLINE uint32_t
-r300_translate_polygon_mode_front(unsigned mode) {
-    switch (mode)
-    {
-        case PIPE_POLYGON_MODE_FILL:
-            return R300_GA_POLY_MODE_FRONT_PTYPE_TRI;
-        case PIPE_POLYGON_MODE_LINE:
-            return R300_GA_POLY_MODE_FRONT_PTYPE_LINE;
-        case PIPE_POLYGON_MODE_POINT:
-            return R300_GA_POLY_MODE_FRONT_PTYPE_POINT;
-
-        default:
-            debug_printf("r300: Bad polygon mode %i in %s\n", mode,
-                __FUNCTION__);
-            return R300_GA_POLY_MODE_FRONT_PTYPE_TRI;
-    }
-}
-
-static INLINE uint32_t
-r300_translate_polygon_mode_back(unsigned mode) {
-    switch (mode)
-    {
-        case PIPE_POLYGON_MODE_FILL:
-            return R300_GA_POLY_MODE_BACK_PTYPE_TRI;
-        case PIPE_POLYGON_MODE_LINE:
-            return R300_GA_POLY_MODE_BACK_PTYPE_LINE;
-        case PIPE_POLYGON_MODE_POINT:
-            return R300_GA_POLY_MODE_BACK_PTYPE_POINT;
-
-        default:
-            debug_printf("r300: Bad polygon mode %i in %s\n", mode,
-                __FUNCTION__);
-            return R300_GA_POLY_MODE_BACK_PTYPE_TRI;
-    }
-}
-
 #endif /* R300_STATE_INLINES_H */
diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c
index c07e6ae..f25f3ca 100644
--- a/src/gallium/drivers/r300/r300_state_invariant.c
+++ b/src/gallium/drivers/r300/r300_state_invariant.c
@@ -43,7 +43,7 @@
     struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps;
     CS_LOCALS(r300);
 
-    BEGIN_CS(24 + (caps->has_tcl ? 2: 0));
+    BEGIN_CS(16 + (caps->has_tcl ? 2: 0));
 
     /*** Graphics Backend (GB) ***/
     /* Various GB enables */
@@ -66,13 +66,8 @@
     OUT_CS_REG(R300_FG_FOG_COLOR_R, 0x0);
     OUT_CS_REG(R300_FG_FOG_COLOR_G, 0x0);
     OUT_CS_REG(R300_FG_FOG_COLOR_B, 0x0);
-    OUT_CS_REG(R300_FG_DEPTH_SRC, 0x0);
-    OUT_CS_REG(R300_US_W_FMT, 0x0);
 
     /*** VAP ***/
-    /* Max and min vertex index clamp. */
-    OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0x0);
-    OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, 0xffffff);
     /* Sign/normalize control */
     OUT_CS_REG(R300_VAP_PSC_SGN_NORM_CNTL, R300_SGN_NORM_NO_ZERO);
     /* TCL-only stuff */
@@ -84,15 +79,11 @@
     END_CS;
 
     /* XXX unsorted stuff from surface_fill */
-    BEGIN_CS(60 + (caps->has_tcl ? 5 : 0) + (caps->is_r500 ? 4 : 0));
-    /* Flush PVS. */
-    OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0);
+    BEGIN_CS(44 + (caps->has_tcl ? 7 : 0) + (caps->is_r500 ? 4 : 0));
 
-    OUT_CS_REG(R300_SE_VTE_CNTL, R300_VPORT_X_SCALE_ENA |
-        R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA |
-        R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA |
-        R300_VPORT_Z_OFFSET_ENA | R300_VTX_W0_FMT);
     if (caps->has_tcl) {
+        /*Flushing PVS is required before the VAP_GB registers can be changed*/
+        OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
         OUT_CS_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4);
         OUT_CS_32F(1.0);
         OUT_CS_32F(1.0);
@@ -123,21 +114,15 @@
     OUT_CS_REG(R300_SU_DEPTH_OFFSET, 0x00000000);
     OUT_CS_REG(R300_SC_HYPERZ, 0x0000001C);
     OUT_CS_REG(R300_SC_EDGERULE, 0x2DA49525);
-    OUT_CS_REG(R300_RB3D_CCTL, 0x00000000);
     OUT_CS_REG(R300_RB3D_AARESOLVE_CTL, 0x00000000);
     if (caps->is_r500) {
-        OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 0x00000000);
-        OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD, 0xFFFFFFFF);
+        OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 0x01010101);
+        OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD, 0xFEFEFEFE);
     }
-    OUT_CS_REG(R300_ZB_FORMAT, 0x00000002);
-    OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT, 0x00000003);
     OUT_CS_REG(R300_ZB_BW_CNTL, 0x00000000);
     OUT_CS_REG(R300_ZB_DEPTHCLEARVALUE, 0x00000000);
     OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0x00000000);
     OUT_CS_REG(R300_ZB_HIZ_PITCH, 0x00000000);
-    OUT_CS_REG(R300_VAP_VTX_STATE_CNTL, 0x1);
-    OUT_CS_REG(R300_VAP_VSM_VTX_ASSM, 0x405);
-    OUT_CS_REG(R300_SE_VTE_CNTL, 0x0000043F);
 
     /* XXX */
     OUT_CS_REG(R300_SC_CLIP_RULE, 0xaaaa);
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index aea25cf..9a96206 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -22,6 +22,7 @@
 
 #include "pipe/p_screen.h"
 
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 
@@ -34,8 +35,8 @@
     struct r300_texture_state* state = &tex->state;
     struct pipe_texture *pt = &tex->tex;
 
-    state->format0 = R300_TX_WIDTH((pt->width[0] - 1) & 0x7ff) |
-                     R300_TX_HEIGHT((pt->height[0] - 1) & 0x7ff);
+    state->format0 = R300_TX_WIDTH((pt->width0 - 1) & 0x7ff) |
+                     R300_TX_HEIGHT((pt->height0 - 1) & 0x7ff);
 
     if (tex->is_npot) {
         /* rectangles love this */
@@ -43,8 +44,7 @@
         state->format2 = (tex->pitch[0] - 1) & 0x1fff;
     } else {
         /* power of two textures (3D, mipmaps, and no pitch) */
-        state->format0 |= R300_TX_DEPTH(util_logbase2(pt->depth[0]) & 0xf) |
-                          R300_TX_NUM_LEVELS(pt->last_level & 0xf);
+        state->format0 |= R300_TX_DEPTH(util_logbase2(pt->depth0) & 0xf);
     }
 
     state->format1 = r300_translate_texformat(pt->format);
@@ -58,17 +58,17 @@
     /* large textures on r500 */
     if (is_r500)
     {
-        if (pt->width[0] > 2048) {
+        if (pt->width0 > 2048) {
             state->format2 |= R500_TXWIDTH_BIT11;
         }
-        if (pt->height[0] > 2048) {
+        if (pt->height0 > 2048) {
             state->format2 |= R500_TXHEIGHT_BIT11;
         }
     }
-    assert(is_r500 || (pt->width[0] <= 2048 && pt->height[0] <= 2048));
+    assert(is_r500 || (pt->width0 <= 2048 && pt->height0 <= 2048));
 
     debug_printf("r300: Set texture state (%dx%d, %d levels)\n",
-		 pt->width[0], pt->height[0], pt->last_level);
+		 pt->width0, pt->height0, pt->last_level);
 }
 
 unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
@@ -106,7 +106,7 @@
         return 0;
     }
 
-    return align(pf_get_stride(&tex->tex.block, tex->tex.width[level]), 32);
+    return align(util_format_get_stride(tex->tex.format, u_minify(tex->tex.width0, level)), 32);
 }
 
 static void r300_setup_miptree(struct r300_texture* tex)
@@ -116,39 +116,32 @@
     int i;
 
     for (i = 0; i <= base->last_level; i++) {
-        if (i > 0) {
-            base->width[i] = minify(base->width[i-1]);
-            base->height[i] = minify(base->height[i-1]);
-            base->depth[i] = minify(base->depth[i-1]);
-        }
-
-        base->nblocksx[i] = pf_get_nblocksx(&base->block, base->width[i]);
-        base->nblocksy[i] = pf_get_nblocksy(&base->block, base->height[i]);
+        unsigned nblocksy = util_format_get_nblocksy(base->format, u_minify(base->height0, i));
 
         stride = r300_texture_get_stride(tex, i);
-        layer_size = stride * base->nblocksy[i];
+        layer_size = stride * nblocksy;
 
         if (base->target == PIPE_TEXTURE_CUBE)
             size = layer_size * 6;
         else
-            size = layer_size * base->depth[i];
+            size = layer_size * u_minify(base->depth0, i);
 
         tex->offset[i] = align(tex->size, 32);
         tex->size = tex->offset[i] + size;
         tex->layer_size[i] = layer_size;
-        tex->pitch[i] = stride / base->block.size;
+        tex->pitch[i] = stride / util_format_get_blocksize(base->format);
 
         debug_printf("r300: Texture miptree: Level %d "
                 "(%dx%dx%d px, pitch %d bytes)\n",
-                i, base->width[i], base->height[i], base->depth[i],
-                stride);
+                i, u_minify(base->width0, i), u_minify(base->height0, i),
+                u_minify(base->depth0, i), stride);
     }
 }
 
 static void r300_setup_flags(struct r300_texture* tex)
 {
-    tex->is_npot = !util_is_power_of_two(tex->tex.width[0]) ||
-                   !util_is_power_of_two(tex->tex.height[0]);
+    tex->is_npot = !util_is_power_of_two(tex->tex.width0) ||
+                   !util_is_power_of_two(tex->tex.height0);
 }
 
 /* Create a new texture. */
@@ -208,8 +201,8 @@
         pipe_reference_init(&surface->reference, 1);
         pipe_texture_reference(&surface->texture, texture);
         surface->format = texture->format;
-        surface->width = texture->width[level];
-        surface->height = texture->height[level];
+        surface->width = u_minify(texture->width0, level);
+        surface->height = u_minify(texture->height0, level);
         surface->offset = offset;
         surface->usage = flags;
         surface->zslice = zslice;
@@ -237,7 +230,7 @@
 
     /* Support only 2D textures without mipmaps */
     if (base->target != PIPE_TEXTURE_2D ||
-        base->depth[0] != 1 ||
+        base->depth0 != 1 ||
         base->last_level != 0) {
         return NULL;
     }
@@ -252,7 +245,7 @@
     tex->tex.screen = screen;
 
     tex->stride_override = *stride;
-    tex->pitch[0] = *stride / base->block.size;
+    tex->pitch[0] = *stride / util_format_get_blocksize(base->format);
 
     r300_setup_flags(tex);
     r300_setup_texture_state(tex, r300_screen(screen)->caps->is_r500);
@@ -287,10 +280,9 @@
     template.target = PIPE_TEXTURE_2D;
     template.format = PIPE_FORMAT_X8R8G8B8_UNORM;
     template.last_level = 0;
-    template.width[0] = util_next_power_of_two(width);
-    template.height[0] = util_next_power_of_two(height);
-    template.depth[0] = 1;
-    pf_get_block(template.format, &template.block);
+    template.width0 = util_next_power_of_two(width);
+    template.height0 = util_next_power_of_two(height);
+    template.depth0 = 1;
     template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER |
                          PIPE_TEXTURE_USAGE_RENDER_TARGET;
 
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
index 589f198..a792c2c 100644
--- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c
+++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
@@ -120,7 +120,7 @@
      /* case TGSI_OPCODE_NOT: return RC_OPCODE_NOT; */
      /* case TGSI_OPCODE_TRUNC: return RC_OPCODE_TRUNC; */
      /* case TGSI_OPCODE_SHL: return RC_OPCODE_SHL; */
-     /* case TGSI_OPCODE_SHR: return RC_OPCODE_SHR; */
+     /* case TGSI_OPCODE_ISHR: return RC_OPCODE_SHR; */
      /* case TGSI_OPCODE_AND: return RC_OPCODE_AND; */
      /* case TGSI_OPCODE_OR: return RC_OPCODE_OR; */
      /* case TGSI_OPCODE_MOD: return RC_OPCODE_MOD; */
@@ -190,10 +190,10 @@
     struct rc_dst_register * dst,
     struct tgsi_full_dst_register * src)
 {
-    dst->File = translate_register_file(src->DstRegister.File);
-    dst->Index = translate_register_index(ttr, src->DstRegister.File, src->DstRegister.Index);
-    dst->WriteMask = src->DstRegister.WriteMask;
-    dst->RelAddr = src->DstRegister.Indirect;
+    dst->File = translate_register_file(src->Register.File);
+    dst->Index = translate_register_index(ttr, src->Register.File, src->Register.Index);
+    dst->WriteMask = src->Register.WriteMask;
+    dst->RelAddr = src->Register.Indirect;
 }
 
 static void transform_srcreg(
@@ -201,18 +201,19 @@
     struct rc_src_register * dst,
     struct tgsi_full_src_register * src)
 {
-    dst->File = translate_register_file(src->SrcRegister.File);
-    dst->Index = translate_register_index(ttr, src->SrcRegister.File, src->SrcRegister.Index);
-    dst->RelAddr = src->SrcRegister.Indirect;
+    dst->File = translate_register_file(src->Register.File);
+    dst->Index = translate_register_index(ttr, src->Register.File, src->Register.Index);
+    dst->RelAddr = src->Register.Indirect;
     dst->Swizzle = tgsi_util_get_full_src_register_swizzle(src, 0);
     dst->Swizzle |= tgsi_util_get_full_src_register_swizzle(src, 1) << 3;
     dst->Swizzle |= tgsi_util_get_full_src_register_swizzle(src, 2) << 6;
     dst->Swizzle |= tgsi_util_get_full_src_register_swizzle(src, 3) << 9;
-    dst->Abs = src->SrcRegisterExtMod.Absolute;
-    dst->Negate = src->SrcRegister.Negate ? RC_MASK_XYZW : 0;
+    dst->Abs = src->Register.Absolute;
+    dst->Negate = src->Register.Negate ? RC_MASK_XYZW : 0;
 }
 
-static void transform_texture(struct rc_instruction * dst, struct tgsi_instruction_ext_texture src)
+static void transform_texture(struct rc_instruction * dst, struct tgsi_instruction_texture src,
+                              uint32_t *shadowSamplers)
 {
     switch(src.Texture) {
         case TGSI_TEXTURE_1D:
@@ -233,14 +234,17 @@
         case TGSI_TEXTURE_SHADOW1D:
             dst->U.I.TexSrcTarget = RC_TEXTURE_1D;
             dst->U.I.TexShadow = 1;
+            *shadowSamplers |= 1 << dst->U.I.TexSrcUnit;
             break;
         case TGSI_TEXTURE_SHADOW2D:
             dst->U.I.TexSrcTarget = RC_TEXTURE_2D;
             dst->U.I.TexShadow = 1;
+            *shadowSamplers |= 1 << dst->U.I.TexSrcUnit;
             break;
         case TGSI_TEXTURE_SHADOWRECT:
             dst->U.I.TexSrcTarget = RC_TEXTURE_RECT;
             dst->U.I.TexShadow = 1;
+            *shadowSamplers |= 1 << dst->U.I.TexSrcUnit;
             break;
     }
 }
@@ -258,17 +262,19 @@
     dst->U.I.SaturateMode = translate_saturate(src->Instruction.Saturate);
 
     if (src->Instruction.NumDstRegs)
-        transform_dstreg(ttr, &dst->U.I.DstReg, &src->FullDstRegisters[0]);
+        transform_dstreg(ttr, &dst->U.I.DstReg, &src->Dst[0]);
 
     for(i = 0; i < src->Instruction.NumSrcRegs; ++i) {
-        if (src->FullSrcRegisters[i].SrcRegister.File == TGSI_FILE_SAMPLER)
-            dst->U.I.TexSrcUnit = src->FullSrcRegisters[i].SrcRegister.Index;
+        if (src->Src[i].Register.File == TGSI_FILE_SAMPLER)
+            dst->U.I.TexSrcUnit = src->Src[i].Register.Index;
         else
-            transform_srcreg(ttr, &dst->U.I.SrcReg[i], &src->FullSrcRegisters[i]);
+            transform_srcreg(ttr, &dst->U.I.SrcReg[i], &src->Src[i]);
     }
 
     /* Texturing. */
-    transform_texture(dst, src->InstructionExtTexture);
+    if (src->Instruction.Texture)
+        transform_texture(dst, src->Texture,
+                          &ttr->compiler->Program.ShadowSamplers);
 }
 
 static void handle_immediate(struct tgsi_to_rc * ttr, struct tgsi_full_immediate * imm)
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index 74ef416..68aef70 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -21,91 +22,296 @@
  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
 
 #include "r300_vs.h"
+#include "r300_fs.h"
 
 #include "r300_context.h"
+#include "r300_screen.h"
 #include "r300_tgsi_to_rc.h"
+#include "r300_reg.h"
 
 #include "tgsi/tgsi_dump.h"
 #include "tgsi/tgsi_parse.h"
 
 #include "radeon_compiler.h"
 
+#include "util/u_math.h"
+
+/* Convert info about VS output semantics into r300_shader_semantics. */
+static void r300_shader_read_vs_outputs(
+    struct tgsi_shader_info* info,
+    struct r300_shader_semantics* vs_outputs)
+{
+    int i;
+    unsigned index;
+
+    r300_shader_semantics_reset(vs_outputs);
+
+    for (i = 0; i < info->num_outputs; i++) {
+        index = info->output_semantic_index[i];
+
+        switch (info->output_semantic_name[i]) {
+            case TGSI_SEMANTIC_POSITION:
+                assert(index == 0);
+                vs_outputs->pos = i;
+                break;
+
+            case TGSI_SEMANTIC_PSIZE:
+                assert(index == 0);
+                vs_outputs->psize = i;
+                break;
+
+            case TGSI_SEMANTIC_COLOR:
+                assert(index <= ATTR_COLOR_COUNT);
+                vs_outputs->color[index] = i;
+                break;
+
+            case TGSI_SEMANTIC_BCOLOR:
+                assert(index <= ATTR_COLOR_COUNT);
+                vs_outputs->bcolor[index] = i;
+                break;
+
+            case TGSI_SEMANTIC_GENERIC:
+                assert(index <= ATTR_GENERIC_COUNT);
+                vs_outputs->generic[index] = i;
+                break;
+
+            case TGSI_SEMANTIC_FOG:
+                assert(index == 0);
+                vs_outputs->fog = i;
+                break;
+
+            case TGSI_SEMANTIC_EDGEFLAG:
+                assert(index == 0);
+                fprintf(stderr, "r300 VP: cannot handle edgeflag output\n");
+                assert(0);
+                break;
+            default:
+                assert(0);
+        }
+    }
+}
+
+static void r300_shader_vap_output_fmt(struct r300_vertex_shader* vs)
+{
+    struct r300_shader_semantics* vs_outputs = &vs->outputs;
+    uint32_t* hwfmt = vs->hwfmt;
+    int i, gen_count;
+    boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED ||
+                              vs_outputs->bcolor[1] != ATTR_UNUSED;
+
+    /* Do the actual vertex_info setup.
+     *
+     * vertex_info has four uints of hardware-specific data in it.
+     * vinfo.hwfmt[0] is R300_VAP_VTX_STATE_CNTL
+     * vinfo.hwfmt[1] is R300_VAP_VSM_VTX_ASSM
+     * vinfo.hwfmt[2] is R300_VAP_OUTPUT_VTX_FMT_0
+     * vinfo.hwfmt[3] is R300_VAP_OUTPUT_VTX_FMT_1 */
+
+    hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */
+
+    /* Position. */
+    if (vs_outputs->pos != ATTR_UNUSED) {
+        hwfmt[1] |= R300_INPUT_CNTL_POS;
+        hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+    } else {
+        assert(0);
+    }
+
+    /* Point size. */
+    if (vs_outputs->psize != ATTR_UNUSED) {
+        hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
+    }
+
+    /* Colors. */
+    for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+        if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used) {
+            hwfmt[1] |= R300_INPUT_CNTL_COLOR;
+            hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i;
+        }
+    }
+
+    /* Back-face colors. */
+    if (any_bcolor_used) {
+        for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+            hwfmt[1] |= R300_INPUT_CNTL_COLOR;
+            hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i);
+        }
+    }
+
+    /* Texture coordinates. */
+    gen_count = 0;
+    for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
+        if (vs_outputs->generic[i] != ATTR_UNUSED) {
+            hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count);
+            hwfmt[3] |= (4 << (3 * gen_count));
+            gen_count++;
+        }
+    }
+
+    /* Fog coordinates. */
+    if (vs_outputs->fog != ATTR_UNUSED) {
+        hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count);
+        hwfmt[3] |= (4 << (3 * gen_count));
+        gen_count++;
+    }
+
+    /* XXX magic */
+    assert(gen_count <= 8);
+
+    /* WPOS. */
+    vs->wpos_tex_output = gen_count;
+}
+
+/* Sets up stream mapping to equivalent VS outputs if TCL is bypassed
+ * or isn't present. */
+static void r300_stream_locations_notcl(
+    struct r300_shader_semantics* vs_outputs,
+    int* stream_loc)
+{
+    int i, tabi = 0, gen_count;
+    boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED ||
+                              vs_outputs->bcolor[1] != ATTR_UNUSED;
+
+    /* Position. */
+    stream_loc[tabi++] = 0;
+
+    /* Point size. */
+    if (vs_outputs->psize != ATTR_UNUSED) {
+        stream_loc[tabi++] = 1;
+    }
+
+    /* Colors. */
+    for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+        if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used) {
+            stream_loc[tabi++] = 2 + i;
+        }
+    }
+
+    /* Back-face colors. */
+    if (any_bcolor_used) {
+        for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+            stream_loc[tabi++] = 4 + i;
+        }
+    }
+
+    /* Texture coordinates. */
+    gen_count = 0;
+    for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
+        if (vs_outputs->generic[i] != ATTR_UNUSED) {
+            assert(tabi < 16);
+            stream_loc[tabi++] = 6 + gen_count;
+            gen_count++;
+        }
+    }
+
+    /* Fog coordinates. */
+    if (vs_outputs->fog != ATTR_UNUSED) {
+        assert(tabi < 16);
+        stream_loc[tabi++] = 6 + gen_count;
+        gen_count++;
+    }
+
+    /* WPOS. */
+    if (vs_outputs->wpos != ATTR_UNUSED) {
+        assert(tabi < 16);
+        stream_loc[tabi++] = 6 + gen_count;
+        gen_count++;
+    }
+
+    for (; tabi < 16;) {
+        stream_loc[tabi++] = -1;
+    }
+}
 
 static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
 {
     struct r300_vertex_shader * vs = c->UserData;
+    struct r300_shader_semantics* outputs = &vs->outputs;
     struct tgsi_shader_info* info = &vs->info;
-    struct tgsi_parse_context parser;
-    struct tgsi_full_declaration * decl;
-    boolean pointsize = FALSE;
-    int out_colors = 0;
-    int colors = 0;
-    int out_generic = 0;
-    int generic = 0;
-    int i;
+    int i, reg = 0;
+    boolean any_bcolor_used = outputs->bcolor[0] != ATTR_UNUSED ||
+                              outputs->bcolor[1] != ATTR_UNUSED;
 
     /* Fill in the input mapping */
     for (i = 0; i < info->num_inputs; i++)
         c->code->inputs[i] = i;
 
-    /* Fill in the output mapping */
-    for (i = 0; i < info->num_outputs; i++) {
-        switch (info->output_semantic_name[i]) {
-            case TGSI_SEMANTIC_PSIZE:
-                pointsize = TRUE;
-                break;
-            case TGSI_SEMANTIC_COLOR:
-                out_colors++;
-                break;
-            case TGSI_SEMANTIC_FOG:
-            case TGSI_SEMANTIC_GENERIC:
-                out_generic++;
-                break;
+    /* Position. */
+    if (outputs->pos != ATTR_UNUSED) {
+        c->code->outputs[outputs->pos] = reg++;
+    } else {
+        assert(0);
+    }
+
+    /* Point size. */
+    if (outputs->psize != ATTR_UNUSED) {
+        c->code->outputs[outputs->psize] = reg++;
+    }
+
+    /* If we're writing back facing colors we need to send
+     * four colors to make front/back face colors selection work.
+     * If the vertex program doesn't write all 4 colors, lets
+     * pretend it does by skipping output index reg so the colors
+     * get written into appropriate output vectors.
+     */
+
+    /* Colors. */
+    for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+        if (outputs->color[i] != ATTR_UNUSED) {
+            c->code->outputs[outputs->color[i]] = reg++;
+        } else if (any_bcolor_used) {
+            reg++;
         }
     }
 
-    tgsi_parse_init(&parser, vs->state.tokens);
-
-    while (!tgsi_parse_end_of_tokens(&parser)) {
-        tgsi_parse_token(&parser);
-
-        if (parser.FullToken.Token.Type != TGSI_TOKEN_TYPE_DECLARATION)
-            continue;
-
-        decl = &parser.FullToken.FullDeclaration;
-
-        if (decl->Declaration.File != TGSI_FILE_OUTPUT)
-            continue;
-
-        switch (decl->Semantic.SemanticName) {
-            case TGSI_SEMANTIC_POSITION:
-                c->code->outputs[decl->DeclarationRange.First] = 0;
-                break;
-            case TGSI_SEMANTIC_PSIZE:
-                c->code->outputs[decl->DeclarationRange.First] = 1;
-                break;
-            case TGSI_SEMANTIC_COLOR:
-                c->code->outputs[decl->DeclarationRange.First] = 1 +
-                    (pointsize ? 1 : 0) +
-                    colors++;
-                break;
-            case TGSI_SEMANTIC_FOG:
-            case TGSI_SEMANTIC_GENERIC:
-                c->code->outputs[decl->DeclarationRange.First] = 1 +
-                    (pointsize ? 1 : 0) +
-                    out_colors +
-                    generic++;
-                break;
-            default:
-                debug_printf("r300: vs: Bad semantic declaration %d\n",
-                    decl->Semantic.SemanticName);
-                break;
+    /* Back-face colors. */
+    for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+        if (outputs->bcolor[i] != ATTR_UNUSED) {
+            c->code->outputs[outputs->bcolor[i]] = reg++;
+        } else if (any_bcolor_used) {
+            reg++;
         }
     }
 
-    tgsi_parse_free(&parser);
+    /* Texture coordinates. */
+    for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
+        if (outputs->generic[i] != ATTR_UNUSED) {
+            c->code->outputs[outputs->generic[i]] = reg++;
+        }
+    }
+
+    /* Fog coordinates. */
+    if (outputs->fog != ATTR_UNUSED) {
+        c->code->outputs[outputs->fog] = reg++;
+    }
+
+    /* WPOS. */
+    if (outputs->wpos != ATTR_UNUSED) {
+        c->code->outputs[outputs->wpos] = reg++;
+    }
 }
 
+static void r300_insert_wpos(struct r300_vertex_program_compiler* c,
+                             struct r300_shader_semantics* outputs)
+{
+    int i, lastOutput = 0;
+
+    /* Find the max output index. */
+    lastOutput = MAX2(lastOutput, outputs->psize);
+    for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+        lastOutput = MAX2(lastOutput, outputs->color[i]);
+        lastOutput = MAX2(lastOutput, outputs->bcolor[i]);
+    }
+    for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
+        lastOutput = MAX2(lastOutput, outputs->generic[i]);
+    }
+    lastOutput = MAX2(lastOutput, outputs->fog);
+
+    /* Set WPOS after the last output. */
+    lastOutput++;
+    rc_copy_output(&c->Base, 0, lastOutput); /* out[lastOutput] = out[0]; */
+    outputs->wpos = lastOutput;
+}
 
 void r300_translate_vertex_shader(struct r300_context* r300,
                                   struct r300_vertex_shader* vs)
@@ -113,6 +319,9 @@
     struct r300_vertex_program_compiler compiler;
     struct tgsi_to_rc ttr;
 
+    /* Initialize. */
+    r300_shader_read_vs_outputs(&vs->info, &vs->outputs);
+
     /* Setup the compiler */
     rc_init(&compiler.Base);
 
@@ -131,13 +340,19 @@
 
     r300_tgsi_to_rc(&ttr, vs->state.tokens);
 
-    compiler.RequiredOutputs = ~(~0 << vs->info.num_outputs);
+    compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs+1));
     compiler.SetHwInputOutput = &set_vertex_inputs_outputs;
 
+    /* Insert the WPOS output. */
+    r300_insert_wpos(&compiler, &vs->outputs);
+
+    r300_shader_vap_output_fmt(vs);
+    r300_stream_locations_notcl(&vs->outputs, vs->stream_loc_notcl);
+
     /* Invoke the compiler */
     r3xx_compile_vertex_program(&compiler);
     if (compiler.Base.Error) {
-        /* Todo: Fail gracefully */
+        /* XXX We should fallback using Draw. */
         fprintf(stderr, "r300 VP: Compiler error\n");
         abort();
     }
@@ -146,3 +361,30 @@
     rc_destroy(&compiler.Base);
     vs->translated = TRUE;
 }
+
+boolean r300_vertex_shader_setup_wpos(struct r300_context* r300)
+{
+    struct r300_vertex_shader* vs = r300->vs;
+    int tex_output = r300->vs->wpos_tex_output;
+    uint32_t tex_fmt = R300_INPUT_CNTL_TC0 << tex_output;
+    uint32_t* hwfmt = vs->hwfmt;
+
+    if (r300->fs->inputs.wpos != ATTR_UNUSED) {
+        /* Enable WPOS in VAP. */
+        if (!(hwfmt[1] & tex_fmt)) {
+            hwfmt[1] |= tex_fmt;
+            hwfmt[3] |= (4 << (3 * tex_output));
+
+            assert(tex_output < 8);
+            return TRUE;
+        }
+    } else {
+        /* Disable WPOS in VAP. */
+        if (hwfmt[1] & tex_fmt) {
+            hwfmt[1] &= ~tex_fmt;
+            hwfmt[3] &= ~(4 << (3 * tex_output));
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h
index 2a4ce31..18cfeee 100644
--- a/src/gallium/drivers/r300/r300_vs.h
+++ b/src/gallium/drivers/r300/r300_vs.h
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2009 Marek Olšák <maraeo@gmail.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -25,18 +26,25 @@
 
 #include "pipe/p_state.h"
 #include "tgsi/tgsi_scan.h"
-
 #include "radeon_code.h"
 
+#include "r300_shader_semantics.h"
+
 struct r300_context;
 
 struct r300_vertex_shader {
     /* Parent class */
     struct pipe_shader_state state;
-    struct tgsi_shader_info info;
 
-    /* Fallback shader, because Draw has issues */
-    struct draw_vertex_shader* draw;
+    struct tgsi_shader_info info;
+    struct r300_shader_semantics outputs;
+    uint hwfmt[4];
+
+    /* Stream locations for SWTCL or if TCL is bypassed. */
+    int stream_loc_notcl[16];
+
+    /* Output stream location for WPOS. */
+    int wpos_tex_output;
 
     /* Has this shader been translated yet? */
     boolean translated;
@@ -45,10 +53,10 @@
     struct r300_vertex_program_code code;
 };
 
-
-extern struct r300_vertex_program_code r300_passthrough_vertex_shader;
-
 void r300_translate_vertex_shader(struct r300_context* r300,
                                   struct r300_vertex_shader* vs);
 
+/* Return TRUE if VAP (hwfmt) needs to be re-emitted. */
+boolean r300_vertex_shader_setup_wpos(struct r300_context* r300);
+
 #endif /* R300_VS_H */
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index 864a614..1ae6de7 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -35,76 +35,10 @@
 #include "pipe/p_state.h"
 #include "pipe/internal/p_winsys_screen.h"
 
-struct r300_winsys {
-    /* Parent class */
-    struct pipe_winsys base;
-
-    /* Opaque Radeon-specific winsys object. */
-    void* radeon_winsys;
-
-    /* PCI ID */
-    uint32_t pci_id;
-
-    /* GB pipe count */
-    uint32_t gb_pipes;
-
-    /* Z pipe count (rv530 only) */
-    uint32_t z_pipes;
-
-    /* GART size. */
-    uint32_t gart_size;
-
-    /* VRAM size. */
-    uint32_t vram_size;
-
-    /* Add a pipe_buffer to the list of buffer objects to validate. */
-    boolean (*add_buffer)(struct r300_winsys* winsys,
-                          struct pipe_buffer* pbuffer,
-                          uint32_t rd,
-                          uint32_t wd);
-
-    /* Revalidate all currently setup pipe_buffers.
-     * Returns TRUE if a flush is required. */
-    boolean (*validate)(struct r300_winsys* winsys);
-
-    /* Check to see if there's room for commands. */
-    boolean (*check_cs)(struct r300_winsys* winsys, int size);
-
-    /* Start a command emit. */
-    void (*begin_cs)(struct r300_winsys* winsys,
-                     int size,
-                     const char* file,
-                     const char* function,
-                     int line);
-
-    /* Write a dword to the command buffer. */
-    void (*write_cs_dword)(struct r300_winsys* winsys, uint32_t dword);
-
-    /* Write a relocated dword to the command buffer. */
-    void (*write_cs_reloc)(struct r300_winsys* winsys,
-                           struct pipe_buffer* bo,
-                           uint32_t rd,
-                           uint32_t wd,
-                           uint32_t flags);
-
-    /* Finish a command emit. */
-    void (*end_cs)(struct r300_winsys* winsys,
-                   const char* file,
-                   const char* function,
-                   int line);
-
-    /* Flush the CS. */
-    void (*flush_cs)(struct r300_winsys* winsys);
-
-    /* winsys flush - callback from winsys when flush required */
-    void (*set_flush_cb)(struct r300_winsys *winsys,
-			 void (*flush_cb)(void *), void *data);
-
-    void (*reset_bos)(struct r300_winsys *winsys);
-};
+#include "radeon_winsys.h"
 
 struct pipe_context* r300_create_context(struct pipe_screen* screen,
-                                         struct r300_winsys* r300_winsys);
+                                         struct radeon_winsys* radeon_winsys);
 
 boolean r300_get_texture_buffer(struct pipe_texture* texture,
                                 struct pipe_buffer** buffer,
diff --git a/src/gallium/drivers/softpipe/sp_clear.c b/src/gallium/drivers/softpipe/sp_clear.c
index 8fac8e6..5f13045 100644
--- a/src/gallium/drivers/softpipe/sp_clear.c
+++ b/src/gallium/drivers/softpipe/sp_clear.c
@@ -36,6 +36,7 @@
 #include "util/u_pack_color.h"
 #include "sp_clear.h"
 #include "sp_context.h"
+#include "sp_query.h"
 #include "sp_tile_cache.h"
 
 
@@ -48,12 +49,16 @@
                double depth, unsigned stencil)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
+   union util_color uc;
    unsigned cv;
    uint i;
 
    if (softpipe->no_rast)
       return;
 
+   if (!softpipe_check_render_cond(softpipe))
+      return;
+
 #if 0
    softpipe_update_derived(softpipe); /* not needed?? */
 #endif
@@ -62,12 +67,12 @@
       for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) {
          struct pipe_surface *ps = softpipe->framebuffer.cbufs[i];
 
-         util_pack_color(rgba, ps->format, &cv);
-         sp_tile_cache_clear(softpipe->cbuf_cache[i], rgba, cv);
+         util_pack_color(rgba, ps->format, &uc);
+         sp_tile_cache_clear(softpipe->cbuf_cache[i], rgba, uc.ui);
 
 #if !TILE_CLEAR_OPTIMIZATION
          /* non-cached surface */
-         pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv);
+         pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, uc.ui);
 #endif
       }
    }
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index 94d000a..f3ac676 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -90,14 +90,15 @@
    if (softpipe->draw)
       draw_destroy( softpipe->draw );
 
-      softpipe->quad.shade->destroy( softpipe->quad.shade );
-      softpipe->quad.depth_test->destroy( softpipe->quad.depth_test );
-      softpipe->quad.blend->destroy( softpipe->quad.blend );
+   softpipe->quad.shade->destroy( softpipe->quad.shade );
+   softpipe->quad.depth_test->destroy( softpipe->quad.depth_test );
+   softpipe->quad.blend->destroy( softpipe->quad.blend );
 
    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
       sp_destroy_tile_cache(softpipe->cbuf_cache[i]);
       pipe_surface_reference(&softpipe->framebuffer.cbufs[i], NULL);
    }
+
    sp_destroy_tile_cache(softpipe->zsbuf_cache);
    pipe_surface_reference(&softpipe->framebuffer.zsbuf, NULL);
 
@@ -106,6 +107,11 @@
       pipe_texture_reference(&softpipe->texture[i], NULL);
    }
 
+   for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+      sp_destroy_tex_tile_cache(softpipe->vertex_tex_cache[i]);
+      pipe_texture_reference(&softpipe->vertex_textures[i], NULL);
+   }
+
    for (i = 0; i < Elements(softpipe->constants); i++) {
       if (softpipe->constants[i].buffer) {
          pipe_buffer_reference(&softpipe->constants[i].buffer, NULL);
@@ -120,7 +126,7 @@
  * if (the texture is being used as a framebuffer surface)
  *    return PIPE_REFERENCED_FOR_WRITE
  * else if (the texture is a bound texture source)
- *    return PIPE_REFERENCED_FOR_READ  XXX not done yet
+ *    return PIPE_REFERENCED_FOR_READ
  * else
  *    return PIPE_UNREFERENCED
  */
@@ -132,6 +138,7 @@
    struct softpipe_context *softpipe = softpipe_context( pipe );
    unsigned i;
 
+   /* check if any of the bound drawing surfaces are this texture */
    if (softpipe->dirty_render_cache) {
       for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) {
          if (softpipe->framebuffer.cbufs[i] && 
@@ -145,7 +152,17 @@
       }
    }
    
-   /* FIXME: we also need to do the same for the texture cache */
+   /* check if any of the tex_cache textures are this texture */
+   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+      if (softpipe->tex_cache[i] &&
+          softpipe->tex_cache[i]->texture == texture)
+         return PIPE_REFERENCED_FOR_READ;
+   }
+   for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+      if (softpipe->vertex_tex_cache[i] &&
+          softpipe->vertex_tex_cache[i]->texture == texture)
+         return PIPE_REFERENCED_FOR_READ;
+   }
    
    return PIPE_UNREFERENCED;
 }
@@ -159,6 +176,19 @@
 }
 
 
+static void
+softpipe_render_condition( struct pipe_context *pipe,
+                           struct pipe_query *query,
+                           uint mode )
+{
+   struct softpipe_context *softpipe = softpipe_context( pipe );
+
+   softpipe->render_cond_query = query;
+   softpipe->render_cond_mode = mode;
+}
+
+
+
 struct pipe_context *
 softpipe_create( struct pipe_screen *screen )
 {
@@ -174,6 +204,7 @@
 #endif
 
    softpipe->dump_fs = debug_get_bool_option( "GALLIUM_DUMP_FS", FALSE );
+   softpipe->dump_gs = debug_get_bool_option( "SOFTPIPE_DUMP_GS", FALSE );
 
    softpipe->pipe.winsys = screen->winsys;
    softpipe->pipe.screen = screen;
@@ -185,7 +216,8 @@
    softpipe->pipe.delete_blend_state = softpipe_delete_blend_state;
 
    softpipe->pipe.create_sampler_state = softpipe_create_sampler_state;
-   softpipe->pipe.bind_sampler_states  = softpipe_bind_sampler_states;
+   softpipe->pipe.bind_fragment_sampler_states  = softpipe_bind_sampler_states;
+   softpipe->pipe.bind_vertex_sampler_states = softpipe_bind_vertex_sampler_states;
    softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state;
 
    softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state;
@@ -204,13 +236,18 @@
    softpipe->pipe.bind_vs_state   = softpipe_bind_vs_state;
    softpipe->pipe.delete_vs_state = softpipe_delete_vs_state;
 
+   softpipe->pipe.create_gs_state = softpipe_create_gs_state;
+   softpipe->pipe.bind_gs_state   = softpipe_bind_gs_state;
+   softpipe->pipe.delete_gs_state = softpipe_delete_gs_state;
+
    softpipe->pipe.set_blend_color = softpipe_set_blend_color;
    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;
    softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
    softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
-   softpipe->pipe.set_sampler_textures = softpipe_set_sampler_textures;
+   softpipe->pipe.set_fragment_sampler_textures = softpipe_set_sampler_textures;
+   softpipe->pipe.set_vertex_sampler_textures = softpipe_set_vertex_sampler_textures;
    softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
 
    softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers;
@@ -219,8 +256,6 @@
    softpipe->pipe.draw_arrays = softpipe_draw_arrays;
    softpipe->pipe.draw_elements = softpipe_draw_elements;
    softpipe->pipe.draw_range_elements = softpipe_draw_range_elements;
-   softpipe->pipe.set_edgeflags = softpipe_set_edgeflags;
-
 
    softpipe->pipe.clear = softpipe_clear;
    softpipe->pipe.flush = softpipe_flush;
@@ -230,6 +265,8 @@
 
    softpipe_init_query_funcs( softpipe );
 
+   softpipe->pipe.render_condition = softpipe_render_condition;
+
    /*
     * Alloc caches for accessing drawing surfaces and textures.
     * Must be before quad stage setup!
@@ -240,12 +277,14 @@
 
    for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
       softpipe->tex_cache[i] = sp_create_tex_tile_cache( screen );
-
+   for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+      softpipe->vertex_tex_cache[i] = sp_create_tex_tile_cache(screen);
+   }
 
    /* setup quad rendering stages */
-      softpipe->quad.shade = sp_quad_shade_stage(softpipe);
-      softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);
-      softpipe->quad.blend = sp_quad_blend_stage(softpipe);
+   softpipe->quad.shade = sp_quad_shade_stage(softpipe);
+   softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);
+   softpipe->quad.blend = sp_quad_blend_stage(softpipe);
 
 
    /*
@@ -256,7 +295,7 @@
       goto fail;
 
    draw_texture_samplers(softpipe->draw,
-                         PIPE_MAX_SAMPLERS,
+                         PIPE_MAX_VERTEX_SAMPLERS,
                          (struct tgsi_sampler **)
                             softpipe->tgsi.vert_samplers_list);
 
@@ -275,7 +314,6 @@
    draw_set_render(softpipe->draw, softpipe->vbuf_backend);
 
 
-
    /* plug in AA line/point stages */
    draw_install_aaline_stage(softpipe->draw, &softpipe->pipe);
    draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe);
@@ -291,4 +329,3 @@
    softpipe_destroy(&softpipe->pipe);
    return NULL;
 }
-
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index a735573..73fa744 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -53,10 +53,12 @@
    /** Constant state objects */
    struct pipe_blend_state *blend;
    struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
+   struct pipe_sampler_state *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS];
    struct pipe_depth_stencil_alpha_state *depth_stencil;
    struct pipe_rasterizer_state *rasterizer;
    struct sp_fragment_shader *fs;
    struct sp_vertex_shader *vs;
+   struct sp_geometry_shader *gs;
 
    /** Other rendering state */
    struct pipe_blend_color blend_color;
@@ -66,12 +68,15 @@
    struct pipe_poly_stipple poly_stipple;
    struct pipe_scissor_state scissor;
    struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
+   struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
    struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
 
    unsigned num_samplers;
    unsigned num_textures;
+   unsigned num_vertex_samplers;
+   unsigned num_vertex_textures;
    unsigned num_vertex_elements;
    unsigned num_vertex_buffers;
 
@@ -111,6 +116,10 @@
 
    unsigned line_stipple_counter;
 
+   /** Conditional query object and mode */
+   struct pipe_query *render_cond_query;
+   uint render_cond_mode;
+
    /** Software quad rendering pipeline */
    struct {
       struct quad_stage *shade;
@@ -121,7 +130,7 @@
 
    /** TGSI exec things */
    struct {
-      struct sp_sampler_varient *vert_samplers_list[PIPE_MAX_SAMPLERS];
+      struct sp_sampler_varient *vert_samplers_list[PIPE_MAX_VERTEX_SAMPLERS];
       struct sp_sampler_varient *frag_samplers_list[PIPE_MAX_SAMPLERS];
    } tgsi;
 
@@ -139,9 +148,11 @@
 
    unsigned tex_timestamp;
    struct softpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
+   struct softpipe_tex_tile_cache *vertex_tex_cache[PIPE_MAX_VERTEX_SAMPLERS];
 
    unsigned use_sse : 1;
    unsigned dump_fs : 1;
+   unsigned dump_gs : 1;
    unsigned no_rast : 1;
 };
 
diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c
index d404581..03d35fb 100644
--- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
+++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
@@ -38,6 +38,7 @@
 #include "util/u_prim.h"
 
 #include "sp_context.h"
+#include "sp_query.h"
 #include "sp_state.h"
 
 #include "draw/draw_context.h"
@@ -48,7 +49,7 @@
 softpipe_map_constant_buffers(struct softpipe_context *sp)
 {
    struct pipe_winsys *ws = sp->pipe.winsys;
-   uint i, size;
+   uint i, vssize, gssize;
 
    for (i = 0; i < PIPE_SHADER_TYPES; i++) {
       if (sp->constants[i].buffer && sp->constants[i].buffer->size)
@@ -57,13 +58,21 @@
    }
 
    if (sp->constants[PIPE_SHADER_VERTEX].buffer)
-      size = sp->constants[PIPE_SHADER_VERTEX].buffer->size;
+      vssize = sp->constants[PIPE_SHADER_VERTEX].buffer->size;
    else
-      size = 0;
+      vssize = 0;
 
-   draw_set_mapped_constant_buffer(sp->draw,
+   if (sp->constants[PIPE_SHADER_GEOMETRY].buffer)
+      gssize = sp->constants[PIPE_SHADER_GEOMETRY].buffer->size;
+   else
+      gssize = 0;
+
+   draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX,
                                    sp->mapped_constants[PIPE_SHADER_VERTEX],
-                                   size);
+                                   vssize);
+   draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_GEOMETRY,
+                                   sp->mapped_constants[PIPE_SHADER_GEOMETRY],
+                                   gssize);
 }
 
 
@@ -78,9 +87,10 @@
     */
    draw_flush(sp->draw);
 
-   draw_set_mapped_constant_buffer(sp->draw, NULL, 0);
+   draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, NULL, 0);
+   draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_GEOMETRY, NULL, 0);
 
-   for (i = 0; i < 2; i++) {
+   for (i = 0; i < PIPE_SHADER_TYPES; i++) {
       if (sp->constants[i].buffer && sp->constants[i].buffer->size)
          ws->buffer_unmap(ws, sp->constants[i].buffer);
       sp->mapped_constants[i] = NULL;
@@ -88,11 +98,11 @@
 }
 
 
-boolean
+void
 softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
                      unsigned start, unsigned count)
 {
-   return softpipe_draw_elements(pipe, NULL, 0, mode, start, count);
+   softpipe_draw_elements(pipe, NULL, 0, mode, start, count);
 }
 
 
@@ -101,7 +111,7 @@
  * Basically, map the vertex buffers (and drawing surfaces), then hand off
  * the drawing to the 'draw' module.
  */
-boolean
+void
 softpipe_draw_range_elements(struct pipe_context *pipe,
                              struct pipe_buffer *indexBuffer,
                              unsigned indexSize,
@@ -113,6 +123,9 @@
    struct draw_context *draw = sp->draw;
    unsigned i;
 
+   if (!softpipe_check_render_cond(sp))
+      return;
+
    sp->reduced_api_prim = u_reduced_prim(mode);
 
    if (sp->dirty)
@@ -168,27 +181,17 @@
    softpipe_unmap_constant_buffers(sp);
 
    sp->dirty_render_cache = TRUE;
-   
-   return TRUE;
 }
 
 
-boolean
+void
 softpipe_draw_elements(struct pipe_context *pipe,
                        struct pipe_buffer *indexBuffer,
                        unsigned indexSize,
                        unsigned mode, unsigned start, unsigned count)
 {
-   return softpipe_draw_range_elements( pipe, indexBuffer,
-                                        indexSize,
-                                        0, 0xffffffff,
-                                        mode, start, count );
-}
-
-
-void
-softpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags)
-{
-   struct softpipe_context *sp = softpipe_context(pipe);
-   draw_set_edgeflags(sp->draw, edgeflags);
+   softpipe_draw_range_elements( pipe, indexBuffer,
+                                 indexSize,
+                                 0, 0xffffffff,
+                                 mode, start, count );
 }
diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c
index e38b767..75dac81 100644
--- a/src/gallium/drivers/softpipe/sp_flush.c
+++ b/src/gallium/drivers/softpipe/sp_flush.c
@@ -55,6 +55,9 @@
       for (i = 0; i < softpipe->num_textures; i++) {
          sp_flush_tex_tile_cache(softpipe->tex_cache[i]);
       }
+      for (i = 0; i < softpipe->num_vertex_textures; i++) {
+         sp_flush_tex_tile_cache(softpipe->vertex_tex_cache[i]);
+      }
    }
 
    if (flags & PIPE_FLUSH_SWAPBUFFERS) {
diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c
index 4076114..27fa126 100644
--- a/src/gallium/drivers/softpipe/sp_fs_exec.c
+++ b/src/gallium/drivers/softpipe/sp_fs_exec.c
@@ -126,7 +126,10 @@
    setup_pos_vector(quad->posCoef, 
                     (float)quad->input.x0, (float)quad->input.y0, 
                     &machine->QuadPos);
-   
+
+   /* convert 0 to 1.0 and 1 to -1.0 */
+   machine->Face = (float) (quad->input.facing * -2 + 1);
+
    quad->inout.mask &= tgsi_exec_machine_run( machine );
    if (quad->inout.mask == 0)
       return FALSE;
diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
index 5fbac06..7f573ae 100644
--- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c
+++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
@@ -128,6 +128,7 @@
 {
    struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
    assert( cvbr->vertex_buffer_size >= (max_index+1) * cvbr->vertex_size );
+   (void) cvbr;
    /* do nothing */
 }
 
diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c
index fe6b6ce..d9babe8 100644
--- a/src/gallium/drivers/softpipe/sp_quad_blend.c
+++ b/src/gallium/drivers/softpipe/sp_quad_blend.c
@@ -229,7 +229,7 @@
    static const float zero[4] = { 0, 0, 0, 0 };
    static const float one[4] = { 1, 1, 1, 1 };
    struct softpipe_context *softpipe = qs->softpipe;
-   float source[4][QUAD_SIZE];
+   float source[4][QUAD_SIZE] = { { 0 } };
 
    /*
     * Compute src/first term RGB
diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c
index 379cf4a..4ef5d9f 100644
--- a/src/gallium/drivers/softpipe/sp_query.c
+++ b/src/gallium/drivers/softpipe/sp_query.c
@@ -99,6 +99,32 @@
 }
 
 
+/**
+ * Called by rendering function to check rendering is conditional.
+ * \return TRUE if we should render, FALSE if we should skip rendering
+ */
+boolean
+softpipe_check_render_cond(struct softpipe_context *sp)
+{
+   struct pipe_context *pipe = &sp->pipe;
+   boolean b, wait;
+   uint64_t result;
+
+   if (!sp->render_cond_query) {
+      return TRUE;  /* no query predicate, draw normally */
+   }
+
+   wait = (sp->render_cond_mode == PIPE_RENDER_COND_WAIT ||
+           sp->render_cond_mode == PIPE_RENDER_COND_BY_REGION_WAIT);
+
+   b = pipe->get_query_result(pipe, sp->render_cond_query, wait, &result);
+   if (b)
+      return result > 0;
+   else
+      return TRUE;
+}
+
+
 void softpipe_init_query_funcs(struct softpipe_context *softpipe )
 {
    softpipe->pipe.create_query = softpipe_create_query;
diff --git a/src/gallium/drivers/softpipe/sp_query.h b/src/gallium/drivers/softpipe/sp_query.h
index 05060a4..736c033 100644
--- a/src/gallium/drivers/softpipe/sp_query.h
+++ b/src/gallium/drivers/softpipe/sp_query.h
@@ -32,6 +32,10 @@
 #ifndef SP_QUERY_H
 #define SP_QUERY_H
 
+extern boolean
+softpipe_check_render_cond(struct softpipe_context *sp);
+
+
 struct softpipe_context;
 extern void softpipe_init_query_funcs(struct softpipe_context * );
 
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 81fb7aa..bd3532d 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -58,7 +58,9 @@
    case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
       return PIPE_MAX_SAMPLERS;
    case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
-      return PIPE_MAX_SAMPLERS;
+      return PIPE_MAX_VERTEX_SAMPLERS;
+   case PIPE_CAP_MAX_COMBINED_SAMPLERS:
+      return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS;
    case PIPE_CAP_NPOT_TEXTURES:
       return 1;
    case PIPE_CAP_TWO_SIDED_STENCIL:
@@ -143,6 +145,11 @@
    case PIPE_FORMAT_DXT3_RGBA:
    case PIPE_FORMAT_DXT5_RGBA:
    case PIPE_FORMAT_Z32_FLOAT:
+   case PIPE_FORMAT_R8G8_SNORM:
+   case PIPE_FORMAT_B6UG5SR5S_NORM:
+   case PIPE_FORMAT_X8UB8UG8SR8S_NORM:
+   case PIPE_FORMAT_A8B8G8R8_SNORM:
+   case PIPE_FORMAT_NONE:
       return FALSE;
    default:
       return TRUE;
diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c
index 615581b..3da7536 100644
--- a/src/gallium/drivers/softpipe/sp_setup.c
+++ b/src/gallium/drivers/softpipe/sp_setup.c
@@ -1268,7 +1268,7 @@
    }
 
    /* Note: nr_attrs is only used for debugging (vertex printing) */
-   setup->nr_vertex_attrs = draw_num_vs_outputs(sp->draw);
+   setup->nr_vertex_attrs = draw_num_shader_outputs(sp->draw);
 
    sp->quad.first->begin( sp->quad.first );
 
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index 77ee3c1..9b18dac 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -50,6 +50,7 @@
 #define SP_NEW_VERTEX        0x1000
 #define SP_NEW_VS            0x2000
 #define SP_NEW_QUERY         0x4000
+#define SP_NEW_GS            0x8000
 
 
 struct tgsi_sampler;
@@ -90,6 +91,11 @@
    int max_sampler;             /* -1 if no samplers */
 };
 
+/** Subclass of pipe_shader_state */
+struct sp_geometry_shader {
+   struct pipe_shader_state shader;
+   struct draw_geometry_shader *draw_data;
+};
 
 
 void *
@@ -104,6 +110,10 @@
 softpipe_create_sampler_state(struct pipe_context *,
                               const struct pipe_sampler_state *);
 void softpipe_bind_sampler_states(struct pipe_context *, unsigned, void **);
+void
+softpipe_bind_vertex_sampler_states(struct pipe_context *,
+                                    unsigned num_samplers,
+                                    void **samplers);
 void softpipe_delete_sampler_state(struct pipe_context *, void *);
 
 void *
@@ -139,6 +149,10 @@
                                const struct pipe_shader_state *);
 void softpipe_bind_vs_state(struct pipe_context *, void *);
 void softpipe_delete_vs_state(struct pipe_context *, void *);
+void *softpipe_create_gs_state(struct pipe_context *,
+                               const struct pipe_shader_state *);
+void softpipe_bind_gs_state(struct pipe_context *, void *);
+void softpipe_delete_gs_state(struct pipe_context *, void *);
 
 void softpipe_set_polygon_stipple( struct pipe_context *,
 				  const struct pipe_poly_stipple * );
@@ -150,6 +164,11 @@
                                     unsigned num,
                                     struct pipe_texture ** );
 
+void
+softpipe_set_vertex_sampler_textures(struct pipe_context *,
+                                     unsigned num_textures,
+                                     struct pipe_texture **);
+
 void softpipe_set_viewport_state( struct pipe_context *,
                                   const struct pipe_viewport_state * );
 
@@ -165,14 +184,14 @@
 void softpipe_update_derived( struct softpipe_context *softpipe );
 
 
-boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
-			     unsigned start, unsigned count);
+void softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
+                          unsigned start, unsigned count);
 
-boolean softpipe_draw_elements(struct pipe_context *pipe,
-			       struct pipe_buffer *indexBuffer,
-			       unsigned indexSize,
-			       unsigned mode, unsigned start, unsigned count);
-boolean
+void softpipe_draw_elements(struct pipe_context *pipe,
+                            struct pipe_buffer *indexBuffer,
+                            unsigned indexSize,
+                            unsigned mode, unsigned start, unsigned count);
+void
 softpipe_draw_range_elements(struct pipe_context *pipe,
                              struct pipe_buffer *indexBuffer,
                              unsigned indexSize,
@@ -181,10 +200,6 @@
                              unsigned mode, unsigned start, unsigned count);
 
 void
-softpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags);
-
-
-void
 softpipe_map_transfers(struct softpipe_context *sp);
 
 void
diff --git a/src/gallium/drivers/softpipe/sp_state_blend.c b/src/gallium/drivers/softpipe/sp_state_blend.c
index efed082..95ab323 100644
--- a/src/gallium/drivers/softpipe/sp_state_blend.c
+++ b/src/gallium/drivers/softpipe/sp_state_blend.c
@@ -29,6 +29,7 @@
  */
 
 #include "util/u_memory.h"
+#include "draw/draw_context.h"
 #include "sp_context.h"
 #include "sp_state.h"
 
@@ -45,6 +46,8 @@
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
 
+   draw_flush(softpipe->draw);
+
    softpipe->blend = (struct pipe_blend_state *)blend;
 
    softpipe->dirty |= SP_NEW_BLEND;
@@ -62,6 +65,8 @@
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
 
+   draw_flush(softpipe->draw);
+
    softpipe->blend_color = *blend_color;
 
    softpipe->dirty |= SP_NEW_BLEND;
diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c
index 3bc96b9..f6856a5 100644
--- a/src/gallium/drivers/softpipe/sp_state_derived.c
+++ b/src/gallium/drivers/softpipe/sp_state_derived.c
@@ -67,7 +67,7 @@
       /* compute vertex layout now */
       const struct sp_fragment_shader *spfs = softpipe->fs;
       struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
-      const uint num = draw_num_vs_outputs(softpipe->draw);
+      const uint num = draw_current_shader_outputs(softpipe->draw);
       uint i;
 
       /* Tell draw_vbuf to simply emit the whole post-xform vertex
@@ -117,13 +117,13 @@
          }
 
          /* this includes texcoords and varying vars */
-         src = draw_find_vs_output(softpipe->draw,
-                                   spfs->info.input_semantic_name[i],
-                                   spfs->info.input_semantic_index[i]);
+         src = draw_find_shader_output(softpipe->draw,
+                                       spfs->info.input_semantic_name[i],
+                                       spfs->info.input_semantic_index[i]);
          draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src);
       }
 
-      softpipe->psize_slot = draw_find_vs_output(softpipe->draw,
+      softpipe->psize_slot = draw_find_shader_output(softpipe->draw,
                                                  TGSI_SEMANTIC_PSIZE, 0);
       if (softpipe->psize_slot > 0) {
          draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
@@ -213,6 +213,19 @@
          }
       }
    }
+
+   for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+      struct softpipe_tex_tile_cache *tc = softpipe->vertex_tex_cache[i];
+
+      if (tc->texture) {
+         struct softpipe_texture *spt = softpipe_texture(tc->texture);
+
+         if (spt->timestamp != tc->timestamp) {
+	    sp_tex_tile_cache_validate_texture(tc);
+            tc->timestamp = spt->timestamp;
+         }
+      }
+   }
 }
 
 
diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c
index 256faa9..aa12bb2 100644
--- a/src/gallium/drivers/softpipe/sp_state_fs.c
+++ b/src/gallium/drivers/softpipe/sp_state_fs.c
@@ -69,7 +69,14 @@
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
 
-   softpipe->fs = (struct sp_fragment_shader *) fs;
+   draw_flush(softpipe->draw);
+
+   if (softpipe->fs == fs)
+      return;
+
+   draw_flush(softpipe->draw);
+
+   softpipe->fs = fs;
 
    softpipe->dirty |= SP_NEW_FS;
 }
@@ -143,6 +150,7 @@
    struct sp_vertex_shader *state = (struct sp_vertex_shader *) vs;
 
    draw_delete_vertex_shader(softpipe->draw, state->draw_data);
+   FREE( (void *)state->shader.tokens );
    FREE( state );
 }
 
@@ -158,9 +166,75 @@
    assert(shader < PIPE_SHADER_TYPES);
    assert(index == 0);
 
+   draw_flush(softpipe->draw);
+
    /* note: reference counting */
    pipe_buffer_reference(&softpipe->constants[shader].buffer,
 			 buf ? buf->buffer : NULL);
 
    softpipe->dirty |= SP_NEW_CONSTANTS;
 }
+
+void *
+softpipe_create_gs_state(struct pipe_context *pipe,
+                         const struct pipe_shader_state *templ)
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+   struct sp_geometry_shader *state;
+
+   state = CALLOC_STRUCT(sp_geometry_shader);
+   if (state == NULL )
+      goto fail;
+
+   /* debug */
+   if (softpipe->dump_gs)
+      tgsi_dump(templ->tokens, 0);
+
+   /* copy shader tokens, the ones passed in will go away.
+    */
+   state->shader.tokens = tgsi_dup_tokens(templ->tokens);
+   if (state->shader.tokens == NULL)
+      goto fail;
+
+   state->draw_data = draw_create_geometry_shader(softpipe->draw, templ);
+   if (state->draw_data == NULL)
+      goto fail;
+
+   return state;
+
+fail:
+   if (state) {
+      FREE( (void *)state->shader.tokens );
+      FREE( state->draw_data );
+      FREE( state );
+   }
+   return NULL;
+}
+
+
+void
+softpipe_bind_gs_state(struct pipe_context *pipe, void *gs)
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   softpipe->gs = (struct sp_geometry_shader *)gs;
+
+   draw_bind_geometry_shader(softpipe->draw,
+                             (softpipe->gs ? softpipe->gs->draw_data : NULL));
+
+   softpipe->dirty |= SP_NEW_GS;
+}
+
+
+void
+softpipe_delete_gs_state(struct pipe_context *pipe, void *gs)
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   struct sp_geometry_shader *state =
+      (struct sp_geometry_shader *)gs;
+
+   draw_delete_geometry_shader(softpipe->draw,
+                               (state) ? state->draw_data : 0);
+   FREE(state);
+}
diff --git a/src/gallium/drivers/softpipe/sp_state_rasterizer.c b/src/gallium/drivers/softpipe/sp_state_rasterizer.c
index 87b7219..a5b0033 100644
--- a/src/gallium/drivers/softpipe/sp_state_rasterizer.c
+++ b/src/gallium/drivers/softpipe/sp_state_rasterizer.c
@@ -41,14 +41,17 @@
 }
 
 void softpipe_bind_rasterizer_state(struct pipe_context *pipe,
-                                    void *setup)
+                                    void *rasterizer)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
 
-   /* pass-through to draw module */
-   draw_set_rasterizer_state(softpipe->draw, setup);
+   if (softpipe->rasterizer == rasterizer)
+      return;
 
-   softpipe->rasterizer = (struct pipe_rasterizer_state *)setup;
+   /* pass-through to draw module */
+   draw_set_rasterizer_state(softpipe->draw, rasterizer);
+
+   softpipe->rasterizer = rasterizer;
 
    softpipe->dirty |= SP_NEW_RASTERIZER;
 }
diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c
index db0b8ab..ceb4e33 100644
--- a/src/gallium/drivers/softpipe/sp_state_sampler.c
+++ b/src/gallium/drivers/softpipe/sp_state_sampler.c
@@ -94,6 +94,34 @@
 
 
 void
+softpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
+                                    unsigned num_samplers,
+                                    void **samplers)
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+   unsigned i;
+
+   assert(num_samplers <= PIPE_MAX_VERTEX_SAMPLERS);
+
+   /* Check for no-op */
+   if (num_samplers == softpipe->num_vertex_samplers &&
+       !memcmp(softpipe->vertex_samplers, samplers, num_samplers * sizeof(void *)))
+      return;
+
+   draw_flush(softpipe->draw);
+
+   for (i = 0; i < num_samplers; ++i)
+      softpipe->vertex_samplers[i] = samplers[i];
+   for (i = num_samplers; i < PIPE_MAX_VERTEX_SAMPLERS; ++i)
+      softpipe->vertex_samplers[i] = NULL;
+
+   softpipe->num_vertex_samplers = num_samplers;
+
+   softpipe->dirty |= SP_NEW_SAMPLER;
+}
+
+
+void
 softpipe_set_sampler_textures(struct pipe_context *pipe,
                               unsigned num, struct pipe_texture **texture)
 {
@@ -122,6 +150,37 @@
 }
 
 
+void
+softpipe_set_vertex_sampler_textures(struct pipe_context *pipe,
+                                     unsigned num_textures,
+                                     struct pipe_texture **textures)
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+   uint i;
+
+   assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS);
+
+   /* Check for no-op */
+   if (num_textures == softpipe->num_vertex_textures &&
+       !memcmp(softpipe->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) {
+      return;
+   }
+
+   draw_flush(softpipe->draw);
+
+   for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+      struct pipe_texture *tex = i < num_textures ? textures[i] : NULL;
+
+      pipe_texture_reference(&softpipe->vertex_textures[i], tex);
+      sp_tex_tile_cache_set_texture(softpipe->vertex_tex_cache[i], tex);
+   }
+
+   softpipe->num_vertex_textures = num_textures;
+
+   softpipe->dirty |= SP_NEW_TEXTURE;
+}
+
+
 /**
  * Find/create an sp_sampler_varient object for sampling the given texture,
  * sampler and tex unit.
@@ -185,16 +244,16 @@
     * fragment programs.
     */
    for (i = 0; i <= softpipe->vs->max_sampler; i++) {
-      if (softpipe->sampler[i]) {
+      if (softpipe->vertex_samplers[i]) {
          softpipe->tgsi.vert_samplers_list[i] = 
             get_sampler_varient( i,
-                                 sp_sampler(softpipe->sampler[i]),
-                                 softpipe->texture[i],
+                                sp_sampler(softpipe->vertex_samplers[i]),
+                                softpipe->vertex_textures[i],
                                  TGSI_PROCESSOR_VERTEX );
 
          sp_sampler_varient_bind_texture( softpipe->tgsi.vert_samplers_list[i], 
-                                          softpipe->tex_cache[i],
-                                          softpipe->texture[i] );
+                                         softpipe->vertex_tex_cache[i],
+                                         softpipe->vertex_textures[i] );
       }
    }
 
diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c
index bc0e201..f615410 100644
--- a/src/gallium/drivers/softpipe/sp_state_surface.c
+++ b/src/gallium/drivers/softpipe/sp_state_surface.c
@@ -35,6 +35,8 @@
 
 #include "draw/draw_context.h"
 
+#include "util/u_format.h"
+
 
 /**
  * XXX this might get moved someday
@@ -49,6 +51,8 @@
    struct softpipe_context *sp = softpipe_context(pipe);
    uint i;
 
+   draw_flush(sp->draw);
+
    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
       /* check if changing cbuf */
       if (sp->framebuffer.cbufs[i] != fb->cbufs[i]) {
@@ -80,8 +84,9 @@
       if (sp->framebuffer.zsbuf) {
          int depth_bits;
          double mrd;
-         depth_bits = pf_get_component_bits(sp->framebuffer.zsbuf->format,
-                                            PIPE_FORMAT_COMP_Z);
+         depth_bits = util_format_get_component_bits(sp->framebuffer.zsbuf->format,
+                                                     UTIL_FORMAT_COLORSPACE_ZS,
+                                                     0);
          if (depth_bits > 16) {
             mrd = 0.0000001;
          }
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index c22ee86..1ae8fec 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -2,7 +2,7 @@
  * 
  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
- * Copyright 2008 VMware, Inc.  All rights reserved.
+ * 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
@@ -514,21 +514,15 @@
 compute_lambda_1d(const struct sp_sampler_varient *samp,
                   const float s[QUAD_SIZE],
                   const float t[QUAD_SIZE],
-                  const float p[QUAD_SIZE],
-                  float lodbias)
+                  const float p[QUAD_SIZE])
 {
    const struct pipe_texture *texture = samp->texture;
    const struct pipe_sampler_state *sampler = samp->sampler;
    float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
    float dsdy = fabsf(s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]);
-   float rho = MAX2(dsdx, dsdy) * texture->width[0];
-   float lambda;
+   float rho = MAX2(dsdx, dsdy) * texture->width0;
 
-   lambda = util_fast_log2(rho);
-   lambda += lodbias + sampler->lod_bias;
-   lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod);
-
-   return lambda;
+   return util_fast_log2(rho);
 }
 
 
@@ -536,8 +530,7 @@
 compute_lambda_2d(const struct sp_sampler_varient *samp,
                   const float s[QUAD_SIZE],
                   const float t[QUAD_SIZE],
-                  const float p[QUAD_SIZE],
-                  float lodbias)
+                  const float p[QUAD_SIZE])
 {
    const struct pipe_texture *texture = samp->texture;
    const struct pipe_sampler_state *sampler = samp->sampler;
@@ -545,16 +538,11 @@
    float dsdy = fabsf(s[QUAD_TOP_LEFT]     - s[QUAD_BOTTOM_LEFT]);
    float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]);
    float dtdy = fabsf(t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT]);
-   float maxx = MAX2(dsdx, dsdy) * texture->width[0];
-   float maxy = MAX2(dtdx, dtdy) * texture->height[0];
+   float maxx = MAX2(dsdx, dsdy) * texture->width0;
+   float maxy = MAX2(dtdx, dtdy) * texture->height0;
    float rho  = MAX2(maxx, maxy);
-   float lambda;
 
-   lambda = util_fast_log2(rho);
-   lambda += lodbias + sampler->lod_bias;
-   lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod);
-
-   return lambda;
+   return util_fast_log2(rho);
 }
 
 
@@ -562,8 +550,7 @@
 compute_lambda_3d(const struct sp_sampler_varient *samp,
                   const float s[QUAD_SIZE],
                   const float t[QUAD_SIZE],
-                  const float p[QUAD_SIZE],
-                  float lodbias)
+                  const float p[QUAD_SIZE])
 {
    const struct pipe_texture *texture = samp->texture;
    const struct pipe_sampler_state *sampler = samp->sampler;
@@ -573,34 +560,29 @@
    float dtdy = fabsf(t[QUAD_TOP_LEFT]     - t[QUAD_BOTTOM_LEFT]);
    float dpdx = fabsf(p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]);
    float dpdy = fabsf(p[QUAD_TOP_LEFT]     - p[QUAD_BOTTOM_LEFT]);
-   float maxx = MAX2(dsdx, dsdy) * texture->width[0];
-   float maxy = MAX2(dtdx, dtdy) * texture->height[0];
-   float maxz = MAX2(dpdx, dpdy) * texture->depth[0];
-   float rho, lambda;
+   float maxx = MAX2(dsdx, dsdy) * texture->width0;
+   float maxy = MAX2(dtdx, dtdy) * texture->height0;
+   float maxz = MAX2(dpdx, dpdy) * texture->depth0;
+   float rho;
 
    rho = MAX2(maxx, maxy);
    rho = MAX2(rho, maxz);
 
-   lambda = util_fast_log2(rho);
-   lambda += lodbias + sampler->lod_bias;
-   lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod);
-
-   return lambda;
+   return util_fast_log2(rho);
 }
 
 
 /**
  * Compute lambda for a vertex texture sampler.
- * Since there aren't derivatives to use, just return the LOD bias.
+ * Since there aren't derivatives to use, just return 0.
  */
 static float
 compute_lambda_vert(const struct sp_sampler_varient *samp,
                     const float s[QUAD_SIZE],
                     const float t[QUAD_SIZE],
-                    const float p[QUAD_SIZE],
-                    float lodbias)
+                    const float p[QUAD_SIZE])
 {
-   return lodbias;
+   return 0.0f;
 }
 
 
@@ -644,8 +626,8 @@
    const struct pipe_texture *texture = samp->texture;
    unsigned level = addr.bits.level;
 
-   if (x < 0 || x >= (int) texture->width[level] ||
-       y < 0 || y >= (int) texture->height[level]) {
+   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
+       y < 0 || y >= (int) u_minify(texture->height0, level)) {
       return samp->sampler->border_color;
    }
    else {
@@ -737,9 +719,9 @@
    const struct pipe_texture *texture = samp->texture;
    unsigned level = addr.bits.level;
 
-   if (x < 0 || x >= (int) texture->width[level] ||
-       y < 0 || y >= (int) texture->height[level] ||
-       z < 0 || z >= (int) texture->depth[level]) {
+   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
+       y < 0 || y >= (int) u_minify(texture->height0, level) ||
+       z < 0 || z >= (int) u_minify(texture->depth0, level)) {
       return samp->sampler->border_color;
    }
    else {
@@ -769,7 +751,8 @@
                                 const float s[QUAD_SIZE],
                                 const float t[QUAD_SIZE],
                                 const float p[QUAD_SIZE],
-                                float lodbias,
+                                const float c0[QUAD_SIZE],
+                                enum tgsi_sampler_control control,
                                 float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
@@ -827,7 +810,8 @@
                                  const float s[QUAD_SIZE],
                                  const float t[QUAD_SIZE],
                                  const float p[QUAD_SIZE],
-                                 float lodbias,
+                                 const float c0[QUAD_SIZE],
+                                 enum tgsi_sampler_control control,
                                  float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
@@ -866,7 +850,8 @@
                                 const float s[QUAD_SIZE],
                                 const float t[QUAD_SIZE],
                                 const float p[QUAD_SIZE],
-                                float lodbias,
+                                const float c0[QUAD_SIZE],
+                                enum tgsi_sampler_control control,
                                 float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
@@ -914,7 +899,8 @@
                         const float s[QUAD_SIZE],
                         const float t[QUAD_SIZE],
                         const float p[QUAD_SIZE],
-                        float lodbias,
+                        const float c0[QUAD_SIZE],
+                        enum tgsi_sampler_control control,
                         float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
@@ -925,7 +911,7 @@
    union tex_tile_address addr;
 
    level0 = samp->level;
-   width = texture->width[level0];
+   width = u_minify(texture->width0, level0);
 
    assert(width > 0);
 
@@ -949,7 +935,8 @@
                       const float s[QUAD_SIZE],
                       const float t[QUAD_SIZE],
                       const float p[QUAD_SIZE],
-                      float lodbias,
+                      const float c0[QUAD_SIZE],
+                      enum tgsi_sampler_control control,
                       float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
@@ -961,8 +948,8 @@
 
 
    level0 = samp->level;
-   width = texture->width[level0];
-   height = texture->height[level0];
+   width = u_minify(texture->width0, level0);
+   height = u_minify(texture->height0, level0);
 
    assert(width > 0);
    assert(height > 0);
@@ -996,7 +983,8 @@
                         const float s[QUAD_SIZE],
                         const float t[QUAD_SIZE],
                         const float p[QUAD_SIZE],
-                        float lodbias,
+                        const float c0[QUAD_SIZE],
+                        enum tgsi_sampler_control control,
                         float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
@@ -1008,8 +996,8 @@
    union tex_tile_address addr;
 
    level0 = samp->level;
-   width = texture->width[level0];
-   height = texture->height[level0];
+   width = u_minify(texture->width0, level0);
+   height = u_minify(texture->height0, level0);
 
    assert(width > 0);
    assert(height > 0);
@@ -1035,7 +1023,8 @@
                       const float s[QUAD_SIZE],
                       const float t[QUAD_SIZE],
                       const float p[QUAD_SIZE],
-                      float lodbias,
+                      const float c0[QUAD_SIZE],
+                      enum tgsi_sampler_control control,
                       float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
@@ -1046,9 +1035,9 @@
    union tex_tile_address addr;
 
    level0 = samp->level;
-   width = texture->width[level0];
-   height = texture->height[level0];
-   depth = texture->depth[level0];
+   width = u_minify(texture->width0, level0);
+   height = u_minify(texture->height0, level0);
+   depth = u_minify(texture->depth0, level0);
 
    assert(width > 0);
    assert(height > 0);
@@ -1076,7 +1065,8 @@
                      const float s[QUAD_SIZE],
                      const float t[QUAD_SIZE],
                      const float p[QUAD_SIZE],
-                     float lodbias,
+                     const float c0[QUAD_SIZE],
+                     enum tgsi_sampler_control control,
                      float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
@@ -1088,7 +1078,7 @@
    union tex_tile_address addr;
 
    level0 = samp->level;
-   width = texture->width[level0];
+   width = u_minify(texture->width0, level0);
 
    assert(width > 0);
 
@@ -1115,7 +1105,8 @@
                      const float s[QUAD_SIZE],
                      const float t[QUAD_SIZE],
                      const float p[QUAD_SIZE],
-                     float lodbias,
+                     const float c0[QUAD_SIZE],
+                     enum tgsi_sampler_control control,
                      float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
@@ -1127,8 +1118,8 @@
    union tex_tile_address addr;
 
    level0 = samp->level;
-   width = texture->width[level0];
-   height = texture->height[level0];
+   width = u_minify(texture->width0, level0);
+   height = u_minify(texture->height0, level0);
 
    assert(width > 0);
    assert(height > 0);
@@ -1161,7 +1152,8 @@
                        const float s[QUAD_SIZE],
                        const float t[QUAD_SIZE],
                        const float p[QUAD_SIZE],
-                       float lodbias,
+                       const float c0[QUAD_SIZE],
+                       enum tgsi_sampler_control control,
                        float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
@@ -1174,8 +1166,8 @@
    union tex_tile_address addr;
 
    level0 = samp->level;
-   width = texture->width[level0];
-   height = texture->height[level0];
+   width = u_minify(texture->width0, level0);
+   height = u_minify(texture->height0, level0);
 
    assert(width > 0);
    assert(height > 0);
@@ -1209,7 +1201,8 @@
                      const float s[QUAD_SIZE],
                      const float t[QUAD_SIZE],
                      const float p[QUAD_SIZE],
-                     float lodbias,
+                     const float c0[QUAD_SIZE],
+                     enum tgsi_sampler_control control,
                      float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
@@ -1221,9 +1214,9 @@
    union tex_tile_address addr;
 
    level0 = samp->level;
-   width = texture->width[level0];
-   height = texture->height[level0];
-   depth = texture->depth[level0];
+   width = u_minify(texture->width0, level0);
+   height = u_minify(texture->height0, level0);
+   depth = u_minify(texture->depth0, level0);
 
    addr.value = 0;
    addr.bits.level = level0;
@@ -1261,29 +1254,60 @@
 }
 
 
+/* Calculate level of detail for every fragment.
+ * Note that lambda has already been biased by global LOD bias.
+ */
+static INLINE void
+compute_lod(const struct pipe_sampler_state *sampler,
+            const float biased_lambda,
+            const float lodbias[QUAD_SIZE],
+            float lod[QUAD_SIZE])
+{
+   uint i;
+
+   for (i = 0; i < QUAD_SIZE; i++) {
+      lod[i] = biased_lambda + lodbias[i];
+      lod[i] = CLAMP(lod[i], sampler->min_lod, sampler->max_lod);
+   }
+}
+
+
 static void
 mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
                   const float s[QUAD_SIZE],
                   const float t[QUAD_SIZE],
                   const float p[QUAD_SIZE],
-                  float lodbias,
+                  const float c0[QUAD_SIZE],
+                  enum tgsi_sampler_control control,
                   float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
    const struct pipe_texture *texture = samp->texture;
    int level0;
    float lambda;
+   float lod[QUAD_SIZE];
 
-   lambda = samp->compute_lambda(samp, s, t, p, lodbias);
+   if (control == tgsi_sampler_lod_bias) {
+      lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
+      compute_lod(samp->sampler, lambda, c0, lod);
+   } else {
+      assert(control == tgsi_sampler_lod_explicit);
+
+      memcpy(lod, c0, sizeof(lod));
+   }
+
+   /* XXX: Take into account all lod values.
+    */
+   lambda = lod[0];
    level0 = (int)lambda;
 
    if (lambda < 0.0) { 
       samp->level = 0;
-      samp->mag_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+      samp->mag_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba);
    }
    else if (level0 >= texture->last_level) {
       samp->level = texture->last_level;
-      samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+      samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba);
    }
    else {
       float levelBlend = lambda - level0;
@@ -1292,10 +1316,10 @@
       int c,j;
 
       samp->level = level0;
-      samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba0 );
+      samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba0);
 
       samp->level = level0+1;
-      samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba1 );
+      samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba1);
 
       for (j = 0; j < QUAD_SIZE; j++) {
          for (c = 0; c < 4; c++) {
@@ -1311,23 +1335,36 @@
                    const float s[QUAD_SIZE],
                    const float t[QUAD_SIZE],
                    const float p[QUAD_SIZE],
-                   float lodbias,
+                   const float c0[QUAD_SIZE],
+                   enum tgsi_sampler_control control,
                    float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
    const struct pipe_texture *texture = samp->texture;
    float lambda;
+   float lod[QUAD_SIZE];
 
-   lambda = samp->compute_lambda(samp, s, t, p, lodbias);
+   if (control == tgsi_sampler_lod_bias) {
+      lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
+      compute_lod(samp->sampler, lambda, c0, lod);
+   } else {
+      assert(control == tgsi_sampler_lod_explicit);
+
+      memcpy(lod, c0, sizeof(lod));
+   }
+
+   /* XXX: Take into account all lod values.
+    */
+   lambda = lod[0];
 
    if (lambda < 0.0) { 
       samp->level = 0;
-      samp->mag_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+      samp->mag_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba);
    }
    else {
       samp->level = (int)(lambda + 0.5) ;
       samp->level = MIN2(samp->level, (int)texture->last_level);
-      samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+      samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba);
    }
 
 #if 0
@@ -1345,17 +1382,32 @@
                 const float s[QUAD_SIZE],
                 const float t[QUAD_SIZE],
                 const float p[QUAD_SIZE],
-                float lodbias,
+                const float c0[QUAD_SIZE],
+                enum tgsi_sampler_control control,
                 float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
-   float lambda = samp->compute_lambda(samp, s, t, p, lodbias);
+   float lambda;
+   float lod[QUAD_SIZE];
+
+   if (control == tgsi_sampler_lod_bias) {
+      lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
+      compute_lod(samp->sampler, lambda, c0, lod);
+   } else {
+      assert(control == tgsi_sampler_lod_explicit);
+
+      memcpy(lod, c0, sizeof(lod));
+   }
+
+   /* XXX: Take into account all lod values.
+    */
+   lambda = lod[0];
 
    if (lambda < 0.0) { 
-      samp->mag_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+      samp->mag_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba);
    }
    else {
-      samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+      samp->min_img_filter(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba);
    }
 }
 
@@ -1371,15 +1423,28 @@
    const float s[QUAD_SIZE],
    const float t[QUAD_SIZE],
    const float p[QUAD_SIZE],
-   float lodbias,
+   const float c0[QUAD_SIZE],
+   enum tgsi_sampler_control control,
    float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
    const struct pipe_texture *texture = samp->texture;
    int level0;
    float lambda;
+   float lod[QUAD_SIZE];
 
-   lambda = compute_lambda_2d(samp, s, t, p, lodbias);
+   if (control == tgsi_sampler_lod_bias) {
+      lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
+      compute_lod(samp->sampler, lambda, c0, lod);
+   } else {
+      assert(control == tgsi_sampler_lod_explicit);
+
+      memcpy(lod, c0, sizeof(lod));
+   }
+
+   /* XXX: Take into account all lod values.
+    */
+   lambda = lod[0];
    level0 = (int)lambda;
 
    /* Catches both negative and large values of level0:
@@ -1390,7 +1455,7 @@
       else
          samp->level = texture->last_level;
 
-      img_filter_2d_linear_repeat_POT( tgsi_sampler, s, t, p, 0, rgba );
+      img_filter_2d_linear_repeat_POT(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba);
    }
    else {
       float levelBlend = lambda - level0;
@@ -1399,10 +1464,10 @@
       int c,j;
 
       samp->level = level0;
-      img_filter_2d_linear_repeat_POT( tgsi_sampler, s, t, p, 0, rgba0 );
+      img_filter_2d_linear_repeat_POT(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba0);
 
       samp->level = level0+1;
-      img_filter_2d_linear_repeat_POT( tgsi_sampler, s, t, p, 0, rgba1 );
+      img_filter_2d_linear_repeat_POT(tgsi_sampler, s, t, p, NULL, tgsi_sampler_lod_bias, rgba1);
 
       for (j = 0; j < QUAD_SIZE; j++) {
          for (c = 0; c < 4; c++) {
@@ -1422,7 +1487,8 @@
                const float s[QUAD_SIZE],
                const float t[QUAD_SIZE],
                const float p[QUAD_SIZE],
-               float lodbias,
+               const float c0[QUAD_SIZE],
+               enum tgsi_sampler_control control,
                float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
@@ -1430,7 +1496,7 @@
    int j, k0, k1, k2, k3;
    float val;
 
-   samp->mip_filter( tgsi_sampler, s, t, p, lodbias, rgba );
+   samp->mip_filter(tgsi_sampler, s, t, p, c0, control, rgba);
 
    /**
     * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
@@ -1508,7 +1574,8 @@
             const float s[QUAD_SIZE],
             const float t[QUAD_SIZE],
             const float p[QUAD_SIZE],
-            float lodbias,
+            const float c0[QUAD_SIZE],
+            enum tgsi_sampler_control control,
             float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
@@ -1589,7 +1656,7 @@
     * is not active, this will point somewhere deeper into the
     * pipeline, eg. to mip_filter or even img_filter.
     */
-   samp->compare(tgsi_sampler, ssss, tttt, NULL, lodbias, rgba);
+   samp->compare(tgsi_sampler, ssss, tttt, NULL, c0, control, rgba);
 }
 
 
@@ -1778,8 +1845,8 @@
 
    samp->texture = texture;
    samp->cache = tex_cache;
-   samp->xpot = util_unsigned_logbase2( texture->width[0] );
-   samp->ypot = util_unsigned_logbase2( texture->height[0] );
+   samp->xpot = util_unsigned_logbase2( texture->width0 );
+   samp->ypot = util_unsigned_logbase2( texture->height0 );
    samp->level = CLAMP((int) sampler->min_lod, 0, (int) texture->last_level);
 }
 
@@ -1862,7 +1929,7 @@
       break;
    }
 
-   if (sampler->compare_mode != FALSE) {
+   if (sampler->compare_mode != PIPE_TEX_COMPARE_NONE) {
       samp->compare = sample_compare;
    }
    else {
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h
index b079771..b6e66c9 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.h
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.h
@@ -2,6 +2,7 @@
  * 
  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
+ * Copyright 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
@@ -46,14 +47,14 @@
 typedef float (*compute_lambda_func)(const struct sp_sampler_varient *sampler,
                                      const float s[QUAD_SIZE],
                                      const float t[QUAD_SIZE],
-                                     const float p[QUAD_SIZE],
-                                     float lodbias);
+                                     const float p[QUAD_SIZE]);
 
 typedef void (*filter_func)(struct tgsi_sampler *tgsi_sampler,
                             const float s[QUAD_SIZE],
                             const float t[QUAD_SIZE],
                             const float p[QUAD_SIZE],
-                            float lodbias,
+                            const float c0[QUAD_SIZE],
+                            enum tgsi_sampler_control control,
                             float rgba[NUM_CHANNELS][QUAD_SIZE]);
 
 
diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
index 407a22a..e50a76a 100644
--- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
@@ -35,6 +35,7 @@
 #include "pipe/p_inlines.h"
 #include "util/u_memory.h"
 #include "util/u_tile.h"
+#include "util/u_math.h"
 #include "sp_context.h"
 #include "sp_surface.h"
 #include "sp_texture.h"
@@ -246,9 +247,9 @@
                                      addr.bits.level, 
                                      addr.bits.z, 
                                      PIPE_TRANSFER_READ, 0, 0,
-                                     tc->texture->width[addr.bits.level],
-                                     tc->texture->height[addr.bits.level]);
-
+                                     u_minify(tc->texture->width0, addr.bits.level),
+                                     u_minify(tc->texture->height0, addr.bits.level));
+         
          tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans);
 
          tc->tex_face = addr.bits.face;
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 7caf292..a9436a3 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -32,6 +32,8 @@
 
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
+
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 
@@ -52,29 +54,28 @@
 {
    struct pipe_texture *pt = &spt->base;
    unsigned level;
-   unsigned width = pt->width[0];
-   unsigned height = pt->height[0];
-   unsigned depth = pt->depth[0];
+   unsigned width = pt->width0;
+   unsigned height = pt->height0;
+   unsigned depth = pt->depth0;
 
    unsigned buffer_size = 0;
 
+   pt->width0 = width;
+   pt->height0 = height;
+   pt->depth0 = depth;
+
    for (level = 0; level <= pt->last_level; level++) {
-      pt->width[level] = width;
-      pt->height[level] = height;
-      pt->depth[level] = depth;
-      pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width);  
-      pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height);  
-      spt->stride[level] = pt->nblocksx[level]*pt->block.size;
+      spt->stride[level] = util_format_get_stride(pt->format, width);
 
       spt->level_offset[level] = buffer_size;
 
-      buffer_size += (pt->nblocksy[level] *
+      buffer_size += (util_format_get_nblocksy(pt->format, height) *
                       ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
                       spt->stride[level]);
 
-      width  = minify(width);
-      height = minify(height);
-      depth = minify(depth);
+      width  = u_minify(width, 1);
+      height = u_minify(height, 1);
+      depth = u_minify(depth, 1);
    }
 
    spt->buffer = screen->buffer_create(screen, 32,
@@ -96,12 +97,9 @@
                      PIPE_BUFFER_USAGE_GPU_READ_WRITE);
    unsigned tex_usage = spt->base.tex_usage;
 
-   spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]);  
-   spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]);  
-
    spt->buffer = screen->surface_buffer_create( screen, 
-                                                spt->base.width[0], 
-                                                spt->base.height[0],
+                                                spt->base.width0, 
+                                                spt->base.height0,
                                                 spt->base.format,
                                                 usage,
                                                 tex_usage,
@@ -126,9 +124,9 @@
    pipe_reference_init(&spt->base.reference, 1);
    spt->base.screen = screen;
 
-   spt->pot = (util_is_power_of_two(template->width[0]) &&
-               util_is_power_of_two(template->height[0]) &&
-               util_is_power_of_two(template->depth[0]));
+   spt->pot = (util_is_power_of_two(template->width0) &&
+               util_is_power_of_two(template->height0) &&
+               util_is_power_of_two(template->depth0));
 
    if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
                               PIPE_TEXTURE_USAGE_PRIMARY)) {
@@ -163,7 +161,7 @@
    /* Only supports one type */
    if (base->target != PIPE_TEXTURE_2D ||
        base->last_level != 0 ||
-       base->depth[0] != 1) {
+       base->depth0 != 1) {
       return NULL;
    }
 
@@ -174,8 +172,6 @@
    spt->base = *base;
    pipe_reference_init(&spt->base.reference, 1);
    spt->base.screen = screen;
-   spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]);  
-   spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]);  
    spt->stride[0] = stride[0];
 
    pipe_buffer_reference(&spt->buffer, buffer);
@@ -213,8 +209,8 @@
       pipe_reference_init(&ps->reference, 1);
       pipe_texture_reference(&ps->texture, pt);
       ps->format = pt->format;
-      ps->width = pt->width[level];
-      ps->height = pt->height[level];
+      ps->width = u_minify(pt->width0, level);
+      ps->height = u_minify(pt->height0, level);
       ps->offset = spt->level_offset[level];
       ps->usage = usage;
 
@@ -243,10 +239,12 @@
       ps->zslice = zslice;
 
       if (pt->target == PIPE_TEXTURE_CUBE) {
-         ps->offset += face * pt->nblocksy[level] * spt->stride[level];
+         ps->offset += face * util_format_get_nblocksy(pt->format, u_minify(pt->height0, level)) *
+                       spt->stride[level];
       }
       else if (pt->target == PIPE_TEXTURE_3D) {
-         ps->offset += zslice * pt->nblocksy[level] * spt->stride[level];
+         ps->offset += zslice * util_format_get_nblocksy(pt->format, u_minify(pt->height0, level)) *
+                       spt->stride[level];
       }
       else {
          assert(face == 0);
@@ -301,15 +299,12 @@
    spt = CALLOC_STRUCT(softpipe_transfer);
    if (spt) {
       struct pipe_transfer *pt = &spt->base;
+      int nblocksy = util_format_get_nblocksy(texture->format, u_minify(texture->height0, level));
       pipe_texture_reference(&pt->texture, texture);
-      pt->format = texture->format;
-      pt->block = texture->block;
       pt->x = x;
       pt->y = y;
       pt->width = w;
       pt->height = h;
-      pt->nblocksx = texture->nblocksx[level];
-      pt->nblocksy = texture->nblocksy[level];
       pt->stride = sptex->stride[level];
       pt->usage = usage;
       pt->face = face;
@@ -319,10 +314,10 @@
       spt->offset = sptex->level_offset[level];
 
       if (texture->target == PIPE_TEXTURE_CUBE) {
-         spt->offset += face * pt->nblocksy * pt->stride;
+         spt->offset += face * nblocksy * pt->stride;
       }
       else if (texture->target == PIPE_TEXTURE_3D) {
-         spt->offset += zslice * pt->nblocksy * pt->stride;
+         spt->offset += zslice * nblocksy * pt->stride;
       }
       else {
          assert(face == 0);
@@ -360,9 +355,11 @@
 {
    ubyte *map, *xfer_map;
    struct softpipe_texture *spt;
+   enum pipe_format format;
 
    assert(transfer->texture);
    spt = softpipe_texture(transfer->texture);
+   format = transfer->texture->format;
 
    map = pipe_buffer_map(screen, spt->buffer, pipe_transfer_buffer_flags(transfer));
    if (map == NULL)
@@ -379,8 +376,8 @@
    }
 
    xfer_map = map + softpipe_transfer(transfer)->offset +
-      transfer->y / transfer->block.height * transfer->stride +
-      transfer->x / transfer->block.width * transfer->block.size;
+      transfer->y / util_format_get_blockheight(format) * transfer->stride +
+      transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
    /*printf("map = %p  xfer map = %p\n", map, xfer_map);*/
    return xfer_map;
 }
@@ -434,10 +431,9 @@
    template.format = PIPE_FORMAT_X8R8G8B8_UNORM;
    template.last_level = 0;
    /* vl_mpeg12_mc_renderer expects this when it's initialized with pot_buffers=true */
-   template.width[0] = util_next_power_of_two(width);
-   template.height[0] = util_next_power_of_two(height);
-   template.depth[0] = 1;
-   pf_get_block(template.format, &template.block);
+   template.width0 = util_next_power_of_two(width);
+   template.height0 = util_next_power_of_two(height);
+   template.depth0 = 1;
    template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET;
 
    sp_vsfc->tex = screen->texture_create(screen, &template);
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c
index 65872ce..112a6fe 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.c
@@ -33,6 +33,7 @@
  */
 
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
 #include "util/u_memory.h"
 #include "util/u_tile.h"
 #include "sp_tile_cache.h"
@@ -238,7 +239,7 @@
 {
    uint i, j;
 
-   switch (pf_get_size(format)) {
+   switch (util_format_get_blocksize(format)) {
    case 1:
       memset(tile->data.any, clear_value, TILE_SIZE * TILE_SIZE);
       break;
@@ -284,8 +285,9 @@
    uint x, y;
    uint numCleared = 0;
 
+   assert(pt->texture);
    /* clear the scratch tile to the clear value */
-   clear_tile(&tc->tile, pt->format, tc->clear_val);
+   clear_tile(&tc->tile, pt->texture->format, tc->clear_val);
 
    /* push the tile to all positions marked as clear */
    for (y = 0; y < h; y += TILE_SIZE) {
@@ -372,6 +374,7 @@
 
    if (addr.value != tile->addr.value) {
 
+      assert(pt->texture);
       if (tile->addr.bits.invalid == 0) {
          /* put dirty tile back in framebuffer */
          if (tc->depth_stencil) {
@@ -395,10 +398,10 @@
       if (is_clear_flag_set(tc->clear_flags, addr)) {
          /* don't get tile from framebuffer, just clear it */
          if (tc->depth_stencil) {
-            clear_tile(tile, pt->format, tc->clear_val);
+            clear_tile(tile, pt->texture->format, tc->clear_val);
          }
          else {
-            clear_tile_rgba(tile, pt->format, tc->clear_color);
+            clear_tile_rgba(tile, pt->texture->format, tc->clear_color);
          }
          clear_clear_flag(tc->clear_flags, addr);
       }
diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_winsys.h
index 9e57186..f203ded 100644
--- a/src/gallium/drivers/softpipe/sp_winsys.h
+++ b/src/gallium/drivers/softpipe/sp_winsys.h
@@ -34,15 +34,17 @@
 #ifndef SP_WINSYS_H
 #define SP_WINSYS_H
 
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#include "pipe/p_defines.h"
 
 struct pipe_screen;
 struct pipe_winsys;
 struct pipe_context;
+struct pipe_texture;
+struct pipe_buffer;
 
 
 struct pipe_context *softpipe_create( struct pipe_screen * );
diff --git a/src/gallium/drivers/svga/Makefile b/src/gallium/drivers/svga/Makefile
new file mode 100644
index 0000000..f361908
--- /dev/null
+++ b/src/gallium/drivers/svga/Makefile
@@ -0,0 +1,60 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = svga
+
+C_SOURCES = \
+	svgadump/svga_shader_dump.c \
+	svgadump/svga_shader_op.c \
+	svgadump/svga_dump.c \
+	svga_cmd.c \
+	svga_context.c \
+	svga_draw.c \
+	svga_draw_arrays.c \
+	svga_draw_elements.c \
+	svga_pipe_blend.c \
+	svga_pipe_blit.c \
+	svga_pipe_clear.c \
+	svga_pipe_constants.c \
+	svga_pipe_depthstencil.c \
+	svga_pipe_draw.c \
+	svga_pipe_flush.c \
+	svga_pipe_fs.c \
+	svga_pipe_misc.c \
+	svga_pipe_query.c \
+	svga_pipe_rasterizer.c \
+	svga_pipe_sampler.c \
+	svga_pipe_vertex.c \
+	svga_pipe_vs.c \
+	svga_screen.c \
+	svga_screen_buffer.c \
+	svga_screen_texture.c \
+	svga_screen_cache.c \
+	svga_state.c \
+	svga_state_need_swtnl.c \
+	svga_state_constants.c \
+	svga_state_framebuffer.c \
+	svga_state_rss.c \
+	svga_state_tss.c \
+	svga_state_vdecl.c \
+	svga_state_fs.c \
+	svga_state_vs.c \
+	svga_swtnl_backend.c \
+	svga_swtnl_draw.c \
+	svga_swtnl_state.c \
+	svga_tgsi.c \
+	svga_tgsi_decl_sm20.c \
+	svga_tgsi_decl_sm30.c \
+	svga_tgsi_insn.c
+
+LIBRARY_INCLUDES = \
+	-I$(TOP)/src/gallium/drivers/svga/include
+
+# With linux-debug we get a lots of warnings, filter out the bad flags.
+CFLAGS := $(filter-out -pedantic, $(filter-out -ansi, $(CFLAGS)))
+
+LIBRARY_DEFINES = \
+	-std=gnu99 -fvisibility=hidden \
+	-DHAVE_STDINT_H -DHAVE_SYS_TYPES_H
+
+include ../../Makefile.template
diff --git a/src/gallium/drivers/svga/SConscript b/src/gallium/drivers/svga/SConscript
new file mode 100644
index 0000000..737b791
--- /dev/null
+++ b/src/gallium/drivers/svga/SConscript
@@ -0,0 +1,72 @@
+Import('*')
+
+env = env.Clone()
+
+if env['platform'] in ['linux']:
+	env.Append(CCFLAGS = ['-fvisibility=hidden'])
+
+if env['gcc']:
+	env.Append(CPPDEFINES = [
+		'HAVE_STDINT_H', 
+		'HAVE_SYS_TYPES_H',
+	])
+	
+env.Prepend(CPPPATH = [
+	'include',
+])
+
+env.Append(CPPDEFINES = [
+])
+
+sources = [
+    'svga_cmd.c',
+    'svga_context.c',
+    'svga_draw.c',
+    'svga_draw_arrays.c',
+    'svga_draw_elements.c',
+    'svga_pipe_blend.c',
+    'svga_pipe_blit.c',
+    'svga_pipe_clear.c',
+    'svga_pipe_constants.c',
+    'svga_pipe_depthstencil.c',
+    'svga_pipe_draw.c',
+    'svga_pipe_flush.c',
+    'svga_pipe_fs.c',
+    'svga_pipe_misc.c',
+    'svga_pipe_query.c',
+    'svga_pipe_rasterizer.c',
+    'svga_pipe_sampler.c',
+    'svga_pipe_vertex.c',
+    'svga_pipe_vs.c',
+    'svga_screen.c',
+    'svga_screen_buffer.c',
+    'svga_screen_cache.c',
+    'svga_screen_texture.c',
+    'svga_state.c',
+    'svga_state_constants.c',
+    'svga_state_framebuffer.c',
+    'svga_state_need_swtnl.c',
+    'svga_state_rss.c',
+    'svga_state_tss.c',
+    'svga_state_vdecl.c',
+    'svga_state_fs.c',
+    'svga_state_vs.c',
+    'svga_swtnl_backend.c',
+    'svga_swtnl_draw.c',
+    'svga_swtnl_state.c',
+    'svga_tgsi.c',
+    'svga_tgsi_decl_sm20.c',
+    'svga_tgsi_decl_sm30.c',
+    'svga_tgsi_insn.c',
+    
+    'svgadump/svga_dump.c',
+    'svgadump/svga_shader_dump.c',
+    'svgadump/svga_shader_op.c',
+]
+
+svga = env.ConvenienceLibrary(
+	target = 'svga',
+	source = sources,
+)
+
+Export('svga')
diff --git a/src/gallium/drivers/svga/include/README b/src/gallium/drivers/svga/include/README
new file mode 100644
index 0000000..a0b8916
--- /dev/null
+++ b/src/gallium/drivers/svga/include/README
@@ -0,0 +1,3 @@
+This directory contains the headers from the VMware SVGA Device Developer Kit:
+
+   https://vmware-svga.svn.sourceforge.net/svnroot/vmware-svga/trunk/lib/vmware/
diff --git a/src/gallium/drivers/svga/include/svga3d_caps.h b/src/gallium/drivers/svga/include/svga3d_caps.h
new file mode 100644
index 0000000..714ce9f
--- /dev/null
+++ b/src/gallium/drivers/svga/include/svga3d_caps.h
@@ -0,0 +1,139 @@
+/**********************************************************
+ * Copyright 2007-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+/*
+ * svga3d_caps.h --
+ *
+ *       Definitions for SVGA3D hardware capabilities.  Capabilities
+ *       are used to query for optional rendering features during
+ *       driver initialization. The capability data is stored as very
+ *       basic key/value dictionary within the "FIFO register" memory
+ *       area at the beginning of BAR2.
+ *
+ *       Note that these definitions are only for 3D capabilities.
+ *       The SVGA device also has "device capabilities" and "FIFO
+ *       capabilities", which are non-3D-specific and are stored as
+ *       bitfields rather than key/value pairs.
+ */
+
+#ifndef _SVGA3D_CAPS_H_
+#define _SVGA3D_CAPS_H_
+
+#define SVGA_FIFO_3D_CAPS_SIZE   (SVGA_FIFO_3D_CAPS_LAST - \
+                                  SVGA_FIFO_3D_CAPS + 1)
+
+
+/*
+ * SVGA3dCapsRecordType
+ *
+ *    Record types that can be found in the caps block.
+ *    Related record types are grouped together numerically so that
+ *    SVGA3dCaps_FindRecord() can be applied on a range of record
+ *    types.
+ */
+
+typedef enum {
+   SVGA3DCAPS_RECORD_UNKNOWN        = 0,
+   SVGA3DCAPS_RECORD_DEVCAPS_MIN    = 0x100,
+   SVGA3DCAPS_RECORD_DEVCAPS        = 0x100,
+   SVGA3DCAPS_RECORD_DEVCAPS_MAX    = 0x1ff,
+} SVGA3dCapsRecordType;
+
+
+/*
+ * SVGA3dCapsRecordHeader
+ *
+ *    Header field leading each caps block record. Contains the offset (in
+ *    register words, NOT bytes) to the next caps block record (or the end
+ *    of caps block records which will be a zero word) and the record type
+ *    as defined above.
+ */
+
+typedef
+struct SVGA3dCapsRecordHeader {
+   uint32 length;
+   SVGA3dCapsRecordType type;
+}
+SVGA3dCapsRecordHeader;
+
+
+/*
+ * SVGA3dCapsRecord
+ *
+ *    Caps block record; "data" is a placeholder for the actual data structure
+ *    contained within the record; for example a record containing a FOOBAR
+ *    structure would be of size "sizeof(SVGA3dCapsRecordHeader) +
+ *    sizeof(FOOBAR)".
+ */
+
+typedef
+struct SVGA3dCapsRecord {
+   SVGA3dCapsRecordHeader header;
+   uint32 data[1];
+}
+SVGA3dCapsRecord;
+
+
+typedef uint32 SVGA3dCapPair[2];
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3dCaps_FindRecord
+ *
+ *    Finds the record with the highest-valued type within the given range
+ *    in the caps block.
+ *
+ *    Result: pointer to found record, or NULL if not found.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static INLINE SVGA3dCapsRecord *
+SVGA3dCaps_FindRecord(const uint32 *capsBlock,
+                      SVGA3dCapsRecordType recordTypeMin,
+                      SVGA3dCapsRecordType recordTypeMax)
+{
+   SVGA3dCapsRecord *record, *found = NULL;
+   uint32 offset;
+
+   /*
+    * Search linearly through the caps block records for the specified type.
+    */
+   for (offset = 0; capsBlock[offset] != 0; offset += capsBlock[offset]) {
+      record = (SVGA3dCapsRecord *) (capsBlock + offset);
+      if ((record->header.type >= recordTypeMin) &&
+          (record->header.type <= recordTypeMax) &&
+          (!found || (record->header.type > found->header.type))) {
+         found = record;
+      }
+   }
+
+   return found;
+}
+
+
+#endif // _SVGA3D_CAPS_H_
diff --git a/src/gallium/drivers/svga/include/svga3d_reg.h b/src/gallium/drivers/svga/include/svga3d_reg.h
new file mode 100644
index 0000000..77cb453
--- /dev/null
+++ b/src/gallium/drivers/svga/include/svga3d_reg.h
@@ -0,0 +1,1793 @@
+/**********************************************************
+ * Copyright 1998-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+/*
+ * svga3d_reg.h --
+ *
+ *       SVGA 3D hardware definitions
+ */
+
+#ifndef _SVGA3D_REG_H_
+#define _SVGA3D_REG_H_
+
+#include "svga_reg.h"
+
+
+/*
+ * 3D Hardware Version
+ *
+ *   The hardware version is stored in the SVGA_FIFO_3D_HWVERSION fifo
+ *   register.   Is set by the host and read by the guest.  This lets
+ *   us make new guest drivers which are backwards-compatible with old
+ *   SVGA hardware revisions.  It does not let us support old guest
+ *   drivers.  Good enough for now.
+ *
+ */
+
+#define SVGA3D_MAKE_HWVERSION(major, minor)      (((major) << 16) | ((minor) & 0xFF))
+#define SVGA3D_MAJOR_HWVERSION(version)          ((version) >> 16)
+#define SVGA3D_MINOR_HWVERSION(version)          ((version) & 0xFF)
+
+typedef enum {
+   SVGA3D_HWVERSION_WS5_RC1   = SVGA3D_MAKE_HWVERSION(0, 1),
+   SVGA3D_HWVERSION_WS5_RC2   = SVGA3D_MAKE_HWVERSION(0, 2),
+   SVGA3D_HWVERSION_WS51_RC1  = SVGA3D_MAKE_HWVERSION(0, 3),
+   SVGA3D_HWVERSION_WS6_B1    = SVGA3D_MAKE_HWVERSION(1, 1),
+   SVGA3D_HWVERSION_FUSION_11 = SVGA3D_MAKE_HWVERSION(1, 4),
+   SVGA3D_HWVERSION_WS65_B1   = SVGA3D_MAKE_HWVERSION(2, 0),
+   SVGA3D_HWVERSION_CURRENT   = SVGA3D_HWVERSION_WS65_B1,
+} SVGA3dHardwareVersion;
+
+/*
+ * Generic Types
+ */
+
+typedef uint32 SVGA3dBool; /* 32-bit Bool definition */
+#define SVGA3D_NUM_CLIPPLANES                   6
+#define SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS  8
+
+
+/*
+ * Surface formats.
+ *
+ * If you modify this list, be sure to keep GLUtil.c in sync. It
+ * includes the internal format definition of each surface in
+ * GLUtil_ConvertSurfaceFormat, and it contains a table of
+ * human-readable names in GLUtil_GetFormatName.
+ */
+
+typedef enum SVGA3dSurfaceFormat {
+   SVGA3D_FORMAT_INVALID = 0,
+
+   SVGA3D_X8R8G8B8       = 1,
+   SVGA3D_A8R8G8B8       = 2,
+
+   SVGA3D_R5G6B5         = 3,
+   SVGA3D_X1R5G5B5       = 4,
+   SVGA3D_A1R5G5B5       = 5,
+   SVGA3D_A4R4G4B4       = 6,
+
+   SVGA3D_Z_D32          = 7,
+   SVGA3D_Z_D16          = 8,
+   SVGA3D_Z_D24S8        = 9,
+   SVGA3D_Z_D15S1        = 10,
+
+   SVGA3D_LUMINANCE8            = 11,
+   SVGA3D_LUMINANCE4_ALPHA4     = 12,
+   SVGA3D_LUMINANCE16           = 13,
+   SVGA3D_LUMINANCE8_ALPHA8     = 14,
+
+   SVGA3D_DXT1           = 15,
+   SVGA3D_DXT2           = 16,
+   SVGA3D_DXT3           = 17,
+   SVGA3D_DXT4           = 18,
+   SVGA3D_DXT5           = 19,
+
+   SVGA3D_BUMPU8V8       = 20,
+   SVGA3D_BUMPL6V5U5     = 21,
+   SVGA3D_BUMPX8L8V8U8   = 22,
+   SVGA3D_BUMPL8V8U8     = 23,
+
+   SVGA3D_ARGB_S10E5     = 24,   /* 16-bit floating-point ARGB */
+   SVGA3D_ARGB_S23E8     = 25,   /* 32-bit floating-point ARGB */
+
+   SVGA3D_A2R10G10B10    = 26,
+
+   /* signed formats */
+   SVGA3D_V8U8           = 27,
+   SVGA3D_Q8W8V8U8       = 28,
+   SVGA3D_CxV8U8         = 29,
+
+   /* mixed formats */
+   SVGA3D_X8L8V8U8       = 30,
+   SVGA3D_A2W10V10U10    = 31,
+
+   SVGA3D_ALPHA8         = 32,
+
+   /* Single- and dual-component floating point formats */
+   SVGA3D_R_S10E5        = 33,
+   SVGA3D_R_S23E8        = 34,
+   SVGA3D_RG_S10E5       = 35,
+   SVGA3D_RG_S23E8       = 36,
+
+   /*
+    * Any surface can be used as a buffer object, but SVGA3D_BUFFER is
+    * the most efficient format to use when creating new surfaces
+    * expressly for index or vertex data.
+    */
+   SVGA3D_BUFFER         = 37,
+
+   SVGA3D_Z_D24X8        = 38,
+
+   SVGA3D_V16U16         = 39,
+
+   SVGA3D_G16R16         = 40,
+   SVGA3D_A16B16G16R16   = 41,
+
+   /* Packed Video formats */
+   SVGA3D_UYVY           = 42,
+   SVGA3D_YUY2           = 43,
+
+   SVGA3D_FORMAT_MAX
+} SVGA3dSurfaceFormat;
+
+typedef uint32 SVGA3dColor; /* a, r, g, b */
+
+/*
+ * These match the D3DFORMAT_OP definitions used by Direct3D. We need
+ * them so that we can query the host for what the supported surface
+ * operations are (when we're using the D3D backend, in particular),
+ * and so we can send those operations to the guest.
+ */
+typedef enum {
+   SVGA3DFORMAT_OP_TEXTURE                               = 0x00000001,
+   SVGA3DFORMAT_OP_VOLUMETEXTURE                         = 0x00000002,
+   SVGA3DFORMAT_OP_CUBETEXTURE                           = 0x00000004,
+   SVGA3DFORMAT_OP_OFFSCREEN_RENDERTARGET                = 0x00000008,
+   SVGA3DFORMAT_OP_SAME_FORMAT_RENDERTARGET              = 0x00000010,
+   SVGA3DFORMAT_OP_ZSTENCIL                              = 0x00000040,
+   SVGA3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH   = 0x00000080,
+
+/*
+ * This format can be used as a render target if the current display mode
+ * is the same depth if the alpha channel is ignored. e.g. if the device
+ * can render to A8R8G8B8 when the display mode is X8R8G8B8, then the
+ * format op list entry for A8R8G8B8 should have this cap.
+ */
+   SVGA3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET  = 0x00000100,
+
+/*
+ * This format contains DirectDraw support (including Flip).  This flag
+ * should not to be set on alpha formats.
+ */
+   SVGA3DFORMAT_OP_DISPLAYMODE                           = 0x00000400,
+
+/*
+ * The rasterizer can support some level of Direct3D support in this format
+ * and implies that the driver can create a Context in this mode (for some
+ * render target format).  When this flag is set, the SVGA3DFORMAT_OP_DISPLAYMODE
+ * flag must also be set.
+ */
+   SVGA3DFORMAT_OP_3DACCELERATION                        = 0x00000800,
+
+/*
+ * This is set for a private format when the driver has put the bpp in
+ * the structure.
+ */
+   SVGA3DFORMAT_OP_PIXELSIZE                             = 0x00001000,
+
+/*
+ * Indicates that this format can be converted to any RGB format for which
+ * SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB is specified
+ */
+   SVGA3DFORMAT_OP_CONVERT_TO_ARGB                       = 0x00002000,
+
+/*
+ * Indicates that this format can be used to create offscreen plain surfaces.
+ */
+   SVGA3DFORMAT_OP_OFFSCREENPLAIN                        = 0x00004000,
+
+/*
+ * Indicated that this format can be read as an SRGB texture (meaning that the
+ * sampler will linearize the looked up data)
+ */
+   SVGA3DFORMAT_OP_SRGBREAD                              = 0x00008000,
+
+/*
+ * Indicates that this format can be used in the bumpmap instructions
+ */
+   SVGA3DFORMAT_OP_BUMPMAP                               = 0x00010000,
+
+/*
+ * Indicates that this format can be sampled by the displacement map sampler
+ */
+   SVGA3DFORMAT_OP_DMAP                                  = 0x00020000,
+
+/*
+ * Indicates that this format cannot be used with texture filtering
+ */
+   SVGA3DFORMAT_OP_NOFILTER                              = 0x00040000,
+
+/*
+ * Indicates that format conversions are supported to this RGB format if
+ * SVGA3DFORMAT_OP_CONVERT_TO_ARGB is specified in the source format.
+ */
+   SVGA3DFORMAT_OP_MEMBEROFGROUP_ARGB                    = 0x00080000,
+
+/*
+ * Indicated that this format can be written as an SRGB target (meaning that the
+ * pixel pipe will DE-linearize data on output to format)
+ */
+   SVGA3DFORMAT_OP_SRGBWRITE                             = 0x00100000,
+
+/*
+ * Indicates that this format cannot be used with alpha blending
+ */
+   SVGA3DFORMAT_OP_NOALPHABLEND                          = 0x00200000,
+
+/*
+ * Indicates that the device can auto-generated sublevels for resources
+ * of this format
+ */
+   SVGA3DFORMAT_OP_AUTOGENMIPMAP                         = 0x00400000,
+
+/*
+ * Indicates that this format can be used by vertex texture sampler
+ */
+   SVGA3DFORMAT_OP_VERTEXTEXTURE                         = 0x00800000,
+
+/*
+ * Indicates that this format supports neither texture coordinate wrap
+ * modes, nor mipmapping
+ */
+   SVGA3DFORMAT_OP_NOTEXCOORDWRAPNORMIP                  = 0x01000000
+} SVGA3dFormatOp;
+
+/*
+ * This structure is a conversion of SVGA3DFORMAT_OP_*.
+ * Entries must be located at the same position.
+ */
+typedef union {
+   uint32 value;
+   struct {
+      uint32 texture : 1;
+      uint32 volumeTexture : 1;
+      uint32 cubeTexture : 1;
+      uint32 offscreenRenderTarget : 1;
+      uint32 sameFormatRenderTarget : 1;
+      uint32 unknown1 : 1;
+      uint32 zStencil : 1;
+      uint32 zStencilArbitraryDepth : 1;
+      uint32 sameFormatUpToAlpha : 1;
+      uint32 unknown2 : 1;
+      uint32 displayMode : 1;
+      uint32 acceleration3d : 1;
+      uint32 pixelSize : 1;
+      uint32 convertToARGB : 1;
+      uint32 offscreenPlain : 1;
+      uint32 sRGBRead : 1;
+      uint32 bumpMap : 1;
+      uint32 dmap : 1;
+      uint32 noFilter : 1;
+      uint32 memberOfGroupARGB : 1;
+      uint32 sRGBWrite : 1;
+      uint32 noAlphaBlend : 1;
+      uint32 autoGenMipMap : 1;
+      uint32 vertexTexture : 1;
+      uint32 noTexCoordWrapNorMip : 1;
+   };
+} SVGA3dSurfaceFormatCaps;
+
+/*
+ * SVGA_3D_CMD_SETRENDERSTATE Types.  All value types
+ * must fit in a uint32.
+ */
+
+typedef enum {
+   SVGA3D_RS_INVALID                   = 0,
+   SVGA3D_RS_ZENABLE                   = 1,     /* SVGA3dBool */
+   SVGA3D_RS_ZWRITEENABLE              = 2,     /* SVGA3dBool */
+   SVGA3D_RS_ALPHATESTENABLE           = 3,     /* SVGA3dBool */
+   SVGA3D_RS_DITHERENABLE              = 4,     /* SVGA3dBool */
+   SVGA3D_RS_BLENDENABLE               = 5,     /* SVGA3dBool */
+   SVGA3D_RS_FOGENABLE                 = 6,     /* SVGA3dBool */
+   SVGA3D_RS_SPECULARENABLE            = 7,     /* SVGA3dBool */
+   SVGA3D_RS_STENCILENABLE             = 8,     /* SVGA3dBool */
+   SVGA3D_RS_LIGHTINGENABLE            = 9,     /* SVGA3dBool */
+   SVGA3D_RS_NORMALIZENORMALS          = 10,    /* SVGA3dBool */
+   SVGA3D_RS_POINTSPRITEENABLE         = 11,    /* SVGA3dBool */
+   SVGA3D_RS_POINTSCALEENABLE          = 12,    /* SVGA3dBool */
+   SVGA3D_RS_STENCILREF                = 13,    /* uint32 */
+   SVGA3D_RS_STENCILMASK               = 14,    /* uint32 */
+   SVGA3D_RS_STENCILWRITEMASK          = 15,    /* uint32 */
+   SVGA3D_RS_FOGSTART                  = 16,    /* float */
+   SVGA3D_RS_FOGEND                    = 17,    /* float */
+   SVGA3D_RS_FOGDENSITY                = 18,    /* float */
+   SVGA3D_RS_POINTSIZE                 = 19,    /* float */
+   SVGA3D_RS_POINTSIZEMIN              = 20,    /* float */
+   SVGA3D_RS_POINTSIZEMAX              = 21,    /* float */
+   SVGA3D_RS_POINTSCALE_A              = 22,    /* float */
+   SVGA3D_RS_POINTSCALE_B              = 23,    /* float */
+   SVGA3D_RS_POINTSCALE_C              = 24,    /* float */
+   SVGA3D_RS_FOGCOLOR                  = 25,    /* SVGA3dColor */
+   SVGA3D_RS_AMBIENT                   = 26,    /* SVGA3dColor */
+   SVGA3D_RS_CLIPPLANEENABLE           = 27,    /* SVGA3dClipPlanes */
+   SVGA3D_RS_FOGMODE                   = 28,    /* SVGA3dFogMode */
+   SVGA3D_RS_FILLMODE                  = 29,    /* SVGA3dFillMode */
+   SVGA3D_RS_SHADEMODE                 = 30,    /* SVGA3dShadeMode */
+   SVGA3D_RS_LINEPATTERN               = 31,    /* SVGA3dLinePattern */
+   SVGA3D_RS_SRCBLEND                  = 32,    /* SVGA3dBlendOp */
+   SVGA3D_RS_DSTBLEND                  = 33,    /* SVGA3dBlendOp */
+   SVGA3D_RS_BLENDEQUATION             = 34,    /* SVGA3dBlendEquation */
+   SVGA3D_RS_CULLMODE                  = 35,    /* SVGA3dFace */
+   SVGA3D_RS_ZFUNC                     = 36,    /* SVGA3dCmpFunc */
+   SVGA3D_RS_ALPHAFUNC                 = 37,    /* SVGA3dCmpFunc */
+   SVGA3D_RS_STENCILFUNC               = 38,    /* SVGA3dCmpFunc */
+   SVGA3D_RS_STENCILFAIL               = 39,    /* SVGA3dStencilOp */
+   SVGA3D_RS_STENCILZFAIL              = 40,    /* SVGA3dStencilOp */
+   SVGA3D_RS_STENCILPASS               = 41,    /* SVGA3dStencilOp */
+   SVGA3D_RS_ALPHAREF                  = 42,    /* float (0.0 .. 1.0) */
+   SVGA3D_RS_FRONTWINDING              = 43,    /* SVGA3dFrontWinding */
+   SVGA3D_RS_COORDINATETYPE            = 44,    /* SVGA3dCoordinateType */
+   SVGA3D_RS_ZBIAS                     = 45,    /* float */
+   SVGA3D_RS_RANGEFOGENABLE            = 46,    /* SVGA3dBool */
+   SVGA3D_RS_COLORWRITEENABLE          = 47,    /* SVGA3dColorMask */
+   SVGA3D_RS_VERTEXMATERIALENABLE      = 48,    /* SVGA3dBool */
+   SVGA3D_RS_DIFFUSEMATERIALSOURCE     = 49,    /* SVGA3dVertexMaterial */
+   SVGA3D_RS_SPECULARMATERIALSOURCE    = 50,    /* SVGA3dVertexMaterial */
+   SVGA3D_RS_AMBIENTMATERIALSOURCE     = 51,    /* SVGA3dVertexMaterial */
+   SVGA3D_RS_EMISSIVEMATERIALSOURCE    = 52,    /* SVGA3dVertexMaterial */
+   SVGA3D_RS_TEXTUREFACTOR             = 53,    /* SVGA3dColor */
+   SVGA3D_RS_LOCALVIEWER               = 54,    /* SVGA3dBool */
+   SVGA3D_RS_SCISSORTESTENABLE         = 55,    /* SVGA3dBool */
+   SVGA3D_RS_BLENDCOLOR                = 56,    /* SVGA3dColor */
+   SVGA3D_RS_STENCILENABLE2SIDED       = 57,    /* SVGA3dBool */
+   SVGA3D_RS_CCWSTENCILFUNC            = 58,    /* SVGA3dCmpFunc */
+   SVGA3D_RS_CCWSTENCILFAIL            = 59,    /* SVGA3dStencilOp */
+   SVGA3D_RS_CCWSTENCILZFAIL           = 60,    /* SVGA3dStencilOp */
+   SVGA3D_RS_CCWSTENCILPASS            = 61,    /* SVGA3dStencilOp */
+   SVGA3D_RS_VERTEXBLEND               = 62,    /* SVGA3dVertexBlendFlags */
+   SVGA3D_RS_SLOPESCALEDEPTHBIAS       = 63,    /* float */
+   SVGA3D_RS_DEPTHBIAS                 = 64,    /* float */
+
+
+   /*
+    * Output Gamma Level
+    *
+    * Output gamma effects the gamma curve of colors that are output from the
+    * rendering pipeline.  A value of 1.0 specifies a linear color space. If the
+    * value is <= 0.0, gamma correction is ignored and linear color space is
+    * used.
+    */
+
+   SVGA3D_RS_OUTPUTGAMMA               = 65,    /* float */
+   SVGA3D_RS_ZVISIBLE                  = 66,    /* SVGA3dBool */
+   SVGA3D_RS_LASTPIXEL                 = 67,    /* SVGA3dBool */
+   SVGA3D_RS_CLIPPING                  = 68,    /* SVGA3dBool */
+   SVGA3D_RS_WRAP0                     = 69,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP1                     = 70,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP2                     = 71,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP3                     = 72,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP4                     = 73,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP5                     = 74,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP6                     = 75,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP7                     = 76,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP8                     = 77,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP9                     = 78,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP10                    = 79,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP11                    = 80,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP12                    = 81,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP13                    = 82,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP14                    = 83,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_WRAP15                    = 84,    /* SVGA3dWrapFlags */
+   SVGA3D_RS_MULTISAMPLEANTIALIAS      = 85,    /* SVGA3dBool */
+   SVGA3D_RS_MULTISAMPLEMASK           = 86,    /* uint32 */
+   SVGA3D_RS_INDEXEDVERTEXBLENDENABLE  = 87,    /* SVGA3dBool */
+   SVGA3D_RS_TWEENFACTOR               = 88,    /* float */
+   SVGA3D_RS_ANTIALIASEDLINEENABLE     = 89,    /* SVGA3dBool */
+   SVGA3D_RS_COLORWRITEENABLE1         = 90,    /* SVGA3dColorMask */
+   SVGA3D_RS_COLORWRITEENABLE2         = 91,    /* SVGA3dColorMask */
+   SVGA3D_RS_COLORWRITEENABLE3         = 92,    /* SVGA3dColorMask */
+   SVGA3D_RS_SEPARATEALPHABLENDENABLE  = 93,    /* SVGA3dBool */
+   SVGA3D_RS_SRCBLENDALPHA             = 94,    /* SVGA3dBlendOp */
+   SVGA3D_RS_DSTBLENDALPHA             = 95,    /* SVGA3dBlendOp */
+   SVGA3D_RS_BLENDEQUATIONALPHA        = 96,    /* SVGA3dBlendEquation */
+   SVGA3D_RS_MAX
+} SVGA3dRenderStateName;
+
+typedef enum {
+   SVGA3D_VERTEXMATERIAL_NONE     = 0,    /* Use the value in the current material */
+   SVGA3D_VERTEXMATERIAL_DIFFUSE  = 1,    /* Use the value in the diffuse component */
+   SVGA3D_VERTEXMATERIAL_SPECULAR = 2,    /* Use the value in the specular component */
+} SVGA3dVertexMaterial;
+
+typedef enum {
+   SVGA3D_FILLMODE_INVALID = 0,
+   SVGA3D_FILLMODE_POINT   = 1,
+   SVGA3D_FILLMODE_LINE    = 2,
+   SVGA3D_FILLMODE_FILL    = 3,
+   SVGA3D_FILLMODE_MAX
+} SVGA3dFillModeType;
+
+
+typedef
+union {
+   struct {
+      uint16   mode;       /* SVGA3dFillModeType */
+      uint16   face;       /* SVGA3dFace */
+   };
+   uint32 uintValue;
+} SVGA3dFillMode;
+
+typedef enum {
+   SVGA3D_SHADEMODE_INVALID = 0,
+   SVGA3D_SHADEMODE_FLAT    = 1,
+   SVGA3D_SHADEMODE_SMOOTH  = 2,
+   SVGA3D_SHADEMODE_PHONG   = 3,     /* Not supported */
+   SVGA3D_SHADEMODE_MAX
+} SVGA3dShadeMode;
+
+typedef
+union {
+   struct {
+      uint16 repeat;
+      uint16 pattern;
+   };
+   uint32 uintValue;
+} SVGA3dLinePattern;
+
+typedef enum {
+   SVGA3D_BLENDOP_INVALID            = 0,
+   SVGA3D_BLENDOP_ZERO               = 1,
+   SVGA3D_BLENDOP_ONE                = 2,
+   SVGA3D_BLENDOP_SRCCOLOR           = 3,
+   SVGA3D_BLENDOP_INVSRCCOLOR        = 4,
+   SVGA3D_BLENDOP_SRCALPHA           = 5,
+   SVGA3D_BLENDOP_INVSRCALPHA        = 6,
+   SVGA3D_BLENDOP_DESTALPHA          = 7,
+   SVGA3D_BLENDOP_INVDESTALPHA       = 8,
+   SVGA3D_BLENDOP_DESTCOLOR          = 9,
+   SVGA3D_BLENDOP_INVDESTCOLOR       = 10,
+   SVGA3D_BLENDOP_SRCALPHASAT        = 11,
+   SVGA3D_BLENDOP_BLENDFACTOR        = 12,
+   SVGA3D_BLENDOP_INVBLENDFACTOR     = 13,
+   SVGA3D_BLENDOP_MAX
+} SVGA3dBlendOp;
+
+typedef enum {
+   SVGA3D_BLENDEQ_INVALID            = 0,
+   SVGA3D_BLENDEQ_ADD                = 1,
+   SVGA3D_BLENDEQ_SUBTRACT           = 2,
+   SVGA3D_BLENDEQ_REVSUBTRACT        = 3,
+   SVGA3D_BLENDEQ_MINIMUM            = 4,
+   SVGA3D_BLENDEQ_MAXIMUM            = 5,
+   SVGA3D_BLENDEQ_MAX
+} SVGA3dBlendEquation;
+
+typedef enum {
+   SVGA3D_FRONTWINDING_INVALID = 0,
+   SVGA3D_FRONTWINDING_CW      = 1,
+   SVGA3D_FRONTWINDING_CCW     = 2,
+   SVGA3D_FRONTWINDING_MAX
+} SVGA3dFrontWinding;
+
+typedef enum {
+   SVGA3D_FACE_INVALID  = 0,
+   SVGA3D_FACE_NONE     = 1,
+   SVGA3D_FACE_FRONT    = 2,
+   SVGA3D_FACE_BACK     = 3,
+   SVGA3D_FACE_FRONT_BACK = 4,
+   SVGA3D_FACE_MAX
+} SVGA3dFace;
+
+/*
+ * The order and the values should not be changed
+ */
+
+typedef enum {
+   SVGA3D_CMP_INVALID              = 0,
+   SVGA3D_CMP_NEVER                = 1,
+   SVGA3D_CMP_LESS                 = 2,
+   SVGA3D_CMP_EQUAL                = 3,
+   SVGA3D_CMP_LESSEQUAL            = 4,
+   SVGA3D_CMP_GREATER              = 5,
+   SVGA3D_CMP_NOTEQUAL             = 6,
+   SVGA3D_CMP_GREATEREQUAL         = 7,
+   SVGA3D_CMP_ALWAYS               = 8,
+   SVGA3D_CMP_MAX
+} SVGA3dCmpFunc;
+
+/*
+ * SVGA3D_FOGFUNC_* specifies the fog equation, or PER_VERTEX which allows
+ * the fog factor to be specified in the alpha component of the specular
+ * (a.k.a. secondary) vertex color.
+ */
+typedef enum {
+   SVGA3D_FOGFUNC_INVALID          = 0,
+   SVGA3D_FOGFUNC_EXP              = 1,
+   SVGA3D_FOGFUNC_EXP2             = 2,
+   SVGA3D_FOGFUNC_LINEAR           = 3,
+   SVGA3D_FOGFUNC_PER_VERTEX       = 4
+} SVGA3dFogFunction;
+
+/*
+ * SVGA3D_FOGTYPE_* specifies if fog factors are computed on a per-vertex
+ * or per-pixel basis.
+ */
+typedef enum {
+   SVGA3D_FOGTYPE_INVALID          = 0,
+   SVGA3D_FOGTYPE_VERTEX           = 1,
+   SVGA3D_FOGTYPE_PIXEL            = 2,
+   SVGA3D_FOGTYPE_MAX              = 3
+} SVGA3dFogType;
+
+/*
+ * SVGA3D_FOGBASE_* selects depth or range-based fog. Depth-based fog is
+ * computed using the eye Z value of each pixel (or vertex), whereas range-
+ * based fog is computed using the actual distance (range) to the eye.
+ */
+typedef enum {
+   SVGA3D_FOGBASE_INVALID          = 0,
+   SVGA3D_FOGBASE_DEPTHBASED       = 1,
+   SVGA3D_FOGBASE_RANGEBASED       = 2,
+   SVGA3D_FOGBASE_MAX              = 3
+} SVGA3dFogBase;
+
+typedef enum {
+   SVGA3D_STENCILOP_INVALID        = 0,
+   SVGA3D_STENCILOP_KEEP           = 1,
+   SVGA3D_STENCILOP_ZERO           = 2,
+   SVGA3D_STENCILOP_REPLACE        = 3,
+   SVGA3D_STENCILOP_INCRSAT        = 4,
+   SVGA3D_STENCILOP_DECRSAT        = 5,
+   SVGA3D_STENCILOP_INVERT         = 6,
+   SVGA3D_STENCILOP_INCR           = 7,
+   SVGA3D_STENCILOP_DECR           = 8,
+   SVGA3D_STENCILOP_MAX
+} SVGA3dStencilOp;
+
+typedef enum {
+   SVGA3D_CLIPPLANE_0              = (1 << 0),
+   SVGA3D_CLIPPLANE_1              = (1 << 1),
+   SVGA3D_CLIPPLANE_2              = (1 << 2),
+   SVGA3D_CLIPPLANE_3              = (1 << 3),
+   SVGA3D_CLIPPLANE_4              = (1 << 4),
+   SVGA3D_CLIPPLANE_5              = (1 << 5),
+} SVGA3dClipPlanes;
+
+typedef enum {
+   SVGA3D_CLEAR_COLOR              = 0x1,
+   SVGA3D_CLEAR_DEPTH              = 0x2,
+   SVGA3D_CLEAR_STENCIL            = 0x4
+} SVGA3dClearFlag;
+
+typedef enum {
+   SVGA3D_RT_DEPTH                 = 0,
+   SVGA3D_RT_STENCIL               = 1,
+   SVGA3D_RT_COLOR0                = 2,
+   SVGA3D_RT_COLOR1                = 3,
+   SVGA3D_RT_COLOR2                = 4,
+   SVGA3D_RT_COLOR3                = 5,
+   SVGA3D_RT_COLOR4                = 6,
+   SVGA3D_RT_COLOR5                = 7,
+   SVGA3D_RT_COLOR6                = 8,
+   SVGA3D_RT_COLOR7                = 9,
+   SVGA3D_RT_MAX,
+   SVGA3D_RT_INVALID               = ((uint32)-1),
+} SVGA3dRenderTargetType;
+
+#define SVGA3D_MAX_RT_COLOR (SVGA3D_RT_COLOR7 - SVGA3D_RT_COLOR0 + 1)
+
+typedef
+union {
+   struct {
+      uint32  red   : 1;
+      uint32  green : 1;
+      uint32  blue  : 1;
+      uint32  alpha : 1;
+   };
+   uint32 uintValue;
+} SVGA3dColorMask;
+
+typedef enum {
+   SVGA3D_VBLEND_DISABLE            = 0,
+   SVGA3D_VBLEND_1WEIGHT            = 1,
+   SVGA3D_VBLEND_2WEIGHT            = 2,
+   SVGA3D_VBLEND_3WEIGHT            = 3,
+} SVGA3dVertexBlendFlags;
+
+typedef enum {
+   SVGA3D_WRAPCOORD_0   = 1 << 0,
+   SVGA3D_WRAPCOORD_1   = 1 << 1,
+   SVGA3D_WRAPCOORD_2   = 1 << 2,
+   SVGA3D_WRAPCOORD_3   = 1 << 3,
+   SVGA3D_WRAPCOORD_ALL = 0xF,
+} SVGA3dWrapFlags;
+
+/*
+ * SVGA_3D_CMD_TEXTURESTATE Types.  All value types
+ * must fit in a uint32.
+ */
+
+typedef enum {
+   SVGA3D_TS_INVALID                    = 0,
+   SVGA3D_TS_BIND_TEXTURE               = 1,    /* SVGA3dSurfaceId */
+   SVGA3D_TS_COLOROP                    = 2,    /* SVGA3dTextureCombiner */
+   SVGA3D_TS_COLORARG1                  = 3,    /* SVGA3dTextureArgData */
+   SVGA3D_TS_COLORARG2                  = 4,    /* SVGA3dTextureArgData */
+   SVGA3D_TS_ALPHAOP                    = 5,    /* SVGA3dTextureCombiner */
+   SVGA3D_TS_ALPHAARG1                  = 6,    /* SVGA3dTextureArgData */
+   SVGA3D_TS_ALPHAARG2                  = 7,    /* SVGA3dTextureArgData */
+   SVGA3D_TS_ADDRESSU                   = 8,    /* SVGA3dTextureAddress */
+   SVGA3D_TS_ADDRESSV                   = 9,    /* SVGA3dTextureAddress */
+   SVGA3D_TS_MIPFILTER                  = 10,   /* SVGA3dTextureFilter */
+   SVGA3D_TS_MAGFILTER                  = 11,   /* SVGA3dTextureFilter */
+   SVGA3D_TS_MINFILTER                  = 12,   /* SVGA3dTextureFilter */
+   SVGA3D_TS_BORDERCOLOR                = 13,   /* SVGA3dColor */
+   SVGA3D_TS_TEXCOORDINDEX              = 14,   /* uint32 */
+   SVGA3D_TS_TEXTURETRANSFORMFLAGS      = 15,   /* SVGA3dTexTransformFlags */
+   SVGA3D_TS_TEXCOORDGEN                = 16,   /* SVGA3dTextureCoordGen */
+   SVGA3D_TS_BUMPENVMAT00               = 17,   /* float */
+   SVGA3D_TS_BUMPENVMAT01               = 18,   /* float */
+   SVGA3D_TS_BUMPENVMAT10               = 19,   /* float */
+   SVGA3D_TS_BUMPENVMAT11               = 20,   /* float */
+   SVGA3D_TS_TEXTURE_MIPMAP_LEVEL       = 21,   /* uint32 */
+   SVGA3D_TS_TEXTURE_LOD_BIAS           = 22,   /* float */
+   SVGA3D_TS_TEXTURE_ANISOTROPIC_LEVEL  = 23,   /* uint32 */
+   SVGA3D_TS_ADDRESSW                   = 24,   /* SVGA3dTextureAddress */
+
+
+   /*
+    * Sampler Gamma Level
+    *
+    * Sampler gamma effects the color of samples taken from the sampler.  A
+    * value of 1.0 will produce linear samples.  If the value is <= 0.0 the
+    * gamma value is ignored and a linear space is used.
+    */
+
+   SVGA3D_TS_GAMMA                      = 25,   /* float */
+   SVGA3D_TS_BUMPENVLSCALE              = 26,   /* float */
+   SVGA3D_TS_BUMPENVLOFFSET             = 27,   /* float */
+   SVGA3D_TS_COLORARG0                  = 28,   /* SVGA3dTextureArgData */
+   SVGA3D_TS_ALPHAARG0                  = 29,   /* SVGA3dTextureArgData */
+   SVGA3D_TS_MAX
+} SVGA3dTextureStateName;
+
+typedef enum {
+   SVGA3D_TC_INVALID                   = 0,
+   SVGA3D_TC_DISABLE                   = 1,
+   SVGA3D_TC_SELECTARG1                = 2,
+   SVGA3D_TC_SELECTARG2                = 3,
+   SVGA3D_TC_MODULATE                  = 4,
+   SVGA3D_TC_ADD                       = 5,
+   SVGA3D_TC_ADDSIGNED                 = 6,
+   SVGA3D_TC_SUBTRACT                  = 7,
+   SVGA3D_TC_BLENDTEXTUREALPHA         = 8,
+   SVGA3D_TC_BLENDDIFFUSEALPHA         = 9,
+   SVGA3D_TC_BLENDCURRENTALPHA         = 10,
+   SVGA3D_TC_BLENDFACTORALPHA          = 11,
+   SVGA3D_TC_MODULATE2X                = 12,
+   SVGA3D_TC_MODULATE4X                = 13,
+   SVGA3D_TC_DSDT                      = 14,
+   SVGA3D_TC_DOTPRODUCT3               = 15,
+   SVGA3D_TC_BLENDTEXTUREALPHAPM       = 16,
+   SVGA3D_TC_ADDSIGNED2X               = 17,
+   SVGA3D_TC_ADDSMOOTH                 = 18,
+   SVGA3D_TC_PREMODULATE               = 19,
+   SVGA3D_TC_MODULATEALPHA_ADDCOLOR    = 20,
+   SVGA3D_TC_MODULATECOLOR_ADDALPHA    = 21,
+   SVGA3D_TC_MODULATEINVALPHA_ADDCOLOR = 22,
+   SVGA3D_TC_MODULATEINVCOLOR_ADDALPHA = 23,
+   SVGA3D_TC_BUMPENVMAPLUMINANCE       = 24,
+   SVGA3D_TC_MULTIPLYADD               = 25,
+   SVGA3D_TC_LERP                      = 26,
+   SVGA3D_TC_MAX
+} SVGA3dTextureCombiner;
+
+#define SVGA3D_TC_CAP_BIT(svga3d_tc_op) (svga3d_tc_op ? (1 << (svga3d_tc_op - 1)) : 0)
+
+typedef enum {
+   SVGA3D_TEX_ADDRESS_INVALID    = 0,
+   SVGA3D_TEX_ADDRESS_WRAP       = 1,
+   SVGA3D_TEX_ADDRESS_MIRROR     = 2,
+   SVGA3D_TEX_ADDRESS_CLAMP      = 3,
+   SVGA3D_TEX_ADDRESS_BORDER     = 4,
+   SVGA3D_TEX_ADDRESS_MIRRORONCE = 5,
+   SVGA3D_TEX_ADDRESS_EDGE       = 6,
+   SVGA3D_TEX_ADDRESS_MAX
+} SVGA3dTextureAddress;
+
+/*
+ * SVGA3D_TEX_FILTER_NONE as the minification filter means mipmapping is
+ * disabled, and the rasterizer should use the magnification filter instead.
+ */
+typedef enum {
+   SVGA3D_TEX_FILTER_NONE           = 0,
+   SVGA3D_TEX_FILTER_NEAREST        = 1,
+   SVGA3D_TEX_FILTER_LINEAR         = 2,
+   SVGA3D_TEX_FILTER_ANISOTROPIC    = 3,
+   SVGA3D_TEX_FILTER_FLATCUBIC      = 4, // Deprecated, not implemented
+   SVGA3D_TEX_FILTER_GAUSSIANCUBIC  = 5, // Deprecated, not implemented
+   SVGA3D_TEX_FILTER_PYRAMIDALQUAD  = 6, // Not currently implemented
+   SVGA3D_TEX_FILTER_GAUSSIANQUAD   = 7, // Not currently implemented
+   SVGA3D_TEX_FILTER_MAX
+} SVGA3dTextureFilter;
+
+typedef enum {
+   SVGA3D_TEX_TRANSFORM_OFF    = 0,
+   SVGA3D_TEX_TRANSFORM_S      = (1 << 0),
+   SVGA3D_TEX_TRANSFORM_T      = (1 << 1),
+   SVGA3D_TEX_TRANSFORM_R      = (1 << 2),
+   SVGA3D_TEX_TRANSFORM_Q      = (1 << 3),
+   SVGA3D_TEX_PROJECTED        = (1 << 15),
+} SVGA3dTexTransformFlags;
+
+typedef enum {
+   SVGA3D_TEXCOORD_GEN_OFF              = 0,
+   SVGA3D_TEXCOORD_GEN_EYE_POSITION     = 1,
+   SVGA3D_TEXCOORD_GEN_EYE_NORMAL       = 2,
+   SVGA3D_TEXCOORD_GEN_REFLECTIONVECTOR = 3,
+   SVGA3D_TEXCOORD_GEN_SPHERE           = 4,
+   SVGA3D_TEXCOORD_GEN_MAX
+} SVGA3dTextureCoordGen;
+
+/*
+ * Texture argument constants for texture combiner
+ */
+typedef enum {
+   SVGA3D_TA_INVALID    = 0,
+   SVGA3D_TA_CONSTANT   = 1,
+   SVGA3D_TA_PREVIOUS   = 2,
+   SVGA3D_TA_DIFFUSE    = 3,
+   SVGA3D_TA_TEXTURE    = 4,
+   SVGA3D_TA_SPECULAR   = 5,
+   SVGA3D_TA_MAX
+} SVGA3dTextureArgData;
+
+#define SVGA3D_TM_MASK_LEN 4
+
+/* Modifiers for texture argument constants defined above. */
+typedef enum {
+   SVGA3D_TM_NONE       = 0,
+   SVGA3D_TM_ALPHA      = (1 << SVGA3D_TM_MASK_LEN),
+   SVGA3D_TM_ONE_MINUS  = (2 << SVGA3D_TM_MASK_LEN),
+} SVGA3dTextureArgModifier;
+
+#define SVGA3D_INVALID_ID         ((uint32)-1)
+#define SVGA3D_MAX_CLIP_PLANES    6
+
+/*
+ * This is the limit to the number of fixed-function texture
+ * transforms and texture coordinates we can support. It does *not*
+ * correspond to the number of texture image units (samplers) we
+ * support!
+ */
+#define SVGA3D_MAX_TEXTURE_COORDS 8
+
+/*
+ * Vertex declarations
+ *
+ * Notes:
+ *
+ * SVGA3D_DECLUSAGE_POSITIONT is for pre-transformed vertices. If you
+ * draw with any POSITIONT vertex arrays, the programmable vertex
+ * pipeline will be implicitly disabled. Drawing will take place as if
+ * no vertex shader was bound.
+ */
+
+typedef enum {
+   SVGA3D_DECLUSAGE_POSITION     = 0,
+   SVGA3D_DECLUSAGE_BLENDWEIGHT,       //  1
+   SVGA3D_DECLUSAGE_BLENDINDICES,      //  2
+   SVGA3D_DECLUSAGE_NORMAL,            //  3
+   SVGA3D_DECLUSAGE_PSIZE,             //  4
+   SVGA3D_DECLUSAGE_TEXCOORD,          //  5
+   SVGA3D_DECLUSAGE_TANGENT,           //  6
+   SVGA3D_DECLUSAGE_BINORMAL,          //  7
+   SVGA3D_DECLUSAGE_TESSFACTOR,        //  8
+   SVGA3D_DECLUSAGE_POSITIONT,         //  9
+   SVGA3D_DECLUSAGE_COLOR,             // 10
+   SVGA3D_DECLUSAGE_FOG,               // 11
+   SVGA3D_DECLUSAGE_DEPTH,             // 12
+   SVGA3D_DECLUSAGE_SAMPLE,            // 13
+   SVGA3D_DECLUSAGE_MAX
+} SVGA3dDeclUsage;
+
+typedef enum {
+   SVGA3D_DECLMETHOD_DEFAULT     = 0,
+   SVGA3D_DECLMETHOD_PARTIALU,
+   SVGA3D_DECLMETHOD_PARTIALV,
+   SVGA3D_DECLMETHOD_CROSSUV,          // Normal
+   SVGA3D_DECLMETHOD_UV,
+   SVGA3D_DECLMETHOD_LOOKUP,           // Lookup a displacement map
+   SVGA3D_DECLMETHOD_LOOKUPPRESAMPLED, // Lookup a pre-sampled displacement map
+} SVGA3dDeclMethod;
+
+typedef enum {
+   SVGA3D_DECLTYPE_FLOAT1        =  0,
+   SVGA3D_DECLTYPE_FLOAT2        =  1,
+   SVGA3D_DECLTYPE_FLOAT3        =  2,
+   SVGA3D_DECLTYPE_FLOAT4        =  3,
+   SVGA3D_DECLTYPE_D3DCOLOR      =  4,
+   SVGA3D_DECLTYPE_UBYTE4        =  5,
+   SVGA3D_DECLTYPE_SHORT2        =  6,
+   SVGA3D_DECLTYPE_SHORT4        =  7,
+   SVGA3D_DECLTYPE_UBYTE4N       =  8,
+   SVGA3D_DECLTYPE_SHORT2N       =  9,
+   SVGA3D_DECLTYPE_SHORT4N       = 10,
+   SVGA3D_DECLTYPE_USHORT2N      = 11,
+   SVGA3D_DECLTYPE_USHORT4N      = 12,
+   SVGA3D_DECLTYPE_UDEC3         = 13,
+   SVGA3D_DECLTYPE_DEC3N         = 14,
+   SVGA3D_DECLTYPE_FLOAT16_2     = 15,
+   SVGA3D_DECLTYPE_FLOAT16_4     = 16,
+   SVGA3D_DECLTYPE_MAX,
+} SVGA3dDeclType;
+
+/*
+ * This structure is used for the divisor for geometry instancing;
+ * it's a direct translation of the Direct3D equivalent.
+ */
+typedef union {
+   struct {
+      /*
+       * For index data, this number represents the number of instances to draw.
+       * For instance data, this number represents the number of
+       * instances/vertex in this stream
+       */
+      uint32 count : 30;
+
+      /*
+       * This is 1 if this is supposed to be the data that is repeated for
+       * every instance.
+       */
+      uint32 indexedData : 1;
+
+      /*
+       * This is 1 if this is supposed to be the per-instance data.
+       */
+      uint32 instanceData : 1;
+   };
+
+   uint32 value;
+} SVGA3dVertexDivisor;
+
+typedef enum {
+   SVGA3D_PRIMITIVE_INVALID                     = 0,
+   SVGA3D_PRIMITIVE_TRIANGLELIST                = 1,
+   SVGA3D_PRIMITIVE_POINTLIST                   = 2,
+   SVGA3D_PRIMITIVE_LINELIST                    = 3,
+   SVGA3D_PRIMITIVE_LINESTRIP                   = 4,
+   SVGA3D_PRIMITIVE_TRIANGLESTRIP               = 5,
+   SVGA3D_PRIMITIVE_TRIANGLEFAN                 = 6,
+   SVGA3D_PRIMITIVE_MAX
+} SVGA3dPrimitiveType;
+
+typedef enum {
+   SVGA3D_COORDINATE_INVALID                   = 0,
+   SVGA3D_COORDINATE_LEFTHANDED                = 1,
+   SVGA3D_COORDINATE_RIGHTHANDED               = 2,
+   SVGA3D_COORDINATE_MAX
+} SVGA3dCoordinateType;
+
+typedef enum {
+   SVGA3D_TRANSFORM_INVALID                     = 0,
+   SVGA3D_TRANSFORM_WORLD                       = 1,
+   SVGA3D_TRANSFORM_VIEW                        = 2,
+   SVGA3D_TRANSFORM_PROJECTION                  = 3,
+   SVGA3D_TRANSFORM_TEXTURE0                    = 4,
+   SVGA3D_TRANSFORM_TEXTURE1                    = 5,
+   SVGA3D_TRANSFORM_TEXTURE2                    = 6,
+   SVGA3D_TRANSFORM_TEXTURE3                    = 7,
+   SVGA3D_TRANSFORM_TEXTURE4                    = 8,
+   SVGA3D_TRANSFORM_TEXTURE5                    = 9,
+   SVGA3D_TRANSFORM_TEXTURE6                    = 10,
+   SVGA3D_TRANSFORM_TEXTURE7                    = 11,
+   SVGA3D_TRANSFORM_WORLD1                      = 12,
+   SVGA3D_TRANSFORM_WORLD2                      = 13,
+   SVGA3D_TRANSFORM_WORLD3                      = 14,
+   SVGA3D_TRANSFORM_MAX
+} SVGA3dTransformType;
+
+typedef enum {
+   SVGA3D_LIGHTTYPE_INVALID                     = 0,
+   SVGA3D_LIGHTTYPE_POINT                       = 1,
+   SVGA3D_LIGHTTYPE_SPOT1                       = 2, /* 1-cone, in degrees */
+   SVGA3D_LIGHTTYPE_SPOT2                       = 3, /* 2-cone, in radians */
+   SVGA3D_LIGHTTYPE_DIRECTIONAL                 = 4,
+   SVGA3D_LIGHTTYPE_MAX
+} SVGA3dLightType;
+
+typedef enum {
+   SVGA3D_CUBEFACE_POSX                         = 0,
+   SVGA3D_CUBEFACE_NEGX                         = 1,
+   SVGA3D_CUBEFACE_POSY                         = 2,
+   SVGA3D_CUBEFACE_NEGY                         = 3,
+   SVGA3D_CUBEFACE_POSZ                         = 4,
+   SVGA3D_CUBEFACE_NEGZ                         = 5,
+} SVGA3dCubeFace;
+
+typedef enum {
+   SVGA3D_SHADERTYPE_COMPILED_DX8               = 0,
+   SVGA3D_SHADERTYPE_VS                         = 1,
+   SVGA3D_SHADERTYPE_PS                         = 2,
+   SVGA3D_SHADERTYPE_MAX
+} SVGA3dShaderType;
+
+typedef enum {
+   SVGA3D_CONST_TYPE_FLOAT                      = 0,
+   SVGA3D_CONST_TYPE_INT                        = 1,
+   SVGA3D_CONST_TYPE_BOOL                       = 2,
+} SVGA3dShaderConstType;
+
+#define SVGA3D_MAX_SURFACE_FACES                6
+
+typedef enum {
+   SVGA3D_STRETCH_BLT_POINT                     = 0,
+   SVGA3D_STRETCH_BLT_LINEAR                    = 1,
+   SVGA3D_STRETCH_BLT_MAX
+} SVGA3dStretchBltMode;
+
+typedef enum {
+   SVGA3D_QUERYTYPE_OCCLUSION                   = 0,
+   SVGA3D_QUERYTYPE_MAX
+} SVGA3dQueryType;
+
+typedef enum {
+   SVGA3D_QUERYSTATE_PENDING     = 0,      /* Waiting on the host (set by guest) */
+   SVGA3D_QUERYSTATE_SUCCEEDED   = 1,      /* Completed successfully (set by host) */
+   SVGA3D_QUERYSTATE_FAILED      = 2,      /* Completed unsuccessfully (set by host) */
+   SVGA3D_QUERYSTATE_NEW         = 3,      /* Never submitted (For guest use only) */
+} SVGA3dQueryState;
+
+typedef enum {
+   SVGA3D_WRITE_HOST_VRAM        = 1,
+   SVGA3D_READ_HOST_VRAM         = 2,
+} SVGA3dTransferType;
+
+/*
+ * The maximum number vertex arrays we're guaranteed to support in
+ * SVGA_3D_CMD_DRAWPRIMITIVES.
+ */
+#define SVGA3D_MAX_VERTEX_ARRAYS   32
+
+/*
+ * Identifiers for commands in the command FIFO.
+ *
+ * IDs between 1000 and 1039 (inclusive) were used by obsolete versions of
+ * the SVGA3D protocol and remain reserved; they should not be used in the
+ * future.
+ *
+ * IDs between 1040 and 1999 (inclusive) are available for use by the
+ * current SVGA3D protocol.
+ *
+ * FIFO clients other than SVGA3D should stay below 1000, or at 2000
+ * and up.
+ */
+
+#define SVGA_3D_CMD_LEGACY_BASE            1000
+#define SVGA_3D_CMD_BASE                   1040
+
+#define SVGA_3D_CMD_SURFACE_DEFINE         SVGA_3D_CMD_BASE + 0
+#define SVGA_3D_CMD_SURFACE_DESTROY        SVGA_3D_CMD_BASE + 1
+#define SVGA_3D_CMD_SURFACE_COPY           SVGA_3D_CMD_BASE + 2
+#define SVGA_3D_CMD_SURFACE_STRETCHBLT     SVGA_3D_CMD_BASE + 3
+#define SVGA_3D_CMD_SURFACE_DMA            SVGA_3D_CMD_BASE + 4
+#define SVGA_3D_CMD_CONTEXT_DEFINE         SVGA_3D_CMD_BASE + 5
+#define SVGA_3D_CMD_CONTEXT_DESTROY        SVGA_3D_CMD_BASE + 6
+#define SVGA_3D_CMD_SETTRANSFORM           SVGA_3D_CMD_BASE + 7
+#define SVGA_3D_CMD_SETZRANGE              SVGA_3D_CMD_BASE + 8
+#define SVGA_3D_CMD_SETRENDERSTATE         SVGA_3D_CMD_BASE + 9
+#define SVGA_3D_CMD_SETRENDERTARGET        SVGA_3D_CMD_BASE + 10
+#define SVGA_3D_CMD_SETTEXTURESTATE        SVGA_3D_CMD_BASE + 11
+#define SVGA_3D_CMD_SETMATERIAL            SVGA_3D_CMD_BASE + 12
+#define SVGA_3D_CMD_SETLIGHTDATA           SVGA_3D_CMD_BASE + 13
+#define SVGA_3D_CMD_SETLIGHTENABLED        SVGA_3D_CMD_BASE + 14
+#define SVGA_3D_CMD_SETVIEWPORT            SVGA_3D_CMD_BASE + 15
+#define SVGA_3D_CMD_SETCLIPPLANE           SVGA_3D_CMD_BASE + 16
+#define SVGA_3D_CMD_CLEAR                  SVGA_3D_CMD_BASE + 17
+#define SVGA_3D_CMD_PRESENT                SVGA_3D_CMD_BASE + 18    // Deprecated
+#define SVGA_3D_CMD_SHADER_DEFINE          SVGA_3D_CMD_BASE + 19
+#define SVGA_3D_CMD_SHADER_DESTROY         SVGA_3D_CMD_BASE + 20
+#define SVGA_3D_CMD_SET_SHADER             SVGA_3D_CMD_BASE + 21
+#define SVGA_3D_CMD_SET_SHADER_CONST       SVGA_3D_CMD_BASE + 22
+#define SVGA_3D_CMD_DRAW_PRIMITIVES        SVGA_3D_CMD_BASE + 23
+#define SVGA_3D_CMD_SETSCISSORRECT         SVGA_3D_CMD_BASE + 24
+#define SVGA_3D_CMD_BEGIN_QUERY            SVGA_3D_CMD_BASE + 25
+#define SVGA_3D_CMD_END_QUERY              SVGA_3D_CMD_BASE + 26
+#define SVGA_3D_CMD_WAIT_FOR_QUERY         SVGA_3D_CMD_BASE + 27
+#define SVGA_3D_CMD_PRESENT_READBACK       SVGA_3D_CMD_BASE + 28    // Deprecated
+#define SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN SVGA_3D_CMD_BASE + 29
+#define SVGA_3D_CMD_MAX                    SVGA_3D_CMD_BASE + 30
+
+#define SVGA_3D_CMD_FUTURE_MAX             2000
+
+/*
+ * Common substructures used in multiple FIFO commands:
+ */
+
+typedef struct {
+   union {
+      struct {
+         uint16  function;       // SVGA3dFogFunction
+         uint8   type;           // SVGA3dFogType
+         uint8   base;           // SVGA3dFogBase
+      };
+      uint32     uintValue;
+   };
+} SVGA3dFogMode;
+
+/*
+ * Uniquely identify one image (a 1D/2D/3D array) from a surface. This
+ * is a surface ID as well as face/mipmap indices.
+ */
+
+typedef
+struct SVGA3dSurfaceImageId {
+   uint32               sid;
+   uint32               face;
+   uint32               mipmap;
+} SVGA3dSurfaceImageId;
+
+typedef
+struct SVGA3dGuestImage {
+   SVGAGuestPtr         ptr;
+
+   /*
+    * A note on interpretation of pitch: This value of pitch is the
+    * number of bytes between vertically adjacent image
+    * blocks. Normally this is the number of bytes between the first
+    * pixel of two adjacent scanlines. With compressed textures,
+    * however, this may represent the number of bytes between
+    * compression blocks rather than between rows of pixels.
+    *
+    * XXX: Compressed textures currently must be tightly packed in guest memory.
+    *
+    * If the image is 1-dimensional, pitch is ignored.
+    *
+    * If 'pitch' is zero, the SVGA3D device calculates a pitch value
+    * assuming each row of blocks is tightly packed.
+    */
+   uint32 pitch;
+} SVGA3dGuestImage;
+
+
+/*
+ * FIFO command format definitions:
+ */
+
+/*
+ * The data size header following cmdNum for every 3d command
+ */
+typedef
+struct {
+   uint32               id;
+   uint32               size;
+} SVGA3dCmdHeader;
+
+/*
+ * A surface is a hierarchy of host VRAM surfaces: 1D, 2D, or 3D, with
+ * optional mipmaps and cube faces.
+ */
+
+typedef
+struct {
+   uint32               width;
+   uint32               height;
+   uint32               depth;
+} SVGA3dSize;
+
+typedef enum {
+   SVGA3D_SURFACE_CUBEMAP              = (1 << 0),
+   SVGA3D_SURFACE_HINT_STATIC          = (1 << 1),
+   SVGA3D_SURFACE_HINT_DYNAMIC         = (1 << 2),
+   SVGA3D_SURFACE_HINT_INDEXBUFFER     = (1 << 3),
+   SVGA3D_SURFACE_HINT_VERTEXBUFFER    = (1 << 4),
+   SVGA3D_SURFACE_HINT_TEXTURE         = (1 << 5),
+   SVGA3D_SURFACE_HINT_RENDERTARGET    = (1 << 6),
+   SVGA3D_SURFACE_HINT_DEPTHSTENCIL    = (1 << 7),
+   SVGA3D_SURFACE_HINT_WRITEONLY       = (1 << 8),
+} SVGA3dSurfaceFlags;
+
+typedef
+struct {
+   uint32               numMipLevels;
+} SVGA3dSurfaceFace;
+
+typedef
+struct {
+   uint32                      sid;
+   SVGA3dSurfaceFlags          surfaceFlags;
+   SVGA3dSurfaceFormat         format;
+   SVGA3dSurfaceFace           face[SVGA3D_MAX_SURFACE_FACES];
+   /*
+    * Followed by an SVGA3dSize structure for each mip level in each face.
+    *
+    * A note on surface sizes: Sizes are always specified in pixels,
+    * even if the true surface size is not a multiple of the minimum
+    * block size of the surface's format. For example, a 3x3x1 DXT1
+    * compressed texture would actually be stored as a 4x4x1 image in
+    * memory.
+    */
+} SVGA3dCmdDefineSurface;       /* SVGA_3D_CMD_SURFACE_DEFINE */
+
+typedef
+struct {
+   uint32               sid;
+} SVGA3dCmdDestroySurface;      /* SVGA_3D_CMD_SURFACE_DESTROY */
+
+typedef
+struct {
+   uint32               cid;
+} SVGA3dCmdDefineContext;       /* SVGA_3D_CMD_CONTEXT_DEFINE */
+
+typedef
+struct {
+   uint32               cid;
+} SVGA3dCmdDestroyContext;      /* SVGA_3D_CMD_CONTEXT_DESTROY */
+
+typedef
+struct {
+   uint32               cid;
+   SVGA3dClearFlag      clearFlag;
+   uint32               color;
+   float                depth;
+   uint32               stencil;
+   /* Followed by variable number of SVGA3dRect structures */
+} SVGA3dCmdClear;               /* SVGA_3D_CMD_CLEAR */
+
+typedef
+struct SVGA3dCopyRect {
+   uint32               x;
+   uint32               y;
+   uint32               w;
+   uint32               h;
+   uint32               srcx;
+   uint32               srcy;
+} SVGA3dCopyRect;
+
+typedef
+struct SVGA3dCopyBox {
+   uint32               x;
+   uint32               y;
+   uint32               z;
+   uint32               w;
+   uint32               h;
+   uint32               d;
+   uint32               srcx;
+   uint32               srcy;
+   uint32               srcz;
+} SVGA3dCopyBox;
+
+typedef
+struct {
+   uint32               x;
+   uint32               y;
+   uint32               w;
+   uint32               h;
+} SVGA3dRect;
+
+typedef
+struct {
+   uint32               x;
+   uint32               y;
+   uint32               z;
+   uint32               w;
+   uint32               h;
+   uint32               d;
+} SVGA3dBox;
+
+typedef
+struct {
+   uint32               x;
+   uint32               y;
+   uint32               z;
+} SVGA3dPoint;
+
+typedef
+struct {
+   SVGA3dLightType      type;
+   SVGA3dBool           inWorldSpace;
+   float                diffuse[4];
+   float                specular[4];
+   float                ambient[4];
+   float                position[4];
+   float                direction[4];
+   float                range;
+   float                falloff;
+   float                attenuation0;
+   float                attenuation1;
+   float                attenuation2;
+   float                theta;
+   float                phi;
+} SVGA3dLightData;
+
+typedef
+struct {
+   uint32               sid;
+   /* Followed by variable number of SVGA3dCopyRect structures */
+} SVGA3dCmdPresent;             /* SVGA_3D_CMD_PRESENT */
+
+typedef
+struct {
+   SVGA3dRenderStateName   state;
+   union {
+      uint32               uintValue;
+      float                floatValue;
+   };
+} SVGA3dRenderState;
+
+typedef
+struct {
+   uint32               cid;
+   /* Followed by variable number of SVGA3dRenderState structures */
+} SVGA3dCmdSetRenderState;      /* SVGA_3D_CMD_SETRENDERSTATE */
+
+typedef
+struct {
+   uint32                 cid;
+   SVGA3dRenderTargetType type;
+   SVGA3dSurfaceImageId   target;
+} SVGA3dCmdSetRenderTarget;     /* SVGA_3D_CMD_SETRENDERTARGET */
+
+typedef
+struct {
+   SVGA3dSurfaceImageId  src;
+   SVGA3dSurfaceImageId  dest;
+   /* Followed by variable number of SVGA3dCopyBox structures */
+} SVGA3dCmdSurfaceCopy;               /* SVGA_3D_CMD_SURFACE_COPY */
+
+typedef
+struct {
+   SVGA3dSurfaceImageId  src;
+   SVGA3dSurfaceImageId  dest;
+   SVGA3dBox             boxSrc;
+   SVGA3dBox             boxDest;
+   SVGA3dStretchBltMode  mode;
+} SVGA3dCmdSurfaceStretchBlt;         /* SVGA_3D_CMD_SURFACE_STRETCHBLT */
+
+typedef
+struct {
+   /*
+    * If the discard flag is present in a surface DMA operation, the host may
+    * discard the contents of the current mipmap level and face of the target
+    * surface before applying the surface DMA contents.
+    */
+   uint32 discard : 1;
+
+   /*
+    * If the unsynchronized flag is present, the host may perform this upload
+    * without syncing to pending reads on this surface.
+    */
+   uint32 unsynchronized : 1;
+
+   /*
+    * Guests *MUST* set the reserved bits to 0 before submitting the command
+    * suffix as future flags may occupy these bits.
+    */
+   uint32 reserved : 30;
+} SVGA3dSurfaceDMAFlags;
+
+typedef
+struct {
+   SVGA3dGuestImage      guest;
+   SVGA3dSurfaceImageId  host;
+   SVGA3dTransferType    transfer;
+   /*
+    * Followed by variable number of SVGA3dCopyBox structures. For consistency
+    * in all clipping logic and coordinate translation, we define the
+    * "source" in each copyBox as the guest image and the
+    * "destination" as the host image, regardless of transfer
+    * direction.
+    *
+    * For efficiency, the SVGA3D device is free to copy more data than
+    * specified. For example, it may round copy boxes outwards such
+    * that they lie on particular alignment boundaries.
+    */
+} SVGA3dCmdSurfaceDMA;                /* SVGA_3D_CMD_SURFACE_DMA */
+
+/*
+ * SVGA3dCmdSurfaceDMASuffix --
+ *
+ *    This is a command suffix that will appear after a SurfaceDMA command in
+ *    the FIFO.  It contains some extra information that hosts may use to
+ *    optimize performance or protect the guest.  This suffix exists to preserve
+ *    backwards compatibility while also allowing for new functionality to be
+ *    implemented.
+ */
+
+typedef
+struct {
+   uint32 suffixSize;
+
+   /*
+    * The maximum offset is used to determine the maximum offset from the
+    * guestPtr base address that will be accessed or written to during this
+    * surfaceDMA.  If the suffix is supported, the host will respect this
+    * boundary while performing surface DMAs.
+    *
+    * Defaults to MAX_UINT32
+    */
+   uint32 maximumOffset;
+
+   /*
+    * A set of flags that describes optimizations that the host may perform
+    * while performing this surface DMA operation.  The guest should never rely
+    * on behaviour that is different when these flags are set for correctness.
+    *
+    * Defaults to 0
+    */
+   SVGA3dSurfaceDMAFlags flags;
+} SVGA3dCmdSurfaceDMASuffix;
+
+/*
+ * SVGA_3D_CMD_DRAW_PRIMITIVES --
+ *
+ *   This command is the SVGA3D device's generic drawing entry point.
+ *   It can draw multiple ranges of primitives, optionally using an
+ *   index buffer, using an arbitrary collection of vertex buffers.
+ *
+ *   Each SVGA3dVertexDecl defines a distinct vertex array to bind
+ *   during this draw call. The declarations specify which surface
+ *   the vertex data lives in, what that vertex data is used for,
+ *   and how to interpret it.
+ *
+ *   Each SVGA3dPrimitiveRange defines a collection of primitives
+ *   to render using the same vertex arrays. An index buffer is
+ *   optional.
+ */
+
+typedef
+struct {
+   /*
+    * A range hint is an optional specification for the range of indices
+    * in an SVGA3dArray that will be used. If 'last' is zero, it is assumed
+    * that the entire array will be used.
+    *
+    * These are only hints. The SVGA3D device may use them for
+    * performance optimization if possible, but it's also allowed to
+    * ignore these values.
+    */
+   uint32               first;
+   uint32               last;
+} SVGA3dArrayRangeHint;
+
+typedef
+struct {
+   /*
+    * Define the origin and shape of a vertex or index array. Both
+    * 'offset' and 'stride' are in bytes. The provided surface will be
+    * reinterpreted as a flat array of bytes in the same format used
+    * by surface DMA operations. To avoid unnecessary conversions, the
+    * surface should be created with the SVGA3D_BUFFER format.
+    *
+    * Index 0 in the array starts 'offset' bytes into the surface.
+    * Index 1 begins at byte 'offset + stride', etc. Array indices may
+    * not be negative.
+    */
+   uint32               surfaceId;
+   uint32               offset;
+   uint32               stride;
+} SVGA3dArray;
+
+typedef
+struct {
+   /*
+    * Describe a vertex array's data type, and define how it is to be
+    * used by the fixed function pipeline or the vertex shader. It
+    * isn't useful to have two VertexDecls with the same
+    * VertexArrayIdentity in one draw call.
+    */
+   SVGA3dDeclType       type;
+   SVGA3dDeclMethod     method;
+   SVGA3dDeclUsage      usage;
+   uint32               usageIndex;
+} SVGA3dVertexArrayIdentity;
+
+typedef
+struct {
+   SVGA3dVertexArrayIdentity  identity;
+   SVGA3dArray                array;
+   SVGA3dArrayRangeHint       rangeHint;
+} SVGA3dVertexDecl;
+
+typedef
+struct {
+   /*
+    * Define a group of primitives to render, from sequential indices.
+    *
+    * The value of 'primitiveType' and 'primitiveCount' imply the
+    * total number of vertices that will be rendered.
+    */
+   SVGA3dPrimitiveType  primType;
+   uint32               primitiveCount;
+
+   /*
+    * Optional index buffer. If indexArray.surfaceId is
+    * SVGA3D_INVALID_ID, we render without an index buffer. Rendering
+    * without an index buffer is identical to rendering with an index
+    * buffer containing the sequence [0, 1, 2, 3, ...].
+    *
+    * If an index buffer is in use, indexWidth specifies the width in
+    * bytes of each index value. It must be less than or equal to
+    * indexArray.stride.
+    *
+    * (Currently, the SVGA3D device requires index buffers to be tightly
+    * packed. In other words, indexWidth == indexArray.stride)
+    */
+   SVGA3dArray          indexArray;
+   uint32               indexWidth;
+
+   /*
+    * Optional index bias. This number is added to all indices from
+    * indexArray before they are used as vertex array indices. This
+    * can be used in multiple ways:
+    *
+    *  - When not using an indexArray, this bias can be used to
+    *    specify where in the vertex arrays to begin rendering.
+    *
+    *  - A positive number here is equivalent to increasing the
+    *    offset in each vertex array.
+    *
+    *  - A negative number can be used to render using a small
+    *    vertex array and an index buffer that contains large
+    *    values. This may be used by some applications that
+    *    crop a vertex buffer without modifying their index
+    *    buffer.
+    *
+    * Note that rendering with a negative bias value may be slower and
+    * use more memory than rendering with a positive or zero bias.
+    */
+   int32                indexBias;
+} SVGA3dPrimitiveRange;
+
+typedef
+struct {
+   uint32               cid;
+   uint32               numVertexDecls;
+   uint32               numRanges;
+
+   /*
+    * There are two variable size arrays after the
+    * SVGA3dCmdDrawPrimitives structure. In order,
+    * they are:
+    *
+    * 1. SVGA3dVertexDecl, quantity 'numVertexDecls'
+    * 2. SVGA3dPrimitiveRange, quantity 'numRanges'
+    * 3. Optionally, SVGA3dVertexDivisor, quantity 'numVertexDecls' (contains
+    *    the frequency divisor for this the corresponding vertex decl)
+    */
+} SVGA3dCmdDrawPrimitives;      /* SVGA_3D_CMD_DRAWPRIMITIVES */
+
+typedef
+struct {
+   uint32                   stage;
+   SVGA3dTextureStateName   name;
+   union {
+      uint32                value;
+      float                 floatValue;
+   };
+} SVGA3dTextureState;
+
+typedef
+struct {
+   uint32               cid;
+   /* Followed by variable number of SVGA3dTextureState structures */
+} SVGA3dCmdSetTextureState;      /* SVGA_3D_CMD_SETTEXTURESTATE */
+
+typedef
+struct {
+   uint32                   cid;
+   SVGA3dTransformType      type;
+   float                    matrix[16];
+} SVGA3dCmdSetTransform;          /* SVGA_3D_CMD_SETTRANSFORM */
+
+typedef
+struct {
+   float                min;
+   float                max;
+} SVGA3dZRange;
+
+typedef
+struct {
+   uint32               cid;
+   SVGA3dZRange         zRange;
+} SVGA3dCmdSetZRange;             /* SVGA_3D_CMD_SETZRANGE */
+
+typedef
+struct {
+   float                diffuse[4];
+   float                ambient[4];
+   float                specular[4];
+   float                emissive[4];
+   float                shininess;
+} SVGA3dMaterial;
+
+typedef
+struct {
+   uint32               cid;
+   SVGA3dFace           face;
+   SVGA3dMaterial       material;
+} SVGA3dCmdSetMaterial;           /* SVGA_3D_CMD_SETMATERIAL */
+
+typedef
+struct {
+   uint32               cid;
+   uint32               index;
+   SVGA3dLightData      data;
+} SVGA3dCmdSetLightData;           /* SVGA_3D_CMD_SETLIGHTDATA */
+
+typedef
+struct {
+   uint32               cid;
+   uint32               index;
+   uint32               enabled;
+} SVGA3dCmdSetLightEnabled;      /* SVGA_3D_CMD_SETLIGHTENABLED */
+
+typedef
+struct {
+   uint32               cid;
+   SVGA3dRect           rect;
+} SVGA3dCmdSetViewport;           /* SVGA_3D_CMD_SETVIEWPORT */
+
+typedef
+struct {
+   uint32               cid;
+   SVGA3dRect           rect;
+} SVGA3dCmdSetScissorRect;         /* SVGA_3D_CMD_SETSCISSORRECT */
+
+typedef
+struct {
+   uint32               cid;
+   uint32               index;
+   float                plane[4];
+} SVGA3dCmdSetClipPlane;           /* SVGA_3D_CMD_SETCLIPPLANE */
+
+typedef
+struct {
+   uint32               cid;
+   uint32               shid;
+   SVGA3dShaderType     type;
+   /* Followed by variable number of DWORDs for shader bycode */
+} SVGA3dCmdDefineShader;           /* SVGA_3D_CMD_SHADER_DEFINE */
+
+typedef
+struct {
+   uint32               cid;
+   uint32               shid;
+   SVGA3dShaderType     type;
+} SVGA3dCmdDestroyShader;         /* SVGA_3D_CMD_SHADER_DESTROY */
+
+typedef
+struct {
+   uint32                  cid;
+   uint32                  reg;     /* register number */
+   SVGA3dShaderType        type;
+   SVGA3dShaderConstType   ctype;
+   uint32                  values[4];
+} SVGA3dCmdSetShaderConst;        /* SVGA_3D_CMD_SET_SHADER_CONST */
+
+typedef
+struct {
+   uint32               cid;
+   SVGA3dShaderType     type;
+   uint32               shid;
+} SVGA3dCmdSetShader;             /* SVGA_3D_CMD_SET_SHADER */
+
+typedef
+struct {
+   uint32               cid;
+   SVGA3dQueryType      type;
+} SVGA3dCmdBeginQuery;           /* SVGA_3D_CMD_BEGIN_QUERY */
+
+typedef
+struct {
+   uint32               cid;
+   SVGA3dQueryType      type;
+   SVGAGuestPtr         guestResult;  /* Points to an SVGA3dQueryResult structure */
+} SVGA3dCmdEndQuery;                  /* SVGA_3D_CMD_END_QUERY */
+
+typedef
+struct {
+   uint32               cid;          /* Same parameters passed to END_QUERY */
+   SVGA3dQueryType      type;
+   SVGAGuestPtr         guestResult;
+} SVGA3dCmdWaitForQuery;              /* SVGA_3D_CMD_WAIT_FOR_QUERY */
+
+typedef
+struct {
+   uint32               totalSize;    /* Set by guest before query is ended. */
+   SVGA3dQueryState     state;        /* Set by host or guest. See SVGA3dQueryState. */
+   union {                            /* Set by host on exit from PENDING state */
+      uint32            result32;
+   };
+} SVGA3dQueryResult;
+
+/*
+ * SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN --
+ *
+ *    This is a blit from an SVGA3D surface to a Screen Object. Just
+ *    like GMR-to-screen blits, this blit may be directed at a
+ *    specific screen or to the virtual coordinate space.
+ *
+ *    The blit copies from a rectangular region of an SVGA3D surface
+ *    image to a rectangular region of a screen or screens.
+ *
+ *    This command takes an optional variable-length list of clipping
+ *    rectangles after the body of the command. If no rectangles are
+ *    specified, there is no clipping region. The entire destRect is
+ *    drawn to. If one or more rectangles are included, they describe
+ *    a clipping region. The clip rectangle coordinates are measured
+ *    relative to the top-left corner of destRect.
+ *
+ *    This clipping region serves multiple purposes:
+ *
+ *      - It can be used to perform an irregularly shaped blit more
+ *        efficiently than by issuing many separate blit commands.
+ *
+ *      - It is equivalent to allowing blits with non-integer
+ *        source coordinates. You could blit just one half-pixel
+ *        of a source, for example, by specifying a larger
+ *        destination rectangle than you need, then removing
+ *        part of it using a clip rectangle.
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT
+ *
+ * Limitations:
+ *
+ *    - Currently, no backend supports blits from a mipmap or face
+ *      other than the first one.
+ */
+
+typedef
+struct {
+   SVGA3dSurfaceImageId srcImage;
+   SVGASignedRect       srcRect;
+   uint32               destScreenId; /* Screen ID or SVGA_ID_INVALID for virt. coords */
+   SVGASignedRect       destRect;     /* Supports scaling if src/rest different size */
+   /* Clipping: zero or more SVGASignedRects follow */
+} SVGA3dCmdBlitSurfaceToScreen;         /* SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN */
+
+
+/*
+ * Capability query index.
+ *
+ * Notes:
+ *
+ *   1. SVGA3D_DEVCAP_MAX_TEXTURES reflects the maximum number of
+ *      fixed-function texture units available. Each of these units
+ *      work in both FFP and Shader modes, and they support texture
+ *      transforms and texture coordinates. The host may have additional
+ *      texture image units that are only usable with shaders.
+ *
+ *   2. The BUFFER_FORMAT capabilities are deprecated, and they always
+ *      return TRUE. Even on physical hardware that does not support
+ *      these formats natively, the SVGA3D device will provide an emulation
+ *      which should be invisible to the guest OS.
+ *
+ *      In general, the SVGA3D device should support any operation on
+ *      any surface format, it just may perform some of these
+ *      operations in software depending on the capabilities of the
+ *      available physical hardware.
+ *
+ *      XXX: In the future, we will add capabilities that describe in
+ *      detail what formats are supported in hardware for what kinds
+ *      of operations.
+ */
+
+typedef enum {
+   SVGA3D_DEVCAP_3D                                = 0,
+   SVGA3D_DEVCAP_MAX_LIGHTS                        = 1,
+   SVGA3D_DEVCAP_MAX_TEXTURES                      = 2,  /* See note (1) */
+   SVGA3D_DEVCAP_MAX_CLIP_PLANES                   = 3,
+   SVGA3D_DEVCAP_VERTEX_SHADER_VERSION             = 4,
+   SVGA3D_DEVCAP_VERTEX_SHADER                     = 5,
+   SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION           = 6,
+   SVGA3D_DEVCAP_FRAGMENT_SHADER                   = 7,
+   SVGA3D_DEVCAP_MAX_RENDER_TARGETS                = 8,
+   SVGA3D_DEVCAP_S23E8_TEXTURES                    = 9,
+   SVGA3D_DEVCAP_S10E5_TEXTURES                    = 10,
+   SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND             = 11,
+   SVGA3D_DEVCAP_D16_BUFFER_FORMAT                 = 12, /* See note (2) */
+   SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT               = 13, /* See note (2) */
+   SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT               = 14, /* See note (2) */
+   SVGA3D_DEVCAP_QUERY_TYPES                       = 15,
+   SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING         = 16,
+   SVGA3D_DEVCAP_MAX_POINT_SIZE                    = 17,
+   SVGA3D_DEVCAP_MAX_SHADER_TEXTURES               = 18,
+   SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH                 = 19,
+   SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT                = 20,
+   SVGA3D_DEVCAP_MAX_VOLUME_EXTENT                 = 21,
+   SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT                = 22,
+   SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO          = 23,
+   SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY            = 24,
+   SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT               = 25,
+   SVGA3D_DEVCAP_MAX_VERTEX_INDEX                  = 26,
+   SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS    = 27,
+   SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS  = 28,
+   SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS           = 29,
+   SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS         = 30,
+   SVGA3D_DEVCAP_TEXTURE_OPS                       = 31,
+   SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8               = 32,
+   SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8               = 33,
+   SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10            = 34,
+   SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5               = 35,
+   SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5               = 36,
+   SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4               = 37,
+   SVGA3D_DEVCAP_SURFACEFMT_R5G6B5                 = 38,
+   SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16            = 39,
+   SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8      = 40,
+   SVGA3D_DEVCAP_SURFACEFMT_ALPHA8                 = 41,
+   SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8             = 42,
+   SVGA3D_DEVCAP_SURFACEFMT_Z_D16                  = 43,
+   SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8                = 44,
+   SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8                = 45,
+   SVGA3D_DEVCAP_SURFACEFMT_DXT1                   = 46,
+   SVGA3D_DEVCAP_SURFACEFMT_DXT2                   = 47,
+   SVGA3D_DEVCAP_SURFACEFMT_DXT3                   = 48,
+   SVGA3D_DEVCAP_SURFACEFMT_DXT4                   = 49,
+   SVGA3D_DEVCAP_SURFACEFMT_DXT5                   = 50,
+   SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8           = 51,
+   SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10            = 52,
+   SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8               = 53,
+   SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8               = 54,
+   SVGA3D_DEVCAP_SURFACEFMT_CxV8U8                 = 55,
+   SVGA3D_DEVCAP_SURFACEFMT_R_S10E5                = 56,
+   SVGA3D_DEVCAP_SURFACEFMT_R_S23E8                = 57,
+   SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5               = 58,
+   SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8               = 59,
+   SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5             = 60,
+   SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8             = 61,
+   SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES        = 63,
+
+   /*
+    * Note that MAX_SIMULTANEOUS_RENDER_TARGETS is a maximum count of color
+    * render targets.  This does no include the depth or stencil targets.
+    */
+   SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS   = 64,
+
+   SVGA3D_DEVCAP_SURFACEFMT_V16U16                 = 65,
+   SVGA3D_DEVCAP_SURFACEFMT_G16R16                 = 66,
+   SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16           = 67,
+   SVGA3D_DEVCAP_SURFACEFMT_UYVY                   = 68,
+   SVGA3D_DEVCAP_SURFACEFMT_YUY2                   = 69,
+
+   /*
+    * Don't add new caps into the previous section; the values in this
+    * enumeration must not change. You can put new values right before
+    * SVGA3D_DEVCAP_MAX.
+    */
+   SVGA3D_DEVCAP_MAX                                  /* This must be the last index. */
+} SVGA3dDevCapIndex;
+
+typedef union {
+   Bool   b;
+   uint32 u;
+   int32  i;
+   float  f;
+} SVGA3dDevCapResult;
+
+#endif /* _SVGA3D_REG_H_ */
diff --git a/src/gallium/drivers/svga/include/svga3d_shaderdefs.h b/src/gallium/drivers/svga/include/svga3d_shaderdefs.h
new file mode 100644
index 0000000..2078c4a
--- /dev/null
+++ b/src/gallium/drivers/svga/include/svga3d_shaderdefs.h
@@ -0,0 +1,519 @@
+/**********************************************************
+ * Copyright 2007-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+/*
+ * svga3d_shaderdefs.h --
+ *
+ * SVGA3D byte code format and limit definitions.
+ *
+ * The format of the byte code directly corresponds to that defined
+ * by Microsoft DirectX SDK 9.0c (file d3d9types.h). The format can
+ * also be extended so that different shader formats can be supported
+ * for example GLSL, ARB vp/fp, NV/ATI shader formats, etc.
+ *
+ */
+
+#ifndef __SVGA3D_SHADER_DEFS__
+#define __SVGA3D_SHADER_DEFS__
+
+/* SVGA3D shader hardware limits. */
+
+#define SVGA3D_INPUTREG_MAX            16
+#define SVGA3D_OUTPUTREG_MAX           12
+#define SVGA3D_VERTEX_SAMPLERREG_MAX   4
+#define SVGA3D_PIXEL_SAMPLERREG_MAX    16
+#define SVGA3D_SAMPLERREG_MAX          (SVGA3D_PIXEL_SAMPLERREG_MAX+\
+                                        SVGA3D_VERTEX_SAMPLERREG_MAX)
+#define SVGA3D_TEMPREG_MAX             32
+#define SVGA3D_CONSTREG_MAX            256
+#define SVGA3D_CONSTINTREG_MAX         16
+#define SVGA3D_CONSTBOOLREG_MAX        16
+#define SVGA3D_ADDRREG_MAX             1
+#define SVGA3D_PREDREG_MAX             1
+
+/* SVGA3D byte code specific limits */
+
+#define SVGA3D_MAX_SRC_REGS      4
+#define SVGA3D_MAX_NESTING_LEVEL 32
+
+/* SVGA3D version information. */
+
+#define SVGA3D_VS_TYPE  0xFFFE
+#define SVGA3D_PS_TYPE  0xFFFF
+
+typedef struct {
+   union {
+      struct {
+         uint32 minor : 8;
+         uint32 major : 8;
+         uint32 type : 16;
+      };
+
+      uint32 value;
+   };
+} SVGA3dShaderVersion;
+
+#define SVGA3D_VS_10 ((SVGA3D_VS_TYPE << 16) | 1 << 8)
+#define SVGA3D_VS_11 (SVGA3D_VS_10 | 1)
+#define SVGA3D_VS_20 ((SVGA3D_VS_TYPE << 16) | 2 << 8)
+#define SVGA3D_VS_30 ((SVGA3D_VS_TYPE << 16) | 3 << 8)
+
+#define SVGA3D_PS_10 ((SVGA3D_PS_TYPE << 16) | 1 << 8)
+#define SVGA3D_PS_11 (SVGA3D_PS_10 | 1)
+#define SVGA3D_PS_12 (SVGA3D_PS_10 | 2)
+#define SVGA3D_PS_13 (SVGA3D_PS_10 | 3)
+#define SVGA3D_PS_14 (SVGA3D_PS_10 | 4)
+#define SVGA3D_PS_20 ((SVGA3D_PS_TYPE << 16) | 2 << 8)
+#define SVGA3D_PS_30 ((SVGA3D_PS_TYPE << 16) | 3 << 8)
+
+/* The *_ENABLED are for backwards compatibility with old drivers */
+typedef enum {
+   SVGA3DPSVERSION_NONE = 0,
+   SVGA3DPSVERSION_ENABLED = 1,
+   SVGA3DPSVERSION_11 = 3,
+   SVGA3DPSVERSION_12 = 5,
+   SVGA3DPSVERSION_13 = 7,
+   SVGA3DPSVERSION_14 = 9,
+   SVGA3DPSVERSION_20 = 11,
+   SVGA3DPSVERSION_30 = 13,
+   SVGA3DPSVERSION_40 = 15,
+   SVGA3DPSVERSION_MAX
+} SVGA3dPixelShaderVersion;
+
+typedef enum {
+   SVGA3DVSVERSION_NONE = 0,
+   SVGA3DVSVERSION_ENABLED = 1,
+   SVGA3DVSVERSION_11 = 3,
+   SVGA3DVSVERSION_20 = 5,
+   SVGA3DVSVERSION_30 = 7,
+   SVGA3DVSVERSION_40 = 9,
+   SVGA3DVSVERSION_MAX
+} SVGA3dVertexShaderVersion;
+
+/* SVGA3D instruction op codes. */
+
+typedef enum {
+   SVGA3DOP_NOP = 0,
+   SVGA3DOP_MOV,
+   SVGA3DOP_ADD,
+   SVGA3DOP_SUB,
+   SVGA3DOP_MAD,
+   SVGA3DOP_MUL,
+   SVGA3DOP_RCP,
+   SVGA3DOP_RSQ,
+   SVGA3DOP_DP3,
+   SVGA3DOP_DP4,
+   SVGA3DOP_MIN,
+   SVGA3DOP_MAX,
+   SVGA3DOP_SLT,
+   SVGA3DOP_SGE,
+   SVGA3DOP_EXP,
+   SVGA3DOP_LOG,
+   SVGA3DOP_LIT,
+   SVGA3DOP_DST,
+   SVGA3DOP_LRP,
+   SVGA3DOP_FRC,
+   SVGA3DOP_M4x4,
+   SVGA3DOP_M4x3,
+   SVGA3DOP_M3x4,
+   SVGA3DOP_M3x3,
+   SVGA3DOP_M3x2,
+   SVGA3DOP_CALL,
+   SVGA3DOP_CALLNZ,
+   SVGA3DOP_LOOP,
+   SVGA3DOP_RET,
+   SVGA3DOP_ENDLOOP,
+   SVGA3DOP_LABEL,
+   SVGA3DOP_DCL,
+   SVGA3DOP_POW,
+   SVGA3DOP_CRS,
+   SVGA3DOP_SGN,
+   SVGA3DOP_ABS,
+   SVGA3DOP_NRM,
+   SVGA3DOP_SINCOS,
+   SVGA3DOP_REP,
+   SVGA3DOP_ENDREP,
+   SVGA3DOP_IF,
+   SVGA3DOP_IFC,
+   SVGA3DOP_ELSE,
+   SVGA3DOP_ENDIF,
+   SVGA3DOP_BREAK,
+   SVGA3DOP_BREAKC,
+   SVGA3DOP_MOVA,
+   SVGA3DOP_DEFB,
+   SVGA3DOP_DEFI,
+   SVGA3DOP_TEXCOORD = 64,
+   SVGA3DOP_TEXKILL,
+   SVGA3DOP_TEX,
+   SVGA3DOP_TEXBEM,
+   SVGA3DOP_TEXBEML,
+   SVGA3DOP_TEXREG2AR,
+   SVGA3DOP_TEXREG2GB = 70,
+   SVGA3DOP_TEXM3x2PAD,
+   SVGA3DOP_TEXM3x2TEX,
+   SVGA3DOP_TEXM3x3PAD,
+   SVGA3DOP_TEXM3x3TEX,
+   SVGA3DOP_RESERVED0,
+   SVGA3DOP_TEXM3x3SPEC,
+   SVGA3DOP_TEXM3x3VSPEC,
+   SVGA3DOP_EXPP,
+   SVGA3DOP_LOGP,
+   SVGA3DOP_CND = 80,
+   SVGA3DOP_DEF,
+   SVGA3DOP_TEXREG2RGB,
+   SVGA3DOP_TEXDP3TEX,
+   SVGA3DOP_TEXM3x2DEPTH,
+   SVGA3DOP_TEXDP3,
+   SVGA3DOP_TEXM3x3,
+   SVGA3DOP_TEXDEPTH,
+   SVGA3DOP_CMP,
+   SVGA3DOP_BEM,
+   SVGA3DOP_DP2ADD = 90,
+   SVGA3DOP_DSX,
+   SVGA3DOP_DSY,
+   SVGA3DOP_TEXLDD,
+   SVGA3DOP_SETP,
+   SVGA3DOP_TEXLDL,
+   SVGA3DOP_BREAKP = 96,
+   SVGA3DOP_LAST_INST,
+   SVGA3DOP_PHASE = 0xFFFD,
+   SVGA3DOP_COMMENT = 0xFFFE,
+   SVGA3DOP_END = 0xFFFF,
+} SVGA3dShaderOpCodeType;
+
+/* SVGA3D operation control/comparison function types */
+
+typedef enum {
+   SVGA3DOPCONT_NONE,
+   SVGA3DOPCONT_PROJECT,   /* Projective texturing */
+   SVGA3DOPCONT_BIAS,      /* Texturing with a LOD bias */
+} SVGA3dShaderOpCodeControlFnType;
+
+typedef enum {
+   SVGA3DOPCOMP_RESERVED0 = 0,
+   SVGA3DOPCOMP_GT,
+   SVGA3DOPCOMP_EQ,
+   SVGA3DOPCOMP_GE,
+   SVGA3DOPCOMP_LT,
+   SVGA3DOPCOMPC_NE,
+   SVGA3DOPCOMP_LE,
+   SVGA3DOPCOMP_RESERVED1
+} SVGA3dShaderOpCodeCompFnType;
+
+/* SVGA3D register types */
+
+typedef enum {
+    SVGA3DREG_TEMP = 0,       /* Temporary register file */
+    SVGA3DREG_INPUT,          /* Input register file */
+    SVGA3DREG_CONST,          /* Constant register file */
+    SVGA3DREG_ADDR,           /* Address register for VS */
+    SVGA3DREG_TEXTURE = 3,    /* Texture register file for PS */
+    SVGA3DREG_RASTOUT,        /* Rasterizer register file */
+    SVGA3DREG_ATTROUT,        /* Attribute output register file */
+    SVGA3DREG_TEXCRDOUT,      /* Texture coordinate output register file */
+    SVGA3DREG_OUTPUT = 6,     /* Output register file for VS 3.0+ */
+    SVGA3DREG_CONSTINT,       /* Constant integer vector register file */
+    SVGA3DREG_COLOROUT,       /* Color output register file */
+    SVGA3DREG_DEPTHOUT,       /* Depth output register file */
+    SVGA3DREG_SAMPLER,        /* Sampler state register file */
+    SVGA3DREG_CONST2,         /* Constant register file 2048 - 4095 */
+    SVGA3DREG_CONST3,         /* Constant register file 4096 - 6143 */
+    SVGA3DREG_CONST4,         /* Constant register file 6144 - 8191 */
+    SVGA3DREG_CONSTBOOL,      /* Constant boolean register file */
+    SVGA3DREG_LOOP,           /* Loop counter register file */
+    SVGA3DREG_TEMPFLOAT16,    /* 16-bit float temp register file */
+    SVGA3DREG_MISCTYPE,       /* Miscellaneous (single) registers */
+    SVGA3DREG_LABEL,          /* Label */
+    SVGA3DREG_PREDICATE,      /* Predicate register */
+} SVGA3dShaderRegType;
+
+/* SVGA3D rasterizer output register types */
+
+typedef enum {
+   SVGA3DRASTOUT_POSITION = 0,
+   SVGA3DRASTOUT_FOG,
+   SVGA3DRASTOUT_PSIZE
+} SVGA3dShaderRastOutRegType;
+
+/* SVGA3D miscellaneous register types */
+
+typedef enum {
+   SVGA3DMISCREG_POSITION = 0,   /* Input position x,y,z,rhw (PS) */
+   SVGA3DMISCREG_FACE            /* Floating point primitive area (PS) */
+} SVGA3DShaderMiscRegType;
+
+/* SVGA3D sampler types */
+
+typedef enum {
+   SVGA3DSAMP_UNKNOWN = 0, /* Uninitialized value */
+   SVGA3DSAMP_2D = 2,      /* dcl_2d s# (for declaring a 2-D texture) */
+   SVGA3DSAMP_CUBE,        /* dcl_cube s# (for declaring a cube texture) */
+   SVGA3DSAMP_VOLUME,      /* dcl_volume s# (for declaring a volume texture) */
+} SVGA3dShaderSamplerType;
+
+/* SVGA3D sampler format classes */
+
+typedef enum {
+   SVGA3DSAMPFORMAT_ARGB,        /* ARGB formats */
+   SVGA3DSAMPFORMAT_V8U8,        /* Sign and normalize (SNORM) V & U */
+   SVGA3DSAMPFORMAT_Q8W8V8U8,    /* SNORM all */
+   SVGA3DSAMPFORMAT_CxV8U8,      /* SNORM V & U, C=SQRT(1-U^2-V^2) */
+   SVGA3DSAMPFORMAT_X8L8V8U8,    /* SNORM V & U */
+   SVGA3DSAMPFORMAT_A2W10V10U10, /* SNORM W, V & U */
+   SVGA3DSAMPFORMAT_DXT_PMA,     /* DXT pre-multiplied alpha */
+   SVGA3DSAMPFORMAT_YUV,         /* YUV video format */
+   SVGA3DSAMPFORMAT_UYVY,        /* UYVY video format */
+   SVGA3DSAMPFORMAT_Rx,          /* R16F/32F */
+   SVGA3DSAMPFORMAT_RxGx,        /* R16FG16F, R32FG32F */
+   SVGA3DSAMPFORMAT_V16U16,      /* SNORM all */
+} SVGA3DShaderSamplerFormatClass;
+
+/* SVGA3D write mask */
+
+#define SVGA3DWRITEMASK_0    1 /* Component 0 (X;Red) */
+#define SVGA3DWRITEMASK_1    2 /* Component 1 (Y;Green) */
+#define SVGA3DWRITEMASK_2    4 /* Component 2 (Z;Blue) */
+#define SVGA3DWRITEMASK_3    8 /* Component 3 (W;Alpha) */
+#define SVGA3DWRITEMASK_ALL 15 /* All components */
+
+/* SVGA3D destination modifiers */
+
+#define SVGA3DDSTMOD_NONE              0 /* nop */
+#define SVGA3DDSTMOD_SATURATE          1 /* clamp to [0, 1] */
+#define SVGA3DDSTMOD_PARTIALPRECISION  2 /* Partial precision hint */
+
+/*
+ * Relevant to multisampling only:
+ * When the pixel center is not covered, sample
+ * attribute or compute gradients/LOD
+ * using multisample "centroid" location.
+ * "Centroid" is some location within the covered
+ * region of the pixel.
+ */
+
+#define SVGA3DDSTMOD_MSAMPCENTROID     4
+
+/* SVGA3D source swizzle */
+
+#define SVGA3DSWIZZLE_REPLICATEX 0x00
+#define SVGA3DSWIZZLE_REPLICATEY 0x55
+#define SVGA3DSWIZZLE_REPLICATEZ 0xAA
+#define SVGA3DSWIZZLE_REPLICATEW 0xFF
+#define SVGA3DSWIZZLE_NONE       0xE4
+#define SVGA3DSWIZZLE_YZXW       0xC9
+#define SVGA3DSWIZZLE_ZXYW       0xD2
+#define SVGA3DSWIZZLE_WXYZ       0x1B
+
+/* SVGA3D source modifiers */
+
+typedef enum {
+    SVGA3DSRCMOD_NONE = 0, /* nop */
+    SVGA3DSRCMOD_NEG,      /* negate */
+    SVGA3DSRCMOD_BIAS,     /* bias */
+    SVGA3DSRCMOD_BIASNEG,  /* bias and negate */
+    SVGA3DSRCMOD_SIGN,     /* sign */
+    SVGA3DSRCMOD_SIGNNEG,  /* sign and negate */
+    SVGA3DSRCMOD_COMP,     /* complement */
+    SVGA3DSRCMOD_X2,       /* x2 */
+    SVGA3DSRCMOD_X2NEG,    /* x2 and negate */
+    SVGA3DSRCMOD_DZ,       /* divide through by z component */
+    SVGA3DSRCMOD_DW,       /* divide through by w component */
+    SVGA3DSRCMOD_ABS,      /* abs() */
+    SVGA3DSRCMOD_ABSNEG,   /* -abs() */
+    SVGA3DSRCMOD_NOT,      /* ! (for predicate register) */
+} SVGA3dShaderSrcModType;
+
+/* SVGA3D instruction token */
+
+typedef struct {
+   union {
+      struct {
+         uint32 comment_op : 16;
+         uint32 comment_size : 16;
+      };
+
+      struct {
+         uint32 op : 16;
+         uint32 control : 3;
+         uint32 reserved2 : 5;
+         uint32 size : 4;
+         uint32 predicated : 1;
+         uint32 reserved1 : 1;
+         uint32 coissue : 1;
+         uint32 reserved0 : 1;
+      };
+
+      uint32 value;
+   };
+} SVGA3dShaderInstToken;
+
+/* SVGA3D destination parameter token */
+
+typedef struct {
+   union {
+      struct {
+         uint32 num : 11;
+         uint32 type_upper : 2;
+         uint32 relAddr : 1;
+         uint32 reserved1 : 2;
+         uint32 mask : 4;
+         uint32 dstMod : 4;
+         uint32 shfScale : 4;
+         uint32 type_lower : 3;
+         uint32 reserved0 : 1;
+      };
+
+      uint32 value;
+   };
+} SVGA3dShaderDestToken;
+
+/* SVGA3D source parameter token */
+
+typedef struct {
+   union {
+      struct {
+         uint32 num : 11;
+         uint32 type_upper : 2;
+         uint32 relAddr : 1;
+         uint32 reserved1 : 2;
+         uint32 swizzle : 8;
+         uint32 srcMod : 4;
+         uint32 type_lower : 3;
+         uint32 reserved0 : 1;
+      };
+
+      uint32 value;
+   };
+} SVGA3dShaderSrcToken;
+
+/* SVGA3DOP_DCL parameter tokens */
+
+typedef struct {
+   union {
+      struct {
+         union {
+            struct {
+               uint32 usage : 5;
+               uint32 reserved1 : 11;
+               uint32 index : 4;
+               uint32 reserved0 : 12;
+            }; /* input / output declaration */
+
+            struct {
+               uint32 reserved3 : 27;
+               uint32 type : 4;
+               uint32 reserved2 : 1;
+            }; /* sampler declaration */
+         };
+
+         SVGA3dShaderDestToken dst;
+      };
+
+      uint32 values[2];
+   };
+} SVGA3DOpDclArgs;
+
+/* SVGA3DOP_DEF parameter tokens */
+
+typedef struct {
+   union {
+      struct {
+         SVGA3dShaderDestToken dst;
+
+         union {
+            float constValues[4];
+            int constIValues[4];
+            Bool constBValue;
+         };
+      };
+
+      uint32 values[5];
+   };
+} SVGA3DOpDefArgs;
+
+/* SVGA3D shader token */
+
+typedef union {
+   uint32 value;
+   SVGA3dShaderInstToken inst;
+   SVGA3dShaderDestToken dest;
+   SVGA3dShaderSrcToken src;
+} SVGA3dShaderToken;
+
+/* SVGA3D shader program */
+
+typedef struct {
+   SVGA3dShaderVersion version;
+   /* SVGA3dShaderToken stream */
+} SVGA3dShaderProgram;
+
+/* SVGA3D version specific register assignments */
+
+static const uint32 SVGA3D_INPUT_REG_POSITION_VS11 = 0;
+static const uint32 SVGA3D_INPUT_REG_PSIZE_VS11 = 1;
+static const uint32 SVGA3D_INPUT_REG_FOG_VS11 = 3;
+static const uint32 SVGA3D_INPUT_REG_FOG_MASK_VS11 = SVGA3DWRITEMASK_3;
+static const uint32 SVGA3D_INPUT_REG_COLOR_BASE_VS11 = 2;
+static const uint32 SVGA3D_INPUT_REG_TEXCOORD_BASE_VS11 = 4;
+
+static const uint32 SVGA3D_INPUT_REG_COLOR_BASE_PS11 = 0;
+static const uint32 SVGA3D_INPUT_REG_TEXCOORD_BASE_PS11 = 2;
+static const uint32 SVGA3D_OUTPUT_REG_DEPTH_PS11 = 0;
+static const uint32 SVGA3D_OUTPUT_REG_COLOR_PS11 = 1;
+
+static const uint32 SVGA3D_INPUT_REG_COLOR_BASE_PS20 = 0;
+static const uint32 SVGA3D_INPUT_REG_COLOR_NUM_PS20 = 2;
+static const uint32 SVGA3D_INPUT_REG_TEXCOORD_BASE_PS20 = 2;
+static const uint32 SVGA3D_INPUT_REG_TEXCOORD_NUM_PS20 = 8;
+static const uint32 SVGA3D_OUTPUT_REG_COLOR_BASE_PS20 = 1;
+static const uint32 SVGA3D_OUTPUT_REG_COLOR_NUM_PS20 = 4;
+static const uint32 SVGA3D_OUTPUT_REG_DEPTH_BASE_PS20 = 0;
+static const uint32 SVGA3D_OUTPUT_REG_DEPTH_NUM_PS20 = 1;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3dShaderGetRegType --
+ *
+ *      As the register type is split into two non sequential fields,
+ *      this function provides an useful way of accessing the actual
+ *      register type without having to manually concatenate the
+ *      type_upper and type_lower fields.
+ *
+ * Results:
+ *      Returns the register type.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static INLINE SVGA3dShaderRegType
+SVGA3dShaderGetRegType(uint32 token)
+{
+   SVGA3dShaderSrcToken src;
+   src.value = token;
+   return (SVGA3dShaderRegType)(src.type_upper << 3 | src.type_lower);
+}
+
+#endif /* __SVGA3D_SHADER_DEFS__ */
diff --git a/src/gallium/drivers/svga/include/svga_escape.h b/src/gallium/drivers/svga/include/svga_escape.h
new file mode 100644
index 0000000..7b85e9b
--- /dev/null
+++ b/src/gallium/drivers/svga/include/svga_escape.h
@@ -0,0 +1,89 @@
+/**********************************************************
+ * Copyright 2007-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+/*
+ * svga_escape.h --
+ *
+ *    Definitions for our own (vendor-specific) SVGA Escape commands.
+ */
+
+#ifndef _SVGA_ESCAPE_H_
+#define _SVGA_ESCAPE_H_
+
+
+/*
+ * Namespace IDs for the escape command
+ */
+
+#define SVGA_ESCAPE_NSID_VMWARE 0x00000000
+#define SVGA_ESCAPE_NSID_DEVEL  0xFFFFFFFF
+
+
+/*
+ * Within SVGA_ESCAPE_NSID_VMWARE, we multiplex commands according to
+ * the first DWORD of escape data (after the nsID and size). As a
+ * guideline we're using the high word and low word as a major and
+ * minor command number, respectively.
+ *
+ * Major command number allocation:
+ *
+ *   0000: Reserved
+ *   0001: SVGA_ESCAPE_VMWARE_LOG (svga_binary_logger.h)
+ *   0002: SVGA_ESCAPE_VMWARE_VIDEO (svga_overlay.h)
+ *   0003: SVGA_ESCAPE_VMWARE_HINT (svga_escape.h)
+ */
+
+#define SVGA_ESCAPE_VMWARE_MAJOR_MASK  0xFFFF0000
+
+
+/*
+ * SVGA Hint commands.
+ *
+ * These escapes let the SVGA driver provide optional information to
+ * he host about the state of the guest or guest applications. The
+ * host can use these hints to make user interface or performance
+ * decisions.
+ *
+ * Notes:
+ *
+ *   - SVGA_ESCAPE_VMWARE_HINT_FULLSCREEN is deprecated for guests
+ *     that use the SVGA Screen Object extension. Instead of sending
+ *     this escape, use the SVGA_SCREEN_FULLSCREEN_HINT flag on your
+ *     Screen Object.
+ */
+
+#define SVGA_ESCAPE_VMWARE_HINT               0x00030000
+#define SVGA_ESCAPE_VMWARE_HINT_FULLSCREEN    0x00030001  // Deprecated
+
+typedef
+struct {
+   uint32 command;
+   uint32 fullscreen;
+   struct {
+      int32 x, y;
+   } monitorPosition;
+} SVGAEscapeHintFullscreen;
+
+#endif /* _SVGA_ESCAPE_H_ */
diff --git a/src/gallium/drivers/svga/include/svga_overlay.h b/src/gallium/drivers/svga/include/svga_overlay.h
new file mode 100644
index 0000000..82c1d3f
--- /dev/null
+++ b/src/gallium/drivers/svga/include/svga_overlay.h
@@ -0,0 +1,201 @@
+/**********************************************************
+ * Copyright 2007-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+/*
+ * svga_overlay.h --
+ *
+ *    Definitions for video-overlay support.
+ */
+
+#ifndef _SVGA_OVERLAY_H_
+#define _SVGA_OVERLAY_H_
+
+#include "svga_reg.h"
+
+/*
+ * Video formats we support
+ */
+
+#define VMWARE_FOURCC_YV12 0x32315659 // 'Y' 'V' '1' '2'
+#define VMWARE_FOURCC_YUY2 0x32595559 // 'Y' 'U' 'Y' '2'
+#define VMWARE_FOURCC_UYVY 0x59565955 // 'U' 'Y' 'V' 'Y'
+
+typedef enum {
+   SVGA_OVERLAY_FORMAT_INVALID = 0,
+   SVGA_OVERLAY_FORMAT_YV12 = VMWARE_FOURCC_YV12,
+   SVGA_OVERLAY_FORMAT_YUY2 = VMWARE_FOURCC_YUY2,
+   SVGA_OVERLAY_FORMAT_UYVY = VMWARE_FOURCC_UYVY,
+} SVGAOverlayFormat;
+
+#define SVGA_VIDEO_COLORKEY_MASK             0x00ffffff
+
+#define SVGA_ESCAPE_VMWARE_VIDEO             0x00020000
+
+#define SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS    0x00020001
+        /* FIFO escape layout:
+         * Type, Stream Id, (Register Id, Value) pairs */
+
+#define SVGA_ESCAPE_VMWARE_VIDEO_FLUSH       0x00020002
+        /* FIFO escape layout:
+         * Type, Stream Id */
+
+typedef
+struct SVGAEscapeVideoSetRegs {
+   struct {
+      uint32 cmdType;
+      uint32 streamId;
+   } header;
+
+   // May include zero or more items.
+   struct {
+      uint32 registerId;
+      uint32 value;
+   } items[1];
+} SVGAEscapeVideoSetRegs;
+
+typedef
+struct SVGAEscapeVideoFlush {
+   uint32 cmdType;
+   uint32 streamId;
+} SVGAEscapeVideoFlush;
+
+
+/*
+ * Struct definitions for the video overlay commands built on
+ * SVGAFifoCmdEscape.
+ */
+typedef
+struct {
+   uint32 command;
+   uint32 overlay;
+} SVGAFifoEscapeCmdVideoBase;
+
+typedef
+struct {
+   SVGAFifoEscapeCmdVideoBase videoCmd;
+} SVGAFifoEscapeCmdVideoFlush;
+
+typedef
+struct {
+   SVGAFifoEscapeCmdVideoBase videoCmd;
+   struct {
+      uint32 regId;
+      uint32 value;
+   } items[1];
+} SVGAFifoEscapeCmdVideoSetRegs;
+
+typedef
+struct {
+   SVGAFifoEscapeCmdVideoBase videoCmd;
+   struct {
+      uint32 regId;
+      uint32 value;
+   } items[SVGA_VIDEO_NUM_REGS];
+} SVGAFifoEscapeCmdVideoSetAllRegs;
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMwareVideoGetAttributes --
+ *
+ *      Computes the size, pitches and offsets for YUV frames.
+ *
+ * Results:
+ *      TRUE on success; otherwise FALSE on failure.
+ *
+ * Side effects:
+ *      Pitches and offsets for the given YUV frame are put in 'pitches'
+ *      and 'offsets' respectively. They are both optional though.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static INLINE Bool
+VMwareVideoGetAttributes(const SVGAOverlayFormat format,    // IN
+                         uint32 *width,                     // IN / OUT
+                         uint32 *height,                    // IN / OUT
+                         uint32 *size,                      // OUT
+                         uint32 *pitches,                   // OUT (optional)
+                         uint32 *offsets)                   // OUT (optional)
+{
+    int tmp;
+
+    *width = (*width + 1) & ~1;
+
+    if (offsets) {
+        offsets[0] = 0;
+    }
+
+    switch (format) {
+    case VMWARE_FOURCC_YV12:
+       *height = (*height + 1) & ~1;
+       *size = (*width + 3) & ~3;
+
+       if (pitches) {
+          pitches[0] = *size;
+       }
+
+       *size *= *height;
+
+       if (offsets) {
+          offsets[1] = *size;
+       }
+
+       tmp = ((*width >> 1) + 3) & ~3;
+
+       if (pitches) {
+          pitches[1] = pitches[2] = tmp;
+       }
+
+       tmp *= (*height >> 1);
+       *size += tmp;
+
+       if (offsets) {
+          offsets[2] = *size;
+       }
+
+       *size += tmp;
+       break;
+
+    case VMWARE_FOURCC_YUY2:
+    case VMWARE_FOURCC_UYVY:
+       *size = *width * 2;
+
+       if (pitches) {
+          pitches[0] = *size;
+       }
+
+       *size *= *height;
+       break;
+
+    default:
+       return FALSE;
+    }
+
+    return TRUE;
+}
+
+#endif // _SVGA_OVERLAY_H_
diff --git a/src/gallium/drivers/svga/include/svga_reg.h b/src/gallium/drivers/svga/include/svga_reg.h
new file mode 100644
index 0000000..1b96c2e
--- /dev/null
+++ b/src/gallium/drivers/svga/include/svga_reg.h
@@ -0,0 +1,1346 @@
+/**********************************************************
+ * Copyright 1998-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+/*
+ * svga_reg.h --
+ *
+ *    Virtual hardware definitions for the VMware SVGA II device.
+ */
+
+#ifndef _SVGA_REG_H_
+#define _SVGA_REG_H_
+
+/*
+ * PCI device IDs.
+ */
+#define PCI_VENDOR_ID_VMWARE            0x15AD
+#define PCI_DEVICE_ID_VMWARE_SVGA2      0x0405
+
+/*
+ * Legal values for the SVGA_REG_CURSOR_ON register in old-fashioned
+ * cursor bypass mode. This is still supported, but no new guest
+ * drivers should use it.
+ */
+#define SVGA_CURSOR_ON_HIDE            0x0   /* Must be 0 to maintain backward compatibility */
+#define SVGA_CURSOR_ON_SHOW            0x1   /* Must be 1 to maintain backward compatibility */
+#define SVGA_CURSOR_ON_REMOVE_FROM_FB  0x2   /* Remove the cursor from the framebuffer because we need to see what's under it */
+#define SVGA_CURSOR_ON_RESTORE_TO_FB   0x3   /* Put the cursor back in the framebuffer so the user can see it */
+
+/*
+ * The maximum framebuffer size that can traced for e.g. guests in VESA mode.
+ * The changeMap in the monitor is proportional to this number. Therefore, we'd
+ * like to keep it as small as possible to reduce monitor overhead (using
+ * SVGA_VRAM_MAX_SIZE for this increases the size of the shared area by over
+ * 4k!).
+ *
+ * NB: For compatibility reasons, this value must be greater than 0xff0000.
+ *     See bug 335072.
+ */
+#define SVGA_FB_MAX_TRACEABLE_SIZE      0x1000000
+
+#define SVGA_MAX_PSEUDOCOLOR_DEPTH      8
+#define SVGA_MAX_PSEUDOCOLORS           (1 << SVGA_MAX_PSEUDOCOLOR_DEPTH)
+#define SVGA_NUM_PALETTE_REGS           (3 * SVGA_MAX_PSEUDOCOLORS)
+
+#define SVGA_MAGIC         0x900000UL
+#define SVGA_MAKE_ID(ver)  (SVGA_MAGIC << 8 | (ver))
+
+/* Version 2 let the address of the frame buffer be unsigned on Win32 */
+#define SVGA_VERSION_2     2
+#define SVGA_ID_2          SVGA_MAKE_ID(SVGA_VERSION_2)
+
+/* Version 1 has new registers starting with SVGA_REG_CAPABILITIES so
+   PALETTE_BASE has moved */
+#define SVGA_VERSION_1     1
+#define SVGA_ID_1          SVGA_MAKE_ID(SVGA_VERSION_1)
+
+/* Version 0 is the initial version */
+#define SVGA_VERSION_0     0
+#define SVGA_ID_0          SVGA_MAKE_ID(SVGA_VERSION_0)
+
+/* "Invalid" value for all SVGA IDs. (Version ID, screen object ID, surface ID...) */
+#define SVGA_ID_INVALID    0xFFFFFFFF
+
+/* Port offsets, relative to BAR0 */
+#define SVGA_INDEX_PORT         0x0
+#define SVGA_VALUE_PORT         0x1
+#define SVGA_BIOS_PORT          0x2
+#define SVGA_IRQSTATUS_PORT     0x8
+
+/*
+ * Interrupt source flags for IRQSTATUS_PORT and IRQMASK.
+ *
+ * Interrupts are only supported when the
+ * SVGA_CAP_IRQMASK capability is present.
+ */
+#define SVGA_IRQFLAG_ANY_FENCE            0x1    /* Any fence was passed */
+#define SVGA_IRQFLAG_FIFO_PROGRESS        0x2    /* Made forward progress in the FIFO */
+#define SVGA_IRQFLAG_FENCE_GOAL           0x4    /* SVGA_FIFO_FENCE_GOAL reached */
+
+/*
+ * Registers
+ */
+
+enum {
+   SVGA_REG_ID = 0,
+   SVGA_REG_ENABLE = 1,
+   SVGA_REG_WIDTH = 2,
+   SVGA_REG_HEIGHT = 3,
+   SVGA_REG_MAX_WIDTH = 4,
+   SVGA_REG_MAX_HEIGHT = 5,
+   SVGA_REG_DEPTH = 6,
+   SVGA_REG_BITS_PER_PIXEL = 7,       /* Current bpp in the guest */
+   SVGA_REG_PSEUDOCOLOR = 8,
+   SVGA_REG_RED_MASK = 9,
+   SVGA_REG_GREEN_MASK = 10,
+   SVGA_REG_BLUE_MASK = 11,
+   SVGA_REG_BYTES_PER_LINE = 12,
+   SVGA_REG_FB_START = 13,            /* (Deprecated) */
+   SVGA_REG_FB_OFFSET = 14,
+   SVGA_REG_VRAM_SIZE = 15,
+   SVGA_REG_FB_SIZE = 16,
+
+   /* ID 0 implementation only had the above registers, then the palette */
+
+   SVGA_REG_CAPABILITIES = 17,
+   SVGA_REG_MEM_START = 18,           /* (Deprecated) */
+   SVGA_REG_MEM_SIZE = 19,
+   SVGA_REG_CONFIG_DONE = 20,         /* Set when memory area configured */
+   SVGA_REG_SYNC = 21,                /* See "FIFO Synchronization Registers" */
+   SVGA_REG_BUSY = 22,                /* See "FIFO Synchronization Registers" */
+   SVGA_REG_GUEST_ID = 23,            /* Set guest OS identifier */
+   SVGA_REG_CURSOR_ID = 24,           /* (Deprecated) */
+   SVGA_REG_CURSOR_X = 25,            /* (Deprecated) */
+   SVGA_REG_CURSOR_Y = 26,            /* (Deprecated) */
+   SVGA_REG_CURSOR_ON = 27,           /* (Deprecated) */
+   SVGA_REG_HOST_BITS_PER_PIXEL = 28, /* (Deprecated) */
+   SVGA_REG_SCRATCH_SIZE = 29,        /* Number of scratch registers */
+   SVGA_REG_MEM_REGS = 30,            /* Number of FIFO registers */
+   SVGA_REG_NUM_DISPLAYS = 31,        /* (Deprecated) */
+   SVGA_REG_PITCHLOCK = 32,           /* Fixed pitch for all modes */
+   SVGA_REG_IRQMASK = 33,             /* Interrupt mask */
+
+   /* Legacy multi-monitor support */
+   SVGA_REG_NUM_GUEST_DISPLAYS = 34,/* Number of guest displays in X/Y direction */
+   SVGA_REG_DISPLAY_ID = 35,        /* Display ID for the following display attributes */
+   SVGA_REG_DISPLAY_IS_PRIMARY = 36,/* Whether this is a primary display */
+   SVGA_REG_DISPLAY_POSITION_X = 37,/* The display position x */
+   SVGA_REG_DISPLAY_POSITION_Y = 38,/* The display position y */
+   SVGA_REG_DISPLAY_WIDTH = 39,     /* The display's width */
+   SVGA_REG_DISPLAY_HEIGHT = 40,    /* The display's height */
+
+   /* See "Guest memory regions" below. */
+   SVGA_REG_GMR_ID = 41,
+   SVGA_REG_GMR_DESCRIPTOR = 42,
+   SVGA_REG_GMR_MAX_IDS = 43,
+   SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH = 44,
+
+   SVGA_REG_TRACES = 45,            /* Enable trace-based updates even when FIFO is on */
+   SVGA_REG_TOP = 46,               /* Must be 1 more than the last register */
+
+   SVGA_PALETTE_BASE = 1024,        /* Base of SVGA color map */
+   /* Next 768 (== 256*3) registers exist for colormap */
+
+   SVGA_SCRATCH_BASE = SVGA_PALETTE_BASE + SVGA_NUM_PALETTE_REGS
+                                    /* Base of scratch registers */
+   /* Next reg[SVGA_REG_SCRATCH_SIZE] registers exist for scratch usage:
+      First 4 are reserved for VESA BIOS Extension; any remaining are for
+      the use of the current SVGA driver. */
+};
+
+
+/*
+ * Guest memory regions (GMRs):
+ *
+ * This is a new memory mapping feature available in SVGA devices
+ * which have the SVGA_CAP_GMR bit set. Previously, there were two
+ * fixed memory regions available with which to share data between the
+ * device and the driver: the FIFO ('MEM') and the framebuffer. GMRs
+ * are our name for an extensible way of providing arbitrary DMA
+ * buffers for use between the driver and the SVGA device. They are a
+ * new alternative to framebuffer memory, usable for both 2D and 3D
+ * graphics operations.
+ *
+ * Since GMR mapping must be done synchronously with guest CPU
+ * execution, we use a new pair of SVGA registers:
+ *
+ *   SVGA_REG_GMR_ID --
+ *
+ *     Read/write.
+ *     This register holds the 32-bit ID (a small positive integer)
+ *     of a GMR to create, delete, or redefine. Writing this register
+ *     has no side-effects.
+ *
+ *   SVGA_REG_GMR_DESCRIPTOR --
+ *
+ *     Write-only.
+ *     Writing this register will create, delete, or redefine the GMR
+ *     specified by the above ID register. If this register is zero,
+ *     the GMR is deleted. Any pointers into this GMR (including those
+ *     currently being processed by FIFO commands) will be
+ *     synchronously invalidated.
+ *
+ *     If this register is nonzero, it must be the physical page
+ *     number (PPN) of a data structure which describes the physical
+ *     layout of the memory region this GMR should describe. The
+ *     descriptor structure will be read synchronously by the SVGA
+ *     device when this register is written. The descriptor need not
+ *     remain allocated for the lifetime of the GMR.
+ *
+ *     The guest driver should write SVGA_REG_GMR_ID first, then
+ *     SVGA_REG_GMR_DESCRIPTOR.
+ *
+ *   SVGA_REG_GMR_MAX_IDS --
+ *
+ *     Read-only.
+ *     The SVGA device may choose to support a maximum number of
+ *     user-defined GMR IDs. This register holds the number of supported
+ *     IDs. (The maximum supported ID plus 1)
+ *
+ *   SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH --
+ *
+ *     Read-only.
+ *     The SVGA device may choose to put a limit on the total number
+ *     of SVGAGuestMemDescriptor structures it will read when defining
+ *     a single GMR.
+ *
+ * The descriptor structure is an array of SVGAGuestMemDescriptor
+ * structures. Each structure may do one of three things:
+ *
+ *   - Terminate the GMR descriptor list.
+ *     (ppn==0, numPages==0)
+ *
+ *   - Add a PPN or range of PPNs to the GMR's virtual address space.
+ *     (ppn != 0, numPages != 0)
+ *
+ *   - Provide the PPN of the next SVGAGuestMemDescriptor, in order to
+ *     support multi-page GMR descriptor tables without forcing the
+ *     driver to allocate physically contiguous memory.
+ *     (ppn != 0, numPages == 0)
+ *
+ * Note that each physical page of SVGAGuestMemDescriptor structures
+ * can describe at least 2MB of guest memory. If the driver needs to
+ * use more than one page of descriptor structures, it must use one of
+ * its SVGAGuestMemDescriptors to point to an additional page.  The
+ * device will never automatically cross a page boundary.
+ *
+ * Once the driver has described a GMR, it is immediately available
+ * for use via any FIFO command that uses an SVGAGuestPtr structure.
+ * These pointers include a GMR identifier plus an offset into that
+ * GMR.
+ *
+ * The driver must check the SVGA_CAP_GMR bit before using the GMR
+ * registers.
+ */
+
+/*
+ * Special GMR IDs, allowing SVGAGuestPtrs to point to framebuffer
+ * memory as well.  In the future, these IDs could even be used to
+ * allow legacy memory regions to be redefined by the guest as GMRs.
+ *
+ * Using the guest framebuffer (GFB) at BAR1 for general purpose DMA
+ * is being phased out. Please try to use user-defined GMRs whenever
+ * possible.
+ */
+#define SVGA_GMR_NULL         ((uint32) -1)
+#define SVGA_GMR_FRAMEBUFFER  ((uint32) -2)  // Guest Framebuffer (GFB)
+
+typedef
+struct SVGAGuestMemDescriptor {
+   uint32 ppn;
+   uint32 numPages;
+} SVGAGuestMemDescriptor;
+
+typedef
+struct SVGAGuestPtr {
+   uint32 gmrId;
+   uint32 offset;
+} SVGAGuestPtr;
+
+
+/*
+ * SVGAGMRImageFormat --
+ *
+ *    This is a packed representation of the source 2D image format
+ *    for a GMR-to-screen blit. Currently it is defined as an encoding
+ *    of the screen's color depth and bits-per-pixel, however, 16 bits
+ *    are reserved for future use to identify other encodings (such as
+ *    RGBA or higher-precision images).
+ *
+ *    Currently supported formats:
+ *
+ *       bpp depth  Format Name
+ *       --- -----  -----------
+ *        32    24  32-bit BGRX
+ *        24    24  24-bit BGR
+ *        16    16  RGB 5-6-5
+ *        16    15  RGB 5-5-5
+ *
+ */
+
+typedef
+struct SVGAGMRImageFormat {
+   union {
+      struct {
+         uint32 bitsPerPixel : 8;
+         uint32 colorDepth   : 8;
+         uint32 reserved     : 16;  // Must be zero
+      };
+
+      uint32 value;
+   };
+} SVGAGMRImageFormat;
+
+/*
+ * SVGAColorBGRX --
+ *
+ *    A 24-bit color format (BGRX), which does not depend on the
+ *    format of the legacy guest framebuffer (GFB) or the current
+ *    GMRFB state.
+ */
+
+typedef
+struct SVGAColorBGRX {
+   union {
+      struct {
+         uint32 b : 8;
+         uint32 g : 8;
+         uint32 r : 8;
+         uint32 x : 8;  // Unused
+      };
+
+      uint32 value;
+   };
+} SVGAColorBGRX;
+
+
+/*
+ * SVGASignedRect --
+ * SVGASignedPoint --
+ *
+ *    Signed rectangle and point primitives. These are used by the new
+ *    2D primitives for drawing to Screen Objects, which can occupy a
+ *    signed virtual coordinate space.
+ *
+ *    SVGASignedRect specifies a half-open interval: the (left, top)
+ *    pixel is part of the rectangle, but the (right, bottom) pixel is
+ *    not.
+ */
+
+typedef
+struct SVGASignedRect {
+   int32  left;
+   int32  top;
+   int32  right;
+   int32  bottom;
+} SVGASignedRect;
+
+typedef
+struct SVGASignedPoint {
+   int32  x;
+   int32  y;
+} SVGASignedPoint;
+
+
+/*
+ *  Capabilities
+ *
+ *  Note the holes in the bitfield. Missing bits have been deprecated,
+ *  and must not be reused. Those capabilities will never be reported
+ *  by new versions of the SVGA device.
+ */
+
+#define SVGA_CAP_NONE               0x00000000
+#define SVGA_CAP_RECT_COPY          0x00000002
+#define SVGA_CAP_CURSOR             0x00000020
+#define SVGA_CAP_CURSOR_BYPASS      0x00000040   // Legacy (Use Cursor Bypass 3 instead)
+#define SVGA_CAP_CURSOR_BYPASS_2    0x00000080   // Legacy (Use Cursor Bypass 3 instead)
+#define SVGA_CAP_8BIT_EMULATION     0x00000100
+#define SVGA_CAP_ALPHA_CURSOR       0x00000200
+#define SVGA_CAP_3D                 0x00004000
+#define SVGA_CAP_EXTENDED_FIFO      0x00008000
+#define SVGA_CAP_MULTIMON           0x00010000   // Legacy multi-monitor support
+#define SVGA_CAP_PITCHLOCK          0x00020000
+#define SVGA_CAP_IRQMASK            0x00040000
+#define SVGA_CAP_DISPLAY_TOPOLOGY   0x00080000   // Legacy multi-monitor support
+#define SVGA_CAP_GMR                0x00100000
+#define SVGA_CAP_TRACES             0x00200000
+
+
+/*
+ * FIFO register indices.
+ *
+ * The FIFO is a chunk of device memory mapped into guest physmem.  It
+ * is always treated as 32-bit words.
+ *
+ * The guest driver gets to decide how to partition it between
+ * - FIFO registers (there are always at least 4, specifying where the
+ *   following data area is and how much data it contains; there may be
+ *   more registers following these, depending on the FIFO protocol
+ *   version in use)
+ * - FIFO data, written by the guest and slurped out by the VMX.
+ * These indices are 32-bit word offsets into the FIFO.
+ */
+
+enum {
+   /*
+    * Block 1 (basic registers): The originally defined FIFO registers.
+    * These exist and are valid for all versions of the FIFO protocol.
+    */
+
+   SVGA_FIFO_MIN = 0,
+   SVGA_FIFO_MAX,       /* The distance from MIN to MAX must be at least 10K */
+   SVGA_FIFO_NEXT_CMD,
+   SVGA_FIFO_STOP,
+
+   /*
+    * Block 2 (extended registers): Mandatory registers for the extended
+    * FIFO.  These exist if the SVGA caps register includes
+    * SVGA_CAP_EXTENDED_FIFO; some of them are valid only if their
+    * associated capability bit is enabled.
+    *
+    * Note that when originally defined, SVGA_CAP_EXTENDED_FIFO implied
+    * support only for (FIFO registers) CAPABILITIES, FLAGS, and FENCE.
+    * This means that the guest has to test individually (in most cases
+    * using FIFO caps) for the presence of registers after this; the VMX
+    * can define "extended FIFO" to mean whatever it wants, and currently
+    * won't enable it unless there's room for that set and much more.
+    */
+
+   SVGA_FIFO_CAPABILITIES = 4,
+   SVGA_FIFO_FLAGS,
+   // Valid with SVGA_FIFO_CAP_FENCE:
+   SVGA_FIFO_FENCE,
+
+   /*
+    * Block 3a (optional extended registers): Additional registers for the
+    * extended FIFO, whose presence isn't actually implied by
+    * SVGA_CAP_EXTENDED_FIFO; these exist if SVGA_FIFO_MIN is high enough to
+    * leave room for them.
+    *
+    * These in block 3a, the VMX currently considers mandatory for the
+    * extended FIFO.
+    */
+
+   // Valid if exists (i.e. if extended FIFO enabled):
+   SVGA_FIFO_3D_HWVERSION,       /* See SVGA3dHardwareVersion in svga3d_reg.h */
+   // Valid with SVGA_FIFO_CAP_PITCHLOCK:
+   SVGA_FIFO_PITCHLOCK,
+
+   // Valid with SVGA_FIFO_CAP_CURSOR_BYPASS_3:
+   SVGA_FIFO_CURSOR_ON,          /* Cursor bypass 3 show/hide register */
+   SVGA_FIFO_CURSOR_X,           /* Cursor bypass 3 x register */
+   SVGA_FIFO_CURSOR_Y,           /* Cursor bypass 3 y register */
+   SVGA_FIFO_CURSOR_COUNT,       /* Incremented when any of the other 3 change */
+   SVGA_FIFO_CURSOR_LAST_UPDATED,/* Last time the host updated the cursor */
+
+   // Valid with SVGA_FIFO_CAP_RESERVE:
+   SVGA_FIFO_RESERVED,           /* Bytes past NEXT_CMD with real contents */
+
+   /*
+    * Valid with SVGA_FIFO_CAP_SCREEN_OBJECT:
+    *
+    * By default this is SVGA_ID_INVALID, to indicate that the cursor
+    * coordinates are specified relative to the virtual root. If this
+    * is set to a specific screen ID, cursor position is reinterpreted
+    * as a signed offset relative to that screen's origin. This is the
+    * only way to place the cursor on a non-rooted screen.
+    */
+   SVGA_FIFO_CURSOR_SCREEN_ID,
+
+   /*
+    * XXX: The gap here, up until SVGA_FIFO_3D_CAPS, can be used for new
+    * registers, but this must be done carefully and with judicious use of
+    * capability bits, since comparisons based on SVGA_FIFO_MIN aren't
+    * enough to tell you whether the register exists: we've shipped drivers
+    * and products that used SVGA_FIFO_3D_CAPS but didn't know about some of
+    * the earlier ones.  The actual order of introduction was:
+    * - PITCHLOCK
+    * - 3D_CAPS
+    * - CURSOR_* (cursor bypass 3)
+    * - RESERVED
+    * So, code that wants to know whether it can use any of the
+    * aforementioned registers, or anything else added after PITCHLOCK and
+    * before 3D_CAPS, needs to reason about something other than
+    * SVGA_FIFO_MIN.
+    */
+
+   /*
+    * 3D caps block space; valid with 3D hardware version >=
+    * SVGA3D_HWVERSION_WS6_B1.
+    */
+   SVGA_FIFO_3D_CAPS      = 32,
+   SVGA_FIFO_3D_CAPS_LAST = 32 + 255,
+
+   /*
+    * End of VMX's current definition of "extended-FIFO registers".
+    * Registers before here are always enabled/disabled as a block; either
+    * the extended FIFO is enabled and includes all preceding registers, or
+    * it's disabled entirely.
+    *
+    * Block 3b (truly optional extended registers): Additional registers for
+    * the extended FIFO, which the VMX already knows how to enable and
+    * disable with correct granularity.
+    *
+    * Registers after here exist if and only if the guest SVGA driver
+    * sets SVGA_FIFO_MIN high enough to leave room for them.
+    */
+
+   // Valid if register exists:
+   SVGA_FIFO_GUEST_3D_HWVERSION, /* Guest driver's 3D version */
+   SVGA_FIFO_FENCE_GOAL,         /* Matching target for SVGA_IRQFLAG_FENCE_GOAL */
+   SVGA_FIFO_BUSY,               /* See "FIFO Synchronization Registers" */
+
+   /*
+    * Always keep this last.  This defines the maximum number of
+    * registers we know about.  At power-on, this value is placed in
+    * the SVGA_REG_MEM_REGS register, and we expect the guest driver
+    * to allocate this much space in FIFO memory for registers.
+    */
+    SVGA_FIFO_NUM_REGS
+};
+
+
+/*
+ * Definition of registers included in extended FIFO support.
+ *
+ * The guest SVGA driver gets to allocate the FIFO between registers
+ * and data.  It must always allocate at least 4 registers, but old
+ * drivers stopped there.
+ *
+ * The VMX will enable extended FIFO support if and only if the guest
+ * left enough room for all registers defined as part of the mandatory
+ * set for the extended FIFO.
+ *
+ * Note that the guest drivers typically allocate the FIFO only at
+ * initialization time, not at mode switches, so it's likely that the
+ * number of FIFO registers won't change without a reboot.
+ *
+ * All registers less than this value are guaranteed to be present if
+ * svgaUser->fifo.extended is set. Any later registers must be tested
+ * individually for compatibility at each use (in the VMX).
+ *
+ * This value is used only by the VMX, so it can change without
+ * affecting driver compatibility; keep it that way?
+ */
+#define SVGA_FIFO_EXTENDED_MANDATORY_REGS  (SVGA_FIFO_3D_CAPS_LAST + 1)
+
+
+/*
+ * FIFO Synchronization Registers
+ *
+ *  This explains the relationship between the various FIFO
+ *  sync-related registers in IOSpace and in FIFO space.
+ *
+ *  SVGA_REG_SYNC --
+ *
+ *       The SYNC register can be used in two different ways by the guest:
+ *
+ *         1. If the guest wishes to fully sync (drain) the FIFO,
+ *            it will write once to SYNC then poll on the BUSY
+ *            register. The FIFO is sync'ed once BUSY is zero.
+ *
+ *         2. If the guest wants to asynchronously wake up the host,
+ *            it will write once to SYNC without polling on BUSY.
+ *            Ideally it will do this after some new commands have
+ *            been placed in the FIFO, and after reading a zero
+ *            from SVGA_FIFO_BUSY.
+ *
+ *       (1) is the original behaviour that SYNC was designed to
+ *       support.  Originally, a write to SYNC would implicitly
+ *       trigger a read from BUSY. This causes us to synchronously
+ *       process the FIFO.
+ *
+ *       This behaviour has since been changed so that writing SYNC
+ *       will *not* implicitly cause a read from BUSY. Instead, it
+ *       makes a channel call which asynchronously wakes up the MKS
+ *       thread.
+ *
+ *       New guests can use this new behaviour to implement (2)
+ *       efficiently. This lets guests get the host's attention
+ *       without waiting for the MKS to poll, which gives us much
+ *       better CPU utilization on SMP hosts and on UP hosts while
+ *       we're blocked on the host GPU.
+ *
+ *       Old guests shouldn't notice the behaviour change. SYNC was
+ *       never guaranteed to process the entire FIFO, since it was
+ *       bounded to a particular number of CPU cycles. Old guests will
+ *       still loop on the BUSY register until the FIFO is empty.
+ *
+ *       Writing to SYNC currently has the following side-effects:
+ *
+ *         - Sets SVGA_REG_BUSY to TRUE (in the monitor)
+ *         - Asynchronously wakes up the MKS thread for FIFO processing
+ *         - The value written to SYNC is recorded as a "reason", for
+ *           stats purposes.
+ *
+ *       If SVGA_FIFO_BUSY is available, drivers are advised to only
+ *       write to SYNC if SVGA_FIFO_BUSY is FALSE. Drivers should set
+ *       SVGA_FIFO_BUSY to TRUE after writing to SYNC. The MKS will
+ *       eventually set SVGA_FIFO_BUSY on its own, but this approach
+ *       lets the driver avoid sending multiple asynchronous wakeup
+ *       messages to the MKS thread.
+ *
+ *  SVGA_REG_BUSY --
+ *
+ *       This register is set to TRUE when SVGA_REG_SYNC is written,
+ *       and it reads as FALSE when the FIFO has been completely
+ *       drained.
+ *
+ *       Every read from this register causes us to synchronously
+ *       process FIFO commands. There is no guarantee as to how many
+ *       commands each read will process.
+ *
+ *       CPU time spent processing FIFO commands will be billed to
+ *       the guest.
+ *
+ *       New drivers should avoid using this register unless they
+ *       need to guarantee that the FIFO is completely drained. It
+ *       is overkill for performing a sync-to-fence. Older drivers
+ *       will use this register for any type of synchronization.
+ *
+ *  SVGA_FIFO_BUSY --
+ *
+ *       This register is a fast way for the guest driver to check
+ *       whether the FIFO is already being processed. It reads and
+ *       writes at normal RAM speeds, with no monitor intervention.
+ *
+ *       If this register reads as TRUE, the host is guaranteeing that
+ *       any new commands written into the FIFO will be noticed before
+ *       the MKS goes back to sleep.
+ *
+ *       If this register reads as FALSE, no such guarantee can be
+ *       made.
+ *
+ *       The guest should use this register to quickly determine
+ *       whether or not it needs to wake up the host. If the guest
+ *       just wrote a command or group of commands that it would like
+ *       the host to begin processing, it should:
+ *
+ *         1. Read SVGA_FIFO_BUSY. If it reads as TRUE, no further
+ *            action is necessary.
+ *
+ *         2. Write TRUE to SVGA_FIFO_BUSY. This informs future guest
+ *            code that we've already sent a SYNC to the host and we
+ *            don't need to send a duplicate.
+ *
+ *         3. Write a reason to SVGA_REG_SYNC. This will send an
+ *            asynchronous wakeup to the MKS thread.
+ */
+
+
+/*
+ * FIFO Capabilities
+ *
+ *      Fence -- Fence register and command are supported
+ *      Accel Front -- Front buffer only commands are supported
+ *      Pitch Lock -- Pitch lock register is supported
+ *      Video -- SVGA Video overlay units are supported
+ *      Escape -- Escape command is supported
+ *
+ * XXX: Add longer descriptions for each capability, including a list
+ *      of the new features that each capability provides.
+ *
+ * SVGA_FIFO_CAP_SCREEN_OBJECT --
+ *
+ *    Provides dynamic multi-screen rendering, for improved Unity and
+ *    multi-monitor modes. With Screen Object, the guest can
+ *    dynamically create and destroy 'screens', which can represent
+ *    Unity windows or virtual monitors. Screen Object also provides
+ *    strong guarantees that DMA operations happen only when
+ *    guest-initiated. Screen Object deprecates the BAR1 guest
+ *    framebuffer (GFB) and all commands that work only with the GFB.
+ *
+ *    New registers:
+ *       FIFO_CURSOR_SCREEN_ID, VIDEO_DATA_GMRID, VIDEO_DST_SCREEN_ID
+ *
+ *    New 2D commands:
+ *       DEFINE_SCREEN, DESTROY_SCREEN, DEFINE_GMRFB, BLIT_GMRFB_TO_SCREEN,
+ *       BLIT_SCREEN_TO_GMRFB, ANNOTATION_FILL, ANNOTATION_COPY
+ *
+ *    New 3D commands:
+ *       BLIT_SURFACE_TO_SCREEN
+ *
+ *    New guarantees:
+ *
+ *       - The host will not read or write guest memory, including the GFB,
+ *         except when explicitly initiated by a DMA command.
+ *
+ *       - All DMA, including legacy DMA like UPDATE and PRESENT_READBACK,
+ *         is guaranteed to complete before any subsequent FENCEs.
+ *
+ *       - All legacy commands which affect a Screen (UPDATE, PRESENT,
+ *         PRESENT_READBACK) as well as new Screen blit commands will
+ *         all behave consistently as blits, and memory will be read
+ *         or written in FIFO order.
+ *
+ *         For example, if you PRESENT from one SVGA3D surface to multiple
+ *         places on the screen, the data copied will always be from the
+ *         SVGA3D surface at the time the PRESENT was issued in the FIFO.
+ *         This was not necessarily true on devices without Screen Object.
+ *
+ *         This means that on devices that support Screen Object, the
+ *         PRESENT_READBACK command should not be necessary unless you
+ *         actually want to read back the results of 3D rendering into
+ *         system memory. (And for that, the BLIT_SCREEN_TO_GMRFB
+ *         command provides a strict superset of functionality.)
+ *
+ *       - When a screen is resized, either using Screen Object commands or
+ *         legacy multimon registers, its contents are preserved.
+ */
+
+#define SVGA_FIFO_CAP_NONE                  0
+#define SVGA_FIFO_CAP_FENCE             (1<<0)
+#define SVGA_FIFO_CAP_ACCELFRONT        (1<<1)
+#define SVGA_FIFO_CAP_PITCHLOCK         (1<<2)
+#define SVGA_FIFO_CAP_VIDEO             (1<<3)
+#define SVGA_FIFO_CAP_CURSOR_BYPASS_3   (1<<4)
+#define SVGA_FIFO_CAP_ESCAPE            (1<<5)
+#define SVGA_FIFO_CAP_RESERVE           (1<<6)
+#define SVGA_FIFO_CAP_SCREEN_OBJECT     (1<<7)
+
+
+/*
+ * FIFO Flags
+ *
+ *      Accel Front -- Driver should use front buffer only commands
+ */
+
+#define SVGA_FIFO_FLAG_NONE                 0
+#define SVGA_FIFO_FLAG_ACCELFRONT       (1<<0)
+#define SVGA_FIFO_FLAG_RESERVED        (1<<31) // Internal use only
+
+/*
+ * FIFO reservation sentinel value
+ */
+
+#define SVGA_FIFO_RESERVED_UNKNOWN      0xffffffff
+
+
+/*
+ * Video overlay support
+ */
+
+#define SVGA_NUM_OVERLAY_UNITS 32
+
+
+/*
+ * Video capabilities that the guest is currently using
+ */
+
+#define SVGA_VIDEO_FLAG_COLORKEY        0x0001
+
+
+/*
+ * Offsets for the video overlay registers
+ */
+
+enum {
+   SVGA_VIDEO_ENABLED = 0,
+   SVGA_VIDEO_FLAGS,
+   SVGA_VIDEO_DATA_OFFSET,
+   SVGA_VIDEO_FORMAT,
+   SVGA_VIDEO_COLORKEY,
+   SVGA_VIDEO_SIZE,          // Deprecated
+   SVGA_VIDEO_WIDTH,
+   SVGA_VIDEO_HEIGHT,
+   SVGA_VIDEO_SRC_X,
+   SVGA_VIDEO_SRC_Y,
+   SVGA_VIDEO_SRC_WIDTH,
+   SVGA_VIDEO_SRC_HEIGHT,
+   SVGA_VIDEO_DST_X,         // Signed int32
+   SVGA_VIDEO_DST_Y,         // Signed int32
+   SVGA_VIDEO_DST_WIDTH,
+   SVGA_VIDEO_DST_HEIGHT,
+   SVGA_VIDEO_PITCH_1,
+   SVGA_VIDEO_PITCH_2,
+   SVGA_VIDEO_PITCH_3,
+   SVGA_VIDEO_DATA_GMRID,    // Optional, defaults to SVGA_GMR_FRAMEBUFFER
+   SVGA_VIDEO_DST_SCREEN_ID, // Optional, defaults to virtual coords (SVGA_ID_INVALID)
+   SVGA_VIDEO_NUM_REGS
+};
+
+
+/*
+ * SVGA Overlay Units
+ *
+ *      width and height relate to the entire source video frame.
+ *      srcX, srcY, srcWidth and srcHeight represent subset of the source
+ *      video frame to be displayed.
+ */
+
+typedef struct SVGAOverlayUnit {
+   uint32 enabled;
+   uint32 flags;
+   uint32 dataOffset;
+   uint32 format;
+   uint32 colorKey;
+   uint32 size;
+   uint32 width;
+   uint32 height;
+   uint32 srcX;
+   uint32 srcY;
+   uint32 srcWidth;
+   uint32 srcHeight;
+   int32  dstX;
+   int32  dstY;
+   uint32 dstWidth;
+   uint32 dstHeight;
+   uint32 pitches[3];
+   uint32 dataGMRId;
+   uint32 dstScreenId;
+} SVGAOverlayUnit;
+
+
+/*
+ * SVGAScreenObject --
+ *
+ *    This is a new way to represent a guest's multi-monitor screen or
+ *    Unity window. Screen objects are only supported if the
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT capability bit is set.
+ *
+ *    If Screen Objects are supported, they can be used to fully
+ *    replace the functionality provided by the framebuffer registers
+ *    (SVGA_REG_WIDTH, HEIGHT, etc.) and by SVGA_CAP_DISPLAY_TOPOLOGY.
+ *
+ *    The screen object is a struct with guaranteed binary
+ *    compatibility. New flags can be added, and the struct may grow,
+ *    but existing fields must retain their meaning.
+ *
+ */
+
+#define SVGA_SCREEN_HAS_ROOT    (1 << 0)  // Screen is present in the virtual coord space
+#define SVGA_SCREEN_IS_PRIMARY  (1 << 1)  // Guest considers this screen to be 'primary'
+#define SVGA_SCREEN_FULLSCREEN_HINT (1 << 2)   // Guest is running a fullscreen app here
+
+typedef
+struct SVGAScreenObject {
+   uint32 structSize;   // sizeof(SVGAScreenObject)
+   uint32 id;
+   uint32 flags;
+   struct {
+      uint32 width;
+      uint32 height;
+   } size;
+   struct {
+      int32 x;
+      int32 y;
+   } root;              // Only used if SVGA_SCREEN_HAS_ROOT is set.
+} SVGAScreenObject;
+
+
+/*
+ *  Commands in the command FIFO:
+ *
+ *  Command IDs defined below are used for the traditional 2D FIFO
+ *  communication (not all commands are available for all versions of the
+ *  SVGA FIFO protocol).
+ *
+ *  Note the holes in the command ID numbers: These commands have been
+ *  deprecated, and the old IDs must not be reused.
+ *
+ *  Command IDs from 1000 to 1999 are reserved for use by the SVGA3D
+ *  protocol.
+ *
+ *  Each command's parameters are described by the comments and
+ *  structs below.
+ */
+
+typedef enum {
+   SVGA_CMD_INVALID_CMD           = 0,
+   SVGA_CMD_UPDATE                = 1,
+   SVGA_CMD_RECT_COPY             = 3,
+   SVGA_CMD_DEFINE_CURSOR         = 19,
+   SVGA_CMD_DEFINE_ALPHA_CURSOR   = 22,
+   SVGA_CMD_UPDATE_VERBOSE        = 25,
+   SVGA_CMD_FRONT_ROP_FILL        = 29,
+   SVGA_CMD_FENCE                 = 30,
+   SVGA_CMD_ESCAPE                = 33,
+   SVGA_CMD_DEFINE_SCREEN         = 34,
+   SVGA_CMD_DESTROY_SCREEN        = 35,
+   SVGA_CMD_DEFINE_GMRFB          = 36,
+   SVGA_CMD_BLIT_GMRFB_TO_SCREEN  = 37,
+   SVGA_CMD_BLIT_SCREEN_TO_GMRFB  = 38,
+   SVGA_CMD_ANNOTATION_FILL       = 39,
+   SVGA_CMD_ANNOTATION_COPY       = 40,
+   SVGA_CMD_MAX
+} SVGAFifoCmdId;
+
+#define SVGA_CMD_MAX_ARGS           64
+
+
+/*
+ * SVGA_CMD_UPDATE --
+ *
+ *    This is a DMA transfer which copies from the Guest Framebuffer
+ *    (GFB) at BAR1 + SVGA_REG_FB_OFFSET to any screens which
+ *    intersect with the provided virtual rectangle.
+ *
+ *    This command does not support using arbitrary guest memory as a
+ *    data source- it only works with the pre-defined GFB memory.
+ *    This command also does not support signed virtual coordinates.
+ *    If you have defined screens (using SVGA_CMD_DEFINE_SCREEN) with
+ *    negative root x/y coordinates, the negative portion of those
+ *    screens will not be reachable by this command.
+ *
+ *    This command is not necessary when using framebuffer
+ *    traces. Traces are automatically enabled if the SVGA FIFO is
+ *    disabled, and you may explicitly enable/disable traces using
+ *    SVGA_REG_TRACES. With traces enabled, any write to the GFB will
+ *    automatically act as if a subsequent SVGA_CMD_UPDATE was issued.
+ *
+ *    Traces and SVGA_CMD_UPDATE are the only supported ways to render
+ *    pseudocolor screen updates. The newer Screen Object commands
+ *    only support true color formats.
+ *
+ * Availability:
+ *    Always available.
+ */
+
+typedef
+struct {
+   uint32 x;
+   uint32 y;
+   uint32 width;
+   uint32 height;
+} SVGAFifoCmdUpdate;
+
+
+/*
+ * SVGA_CMD_RECT_COPY --
+ *
+ *    Perform a rectangular DMA transfer from one area of the GFB to
+ *    another, and copy the result to any screens which intersect it.
+ *
+ * Availability:
+ *    SVGA_CAP_RECT_COPY
+ */
+
+typedef
+struct {
+   uint32 srcX;
+   uint32 srcY;
+   uint32 destX;
+   uint32 destY;
+   uint32 width;
+   uint32 height;
+} SVGAFifoCmdRectCopy;
+
+
+/*
+ * SVGA_CMD_DEFINE_CURSOR --
+ *
+ *    Provide a new cursor image, as an AND/XOR mask.
+ *
+ *    The recommended way to position the cursor overlay is by using
+ *    the SVGA_FIFO_CURSOR_* registers, supported by the
+ *    SVGA_FIFO_CAP_CURSOR_BYPASS_3 capability.
+ *
+ * Availability:
+ *    SVGA_CAP_CURSOR
+ */
+
+typedef
+struct {
+   uint32 id;             // Reserved, must be zero.
+   uint32 hotspotX;
+   uint32 hotspotY;
+   uint32 width;
+   uint32 height;
+   uint32 andMaskDepth;   // Value must be 1 or equal to BITS_PER_PIXEL
+   uint32 xorMaskDepth;   // Value must be 1 or equal to BITS_PER_PIXEL
+   /*
+    * Followed by scanline data for AND mask, then XOR mask.
+    * Each scanline is padded to a 32-bit boundary.
+   */
+} SVGAFifoCmdDefineCursor;
+
+
+/*
+ * SVGA_CMD_DEFINE_ALPHA_CURSOR --
+ *
+ *    Provide a new cursor image, in 32-bit BGRA format.
+ *
+ *    The recommended way to position the cursor overlay is by using
+ *    the SVGA_FIFO_CURSOR_* registers, supported by the
+ *    SVGA_FIFO_CAP_CURSOR_BYPASS_3 capability.
+ *
+ * Availability:
+ *    SVGA_CAP_ALPHA_CURSOR
+ */
+
+typedef
+struct {
+   uint32 id;             // Reserved, must be zero.
+   uint32 hotspotX;
+   uint32 hotspotY;
+   uint32 width;
+   uint32 height;
+   /* Followed by scanline data */
+} SVGAFifoCmdDefineAlphaCursor;
+
+
+/*
+ * SVGA_CMD_UPDATE_VERBOSE --
+ *
+ *    Just like SVGA_CMD_UPDATE, but also provide a per-rectangle
+ *    'reason' value, an opaque cookie which is used by internal
+ *    debugging tools. Third party drivers should not use this
+ *    command.
+ *
+ * Availability:
+ *    SVGA_CAP_EXTENDED_FIFO
+ */
+
+typedef
+struct {
+   uint32 x;
+   uint32 y;
+   uint32 width;
+   uint32 height;
+   uint32 reason;
+} SVGAFifoCmdUpdateVerbose;
+
+
+/*
+ * SVGA_CMD_FRONT_ROP_FILL --
+ *
+ *    This is a hint which tells the SVGA device that the driver has
+ *    just filled a rectangular region of the GFB with a solid
+ *    color. Instead of reading these pixels from the GFB, the device
+ *    can assume that they all equal 'color'. This is primarily used
+ *    for remote desktop protocols.
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_ACCELFRONT
+ */
+
+#define  SVGA_ROP_COPY                    0x03
+
+typedef
+struct {
+   uint32 color;     // In the same format as the GFB
+   uint32 x;
+   uint32 y;
+   uint32 width;
+   uint32 height;
+   uint32 rop;       // Must be SVGA_ROP_COPY
+} SVGAFifoCmdFrontRopFill;
+
+
+/*
+ * SVGA_CMD_FENCE --
+ *
+ *    Insert a synchronization fence.  When the SVGA device reaches
+ *    this command, it will copy the 'fence' value into the
+ *    SVGA_FIFO_FENCE register. It will also compare the fence against
+ *    SVGA_FIFO_FENCE_GOAL. If the fence matches the goal and the
+ *    SVGA_IRQFLAG_FENCE_GOAL interrupt is enabled, the device will
+ *    raise this interrupt.
+ *
+ * Availability:
+ *    SVGA_FIFO_FENCE for this command,
+ *    SVGA_CAP_IRQMASK for SVGA_FIFO_FENCE_GOAL.
+ */
+
+typedef
+struct {
+   uint32 fence;
+} SVGAFifoCmdFence;
+
+
+/*
+ * SVGA_CMD_ESCAPE --
+ *
+ *    Send an extended or vendor-specific variable length command.
+ *    This is used for video overlay, third party plugins, and
+ *    internal debugging tools. See svga_escape.h
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_ESCAPE
+ */
+
+typedef
+struct {
+   uint32 nsid;
+   uint32 size;
+   /* followed by 'size' bytes of data */
+} SVGAFifoCmdEscape;
+
+
+/*
+ * SVGA_CMD_DEFINE_SCREEN --
+ *
+ *    Define or redefine an SVGAScreenObject. See the description of
+ *    SVGAScreenObject above.  The video driver is responsible for
+ *    generating new screen IDs. They should be small positive
+ *    integers. The virtual device will have an implementation
+ *    specific upper limit on the number of screen IDs
+ *    supported. Drivers are responsible for recycling IDs. The first
+ *    valid ID is zero.
+ *
+ *    - Interaction with other registers:
+ *
+ *    For backwards compatibility, when the GFB mode registers (WIDTH,
+ *    HEIGHT, PITCHLOCK, BITS_PER_PIXEL) are modified, the SVGA device
+ *    deletes all screens other than screen #0, and redefines screen
+ *    #0 according to the specified mode. Drivers that use
+ *    SVGA_CMD_DEFINE_SCREEN should destroy or redefine screen #0.
+ *
+ *    If you use screen objects, do not use the legacy multi-mon
+ *    registers (SVGA_REG_NUM_GUEST_DISPLAYS, SVGA_REG_DISPLAY_*).
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT
+ */
+
+typedef
+struct {
+   SVGAScreenObject screen;   // Variable-length according to version
+} SVGAFifoCmdDefineScreen;
+
+
+/*
+ * SVGA_CMD_DESTROY_SCREEN --
+ *
+ *    Destroy an SVGAScreenObject. Its ID is immediately available for
+ *    re-use.
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT
+ */
+
+typedef
+struct {
+   uint32 screenId;
+} SVGAFifoCmdDestroyScreen;
+
+
+/*
+ * SVGA_CMD_DEFINE_GMRFB --
+ *
+ *    This command sets a piece of SVGA device state called the
+ *    Guest Memory Region Framebuffer, or GMRFB. The GMRFB is a
+ *    piece of light-weight state which identifies the location and
+ *    format of an image in guest memory or in BAR1. The GMRFB has
+ *    an arbitrary size, and it doesn't need to match the geometry
+ *    of the GFB or any screen object.
+ *
+ *    The GMRFB can be redefined as often as you like. You could
+ *    always use the same GMRFB, you could redefine it before
+ *    rendering from a different guest screen, or you could even
+ *    redefine it before every blit.
+ *
+ *    There are multiple ways to use this command. The simplest way is
+ *    to use it to move the framebuffer either to elsewhere in the GFB
+ *    (BAR1) memory region, or to a user-defined GMR. This lets a
+ *    driver use a framebuffer allocated entirely out of normal system
+ *    memory, which we encourage.
+ *
+ *    Another way to use this command is to set up a ring buffer of
+ *    updates in GFB memory. If a driver wants to ensure that no
+ *    frames are skipped by the SVGA device, it is important that the
+ *    driver not modify the source data for a blit until the device is
+ *    done processing the command. One efficient way to accomplish
+ *    this is to use a ring of small DMA buffers. Each buffer is used
+ *    for one blit, then we move on to the next buffer in the
+ *    ring. The FENCE mechanism is used to protect each buffer from
+ *    re-use until the device is finished with that buffer's
+ *    corresponding blit.
+ *
+ *    This command does not affect the meaning of SVGA_CMD_UPDATE.
+ *    UPDATEs always occur from the legacy GFB memory area. This
+ *    command has no support for pseudocolor GMRFBs. Currently only
+ *    true-color 15, 16, and 24-bit depths are supported. Future
+ *    devices may expose capabilities for additional framebuffer
+ *    formats.
+ *
+ *    The default GMRFB value is undefined. Drivers must always send
+ *    this command at least once before performing any blit from the
+ *    GMRFB.
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT
+ */
+
+typedef
+struct {
+   SVGAGuestPtr        ptr;
+   uint32              bytesPerLine;
+   SVGAGMRImageFormat  format;
+} SVGAFifoCmdDefineGMRFB;
+
+
+/*
+ * SVGA_CMD_BLIT_GMRFB_TO_SCREEN --
+ *
+ *    This is a guest-to-host blit. It performs a DMA operation to
+ *    copy a rectangular region of pixels from the current GMRFB to
+ *    one or more Screen Objects.
+ *
+ *    The destination coordinate may be specified relative to a
+ *    screen's origin (if a screen ID is specified) or relative to the
+ *    virtual coordinate system's origin (if the screen ID is
+ *    SVGA_ID_INVALID). The actual destination may span zero or more
+ *    screens, in the case of a virtual destination rect or a rect
+ *    which extends off the edge of the specified screen.
+ *
+ *    This command writes to the screen's "base layer": the underlying
+ *    framebuffer which exists below any cursor or video overlays. No
+ *    action is necessary to explicitly hide or update any overlays
+ *    which exist on top of the updated region.
+ *
+ *    The SVGA device is guaranteed to finish reading from the GMRFB
+ *    by the time any subsequent FENCE commands are reached.
+ *
+ *    This command consumes an annotation. See the
+ *    SVGA_CMD_ANNOTATION_* commands for details.
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT
+ */
+
+typedef
+struct {
+   SVGASignedPoint  srcOrigin;
+   SVGASignedRect   destRect;
+   uint32           destScreenId;
+} SVGAFifoCmdBlitGMRFBToScreen;
+
+
+/*
+ * SVGA_CMD_BLIT_SCREEN_TO_GMRFB --
+ *
+ *    This is a host-to-guest blit. It performs a DMA operation to
+ *    copy a rectangular region of pixels from a single Screen Object
+ *    back to the current GMRFB.
+ *
+ *    Usage note: This command should be used rarely. It will
+ *    typically be inefficient, but it is necessary for some types of
+ *    synchronization between 3D (GPU) and 2D (CPU) rendering into
+ *    overlapping areas of a screen.
+ *
+ *    The source coordinate is specified relative to a screen's
+ *    origin. The provided screen ID must be valid. If any parameters
+ *    are invalid, the resulting pixel values are undefined.
+ *
+ *    This command reads the screen's "base layer". Overlays like
+ *    video and cursor are not included, but any data which was sent
+ *    using a blit-to-screen primitive will be available, no matter
+ *    whether the data's original source was the GMRFB or the 3D
+ *    acceleration hardware.
+ *
+ *    Note that our guest-to-host blits and host-to-guest blits aren't
+ *    symmetric in their current implementation. While the parameters
+ *    are identical, host-to-guest blits are a lot less featureful.
+ *    They do not support clipping: If the source parameters don't
+ *    fully fit within a screen, the blit fails. They must originate
+ *    from exactly one screen. Virtual coordinates are not directly
+ *    supported.
+ *
+ *    Host-to-guest blits do support the same set of GMRFB formats
+ *    offered by guest-to-host blits.
+ *
+ *    The SVGA device is guaranteed to finish writing to the GMRFB by
+ *    the time any subsequent FENCE commands are reached.
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT
+ */
+
+typedef
+struct {
+   SVGASignedPoint  destOrigin;
+   SVGASignedRect   srcRect;
+   uint32           srcScreenId;
+} SVGAFifoCmdBlitScreenToGMRFB;
+
+
+/*
+ * SVGA_CMD_ANNOTATION_FILL --
+ *
+ *    This is a blit annotation. This command stores a small piece of
+ *    device state which is consumed by the next blit-to-screen
+ *    command. The state is only cleared by commands which are
+ *    specifically documented as consuming an annotation. Other
+ *    commands (such as ESCAPEs for debugging) may intervene between
+ *    the annotation and its associated blit.
+ *
+ *    This annotation is a promise about the contents of the next
+ *    blit: The video driver is guaranteeing that all pixels in that
+ *    blit will have the same value, specified here as a color in
+ *    SVGAColorBGRX format.
+ *
+ *    The SVGA device can still render the blit correctly even if it
+ *    ignores this annotation, but the annotation may allow it to
+ *    perform the blit more efficiently, for example by ignoring the
+ *    source data and performing a fill in hardware.
+ *
+ *    This annotation is most important for performance when the
+ *    user's display is being remoted over a network connection.
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT
+ */
+
+typedef
+struct {
+   SVGAColorBGRX  color;
+} SVGAFifoCmdAnnotationFill;
+
+
+/*
+ * SVGA_CMD_ANNOTATION_COPY --
+ *
+ *    This is a blit annotation. See SVGA_CMD_ANNOTATION_FILL for more
+ *    information about annotations.
+ *
+ *    This annotation is a promise about the contents of the next
+ *    blit: The video driver is guaranteeing that all pixels in that
+ *    blit will have the same value as those which already exist at an
+ *    identically-sized region on the same or a different screen.
+ *
+ *    Note that the source pixels for the COPY in this annotation are
+ *    sampled before applying the anqnotation's associated blit. They
+ *    are allowed to overlap with the blit's destination pixels.
+ *
+ *    The copy source rectangle is specified the same way as the blit
+ *    destination: it can be a rectangle which spans zero or more
+ *    screens, specified relative to either a screen or to the virtual
+ *    coordinate system's origin. If the source rectangle includes
+ *    pixels which are not from exactly one screen, the results are
+ *    undefined.
+ *
+ * Availability:
+ *    SVGA_FIFO_CAP_SCREEN_OBJECT
+ */
+
+typedef
+struct {
+   SVGASignedPoint  srcOrigin;
+   uint32           srcScreenId;
+} SVGAFifoCmdAnnotationCopy;
+
+#endif
diff --git a/src/gallium/drivers/svga/include/svga_types.h b/src/gallium/drivers/svga/include/svga_types.h
new file mode 100644
index 0000000..7fd9bab
--- /dev/null
+++ b/src/gallium/drivers/svga/include/svga_types.h
@@ -0,0 +1,46 @@
+/**********************************************************
+ * Copyright 1998-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef _SVGA_TYPES_H_
+#define _SVGA_TYPES_H_
+
+#include "pipe/p_compiler.h"
+
+typedef int64_t int64;
+typedef uint64_t uint64;
+
+typedef int32_t int32;
+typedef uint32_t uint32;
+
+typedef int16_t int16;
+typedef uint16_t uint16;
+
+typedef int8_t int8;
+typedef uint8_t uint8;
+
+typedef uint8_t Bool;
+
+#endif /* _SVGA_TYPES_H_ */
+
diff --git a/src/gallium/drivers/svga/svga_cmd.c b/src/gallium/drivers/svga/svga_cmd.c
new file mode 100644
index 0000000..a0da7d7
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_cmd.c
@@ -0,0 +1,1427 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+/**
+ * svga_cmd.c --
+ *
+ *      Command construction utility for the SVGA3D protocol used by
+ *      the VMware SVGA device, based on the svgautil library.
+ */
+
+#include "svga_winsys.h"
+#include "svga_screen_buffer.h"
+#include "svga_screen_texture.h"
+#include "svga_cmd.h"
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * surface_to_surfaceid --
+ *
+ *      Utility function for surface ids.
+ *      Can handle null surface. Does a surface_reallocation so you need
+ *      to have allocated the fifo space before converting.
+ *
+ * Results:
+ *      id is filld out.
+ *
+ * Side effects:
+ *      One surface relocation is preformed for texture handle.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static INLINE
+void surface_to_surfaceid(struct svga_winsys_context *swc, // IN
+                          struct pipe_surface *surface,    // IN
+                          SVGA3dSurfaceImageId *id,        // OUT
+                          unsigned flags)                  // IN
+{
+   if(surface) {
+      struct svga_surface *s = svga_surface(surface);
+      swc->surface_relocation(swc, &id->sid, s->handle, flags);
+      id->face = s->real_face; /* faces have the same order */
+      id->mipmap = s->real_level;
+   }
+   else {
+      id->sid = SVGA3D_INVALID_ID;
+      id->face = 0;
+      id->mipmap = 0;
+   }
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_FIFOReserve --
+ *
+ *      Reserve space for an SVGA3D FIFO command.
+ *
+ *      The 2D SVGA commands have been around for a while, so they
+ *      have a rather asymmetric structure. The SVGA3D protocol is
+ *      more uniform: each command begins with a header containing the
+ *      command number and the full size.
+ *
+ *      This is a convenience wrapper around SVGA_FIFOReserve. We
+ *      reserve space for the whole command, and write the header.
+ *
+ *      This function must be paired with SVGA_FIFOCommitAll().
+ *
+ * Results:
+ *      Returns a pointer to the space reserved for command-specific
+ *      data. It must be 'cmdSize' bytes long.
+ *
+ * Side effects:
+ *      Begins a FIFO reservation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void *
+SVGA3D_FIFOReserve(struct svga_winsys_context *swc,
+                   uint32 cmd,       // IN
+                   uint32 cmdSize,   // IN
+                   uint32 nr_relocs) // IN
+{
+   SVGA3dCmdHeader *header;
+
+   header = swc->reserve(swc, sizeof *header + cmdSize, nr_relocs);
+   if(!header)
+      return NULL;
+
+   header->id = cmd;
+   header->size = cmdSize;
+
+   return &header[1];
+}
+
+
+void
+SVGA_FIFOCommitAll(struct svga_winsys_context *swc)
+{
+   swc->commit(swc);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_DefineContext --
+ *
+ *      Create a new context, to be referred to with the provided ID.
+ *
+ *      Context objects encapsulate all render state, and shader
+ *      objects are per-context.
+ *
+ *      Surfaces are not per-context. The same surface can be shared
+ *      between multiple contexts, and surface operations can occur
+ *      without a context.
+ *
+ *      If the provided context ID already existed, it is redefined.
+ *
+ *      Context IDs are arbitrary small non-negative integers,
+ *      global to the entire SVGA device.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_DefineContext(struct svga_winsys_context *swc)  // IN
+{
+   SVGA3dCmdDefineContext *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_CONTEXT_DEFINE, sizeof *cmd, 0);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+
+   swc->commit(swc);
+   
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_DestroyContext --
+ *
+ *      Delete a context created with SVGA3D_DefineContext.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_DestroyContext(struct svga_winsys_context *swc)  // IN
+{
+   SVGA3dCmdDestroyContext *cmd;
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_CONTEXT_DESTROY, sizeof *cmd, 0);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+   
+   cmd->cid = swc->cid;
+   
+   swc->commit(swc);
+   
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginDefineSurface --
+ *
+ *      Begin a SURFACE_DEFINE command. This reserves space for it in
+ *      the FIFO, and returns pointers to the command's faces and
+ *      mipsizes arrays.
+ *
+ *      This function must be paired with SVGA_FIFOCommitAll().
+ *      The faces and mipSizes arrays are initialized to zero.
+ *
+ *      This creates a "surface" object in the SVGA3D device,
+ *      with the provided surface ID (sid). Surfaces are generic
+ *      containers for host VRAM objects like textures, vertex
+ *      buffers, and depth/stencil buffers.
+ *
+ *      Surfaces are hierarchial:
+ *
+ *        - Surface may have multiple faces (for cube maps)
+ *
+ *          - Each face has a list of mipmap levels
+ *
+ *             - Each mipmap image may have multiple volume
+ *               slices, if the image is three dimensional.
+ *
+ *                - Each slice is a 2D array of 'blocks'
+ *
+ *                   - Each block may be one or more pixels.
+ *                     (Usually 1, more for DXT or YUV formats.)
+ *
+ *      Surfaces are generic host VRAM objects. The SVGA3D device
+ *      may optimize surfaces according to the format they were
+ *      created with, but this format does not limit the ways in
+ *      which the surface may be used. For example, a depth surface
+ *      can be used as a texture, or a floating point image may
+ *      be used as a vertex buffer. Some surface usages may be
+ *      lower performance, due to software emulation, but any
+ *      usage should work with any surface.
+ *
+ *      If 'sid' is already defined, the old surface is deleted
+ *      and this new surface replaces it.
+ *
+ *      Surface IDs are arbitrary small non-negative integers,
+ *      global to the entire SVGA device.
+ *
+ * Results:
+ *      Returns pointers to arrays allocated in the FIFO for 'faces'
+ *      and 'mipSizes'.
+ *
+ * Side effects:
+ *      Begins a FIFO reservation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_BeginDefineSurface(struct svga_winsys_context *swc,
+                          struct svga_winsys_surface *sid, // IN
+                          SVGA3dSurfaceFlags flags,    // IN
+                          SVGA3dSurfaceFormat format,  // IN
+                          SVGA3dSurfaceFace **faces,   // OUT
+                          SVGA3dSize **mipSizes,       // OUT
+                          uint32 numMipSizes)          // IN
+{
+   SVGA3dCmdDefineSurface *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SURFACE_DEFINE, sizeof *cmd +
+                            sizeof **mipSizes * numMipSizes, 1);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->sid, sid, PIPE_BUFFER_USAGE_GPU_WRITE);
+   cmd->surfaceFlags = flags;
+   cmd->format = format;
+
+   *faces = &cmd->face[0];
+   *mipSizes = (SVGA3dSize*) &cmd[1];
+
+   memset(*faces, 0, sizeof **faces * SVGA3D_MAX_SURFACE_FACES);
+   memset(*mipSizes, 0, sizeof **mipSizes * numMipSizes);
+   
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_DefineSurface2D --
+ *
+ *      This is a simplified version of SVGA3D_BeginDefineSurface(),
+ *      which does not support cube maps, mipmaps, or volume textures.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_DefineSurface2D(struct svga_winsys_context *swc,    // IN
+                       struct svga_winsys_surface *sid, // IN
+                       uint32 width,                // IN
+                       uint32 height,               // IN
+                       SVGA3dSurfaceFormat format)  // IN
+{
+   SVGA3dSize *mipSizes;
+   SVGA3dSurfaceFace *faces;
+   enum pipe_error ret;
+
+   ret = SVGA3D_BeginDefineSurface(swc,
+                                   sid, 0, format, &faces, &mipSizes, 1);
+   if(ret != PIPE_OK)
+      return ret;
+
+   faces[0].numMipLevels = 1;
+
+   mipSizes[0].width = width;
+   mipSizes[0].height = height;
+   mipSizes[0].depth = 1;
+ 
+   swc->commit(swc);;
+   
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_DestroySurface --
+ *
+ *      Release the host VRAM encapsulated by a particular surface ID.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_DestroySurface(struct svga_winsys_context *swc,
+                      struct svga_winsys_surface *sid)  // IN
+{
+   SVGA3dCmdDestroySurface *cmd;
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SURFACE_DESTROY, sizeof *cmd, 1);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+   
+   swc->surface_relocation(swc, &cmd->sid, sid, PIPE_BUFFER_USAGE_GPU_READ);
+   swc->commit(swc);;
+   
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginSurfaceDMA--
+ *
+ *      Begin a SURFACE_DMA command. This reserves space for it in
+ *      the FIFO, and returns a pointer to the command's box array.
+ *      This function must be paired with SVGA_FIFOCommitAll().
+ *
+ *      When the SVGA3D device asynchronously processes this FIFO
+ *      command, a DMA operation is performed between host VRAM and
+ *      a generic SVGAGuestPtr. The guest pointer may refer to guest
+ *      VRAM (provided by the SVGA PCI device) or to guest system
+ *      memory that has been set up as a Guest Memory Region (GMR)
+ *      by the SVGA device.
+ *
+ *      The guest's DMA buffer must remain valid (not freed, paged out,
+ *      or overwritten) until the host has finished processing this
+ *      command. The guest can determine that the host has finished
+ *      by using the SVGA device's FIFO Fence mechanism.
+ *
+ *      The guest's image buffer can be an arbitrary size and shape.
+ *      Guest image data is interpreted according to the SVGA3D surface
+ *      format specified when the surface was defined.
+ *
+ *      The caller may optionally define the guest image's pitch.
+ *      guestImage->pitch can either be zero (assume image is tightly
+ *      packed) or it must be the number of bytes between vertically
+ *      adjacent image blocks.
+ *
+ *      The provided copybox list specifies which regions of the source
+ *      image are to be copied, and where they appear on the destination.
+ *
+ *      NOTE: srcx/srcy are always on the guest image and x/y are
+ *      always on the host image, regardless of the actual transfer
+ *      direction!
+ *
+ *      For efficiency, the SVGA3D device is free to copy more data
+ *      than specified. For example, it may round copy boxes outwards
+ *      such that they lie on particular alignment boundaries.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
+                  struct svga_transfer *st,         // IN
+                  SVGA3dTransferType transfer,      // IN
+                  const SVGA3dCopyBox *boxes,       // IN
+                  uint32 numBoxes)                  // IN
+{
+   struct svga_texture *texture = svga_texture(st->base.texture); 
+   SVGA3dCmdSurfaceDMA *cmd;
+   SVGA3dCmdSurfaceDMASuffix *pSuffix;
+   uint32 boxesSize = sizeof *boxes * numBoxes;
+   unsigned region_flags;
+   unsigned surface_flags;
+   
+   if(transfer == SVGA3D_WRITE_HOST_VRAM) {
+      region_flags = PIPE_BUFFER_USAGE_GPU_READ;
+      surface_flags = PIPE_BUFFER_USAGE_GPU_WRITE;
+   }
+   else if(transfer == SVGA3D_READ_HOST_VRAM) {
+      region_flags = PIPE_BUFFER_USAGE_GPU_WRITE;
+      surface_flags = PIPE_BUFFER_USAGE_GPU_READ;
+   }
+   else {
+      assert(0);
+      return PIPE_ERROR_BAD_INPUT;
+   }
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SURFACE_DMA,
+                            sizeof *cmd + boxesSize + sizeof *pSuffix,
+                            2);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->region_relocation(swc, &cmd->guest.ptr, st->hwbuf, 0, region_flags);
+   cmd->guest.pitch = st->base.stride;
+
+   swc->surface_relocation(swc, &cmd->host.sid, texture->handle, surface_flags);
+   cmd->host.face = st->base.face; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */
+   cmd->host.mipmap = st->base.level;
+
+   cmd->transfer = transfer;
+
+   memcpy(&cmd[1], boxes, boxesSize);
+   
+   pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + boxesSize);
+   pSuffix->suffixSize = sizeof *pSuffix;
+   pSuffix->maximumOffset = st->hw_nblocksy*st->base.stride;
+   memset(&pSuffix->flags, 0, sizeof pSuffix->flags);
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_BufferDMA(struct svga_winsys_context *swc,
+                 struct svga_winsys_buffer *guest,
+                 struct svga_winsys_surface *host,
+                 SVGA3dTransferType transfer,      // IN
+                 uint32 size,                      // IN
+                 uint32 offset,                    // IN
+                 SVGA3dSurfaceDMAFlags flags)      // IN
+{
+   SVGA3dCmdSurfaceDMA *cmd;
+   SVGA3dCopyBox *box;
+   SVGA3dCmdSurfaceDMASuffix *pSuffix;
+   unsigned region_flags;
+   unsigned surface_flags;
+   
+   if(transfer == SVGA3D_WRITE_HOST_VRAM) {
+      region_flags = PIPE_BUFFER_USAGE_GPU_READ;
+      surface_flags = PIPE_BUFFER_USAGE_GPU_WRITE;
+   }
+   else if(transfer == SVGA3D_READ_HOST_VRAM) {
+      region_flags = PIPE_BUFFER_USAGE_GPU_WRITE;
+      surface_flags = PIPE_BUFFER_USAGE_GPU_READ;
+   }
+   else {
+      assert(0);
+      return PIPE_ERROR_BAD_INPUT;
+   }
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SURFACE_DMA,
+                            sizeof *cmd + sizeof *box + sizeof *pSuffix,
+                            2);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->region_relocation(swc, &cmd->guest.ptr, guest, 0, region_flags);
+   cmd->guest.pitch = 0;
+
+   swc->surface_relocation(swc, &cmd->host.sid, host, surface_flags);
+   cmd->host.face = 0;
+   cmd->host.mipmap = 0;
+
+   cmd->transfer = transfer;
+
+   box = (SVGA3dCopyBox *)&cmd[1];
+   box->x = offset;
+   box->y = 0;
+   box->z = 0;
+   box->w = size;
+   box->h = 1;
+   box->d = 1;
+   box->srcx = offset;
+   box->srcy = 0;
+   box->srcz = 0;
+   
+   pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + sizeof *box);
+   pSuffix->suffixSize = sizeof *pSuffix;
+   pSuffix->maximumOffset = offset + size;
+   pSuffix->flags = flags;
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SetRenderTarget --
+ *
+ *      Bind a surface object to a particular render target attachment
+ *      point on the current context. Render target attachment points
+ *      exist for color buffers, a depth buffer, and a stencil buffer.
+ *
+ *      The SVGA3D device is quite lenient about the types of surfaces
+ *      that may be used as render targets. The color buffers must
+ *      all be the same size, but the depth and stencil buffers do not
+ *      have to be the same size as the color buffer. All attachments
+ *      are optional.
+ *
+ *      Some combinations of render target formats may require software
+ *      emulation, depending on the capabilities of the host graphics
+ *      API and graphics hardware.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_SetRenderTarget(struct svga_winsys_context *swc,
+                       SVGA3dRenderTargetType type,   // IN
+                       struct pipe_surface *surface)  // IN
+{
+   SVGA3dCmdSetRenderTarget *cmd;
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SETRENDERTARGET, sizeof *cmd, 1);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+
+   cmd->cid = swc->cid;
+
+   cmd->type = type;
+
+   surface_to_surfaceid(swc, surface, &cmd->target, PIPE_BUFFER_USAGE_GPU_WRITE);
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+
+
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_DefineShader --
+ *
+ *      Upload the bytecode for a new shader. The bytecode is "SVGA3D
+ *      format", which is theoretically a binary-compatible superset
+ *      of Microsoft's DirectX shader bytecode. In practice, the
+ *      SVGA3D bytecode doesn't yet have any extensions to DirectX's
+ *      bytecode format.
+ *
+ *      The SVGA3D device supports shader models 1.1 through 2.0.
+ *
+ *      The caller chooses a shader ID (small positive integer) by
+ *      which this shader will be identified in future commands. This
+ *      ID is in a namespace which is per-context and per-shader-type.
+ *
+ *      'bytecodeLen' is specified in bytes. It must be a multiple of 4.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_DefineShader(struct svga_winsys_context *swc,
+                    uint32 shid,                  // IN
+                    SVGA3dShaderType type,        // IN
+                    const uint32 *bytecode,       // IN
+                    uint32 bytecodeLen)           // IN
+{
+   SVGA3dCmdDefineShader *cmd;
+
+   assert(bytecodeLen % 4 == 0);
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SHADER_DEFINE, sizeof *cmd + bytecodeLen,
+                            0);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   cmd->shid = shid;
+   cmd->type = type;
+   memcpy(&cmd[1], bytecode, bytecodeLen);
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_DestroyShader --
+ *
+ *      Delete a shader that was created by SVGA3D_DefineShader. If
+ *      the shader was the current vertex or pixel shader for its
+ *      context, rendering results are undefined until a new shader is
+ *      bound.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_DestroyShader(struct svga_winsys_context *swc,
+                     uint32 shid,            // IN
+                     SVGA3dShaderType type)  // IN
+{
+   SVGA3dCmdDestroyShader *cmd;
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SHADER_DESTROY, sizeof *cmd,
+                            0);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   cmd->shid = shid;
+   cmd->type = type;
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SetShaderConst --
+ *
+ *      Set the value of a shader constant.
+ *
+ *      Shader constants are analogous to uniform variables in GLSL,
+ *      except that they belong to the render context rather than to
+ *      an individual shader.
+ *
+ *      Constants may have one of three types: A 4-vector of floats,
+ *      a 4-vector of integers, or a single boolean flag.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_SetShaderConst(struct svga_winsys_context *swc,
+                      uint32 reg,                   // IN
+                      SVGA3dShaderType type,        // IN
+                      SVGA3dShaderConstType ctype,  // IN
+                      const void *value)            // IN
+{
+   SVGA3dCmdSetShaderConst *cmd;
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SET_SHADER_CONST, sizeof *cmd,
+                            0);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   cmd->reg = reg;
+   cmd->type = type;
+   cmd->ctype = ctype;
+
+   switch (ctype) {
+
+   case SVGA3D_CONST_TYPE_FLOAT:
+   case SVGA3D_CONST_TYPE_INT:
+      memcpy(&cmd->values, value, sizeof cmd->values);
+      break;
+
+   case SVGA3D_CONST_TYPE_BOOL:
+      memset(&cmd->values, 0, sizeof cmd->values);
+      cmd->values[0] = *(uint32*)value;
+      break;
+
+   default:
+      assert(0);
+      break;
+
+   }
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SetShader --
+ *
+ *      Switch active shaders. This binds a new vertex or pixel shader
+ *      to the specified context.
+ *
+ *      A shader ID of SVGA3D_INVALID_ID unbinds any shader, switching
+ *      back to the fixed function vertex or pixel pipeline.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_SetShader(struct svga_winsys_context *swc,
+                 SVGA3dShaderType type,  // IN
+                 uint32 shid)            // IN
+{
+   SVGA3dCmdSetShader *cmd;
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SET_SHADER, sizeof *cmd,
+                            0);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+   
+   cmd->cid = swc->cid;
+   cmd->type = type;
+   cmd->shid = shid;
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginClear --
+ *
+ *      Begin a CLEAR command. This reserves space for it in the FIFO,
+ *      and returns a pointer to the command's rectangle array.  This
+ *      function must be paired with SVGA_FIFOCommitAll().
+ *
+ *      Clear is a rendering operation which fills a list of
+ *      rectangles with constant values on all render target types
+ *      indicated by 'flags'.
+ *
+ *      Clear is not affected by clipping, depth test, or other
+ *      render state which affects the fragment pipeline.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      May write to attached render target surfaces.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_BeginClear(struct svga_winsys_context *swc,
+                  SVGA3dClearFlag flags,  // IN
+                  uint32 color,           // IN
+                  float depth,            // IN
+                  uint32 stencil,         // IN
+                  SVGA3dRect **rects,     // OUT
+                  uint32 numRects)        // IN
+{
+   SVGA3dCmdClear *cmd;
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_CLEAR, 
+                            sizeof *cmd + sizeof **rects * numRects,
+                            0);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   cmd->clearFlag = flags;
+   cmd->color = color;
+   cmd->depth = depth;
+   cmd->stencil = stencil;
+   *rects = (SVGA3dRect*) &cmd[1];
+
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_ClearRect --
+ *
+ *      This is a simplified version of SVGA3D_BeginClear().
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_ClearRect(struct svga_winsys_context *swc,
+                 SVGA3dClearFlag flags,  // IN
+                 uint32 color,           // IN
+                 float depth,            // IN
+                 uint32 stencil,         // IN
+                 uint32 x,               // IN
+                 uint32 y,               // IN
+                 uint32 w,               // IN
+                 uint32 h)               // IN
+{
+   SVGA3dRect *rect;
+   enum pipe_error ret;
+
+   ret = SVGA3D_BeginClear(swc, flags, color, depth, stencil, &rect, 1);
+   if(ret != PIPE_OK)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   memset(rect, 0, sizeof *rect);
+   rect->x = x;
+   rect->y = y;
+   rect->w = w;
+   rect->h = h;
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginDrawPrimitives --
+ *
+ *      Begin a DRAW_PRIMITIVES command. This reserves space for it in
+ *      the FIFO, and returns a pointer to the command's arrays.
+ *      This function must be paired with SVGA_FIFOCommitAll().
+ *
+ *      Drawing commands consist of two variable-length arrays:
+ *      SVGA3dVertexDecl elements declare a set of vertex buffers to
+ *      use while rendering, and SVGA3dPrimitiveRange elements specify
+ *      groups of primitives each with an optional index buffer.
+ *
+ *      The decls and ranges arrays are initialized to zero.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      May write to attached render target surfaces.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc,
+                           SVGA3dVertexDecl **decls,      // OUT
+                           uint32 numVertexDecls,         // IN
+                           SVGA3dPrimitiveRange **ranges, // OUT
+                           uint32 numRanges)              // IN
+{
+   SVGA3dCmdDrawPrimitives *cmd;
+   SVGA3dVertexDecl *declArray;
+   SVGA3dPrimitiveRange *rangeArray;
+   uint32 declSize = sizeof **decls * numVertexDecls;
+   uint32 rangeSize = sizeof **ranges * numRanges;
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_DRAW_PRIMITIVES, 
+                            sizeof *cmd + declSize + rangeSize,
+                            numVertexDecls + numRanges);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   cmd->numVertexDecls = numVertexDecls;
+   cmd->numRanges = numRanges;
+
+   declArray = (SVGA3dVertexDecl*) &cmd[1];
+   rangeArray = (SVGA3dPrimitiveRange*) &declArray[numVertexDecls];
+
+   memset(declArray, 0, declSize);
+   memset(rangeArray, 0, rangeSize);
+
+   *decls = declArray;
+   *ranges = rangeArray;
+
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginSurfaceCopy --
+ *
+ *      Begin a SURFACE_COPY command. This reserves space for it in
+ *      the FIFO, and returns a pointer to the command's arrays.  This
+ *      function must be paired with SVGA_FIFOCommitAll().
+ *
+ *      The box array is initialized with zeroes.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Asynchronously copies a list of boxes from surface to surface.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc,
+                        struct pipe_surface *src,    // IN
+                        struct pipe_surface *dest,   // IN
+                        SVGA3dCopyBox **boxes,       // OUT
+                        uint32 numBoxes)             // IN
+{
+   SVGA3dCmdSurfaceCopy *cmd;
+   uint32 boxesSize = sizeof **boxes * numBoxes;
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SURFACE_COPY, sizeof *cmd + boxesSize,
+                            2);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   surface_to_surfaceid(swc, src, &cmd->src, PIPE_BUFFER_USAGE_GPU_READ);
+   surface_to_surfaceid(swc, dest, &cmd->dest, PIPE_BUFFER_USAGE_GPU_WRITE);
+   *boxes = (SVGA3dCopyBox*) &cmd[1];
+
+   memset(*boxes, 0, boxesSize);
+
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SurfaceStretchBlt --
+ *
+ *      Issue a SURFACE_STRETCHBLT command: an asynchronous
+ *      surface-to-surface blit, with scaling.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Asynchronously copies one box from surface to surface.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc,
+                         struct pipe_surface *src,    // IN
+                         struct pipe_surface *dest,   // IN
+                         SVGA3dBox *boxSrc,           // IN
+                         SVGA3dBox *boxDest,          // IN
+                         SVGA3dStretchBltMode mode)   // IN
+{
+   SVGA3dCmdSurfaceStretchBlt *cmd;
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SURFACE_STRETCHBLT, sizeof *cmd,
+                            2);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   surface_to_surfaceid(swc, src, &cmd->src, PIPE_BUFFER_USAGE_GPU_READ);
+   surface_to_surfaceid(swc, dest, &cmd->dest, PIPE_BUFFER_USAGE_GPU_WRITE);
+   cmd->boxSrc = *boxSrc;
+   cmd->boxDest = *boxDest;
+   cmd->mode = mode;
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SetViewport --
+ *
+ *      Set the current context's viewport rectangle. The viewport
+ *      is clipped to the dimensions of the current render target,
+ *      then all rendering is clipped to the viewport.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_SetViewport(struct svga_winsys_context *swc,
+                   SVGA3dRect *rect)  // IN
+{
+   SVGA3dCmdSetViewport *cmd;
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SETVIEWPORT, sizeof *cmd,
+                            0);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   cmd->rect = *rect;
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SetScissorRect --
+ *
+ *      Set the current context's scissor rectangle. If scissor
+ *      is enabled then all rendering is clipped to the scissor.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_SetScissorRect(struct svga_winsys_context *swc,
+                      SVGA3dRect *rect)  // IN
+{
+   SVGA3dCmdSetScissorRect *cmd;
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SETSCISSORRECT, sizeof *cmd,
+                            0);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   cmd->rect = *rect;
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SetClipPlane --
+ *
+ *      Set one of the current context's clip planes. If the clip
+ *      plane is enabled then all 3d rendering is clipped to against
+ *      the plane.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error SVGA3D_SetClipPlane(struct svga_winsys_context *swc,
+                         uint32 index, const float *plane)
+{
+   SVGA3dCmdSetClipPlane *cmd;
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SETCLIPPLANE, sizeof *cmd,
+                            0);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   cmd->index = index;
+   cmd->plane[0] = plane[0];
+   cmd->plane[1] = plane[1];
+   cmd->plane[2] = plane[2];
+   cmd->plane[3] = plane[3];
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_SetZRange --
+ *
+ *      Set the range of the depth buffer to use. 'min' and 'max'
+ *      are values between 0.0 and 1.0.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_SetZRange(struct svga_winsys_context *swc,
+                 float zMin,  // IN
+                 float zMax)  // IN
+{
+   SVGA3dCmdSetZRange *cmd;
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SETZRANGE, sizeof *cmd,
+                            0);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   cmd->zRange.min = zMin;
+   cmd->zRange.max = zMax;
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginSetTextureState --
+ *
+ *      Begin a SETTEXTURESTATE command. This reserves space for it in
+ *      the FIFO, and returns a pointer to the command's texture state
+ *      array.  This function must be paired with SVGA_FIFOCommitAll().
+ *
+ *      This command sets rendering state which is per-texture-unit.
+ *
+ *      XXX: Individual texture states need documentation. However,
+ *           they are very similar to the texture states defined by
+ *           Direct3D. The D3D documentation is a good starting point
+ *           for understanding SVGA3D texture states.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_BeginSetTextureState(struct svga_winsys_context *swc,
+                            SVGA3dTextureState **states,  // OUT
+                            uint32 numStates)             // IN
+{
+   SVGA3dCmdSetTextureState *cmd;
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SETTEXTURESTATE, 
+                            sizeof *cmd + sizeof **states * numStates,
+                            numStates);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   *states = (SVGA3dTextureState*) &cmd[1];
+
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginSetRenderState --
+ *
+ *      Begin a SETRENDERSTATE command. This reserves space for it in
+ *      the FIFO, and returns a pointer to the command's texture state
+ *      array.  This function must be paired with SVGA_FIFOCommitAll().
+ *
+ *      This command sets rendering state which is global to the context.
+ *
+ *      XXX: Individual render states need documentation. However,
+ *           they are very similar to the render states defined by
+ *           Direct3D. The D3D documentation is a good starting point
+ *           for understanding SVGA3D render states.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_BeginSetRenderState(struct svga_winsys_context *swc,
+                           SVGA3dRenderState **states,  // OUT
+                           uint32 numStates)            // IN
+{
+   SVGA3dCmdSetRenderState *cmd;
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SETRENDERSTATE, 
+                            sizeof *cmd + sizeof **states * numStates,
+                            0);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   *states = (SVGA3dRenderState*) &cmd[1];
+
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginQuery--
+ *
+ *      Issues a SVGA_3D_CMD_BEGIN_QUERY command.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Commits space in the FIFO memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_BeginQuery(struct svga_winsys_context *swc,
+                  SVGA3dQueryType type) // IN
+{
+   SVGA3dCmdBeginQuery *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_BEGIN_QUERY,
+                            sizeof *cmd,
+                            0);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   cmd->type = type;
+
+   swc->commit(swc);
+   
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_EndQuery--
+ *
+ *      Issues a SVGA_3D_CMD_END_QUERY command.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Commits space in the FIFO memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_EndQuery(struct svga_winsys_context *swc,
+                SVGA3dQueryType type,              // IN
+                struct svga_winsys_buffer *buffer) // IN/OUT
+{
+   SVGA3dCmdEndQuery *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_END_QUERY, 
+                            sizeof *cmd,
+                            1);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   cmd->type = type;
+
+   swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
+                          PIPE_BUFFER_USAGE_GPU_WRITE);
+
+   swc->commit(swc);
+   
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_WaitForQuery--
+ *
+ *      Issues a SVGA_3D_CMD_WAIT_FOR_QUERY command.  This reserves space
+ *      for it in the FIFO.  This doesn't actually wait for the query to
+ *      finish but instead tells the host to start a wait at the driver
+ *      level.  The caller can wait on the status variable in the
+ *      guestPtr memory or send an insert fence instruction after this
+ *      command and wait on the fence.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Commits space in the FIFO memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+enum pipe_error
+SVGA3D_WaitForQuery(struct svga_winsys_context *swc,
+                    SVGA3dQueryType type,              // IN
+                    struct svga_winsys_buffer *buffer) // IN/OUT
+{
+   SVGA3dCmdWaitForQuery *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_WAIT_FOR_QUERY, 
+                            sizeof *cmd,
+                            1);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   cmd->type = type;
+   
+   swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
+                          PIPE_BUFFER_USAGE_GPU_WRITE);
+
+   swc->commit(swc);
+   
+   return PIPE_OK;
+}
diff --git a/src/gallium/drivers/svga/svga_cmd.h b/src/gallium/drivers/svga/svga_cmd.h
new file mode 100644
index 0000000..8041054
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_cmd.h
@@ -0,0 +1,235 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+/*
+ * svga_cmd.h --
+ *
+ *      Command construction utility for the SVGA3D protocol used by
+ *      the VMware SVGA device, based on the svgautil library.
+ */
+
+#ifndef __SVGA3D_H__
+#define __SVGA3D_H__
+
+
+#include "svga_types.h"
+#include "svga_reg.h"
+#include "svga3d_reg.h"
+
+#include "pipe/p_defines.h"
+
+
+struct pipe_buffer;
+struct pipe_surface;
+struct svga_transfer;
+struct svga_winsys_context;
+struct svga_winsys_buffer;
+struct svga_winsys_surface;
+
+
+/*
+ * SVGA Device Interoperability
+ */
+
+void *
+SVGA3D_FIFOReserve(struct svga_winsys_context *swc, uint32 cmd, uint32 cmdSize, uint32 nr_relocs);
+
+void
+SVGA_FIFOCommitAll(struct svga_winsys_context *swc);
+
+
+/*
+ * Context Management
+ */
+
+enum pipe_error
+SVGA3D_DefineContext(struct svga_winsys_context *swc);
+
+enum pipe_error
+SVGA3D_DestroyContext(struct svga_winsys_context *swc);
+
+
+/*
+ * Surface Management
+ */
+
+enum pipe_error
+SVGA3D_BeginDefineSurface(struct svga_winsys_context *swc,
+                          struct svga_winsys_surface *sid,
+                          SVGA3dSurfaceFlags flags,
+                          SVGA3dSurfaceFormat format,
+                          SVGA3dSurfaceFace **faces,
+                          SVGA3dSize **mipSizes,
+                          uint32 numMipSizes);
+enum pipe_error
+SVGA3D_DefineSurface2D(struct svga_winsys_context *swc,
+                       struct svga_winsys_surface *sid,
+                       uint32 width,
+                       uint32 height,
+                       SVGA3dSurfaceFormat format);
+enum pipe_error
+SVGA3D_DestroySurface(struct svga_winsys_context *swc,
+                      struct svga_winsys_surface *sid);
+
+
+/*
+ * Surface Operations
+ */
+
+enum pipe_error
+SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
+                  struct svga_transfer *st,
+                  SVGA3dTransferType transfer,
+                  const SVGA3dCopyBox *boxes,
+                  uint32 numBoxes);
+
+enum pipe_error
+SVGA3D_BufferDMA(struct svga_winsys_context *swc,
+                 struct svga_winsys_buffer *guest,
+                 struct svga_winsys_surface *host,
+                 SVGA3dTransferType transfer,
+                 uint32 size,
+                 uint32 offset,
+                 SVGA3dSurfaceDMAFlags flags);
+
+/*
+ * Drawing Operations
+ */
+
+
+enum pipe_error
+SVGA3D_BeginClear(struct svga_winsys_context *swc,
+                  SVGA3dClearFlag flags,
+                  uint32 color, float depth, uint32 stencil,
+                  SVGA3dRect **rects, uint32 numRects);
+
+enum pipe_error
+SVGA3D_ClearRect(struct svga_winsys_context *swc,
+                 SVGA3dClearFlag flags, uint32 color, float depth,
+                 uint32 stencil, uint32 x, uint32 y, uint32 w, uint32 h);
+
+enum pipe_error
+SVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc,
+                           SVGA3dVertexDecl **decls,
+                           uint32 numVertexDecls,
+                           SVGA3dPrimitiveRange **ranges,
+                           uint32 numRanges);
+
+/*
+ * Blits
+ */
+
+enum pipe_error
+SVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc,
+                        struct pipe_surface *src,
+                        struct pipe_surface *dest,
+                        SVGA3dCopyBox **boxes, uint32 numBoxes);
+
+
+enum pipe_error
+SVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc,
+                         struct pipe_surface *src,
+                         struct pipe_surface *dest,
+                         SVGA3dBox *boxSrc, SVGA3dBox *boxDest,
+                         SVGA3dStretchBltMode mode);
+
+/*
+ * Shared FFP/Shader Render State
+ */
+
+enum pipe_error
+SVGA3D_SetRenderTarget(struct svga_winsys_context *swc,
+                       SVGA3dRenderTargetType type,
+                       struct pipe_surface *surface);
+
+enum pipe_error
+SVGA3D_SetZRange(struct svga_winsys_context *swc,
+                 float zMin, float zMax);
+
+enum pipe_error
+SVGA3D_SetViewport(struct svga_winsys_context *swc,
+                   SVGA3dRect *rect);
+
+enum pipe_error
+SVGA3D_SetScissorRect(struct svga_winsys_context *swc,
+                      SVGA3dRect *rect);
+
+enum pipe_error
+SVGA3D_SetClipPlane(struct svga_winsys_context *swc,
+                    uint32 index, const float *plane);
+
+enum pipe_error
+SVGA3D_BeginSetTextureState(struct svga_winsys_context *swc,
+                            SVGA3dTextureState **states,
+                            uint32 numStates);
+
+enum pipe_error
+SVGA3D_BeginSetRenderState(struct svga_winsys_context *swc,
+                           SVGA3dRenderState **states,
+                           uint32 numStates);
+
+
+/*
+ * Shaders
+ */
+
+enum pipe_error
+SVGA3D_DefineShader(struct svga_winsys_context *swc,
+                    uint32 shid, SVGA3dShaderType type,
+                    const uint32 *bytecode, uint32 bytecodeLen);
+
+enum pipe_error
+SVGA3D_DestroyShader(struct svga_winsys_context *swc,
+                     uint32 shid, SVGA3dShaderType type);
+
+enum pipe_error
+SVGA3D_SetShaderConst(struct svga_winsys_context *swc,
+                      uint32 reg, SVGA3dShaderType type,
+                      SVGA3dShaderConstType ctype, const void *value);
+
+enum pipe_error
+SVGA3D_SetShader(struct svga_winsys_context *swc,
+                 SVGA3dShaderType type, uint32 shid);
+
+
+/*
+ * Queries
+ */
+
+enum pipe_error
+SVGA3D_BeginQuery(struct svga_winsys_context *swc,
+                  SVGA3dQueryType type);
+
+enum pipe_error
+SVGA3D_EndQuery(struct svga_winsys_context *swc,
+                SVGA3dQueryType type,
+                struct svga_winsys_buffer *buffer);
+
+enum pipe_error
+SVGA3D_WaitForQuery(struct svga_winsys_context *swc,
+                    SVGA3dQueryType type,
+                    struct svga_winsys_buffer *buffer);
+
+#endif /* __SVGA3D_H__ */
diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
new file mode 100644
index 0000000..af99c9d
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -0,0 +1,287 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "svga_cmd.h"
+
+#include "pipe/p_defines.h"
+#include "pipe/p_inlines.h"
+#include "pipe/p_screen.h"
+#include "util/u_memory.h"
+#include "util/u_bitmask.h"
+#include "util/u_upload_mgr.h"
+
+#include "svga_context.h"
+#include "svga_screen.h"
+#include "svga_screen_texture.h"
+#include "svga_screen_buffer.h"
+#include "svga_winsys.h"
+#include "svga_swtnl.h"
+#include "svga_draw.h"
+#include "svga_debug.h"
+#include "svga_state.h"
+
+
+static void svga_destroy( struct pipe_context *pipe )
+{
+   struct svga_context *svga = svga_context( pipe );
+   unsigned shader;
+
+   svga_cleanup_framebuffer( svga );
+   svga_cleanup_tss_binding( svga );
+
+   svga_hwtnl_destroy( svga->hwtnl );
+
+   svga_cleanup_vertex_state(svga);
+   
+   svga->swc->destroy(svga->swc);
+   
+   svga_destroy_swtnl( svga );
+
+   u_upload_destroy( svga->upload_vb );
+   u_upload_destroy( svga->upload_ib );
+
+   util_bitmask_destroy( svga->vs_bm );
+   util_bitmask_destroy( svga->fs_bm );
+
+   for(shader = 0; shader < PIPE_SHADER_TYPES; ++shader)
+      pipe_buffer_reference( &svga->curr.cb[shader], NULL );
+
+   FREE( svga );
+}
+
+static unsigned int
+svga_is_texture_referenced( struct pipe_context *pipe,
+			    struct pipe_texture *texture,
+			    unsigned face, unsigned level)
+{
+   struct svga_texture *tex = svga_texture(texture);
+   struct svga_screen *ss = svga_screen(pipe->screen);
+
+   /**
+    * The screen does not cache texture writes.
+    */
+
+   if (!tex->handle || ss->sws->surface_is_flushed(ss->sws, tex->handle))
+      return PIPE_UNREFERENCED;
+
+   /**
+    * sws->surface_is_flushed() does not distinguish between read references
+    * and write references. So assume a reference is both.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+svga_is_buffer_referenced( struct pipe_context *pipe,
+			   struct pipe_buffer *buf)
+
+{
+   struct svga_screen *ss = svga_screen(pipe->screen);
+   struct svga_buffer *sbuf = svga_buffer(buf);
+
+   /**
+    * XXX: Check this.
+    * The screen may cache buffer writes, but when we map, we map out
+    * of those cached writes, so we don't need to set a
+    * PIPE_REFERENCED_FOR_WRITE flag for cached buffers.
+    */
+
+   if (!sbuf->handle || ss->sws->surface_is_flushed(ss->sws, sbuf->handle))
+     return PIPE_UNREFERENCED;
+
+   /**
+    * sws->surface_is_flushed() does not distinguish between read references
+    * and write references. So assume a reference is both,
+    * however, we make an exception for index- and vertex buffers, to avoid
+    * a flush in st_bufferobj_get_subdata, during display list replay.
+    */
+
+   if (sbuf->base.usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_INDEX))
+      return PIPE_REFERENCED_FOR_READ;
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+
+struct pipe_context *svga_context_create( struct pipe_screen *screen )
+{
+   struct svga_screen *svgascreen = svga_screen(screen);
+   struct svga_context *svga = NULL;
+   enum pipe_error ret;
+
+   svga = CALLOC_STRUCT(svga_context);
+   if (svga == NULL)
+      goto no_svga;
+
+   svga->pipe.winsys = screen->winsys;
+   svga->pipe.screen = screen;
+   svga->pipe.destroy = svga_destroy;
+   svga->pipe.clear = svga_clear;
+
+   svga->pipe.is_texture_referenced = svga_is_texture_referenced;
+   svga->pipe.is_buffer_referenced = svga_is_buffer_referenced;
+
+   svga->swc = svgascreen->sws->context_create(svgascreen->sws);
+   if(!svga->swc)
+      goto no_swc;
+
+   svga_init_blend_functions(svga);
+   svga_init_blit_functions(svga);
+   svga_init_depth_stencil_functions(svga);
+   svga_init_draw_functions(svga);
+   svga_init_flush_functions(svga);
+   svga_init_misc_functions(svga);
+   svga_init_rasterizer_functions(svga);
+   svga_init_sampler_functions(svga);
+   svga_init_fs_functions(svga);
+   svga_init_vs_functions(svga);
+   svga_init_vertex_functions(svga);
+   svga_init_constbuffer_functions(svga);
+   svga_init_query_functions(svga);
+
+   /* debug */
+   svga->debug.no_swtnl = debug_get_bool_option("SVGA_NO_SWTNL", FALSE);
+   svga->debug.force_swtnl = debug_get_bool_option("SVGA_FORCE_SWTNL", FALSE);
+   svga->debug.use_min_mipmap = debug_get_bool_option("SVGA_USE_MIN_MIPMAP", FALSE);
+   svga->debug.disable_shader = debug_get_num_option("SVGA_DISABLE_SHADER", ~0);
+
+   if (!svga_init_swtnl(svga))
+      goto no_swtnl;
+
+   svga->fs_bm = util_bitmask_create();
+   if (svga->fs_bm == NULL)
+      goto no_fs_bm;
+
+   svga->vs_bm = util_bitmask_create();
+   if (svga->vs_bm == NULL)
+      goto no_vs_bm;
+
+   svga->upload_ib = u_upload_create( svga->pipe.screen,
+                                      32 * 1024,
+                                      16,
+                                      PIPE_BUFFER_USAGE_INDEX );
+   if (svga->upload_ib == NULL)
+      goto no_upload_ib;
+
+   svga->upload_vb = u_upload_create( svga->pipe.screen,
+                                      128 * 1024,
+                                      16,
+                                      PIPE_BUFFER_USAGE_VERTEX );
+   if (svga->upload_vb == NULL)
+      goto no_upload_vb;
+
+   svga->hwtnl = svga_hwtnl_create( svga,
+                                    svga->upload_ib,
+                                    svga->swc );
+   if (svga->hwtnl == NULL)
+      goto no_hwtnl;
+
+
+   ret = svga_emit_initial_state( svga );
+   if (ret)
+      goto no_state;
+   
+   /* Avoid shortcircuiting state with initial value of zero.
+    */
+   memset(&svga->state.hw_clear, 0xcd, sizeof(svga->state.hw_clear));
+   memset(&svga->state.hw_clear.framebuffer, 0x0, 
+          sizeof(svga->state.hw_clear.framebuffer));
+
+   memset(&svga->state.hw_draw, 0xcd, sizeof(svga->state.hw_draw));
+   memset(&svga->state.hw_draw.views, 0x0, sizeof(svga->state.hw_draw.views));
+   svga->state.hw_draw.num_views = 0;
+
+   svga->dirty = ~0;
+   svga->state.white_fs_id = SVGA3D_INVALID_ID;
+
+   LIST_INITHEAD(&svga->dirty_buffers);
+
+   return &svga->pipe;
+
+no_state:
+   svga_hwtnl_destroy( svga->hwtnl );
+no_hwtnl:
+   u_upload_destroy( svga->upload_vb );
+no_upload_vb:
+   u_upload_destroy( svga->upload_ib );
+no_upload_ib:
+   util_bitmask_destroy( svga->vs_bm );
+no_vs_bm:
+   util_bitmask_destroy( svga->fs_bm );
+no_fs_bm:
+   svga_destroy_swtnl(svga);
+no_swtnl:
+   svga->swc->destroy(svga->swc);
+no_swc:
+   FREE(svga);
+no_svga:
+   return NULL;
+}
+
+
+void svga_context_flush( struct svga_context *svga, 
+                         struct pipe_fence_handle **pfence )
+{
+   struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
+
+   svga->curr.nr_fbs = 0;
+
+   /* Unmap upload manager buffers: 
+    */
+   u_upload_flush(svga->upload_vb);
+   u_upload_flush(svga->upload_ib);
+
+   /* Flush screen, to ensure that texture dma uploads are processed
+    * before submitting commands.
+    */
+   svga_screen_flush(svgascreen, NULL);
+   
+   svga_context_flush_buffers(svga);
+
+   /* Flush pending commands to hardware:
+    */
+   svga->swc->flush(svga->swc, pfence);
+
+   if (SVGA_DEBUG & DEBUG_SYNC) {
+      if (pfence && *pfence)
+         svga->pipe.screen->fence_finish( svga->pipe.screen, *pfence, 0);
+   }
+}
+
+
+void svga_hwtnl_flush_retry( struct svga_context *svga )
+{
+   enum pipe_error ret = PIPE_OK;
+
+   ret = svga_hwtnl_flush( svga->hwtnl );
+   if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
+      svga_context_flush( svga, NULL );
+      ret = svga_hwtnl_flush( svga->hwtnl );
+   }
+
+   assert(ret == 0);
+}
+
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
new file mode 100644
index 0000000..66259fd
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -0,0 +1,446 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_CONTEXT_H
+#define SVGA_CONTEXT_H
+
+
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_state.h"
+
+#include "util/u_double_list.h"
+
+#include "tgsi/tgsi_scan.h"
+
+
+#define SVGA_TEX_UNITS 8
+
+struct draw_vertex_shader;
+struct svga_shader_result;
+struct SVGACmdMemory;
+struct util_bitmask;
+struct u_upload_mgr;
+
+
+struct svga_shader
+{
+   const struct tgsi_token *tokens;
+
+   struct tgsi_shader_info info;
+
+   struct svga_shader_result *results;
+
+   unsigned id;
+
+   boolean use_sm30;
+};
+
+struct svga_fragment_shader
+{
+   struct svga_shader base;
+};
+
+struct svga_vertex_shader
+{
+   struct svga_shader base;
+
+   struct draw_vertex_shader *draw_shader;
+};
+
+
+struct svga_cache_context;
+struct svga_tracked_state;
+
+struct svga_blend_state {
+
+   boolean need_white_fragments;
+
+   /* Should be per-render-target:
+    */
+   struct {
+      uint8_t writemask;
+
+      boolean blend_enable;
+      uint8_t srcblend;
+      uint8_t dstblend;
+      uint8_t blendeq;
+      
+      boolean separate_alpha_blend_enable;
+      uint8_t srcblend_alpha;
+      uint8_t dstblend_alpha;
+      uint8_t blendeq_alpha;
+
+   } rt[1];
+};
+
+struct svga_depth_stencil_state {
+   unsigned zfunc:8;
+   unsigned zenable:1;
+   unsigned zwriteenable:1;
+
+   unsigned alphatestenable:1;
+   unsigned alphafunc:8;
+  
+   struct {
+      unsigned enabled:1;
+      unsigned func:8;
+      unsigned fail:8;
+      unsigned zfail:8;
+      unsigned pass:8;
+   } stencil[2];
+   
+   /* 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;
+
+   float    alpharef;
+};
+
+#define SVGA_UNFILLED_DISABLE 0
+#define SVGA_UNFILLED_LINE    1
+#define SVGA_UNFILLED_POINT   2
+
+#define SVGA_PIPELINE_FLAG_POINTS   (1<<PIPE_PRIM_POINTS)
+#define SVGA_PIPELINE_FLAG_LINES    (1<<PIPE_PRIM_LINES)
+#define SVGA_PIPELINE_FLAG_TRIS     (1<<PIPE_PRIM_TRIANGLES)
+
+struct svga_rasterizer_state {
+   struct pipe_rasterizer_state templ; /* needed for draw module */
+
+   unsigned shademode:8;
+   unsigned cullmode:8;
+   unsigned scissortestenable:1;
+   unsigned multisampleantialias:1;
+   unsigned antialiasedlineenable:1;
+   unsigned lastpixel:1;
+
+   unsigned linepattern;
+
+   float slopescaledepthbias;
+   float depthbias;
+   float pointsize;
+   float pointsize_min;
+   float pointsize_max;
+   
+   unsigned hw_unfilled:16;         /* PIPE_POLYGON_MODE_x */
+   unsigned need_pipeline:16;    /* which prims do we need help for? */
+};
+
+struct svga_sampler_state {
+   unsigned mipfilter;
+   unsigned magfilter;
+   unsigned minfilter;
+   unsigned aniso_level;
+   float lod_bias;
+   unsigned addressu;
+   unsigned addressv;
+   unsigned addressw;
+   unsigned bordercolor;
+   unsigned normalized_coords:1;
+   unsigned compare_mode:1;
+   unsigned compare_func:3;
+
+   unsigned min_lod;
+   unsigned view_min_lod;
+   unsigned view_max_lod;
+};
+
+/* Use to calculate differences between state emitted to hardware and
+ * current driver-calculated state.  
+ */
+struct svga_state 
+{
+   const struct svga_blend_state *blend;
+   const struct svga_depth_stencil_state *depth;
+   const struct svga_rasterizer_state *rast;
+   const struct svga_sampler_state *sampler[PIPE_MAX_SAMPLERS];
+
+   struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; /* or texture ID's? */
+   struct svga_fragment_shader *fs;
+   struct svga_vertex_shader *vs;
+
+   struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
+   struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS];
+   struct pipe_buffer *cb[PIPE_SHADER_TYPES];
+
+   struct pipe_framebuffer_state framebuffer;
+   float depthscale;
+
+   /* Hack to limit the number of different render targets between
+    * flushes.  Helps avoid blowing out our surface cache in EXA.
+    */
+   int nr_fbs;
+
+   struct pipe_poly_stipple poly_stipple;
+   struct pipe_scissor_state scissor;
+   struct pipe_blend_color blend_color;
+   struct pipe_clip_state clip;
+   struct pipe_viewport_state viewport;
+
+   unsigned num_samplers;
+   unsigned num_textures;
+   unsigned num_vertex_elements;
+   unsigned num_vertex_buffers;
+   unsigned reduced_prim;
+
+   struct {
+      unsigned flag_1d;
+      unsigned flag_srgb;
+   } tex_flags;
+
+   boolean any_user_vertex_buffers;
+
+   unsigned zero_stride_vertex_elements;
+   unsigned num_zero_stride_vertex_elements;
+   /* ### maybe dynamically allocate this */
+   float zero_stride_constants[PIPE_MAX_ATTRIBS*4];
+};
+
+#define RS_MAX 97
+#define TS_MAX 30
+#define CB_MAX 256
+
+struct svga_prescale {
+   float translate[4];
+   float scale[4];
+   boolean enabled;
+};
+
+
+/* Updated by calling svga_update_state( SVGA_STATE_HW_VIEWPORT )
+ */
+struct svga_hw_clear_state
+{
+   struct {
+      unsigned x,y,w,h;
+   } viewport;
+
+   struct {
+      float zmin, zmax;
+   } depthrange;
+   
+   struct pipe_framebuffer_state framebuffer;
+   struct svga_prescale prescale;
+};
+
+struct svga_hw_view_state
+{
+   struct pipe_texture *texture;
+   struct svga_sampler_view *v;
+   unsigned min_lod;
+   unsigned max_lod;
+   int dirty;
+};
+
+/* Updated by calling svga_update_state( SVGA_STATE_HW_DRAW )
+ */
+struct svga_hw_draw_state
+{
+   unsigned rs[RS_MAX];
+   unsigned ts[16][TS_MAX];
+   float cb[PIPE_SHADER_TYPES][CB_MAX][4];
+
+   struct svga_shader_result *fs;
+   struct svga_shader_result *vs;
+   struct svga_hw_view_state views[PIPE_MAX_SAMPLERS];
+
+   unsigned num_views;
+};
+
+
+/* Updated by calling svga_update_state( SVGA_STATE_NEED_SWTNL )
+ */
+struct svga_sw_state
+{
+   unsigned ve_format[PIPE_MAX_ATTRIBS]; /* NEW_VELEMENT */
+
+   /* which parts we need */
+   boolean need_swvfetch;
+   boolean need_pipeline;
+   boolean need_swtnl;
+};
+
+
+/* Queue some state updates (like rss) and submit them to hardware in
+ * a single packet.
+ */
+struct svga_hw_queue;
+
+struct svga_query;
+
+struct svga_context
+{
+   struct pipe_context pipe;
+   struct svga_winsys_context *swc;
+
+   struct {
+      boolean no_swtnl;
+      boolean force_swtnl;
+      boolean use_min_mipmap;
+
+      /* incremented for each shader */
+      unsigned shader_id;
+
+      unsigned disable_shader;
+   } debug;
+
+   struct {
+      struct draw_context *draw;
+      struct vbuf_render *backend;
+      unsigned hw_prim;
+      boolean new_vbuf;
+      boolean new_vdecl;
+   } swtnl;
+
+   /* Bitmask of used shader IDs */
+   struct util_bitmask *fs_bm;
+   struct util_bitmask *vs_bm;
+
+   struct {
+      unsigned dirty[4];
+
+      unsigned texture_timestamp;
+
+      /* Internally generated shaders:
+       */
+      unsigned white_fs_id;
+
+      /* 
+       */
+      struct svga_sw_state          sw;
+      struct svga_hw_draw_state     hw_draw;
+      struct svga_hw_clear_state    hw_clear;
+   } state;
+
+   struct svga_state curr;      /* state from the state tracker */
+   unsigned dirty;              /* statechanges since last update_state() */
+
+   struct u_upload_mgr *upload_ib;
+   struct u_upload_mgr *upload_vb;
+   struct svga_hwtnl *hwtnl;
+
+   /** The occlusion query currently in progress */
+   struct svga_query *sq;
+
+   /** List of buffers with queued transfers */
+   struct list_head dirty_buffers;
+};
+
+/* A flag for each state_tracker state object:
+ */
+#define SVGA_NEW_BLEND               0x1
+#define SVGA_NEW_DEPTH_STENCIL       0x2
+#define SVGA_NEW_RAST                0x4
+#define SVGA_NEW_SAMPLER             0x8
+#define SVGA_NEW_TEXTURE             0x10
+#define SVGA_NEW_VBUFFER             0x20
+#define SVGA_NEW_VELEMENT            0x40
+#define SVGA_NEW_FS                  0x80
+#define SVGA_NEW_VS                  0x100
+#define SVGA_NEW_FS_CONST_BUFFER     0x200
+#define SVGA_NEW_VS_CONST_BUFFER     0x400
+#define SVGA_NEW_FRAME_BUFFER        0x800
+#define SVGA_NEW_STIPPLE             0x1000
+#define SVGA_NEW_SCISSOR             0x2000
+#define SVGA_NEW_BLEND_COLOR         0x4000
+#define SVGA_NEW_CLIP                0x8000
+#define SVGA_NEW_VIEWPORT            0x10000
+#define SVGA_NEW_PRESCALE            0x20000
+#define SVGA_NEW_REDUCED_PRIMITIVE   0x40000
+#define SVGA_NEW_TEXTURE_BINDING     0x80000
+#define SVGA_NEW_NEED_PIPELINE       0x100000
+#define SVGA_NEW_NEED_SWVFETCH       0x200000
+#define SVGA_NEW_NEED_SWTNL          0x400000
+#define SVGA_NEW_FS_RESULT           0x800000
+#define SVGA_NEW_VS_RESULT           0x1000000
+#define SVGA_NEW_ZERO_STRIDE         0x2000000
+#define SVGA_NEW_TEXTURE_FLAGS       0x4000000
+
+
+
+
+
+/***********************************************************************
+ * svga_clear.c: 
+ */
+void svga_clear(struct pipe_context *pipe, 
+                unsigned buffers,
+                const float *rgba,
+                double depth,
+                unsigned stencil);
+
+
+/***********************************************************************
+ * svga_screen_texture.c: 
+ */
+void svga_mark_surfaces_dirty(struct svga_context *svga);
+
+
+
+
+void svga_init_state_functions( struct svga_context *svga );
+void svga_init_flush_functions( struct svga_context *svga );
+void svga_init_string_functions( struct svga_context *svga );
+void svga_init_blit_functions(struct svga_context *svga);
+
+void svga_init_blend_functions( struct svga_context *svga );
+void svga_init_depth_stencil_functions( struct svga_context *svga );
+void svga_init_misc_functions( struct svga_context *svga );
+void svga_init_rasterizer_functions( struct svga_context *svga );
+void svga_init_sampler_functions( struct svga_context *svga );
+void svga_init_fs_functions( struct svga_context *svga );
+void svga_init_vs_functions( struct svga_context *svga );
+void svga_init_vertex_functions( struct svga_context *svga );
+void svga_init_constbuffer_functions( struct svga_context *svga );
+void svga_init_draw_functions( struct svga_context *svga );
+void svga_init_query_functions( struct svga_context *svga );
+
+void svga_cleanup_vertex_state( struct svga_context *svga );
+void svga_cleanup_tss_binding( struct svga_context *svga );
+void svga_cleanup_framebuffer( struct svga_context *svga );
+
+void svga_context_flush( struct svga_context *svga,
+                         struct pipe_fence_handle **pfence );
+
+void svga_hwtnl_flush_retry( struct svga_context *svga );
+
+
+/***********************************************************************
+ * Inline conversion functions.  These are better-typed than the
+ * macros used previously:
+ */
+static INLINE struct svga_context *
+svga_context( struct pipe_context *pipe )
+{
+   return (struct svga_context *)pipe;
+}
+
+
+
+#endif
diff --git a/src/gallium/drivers/svga/svga_debug.h b/src/gallium/drivers/svga/svga_debug.h
new file mode 100644
index 0000000..3a3fcd8
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_debug.h
@@ -0,0 +1,75 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_DEBUG_H
+#define SVGA_DEBUG_H
+
+#include "pipe/p_compiler.h"
+#include "util/u_debug.h"
+
+#define DEBUG_DMA      0x1
+#define DEBUG_TGSI     0x4
+#define DEBUG_PIPE     0x8
+#define DEBUG_STATE    0x10
+#define DEBUG_SCREEN   0x20
+#define DEBUG_TEX      0x40
+#define DEBUG_SWTNL    0x80
+#define DEBUG_CONSTS   0x100
+#define DEBUG_VIEWPORT 0x200
+#define DEBUG_VIEWS    0x400
+#define DEBUG_PERF     0x800    /* print something when we hit any slow path operation */
+#define DEBUG_FLUSH    0x1000   /* flush after every draw */
+#define DEBUG_SYNC     0x2000   /* sync after every flush */
+#define DEBUG_QUERY    0x4000
+#define DEBUG_CACHE    0x8000
+
+#ifdef DEBUG
+extern int SVGA_DEBUG;
+#define DBSTR(x) x
+#else
+#define SVGA_DEBUG 0
+#define DBSTR(x) ""
+#endif
+
+static INLINE void
+SVGA_DBG( unsigned flag, const char *fmt, ... )
+{
+#ifdef DEBUG 
+    if (SVGA_DEBUG & flag)
+    {
+        va_list args;
+
+        va_start( args, fmt );
+        debug_vprintf( fmt, args );
+        va_end( args );
+    }
+#else
+    (void)flag;
+    (void)fmt;
+#endif
+}
+
+
+#endif
diff --git a/src/gallium/drivers/svga/svga_draw.c b/src/gallium/drivers/svga/svga_draw.c
new file mode 100644
index 0000000..ca73cf9
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_draw.c
@@ -0,0 +1,378 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "pipe/p_inlines.h"
+#include "pipe/p_defines.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "svga_context.h"
+#include "svga_draw.h"
+#include "svga_draw_private.h"
+#include "svga_debug.h"
+#include "svga_screen.h"
+#include "svga_screen_buffer.h"
+#include "svga_screen_texture.h"
+#include "svga_winsys.h"
+#include "svga_cmd.h"
+
+
+struct svga_hwtnl *svga_hwtnl_create( struct svga_context *svga,
+                                      struct u_upload_mgr *upload_ib,
+                                      struct svga_winsys_context *swc )
+{
+   struct svga_hwtnl *hwtnl = CALLOC_STRUCT(svga_hwtnl);
+   if (hwtnl == NULL)
+      goto fail;
+
+   hwtnl->svga = svga;
+   hwtnl->upload_ib = upload_ib;
+   
+   hwtnl->cmd.swc = swc;
+
+   return hwtnl;
+
+fail:
+   return NULL;
+}
+
+void svga_hwtnl_destroy( struct svga_hwtnl *hwtnl )
+{
+   int i, j;
+
+   for (i = 0; i < PIPE_PRIM_MAX; i++) {
+      for (j = 0; j < IDX_CACHE_MAX; j++) {
+         pipe_buffer_reference( &hwtnl->index_cache[i][j].buffer,
+                                NULL );
+      }
+   }
+
+   for (i = 0; i < hwtnl->cmd.vdecl_count; i++)
+      pipe_buffer_reference(&hwtnl->cmd.vdecl_vb[i], NULL);
+
+   for (i = 0; i < hwtnl->cmd.prim_count; i++)
+      pipe_buffer_reference(&hwtnl->cmd.prim_ib[i], NULL);
+      
+
+   FREE(hwtnl);
+}
+
+
+void svga_hwtnl_set_flatshade( struct svga_hwtnl *hwtnl,
+                               boolean flatshade,
+                               boolean flatshade_first )
+{
+   hwtnl->hw_pv = PV_FIRST;
+   hwtnl->api_pv = (flatshade && !flatshade_first) ? PV_LAST : PV_FIRST;
+}                               
+
+void svga_hwtnl_set_unfilled( struct svga_hwtnl *hwtnl,
+                              unsigned mode )
+{
+   hwtnl->api_fillmode = mode;
+}                               
+
+void svga_hwtnl_reset_vdecl( struct svga_hwtnl *hwtnl,
+                             unsigned count )
+{
+   unsigned i;
+
+   assert(hwtnl->cmd.prim_count == 0);
+
+   for (i = count; i < hwtnl->cmd.vdecl_count; i++) {
+      pipe_buffer_reference(&hwtnl->cmd.vdecl_vb[i],
+                            NULL);
+   }
+
+   hwtnl->cmd.vdecl_count = count;
+}
+
+
+void svga_hwtnl_vdecl( struct svga_hwtnl *hwtnl,
+                          unsigned i,
+                          const SVGA3dVertexDecl *decl,
+                          struct pipe_buffer *vb)
+{
+   assert(hwtnl->cmd.prim_count == 0);
+
+   assert( i < hwtnl->cmd.vdecl_count );
+
+   hwtnl->cmd.vdecl[i] = *decl;
+
+   pipe_buffer_reference(&hwtnl->cmd.vdecl_vb[i],
+                         vb);   
+}
+
+
+
+enum pipe_error
+svga_hwtnl_flush( struct svga_hwtnl *hwtnl )
+{
+   struct svga_winsys_context *swc = hwtnl->cmd.swc;
+   struct svga_context *svga = hwtnl->svga;
+   enum pipe_error ret;
+
+   if (hwtnl->cmd.prim_count) {
+      struct svga_winsys_surface *vb_handle[SVGA3D_INPUTREG_MAX];
+      struct svga_winsys_surface *ib_handle[QSZ];
+      struct svga_winsys_surface *handle;
+      SVGA3dVertexDecl *vdecl;
+      SVGA3dPrimitiveRange *prim;
+      unsigned i;
+
+      for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
+         handle = svga_buffer_handle(svga, hwtnl->cmd.vdecl_vb[i]);
+         if (handle == NULL)
+            return PIPE_ERROR_OUT_OF_MEMORY;
+
+         vb_handle[i] = handle;
+      }
+
+      for (i = 0; i < hwtnl->cmd.prim_count; i++) {
+         if (hwtnl->cmd.prim_ib[i]) {
+            handle = svga_buffer_handle(svga, hwtnl->cmd.prim_ib[i]);
+            if (handle == NULL)
+               return PIPE_ERROR_OUT_OF_MEMORY;
+         }
+         else
+            handle = NULL;
+
+         ib_handle[i] = handle;
+      }
+
+      SVGA_DBG(DEBUG_DMA, "draw to sid %p, %d prims\n",
+               svga->curr.framebuffer.cbufs[0] ?
+               svga_surface(svga->curr.framebuffer.cbufs[0])->handle : NULL,
+               hwtnl->cmd.prim_count);
+
+      ret = SVGA3D_BeginDrawPrimitives(swc, 
+                                       &vdecl, 
+                                       hwtnl->cmd.vdecl_count, 
+                                       &prim, 
+                                       hwtnl->cmd.prim_count);
+      if (ret != PIPE_OK) 
+         return ret;
+
+      
+      memcpy( vdecl,
+              hwtnl->cmd.vdecl,
+              hwtnl->cmd.vdecl_count * sizeof hwtnl->cmd.vdecl[0]);
+
+      for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
+         /* Given rangeHint is considered to be relative to indexBias, and 
+          * indexBias varies per primitive, we cannot accurately supply an 
+          * rangeHint when emitting more than one primitive per draw command.
+          */
+         if (hwtnl->cmd.prim_count == 1) {
+            vdecl[i].rangeHint.first = hwtnl->cmd.min_index[0];
+            vdecl[i].rangeHint.last = hwtnl->cmd.max_index[0] + 1;
+         }
+         else {
+            vdecl[i].rangeHint.first = 0;
+            vdecl[i].rangeHint.last = 0;
+         }
+
+         swc->surface_relocation(swc,
+                                 &vdecl[i].array.surfaceId,
+                                 vb_handle[i],
+                                 PIPE_BUFFER_USAGE_GPU_READ);
+      }
+
+      memcpy( prim,
+              hwtnl->cmd.prim,
+              hwtnl->cmd.prim_count * sizeof hwtnl->cmd.prim[0]);
+
+      for (i = 0; i < hwtnl->cmd.prim_count; i++) {
+         swc->surface_relocation(swc,
+                                 &prim[i].indexArray.surfaceId,
+                                 ib_handle[i],
+                                 PIPE_BUFFER_USAGE_GPU_READ);
+         pipe_buffer_reference(&hwtnl->cmd.prim_ib[i], NULL);
+      }
+      
+      SVGA_FIFOCommitAll( swc );
+      hwtnl->cmd.prim_count = 0;
+   }
+
+   return PIPE_OK;
+}
+
+
+
+
+
+/***********************************************************************
+ * Internal functions:
+ */
+
+enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
+                                 const SVGA3dPrimitiveRange *range,
+                                 unsigned min_index,
+                                 unsigned max_index,
+                                 struct pipe_buffer *ib )
+{
+   int ret = PIPE_OK;
+
+#ifdef DEBUG
+   {
+      unsigned i;
+      for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
+         struct pipe_buffer *vb = hwtnl->cmd.vdecl_vb[i];
+         unsigned size = vb ? vb->size : 0;
+         unsigned offset = hwtnl->cmd.vdecl[i].array.offset;
+         unsigned stride = hwtnl->cmd.vdecl[i].array.stride;
+         unsigned index_bias = range->indexBias;
+         unsigned width;
+
+         assert(vb);
+         assert(size);
+         assert(offset < size);
+         assert(index_bias >= 0);
+         assert(min_index <= max_index);
+         assert(offset + index_bias*stride < size);
+         assert(offset + (index_bias + min_index)*stride < size);
+
+         switch (hwtnl->cmd.vdecl[i].identity.type) {
+         case SVGA3D_DECLTYPE_FLOAT1:
+            width = 4;
+            break;
+         case SVGA3D_DECLTYPE_FLOAT2:
+            width = 4*2;
+            break;
+         case SVGA3D_DECLTYPE_FLOAT3:
+            width = 4*3;
+            break;
+         case SVGA3D_DECLTYPE_FLOAT4:
+            width = 4*4;
+            break;
+         case SVGA3D_DECLTYPE_D3DCOLOR:
+            width = 4;
+            break;
+         case SVGA3D_DECLTYPE_UBYTE4:
+            width = 1*4;
+            break;
+         case SVGA3D_DECLTYPE_SHORT2:
+            width = 2*2;
+            break;
+         case SVGA3D_DECLTYPE_SHORT4:
+            width = 2*4;
+            break;
+         case SVGA3D_DECLTYPE_UBYTE4N:
+            width = 1*4;
+            break;
+         case SVGA3D_DECLTYPE_SHORT2N:
+            width = 2*2;
+            break;
+         case SVGA3D_DECLTYPE_SHORT4N:
+            width = 2*4;
+            break;
+         case SVGA3D_DECLTYPE_USHORT2N:
+            width = 2*2;
+            break;
+         case SVGA3D_DECLTYPE_USHORT4N:
+            width = 2*4;
+            break;
+         case SVGA3D_DECLTYPE_UDEC3:
+            width = 4;
+            break;
+         case SVGA3D_DECLTYPE_DEC3N:
+            width = 4;
+            break;
+         case SVGA3D_DECLTYPE_FLOAT16_2:
+            width = 2*2;
+            break;
+         case SVGA3D_DECLTYPE_FLOAT16_4:
+            width = 2*4;
+            break;
+         default:
+            assert(0);
+            width = 0;
+            break;
+         }
+
+         assert(!stride || width <= stride);
+         assert(offset + (index_bias + max_index)*stride + width <= size);
+      }
+
+      assert(range->indexWidth == range->indexArray.stride);
+
+      if(ib) {
+         unsigned size = ib->size;
+         unsigned offset = range->indexArray.offset;
+         unsigned stride = range->indexArray.stride;
+         unsigned count;
+
+         assert(size);
+         assert(offset < size);
+         assert(stride);
+
+         switch (range->primType) {
+         case SVGA3D_PRIMITIVE_POINTLIST:
+            count = range->primitiveCount;
+            break;
+         case SVGA3D_PRIMITIVE_LINELIST:
+            count = range->primitiveCount * 2;
+            break;
+         case SVGA3D_PRIMITIVE_LINESTRIP:
+            count = range->primitiveCount + 1;
+            break;
+         case SVGA3D_PRIMITIVE_TRIANGLELIST:
+            count = range->primitiveCount * 3;
+            break;
+         case SVGA3D_PRIMITIVE_TRIANGLESTRIP:
+            count = range->primitiveCount + 2;
+            break;
+         case SVGA3D_PRIMITIVE_TRIANGLEFAN:
+            count = range->primitiveCount + 2;
+            break;
+         default:
+            assert(0);
+            count = 0;
+            break;
+         }
+
+         assert(offset + count*stride <= size);
+      }
+   }
+#endif
+
+   if (hwtnl->cmd.prim_count+1 >= QSZ) {
+      ret = svga_hwtnl_flush( hwtnl );
+      if (ret != PIPE_OK)
+         return ret;
+   }
+   
+   /* min/max indices are relative to bias */
+   hwtnl->cmd.min_index[hwtnl->cmd.prim_count] = min_index;
+   hwtnl->cmd.max_index[hwtnl->cmd.prim_count] = max_index;
+
+   hwtnl->cmd.prim[hwtnl->cmd.prim_count] = *range;
+
+   pipe_buffer_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib);
+   hwtnl->cmd.prim_count++;
+
+   return ret;
+}
diff --git a/src/gallium/drivers/svga/svga_draw.h b/src/gallium/drivers/svga/svga_draw.h
new file mode 100644
index 0000000..14553b1
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_draw.h
@@ -0,0 +1,83 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_DRAW_H
+#define SVGA_DRAW_H
+
+#include "pipe/p_compiler.h"
+
+#include "svga_hw_reg.h"
+
+struct svga_hwtnl;
+struct svga_winsys_context;
+struct svga_screen;
+struct svga_context;
+struct pipe_buffer;
+struct u_upload_mgr;
+
+struct svga_hwtnl *svga_hwtnl_create( struct svga_context *svga,
+                                      struct u_upload_mgr *upload_ib,
+                                      struct svga_winsys_context *swc );
+
+void svga_hwtnl_destroy( struct svga_hwtnl *hwtnl );
+
+void svga_hwtnl_set_flatshade( struct svga_hwtnl *hwtnl,
+                               boolean flatshade,
+                               boolean flatshade_first );
+
+void svga_hwtnl_set_unfilled( struct svga_hwtnl *hwtnl,
+                              unsigned mode );
+
+void svga_hwtnl_vdecl( struct svga_hwtnl *hwtnl,
+                       unsigned i,
+                       const SVGA3dVertexDecl *decl,
+                       struct pipe_buffer *vb);
+
+void svga_hwtnl_reset_vdecl( struct svga_hwtnl *hwtnl,
+                             unsigned count );
+
+
+enum pipe_error 
+svga_hwtnl_draw_arrays( struct svga_hwtnl *hwtnl,
+                        unsigned prim, 
+                        unsigned start, 
+                        unsigned count);
+
+enum pipe_error
+svga_hwtnl_draw_range_elements( struct svga_hwtnl *hwtnl,
+                                struct pipe_buffer *indexBuffer,
+                                unsigned index_size,
+                                unsigned min_index,
+                                unsigned max_index,
+                                unsigned prim, 
+                                unsigned start, 
+                                unsigned count,
+                                unsigned bias );
+
+enum pipe_error
+svga_hwtnl_flush( struct svga_hwtnl *hwtnl );
+
+
+#endif /* SVGA_DRAW_H_ */
diff --git a/src/gallium/drivers/svga/svga_draw_arrays.c b/src/gallium/drivers/svga/svga_draw_arrays.c
new file mode 100644
index 0000000..75492df
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_draw_arrays.c
@@ -0,0 +1,297 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "svga_cmd.h"
+
+#include "pipe/p_inlines.h"
+#include "util/u_prim.h"
+#include "indices/u_indices.h"
+
+#include "svga_hw_reg.h"
+#include "svga_draw.h"
+#include "svga_draw_private.h"
+#include "svga_context.h"
+
+
+#define DBG 0
+
+
+
+
+static enum pipe_error generate_indices( struct svga_hwtnl *hwtnl,
+                                         unsigned nr,
+                                         unsigned index_size,
+                                         u_generate_func generate,
+                                         struct pipe_buffer **out_buf )
+{
+   struct pipe_screen *screen = hwtnl->svga->pipe.screen;
+   unsigned size = index_size * nr;
+   struct pipe_buffer *dst = NULL;
+   void *dst_map = NULL;
+
+   dst = screen->buffer_create( screen, 32, 
+                                PIPE_BUFFER_USAGE_INDEX |
+                                PIPE_BUFFER_USAGE_CPU_WRITE |
+                                PIPE_BUFFER_USAGE_GPU_READ, 
+                                size );
+   if (dst == NULL)
+      goto fail;
+
+   dst_map = pipe_buffer_map( screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE );
+   if (dst_map == NULL)
+      goto fail;
+
+   generate( nr,
+             dst_map );
+
+   pipe_buffer_unmap( screen, dst );
+
+   *out_buf = dst;
+   return PIPE_OK;
+
+fail:
+   if (dst_map)
+      screen->buffer_unmap( screen, dst );
+
+   if (dst)
+      screen->buffer_destroy( dst );
+
+   return PIPE_ERROR_OUT_OF_MEMORY;
+}
+
+static boolean compare( unsigned cached_nr,
+                        unsigned nr,
+                        unsigned type )
+{
+   if (type == U_GENERATE_REUSABLE)
+      return cached_nr >= nr;
+   else
+      return cached_nr == nr;
+}
+
+static enum pipe_error retrieve_or_generate_indices( struct svga_hwtnl *hwtnl,
+                                                     unsigned prim,
+                                                     unsigned gen_type,
+                                                     unsigned gen_nr,
+                                                     unsigned gen_size,
+                                                     u_generate_func generate,
+                                                     struct pipe_buffer **out_buf )
+{
+   enum pipe_error ret = PIPE_OK;
+   int i;
+
+   for (i = 0; i < IDX_CACHE_MAX; i++) {
+      if (hwtnl->index_cache[prim][i].buffer != NULL &&
+          hwtnl->index_cache[prim][i].generate == generate)
+      {
+         if (compare(hwtnl->index_cache[prim][i].gen_nr, gen_nr, gen_type))
+         {
+            pipe_buffer_reference( out_buf,
+                                   hwtnl->index_cache[prim][i].buffer );
+
+            if (DBG) 
+               debug_printf("%s retrieve %d/%d\n", __FUNCTION__, i, gen_nr);
+
+            return PIPE_OK;
+         }
+         else if (gen_type == U_GENERATE_REUSABLE) 
+         {
+            pipe_buffer_reference( &hwtnl->index_cache[prim][i].buffer,
+                                   NULL );
+
+            if (DBG) 
+               debug_printf("%s discard %d/%d\n", __FUNCTION__, 
+                            i, hwtnl->index_cache[prim][i].gen_nr);
+
+            break;
+         }
+      }
+   }
+
+   if (i == IDX_CACHE_MAX)
+   {
+      unsigned smallest = 0;
+      unsigned smallest_size = ~0;
+      
+      for (i = 0; i < IDX_CACHE_MAX && smallest_size; i++) {
+         if (hwtnl->index_cache[prim][i].buffer == NULL)
+         {
+            smallest = i;
+            smallest_size = 0;
+         }
+         else if (hwtnl->index_cache[prim][i].gen_nr < smallest)
+         {
+            smallest = i;
+            smallest_size = hwtnl->index_cache[prim][i].gen_nr;
+         }
+      }
+
+      assert (smallest != IDX_CACHE_MAX);
+
+      pipe_buffer_reference( &hwtnl->index_cache[prim][smallest].buffer,
+                             NULL );
+
+      if (DBG)
+         debug_printf("%s discard smallest %d/%d\n", __FUNCTION__, 
+                      smallest, smallest_size);
+      
+      i = smallest;
+   }
+      
+      
+   ret = generate_indices( hwtnl, 
+                           gen_nr,
+                           gen_size,
+                           generate,
+                           out_buf );
+   if (ret != PIPE_OK)
+      return ret;
+
+
+   hwtnl->index_cache[prim][i].generate = generate;
+   hwtnl->index_cache[prim][i].gen_nr = gen_nr;
+   pipe_buffer_reference( &hwtnl->index_cache[prim][i].buffer,
+                          *out_buf );
+
+   if (DBG)
+      debug_printf("%s cache %d/%d\n", __FUNCTION__, 
+                   i, hwtnl->index_cache[prim][i].gen_nr);
+
+   return PIPE_OK;
+}
+
+
+
+static enum pipe_error
+simple_draw_arrays( struct svga_hwtnl *hwtnl,
+                    unsigned prim, unsigned start, unsigned count )
+{
+   SVGA3dPrimitiveRange range;
+   unsigned hw_prim;
+   unsigned hw_count;
+
+   hw_prim = svga_translate_prim(prim, count, &hw_count);
+   if (hw_count == 0)
+      return PIPE_ERROR_BAD_INPUT;
+      
+   range.primType = hw_prim;
+   range.primitiveCount = hw_count;
+   range.indexArray.surfaceId = SVGA3D_INVALID_ID;
+   range.indexArray.offset = 0;
+   range.indexArray.stride = 0;
+   range.indexWidth = 0;
+   range.indexBias = start;
+
+   /* Min/max index should be calculated prior to applying bias, so we
+    * end up with min_index = 0, max_index = count - 1 and everybody
+    * looking at those numbers knows to adjust them by
+    * range.indexBias.
+    */
+   return svga_hwtnl_prim( hwtnl, &range, 0, count - 1, NULL );
+}
+
+
+
+
+
+
+
+
+
+
+enum pipe_error 
+svga_hwtnl_draw_arrays( struct svga_hwtnl *hwtnl,
+                        unsigned prim, 
+                        unsigned start, 
+                        unsigned count)
+{
+   unsigned gen_prim, gen_size, gen_nr, gen_type;
+   u_generate_func gen_func;
+   enum pipe_error ret = PIPE_OK;
+
+   if (hwtnl->api_fillmode != PIPE_POLYGON_MODE_FILL && 
+       prim >= PIPE_PRIM_TRIANGLES) 
+   {
+      gen_type = u_unfilled_generator( prim,
+                                       start,
+                                       count,
+                                       hwtnl->api_fillmode,
+                                       &gen_prim,
+                                       &gen_size,
+                                       &gen_nr,
+                                       &gen_func );
+   }
+   else {
+      gen_type = u_index_generator( svga_hw_prims,
+                                    prim,
+                                    start,
+                                    count,
+                                    hwtnl->api_pv,
+                                    hwtnl->hw_pv,
+                                    &gen_prim,
+                                    &gen_size,
+                                    &gen_nr,
+                                    &gen_func );
+   }
+
+   if (gen_type == U_GENERATE_LINEAR) {
+      return simple_draw_arrays( hwtnl, gen_prim, start, count );
+   }
+   else {
+      struct pipe_buffer *gen_buf = NULL;
+
+      /* Need to draw as indexed primitive. 
+       * Potentially need to run the gen func to build an index buffer.
+       */
+      ret = retrieve_or_generate_indices( hwtnl,
+                                          prim,
+                                          gen_type,
+                                          gen_nr,
+                                          gen_size,
+                                          gen_func,
+                                          &gen_buf );
+      if (ret)
+         goto done;
+
+      ret = svga_hwtnl_simple_draw_range_elements( hwtnl,
+                                                   gen_buf,
+                                                   gen_size,
+                                                   0,
+                                                   count - 1,
+                                                   gen_prim,
+                                                   0,
+                                                   gen_nr,
+                                                   start );
+      if (ret)
+         goto done;
+
+   done:
+      if (gen_buf)
+         pipe_buffer_reference( &gen_buf, NULL );
+
+      return ret;
+   }
+}
+
diff --git a/src/gallium/drivers/svga/svga_draw_elements.c b/src/gallium/drivers/svga/svga_draw_elements.c
new file mode 100644
index 0000000..167d817
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_draw_elements.c
@@ -0,0 +1,255 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_inlines.h"
+#include "util/u_prim.h"
+#include "util/u_upload_mgr.h"
+#include "indices/u_indices.h"
+
+#include "svga_cmd.h"
+#include "svga_draw.h"
+#include "svga_draw_private.h"
+#include "svga_screen_buffer.h"
+#include "svga_winsys.h"
+#include "svga_context.h"
+
+#include "svga_hw_reg.h"
+
+
+static enum pipe_error
+translate_indices( struct svga_hwtnl *hwtnl,
+                   struct pipe_buffer *src,
+                   unsigned offset,
+                   unsigned nr,
+                   unsigned index_size,
+                   u_translate_func translate,
+                   struct pipe_buffer **out_buf )
+{
+   struct pipe_screen *screen = hwtnl->svga->pipe.screen;
+   unsigned size = index_size * nr;
+   const void *src_map = NULL;
+   struct pipe_buffer *dst = NULL;
+   void *dst_map = NULL;
+
+   dst = screen->buffer_create( screen, 32, 
+                                PIPE_BUFFER_USAGE_INDEX |
+                                PIPE_BUFFER_USAGE_CPU_WRITE |
+                                PIPE_BUFFER_USAGE_GPU_READ, 
+                                size );
+   if (dst == NULL)
+      goto fail;
+
+   src_map = pipe_buffer_map( screen, src, PIPE_BUFFER_USAGE_CPU_READ );
+   if (src_map == NULL)
+      goto fail;
+
+   dst_map = pipe_buffer_map( screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE );
+   if (dst_map == NULL)
+      goto fail;
+
+   translate( (const char *)src_map + offset,
+              nr,
+              dst_map );
+
+   pipe_buffer_unmap( screen, src );
+   pipe_buffer_unmap( screen, dst );
+
+   *out_buf = dst;
+   return PIPE_OK;
+
+fail:
+   if (src_map)
+      screen->buffer_unmap( screen, src );
+
+   if (dst_map)
+      screen->buffer_unmap( screen, dst );
+
+   if (dst)
+      screen->buffer_destroy( dst );
+
+   return PIPE_ERROR_OUT_OF_MEMORY;
+}
+
+
+
+
+
+enum pipe_error
+svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl,
+                                       struct pipe_buffer *index_buffer,
+                                       unsigned index_size,
+                                       unsigned min_index,
+                                       unsigned max_index,
+                                       unsigned prim, 
+                                       unsigned start,
+                                       unsigned count,
+                                       unsigned bias )
+{
+   struct pipe_buffer *upload_buffer = NULL;
+   SVGA3dPrimitiveRange range;
+   unsigned hw_prim;
+   unsigned hw_count;
+   unsigned index_offset = start * index_size;
+   int ret = PIPE_OK;
+
+   hw_prim = svga_translate_prim(prim, count, &hw_count);
+   if (hw_count == 0)
+      goto done;
+
+   if (index_buffer && 
+       svga_buffer_is_user_buffer(index_buffer)) 
+   {
+      assert( index_buffer->size >= index_offset + count * index_size );
+
+      ret = u_upload_buffer( hwtnl->upload_ib,
+                             index_offset,
+                             count * index_size,
+                             index_buffer,
+                             &index_offset,
+                             &upload_buffer );
+      if (ret)
+         goto done;
+
+      /* Don't need to worry about refcounting index_buffer as this is
+       * just a stack variable without a counted reference of its own.
+       * The caller holds the reference.
+       */
+      index_buffer = upload_buffer;
+   }
+
+   range.primType = hw_prim;
+   range.primitiveCount = hw_count;
+   range.indexArray.offset = index_offset;
+   range.indexArray.stride = index_size;
+   range.indexWidth = index_size;
+   range.indexBias = bias;
+      
+   ret = svga_hwtnl_prim( hwtnl, &range, min_index, max_index, index_buffer );
+   if (ret)
+      goto done;
+
+done:
+   if (upload_buffer)
+      pipe_buffer_reference( &upload_buffer, NULL );
+
+   return ret;
+}
+
+
+
+
+enum pipe_error
+svga_hwtnl_draw_range_elements( struct svga_hwtnl *hwtnl,
+                                struct pipe_buffer *index_buffer,
+                                unsigned index_size,
+                                unsigned min_index,
+                                unsigned max_index,
+                                unsigned prim, unsigned start, unsigned count,
+                                unsigned bias)
+{
+   unsigned gen_prim, gen_size, gen_nr, gen_type;
+   u_translate_func gen_func;
+   enum pipe_error ret = PIPE_OK;
+
+   if (hwtnl->api_fillmode != PIPE_POLYGON_MODE_FILL && 
+       prim >= PIPE_PRIM_TRIANGLES) 
+   {
+      gen_type = u_unfilled_translator( prim,
+                                        index_size,
+                                        count,
+                                        hwtnl->api_fillmode,
+                                        &gen_prim,
+                                        &gen_size,
+                                        &gen_nr,
+                                        &gen_func );
+   }
+   else
+   {
+      gen_type = u_index_translator( svga_hw_prims,
+                                     prim,
+                                     index_size,
+                                     count,
+                                     hwtnl->api_pv,
+                                     hwtnl->hw_pv,
+                                     &gen_prim,
+                                     &gen_size,
+                                     &gen_nr,
+                                     &gen_func );
+   }
+
+   
+   if (gen_type == U_TRANSLATE_MEMCPY) {
+      /* No need for translation, just pass through to hardware: 
+       */
+      return svga_hwtnl_simple_draw_range_elements( hwtnl, index_buffer,
+                                                    index_size,
+                                                    min_index,
+                                                    max_index,
+                                                    gen_prim, start, count, bias );
+   }
+   else {
+      struct pipe_buffer *gen_buf = NULL;
+
+      /* Need to allocate a new index buffer and run the translate
+       * func to populate it.  Could potentially cache this translated
+       * index buffer with the original to avoid future
+       * re-translations.  Not much point if we're just accelerating
+       * GL though, as index buffers are typically used only once
+       * there.
+       */
+      ret = translate_indices( hwtnl,
+                               index_buffer,
+                               start * index_size,
+                               gen_nr,
+                               gen_size,
+                               gen_func,
+                               &gen_buf );
+      if (ret)
+         goto done;
+
+      ret = svga_hwtnl_simple_draw_range_elements( hwtnl,
+                                                   gen_buf,
+                                                   gen_size,
+                                                   min_index,
+                                                   max_index,
+                                                   gen_prim,
+                                                   0,
+                                                   gen_nr,
+                                                   bias );
+      if (ret)
+         goto done;
+
+   done:
+      if (gen_buf)
+         pipe_buffer_reference( &gen_buf, NULL );
+
+      return ret;
+   }
+}
+
+
+
+
+
diff --git a/src/gallium/drivers/svga/svga_draw_private.h b/src/gallium/drivers/svga/svga_draw_private.h
new file mode 100644
index 0000000..9aa40e1
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_draw_private.h
@@ -0,0 +1,158 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_DRAW_H_
+#define SVGA_DRAW_H_
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_defines.h"
+#include "indices/u_indices.h"
+#include "svga_hw_reg.h"
+#include "svga3d_shaderdefs.h"
+
+struct svga_context;
+struct u_upload_mgr;
+
+/* Should include polygon?
+ */
+static const unsigned svga_hw_prims = 
+   ((1 << PIPE_PRIM_POINTS) |
+    (1 << PIPE_PRIM_LINES) |
+    (1 << PIPE_PRIM_LINE_STRIP) |
+    (1 << PIPE_PRIM_TRIANGLES) |
+    (1 << PIPE_PRIM_TRIANGLE_STRIP) |
+    (1 << PIPE_PRIM_TRIANGLE_FAN));
+
+
+static INLINE unsigned svga_translate_prim(unsigned mode, 
+                                           unsigned count,
+                                           unsigned *out_count)
+{
+   switch (mode) {
+   case PIPE_PRIM_POINTS:
+      *out_count = count;
+      return SVGA3D_PRIMITIVE_POINTLIST;
+
+   case PIPE_PRIM_LINES:
+      *out_count = count / 2;
+      return SVGA3D_PRIMITIVE_LINELIST; 
+
+   case PIPE_PRIM_LINE_STRIP:
+      *out_count = count - 1;
+      return SVGA3D_PRIMITIVE_LINESTRIP; 
+
+   case PIPE_PRIM_TRIANGLES:
+      *out_count = count / 3;
+      return SVGA3D_PRIMITIVE_TRIANGLELIST; 
+
+   case PIPE_PRIM_TRIANGLE_STRIP:
+      *out_count = count - 2;
+      return SVGA3D_PRIMITIVE_TRIANGLESTRIP; 
+
+   case PIPE_PRIM_TRIANGLE_FAN:
+      *out_count = count - 2;
+      return SVGA3D_PRIMITIVE_TRIANGLEFAN; 
+
+   default:
+      assert(0);
+      *out_count = 0;
+      return 0;
+   }
+}
+
+
+struct index_cache {
+   u_generate_func generate;
+   unsigned gen_nr;
+
+   /* If non-null, this buffer is filled by calling 
+    *   generate(nr, map(buffer))
+    */
+   struct pipe_buffer *buffer;
+};
+
+#define QSZ 32
+
+struct draw_cmd {
+   struct svga_winsys_context *swc;
+
+   SVGA3dVertexDecl vdecl[SVGA3D_INPUTREG_MAX];
+   struct pipe_buffer *vdecl_vb[SVGA3D_INPUTREG_MAX];
+   unsigned vdecl_count;
+
+   SVGA3dPrimitiveRange prim[QSZ];
+   struct pipe_buffer *prim_ib[QSZ];
+   unsigned prim_count;
+   unsigned min_index[QSZ];
+   unsigned max_index[QSZ];
+};
+
+#define IDX_CACHE_MAX  8
+
+struct svga_hwtnl {
+   struct svga_context *svga;
+   struct u_upload_mgr *upload_ib;
+   
+   /* Flatshade information:
+    */
+   unsigned api_pv;
+   unsigned hw_pv;
+   unsigned api_fillmode;
+
+   /* Cache the results of running a particular generate func on each
+    * primitive type.
+    */
+   struct index_cache index_cache[PIPE_PRIM_MAX][IDX_CACHE_MAX];
+
+   /* Try to build the maximal draw command packet before emitting:
+    */
+   struct draw_cmd cmd;
+};
+
+
+
+/***********************************************************************
+ * Internal functions
+ */
+enum pipe_error 
+svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
+                 const SVGA3dPrimitiveRange *range,
+                 unsigned min_index,
+                 unsigned max_index,
+                 struct pipe_buffer *ib );
+
+enum pipe_error
+svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl,
+                                       struct pipe_buffer *indexBuffer,
+                                       unsigned index_size,
+                                       unsigned min_index,
+                                       unsigned max_index,
+                                       unsigned prim, 
+                                       unsigned start,
+                                       unsigned count,
+                                       unsigned bias );
+
+
+#endif
diff --git a/src/gallium/drivers/svga/svga_hw_reg.h b/src/gallium/drivers/svga/svga_hw_reg.h
new file mode 100644
index 0000000..183f4b9
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_hw_reg.h
@@ -0,0 +1,42 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_HW_REG_H
+#define SVGA_HW_REG_H
+
+#include "pipe/p_compiler.h"
+
+#if defined(PIPE_CC_GCC)
+#ifndef HAVE_STDINT_H
+#define HAVE_STDINT_H
+#endif
+#endif
+
+#include "svga_types.h"
+
+#include "svga3d_reg.h"
+
+
+#endif
diff --git a/src/gallium/drivers/svga/svga_pipe_blend.c b/src/gallium/drivers/svga/svga_pipe_blend.c
new file mode 100644
index 0000000..855d228
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_pipe_blend.c
@@ -0,0 +1,246 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_inlines.h"
+#include "pipe/p_defines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "svga_context.h"
+#include "svga_state.h"
+
+#include "svga_hw_reg.h"
+
+
+static INLINE unsigned
+svga_translate_blend_factor(unsigned factor)
+{
+   switch (factor) {
+   case PIPE_BLENDFACTOR_ZERO:            return SVGA3D_BLENDOP_ZERO;
+   case PIPE_BLENDFACTOR_SRC_ALPHA:       return SVGA3D_BLENDOP_SRCALPHA;
+   case PIPE_BLENDFACTOR_ONE:             return SVGA3D_BLENDOP_ONE;
+   case PIPE_BLENDFACTOR_SRC_COLOR:       return SVGA3D_BLENDOP_SRCCOLOR;
+   case PIPE_BLENDFACTOR_INV_SRC_COLOR:   return SVGA3D_BLENDOP_INVSRCCOLOR;
+   case PIPE_BLENDFACTOR_DST_COLOR:       return SVGA3D_BLENDOP_DESTCOLOR;
+   case PIPE_BLENDFACTOR_INV_DST_COLOR:   return SVGA3D_BLENDOP_INVDESTCOLOR;
+   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:   return SVGA3D_BLENDOP_INVSRCALPHA;
+   case PIPE_BLENDFACTOR_DST_ALPHA:       return SVGA3D_BLENDOP_DESTALPHA;
+   case PIPE_BLENDFACTOR_INV_DST_ALPHA:   return SVGA3D_BLENDOP_INVDESTALPHA;
+   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return SVGA3D_BLENDOP_SRCALPHASAT;
+   case PIPE_BLENDFACTOR_CONST_COLOR:     return SVGA3D_BLENDOP_BLENDFACTOR;
+   case PIPE_BLENDFACTOR_INV_CONST_COLOR: return SVGA3D_BLENDOP_INVBLENDFACTOR;
+   case PIPE_BLENDFACTOR_CONST_ALPHA:     return SVGA3D_BLENDOP_BLENDFACTOR; /* ? */
+   case PIPE_BLENDFACTOR_INV_CONST_ALPHA: return SVGA3D_BLENDOP_INVBLENDFACTOR; /* ? */
+   default:
+      assert(0);
+      return SVGA3D_BLENDOP_ZERO;
+   }
+}
+
+static INLINE unsigned
+svga_translate_blend_func(unsigned mode)
+{
+   switch (mode) {
+   case PIPE_BLEND_ADD:              return SVGA3D_BLENDEQ_ADD;
+   case PIPE_BLEND_SUBTRACT:         return SVGA3D_BLENDEQ_SUBTRACT;
+   case PIPE_BLEND_REVERSE_SUBTRACT: return SVGA3D_BLENDEQ_REVSUBTRACT;
+   case PIPE_BLEND_MIN:              return SVGA3D_BLENDEQ_MINIMUM;
+   case PIPE_BLEND_MAX:              return SVGA3D_BLENDEQ_MAXIMUM;
+   default:
+      assert(0);
+      return SVGA3D_BLENDEQ_ADD;
+   }
+}
+
+
+static void *
+svga_create_blend_state(struct pipe_context *pipe,
+                        const struct pipe_blend_state *templ)
+{
+   struct svga_blend_state *blend = CALLOC_STRUCT( svga_blend_state );
+   unsigned i;
+
+ 
+   /* Fill in the per-rendertarget blend state.  We currently only
+    * have one rendertarget.
+    */
+   for (i = 0; i < 1; i++) {
+      /* No way to set this in SVGA3D, and no way to correctly implement it on
+       * top of D3D9 API.  Instead we try to simulate with various blend modes.
+       */
+      if (templ->logicop_enable) {
+         switch (templ->logicop_func) {
+         case PIPE_LOGICOP_XOR:
+            blend->need_white_fragments = TRUE;
+            blend->rt[i].blend_enable = TRUE;
+            blend->rt[i].srcblend       = SVGA3D_BLENDOP_ONE;
+            blend->rt[i].dstblend       = SVGA3D_BLENDOP_ONE;
+            blend->rt[i].blendeq        = SVGA3D_BLENDEQ_SUBTRACT;
+            break;
+         case PIPE_LOGICOP_CLEAR:
+            blend->rt[i].blend_enable = TRUE;
+            blend->rt[i].srcblend       = SVGA3D_BLENDOP_ZERO;
+            blend->rt[i].dstblend       = SVGA3D_BLENDOP_ZERO;
+            blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MINIMUM;
+            break;
+         case PIPE_LOGICOP_COPY:
+            blend->rt[i].blend_enable = FALSE;
+            break;
+         case PIPE_LOGICOP_COPY_INVERTED:
+            blend->rt[i].blend_enable   = TRUE;
+            blend->rt[i].srcblend       = SVGA3D_BLENDOP_INVSRCCOLOR;
+            blend->rt[i].dstblend       = SVGA3D_BLENDOP_ZERO;
+            blend->rt[i].blendeq        = SVGA3D_BLENDEQ_ADD;
+            break;
+         case PIPE_LOGICOP_NOOP:
+            blend->rt[i].blend_enable   = TRUE;
+            blend->rt[i].srcblend       = SVGA3D_BLENDOP_ZERO;
+            blend->rt[i].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
+            blend->rt[i].blendeq        = SVGA3D_BLENDEQ_ADD;
+            break;
+         case PIPE_LOGICOP_SET:
+            blend->rt[i].blend_enable = TRUE;
+            blend->rt[i].srcblend       = SVGA3D_BLENDOP_ONE;
+            blend->rt[i].dstblend       = SVGA3D_BLENDOP_ONE;
+            blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
+            break;
+         case PIPE_LOGICOP_INVERT:
+            blend->rt[i].blend_enable = TRUE;
+            blend->rt[i].srcblend       = SVGA3D_BLENDOP_INVSRCCOLOR;
+            blend->rt[i].dstblend       = SVGA3D_BLENDOP_ZERO;
+            blend->rt[i].blendeq        = SVGA3D_BLENDEQ_ADD;
+            break;
+         case PIPE_LOGICOP_AND:
+            /* Approximate with minimum - works for the 0 & anything case: */
+            blend->rt[i].blend_enable = TRUE;
+            blend->rt[i].srcblend       = SVGA3D_BLENDOP_SRCCOLOR;
+            blend->rt[i].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
+            blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MINIMUM;
+            break;
+         case PIPE_LOGICOP_AND_REVERSE:
+            blend->rt[i].blend_enable = TRUE;
+            blend->rt[i].srcblend       = SVGA3D_BLENDOP_SRCCOLOR;
+            blend->rt[i].dstblend       = SVGA3D_BLENDOP_INVDESTCOLOR;
+            blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MINIMUM;
+            break;
+         case PIPE_LOGICOP_AND_INVERTED:
+            blend->rt[i].blend_enable = TRUE;
+            blend->rt[i].srcblend       = SVGA3D_BLENDOP_INVSRCCOLOR;
+            blend->rt[i].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
+            blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MINIMUM;
+            break;
+         case PIPE_LOGICOP_OR:
+            /* Approximate with maximum - works for the 1 | anything case: */
+            blend->rt[i].blend_enable = TRUE;
+            blend->rt[i].srcblend       = SVGA3D_BLENDOP_SRCCOLOR;
+            blend->rt[i].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
+            blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
+            break;
+         case PIPE_LOGICOP_OR_REVERSE:
+            blend->rt[i].blend_enable = TRUE;
+            blend->rt[i].srcblend       = SVGA3D_BLENDOP_SRCCOLOR;
+            blend->rt[i].dstblend       = SVGA3D_BLENDOP_INVDESTCOLOR;
+            blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
+            break;
+         case PIPE_LOGICOP_OR_INVERTED:
+            blend->rt[i].blend_enable = TRUE;
+            blend->rt[i].srcblend       = SVGA3D_BLENDOP_INVSRCCOLOR;
+            blend->rt[i].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
+            blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
+            break;
+         case PIPE_LOGICOP_NAND:
+         case PIPE_LOGICOP_NOR:
+         case PIPE_LOGICOP_EQUIV:
+            /* Fill these in with plausible values */
+            blend->rt[i].blend_enable = FALSE;
+            break;
+         default:
+            assert(0);
+            break;
+         }
+      }
+      else {
+         blend->rt[i].blend_enable   = templ->blend_enable;
+
+         if (templ->blend_enable) {
+            blend->rt[i].srcblend       = svga_translate_blend_factor(templ->rgb_src_factor);
+            blend->rt[i].dstblend       = svga_translate_blend_factor(templ->rgb_dst_factor);
+            blend->rt[i].blendeq        = svga_translate_blend_func(templ->rgb_func);
+            blend->rt[i].srcblend_alpha = svga_translate_blend_factor(templ->alpha_src_factor);
+            blend->rt[i].dstblend_alpha = svga_translate_blend_factor(templ->alpha_dst_factor);
+            blend->rt[i].blendeq_alpha  = svga_translate_blend_func(templ->alpha_func);
+
+            if (blend->rt[i].srcblend_alpha != blend->rt[i].srcblend ||
+                blend->rt[i].dstblend_alpha != blend->rt[i].dstblend ||
+                blend->rt[i].blendeq_alpha  != blend->rt[i].blendeq)
+            {
+               blend->rt[i].separate_alpha_blend_enable = TRUE;
+            }
+         }
+      }
+
+      blend->rt[i].writemask = templ->colormask;
+   }
+
+   return blend;
+}
+
+static void svga_bind_blend_state(struct pipe_context *pipe,
+                                  void *blend)
+{
+   struct svga_context *svga = svga_context(pipe);
+
+   svga->curr.blend = (struct svga_blend_state*)blend;
+   svga->dirty |= SVGA_NEW_BLEND;
+}
+
+
+static void svga_delete_blend_state(struct pipe_context *pipe, void *blend)
+{
+   FREE(blend);
+}
+
+static void svga_set_blend_color( struct pipe_context *pipe,
+                                  const struct pipe_blend_color *blend_color )
+{
+   struct svga_context *svga = svga_context(pipe);
+
+   svga->curr.blend_color = *blend_color;
+
+   svga->dirty |= SVGA_NEW_BLEND;
+}
+
+
+void svga_init_blend_functions( struct svga_context *svga )
+{
+   svga->pipe.create_blend_state = svga_create_blend_state;
+   svga->pipe.bind_blend_state = svga_bind_blend_state;
+   svga->pipe.delete_blend_state = svga_delete_blend_state;
+
+   svga->pipe.set_blend_color = svga_set_blend_color;
+}
+
+
+
diff --git a/src/gallium/drivers/svga/svga_pipe_blit.c b/src/gallium/drivers/svga/svga_pipe_blit.c
new file mode 100644
index 0000000..4f575b0
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_pipe_blit.c
@@ -0,0 +1,92 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "svga_screen_texture.h"
+#include "svga_context.h"
+#include "svga_debug.h"
+#include "svga_cmd.h"
+
+#define FILE_DEBUG_FLAG DEBUG_BLIT
+
+
+static void svga_surface_copy(struct pipe_context *pipe,
+                              struct pipe_surface *dest,
+                              unsigned destx, unsigned desty,
+                              struct pipe_surface *src,
+                              unsigned srcx, unsigned srcy,
+                              unsigned width, unsigned height)
+{
+   struct svga_context *svga = svga_context(pipe);
+   SVGA3dCopyBox *box;
+   enum pipe_error ret;
+
+   svga_hwtnl_flush_retry( svga );
+
+   SVGA_DBG(DEBUG_DMA, "blit to sid %p (%d,%d), from sid %p (%d,%d) sz %dx%d\n",
+            svga_surface(dest)->handle,
+            destx, desty,
+            svga_surface(src)->handle,
+            srcx, srcy,
+            width, height);
+
+   ret = SVGA3D_BeginSurfaceCopy(svga->swc,
+                                 src,
+                                 dest,
+                                 &box,
+                                 1);
+   if(ret != PIPE_OK) {
+
+      svga_context_flush(svga, NULL);
+
+      ret = SVGA3D_BeginSurfaceCopy(svga->swc,
+                                    src,
+                                    dest,
+                                    &box,
+                                    1);
+      assert(ret == PIPE_OK);
+   }
+
+   box->x = destx;
+   box->y = desty;
+   box->z = 0;
+   box->w = width;
+   box->h = height;
+   box->d = 1;
+   box->srcx = srcx;
+   box->srcy = srcy;
+   box->srcz = 0;
+
+   SVGA_FIFOCommitAll(svga->swc);
+
+   svga_surface(dest)->dirty = TRUE;
+   svga_propagate_surface(pipe, dest);
+}
+
+
+void
+svga_init_blit_functions(struct svga_context *svga)
+{
+   svga->pipe.surface_copy = svga_surface_copy;
+}
diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c
new file mode 100644
index 0000000..409b3b4
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_pipe_clear.c
@@ -0,0 +1,125 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "svga_cmd.h"
+#include "svga_debug.h"
+
+#include "pipe/p_defines.h"
+#include "util/u_pack_color.h"
+
+#include "svga_context.h"
+#include "svga_state.h"
+#include "svga_screen_texture.h"
+
+
+static enum pipe_error
+try_clear(struct svga_context *svga, 
+          unsigned buffers,
+          const float *rgba,
+          double depth,
+          unsigned stencil)
+{
+   int ret = PIPE_OK;
+   SVGA3dRect rect = { 0, 0, 0, 0 };
+   boolean restore_viewport = FALSE;
+   SVGA3dClearFlag flags = 0;
+   struct pipe_framebuffer_state *fb = &svga->curr.framebuffer;
+   union util_color uc;
+
+   ret = svga_update_state(svga, SVGA_STATE_HW_CLEAR);
+   if (ret)
+      return ret;
+
+   if ((buffers & PIPE_CLEAR_COLOR) && fb->cbufs[0]) {
+      flags |= SVGA3D_CLEAR_COLOR;
+      util_pack_color(rgba, PIPE_FORMAT_A8R8G8B8_UNORM, &uc);
+
+      rect.w = fb->cbufs[0]->width;
+      rect.h = fb->cbufs[0]->height;
+   }
+
+   if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && fb->zsbuf) {
+      flags |= SVGA3D_CLEAR_DEPTH;
+
+      if (svga->curr.framebuffer.zsbuf->format == PIPE_FORMAT_Z24S8_UNORM)
+         flags |= SVGA3D_CLEAR_STENCIL;
+
+      rect.w = MAX2(rect.w, fb->zsbuf->width);
+      rect.h = MAX2(rect.h, fb->zsbuf->height);
+   }
+
+   if (memcmp(&rect, &svga->state.hw_clear.viewport, sizeof(rect)) != 0) {
+      restore_viewport = TRUE;
+      ret = SVGA3D_SetViewport(svga->swc, &rect);
+      if (ret)
+         return ret;
+   }
+
+   ret = SVGA3D_ClearRect(svga->swc, flags, uc.ui, depth, stencil,
+                          rect.x, rect.y, rect.w, rect.h);
+   if (ret != PIPE_OK)
+      return ret;
+
+   if (restore_viewport) {
+      memcpy(&rect, &svga->state.hw_clear.viewport, sizeof rect);
+      ret = SVGA3D_SetViewport(svga->swc, &rect);
+   }
+   
+   return ret;
+}
+
+/**
+ * Clear the given surface to the specified value.
+ * No masking, no scissor (clear entire buffer).
+ */
+void
+svga_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
+	   double depth, unsigned stencil)
+{
+   struct svga_context *svga = svga_context( pipe );
+   int ret;
+   
+   if (buffers & PIPE_CLEAR_COLOR)
+      SVGA_DBG(DEBUG_DMA, "clear sid %p\n",
+               svga_surface(svga->curr.framebuffer.cbufs[0])->handle);
+
+   ret = try_clear( svga, buffers, rgba, depth, stencil );
+
+   if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
+      /* Flush command buffer and retry:
+       */
+      svga_context_flush( svga, NULL );
+
+      ret = try_clear( svga, buffers, rgba, depth, stencil );
+   }
+
+   /*
+    * Mark target surfaces as dirty
+    * TODO Mark only cleared surfaces.
+    */
+   svga_mark_surfaces_dirty(svga);
+
+   assert (ret == PIPE_OK);
+}
diff --git a/src/gallium/drivers/svga/svga_pipe_constants.c b/src/gallium/drivers/svga/svga_pipe_constants.c
new file mode 100644
index 0000000..10e7a12
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_pipe_constants.c
@@ -0,0 +1,74 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_inlines.h"
+#include "pipe/p_defines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "tgsi/tgsi_parse.h"
+
+#include "svga_context.h"
+#include "svga_state.h"
+#include "svga_hw_reg.h"
+#include "svga_cmd.h"
+
+/***********************************************************************
+ * Constant buffers 
+ */
+
+struct svga_constbuf 
+{
+   unsigned type;
+   float (*data)[4];
+   unsigned count;
+};
+
+
+
+static void svga_set_constant_buffer(struct pipe_context *pipe,
+                                     uint shader, uint index,
+                                     const struct pipe_constant_buffer *buf)
+{
+   struct svga_context *svga = svga_context(pipe);
+
+   assert(shader < PIPE_SHADER_TYPES);
+   assert(index == 0);
+
+   pipe_buffer_reference( &svga->curr.cb[shader],
+                          buf->buffer );
+
+   if (shader == PIPE_SHADER_FRAGMENT)
+      svga->dirty |= SVGA_NEW_FS_CONST_BUFFER;
+   else
+      svga->dirty |= SVGA_NEW_VS_CONST_BUFFER;
+}
+
+
+
+void svga_init_constbuffer_functions( struct svga_context *svga )
+{
+   svga->pipe.set_constant_buffer = svga_set_constant_buffer;
+}
+
diff --git a/src/gallium/drivers/svga/svga_pipe_depthstencil.c b/src/gallium/drivers/svga/svga_pipe_depthstencil.c
new file mode 100644
index 0000000..df636c0
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_pipe_depthstencil.c
@@ -0,0 +1,153 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_inlines.h"
+#include "pipe/p_defines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "svga_context.h"
+#include "svga_state.h"
+#include "svga_hw_reg.h"
+
+
+static INLINE unsigned
+svga_translate_compare_func(unsigned func)
+{
+   switch (func) {
+   case PIPE_FUNC_NEVER:     return SVGA3D_CMP_NEVER;
+   case PIPE_FUNC_LESS:      return SVGA3D_CMP_LESS;
+   case PIPE_FUNC_LEQUAL:    return SVGA3D_CMP_LESSEQUAL;
+   case PIPE_FUNC_GREATER:   return SVGA3D_CMP_GREATER;
+   case PIPE_FUNC_GEQUAL:    return SVGA3D_CMP_GREATEREQUAL;
+   case PIPE_FUNC_NOTEQUAL:  return SVGA3D_CMP_NOTEQUAL;
+   case PIPE_FUNC_EQUAL:     return SVGA3D_CMP_EQUAL;
+   case PIPE_FUNC_ALWAYS:    return SVGA3D_CMP_ALWAYS;
+   default:
+      assert(0);
+      return SVGA3D_CMP_ALWAYS;
+   }
+}
+
+static INLINE unsigned
+svga_translate_stencil_op(unsigned op)
+{
+   switch (op) {
+   case PIPE_STENCIL_OP_KEEP:      return SVGA3D_STENCILOP_KEEP;
+   case PIPE_STENCIL_OP_ZERO:      return SVGA3D_STENCILOP_ZERO;
+   case PIPE_STENCIL_OP_REPLACE:   return SVGA3D_STENCILOP_REPLACE;
+   case PIPE_STENCIL_OP_INCR:      return SVGA3D_STENCILOP_INCR;
+   case PIPE_STENCIL_OP_DECR:      return SVGA3D_STENCILOP_DECR;
+   case PIPE_STENCIL_OP_INCR_WRAP: return SVGA3D_STENCILOP_INCRSAT; /* incorrect? */
+   case PIPE_STENCIL_OP_DECR_WRAP: return SVGA3D_STENCILOP_DECRSAT; /* incorrect? */
+   case PIPE_STENCIL_OP_INVERT:    return SVGA3D_STENCILOP_INVERT;
+   default:
+      assert(0);
+      return SVGA3D_STENCILOP_KEEP;
+   }
+}
+
+
+static void *
+svga_create_depth_stencil_state(struct pipe_context *pipe,
+				const struct pipe_depth_stencil_alpha_state *templ)
+{
+   struct svga_depth_stencil_state *ds = CALLOC_STRUCT( svga_depth_stencil_state );
+
+   /* Don't try to figure out CW/CCW correspondence with
+    * stencil[0]/[1] at this point.  Presumably this can change as
+    * back/front face are modified.
+    */
+   ds->stencil[0].enabled = templ->stencil[0].enabled;
+   if (ds->stencil[0].enabled) {
+      ds->stencil[0].func  = svga_translate_compare_func(templ->stencil[0].func);
+      ds->stencil[0].fail  = svga_translate_stencil_op(templ->stencil[0].fail_op);
+      ds->stencil[0].zfail = svga_translate_stencil_op(templ->stencil[0].zfail_op);
+      ds->stencil[0].pass  = svga_translate_stencil_op(templ->stencil[0].zpass_op);
+      
+      /* 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;
+   }
+
+
+   ds->stencil[1].enabled = templ->stencil[1].enabled;
+   if (templ->stencil[1].enabled) {
+      ds->stencil[1].func   = svga_translate_compare_func(templ->stencil[1].func);
+      ds->stencil[1].fail   = svga_translate_stencil_op(templ->stencil[1].fail_op);
+      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;
+   }
+
+
+   ds->zenable = templ->depth.enabled;
+   if (ds->zenable) {
+      ds->zfunc = svga_translate_compare_func(templ->depth.func);
+      ds->zwriteenable = templ->depth.writemask;
+   }
+
+   ds->alphatestenable = templ->alpha.enabled;
+   if (ds->alphatestenable) {
+      ds->alphafunc = svga_translate_compare_func(templ->alpha.func);
+      ds->alpharef = templ->alpha.ref_value;
+   }
+
+   return ds;
+}
+
+static void svga_bind_depth_stencil_state(struct pipe_context *pipe,
+                                          void *depth_stencil)
+{
+   struct svga_context *svga = svga_context(pipe);
+
+   svga->curr.depth = (const struct svga_depth_stencil_state *)depth_stencil;
+   svga->dirty |= SVGA_NEW_DEPTH_STENCIL;
+}
+
+static void svga_delete_depth_stencil_state(struct pipe_context *pipe,
+                                            void *depth_stencil)
+{
+   FREE(depth_stencil);
+}
+
+
+
+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;
+}
+
+
+
+
diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c
new file mode 100644
index 0000000..0f24ef4
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_pipe_draw.c
@@ -0,0 +1,259 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "svga_cmd.h"
+
+#include "pipe/p_inlines.h"
+#include "util/u_prim.h"
+#include "util/u_time.h"
+#include "indices/u_indices.h"
+
+#include "svga_hw_reg.h"
+#include "svga_context.h"
+#include "svga_screen.h"
+#include "svga_winsys.h"
+#include "svga_draw.h"
+#include "svga_state.h"
+#include "svga_swtnl.h"
+#include "svga_debug.h"
+
+
+
+static enum pipe_error
+retry_draw_range_elements( struct svga_context *svga,
+                           struct pipe_buffer *index_buffer,
+                           unsigned index_size,
+                           unsigned min_index,
+                           unsigned max_index,
+                           unsigned prim, 
+                           unsigned start, 
+                           unsigned count,
+                           boolean do_retry )
+{
+   enum pipe_error ret = 0;
+
+   svga_hwtnl_set_unfilled( svga->hwtnl,
+                            svga->curr.rast->hw_unfilled );
+
+   svga_hwtnl_set_flatshade( svga->hwtnl,
+                             svga->curr.rast->templ.flatshade,
+                             svga->curr.rast->templ.flatshade_first );
+
+
+   ret = svga_update_state( svga, SVGA_STATE_HW_DRAW );
+   if (ret)
+      goto retry;
+
+   ret = svga_hwtnl_draw_range_elements( svga->hwtnl,
+                                         index_buffer, index_size,
+                                         min_index, max_index,
+                                         prim, start, count, 0 );
+   if (ret)
+      goto retry;
+
+   if (svga->curr.any_user_vertex_buffers) {
+      ret = svga_hwtnl_flush( svga->hwtnl );
+      if (ret)
+         goto retry;
+   }
+
+   return PIPE_OK;
+
+retry:
+   svga_context_flush( svga, NULL );
+
+   if (do_retry)
+   {
+      return retry_draw_range_elements( svga,
+                                        index_buffer, index_size,
+                                        min_index, max_index,
+                                        prim, start, count,
+                                        FALSE );
+   }
+
+   return ret;
+}
+
+
+static enum pipe_error
+retry_draw_arrays( struct svga_context *svga,
+                   unsigned prim, 
+                   unsigned start, 
+                   unsigned count,
+                   boolean do_retry )
+{
+   enum pipe_error ret;
+
+   svga_hwtnl_set_unfilled( svga->hwtnl,
+                            svga->curr.rast->hw_unfilled );
+
+   svga_hwtnl_set_flatshade( svga->hwtnl,
+                             svga->curr.rast->templ.flatshade,
+                             svga->curr.rast->templ.flatshade_first );
+
+   ret = svga_update_state( svga, SVGA_STATE_HW_DRAW );
+   if (ret)
+      goto retry;
+
+   ret = svga_hwtnl_draw_arrays( svga->hwtnl, prim,
+                                 start, count );
+   if (ret)
+      goto retry;
+
+   if (svga->curr.any_user_vertex_buffers) {
+      ret = svga_hwtnl_flush( svga->hwtnl );
+      if (ret)
+         goto retry;
+   }
+
+   return 0;
+
+retry:
+   if (ret == PIPE_ERROR_OUT_OF_MEMORY && do_retry) 
+   {
+      svga_context_flush( svga, NULL );
+
+      return retry_draw_arrays( svga,
+                                prim,
+                                start,
+                                count,
+                                FALSE );
+   }
+
+   return ret;
+}
+
+
+
+
+
+static void
+svga_draw_range_elements( struct pipe_context *pipe,
+                          struct pipe_buffer *index_buffer,
+                          unsigned index_size,
+                          unsigned min_index,
+                          unsigned max_index,
+                          unsigned prim, unsigned start, unsigned count)
+{
+   struct svga_context *svga = svga_context( pipe );
+   unsigned reduced_prim = u_reduced_prim(prim);
+   enum pipe_error ret = 0;
+
+   if (!u_trim_pipe_prim( prim, &count ))
+      return;
+
+   /*
+    * Mark currently bound target surfaces as dirty
+    * doesn't really matter if it is done before drawing.
+    *
+    * TODO If we ever normaly return something other then
+    * true we should not mark it as dirty then.
+    */
+   svga_mark_surfaces_dirty(svga_context(pipe));
+
+   if (svga->curr.reduced_prim != reduced_prim) {
+      svga->curr.reduced_prim = reduced_prim;
+      svga->dirty |= SVGA_NEW_REDUCED_PRIMITIVE;
+   }
+   
+   svga_update_state_retry( svga, SVGA_STATE_NEED_SWTNL );
+
+#ifdef DEBUG
+   if (svga->curr.vs->base.id == svga->debug.disable_shader ||
+       svga->curr.fs->base.id == svga->debug.disable_shader)
+      return;
+#endif
+
+   if (svga->state.sw.need_swtnl)
+   {
+      ret = svga_swtnl_draw_range_elements( svga, 
+                                            index_buffer, 
+                                            index_size,
+                                            min_index, max_index,
+                                            prim,
+                                            start, count );
+   }
+   else {
+      if (index_buffer) {
+         ret = retry_draw_range_elements( svga,
+                                          index_buffer,
+                                          index_size,
+                                          min_index,
+                                          max_index,
+                                          prim,
+                                          start,
+                                          count,
+                                          TRUE );
+      }
+      else {
+         ret = retry_draw_arrays( svga, 
+                                  prim, 
+                                  start, 
+                                  count,
+                                  TRUE );
+      }
+   }
+
+   if (SVGA_DEBUG & DEBUG_FLUSH) {
+      static unsigned id;
+      debug_printf("%s %d\n", __FUNCTION__, id++);
+      if (id > 1300)
+         util_time_sleep( 2000 );
+
+      svga_hwtnl_flush_retry( svga );
+      svga_context_flush(svga, NULL);
+   }
+}
+
+
+static void
+svga_draw_elements( struct pipe_context *pipe,
+                    struct pipe_buffer *index_buffer,
+                    unsigned index_size,
+                    unsigned prim, unsigned start, unsigned count)
+{
+   svga_draw_range_elements( pipe, index_buffer,
+                             index_size,
+                             0, 0xffffffff,
+                             prim, start, count );
+}
+
+static void
+svga_draw_arrays( struct pipe_context *pipe,
+                  unsigned prim, unsigned start, unsigned count)
+{
+   svga_draw_range_elements(pipe, NULL, 0, 
+                            start, start + count - 1, 
+                            prim, 
+                            start, count);
+}
+
+
+void svga_init_draw_functions( struct svga_context *svga )
+{
+   svga->pipe.draw_arrays = svga_draw_arrays;
+   svga->pipe.draw_elements = svga_draw_elements;
+   svga->pipe.draw_range_elements = svga_draw_range_elements;
+}
diff --git a/src/gallium/drivers/svga/svga_pipe_flush.c b/src/gallium/drivers/svga/svga_pipe_flush.c
new file mode 100644
index 0000000..0becb07
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_pipe_flush.c
@@ -0,0 +1,71 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_defines.h"
+#include "svga_screen.h"
+#include "svga_screen_texture.h"
+#include "svga_context.h"
+#include "svga_winsys.h"
+#include "svga_draw.h"
+#include "svga_debug.h"
+
+#include "svga_hw_reg.h"
+
+
+
+
+static void svga_flush( struct pipe_context *pipe,
+                        unsigned flags,
+                        struct pipe_fence_handle **fence )
+{
+   struct svga_context *svga = svga_context(pipe);
+   int i;
+
+   /* Emit buffered drawing commands.
+    */
+   svga_hwtnl_flush_retry( svga );
+
+   /* Emit back-copy from render target view to texture.
+    */
+   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+      if (svga->curr.framebuffer.cbufs[i])
+         svga_propagate_surface(pipe, svga->curr.framebuffer.cbufs[i]);
+   }
+   if (svga->curr.framebuffer.zsbuf)
+      svga_propagate_surface(pipe, svga->curr.framebuffer.zsbuf);
+
+   /* Flush command queue.
+    */
+   svga_context_flush(svga, fence);
+
+   SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s flags %x fence_ptr %p\n",
+            __FUNCTION__, flags, fence ? *fence : 0x0);
+}
+
+
+void svga_init_flush_functions( struct svga_context *svga )
+{
+   svga->pipe.flush = svga_flush;
+}
diff --git a/src/gallium/drivers/svga/svga_pipe_fs.c b/src/gallium/drivers/svga/svga_pipe_fs.c
new file mode 100644
index 0000000..5f1213e
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_pipe_fs.c
@@ -0,0 +1,134 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_inlines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "util/u_bitmask.h"
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_text.h"
+
+#include "svga_screen.h"
+#include "svga_context.h"
+#include "svga_state.h"
+#include "svga_tgsi.h"
+#include "svga_hw_reg.h"
+#include "svga_cmd.h"
+#include "svga_draw.h"
+#include "svga_debug.h"
+
+
+/***********************************************************************
+ * Fragment shaders 
+ */
+
+static void *
+svga_create_fs_state(struct pipe_context *pipe,
+                     const struct pipe_shader_state *templ)
+{
+   struct svga_context *svga = svga_context(pipe);
+   struct svga_screen *svgascreen = svga_screen(pipe->screen);
+   struct svga_fragment_shader *fs;
+
+   fs = CALLOC_STRUCT(svga_fragment_shader);
+   if (!fs)
+      return NULL;
+
+   fs->base.tokens = tgsi_dup_tokens(templ->tokens);
+
+   /* Collect basic info that we'll need later:
+    */
+   tgsi_scan_shader(fs->base.tokens, &fs->base.info);
+
+   fs->base.id = svga->debug.shader_id++;
+   fs->base.use_sm30 = svgascreen->use_ps30;
+   
+   if (SVGA_DEBUG & DEBUG_TGSI || 0) {
+      debug_printf("%s id: %u, inputs: %u, outputs: %u\n",
+                   __FUNCTION__, fs->base.id,
+                   fs->base.info.num_inputs, fs->base.info.num_outputs);
+   }
+
+   return fs;
+}
+
+static void
+svga_bind_fs_state(struct pipe_context *pipe, void *shader)
+{
+   struct svga_fragment_shader *fs = (struct svga_fragment_shader *) shader;
+   struct svga_context *svga = svga_context(pipe);
+
+   svga->curr.fs = fs;
+   svga->dirty |= SVGA_NEW_FS;
+}
+
+static
+void svga_delete_fs_state(struct pipe_context *pipe, void *shader)
+{
+   struct svga_context *svga = svga_context(pipe);
+   struct svga_fragment_shader *fs = (struct svga_fragment_shader *) shader;
+   struct svga_shader_result *result, *tmp;
+   enum pipe_error ret;
+
+   svga_hwtnl_flush_retry( svga );
+
+   for (result = fs->base.results; result; result = tmp ) {
+      tmp = result->next;
+
+      ret = SVGA3D_DestroyShader(svga->swc, 
+                                 result->id,
+                                 SVGA3D_SHADERTYPE_PS );
+      if(ret != PIPE_OK) {
+         svga_context_flush(svga, NULL);
+         ret = SVGA3D_DestroyShader(svga->swc, 
+                                    result->id,
+                                    SVGA3D_SHADERTYPE_PS );
+         assert(ret == PIPE_OK);
+      }
+
+      util_bitmask_clear( svga->fs_bm, result->id );
+
+      svga_destroy_shader_result( result );
+
+      /*
+       * Remove stale references to this result to ensure a new result on the
+       * same address will be detected as a change.
+       */
+      if(result == svga->state.hw_draw.fs)
+         svga->state.hw_draw.fs = NULL;
+   }
+
+   FREE((void *)fs->base.tokens);
+   FREE(fs);
+}
+
+
+void svga_init_fs_functions( struct svga_context *svga )
+{
+   svga->pipe.create_fs_state = svga_create_fs_state;
+   svga->pipe.bind_fs_state = svga_bind_fs_state;
+   svga->pipe.delete_fs_state = svga_delete_fs_state;
+}
+
diff --git a/src/gallium/drivers/svga/svga_pipe_misc.c b/src/gallium/drivers/svga/svga_pipe_misc.c
new file mode 100644
index 0000000..58cb1e6
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_pipe_misc.c
@@ -0,0 +1,187 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "svga_cmd.h"
+
+#include "svga_context.h"
+#include "svga_screen_texture.h"
+#include "svga_state.h"
+#include "svga_winsys.h"
+
+#include "svga_hw_reg.h"
+
+
+
+
+static void svga_set_scissor_state( struct pipe_context *pipe,
+                                 const struct pipe_scissor_state *scissor )
+{
+   struct svga_context *svga = svga_context(pipe);
+
+   memcpy( &svga->curr.scissor, scissor, sizeof(*scissor) );
+   svga->dirty |= SVGA_NEW_SCISSOR;
+}
+
+
+static void svga_set_polygon_stipple( struct pipe_context *pipe,
+                                      const struct pipe_poly_stipple *stipple )
+{
+   /* overridden by the draw module */
+}
+
+
+void svga_cleanup_framebuffer(struct svga_context *svga)
+{
+   struct pipe_framebuffer_state *curr = &svga->curr.framebuffer;
+   struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;
+   int i;
+
+   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+      pipe_surface_reference(&curr->cbufs[i], NULL);
+      pipe_surface_reference(&hw->cbufs[i], NULL);
+   }
+
+   pipe_surface_reference(&curr->zsbuf, NULL);
+   pipe_surface_reference(&hw->zsbuf, NULL);
+}
+
+
+#define DEPTH_BIAS_SCALE_FACTOR_D16    ((float)(1<<15))
+#define DEPTH_BIAS_SCALE_FACTOR_D24S8  ((float)(1<<23))
+#define DEPTH_BIAS_SCALE_FACTOR_D32    ((float)(1<<31))
+
+
+static void svga_set_framebuffer_state(struct pipe_context *pipe,
+				       const struct pipe_framebuffer_state *fb)
+{
+   struct svga_context *svga = svga_context(pipe);
+   struct pipe_framebuffer_state *dst = &svga->curr.framebuffer;
+   boolean propagate = FALSE;
+   int i;
+
+   dst->width = fb->width;
+   dst->height = fb->height;
+   dst->nr_cbufs = fb->nr_cbufs;
+
+   /* check if we need to propaget any of the target surfaces */
+   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+      if (dst->cbufs[i] && dst->cbufs[i] != fb->cbufs[i])
+         if (svga_surface_needs_propagation(dst->cbufs[i]))
+            propagate = TRUE;
+   }
+
+   if (propagate) {
+      /* make sure that drawing calls comes before propagation calls */
+      svga_hwtnl_flush_retry( svga );
+   
+      for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
+         if (dst->cbufs[i] && dst->cbufs[i] != fb->cbufs[i])
+            svga_propagate_surface(pipe, dst->cbufs[i]);
+   }
+
+   /* XXX: Actually the virtual hardware may support rendertargets with
+    * different size, depending on the host API and driver, but since we cannot
+    * know that make no such assumption here. */
+   for(i = 0; i < fb->nr_cbufs; ++i) {
+      if (fb->zsbuf && fb->cbufs[i]) {
+         assert(fb->zsbuf->width == fb->cbufs[i]->width); 
+         assert(fb->zsbuf->height == fb->cbufs[i]->height); 
+      }
+   }
+
+   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
+      pipe_surface_reference(&dst->cbufs[i], fb->cbufs[i]);
+   pipe_surface_reference(&dst->zsbuf, fb->zsbuf);
+
+
+   if (svga->curr.framebuffer.zsbuf)
+   {
+      switch (svga->curr.framebuffer.zsbuf->format) {
+      case PIPE_FORMAT_Z16_UNORM:
+         svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D16;
+         break;
+      case PIPE_FORMAT_S8Z24_UNORM:
+      case PIPE_FORMAT_X8Z24_UNORM:
+      case PIPE_FORMAT_Z24S8_UNORM:
+      case PIPE_FORMAT_Z24X8_UNORM:
+         svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D24S8;
+         break;
+      case PIPE_FORMAT_Z32_UNORM:
+         svga->curr.depthscale = 1.0f / DEPTH_BIAS_SCALE_FACTOR_D32;
+         break;
+      case PIPE_FORMAT_Z32_FLOAT:
+         svga->curr.depthscale = 1.0f / ((float)(1<<23));
+         break;
+      default:
+         svga->curr.depthscale = 0.0f;
+         break;
+      }
+   }
+   else {
+      svga->curr.depthscale = 0.0f;
+   }
+
+   svga->dirty |= SVGA_NEW_FRAME_BUFFER;
+}
+
+
+
+static void svga_set_clip_state( struct pipe_context *pipe,
+                                 const struct pipe_clip_state *clip )
+{
+   struct svga_context *svga = svga_context(pipe);
+
+   svga->curr.clip = *clip; /* struct copy */
+
+   svga->dirty |= SVGA_NEW_CLIP;
+}
+
+
+
+/* Called when driver state tracker notices changes to the viewport
+ * matrix:
+ */
+static void svga_set_viewport_state( struct pipe_context *pipe,
+				     const struct pipe_viewport_state *viewport )
+{
+   struct svga_context *svga = svga_context(pipe);
+
+   svga->curr.viewport = *viewport; /* struct copy */
+
+   svga->dirty |= SVGA_NEW_VIEWPORT;
+}
+
+
+
+void svga_init_misc_functions( struct svga_context *svga )
+{
+   svga->pipe.set_scissor_state = svga_set_scissor_state;
+   svga->pipe.set_polygon_stipple = svga_set_polygon_stipple;
+   svga->pipe.set_framebuffer_state = svga_set_framebuffer_state;
+   svga->pipe.set_clip_state = svga_set_clip_state;
+   svga->pipe.set_viewport_state = svga_set_viewport_state;
+}
+
+
diff --git a/src/gallium/drivers/svga/svga_pipe_query.c b/src/gallium/drivers/svga/svga_pipe_query.c
new file mode 100644
index 0000000..01336b0
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_pipe_query.c
@@ -0,0 +1,267 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_state.h"
+#include "pipe/p_context.h"
+#include "util/u_memory.h"
+
+#include "svga_cmd.h"
+#include "svga_context.h"
+#include "svga_screen.h"
+#include "svga_screen_buffer.h"
+#include "svga_winsys.h"
+#include "svga_draw.h"
+#include "svga_debug.h"
+
+
+/* Fixme: want a public base class for all pipe structs, even if there
+ * isn't much in them.
+ */
+struct pipe_query {
+   int dummy;
+};
+
+struct svga_query {
+   struct pipe_query base;
+   SVGA3dQueryType type;
+   struct svga_winsys_buffer *hwbuf;
+   volatile SVGA3dQueryResult *queryResult;
+   struct pipe_fence_handle *fence;
+};
+
+/***********************************************************************
+ * Inline conversion functions.  These are better-typed than the
+ * macros used previously:
+ */
+static INLINE struct svga_query *
+svga_query( struct pipe_query *q )
+{
+   return (struct svga_query *)q;
+}
+
+static boolean svga_get_query_result(struct pipe_context *pipe, 
+                                     struct pipe_query *q,
+                                     boolean wait,
+                                     uint64_t *result);
+
+static struct pipe_query *svga_create_query( struct pipe_context *pipe,
+                                             unsigned query_type )
+{
+   struct svga_screen *svgascreen = svga_screen(pipe->screen);
+   struct svga_winsys_screen *sws = svgascreen->sws;
+   struct svga_query *sq;
+
+   SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);
+
+   sq = CALLOC_STRUCT(svga_query);
+   if (!sq)
+      goto no_sq;
+
+   sq->type = SVGA3D_QUERYTYPE_OCCLUSION;
+
+   sq->hwbuf = svga_winsys_buffer_create(svgascreen, 
+                                         1,
+                                         SVGA_BUFFER_USAGE_PINNED,
+                                         sizeof *sq->queryResult);
+   if(!sq->hwbuf)
+      goto no_hwbuf;
+    
+   sq->queryResult = (SVGA3dQueryResult *)sws->buffer_map(sws, 
+                                                          sq->hwbuf, 
+                                                          PIPE_BUFFER_USAGE_CPU_WRITE);
+   if(!sq->queryResult)
+      goto no_query_result;
+
+   sq->queryResult->totalSize = sizeof *sq->queryResult;
+   sq->queryResult->state = SVGA3D_QUERYSTATE_NEW;
+
+   /*
+    * We request the buffer to be pinned and assume it is always mapped.
+    * 
+    * The reason is that we don't want to wait for fences when checking the
+    * query status.
+    */
+   sws->buffer_unmap(sws, sq->hwbuf);
+
+   return &sq->base;
+
+no_query_result:
+   sws->buffer_destroy(sws, sq->hwbuf);
+no_hwbuf:
+   FREE(sq);
+no_sq:
+   return NULL;
+}
+
+static void svga_destroy_query(struct pipe_context *pipe,
+                               struct pipe_query *q)
+{
+   struct svga_screen *svgascreen = svga_screen(pipe->screen);
+   struct svga_winsys_screen *sws = svgascreen->sws;
+   struct svga_query *sq = svga_query( q );
+
+   SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);
+   sws->buffer_destroy(sws, sq->hwbuf);
+   sws->fence_reference(sws, &sq->fence, NULL);
+   FREE(sq);
+}
+
+static void svga_begin_query(struct pipe_context *pipe, 
+                             struct pipe_query *q)
+{
+   struct svga_screen *svgascreen = svga_screen(pipe->screen);
+   struct svga_winsys_screen *sws = svgascreen->sws;
+   struct svga_context *svga = svga_context( pipe );
+   struct svga_query *sq = svga_query( q );
+   enum pipe_error ret;
+
+   SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);
+   
+   assert(!svga->sq);
+
+   /* Need to flush out buffered drawing commands so that they don't
+    * get counted in the query results.
+    */
+   svga_hwtnl_flush_retry(svga);
+   
+   if(sq->queryResult->state == SVGA3D_QUERYSTATE_PENDING) {
+      /* The application doesn't care for the pending query result. We cannot
+       * let go the existing buffer and just get a new one because its storage
+       * may be reused for other purposes and clobbered by the host when it
+       * determines the query result. So the only option here is to wait for
+       * the existing query's result -- not a big deal, given that no sane
+       * application would do this.
+       */
+      uint64_t result;
+
+      svga_get_query_result(pipe, q, TRUE, &result);
+      
+      assert(sq->queryResult->state != SVGA3D_QUERYSTATE_PENDING);
+   }
+   
+   sq->queryResult->state = SVGA3D_QUERYSTATE_NEW;
+   sws->fence_reference(sws, &sq->fence, NULL);
+
+   ret = SVGA3D_BeginQuery(svga->swc, sq->type);
+   if(ret != PIPE_OK) {
+      svga_context_flush(svga, NULL);
+      ret = SVGA3D_BeginQuery(svga->swc, sq->type);
+      assert(ret == PIPE_OK);
+   }
+
+   svga->sq = sq;
+}
+
+static void svga_end_query(struct pipe_context *pipe, 
+                           struct pipe_query *q)
+{
+   struct svga_context *svga = svga_context( pipe );
+   struct svga_query *sq = svga_query( q );
+   enum pipe_error ret;
+
+   SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);
+   assert(svga->sq == sq);
+
+   svga_hwtnl_flush_retry(svga);
+   
+   /* Set to PENDING before sending EndQuery. */
+   sq->queryResult->state = SVGA3D_QUERYSTATE_PENDING;
+
+   ret = SVGA3D_EndQuery( svga->swc, sq->type, sq->hwbuf);
+   if(ret != PIPE_OK) {
+      svga_context_flush(svga, NULL);
+      ret = SVGA3D_EndQuery( svga->swc, sq->type, sq->hwbuf);
+      assert(ret == PIPE_OK);
+   }
+   
+   /* TODO: Delay flushing. We don't really need to flush here, just ensure 
+    * that there is one flush before svga_get_query_result attempts to get the
+    * result */
+   svga_context_flush(svga, NULL);
+
+   svga->sq = NULL;
+}
+
+static boolean svga_get_query_result(struct pipe_context *pipe, 
+                                     struct pipe_query *q,
+                                     boolean wait,
+                                     uint64_t *result)
+{
+   struct svga_context *svga = svga_context( pipe );
+   struct svga_screen *svgascreen = svga_screen( pipe->screen );
+   struct svga_winsys_screen *sws = svgascreen->sws;
+   struct svga_query *sq = svga_query( q );
+   SVGA3dQueryState state;
+   
+   SVGA_DBG(DEBUG_QUERY, "%s wait: %d\n", __FUNCTION__);
+
+   /* The query status won't be updated by the host unless 
+    * SVGA_3D_CMD_WAIT_FOR_QUERY is emitted. Unfortunately this will cause a 
+    * synchronous wait on the host */
+   if(!sq->fence) {
+      enum pipe_error ret;
+
+      ret = SVGA3D_WaitForQuery( svga->swc, sq->type, sq->hwbuf);
+      if(ret != PIPE_OK) {
+         svga_context_flush(svga, NULL);
+         ret = SVGA3D_WaitForQuery( svga->swc, sq->type, sq->hwbuf);
+         assert(ret == PIPE_OK);
+      }
+   
+      svga_context_flush(svga, &sq->fence);
+      
+      assert(sq->fence);
+   }
+
+   state = sq->queryResult->state;
+   if(state == SVGA3D_QUERYSTATE_PENDING) {
+      if(!wait)
+         return FALSE;
+   
+      sws->fence_finish(sws, sq->fence, 0);
+      
+      state = sq->queryResult->state;
+   }
+
+   assert(state == SVGA3D_QUERYSTATE_SUCCEEDED || 
+          state == SVGA3D_QUERYSTATE_FAILED);
+   
+   *result = (uint64_t)sq->queryResult->result32;
+
+   SVGA_DBG(DEBUG_QUERY, "%s result %d\n", __FUNCTION__, (unsigned)*result);
+
+   return TRUE;
+}
+
+
+
+void svga_init_query_functions( struct svga_context *svga )
+{
+   svga->pipe.create_query = svga_create_query;
+   svga->pipe.destroy_query = svga_destroy_query;
+   svga->pipe.begin_query = svga_begin_query;
+   svga->pipe.end_query = svga_end_query;
+   svga->pipe.get_query_result = svga_get_query_result;
+}
diff --git a/src/gallium/drivers/svga/svga_pipe_rasterizer.c b/src/gallium/drivers/svga/svga_pipe_rasterizer.c
new file mode 100644
index 0000000..b03f8eb
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_pipe_rasterizer.c
@@ -0,0 +1,250 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "draw/draw_context.h"
+#include "pipe/p_inlines.h"
+#include "pipe/p_defines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "svga_context.h"
+#include "svga_state.h"
+
+#include "svga_hw_reg.h"
+
+/* Hardware frontwinding is always set up as SVGA3D_FRONTWINDING_CW.
+ */
+static SVGA3dFace svga_translate_cullmode( unsigned mode,
+                                           unsigned front_winding )
+{
+   switch (mode) {
+   case PIPE_WINDING_NONE:
+      return SVGA3D_FACE_NONE;
+   case PIPE_WINDING_CCW:
+      return SVGA3D_FACE_BACK;
+   case PIPE_WINDING_CW:
+      return SVGA3D_FACE_FRONT;
+   case PIPE_WINDING_BOTH:
+      return SVGA3D_FACE_FRONT_BACK;
+   default:
+      assert(0);
+      return SVGA3D_FACE_NONE;
+   }
+}
+
+static SVGA3dShadeMode svga_translate_flatshade( unsigned mode )
+{
+   return mode ? SVGA3D_SHADEMODE_FLAT : SVGA3D_SHADEMODE_SMOOTH;
+}
+
+
+static void *
+svga_create_rasterizer_state(struct pipe_context *pipe,
+                             const struct pipe_rasterizer_state *templ)
+{
+   struct svga_rasterizer_state *rast = CALLOC_STRUCT( svga_rasterizer_state );
+   /* need this for draw module. */
+   rast->templ = *templ;
+
+   /* light_twoside          - XXX: need fragment shader varient */
+   /* poly_smooth            - XXX: no fallback available */
+   /* poly_stipple_enable    - draw module */
+   /* point_sprite           - ? */
+   /* point_size_per_vertex  - ? */
+   /* sprite_coord_mode      - ??? */
+   /* bypass_vs_viewport_and_clip        - handled by viewport setup */
+   /* flatshade_first        - handled by index translation */
+   /* gl_rasterization_rules - XXX - viewport code */
+   /* line_width             - draw module */
+   /* fill_cw, fill_ccw      - draw module or index translation */
+
+   rast->shademode = svga_translate_flatshade( templ->flatshade );
+   rast->cullmode = svga_translate_cullmode( templ->cull_mode, 
+                                             templ->front_winding );
+   rast->scissortestenable = templ->scissor;
+   rast->multisampleantialias = templ->multisample;
+   rast->antialiasedlineenable = templ->line_smooth;
+   rast->lastpixel = templ->line_last_pixel;
+   rast->pointsize = templ->point_size;
+   rast->pointsize_min = templ->point_size_min;
+   rast->pointsize_max = templ->point_size_max;
+   rast->hw_unfilled = PIPE_POLYGON_MODE_FILL;
+
+   /* Use swtnl + decomposition implement these:
+    */
+   if (templ->poly_stipple_enable)
+      rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
+
+   if (templ->line_width != 1.0 &&
+       templ->line_width != 0.0)
+      rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES;
+
+   if (templ->line_stipple_enable) {
+      /* LinePattern not implemented on all backends. 
+       */
+      if (0) {
+         SVGA3dLinePattern lp;
+         lp.repeat = templ->line_stipple_factor + 1;
+         lp.pattern = templ->line_stipple_pattern;
+         rast->linepattern = lp.uintValue;
+      }
+      else {
+         rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES;
+      }
+   } 
+
+   if (templ->point_smooth)
+      rast->need_pipeline |= SVGA_PIPELINE_FLAG_POINTS;
+
+   {
+      boolean offset_cw = templ->offset_cw;
+      boolean offset_ccw = templ->offset_ccw;
+      boolean offset  = 0;
+      int fill_cw = templ->fill_cw;
+      int fill_ccw = templ->fill_ccw;
+      int fill = PIPE_POLYGON_MODE_FILL;
+
+      switch (templ->cull_mode) {
+      case PIPE_WINDING_BOTH:
+         offset = 0;
+         fill = PIPE_POLYGON_MODE_FILL;
+         break;
+
+      case PIPE_WINDING_CW:
+         offset = offset_ccw;
+         fill = fill_ccw;
+         break;
+
+      case PIPE_WINDING_CCW:
+         offset = offset_cw;
+         fill = fill_cw;
+         break;
+
+      case PIPE_WINDING_NONE:
+         if (fill_cw != fill_ccw || offset_cw != offset_ccw) 
+         {
+            /* Always need the draw module to work out different
+             * front/back fill modes:
+             */
+            rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
+         }
+         else {
+            offset = offset_ccw;
+            fill = fill_ccw;
+         }
+         break;
+
+      default:
+         assert(0);
+         break;
+      }
+
+      /* Unfilled primitive modes aren't implemented on all virtual
+       * hardware.  We can do some unfilled processing with index
+       * translation, but otherwise need the draw module:
+       */
+      if (fill != PIPE_POLYGON_MODE_FILL &&
+          (templ->flatshade ||
+           templ->light_twoside ||
+           offset ||
+           templ->cull_mode != PIPE_WINDING_NONE)) 
+      {
+         fill = PIPE_POLYGON_MODE_FILL;
+         rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
+      }
+
+      /* If we are decomposing to lines, and lines need the pipeline,
+       * then we also need the pipeline for tris.
+       */
+      if (fill == PIPE_POLYGON_MODE_LINE &&
+          (rast->need_pipeline & SVGA_PIPELINE_FLAG_LINES))
+      {
+         fill = PIPE_POLYGON_MODE_FILL;
+         rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
+      }
+
+      /* Similarly for points:
+       */
+      if (fill == PIPE_POLYGON_MODE_POINT &&
+          (rast->need_pipeline & SVGA_PIPELINE_FLAG_POINTS))
+      {
+         fill = PIPE_POLYGON_MODE_FILL;
+         rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
+      }
+
+      if (offset) {
+         rast->slopescaledepthbias = templ->offset_scale;
+         rast->depthbias = templ->offset_units;
+      }
+
+      rast->hw_unfilled = fill;
+   }
+
+
+
+
+   if (rast->need_pipeline & SVGA_PIPELINE_FLAG_TRIS) {
+      /* Turn off stuff which will get done in the draw module:
+       */
+      rast->hw_unfilled = PIPE_POLYGON_MODE_FILL;
+      rast->slopescaledepthbias = 0;
+      rast->depthbias = 0;
+   }
+
+   return rast;
+}
+
+static void svga_bind_rasterizer_state( struct pipe_context *pipe,
+                                        void *state )
+{
+   struct svga_context *svga = svga_context(pipe);
+   struct svga_rasterizer_state *raster = (struct svga_rasterizer_state *)state;
+
+   svga->curr.rast = raster;
+
+   draw_set_rasterizer_state(svga->swtnl.draw, raster ? &raster->templ : NULL);
+   
+   svga->dirty |= SVGA_NEW_RAST;
+}
+
+static void svga_delete_rasterizer_state(struct pipe_context *pipe,
+                                         void *raster)
+{
+   FREE(raster);
+}
+
+
+void svga_init_rasterizer_functions( struct svga_context *svga )
+{
+   svga->pipe.create_rasterizer_state = svga_create_rasterizer_state;
+   svga->pipe.bind_rasterizer_state = svga_bind_rasterizer_state;
+   svga->pipe.delete_rasterizer_state = svga_delete_rasterizer_state;
+}
+
+
+/***********************************************************************
+ * Hardware state update
+ */
+
diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c
new file mode 100644
index 0000000..460a101
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_pipe_sampler.c
@@ -0,0 +1,245 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_inlines.h"
+#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"
+#include "svga_screen_texture.h"
+#include "svga_state.h"
+
+#include "svga_hw_reg.h"
+
+#include "svga_debug.h"
+
+static INLINE unsigned
+translate_wrap_mode(unsigned wrap)
+{
+   switch (wrap) {
+   case PIPE_TEX_WRAP_REPEAT: 
+      return SVGA3D_TEX_ADDRESS_WRAP;
+
+   case PIPE_TEX_WRAP_CLAMP: 
+      return SVGA3D_TEX_ADDRESS_CLAMP;
+
+   case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 
+      /* Unfortunately SVGA3D_TEX_ADDRESS_EDGE not respected by
+       * hardware.
+       */
+      return SVGA3D_TEX_ADDRESS_CLAMP;
+
+   case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 
+      return SVGA3D_TEX_ADDRESS_BORDER;
+
+   case PIPE_TEX_WRAP_MIRROR_REPEAT: 
+      return SVGA3D_TEX_ADDRESS_MIRROR;
+
+   case PIPE_TEX_WRAP_MIRROR_CLAMP:  
+   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:   
+   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 
+      return SVGA3D_TEX_ADDRESS_MIRRORONCE;
+
+   default:
+      assert(0);
+      return SVGA3D_TEX_ADDRESS_WRAP;
+   }
+}
+
+static INLINE unsigned translate_img_filter( unsigned filter )
+{
+   switch (filter) {
+   case PIPE_TEX_FILTER_NEAREST: return SVGA3D_TEX_FILTER_NEAREST;
+   case PIPE_TEX_FILTER_LINEAR:  return SVGA3D_TEX_FILTER_LINEAR;
+   default:
+      assert(0);
+      return SVGA3D_TEX_FILTER_NEAREST;
+   }
+}
+
+static INLINE unsigned translate_mip_filter( unsigned filter )
+{
+   switch (filter) {
+   case PIPE_TEX_MIPFILTER_NONE:    return SVGA3D_TEX_FILTER_NONE;
+   case PIPE_TEX_MIPFILTER_NEAREST: return SVGA3D_TEX_FILTER_NEAREST;
+   case PIPE_TEX_MIPFILTER_LINEAR:  return SVGA3D_TEX_FILTER_LINEAR;
+   default:
+      assert(0);
+      return SVGA3D_TEX_FILTER_NONE;
+   }
+}
+
+static void *
+svga_create_sampler_state(struct pipe_context *pipe,
+                          const struct pipe_sampler_state *sampler)
+{
+   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->magfilter = cso->minfilter = SVGA3D_TEX_FILTER_ANISOTROPIC;
+   cso->lod_bias = sampler->lod_bias;
+   cso->addressu = translate_wrap_mode(sampler->wrap_s);
+   cso->addressv = translate_wrap_mode(sampler->wrap_t);
+   cso->addressw = translate_wrap_mode(sampler->wrap_r);
+   cso->normalized_coords = sampler->normalized_coords;
+   cso->compare_mode = sampler->compare_mode;
+   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]);
+
+      util_pack_color_ub( r, g, b, a,
+                          PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
+      cso->bordercolor = uc.ui;
+   }
+
+   /* No SVGA3D support for:
+    *    - min/max LOD clamping
+    */
+   cso->min_lod = 0;
+   cso->view_min_lod = MAX2(sampler->min_lod, 0);
+   cso->view_max_lod = MAX2(sampler->max_lod, 0);
+
+   /* Use min_mipmap */
+   if (svga->debug.use_min_mipmap) {
+      if (cso->view_min_lod == cso->view_max_lod) {
+         cso->min_lod = cso->view_min_lod;
+         cso->view_min_lod = 0;
+         cso->view_max_lod = 1000; /* Just a high number */
+         cso->mipfilter = SVGA3D_TEX_FILTER_NONE;
+      }
+   }
+
+   SVGA_DBG(DEBUG_VIEWS, "min %u, view(min %u, max %u) lod, mipfilter %s\n",
+            cso->min_lod, cso->view_min_lod, cso->view_max_lod,
+            cso->mipfilter == SVGA3D_TEX_FILTER_NONE ? "SVGA3D_TEX_FILTER_NONE" : "SOMETHING");
+
+   return cso;
+}
+
+static void svga_bind_sampler_states(struct pipe_context *pipe,
+                                     unsigned num, void **sampler)
+{
+   struct svga_context *svga = svga_context(pipe);
+   unsigned i;
+
+   assert(num <= PIPE_MAX_SAMPLERS);
+
+   /* Check for no-op */
+   if (num == svga->curr.num_samplers &&
+       !memcmp(svga->curr.sampler, sampler, num * sizeof(void *))) {
+      debug_printf("sampler noop\n");
+      return;
+   }
+
+   for (i = 0; i < num; i++)
+      svga->curr.sampler[i] = sampler[i];
+
+   for (i = num; i < svga->curr.num_samplers; i++)
+      svga->curr.sampler[i] = NULL;
+
+   svga->curr.num_samplers = num;
+   svga->dirty |= SVGA_NEW_SAMPLER;
+}
+
+static void svga_delete_sampler_state(struct pipe_context *pipe,
+                                      void *sampler)
+{
+   FREE(sampler);
+}
+
+
+static void svga_set_sampler_textures(struct pipe_context *pipe,
+                                      unsigned num,
+                                      struct pipe_texture **texture)
+{
+   struct svga_context *svga = svga_context(pipe);
+   unsigned flag_1d = 0;
+   unsigned flag_srgb = 0;
+   uint i;
+
+   assert(num <= PIPE_MAX_SAMPLERS);
+
+   /* Check for no-op */
+   if (num == svga->curr.num_textures &&
+       !memcmp(svga->curr.texture, texture, num * sizeof(struct pipe_texture *))) {
+      if (0) debug_printf("texture noop\n");
+      return;
+   }
+
+   for (i = 0; i < num; i++) {
+      pipe_texture_reference(&svga->curr.texture[i],
+                             texture[i]);
+
+      if (!texture[i])
+         continue;
+
+      if (texture[i]->format == PIPE_FORMAT_A8R8G8B8_SRGB)
+         flag_srgb |= 1 << i;
+
+      if (texture[i]->target == PIPE_TEXTURE_1D)
+         flag_1d |= 1 << i;
+   }
+
+   for (i = num; i < svga->curr.num_textures; i++)
+      pipe_texture_reference(&svga->curr.texture[i],
+                             NULL);
+
+   svga->curr.num_textures = num;
+   svga->dirty |= SVGA_NEW_TEXTURE_BINDING;
+
+   if (flag_srgb != svga->curr.tex_flags.flag_srgb ||
+       flag_1d != svga->curr.tex_flags.flag_1d) 
+   {
+      svga->dirty |= SVGA_NEW_TEXTURE_FLAGS;
+      svga->curr.tex_flags.flag_1d = flag_1d;
+      svga->curr.tex_flags.flag_srgb = flag_srgb;
+   }  
+}
+
+
+
+void svga_init_sampler_functions( struct svga_context *svga )
+{
+   svga->pipe.create_sampler_state = svga_create_sampler_state;
+   svga->pipe.bind_fragment_sampler_states = svga_bind_sampler_states;
+   svga->pipe.delete_sampler_state = svga_delete_sampler_state;
+   svga->pipe.set_fragment_sampler_textures = svga_set_sampler_textures;
+}
+
+
+
diff --git a/src/gallium/drivers/svga/svga_pipe_vertex.c b/src/gallium/drivers/svga/svga_pipe_vertex.c
new file mode 100644
index 0000000..42f290d
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_pipe_vertex.c
@@ -0,0 +1,102 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_inlines.h"
+#include "pipe/p_defines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "tgsi/tgsi_parse.h"
+
+#include "svga_screen.h"
+#include "svga_screen_buffer.h"
+#include "svga_context.h"
+#include "svga_state.h"
+#include "svga_winsys.h"
+
+#include "svga_hw_reg.h"
+
+
+static void svga_set_vertex_buffers(struct pipe_context *pipe,
+                                    unsigned count,
+                                    const struct pipe_vertex_buffer *buffers)
+{
+   struct svga_context *svga = svga_context(pipe);
+   unsigned i;
+   boolean any_user_buffer = FALSE;
+
+   /* Check for no change */
+   if (count == svga->curr.num_vertex_buffers &&
+       memcmp(svga->curr.vb, buffers, count * sizeof buffers[0]) == 0)
+      return;
+
+   /* Adjust refcounts */
+   for (i = 0; i < count; i++) {
+      pipe_buffer_reference(&svga->curr.vb[i].buffer, buffers[i].buffer);
+      if (svga_buffer(buffers[i].buffer)->user)
+         any_user_buffer = TRUE;
+   }
+
+   for ( ; i < svga->curr.num_vertex_buffers; i++)
+      pipe_buffer_reference(&svga->curr.vb[i].buffer, NULL);
+
+   /* Copy remaining data */
+   memcpy(svga->curr.vb, buffers, count * sizeof buffers[0]);
+   svga->curr.num_vertex_buffers = count;
+   svga->curr.any_user_vertex_buffers = any_user_buffer;
+
+   svga->dirty |= SVGA_NEW_VBUFFER;
+}
+
+static void svga_set_vertex_elements(struct pipe_context *pipe,
+                                     unsigned count,
+                                     const struct pipe_vertex_element *elements)
+{
+   struct svga_context *svga = svga_context(pipe);
+   unsigned i;
+
+   for (i = 0; i < count; i++)
+      svga->curr.ve[i] = elements[i];
+
+   svga->curr.num_vertex_elements = count;
+   svga->dirty |= SVGA_NEW_VELEMENT;
+}
+
+
+void svga_cleanup_vertex_state( struct svga_context *svga )
+{
+   unsigned i;
+   
+   for (i = 0 ; i < svga->curr.num_vertex_buffers; i++)
+      pipe_buffer_reference(&svga->curr.vb[i].buffer, NULL);
+}
+
+
+void svga_init_vertex_functions( struct svga_context *svga )
+{
+   svga->pipe.set_vertex_buffers = svga_set_vertex_buffers;
+   svga->pipe.set_vertex_elements = svga_set_vertex_elements;
+}
+
+
diff --git a/src/gallium/drivers/svga/svga_pipe_vs.c b/src/gallium/drivers/svga/svga_pipe_vs.c
new file mode 100644
index 0000000..7e6ab57
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_pipe_vs.c
@@ -0,0 +1,199 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "draw/draw_context.h"
+#include "pipe/p_inlines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "util/u_bitmask.h"
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_text.h"
+
+#include "svga_screen.h"
+#include "svga_context.h"
+#include "svga_state.h"
+#include "svga_tgsi.h"
+#include "svga_hw_reg.h"
+#include "svga_cmd.h"
+#include "svga_debug.h"
+
+
+static const struct tgsi_token *substitute_vs( 
+   unsigned shader_id,
+   const struct tgsi_token *old_tokens )
+{
+#if 0
+   if (shader_id == 12) {
+   static struct tgsi_token tokens[300];
+
+   const char *text = 
+      "VERT\n"
+      "DCL IN[0]\n"
+      "DCL IN[1]\n"
+      "DCL IN[2]\n"
+      "DCL OUT[0], POSITION\n"
+      "DCL TEMP[0..4]\n"
+      "IMM FLT32 {     1.0000,     1.0000,     1.0000,     1.0000 }\n"
+      "IMM FLT32 {     0.45,     1.0000,     1.0000,     1.0000 }\n"
+      "IMM FLT32 { 1.297863, 0.039245, 0.035993, 0.035976}\n"
+      "IMM FLT32 { -0.019398, 1.696131, -0.202151, -0.202050  }\n"
+      "IMM FLT32 { 0.051711, -0.348713, -0.979204, -0.978714  }\n"
+      "IMM FLT32 { 0.000000, 0.000003, 139.491577, 141.421356 }\n"
+      "DCL CONST[0..7]\n"
+      "DCL CONST[9..16]\n"
+      "  MOV TEMP[2], IMM[0]\n"
+
+      "  MOV TEMP[2].xyz, IN[2]\n"
+      "  MOV TEMP[2].xyz, IN[0]\n"
+      "  MOV TEMP[2].xyz, IN[1]\n"
+
+      "  MUL TEMP[1], IMM[3], TEMP[2].yyyy\n"
+      "  MAD TEMP[3], IMM[2],  TEMP[2].xxxx, TEMP[1]\n"
+      "  MAD TEMP[1], IMM[4], TEMP[2].zzzz, TEMP[3]\n"
+      "  MAD TEMP[4], IMM[5], TEMP[2].wwww, TEMP[1]\n"
+
+      "  MOV OUT[0], TEMP[4]\n"
+      "  END\n";
+
+   if (!tgsi_text_translate( text,
+                             tokens,
+                             Elements(tokens) ))
+   {
+      assert(0);
+      return NULL;
+   }
+
+   return tokens;
+   }
+#endif
+
+   return old_tokens;
+}
+
+
+/***********************************************************************
+ * Vertex shaders 
+ */
+
+static void *
+svga_create_vs_state(struct pipe_context *pipe,
+                     const struct pipe_shader_state *templ)
+{
+   struct svga_context *svga = svga_context(pipe);
+   struct svga_screen *svgascreen = svga_screen(pipe->screen);
+   struct svga_vertex_shader *vs = CALLOC_STRUCT(svga_vertex_shader);
+   if (!vs)
+      return NULL;
+
+   /* substitute a debug shader?
+    */
+   vs->base.tokens = tgsi_dup_tokens(substitute_vs(svga->debug.shader_id,
+                                                   templ->tokens));
+
+
+   /* Collect basic info that we'll need later:
+    */
+   tgsi_scan_shader(vs->base.tokens, &vs->base.info);
+
+   {
+      /* Need to do construct a new template in case we substitued a
+       * debug shader.
+       */
+      struct pipe_shader_state tmp2 = *templ;
+      tmp2.tokens = vs->base.tokens;
+      vs->draw_shader = draw_create_vertex_shader(svga->swtnl.draw, &tmp2);
+   }
+
+   vs->base.id = svga->debug.shader_id++;
+   vs->base.use_sm30 = svgascreen->use_vs30;
+
+   if (SVGA_DEBUG & DEBUG_TGSI || 0) {
+      debug_printf("%s id: %u, inputs: %u, outputs: %u\n",
+                   __FUNCTION__, vs->base.id,
+                   vs->base.info.num_inputs, vs->base.info.num_outputs);
+   }
+
+   return vs;
+}
+
+static void svga_bind_vs_state(struct pipe_context *pipe, void *shader)
+{
+   struct svga_vertex_shader *vs = (struct svga_vertex_shader *)shader;
+   struct svga_context *svga = svga_context(pipe);
+
+   svga->curr.vs = vs;
+   svga->dirty |= SVGA_NEW_VS;
+}
+
+
+static void svga_delete_vs_state(struct pipe_context *pipe, void *shader)
+{
+   struct svga_context *svga = svga_context(pipe);
+   struct svga_vertex_shader *vs = (struct svga_vertex_shader *)shader;
+   struct svga_shader_result *result, *tmp;
+   enum pipe_error ret;
+
+   svga_hwtnl_flush_retry( svga );
+
+   draw_delete_vertex_shader(svga->swtnl.draw, vs->draw_shader);
+   
+   for (result = vs->base.results; result; result = tmp ) {
+      tmp = result->next;
+
+      ret = SVGA3D_DestroyShader(svga->swc, 
+                                 result->id,
+                                 SVGA3D_SHADERTYPE_VS );
+      if(ret != PIPE_OK) {
+         svga_context_flush(svga, NULL);
+         ret = SVGA3D_DestroyShader(svga->swc, 
+                                    result->id,
+                                    SVGA3D_SHADERTYPE_VS );
+         assert(ret == PIPE_OK);
+      }
+
+      util_bitmask_clear( svga->vs_bm, result->id );
+
+      svga_destroy_shader_result( result );
+
+      /*
+       * Remove stale references to this result to ensure a new result on the
+       * same address will be detected as a change.
+       */
+      if(result == svga->state.hw_draw.vs)
+         svga->state.hw_draw.vs = NULL;
+   }
+
+   FREE((void *)vs->base.tokens);
+   FREE(vs);
+}
+
+
+void svga_init_vs_functions( struct svga_context *svga )
+{
+   svga->pipe.create_vs_state = svga_create_vs_state;
+   svga->pipe.bind_vs_state = svga_bind_vs_state;
+   svga->pipe.delete_vs_state = svga_delete_vs_state;
+}
+
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
new file mode 100644
index 0000000..fc1b3c9
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -0,0 +1,440 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "util/u_memory.h"
+#include "pipe/p_inlines.h"
+#include "util/u_string.h"
+#include "util/u_math.h"
+
+#include "svga_winsys.h"
+#include "svga_context.h"
+#include "svga_screen.h"
+#include "svga_screen_texture.h"
+#include "svga_screen_buffer.h"
+#include "svga_cmd.h"
+#include "svga_debug.h"
+
+#include "svga_hw_reg.h"
+#include "svga3d_shaderdefs.h"
+
+
+#ifdef DEBUG
+int SVGA_DEBUG = 0;
+
+static const struct debug_named_value svga_debug_flags[] = {
+   { "dma",      DEBUG_DMA },
+   { "tgsi",     DEBUG_TGSI },
+   { "pipe",     DEBUG_PIPE },
+   { "state",    DEBUG_STATE },
+   { "screen",   DEBUG_SCREEN },
+   { "tex",      DEBUG_TEX },
+   { "swtnl",    DEBUG_SWTNL },
+   { "const",    DEBUG_CONSTS },
+   { "viewport", DEBUG_VIEWPORT },
+   { "views",    DEBUG_VIEWS },
+   { "perf",     DEBUG_PERF },
+   { "flush",    DEBUG_FLUSH },
+   { "sync",     DEBUG_SYNC },
+   { "cache",    DEBUG_CACHE },
+   {NULL, 0}
+};
+#endif
+
+static const char *
+svga_get_vendor( struct pipe_screen *pscreen )
+{
+   return "VMware, Inc.";
+}
+
+
+static const char *
+svga_get_name( struct pipe_screen *pscreen )
+{
+#ifdef DEBUG
+   /* Only return internal details in the DEBUG version:
+    */
+   return "SVGA3D; build: DEBUG; mutex: " PIPE_ATOMIC;
+#else
+   return "SVGA3D; build: RELEASE; ";
+#endif
+}
+
+
+
+
+static float
+svga_get_paramf(struct pipe_screen *screen, int param)
+{
+   struct svga_screen *svgascreen = svga_screen(screen);
+   struct svga_winsys_screen *sws = svgascreen->sws;
+   SVGA3dDevCapResult result;
+
+   switch (param) {
+   case PIPE_CAP_MAX_LINE_WIDTH:
+      /* fall-through */
+   case PIPE_CAP_MAX_LINE_WIDTH_AA:
+      return 7.0;
+
+   case PIPE_CAP_MAX_POINT_WIDTH:
+      /* fall-through */
+   case PIPE_CAP_MAX_POINT_WIDTH_AA:
+      /* Keep this to a reasonable size to avoid failures in
+       * conform/pntaa.c:
+       */
+      return 80.0;
+
+   case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
+      return 4.0;
+
+   case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
+      return 16.0;
+
+   case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+      return 16;
+   case PIPE_CAP_NPOT_TEXTURES:
+      return 1;
+   case PIPE_CAP_TWO_SIDED_STENCIL:
+      return 1;
+   case PIPE_CAP_GLSL:
+      return svgascreen->use_ps30 && svgascreen->use_vs30;
+   case PIPE_CAP_ANISOTROPIC_FILTER:
+      return 1;
+   case PIPE_CAP_POINT_SPRITE:
+      return 1;
+   case PIPE_CAP_MAX_RENDER_TARGETS:
+      if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_RENDER_TARGETS, &result))
+         return 1;
+      if(!result.u)
+         return 1;
+      return MIN2(result.u, PIPE_MAX_COLOR_BUFS);
+   case PIPE_CAP_OCCLUSION_QUERY:
+      return 1;
+   case PIPE_CAP_TEXTURE_SHADOW_MAP:
+      return 1;
+   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+      return SVGA_MAX_TEXTURE_LEVELS;
+   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+      return 8;  /* max 128x128x128 */
+   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+      return SVGA_MAX_TEXTURE_LEVELS;
+
+   case PIPE_CAP_TEXTURE_MIRROR_REPEAT: /* req. for GL 1.4 */
+      return 1;
+
+   case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */
+      return 1;
+
+   default:
+      return 0;
+   }
+}
+
+
+/* This is a fairly pointless interface
+ */
+static int
+svga_get_param(struct pipe_screen *screen, int param)
+{
+   return (int) svga_get_paramf( screen, param );
+}
+
+
+static INLINE SVGA3dDevCapIndex
+svga_translate_format_cap(enum pipe_format format)
+{
+   switch(format) {
+   
+   case PIPE_FORMAT_A8R8G8B8_UNORM:
+      return SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8;
+   case PIPE_FORMAT_X8R8G8B8_UNORM:
+      return SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8;
+
+   case PIPE_FORMAT_R5G6B5_UNORM:
+      return SVGA3D_DEVCAP_SURFACEFMT_R5G6B5;
+   case PIPE_FORMAT_A1R5G5B5_UNORM:
+      return SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5;
+   case PIPE_FORMAT_A4R4G4B4_UNORM:
+      return SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4;
+
+   case PIPE_FORMAT_Z16_UNORM:
+      return SVGA3D_DEVCAP_SURFACEFMT_Z_D16;
+   case PIPE_FORMAT_Z24S8_UNORM:
+      return SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8;
+   case PIPE_FORMAT_Z24X8_UNORM:
+      return SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8;
+
+   case PIPE_FORMAT_A8_UNORM:
+      return SVGA3D_DEVCAP_SURFACEFMT_ALPHA8;
+   case PIPE_FORMAT_L8_UNORM:
+      return SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8;
+
+   case PIPE_FORMAT_DXT1_RGB:
+   case PIPE_FORMAT_DXT1_RGBA:
+      return SVGA3D_DEVCAP_SURFACEFMT_DXT1;
+   case PIPE_FORMAT_DXT3_RGBA:
+      return SVGA3D_DEVCAP_SURFACEFMT_DXT3;
+   case PIPE_FORMAT_DXT5_RGBA:
+      return SVGA3D_DEVCAP_SURFACEFMT_DXT5;
+
+   default:
+      return SVGA3D_DEVCAP_MAX;
+   }
+}
+
+
+static boolean
+svga_is_format_supported( struct pipe_screen *screen,
+                          enum pipe_format format, 
+                          enum pipe_texture_target target,
+                          unsigned tex_usage, 
+                          unsigned geom_flags )
+{
+   struct svga_winsys_screen *sws = svga_screen(screen)->sws;
+   SVGA3dDevCapIndex index;
+   SVGA3dDevCapResult result;
+   
+   assert(tex_usage);
+
+   /* Override host capabilities */
+   if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
+      switch(format) { 
+
+      /* Often unsupported/problematic. This means we end up with the same
+       * visuals for all virtual hardware implementations.
+       */
+      case PIPE_FORMAT_A4R4G4B4_UNORM:
+      case PIPE_FORMAT_A1R5G5B5_UNORM:
+         return FALSE;
+         
+      /* Simulate ability to render into compressed textures */
+      case PIPE_FORMAT_DXT1_RGB:
+      case PIPE_FORMAT_DXT1_RGBA:
+      case PIPE_FORMAT_DXT3_RGBA:
+      case PIPE_FORMAT_DXT5_RGBA:
+         return TRUE;
+
+      default:
+         break;
+      }
+   }
+   
+   /* Try to query the host */
+   index = svga_translate_format_cap(format);
+   if( index < SVGA3D_DEVCAP_MAX && 
+       sws->get_cap(sws, index, &result) )
+   {
+      SVGA3dSurfaceFormatCaps mask;
+      
+      mask.value = 0;
+      if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET)
+         mask.offscreenRenderTarget = 1;
+      if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL)
+         mask.zStencil = 1;
+      if (tex_usage & PIPE_TEXTURE_USAGE_SAMPLER)
+         mask.texture = 1;
+
+      if ((result.u & mask.value) == mask.value)
+         return TRUE;
+      else
+         return FALSE;
+   }
+
+   /* Use our translate functions directly rather than relying on a
+    * duplicated list of supported formats which is prone to getting
+    * out of sync:
+    */
+   if(tex_usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
+      return svga_translate_format_render(format) != SVGA3D_FORMAT_INVALID;
+   else
+      return svga_translate_format(format) != SVGA3D_FORMAT_INVALID;
+}
+
+
+static void
+svga_fence_reference(struct pipe_screen *screen,
+                     struct pipe_fence_handle **ptr,
+                     struct pipe_fence_handle *fence)
+{
+   struct svga_winsys_screen *sws = svga_screen(screen)->sws;
+   sws->fence_reference(sws, ptr, fence);
+}
+
+
+static int
+svga_fence_signalled(struct pipe_screen *screen,
+                     struct pipe_fence_handle *fence,
+                     unsigned flag)
+{
+   struct svga_winsys_screen *sws = svga_screen(screen)->sws;
+   return sws->fence_signalled(sws, fence, flag);
+}
+
+
+static int
+svga_fence_finish(struct pipe_screen *screen,
+                  struct pipe_fence_handle *fence,
+                  unsigned flag)
+{
+   struct svga_winsys_screen *sws = svga_screen(screen)->sws;
+
+   SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n",
+            __FUNCTION__, fence);
+
+   return sws->fence_finish(sws, fence, flag);
+}
+
+
+static void
+svga_destroy_screen( struct pipe_screen *screen )
+{
+   struct svga_screen *svgascreen = svga_screen(screen);
+   
+   svga_screen_cache_cleanup(svgascreen);
+
+   pipe_mutex_destroy(svgascreen->swc_mutex);
+   pipe_mutex_destroy(svgascreen->tex_mutex);
+
+   svgascreen->swc->destroy(svgascreen->swc);
+   
+   svgascreen->sws->destroy(svgascreen->sws);
+   
+   FREE(svgascreen);
+}
+
+
+/**
+ * Create a new svga_screen object
+ */
+struct pipe_screen *
+svga_screen_create(struct svga_winsys_screen *sws)
+{
+   struct svga_screen *svgascreen;
+   struct pipe_screen *screen;
+   SVGA3dDevCapResult result;
+
+#ifdef DEBUG
+   SVGA_DEBUG = debug_get_flags_option("SVGA_DEBUG", svga_debug_flags, 0 );
+#endif
+
+   svgascreen = CALLOC_STRUCT(svga_screen);
+   if (!svgascreen)
+      goto error1;
+
+   svgascreen->debug.force_level_surface_view =
+      debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE);
+   svgascreen->debug.force_surface_view =
+      debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE);
+   svgascreen->debug.force_sampler_view =
+      debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE);
+   svgascreen->debug.no_surface_view =
+      debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE);
+   svgascreen->debug.no_sampler_view =
+      debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE);
+
+   screen = &svgascreen->screen;
+
+   screen->destroy = svga_destroy_screen;
+   screen->get_name = svga_get_name;
+   screen->get_vendor = svga_get_vendor;
+   screen->get_param = svga_get_param;
+   screen->get_paramf = svga_get_paramf;
+   screen->is_format_supported = svga_is_format_supported;
+   screen->fence_reference = svga_fence_reference;
+   screen->fence_signalled = svga_fence_signalled;
+   screen->fence_finish = svga_fence_finish;
+   svgascreen->sws = sws;
+
+   svga_screen_init_texture_functions(screen);
+   svga_screen_init_buffer_functions(screen);
+
+   svgascreen->use_ps30 =
+      sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) &&
+      result.u >= SVGA3DPSVERSION_30 ? TRUE : FALSE;
+
+   svgascreen->use_vs30 =
+      sws->get_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION, &result) &&
+      result.u >= SVGA3DVSVERSION_30 ? TRUE : FALSE;
+
+#if 1
+   /* Shader model 2.0 is unsupported at the moment. */
+   if(!svgascreen->use_ps30 || !svgascreen->use_vs30)
+      goto error2;
+#else
+   if(debug_get_bool_option("SVGA_NO_SM30", FALSE))
+      svgascreen->use_vs30 = svgascreen->use_ps30 = FALSE;
+#endif
+
+   svgascreen->swc = sws->context_create(sws);
+   if(!svgascreen->swc)
+      goto error2;
+
+   pipe_mutex_init(svgascreen->tex_mutex);
+   pipe_mutex_init(svgascreen->swc_mutex);
+
+   LIST_INITHEAD(&svgascreen->cached_buffers);
+   
+   svga_screen_cache_init(svgascreen);
+
+   return screen;
+error2:
+   FREE(svgascreen);
+error1:
+   return NULL;
+}
+
+void svga_screen_flush( struct svga_screen *svgascreen, 
+                        struct pipe_fence_handle **pfence )
+{
+   struct pipe_fence_handle *fence = NULL;
+
+   SVGA_DBG(DEBUG_PERF, "%s\n", __FUNCTION__);
+   
+   pipe_mutex_lock(svgascreen->swc_mutex);
+   svgascreen->swc->flush(svgascreen->swc, &fence);
+   pipe_mutex_unlock(svgascreen->swc_mutex);
+   
+   svga_screen_cache_flush(svgascreen, fence);
+   
+   if(pfence)
+      *pfence = fence;
+   else
+      svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL);
+}
+
+struct svga_winsys_screen *
+svga_winsys_screen(struct pipe_screen *screen)
+{
+   return svga_screen(screen)->sws;
+}
+
+#ifdef DEBUG
+struct svga_screen *
+svga_screen(struct pipe_screen *screen)
+{
+   assert(screen);
+   assert(screen->destroy == svga_destroy_screen);
+   return (struct svga_screen *)screen;
+}
+#endif
diff --git a/src/gallium/drivers/svga/svga_screen.h b/src/gallium/drivers/svga/svga_screen.h
new file mode 100644
index 0000000..b94ca7f
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_screen.h
@@ -0,0 +1,95 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_SCREEN_H
+#define SVGA_SCREEN_H
+
+
+#include "pipe/p_screen.h"
+#include "pipe/p_thread.h"
+
+#include "util/u_double_list.h"
+
+#include "svga_screen_cache.h"
+
+
+struct svga_winsys_screen;
+struct svga_winsys_context;
+struct SVGACmdMemory;
+
+#define SVGA_COMBINE_USERBUFFERS 1
+
+/**
+ * Subclass of pipe_screen
+ */
+struct svga_screen
+{
+   struct pipe_screen screen;
+   struct svga_winsys_screen *sws;
+
+   unsigned use_ps30;
+   unsigned use_vs30;
+   
+   struct {
+      boolean force_level_surface_view;
+      boolean force_surface_view;
+      boolean no_surface_view;
+      boolean force_sampler_view;
+      boolean no_sampler_view;
+   } debug;
+
+   /* The screen needs its own context */
+   struct svga_winsys_context *swc;
+   struct SVGACmdMemory *fifo;
+
+   unsigned texture_timestamp;
+   pipe_mutex tex_mutex; 
+   pipe_mutex swc_mutex; /* Protects the use of swc and dirty_buffers */
+   
+   /** 
+    * List of buffers with cached GMR. Ordered from the most recently used to
+    * the least recently used 
+    */
+   struct list_head cached_buffers;
+   
+   struct svga_host_surface_cache cache;
+};
+
+#ifndef DEBUG
+/** cast wrapper */
+static INLINE struct svga_screen *
+svga_screen(struct pipe_screen *pscreen)
+{
+   return (struct svga_screen *) pscreen;
+}
+#else
+struct svga_screen *
+svga_screen(struct pipe_screen *screen);
+#endif
+
+void svga_screen_flush( struct svga_screen *svga_screen, 
+                        struct pipe_fence_handle **pfence );
+
+#endif /* SVGA_SCREEN_H */
diff --git a/src/gallium/drivers/svga/svga_screen_buffer.c b/src/gallium/drivers/svga/svga_screen_buffer.c
new file mode 100644
index 0000000..58a1aba
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_screen_buffer.c
@@ -0,0 +1,825 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "svga_cmd.h"
+
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_inlines.h"
+#include "pipe/p_thread.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "svga_context.h"
+#include "svga_screen.h"
+#include "svga_screen_buffer.h"
+#include "svga_winsys.h"
+#include "svga_debug.h"
+
+
+/**
+ * Vertex and index buffers have to be treated slightly differently from 
+ * regular guest memory regions because the SVGA device sees them as 
+ * surfaces, and the state tracker can create/destroy without the pipe 
+ * driver, therefore we must do the uploads from the vws.
+ */
+static INLINE boolean
+svga_buffer_needs_hw_storage(unsigned usage)
+{
+   return usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_INDEX);
+}
+
+
+static INLINE enum pipe_error
+svga_buffer_create_host_surface(struct svga_screen *ss,
+                                struct svga_buffer *sbuf)
+{
+   if(!sbuf->handle) {
+      sbuf->key.flags = 0;
+      
+      sbuf->key.format = SVGA3D_BUFFER;
+      if(sbuf->base.usage & PIPE_BUFFER_USAGE_VERTEX)
+         sbuf->key.flags |= SVGA3D_SURFACE_HINT_VERTEXBUFFER;
+      if(sbuf->base.usage & PIPE_BUFFER_USAGE_INDEX)
+         sbuf->key.flags |= SVGA3D_SURFACE_HINT_INDEXBUFFER;
+      
+      sbuf->key.size.width = sbuf->base.size;
+      sbuf->key.size.height = 1;
+      sbuf->key.size.depth = 1;
+      
+      sbuf->key.numFaces = 1;
+      sbuf->key.numMipLevels = 1;
+      sbuf->key.cachable = 1;
+      
+      SVGA_DBG(DEBUG_DMA, "surface_create for buffer sz %d\n", sbuf->base.size);
+
+      sbuf->handle = svga_screen_surface_create(ss, &sbuf->key);
+      if(!sbuf->handle)
+         return PIPE_ERROR_OUT_OF_MEMORY;
+   
+      /* Always set the discard flag on the first time the buffer is written
+       * as svga_screen_surface_create might have passed a recycled host
+       * buffer.
+       */
+      sbuf->hw.flags.discard = TRUE;
+
+      SVGA_DBG(DEBUG_DMA, "   --> got sid %p sz %d (buffer)\n", sbuf->handle, sbuf->base.size);
+   }
+   
+   return PIPE_OK;
+}   
+
+
+static INLINE void
+svga_buffer_destroy_host_surface(struct svga_screen *ss,
+                                 struct svga_buffer *sbuf)
+{
+   if(sbuf->handle) {
+      SVGA_DBG(DEBUG_DMA, " ungrab sid %p sz %d\n", sbuf->handle, sbuf->base.size);
+      svga_screen_surface_destroy(ss, &sbuf->key, &sbuf->handle);
+   }
+}   
+
+
+static INLINE void
+svga_buffer_destroy_hw_storage(struct svga_screen *ss, struct svga_buffer *sbuf)
+{
+   struct svga_winsys_screen *sws = ss->sws;
+
+   assert(!sbuf->map.count);
+   assert(sbuf->hw.buf);
+   if(sbuf->hw.buf) {
+      sws->buffer_destroy(sws, sbuf->hw.buf);
+      sbuf->hw.buf = NULL;
+      assert(sbuf->head.prev && sbuf->head.next);
+      LIST_DEL(&sbuf->head);
+#ifdef DEBUG
+      sbuf->head.next = sbuf->head.prev = NULL; 
+#endif
+   }
+}
+
+static INLINE enum pipe_error
+svga_buffer_backup(struct svga_screen *ss, struct svga_buffer *sbuf)
+{
+   if (sbuf->hw.buf && sbuf->hw.num_ranges) {
+      void *src;
+
+      if (!sbuf->swbuf)
+	 sbuf->swbuf = align_malloc(sbuf->base.size, sbuf->base.alignment);
+      if (!sbuf->swbuf)
+	 return PIPE_ERROR_OUT_OF_MEMORY;
+
+      src = ss->sws->buffer_map(ss->sws, sbuf->hw.buf,
+				PIPE_BUFFER_USAGE_CPU_READ);
+      if (!src)
+	 return PIPE_ERROR;
+
+      memcpy(sbuf->swbuf, src, sbuf->base.size);
+      ss->sws->buffer_unmap(ss->sws, sbuf->hw.buf);
+   }
+
+   return PIPE_OK;
+}
+
+/**
+ * Try to make GMR space available by freeing the hardware storage of 
+ * unmapped
+ */
+boolean
+svga_buffer_free_cached_hw_storage(struct svga_screen *ss)
+{
+   struct list_head *curr;
+   struct svga_buffer *sbuf;
+   enum pipe_error ret = PIPE_OK;
+
+   curr = ss->cached_buffers.prev;
+   
+   /* free the least recently used buffer's hw storage which is not mapped */
+   do {
+      if(curr == &ss->cached_buffers)
+         return FALSE;
+
+      sbuf = LIST_ENTRY(struct svga_buffer, curr, head);
+      
+      curr = curr->prev;
+      if (sbuf->map.count == 0)
+	 ret = svga_buffer_backup(ss, sbuf);
+
+   } while(sbuf->map.count != 0 || ret != PIPE_OK);
+   
+   svga_buffer_destroy_hw_storage(ss, sbuf);
+   
+   return TRUE;
+}
+
+struct svga_winsys_buffer *
+svga_winsys_buffer_create( struct svga_screen *ss,
+                           unsigned alignment, 
+                           unsigned usage,
+                           unsigned size )
+{
+   struct svga_winsys_screen *sws = ss->sws;
+   struct svga_winsys_buffer *buf;
+   
+   /* Just try */
+   buf = sws->buffer_create(sws, alignment, usage, size);
+   if(!buf) {
+
+      SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "flushing screen to find %d bytes GMR\n", 
+               size); 
+      
+      /* Try flushing all pending DMAs */
+      svga_screen_flush(ss, NULL);
+      buf = sws->buffer_create(sws, alignment, usage, size);
+
+      SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "evicting buffers to find %d bytes GMR\n", 
+               size);
+
+      /* Try evicing all buffer storage */
+      while(!buf && svga_buffer_free_cached_hw_storage(ss))
+         buf = sws->buffer_create(sws, alignment, usage, size);
+   }
+   
+   return buf;
+}
+
+
+/**
+ * Allocate DMA'ble storage for the buffer. 
+ * 
+ * Called before mapping a buffer.
+ */
+static INLINE enum pipe_error
+svga_buffer_create_hw_storage(struct svga_screen *ss,
+                              struct svga_buffer *sbuf)
+{
+   if(!sbuf->hw.buf) {
+      unsigned alignment = sbuf->base.alignment;
+      unsigned usage = 0;
+      unsigned size = sbuf->base.size;
+      
+      sbuf->hw.buf = svga_winsys_buffer_create(ss, alignment, usage, size);
+      if(!sbuf->hw.buf)
+         return PIPE_ERROR_OUT_OF_MEMORY;
+      
+      assert(!sbuf->needs_flush);
+      assert(!sbuf->head.prev && !sbuf->head.next);
+      LIST_ADD(&sbuf->head, &ss->cached_buffers);
+   }
+   
+   return PIPE_OK;
+}
+
+
+/**
+ * Variant of SVGA3D_BufferDMA which leaves the copy box temporarily in blank.
+ */
+static enum pipe_error
+svga_buffer_upload_command(struct svga_context *svga,
+                           struct svga_buffer *sbuf)
+{
+   struct svga_winsys_context *swc = svga->swc;
+   struct svga_winsys_buffer *guest = sbuf->hw.buf;
+   struct svga_winsys_surface *host = sbuf->handle;
+   SVGA3dTransferType transfer = SVGA3D_WRITE_HOST_VRAM;
+   SVGA3dSurfaceDMAFlags flags = sbuf->hw.flags;
+   SVGA3dCmdSurfaceDMA *cmd;
+   uint32 numBoxes = sbuf->hw.num_ranges;
+   SVGA3dCopyBox *boxes;
+   SVGA3dCmdSurfaceDMASuffix *pSuffix;
+   unsigned region_flags;
+   unsigned surface_flags;
+   struct pipe_buffer *dummy;
+
+   if(transfer == SVGA3D_WRITE_HOST_VRAM) {
+      region_flags = PIPE_BUFFER_USAGE_GPU_READ;
+      surface_flags = PIPE_BUFFER_USAGE_GPU_WRITE;
+   }
+   else if(transfer == SVGA3D_READ_HOST_VRAM) {
+      region_flags = PIPE_BUFFER_USAGE_GPU_WRITE;
+      surface_flags = PIPE_BUFFER_USAGE_GPU_READ;
+   }
+   else {
+      assert(0);
+      return PIPE_ERROR_BAD_INPUT;
+   }
+
+   assert(numBoxes);
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SURFACE_DMA,
+                            sizeof *cmd + numBoxes * sizeof *boxes + sizeof *pSuffix,
+                            2);
+   if(!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->region_relocation(swc, &cmd->guest.ptr, guest, 0, region_flags);
+   cmd->guest.pitch = 0;
+
+   swc->surface_relocation(swc, &cmd->host.sid, host, surface_flags);
+   cmd->host.face = 0;
+   cmd->host.mipmap = 0;
+
+   cmd->transfer = transfer;
+
+   sbuf->hw.boxes = (SVGA3dCopyBox *)&cmd[1];
+   sbuf->hw.svga = svga;
+
+   /* Increment reference count */
+   dummy = NULL;
+   pipe_buffer_reference(&dummy, &sbuf->base);
+
+   pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + numBoxes * sizeof *boxes);
+   pSuffix->suffixSize = sizeof *pSuffix;
+   pSuffix->maximumOffset = sbuf->base.size;
+   pSuffix->flags = flags;
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+/**
+ * Patch up the upload DMA command reserved by svga_buffer_upload_command
+ * with the final ranges.
+ */
+static void
+svga_buffer_upload_flush(struct svga_context *svga,
+                         struct svga_buffer *sbuf)
+{
+   struct svga_screen *ss = svga_screen(svga->pipe.screen);
+   SVGA3dCopyBox *boxes;
+   unsigned i;
+
+   assert(sbuf->handle); 
+   assert(sbuf->hw.buf);
+   assert(sbuf->hw.num_ranges);
+   assert(sbuf->hw.svga == svga);
+   assert(sbuf->hw.boxes);
+   
+   /*
+    * Patch the DMA command with the final copy box.
+    */
+
+   SVGA_DBG(DEBUG_DMA, "dma to sid %p\n", sbuf->handle);
+
+   boxes = sbuf->hw.boxes;
+   for(i = 0; i < sbuf->hw.num_ranges; ++i) {
+      SVGA_DBG(DEBUG_DMA, "  bytes %u - %u\n",
+               sbuf->hw.ranges[i].start, sbuf->hw.ranges[i].end);
+
+      boxes[i].x = sbuf->hw.ranges[i].start;
+      boxes[i].y = 0;
+      boxes[i].z = 0;
+      boxes[i].w = sbuf->hw.ranges[i].end - sbuf->hw.ranges[i].start;
+      boxes[i].h = 1;
+      boxes[i].d = 1;
+      boxes[i].srcx = sbuf->hw.ranges[i].start;
+      boxes[i].srcy = 0;
+      boxes[i].srcz = 0;
+   }
+
+   sbuf->hw.num_ranges = 0;
+   memset(&sbuf->hw.flags, 0, sizeof sbuf->hw.flags);
+
+   assert(sbuf->head.prev && sbuf->head.next);
+   LIST_DEL(&sbuf->head);
+   sbuf->needs_flush = FALSE;
+   /* XXX: do we care about cached_buffers any more ?*/
+   LIST_ADD(&sbuf->head, &ss->cached_buffers);
+
+   sbuf->hw.svga = NULL;
+   sbuf->hw.boxes = NULL;
+
+   /* Decrement reference count */
+   pipe_reference(&(sbuf->base.reference), NULL);
+   sbuf = NULL;
+}
+
+
+/**
+ * Queue a DMA upload of a range of this buffer to the host.
+ *
+ * This function only notes the range down. It doesn't actually emit a DMA
+ * upload command. That only happens when a context tries to refer to this
+ * buffer, and the DMA upload command is added to that context's command buffer.
+ * 
+ * We try to lump as many contiguous DMA transfers together as possible.
+ */
+static void
+svga_buffer_upload_queue(struct svga_buffer *sbuf,
+                         unsigned start,
+                         unsigned end)
+{
+   unsigned i;
+
+   assert(sbuf->hw.buf);
+   assert(end > start);
+   
+   /*
+    * Try to grow one of the ranges.
+    *
+    * Note that it is not this function task to care about overlapping ranges,
+    * as the GMR was already given so it is too late to do anything. Situations
+    * where overlapping ranges may pose a problem should be detected via
+    * pipe_context::is_buffer_referenced and the context that refers to the
+    * buffer should be flushed.
+    */
+
+   for(i = 0; i < sbuf->hw.num_ranges; ++i) {
+      if(start <= sbuf->hw.ranges[i].end && sbuf->hw.ranges[i].start <= end) {
+         sbuf->hw.ranges[i].start = MIN2(sbuf->hw.ranges[i].start, start);
+         sbuf->hw.ranges[i].end   = MAX2(sbuf->hw.ranges[i].end,    end);
+         return;
+      }
+   }
+
+   /*
+    * We cannot add a new range to an existing DMA command, so patch-up the
+    * pending DMA upload and start clean.
+    */
+
+   if(sbuf->needs_flush)
+      svga_buffer_upload_flush(sbuf->hw.svga, sbuf);
+
+   assert(!sbuf->needs_flush);
+   assert(!sbuf->hw.svga);
+   assert(!sbuf->hw.boxes);
+
+   /*
+    * Add a new range.
+    */
+
+   sbuf->hw.ranges[sbuf->hw.num_ranges].start = start;
+   sbuf->hw.ranges[sbuf->hw.num_ranges].end = end;
+   ++sbuf->hw.num_ranges;
+}
+
+
+static void *
+svga_buffer_map_range( struct pipe_screen *screen,
+                       struct pipe_buffer *buf,
+                       unsigned offset, unsigned length,
+                       unsigned usage )
+{
+   struct svga_screen *ss = svga_screen(screen); 
+   struct svga_winsys_screen *sws = ss->sws;
+   struct svga_buffer *sbuf = svga_buffer( buf );
+   void *map;
+
+   if(sbuf->swbuf) {
+      /* User/malloc buffer */
+      map = sbuf->swbuf;
+   }
+   else {
+      if(!sbuf->hw.buf) {
+         struct svga_winsys_surface *handle = sbuf->handle;
+
+         if(svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK)
+            return NULL;
+         
+         /* Populate the hardware storage if the host surface pre-existed */
+         if((usage & PIPE_BUFFER_USAGE_CPU_READ) && handle) {
+            SVGA3dSurfaceDMAFlags flags;
+            enum pipe_error ret;
+            struct pipe_fence_handle *fence = NULL;
+            
+            SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "dma from sid %p (buffer), bytes %u - %u\n", 
+                     sbuf->handle, 0, sbuf->base.size);
+
+            memset(&flags, 0, sizeof flags);
+            
+            ret = SVGA3D_BufferDMA(ss->swc,
+                                   sbuf->hw.buf,
+                                   sbuf->handle,
+                                   SVGA3D_READ_HOST_VRAM,
+                                   sbuf->base.size,
+                                   0,
+                                   flags);
+            if(ret != PIPE_OK) {
+               ss->swc->flush(ss->swc, NULL);
+               
+               ret = SVGA3D_BufferDMA(ss->swc,
+                                      sbuf->hw.buf,
+                                      sbuf->handle,
+                                      SVGA3D_READ_HOST_VRAM,
+                                      sbuf->base.size,
+                                      0,
+                                      flags);
+               assert(ret == PIPE_OK);
+            }
+            
+            ss->swc->flush(ss->swc, &fence);
+            sws->fence_finish(sws, fence, 0);
+            sws->fence_reference(sws, &fence, NULL);
+         }
+      }
+      else {
+         if((usage & PIPE_BUFFER_USAGE_CPU_READ) && !sbuf->needs_flush) {
+            /* We already had the hardware storage but we would have to issue
+             * a download if we hadn't, so move the buffer to the begginning
+             * of the LRU list.
+             */
+            assert(sbuf->head.prev && sbuf->head.next);
+            LIST_DEL(&sbuf->head);
+            LIST_ADD(&sbuf->head, &ss->cached_buffers);
+         }
+      }
+         
+      map = sws->buffer_map(sws, sbuf->hw.buf, usage);
+   }
+
+   if(map) {
+      pipe_mutex_lock(ss->swc_mutex);
+
+      ++sbuf->map.count;
+
+      if (usage & PIPE_BUFFER_USAGE_CPU_WRITE) {
+         assert(sbuf->map.count <= 1);
+         sbuf->map.writing = TRUE;
+         if (usage & PIPE_BUFFER_USAGE_FLUSH_EXPLICIT)
+            sbuf->map.flush_explicit = TRUE;
+      }
+      
+      pipe_mutex_unlock(ss->swc_mutex);
+   }
+   
+   return map;
+}
+
+static void 
+svga_buffer_flush_mapped_range( struct pipe_screen *screen,
+                                struct pipe_buffer *buf,
+                                unsigned offset, unsigned length)
+{
+   struct svga_buffer *sbuf = svga_buffer( buf );
+   struct svga_screen *ss = svga_screen(screen);
+   
+   pipe_mutex_lock(ss->swc_mutex);
+   assert(sbuf->map.writing);
+   if(sbuf->map.writing) {
+      assert(sbuf->map.flush_explicit);
+      if(sbuf->hw.buf)
+         svga_buffer_upload_queue(sbuf, offset, offset + length);
+   }
+   pipe_mutex_unlock(ss->swc_mutex);
+}
+
+static void 
+svga_buffer_unmap( struct pipe_screen *screen,
+                   struct pipe_buffer *buf)
+{
+   struct svga_screen *ss = svga_screen(screen); 
+   struct svga_winsys_screen *sws = ss->sws;
+   struct svga_buffer *sbuf = svga_buffer( buf );
+   
+   pipe_mutex_lock(ss->swc_mutex);
+   
+   assert(sbuf->map.count);
+   if(sbuf->map.count)
+      --sbuf->map.count;
+
+   if(sbuf->hw.buf)
+      sws->buffer_unmap(sws, sbuf->hw.buf);
+
+   if(sbuf->map.writing) {
+      if(!sbuf->map.flush_explicit) {
+         /* No mapped range was flushed -- flush the whole buffer */
+         SVGA_DBG(DEBUG_DMA, "flushing the whole buffer\n");
+   
+         if(sbuf->hw.buf)
+            svga_buffer_upload_queue(sbuf, 0, sbuf->base.size);
+      }
+      
+      sbuf->map.writing = FALSE;
+      sbuf->map.flush_explicit = FALSE;
+   }
+
+   pipe_mutex_unlock(ss->swc_mutex);
+}
+
+static void
+svga_buffer_destroy( struct pipe_buffer *buf )
+{
+   struct svga_screen *ss = svga_screen(buf->screen); 
+   struct svga_buffer *sbuf = svga_buffer( buf );
+
+   assert(!p_atomic_read(&buf->reference.count));
+   
+   assert(!sbuf->needs_flush);
+
+   if(sbuf->handle) {
+      SVGA_DBG(DEBUG_DMA, "release sid %p sz %d\n", sbuf->handle, sbuf->base.size);
+      svga_screen_surface_destroy(ss, &sbuf->key, &sbuf->handle);
+   }
+   
+   if(sbuf->hw.buf)
+      svga_buffer_destroy_hw_storage(ss, sbuf);
+   
+   if(sbuf->swbuf && !sbuf->user)
+      align_free(sbuf->swbuf);
+   
+   FREE(sbuf);
+}
+
+static struct pipe_buffer *
+svga_buffer_create(struct pipe_screen *screen,
+                   unsigned alignment,
+                   unsigned usage,
+                   unsigned size)
+{
+   struct svga_screen *ss = svga_screen(screen);
+   struct svga_buffer *sbuf;
+   
+   sbuf = CALLOC_STRUCT(svga_buffer);
+   if(!sbuf)
+      goto error1;
+      
+   sbuf->magic = SVGA_BUFFER_MAGIC;
+   
+   pipe_reference_init(&sbuf->base.reference, 1);
+   sbuf->base.screen = screen;
+   sbuf->base.alignment = alignment;
+   sbuf->base.usage = usage;
+   sbuf->base.size = size;
+
+   if(svga_buffer_needs_hw_storage(usage)) {
+      if(svga_buffer_create_host_surface(ss, sbuf) != PIPE_OK)
+         goto error2;
+   }
+   else {
+      if(alignment < sizeof(void*))
+         alignment = sizeof(void*);
+
+      usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+      
+      sbuf->swbuf = align_malloc(size, alignment);
+      if(!sbuf->swbuf)
+         goto error2;
+   }
+      
+   return &sbuf->base; 
+
+error2:
+   FREE(sbuf);
+error1:
+   return NULL;
+}
+
+static struct pipe_buffer *
+svga_user_buffer_create(struct pipe_screen *screen,
+                        void *ptr,
+                        unsigned bytes)
+{
+   struct svga_buffer *sbuf;
+   
+   sbuf = CALLOC_STRUCT(svga_buffer);
+   if(!sbuf)
+      goto no_sbuf;
+      
+   sbuf->magic = SVGA_BUFFER_MAGIC;
+   
+   sbuf->swbuf = ptr;
+   sbuf->user = TRUE;
+   
+   pipe_reference_init(&sbuf->base.reference, 1);
+   sbuf->base.screen = screen;
+   sbuf->base.alignment = 1;
+   sbuf->base.usage = 0;
+   sbuf->base.size = bytes;
+   
+   return &sbuf->base; 
+
+no_sbuf:
+   return NULL;
+}
+
+   
+void
+svga_screen_init_buffer_functions(struct pipe_screen *screen)
+{
+   screen->buffer_create = svga_buffer_create;
+   screen->user_buffer_create = svga_user_buffer_create;
+   screen->buffer_map_range = svga_buffer_map_range;
+   screen->buffer_flush_mapped_range = svga_buffer_flush_mapped_range;
+   screen->buffer_unmap = svga_buffer_unmap;
+   screen->buffer_destroy = svga_buffer_destroy;
+}
+
+
+/** 
+ * Copy the contents of the user buffer / malloc buffer to a hardware buffer.
+ */
+static INLINE enum pipe_error
+svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf)
+{
+   if(!sbuf->hw.buf) {
+      enum pipe_error ret;
+      void *map;
+      
+      assert(sbuf->swbuf);
+      if(!sbuf->swbuf)
+         return PIPE_ERROR;
+      
+      ret = svga_buffer_create_hw_storage(ss, sbuf);
+      assert(ret == PIPE_OK);
+      if(ret != PIPE_OK)
+         return ret;
+
+      pipe_mutex_lock(ss->swc_mutex);
+      map = ss->sws->buffer_map(ss->sws, sbuf->hw.buf, PIPE_BUFFER_USAGE_CPU_WRITE);
+      assert(map);
+      if(!map) {
+	 pipe_mutex_unlock(ss->swc_mutex);
+         return PIPE_ERROR_OUT_OF_MEMORY;
+      }
+
+      memcpy(map, sbuf->swbuf, sbuf->base.size);
+      ss->sws->buffer_unmap(ss->sws, sbuf->hw.buf);
+
+      /* This user/malloc buffer is now indistinguishable from a gpu buffer */
+      assert(!sbuf->map.count);
+      if(!sbuf->map.count) {
+         if(sbuf->user)
+            sbuf->user = FALSE;
+         else
+            align_free(sbuf->swbuf);
+         sbuf->swbuf = NULL;
+      }
+      
+      svga_buffer_upload_queue(sbuf, 0, sbuf->base.size);
+   }
+   
+   pipe_mutex_unlock(ss->swc_mutex);
+   return PIPE_OK;
+}
+
+
+struct svga_winsys_surface *
+svga_buffer_handle(struct svga_context *svga,
+                   struct pipe_buffer *buf)
+{
+   struct pipe_screen *screen = svga->pipe.screen;
+   struct svga_screen *ss = svga_screen(screen);
+   struct svga_buffer *sbuf;
+   enum pipe_error ret;
+
+   if(!buf)
+      return NULL;
+
+   sbuf = svga_buffer(buf);
+   
+   assert(!sbuf->map.count);
+   
+   if(!sbuf->handle) {
+      ret = svga_buffer_create_host_surface(ss, sbuf);
+      if(ret != PIPE_OK)
+	 return NULL;
+
+      ret = svga_buffer_update_hw(ss, sbuf);
+      if(ret != PIPE_OK)
+	 return NULL;
+   }
+
+   if(!sbuf->needs_flush && sbuf->hw.num_ranges) {
+      /* Queue the buffer for flushing */
+      ret = svga_buffer_upload_command(svga, sbuf);
+      if(ret != PIPE_OK)
+         /* XXX: Should probably have a richer return value */
+         return NULL;
+
+      assert(sbuf->hw.svga == svga);
+
+      sbuf->needs_flush = TRUE;
+      assert(sbuf->head.prev && sbuf->head.next);
+      LIST_DEL(&sbuf->head);
+      LIST_ADDTAIL(&sbuf->head, &svga->dirty_buffers);
+   }
+
+   return sbuf->handle;
+}
+
+struct pipe_buffer *
+svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
+				enum SVGA3dSurfaceFormat format,
+				struct svga_winsys_surface *srf)
+{
+   struct pipe_buffer *buf;
+   struct svga_buffer *sbuf;
+   struct svga_winsys_screen *sws = svga_winsys_screen(screen);
+
+   buf = svga_buffer_create(screen, 0, SVGA_BUFFER_USAGE_WRAPPED, 0);
+   if (!buf)
+      return NULL;
+
+   sbuf = svga_buffer(buf);
+
+   /*
+    * We are not the creator of this surface and therefore we must not
+    * cache it for reuse. Set the cacheable flag to zero in the key to
+    * prevent this.
+    */
+   sbuf->key.format = format;
+   sbuf->key.cachable = 0;
+   sws->surface_reference(sws, &sbuf->handle, srf);
+
+   return buf;
+}
+
+
+struct svga_winsys_surface *
+svga_screen_buffer_get_winsys_surface(struct pipe_buffer *buffer)
+{
+   struct svga_winsys_screen *sws = svga_winsys_screen(buffer->screen);
+   struct svga_winsys_surface *vsurf = NULL;
+
+   assert(svga_buffer(buffer)->key.cachable == 0);
+   svga_buffer(buffer)->key.cachable = 0;
+   sws->surface_reference(sws, &vsurf, svga_buffer(buffer)->handle);
+   return vsurf;
+}
+
+void
+svga_context_flush_buffers(struct svga_context *svga)
+{
+   struct list_head *curr, *next;
+   struct svga_buffer *sbuf;
+
+   curr = svga->dirty_buffers.next;
+   next = curr->next;
+   while(curr != &svga->dirty_buffers) {
+      sbuf = LIST_ENTRY(struct svga_buffer, curr, head);
+
+      assert(p_atomic_read(&sbuf->base.reference.count) != 0);
+      assert(sbuf->needs_flush);
+      
+      svga_buffer_upload_flush(svga, sbuf);
+
+      curr = next; 
+      next = curr->next;
+   }
+}
diff --git a/src/gallium/drivers/svga/svga_screen_buffer.h b/src/gallium/drivers/svga/svga_screen_buffer.h
new file mode 100644
index 0000000..5d7af5a
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_screen_buffer.h
@@ -0,0 +1,190 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_BUFFER_H
+#define SVGA_BUFFER_H
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+
+#include "util/u_double_list.h"
+
+#include "svga_screen_cache.h"
+
+
+#define SVGA_BUFFER_MAGIC 0x344f9005
+
+/**
+ * Maximum number of discontiguous ranges
+ */
+#define SVGA_BUFFER_MAX_RANGES 32
+
+
+struct svga_screen;
+struct svga_context;
+struct svga_winsys_buffer;
+struct svga_winsys_surface;
+
+
+struct svga_buffer_range
+{
+   unsigned start;
+   unsigned end;
+};
+
+
+/**
+ * Describe a
+ *
+ * This holds the information to emit a SVGA3dCmdSurfaceDMA.
+ */
+struct svga_buffer_upload
+{
+   /**
+    * Guest memory region.
+    */
+   struct svga_winsys_buffer *buf;
+
+   struct svga_buffer_range ranges[SVGA_BUFFER_MAX_RANGES];
+   unsigned num_ranges;
+
+   SVGA3dSurfaceDMAFlags flags;
+
+   /**
+    * Pointer to the DMA copy box *inside* the command buffer.
+    */
+   SVGA3dCopyBox *boxes;
+
+   /**
+    * Context that has the pending DMA to this buffer.
+    */
+   struct svga_context *svga;
+};
+
+
+/**
+ * SVGA pipe buffer.
+ */
+struct svga_buffer 
+{
+   struct pipe_buffer base;
+
+   /** 
+    * Marker to detect bad casts in runtime.
+    */ 
+   uint32_t magic;
+
+   /**
+    * Regular (non DMA'able) memory.
+    * 
+    * Used for user buffers or for buffers which we know before hand that can
+    * never be used by the virtual hardware directly, such as constant buffers.
+    */
+   void *swbuf;
+   
+   /** 
+    * Whether swbuf was created by the user or not.
+    */
+   boolean user;
+   
+   /**
+    * DMA'ble memory.
+    * 
+    * A piece of GMR memory. It is created when mapping the buffer, and will be
+    * used to upload/download vertex data from the host.
+    */
+   struct svga_buffer_upload hw;
+
+   /**
+    * Creation key for the host surface handle.
+    * 
+    * This structure describes all the host surface characteristics so that it 
+    * can be looked up in cache, since creating a host surface is often a slow
+    * operation.
+    */
+   struct svga_host_surface_cache_key key;
+   
+   /**
+    * Host surface handle.
+    * 
+    * This is a platform independent abstraction for host SID. We create when 
+    * trying to bind
+    */
+   struct svga_winsys_surface *handle;
+   
+   struct {
+      unsigned count;
+      boolean writing;
+      boolean flush_explicit;
+   } map;
+   
+   boolean needs_flush;
+   struct list_head head;
+};
+
+
+static INLINE struct svga_buffer *
+svga_buffer(struct pipe_buffer *buffer)
+{
+   if (buffer) {
+      assert(((struct svga_buffer *)buffer)->magic == SVGA_BUFFER_MAGIC);
+      return (struct svga_buffer *)buffer;
+   }
+   return NULL;
+}
+
+
+/**
+ * Returns TRUE for user buffers.  We may
+ * decide to use an alternate upload path for these buffers.
+ */
+static INLINE boolean 
+svga_buffer_is_user_buffer( struct pipe_buffer *buffer )
+{
+   return svga_buffer(buffer)->user;
+}
+
+
+void
+svga_screen_init_buffer_functions(struct pipe_screen *screen);
+
+struct svga_winsys_surface *
+svga_buffer_handle(struct svga_context *svga,
+                   struct pipe_buffer *buf);
+
+void
+svga_context_flush_buffers(struct svga_context *svga);
+
+boolean
+svga_buffer_free_cached_hw_storage(struct svga_screen *ss);
+
+struct svga_winsys_buffer *
+svga_winsys_buffer_create(struct svga_screen *ss,
+                          unsigned alignment, 
+                          unsigned usage,
+                          unsigned size);
+
+#endif /* SVGA_BUFFER_H */
diff --git a/src/gallium/drivers/svga/svga_screen_cache.c b/src/gallium/drivers/svga/svga_screen_cache.c
new file mode 100644
index 0000000..eff36e0
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_screen_cache.c
@@ -0,0 +1,347 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "util/u_memory.h"
+#include "util/u_hash.h"
+
+#include "svga_debug.h"
+#include "svga_winsys.h"
+#include "svga_screen.h"
+#include "svga_screen_cache.h"
+
+
+#define SVGA_SURFACE_CACHE_ENABLED 1
+
+
+/** 
+ * Compute the bucket for this key. 
+ */
+static INLINE unsigned
+svga_screen_cache_bucket(const struct svga_host_surface_cache_key *key)
+{
+   return util_hash_crc32( key, sizeof *key ) % SVGA_HOST_SURFACE_CACHE_BUCKETS;
+}
+
+
+static INLINE struct svga_winsys_surface *
+svga_screen_cache_lookup(struct svga_screen *svgascreen,
+                         const struct svga_host_surface_cache_key *key)
+{
+   struct svga_host_surface_cache *cache = &svgascreen->cache;
+   struct svga_winsys_screen *sws = svgascreen->sws;
+   struct svga_host_surface_cache_entry *entry;
+   struct svga_winsys_surface *handle = NULL;
+   struct list_head *curr, *next;
+   unsigned bucket;
+   unsigned tries = 0;
+
+   assert(key->cachable);
+
+   bucket = svga_screen_cache_bucket(key);
+
+   pipe_mutex_lock(cache->mutex);
+
+   curr = cache->bucket[bucket].next;
+   next = curr->next;
+   while(curr != &cache->bucket[bucket]) {
+      ++tries;
+      
+      entry = LIST_ENTRY(struct svga_host_surface_cache_entry, curr, bucket_head);
+
+      assert(entry->handle);
+      
+      if(memcmp(&entry->key, key, sizeof *key) == 0 &&
+         sws->fence_signalled( sws, entry->fence, 0 ) == 0) {
+         assert(sws->surface_is_flushed(sws, entry->handle));
+         
+         handle = entry->handle; // Reference is transfered here.
+         entry->handle = NULL;
+         
+         LIST_DEL(&entry->bucket_head);
+
+         LIST_DEL(&entry->head);
+         
+         LIST_ADD(&entry->head, &cache->empty);
+
+         break;
+      }
+
+      curr = next; 
+      next = curr->next;
+   }
+
+   pipe_mutex_unlock(cache->mutex);
+   
+   if (SVGA_DEBUG & DEBUG_DMA)
+      debug_printf("%s: cache %s after %u tries (bucket %d)\n", __FUNCTION__, 
+                   handle ? "hit" : "miss", tries, bucket);
+   
+   return handle;
+}
+
+
+/*
+ * Transfers a handle reference.
+ */
+                           
+static INLINE void
+svga_screen_cache_add(struct svga_screen *svgascreen,
+                      const struct svga_host_surface_cache_key *key, 
+                      struct svga_winsys_surface **p_handle)
+{
+   struct svga_host_surface_cache *cache = &svgascreen->cache;
+   struct svga_winsys_screen *sws = svgascreen->sws;
+   struct svga_host_surface_cache_entry *entry = NULL;
+   struct svga_winsys_surface *handle = *p_handle;
+   
+   assert(key->cachable);
+
+   assert(handle);
+   if(!handle)
+      return;
+   
+   *p_handle = NULL;
+   pipe_mutex_lock(cache->mutex);
+   
+   if(!LIST_IS_EMPTY(&cache->empty)) {
+      /* use the first empty entry */
+      entry = LIST_ENTRY(struct svga_host_surface_cache_entry, cache->empty.next, head);
+        
+      LIST_DEL(&entry->head);
+   }
+   else if(!LIST_IS_EMPTY(&cache->unused)) {
+      /* free the last used buffer and reuse its entry */
+      entry = LIST_ENTRY(struct svga_host_surface_cache_entry, cache->unused.prev, head);
+      SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
+               "unref sid %p (make space)\n", entry->handle);
+      sws->surface_reference(sws, &entry->handle, NULL);
+
+      LIST_DEL(&entry->bucket_head);
+
+      LIST_DEL(&entry->head);
+   }
+
+   if(entry) {
+      entry->handle = handle;
+      memcpy(&entry->key, key, sizeof entry->key);
+   
+      SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
+               "cache sid %p\n", entry->handle);
+      LIST_ADD(&entry->head, &cache->validated);
+   }
+   else {
+      /* Couldn't cache the buffer -- this really shouldn't happen */
+      SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
+               "unref sid %p (couldn't find space)\n", handle);
+      sws->surface_reference(sws, &handle, NULL);
+   }
+   
+   pipe_mutex_unlock(cache->mutex);
+}
+
+
+/**
+ * Called during the screen flush to move all buffers not in a validate list
+ * into the unused list.
+ */
+void
+svga_screen_cache_flush(struct svga_screen *svgascreen,
+                        struct pipe_fence_handle *fence)
+{
+   struct svga_host_surface_cache *cache = &svgascreen->cache;
+   struct svga_winsys_screen *sws = svgascreen->sws;
+   struct svga_host_surface_cache_entry *entry;
+   struct list_head *curr, *next;
+   unsigned bucket;
+
+   pipe_mutex_lock(cache->mutex);
+
+   curr = cache->validated.next;
+   next = curr->next;
+   while(curr != &cache->validated) {
+      entry = LIST_ENTRY(struct svga_host_surface_cache_entry, curr, head);
+
+      assert(entry->handle);
+
+      if(sws->surface_is_flushed(sws, entry->handle)) {
+         LIST_DEL(&entry->head);
+         
+         svgascreen->sws->fence_reference(svgascreen->sws, &entry->fence, fence);
+
+         LIST_ADD(&entry->head, &cache->unused);
+
+         bucket = svga_screen_cache_bucket(&entry->key);
+         LIST_ADD(&entry->bucket_head, &cache->bucket[bucket]);
+      }
+
+      curr = next; 
+      next = curr->next;
+   }
+
+   pipe_mutex_unlock(cache->mutex);
+}
+
+
+void
+svga_screen_cache_cleanup(struct svga_screen *svgascreen)
+{
+   struct svga_host_surface_cache *cache = &svgascreen->cache;
+   struct svga_winsys_screen *sws = svgascreen->sws;
+   unsigned i;
+   
+   for(i = 0; i < SVGA_HOST_SURFACE_CACHE_SIZE; ++i) {
+      if(cache->entries[i].handle) {
+	 SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
+                  "unref sid %p (shutdown)\n", cache->entries[i].handle);
+	 sws->surface_reference(sws, &cache->entries[i].handle, NULL);
+      }
+
+      if(cache->entries[i].fence)
+         svgascreen->sws->fence_reference(svgascreen->sws, &cache->entries[i].fence, NULL);
+   }
+   
+   pipe_mutex_destroy(cache->mutex);
+}
+
+
+enum pipe_error
+svga_screen_cache_init(struct svga_screen *svgascreen)
+{
+   struct svga_host_surface_cache *cache = &svgascreen->cache;
+   unsigned i;
+
+   pipe_mutex_init(cache->mutex);
+   
+   for(i = 0; i < SVGA_HOST_SURFACE_CACHE_BUCKETS; ++i)
+      LIST_INITHEAD(&cache->bucket[i]);
+
+   LIST_INITHEAD(&cache->unused);
+   
+   LIST_INITHEAD(&cache->validated);
+   
+   LIST_INITHEAD(&cache->empty);
+   for(i = 0; i < SVGA_HOST_SURFACE_CACHE_SIZE; ++i)
+      LIST_ADDTAIL(&cache->entries[i].head, &cache->empty);
+
+   return PIPE_OK;
+}
+
+                           
+struct svga_winsys_surface *
+svga_screen_surface_create(struct svga_screen *svgascreen,
+                           struct svga_host_surface_cache_key *key)
+{
+   struct svga_winsys_screen *sws = svgascreen->sws;
+   struct svga_winsys_surface *handle = NULL;
+   boolean cachable = SVGA_SURFACE_CACHE_ENABLED && key->cachable;
+
+   SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
+            "%s sz %dx%dx%d mips %d faces %d cachable %d\n", 
+            __FUNCTION__,
+            key->size.width,
+            key->size.height,
+            key->size.depth,
+            key->numMipLevels,
+            key->numFaces,
+            key->cachable);
+
+   if (cachable) {
+      if (key->format == SVGA3D_BUFFER) {
+         /* For buffers, round the buffer size up to the nearest power
+          * of two to increase the probability of cache hits.  Keep
+          * texture surface dimensions unchanged.
+          */
+         uint32_t size = 1;
+         while(size < key->size.width)
+            size <<= 1;
+         key->size.width = size;
+	 /* Since we're reusing buffers we're effectively transforming all
+	  * of them into dynamic buffers.
+	  *
+	  * It would be nice to not cache long lived static buffers. But there
+	  * is no way to detect the long lived from short lived ones yet. A
+	  * good heuristic would be buffer size.
+	  */
+	 key->flags &= ~SVGA3D_SURFACE_HINT_STATIC;
+	 key->flags |= SVGA3D_SURFACE_HINT_DYNAMIC;
+      }
+
+      handle = svga_screen_cache_lookup(svgascreen, key);
+      if (handle) {
+         if (key->format == SVGA3D_BUFFER)
+            SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
+                     "reuse sid %p sz %d (buffer)\n", handle, 
+                     key->size.width);
+         else
+            SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
+                     "reuse sid %p sz %dx%dx%d mips %d faces %d\n", handle, 
+                     key->size.width,
+                     key->size.height,
+                     key->size.depth,
+                     key->numMipLevels,
+                     key->numFaces);
+      }
+   }
+
+   if (!handle) {
+      handle = sws->surface_create(sws,
+                                   key->flags,
+                                   key->format,
+                                   key->size, 
+                                   key->numFaces, 
+                                   key->numMipLevels);
+      if (handle)
+         SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
+                  "  CREATE sid %p sz %dx%dx%d\n", 
+                  handle, 
+                  key->size.width,
+                  key->size.height,
+                  key->size.depth);
+   }
+
+   return handle;
+}
+
+
+void
+svga_screen_surface_destroy(struct svga_screen *svgascreen,
+                            const struct svga_host_surface_cache_key *key,
+                            struct svga_winsys_surface **p_handle)
+{
+   struct svga_winsys_screen *sws = svgascreen->sws;
+   
+   /* We only set the cachable flag for surfaces of which we are the
+    * exclusive owner.  So just hold onto our existing reference in
+    * that case.
+    */
+   if(SVGA_SURFACE_CACHE_ENABLED && key->cachable) {
+      svga_screen_cache_add(svgascreen, key, p_handle);
+   }
+   else {
+      SVGA_DBG(DEBUG_DMA,
+               "unref sid %p (uncachable)\n", *p_handle);
+      sws->surface_reference(sws, p_handle, NULL);
+   }
+}
diff --git a/src/gallium/drivers/svga/svga_screen_cache.h b/src/gallium/drivers/svga/svga_screen_cache.h
new file mode 100644
index 0000000..f5aa740
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_screen_cache.h
@@ -0,0 +1,144 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_SCREEN_CACHE_H_
+#define SVGA_SCREEN_CACHE_H_
+
+
+#include "svga_types.h"
+#include "svga_reg.h"
+#include "svga3d_reg.h"
+
+#include "pipe/p_thread.h"
+
+#include "util/u_double_list.h"
+
+
+/* Guess the storage size of cached surfaces and try and keep it under
+ * this amount:
+ */ 
+#define SVGA_HOST_SURFACE_CACHE_BYTES 16*1024*1024
+
+/* Maximum number of discrete surfaces in the cache:
+ */
+#define SVGA_HOST_SURFACE_CACHE_SIZE 1024
+
+/* Number of hash buckets:
+ */
+#define SVGA_HOST_SURFACE_CACHE_BUCKETS 256
+
+
+struct svga_winsys_surface;
+struct svga_screen;
+
+/**
+ * Same as svga_winsys_screen::surface_create.
+ */
+struct svga_host_surface_cache_key
+{
+   SVGA3dSurfaceFlags flags;
+   SVGA3dSurfaceFormat format;
+   SVGA3dSize size;
+   uint32_t numFaces:24;
+   uint32_t numMipLevels:7;
+   uint32_t cachable:1;         /* False if this is a shared surface */
+};
+
+
+struct svga_host_surface_cache_entry 
+{
+   /** 
+    * Head for the LRU list, svga_host_surface_cache::unused, and
+    * svga_host_surface_cache::empty
+    */
+   struct list_head head;
+   
+   /** Head for the bucket lists. */
+   struct list_head bucket_head;
+
+   struct svga_host_surface_cache_key key;
+   struct svga_winsys_surface *handle;
+   
+   struct pipe_fence_handle *fence;
+};
+
+
+/**
+ * Cache of the host surfaces.
+ * 
+ * A cache entry can be in the following stages:
+ * 1. empty
+ * 2. holding a buffer in a validate list
+ * 3. holding a flushed buffer (not in any validate list) with an active fence
+ * 4. holding a flushed buffer with an expired fence
+ * 
+ * An entry progresses from 1 -> 2 -> 3 -> 4. When we need an entry to put a 
+ * buffer into we preferencial take from 1, or from the least recentely used 
+ * buffer from 3/4.
+ */
+struct svga_host_surface_cache 
+{
+   pipe_mutex mutex;
+   
+   /* Unused buffers are put in buckets to speed up lookups */
+   struct list_head bucket[SVGA_HOST_SURFACE_CACHE_BUCKETS];
+   
+   /* Entries with unused buffers, ordered from most to least recently used 
+    * (3 and 4) */
+   struct list_head unused;
+   
+   /* Entries with buffers still in validate lists (2) */
+   struct list_head validated;
+   
+   /** Empty entries (1) */
+   struct list_head empty;
+
+   /** The actual storage for the entries */
+   struct svga_host_surface_cache_entry entries[SVGA_HOST_SURFACE_CACHE_SIZE];
+};
+
+
+void
+svga_screen_cache_cleanup(struct svga_screen *svgascreen);
+
+void
+svga_screen_cache_flush(struct svga_screen *svgascreen,
+                        struct pipe_fence_handle *fence);
+
+enum pipe_error
+svga_screen_cache_init(struct svga_screen *svgascreen);
+
+
+struct svga_winsys_surface *
+svga_screen_surface_create(struct svga_screen *svgascreen,
+                           struct svga_host_surface_cache_key *key);
+
+void
+svga_screen_surface_destroy(struct svga_screen *svgascreen,
+                            const struct svga_host_surface_cache_key *key,
+                            struct svga_winsys_surface **handle);
+
+
+#endif /* SVGA_SCREEN_CACHE_H_ */
diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c
new file mode 100644
index 0000000..2224c2d
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_screen_texture.c
@@ -0,0 +1,1090 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "svga_cmd.h"
+
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_inlines.h"
+#include "pipe/p_thread.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "svga_screen.h"
+#include "svga_context.h"
+#include "svga_screen_texture.h"
+#include "svga_screen_buffer.h"
+#include "svga_winsys.h"
+#include "svga_debug.h"
+#include "svga_screen_buffer.h"
+
+#include <util/u_string.h>
+
+
+/* XXX: This isn't a real hardware flag, but just a hack for kernel to
+ * know about primary surfaces. Find a better way to accomplish this.
+ */
+#define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9)
+
+
+/*
+ * Helper function and arrays
+ */
+
+SVGA3dSurfaceFormat
+svga_translate_format(enum pipe_format format)
+{
+   switch(format) {
+   
+   case PIPE_FORMAT_A8R8G8B8_UNORM:
+      return SVGA3D_A8R8G8B8;
+   case PIPE_FORMAT_X8R8G8B8_UNORM:
+      return SVGA3D_X8R8G8B8;
+
+      /* Required for GL2.1:
+       */
+   case PIPE_FORMAT_A8R8G8B8_SRGB:
+      return SVGA3D_A8R8G8B8;
+
+   case PIPE_FORMAT_R5G6B5_UNORM:
+      return SVGA3D_R5G6B5;
+   case PIPE_FORMAT_A1R5G5B5_UNORM:
+      return SVGA3D_A1R5G5B5;
+   case PIPE_FORMAT_A4R4G4B4_UNORM:
+      return SVGA3D_A4R4G4B4;
+
+      
+   /* XXX: Doesn't seem to work properly.
+   case PIPE_FORMAT_Z32_UNORM:
+      return SVGA3D_Z_D32;
+    */
+   case PIPE_FORMAT_Z16_UNORM:
+      return SVGA3D_Z_D16;
+   case PIPE_FORMAT_Z24S8_UNORM:
+      return SVGA3D_Z_D24S8;
+   case PIPE_FORMAT_Z24X8_UNORM:
+      return SVGA3D_Z_D24X8;
+
+   case PIPE_FORMAT_A8_UNORM:
+      return SVGA3D_ALPHA8;
+   case PIPE_FORMAT_L8_UNORM:
+      return SVGA3D_LUMINANCE8;
+
+   case PIPE_FORMAT_DXT1_RGB:
+   case PIPE_FORMAT_DXT1_RGBA:
+      return SVGA3D_DXT1;
+   case PIPE_FORMAT_DXT3_RGBA:
+      return SVGA3D_DXT3;
+   case PIPE_FORMAT_DXT5_RGBA:
+      return SVGA3D_DXT5;
+
+   default:
+      return SVGA3D_FORMAT_INVALID;
+   }
+}
+
+
+SVGA3dSurfaceFormat
+svga_translate_format_render(enum pipe_format format)
+{
+   switch(format) { 
+   case PIPE_FORMAT_A8R8G8B8_UNORM:
+   case PIPE_FORMAT_X8R8G8B8_UNORM:
+   case PIPE_FORMAT_A1R5G5B5_UNORM:
+   case PIPE_FORMAT_A4R4G4B4_UNORM:
+   case PIPE_FORMAT_R5G6B5_UNORM:
+   case PIPE_FORMAT_Z24S8_UNORM:
+   case PIPE_FORMAT_Z24X8_UNORM:
+   case PIPE_FORMAT_Z32_UNORM:
+   case PIPE_FORMAT_Z16_UNORM:
+   case PIPE_FORMAT_L8_UNORM:
+      return svga_translate_format(format);
+
+#if 1
+   /* For on host conversion */
+   case PIPE_FORMAT_DXT1_RGB:
+      return SVGA3D_X8R8G8B8;
+   case PIPE_FORMAT_DXT1_RGBA:
+   case PIPE_FORMAT_DXT3_RGBA:
+   case PIPE_FORMAT_DXT5_RGBA:
+      return SVGA3D_A8R8G8B8;
+#endif
+
+   default:
+      return SVGA3D_FORMAT_INVALID;
+   }
+}
+
+
+static INLINE void
+svga_transfer_dma_band(struct svga_transfer *st,
+                       SVGA3dTransferType transfer,
+                       unsigned y, unsigned h, unsigned srcy)
+{
+   struct svga_texture *texture = svga_texture(st->base.texture); 
+   struct svga_screen *screen = svga_screen(texture->base.screen);
+   SVGA3dCopyBox box;
+   enum pipe_error ret;
+   
+   SVGA_DBG(DEBUG_DMA, "dma %s sid %p, face %u, (%u, %u, %u) - (%u, %u, %u), %ubpp\n",
+                transfer == SVGA3D_WRITE_HOST_VRAM ? "to" : "from", 
+                texture->handle,
+                st->base.face,
+                st->base.x,
+                y,
+                st->base.zslice,
+                st->base.x + st->base.width,
+                y + h,
+                st->base.zslice + 1,
+                util_format_get_blocksize(texture->base.format)*8/
+                (util_format_get_blockwidth(texture->base.format)*util_format_get_blockheight(texture->base.format)));
+   
+   box.x = st->base.x;
+   box.y = y;
+   box.z = st->base.zslice;
+   box.w = st->base.width;
+   box.h = h;
+   box.d = 1;
+   box.srcx = 0;
+   box.srcy = srcy;
+   box.srcz = 0;
+
+   pipe_mutex_lock(screen->swc_mutex);
+   ret = SVGA3D_SurfaceDMA(screen->swc, st, transfer, &box, 1);
+   if(ret != PIPE_OK) {
+      screen->swc->flush(screen->swc, NULL);
+      ret = SVGA3D_SurfaceDMA(screen->swc, st, transfer, &box, 1);
+      assert(ret == PIPE_OK);
+   }
+   pipe_mutex_unlock(screen->swc_mutex);
+}
+
+
+static INLINE void
+svga_transfer_dma(struct svga_transfer *st,
+                 SVGA3dTransferType transfer)
+{
+   struct svga_texture *texture = svga_texture(st->base.texture); 
+   struct svga_screen *screen = svga_screen(texture->base.screen);
+   struct svga_winsys_screen *sws = screen->sws;
+   struct pipe_fence_handle *fence = NULL;
+   
+   if (transfer == SVGA3D_READ_HOST_VRAM) {
+      SVGA_DBG(DEBUG_PERF, "%s: readback transfer\n", __FUNCTION__);
+   }
+
+
+   if(!st->swbuf) {
+      /* Do the DMA transfer in a single go */
+      
+      svga_transfer_dma_band(st, transfer, st->base.y, st->base.height, 0);
+
+      if(transfer == SVGA3D_READ_HOST_VRAM) {
+         svga_screen_flush(screen, &fence);
+         sws->fence_finish(sws, fence, 0);
+         //sws->fence_reference(sws, &fence, NULL);
+      }
+   }
+   else {
+      unsigned y, h, srcy;
+      unsigned blockheight = util_format_get_blockheight(st->base.texture->format);
+      h = st->hw_nblocksy * blockheight;
+      srcy = 0;
+      for(y = 0; y < st->base.height; y += h) {
+         unsigned offset, length;
+         void *hw, *sw;
+
+         if (y + h > st->base.height)
+            h = st->base.height - y;
+
+         /* Transfer band must be aligned to pixel block boundaries */
+         assert(y % blockheight == 0);
+         assert(h % blockheight == 0);
+         
+         offset = y * st->base.stride / blockheight;
+         length = h * st->base.stride / blockheight;
+
+         sw = (uint8_t *)st->swbuf + offset;
+         
+         if(transfer == SVGA3D_WRITE_HOST_VRAM) {
+            /* Wait for the previous DMAs to complete */
+            /* TODO: keep one DMA (at half the size) in the background */
+            if(y) {
+               svga_screen_flush(screen, &fence);
+               sws->fence_finish(sws, fence, 0);
+               //sws->fence_reference(sws, &fence, NULL);
+            }
+
+            hw = sws->buffer_map(sws, st->hwbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
+            assert(hw);
+            if(hw) {
+               memcpy(hw, sw, length);
+               sws->buffer_unmap(sws, st->hwbuf);
+            }
+         }
+         
+         svga_transfer_dma_band(st, transfer, y, h, srcy);
+         
+         if(transfer == SVGA3D_READ_HOST_VRAM) {
+            svga_screen_flush(screen, &fence);
+            sws->fence_finish(sws, fence, 0);
+
+            hw = sws->buffer_map(sws, st->hwbuf, PIPE_BUFFER_USAGE_CPU_READ);
+            assert(hw);
+            if(hw) {
+               memcpy(sw, hw, length);
+               sws->buffer_unmap(sws, st->hwbuf);
+            }
+         }
+      }
+   }
+}
+
+
+static struct pipe_texture *
+svga_texture_create(struct pipe_screen *screen,
+                    const struct pipe_texture *templat)
+{
+   struct svga_screen *svgascreen = svga_screen(screen);
+   struct svga_texture *tex = CALLOC_STRUCT(svga_texture);
+   unsigned width, height, depth;
+   unsigned level;
+   
+   if (!tex)
+      goto error1;
+
+   tex->base = *templat;
+   pipe_reference_init(&tex->base.reference, 1);
+   tex->base.screen = screen;
+
+   assert(templat->last_level < SVGA_MAX_TEXTURE_LEVELS);
+   if(templat->last_level >= SVGA_MAX_TEXTURE_LEVELS)
+      goto error2;
+   
+   width = templat->width0;
+   height = templat->height0;
+   depth = templat->depth0;
+   for(level = 0; level <= templat->last_level; ++level) {
+      width = u_minify(width, 1);
+      height = u_minify(height, 1);
+      depth = u_minify(depth, 1);
+   }
+   
+   tex->key.flags = 0;
+   tex->key.size.width = templat->width0;
+   tex->key.size.height = templat->height0;
+   tex->key.size.depth = templat->depth0;
+   
+   if(templat->target == PIPE_TEXTURE_CUBE) {
+      tex->key.flags |= SVGA3D_SURFACE_CUBEMAP;
+      tex->key.numFaces = 6;
+   }
+   else {
+      tex->key.numFaces = 1;
+   }
+
+   if(templat->tex_usage & PIPE_TEXTURE_USAGE_SAMPLER)
+      tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE;
+
+   if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+      tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT;
+   
+   /* 
+    * XXX: Never pass the SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot
+    * know beforehand whether a texture will be used as a rendertarget or not
+    * and it always requests PIPE_TEXTURE_USAGE_RENDER_TARGET, therefore
+    * passing the SVGA3D_SURFACE_HINT_RENDERTARGET here defeats its purpose.
+    */
+#if 0
+   if((templat->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) &&
+      !util_format_is_compressed(templat->format))
+      tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET;
+#endif
+   
+   if(templat->tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL)
+      tex->key.flags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL;
+   
+   tex->key.numMipLevels = templat->last_level + 1;
+   
+   tex->key.format = svga_translate_format(templat->format);
+   if(tex->key.format == SVGA3D_FORMAT_INVALID)
+      goto error2;
+
+   tex->key.cachable = 1;
+   
+   SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle);
+   tex->handle = svga_screen_surface_create(svgascreen, &tex->key);
+   if (tex->handle)
+      SVGA_DBG(DEBUG_DMA, "  --> got sid %p (texture)\n", tex->handle);
+
+   return &tex->base;
+
+error2:
+   FREE(tex);
+error1:
+   return NULL;
+}
+
+
+static struct pipe_texture *
+svga_texture_blanket(struct pipe_screen * screen,
+                     const struct pipe_texture *base,
+                     const unsigned *stride,
+                     struct pipe_buffer *buffer)
+{
+   struct svga_texture *tex;
+   struct svga_buffer *sbuf = svga_buffer(buffer);
+   struct svga_winsys_screen *sws = svga_winsys_screen(screen);
+   assert(screen);
+
+   /* Only supports one type */
+   if (base->target != PIPE_TEXTURE_2D ||
+       base->last_level != 0 ||
+       base->depth0 != 1) {
+      return NULL;
+   }
+
+   /**
+    * We currently can't do texture blanket on
+    * SVGA3D_BUFFER. Need to blit to a temporary surface?
+    */
+
+   assert(sbuf->handle);
+   if (!sbuf->handle)
+      return NULL;
+
+   if (svga_translate_format(base->format) != sbuf->key.format) {
+      unsigned f1 = svga_translate_format(base->format);
+      unsigned f2 = sbuf->key.format;
+
+      /* It's okay for XRGB and ARGB or depth with/out stencil to get mixed up */
+      if ( !( (f1 == SVGA3D_X8R8G8B8 && f2 == SVGA3D_A8R8G8B8) ||
+              (f1 == SVGA3D_A8R8G8B8 && f2 == SVGA3D_X8R8G8B8) ||
+              (f1 == SVGA3D_Z_D24X8 && f2 == SVGA3D_Z_D24S8) ) ) {
+         debug_printf("%s wrong format %u != %u\n", __FUNCTION__, f1, f2);
+         return NULL;
+      }
+   }
+
+   tex = CALLOC_STRUCT(svga_texture);
+   if (!tex)
+      return NULL;
+
+   tex->base = *base;
+   
+
+   if (sbuf->key.format == 1)
+      tex->base.format = PIPE_FORMAT_X8R8G8B8_UNORM;
+   else if (sbuf->key.format == 2)
+      tex->base.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+
+   pipe_reference_init(&tex->base.reference, 1);
+   tex->base.screen = screen;
+
+   SVGA_DBG(DEBUG_DMA, "blanket sid %p\n", sbuf->handle);
+
+   /* We don't own this storage, so don't try to cache it.
+    */
+   assert(sbuf->key.cachable == 0);
+   tex->key.cachable = 0;
+   sws->surface_reference(sws, &tex->handle, sbuf->handle);
+
+   return &tex->base;
+}
+
+
+static void
+svga_texture_destroy(struct pipe_texture *pt)
+{
+   struct svga_screen *ss = svga_screen(pt->screen);
+   struct svga_texture *tex = (struct svga_texture *)pt;
+
+   ss->texture_timestamp++;
+
+   svga_sampler_view_reference(&tex->cached_view, NULL);
+
+   /*
+     DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
+   */
+   SVGA_DBG(DEBUG_DMA, "unref sid %p (texture)\n", tex->handle);
+   svga_screen_surface_destroy(ss, &tex->key, &tex->handle);
+
+   FREE(tex);
+}
+
+
+static void
+svga_texture_copy_handle(struct svga_context *svga,
+                         struct svga_screen *ss,
+                         struct svga_winsys_surface *src_handle,
+                         unsigned src_x, unsigned src_y, unsigned src_z,
+                         unsigned src_level, unsigned src_face,
+                         struct svga_winsys_surface *dst_handle,
+                         unsigned dst_x, unsigned dst_y, unsigned dst_z,
+                         unsigned dst_level, unsigned dst_face,
+                         unsigned width, unsigned height, unsigned depth)
+{
+   struct svga_surface dst, src;
+   enum pipe_error ret;
+   SVGA3dCopyBox box, *boxes;
+
+   assert(svga || ss);
+
+   src.handle = src_handle;
+   src.real_level = src_level;
+   src.real_face = src_face;
+   src.real_zslice = 0;
+
+   dst.handle = dst_handle;
+   dst.real_level = dst_level;
+   dst.real_face = dst_face;
+   dst.real_zslice = 0;
+
+   box.x = dst_x;
+   box.y = dst_y;
+   box.z = dst_z;
+   box.w = width;
+   box.h = height;
+   box.d = depth;
+   box.srcx = src_x;
+   box.srcy = src_y;
+   box.srcz = src_z;
+
+/*
+   SVGA_DBG(DEBUG_VIEWS, "mipcopy src: %p %u (%ux%ux%u), dst: %p %u (%ux%ux%u)\n",
+            src_handle, src_level, src_x, src_y, src_z,
+            dst_handle, dst_level, dst_x, dst_y, dst_z);
+*/
+
+   if (svga) {
+      ret = SVGA3D_BeginSurfaceCopy(svga->swc,
+                                    &src.base,
+                                    &dst.base,
+                                    &boxes, 1);
+      if(ret != PIPE_OK) {
+         svga_context_flush(svga, NULL);
+         ret = SVGA3D_BeginSurfaceCopy(svga->swc,
+                                       &src.base,
+                                       &dst.base,
+                                       &boxes, 1);
+         assert(ret == PIPE_OK);
+      }
+      *boxes = box;
+      SVGA_FIFOCommitAll(svga->swc);
+   } else {
+      pipe_mutex_lock(ss->swc_mutex);
+      ret = SVGA3D_BeginSurfaceCopy(ss->swc,
+                                    &src.base,
+                                    &dst.base,
+                                    &boxes, 1);
+      if(ret != PIPE_OK) {
+         ss->swc->flush(ss->swc, NULL);
+         ret = SVGA3D_BeginSurfaceCopy(ss->swc,
+                                       &src.base,
+                                       &dst.base,
+                                       &boxes, 1);
+         assert(ret == PIPE_OK);
+      }
+      *boxes = box;
+      SVGA_FIFOCommitAll(ss->swc);
+      pipe_mutex_unlock(ss->swc_mutex);
+   }
+}
+
+static struct svga_winsys_surface *
+svga_texture_view_surface(struct pipe_context *pipe,
+                          struct svga_texture *tex,
+                          SVGA3dSurfaceFormat format,
+                          unsigned start_mip,
+                          unsigned num_mip,
+                          int face_pick,
+                          int zslice_pick,
+                          struct svga_host_surface_cache_key *key) /* OUT */
+{
+   struct svga_screen *ss = svga_screen(tex->base.screen);
+   struct svga_winsys_surface *handle;
+   uint32_t i, j;
+   unsigned z_offset = 0;
+
+   SVGA_DBG(DEBUG_PERF, 
+            "svga: Create surface view: face %d zslice %d mips %d..%d\n",
+            face_pick, zslice_pick, start_mip, start_mip+num_mip-1);
+
+   key->flags = 0;
+   key->format = format;
+   key->numMipLevels = num_mip;
+   key->size.width = u_minify(tex->base.width0, start_mip);
+   key->size.height = u_minify(tex->base.height0, start_mip);
+   key->size.depth = zslice_pick < 0 ? u_minify(tex->base.depth0, start_mip) : 1;
+   key->cachable = 1;
+   assert(key->size.depth == 1);
+   
+   if(tex->base.target == PIPE_TEXTURE_CUBE && face_pick < 0) {
+      key->flags |= SVGA3D_SURFACE_CUBEMAP;
+      key->numFaces = 6;
+   } else {
+      key->numFaces = 1;
+   }
+
+   if(key->format == SVGA3D_FORMAT_INVALID) {
+      key->cachable = 0;
+      return NULL;
+   }
+
+   SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n");
+   handle = svga_screen_surface_create(ss, key);
+   if (!handle) {
+      key->cachable = 0;
+      return NULL;
+   }
+
+   SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture view)\n", handle);
+
+   if (face_pick < 0)
+      face_pick = 0;
+
+   if (zslice_pick >= 0)
+       z_offset = zslice_pick;
+
+   for (i = 0; i < key->numMipLevels; i++) {
+      for (j = 0; j < key->numFaces; j++) {
+         if(tex->defined[j + face_pick][i + start_mip]) {
+            unsigned depth = (zslice_pick < 0 ?
+                              u_minify(tex->base.depth0, i + start_mip) :
+                              1);
+
+            svga_texture_copy_handle(svga_context(pipe),
+                                     ss,
+                                     tex->handle, 
+                                     0, 0, z_offset, 
+                                     i + start_mip, 
+                                     j + face_pick,
+                                     handle, 0, 0, 0, i, j,
+                                     u_minify(tex->base.width0, i + start_mip),
+                                     u_minify(tex->base.height0, i + start_mip),
+                                     depth);
+         }
+      }
+   }
+
+   return handle;
+}
+
+
+static struct pipe_surface *
+svga_get_tex_surface(struct pipe_screen *screen,
+                     struct pipe_texture *pt,
+                     unsigned face, unsigned level, unsigned zslice,
+                     unsigned flags)
+{
+   struct svga_texture *tex = svga_texture(pt);
+   struct svga_surface *s;
+   boolean render = flags & PIPE_BUFFER_USAGE_GPU_WRITE ? TRUE : FALSE;
+   boolean view = FALSE;
+   SVGA3dSurfaceFormat format;
+
+   s = CALLOC_STRUCT(svga_surface);
+   if (!s)
+      return NULL;
+
+   pipe_reference_init(&s->base.reference, 1);
+   pipe_texture_reference(&s->base.texture, pt);
+   s->base.format = pt->format;
+   s->base.width = u_minify(pt->width0, level);
+   s->base.height = u_minify(pt->height0, level);
+   s->base.usage = flags;
+   s->base.level = level;
+   s->base.face = face;
+   s->base.zslice = zslice;
+
+   if (!render)
+      format = svga_translate_format(pt->format);
+   else
+      format = svga_translate_format_render(pt->format);
+
+   assert(format != SVGA3D_FORMAT_INVALID);
+   assert(!(flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE));
+
+
+   if (svga_screen(screen)->debug.force_surface_view)
+      view = TRUE;
+
+   /* Currently only used for compressed textures */
+   if (render && 
+       format != svga_translate_format(pt->format)) {
+      view = TRUE;
+   }
+
+   if (level != 0 && 
+       svga_screen(screen)->debug.force_level_surface_view)
+      view = TRUE;
+
+   if (pt->target == PIPE_TEXTURE_3D)
+      view = TRUE;
+
+   if (svga_screen(screen)->debug.no_surface_view)
+      view = FALSE;
+
+   if (view) {
+      SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: yes %p, level %u face %u z %u, %p\n",
+               pt, level, face, zslice, s);
+
+      s->handle = svga_texture_view_surface(NULL, tex, format, level, 1, face, zslice,
+                                            &s->key);
+      s->real_face = 0;
+      s->real_level = 0;
+      s->real_zslice = 0;
+   } else {
+      SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: no %p, level %u, face %u, z %u, %p\n",
+               pt, level, face, zslice, s);
+
+      memset(&s->key, 0, sizeof s->key);
+      s->handle = tex->handle;
+      s->real_face = face;
+      s->real_level = level;
+      s->real_zslice = zslice;
+   }
+
+   return &s->base;
+}
+
+
+static void
+svga_tex_surface_destroy(struct pipe_surface *surf)
+{
+   struct svga_surface *s = svga_surface(surf);
+   struct svga_texture *t = svga_texture(surf->texture);
+   struct svga_screen *ss = svga_screen(surf->texture->screen);
+
+   if(s->handle != t->handle) {
+      SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle);
+      svga_screen_surface_destroy(ss, &s->key, &s->handle);
+   }
+
+   pipe_texture_reference(&surf->texture, NULL);
+   FREE(surf);
+}
+
+
+static INLINE void 
+svga_mark_surface_dirty(struct pipe_surface *surf)
+{
+   struct svga_surface *s = svga_surface(surf);
+
+   if(!s->dirty) {
+      struct svga_texture *tex = svga_texture(surf->texture);
+
+      s->dirty = TRUE;
+
+      if (s->handle == tex->handle)
+         tex->defined[surf->face][surf->level] = TRUE;
+      else {
+         /* this will happen later in svga_propagate_surface */
+      }
+   }
+}
+
+
+void svga_mark_surfaces_dirty(struct svga_context *svga)
+{
+   unsigned i;
+
+   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+      if (svga->curr.framebuffer.cbufs[i])
+         svga_mark_surface_dirty(svga->curr.framebuffer.cbufs[i]);
+   }
+   if (svga->curr.framebuffer.zsbuf)
+      svga_mark_surface_dirty(svga->curr.framebuffer.zsbuf);
+}
+
+/**
+ * Progagate any changes from surfaces to texture.
+ * pipe is optional context to inline the blit command in.
+ */
+void
+svga_propagate_surface(struct pipe_context *pipe, struct pipe_surface *surf)
+{
+   struct svga_surface *s = svga_surface(surf);
+   struct svga_texture *tex = svga_texture(surf->texture);
+   struct svga_screen *ss = svga_screen(surf->texture->screen);
+
+   if (!s->dirty)
+      return;
+
+   s->dirty = FALSE;
+   ss->texture_timestamp++;
+   tex->view_age[surf->level] = ++(tex->age);
+
+   if (s->handle != tex->handle) {
+      SVGA_DBG(DEBUG_VIEWS, "svga: Surface propagate: tex %p, level %u, from %p\n", tex, surf->level, surf);
+      svga_texture_copy_handle(svga_context(pipe), ss,
+                               s->handle, 0, 0, 0, s->real_level, s->real_face,
+                               tex->handle, 0, 0, surf->zslice, surf->level, surf->face,
+                               u_minify(tex->base.width0, surf->level),
+                               u_minify(tex->base.height0, surf->level), 1);
+      tex->defined[surf->face][surf->level] = TRUE;
+   }
+}
+
+/**
+ * Check if we should call svga_propagate_surface on the surface.
+ */
+extern boolean
+svga_surface_needs_propagation(struct pipe_surface *surf)
+{
+   struct svga_surface *s = svga_surface(surf);
+   struct svga_texture *tex = svga_texture(surf->texture);
+
+   return s->dirty && s->handle != tex->handle;
+}
+
+
+static struct pipe_transfer *
+svga_get_tex_transfer(struct pipe_screen *screen,
+                     struct pipe_texture *texture,
+                     unsigned face, unsigned level, unsigned zslice,
+                     enum pipe_transfer_usage usage, unsigned x, unsigned y,
+                     unsigned w, unsigned h)
+{
+   struct svga_screen *ss = svga_screen(screen);
+   struct svga_winsys_screen *sws = ss->sws;
+   struct svga_transfer *st;
+   unsigned nblocksx = util_format_get_nblocksx(texture->format, w);
+   unsigned nblocksy = util_format_get_nblocksy(texture->format, h);
+
+   /* We can't map texture storage directly */
+   if (usage & PIPE_TRANSFER_MAP_DIRECTLY)
+      return NULL;
+
+   st = CALLOC_STRUCT(svga_transfer);
+   if (!st)
+      return NULL;
+   
+   st->base.x = x;
+   st->base.y = y;
+   st->base.width = w;
+   st->base.height = h;
+   st->base.stride = nblocksx*util_format_get_blocksize(texture->format);
+   st->base.usage = usage;
+   st->base.face = face;
+   st->base.level = level;
+   st->base.zslice = zslice;
+
+   st->hw_nblocksy = nblocksy;
+   
+   st->hwbuf = svga_winsys_buffer_create(ss, 
+                                         1, 
+                                         0,
+                                         st->hw_nblocksy*st->base.stride);
+   while(!st->hwbuf && (st->hw_nblocksy /= 2)) {
+      st->hwbuf = svga_winsys_buffer_create(ss, 
+                                            1, 
+                                            0,
+                                            st->hw_nblocksy*st->base.stride);
+   }
+
+   if(!st->hwbuf)
+      goto no_hwbuf;
+
+   if(st->hw_nblocksy < nblocksy) {
+      /* We couldn't allocate a hardware buffer big enough for the transfer, 
+       * so allocate regular malloc memory instead */
+      debug_printf("%s: failed to allocate %u KB of DMA, splitting into %u x %u KB DMA transfers\n",
+                   __FUNCTION__,
+                   (nblocksy*st->base.stride + 1023)/1024,
+                   (nblocksy + st->hw_nblocksy - 1)/st->hw_nblocksy,
+                   (st->hw_nblocksy*st->base.stride + 1023)/1024);
+      st->swbuf = MALLOC(nblocksy*st->base.stride);
+      if(!st->swbuf)
+         goto no_swbuf;
+   }
+   
+   pipe_texture_reference(&st->base.texture, texture);
+
+   if (usage & PIPE_TRANSFER_READ)
+      svga_transfer_dma(st, SVGA3D_READ_HOST_VRAM);
+
+   return &st->base;
+
+no_swbuf:
+   sws->buffer_destroy(sws, st->hwbuf);
+no_hwbuf:
+   FREE(st);
+   return NULL;
+}
+
+
+static void *
+svga_transfer_map( struct pipe_screen *screen,
+                   struct pipe_transfer *transfer )
+{
+   struct svga_screen *ss = svga_screen(screen);
+   struct svga_winsys_screen *sws = ss->sws;
+   struct svga_transfer *st = svga_transfer(transfer);
+
+   if(st->swbuf)
+      return st->swbuf;
+   else
+      /* The wait for read transfers already happened when svga_transfer_dma
+       * was called. */
+      return sws->buffer_map(sws, st->hwbuf,
+                             pipe_transfer_buffer_flags(transfer));
+}
+
+
+static void
+svga_transfer_unmap(struct pipe_screen *screen,
+                    struct pipe_transfer *transfer)
+{
+   struct svga_screen *ss = svga_screen(screen);
+   struct svga_winsys_screen *sws = ss->sws;
+   struct svga_transfer *st = svga_transfer(transfer);
+   
+   if(!st->swbuf)
+      sws->buffer_unmap(sws, st->hwbuf);
+}
+
+
+static void
+svga_tex_transfer_destroy(struct pipe_transfer *transfer)
+{
+   struct svga_texture *tex = svga_texture(transfer->texture);
+   struct svga_screen *ss = svga_screen(transfer->texture->screen);
+   struct svga_winsys_screen *sws = ss->sws;
+   struct svga_transfer *st = svga_transfer(transfer);
+
+   if (st->base.usage & PIPE_TRANSFER_WRITE) {
+      svga_transfer_dma(st, SVGA3D_WRITE_HOST_VRAM);
+      ss->texture_timestamp++;
+      tex->view_age[transfer->level] = ++(tex->age);
+      tex->defined[transfer->face][transfer->level] = TRUE;
+   }
+
+   pipe_texture_reference(&st->base.texture, NULL);
+   FREE(st->swbuf);
+   sws->buffer_destroy(sws, st->hwbuf);
+   FREE(st);
+}
+
+void
+svga_screen_init_texture_functions(struct pipe_screen *screen)
+{
+   screen->texture_create = svga_texture_create;
+   screen->texture_destroy = svga_texture_destroy;
+   screen->get_tex_surface = svga_get_tex_surface;
+   screen->tex_surface_destroy = svga_tex_surface_destroy;
+   screen->texture_blanket = svga_texture_blanket;
+   screen->get_tex_transfer = svga_get_tex_transfer;
+   screen->transfer_map = svga_transfer_map;
+   screen->transfer_unmap = svga_transfer_unmap;
+   screen->tex_transfer_destroy = svga_tex_transfer_destroy;
+}
+
+/*********************************************************************** 
+ */
+
+struct svga_sampler_view *
+svga_get_tex_sampler_view(struct pipe_context *pipe, struct pipe_texture *pt,
+                          unsigned min_lod, unsigned max_lod)
+{
+   struct svga_screen *ss = svga_screen(pt->screen);
+   struct svga_texture *tex = svga_texture(pt); 
+   struct svga_sampler_view *sv = NULL;
+   SVGA3dSurfaceFormat format = svga_translate_format(pt->format);
+   boolean view = TRUE;
+
+   assert(pt);
+   assert(min_lod >= 0);
+   assert(min_lod <= max_lod);
+   assert(max_lod <= pt->last_level);
+
+
+   /* Is a view needed */
+   {
+      /*
+       * Can't control max lod. For first level views and when we only
+       * look at one level we disable mip filtering to achive the same
+       * results as a view.
+       */
+      if (min_lod == 0 && max_lod >= pt->last_level)
+         view = FALSE;
+
+      if (util_format_is_compressed(pt->format) && view) {
+         format = svga_translate_format_render(pt->format);
+      }
+
+      if (ss->debug.no_sampler_view)
+         view = FALSE;
+
+      if (ss->debug.force_sampler_view)
+         view = TRUE;
+   }
+
+   /* First try the cache */
+   if (view) {
+      pipe_mutex_lock(ss->tex_mutex);
+      if (tex->cached_view &&
+          tex->cached_view->min_lod == min_lod &&
+          tex->cached_view->max_lod == max_lod) {
+         svga_sampler_view_reference(&sv, tex->cached_view);
+         pipe_mutex_unlock(ss->tex_mutex);
+         SVGA_DBG(DEBUG_VIEWS, "svga: Sampler view: reuse %p, %u %u, last %u\n",
+                              pt, min_lod, max_lod, pt->last_level);
+         svga_validate_sampler_view(svga_context(pipe), sv);
+         return sv;
+      }
+      pipe_mutex_unlock(ss->tex_mutex);
+   }
+
+   sv = CALLOC_STRUCT(svga_sampler_view);
+   pipe_reference_init(&sv->reference, 1);
+   pipe_texture_reference(&sv->texture, pt);
+   sv->min_lod = min_lod;
+   sv->max_lod = max_lod;
+
+   /* No view needed just use the whole texture */
+   if (!view) {
+      SVGA_DBG(DEBUG_VIEWS,
+               "svga: Sampler view: no %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n",
+               pt, min_lod, max_lod,
+               max_lod - min_lod + 1,
+               pt->width0,
+               pt->height0,
+               pt->depth0,
+               pt->last_level);
+      sv->key.cachable = 0;
+      sv->handle = tex->handle;
+      return sv;
+   }
+
+   SVGA_DBG(DEBUG_VIEWS,
+            "svga: Sampler view: yes %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n",
+            pt, min_lod, max_lod,
+            max_lod - min_lod + 1,
+            pt->width0,
+            pt->height0,
+            pt->depth0,
+            pt->last_level);
+
+   sv->age = tex->age;
+   sv->handle = svga_texture_view_surface(pipe, tex, format,
+                                          min_lod,
+                                          max_lod - min_lod + 1,
+                                          -1, -1,
+                                          &sv->key);
+
+   if (!sv->handle) {
+      assert(0);
+      sv->key.cachable = 0;
+      sv->handle = tex->handle;
+      return sv;
+   }
+
+   pipe_mutex_lock(ss->tex_mutex);
+   svga_sampler_view_reference(&tex->cached_view, sv);
+   pipe_mutex_unlock(ss->tex_mutex);
+
+   return sv;
+}
+
+void
+svga_validate_sampler_view(struct svga_context *svga, struct svga_sampler_view *v)
+{
+   struct svga_texture *tex = svga_texture(v->texture);
+   unsigned numFaces;
+   unsigned age = 0;
+   int i, k;
+
+   assert(svga);
+
+   if (v->handle == tex->handle)
+      return;
+
+   age = tex->age;
+
+   if(tex->base.target == PIPE_TEXTURE_CUBE)
+      numFaces = 6;
+   else
+      numFaces = 1;
+
+   for (i = v->min_lod; i <= v->max_lod; i++) {
+      for (k = 0; k < numFaces; k++) {
+         if (v->age < tex->view_age[i])
+            svga_texture_copy_handle(svga, NULL,
+                                     tex->handle, 0, 0, 0, i, k,
+                                     v->handle, 0, 0, 0, i - v->min_lod, k,
+                                     u_minify(tex->base.width0, i),
+                                     u_minify(tex->base.height0, i),
+                                     u_minify(tex->base.depth0, i));
+      }
+   }
+
+   v->age = age;
+}
+
+void
+svga_destroy_sampler_view_priv(struct svga_sampler_view *v)
+{
+   struct svga_texture *tex = svga_texture(v->texture);
+
+   if(v->handle != tex->handle) {
+      struct svga_screen *ss = svga_screen(v->texture->screen);
+      SVGA_DBG(DEBUG_DMA, "unref sid %p (sampler view)\n", v->handle);
+      svga_screen_surface_destroy(ss, &v->key, &v->handle);
+   }
+   pipe_texture_reference(&v->texture, NULL);
+   FREE(v);
+}
+
+boolean
+svga_screen_buffer_from_texture(struct pipe_texture *texture,
+				struct pipe_buffer **buffer,
+				unsigned *stride)
+{
+   struct svga_texture *stex = svga_texture(texture);
+
+   *buffer = svga_screen_buffer_wrap_surface
+      (texture->screen,
+       svga_translate_format(texture->format),
+       stex->handle);
+
+   *stride = util_format_get_stride(texture->format, texture->width0);
+
+   return *buffer != NULL;
+}
+
+
+struct svga_winsys_surface *
+svga_screen_texture_get_winsys_surface(struct pipe_texture *texture)
+{
+   struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen);
+   struct svga_winsys_surface *vsurf = NULL;
+
+   assert(svga_texture(texture)->key.cachable == 0);
+   svga_texture(texture)->key.cachable = 0;
+   sws->surface_reference(sws, &vsurf, svga_texture(texture)->handle);
+   return vsurf;
+}
diff --git a/src/gallium/drivers/svga/svga_screen_texture.h b/src/gallium/drivers/svga/svga_screen_texture.h
new file mode 100644
index 0000000..89ae242
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_screen_texture.h
@@ -0,0 +1,195 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_TEXTURE_H
+#define SVGA_TEXTURE_H
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+#include "svga_screen_cache.h"
+
+struct pipe_context;
+struct pipe_screen;
+struct svga_context;
+struct svga_winsys_surface;
+enum SVGA3dSurfaceFormat;
+
+
+#define SVGA_MAX_TEXTURE_LEVELS 12 /* 2048x2048 */
+
+
+/**
+ * A sampler's view into a texture
+ *
+ * We currently cache one sampler view on
+ * the texture and in there by holding a reference
+ * from the texture to the sampler view.
+ *
+ * Because of this we can not hold a refernce to the
+ * texture from the sampler view. So the user
+ * of the sampler views must make sure that the
+ * texture has a reference take for as long as
+ * the sampler view is refrenced.
+ *
+ * Just unreferencing the sampler_view before the
+ * texture is enough.
+ */
+struct svga_sampler_view
+{
+   struct pipe_reference reference;
+
+   struct pipe_texture *texture;
+
+   int min_lod;
+   int max_lod;
+
+   unsigned age;
+
+   struct svga_host_surface_cache_key key;
+   struct svga_winsys_surface *handle;
+};
+
+
+struct svga_texture 
+{
+   struct pipe_texture base;
+
+   boolean defined[6][PIPE_MAX_TEXTURE_LEVELS];
+   
+   struct svga_sampler_view *cached_view;
+
+   unsigned view_age[SVGA_MAX_TEXTURE_LEVELS];
+   unsigned age;
+
+   boolean views_modified;
+
+   /**
+    * Creation key for the host surface handle.
+    * 
+    * This structure describes all the host surface characteristics so that it 
+    * can be looked up in cache, since creating a host surface is often a slow
+    * operation.
+    */
+   struct svga_host_surface_cache_key key;
+
+   /**
+    * Handle for the host side surface.
+    *
+    * This handle is owned by this texture. Views should hold on to a reference
+    * to this texture and never destroy this handle directly.
+    */
+   struct svga_winsys_surface *handle;
+};
+
+
+struct svga_surface
+{
+   struct pipe_surface base;
+
+   struct svga_host_surface_cache_key key;
+   struct svga_winsys_surface *handle;
+
+   unsigned real_face;
+   unsigned real_level;
+   unsigned real_zslice;
+
+   boolean dirty;
+};
+
+
+struct svga_transfer
+{
+   struct pipe_transfer base;
+
+   struct svga_winsys_buffer *hwbuf;
+
+   /* Height of the hardware buffer in pixel blocks */
+   unsigned hw_nblocksy;
+
+   /* Temporary malloc buffer when we can't allocate a hardware buffer
+    * big enough */
+   void *swbuf;
+};
+
+
+static INLINE struct svga_texture *
+svga_texture(struct pipe_texture *texture)
+{
+   return (struct svga_texture *)texture;
+}
+
+static INLINE struct svga_surface *
+svga_surface(struct pipe_surface *surface)
+{
+   assert(surface);
+   return (struct svga_surface *)surface;
+}
+
+static INLINE struct svga_transfer *
+svga_transfer(struct pipe_transfer *transfer)
+{
+   assert(transfer);
+   return (struct svga_transfer *)transfer;
+}
+
+extern struct svga_sampler_view *
+svga_get_tex_sampler_view(struct pipe_context *pipe,
+                          struct pipe_texture *pt,
+                          unsigned min_lod, unsigned max_lod);
+
+void
+svga_validate_sampler_view(struct svga_context *svga, struct svga_sampler_view *v);
+
+void
+svga_destroy_sampler_view_priv(struct svga_sampler_view *v);
+
+static INLINE void
+svga_sampler_view_reference(struct svga_sampler_view **ptr, struct svga_sampler_view *v)
+{
+   struct svga_sampler_view *old = *ptr;
+
+   if (pipe_reference(&(*ptr)->reference, &v->reference))
+      svga_destroy_sampler_view_priv(old);
+   *ptr = v;
+}
+
+extern void
+svga_propagate_surface(struct pipe_context *pipe, struct pipe_surface *surf);
+
+extern boolean
+svga_surface_needs_propagation(struct pipe_surface *surf);
+
+extern void
+svga_screen_init_texture_functions(struct pipe_screen *screen);
+
+enum SVGA3dSurfaceFormat
+svga_translate_format(enum pipe_format format);
+
+enum SVGA3dSurfaceFormat
+svga_translate_format_render(enum pipe_format format);
+
+
+#endif /* SVGA_TEXTURE_H */
diff --git a/src/gallium/drivers/svga/svga_state.c b/src/gallium/drivers/svga/svga_state.c
new file mode 100644
index 0000000..1c21d3a
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_state.c
@@ -0,0 +1,278 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "util/u_debug.h"
+#include "pipe/p_defines.h"
+#include "util/u_memory.h"
+#include "draw/draw_context.h"
+
+#include "svga_context.h"
+#include "svga_screen.h"
+#include "svga_state.h"
+#include "svga_draw.h"
+#include "svga_cmd.h"
+#include "svga_hw_reg.h"
+
+/* This is just enough to decide whether we need to use the draw
+ * module (swtnl) or not.
+ */
+static const struct svga_tracked_state *need_swtnl_state[] =
+{
+   &svga_update_need_swvfetch,
+   &svga_update_need_pipeline,
+   &svga_update_need_swtnl,
+   NULL
+};
+
+
+/* Atoms to update hardware state prior to emitting a clear or draw
+ * packet.
+ */
+static const struct svga_tracked_state *hw_clear_state[] =
+{
+   &svga_hw_scissor,
+   &svga_hw_viewport,
+   &svga_hw_framebuffer,
+   NULL
+};
+
+
+/* Atoms to update hardware state prior to emitting a draw packet.
+ */
+static const struct svga_tracked_state *hw_draw_state[] =
+{
+   &svga_hw_update_zero_stride,
+   &svga_hw_fs,
+   &svga_hw_vs,
+   &svga_hw_rss,
+   &svga_hw_tss,
+   &svga_hw_tss_binding,
+   &svga_hw_clip_planes,
+   &svga_hw_vdecl,
+   &svga_hw_fs_parameters,
+   &svga_hw_vs_parameters,
+   NULL
+};
+
+
+static const struct svga_tracked_state *swtnl_draw_state[] =
+{
+   &svga_update_swtnl_draw,
+   &svga_update_swtnl_vdecl,
+   NULL
+};
+
+/* Flattens the graph of state dependencies.  Could swap the positions
+ * of hw_clear_state and need_swtnl_state without breaking anything.
+ */
+static const struct svga_tracked_state **state_levels[] = 
+{
+   need_swtnl_state,
+   hw_clear_state,
+   hw_draw_state,
+   swtnl_draw_state
+};
+
+
+
+static unsigned check_state( unsigned a,
+                             unsigned b )
+{
+   return (a & b);
+}
+
+static void accumulate_state( unsigned *a,
+			      unsigned b )
+{
+   *a |= b;
+}
+
+
+static void xor_states( unsigned *result,
+                        unsigned a,
+                        unsigned b )
+{
+   *result = a ^ b;
+}
+
+
+
+static int update_state( struct svga_context *svga,
+                         const struct svga_tracked_state *atoms[],
+                         unsigned *state )
+{
+   boolean debug = TRUE;
+   enum pipe_error ret = 0;
+   unsigned i;
+
+   ret = svga_hwtnl_flush( svga->hwtnl );
+   if (ret != 0)
+      return ret;
+
+   if (debug) {
+      /* Debug version which enforces various sanity checks on the
+       * state flags which are generated and checked to help ensure
+       * state atoms are ordered correctly in the list.
+       */
+      unsigned examined, prev;      
+
+      examined = 0;
+      prev = *state;
+
+      for (i = 0; atoms[i] != NULL; i++) {	 
+	 unsigned generated;
+
+	 assert(atoms[i]->dirty); 
+	 assert(atoms[i]->update);
+
+	 if (check_state(*state, atoms[i]->dirty)) {
+	    if (0)
+               debug_printf("update: %s\n", atoms[i]->name);
+	    ret = atoms[i]->update( svga, *state );
+            if (ret != 0)
+               return ret;
+	 }
+
+	 /* generated = (prev ^ state)
+	  * if (examined & generated)
+	  *     fail;
+	  */
+	 xor_states(&generated, prev, *state);
+	 if (check_state(examined, generated)) {
+	    debug_printf("state atom %s generated state already examined\n", 
+                         atoms[i]->name);
+	    assert(0);
+	 }
+			 
+	 prev = *state;
+	 accumulate_state(&examined, atoms[i]->dirty);
+      }
+   }
+   else {
+      for (i = 0; atoms[i] != NULL; i++) {	 
+	 if (check_state(*state, atoms[i]->dirty)) {
+	    ret = atoms[i]->update( svga, *state );
+            if (ret != 0)
+               return ret;
+         }
+      }
+   }
+
+   return 0;
+}
+
+
+
+int svga_update_state( struct svga_context *svga,
+                       unsigned max_level )
+{
+   struct svga_screen *screen = svga_screen(svga->pipe.screen);
+   int ret = 0;
+   int i;
+
+   /* Check for updates to bound textures.  This can't be done in an
+    * atom as there is no flag which could provoke this test, and we
+    * cannot create one.
+    */
+   if (svga->state.texture_timestamp != screen->texture_timestamp) {
+      svga->state.texture_timestamp = screen->texture_timestamp;
+      svga->dirty |= SVGA_NEW_TEXTURE;
+   }
+
+   for (i = 0; i <= max_level; i++) {
+      svga->dirty |= svga->state.dirty[i];
+
+      if (svga->dirty) {
+         ret = update_state( svga, 
+                             state_levels[i], 
+                             &svga->dirty );
+         if (ret != 0)
+            return ret;
+
+         svga->state.dirty[i] = 0;
+      }
+   }
+   
+   for (; i < SVGA_STATE_MAX; i++) 
+      svga->state.dirty[i] |= svga->dirty;
+
+   svga->dirty = 0;
+   return 0;
+}
+
+
+
+
+void svga_update_state_retry( struct svga_context *svga,
+                              unsigned max_level )
+{
+   int ret;
+
+   ret = svga_update_state( svga, max_level );
+
+   if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
+      svga_context_flush(svga, NULL);
+      ret = svga_update_state( svga, max_level );
+   }
+
+   assert( ret == 0 );
+}
+
+
+
+#define EMIT_RS(_rs, _count, _name, _value)     \
+do {                                            \
+   _rs[_count].state = _name;                   \
+   _rs[_count].uintValue = _value;              \
+   _count++;                                    \
+} while (0)
+
+
+/* Setup any hardware state which will be constant through the life of
+ * a context.
+ */
+enum pipe_error svga_emit_initial_state( struct svga_context *svga )
+{
+   SVGA3dRenderState *rs;
+   unsigned count = 0;
+   const unsigned COUNT = 2;
+   enum pipe_error ret;
+
+   ret = SVGA3D_BeginSetRenderState( svga->swc, &rs, COUNT );
+   if (ret)
+      return ret;
+
+   /* Always use D3D style coordinate space as this is the only one
+    * which is implemented on all backends.
+    */
+   EMIT_RS(rs, count, SVGA3D_RS_COORDINATETYPE, SVGA3D_COORDINATE_LEFTHANDED );
+   EMIT_RS(rs, count, SVGA3D_RS_FRONTWINDING, SVGA3D_FRONTWINDING_CW );
+   
+   assert( COUNT == count );
+   SVGA_FIFOCommitAll( svga->swc );
+
+   return 0;
+
+}
diff --git a/src/gallium/drivers/svga/svga_state.h b/src/gallium/drivers/svga/svga_state.h
new file mode 100644
index 0000000..22d5a6d
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_state.h
@@ -0,0 +1,95 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_STATE_H
+#define SVGA_STATE_H
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_defines.h"
+
+struct svga_context;
+
+
+void svga_init_state( struct svga_context *svga );
+void svga_destroy_state( struct svga_context *svga );
+
+
+struct svga_tracked_state {
+   const char *name;
+   unsigned dirty;
+   int (*update)( struct svga_context *svga, unsigned dirty );
+};
+
+/* NEED_SWTNL
+ */
+extern struct svga_tracked_state svga_update_need_swvfetch;
+extern struct svga_tracked_state svga_update_need_pipeline;
+extern struct svga_tracked_state svga_update_need_swtnl;
+
+/* HW_CLEAR
+ */
+extern struct svga_tracked_state svga_hw_viewport;
+extern struct svga_tracked_state svga_hw_scissor;
+extern struct svga_tracked_state svga_hw_framebuffer;
+
+/* HW_DRAW
+ */
+extern struct svga_tracked_state svga_hw_vs;
+extern struct svga_tracked_state svga_hw_fs;
+extern struct svga_tracked_state svga_hw_rss;
+extern struct svga_tracked_state svga_hw_tss;
+extern struct svga_tracked_state svga_hw_tss_binding;
+extern struct svga_tracked_state svga_hw_clip_planes;
+extern struct svga_tracked_state svga_hw_vdecl;
+extern struct svga_tracked_state svga_hw_fs_parameters;
+extern struct svga_tracked_state svga_hw_vs_parameters;
+extern struct svga_tracked_state svga_hw_update_zero_stride;
+
+/* SWTNL_DRAW
+ */
+extern struct svga_tracked_state svga_update_swtnl_draw;
+extern struct svga_tracked_state svga_update_swtnl_vdecl;
+
+/* Bring the hardware fully up-to-date so that we can emit draw
+ * commands.
+ */
+#define SVGA_STATE_NEED_SWTNL        0
+#define SVGA_STATE_HW_CLEAR          1
+#define SVGA_STATE_HW_DRAW           2
+#define SVGA_STATE_SWTNL_DRAW        3
+#define SVGA_STATE_MAX               4
+
+
+enum pipe_error svga_update_state( struct svga_context *svga,
+                                   unsigned level );
+
+void svga_update_state_retry( struct svga_context *svga,
+                              unsigned level );
+
+
+enum pipe_error svga_emit_initial_state( struct svga_context *svga );
+
+#endif
diff --git a/src/gallium/drivers/svga/svga_state_constants.c b/src/gallium/drivers/svga/svga_state_constants.c
new file mode 100644
index 0000000..6b0e511
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_state_constants.c
@@ -0,0 +1,240 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_inlines.h"
+#include "pipe/p_defines.h"
+
+#include "svga_context.h"
+#include "svga_state.h"
+#include "svga_cmd.h"
+#include "svga_tgsi.h"
+#include "svga_debug.h"
+
+#include "svga_hw_reg.h"
+
+/***********************************************************************
+ * Hardware update 
+ */
+
+/* Convert from PIPE_SHADER_* to SVGA3D_SHADERTYPE_*
+ */
+static int svga_shader_type( int unit )
+{
+   return unit + 1;
+}
+
+
+static int emit_const( struct svga_context *svga,
+                       int unit,
+                       int i,
+                       const float *value )
+{
+   int ret = PIPE_OK;
+
+   if (memcmp(svga->state.hw_draw.cb[unit][i], value, 4 * sizeof(float)) != 0) {
+      if (SVGA_DEBUG & DEBUG_CONSTS)
+         debug_printf("%s %s %d: %f %f %f %f\n",
+                      __FUNCTION__,
+                      unit == PIPE_SHADER_VERTEX ? "VERT" : "FRAG",
+                      i,
+                      value[0],
+                      value[1],
+                      value[2],
+                      value[3]);
+
+      ret = SVGA3D_SetShaderConst( svga->swc, 
+                                   i,
+                                   svga_shader_type(unit),
+                                   SVGA3D_CONST_TYPE_FLOAT,
+                                   value );
+      if (ret)
+         return ret;
+
+      memcpy(svga->state.hw_draw.cb[unit][i], value, 4 * sizeof(float));
+   }
+   
+   return ret;
+}
+
+static int emit_consts( struct svga_context *svga,
+                        int offset,
+                        int unit )
+{
+   struct pipe_screen *screen = svga->pipe.screen;
+   unsigned count;
+   const float (*data)[4] = NULL;
+   unsigned i;
+   int ret = PIPE_OK;
+
+   if (svga->curr.cb[unit] == NULL)
+      goto done;
+
+   count = svga->curr.cb[unit]->size / (4 * sizeof(float));
+
+   data = (const float (*)[4])pipe_buffer_map(screen,
+                                              svga->curr.cb[unit],
+                                              PIPE_BUFFER_USAGE_CPU_READ);
+   if (data == NULL) {
+      ret = PIPE_ERROR_OUT_OF_MEMORY;
+      goto done;
+   }
+
+   for (i = 0; i < count; i++) {
+      ret = emit_const( svga, unit, offset + i, data[i] );
+      if (ret)
+         goto done;
+   }
+
+done:
+   if (data)
+      pipe_buffer_unmap(screen, svga->curr.cb[unit]);
+
+   return ret;
+}
+   
+static int emit_fs_consts( struct svga_context *svga,
+                           unsigned dirty )
+{
+   const struct svga_shader_result *result = svga->state.hw_draw.fs;
+   const struct svga_fs_compile_key *key = &result->key.fkey;
+   int ret = 0;
+
+   ret = emit_consts( svga, 0, PIPE_SHADER_FRAGMENT );
+   if (ret)
+      return ret;
+
+   /* The internally generated fragment shader for xor blending
+    * doesn't have a 'result' struct.  It should be fixed to avoid
+    * this special case, but work around it with a NULL check:
+    */
+   if (result != NULL &&
+       key->num_unnormalized_coords)
+   {
+      unsigned offset = result->shader->info.file_max[TGSI_FILE_CONSTANT] + 1;
+      int i;
+
+      for (i = 0; i < key->num_textures; i++) {
+         if (key->tex[i].unnormalized) {
+            struct pipe_texture *tex = svga->curr.texture[i];
+            float data[4];
+
+            data[0] = 1.0 / (float)tex->width0;
+            data[1] = 1.0 / (float)tex->height0;
+            data[2] = 1.0;
+            data[3] = 1.0;
+
+            ret = emit_const( svga,
+                              PIPE_SHADER_FRAGMENT,
+                              key->tex[i].width_height_idx + offset,
+                              data );
+            if (ret)
+               return ret;
+         }
+      }
+
+      offset += key->num_unnormalized_coords;
+   }
+
+   return 0;
+}
+
+
+struct svga_tracked_state svga_hw_fs_parameters = 
+{
+   "hw fs params",
+   (SVGA_NEW_FS_CONST_BUFFER |
+    SVGA_NEW_FS_RESULT |
+    SVGA_NEW_TEXTURE_BINDING),
+   emit_fs_consts
+};
+
+/***********************************************************************
+ */
+
+static int emit_vs_consts( struct svga_context *svga,
+                           unsigned dirty )
+{
+   const struct svga_shader_result *result = svga->state.hw_draw.vs;
+   const struct svga_vs_compile_key *key = &result->key.vkey;
+   int ret = 0;
+   unsigned offset;
+
+   /* SVGA_NEW_VS_RESULT
+    */
+   if (result == NULL) 
+      return 0;
+
+   /* SVGA_NEW_VS_CONST_BUFFER 
+    */
+   ret = emit_consts( svga, 0, PIPE_SHADER_VERTEX );
+   if (ret)
+      return ret;
+
+   offset = result->shader->info.file_max[TGSI_FILE_CONSTANT] + 1;
+
+   /* SVGA_NEW_VS_RESULT
+    */
+   if (key->need_prescale) {
+      ret = emit_const( svga, PIPE_SHADER_VERTEX, offset++,
+                        svga->state.hw_clear.prescale.scale );
+      if (ret)
+         return ret;
+
+      ret = emit_const( svga, PIPE_SHADER_VERTEX, offset++,
+                        svga->state.hw_clear.prescale.translate );
+      if (ret)
+         return ret;
+   }
+
+   /* SVGA_NEW_ZERO_STRIDE
+    */
+   if (key->zero_stride_vertex_elements) {
+      unsigned i, curr_zero_stride = 0;
+      for (i = 0; i < PIPE_MAX_ATTRIBS; ++i) {
+         if (key->zero_stride_vertex_elements & (1 << i)) {
+            ret = emit_const( svga, PIPE_SHADER_VERTEX, offset++,
+                              svga->curr.zero_stride_constants +
+                              4 * curr_zero_stride );
+            if (ret)
+               return ret;
+            ++curr_zero_stride;
+         }
+      }
+   }
+
+   return 0;
+}
+
+
+struct svga_tracked_state svga_hw_vs_parameters = 
+{
+   "hw vs params",
+   (SVGA_NEW_PRESCALE |
+    SVGA_NEW_VS_CONST_BUFFER |
+    SVGA_NEW_ZERO_STRIDE |
+    SVGA_NEW_VS_RESULT),
+   emit_vs_consts
+};
+
diff --git a/src/gallium/drivers/svga/svga_state_framebuffer.c b/src/gallium/drivers/svga/svga_state_framebuffer.c
new file mode 100644
index 0000000..cfdcae4
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_state_framebuffer.c
@@ -0,0 +1,458 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_inlines.h"
+#include "pipe/p_defines.h"
+#include "util/u_math.h"
+
+#include "svga_context.h"
+#include "svga_state.h"
+#include "svga_cmd.h"
+#include "svga_debug.h"
+
+#include "svga_hw_reg.h"
+
+
+/***********************************************************************
+ * Hardware state update
+ */
+
+
+static int emit_framebuffer( struct svga_context *svga,
+                             unsigned dirty )
+{
+   const struct pipe_framebuffer_state *curr = &svga->curr.framebuffer;
+   struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;
+   unsigned i;
+   enum pipe_error ret;
+
+   /* XXX: Need shadow state in svga->hw to eliminate redundant
+    * uploads, especially of NULL buffers.
+    */
+   
+   for(i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
+      if (curr->cbufs[i] != hw->cbufs[i]) {
+         if (svga->curr.nr_fbs++ > 8)
+            return PIPE_ERROR_OUT_OF_MEMORY;
+
+         ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_COLOR0 + i, curr->cbufs[i]);
+         if (ret != PIPE_OK)
+            return ret;
+         
+         pipe_surface_reference(&hw->cbufs[i], curr->cbufs[i]);
+      }
+   }
+
+   
+   if (curr->zsbuf != hw->zsbuf) {
+      ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_DEPTH, curr->zsbuf);
+      if (ret != PIPE_OK)
+         return ret;
+
+      if (curr->zsbuf &&
+          curr->zsbuf->format == PIPE_FORMAT_Z24S8_UNORM) {
+         ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_STENCIL, curr->zsbuf);
+         if (ret != PIPE_OK)
+            return ret;
+      }
+      else {
+         ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_STENCIL, NULL);
+         if (ret != PIPE_OK)
+            return ret;
+      }
+      
+      pipe_surface_reference(&hw->zsbuf, curr->zsbuf);
+   }
+
+
+   return 0;
+}
+
+
+struct svga_tracked_state svga_hw_framebuffer = 
+{
+   "hw framebuffer state",
+   SVGA_NEW_FRAME_BUFFER,
+   emit_framebuffer
+};
+
+
+
+
+/*********************************************************************** 
+ */
+
+static int emit_viewport( struct svga_context *svga,
+                          unsigned dirty )
+{
+   const struct pipe_viewport_state *viewport = &svga->curr.viewport;
+   struct svga_prescale prescale;
+   SVGA3dRect rect;
+   /* Not sure if this state is relevant with POSITIONT.  Probably
+    * not, but setting to 0,1 avoids some state pingponging.
+    */
+   float range_min = 0.0;
+   float range_max = 1.0;
+   float flip = -1.0;
+   boolean degenerate = FALSE;
+   enum pipe_error ret;
+
+   float fb_width = svga->curr.framebuffer.width;
+   float fb_height = svga->curr.framebuffer.height;
+
+   memset( &prescale, 0, sizeof(prescale) );
+
+   if (svga->curr.rast->templ.bypass_vs_clip_and_viewport) {
+
+      /* Avoid POSITIONT as it has a non trivial implementation outside the D3D
+       * API. Always generate a vertex shader.
+       */
+      rect.x = 0;
+      rect.y = 0;
+      rect.w = svga->curr.framebuffer.width;
+      rect.h = svga->curr.framebuffer.height;
+
+      prescale.scale[0] = 2.0 / (float)rect.w;
+      prescale.scale[1] = - 2.0 / (float)rect.h;
+      prescale.scale[2] = 1.0;
+      prescale.scale[3] = 1.0;
+      prescale.translate[0] = -1.0f;
+      prescale.translate[1] = 1.0f;
+      prescale.translate[2] = 0;
+      prescale.translate[3] = 0;
+      prescale.enabled = TRUE;
+   } else {
+
+      /* Examine gallium viewport transformation and produce a screen
+       * rectangle and possibly vertex shader pre-transformation to
+       * get the same results.
+       */
+      float fx =        viewport->scale[0] * -1.0 + viewport->translate[0];
+      float fy = flip * viewport->scale[1] * -1.0 + viewport->translate[1];
+      float fw =        viewport->scale[0] * 2; 
+      float fh = flip * viewport->scale[1] * 2; 
+
+      SVGA_DBG(DEBUG_VIEWPORT,
+               "\ninitial %f,%f %fx%f\n",
+               fx,
+               fy,
+               fw,
+               fh);
+
+      prescale.scale[0] = 1.0;
+      prescale.scale[1] = 1.0;
+      prescale.scale[2] = 1.0;
+      prescale.scale[3] = 1.0;
+      prescale.translate[0] = 0;
+      prescale.translate[1] = 0;
+      prescale.translate[2] = 0;
+      prescale.translate[3] = 0;
+      prescale.enabled = TRUE;
+
+
+
+      if (fw < 0) {
+         prescale.scale[0] *= -1.0;
+         prescale.translate[0] += -fw;
+         fw = -fw;
+         fx =        viewport->scale[0] * 1.0 + viewport->translate[0];
+      }
+
+      if (fh < 0) {
+         prescale.scale[1] *= -1.0;
+         prescale.translate[1] += -fh;
+         fh = -fh;
+         fy = flip * viewport->scale[1] * 1.0 + viewport->translate[1];
+      }
+
+      if (fx < 0) {
+         prescale.translate[0] += fx;
+         prescale.scale[0] *= fw / (fw + fx); 
+         fw += fx;
+         fx = 0;
+      }
+
+      if (fy < 0) {
+         prescale.translate[1] += fy;
+         prescale.scale[1] *= fh / (fh + fy); 
+         fh += fy;
+         fy = 0;
+      }
+
+      if (fx + fw > fb_width) {
+         prescale.scale[0] *= fw / (fb_width - fx); 
+         prescale.translate[0] -= fx * (fw / (fb_width - fx));
+         prescale.translate[0] += fx;
+         fw = fb_width - fx;
+         
+      }
+
+      if (fy + fh > fb_height) {
+         prescale.scale[1] *= fh / (fb_height - fy);
+         prescale.translate[1] -= fy * (fh / (fb_height - fy));
+         prescale.translate[1] += fy;
+         fh = fb_height - fy;
+      }
+
+      if (fw < 0 || fh < 0) {
+         fw = fh = fx = fy = 0;
+         degenerate = TRUE;
+         goto out;
+      }
+
+
+      /* D3D viewport is integer space.  Convert fx,fy,etc. to
+       * integers.
+       *
+       * TODO: adjust pretranslate correct for any subpixel error
+       * introduced converting to integers.
+       */
+      rect.x = fx;
+      rect.y = fy;
+      rect.w = fw;
+      rect.h = fh;
+
+      SVGA_DBG(DEBUG_VIEWPORT,
+               "viewport error %f,%f %fx%f\n",
+               fabs((float)rect.x - fx),
+               fabs((float)rect.y - fy),
+               fabs((float)rect.w - fw),
+               fabs((float)rect.h - fh));
+
+      SVGA_DBG(DEBUG_VIEWPORT,
+               "viewport %d,%d %dx%d\n",
+               rect.x,
+               rect.y,
+               rect.w,
+               rect.h);
+      
+
+      /* Finally, to get GL rasterization rules, need to tweak the
+       * screen-space coordinates slightly relative to D3D which is
+       * what hardware implements natively.
+       */
+      if (svga->curr.rast->templ.gl_rasterization_rules) {
+         float adjust_x = 0.0;
+         float adjust_y = 0.0;
+
+         switch (svga->curr.reduced_prim) {
+         case PIPE_PRIM_LINES:
+            adjust_x = -0.5;
+            adjust_y = 0;
+            break;
+         case PIPE_PRIM_POINTS:
+         case PIPE_PRIM_TRIANGLES:
+            adjust_x = -0.375;
+            adjust_y = -0.5;
+            break;
+         }
+
+         prescale.translate[0] += adjust_x;
+         prescale.translate[1] += adjust_y;
+         prescale.translate[2] = 0.5; /* D3D clip space */
+         prescale.scale[2]     = 0.5; /* D3D clip space */
+      }
+
+
+      range_min = viewport->scale[2] * -1.0 + viewport->translate[2];
+      range_max = viewport->scale[2] *  1.0 + viewport->translate[2];
+
+      /* D3D (and by implication SVGA) doesn't like dealing with zmax
+       * less than zmin.  Detect that case, flip the depth range and
+       * invert our z-scale factor to achieve the same effect.
+       */
+      if (range_min > range_max) {
+         float range_tmp;
+         range_tmp = range_min; 
+         range_min = range_max; 
+         range_max = range_tmp;
+         prescale.scale[2]     = -prescale.scale[2];
+      }
+   }
+
+   if (prescale.enabled) {
+      float H[2];
+      float J[2];
+      int i;
+
+      SVGA_DBG(DEBUG_VIEWPORT,
+               "prescale %f,%f %fx%f\n",
+               prescale.translate[0],
+               prescale.translate[1],
+               prescale.scale[0],
+               prescale.scale[1]);
+
+      H[0] = (float)rect.w / 2.0;
+      H[1] = -(float)rect.h / 2.0;
+      J[0] = (float)rect.x + (float)rect.w / 2.0;
+      J[1] = (float)rect.y + (float)rect.h / 2.0;
+
+      SVGA_DBG(DEBUG_VIEWPORT,
+               "H %f,%f\n"
+               "J %fx%f\n",
+               H[0],
+               H[1],
+               J[0],
+               J[1]);
+
+      /* Adjust prescale to take into account the fact that it is
+       * going to be applied prior to the perspective divide and
+       * viewport transformation.
+       * 
+       * Vwin = H(Vc/Vc.w) + J
+       *
+       * We want to tweak Vwin with scale and translation from above,
+       * as in:
+       *
+       * Vwin' = S Vwin + T
+       *
+       * But we can only modify the values at Vc.  Plugging all the
+       * above together, and rearranging, eventually we get:
+       *
+       *   Vwin' = H(Vc'/Vc'.w) + J
+       * where:
+       *   Vc' = SVc + KVc.w
+       *   K = (T + (S-1)J) / H
+       *
+       * Overwrite prescale.translate with values for K:
+       */
+      for (i = 0; i < 2; i++) {
+         prescale.translate[i] = ((prescale.translate[i] +
+                                   (prescale.scale[i] - 1.0) * J[i]) / H[i]);
+      }
+
+      SVGA_DBG(DEBUG_VIEWPORT,
+               "clipspace %f,%f %fx%f\n",
+               prescale.translate[0],
+               prescale.translate[1],
+               prescale.scale[0],
+               prescale.scale[1]);
+   }
+
+out:
+   if (degenerate) {
+      rect.x = 0;
+      rect.y = 0;
+      rect.w = 1;
+      rect.h = 1;
+      prescale.enabled = FALSE;
+   }
+
+   if (memcmp(&rect, &svga->state.hw_clear.viewport, sizeof(rect)) != 0) {
+      ret = SVGA3D_SetViewport(svga->swc, &rect);
+      if(ret != PIPE_OK)
+         return ret;
+
+      memcpy(&svga->state.hw_clear.viewport, &rect, sizeof(rect));
+      assert(sizeof(rect) == sizeof(svga->state.hw_clear.viewport));
+   }
+
+   if (svga->state.hw_clear.depthrange.zmin != range_min ||
+       svga->state.hw_clear.depthrange.zmax != range_max) 
+   {
+      ret = SVGA3D_SetZRange(svga->swc, range_min, range_max );
+      if(ret != PIPE_OK)
+         return ret;
+
+      svga->state.hw_clear.depthrange.zmin = range_min;
+      svga->state.hw_clear.depthrange.zmax = range_max;
+   }
+
+   if (memcmp(&prescale, &svga->state.hw_clear.prescale, sizeof prescale) != 0) {
+      svga->dirty |= SVGA_NEW_PRESCALE;
+      svga->state.hw_clear.prescale = prescale;
+   }
+
+   return 0;
+}
+
+
+struct svga_tracked_state svga_hw_viewport = 
+{
+   "hw viewport state",
+   ( SVGA_NEW_FRAME_BUFFER |
+     SVGA_NEW_VIEWPORT |
+     SVGA_NEW_RAST |
+     SVGA_NEW_REDUCED_PRIMITIVE ),
+   emit_viewport
+};
+
+
+/***********************************************************************
+ * Scissor state
+ */
+static int emit_scissor_rect( struct svga_context *svga,
+                              unsigned dirty )
+{
+   const struct pipe_scissor_state *scissor = &svga->curr.scissor;
+   SVGA3dRect rect;
+
+   rect.x = scissor->minx;
+   rect.y = scissor->miny;
+   rect.w = scissor->maxx - scissor->minx; /* + 1 ?? */
+   rect.h = scissor->maxy - scissor->miny; /* + 1 ?? */
+   
+   return SVGA3D_SetScissorRect(svga->swc, &rect);
+}
+
+
+struct svga_tracked_state svga_hw_scissor = 
+{
+   "hw scissor state",
+   SVGA_NEW_SCISSOR,
+   emit_scissor_rect
+};
+
+
+/***********************************************************************
+ * Userclip state
+ */
+
+static int emit_clip_planes( struct svga_context *svga,
+                             unsigned dirty )
+{
+   unsigned i;
+   enum pipe_error ret;
+
+   /* TODO: just emit directly from svga_set_clip_state()?
+    */
+   for (i = 0; i < svga->curr.clip.nr; i++) {
+      ret = SVGA3D_SetClipPlane( svga->swc,
+                                 i,
+                                 svga->curr.clip.ucp[i] );
+      if(ret != PIPE_OK)
+         return ret;
+   }
+
+   return 0;
+}
+
+
+struct svga_tracked_state svga_hw_clip_planes = 
+{
+   "hw viewport state",
+   SVGA_NEW_CLIP,
+   emit_clip_planes
+};
diff --git a/src/gallium/drivers/svga/svga_state_fs.c b/src/gallium/drivers/svga/svga_state_fs.c
new file mode 100644
index 0000000..d29f376
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_state_fs.c
@@ -0,0 +1,302 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_inlines.h"
+#include "pipe/p_defines.h"
+#include "util/u_math.h"
+#include "util/u_bitmask.h"
+
+#include "svga_context.h"
+#include "svga_state.h"
+#include "svga_cmd.h"
+#include "svga_tgsi.h"
+
+#include "svga_hw_reg.h"
+
+
+
+static INLINE int compare_fs_keys( const struct svga_fs_compile_key *a,
+                                   const struct svga_fs_compile_key *b )
+{
+   unsigned keysize_a = svga_fs_key_size( a );
+   unsigned keysize_b = svga_fs_key_size( b );
+
+   if (keysize_a != keysize_b) {
+      return (int)(keysize_a - keysize_b);
+   }
+   return memcmp( a, b, keysize_a );
+}
+
+
+static struct svga_shader_result *search_fs_key( struct svga_fragment_shader *fs,
+                                                 const struct svga_fs_compile_key *key )
+{
+   struct svga_shader_result *result = fs->base.results;
+
+   assert(key);
+
+   for ( ; result; result = result->next) {
+      if (compare_fs_keys( key, &result->key.fkey ) == 0)
+         return result;
+   }
+   
+   return NULL;
+}
+
+
+static enum pipe_error compile_fs( struct svga_context *svga,
+                                   struct svga_fragment_shader *fs,
+                                   const struct svga_fs_compile_key *key,
+                                   struct svga_shader_result **out_result )
+{
+   struct svga_shader_result *result;
+   enum pipe_error ret = PIPE_ERROR;
+
+   result = svga_translate_fragment_program( fs, key );
+   if (result == NULL) {
+      ret = PIPE_ERROR_OUT_OF_MEMORY;
+      goto fail;
+   }
+
+   result->id = util_bitmask_add(svga->fs_bm);
+   if(result->id == UTIL_BITMASK_INVALID_INDEX)
+      goto fail;
+
+   ret = SVGA3D_DefineShader(svga->swc, 
+                             result->id,
+                             SVGA3D_SHADERTYPE_PS,
+                             result->tokens, 
+                             result->nr_tokens * sizeof result->tokens[0]);
+   if (ret)
+      goto fail;
+
+   *out_result = result;
+   result->next = fs->base.results;
+   fs->base.results = result;
+   return PIPE_OK;
+
+fail:
+   if (result) {
+      if (result->id != UTIL_BITMASK_INVALID_INDEX)
+         util_bitmask_clear( svga->fs_bm, result->id );
+      svga_destroy_shader_result( result );
+   }
+   return ret;
+}
+
+/* The blend workaround for simulating logicop xor behaviour requires
+ * that the incoming fragment color be white.  This change achieves
+ * that by hooking up a hard-wired fragment shader that just emits
+ * color 1,1,1,1
+ *   
+ * This is a slightly incomplete solution as it assumes that the
+ * actual bound shader has no other effects beyond generating a
+ * fragment color.  In particular shaders containing TEXKIL and/or
+ * depth-write will not have the correct behaviour, nor will those
+ * expecting to use alphatest.
+ *   
+ * These are avoidable issues, but they are not much worse than the
+ * unavoidable ones associated with this technique, so it's not clear
+ * how much effort should be expended trying to resolve them - the
+ * ultimate result will still not be correct in most cases.
+ *
+ * Shader below was generated with:
+ *   SVGA_DEBUG=tgsi ./mesa/progs/fp/fp-tri white.txt
+ */
+static int emit_white_fs( struct svga_context *svga )
+{
+   int ret = PIPE_ERROR;
+
+   /* ps_3_0
+    * def c0, 1.000000, 0.000000, 0.000000, 1.000000
+    * mov oC0, c0.x
+    * end
+    */
+   static const unsigned white_tokens[] = {
+      0xffff0300,
+      0x05000051,
+      0xa00f0000,
+      0x3f800000,
+      0x00000000,
+      0x00000000,
+      0x3f800000,
+      0x02000001,
+      0x800f0800,
+      0xa0000000,
+      0x0000ffff,
+   };
+
+   assert(SVGA3D_INVALID_ID == UTIL_BITMASK_INVALID_INDEX);
+   svga->state.white_fs_id = util_bitmask_add(svga->fs_bm);
+   if(svga->state.white_fs_id == SVGA3D_INVALID_ID)
+      goto no_fs_id;
+
+   ret = SVGA3D_DefineShader(svga->swc, 
+                             svga->state.white_fs_id,
+                             SVGA3D_SHADERTYPE_PS,
+                             white_tokens, 
+                             sizeof(white_tokens));
+   if (ret)
+      goto no_definition;
+
+   return 0;
+
+no_definition:
+   util_bitmask_clear(svga->fs_bm, svga->state.white_fs_id);
+   svga->state.white_fs_id = SVGA3D_INVALID_ID;
+no_fs_id:
+   return ret;
+}
+
+
+/* SVGA_NEW_TEXTURE_BINDING
+ * SVGA_NEW_RAST
+ * SVGA_NEW_NEED_SWTNL
+ * SVGA_NEW_SAMPLER
+ */
+static int make_fs_key( const struct svga_context *svga,
+                        struct svga_fs_compile_key *key )
+{
+   int i;
+   int idx = 0;
+
+   memset(key, 0, sizeof *key);
+
+   /* Only need fragment shader fixup for twoside lighting if doing
+    * hwtnl.  Otherwise the draw module does the whole job for us.
+    *
+    * SVGA_NEW_SWTNL
+    */
+   if (!svga->state.sw.need_swtnl) {
+      /* SVGA_NEW_RAST
+       */
+      key->light_twoside = svga->curr.rast->templ.light_twoside;
+      key->front_cw = (svga->curr.rast->templ.front_winding == 
+                       PIPE_WINDING_CW);
+   }
+
+   
+   /* XXX: want to limit this to the textures that the shader actually
+    * refers to.
+    *
+    * SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER
+    */
+   for (i = 0; i < svga->curr.num_textures; i++) {
+      if (svga->curr.texture[i]) {
+         assert(svga->curr.sampler[i]);
+         key->tex[i].texture_target = svga->curr.texture[i]->target;
+         if (!svga->curr.sampler[i]->normalized_coords) {
+            key->tex[i].width_height_idx = idx++;
+            key->tex[i].unnormalized = TRUE;
+            ++key->num_unnormalized_coords;
+         }
+      }
+   }
+   key->num_textures = svga->curr.num_textures;
+
+   idx = 0;
+   for (i = 0; i < svga->curr.num_samplers; ++i) {
+      if (svga->curr.sampler[i]) {
+         key->tex[i].compare_mode = svga->curr.sampler[i]->compare_mode;
+         key->tex[i].compare_func = svga->curr.sampler[i]->compare_func;
+      }
+   }
+
+   return 0;
+}
+
+
+
+static int emit_hw_fs( struct svga_context *svga,
+                       unsigned dirty )
+{
+   struct svga_shader_result *result = NULL;
+   unsigned id = SVGA3D_INVALID_ID;
+   int ret = 0;
+
+   /* SVGA_NEW_BLEND
+    */
+   if (svga->curr.blend->need_white_fragments) {
+      if (svga->state.white_fs_id == SVGA3D_INVALID_ID) {
+         ret = emit_white_fs( svga );
+         if (ret)
+            return ret;
+      }
+      id = svga->state.white_fs_id;
+   }
+   else {
+      struct svga_fragment_shader *fs = svga->curr.fs;
+      struct svga_fs_compile_key key;
+
+      /* SVGA_NEW_TEXTURE_BINDING
+       * SVGA_NEW_RAST
+       * SVGA_NEW_NEED_SWTNL
+       * SVGA_NEW_SAMPLER
+       */
+      ret = make_fs_key( svga, &key );
+      if (ret)
+         return ret;
+
+      result = search_fs_key( fs, &key );
+      if (!result) {
+         ret = compile_fs( svga, fs, &key, &result );
+         if (ret)
+            return ret;
+      }
+
+      assert (result);
+      id = result->id;
+   }
+
+   assert(id != SVGA3D_INVALID_ID);
+
+   if (result != svga->state.hw_draw.fs) {
+      ret = SVGA3D_SetShader(svga->swc,
+                             SVGA3D_SHADERTYPE_PS,
+                             id );
+      if (ret)
+         return ret;
+
+      svga->dirty |= SVGA_NEW_FS_RESULT;
+      svga->state.hw_draw.fs = result;      
+   }
+
+   return 0;
+}
+
+struct svga_tracked_state svga_hw_fs = 
+{
+   "fragment shader (hwtnl)",
+   (SVGA_NEW_FS |
+    SVGA_NEW_TEXTURE_BINDING |
+    SVGA_NEW_NEED_SWTNL |
+    SVGA_NEW_RAST |
+    SVGA_NEW_SAMPLER |
+    SVGA_NEW_BLEND),
+   emit_hw_fs
+};
+
+
+
diff --git a/src/gallium/drivers/svga/svga_state_need_swtnl.c b/src/gallium/drivers/svga/svga_state_need_swtnl.c
new file mode 100644
index 0000000..3c35a85
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_state_need_swtnl.c
@@ -0,0 +1,200 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_inlines.h"
+#include "pipe/p_state.h"
+
+
+#include "svga_context.h"
+#include "svga_state.h"
+#include "svga_debug.h"
+#include "svga_hw_reg.h"
+
+/***********************************************************************
+ */
+
+static INLINE SVGA3dDeclType 
+svga_translate_vertex_format(enum pipe_format format)
+{
+   switch (format) {
+   case PIPE_FORMAT_R32_FLOAT:            return SVGA3D_DECLTYPE_FLOAT1;
+   case PIPE_FORMAT_R32G32_FLOAT:         return SVGA3D_DECLTYPE_FLOAT2;
+   case PIPE_FORMAT_R32G32B32_FLOAT:      return SVGA3D_DECLTYPE_FLOAT3;
+   case PIPE_FORMAT_R32G32B32A32_FLOAT:   return SVGA3D_DECLTYPE_FLOAT4;
+   case PIPE_FORMAT_B8G8R8A8_UNORM:       return SVGA3D_DECLTYPE_D3DCOLOR;
+   case PIPE_FORMAT_R8G8B8A8_USCALED:     return SVGA3D_DECLTYPE_UBYTE4;
+   case PIPE_FORMAT_R16G16_SSCALED:       return SVGA3D_DECLTYPE_SHORT2;
+   case PIPE_FORMAT_R16G16B16A16_SSCALED: return SVGA3D_DECLTYPE_SHORT4;
+   case PIPE_FORMAT_R8G8B8A8_UNORM:       return SVGA3D_DECLTYPE_UBYTE4N;
+   case PIPE_FORMAT_R16G16_SNORM:         return SVGA3D_DECLTYPE_SHORT2N;
+   case PIPE_FORMAT_R16G16B16A16_SNORM:   return SVGA3D_DECLTYPE_SHORT4N;
+   case PIPE_FORMAT_R16G16_UNORM:         return SVGA3D_DECLTYPE_USHORT2N;
+   case PIPE_FORMAT_R16G16B16A16_UNORM:   return SVGA3D_DECLTYPE_USHORT4N;
+
+   /* These formats don't exist yet:
+    * 
+   case PIPE_FORMAT_R10G10B10_USCALED:    return SVGA3D_DECLTYPE_UDEC3;
+   case PIPE_FORMAT_R10G10B10_SNORM:      return SVGA3D_DECLTYPE_DEC3N;
+   case PIPE_FORMAT_R16G16_FLOAT:         return SVGA3D_DECLTYPE_FLOAT16_2;
+   case PIPE_FORMAT_R16G16B16A16_FLOAT:   return SVGA3D_DECLTYPE_FLOAT16_4;
+   */
+
+   default:
+      /* There are many formats without hardware support.  This case
+       * will be hit regularly, meaning we'll need swvfetch.
+       */
+      return SVGA3D_DECLTYPE_MAX;
+   }
+}
+
+
+static int update_need_swvfetch( struct svga_context *svga,
+                                 unsigned dirty )
+{
+   unsigned i;
+   boolean need_swvfetch = FALSE;
+
+   for (i = 0; i < svga->curr.num_vertex_elements; i++) {
+      svga->state.sw.ve_format[i] = svga_translate_vertex_format(svga->curr.ve[i].src_format);
+      if (svga->state.sw.ve_format[i] == SVGA3D_DECLTYPE_MAX) {
+         need_swvfetch = TRUE;
+         break;
+      }
+   }
+
+   if (need_swvfetch != svga->state.sw.need_swvfetch) {
+      svga->state.sw.need_swvfetch = need_swvfetch;
+      svga->dirty |= SVGA_NEW_NEED_SWVFETCH;
+   }
+   
+   return 0;
+}
+
+struct svga_tracked_state svga_update_need_swvfetch = 
+{
+   "update need_swvfetch",
+   ( SVGA_NEW_VELEMENT ),
+   update_need_swvfetch
+};
+
+
+/*********************************************************************** 
+ */
+
+static int update_need_pipeline( struct svga_context *svga,
+                                 unsigned dirty )
+{
+   
+   boolean need_pipeline = FALSE;
+   struct svga_vertex_shader *vs = svga->curr.vs;
+
+   /* SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE
+    */
+   if (svga->curr.rast->need_pipeline & (1 << svga->curr.reduced_prim)) {
+      SVGA_DBG(DEBUG_SWTNL, "%s: rast need_pipeline (%d) & prim (%x)\n", 
+                 __FUNCTION__,
+                 svga->curr.rast->need_pipeline,
+                 (1 << svga->curr.reduced_prim) );
+      need_pipeline = TRUE;
+   }
+
+   /* EDGEFLAGS
+    */
+    if (vs->base.info.writes_edgeflag) {
+      SVGA_DBG(DEBUG_SWTNL, "%s: edgeflags\n", __FUNCTION__);
+      need_pipeline = TRUE;
+   }
+
+   /* SVGA_NEW_CLIP 
+    */
+   if (!svga->curr.rast->templ.bypass_vs_clip_and_viewport &&
+       svga->curr.clip.nr) {
+      SVGA_DBG(DEBUG_SWTNL, "%s: userclip\n", __FUNCTION__);
+      need_pipeline = TRUE;
+   }
+
+   if (need_pipeline != svga->state.sw.need_pipeline) {
+      svga->state.sw.need_pipeline = need_pipeline;
+      svga->dirty |= SVGA_NEW_NEED_PIPELINE;
+   }
+
+   return 0;
+}
+
+
+struct svga_tracked_state svga_update_need_pipeline = 
+{
+   "need pipeline",
+   (SVGA_NEW_RAST |
+    SVGA_NEW_CLIP |
+    SVGA_NEW_VS |
+    SVGA_NEW_REDUCED_PRIMITIVE),
+   update_need_pipeline
+};
+
+
+/*********************************************************************** 
+ */
+
+static int update_need_swtnl( struct svga_context *svga,
+                              unsigned dirty )
+{
+   boolean need_swtnl;
+
+   if (svga->debug.no_swtnl) {
+      svga->state.sw.need_swvfetch = 0;
+      svga->state.sw.need_pipeline = 0;
+   }
+
+   need_swtnl = (svga->state.sw.need_swvfetch ||
+                 svga->state.sw.need_pipeline);
+
+   if (svga->debug.force_swtnl) {
+      need_swtnl = 1;
+   }
+
+   if (need_swtnl != svga->state.sw.need_swtnl) {
+      SVGA_DBG(DEBUG_SWTNL|DEBUG_PERF,
+               "%s need_swvfetch: %s, need_pipeline %s\n",
+               __FUNCTION__,
+               svga->state.sw.need_swvfetch ? "true" : "false",
+               svga->state.sw.need_pipeline ? "true" : "false");
+
+      svga->state.sw.need_swtnl = need_swtnl;
+      svga->dirty |= SVGA_NEW_NEED_SWTNL;
+      svga->swtnl.new_vdecl = TRUE;
+   }
+  
+   return 0;
+}
+
+
+struct svga_tracked_state svga_update_need_swtnl =
+{
+   "need swtnl",
+   (SVGA_NEW_NEED_PIPELINE |
+    SVGA_NEW_NEED_SWVFETCH),
+   update_need_swtnl
+};
diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c
new file mode 100644
index 0000000..8b6803a
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_state_rss.c
@@ -0,0 +1,268 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_inlines.h"
+#include "pipe/p_defines.h"
+#include "util/u_math.h"
+
+#include "svga_context.h"
+#include "svga_state.h"
+#include "svga_cmd.h"
+
+#include "svga_hw_reg.h"
+
+
+
+struct rs_queue {
+   unsigned rs_count;
+   SVGA3dRenderState rs[SVGA3D_RS_MAX];
+};
+
+
+#define EMIT_RS(svga, value, token, fail)                       \
+do {                                                            \
+   if (svga->state.hw_draw.rs[SVGA3D_RS_##token] != value) {    \
+      svga_queue_rs( &queue, SVGA3D_RS_##token, value );        \
+      svga->state.hw_draw.rs[SVGA3D_RS_##token] = value;        \
+   }                                                            \
+} while (0)
+
+#define EMIT_RS_FLOAT(svga, fvalue, token, fail)                \
+do {                                                            \
+   unsigned value = fui(fvalue);                                \
+   if (svga->state.hw_draw.rs[SVGA3D_RS_##token] != value) {    \
+      svga_queue_rs( &queue, SVGA3D_RS_##token, value );        \
+      svga->state.hw_draw.rs[SVGA3D_RS_##token] = value;        \
+   }                                                            \
+} while (0)
+
+
+static INLINE void
+svga_queue_rs( struct rs_queue *q,
+               unsigned rss,
+               unsigned value )
+{
+   q->rs[q->rs_count].state = rss;
+   q->rs[q->rs_count].uintValue = value;
+   q->rs_count++;
+}
+
+
+/* Compare old and new render states and emit differences between them
+ * to hardware.  Simplest implementation would be to emit the whole of
+ * the "to" state.
+ */
+static int emit_rss( struct svga_context *svga,
+                     unsigned dirty )
+{
+   struct rs_queue queue;
+
+   queue.rs_count = 0;
+
+   if (dirty & SVGA_NEW_BLEND) {
+      const struct svga_blend_state *curr = svga->curr.blend;
+
+      EMIT_RS( svga, curr->rt[0].writemask, COLORWRITEENABLE, fail );
+      EMIT_RS( svga, curr->rt[0].blend_enable, BLENDENABLE, fail );
+
+      if (curr->rt[0].blend_enable) {
+         EMIT_RS( svga, curr->rt[0].srcblend, SRCBLEND, fail );
+         EMIT_RS( svga, curr->rt[0].dstblend, DSTBLEND, fail );
+         EMIT_RS( svga, curr->rt[0].blendeq, BLENDEQUATION, fail );
+
+         EMIT_RS( svga, curr->rt[0].separate_alpha_blend_enable, 
+                  SEPARATEALPHABLENDENABLE, fail );
+
+         if (curr->rt[0].separate_alpha_blend_enable) {
+            EMIT_RS( svga, curr->rt[0].srcblend_alpha, SRCBLENDALPHA, fail );
+            EMIT_RS( svga, curr->rt[0].dstblend_alpha, DSTBLENDALPHA, fail );
+            EMIT_RS( svga, curr->rt[0].blendeq_alpha, BLENDEQUATIONALPHA, fail );
+         }
+      }
+   }
+
+
+   if (dirty & (SVGA_NEW_DEPTH_STENCIL | SVGA_NEW_RAST)) {
+      const struct svga_depth_stencil_state *curr = svga->curr.depth; 
+      const struct svga_rasterizer_state *rast = svga->curr.rast; 
+
+      if (!curr->stencil[0].enabled) 
+      {
+         /* Stencil disabled
+          */
+         EMIT_RS( svga, FALSE, STENCILENABLE, fail );
+         EMIT_RS( svga, FALSE, STENCILENABLE2SIDED, fail );
+      }
+      else if (curr->stencil[0].enabled && !curr->stencil[1].enabled)
+      {
+         /* Regular stencil
+          */
+         EMIT_RS( svga, TRUE, STENCILENABLE, fail );
+         EMIT_RS( svga, FALSE, STENCILENABLE2SIDED, fail );
+
+         EMIT_RS( svga, curr->stencil[0].func,  STENCILFUNC, fail );
+         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 );
+      }
+      else 
+      {
+         int cw, ccw;
+
+         /* Hardware frontwinding is always CW, so if ours is also CW,
+          * then our definition of front face agrees with hardware.
+          * Otherwise need to flip.
+          */
+         if (rast->templ.front_winding == PIPE_WINDING_CW) {
+            cw = 0;
+            ccw = 1;
+         }
+         else {
+            cw = 1;
+            ccw = 0;
+         }
+
+         /* Twoside stencil
+          */
+         EMIT_RS( svga, TRUE, STENCILENABLE, fail );
+         EMIT_RS( svga, TRUE, STENCILENABLE2SIDED, fail );
+
+         EMIT_RS( svga, curr->stencil[cw].func,  STENCILFUNC, fail );
+         EMIT_RS( svga, curr->stencil[cw].fail,  STENCILFAIL, fail );
+         EMIT_RS( svga, curr->stencil[cw].zfail, STENCILZFAIL, fail );
+         EMIT_RS( svga, curr->stencil[cw].pass,  STENCILPASS, fail );
+
+         EMIT_RS( svga, curr->stencil[ccw].func,  CCWSTENCILFUNC, fail );
+         EMIT_RS( svga, curr->stencil[ccw].fail,  CCWSTENCILFAIL, fail );
+         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 );
+      }
+
+      EMIT_RS( svga, curr->zenable, ZENABLE, fail );
+      if (curr->zenable) {
+         EMIT_RS( svga, curr->zfunc, ZFUNC, fail );
+         EMIT_RS( svga, curr->zwriteenable, ZWRITEENABLE, fail );
+      }
+
+      EMIT_RS( svga, curr->alphatestenable, ALPHATESTENABLE, fail );
+      if (curr->alphatestenable) {
+         EMIT_RS( svga, curr->alphafunc, ALPHAFUNC, fail );
+         EMIT_RS_FLOAT( svga, curr->alpharef, ALPHAREF, fail );
+      }
+   }
+
+
+   if (dirty & SVGA_NEW_RAST)
+   {
+      const struct svga_rasterizer_state *curr = svga->curr.rast; 
+
+      /* Shademode: still need to rearrange index list to move
+       * flat-shading PV first vertex.
+       */
+      EMIT_RS( svga, curr->shademode, SHADEMODE, fail );
+      EMIT_RS( svga, curr->cullmode, CULLMODE, fail );
+      EMIT_RS( svga, curr->scissortestenable, SCISSORTESTENABLE, fail );
+      EMIT_RS( svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS, fail );
+      EMIT_RS( svga, curr->lastpixel, LASTPIXEL, fail );
+      EMIT_RS( svga, curr->linepattern, LINEPATTERN, fail );
+      EMIT_RS_FLOAT( svga, curr->pointsize, POINTSIZE, fail );
+      EMIT_RS_FLOAT( svga, curr->pointsize_min, POINTSIZEMIN, fail );
+      EMIT_RS_FLOAT( svga, curr->pointsize_max, POINTSIZEMAX, fail );
+   }
+
+   if (dirty & (SVGA_NEW_RAST | SVGA_NEW_FRAME_BUFFER | SVGA_NEW_NEED_PIPELINE))
+   {
+      const struct svga_rasterizer_state *curr = svga->curr.rast; 
+      float slope = 0.0;
+      float bias  = 0.0;
+
+      /* Need to modify depth bias according to bound depthbuffer
+       * format.  Don't do hardware depthbias while the software
+       * pipeline is active.
+       */
+      if (!svga->state.sw.need_pipeline &&
+          svga->curr.framebuffer.zsbuf)
+      {
+         slope = curr->slopescaledepthbias;
+         bias  = svga->curr.depthscale * curr->depthbias;
+      }
+
+      EMIT_RS_FLOAT( svga, slope, SLOPESCALEDEPTHBIAS, fail );
+      EMIT_RS_FLOAT( svga, bias, DEPTHBIAS, fail );
+   }
+
+
+   if (queue.rs_count) {
+      SVGA3dRenderState *rs;
+
+      if (SVGA3D_BeginSetRenderState( svga->swc,
+                                      &rs,
+                                      queue.rs_count ) != PIPE_OK)
+         goto fail;
+
+      memcpy( rs,
+              queue.rs,
+              queue.rs_count * sizeof queue.rs[0]);
+      
+      SVGA_FIFOCommitAll( svga->swc );
+   }
+
+   /* Also blend color:
+    */
+
+   return 0;
+
+fail:
+   /* XXX: need to poison cached hardware state on failure to ensure
+    * dirty state gets re-emitted.  Fix this by re-instating partial
+    * FIFOCommit command and only updating cached hw state once the
+    * initial allocation has succeeded.
+    */
+   memset(svga->state.hw_draw.rs, 0xcd, sizeof(svga->state.hw_draw.rs));
+
+   return PIPE_ERROR_OUT_OF_MEMORY;
+}
+
+
+struct svga_tracked_state svga_hw_rss = 
+{
+   "hw rss state",
+
+   (SVGA_NEW_BLEND |
+    SVGA_NEW_DEPTH_STENCIL |
+    SVGA_NEW_RAST |
+    SVGA_NEW_FRAME_BUFFER |
+    SVGA_NEW_NEED_PIPELINE),
+
+   emit_rss
+};
diff --git a/src/gallium/drivers/svga/svga_state_tss.c b/src/gallium/drivers/svga/svga_state_tss.c
new file mode 100644
index 0000000..b313794
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_state_tss.c
@@ -0,0 +1,279 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_inlines.h"
+#include "pipe/p_defines.h"
+#include "util/u_math.h"
+
+#include "svga_screen_texture.h"
+#include "svga_winsys.h"
+#include "svga_context.h"
+#include "svga_state.h"
+#include "svga_cmd.h"
+
+#include "svga_hw_reg.h"
+
+
+void svga_cleanup_tss_binding(struct svga_context *svga)
+{
+   int i;
+   unsigned count = MAX2( svga->curr.num_textures,
+                          svga->state.hw_draw.num_views );
+
+   for (i = 0; i < count; i++) {
+      struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];
+
+      svga_sampler_view_reference(&view->v, NULL);
+      pipe_texture_reference( &svga->curr.texture[i], NULL );
+      pipe_texture_reference( &view->texture, NULL );
+
+      view->dirty = 1;
+   }
+}
+
+
+static int
+update_tss_binding(struct svga_context *svga, 
+                   unsigned dirty )
+{
+   unsigned i;
+   unsigned count = MAX2( svga->curr.num_textures,
+                          svga->state.hw_draw.num_views );
+   unsigned min_lod;
+   unsigned max_lod;
+
+
+   struct {
+      struct {
+         unsigned unit;
+         struct svga_hw_view_state *view;
+      } bind[PIPE_MAX_SAMPLERS];
+
+      unsigned bind_count;
+   } queue;
+
+   queue.bind_count = 0;
+   
+   for (i = 0; i < count; i++) {
+      const struct svga_sampler_state *s = svga->curr.sampler[i];
+      struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];
+
+      /* get min max lod */
+      if (svga->curr.texture[i]) {
+         min_lod = MAX2(s->view_min_lod, 0);
+         max_lod = MIN2(s->view_max_lod, svga->curr.texture[i]->last_level);
+      } else {
+         min_lod = 0;
+         max_lod = 0;
+      }
+
+      if (view->texture != svga->curr.texture[i] ||
+          view->min_lod != min_lod ||
+          view->max_lod != max_lod) {
+
+         svga_sampler_view_reference(&view->v, NULL);
+         pipe_texture_reference( &view->texture, svga->curr.texture[i] );
+
+         view->dirty = TRUE;
+         view->min_lod = min_lod;
+         view->max_lod = max_lod;
+
+         if (svga->curr.texture[i])
+            view->v = svga_get_tex_sampler_view(&svga->pipe, 
+                                                svga->curr.texture[i], 
+                                                min_lod,
+                                                max_lod);
+      }
+
+      if (view->dirty) {
+         queue.bind[queue.bind_count].unit = i;
+         queue.bind[queue.bind_count].view = view;
+         queue.bind_count++;
+      } 
+      else if (view->v) {
+         svga_validate_sampler_view(svga, view->v);
+      }
+   }
+
+   svga->state.hw_draw.num_views = svga->curr.num_textures;
+
+   if (queue.bind_count) {
+      SVGA3dTextureState *ts;
+
+      if (SVGA3D_BeginSetTextureState( svga->swc,
+                                       &ts,
+                                       queue.bind_count ) != PIPE_OK)
+         goto fail;
+
+      for (i = 0; i < queue.bind_count; i++) {
+         ts[i].stage = queue.bind[i].unit;
+         ts[i].name = SVGA3D_TS_BIND_TEXTURE;
+
+         if (queue.bind[i].view->v) {
+            svga->swc->surface_relocation(svga->swc,
+                                          &ts[i].value,
+                                          queue.bind[i].view->v->handle,
+                                          PIPE_BUFFER_USAGE_GPU_READ);
+         }
+         else {
+            ts[i].value = SVGA3D_INVALID_ID;
+         }
+         
+         queue.bind[i].view->dirty = FALSE;
+      }
+
+      SVGA_FIFOCommitAll( svga->swc );
+   }
+
+   return 0;
+
+fail:
+   return PIPE_ERROR_OUT_OF_MEMORY;
+}
+
+
+struct svga_tracked_state svga_hw_tss_binding = {
+   "texture binding emit",
+   SVGA_NEW_TEXTURE_BINDING |
+   SVGA_NEW_SAMPLER,
+   update_tss_binding
+};
+
+
+/***********************************************************************
+ */
+
+struct ts_queue {
+   unsigned ts_count;
+   SVGA3dTextureState ts[PIPE_MAX_SAMPLERS*SVGA3D_TS_MAX];
+};
+
+
+#define EMIT_TS(svga, unit, val, token, fail)                           \
+do {                                                                    \
+   if (svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] != val) {        \
+      svga_queue_tss( &queue, unit, SVGA3D_TS_##token, val );           \
+      svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] = val;            \
+   }                                                                    \
+} while (0)
+
+#define EMIT_TS_FLOAT(svga, unit, fvalue, token, fail)                  \
+do {                                                                    \
+   unsigned val = fui(fvalue);                                          \
+   if (svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] != val) {        \
+      svga_queue_tss( &queue, unit, SVGA3D_TS_##token, val );           \
+      svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] = val;            \
+   }                                                                    \
+} while (0)
+
+
+static INLINE void 
+svga_queue_tss( struct ts_queue *q,
+                unsigned unit,
+                unsigned tss,
+                unsigned value )
+{
+   assert(q->ts_count < sizeof(q->ts)/sizeof(q->ts[0]));
+   q->ts[q->ts_count].stage = unit;
+   q->ts[q->ts_count].name = tss;
+   q->ts[q->ts_count].value = value;
+   q->ts_count++;
+}
+
+
+static int
+update_tss(struct svga_context *svga, 
+           unsigned dirty )
+{
+   unsigned i;
+   struct ts_queue queue;
+
+   queue.ts_count = 0;
+   for (i = 0; i < svga->curr.num_samplers; i++) {
+      if (svga->curr.sampler[i]) {
+         const struct svga_sampler_state *curr = svga->curr.sampler[i];
+
+         EMIT_TS(svga, i, curr->mipfilter, MIPFILTER, fail);
+         EMIT_TS(svga, i, curr->min_lod, TEXTURE_MIPMAP_LEVEL, fail);
+         EMIT_TS(svga, i, curr->magfilter, MAGFILTER, fail);
+         EMIT_TS(svga, i, curr->minfilter, MINFILTER, fail);
+         EMIT_TS(svga, i, curr->aniso_level, TEXTURE_ANISOTROPIC_LEVEL, fail);
+         EMIT_TS_FLOAT(svga, i, curr->lod_bias, TEXTURE_LOD_BIAS, fail);
+         EMIT_TS(svga, i, curr->addressu, ADDRESSU, fail);
+         EMIT_TS(svga, i, curr->addressw, ADDRESSW, fail);
+         EMIT_TS(svga, i, curr->bordercolor, BORDERCOLOR, fail);
+         // TEXCOORDINDEX -- hopefully not needed
+
+         if (svga->curr.tex_flags.flag_1d & (1 << i)) {
+            debug_printf("wrap 1d tex %d\n", i);
+            EMIT_TS(svga, i, SVGA3D_TEX_ADDRESS_WRAP, ADDRESSV, fail);
+         }
+         else
+            EMIT_TS(svga, i, curr->addressv, ADDRESSV, fail);
+
+         if (svga->curr.tex_flags.flag_srgb & (1 << i))
+            EMIT_TS_FLOAT(svga, i, 2.2f, GAMMA, fail);
+         else
+            EMIT_TS_FLOAT(svga, i, 1.0f, GAMMA, fail);
+
+      }
+   }
+ 
+   if (queue.ts_count) {
+      SVGA3dTextureState *ts;
+
+      if (SVGA3D_BeginSetTextureState( svga->swc,
+                                       &ts,
+                                       queue.ts_count ) != PIPE_OK)
+         goto fail;
+
+      memcpy( ts,
+              queue.ts,
+              queue.ts_count * sizeof queue.ts[0]);
+      
+      SVGA_FIFOCommitAll( svga->swc );
+   }
+
+   return 0;
+
+fail:
+   /* XXX: need to poison cached hardware state on failure to ensure
+    * dirty state gets re-emitted.  Fix this by re-instating partial
+    * FIFOCommit command and only updating cached hw state once the
+    * initial allocation has succeeded.
+    */
+   memset(svga->state.hw_draw.ts, 0xcd, sizeof(svga->state.hw_draw.ts));
+
+   return PIPE_ERROR_OUT_OF_MEMORY;
+}
+
+
+struct svga_tracked_state svga_hw_tss = {
+   "texture state emit",
+   (SVGA_NEW_SAMPLER |
+    SVGA_NEW_TEXTURE_FLAGS),
+   update_tss
+};
+
diff --git a/src/gallium/drivers/svga/svga_state_vdecl.c b/src/gallium/drivers/svga/svga_state_vdecl.c
new file mode 100644
index 0000000..c534308
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_state_vdecl.c
@@ -0,0 +1,182 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_inlines.h"
+#include "pipe/p_defines.h"
+#include "util/u_math.h"
+#include "util/u_upload_mgr.h"
+
+#include "svga_context.h"
+#include "svga_state.h"
+#include "svga_draw.h"
+#include "svga_tgsi.h"
+#include "svga_screen.h"
+#include "svga_screen_buffer.h"
+
+#include "svga_hw_reg.h"
+
+
+static int
+upload_user_buffers( struct svga_context *svga )
+{
+   enum pipe_error ret = PIPE_OK;
+   int i;
+   int nr;
+
+   if (0) 
+      debug_printf("%s: %d\n", __FUNCTION__, svga->curr.num_vertex_buffers);
+
+   nr = svga->curr.num_vertex_buffers;
+
+   for (i = 0; i < nr; i++) 
+   {
+      if (svga_buffer_is_user_buffer(svga->curr.vb[i].buffer))
+      {
+         struct pipe_buffer *upload_buffer = NULL;
+         unsigned offset = /*svga->curr.vb[i].buffer_offset*/ 0;
+         unsigned size = svga->curr.vb[i].buffer->size /*- offset*/;
+         unsigned upload_offset;
+
+         ret = u_upload_buffer( svga->upload_vb,
+                                offset,
+                                size,
+                                svga->curr.vb[i].buffer,
+                                &upload_offset,
+                                &upload_buffer );
+         if (ret)
+            return ret;
+
+         if (0)
+            debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n", 
+                         __FUNCTION__, 
+                         i,
+                         svga->curr.vb[i].buffer,
+                         upload_buffer, upload_offset, size);
+
+         /* Make sure we release the old buffer and end up with the
+          * correct refcount on the uploaded buffer.
+          */
+         pipe_buffer_reference( &svga->curr.vb[i].buffer, NULL );
+         svga->curr.vb[i].buffer = upload_buffer;
+         svga->curr.vb[i].buffer_offset = upload_offset;
+      }
+   }
+
+   if (0)
+      debug_printf("%s: DONE\n", __FUNCTION__);
+
+   return ret;
+}
+
+
+/***********************************************************************
+ */
+
+
+static int emit_hw_vs_vdecl( struct svga_context *svga,
+                             unsigned dirty )
+{
+   const struct pipe_vertex_element *ve = svga->curr.ve;
+   SVGA3dVertexDecl decl;
+   unsigned i;
+
+   assert(svga->curr.num_vertex_elements >=
+          svga->curr.vs->base.info.file_count[TGSI_FILE_INPUT]);
+
+   svga_hwtnl_reset_vdecl( svga->hwtnl, 
+                           svga->curr.num_vertex_elements );
+
+   for (i = 0; i < svga->curr.num_vertex_elements; i++) {
+      const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index];
+      unsigned usage, index;
+
+
+      svga_generate_vdecl_semantics( i, &usage, &index );
+
+      /* SVGA_NEW_VELEMENT
+       */
+      decl.identity.type = svga->state.sw.ve_format[i];
+      decl.identity.method = SVGA3D_DECLMETHOD_DEFAULT;
+      decl.identity.usage = usage;
+      decl.identity.usageIndex = index;
+      decl.array.stride = vb->stride;
+      decl.array.offset = (vb->buffer_offset +
+                           ve[i].src_offset);
+
+      svga_hwtnl_vdecl( svga->hwtnl,
+                        i,
+                        &decl,
+                        vb->buffer );
+   }
+
+   return 0;
+}
+
+
+static int emit_hw_vdecl( struct svga_context *svga,
+                          unsigned dirty )
+{
+   int ret = 0;
+
+   /* SVGA_NEW_NEED_SWTNL
+    */
+   if (svga->state.sw.need_swtnl)
+      return 0; /* Do not emit during swtnl */
+
+   /* If we get to here, we know that we're going to draw.  Upload
+    * userbuffers now and try to combine multiple userbuffers from
+    * multiple draw calls into a single host buffer for performance.
+    */
+   if (svga->curr.any_user_vertex_buffers &&
+       SVGA_COMBINE_USERBUFFERS)
+   {
+      ret = upload_user_buffers( svga );
+      if (ret)
+         return ret;
+
+      svga->curr.any_user_vertex_buffers = FALSE;
+   }
+
+   return emit_hw_vs_vdecl( svga, dirty );
+}
+
+
+struct svga_tracked_state svga_hw_vdecl = 
+{
+   "hw vertex decl state (hwtnl version)",
+   ( SVGA_NEW_NEED_SWTNL |
+     SVGA_NEW_VELEMENT |
+     SVGA_NEW_VBUFFER |
+     SVGA_NEW_RAST |
+     SVGA_NEW_FS |
+     SVGA_NEW_VS ),
+   emit_hw_vdecl
+};
+
+
+
+
+
+
diff --git a/src/gallium/drivers/svga/svga_state_vs.c b/src/gallium/drivers/svga/svga_state_vs.c
new file mode 100644
index 0000000..ae1e77e
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_state_vs.c
@@ -0,0 +1,246 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_inlines.h"
+#include "pipe/p_defines.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_bitmask.h"
+#include "translate/translate.h"
+
+#include "svga_context.h"
+#include "svga_state.h"
+#include "svga_cmd.h"
+#include "svga_tgsi.h"
+
+#include "svga_hw_reg.h"
+
+/***********************************************************************
+ */
+
+
+static INLINE int compare_vs_keys( const struct svga_vs_compile_key *a,
+                                   const struct svga_vs_compile_key *b )
+{
+   unsigned keysize = svga_vs_key_size( a );
+   return memcmp( a, b, keysize );
+}
+
+
+static struct svga_shader_result *search_vs_key( struct svga_vertex_shader *vs,
+                                                 const struct svga_vs_compile_key *key )
+{
+   struct svga_shader_result *result = vs->base.results;
+
+   assert(key);
+
+   for ( ; result; result = result->next) {
+      if (compare_vs_keys( key, &result->key.vkey ) == 0)
+         return result;
+   }
+   
+   return NULL;
+}
+
+
+static enum pipe_error compile_vs( struct svga_context *svga,
+                                   struct svga_vertex_shader *vs,
+                                   const struct svga_vs_compile_key *key,
+                                   struct svga_shader_result **out_result )
+{
+   struct svga_shader_result *result;
+   enum pipe_error ret = PIPE_OK;
+
+   result = svga_translate_vertex_program( vs, key );
+   if (result == NULL) {
+      ret = PIPE_ERROR_OUT_OF_MEMORY;
+      goto fail;
+   }
+
+   result->id = util_bitmask_add(svga->vs_bm);
+   if(result->id == UTIL_BITMASK_INVALID_INDEX)
+      goto fail;
+
+   ret = SVGA3D_DefineShader(svga->swc, 
+                             result->id,
+                             SVGA3D_SHADERTYPE_VS,
+                             result->tokens, 
+                             result->nr_tokens * sizeof result->tokens[0]);
+   if (ret)
+      goto fail;
+
+   *out_result = result;
+   result->next = vs->base.results;
+   vs->base.results = result;
+   return PIPE_OK;
+
+fail:
+   if (result) {
+      if (result->id != UTIL_BITMASK_INVALID_INDEX)
+         util_bitmask_clear( svga->vs_bm, result->id );
+      svga_destroy_shader_result( result );
+   }
+   return ret;
+}
+
+/* SVGA_NEW_PRESCALE, SVGA_NEW_RAST, SVGA_NEW_ZERO_STRIDE
+ */
+static int make_vs_key( struct svga_context *svga,
+                        struct svga_vs_compile_key *key )
+{
+   memset(key, 0, sizeof *key);
+   key->need_prescale = svga->state.hw_clear.prescale.enabled;
+   key->allow_psiz = svga->curr.rast->templ.point_size_per_vertex;
+   key->zero_stride_vertex_elements =
+      svga->curr.zero_stride_vertex_elements;
+   key->num_zero_stride_vertex_elements =
+      svga->curr.num_zero_stride_vertex_elements;
+   return 0;
+}
+
+
+
+static int emit_hw_vs( struct svga_context *svga,
+                       unsigned dirty )
+{
+   struct svga_shader_result *result = NULL;
+   unsigned id = SVGA3D_INVALID_ID;
+   int ret = 0;
+
+   /* SVGA_NEW_NEED_SWTNL */
+   if (!svga->state.sw.need_swtnl) {
+      struct svga_vertex_shader *vs = svga->curr.vs;
+      struct svga_vs_compile_key key;
+
+      ret = make_vs_key( svga, &key );
+      if (ret)
+         return ret;
+
+      result = search_vs_key( vs, &key );
+      if (!result) {
+         ret = compile_vs( svga, vs, &key, &result );
+         if (ret)
+            return ret;
+      }
+
+      assert (result);
+      id = result->id;
+   }
+
+   if (result != svga->state.hw_draw.vs) {
+      ret = SVGA3D_SetShader(svga->swc,
+                             SVGA3D_SHADERTYPE_VS,
+                             id );
+      if (ret)
+         return ret;
+
+      svga->dirty |= SVGA_NEW_VS_RESULT;
+      svga->state.hw_draw.vs = result;      
+   }
+
+   return 0;
+}
+
+struct svga_tracked_state svga_hw_vs = 
+{
+   "vertex shader (hwtnl)",
+   (SVGA_NEW_VS |
+    SVGA_NEW_PRESCALE |
+    SVGA_NEW_NEED_SWTNL |
+    SVGA_NEW_ZERO_STRIDE),
+   emit_hw_vs
+};
+
+
+/***********************************************************************
+ */
+static int update_zero_stride( struct svga_context *svga,
+                               unsigned dirty )
+{
+   unsigned i;
+
+   svga->curr.zero_stride_vertex_elements = 0;
+   svga->curr.num_zero_stride_vertex_elements = 0;
+
+   for (i = 0; i < svga->curr.num_vertex_elements; i++) {
+      const struct pipe_vertex_element *vel = &svga->curr.ve[i];
+      const struct pipe_vertex_buffer *vbuffer = &svga->curr.vb[
+         vel->vertex_buffer_index];
+      if (vbuffer->stride == 0) {
+         unsigned const_idx =
+            svga->curr.num_zero_stride_vertex_elements;
+         struct translate *translate;
+         struct translate_key key;
+         void *mapped_buffer;
+
+         svga->curr.zero_stride_vertex_elements |= (1 << i);
+         ++svga->curr.num_zero_stride_vertex_elements;
+
+         key.output_stride = 4 * sizeof(float);
+         key.nr_elements = 1;
+         key.element[0].input_format = vel->src_format;
+         key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+         key.element[0].input_buffer = vel->vertex_buffer_index;
+         key.element[0].input_offset = vel->src_offset;
+         key.element[0].output_offset = const_idx * 4 * sizeof(float);
+
+         translate_key_sanitize(&key);
+         /* translate_generic_create is technically private but
+          * we don't want to code-generate, just want generic
+          * translation */
+         translate = translate_generic_create(&key);
+
+         assert(vel->src_offset == 0);
+         
+         mapped_buffer = pipe_buffer_map_range(svga->pipe.screen, 
+                                               vbuffer->buffer,
+                                               vel->src_offset,
+                                               util_format_get_blocksize(vel->src_format),
+                                               PIPE_BUFFER_USAGE_CPU_READ);
+         translate->set_buffer(translate, vel->vertex_buffer_index,
+                               mapped_buffer,
+                               vbuffer->stride);
+         translate->run(translate, 0, 1,
+                        svga->curr.zero_stride_constants);
+
+         pipe_buffer_unmap(svga->pipe.screen,
+                           vbuffer->buffer);
+         translate->release(translate);
+      }
+   }
+
+   if (svga->curr.num_zero_stride_vertex_elements)
+      svga->dirty |= SVGA_NEW_ZERO_STRIDE;
+
+   return 0;
+}
+
+struct svga_tracked_state svga_hw_update_zero_stride =
+{
+   "update zero_stride",
+   ( SVGA_NEW_VELEMENT |
+     SVGA_NEW_VBUFFER ),
+   update_zero_stride
+};
diff --git a/src/gallium/drivers/svga/svga_swtnl.h b/src/gallium/drivers/svga/svga_swtnl.h
new file mode 100644
index 0000000..4882f26
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_swtnl.h
@@ -0,0 +1,52 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_SWTNL_H
+#define SVGA_SWTNL_H
+
+#include "pipe/p_compiler.h"
+
+struct svga_context;
+struct pipe_context;
+struct pipe_buffer;
+struct vbuf_render;
+
+
+boolean svga_init_swtnl( struct svga_context *svga );
+void svga_destroy_swtnl( struct svga_context *svga );
+
+
+enum pipe_error
+svga_swtnl_draw_range_elements(struct svga_context *svga,
+                               struct pipe_buffer *indexBuffer,
+                               unsigned indexSize,
+                               unsigned min_index,
+                               unsigned max_index,
+                               unsigned prim, 
+                               unsigned start, 
+                               unsigned count);
+
+
+#endif
diff --git a/src/gallium/drivers/svga/svga_swtnl_backend.c b/src/gallium/drivers/svga/svga_swtnl_backend.c
new file mode 100644
index 0000000..b4f757a
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_swtnl_backend.c
@@ -0,0 +1,349 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "draw/draw_vbuf.h"
+#include "draw/draw_context.h"
+#include "draw/draw_vertex.h"
+
+#include "util/u_debug.h"
+#include "pipe/p_inlines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "util/u_simple_shaders.h"
+
+#include "svga_context.h"
+#include "svga_state.h"
+#include "svga_swtnl.h"
+
+#include "svga_types.h"
+#include "svga_reg.h"
+#include "svga3d_reg.h"
+#include "svga_draw.h"
+#include "svga_swtnl_private.h"
+
+
+static const struct vertex_info *
+svga_vbuf_render_get_vertex_info( struct vbuf_render *render )
+{
+   struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
+   struct svga_context *svga = svga_render->svga;
+
+   svga_swtnl_update_vdecl(svga);
+
+   return &svga_render->vertex_info;
+}
+
+
+static boolean
+svga_vbuf_render_allocate_vertices( struct vbuf_render *render,
+                                    ushort vertex_size,
+                                    ushort nr_vertices )
+{
+   struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
+   struct svga_context *svga = svga_render->svga;
+   struct pipe_screen *screen = svga->pipe.screen;
+   size_t size = (size_t)nr_vertices * (size_t)vertex_size;
+   boolean new_vbuf = FALSE;
+   boolean new_ibuf = FALSE;
+
+   if (svga_render->vertex_size != vertex_size)
+      svga->swtnl.new_vdecl = TRUE;
+   svga_render->vertex_size = (size_t)vertex_size;
+
+   if (svga->swtnl.new_vbuf)
+      new_ibuf = new_vbuf = TRUE;
+   svga->swtnl.new_vbuf = FALSE;
+
+   if (svga_render->vbuf_size < svga_render->vbuf_offset + svga_render->vbuf_used + size)
+      new_vbuf = TRUE;
+
+   if (new_vbuf)
+      pipe_buffer_reference(&svga_render->vbuf, NULL);
+   if (new_ibuf)
+      pipe_buffer_reference(&svga_render->ibuf, NULL);
+
+   if (!svga_render->vbuf) {
+      svga_render->vbuf_size = MAX2(size, svga_render->vbuf_alloc_size);
+      svga_render->vbuf = pipe_buffer_create(screen,
+                                             0,
+                                             PIPE_BUFFER_USAGE_VERTEX,
+                                             svga_render->vbuf_size);
+      if(!svga_render->vbuf) {
+         svga_context_flush(svga, NULL);
+         svga_render->vbuf = pipe_buffer_create(screen,
+                                                0,
+                                                PIPE_BUFFER_USAGE_VERTEX,
+                                                svga_render->vbuf_size);
+         assert(svga_render->vbuf);
+      }
+
+      svga->swtnl.new_vdecl = TRUE;
+      svga_render->vbuf_offset = 0;
+   } else {
+      svga_render->vbuf_offset += svga_render->vbuf_used;
+   }
+
+   svga_render->vbuf_used = 0;
+
+   if (svga->swtnl.new_vdecl)
+      svga_render->vdecl_offset = svga_render->vbuf_offset;
+
+   return TRUE;
+}
+
+static void *
+svga_vbuf_render_map_vertices( struct vbuf_render *render )
+{
+   struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
+   struct svga_context *svga = svga_render->svga;
+   struct pipe_screen *screen = svga->pipe.screen;
+
+   char *ptr = (char*)pipe_buffer_map(screen,
+                                      svga_render->vbuf,
+                                      PIPE_BUFFER_USAGE_CPU_WRITE | 
+                                      PIPE_BUFFER_USAGE_FLUSH_EXPLICIT);
+   return ptr + svga_render->vbuf_offset;
+}
+
+static void
+svga_vbuf_render_unmap_vertices( struct vbuf_render *render,
+                                 ushort min_index,
+                                 ushort max_index )
+{
+   struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
+   struct svga_context *svga = svga_render->svga;
+   struct pipe_screen *screen = svga->pipe.screen;
+   unsigned offset, length;
+   size_t used = svga_render->vertex_size * ((size_t)max_index + 1);
+
+   offset = svga_render->vbuf_offset + svga_render->vertex_size * min_index;
+   length = svga_render->vertex_size * (max_index + 1 - min_index);
+   pipe_buffer_flush_mapped_range(screen, svga_render->vbuf, offset, length);
+   pipe_buffer_unmap(screen, svga_render->vbuf);
+   svga_render->min_index = min_index;
+   svga_render->max_index = max_index;
+   svga_render->vbuf_used = MAX2(svga_render->vbuf_used, used);
+}
+
+static boolean
+svga_vbuf_render_set_primitive( struct vbuf_render *render,
+                                unsigned prim )
+{
+   struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
+   svga_render->prim = prim;
+
+   return TRUE;
+}
+
+static void
+svga_vbuf_sumbit_state( struct svga_vbuf_render *svga_render )
+{
+   struct svga_context *svga = svga_render->svga;
+   SVGA3dVertexDecl vdecl[PIPE_MAX_ATTRIBS];
+   enum pipe_error ret;
+   int i;
+
+   /* if the vdecl or vbuf hasn't changed do nothing */
+   if (!svga->swtnl.new_vdecl)
+      return;
+
+   memcpy(vdecl, svga_render->vdecl, sizeof(vdecl));
+
+   /* flush the hw state */
+   ret = svga_hwtnl_flush(svga->hwtnl);
+   if (ret) {
+      svga_context_flush(svga, NULL);
+      ret = svga_hwtnl_flush(svga->hwtnl);
+      /* if we hit this path we might become synced with hw */
+      svga->swtnl.new_vbuf = TRUE;
+      assert(ret == 0);
+   }
+
+   svga_hwtnl_reset_vdecl(svga->hwtnl, svga_render->vdecl_count);
+
+   for (i = 0; i < svga_render->vdecl_count; i++) {
+      vdecl[i].array.offset += svga_render->vdecl_offset;
+
+      svga_hwtnl_vdecl( svga->hwtnl,
+                        i,
+                        &vdecl[i],
+                        svga_render->vbuf );
+   }
+
+   /* We have already taken care of flatshading, so let the hwtnl
+    * module use whatever is most convenient:
+    */
+   if (svga->state.sw.need_pipeline) {
+      svga_hwtnl_set_flatshade(svga->hwtnl, FALSE, FALSE);
+      svga_hwtnl_set_unfilled(svga->hwtnl, PIPE_POLYGON_MODE_FILL);
+   }
+   else {
+      svga_hwtnl_set_flatshade( svga->hwtnl,
+                                svga->curr.rast->templ.flatshade,
+                                svga->curr.rast->templ.flatshade_first );
+
+      svga_hwtnl_set_unfilled( svga->hwtnl,
+                               svga->curr.rast->hw_unfilled );
+   }
+
+   svga->swtnl.new_vdecl = FALSE;
+}
+
+static void
+svga_vbuf_render_draw_arrays( struct vbuf_render *render,
+                              unsigned start,
+                              uint nr )
+{
+   struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
+   struct svga_context *svga = svga_render->svga;
+   unsigned bias = (svga_render->vbuf_offset - svga_render->vdecl_offset) / svga_render->vertex_size;
+   enum pipe_error ret = 0;
+
+   svga_vbuf_sumbit_state(svga_render);
+
+   /* Need to call update_state() again as the draw module may have
+    * altered some of our state behind our backs.  Testcase:
+    * redbook/polys.c
+    */
+   svga_update_state_retry( svga, SVGA_STATE_HW_DRAW );
+
+   ret = svga_hwtnl_draw_arrays(svga->hwtnl, svga_render->prim, start + bias, nr);
+   if (ret != PIPE_OK) {
+      svga_context_flush(svga, NULL);
+      ret = svga_hwtnl_draw_arrays(svga->hwtnl, svga_render->prim, start + bias, nr);
+      svga->swtnl.new_vbuf = TRUE;
+      assert(ret == PIPE_OK);
+   }
+}
+
+
+static void
+svga_vbuf_render_draw( struct vbuf_render *render,
+                       const ushort *indices,
+                       uint nr_indices)
+{
+   struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
+   struct svga_context *svga = svga_render->svga;
+   struct pipe_screen *screen = svga->pipe.screen;
+   unsigned bias = (svga_render->vbuf_offset - svga_render->vdecl_offset) / svga_render->vertex_size;
+   boolean ret;
+   size_t size = 2 * nr_indices;
+
+   assert(( svga_render->vbuf_offset - svga_render->vdecl_offset) % svga_render->vertex_size == 0);
+   
+   if (svga_render->ibuf_size < svga_render->ibuf_offset + size)
+      pipe_buffer_reference(&svga_render->ibuf, NULL);
+
+   if (!svga_render->ibuf) {
+      svga_render->ibuf_size = MAX2(size, svga_render->ibuf_alloc_size);
+      svga_render->ibuf = pipe_buffer_create(screen,
+                                             0,
+                                             PIPE_BUFFER_USAGE_VERTEX,
+                                             svga_render->ibuf_size);
+      svga_render->ibuf_offset = 0;
+   }
+
+   pipe_buffer_write(screen, svga_render->ibuf,
+                     svga_render->ibuf_offset, 2 * nr_indices, indices);
+
+
+   /* off to hardware */
+   svga_vbuf_sumbit_state(svga_render);
+
+   /* Need to call update_state() again as the draw module may have
+    * altered some of our state behind our backs.  Testcase:
+    * redbook/polys.c
+    */
+   svga_update_state_retry( svga, SVGA_STATE_HW_DRAW );
+
+   ret = svga_hwtnl_draw_range_elements(svga->hwtnl,
+                                        svga_render->ibuf,
+                                        2,
+                                        svga_render->min_index,
+                                        svga_render->max_index,
+                                        svga_render->prim,
+                                        svga_render->ibuf_offset / 2, nr_indices, bias);
+   if(ret != PIPE_OK) {
+      svga_context_flush(svga, NULL);
+      ret = svga_hwtnl_draw_range_elements(svga->hwtnl,
+                                           svga_render->ibuf,
+                                           2,
+                                           svga_render->min_index,
+                                           svga_render->max_index,
+                                           svga_render->prim,
+                                           svga_render->ibuf_offset / 2, nr_indices, bias);
+      svga->swtnl.new_vbuf = TRUE;
+      assert(ret == PIPE_OK);
+   }
+
+   svga_render->ibuf_offset += size;
+}
+
+
+static void
+svga_vbuf_render_release_vertices( struct vbuf_render *render )
+{
+
+}
+
+
+static void
+svga_vbuf_render_destroy( struct vbuf_render *render )
+{
+   struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
+
+   pipe_buffer_reference(&svga_render->vbuf, NULL);
+   pipe_buffer_reference(&svga_render->ibuf, NULL);
+   FREE(svga_render);
+}
+
+
+/**
+ * Create a new primitive render.
+ */
+struct vbuf_render *
+svga_vbuf_render_create( struct svga_context *svga )
+{
+   struct svga_vbuf_render *svga_render = CALLOC_STRUCT(svga_vbuf_render);
+
+   svga_render->svga = svga;
+   svga_render->ibuf_size = 0;
+   svga_render->vbuf_size = 0;
+   svga_render->ibuf_alloc_size = 4*1024;
+   svga_render->vbuf_alloc_size = 64*1024;
+   svga_render->base.max_vertex_buffer_bytes = 64*1024/10;
+   svga_render->base.max_indices = 65536;
+   svga_render->base.get_vertex_info = svga_vbuf_render_get_vertex_info;
+   svga_render->base.allocate_vertices = svga_vbuf_render_allocate_vertices;
+   svga_render->base.map_vertices = svga_vbuf_render_map_vertices;
+   svga_render->base.unmap_vertices = svga_vbuf_render_unmap_vertices;
+   svga_render->base.set_primitive = svga_vbuf_render_set_primitive;
+   svga_render->base.draw = svga_vbuf_render_draw;
+   svga_render->base.draw_arrays = svga_vbuf_render_draw_arrays;
+   svga_render->base.release_vertices = svga_vbuf_render_release_vertices;
+   svga_render->base.destroy = svga_vbuf_render_destroy;
+
+   return &svga_render->base;
+}
diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c
new file mode 100644
index 0000000..7655121
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_swtnl_draw.c
@@ -0,0 +1,170 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "draw/draw_context.h"
+#include "draw/draw_vbuf.h"
+#include "pipe/p_inlines.h"
+#include "pipe/p_state.h"
+#include "util/u_memory.h"
+
+#include "svga_context.h"
+#include "svga_swtnl.h"
+#include "svga_state.h"
+#include "svga_swtnl_private.h"
+
+
+
+enum pipe_error
+svga_swtnl_draw_range_elements(struct svga_context *svga,
+                               struct pipe_buffer *indexBuffer,
+                               unsigned indexSize,
+                               unsigned min_index,
+                               unsigned max_index,
+                               unsigned prim, unsigned start, unsigned count)
+{
+   struct draw_context *draw = svga->swtnl.draw;
+   unsigned i;
+   const void *map;
+   enum pipe_error ret;
+
+   assert(!svga->dirty);
+   assert(svga->state.sw.need_swtnl);
+   assert(draw);
+
+   ret = svga_update_state(svga, SVGA_STATE_SWTNL_DRAW);
+   if (ret) {
+      svga_context_flush(svga, NULL);
+      ret = svga_update_state(svga, SVGA_STATE_SWTNL_DRAW);
+      svga->swtnl.new_vbuf = TRUE;
+      assert(ret == PIPE_OK);
+   }
+
+   /*
+    * Map vertex buffers
+    */
+   for (i = 0; i < svga->curr.num_vertex_buffers; i++) {
+      map = pipe_buffer_map(svga->pipe.screen,
+                            svga->curr.vb[i].buffer,
+                            PIPE_BUFFER_USAGE_CPU_READ);
+
+      draw_set_mapped_vertex_buffer(draw, i, map);
+   }
+
+   /* Map index buffer, if present */
+   if (indexBuffer) {
+      map = pipe_buffer_map(svga->pipe.screen, indexBuffer,
+                            PIPE_BUFFER_USAGE_CPU_READ);
+
+      draw_set_mapped_element_buffer_range(draw, 
+                                           indexSize, 
+                                           min_index,
+                                           max_index,
+                                           map);
+   }
+   
+   if (svga->curr.cb[PIPE_SHADER_VERTEX]) {
+      map = pipe_buffer_map(svga->pipe.screen,
+                            svga->curr.cb[PIPE_SHADER_VERTEX],
+                            PIPE_BUFFER_USAGE_CPU_READ);
+      assert(map);
+      draw_set_mapped_constant_buffer(
+         draw, PIPE_SHADER_VERTEX,
+         map,
+         svga->curr.cb[PIPE_SHADER_VERTEX]->size);
+   }
+
+   draw_arrays(svga->swtnl.draw, prim, start, count);
+
+   draw_flush(svga->swtnl.draw);
+
+   /* Ensure the draw module didn't touch this */
+   assert(i == svga->curr.num_vertex_buffers);
+   
+   /*
+    * unmap vertex/index buffers
+    */
+   for (i = 0; i < svga->curr.num_vertex_buffers; i++) {
+      pipe_buffer_unmap(svga->pipe.screen, svga->curr.vb[i].buffer);
+      draw_set_mapped_vertex_buffer(draw, i, NULL);
+   }
+
+   if (indexBuffer) {
+      pipe_buffer_unmap(svga->pipe.screen, indexBuffer);
+      draw_set_mapped_element_buffer(draw, 0, NULL);
+   }
+
+   if (svga->curr.cb[PIPE_SHADER_VERTEX]) {
+      pipe_buffer_unmap(svga->pipe.screen,
+                        svga->curr.cb[PIPE_SHADER_VERTEX]);
+   }
+
+   return ret;
+}
+
+
+
+
+boolean svga_init_swtnl( struct svga_context *svga )
+{
+   svga->swtnl.backend = svga_vbuf_render_create(svga);
+   if(!svga->swtnl.backend)
+      goto fail;
+
+   /*
+    * Create drawing context and plug our rendering stage into it.
+    */
+   svga->swtnl.draw = draw_create();
+   if (svga->swtnl.draw == NULL)
+      goto fail;
+
+
+   draw_set_rasterize_stage(svga->swtnl.draw, 
+                            draw_vbuf_stage( svga->swtnl.draw, svga->swtnl.backend ));
+
+   draw_set_render(svga->swtnl.draw, svga->swtnl.backend);
+
+   draw_install_aaline_stage(svga->swtnl.draw, &svga->pipe);
+   draw_install_aapoint_stage(svga->swtnl.draw, &svga->pipe);
+   draw_install_pstipple_stage(svga->swtnl.draw, &svga->pipe);
+
+   draw_set_driver_clipping(svga->swtnl.draw, debug_get_bool_option("SVGA_SWTNL_FSE", FALSE));
+
+   return TRUE;
+
+fail:
+   if (svga->swtnl.backend)
+      svga->swtnl.backend->destroy( svga->swtnl.backend );
+
+   if (svga->swtnl.draw)
+      draw_destroy( svga->swtnl.draw );
+
+   return FALSE;
+}
+
+
+void svga_destroy_swtnl( struct svga_context *svga )
+{
+   draw_destroy( svga->swtnl.draw );
+}
diff --git a/src/gallium/drivers/svga/svga_swtnl_private.h b/src/gallium/drivers/svga/svga_swtnl_private.h
new file mode 100644
index 0000000..9bbb429
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_swtnl_private.h
@@ -0,0 +1,93 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_SWTNL_PRIVATE_H
+#define SVGA_SWTNL_PRIVATE_H
+
+#include "svga_swtnl.h"
+#include "draw/draw_vertex.h"
+
+#include "svga_types.h"
+#include "svga3d_reg.h"
+
+/**
+ * Primitive renderer for svga.
+ */
+struct svga_vbuf_render {
+   struct vbuf_render base;
+
+   struct svga_context *svga;
+   struct vertex_info vertex_info;
+
+   unsigned vertex_size;
+
+   unsigned prim;
+
+   struct pipe_buffer *vbuf;
+   struct pipe_buffer *ibuf;
+
+   /* current size of buffer */
+   size_t vbuf_size;
+   size_t ibuf_size;
+
+   /* size of that the buffer should be */
+   size_t vbuf_alloc_size;
+   size_t ibuf_alloc_size;
+
+   /* current write place */
+   size_t vbuf_offset;
+   size_t ibuf_offset;
+
+   /* currently used */
+   size_t vbuf_used;
+
+   SVGA3dVertexDecl vdecl[PIPE_MAX_ATTRIBS];
+   unsigned vdecl_offset;
+   unsigned vdecl_count;
+
+   ushort min_index;
+   ushort max_index;
+};
+
+/**
+ * Basically a cast wrapper.
+ */
+static INLINE struct svga_vbuf_render *
+svga_vbuf_render( struct vbuf_render *render )
+{
+   assert(render);
+   return (struct svga_vbuf_render *)render;
+}
+
+
+struct vbuf_render *
+svga_vbuf_render_create( struct svga_context *svga );
+
+
+int
+svga_swtnl_update_vdecl( struct svga_context *svga );
+
+
+#endif
diff --git a/src/gallium/drivers/svga/svga_swtnl_state.c b/src/gallium/drivers/svga/svga_swtnl_state.c
new file mode 100644
index 0000000..94b6ccc
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_swtnl_state.c
@@ -0,0 +1,237 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "draw/draw_context.h"
+#include "draw/draw_vbuf.h"
+#include "pipe/p_inlines.h"
+#include "pipe/p_state.h"
+#include "util/u_memory.h"
+
+#include "svga_context.h"
+#include "svga_swtnl.h"
+#include "svga_state.h"
+
+#include "svga_swtnl_private.h"
+
+
+#define SVGA_POINT_ADJ_X -0.375
+#define SVGA_POINT_ADJ_Y -0.5
+
+#define SVGA_LINE_ADJ_X -0.5
+#define SVGA_LINE_ADJ_Y -0.5
+
+#define SVGA_TRIANGLE_ADJ_X -0.375
+#define SVGA_TRIANGLE_ADJ_Y -0.5
+
+
+static void set_draw_viewport( struct svga_context *svga )
+{
+   struct pipe_viewport_state vp = svga->curr.viewport;
+   float adjx = 0;
+   float adjy = 0;
+
+   switch (svga->curr.reduced_prim) {
+   case PIPE_PRIM_POINTS:
+      adjx = SVGA_POINT_ADJ_X;
+      adjy = SVGA_POINT_ADJ_Y;
+      break;
+   case PIPE_PRIM_LINES:
+      /* XXX: This is to compensate for the fact that wide lines are
+       * going to be drawn with triangles, but we're not catching all
+       * cases where that will happen.
+       */
+      if (svga->curr.rast->templ.line_width > 1.0) 
+      {
+         adjx = SVGA_LINE_ADJ_X + 0.175;
+         adjy = SVGA_LINE_ADJ_Y - 0.175;
+      }
+      else {
+         adjx = SVGA_LINE_ADJ_X;
+         adjy = SVGA_LINE_ADJ_Y;
+      }
+      break;
+   case PIPE_PRIM_TRIANGLES:
+      adjx += SVGA_TRIANGLE_ADJ_X;
+      adjy += SVGA_TRIANGLE_ADJ_Y;
+      break;
+   }
+
+   vp.translate[0] += adjx;
+   vp.translate[1] += adjy;
+
+   draw_set_viewport_state(svga->swtnl.draw, &vp);
+}
+
+static int update_swtnl_draw( struct svga_context *svga,
+                              unsigned dirty )
+{
+   draw_flush( svga->swtnl.draw );
+
+   if (dirty & SVGA_NEW_VS) 
+      draw_bind_vertex_shader(svga->swtnl.draw,
+                              svga->curr.vs->draw_shader);
+
+   if (dirty & SVGA_NEW_VBUFFER)
+      draw_set_vertex_buffers(svga->swtnl.draw, 
+                              svga->curr.num_vertex_buffers, 
+                              svga->curr.vb);
+
+   if (dirty & SVGA_NEW_VELEMENT)
+      draw_set_vertex_elements(svga->swtnl.draw, 
+                               svga->curr.num_vertex_elements, 
+                               svga->curr.ve );
+
+   if (dirty & SVGA_NEW_CLIP)
+      draw_set_clip_state(svga->swtnl.draw, 
+                          &svga->curr.clip);
+
+   if (dirty & (SVGA_NEW_VIEWPORT |
+                SVGA_NEW_REDUCED_PRIMITIVE | 
+                SVGA_NEW_RAST))
+      set_draw_viewport( svga );
+
+   if (dirty & SVGA_NEW_RAST)
+      draw_set_rasterizer_state(svga->swtnl.draw,
+                                &svga->curr.rast->templ);
+
+   if (dirty & SVGA_NEW_FRAME_BUFFER)
+      draw_set_mrd(svga->swtnl.draw, 
+                   svga->curr.depthscale);
+
+   return 0;
+}
+
+
+struct svga_tracked_state svga_update_swtnl_draw =
+{
+   "update draw module state",
+   (SVGA_NEW_VS |
+    SVGA_NEW_VBUFFER |
+    SVGA_NEW_VELEMENT |
+    SVGA_NEW_CLIP |
+    SVGA_NEW_VIEWPORT |
+    SVGA_NEW_RAST |
+    SVGA_NEW_FRAME_BUFFER |
+    SVGA_NEW_REDUCED_PRIMITIVE),
+   update_swtnl_draw
+};
+
+
+int svga_swtnl_update_vdecl( struct svga_context *svga )
+{
+   struct svga_vbuf_render *svga_render = svga_vbuf_render(svga->swtnl.backend);
+   struct draw_context *draw = svga->swtnl.draw;
+   struct vertex_info *vinfo = &svga_render->vertex_info;
+   SVGA3dVertexDecl vdecl[PIPE_MAX_ATTRIBS];
+   const enum interp_mode colorInterp =
+      svga->curr.rast->templ.flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
+   const struct svga_fragment_shader *fs = svga->curr.fs;
+   int offset = 0;
+   int nr_decls = 0;
+   int src, i;
+
+   memset(vinfo, 0, sizeof(*vinfo));
+   memset(vdecl, 0, sizeof(vdecl));
+
+   /* always add position */
+   src = draw_find_shader_output(draw, TGSI_SEMANTIC_POSITION, 0);
+   draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR, src);
+   vinfo->attrib[0].emit = EMIT_4F;
+   vdecl[0].array.offset = offset;
+   vdecl[0].identity.type = SVGA3D_DECLTYPE_FLOAT4;
+   vdecl[0].identity.usage = SVGA3D_DECLUSAGE_POSITIONT;
+   vdecl[0].identity.usageIndex = 0;
+   offset += 16;
+   nr_decls++;
+
+   for (i = 0; i < fs->base.info.num_inputs; i++) {
+      unsigned name = fs->base.info.input_semantic_name[i];
+      unsigned index = fs->base.info.input_semantic_index[i];
+      src = draw_find_shader_output(draw, name, index);
+      vdecl[nr_decls].array.offset = offset;
+      vdecl[nr_decls].identity.usageIndex = fs->base.info.input_semantic_index[i];
+
+      switch (name) {
+      case TGSI_SEMANTIC_COLOR:
+         draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
+         vdecl[nr_decls].identity.usage = SVGA3D_DECLUSAGE_COLOR;
+         vdecl[nr_decls].identity.type = SVGA3D_DECLTYPE_FLOAT4;
+         offset += 16;
+         nr_decls++;
+         break;
+      case TGSI_SEMANTIC_GENERIC:
+         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
+         vdecl[nr_decls].identity.usage = SVGA3D_DECLUSAGE_TEXCOORD;
+         vdecl[nr_decls].identity.type = SVGA3D_DECLTYPE_FLOAT4;
+         vdecl[nr_decls].identity.usageIndex += 1;
+         offset += 16;
+         nr_decls++;
+         break;
+      case TGSI_SEMANTIC_FOG:
+         draw_emit_vertex_attr(vinfo, EMIT_1F, INTERP_PERSPECTIVE, src);
+         vdecl[nr_decls].identity.usage = SVGA3D_DECLUSAGE_TEXCOORD;
+         vdecl[nr_decls].identity.type = SVGA3D_DECLTYPE_FLOAT1;
+         assert(vdecl[nr_decls].identity.usageIndex == 0);
+         offset += 4;
+         nr_decls++;
+         break;
+      case TGSI_SEMANTIC_POSITION:
+         /* generated internally, not a vertex shader output */
+         break;
+      default:
+         assert(0);
+      }
+   }
+
+   draw_compute_vertex_size(vinfo);
+
+   svga_render->vdecl_count = nr_decls;
+   for (i = 0; i < svga_render->vdecl_count; i++)
+      vdecl[i].array.stride = offset;
+
+   if (memcmp(svga_render->vdecl, vdecl, sizeof(vdecl)) == 0)
+      return 0;
+
+   memcpy(svga_render->vdecl, vdecl, sizeof(vdecl));
+   svga->swtnl.new_vdecl = TRUE;
+
+   return 0;
+}
+
+
+static int update_swtnl_vdecl( struct svga_context *svga,
+                               unsigned dirty )
+{
+   return svga_swtnl_update_vdecl( svga );
+}
+
+
+struct svga_tracked_state svga_update_swtnl_vdecl =
+{
+   "update draw module vdecl",
+   (SVGA_NEW_VS |
+    SVGA_NEW_FS),
+   update_swtnl_vdecl
+};
diff --git a/src/gallium/drivers/svga/svga_tgsi.c b/src/gallium/drivers/svga/svga_tgsi.c
new file mode 100644
index 0000000..0cd6201
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_tgsi.c
@@ -0,0 +1,282 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "pipe/p_shader_tokens.h"
+#include "pipe/p_defines.h"
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_scan.h"
+#include "util/u_memory.h"
+#include "util/u_bitmask.h"
+
+#include "svgadump/svga_shader_dump.h"
+
+#include "svga_context.h"
+#include "svga_tgsi.h"
+#include "svga_tgsi_emit.h"
+#include "svga_debug.h"
+
+#include "svga_hw_reg.h"
+#include "svga3d_shaderdefs.h"
+
+
+/* Sinkhole used only in error conditions.
+ */
+static char err_buf[128];
+
+#if 0
+static void svga_destroy_shader_emitter( struct svga_shader_emitter *emit )
+{
+   if (emit->buf != err_buf)
+      FREE(emit->buf);
+}
+#endif
+
+
+static boolean svga_shader_expand( struct svga_shader_emitter *emit )
+{
+   char *new_buf;
+   unsigned newsize = emit->size * 2;
+
+   if(emit->buf != err_buf)
+      new_buf = REALLOC(emit->buf, emit->size, newsize);
+   else
+      new_buf = NULL;
+
+   if (new_buf == NULL) {
+      emit->ptr = err_buf;
+      emit->buf = err_buf;
+      emit->size = sizeof(err_buf);
+      return FALSE;
+   }
+
+   emit->size = newsize;
+   emit->ptr = new_buf + (emit->ptr - emit->buf);
+   emit->buf = new_buf;
+   return TRUE;
+}   
+
+static INLINE boolean reserve(  struct svga_shader_emitter *emit,
+                                unsigned nr_dwords )
+{
+   if (emit->ptr - emit->buf + nr_dwords * sizeof(unsigned) >= emit->size) {
+      if (!svga_shader_expand( emit ))
+         return FALSE;
+   }
+
+   return TRUE;
+}
+
+boolean svga_shader_emit_dword( struct svga_shader_emitter *emit,
+                                unsigned dword )
+{
+   if (!reserve(emit, 1))
+      return FALSE;
+
+   *(unsigned *)emit->ptr = dword;
+   emit->ptr += sizeof dword;
+   return TRUE;
+}
+
+boolean svga_shader_emit_dwords( struct svga_shader_emitter *emit,
+                                 const unsigned *dwords,
+                                 unsigned nr )
+{
+   if (!reserve(emit, nr))
+      return FALSE;
+
+   memcpy( emit->ptr, dwords, nr * sizeof *dwords );
+   emit->ptr += nr * sizeof *dwords;
+   return TRUE;
+}
+
+boolean svga_shader_emit_opcode( struct svga_shader_emitter *emit,
+                                 unsigned opcode )
+{
+   SVGA3dShaderInstToken *here;
+
+   if (!reserve(emit, 1))
+      return FALSE;
+
+   here = (SVGA3dShaderInstToken *)emit->ptr;
+   here->value = opcode;
+
+   if (emit->insn_offset) {
+      SVGA3dShaderInstToken *prev = (SVGA3dShaderInstToken *)(emit->buf + 
+                                                              emit->insn_offset);
+      prev->size = (here - prev) - 1;
+   }
+   
+   emit->insn_offset = emit->ptr - emit->buf;
+   emit->ptr += sizeof(unsigned);
+   return TRUE;
+}
+
+#define SVGA3D_PS_2X (SVGA3D_PS_20 | 1)
+#define SVGA3D_VS_2X (SVGA3D_VS_20 | 1)
+
+static boolean svga_shader_emit_header( struct svga_shader_emitter *emit )
+{
+   SVGA3dShaderVersion header;
+
+   memset( &header, 0, sizeof header );
+
+   switch (emit->unit) {
+   case PIPE_SHADER_FRAGMENT:
+      header.value = emit->use_sm30 ? SVGA3D_PS_30 : SVGA3D_PS_2X;
+      break;
+   case PIPE_SHADER_VERTEX:
+      header.value = emit->use_sm30 ? SVGA3D_VS_30 : SVGA3D_VS_2X;
+      break;
+   }
+ 
+   return svga_shader_emit_dword( emit, header.value );
+}
+
+
+
+
+
+/* Parse TGSI shader and translate to SVGA/DX9 serialized
+ * representation.  
+ *
+ * In this function SVGA shader is emitted to an in-memory buffer that
+ * can be dynamically grown.  Once we've finished and know how large
+ * it is, it will be copied to a hardware buffer for upload.
+ */
+static struct svga_shader_result *
+svga_tgsi_translate( const struct svga_shader *shader,
+                     union svga_compile_key key,
+                     unsigned unit )
+{
+   struct svga_shader_result *result = NULL;
+   struct svga_shader_emitter emit;
+   int ret = 0;
+
+   memset(&emit, 0, sizeof(emit));
+
+   emit.use_sm30 = shader->use_sm30;
+   emit.size = 1024;
+   emit.buf = MALLOC(emit.size);
+   if (emit.buf == NULL) {
+      ret = PIPE_ERROR_OUT_OF_MEMORY;
+      goto fail;
+   }
+
+   emit.ptr = emit.buf;
+   emit.unit = unit;
+   emit.key = key;
+
+   tgsi_scan_shader( shader->tokens, &emit.info);
+
+   emit.imm_start = emit.info.file_max[TGSI_FILE_CONSTANT] + 1;
+   
+   if (unit == PIPE_SHADER_FRAGMENT)
+      emit.imm_start += key.fkey.num_unnormalized_coords;
+
+   if (unit == PIPE_SHADER_VERTEX) {
+      emit.imm_start += key.vkey.need_prescale ? 2 : 0;
+      emit.imm_start += key.vkey.num_zero_stride_vertex_elements;
+   }
+
+   emit.nr_hw_const = (emit.imm_start + emit.info.file_max[TGSI_FILE_IMMEDIATE] + 1);
+
+   emit.nr_hw_temp = emit.info.file_max[TGSI_FILE_TEMPORARY] + 1;
+   emit.in_main_func = TRUE;
+
+   if (!svga_shader_emit_header( &emit ))
+      goto fail;
+
+   if (!svga_shader_emit_instructions( &emit, shader->tokens ))
+      goto fail;
+   
+   result = CALLOC_STRUCT(svga_shader_result);
+   if (result == NULL)
+      goto fail;
+
+   result->shader = shader;
+   result->tokens = (const unsigned *)emit.buf;
+   result->nr_tokens = (emit.ptr - emit.buf) / sizeof(unsigned);
+   memcpy(&result->key, &key, sizeof key);
+   result->id = UTIL_BITMASK_INVALID_INDEX;
+
+   if (SVGA_DEBUG & DEBUG_TGSI) 
+   {
+      debug_printf( "#####################################\n" );
+      debug_printf( "Shader %u below\n", shader->id );
+      tgsi_dump( shader->tokens, 0 );
+      if (SVGA_DEBUG & DEBUG_TGSI) {
+         debug_printf( "Shader %u compiled below\n", shader->id );
+         svga_shader_dump( result->tokens,
+                           result->nr_tokens ,
+                           FALSE );
+      }
+      debug_printf( "#####################################\n" );
+   }
+
+   return result;
+
+fail:
+   FREE(result);
+   FREE(emit.buf);
+   return NULL;
+}
+
+
+
+
+struct svga_shader_result *
+svga_translate_fragment_program( const struct svga_fragment_shader *fs,
+                                 const struct svga_fs_compile_key *fkey )
+{
+   union svga_compile_key key;
+   memcpy(&key.fkey, fkey, sizeof *fkey);
+
+   return svga_tgsi_translate( &fs->base, 
+                               key,
+                               PIPE_SHADER_FRAGMENT );
+}
+
+struct svga_shader_result *
+svga_translate_vertex_program( const struct svga_vertex_shader *vs,
+                               const struct svga_vs_compile_key *vkey )
+{
+   union svga_compile_key key;
+   memcpy(&key.vkey, vkey, sizeof *vkey);
+
+   return svga_tgsi_translate( &vs->base, 
+                               key,
+                               PIPE_SHADER_VERTEX );
+}
+
+
+void svga_destroy_shader_result( struct svga_shader_result *result )
+{
+   FREE((unsigned *)result->tokens);
+   FREE(result);
+}
+
diff --git a/src/gallium/drivers/svga/svga_tgsi.h b/src/gallium/drivers/svga/svga_tgsi.h
new file mode 100644
index 0000000..737a221
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_tgsi.h
@@ -0,0 +1,136 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_TGSI_H
+#define SVGA_TGSI_H
+
+#include "pipe/p_state.h"
+
+#include "svga_hw_reg.h"
+
+struct svga_fragment_shader;
+struct svga_vertex_shader;
+struct svga_shader;
+struct tgsi_shader_info;
+struct tgsi_token;
+
+
+struct svga_vs_compile_key
+{
+   unsigned zero_stride_vertex_elements;
+   unsigned need_prescale:1;
+   unsigned allow_psiz:1;
+   unsigned num_zero_stride_vertex_elements:6;
+};
+
+struct svga_fs_compile_key
+{
+   unsigned light_twoside:1;
+   unsigned front_cw:1;
+   unsigned num_textures:8;
+   unsigned num_unnormalized_coords:8;
+   struct {
+      unsigned compare_mode:1;
+      unsigned compare_func:3;
+      unsigned unnormalized:1;
+      unsigned width_height_idx:7;
+      unsigned texture_target:8;
+   } tex[PIPE_MAX_SAMPLERS];
+};
+
+union svga_compile_key {
+   struct svga_vs_compile_key vkey;
+   struct svga_fs_compile_key fkey;
+};
+
+struct svga_shader_result
+{
+   const struct svga_shader *shader;
+
+   /* Parameters used to generate this compilation result:
+    */
+   union svga_compile_key key;
+
+   /* Compiled shader tokens:
+    */
+   const unsigned *tokens;
+   unsigned nr_tokens;
+
+   /* SVGA Shader ID:
+    */
+   unsigned id;
+   
+   /* Next compilation result:
+    */
+   struct svga_shader_result *next;
+};
+
+
+/* TGSI doesn't provide use with VS input semantics (they're actually
+ * pretty meaningless), so we just generate some plausible ones here.
+ * This is called both from within the TGSI translator and when
+ * building vdecls to ensure they match up.
+ *
+ * The real use of this information is matching vertex elements to
+ * fragment shader inputs in the case where vertex shader is disabled.
+ */
+static INLINE void svga_generate_vdecl_semantics( unsigned idx,
+                                                  unsigned *usage,
+                                                  unsigned *usage_index )
+{
+   if (idx == 0) {
+      *usage = SVGA3D_DECLUSAGE_POSITION;
+      *usage_index = 0;
+   }
+   else {
+      *usage = SVGA3D_DECLUSAGE_TEXCOORD;
+      *usage_index = idx - 1;
+   }
+}
+
+
+
+static INLINE unsigned svga_vs_key_size( const struct svga_vs_compile_key *key )
+{
+   return sizeof *key;
+}
+
+static INLINE unsigned svga_fs_key_size( const struct svga_fs_compile_key *key )
+{
+   return (const char *)&key->tex[key->num_textures] - (const char *)key;
+}
+
+struct svga_shader_result *
+svga_translate_fragment_program( const struct svga_fragment_shader *fs,
+                                 const struct svga_fs_compile_key *fkey );
+
+struct svga_shader_result *
+svga_translate_vertex_program( const struct svga_vertex_shader *fs,
+                               const struct svga_vs_compile_key *vkey );
+
+
+void svga_destroy_shader_result( struct svga_shader_result *result );
+
+#endif
diff --git a/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c b/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c
new file mode 100644
index 0000000..23b3ace
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c
@@ -0,0 +1,280 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_shader_tokens.h"
+#include "tgsi/tgsi_parse.h"
+#include "util/u_memory.h"
+
+#include "svga_tgsi_emit.h"
+#include "svga_context.h"
+
+
+
+
+static boolean ps20_input( struct svga_shader_emitter *emit,
+                           struct tgsi_declaration_semantic semantic,
+                           unsigned idx )
+{
+   struct src_register reg;
+   SVGA3DOpDclArgs dcl;
+   SVGA3dShaderInstToken opcode;
+
+   opcode = inst_token( SVGA3DOP_DCL );
+   dcl.values[0] = 0;
+   dcl.values[1] = 0;
+
+   switch (semantic.Name) {
+   case TGSI_SEMANTIC_POSITION:
+      /* Special case:
+       */
+      reg = src_register( SVGA3DREG_MISCTYPE, 
+                          SVGA3DMISCREG_POSITION );
+      break;
+   case TGSI_SEMANTIC_COLOR:
+      reg = src_register( SVGA3DREG_INPUT, 
+                          semantic.Index );
+      break;
+   case TGSI_SEMANTIC_FOG:
+      assert(semantic.Index == 0);
+      reg = src_register( SVGA3DREG_TEXTURE, 0 );
+      break;
+   case TGSI_SEMANTIC_GENERIC:
+      reg = src_register( SVGA3DREG_TEXTURE,
+                          semantic.Index + 1 );
+      break;
+   default:
+      assert(0);
+      return TRUE;
+   }
+
+   emit->input_map[idx] = reg;
+
+   dcl.dst = dst( reg );
+
+   dcl.usage = 0;
+   dcl.index = 0;
+
+   dcl.values[0] |= 1<<31;
+
+   return  (emit_instruction(emit, opcode) &&
+            svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
+}
+
+
+static boolean ps20_output( struct svga_shader_emitter *emit,
+                            struct tgsi_declaration_semantic semantic,
+                            unsigned idx )
+{
+   SVGA3dShaderDestToken reg;
+
+   switch (semantic.Name) {
+   case TGSI_SEMANTIC_COLOR:
+      if (semantic.Index < PIPE_MAX_COLOR_BUFS) {
+         unsigned cbuf = semantic.Index;
+
+         emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
+                                               emit->nr_hw_temp++ );
+         emit->temp_col[cbuf] = emit->output_map[idx];
+         emit->true_col[cbuf] = dst_register( SVGA3DREG_COLOROUT, 
+                                              semantic.Index );
+      }
+      else {
+         assert(0);
+         reg = dst_register( SVGA3DREG_COLOROUT, 0 );
+      }
+      break;
+   case TGSI_SEMANTIC_POSITION:
+      emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
+                                            emit->nr_hw_temp++ );
+      emit->temp_pos = emit->output_map[idx];
+      emit->true_pos = dst_register( SVGA3DREG_DEPTHOUT, 
+                                     semantic.Index );
+      break;
+   default:
+      assert(0);
+      reg = dst_register( SVGA3DREG_COLOROUT, 0 );
+      break;
+   }
+
+   return TRUE;
+}
+
+
+static boolean vs20_input( struct svga_shader_emitter *emit,
+                           struct tgsi_declaration_semantic semantic,
+                           unsigned idx )
+{
+   SVGA3DOpDclArgs dcl;
+   SVGA3dShaderInstToken opcode;
+
+   opcode = inst_token( SVGA3DOP_DCL );
+   dcl.values[0] = 0;
+   dcl.values[1] = 0;
+
+   emit->input_map[idx] = src_register( SVGA3DREG_INPUT, idx );
+   dcl.dst = dst_register( SVGA3DREG_INPUT, idx );
+
+   assert(dcl.dst.reserved0);
+
+   /* Mesa doesn't provide use with VS input semantics (they're
+    * actually pretty meaningless), so we just generate some plausible
+    * ones here.  This has to match what we declare in the vdecl code
+    * in svga_pipe_vertex.c.
+    */
+   if (idx == 0) {
+      dcl.usage = SVGA3D_DECLUSAGE_POSITION;
+      dcl.index = 0;
+   }
+   else {
+      dcl.usage = SVGA3D_DECLUSAGE_TEXCOORD;
+      dcl.index = idx - 1;
+   }
+
+   dcl.values[0] |= 1<<31;
+
+   return  (emit_instruction(emit, opcode) &&
+            svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
+}
+
+
+static boolean vs20_output( struct svga_shader_emitter *emit,
+                         struct tgsi_declaration_semantic semantic,
+                         unsigned idx )
+{
+   /* Don't emit dcl instruction for vs20 inputs
+    */
+
+   /* Just build the register map table: 
+    */
+   switch (semantic.Name) {
+   case TGSI_SEMANTIC_POSITION:
+      assert(semantic.Index == 0);
+      emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
+                                            emit->nr_hw_temp++ );
+      emit->temp_pos = emit->output_map[idx];
+      emit->true_pos = dst_register( SVGA3DREG_RASTOUT, 
+                                     SVGA3DRASTOUT_POSITION);
+      break;
+   case TGSI_SEMANTIC_PSIZE:
+      assert(semantic.Index == 0);
+      emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
+                                            emit->nr_hw_temp++ );
+      emit->temp_psiz = emit->output_map[idx];
+      emit->true_psiz = dst_register( SVGA3DREG_RASTOUT, 
+                                      SVGA3DRASTOUT_PSIZE );
+      break;
+   case TGSI_SEMANTIC_FOG:
+      assert(semantic.Index == 0);
+      emit->output_map[idx] = dst_register( SVGA3DREG_TEXCRDOUT, 0 );
+      break;
+   case TGSI_SEMANTIC_COLOR:
+      /* oD0 */
+      emit->output_map[idx] = dst_register( SVGA3DREG_ATTROUT,
+                                            semantic.Index );
+      break;
+   case TGSI_SEMANTIC_GENERIC:
+      emit->output_map[idx] = dst_register( SVGA3DREG_TEXCRDOUT,
+                                            semantic.Index + 1 );
+      break;
+   default:
+      assert(0);
+      emit->output_map[idx] = dst_register(  SVGA3DREG_TEMP, 0 );
+      return FALSE;
+   }
+
+   return TRUE;
+}
+
+static boolean ps20_sampler( struct svga_shader_emitter *emit,
+                          struct tgsi_declaration_semantic semantic,
+                          unsigned idx )
+{
+   SVGA3DOpDclArgs dcl;
+   SVGA3dShaderInstToken opcode;
+
+   opcode = inst_token( SVGA3DOP_DCL );
+   dcl.values[0] = 0;
+   dcl.values[1] = 0;
+
+   dcl.dst = dst_register( SVGA3DREG_SAMPLER, idx );
+   dcl.type = svga_tgsi_sampler_type( emit, idx );
+
+   return  (emit_instruction(emit, opcode) &&
+            svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
+}
+
+
+boolean svga_translate_decl_sm20( struct svga_shader_emitter *emit,
+                             const struct tgsi_full_declaration *decl )
+{
+   unsigned first = decl->Range.First;
+   unsigned last = decl->Range.Last;
+   unsigned semantic = 0;
+   unsigned semantic_idx = 0;
+   unsigned idx;
+   
+   if (decl->Declaration.Semantic) {
+      semantic = decl->Semantic.Name;
+      semantic_idx = decl->Semantic.Index;
+   }
+
+   for( idx = first; idx <= last; idx++ ) {
+      boolean ok;
+
+      switch (decl->Declaration.File) {
+      case TGSI_FILE_SAMPLER:
+         assert (emit->unit == PIPE_SHADER_FRAGMENT);
+         ok = ps20_sampler( emit, decl->Semantic, idx );
+         break;
+
+      case TGSI_FILE_INPUT:
+         if (emit->unit == PIPE_SHADER_VERTEX)
+            ok = vs20_input( emit, decl->Semantic, idx );
+         else
+            ok = ps20_input( emit, decl->Semantic, idx );
+         break;
+
+      case TGSI_FILE_OUTPUT:
+         if (emit->unit == PIPE_SHADER_VERTEX)
+            ok = vs20_output( emit, decl->Semantic, idx );
+         else
+            ok = ps20_output( emit, decl->Semantic, idx );
+         break;
+
+      default:
+         /* don't need to declare other vars */
+         ok = TRUE;
+      }
+
+      if (!ok)
+         return FALSE;
+   }
+
+   return TRUE;
+}
+
+
+
diff --git a/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c b/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c
new file mode 100644
index 0000000..d1c7336
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c
@@ -0,0 +1,385 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_shader_tokens.h"
+#include "tgsi/tgsi_parse.h"
+#include "util/u_memory.h"
+
+#include "svga_tgsi_emit.h"
+#include "svga_context.h"
+
+static boolean translate_vs_ps_semantic( struct tgsi_declaration_semantic semantic,
+                                         unsigned *usage,
+                                         unsigned *idx )
+{
+   switch (semantic.Name) {
+   case TGSI_SEMANTIC_POSITION:  
+      *idx = semantic.Index;
+      *usage = SVGA3D_DECLUSAGE_POSITION;
+      break;
+   case TGSI_SEMANTIC_COLOR:     
+
+      *idx = semantic.Index;
+      *usage = SVGA3D_DECLUSAGE_COLOR;
+      break;
+   case TGSI_SEMANTIC_BCOLOR:
+      *idx = semantic.Index + 2; /* sharing with COLOR */
+      *usage = SVGA3D_DECLUSAGE_COLOR;
+      break;
+   case TGSI_SEMANTIC_FOG:       
+      *idx = 0;
+      assert(semantic.Index == 0);
+      *usage = SVGA3D_DECLUSAGE_TEXCOORD;
+      break;
+   case TGSI_SEMANTIC_PSIZE:     
+      *idx = semantic.Index;
+      *usage = SVGA3D_DECLUSAGE_PSIZE;
+      break;
+   case TGSI_SEMANTIC_GENERIC:   
+      *idx = semantic.Index + 1; /* texcoord[0] is reserved for fog */
+      *usage = SVGA3D_DECLUSAGE_TEXCOORD;
+      break;
+   case TGSI_SEMANTIC_NORMAL:    
+      *idx = semantic.Index;
+      *usage = SVGA3D_DECLUSAGE_NORMAL;
+      break;
+   default:
+      assert(0);
+      *usage = SVGA3D_DECLUSAGE_TEXCOORD;
+      *idx = 0;
+      return FALSE;
+   }
+
+   return TRUE;
+}
+
+
+static boolean emit_decl( struct svga_shader_emitter *emit,
+                          SVGA3dShaderDestToken reg,
+                          unsigned usage, 
+                          unsigned index )
+{
+   SVGA3DOpDclArgs dcl;
+   SVGA3dShaderInstToken opcode;
+
+   opcode = inst_token( SVGA3DOP_DCL );
+   dcl.values[0] = 0;
+   dcl.values[1] = 0;
+
+   dcl.dst = reg;
+   dcl.usage = usage;
+   dcl.index = index;
+   dcl.values[0] |= 1<<31;
+
+   return  (emit_instruction(emit, opcode) &&
+            svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
+}
+
+static boolean emit_vface_decl( struct svga_shader_emitter *emit )
+{
+   if (!emit->emitted_vface) {
+      SVGA3dShaderDestToken reg =
+         dst_register( SVGA3DREG_MISCTYPE,
+                       SVGA3DMISCREG_FACE );
+
+      if (!emit_decl( emit, reg, 0, 0 ))
+         return FALSE;
+
+      emit->emitted_vface = TRUE;
+   }
+   return TRUE;
+}
+
+static boolean ps30_input( struct svga_shader_emitter *emit,
+                           struct tgsi_declaration_semantic semantic,
+                           unsigned idx )
+{
+   unsigned usage, index;
+   SVGA3dShaderDestToken reg;
+
+   if (semantic.Name == TGSI_SEMANTIC_POSITION) {
+      emit->input_map[idx] = src_register( SVGA3DREG_MISCTYPE,
+                                           SVGA3DMISCREG_POSITION );
+
+      emit->input_map[idx].base.swizzle = TRANSLATE_SWIZZLE( TGSI_SWIZZLE_X,
+                                                             TGSI_SWIZZLE_Y,
+                                                             TGSI_SWIZZLE_Y,
+                                                             TGSI_SWIZZLE_Y );
+
+      reg = writemask( dst(emit->input_map[idx]),
+                       TGSI_WRITEMASK_XY );
+
+      return emit_decl( emit, reg, 0, 0 );
+   }
+   else if (emit->key.fkey.light_twoside &&
+            (semantic.Name == TGSI_SEMANTIC_COLOR)) {
+
+      if (!translate_vs_ps_semantic( semantic, &usage, &index ))
+         return FALSE;
+
+      emit->internal_color_idx[emit->internal_color_count] = idx;
+      emit->input_map[idx] = src_register( SVGA3DREG_INPUT, emit->ps30_input_count );
+      emit->ps30_input_count++;
+      emit->internal_color_count++;
+
+      reg = dst( emit->input_map[idx] );
+
+      if (!emit_decl( emit, reg, usage, index ))
+         return FALSE;
+
+      semantic.Name = TGSI_SEMANTIC_BCOLOR;
+      if (!translate_vs_ps_semantic( semantic, &usage, &index ))
+         return FALSE;
+
+      reg = dst_register( SVGA3DREG_INPUT, emit->ps30_input_count++ );
+
+      if (!emit_decl( emit, reg, usage, index ))
+         return FALSE;
+
+      if (!emit_vface_decl( emit ))
+         return FALSE;
+
+      return TRUE;
+   }
+   else if (semantic.Name == TGSI_SEMANTIC_FACE) {
+      if (!emit_vface_decl( emit ))
+         return FALSE;
+      emit->emit_frontface = TRUE;
+      emit->internal_frontface_idx = idx;
+      return TRUE;
+   }
+   else {
+
+      if (!translate_vs_ps_semantic( semantic, &usage, &index ))
+         return FALSE;
+
+      emit->input_map[idx] = src_register( SVGA3DREG_INPUT, emit->ps30_input_count++ );
+      reg = dst( emit->input_map[idx] );
+
+      return emit_decl( emit, reg, usage, index );
+   }
+
+}
+
+
+/* PS output registers are the same as 2.0
+ */
+static boolean ps30_output( struct svga_shader_emitter *emit,
+                            struct tgsi_declaration_semantic semantic,
+                            unsigned idx )
+{
+   SVGA3dShaderDestToken reg;
+
+   switch (semantic.Name) {
+   case TGSI_SEMANTIC_COLOR:
+      emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT, 
+                                            semantic.Index );
+      break;
+   case TGSI_SEMANTIC_POSITION:
+      emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
+                                            emit->nr_hw_temp++ );
+      emit->temp_pos = emit->output_map[idx];
+      emit->true_pos = dst_register( SVGA3DREG_DEPTHOUT, 
+                                     semantic.Index );
+      break;
+   default:
+      assert(0);
+      reg = dst_register( SVGA3DREG_COLOROUT, 0 );
+      break;
+   }
+
+   return TRUE;
+}
+
+
+/* We still make up the input semantics the same as in 2.0
+ */
+static boolean vs30_input( struct svga_shader_emitter *emit,
+                           struct tgsi_declaration_semantic semantic,
+                           unsigned idx )
+{
+   SVGA3DOpDclArgs dcl;
+   SVGA3dShaderInstToken opcode;
+   unsigned usage, index;
+
+   opcode = inst_token( SVGA3DOP_DCL );
+   dcl.values[0] = 0;
+   dcl.values[1] = 0;
+
+   if (emit->key.vkey.zero_stride_vertex_elements & (1 << idx)) {
+      unsigned i;
+      unsigned offset = 0;
+      unsigned start_idx = emit->info.file_max[TGSI_FILE_CONSTANT] + 1;
+      /* adjust for prescale constants */
+      start_idx += emit->key.vkey.need_prescale ? 2 : 0;
+      /* compute the offset from the start of zero stride constants */
+      for (i = 0; i < PIPE_MAX_ATTRIBS && i < idx; ++i) {
+         if (emit->key.vkey.zero_stride_vertex_elements & (1<<i))
+            ++offset;
+      }
+      emit->input_map[idx] = src_register( SVGA3DREG_CONST,
+                                           start_idx + offset );
+   } else {
+      emit->input_map[idx] = src_register( SVGA3DREG_INPUT, idx );
+      dcl.dst = dst_register( SVGA3DREG_INPUT, idx );
+
+      assert(dcl.dst.reserved0);
+
+      svga_generate_vdecl_semantics( idx, &usage, &index );
+
+      dcl.usage = usage;
+      dcl.index = index;
+      dcl.values[0] |= 1<<31;
+
+      return  (emit_instruction(emit, opcode) &&
+               svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
+   }
+   return TRUE;
+}
+
+/* VS3.0 outputs have proper declarations and semantic info for
+ * matching against PS inputs.
+ */
+static boolean vs30_output( struct svga_shader_emitter *emit,
+                         struct tgsi_declaration_semantic semantic,
+                         unsigned idx )
+{
+   SVGA3DOpDclArgs dcl;
+   SVGA3dShaderInstToken opcode;
+   unsigned usage, index;
+
+   opcode = inst_token( SVGA3DOP_DCL );
+   dcl.values[0] = 0;
+   dcl.values[1] = 0;
+
+   if (!translate_vs_ps_semantic( semantic, &usage, &index ))
+      return FALSE;
+
+   dcl.dst = dst_register( SVGA3DREG_OUTPUT, idx );
+   dcl.usage = usage;
+   dcl.index = index;
+   dcl.values[0] |= 1<<31;
+
+   if (semantic.Name == TGSI_SEMANTIC_POSITION) {
+      assert(idx == 0);
+      emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
+                                            emit->nr_hw_temp++ );
+      emit->temp_pos = emit->output_map[idx];
+      emit->true_pos = dcl.dst;
+   }
+   else if (semantic.Name == TGSI_SEMANTIC_PSIZE) {
+      emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
+                                            emit->nr_hw_temp++ );
+      emit->temp_psiz = emit->output_map[idx];
+
+      /* This has the effect of not declaring psiz (below) and not 
+       * emitting the final MOV to true_psiz in the postamble.
+       */
+      if (!emit->key.vkey.allow_psiz)
+         return TRUE;
+
+      emit->true_psiz = dcl.dst;
+   }
+   else {
+      emit->output_map[idx] = dcl.dst;
+   }
+
+
+   return  (emit_instruction(emit, opcode) &&
+            svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
+}
+
+static boolean ps30_sampler( struct svga_shader_emitter *emit,
+                          struct tgsi_declaration_semantic semantic,
+                          unsigned idx )
+{
+   SVGA3DOpDclArgs dcl;
+   SVGA3dShaderInstToken opcode;
+
+   opcode = inst_token( SVGA3DOP_DCL );
+   dcl.values[0] = 0;
+   dcl.values[1] = 0;
+
+   dcl.dst = dst_register( SVGA3DREG_SAMPLER, idx );
+   dcl.type = svga_tgsi_sampler_type( emit, idx );
+   dcl.values[0] |= 1<<31;
+
+   return  (emit_instruction(emit, opcode) &&
+            svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
+}
+
+
+boolean svga_translate_decl_sm30( struct svga_shader_emitter *emit,
+                             const struct tgsi_full_declaration *decl )
+{
+   unsigned first = decl->Range.First;
+   unsigned last = decl->Range.Last;
+   unsigned semantic = 0;
+   unsigned semantic_idx = 0;
+   unsigned idx;
+
+   if (decl->Declaration.Semantic) {
+      semantic = decl->Semantic.Name;
+      semantic_idx = decl->Semantic.Index;
+   }
+
+   for( idx = first; idx <= last; idx++ ) {
+      boolean ok;
+
+      switch (decl->Declaration.File) {
+      case TGSI_FILE_SAMPLER:
+         assert (emit->unit == PIPE_SHADER_FRAGMENT);
+         ok = ps30_sampler( emit, decl->Semantic, idx );
+         break;
+
+      case TGSI_FILE_INPUT:
+         if (emit->unit == PIPE_SHADER_VERTEX)
+            ok = vs30_input( emit, decl->Semantic, idx );
+         else
+            ok = ps30_input( emit, decl->Semantic, idx );
+         break;
+
+      case TGSI_FILE_OUTPUT:
+         if (emit->unit == PIPE_SHADER_VERTEX)
+            ok = vs30_output( emit, decl->Semantic, idx );
+         else
+            ok = ps30_output( emit, decl->Semantic, idx );
+         break;
+
+      default:
+         /* don't need to declare other vars */
+         ok = TRUE;
+      }
+
+      if (!ok)
+         return FALSE;
+   }
+
+   return TRUE;
+}
+
+
+
diff --git a/src/gallium/drivers/svga/svga_tgsi_emit.h b/src/gallium/drivers/svga/svga_tgsi_emit.h
new file mode 100644
index 0000000..2557824
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_tgsi_emit.h
@@ -0,0 +1,345 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_TGSI_EMIT_H
+#define SVGA_TGSI_EMIT_H
+
+#include "tgsi/tgsi_scan.h"
+#include "svga_hw_reg.h"
+#include "svga_tgsi.h"
+#include "svga3d_shaderdefs.h"
+
+struct src_register
+{
+   SVGA3dShaderSrcToken base;
+   SVGA3dShaderSrcToken indirect;
+};
+
+
+struct svga_arl_consts {
+   int number;
+   int idx;
+   int swizzle;
+   int arl_num;
+};
+
+/* Internal functions:
+ */
+
+struct svga_shader_emitter
+{
+   boolean use_sm30;
+   
+   unsigned size;
+   char *buf;
+   char *ptr;
+
+   union svga_compile_key key;
+   struct tgsi_shader_info info;
+   int unit;
+
+   int imm_start;
+
+   int nr_hw_const;
+   int nr_hw_temp;
+   
+   int insn_offset;
+
+   int internal_temp_count;
+   int internal_imm_count;
+
+   int internal_color_idx[2]; /* diffuse, specular */
+   int internal_color_count;
+
+   boolean emitted_vface;
+   boolean emit_frontface;
+   int internal_frontface_idx;
+
+   int ps30_input_count;
+
+   boolean in_main_func;
+
+   boolean created_zero_immediate;
+   int zero_immediate_idx;
+
+   boolean created_loop_const;
+   int loop_const_idx;
+
+   boolean created_sincos_consts;
+   int sincos_consts_idx;
+
+   unsigned label[32];
+   unsigned nr_labels;
+
+   struct src_register input_map[PIPE_MAX_ATTRIBS];
+   SVGA3dShaderDestToken output_map[PIPE_MAX_ATTRIBS];
+
+   struct src_register imm_0055;
+   SVGA3dShaderDestToken temp_pos;
+   SVGA3dShaderDestToken true_pos;
+
+   SVGA3dShaderDestToken temp_col[PIPE_MAX_COLOR_BUFS];
+   SVGA3dShaderDestToken true_col[PIPE_MAX_COLOR_BUFS];
+
+   SVGA3dShaderDestToken temp_psiz;
+   SVGA3dShaderDestToken true_psiz;
+
+   struct svga_arl_consts arl_consts[12];
+   int num_arl_consts;
+   int current_arl;
+};
+
+
+boolean svga_shader_emit_dword( struct svga_shader_emitter *emit,
+                                unsigned dword );
+
+boolean svga_shader_emit_dwords( struct svga_shader_emitter *emit,
+                                 const unsigned *dwords,
+                                 unsigned nr );
+
+boolean svga_shader_emit_opcode( struct svga_shader_emitter *emit,
+                                 unsigned opcode );
+
+boolean svga_shader_emit_instructions( struct svga_shader_emitter *emit,
+                                       const struct tgsi_token *tokens );
+
+boolean svga_translate_decl_sm20( struct svga_shader_emitter *emit,
+                               const struct tgsi_full_declaration *decl );
+
+boolean svga_translate_decl_sm30( struct svga_shader_emitter *emit,
+                               const struct tgsi_full_declaration *decl );
+
+
+static INLINE boolean emit_dst( struct svga_shader_emitter *emit,
+                         SVGA3dShaderDestToken dest )
+{
+   assert(dest.reserved0);
+   return svga_shader_emit_dword( emit, dest.value );
+}
+
+static INLINE boolean emit_src( struct svga_shader_emitter *emit,
+                         const struct src_register src )
+{
+   if (src.base.relAddr) {
+      assert(src.base.reserved0);
+      assert(src.indirect.reserved0);
+      return (svga_shader_emit_dword( emit, src.base.value ) &&
+              svga_shader_emit_dword( emit, src.indirect.value ));
+   }
+   else {
+      assert(src.base.reserved0);
+      return svga_shader_emit_dword( emit, src.base.value );
+   }
+}
+
+
+static INLINE boolean emit_instruction( struct svga_shader_emitter *emit,
+                                 SVGA3dShaderInstToken opcode )
+{
+   return svga_shader_emit_opcode( emit, opcode.value );
+}
+
+
+static INLINE boolean emit_op1( struct svga_shader_emitter *emit,
+                         SVGA3dShaderInstToken inst,
+                         SVGA3dShaderDestToken dest,
+                         struct src_register src0 )
+{
+   return (emit_instruction( emit, inst ) &&
+           emit_dst( emit, dest ) &&
+           emit_src( emit, src0 ));
+}
+
+static INLINE boolean emit_op2( struct svga_shader_emitter *emit,
+                     SVGA3dShaderInstToken inst,
+                     SVGA3dShaderDestToken dest,
+                     struct src_register src0,
+                     struct src_register src1 )
+{
+   return (emit_instruction( emit, inst ) &&
+           emit_dst( emit, dest ) &&
+           emit_src( emit, src0 ) &&
+           emit_src( emit, src1 ));
+}
+
+static INLINE boolean emit_op3( struct svga_shader_emitter *emit,
+                         SVGA3dShaderInstToken inst,
+                         SVGA3dShaderDestToken dest,
+                         struct src_register src0,
+                         struct src_register src1,
+                         struct src_register src2 )
+{
+   return (emit_instruction( emit, inst ) &&
+           emit_dst( emit, dest ) &&
+           emit_src( emit, src0 ) &&
+           emit_src( emit, src1 ) &&
+           emit_src( emit, src2 ));
+}
+
+
+#define TRANSLATE_SWIZZLE(x,y,z,w)  ((x) | ((y) << 2) | ((z) << 4) | ((w) << 6))
+#define SWIZZLE_XYZW  \
+ TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_W)
+#define SWIZZLE_XXXX  \
+ TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_X,TGSI_SWIZZLE_X,TGSI_SWIZZLE_X)
+#define SWIZZLE_YYYY  \
+ TRANSLATE_SWIZZLE(TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y)
+#define SWIZZLE_ZZZZ  \
+ TRANSLATE_SWIZZLE(TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z)
+#define SWIZZLE_WWWW  \
+ TRANSLATE_SWIZZLE(TGSI_SWIZZLE_W,TGSI_SWIZZLE_W,TGSI_SWIZZLE_W,TGSI_SWIZZLE_W)
+
+
+
+static INLINE SVGA3dShaderInstToken
+inst_token( unsigned opcode )
+{
+   SVGA3dShaderInstToken inst;
+
+   inst.value = 0;
+   inst.op = opcode;
+
+   return inst;
+}
+
+static INLINE SVGA3dShaderDestToken 
+dst_register( unsigned file,
+              int number )
+{
+   SVGA3dShaderDestToken dest;
+
+   dest.value = 0;
+   dest.num = number;
+   dest.type_upper = file >> 3;
+   dest.relAddr = 0;
+   dest.reserved1 = 0;
+   dest.mask = 0xf;
+   dest.dstMod = 0;
+   dest.shfScale = 0;
+   dest.type_lower = file & 0x7;
+   dest.reserved0 = 1;          /* is_reg */
+   
+   return dest;
+}
+
+static INLINE SVGA3dShaderDestToken
+writemask( SVGA3dShaderDestToken dest,
+           unsigned mask )
+{
+   dest.mask &= mask;
+   return dest;
+}
+
+
+static INLINE SVGA3dShaderSrcToken 
+src_token( unsigned file, int number )
+{
+   SVGA3dShaderSrcToken src;
+
+   src.value = 0;
+   src.num = number;
+   src.type_upper = file >> 3;
+   src.relAddr = 0;
+   src.reserved1 = 0;
+   src.swizzle = SWIZZLE_XYZW;
+   src.srcMod = 0;
+   src.type_lower = file & 0x7;
+   src.reserved0 = 1;           /* is_reg */
+
+   return src;
+}
+
+
+static INLINE struct src_register 
+absolute( struct src_register src )
+{
+   src.base.srcMod = SVGA3DSRCMOD_ABS;
+
+   return src;
+}
+
+
+static INLINE struct src_register 
+negate( struct src_register src )
+{
+   switch (src.base.srcMod) {
+   case SVGA3DSRCMOD_ABS:
+      src.base.srcMod = SVGA3DSRCMOD_ABSNEG;
+      break;
+   case SVGA3DSRCMOD_ABSNEG:
+      src.base.srcMod = SVGA3DSRCMOD_ABS;
+      break;
+   case SVGA3DSRCMOD_NEG:
+      src.base.srcMod = SVGA3DSRCMOD_NONE;
+      break;
+   case SVGA3DSRCMOD_NONE:
+      src.base.srcMod = SVGA3DSRCMOD_NEG;
+      break;
+   }
+   return src;
+}
+
+
+static INLINE struct src_register 
+src_register( unsigned file, int number )
+{
+   struct src_register src;
+   
+   src.base = src_token( file, number );
+   src.indirect.value = 0;
+
+   return src;
+}
+
+static INLINE SVGA3dShaderDestToken dst( struct src_register src )
+{
+   return dst_register( SVGA3dShaderGetRegType( src.base.value ),
+                        src.base.num );
+}
+
+static INLINE struct src_register src( SVGA3dShaderDestToken dst )
+{
+   return src_register( SVGA3dShaderGetRegType( dst.value ),
+                        dst.num );
+}
+
+static INLINE ubyte svga_tgsi_sampler_type( struct svga_shader_emitter *emit,
+                                            int idx )
+{
+   switch (emit->key.fkey.tex[idx].texture_target) {
+   case PIPE_TEXTURE_1D:
+      return SVGA3DSAMP_2D;
+   case PIPE_TEXTURE_2D:
+      return SVGA3DSAMP_2D;
+   case PIPE_TEXTURE_3D:
+      return SVGA3DSAMP_VOLUME;
+   case PIPE_TEXTURE_CUBE:
+      return SVGA3DSAMP_CUBE;
+   }
+
+   return SVGA3DSAMP_UNKNOWN;
+}
+
+#endif
diff --git a/src/gallium/drivers/svga/svga_tgsi_insn.c b/src/gallium/drivers/svga/svga_tgsi_insn.c
new file mode 100644
index 0000000..dc5eb8f
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_tgsi_insn.c
@@ -0,0 +1,2716 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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_shader_tokens.h"
+#include "tgsi/tgsi_parse.h"
+#include "util/u_memory.h"
+
+#include "svga_tgsi_emit.h"
+#include "svga_context.h"
+
+
+static boolean emit_vs_postamble( struct svga_shader_emitter *emit );
+static boolean emit_ps_postamble( struct svga_shader_emitter *emit );
+
+
+
+ 
+static unsigned
+translate_opcode(
+   uint opcode )
+{
+   switch (opcode) {
+   case TGSI_OPCODE_ABS:        return SVGA3DOP_ABS;
+   case TGSI_OPCODE_ADD:        return SVGA3DOP_ADD;
+   case TGSI_OPCODE_BREAKC:     return SVGA3DOP_BREAKC;
+   case TGSI_OPCODE_DDX:        return SVGA3DOP_DSX;
+   case TGSI_OPCODE_DDY:        return SVGA3DOP_DSY;
+   case TGSI_OPCODE_DP2A:       return SVGA3DOP_DP2ADD;
+   case TGSI_OPCODE_DP3:        return SVGA3DOP_DP3;
+   case TGSI_OPCODE_DP4:        return SVGA3DOP_DP4;
+   case TGSI_OPCODE_ENDFOR:     return SVGA3DOP_ENDLOOP;
+   case TGSI_OPCODE_FRC:        return SVGA3DOP_FRC;
+   case TGSI_OPCODE_BGNFOR:     return SVGA3DOP_LOOP;
+   case TGSI_OPCODE_MAD:        return SVGA3DOP_MAD;
+   case TGSI_OPCODE_MAX:        return SVGA3DOP_MAX;
+   case TGSI_OPCODE_MIN:        return SVGA3DOP_MIN;
+   case TGSI_OPCODE_MOV:        return SVGA3DOP_MOV;
+   case TGSI_OPCODE_MUL:        return SVGA3DOP_MUL;
+   case TGSI_OPCODE_NOP:        return SVGA3DOP_NOP;
+   case TGSI_OPCODE_NRM4:       return SVGA3DOP_NRM;
+   case TGSI_OPCODE_SSG:        return SVGA3DOP_SGN;
+   default:
+      debug_printf("Unkown opcode %u\n", opcode);
+      assert( 0 );
+      return SVGA3DOP_LAST_INST;
+   }
+}
+
+
+static unsigned translate_file( unsigned file )
+{
+   switch (file) {
+   case TGSI_FILE_TEMPORARY: return SVGA3DREG_TEMP;
+   case TGSI_FILE_INPUT:     return SVGA3DREG_INPUT;
+   case TGSI_FILE_OUTPUT:    return SVGA3DREG_OUTPUT; /* VS3.0+ only */
+   case TGSI_FILE_IMMEDIATE: return SVGA3DREG_CONST;
+   case TGSI_FILE_CONSTANT:  return SVGA3DREG_CONST;
+   case TGSI_FILE_SAMPLER:   return SVGA3DREG_SAMPLER;
+   case TGSI_FILE_ADDRESS:   return SVGA3DREG_ADDR;
+   default:
+      assert( 0 );
+      return SVGA3DREG_TEMP;
+   }
+}
+
+
+
+
+
+
+static SVGA3dShaderDestToken 
+translate_dst_register( struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn,
+                        unsigned idx )
+{
+   const struct tgsi_full_dst_register *reg = &insn->Dst[idx];
+   SVGA3dShaderDestToken dest;
+
+   switch (reg->Register.File) {
+   case TGSI_FILE_OUTPUT:
+      /* Output registers encode semantic information in their name.
+       * Need to lookup a table built at decl time:
+       */
+      dest = emit->output_map[reg->Register.Index];
+      break;
+
+   default:
+      dest = dst_register( translate_file( reg->Register.File ),
+                           reg->Register.Index );
+      break;
+   }
+
+   dest.mask = reg->Register.WriteMask;
+
+   if (insn->Instruction.Saturate) 
+      dest.dstMod = SVGA3DDSTMOD_SATURATE;
+
+   return dest;
+}
+
+
+static struct src_register 
+swizzle( struct src_register src,
+         int x,
+         int y,
+         int z,
+         int w )
+{
+   x = (src.base.swizzle >> (x * 2)) & 0x3;
+   y = (src.base.swizzle >> (y * 2)) & 0x3;
+   z = (src.base.swizzle >> (z * 2)) & 0x3;
+   w = (src.base.swizzle >> (w * 2)) & 0x3;
+
+   src.base.swizzle = TRANSLATE_SWIZZLE(x,y,z,w);
+
+   return src;
+}
+
+static struct src_register
+scalar( struct src_register src,
+        int comp )
+{
+   return swizzle( src, comp, comp, comp, comp );
+}
+
+static INLINE boolean
+svga_arl_needs_adjustment( const struct svga_shader_emitter *emit )
+{
+   int i;
+
+   for (i = 0; i < emit->num_arl_consts; ++i) {
+      if (emit->arl_consts[i].arl_num == emit->current_arl)
+         return TRUE;
+   }
+   return FALSE;
+}
+
+static INLINE int
+svga_arl_adjustment( const struct svga_shader_emitter *emit )
+{
+   int i;
+
+   for (i = 0; i < emit->num_arl_consts; ++i) {
+      if (emit->arl_consts[i].arl_num == emit->current_arl)
+         return emit->arl_consts[i].number;
+   }
+   return 0;
+}
+
+static struct src_register 
+translate_src_register( const struct svga_shader_emitter *emit,
+                        const struct tgsi_full_src_register *reg )
+{
+   struct src_register src;
+
+   switch (reg->Register.File) {
+   case TGSI_FILE_INPUT:
+      /* Input registers are referred to by their semantic name rather
+       * than by index.  Use the mapping build up from the decls:
+       */
+      src = emit->input_map[reg->Register.Index];
+      break;
+       
+   case TGSI_FILE_IMMEDIATE:
+      /* Immediates are appended after TGSI constants in the D3D
+       * constant buffer.
+       */
+      src = src_register( translate_file( reg->Register.File ),
+                          reg->Register.Index + 
+                          emit->imm_start );
+      break;
+
+   default:
+      src = src_register( translate_file( reg->Register.File ),
+                          reg->Register.Index );
+
+      break;
+   }
+
+   /* Indirect addressing (for coninstant buffer lookups only)
+    */
+   if (reg->Register.Indirect)
+   {
+      /* we shift the offset towards the minimum */
+      if (svga_arl_needs_adjustment( emit )) {
+         src.base.num -= svga_arl_adjustment( emit );
+      }
+      src.base.relAddr = 1;
+
+      /* Not really sure what should go in the second token:
+       */
+      src.indirect = src_token( SVGA3DREG_ADDR,
+                                reg->Indirect.Index );
+
+      src.indirect.swizzle = SWIZZLE_XXXX;
+   }
+
+   src = swizzle( src,
+                  reg->Register.SwizzleX,
+                  reg->Register.SwizzleY,
+                  reg->Register.SwizzleZ,
+                  reg->Register.SwizzleW );
+
+   /* src.mod isn't a bitfield, unfortunately:
+    * See tgsi_util_get_full_src_register_sign_mode for implementation details.
+    */
+   if (reg->Register.Absolute) {
+      if (reg->Register.Negate)
+         src.base.srcMod = SVGA3DSRCMOD_ABSNEG;
+      else
+         src.base.srcMod = SVGA3DSRCMOD_ABS;
+   }
+   else {
+      if (reg->Register.Negate)
+         src.base.srcMod = SVGA3DSRCMOD_NEG;
+      else
+         src.base.srcMod = SVGA3DSRCMOD_NONE;
+   }
+
+   return src;
+}
+
+
+/*
+ * Get a temporary register, return -1 if none available
+ */
+static INLINE SVGA3dShaderDestToken 
+get_temp( struct svga_shader_emitter *emit )
+{
+   int i = emit->nr_hw_temp + emit->internal_temp_count++;
+
+   return dst_register( SVGA3DREG_TEMP, i );
+}
+
+/* Release a single temp.  Currently only effective if it was the last
+ * allocated temp, otherwise release will be delayed until the next
+ * call to reset_temp_regs().
+ */
+static INLINE void 
+release_temp( struct svga_shader_emitter *emit,
+              SVGA3dShaderDestToken temp )
+{
+   if (temp.num == emit->internal_temp_count - 1)
+      emit->internal_temp_count--;
+}
+
+static void reset_temp_regs( struct svga_shader_emitter *emit )
+{
+   emit->internal_temp_count = 0;
+}
+   
+
+static boolean submit_op0( struct svga_shader_emitter *emit,
+                           SVGA3dShaderInstToken inst,
+                           SVGA3dShaderDestToken dest )
+{
+   return (emit_instruction( emit, inst ) && 
+           emit_dst( emit, dest ));
+}
+
+static boolean submit_op1( struct svga_shader_emitter *emit,
+                           SVGA3dShaderInstToken inst,
+                           SVGA3dShaderDestToken dest,
+                           struct src_register src0 )
+{
+   return emit_op1( emit, inst, dest, src0 );
+}
+
+
+/* SVGA shaders may not refer to >1 constant register in a single
+ * instruction.  This function checks for that usage and inserts a
+ * move to temporary if detected.
+ *
+ * The same applies to input registers -- at most a single input
+ * register may be read by any instruction.
+ */
+static boolean submit_op2( struct svga_shader_emitter *emit,
+                           SVGA3dShaderInstToken inst,
+                           SVGA3dShaderDestToken dest,
+                           struct src_register src0,
+                           struct src_register src1 )
+{
+   SVGA3dShaderDestToken temp;
+   SVGA3dShaderRegType type0, type1;
+   boolean need_temp = FALSE;
+
+   temp.value = 0;
+   type0 = SVGA3dShaderGetRegType( src0.base.value );
+   type1 = SVGA3dShaderGetRegType( src1.base.value );
+
+   if (type0 == SVGA3DREG_CONST &&
+       type1 == SVGA3DREG_CONST &&
+       src0.base.num != src1.base.num)
+      need_temp = TRUE;
+
+   if (type0 == SVGA3DREG_INPUT &&
+       type1 == SVGA3DREG_INPUT &&
+       src0.base.num != src1.base.num)
+      need_temp = TRUE;
+
+   if (need_temp)
+   {
+      temp = get_temp( emit );
+
+      if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), temp, src0 ))
+         return FALSE;
+
+      src0 = src( temp );
+   }
+
+   if (!emit_op2( emit, inst, dest, src0, src1 ))
+      return FALSE;
+
+   if (need_temp)
+      release_temp( emit, temp );
+
+   return TRUE;
+}
+
+
+/* SVGA shaders may not refer to >1 constant register in a single
+ * instruction.  This function checks for that usage and inserts a
+ * move to temporary if detected.
+ */
+static boolean submit_op3( struct svga_shader_emitter *emit,
+                           SVGA3dShaderInstToken inst,
+                           SVGA3dShaderDestToken dest,
+                           struct src_register src0,
+                           struct src_register src1,
+                           struct src_register src2 )
+{
+   SVGA3dShaderDestToken temp0;
+   SVGA3dShaderDestToken temp1;
+   boolean need_temp0 = FALSE;
+   boolean need_temp1 = FALSE;
+   SVGA3dShaderRegType type0, type1, type2;
+
+   temp0.value = 0;
+   temp1.value = 0;
+   type0 = SVGA3dShaderGetRegType( src0.base.value );
+   type1 = SVGA3dShaderGetRegType( src1.base.value );
+   type2 = SVGA3dShaderGetRegType( src2.base.value );
+
+   if (inst.op != SVGA3DOP_SINCOS) {
+      if (type0 == SVGA3DREG_CONST &&
+          ((type1 == SVGA3DREG_CONST && src0.base.num != src1.base.num) ||
+           (type2 == SVGA3DREG_CONST && src0.base.num != src2.base.num)))
+         need_temp0 = TRUE;
+
+      if (type1 == SVGA3DREG_CONST &&
+          (type2 == SVGA3DREG_CONST && src1.base.num != src2.base.num))
+         need_temp1 = TRUE;
+   }
+
+   if (type0 == SVGA3DREG_INPUT &&
+       ((type1 == SVGA3DREG_INPUT && src0.base.num != src1.base.num) ||
+        (type2 == SVGA3DREG_INPUT && src0.base.num != src2.base.num)))
+      need_temp0 = TRUE;
+
+   if (type1 == SVGA3DREG_INPUT &&
+       (type2 == SVGA3DREG_INPUT && src1.base.num != src2.base.num))
+      need_temp1 = TRUE;
+
+   if (need_temp0)
+   {
+      temp0 = get_temp( emit );
+ 
+      if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), temp0, src0 ))
+         return FALSE;
+         
+      src0 = src( temp0 );
+   }
+
+   if (need_temp1)
+   {
+      temp1 = get_temp( emit );
+
+      if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), temp1, src1 ))
+         return FALSE;
+
+      src1 = src( temp1 );
+   }
+
+   if (!emit_op3( emit, inst, dest, src0, src1, src2 ))
+      return FALSE;
+
+   if (need_temp1)
+      release_temp( emit, temp1 );
+   if (need_temp0)
+      release_temp( emit, temp0 );
+   return TRUE;
+}
+
+
+static boolean emit_def_const( struct svga_shader_emitter *emit,
+                               SVGA3dShaderConstType type,
+                               unsigned idx,
+                               float a,
+                               float b,
+                               float c,
+                               float d )
+{
+   SVGA3DOpDefArgs def;
+   SVGA3dShaderInstToken opcode;
+
+   switch (type) {
+   case SVGA3D_CONST_TYPE_FLOAT:
+      opcode = inst_token( SVGA3DOP_DEF );
+      def.dst = dst_register( SVGA3DREG_CONST, idx );
+      def.constValues[0] = a;
+      def.constValues[1] = b;
+      def.constValues[2] = c;
+      def.constValues[3] = d;
+      break;
+   case SVGA3D_CONST_TYPE_INT:
+      opcode = inst_token( SVGA3DOP_DEFI );
+      def.dst = dst_register( SVGA3DREG_CONSTINT, idx );
+      def.constIValues[0] = (int)a;
+      def.constIValues[1] = (int)b;
+      def.constIValues[2] = (int)c;
+      def.constIValues[3] = (int)d;
+      break;
+   default:
+      assert(0);
+      break;
+   }
+
+   if (!emit_instruction(emit, opcode) ||
+       !svga_shader_emit_dwords( emit, def.values, Elements(def.values)))
+      return FALSE;
+
+   return TRUE;
+}
+
+static INLINE boolean
+create_zero_immediate( struct svga_shader_emitter *emit )
+{
+   unsigned idx = emit->nr_hw_const++;
+
+   if (!emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT,
+                        idx, 0, 0, 0, 1 ))
+      return FALSE;
+
+   emit->zero_immediate_idx = idx;
+   emit->created_zero_immediate = TRUE;
+
+   return TRUE;
+}
+
+static INLINE boolean
+create_loop_const( struct svga_shader_emitter *emit )
+{
+   unsigned idx = emit->nr_hw_const++;
+
+   if (!emit_def_const( emit, SVGA3D_CONST_TYPE_INT, idx,
+                        255, /* iteration count */
+                        0, /* initial value */
+                        1, /* step size */
+                        0 /* not used, must be 0 */))
+      return FALSE;
+
+   emit->loop_const_idx = idx;
+   emit->created_loop_const = TRUE;
+
+   return TRUE;
+}
+
+static INLINE boolean
+create_sincos_consts( struct svga_shader_emitter *emit )
+{
+   unsigned idx = emit->nr_hw_const++;
+
+   if (!emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT, idx,
+                        -1.5500992e-006f,
+                        -2.1701389e-005f,
+                        0.0026041667f,
+                        0.00026041668f ))
+      return FALSE;
+
+   emit->sincos_consts_idx = idx;
+   idx = emit->nr_hw_const++;
+
+   if (!emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT, idx,
+                        -0.020833334f,
+                        -0.12500000f,
+                        1.0f,
+                        0.50000000f ))
+      return FALSE;
+
+   emit->created_sincos_consts = TRUE;
+
+   return TRUE;
+}
+
+static INLINE boolean
+create_arl_consts( struct svga_shader_emitter *emit )
+{
+   int i;
+
+   for (i = 0; i < emit->num_arl_consts; i += 4) {
+      int j;
+      unsigned idx = emit->nr_hw_const++;
+      float vals[4];
+      for (j = 0; j < 4 && (j + i) < emit->num_arl_consts; ++j) {
+         vals[j] = emit->arl_consts[i + j].number;
+         emit->arl_consts[i + j].idx = idx;
+         switch (j) {
+         case 0:
+            emit->arl_consts[i + 0].swizzle = TGSI_SWIZZLE_X;
+            break;
+         case 1:
+            emit->arl_consts[i + 0].swizzle = TGSI_SWIZZLE_Y;
+            break;
+         case 2:
+            emit->arl_consts[i + 0].swizzle = TGSI_SWIZZLE_Z;
+            break;
+         case 3:
+            emit->arl_consts[i + 0].swizzle = TGSI_SWIZZLE_W;
+            break;
+         }
+      }
+      while (j < 4)
+         vals[j++] = 0;
+
+      if (!emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT, idx,
+                           vals[0], vals[1],
+                           vals[2], vals[3]))
+         return FALSE;
+   }
+
+   return TRUE;
+}
+
+static INLINE struct src_register
+get_vface( struct svga_shader_emitter *emit )
+{
+   assert(emit->emitted_vface);
+   return src_register(SVGA3DREG_MISCTYPE, 
+                       SVGA3DMISCREG_FACE);
+}
+
+/* returns {0, 0, 0, 1} immediate */
+static INLINE struct src_register
+get_zero_immediate( struct svga_shader_emitter *emit )
+{
+   assert(emit->created_zero_immediate);
+   assert(emit->zero_immediate_idx >= 0);
+   return src_register( SVGA3DREG_CONST,
+                        emit->zero_immediate_idx );
+}
+
+/* returns the loop const */
+static INLINE struct src_register
+get_loop_const( struct svga_shader_emitter *emit )
+{
+   assert(emit->created_loop_const);
+   assert(emit->loop_const_idx >= 0);
+   return src_register( SVGA3DREG_CONSTINT,
+                        emit->loop_const_idx );
+}
+
+/* returns a sincos const */
+static INLINE struct src_register
+get_sincos_const( struct svga_shader_emitter *emit,
+                  unsigned index )
+{
+   assert(emit->created_sincos_consts);
+   assert(emit->sincos_consts_idx >= 0);
+   assert(index == 0 || index == 1);
+   return src_register( SVGA3DREG_CONST,
+                        emit->sincos_consts_idx + index );
+}
+
+static INLINE struct src_register
+get_fake_arl_const( struct svga_shader_emitter *emit )
+{
+   struct src_register reg;
+   int idx = 0, swizzle = 0, i;
+
+   for (i = 0; i < emit->num_arl_consts; ++ i) {
+      if (emit->arl_consts[i].arl_num == emit->current_arl) {
+         idx = emit->arl_consts[i].idx;
+         swizzle = emit->arl_consts[i].swizzle;
+      }
+   }
+
+   reg = src_register( SVGA3DREG_CONST, idx );
+   return scalar(reg, swizzle);
+}
+
+static INLINE struct src_register
+get_tex_dimensions( struct svga_shader_emitter *emit, int sampler_num )
+{
+   int idx;
+   struct src_register reg;
+
+   /* the width/height indexes start right after constants */
+   idx = emit->key.fkey.tex[sampler_num].width_height_idx +
+         emit->info.file_max[TGSI_FILE_CONSTANT] + 1;
+
+   reg = src_register( SVGA3DREG_CONST, idx );
+   return reg;
+}
+
+static boolean emit_fake_arl(struct svga_shader_emitter *emit,
+                             const struct tgsi_full_instruction *insn)
+{
+   const struct src_register src0 = translate_src_register(
+      emit, &insn->Src[0] );
+   struct src_register src1 = get_fake_arl_const( emit );
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   SVGA3dShaderDestToken tmp = get_temp( emit );
+
+   if (!submit_op1(emit, inst_token( SVGA3DOP_MOV ), tmp, src0))
+      return FALSE;
+
+   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), tmp, src( tmp ),
+                    src1))
+      return FALSE;
+
+   /* replicate the original swizzle */
+   src1 = src(tmp);
+   src1.base.swizzle = src0.base.swizzle;
+
+   return submit_op1( emit, inst_token( SVGA3DOP_MOVA ),
+                      dst, src1 );
+}
+
+static boolean emit_if(struct svga_shader_emitter *emit,
+                       const struct tgsi_full_instruction *insn)
+{
+   const struct src_register src = translate_src_register(
+      emit, &insn->Src[0] );
+   struct src_register zero = get_zero_immediate( emit );
+   SVGA3dShaderInstToken if_token = inst_token( SVGA3DOP_IFC );
+
+   if_token.control = SVGA3DOPCOMPC_NE;
+   zero = scalar(zero, TGSI_SWIZZLE_X);
+
+   return (emit_instruction( emit, if_token ) &&
+           emit_src( emit, src ) &&
+           emit_src( emit, zero ) );
+}
+
+static boolean emit_endif(struct svga_shader_emitter *emit,
+                       const struct tgsi_full_instruction *insn)
+{
+   return (emit_instruction( emit,
+                             inst_token( SVGA3DOP_ENDIF )));
+}
+
+static boolean emit_else(struct svga_shader_emitter *emit,
+                         const struct tgsi_full_instruction *insn)
+{
+   return (emit_instruction( emit,
+                             inst_token( SVGA3DOP_ELSE )));
+}
+
+/* Translate the following TGSI FLR instruction.
+ *    FLR  DST, SRC
+ * To the following SVGA3D instruction sequence.
+ *    FRC  TMP, SRC
+ *    SUB  DST, SRC, TMP
+ */
+static boolean emit_floor(struct svga_shader_emitter *emit,
+                          const struct tgsi_full_instruction *insn )
+{
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   const struct src_register src0 = translate_src_register(
+      emit, &insn->Src[0] );
+   SVGA3dShaderDestToken temp = get_temp( emit );
+
+   /* FRC  TMP, SRC */
+   if (!submit_op1( emit, inst_token( SVGA3DOP_FRC ), temp, src0 ))
+      return FALSE;
+
+   /* SUB  DST, SRC, TMP */
+   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst, src0,
+                    negate( src( temp ) ) ))
+      return FALSE;
+
+   return TRUE;
+}
+
+
+/* Translate the following TGSI CMP instruction.
+ *    CMP  DST, SRC0, SRC1, SRC2
+ * To the following SVGA3D instruction sequence.
+ *    CMP  DST, SRC0, SRC2, SRC1
+ */
+static boolean emit_cmp(struct svga_shader_emitter *emit,
+                          const struct tgsi_full_instruction *insn )
+{
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   const struct src_register src0 = translate_src_register(
+      emit, &insn->Src[0] );
+   const struct src_register src1 = translate_src_register(
+      emit, &insn->Src[1] );
+   const struct src_register src2 = translate_src_register(
+      emit, &insn->Src[2] );
+
+   /* CMP  DST, SRC0, SRC2, SRC1 */
+   return submit_op3( emit, inst_token( SVGA3DOP_CMP ), dst, src0, src2, src1);
+}
+
+
+
+/* Translate the following TGSI DIV instruction.
+ *    DIV  DST.xy, SRC0, SRC1
+ * To the following SVGA3D instruction sequence.
+ *    RCP  TMP.x, SRC1.xxxx
+ *    RCP  TMP.y, SRC1.yyyy
+ *    MUL  DST.xy, SRC0, TMP
+ */
+static boolean emit_div(struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn )
+{
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   const struct src_register src0 = translate_src_register(
+      emit, &insn->Src[0] );
+   const struct src_register src1 = translate_src_register(
+      emit, &insn->Src[1] );
+   SVGA3dShaderDestToken temp = get_temp( emit );
+   int i;
+
+   /* For each enabled element, perform a RCP instruction.  Note that
+    * RCP is scalar in SVGA3D:
+    */
+   for (i = 0; i < 4; i++) {
+      unsigned channel = 1 << i;
+      if (dst.mask & channel) {
+         /* RCP  TMP.?, SRC1.???? */
+         if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ), 
+                          writemask(temp, channel), 
+                          scalar(src1, i) ))
+            return FALSE;
+      }
+   }
+
+   /* Then multiply them out with a single mul:
+    *
+    * MUL  DST, SRC0, TMP
+    */
+   if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), dst, src0,
+                    src( temp ) ))
+      return FALSE;
+
+   return TRUE;
+}
+
+/* Translate the following TGSI DP2 instruction.
+ *    DP2  DST, SRC1, SRC2
+ * To the following SVGA3D instruction sequence.
+ *    MUL  TMP, SRC1, SRC2
+ *    ADD  DST, TMP.xxxx, TMP.yyyy
+ */
+static boolean emit_dp2(struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn )
+{
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   const struct src_register src0 = translate_src_register(
+      emit, &insn->Src[0] );
+   const struct src_register src1 = translate_src_register(
+      emit, &insn->Src[1] );
+   SVGA3dShaderDestToken temp = get_temp( emit );
+   struct src_register temp_src0, temp_src1;
+
+   /* MUL  TMP, SRC1, SRC2 */
+   if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), temp, src0, src1 ))
+      return FALSE;
+
+   temp_src0 = scalar(src( temp ), TGSI_SWIZZLE_X);
+   temp_src1 = scalar(src( temp ), TGSI_SWIZZLE_Y);
+
+   /* ADD  DST, TMP.xxxx, TMP.yyyy */
+   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst,
+                    temp_src0, temp_src1 ))
+      return FALSE;
+
+   return TRUE;
+}
+
+
+/* Translate the following TGSI DPH instruction.
+ *    DPH  DST, SRC1, SRC2
+ * To the following SVGA3D instruction sequence.
+ *    DP3  TMP, SRC1, SRC2
+ *    ADD  DST, TMP, SRC2.wwww
+ */
+static boolean emit_dph(struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn )
+{
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   const struct src_register src0 = translate_src_register(
+      emit, &insn->Src[0] );
+   struct src_register src1 = translate_src_register(
+      emit, &insn->Src[1] );
+   SVGA3dShaderDestToken temp = get_temp( emit );
+
+   /* DP3  TMP, SRC1, SRC2 */
+   if (!submit_op2( emit, inst_token( SVGA3DOP_DP3 ), temp, src0, src1 ))
+      return FALSE;
+
+   src1 = scalar(src1, TGSI_SWIZZLE_W);
+
+   /* ADD  DST, TMP, SRC2.wwww */
+   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst,
+                    src( temp ), src1 ))
+      return FALSE;
+
+   return TRUE;
+}
+
+/* Translate the following TGSI DST instruction.
+ *    NRM  DST, SRC
+ * To the following SVGA3D instruction sequence.
+ *    DP3  TMP, SRC, SRC
+ *    RSQ  TMP, TMP
+ *    MUL  DST, SRC, TMP
+ */
+static boolean emit_nrm(struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn )
+{
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   const struct src_register src0 = translate_src_register(
+      emit, &insn->Src[0] );
+   SVGA3dShaderDestToken temp = get_temp( emit );
+
+   /* DP3  TMP, SRC, SRC */
+   if (!submit_op2( emit, inst_token( SVGA3DOP_DP3 ), temp, src0, src0 ))
+      return FALSE;
+
+   /* RSQ  TMP, TMP */
+   if (!submit_op1( emit, inst_token( SVGA3DOP_RSQ ), temp, src( temp )))
+      return FALSE;
+
+   /* MUL  DST, SRC, TMP */
+   if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), dst,
+                    src0, src( temp )))
+      return FALSE;
+
+   return TRUE;
+
+}
+
+static boolean do_emit_sincos(struct svga_shader_emitter *emit,
+                              SVGA3dShaderDestToken dst,
+                              struct src_register src0)
+{
+   src0 = scalar(src0, TGSI_SWIZZLE_X);
+
+   if (emit->use_sm30) {
+      return submit_op1( emit, inst_token( SVGA3DOP_SINCOS ),
+                         dst, src0 );
+   } else {
+      struct src_register const1 = get_sincos_const( emit, 0 );
+      struct src_register const2 = get_sincos_const( emit, 1 );
+
+      return submit_op3( emit, inst_token( SVGA3DOP_SINCOS ),
+                         dst, src0, const1, const2 );
+   }
+}
+
+static boolean emit_sincos(struct svga_shader_emitter *emit,
+                           const struct tgsi_full_instruction *insn)
+{
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   struct src_register src0 = translate_src_register(
+      emit, &insn->Src[0] );
+   SVGA3dShaderDestToken temp = get_temp( emit );
+
+   /* SCS TMP SRC */
+   if (!do_emit_sincos(emit, writemask(temp, TGSI_WRITEMASK_XY), src0 ))
+      return FALSE;
+
+   /* MOV DST TMP */
+   if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, src( temp ) ))
+      return FALSE;
+
+   return TRUE;
+}
+
+/*
+ * SCS TMP SRC
+ * MOV DST TMP.yyyy
+ */
+static boolean emit_sin(struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn )
+{
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   struct src_register src0 = translate_src_register(
+      emit, &insn->Src[0] );
+   SVGA3dShaderDestToken temp = get_temp( emit );
+
+   /* SCS TMP SRC */
+   if (!do_emit_sincos(emit, writemask(temp, TGSI_WRITEMASK_Y), src0))
+      return FALSE;
+
+   src0 = scalar(src( temp ), TGSI_SWIZZLE_Y);
+
+   /* MOV DST TMP.yyyy */
+   if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, src0 ))
+      return FALSE;
+
+   return TRUE;
+}
+
+/*
+ * SCS TMP SRC
+ * MOV DST TMP.xxxx
+ */
+static boolean emit_cos(struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn )
+{
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   struct src_register src0 = translate_src_register(
+      emit, &insn->Src[0] );
+   SVGA3dShaderDestToken temp = get_temp( emit );
+
+   /* SCS TMP SRC */
+   if (!do_emit_sincos( emit, writemask(temp, TGSI_WRITEMASK_X), src0 ))
+      return FALSE;
+
+   src0 = scalar(src( temp ), TGSI_SWIZZLE_X);
+
+   /* MOV DST TMP.xxxx */
+   if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, src0 ))
+      return FALSE;
+
+   return TRUE;
+}
+
+
+/*
+ * ADD DST SRC0, negate(SRC0)
+ */
+static boolean emit_sub(struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn)
+{
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   struct src_register src0 = translate_src_register(
+      emit, &insn->Src[0] );
+   struct src_register src1 = translate_src_register(
+      emit, &insn->Src[1] );
+
+   src1 = negate(src1);
+
+   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst,
+                    src0, src1 ))
+      return FALSE;
+
+   return TRUE;
+}
+
+
+static boolean emit_kil(struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn )
+{
+   SVGA3dShaderInstToken inst;
+   const struct tgsi_full_src_register *reg = &insn->Src[0];
+   struct src_register src0;
+
+   inst = inst_token( SVGA3DOP_TEXKILL );
+   src0 = translate_src_register( emit, reg );
+
+   if (reg->Register.Absolute ||
+       reg->Register.Negate ||
+       reg->Register.Indirect ||
+       reg->Register.SwizzleX != 0 ||
+       reg->Register.SwizzleY != 1 ||
+       reg->Register.SwizzleZ != 2 ||
+       reg->Register.File != TGSI_FILE_TEMPORARY)
+   {
+      SVGA3dShaderDestToken temp = get_temp( emit );
+
+      submit_op1( emit, inst_token( SVGA3DOP_MOV ), temp, src0 );
+      src0 = src( temp );
+   }
+
+   return submit_op0( emit, inst, dst(src0) );
+}
+
+
+/* mesa state tracker always emits kilp as an unconditional
+ * kil */
+static boolean emit_kilp(struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn )
+{
+   SVGA3dShaderInstToken inst;
+   SVGA3dShaderDestToken temp;
+   struct src_register one = get_zero_immediate( emit );
+
+   inst = inst_token( SVGA3DOP_TEXKILL );
+   one = scalar( one, TGSI_SWIZZLE_W );
+
+   /* texkill doesn't allow negation on the operand so lets move
+    * negation of {1} to a temp register */
+   temp = get_temp( emit );
+   if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), temp,
+                    negate( one ) ))
+      return FALSE;
+
+   return submit_op0( emit, inst, temp );
+}
+
+/* Implement conditionals by initializing destination reg to 'fail',
+ * then set predicate reg with UFOP_SETP, then move 'pass' to dest
+ * based on predicate reg.
+ *
+ * SETP src0, cmp, src1  -- do this first to avoid aliasing problems.
+ * MOV dst, fail
+ * MOV dst, pass, p0 
+ */
+static boolean
+emit_conditional(struct svga_shader_emitter *emit,
+                 unsigned compare_func,
+                 SVGA3dShaderDestToken dst,
+                 struct src_register src0,
+                 struct src_register src1,
+                 struct src_register pass,
+                 struct src_register fail)
+{
+   SVGA3dShaderDestToken pred_reg = dst_register( SVGA3DREG_PREDICATE, 0 );
+   SVGA3dShaderInstToken setp_token, mov_token;
+   setp_token = inst_token( SVGA3DOP_SETP );
+
+   switch (compare_func) {
+   case PIPE_FUNC_NEVER:
+      return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
+                         dst, fail );
+      break;
+   case PIPE_FUNC_LESS:
+      setp_token.control = SVGA3DOPCOMP_LT;
+      break;
+   case PIPE_FUNC_EQUAL:
+      setp_token.control = SVGA3DOPCOMP_EQ;
+      break;
+   case PIPE_FUNC_LEQUAL:
+      setp_token.control = SVGA3DOPCOMP_LE;
+      break;
+   case PIPE_FUNC_GREATER:
+      setp_token.control = SVGA3DOPCOMP_GT;
+      break;
+   case PIPE_FUNC_NOTEQUAL:
+      setp_token.control = SVGA3DOPCOMPC_NE;
+      break;
+   case PIPE_FUNC_GEQUAL:
+      setp_token.control = SVGA3DOPCOMP_GE;
+      break;
+   case PIPE_FUNC_ALWAYS:
+      return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
+                         dst, pass );
+      break;
+   }
+
+   /* SETP src0, COMPOP, src1 */
+   if (!submit_op2( emit, setp_token, pred_reg,
+                    src0, src1 ))
+      return FALSE;
+
+   mov_token = inst_token( SVGA3DOP_MOV );
+
+   /* MOV dst, fail */
+   if (!submit_op1( emit, mov_token, dst,
+                    fail ))
+      return FALSE;
+
+   /* MOV dst, pass (predicated)
+    *
+    * Note that the predicate reg (and possible modifiers) is passed
+    * as the first source argument.
+    */
+   mov_token.predicated = 1;
+   if (!submit_op2( emit, mov_token, dst,
+                    src( pred_reg ), pass ))
+      return FALSE;
+
+   return TRUE;
+}
+
+
+static boolean
+emit_select(struct svga_shader_emitter *emit,
+            unsigned compare_func,
+            SVGA3dShaderDestToken dst,
+            struct src_register src0,
+            struct src_register src1 )
+{
+   /* There are some SVGA instructions which implement some selects
+    * directly, but they are only available in the vertex shader.
+    */
+   if (emit->unit == PIPE_SHADER_VERTEX) {
+      switch (compare_func) {
+      case PIPE_FUNC_GEQUAL:
+         return submit_op2( emit, inst_token( SVGA3DOP_SGE ), dst, src0, src1 );
+      case PIPE_FUNC_LEQUAL:
+         return submit_op2( emit, inst_token( SVGA3DOP_SGE ), dst, src1, src0 );
+      case PIPE_FUNC_GREATER:
+         return submit_op2( emit, inst_token( SVGA3DOP_SLT ), dst, src1, src0 );
+      case PIPE_FUNC_LESS:
+         return submit_op2( emit, inst_token( SVGA3DOP_SLT ), dst, src0, src1 );
+      default:
+         break;
+      }
+   }
+
+
+   /* Otherwise, need to use the setp approach:
+    */
+   {
+      struct src_register one, zero;
+      /* zero immediate is 0,0,0,1 */
+      zero = get_zero_immediate( emit );
+      one  = scalar( zero, TGSI_SWIZZLE_W );
+      zero = scalar( zero, TGSI_SWIZZLE_X );
+
+      return emit_conditional(
+         emit,
+         compare_func,
+         dst,
+         src0,
+         src1,
+         one, zero);
+   }
+}
+
+
+static boolean emit_select_op(struct svga_shader_emitter *emit,
+                              unsigned compare,
+                              const struct tgsi_full_instruction *insn)
+{
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   struct src_register src0 = translate_src_register(
+      emit, &insn->Src[0] );
+   struct src_register src1 = translate_src_register(
+      emit, &insn->Src[1] );
+      
+   return emit_select( emit, compare, dst, src0, src1 );
+}
+
+
+/* Translate texture instructions to SVGA3D representation.
+ */
+static boolean emit_tex2(struct svga_shader_emitter *emit,
+                         const struct tgsi_full_instruction *insn,
+                         SVGA3dShaderDestToken dst )
+{
+   SVGA3dShaderInstToken inst;
+   struct src_register src0;
+   struct src_register src1;
+
+   inst.value = 0;
+   inst.op = SVGA3DOP_TEX;
+
+   switch (insn->Instruction.Opcode) {
+   case TGSI_OPCODE_TEX:
+      break;
+   case TGSI_OPCODE_TXP:
+      inst.control = SVGA3DOPCONT_PROJECT;
+      break;
+   case TGSI_OPCODE_TXB:
+      inst.control = SVGA3DOPCONT_BIAS;
+      break;
+   default:
+      assert(0);
+      return FALSE;
+   }
+
+   src0 = translate_src_register( emit, &insn->Src[0] );
+   src1 = translate_src_register( emit, &insn->Src[1] );
+
+   if (emit->key.fkey.tex[src1.base.num].unnormalized) {
+      struct src_register wh = get_tex_dimensions( emit, src1.base.num );
+      SVGA3dShaderDestToken tmp = get_temp( emit );
+
+      /* MUL  tmp, SRC0, WH */
+      if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
+                       tmp, src0, wh ))
+         return FALSE;
+      src0 = src( tmp );
+   }
+
+   return submit_op2( emit, inst, dst, src0, src1 );
+}
+
+
+
+
+/* Translate texture instructions to SVGA3D representation.
+ */
+static boolean emit_tex3(struct svga_shader_emitter *emit,
+                         const struct tgsi_full_instruction *insn,
+                         SVGA3dShaderDestToken dst )
+{
+   SVGA3dShaderInstToken inst;
+   struct src_register src0;
+   struct src_register src1;
+   struct src_register src2;
+
+   inst.value = 0;
+
+   switch (insn->Instruction.Opcode) {
+   case TGSI_OPCODE_TXD: 
+      inst.op = SVGA3DOP_TEXLDD;
+      break;
+   case TGSI_OPCODE_TXL:
+      inst.op = SVGA3DOP_TEXLDL;
+      break;
+   }
+
+   src0 = translate_src_register( emit, &insn->Src[0] );
+   src1 = translate_src_register( emit, &insn->Src[1] );
+   src2 = translate_src_register( emit, &insn->Src[2] );
+
+   return submit_op3( emit, inst, dst, src0, src1, src2 );
+}
+
+
+static boolean emit_tex(struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn )
+{
+   SVGA3dShaderDestToken dst = 
+      translate_dst_register( emit, insn, 0 );
+   struct src_register src0 =
+      translate_src_register( emit, &insn->Src[0] );
+   struct src_register src1 =
+      translate_src_register( emit, &insn->Src[1] );
+
+   SVGA3dShaderDestToken tex_result;
+
+   /* check for shadow samplers */
+   boolean compare = (emit->key.fkey.tex[src1.base.num].compare_mode ==
+                      PIPE_TEX_COMPARE_R_TO_TEXTURE);
+
+
+   /* If doing compare processing, need to put this value into a
+    * temporary so it can be used as a source later on.
+    */
+   if (compare ||
+       (!emit->use_sm30 && dst.mask != TGSI_WRITEMASK_XYZW) ) {
+      tex_result = get_temp( emit );
+   }
+   else {
+      tex_result = dst;
+   }
+
+   switch(insn->Instruction.Opcode) {
+   case TGSI_OPCODE_TEX:
+   case TGSI_OPCODE_TXB:
+   case TGSI_OPCODE_TXP:
+      if (!emit_tex2( emit, insn, tex_result ))
+         return FALSE;
+      break;
+   case TGSI_OPCODE_TXL:
+   case TGSI_OPCODE_TXD:
+      if (!emit_tex3( emit, insn, tex_result ))
+         return FALSE;
+      break;
+   default:
+      assert(0);
+   }
+
+
+   if (compare) {
+      SVGA3dShaderDestToken src0_zdivw = get_temp( emit );
+      struct src_register tex_src_x = scalar(src(tex_result), TGSI_SWIZZLE_Y);
+      struct src_register one =
+         scalar( get_zero_immediate( emit ), TGSI_SWIZZLE_W );
+
+      /* Divide texcoord R by Q */
+      if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
+                       src0_zdivw,
+                       scalar(src0, TGSI_SWIZZLE_W) ))
+         return FALSE;
+
+      if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
+                       src0_zdivw,
+                       scalar(src0, TGSI_SWIZZLE_Z),
+                       src(src0_zdivw) ))
+         return FALSE;
+
+      if (!emit_select(
+             emit,
+             emit->key.fkey.tex[src1.base.num].compare_func,
+             dst,
+             src(src0_zdivw),
+             tex_src_x))
+         return FALSE;
+
+      return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
+                         writemask( dst, TGSI_WRITEMASK_W),
+                         one );
+   }
+   else if (!emit->use_sm30 && dst.mask != TGSI_WRITEMASK_XYZW) 
+   {
+      if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, src(tex_result) ))
+         return FALSE;
+   }
+
+   return TRUE;
+}
+
+static boolean emit_bgnloop2( struct svga_shader_emitter *emit,
+                              const struct tgsi_full_instruction *insn )
+{
+   SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_LOOP );
+   struct src_register loop_reg = src_register( SVGA3DREG_LOOP, 0 );
+   struct src_register const_int = get_loop_const( emit );
+
+   return (emit_instruction( emit, inst ) &&
+           emit_src( emit, loop_reg ) &&
+           emit_src( emit, const_int ) );
+}
+
+static boolean emit_endloop2( struct svga_shader_emitter *emit,
+                              const struct tgsi_full_instruction *insn )
+{
+   SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_ENDLOOP );
+   return emit_instruction( emit, inst );
+}
+
+static boolean emit_brk( struct svga_shader_emitter *emit,
+                         const struct tgsi_full_instruction *insn )
+{
+   SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_BREAK );
+   return emit_instruction( emit, inst );
+}
+
+static boolean emit_scalar_op1( struct svga_shader_emitter *emit,
+                                unsigned opcode,
+                                const struct tgsi_full_instruction *insn )
+{
+   SVGA3dShaderInstToken inst;
+   SVGA3dShaderDestToken dst;
+   struct src_register src;
+
+   inst = inst_token( opcode );
+   dst = translate_dst_register( emit, insn, 0 );
+   src = translate_src_register( emit, &insn->Src[0] );
+   src = scalar( src, TGSI_SWIZZLE_X );
+
+   return submit_op1( emit, inst, dst, src );
+}
+
+
+static boolean emit_simple_instruction(struct svga_shader_emitter *emit,
+                                       unsigned opcode,
+                                       const struct tgsi_full_instruction *insn )
+{
+   const struct tgsi_full_src_register *src = insn->Src;
+   SVGA3dShaderInstToken inst;
+   SVGA3dShaderDestToken dst;
+
+   inst = inst_token( opcode );
+   dst = translate_dst_register( emit, insn, 0 );
+
+   switch (insn->Instruction.NumSrcRegs) {
+   case 0:
+      return submit_op0( emit, inst, dst );
+   case 1:
+      return submit_op1( emit, inst, dst,
+                         translate_src_register( emit, &src[0] ));
+   case 2:
+      return submit_op2( emit, inst, dst,
+                         translate_src_register( emit, &src[0] ),
+                         translate_src_register( emit, &src[1] ) );
+   case 3:
+      return submit_op3( emit, inst, dst,
+                         translate_src_register( emit, &src[0] ),
+                         translate_src_register( emit, &src[1] ),
+                         translate_src_register( emit, &src[2] ) );
+   default:
+      assert(0);
+      return FALSE;
+   }
+}
+
+static boolean emit_arl(struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn)
+{
+   ++emit->current_arl;
+   if (svga_arl_needs_adjustment( emit )) {
+      return emit_fake_arl( emit, insn );
+   } else {
+      /* no need to adjust, just emit straight arl */
+      return emit_simple_instruction(emit, SVGA3DOP_MOVA, insn);
+   }
+}
+
+static boolean alias_src_dst( struct src_register src,
+                              SVGA3dShaderDestToken dst )
+{
+   if (src.base.num != dst.num)
+      return FALSE;
+
+   if (SVGA3dShaderGetRegType(dst.value) != 
+       SVGA3dShaderGetRegType(src.base.value))
+      return FALSE;
+
+   return TRUE;
+}
+
+static boolean emit_pow(struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn)
+{
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   struct src_register src0 = translate_src_register(
+      emit, &insn->Src[0] );
+   struct src_register src1 = translate_src_register(
+      emit, &insn->Src[1] );
+   boolean need_tmp = FALSE;
+   
+   /* POW can only output to a temporary */
+   if (insn->Dst[0].Register.File != TGSI_FILE_TEMPORARY)
+      need_tmp = TRUE;
+   
+   /* POW src1 must not be the same register as dst */
+   if (alias_src_dst( src1, dst ))
+      need_tmp = TRUE;
+
+   /* it's a scalar op */
+   src0 = scalar( src0, TGSI_SWIZZLE_X );
+   src1 = scalar( src1, TGSI_SWIZZLE_X );
+
+   if (need_tmp) {
+      SVGA3dShaderDestToken tmp = writemask(get_temp( emit ), TGSI_WRITEMASK_X );
+
+      if (!submit_op2(emit, inst_token( SVGA3DOP_POW ), tmp, src0, src1))
+         return FALSE;
+
+      return submit_op1(emit, inst_token( SVGA3DOP_MOV ), dst, scalar(src(tmp), 0) );
+   } 
+   else {
+      return submit_op2(emit, inst_token( SVGA3DOP_POW ), dst, src0, src1);
+   }
+}
+
+static boolean emit_xpd(struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn)
+{
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   const struct src_register src0 = translate_src_register(
+      emit, &insn->Src[0] );
+   const struct src_register src1 = translate_src_register(
+      emit, &insn->Src[1] );
+   boolean need_dst_tmp = FALSE;
+
+   /* XPD can only output to a temporary */
+   if (SVGA3dShaderGetRegType(dst.value) != SVGA3DREG_TEMP) 
+      need_dst_tmp = TRUE;
+
+   /* The dst reg must not be the same as src0 or src1*/
+   if (alias_src_dst(src0, dst) ||
+       alias_src_dst(src1, dst))
+      need_dst_tmp = TRUE;
+
+   if (need_dst_tmp) {
+      SVGA3dShaderDestToken tmp = get_temp( emit );
+
+      /* Obey DX9 restrictions on mask:
+       */
+      tmp.mask = dst.mask & TGSI_WRITEMASK_XYZ;
+
+      if (!submit_op2(emit, inst_token( SVGA3DOP_CRS ), tmp, src0, src1))
+         return FALSE;
+
+      if (!submit_op1(emit, inst_token( SVGA3DOP_MOV ), dst, src( tmp )))
+         return FALSE;
+   } 
+   else {
+      if (!submit_op2(emit, inst_token( SVGA3DOP_CRS ), dst, src0, src1))
+         return FALSE;
+   }
+
+   /* Need to emit 1.0 to dst.w?
+    */
+   if (dst.mask & TGSI_WRITEMASK_W) {
+      struct src_register zero = get_zero_immediate( emit );
+
+      if (!submit_op1(emit, 
+                      inst_token( SVGA3DOP_MOV ), 
+                      writemask(dst, TGSI_WRITEMASK_W),
+                      zero))
+         return FALSE;
+   }
+
+   return TRUE;
+}
+
+
+static boolean emit_lrp(struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn)
+{
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   SVGA3dShaderDestToken tmp;
+   const struct src_register src0 = translate_src_register(
+      emit, &insn->Src[0] );
+   const struct src_register src1 = translate_src_register(
+      emit, &insn->Src[1] );
+   const struct src_register src2 = translate_src_register(
+      emit, &insn->Src[2] );
+   boolean need_dst_tmp = FALSE;
+
+   /* The dst reg must not be the same as src0 or src2 */
+   if (alias_src_dst(src0, dst) ||
+       alias_src_dst(src2, dst))
+      need_dst_tmp = TRUE;
+
+   if (need_dst_tmp) {
+      tmp = get_temp( emit );
+      tmp.mask = dst.mask;
+   }
+   else {
+      tmp = dst;
+   }
+
+   if (!submit_op3(emit, inst_token( SVGA3DOP_LRP ), tmp, src0, src1, src2))
+      return FALSE;
+
+   if (need_dst_tmp) {
+      if (!submit_op1(emit, inst_token( SVGA3DOP_MOV ), dst, src( tmp )))
+         return FALSE;      
+   } 
+
+   return TRUE;
+}
+
+
+static boolean emit_dst_insn(struct svga_shader_emitter *emit,
+                             const struct tgsi_full_instruction *insn )
+{
+   if (emit->unit == PIPE_SHADER_VERTEX) {
+      /* SVGA/DX9 has a DST instruction, but only for vertex shaders:
+       */
+      return emit_simple_instruction(emit, SVGA3DOP_DST, insn);
+   }
+   else {
+
+      /* result[0] = 1    * 1;
+       * result[1] = a[1] * b[1];
+       * result[2] = a[2] * 1;
+       * result[3] = 1    * b[3];
+       */
+
+      SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+      SVGA3dShaderDestToken tmp;
+      const struct src_register src0 = translate_src_register(
+         emit, &insn->Src[0] );
+      const struct src_register src1 = translate_src_register(
+         emit, &insn->Src[1] );
+      struct src_register zero = get_zero_immediate( emit );
+      boolean need_tmp = FALSE;
+
+      if (SVGA3dShaderGetRegType(dst.value) != SVGA3DREG_TEMP ||
+          alias_src_dst(src0, dst) ||
+          alias_src_dst(src1, dst))
+         need_tmp = TRUE;
+
+      if (need_tmp) {
+         tmp = get_temp( emit );
+      }
+      else {
+         tmp = dst;
+      }
+
+      /* tmp.xw = 1.0
+       */
+      if (tmp.mask & TGSI_WRITEMASK_XW) {
+         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), 
+                          writemask(tmp, TGSI_WRITEMASK_XW ),
+                          scalar( zero, 3 )))
+            return FALSE;
+      }
+      
+      /* tmp.yz = src0
+       */
+      if (tmp.mask & TGSI_WRITEMASK_YZ) {
+         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), 
+                          writemask(tmp, TGSI_WRITEMASK_YZ ),
+                          src0))
+            return FALSE;
+      }
+
+      /* tmp.yw = tmp * src1
+       */
+      if (tmp.mask & TGSI_WRITEMASK_YW) {
+         if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), 
+                          writemask(tmp, TGSI_WRITEMASK_YW ),
+                          src(tmp),
+                          src1))
+            return FALSE;
+      }
+
+      /* dst = tmp
+       */
+      if (need_tmp) {
+         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), 
+                          dst,
+                          src(tmp)))
+            return FALSE;
+      }      
+   }
+   
+   return TRUE;
+}
+
+
+static boolean emit_exp(struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn)
+{
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   struct src_register src0 =
+      translate_src_register( emit, &insn->Src[0] );
+   struct src_register zero = get_zero_immediate( emit );
+   SVGA3dShaderDestToken fraction;
+
+   if (dst.mask & TGSI_WRITEMASK_Y)
+      fraction = dst;
+   else if (dst.mask & TGSI_WRITEMASK_X)
+      fraction = get_temp( emit );
+
+   /* If y is being written, fill it with src0 - floor(src0).
+    */
+   if (dst.mask & TGSI_WRITEMASK_XY) {
+      if (!submit_op1( emit, inst_token( SVGA3DOP_FRC ),
+                       writemask( fraction, TGSI_WRITEMASK_Y ),
+                       src0 ))
+         return FALSE;
+   }
+
+   /* If x is being written, fill it with 2 ^ floor(src0).
+    */
+   if (dst.mask & TGSI_WRITEMASK_X) {
+      if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ),
+                       writemask( dst, dst.mask & TGSI_WRITEMASK_X ),
+                       src0,
+                       scalar( negate( src( fraction ) ), TGSI_SWIZZLE_Y ) ) )
+         return FALSE;
+
+      if (!submit_op1( emit, inst_token( SVGA3DOP_EXP ),
+                       writemask( dst, dst.mask & TGSI_WRITEMASK_X ),
+                       scalar( src( dst ), TGSI_SWIZZLE_X ) ) )
+         return FALSE;
+
+      if (!(dst.mask & TGSI_WRITEMASK_Y))
+         release_temp( emit, fraction );
+   }
+
+   /* If z is being written, fill it with 2 ^ src0 (partial precision).
+    */
+   if (dst.mask & TGSI_WRITEMASK_Z) {
+      if (!submit_op1( emit, inst_token( SVGA3DOP_EXPP ),
+                       writemask( dst, dst.mask & TGSI_WRITEMASK_Z ),
+                       src0 ) )
+         return FALSE;
+   }
+
+   /* If w is being written, fill it with one.
+    */
+   if (dst.mask & TGSI_WRITEMASK_W) {
+      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
+                       writemask(dst, TGSI_WRITEMASK_W),
+                       scalar( zero, TGSI_SWIZZLE_W ) ))
+         return FALSE;
+   }
+
+   return TRUE;
+}
+
+static boolean emit_lit(struct svga_shader_emitter *emit,
+                             const struct tgsi_full_instruction *insn )
+{
+   if (emit->unit == PIPE_SHADER_VERTEX) {
+      /* SVGA/DX9 has a LIT instruction, but only for vertex shaders:
+       */
+      return emit_simple_instruction(emit, SVGA3DOP_LIT, insn);
+   }
+   else {
+
+      /* D3D vs. GL semantics can be fairly easily accomodated by
+       * variations on this sequence.
+       *
+       * GL:
+       *   tmp.y = src.x
+       *   tmp.z = pow(src.y,src.w)
+       *   p0 = src0.xxxx > 0
+       *   result = zero.wxxw
+       *   (p0) result.yz = tmp
+       *
+       * D3D:
+       *   tmp.y = src.x
+       *   tmp.z = pow(src.y,src.w)
+       *   p0 = src0.xxyy > 0
+       *   result = zero.wxxw
+       *   (p0) result.yz = tmp
+       *
+       * Will implement the GL version for now.
+       */
+
+      SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+      SVGA3dShaderDestToken tmp = get_temp( emit );
+      const struct src_register src0 = translate_src_register(
+         emit, &insn->Src[0] );
+      struct src_register zero = get_zero_immediate( emit );
+
+      /* tmp = pow(src.y, src.w)
+       */
+      if (dst.mask & TGSI_WRITEMASK_Z) {
+         if (!submit_op2(emit, inst_token( SVGA3DOP_POW ), 
+                         tmp, 
+                         scalar(src0, 1), 
+                         scalar(src0, 3)))
+            return FALSE;
+      }
+
+      /* tmp.y = src.x
+       */
+      if (dst.mask & TGSI_WRITEMASK_Y) {
+         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), 
+                          writemask(tmp, TGSI_WRITEMASK_Y ),
+                          scalar(src0, 0)))
+            return FALSE;
+      }
+      
+      /* Can't quite do this with emit conditional due to the extra
+       * writemask on the predicated mov:
+       */
+      {
+         SVGA3dShaderDestToken pred_reg = dst_register( SVGA3DREG_PREDICATE, 0 );
+         SVGA3dShaderInstToken setp_token, mov_token;
+         struct src_register predsrc;
+
+         setp_token = inst_token( SVGA3DOP_SETP );
+         mov_token = inst_token( SVGA3DOP_MOV );
+
+         setp_token.control = SVGA3DOPCOMP_GT;
+
+         /* D3D vs GL semantics:
+          */
+         if (0)
+            predsrc = swizzle(src0, 0, 0, 1, 1); /* D3D */
+         else
+            predsrc = swizzle(src0, 0, 0, 0, 0); /* GL */
+
+         /* SETP src0.xxyy, GT, {0}.x */
+         if (!submit_op2( emit, setp_token, pred_reg,
+                          predsrc, 
+                          swizzle(zero, 0, 0, 0, 0) ))
+            return FALSE;
+         
+         /* MOV dst, fail */
+         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst,
+                          swizzle(zero, 3, 0, 0, 3 )))
+             return FALSE;
+
+         /* MOV dst.yz, tmp (predicated)
+          *
+          * Note that the predicate reg (and possible modifiers) is passed
+          * as the first source argument.
+          */
+         if (dst.mask & TGSI_WRITEMASK_YZ) {
+            mov_token.predicated = 1;
+            if (!submit_op2( emit, mov_token,
+                             writemask(dst, TGSI_WRITEMASK_YZ),
+                             src( pred_reg ), src( tmp ) ))
+               return FALSE;
+         }
+      }
+   }
+
+   return TRUE;
+}
+
+
+
+
+static boolean emit_ex2( struct svga_shader_emitter *emit,
+                         const struct tgsi_full_instruction *insn )
+{
+   SVGA3dShaderInstToken inst;
+   SVGA3dShaderDestToken dst;
+   struct src_register src0;
+
+   inst = inst_token( SVGA3DOP_EXP );
+   dst = translate_dst_register( emit, insn, 0 );
+   src0 = translate_src_register( emit, &insn->Src[0] );
+   src0 = scalar( src0, TGSI_SWIZZLE_X );
+
+   if (dst.mask != TGSI_WRITEMASK_XYZW) {
+      SVGA3dShaderDestToken tmp = get_temp( emit );
+
+      if (!submit_op1( emit, inst, tmp, src0 ))
+         return FALSE;
+
+      return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
+                         dst,
+                         scalar( src( tmp ), TGSI_SWIZZLE_X ) );
+   }
+
+   return submit_op1( emit, inst, dst, src0 );
+}
+
+
+static boolean emit_log(struct svga_shader_emitter *emit,
+                        const struct tgsi_full_instruction *insn)
+{
+   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
+   struct src_register src0 =
+      translate_src_register( emit, &insn->Src[0] );
+   struct src_register zero = get_zero_immediate( emit );
+   SVGA3dShaderDestToken abs_tmp;
+   struct src_register abs_src0;
+   SVGA3dShaderDestToken log2_abs;
+
+   if (dst.mask & TGSI_WRITEMASK_Z)
+      log2_abs = dst;
+   else if (dst.mask & TGSI_WRITEMASK_XY)
+      log2_abs = get_temp( emit );
+
+   /* If z is being written, fill it with log2( abs( src0 ) ).
+    */
+   if (dst.mask & TGSI_WRITEMASK_XYZ) {
+      if (!src0.base.srcMod || src0.base.srcMod == SVGA3DSRCMOD_ABS)
+         abs_src0 = src0;
+      else {
+         abs_tmp = get_temp( emit );
+
+         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
+                          abs_tmp,
+                          src0 ) )
+            return FALSE;
+
+         abs_src0 = src( abs_tmp );
+      }
+
+      abs_src0 = absolute( scalar( abs_src0, TGSI_SWIZZLE_X ) );
+
+      if (!submit_op1( emit, inst_token( SVGA3DOP_LOG ),
+                       writemask( log2_abs, TGSI_WRITEMASK_Z ),
+                       abs_src0 ) )
+         return FALSE;
+   }
+
+   if (dst.mask & TGSI_WRITEMASK_XY) {
+      SVGA3dShaderDestToken floor_log2;
+
+      if (dst.mask & TGSI_WRITEMASK_X)
+         floor_log2 = dst;
+      else
+         floor_log2 = get_temp( emit );
+
+      /* If x is being written, fill it with floor( log2( abs( src0 ) ) ).
+       */
+      if (!submit_op1( emit, inst_token( SVGA3DOP_FRC ),
+                       writemask( floor_log2, TGSI_WRITEMASK_X ),
+                       scalar( src( log2_abs ), TGSI_SWIZZLE_Z ) ) )
+         return FALSE;
+
+      if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ),
+                       writemask( floor_log2, TGSI_WRITEMASK_X ),
+                       scalar( src( log2_abs ), TGSI_SWIZZLE_Z ),
+                       negate( src( floor_log2 ) ) ) )
+         return FALSE;
+
+      /* If y is being written, fill it with
+       * abs ( src0 ) / ( 2 ^ floor( log2( abs( src0 ) ) ) ).
+       */
+      if (dst.mask & TGSI_WRITEMASK_Y) {
+         if (!submit_op1( emit, inst_token( SVGA3DOP_EXP ),
+                          writemask( dst, TGSI_WRITEMASK_Y ),
+                          negate( scalar( src( floor_log2 ),
+                                          TGSI_SWIZZLE_X ) ) ) )
+            return FALSE;
+
+         if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
+                          writemask( dst, TGSI_WRITEMASK_Y ),
+                          src( dst ),
+                          abs_src0 ) )
+            return FALSE;
+      }
+
+      if (!(dst.mask & TGSI_WRITEMASK_X))
+         release_temp( emit, floor_log2 );
+
+      if (!(dst.mask & TGSI_WRITEMASK_Z))
+         release_temp( emit, log2_abs );
+   }
+
+   if (dst.mask & TGSI_WRITEMASK_XYZ && src0.base.srcMod &&
+       src0.base.srcMod != SVGA3DSRCMOD_ABS)
+      release_temp( emit, abs_tmp );
+
+   /* If w is being written, fill it with one.
+    */
+   if (dst.mask & TGSI_WRITEMASK_W) {
+      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
+                       writemask(dst, TGSI_WRITEMASK_W),
+                       scalar( zero, TGSI_SWIZZLE_W ) ))
+         return FALSE;
+   }
+
+   return TRUE;
+}
+
+
+static boolean emit_bgnsub( struct svga_shader_emitter *emit,
+                           unsigned position,
+                           const struct tgsi_full_instruction *insn )
+{
+   unsigned i;
+
+   /* Note that we've finished the main function and are now emitting
+    * subroutines.  This affects how we terminate the generated
+    * shader.
+    */
+   emit->in_main_func = FALSE;
+   
+   for (i = 0; i < emit->nr_labels; i++) {
+      if (emit->label[i] == position) {
+         return (emit_instruction( emit, inst_token( SVGA3DOP_RET ) ) &&
+                 emit_instruction( emit, inst_token( SVGA3DOP_LABEL ) ) &&
+                 emit_src( emit, src_register( SVGA3DREG_LABEL, i )));
+      }
+   }
+
+   assert(0);
+   return TRUE;
+}
+
+static boolean emit_call( struct svga_shader_emitter *emit,
+                           const struct tgsi_full_instruction *insn )
+{
+   unsigned position = insn->Label.Label;
+   unsigned i;
+   
+   for (i = 0; i < emit->nr_labels; i++) {
+      if (emit->label[i] == position) 
+         break;
+   }
+
+   if (emit->nr_labels == Elements(emit->label))
+      return FALSE;
+
+   if (i == emit->nr_labels) {
+      emit->label[i] = position;
+      emit->nr_labels++;
+   }
+
+   return (emit_instruction( emit, inst_token( SVGA3DOP_CALL ) ) &&
+           emit_src( emit, src_register( SVGA3DREG_LABEL, i )));
+}
+
+
+static boolean emit_end( struct svga_shader_emitter *emit )
+{
+   if (emit->unit == PIPE_SHADER_VERTEX) {
+      return emit_vs_postamble( emit );
+   }
+   else {
+      return emit_ps_postamble( emit );
+   }
+}
+
+
+
+static boolean svga_emit_instruction( struct svga_shader_emitter *emit,
+                                      unsigned position,
+                                      const struct tgsi_full_instruction *insn )
+{
+   switch (insn->Instruction.Opcode) {
+
+   case TGSI_OPCODE_ARL:
+      return emit_arl( emit, insn );
+
+   case TGSI_OPCODE_TEX:
+   case TGSI_OPCODE_TXB:
+   case TGSI_OPCODE_TXP:
+   case TGSI_OPCODE_TXL:
+   case TGSI_OPCODE_TXD:
+      return emit_tex( emit, insn );
+
+   case TGSI_OPCODE_BGNSUB:
+      return emit_bgnsub( emit, position, insn );
+
+   case TGSI_OPCODE_ENDSUB:
+      return TRUE;
+
+   case TGSI_OPCODE_CAL:
+      return emit_call( emit, insn );
+
+   case TGSI_OPCODE_FLR:
+   case TGSI_OPCODE_TRUNC:        /* should be TRUNC, not FLR */
+      return emit_floor( emit, insn );
+
+   case TGSI_OPCODE_CMP:
+      return emit_cmp( emit, insn );
+
+   case TGSI_OPCODE_DIV:
+      return emit_div( emit, insn );
+
+   case TGSI_OPCODE_DP2:
+      return emit_dp2( emit, insn );
+
+   case TGSI_OPCODE_DPH:
+      return emit_dph( emit, insn );
+
+   case TGSI_OPCODE_NRM:
+      return emit_nrm( emit, insn );
+
+   case TGSI_OPCODE_COS:
+      return emit_cos( emit, insn );
+
+   case TGSI_OPCODE_SIN:
+      return emit_sin( emit, insn );
+
+   case TGSI_OPCODE_SCS:
+      return emit_sincos( emit, insn );
+
+   case TGSI_OPCODE_END:
+      /* TGSI always finishes the main func with an END */
+      return emit_end( emit );
+
+   case TGSI_OPCODE_KIL:
+      return emit_kil( emit, insn );
+
+      /* Selection opcodes.  The underlying language is fairly
+       * non-orthogonal about these.
+       */
+   case TGSI_OPCODE_SEQ:
+      return emit_select_op( emit, PIPE_FUNC_EQUAL, insn );
+
+   case TGSI_OPCODE_SNE:
+      return emit_select_op( emit, PIPE_FUNC_NOTEQUAL, insn );
+
+   case TGSI_OPCODE_SGT:
+      return emit_select_op( emit, PIPE_FUNC_GREATER, insn );
+
+   case TGSI_OPCODE_SGE:
+      return emit_select_op( emit, PIPE_FUNC_GEQUAL, insn );
+
+   case TGSI_OPCODE_SLT:
+      return emit_select_op( emit, PIPE_FUNC_LESS, insn );
+
+   case TGSI_OPCODE_SLE:
+      return emit_select_op( emit, PIPE_FUNC_LEQUAL, insn );
+
+   case TGSI_OPCODE_SUB:
+      return emit_sub( emit, insn );
+
+   case TGSI_OPCODE_POW:
+      return emit_pow( emit, insn );
+
+   case TGSI_OPCODE_EX2:
+      return emit_ex2( emit, insn );
+
+   case TGSI_OPCODE_EXP:
+      return emit_exp( emit, insn );
+
+   case TGSI_OPCODE_LOG:
+      return emit_log( emit, insn );
+
+   case TGSI_OPCODE_LG2:
+      return emit_scalar_op1( emit, SVGA3DOP_LOG, insn );
+
+   case TGSI_OPCODE_RSQ:
+      return emit_scalar_op1( emit, SVGA3DOP_RSQ, insn );
+
+   case TGSI_OPCODE_RCP:
+      return emit_scalar_op1( emit, SVGA3DOP_RCP, insn );
+
+   case TGSI_OPCODE_CONT:
+   case TGSI_OPCODE_RET:
+      /* This is a noop -- we tell mesa that we can't support RET
+       * within a function (early return), so this will always be
+       * followed by an ENDSUB.
+       */
+      return TRUE;
+
+      /* These aren't actually used by any of the frontends we care
+       * about:
+       */
+   case TGSI_OPCODE_CLAMP:
+   case TGSI_OPCODE_ROUND:
+   case TGSI_OPCODE_AND:
+   case TGSI_OPCODE_OR:
+   case TGSI_OPCODE_I2F:
+   case TGSI_OPCODE_NOT:
+   case TGSI_OPCODE_SHL:
+   case TGSI_OPCODE_ISHR:
+   case TGSI_OPCODE_XOR:
+      return FALSE;
+
+   case TGSI_OPCODE_IF:
+      return emit_if( emit, insn );
+   case TGSI_OPCODE_ELSE:
+      return emit_else( emit, insn );
+   case TGSI_OPCODE_ENDIF:
+      return emit_endif( emit, insn );
+
+   case TGSI_OPCODE_BGNLOOP:
+      return emit_bgnloop2( emit, insn );
+   case TGSI_OPCODE_ENDLOOP:
+      return emit_endloop2( emit, insn );
+   case TGSI_OPCODE_BRK:
+      return emit_brk( emit, insn );
+
+   case TGSI_OPCODE_XPD:
+      return emit_xpd( emit, insn );
+
+   case TGSI_OPCODE_KILP:
+      return emit_kilp( emit, insn );
+
+   case TGSI_OPCODE_DST:
+      return emit_dst_insn( emit, insn );
+
+   case TGSI_OPCODE_LIT:
+      return emit_lit( emit, insn );
+
+   case TGSI_OPCODE_LRP:
+      return emit_lrp( emit, insn );
+
+   default: {
+      unsigned opcode = translate_opcode(insn->Instruction.Opcode);
+
+      if (opcode == SVGA3DOP_LAST_INST)
+         return FALSE;
+
+      if (!emit_simple_instruction( emit, opcode, insn ))
+         return FALSE;
+   }
+   }
+
+   return TRUE;
+}
+
+
+static boolean svga_emit_immediate( struct svga_shader_emitter *emit,
+                                    struct tgsi_full_immediate *imm)
+{
+   static const float id[4] = {0,0,0,1};
+   float value[4];
+   unsigned i;
+
+   assert(1 <= imm->Immediate.NrTokens && imm->Immediate.NrTokens <= 5);
+   for (i = 0; i < imm->Immediate.NrTokens - 1; i++)
+      value[i] = imm->u[i].Float;
+
+   for ( ; i < 4; i++ )
+      value[i] = id[i];
+
+   return emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT,
+                          emit->imm_start + emit->internal_imm_count++,
+                          value[0], value[1], value[2], value[3]);
+}
+
+static boolean make_immediate( struct svga_shader_emitter *emit,
+                               float a,
+                               float b,
+                               float c,
+                               float d,
+                               struct src_register *out )
+{
+   unsigned idx = emit->nr_hw_const++;
+
+   if (!emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT,
+                        idx, a, b, c, d ))
+      return FALSE;
+
+   *out = src_register( SVGA3DREG_CONST, idx );
+
+   return TRUE;
+}
+
+static boolean emit_vs_preamble( struct svga_shader_emitter *emit )
+{
+   if (!emit->key.vkey.need_prescale) {
+      if (!make_immediate( emit, 0, 0, .5, .5,
+                           &emit->imm_0055))
+         return FALSE;
+   }
+
+   return TRUE;
+}
+
+static boolean emit_ps_preamble( struct svga_shader_emitter *emit )
+{
+   unsigned i;
+
+   /* For SM20, need to initialize the temporaries we're using to hold
+    * color outputs to some value.  Shaders which don't set all of
+    * these values are likely to be rejected by the DX9 runtime.
+    */
+   if (!emit->use_sm30) {
+      struct src_register zero = get_zero_immediate( emit );
+      for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+         if (SVGA3dShaderGetRegType(emit->true_col[i].value) != 0) {
+            
+            if (!submit_op1( emit,
+                             inst_token(SVGA3DOP_MOV),
+                             emit->temp_col[i],
+                             zero ))
+               return FALSE;
+         }
+      }
+   }
+   
+   return TRUE;
+}
+
+static boolean emit_ps_postamble( struct svga_shader_emitter *emit )
+{
+   unsigned i;
+
+   /* PS oDepth is incredibly fragile and it's very hard to catch the
+    * types of usage that break it during shader emit.  Easier just to
+    * redirect the main program to a temporary and then only touch
+    * oDepth with a hand-crafted MOV below.
+    */
+   if (SVGA3dShaderGetRegType(emit->true_pos.value) != 0) {
+
+      if (!submit_op1( emit,
+                       inst_token(SVGA3DOP_MOV),
+                       emit->true_pos,
+                       scalar(src(emit->temp_pos), TGSI_SWIZZLE_Z) ))
+         return FALSE;
+   }
+
+   /* Similarly for SM20 color outputs...  Luckily SM30 isn't so
+    * fragile.
+    */
+   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+      if (SVGA3dShaderGetRegType(emit->true_col[i].value) != 0) {
+
+         if (!submit_op1( emit,
+                          inst_token(SVGA3DOP_MOV),
+                          emit->true_col[i],
+                          src(emit->temp_col[i]) ))
+            return FALSE;
+      }
+   }
+
+   return TRUE;
+}
+
+static boolean emit_vs_postamble( struct svga_shader_emitter *emit )
+{
+   /* PSIZ output is incredibly fragile and it's very hard to catch
+    * the types of usage that break it during shader emit.  Easier
+    * just to redirect the main program to a temporary and then only
+    * touch PSIZ with a hand-crafted MOV below.
+    */
+   if (SVGA3dShaderGetRegType(emit->true_psiz.value) != 0) {
+      
+      if (!submit_op1( emit,
+                       inst_token(SVGA3DOP_MOV),
+                       emit->true_psiz,
+                       scalar(src(emit->temp_psiz), TGSI_SWIZZLE_X) ))
+         return FALSE;
+   }
+
+   /* Need to perform various manipulations on vertex position to cope
+    * with the different GL and D3D clip spaces.
+    */
+   if (emit->key.vkey.need_prescale) {
+      SVGA3dShaderDestToken temp_pos = emit->temp_pos;
+      SVGA3dShaderDestToken pos = emit->true_pos;
+      unsigned offset = emit->info.file_max[TGSI_FILE_CONSTANT] + 1;
+      struct src_register prescale_scale = src_register( SVGA3DREG_CONST, 
+                                                         offset + 0 ); 
+      struct src_register prescale_trans = src_register( SVGA3DREG_CONST, 
+                                                         offset + 1 ); 
+
+      /* MUL temp_pos.xyz,    temp_pos,      prescale.scale
+       * MAD result.position, temp_pos.wwww, prescale.trans, temp_pos
+       *   --> Note that prescale.trans.w == 0
+       */
+      if (!submit_op2( emit, 
+                       inst_token(SVGA3DOP_MUL), 
+                       writemask(temp_pos, TGSI_WRITEMASK_XYZ), 
+                       src(temp_pos),
+                       prescale_scale ))
+         return FALSE;
+
+      if (!submit_op3( emit, 
+                       inst_token(SVGA3DOP_MAD), 
+                       pos, 
+                       swizzle(src(temp_pos), 3, 3, 3, 3),
+                       prescale_trans,
+                       src(temp_pos)))
+         return FALSE;
+   }
+   else {
+      SVGA3dShaderDestToken temp_pos = emit->temp_pos;
+      SVGA3dShaderDestToken pos = emit->true_pos;
+      struct src_register imm_0055 = emit->imm_0055;
+
+      /* Adjust GL clipping coordinate space to hardware (D3D-style):
+       *
+       * DP4 temp_pos.z, {0,0,.5,.5}, temp_pos
+       * MOV result.position, temp_pos 
+       */
+      if (!submit_op2( emit, 
+                       inst_token(SVGA3DOP_DP4), 
+                       writemask(temp_pos, TGSI_WRITEMASK_Z), 
+                       imm_0055, 
+                       src(temp_pos) ))
+         return FALSE;
+
+      if (!submit_op1( emit,
+                       inst_token(SVGA3DOP_MOV),
+                       pos,
+                       src(temp_pos) ))
+         return FALSE;
+   }
+
+   return TRUE;
+}
+
+/*
+  0: IF VFACE :4
+  1:   COLOR = FrontColor;
+  2: ELSE
+  3:   COLOR = BackColor;
+  4: ENDIF
+ */
+static boolean emit_light_twoside( struct svga_shader_emitter *emit )
+{
+   struct src_register vface, zero;
+   struct src_register front[2];
+   struct src_register back[2];
+   SVGA3dShaderDestToken color[2];
+   int count =  emit->internal_color_count;
+   int i;
+   SVGA3dShaderInstToken if_token;
+
+   if (count == 0)
+      return TRUE;
+
+   vface = get_vface( emit );
+   zero = get_zero_immediate( emit );
+
+   /* Can't use get_temp() to allocate the color reg as such
+    * temporaries will be reclaimed after each instruction by the call
+    * to reset_temp_regs().
+    */
+   for (i = 0; i < count; i++) {
+      color[i] = dst_register( SVGA3DREG_TEMP, 
+                               emit->nr_hw_temp++ );
+
+      front[i] = emit->input_map[emit->internal_color_idx[i]];
+
+      /* Back is always the next input:
+       */
+      back[i] = front[i];
+      back[i].base.num = front[i].base.num + 1;
+
+      /* Reassign the input_map to the actual front-face color:
+       */
+      emit->input_map[emit->internal_color_idx[i]] = src(color[i]);
+   }
+   
+   if_token = inst_token( SVGA3DOP_IFC );
+
+   if (emit->key.fkey.front_cw)
+      if_token.control = SVGA3DOPCOMP_GT;
+   else
+      if_token.control = SVGA3DOPCOMP_LT;
+
+   zero = scalar(zero, TGSI_SWIZZLE_X);
+
+   if (!(emit_instruction( emit, if_token ) &&
+         emit_src( emit, vface ) &&
+         emit_src( emit, zero ) ))
+      return FALSE;
+
+   for (i = 0; i < count; i++) {
+      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), color[i], front[i] ))
+         return FALSE;
+   }
+
+   if (!(emit_instruction( emit, inst_token( SVGA3DOP_ELSE))))
+      return FALSE;
+   
+   for (i = 0; i < count; i++) {
+      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), color[i], back[i] ))
+         return FALSE;
+   }
+
+   if (!emit_instruction( emit, inst_token( SVGA3DOP_ENDIF ) ))
+      return FALSE;
+
+   return TRUE;
+}
+
+/*
+  0: SETP_GT TEMP, VFACE, 0
+  where TEMP is a fake frontface register
+ */
+static boolean emit_frontface( struct svga_shader_emitter *emit )
+{
+   struct src_register vface, zero;
+   SVGA3dShaderDestToken temp;
+   struct src_register pass, fail;
+
+   vface = get_vface( emit );
+   zero = get_zero_immediate( emit );
+
+   /* Can't use get_temp() to allocate the fake frontface reg as such
+    * temporaries will be reclaimed after each instruction by the call
+    * to reset_temp_regs().
+    */
+   temp = dst_register( SVGA3DREG_TEMP,
+                        emit->nr_hw_temp++ );
+
+   if (emit->key.fkey.front_cw) {
+      pass = scalar( zero, TGSI_SWIZZLE_W );
+      fail = scalar( zero, TGSI_SWIZZLE_X );
+   } else {
+      pass = scalar( zero, TGSI_SWIZZLE_X );
+      fail = scalar( zero, TGSI_SWIZZLE_W );
+   }
+
+   if (!emit_conditional(emit, PIPE_FUNC_GREATER,
+                         temp, vface, scalar( zero, TGSI_SWIZZLE_X ),
+                         pass, fail))
+      return FALSE;
+
+   /* Reassign the input_map to the actual front-face color:
+    */
+   emit->input_map[emit->internal_frontface_idx] = src(temp);
+
+   return TRUE;
+}
+
+static INLINE boolean
+needs_to_create_zero( struct svga_shader_emitter *emit )
+{
+   int i;
+
+   if (emit->unit == PIPE_SHADER_FRAGMENT) {
+      if (!emit->use_sm30)
+         return TRUE;
+
+      if (emit->key.fkey.light_twoside)
+         return TRUE;
+
+      if (emit->emit_frontface)
+         return TRUE;
+
+      if (emit->info.opcode_count[TGSI_OPCODE_DST] >= 1 ||
+          emit->info.opcode_count[TGSI_OPCODE_LIT] >= 1)
+         return TRUE;
+   }
+
+   if (emit->info.opcode_count[TGSI_OPCODE_IF] >= 1 ||
+       emit->info.opcode_count[TGSI_OPCODE_SGE] >= 1 ||
+       emit->info.opcode_count[TGSI_OPCODE_SGT] >= 1 ||
+       emit->info.opcode_count[TGSI_OPCODE_SLE] >= 1 ||
+       emit->info.opcode_count[TGSI_OPCODE_SLT] >= 1 ||
+       emit->info.opcode_count[TGSI_OPCODE_SNE] >= 1 ||
+       emit->info.opcode_count[TGSI_OPCODE_SEQ] >= 1 ||
+       emit->info.opcode_count[TGSI_OPCODE_EXP] >= 1 ||
+       emit->info.opcode_count[TGSI_OPCODE_LOG] >= 1 ||
+       emit->info.opcode_count[TGSI_OPCODE_XPD] >= 1 ||
+       emit->info.opcode_count[TGSI_OPCODE_KILP] >= 1)
+      return TRUE;
+
+   for (i = 0; i < emit->key.fkey.num_textures; i++) {
+      if (emit->key.fkey.tex[i].compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
+         return TRUE;
+   }
+
+   return FALSE;
+}
+
+static INLINE boolean
+needs_to_create_loop_const( struct svga_shader_emitter *emit )
+{
+   return (emit->info.opcode_count[TGSI_OPCODE_BGNLOOP] >= 1);
+}
+
+static INLINE boolean
+needs_to_create_sincos_consts( struct svga_shader_emitter *emit )
+{
+   return !emit->use_sm30 && (emit->info.opcode_count[TGSI_OPCODE_SIN] >= 1 ||
+                              emit->info.opcode_count[TGSI_OPCODE_COS] >= 1 ||
+                              emit->info.opcode_count[TGSI_OPCODE_SCS] >= 1);
+}
+
+static INLINE boolean
+needs_to_create_arl_consts( struct svga_shader_emitter *emit )
+{
+   return (emit->num_arl_consts > 0);
+}
+
+static INLINE boolean
+pre_parse_add_indirect( struct svga_shader_emitter *emit,
+                        int num, int current_arl)
+{
+   int i;
+   assert(num < 0);
+
+   for (i = 0; i < emit->num_arl_consts; ++i) {
+      if (emit->arl_consts[i].arl_num == current_arl)
+         break;
+   }
+   /* new entry */
+   if (emit->num_arl_consts == i) {
+      ++emit->num_arl_consts;
+   }
+   emit->arl_consts[i].number = (emit->arl_consts[i].number > num) ?
+                                num :
+                                emit->arl_consts[i].number;
+   emit->arl_consts[i].arl_num = current_arl;
+   return TRUE;
+}
+
+static boolean
+pre_parse_instruction( struct svga_shader_emitter *emit,
+                       const struct tgsi_full_instruction *insn,
+                       int current_arl)
+{
+   if (insn->Src[0].Register.Indirect &&
+       insn->Src[0].Indirect.File == TGSI_FILE_ADDRESS) {
+      const struct tgsi_full_src_register *reg = &insn->Src[0];
+      if (reg->Register.Index < 0) {
+         pre_parse_add_indirect(emit, reg->Register.Index, current_arl);
+      }
+   }
+
+   if (insn->Src[1].Register.Indirect &&
+       insn->Src[1].Indirect.File == TGSI_FILE_ADDRESS) {
+      const struct tgsi_full_src_register *reg = &insn->Src[1];
+      if (reg->Register.Index < 0) {
+         pre_parse_add_indirect(emit, reg->Register.Index, current_arl);
+      }
+   }
+
+   if (insn->Src[2].Register.Indirect &&
+       insn->Src[2].Indirect.File == TGSI_FILE_ADDRESS) {
+      const struct tgsi_full_src_register *reg = &insn->Src[2];
+      if (reg->Register.Index < 0) {
+         pre_parse_add_indirect(emit, reg->Register.Index, current_arl);
+      }
+   }
+
+   return TRUE;
+}
+
+static boolean
+pre_parse_tokens( struct svga_shader_emitter *emit,
+                  const struct tgsi_token *tokens )
+{
+   struct tgsi_parse_context parse;
+   int current_arl = 0;
+
+   tgsi_parse_init( &parse, tokens );
+
+   while (!tgsi_parse_end_of_tokens( &parse )) {
+      tgsi_parse_token( &parse );
+      switch (parse.FullToken.Token.Type) {
+      case TGSI_TOKEN_TYPE_IMMEDIATE:
+      case TGSI_TOKEN_TYPE_DECLARATION:
+         break;
+      case TGSI_TOKEN_TYPE_INSTRUCTION:
+         if (parse.FullToken.FullInstruction.Instruction.Opcode ==
+             TGSI_OPCODE_ARL) {
+            ++current_arl;
+         }
+         if (!pre_parse_instruction( emit, &parse.FullToken.FullInstruction,
+                                     current_arl ))
+            return FALSE;
+         break;
+      default:
+         break;
+      }
+
+   }
+   return TRUE;
+}
+
+static boolean svga_shader_emit_helpers( struct svga_shader_emitter *emit )
+
+{
+   if (needs_to_create_zero( emit )) {
+      create_zero_immediate( emit );
+   }
+   if (needs_to_create_loop_const( emit )) {
+      create_loop_const( emit );
+   }
+   if (needs_to_create_sincos_consts( emit )) {
+      create_sincos_consts( emit );
+   }
+   if (needs_to_create_arl_consts( emit )) {
+      create_arl_consts( emit );
+   }
+
+   if (emit->unit == PIPE_SHADER_FRAGMENT) {
+      if (!emit_ps_preamble( emit ))
+         return FALSE;
+
+      if (emit->key.fkey.light_twoside) {
+         if (!emit_light_twoside( emit ))
+            return FALSE;
+      }
+      if (emit->emit_frontface) {
+         if (!emit_frontface( emit ))
+            return FALSE;
+      }
+   }
+
+   return TRUE;
+}
+
+boolean svga_shader_emit_instructions( struct svga_shader_emitter *emit,
+                                       const struct tgsi_token *tokens )
+{
+   struct tgsi_parse_context parse;
+   boolean ret = TRUE;
+   boolean helpers_emitted = FALSE;
+   unsigned line_nr = 0;
+
+   tgsi_parse_init( &parse, tokens );
+   emit->internal_imm_count = 0;
+
+   if (emit->unit == PIPE_SHADER_VERTEX) {
+      ret = emit_vs_preamble( emit );
+      if (!ret)
+         goto done;
+   }
+
+   pre_parse_tokens(emit, tokens);
+
+   while (!tgsi_parse_end_of_tokens( &parse )) {
+      tgsi_parse_token( &parse );
+
+      switch (parse.FullToken.Token.Type) {
+      case TGSI_TOKEN_TYPE_IMMEDIATE:
+         ret = svga_emit_immediate( emit, &parse.FullToken.FullImmediate );
+         if (!ret)
+            goto done;
+         break;
+
+      case TGSI_TOKEN_TYPE_DECLARATION:
+         if (emit->use_sm30)
+            ret = svga_translate_decl_sm30( emit, &parse.FullToken.FullDeclaration );
+         else
+            ret = svga_translate_decl_sm20( emit, &parse.FullToken.FullDeclaration );
+         if (!ret)
+            goto done;
+         break;
+         
+      case TGSI_TOKEN_TYPE_INSTRUCTION:
+         if (!helpers_emitted) {
+            if (!svga_shader_emit_helpers( emit ))
+               goto done;
+            helpers_emitted = TRUE;
+         }
+         ret = svga_emit_instruction( emit, 
+                                      line_nr++,
+                                      &parse.FullToken.FullInstruction );
+         if (!ret)
+            goto done;
+         break;
+      default:
+         break;
+      }
+      
+      reset_temp_regs( emit );
+   }
+
+   /* Need to terminate the current subroutine.  Note that the
+    * hardware doesn't tolerate shaders without sub-routines
+    * terminating with RET+END.
+    */
+   if (!emit->in_main_func) {
+      ret = emit_instruction( emit, inst_token( SVGA3DOP_RET ) );
+      if (!ret)
+         goto done;
+   }
+
+   /* Need to terminate the whole shader:
+    */
+   ret = emit_instruction( emit, inst_token( SVGA3DOP_END ) );
+   if (!ret)
+      goto done;
+
+done:
+   assert(ret);
+   tgsi_parse_free( &parse );
+   return ret;
+}
+
diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h
new file mode 100644
index 0000000..59f299c
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -0,0 +1,299 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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
+ * VMware SVGA specific winsys interface.
+ * 
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ * 
+ * Documentation taken from the VMware SVGA DDK.
+ */
+
+#ifndef SVGA_WINSYS_H_
+#define SVGA_WINSYS_H_
+
+
+#include "svga_types.h"
+#include "svga_reg.h"
+#include "svga3d_reg.h"
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_defines.h"
+
+
+struct svga_winsys_screen;
+struct svga_winsys_buffer;
+struct pipe_screen;
+struct pipe_context;
+struct pipe_fence_handle;
+struct pipe_texture;
+struct svga_region;
+
+
+#define SVGA_BUFFER_USAGE_PINNED  (PIPE_BUFFER_USAGE_CUSTOM << 0)
+#define SVGA_BUFFER_USAGE_WRAPPED (PIPE_BUFFER_USAGE_CUSTOM << 1)
+
+
+/** Opaque surface handle */
+struct svga_winsys_surface;
+
+/** Opaque buffer handle */
+struct svga_winsys_handle;
+
+
+/**
+ * SVGA per-context winsys interface.
+ */
+struct svga_winsys_context
+{
+   void
+   (*destroy)(struct svga_winsys_context *swc);
+
+   void *       
+   (*reserve)(struct svga_winsys_context *swc, 
+	      uint32_t nr_bytes, uint32_t nr_relocs );
+   
+   /**
+    * Emit a relocation for a host surface.
+    * 
+    * @param flags PIPE_BUFFER_USAGE_GPU_READ/WRITE
+    * 
+    * NOTE: Order of this call does matter. It should be the same order
+    * as relocations appear in the command buffer.
+    */
+   void
+   (*surface_relocation)(struct svga_winsys_context *swc, 
+	                 uint32 *sid, 
+	                 struct svga_winsys_surface *surface,
+	                 unsigned flags);
+   
+   /**
+    * Emit a relocation for a guest memory region.
+    * 
+    * @param flags PIPE_BUFFER_USAGE_GPU_READ/WRITE
+    * 
+    * NOTE: Order of this call does matter. It should be the same order
+    * as relocations appear in the command buffer.
+    */
+   void
+   (*region_relocation)(struct svga_winsys_context *swc, 
+	                struct SVGAGuestPtr *ptr, 
+	                struct svga_winsys_buffer *buffer,
+	                uint32 offset,
+                        unsigned flags);
+
+   void
+   (*commit)(struct svga_winsys_context *swc);
+   
+   enum pipe_error
+   (*flush)(struct svga_winsys_context *swc, 
+	    struct pipe_fence_handle **pfence);
+
+   /** 
+    * Context ID used to fill in the commands
+    * 
+    * Context IDs are arbitrary small non-negative integers,
+    * global to the entire SVGA device.
+    */
+   uint32 cid;
+};
+
+
+/**
+ * SVGA per-screen winsys interface.
+ */
+struct svga_winsys_screen
+{
+   void
+   (*destroy)(struct svga_winsys_screen *sws);
+   
+   boolean
+   (*get_cap)(struct svga_winsys_screen *sws,
+              SVGA3dDevCapIndex index,
+              SVGA3dDevCapResult *result);
+   
+   /**
+    * Create a new context.
+    *
+    * Context objects encapsulate all render state, and shader
+    * objects are per-context.
+    *
+    * Surfaces are not per-context. The same surface can be shared
+    * between multiple contexts, and surface operations can occur
+    * without a context.
+    */
+   struct svga_winsys_context *
+   (*context_create)(struct svga_winsys_screen *sws);
+   
+   
+   /**
+    * This creates a "surface" object in the SVGA3D device,
+    * and returns the surface ID (sid). Surfaces are generic
+    * containers for host VRAM objects like textures, vertex
+    * buffers, and depth/stencil buffers.
+    *
+    * Surfaces are hierarchial:
+    *
+    * - Surface may have multiple faces (for cube maps)
+    *
+    * - Each face has a list of mipmap levels
+    *
+    * - Each mipmap image may have multiple volume
+    *   slices, if the image is three dimensional.
+    *
+    * - Each slice is a 2D array of 'blocks'
+    *
+    * - Each block may be one or more pixels.
+    *   (Usually 1, more for DXT or YUV formats.)
+    *
+    * Surfaces are generic host VRAM objects. The SVGA3D device
+    * may optimize surfaces according to the format they were
+    * created with, but this format does not limit the ways in
+    * which the surface may be used. For example, a depth surface
+    * can be used as a texture, or a floating point image may
+    * be used as a vertex buffer. Some surface usages may be
+    * lower performance, due to software emulation, but any
+    * usage should work with any surface.
+    */
+   struct svga_winsys_surface *
+   (*surface_create)(struct svga_winsys_screen *sws,
+                     SVGA3dSurfaceFlags flags,
+                     SVGA3dSurfaceFormat format,
+                     SVGA3dSize size,
+                     uint32 numFaces,
+                     uint32 numMipLevels);
+
+   /**
+    * Whether this surface is sitting in a validate list
+    */
+   boolean
+   (*surface_is_flushed)(struct svga_winsys_screen *sws,
+                         struct svga_winsys_surface *surface);
+
+   /**
+    * Reference a SVGA3D surface object. This allows sharing of a
+    * surface between different objects.
+    */
+   void 
+   (*surface_reference)(struct svga_winsys_screen *sws,
+			struct svga_winsys_surface **pdst,
+			struct svga_winsys_surface *src);
+
+   /**
+    * Buffer management. Buffer attributes are mostly fixed over its lifetime.
+    *
+    * Remember that gallium gets to choose the interface it needs, and the
+    * window systems must then implement that interface (rather than the
+    * other way around...).
+    *
+    * usage is a bitmask of PIPE_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This
+    * usage argument is only an optimization hint, not a guarantee, therefore 
+    * proper behavior must be observed in all circumstances.
+    *
+    * alignment indicates the client's alignment requirements, eg for
+    * SSE instructions.
+    */
+   struct svga_winsys_buffer *
+   (*buffer_create)( struct svga_winsys_screen *sws, 
+	             unsigned alignment, 
+	             unsigned usage,
+	             unsigned size );
+
+   /** 
+    * Map the entire data store of a buffer object into the client's address.
+    * flags is a bitmask of:
+    * - PIPE_BUFFER_USAGE_CPU_READ/WRITE
+    * - PIPE_BUFFER_USAGE_DONTBLOCK
+    * - PIPE_BUFFER_USAGE_UNSYNCHRONIZED
+    */
+   void *
+   (*buffer_map)( struct svga_winsys_screen *sws, 
+	          struct svga_winsys_buffer *buf,
+		  unsigned usage );
+   
+   void 
+   (*buffer_unmap)( struct svga_winsys_screen *sws, 
+                    struct svga_winsys_buffer *buf );
+
+   void 
+   (*buffer_destroy)( struct svga_winsys_screen *sws,
+	              struct svga_winsys_buffer *buf );
+
+
+   /**
+    * Reference a fence object.
+    */
+   void
+   (*fence_reference)( struct svga_winsys_screen *sws,
+                       struct pipe_fence_handle **pdst,
+                       struct pipe_fence_handle *src );
+
+   /**
+    * Checks whether the fence has been signalled.
+    * \param flags  driver-specific meaning
+    * \return zero on success.
+    */
+   int (*fence_signalled)( struct svga_winsys_screen *sws,
+                           struct pipe_fence_handle *fence,
+                           unsigned flag );
+
+   /**
+    * Wait for the fence to finish.
+    * \param flags  driver-specific meaning
+    * \return zero on success.
+    */
+   int (*fence_finish)( struct svga_winsys_screen *sws,
+                        struct pipe_fence_handle *fence,
+                        unsigned flag );
+
+};
+
+
+struct pipe_context *
+svga_context_create(struct pipe_screen *screen);
+
+struct pipe_screen *
+svga_screen_create(struct svga_winsys_screen *sws);
+
+struct svga_winsys_screen *
+svga_winsys_screen(struct pipe_screen *screen);
+
+struct pipe_buffer *
+svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
+				enum SVGA3dSurfaceFormat format,
+				struct svga_winsys_surface *srf);
+
+struct svga_winsys_surface *
+svga_screen_texture_get_winsys_surface(struct pipe_texture *texture);
+struct svga_winsys_surface *
+svga_screen_buffer_get_winsys_surface(struct pipe_buffer *buffer);
+
+boolean
+svga_screen_buffer_from_texture(struct pipe_texture *texture,
+				struct pipe_buffer **buffer,
+				unsigned *stride);
+
+#endif /* SVGA_WINSYS_H_ */
diff --git a/src/gallium/drivers/svga/svgadump/svga_dump.c b/src/gallium/drivers/svga/svgadump/svga_dump.c
new file mode 100644
index 0000000..d59fb89
--- /dev/null
+++ b/src/gallium/drivers/svga/svgadump/svga_dump.c
@@ -0,0 +1,1784 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 SVGA commands.
+ *
+ * Generated automatically from svga3d_reg.h by svga_dump.py.
+ */
+
+#include "svga_types.h"
+#include "svga_shader_dump.h"
+#include "svga3d_reg.h"
+
+#include "util/u_debug.h"
+#include "svga_dump.h"
+
+static void
+dump_SVGA3dVertexDecl(const SVGA3dVertexDecl *cmd)
+{
+   switch((*cmd).identity.type) {
+   case SVGA3D_DECLTYPE_FLOAT1:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_FLOAT1\n");
+      break;
+   case SVGA3D_DECLTYPE_FLOAT2:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_FLOAT2\n");
+      break;
+   case SVGA3D_DECLTYPE_FLOAT3:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_FLOAT3\n");
+      break;
+   case SVGA3D_DECLTYPE_FLOAT4:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_FLOAT4\n");
+      break;
+   case SVGA3D_DECLTYPE_D3DCOLOR:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_D3DCOLOR\n");
+      break;
+   case SVGA3D_DECLTYPE_UBYTE4:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_UBYTE4\n");
+      break;
+   case SVGA3D_DECLTYPE_SHORT2:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_SHORT2\n");
+      break;
+   case SVGA3D_DECLTYPE_SHORT4:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_SHORT4\n");
+      break;
+   case SVGA3D_DECLTYPE_UBYTE4N:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_UBYTE4N\n");
+      break;
+   case SVGA3D_DECLTYPE_SHORT2N:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_SHORT2N\n");
+      break;
+   case SVGA3D_DECLTYPE_SHORT4N:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_SHORT4N\n");
+      break;
+   case SVGA3D_DECLTYPE_USHORT2N:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_USHORT2N\n");
+      break;
+   case SVGA3D_DECLTYPE_USHORT4N:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_USHORT4N\n");
+      break;
+   case SVGA3D_DECLTYPE_UDEC3:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_UDEC3\n");
+      break;
+   case SVGA3D_DECLTYPE_DEC3N:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_DEC3N\n");
+      break;
+   case SVGA3D_DECLTYPE_FLOAT16_2:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_FLOAT16_2\n");
+      break;
+   case SVGA3D_DECLTYPE_FLOAT16_4:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_FLOAT16_4\n");
+      break;
+   case SVGA3D_DECLTYPE_MAX:
+      _debug_printf("\t\t.identity.type = SVGA3D_DECLTYPE_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.identity.type = %i\n", (*cmd).identity.type);
+      break;
+   }
+   switch((*cmd).identity.method) {
+   case SVGA3D_DECLMETHOD_DEFAULT:
+      _debug_printf("\t\t.identity.method = SVGA3D_DECLMETHOD_DEFAULT\n");
+      break;
+   case SVGA3D_DECLMETHOD_PARTIALU:
+      _debug_printf("\t\t.identity.method = SVGA3D_DECLMETHOD_PARTIALU\n");
+      break;
+   case SVGA3D_DECLMETHOD_PARTIALV:
+      _debug_printf("\t\t.identity.method = SVGA3D_DECLMETHOD_PARTIALV\n");
+      break;
+   case SVGA3D_DECLMETHOD_CROSSUV:
+      _debug_printf("\t\t.identity.method = SVGA3D_DECLMETHOD_CROSSUV\n");
+      break;
+   case SVGA3D_DECLMETHOD_UV:
+      _debug_printf("\t\t.identity.method = SVGA3D_DECLMETHOD_UV\n");
+      break;
+   case SVGA3D_DECLMETHOD_LOOKUP:
+      _debug_printf("\t\t.identity.method = SVGA3D_DECLMETHOD_LOOKUP\n");
+      break;
+   case SVGA3D_DECLMETHOD_LOOKUPPRESAMPLED:
+      _debug_printf("\t\t.identity.method = SVGA3D_DECLMETHOD_LOOKUPPRESAMPLED\n");
+      break;
+   default:
+      _debug_printf("\t\t.identity.method = %i\n", (*cmd).identity.method);
+      break;
+   }
+   switch((*cmd).identity.usage) {
+   case SVGA3D_DECLUSAGE_POSITION:
+      _debug_printf("\t\t.identity.usage = SVGA3D_DECLUSAGE_POSITION\n");
+      break;
+   case SVGA3D_DECLUSAGE_BLENDWEIGHT:
+      _debug_printf("\t\t.identity.usage = SVGA3D_DECLUSAGE_BLENDWEIGHT\n");
+      break;
+   case SVGA3D_DECLUSAGE_BLENDINDICES:
+      _debug_printf("\t\t.identity.usage = SVGA3D_DECLUSAGE_BLENDINDICES\n");
+      break;
+   case SVGA3D_DECLUSAGE_NORMAL:
+      _debug_printf("\t\t.identity.usage = SVGA3D_DECLUSAGE_NORMAL\n");
+      break;
+   case SVGA3D_DECLUSAGE_PSIZE:
+      _debug_printf("\t\t.identity.usage = SVGA3D_DECLUSAGE_PSIZE\n");
+      break;
+   case SVGA3D_DECLUSAGE_TEXCOORD:
+      _debug_printf("\t\t.identity.usage = SVGA3D_DECLUSAGE_TEXCOORD\n");
+      break;
+   case SVGA3D_DECLUSAGE_TANGENT:
+      _debug_printf("\t\t.identity.usage = SVGA3D_DECLUSAGE_TANGENT\n");
+      break;
+   case SVGA3D_DECLUSAGE_BINORMAL:
+      _debug_printf("\t\t.identity.usage = SVGA3D_DECLUSAGE_BINORMAL\n");
+      break;
+   case SVGA3D_DECLUSAGE_TESSFACTOR:
+      _debug_printf("\t\t.identity.usage = SVGA3D_DECLUSAGE_TESSFACTOR\n");
+      break;
+   case SVGA3D_DECLUSAGE_POSITIONT:
+      _debug_printf("\t\t.identity.usage = SVGA3D_DECLUSAGE_POSITIONT\n");
+      break;
+   case SVGA3D_DECLUSAGE_COLOR:
+      _debug_printf("\t\t.identity.usage = SVGA3D_DECLUSAGE_COLOR\n");
+      break;
+   case SVGA3D_DECLUSAGE_FOG:
+      _debug_printf("\t\t.identity.usage = SVGA3D_DECLUSAGE_FOG\n");
+      break;
+   case SVGA3D_DECLUSAGE_DEPTH:
+      _debug_printf("\t\t.identity.usage = SVGA3D_DECLUSAGE_DEPTH\n");
+      break;
+   case SVGA3D_DECLUSAGE_SAMPLE:
+      _debug_printf("\t\t.identity.usage = SVGA3D_DECLUSAGE_SAMPLE\n");
+      break;
+   case SVGA3D_DECLUSAGE_MAX:
+      _debug_printf("\t\t.identity.usage = SVGA3D_DECLUSAGE_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.identity.usage = %i\n", (*cmd).identity.usage);
+      break;
+   }
+   _debug_printf("\t\t.identity.usageIndex = %u\n", (*cmd).identity.usageIndex);
+   _debug_printf("\t\t.array.surfaceId = %u\n", (*cmd).array.surfaceId);
+   _debug_printf("\t\t.array.offset = %u\n", (*cmd).array.offset);
+   _debug_printf("\t\t.array.stride = %u\n", (*cmd).array.stride);
+   _debug_printf("\t\t.rangeHint.first = %u\n", (*cmd).rangeHint.first);
+   _debug_printf("\t\t.rangeHint.last = %u\n", (*cmd).rangeHint.last);
+}
+
+static void
+dump_SVGA3dTextureState(const SVGA3dTextureState *cmd)
+{
+   _debug_printf("\t\t.stage = %u\n", (*cmd).stage);
+   switch((*cmd).name) {
+   case SVGA3D_TS_INVALID:
+      _debug_printf("\t\t.name = SVGA3D_TS_INVALID\n");
+      break;
+   case SVGA3D_TS_BIND_TEXTURE:
+      _debug_printf("\t\t.name = SVGA3D_TS_BIND_TEXTURE\n");
+      break;
+   case SVGA3D_TS_COLOROP:
+      _debug_printf("\t\t.name = SVGA3D_TS_COLOROP\n");
+      break;
+   case SVGA3D_TS_COLORARG1:
+      _debug_printf("\t\t.name = SVGA3D_TS_COLORARG1\n");
+      break;
+   case SVGA3D_TS_COLORARG2:
+      _debug_printf("\t\t.name = SVGA3D_TS_COLORARG2\n");
+      break;
+   case SVGA3D_TS_ALPHAOP:
+      _debug_printf("\t\t.name = SVGA3D_TS_ALPHAOP\n");
+      break;
+   case SVGA3D_TS_ALPHAARG1:
+      _debug_printf("\t\t.name = SVGA3D_TS_ALPHAARG1\n");
+      break;
+   case SVGA3D_TS_ALPHAARG2:
+      _debug_printf("\t\t.name = SVGA3D_TS_ALPHAARG2\n");
+      break;
+   case SVGA3D_TS_ADDRESSU:
+      _debug_printf("\t\t.name = SVGA3D_TS_ADDRESSU\n");
+      break;
+   case SVGA3D_TS_ADDRESSV:
+      _debug_printf("\t\t.name = SVGA3D_TS_ADDRESSV\n");
+      break;
+   case SVGA3D_TS_MIPFILTER:
+      _debug_printf("\t\t.name = SVGA3D_TS_MIPFILTER\n");
+      break;
+   case SVGA3D_TS_MAGFILTER:
+      _debug_printf("\t\t.name = SVGA3D_TS_MAGFILTER\n");
+      break;
+   case SVGA3D_TS_MINFILTER:
+      _debug_printf("\t\t.name = SVGA3D_TS_MINFILTER\n");
+      break;
+   case SVGA3D_TS_BORDERCOLOR:
+      _debug_printf("\t\t.name = SVGA3D_TS_BORDERCOLOR\n");
+      break;
+   case SVGA3D_TS_TEXCOORDINDEX:
+      _debug_printf("\t\t.name = SVGA3D_TS_TEXCOORDINDEX\n");
+      break;
+   case SVGA3D_TS_TEXTURETRANSFORMFLAGS:
+      _debug_printf("\t\t.name = SVGA3D_TS_TEXTURETRANSFORMFLAGS\n");
+      break;
+   case SVGA3D_TS_TEXCOORDGEN:
+      _debug_printf("\t\t.name = SVGA3D_TS_TEXCOORDGEN\n");
+      break;
+   case SVGA3D_TS_BUMPENVMAT00:
+      _debug_printf("\t\t.name = SVGA3D_TS_BUMPENVMAT00\n");
+      break;
+   case SVGA3D_TS_BUMPENVMAT01:
+      _debug_printf("\t\t.name = SVGA3D_TS_BUMPENVMAT01\n");
+      break;
+   case SVGA3D_TS_BUMPENVMAT10:
+      _debug_printf("\t\t.name = SVGA3D_TS_BUMPENVMAT10\n");
+      break;
+   case SVGA3D_TS_BUMPENVMAT11:
+      _debug_printf("\t\t.name = SVGA3D_TS_BUMPENVMAT11\n");
+      break;
+   case SVGA3D_TS_TEXTURE_MIPMAP_LEVEL:
+      _debug_printf("\t\t.name = SVGA3D_TS_TEXTURE_MIPMAP_LEVEL\n");
+      break;
+   case SVGA3D_TS_TEXTURE_LOD_BIAS:
+      _debug_printf("\t\t.name = SVGA3D_TS_TEXTURE_LOD_BIAS\n");
+      break;
+   case SVGA3D_TS_TEXTURE_ANISOTROPIC_LEVEL:
+      _debug_printf("\t\t.name = SVGA3D_TS_TEXTURE_ANISOTROPIC_LEVEL\n");
+      break;
+   case SVGA3D_TS_ADDRESSW:
+      _debug_printf("\t\t.name = SVGA3D_TS_ADDRESSW\n");
+      break;
+   case SVGA3D_TS_GAMMA:
+      _debug_printf("\t\t.name = SVGA3D_TS_GAMMA\n");
+      break;
+   case SVGA3D_TS_BUMPENVLSCALE:
+      _debug_printf("\t\t.name = SVGA3D_TS_BUMPENVLSCALE\n");
+      break;
+   case SVGA3D_TS_BUMPENVLOFFSET:
+      _debug_printf("\t\t.name = SVGA3D_TS_BUMPENVLOFFSET\n");
+      break;
+   case SVGA3D_TS_COLORARG0:
+      _debug_printf("\t\t.name = SVGA3D_TS_COLORARG0\n");
+      break;
+   case SVGA3D_TS_ALPHAARG0:
+      _debug_printf("\t\t.name = SVGA3D_TS_ALPHAARG0\n");
+      break;
+   case SVGA3D_TS_MAX:
+      _debug_printf("\t\t.name = SVGA3D_TS_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.name = %i\n", (*cmd).name);
+      break;
+   }
+   _debug_printf("\t\t.value = %u\n", (*cmd).value);
+   _debug_printf("\t\t.floatValue = %f\n", (*cmd).floatValue);
+}
+
+static void
+dump_SVGA3dCopyBox(const SVGA3dCopyBox *cmd)
+{
+   _debug_printf("\t\t.x = %u\n", (*cmd).x);
+   _debug_printf("\t\t.y = %u\n", (*cmd).y);
+   _debug_printf("\t\t.z = %u\n", (*cmd).z);
+   _debug_printf("\t\t.w = %u\n", (*cmd).w);
+   _debug_printf("\t\t.h = %u\n", (*cmd).h);
+   _debug_printf("\t\t.d = %u\n", (*cmd).d);
+   _debug_printf("\t\t.srcx = %u\n", (*cmd).srcx);
+   _debug_printf("\t\t.srcy = %u\n", (*cmd).srcy);
+   _debug_printf("\t\t.srcz = %u\n", (*cmd).srcz);
+}
+
+static void
+dump_SVGA3dCmdSetClipPlane(const SVGA3dCmdSetClipPlane *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   _debug_printf("\t\t.index = %u\n", (*cmd).index);
+   _debug_printf("\t\t.plane[0] = %f\n", (*cmd).plane[0]);
+   _debug_printf("\t\t.plane[1] = %f\n", (*cmd).plane[1]);
+   _debug_printf("\t\t.plane[2] = %f\n", (*cmd).plane[2]);
+   _debug_printf("\t\t.plane[3] = %f\n", (*cmd).plane[3]);
+}
+
+static void
+dump_SVGA3dCmdWaitForQuery(const SVGA3dCmdWaitForQuery *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   switch((*cmd).type) {
+   case SVGA3D_QUERYTYPE_OCCLUSION:
+      _debug_printf("\t\t.type = SVGA3D_QUERYTYPE_OCCLUSION\n");
+      break;
+   case SVGA3D_QUERYTYPE_MAX:
+      _debug_printf("\t\t.type = SVGA3D_QUERYTYPE_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.type = %i\n", (*cmd).type);
+      break;
+   }
+   _debug_printf("\t\t.guestResult.gmrId = %u\n", (*cmd).guestResult.gmrId);
+   _debug_printf("\t\t.guestResult.offset = %u\n", (*cmd).guestResult.offset);
+}
+
+static void
+dump_SVGA3dCmdSetRenderTarget(const SVGA3dCmdSetRenderTarget *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   switch((*cmd).type) {
+   case SVGA3D_RT_DEPTH:
+      _debug_printf("\t\t.type = SVGA3D_RT_DEPTH\n");
+      break;
+   case SVGA3D_RT_STENCIL:
+      _debug_printf("\t\t.type = SVGA3D_RT_STENCIL\n");
+      break;
+   default:
+      _debug_printf("\t\t.type = SVGA3D_RT_COLOR%u\n", (*cmd).type - SVGA3D_RT_COLOR0);
+      break;
+   }
+   _debug_printf("\t\t.target.sid = %u\n", (*cmd).target.sid);
+   _debug_printf("\t\t.target.face = %u\n", (*cmd).target.face);
+   _debug_printf("\t\t.target.mipmap = %u\n", (*cmd).target.mipmap);
+}
+
+static void
+dump_SVGA3dCmdSetTextureState(const SVGA3dCmdSetTextureState *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+}
+
+static void
+dump_SVGA3dCmdSurfaceCopy(const SVGA3dCmdSurfaceCopy *cmd)
+{
+   _debug_printf("\t\t.src.sid = %u\n", (*cmd).src.sid);
+   _debug_printf("\t\t.src.face = %u\n", (*cmd).src.face);
+   _debug_printf("\t\t.src.mipmap = %u\n", (*cmd).src.mipmap);
+   _debug_printf("\t\t.dest.sid = %u\n", (*cmd).dest.sid);
+   _debug_printf("\t\t.dest.face = %u\n", (*cmd).dest.face);
+   _debug_printf("\t\t.dest.mipmap = %u\n", (*cmd).dest.mipmap);
+}
+
+static void
+dump_SVGA3dCmdSetMaterial(const SVGA3dCmdSetMaterial *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   switch((*cmd).face) {
+   case SVGA3D_FACE_INVALID:
+      _debug_printf("\t\t.face = SVGA3D_FACE_INVALID\n");
+      break;
+   case SVGA3D_FACE_NONE:
+      _debug_printf("\t\t.face = SVGA3D_FACE_NONE\n");
+      break;
+   case SVGA3D_FACE_FRONT:
+      _debug_printf("\t\t.face = SVGA3D_FACE_FRONT\n");
+      break;
+   case SVGA3D_FACE_BACK:
+      _debug_printf("\t\t.face = SVGA3D_FACE_BACK\n");
+      break;
+   case SVGA3D_FACE_FRONT_BACK:
+      _debug_printf("\t\t.face = SVGA3D_FACE_FRONT_BACK\n");
+      break;
+   case SVGA3D_FACE_MAX:
+      _debug_printf("\t\t.face = SVGA3D_FACE_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.face = %i\n", (*cmd).face);
+      break;
+   }
+   _debug_printf("\t\t.material.diffuse[0] = %f\n", (*cmd).material.diffuse[0]);
+   _debug_printf("\t\t.material.diffuse[1] = %f\n", (*cmd).material.diffuse[1]);
+   _debug_printf("\t\t.material.diffuse[2] = %f\n", (*cmd).material.diffuse[2]);
+   _debug_printf("\t\t.material.diffuse[3] = %f\n", (*cmd).material.diffuse[3]);
+   _debug_printf("\t\t.material.ambient[0] = %f\n", (*cmd).material.ambient[0]);
+   _debug_printf("\t\t.material.ambient[1] = %f\n", (*cmd).material.ambient[1]);
+   _debug_printf("\t\t.material.ambient[2] = %f\n", (*cmd).material.ambient[2]);
+   _debug_printf("\t\t.material.ambient[3] = %f\n", (*cmd).material.ambient[3]);
+   _debug_printf("\t\t.material.specular[0] = %f\n", (*cmd).material.specular[0]);
+   _debug_printf("\t\t.material.specular[1] = %f\n", (*cmd).material.specular[1]);
+   _debug_printf("\t\t.material.specular[2] = %f\n", (*cmd).material.specular[2]);
+   _debug_printf("\t\t.material.specular[3] = %f\n", (*cmd).material.specular[3]);
+   _debug_printf("\t\t.material.emissive[0] = %f\n", (*cmd).material.emissive[0]);
+   _debug_printf("\t\t.material.emissive[1] = %f\n", (*cmd).material.emissive[1]);
+   _debug_printf("\t\t.material.emissive[2] = %f\n", (*cmd).material.emissive[2]);
+   _debug_printf("\t\t.material.emissive[3] = %f\n", (*cmd).material.emissive[3]);
+   _debug_printf("\t\t.material.shininess = %f\n", (*cmd).material.shininess);
+}
+
+static void
+dump_SVGA3dCmdSetLightData(const SVGA3dCmdSetLightData *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   _debug_printf("\t\t.index = %u\n", (*cmd).index);
+   switch((*cmd).data.type) {
+   case SVGA3D_LIGHTTYPE_INVALID:
+      _debug_printf("\t\t.data.type = SVGA3D_LIGHTTYPE_INVALID\n");
+      break;
+   case SVGA3D_LIGHTTYPE_POINT:
+      _debug_printf("\t\t.data.type = SVGA3D_LIGHTTYPE_POINT\n");
+      break;
+   case SVGA3D_LIGHTTYPE_SPOT1:
+      _debug_printf("\t\t.data.type = SVGA3D_LIGHTTYPE_SPOT1\n");
+      break;
+   case SVGA3D_LIGHTTYPE_SPOT2:
+      _debug_printf("\t\t.data.type = SVGA3D_LIGHTTYPE_SPOT2\n");
+      break;
+   case SVGA3D_LIGHTTYPE_DIRECTIONAL:
+      _debug_printf("\t\t.data.type = SVGA3D_LIGHTTYPE_DIRECTIONAL\n");
+      break;
+   case SVGA3D_LIGHTTYPE_MAX:
+      _debug_printf("\t\t.data.type = SVGA3D_LIGHTTYPE_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.data.type = %i\n", (*cmd).data.type);
+      break;
+   }
+   _debug_printf("\t\t.data.inWorldSpace = %u\n", (*cmd).data.inWorldSpace);
+   _debug_printf("\t\t.data.diffuse[0] = %f\n", (*cmd).data.diffuse[0]);
+   _debug_printf("\t\t.data.diffuse[1] = %f\n", (*cmd).data.diffuse[1]);
+   _debug_printf("\t\t.data.diffuse[2] = %f\n", (*cmd).data.diffuse[2]);
+   _debug_printf("\t\t.data.diffuse[3] = %f\n", (*cmd).data.diffuse[3]);
+   _debug_printf("\t\t.data.specular[0] = %f\n", (*cmd).data.specular[0]);
+   _debug_printf("\t\t.data.specular[1] = %f\n", (*cmd).data.specular[1]);
+   _debug_printf("\t\t.data.specular[2] = %f\n", (*cmd).data.specular[2]);
+   _debug_printf("\t\t.data.specular[3] = %f\n", (*cmd).data.specular[3]);
+   _debug_printf("\t\t.data.ambient[0] = %f\n", (*cmd).data.ambient[0]);
+   _debug_printf("\t\t.data.ambient[1] = %f\n", (*cmd).data.ambient[1]);
+   _debug_printf("\t\t.data.ambient[2] = %f\n", (*cmd).data.ambient[2]);
+   _debug_printf("\t\t.data.ambient[3] = %f\n", (*cmd).data.ambient[3]);
+   _debug_printf("\t\t.data.position[0] = %f\n", (*cmd).data.position[0]);
+   _debug_printf("\t\t.data.position[1] = %f\n", (*cmd).data.position[1]);
+   _debug_printf("\t\t.data.position[2] = %f\n", (*cmd).data.position[2]);
+   _debug_printf("\t\t.data.position[3] = %f\n", (*cmd).data.position[3]);
+   _debug_printf("\t\t.data.direction[0] = %f\n", (*cmd).data.direction[0]);
+   _debug_printf("\t\t.data.direction[1] = %f\n", (*cmd).data.direction[1]);
+   _debug_printf("\t\t.data.direction[2] = %f\n", (*cmd).data.direction[2]);
+   _debug_printf("\t\t.data.direction[3] = %f\n", (*cmd).data.direction[3]);
+   _debug_printf("\t\t.data.range = %f\n", (*cmd).data.range);
+   _debug_printf("\t\t.data.falloff = %f\n", (*cmd).data.falloff);
+   _debug_printf("\t\t.data.attenuation0 = %f\n", (*cmd).data.attenuation0);
+   _debug_printf("\t\t.data.attenuation1 = %f\n", (*cmd).data.attenuation1);
+   _debug_printf("\t\t.data.attenuation2 = %f\n", (*cmd).data.attenuation2);
+   _debug_printf("\t\t.data.theta = %f\n", (*cmd).data.theta);
+   _debug_printf("\t\t.data.phi = %f\n", (*cmd).data.phi);
+}
+
+static void
+dump_SVGA3dCmdSetViewport(const SVGA3dCmdSetViewport *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   _debug_printf("\t\t.rect.x = %u\n", (*cmd).rect.x);
+   _debug_printf("\t\t.rect.y = %u\n", (*cmd).rect.y);
+   _debug_printf("\t\t.rect.w = %u\n", (*cmd).rect.w);
+   _debug_printf("\t\t.rect.h = %u\n", (*cmd).rect.h);
+}
+
+static void
+dump_SVGA3dCmdSetScissorRect(const SVGA3dCmdSetScissorRect *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   _debug_printf("\t\t.rect.x = %u\n", (*cmd).rect.x);
+   _debug_printf("\t\t.rect.y = %u\n", (*cmd).rect.y);
+   _debug_printf("\t\t.rect.w = %u\n", (*cmd).rect.w);
+   _debug_printf("\t\t.rect.h = %u\n", (*cmd).rect.h);
+}
+
+static void
+dump_SVGA3dCopyRect(const SVGA3dCopyRect *cmd)
+{
+   _debug_printf("\t\t.x = %u\n", (*cmd).x);
+   _debug_printf("\t\t.y = %u\n", (*cmd).y);
+   _debug_printf("\t\t.w = %u\n", (*cmd).w);
+   _debug_printf("\t\t.h = %u\n", (*cmd).h);
+   _debug_printf("\t\t.srcx = %u\n", (*cmd).srcx);
+   _debug_printf("\t\t.srcy = %u\n", (*cmd).srcy);
+}
+
+static void
+dump_SVGA3dCmdSetShader(const SVGA3dCmdSetShader *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   switch((*cmd).type) {
+   case SVGA3D_SHADERTYPE_COMPILED_DX8:
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_COMPILED_DX8\n");
+      break;
+   case SVGA3D_SHADERTYPE_VS:
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_VS\n");
+      break;
+   case SVGA3D_SHADERTYPE_PS:
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_PS\n");
+      break;
+   case SVGA3D_SHADERTYPE_MAX:
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.type = %i\n", (*cmd).type);
+      break;
+   }
+   _debug_printf("\t\t.shid = %u\n", (*cmd).shid);
+}
+
+static void
+dump_SVGA3dCmdEndQuery(const SVGA3dCmdEndQuery *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   switch((*cmd).type) {
+   case SVGA3D_QUERYTYPE_OCCLUSION:
+      _debug_printf("\t\t.type = SVGA3D_QUERYTYPE_OCCLUSION\n");
+      break;
+   case SVGA3D_QUERYTYPE_MAX:
+      _debug_printf("\t\t.type = SVGA3D_QUERYTYPE_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.type = %i\n", (*cmd).type);
+      break;
+   }
+   _debug_printf("\t\t.guestResult.gmrId = %u\n", (*cmd).guestResult.gmrId);
+   _debug_printf("\t\t.guestResult.offset = %u\n", (*cmd).guestResult.offset);
+}
+
+static void
+dump_SVGA3dSize(const SVGA3dSize *cmd)
+{
+   _debug_printf("\t\t.width = %u\n", (*cmd).width);
+   _debug_printf("\t\t.height = %u\n", (*cmd).height);
+   _debug_printf("\t\t.depth = %u\n", (*cmd).depth);
+}
+
+static void
+dump_SVGA3dCmdDestroySurface(const SVGA3dCmdDestroySurface *cmd)
+{
+   _debug_printf("\t\t.sid = %u\n", (*cmd).sid);
+}
+
+static void
+dump_SVGA3dCmdDefineContext(const SVGA3dCmdDefineContext *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+}
+
+static void
+dump_SVGA3dRect(const SVGA3dRect *cmd)
+{
+   _debug_printf("\t\t.x = %u\n", (*cmd).x);
+   _debug_printf("\t\t.y = %u\n", (*cmd).y);
+   _debug_printf("\t\t.w = %u\n", (*cmd).w);
+   _debug_printf("\t\t.h = %u\n", (*cmd).h);
+}
+
+static void
+dump_SVGA3dCmdBeginQuery(const SVGA3dCmdBeginQuery *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   switch((*cmd).type) {
+   case SVGA3D_QUERYTYPE_OCCLUSION:
+      _debug_printf("\t\t.type = SVGA3D_QUERYTYPE_OCCLUSION\n");
+      break;
+   case SVGA3D_QUERYTYPE_MAX:
+      _debug_printf("\t\t.type = SVGA3D_QUERYTYPE_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.type = %i\n", (*cmd).type);
+      break;
+   }
+}
+
+static void
+dump_SVGA3dRenderState(const SVGA3dRenderState *cmd)
+{
+   switch((*cmd).state) {
+   case SVGA3D_RS_INVALID:
+      _debug_printf("\t\t.state = SVGA3D_RS_INVALID\n");
+      break;
+   case SVGA3D_RS_ZENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_ZENABLE\n");
+      break;
+   case SVGA3D_RS_ZWRITEENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_ZWRITEENABLE\n");
+      break;
+   case SVGA3D_RS_ALPHATESTENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_ALPHATESTENABLE\n");
+      break;
+   case SVGA3D_RS_DITHERENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_DITHERENABLE\n");
+      break;
+   case SVGA3D_RS_BLENDENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_BLENDENABLE\n");
+      break;
+   case SVGA3D_RS_FOGENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_FOGENABLE\n");
+      break;
+   case SVGA3D_RS_SPECULARENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_SPECULARENABLE\n");
+      break;
+   case SVGA3D_RS_STENCILENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILENABLE\n");
+      break;
+   case SVGA3D_RS_LIGHTINGENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_LIGHTINGENABLE\n");
+      break;
+   case SVGA3D_RS_NORMALIZENORMALS:
+      _debug_printf("\t\t.state = SVGA3D_RS_NORMALIZENORMALS\n");
+      break;
+   case SVGA3D_RS_POINTSPRITEENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_POINTSPRITEENABLE\n");
+      break;
+   case SVGA3D_RS_POINTSCALEENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_POINTSCALEENABLE\n");
+      break;
+   case SVGA3D_RS_STENCILREF:
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILREF\n");
+      break;
+   case SVGA3D_RS_STENCILMASK:
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILMASK\n");
+      break;
+   case SVGA3D_RS_STENCILWRITEMASK:
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILWRITEMASK\n");
+      break;
+   case SVGA3D_RS_FOGSTART:
+      _debug_printf("\t\t.state = SVGA3D_RS_FOGSTART\n");
+      break;
+   case SVGA3D_RS_FOGEND:
+      _debug_printf("\t\t.state = SVGA3D_RS_FOGEND\n");
+      break;
+   case SVGA3D_RS_FOGDENSITY:
+      _debug_printf("\t\t.state = SVGA3D_RS_FOGDENSITY\n");
+      break;
+   case SVGA3D_RS_POINTSIZE:
+      _debug_printf("\t\t.state = SVGA3D_RS_POINTSIZE\n");
+      break;
+   case SVGA3D_RS_POINTSIZEMIN:
+      _debug_printf("\t\t.state = SVGA3D_RS_POINTSIZEMIN\n");
+      break;
+   case SVGA3D_RS_POINTSIZEMAX:
+      _debug_printf("\t\t.state = SVGA3D_RS_POINTSIZEMAX\n");
+      break;
+   case SVGA3D_RS_POINTSCALE_A:
+      _debug_printf("\t\t.state = SVGA3D_RS_POINTSCALE_A\n");
+      break;
+   case SVGA3D_RS_POINTSCALE_B:
+      _debug_printf("\t\t.state = SVGA3D_RS_POINTSCALE_B\n");
+      break;
+   case SVGA3D_RS_POINTSCALE_C:
+      _debug_printf("\t\t.state = SVGA3D_RS_POINTSCALE_C\n");
+      break;
+   case SVGA3D_RS_FOGCOLOR:
+      _debug_printf("\t\t.state = SVGA3D_RS_FOGCOLOR\n");
+      break;
+   case SVGA3D_RS_AMBIENT:
+      _debug_printf("\t\t.state = SVGA3D_RS_AMBIENT\n");
+      break;
+   case SVGA3D_RS_CLIPPLANEENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_CLIPPLANEENABLE\n");
+      break;
+   case SVGA3D_RS_FOGMODE:
+      _debug_printf("\t\t.state = SVGA3D_RS_FOGMODE\n");
+      break;
+   case SVGA3D_RS_FILLMODE:
+      _debug_printf("\t\t.state = SVGA3D_RS_FILLMODE\n");
+      break;
+   case SVGA3D_RS_SHADEMODE:
+      _debug_printf("\t\t.state = SVGA3D_RS_SHADEMODE\n");
+      break;
+   case SVGA3D_RS_LINEPATTERN:
+      _debug_printf("\t\t.state = SVGA3D_RS_LINEPATTERN\n");
+      break;
+   case SVGA3D_RS_SRCBLEND:
+      _debug_printf("\t\t.state = SVGA3D_RS_SRCBLEND\n");
+      break;
+   case SVGA3D_RS_DSTBLEND:
+      _debug_printf("\t\t.state = SVGA3D_RS_DSTBLEND\n");
+      break;
+   case SVGA3D_RS_BLENDEQUATION:
+      _debug_printf("\t\t.state = SVGA3D_RS_BLENDEQUATION\n");
+      break;
+   case SVGA3D_RS_CULLMODE:
+      _debug_printf("\t\t.state = SVGA3D_RS_CULLMODE\n");
+      break;
+   case SVGA3D_RS_ZFUNC:
+      _debug_printf("\t\t.state = SVGA3D_RS_ZFUNC\n");
+      break;
+   case SVGA3D_RS_ALPHAFUNC:
+      _debug_printf("\t\t.state = SVGA3D_RS_ALPHAFUNC\n");
+      break;
+   case SVGA3D_RS_STENCILFUNC:
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILFUNC\n");
+      break;
+   case SVGA3D_RS_STENCILFAIL:
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILFAIL\n");
+      break;
+   case SVGA3D_RS_STENCILZFAIL:
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILZFAIL\n");
+      break;
+   case SVGA3D_RS_STENCILPASS:
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILPASS\n");
+      break;
+   case SVGA3D_RS_ALPHAREF:
+      _debug_printf("\t\t.state = SVGA3D_RS_ALPHAREF\n");
+      break;
+   case SVGA3D_RS_FRONTWINDING:
+      _debug_printf("\t\t.state = SVGA3D_RS_FRONTWINDING\n");
+      break;
+   case SVGA3D_RS_COORDINATETYPE:
+      _debug_printf("\t\t.state = SVGA3D_RS_COORDINATETYPE\n");
+      break;
+   case SVGA3D_RS_ZBIAS:
+      _debug_printf("\t\t.state = SVGA3D_RS_ZBIAS\n");
+      break;
+   case SVGA3D_RS_RANGEFOGENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_RANGEFOGENABLE\n");
+      break;
+   case SVGA3D_RS_COLORWRITEENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_COLORWRITEENABLE\n");
+      break;
+   case SVGA3D_RS_VERTEXMATERIALENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_VERTEXMATERIALENABLE\n");
+      break;
+   case SVGA3D_RS_DIFFUSEMATERIALSOURCE:
+      _debug_printf("\t\t.state = SVGA3D_RS_DIFFUSEMATERIALSOURCE\n");
+      break;
+   case SVGA3D_RS_SPECULARMATERIALSOURCE:
+      _debug_printf("\t\t.state = SVGA3D_RS_SPECULARMATERIALSOURCE\n");
+      break;
+   case SVGA3D_RS_AMBIENTMATERIALSOURCE:
+      _debug_printf("\t\t.state = SVGA3D_RS_AMBIENTMATERIALSOURCE\n");
+      break;
+   case SVGA3D_RS_EMISSIVEMATERIALSOURCE:
+      _debug_printf("\t\t.state = SVGA3D_RS_EMISSIVEMATERIALSOURCE\n");
+      break;
+   case SVGA3D_RS_TEXTUREFACTOR:
+      _debug_printf("\t\t.state = SVGA3D_RS_TEXTUREFACTOR\n");
+      break;
+   case SVGA3D_RS_LOCALVIEWER:
+      _debug_printf("\t\t.state = SVGA3D_RS_LOCALVIEWER\n");
+      break;
+   case SVGA3D_RS_SCISSORTESTENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_SCISSORTESTENABLE\n");
+      break;
+   case SVGA3D_RS_BLENDCOLOR:
+      _debug_printf("\t\t.state = SVGA3D_RS_BLENDCOLOR\n");
+      break;
+   case SVGA3D_RS_STENCILENABLE2SIDED:
+      _debug_printf("\t\t.state = SVGA3D_RS_STENCILENABLE2SIDED\n");
+      break;
+   case SVGA3D_RS_CCWSTENCILFUNC:
+      _debug_printf("\t\t.state = SVGA3D_RS_CCWSTENCILFUNC\n");
+      break;
+   case SVGA3D_RS_CCWSTENCILFAIL:
+      _debug_printf("\t\t.state = SVGA3D_RS_CCWSTENCILFAIL\n");
+      break;
+   case SVGA3D_RS_CCWSTENCILZFAIL:
+      _debug_printf("\t\t.state = SVGA3D_RS_CCWSTENCILZFAIL\n");
+      break;
+   case SVGA3D_RS_CCWSTENCILPASS:
+      _debug_printf("\t\t.state = SVGA3D_RS_CCWSTENCILPASS\n");
+      break;
+   case SVGA3D_RS_VERTEXBLEND:
+      _debug_printf("\t\t.state = SVGA3D_RS_VERTEXBLEND\n");
+      break;
+   case SVGA3D_RS_SLOPESCALEDEPTHBIAS:
+      _debug_printf("\t\t.state = SVGA3D_RS_SLOPESCALEDEPTHBIAS\n");
+      break;
+   case SVGA3D_RS_DEPTHBIAS:
+      _debug_printf("\t\t.state = SVGA3D_RS_DEPTHBIAS\n");
+      break;
+   case SVGA3D_RS_OUTPUTGAMMA:
+      _debug_printf("\t\t.state = SVGA3D_RS_OUTPUTGAMMA\n");
+      break;
+   case SVGA3D_RS_ZVISIBLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_ZVISIBLE\n");
+      break;
+   case SVGA3D_RS_LASTPIXEL:
+      _debug_printf("\t\t.state = SVGA3D_RS_LASTPIXEL\n");
+      break;
+   case SVGA3D_RS_CLIPPING:
+      _debug_printf("\t\t.state = SVGA3D_RS_CLIPPING\n");
+      break;
+   case SVGA3D_RS_WRAP0:
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP0\n");
+      break;
+   case SVGA3D_RS_WRAP1:
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP1\n");
+      break;
+   case SVGA3D_RS_WRAP2:
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP2\n");
+      break;
+   case SVGA3D_RS_WRAP3:
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP3\n");
+      break;
+   case SVGA3D_RS_WRAP4:
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP4\n");
+      break;
+   case SVGA3D_RS_WRAP5:
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP5\n");
+      break;
+   case SVGA3D_RS_WRAP6:
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP6\n");
+      break;
+   case SVGA3D_RS_WRAP7:
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP7\n");
+      break;
+   case SVGA3D_RS_WRAP8:
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP8\n");
+      break;
+   case SVGA3D_RS_WRAP9:
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP9\n");
+      break;
+   case SVGA3D_RS_WRAP10:
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP10\n");
+      break;
+   case SVGA3D_RS_WRAP11:
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP11\n");
+      break;
+   case SVGA3D_RS_WRAP12:
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP12\n");
+      break;
+   case SVGA3D_RS_WRAP13:
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP13\n");
+      break;
+   case SVGA3D_RS_WRAP14:
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP14\n");
+      break;
+   case SVGA3D_RS_WRAP15:
+      _debug_printf("\t\t.state = SVGA3D_RS_WRAP15\n");
+      break;
+   case SVGA3D_RS_MULTISAMPLEANTIALIAS:
+      _debug_printf("\t\t.state = SVGA3D_RS_MULTISAMPLEANTIALIAS\n");
+      break;
+   case SVGA3D_RS_MULTISAMPLEMASK:
+      _debug_printf("\t\t.state = SVGA3D_RS_MULTISAMPLEMASK\n");
+      break;
+   case SVGA3D_RS_INDEXEDVERTEXBLENDENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_INDEXEDVERTEXBLENDENABLE\n");
+      break;
+   case SVGA3D_RS_TWEENFACTOR:
+      _debug_printf("\t\t.state = SVGA3D_RS_TWEENFACTOR\n");
+      break;
+   case SVGA3D_RS_ANTIALIASEDLINEENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_ANTIALIASEDLINEENABLE\n");
+      break;
+   case SVGA3D_RS_COLORWRITEENABLE1:
+      _debug_printf("\t\t.state = SVGA3D_RS_COLORWRITEENABLE1\n");
+      break;
+   case SVGA3D_RS_COLORWRITEENABLE2:
+      _debug_printf("\t\t.state = SVGA3D_RS_COLORWRITEENABLE2\n");
+      break;
+   case SVGA3D_RS_COLORWRITEENABLE3:
+      _debug_printf("\t\t.state = SVGA3D_RS_COLORWRITEENABLE3\n");
+      break;
+   case SVGA3D_RS_SEPARATEALPHABLENDENABLE:
+      _debug_printf("\t\t.state = SVGA3D_RS_SEPARATEALPHABLENDENABLE\n");
+      break;
+   case SVGA3D_RS_SRCBLENDALPHA:
+      _debug_printf("\t\t.state = SVGA3D_RS_SRCBLENDALPHA\n");
+      break;
+   case SVGA3D_RS_DSTBLENDALPHA:
+      _debug_printf("\t\t.state = SVGA3D_RS_DSTBLENDALPHA\n");
+      break;
+   case SVGA3D_RS_BLENDEQUATIONALPHA:
+      _debug_printf("\t\t.state = SVGA3D_RS_BLENDEQUATIONALPHA\n");
+      break;
+   case SVGA3D_RS_MAX:
+      _debug_printf("\t\t.state = SVGA3D_RS_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.state = %i\n", (*cmd).state);
+      break;
+   }
+   _debug_printf("\t\t.uintValue = %u\n", (*cmd).uintValue);
+   _debug_printf("\t\t.floatValue = %f\n", (*cmd).floatValue);
+}
+
+static void
+dump_SVGA3dVertexDivisor(const SVGA3dVertexDivisor *cmd)
+{
+   _debug_printf("\t\t.value = %u\n", (*cmd).value);
+   _debug_printf("\t\t.count = %u\n", (*cmd).count);
+   _debug_printf("\t\t.indexedData = %u\n", (*cmd).indexedData);
+   _debug_printf("\t\t.instanceData = %u\n", (*cmd).instanceData);
+}
+
+static void
+dump_SVGA3dCmdDefineShader(const SVGA3dCmdDefineShader *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   _debug_printf("\t\t.shid = %u\n", (*cmd).shid);
+   switch((*cmd).type) {
+   case SVGA3D_SHADERTYPE_COMPILED_DX8:
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_COMPILED_DX8\n");
+      break;
+   case SVGA3D_SHADERTYPE_VS:
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_VS\n");
+      break;
+   case SVGA3D_SHADERTYPE_PS:
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_PS\n");
+      break;
+   case SVGA3D_SHADERTYPE_MAX:
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.type = %i\n", (*cmd).type);
+      break;
+   }
+}
+
+static void
+dump_SVGA3dCmdSetShaderConst(const SVGA3dCmdSetShaderConst *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   _debug_printf("\t\t.reg = %u\n", (*cmd).reg);
+   switch((*cmd).type) {
+   case SVGA3D_SHADERTYPE_COMPILED_DX8:
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_COMPILED_DX8\n");
+      break;
+   case SVGA3D_SHADERTYPE_VS:
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_VS\n");
+      break;
+   case SVGA3D_SHADERTYPE_PS:
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_PS\n");
+      break;
+   case SVGA3D_SHADERTYPE_MAX:
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.type = %i\n", (*cmd).type);
+      break;
+   }
+   switch((*cmd).ctype) {
+   case SVGA3D_CONST_TYPE_FLOAT:
+      _debug_printf("\t\t.ctype = SVGA3D_CONST_TYPE_FLOAT\n");
+      _debug_printf("\t\t.values[0] = %f\n", *(const float *)&(*cmd).values[0]);
+      _debug_printf("\t\t.values[1] = %f\n", *(const float *)&(*cmd).values[1]);
+      _debug_printf("\t\t.values[2] = %f\n", *(const float *)&(*cmd).values[2]);
+      _debug_printf("\t\t.values[3] = %f\n", *(const float *)&(*cmd).values[3]);
+      break;
+   case SVGA3D_CONST_TYPE_INT:
+      _debug_printf("\t\t.ctype = SVGA3D_CONST_TYPE_INT\n");
+      _debug_printf("\t\t.values[0] = %u\n", (*cmd).values[0]);
+      _debug_printf("\t\t.values[1] = %u\n", (*cmd).values[1]);
+      _debug_printf("\t\t.values[2] = %u\n", (*cmd).values[2]);
+      _debug_printf("\t\t.values[3] = %u\n", (*cmd).values[3]);
+      break;
+   case SVGA3D_CONST_TYPE_BOOL:
+      _debug_printf("\t\t.ctype = SVGA3D_CONST_TYPE_BOOL\n");
+      _debug_printf("\t\t.values[0] = %u\n", (*cmd).values[0]);
+      _debug_printf("\t\t.values[1] = %u\n", (*cmd).values[1]);
+      _debug_printf("\t\t.values[2] = %u\n", (*cmd).values[2]);
+      _debug_printf("\t\t.values[3] = %u\n", (*cmd).values[3]);
+      break;
+   default:
+      _debug_printf("\t\t.ctype = %i\n", (*cmd).ctype);
+      _debug_printf("\t\t.values[0] = %u\n", (*cmd).values[0]);
+      _debug_printf("\t\t.values[1] = %u\n", (*cmd).values[1]);
+      _debug_printf("\t\t.values[2] = %u\n", (*cmd).values[2]);
+      _debug_printf("\t\t.values[3] = %u\n", (*cmd).values[3]);
+      break;
+   }
+}
+
+static void
+dump_SVGA3dCmdSetZRange(const SVGA3dCmdSetZRange *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   _debug_printf("\t\t.zRange.min = %f\n", (*cmd).zRange.min);
+   _debug_printf("\t\t.zRange.max = %f\n", (*cmd).zRange.max);
+}
+
+static void
+dump_SVGA3dCmdDrawPrimitives(const SVGA3dCmdDrawPrimitives *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   _debug_printf("\t\t.numVertexDecls = %u\n", (*cmd).numVertexDecls);
+   _debug_printf("\t\t.numRanges = %u\n", (*cmd).numRanges);
+}
+
+static void
+dump_SVGA3dCmdSetLightEnabled(const SVGA3dCmdSetLightEnabled *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   _debug_printf("\t\t.index = %u\n", (*cmd).index);
+   _debug_printf("\t\t.enabled = %u\n", (*cmd).enabled);
+}
+
+static void
+dump_SVGA3dPrimitiveRange(const SVGA3dPrimitiveRange *cmd)
+{
+   switch((*cmd).primType) {
+   case SVGA3D_PRIMITIVE_INVALID:
+      _debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_INVALID\n");
+      break;
+   case SVGA3D_PRIMITIVE_TRIANGLELIST:
+      _debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_TRIANGLELIST\n");
+      break;
+   case SVGA3D_PRIMITIVE_POINTLIST:
+      _debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_POINTLIST\n");
+      break;
+   case SVGA3D_PRIMITIVE_LINELIST:
+      _debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_LINELIST\n");
+      break;
+   case SVGA3D_PRIMITIVE_LINESTRIP:
+      _debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_LINESTRIP\n");
+      break;
+   case SVGA3D_PRIMITIVE_TRIANGLESTRIP:
+      _debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_TRIANGLESTRIP\n");
+      break;
+   case SVGA3D_PRIMITIVE_TRIANGLEFAN:
+      _debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_TRIANGLEFAN\n");
+      break;
+   case SVGA3D_PRIMITIVE_MAX:
+      _debug_printf("\t\t.primType = SVGA3D_PRIMITIVE_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.primType = %i\n", (*cmd).primType);
+      break;
+   }
+   _debug_printf("\t\t.primitiveCount = %u\n", (*cmd).primitiveCount);
+   _debug_printf("\t\t.indexArray.surfaceId = %u\n", (*cmd).indexArray.surfaceId);
+   _debug_printf("\t\t.indexArray.offset = %u\n", (*cmd).indexArray.offset);
+   _debug_printf("\t\t.indexArray.stride = %u\n", (*cmd).indexArray.stride);
+   _debug_printf("\t\t.indexWidth = %u\n", (*cmd).indexWidth);
+   _debug_printf("\t\t.indexBias = %i\n", (*cmd).indexBias);
+}
+
+static void
+dump_SVGA3dCmdPresent(const SVGA3dCmdPresent *cmd)
+{
+   _debug_printf("\t\t.sid = %u\n", (*cmd).sid);
+}
+
+static void
+dump_SVGA3dCmdSetRenderState(const SVGA3dCmdSetRenderState *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+}
+
+static void
+dump_SVGA3dCmdSurfaceStretchBlt(const SVGA3dCmdSurfaceStretchBlt *cmd)
+{
+   _debug_printf("\t\t.src.sid = %u\n", (*cmd).src.sid);
+   _debug_printf("\t\t.src.face = %u\n", (*cmd).src.face);
+   _debug_printf("\t\t.src.mipmap = %u\n", (*cmd).src.mipmap);
+   _debug_printf("\t\t.dest.sid = %u\n", (*cmd).dest.sid);
+   _debug_printf("\t\t.dest.face = %u\n", (*cmd).dest.face);
+   _debug_printf("\t\t.dest.mipmap = %u\n", (*cmd).dest.mipmap);
+   _debug_printf("\t\t.boxSrc.x = %u\n", (*cmd).boxSrc.x);
+   _debug_printf("\t\t.boxSrc.y = %u\n", (*cmd).boxSrc.y);
+   _debug_printf("\t\t.boxSrc.z = %u\n", (*cmd).boxSrc.z);
+   _debug_printf("\t\t.boxSrc.w = %u\n", (*cmd).boxSrc.w);
+   _debug_printf("\t\t.boxSrc.h = %u\n", (*cmd).boxSrc.h);
+   _debug_printf("\t\t.boxSrc.d = %u\n", (*cmd).boxSrc.d);
+   _debug_printf("\t\t.boxDest.x = %u\n", (*cmd).boxDest.x);
+   _debug_printf("\t\t.boxDest.y = %u\n", (*cmd).boxDest.y);
+   _debug_printf("\t\t.boxDest.z = %u\n", (*cmd).boxDest.z);
+   _debug_printf("\t\t.boxDest.w = %u\n", (*cmd).boxDest.w);
+   _debug_printf("\t\t.boxDest.h = %u\n", (*cmd).boxDest.h);
+   _debug_printf("\t\t.boxDest.d = %u\n", (*cmd).boxDest.d);
+   switch((*cmd).mode) {
+   case SVGA3D_STRETCH_BLT_POINT:
+      _debug_printf("\t\t.mode = SVGA3D_STRETCH_BLT_POINT\n");
+      break;
+   case SVGA3D_STRETCH_BLT_LINEAR:
+      _debug_printf("\t\t.mode = SVGA3D_STRETCH_BLT_LINEAR\n");
+      break;
+   case SVGA3D_STRETCH_BLT_MAX:
+      _debug_printf("\t\t.mode = SVGA3D_STRETCH_BLT_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.mode = %i\n", (*cmd).mode);
+      break;
+   }
+}
+
+static void
+dump_SVGA3dCmdSurfaceDMA(const SVGA3dCmdSurfaceDMA *cmd)
+{
+   _debug_printf("\t\t.guest.ptr.gmrId = %u\n", (*cmd).guest.ptr.gmrId);
+   _debug_printf("\t\t.guest.ptr.offset = %u\n", (*cmd).guest.ptr.offset);
+   _debug_printf("\t\t.guest.pitch = %u\n", (*cmd).guest.pitch);
+   _debug_printf("\t\t.host.sid = %u\n", (*cmd).host.sid);
+   _debug_printf("\t\t.host.face = %u\n", (*cmd).host.face);
+   _debug_printf("\t\t.host.mipmap = %u\n", (*cmd).host.mipmap);
+   switch((*cmd).transfer) {
+   case SVGA3D_WRITE_HOST_VRAM:
+      _debug_printf("\t\t.transfer = SVGA3D_WRITE_HOST_VRAM\n");
+      break;
+   case SVGA3D_READ_HOST_VRAM:
+      _debug_printf("\t\t.transfer = SVGA3D_READ_HOST_VRAM\n");
+      break;
+   default:
+      _debug_printf("\t\t.transfer = %i\n", (*cmd).transfer);
+      break;
+   }
+}
+
+static void
+dump_SVGA3dCmdSurfaceDMASuffix(const SVGA3dCmdSurfaceDMASuffix *cmd)
+{
+   _debug_printf("\t\t.suffixSize = %u\n", (*cmd).suffixSize);
+   _debug_printf("\t\t.maximumOffset = %u\n", (*cmd).maximumOffset);
+   _debug_printf("\t\t.flags.discard = %u\n", (*cmd).flags.discard);
+   _debug_printf("\t\t.flags.unsynchronized = %u\n", (*cmd).flags.unsynchronized);
+}
+
+static void
+dump_SVGA3dCmdSetTransform(const SVGA3dCmdSetTransform *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   switch((*cmd).type) {
+   case SVGA3D_TRANSFORM_INVALID:
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_INVALID\n");
+      break;
+   case SVGA3D_TRANSFORM_WORLD:
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_WORLD\n");
+      break;
+   case SVGA3D_TRANSFORM_VIEW:
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_VIEW\n");
+      break;
+   case SVGA3D_TRANSFORM_PROJECTION:
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_PROJECTION\n");
+      break;
+   case SVGA3D_TRANSFORM_TEXTURE0:
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE0\n");
+      break;
+   case SVGA3D_TRANSFORM_TEXTURE1:
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE1\n");
+      break;
+   case SVGA3D_TRANSFORM_TEXTURE2:
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE2\n");
+      break;
+   case SVGA3D_TRANSFORM_TEXTURE3:
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE3\n");
+      break;
+   case SVGA3D_TRANSFORM_TEXTURE4:
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE4\n");
+      break;
+   case SVGA3D_TRANSFORM_TEXTURE5:
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE5\n");
+      break;
+   case SVGA3D_TRANSFORM_TEXTURE6:
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE6\n");
+      break;
+   case SVGA3D_TRANSFORM_TEXTURE7:
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_TEXTURE7\n");
+      break;
+   case SVGA3D_TRANSFORM_WORLD1:
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_WORLD1\n");
+      break;
+   case SVGA3D_TRANSFORM_WORLD2:
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_WORLD2\n");
+      break;
+   case SVGA3D_TRANSFORM_WORLD3:
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_WORLD3\n");
+      break;
+   case SVGA3D_TRANSFORM_MAX:
+      _debug_printf("\t\t.type = SVGA3D_TRANSFORM_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.type = %i\n", (*cmd).type);
+      break;
+   }
+   _debug_printf("\t\t.matrix[0] = %f\n", (*cmd).matrix[0]);
+   _debug_printf("\t\t.matrix[1] = %f\n", (*cmd).matrix[1]);
+   _debug_printf("\t\t.matrix[2] = %f\n", (*cmd).matrix[2]);
+   _debug_printf("\t\t.matrix[3] = %f\n", (*cmd).matrix[3]);
+   _debug_printf("\t\t.matrix[4] = %f\n", (*cmd).matrix[4]);
+   _debug_printf("\t\t.matrix[5] = %f\n", (*cmd).matrix[5]);
+   _debug_printf("\t\t.matrix[6] = %f\n", (*cmd).matrix[6]);
+   _debug_printf("\t\t.matrix[7] = %f\n", (*cmd).matrix[7]);
+   _debug_printf("\t\t.matrix[8] = %f\n", (*cmd).matrix[8]);
+   _debug_printf("\t\t.matrix[9] = %f\n", (*cmd).matrix[9]);
+   _debug_printf("\t\t.matrix[10] = %f\n", (*cmd).matrix[10]);
+   _debug_printf("\t\t.matrix[11] = %f\n", (*cmd).matrix[11]);
+   _debug_printf("\t\t.matrix[12] = %f\n", (*cmd).matrix[12]);
+   _debug_printf("\t\t.matrix[13] = %f\n", (*cmd).matrix[13]);
+   _debug_printf("\t\t.matrix[14] = %f\n", (*cmd).matrix[14]);
+   _debug_printf("\t\t.matrix[15] = %f\n", (*cmd).matrix[15]);
+}
+
+static void
+dump_SVGA3dCmdDestroyShader(const SVGA3dCmdDestroyShader *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   _debug_printf("\t\t.shid = %u\n", (*cmd).shid);
+   switch((*cmd).type) {
+   case SVGA3D_SHADERTYPE_COMPILED_DX8:
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_COMPILED_DX8\n");
+      break;
+   case SVGA3D_SHADERTYPE_VS:
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_VS\n");
+      break;
+   case SVGA3D_SHADERTYPE_PS:
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_PS\n");
+      break;
+   case SVGA3D_SHADERTYPE_MAX:
+      _debug_printf("\t\t.type = SVGA3D_SHADERTYPE_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.type = %i\n", (*cmd).type);
+      break;
+   }
+}
+
+static void
+dump_SVGA3dCmdDestroyContext(const SVGA3dCmdDestroyContext *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+}
+
+static void
+dump_SVGA3dCmdClear(const SVGA3dCmdClear *cmd)
+{
+   _debug_printf("\t\t.cid = %u\n", (*cmd).cid);
+   switch((*cmd).clearFlag) {
+   case SVGA3D_CLEAR_COLOR:
+      _debug_printf("\t\t.clearFlag = SVGA3D_CLEAR_COLOR\n");
+      break;
+   case SVGA3D_CLEAR_DEPTH:
+      _debug_printf("\t\t.clearFlag = SVGA3D_CLEAR_DEPTH\n");
+      break;
+   case SVGA3D_CLEAR_STENCIL:
+      _debug_printf("\t\t.clearFlag = SVGA3D_CLEAR_STENCIL\n");
+      break;
+   default:
+      _debug_printf("\t\t.clearFlag = %i\n", (*cmd).clearFlag);
+      break;
+   }
+   _debug_printf("\t\t.color = %u\n", (*cmd).color);
+   _debug_printf("\t\t.depth = %f\n", (*cmd).depth);
+   _debug_printf("\t\t.stencil = %u\n", (*cmd).stencil);
+}
+
+static void
+dump_SVGA3dCmdDefineSurface(const SVGA3dCmdDefineSurface *cmd)
+{
+   _debug_printf("\t\t.sid = %u\n", (*cmd).sid);
+   switch((*cmd).surfaceFlags) {
+   case SVGA3D_SURFACE_CUBEMAP:
+      _debug_printf("\t\t.surfaceFlags = SVGA3D_SURFACE_CUBEMAP\n");
+      break;
+   case SVGA3D_SURFACE_HINT_STATIC:
+      _debug_printf("\t\t.surfaceFlags = SVGA3D_SURFACE_HINT_STATIC\n");
+      break;
+   case SVGA3D_SURFACE_HINT_DYNAMIC:
+      _debug_printf("\t\t.surfaceFlags = SVGA3D_SURFACE_HINT_DYNAMIC\n");
+      break;
+   case SVGA3D_SURFACE_HINT_INDEXBUFFER:
+      _debug_printf("\t\t.surfaceFlags = SVGA3D_SURFACE_HINT_INDEXBUFFER\n");
+      break;
+   case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
+      _debug_printf("\t\t.surfaceFlags = SVGA3D_SURFACE_HINT_VERTEXBUFFER\n");
+      break;
+   default:
+      _debug_printf("\t\t.surfaceFlags = %i\n", (*cmd).surfaceFlags);
+      break;
+   }
+   switch((*cmd).format) {
+   case SVGA3D_FORMAT_INVALID:
+      _debug_printf("\t\t.format = SVGA3D_FORMAT_INVALID\n");
+      break;
+   case SVGA3D_X8R8G8B8:
+      _debug_printf("\t\t.format = SVGA3D_X8R8G8B8\n");
+      break;
+   case SVGA3D_A8R8G8B8:
+      _debug_printf("\t\t.format = SVGA3D_A8R8G8B8\n");
+      break;
+   case SVGA3D_R5G6B5:
+      _debug_printf("\t\t.format = SVGA3D_R5G6B5\n");
+      break;
+   case SVGA3D_X1R5G5B5:
+      _debug_printf("\t\t.format = SVGA3D_X1R5G5B5\n");
+      break;
+   case SVGA3D_A1R5G5B5:
+      _debug_printf("\t\t.format = SVGA3D_A1R5G5B5\n");
+      break;
+   case SVGA3D_A4R4G4B4:
+      _debug_printf("\t\t.format = SVGA3D_A4R4G4B4\n");
+      break;
+   case SVGA3D_Z_D32:
+      _debug_printf("\t\t.format = SVGA3D_Z_D32\n");
+      break;
+   case SVGA3D_Z_D16:
+      _debug_printf("\t\t.format = SVGA3D_Z_D16\n");
+      break;
+   case SVGA3D_Z_D24S8:
+      _debug_printf("\t\t.format = SVGA3D_Z_D24S8\n");
+      break;
+   case SVGA3D_Z_D15S1:
+      _debug_printf("\t\t.format = SVGA3D_Z_D15S1\n");
+      break;
+   case SVGA3D_LUMINANCE8:
+      _debug_printf("\t\t.format = SVGA3D_LUMINANCE8\n");
+      break;
+   case SVGA3D_LUMINANCE4_ALPHA4:
+      _debug_printf("\t\t.format = SVGA3D_LUMINANCE4_ALPHA4\n");
+      break;
+   case SVGA3D_LUMINANCE16:
+      _debug_printf("\t\t.format = SVGA3D_LUMINANCE16\n");
+      break;
+   case SVGA3D_LUMINANCE8_ALPHA8:
+      _debug_printf("\t\t.format = SVGA3D_LUMINANCE8_ALPHA8\n");
+      break;
+   case SVGA3D_DXT1:
+      _debug_printf("\t\t.format = SVGA3D_DXT1\n");
+      break;
+   case SVGA3D_DXT2:
+      _debug_printf("\t\t.format = SVGA3D_DXT2\n");
+      break;
+   case SVGA3D_DXT3:
+      _debug_printf("\t\t.format = SVGA3D_DXT3\n");
+      break;
+   case SVGA3D_DXT4:
+      _debug_printf("\t\t.format = SVGA3D_DXT4\n");
+      break;
+   case SVGA3D_DXT5:
+      _debug_printf("\t\t.format = SVGA3D_DXT5\n");
+      break;
+   case SVGA3D_BUMPU8V8:
+      _debug_printf("\t\t.format = SVGA3D_BUMPU8V8\n");
+      break;
+   case SVGA3D_BUMPL6V5U5:
+      _debug_printf("\t\t.format = SVGA3D_BUMPL6V5U5\n");
+      break;
+   case SVGA3D_BUMPX8L8V8U8:
+      _debug_printf("\t\t.format = SVGA3D_BUMPX8L8V8U8\n");
+      break;
+   case SVGA3D_BUMPL8V8U8:
+      _debug_printf("\t\t.format = SVGA3D_BUMPL8V8U8\n");
+      break;
+   case SVGA3D_ARGB_S10E5:
+      _debug_printf("\t\t.format = SVGA3D_ARGB_S10E5\n");
+      break;
+   case SVGA3D_ARGB_S23E8:
+      _debug_printf("\t\t.format = SVGA3D_ARGB_S23E8\n");
+      break;
+   case SVGA3D_A2R10G10B10:
+      _debug_printf("\t\t.format = SVGA3D_A2R10G10B10\n");
+      break;
+   case SVGA3D_V8U8:
+      _debug_printf("\t\t.format = SVGA3D_V8U8\n");
+      break;
+   case SVGA3D_Q8W8V8U8:
+      _debug_printf("\t\t.format = SVGA3D_Q8W8V8U8\n");
+      break;
+   case SVGA3D_CxV8U8:
+      _debug_printf("\t\t.format = SVGA3D_CxV8U8\n");
+      break;
+   case SVGA3D_X8L8V8U8:
+      _debug_printf("\t\t.format = SVGA3D_X8L8V8U8\n");
+      break;
+   case SVGA3D_A2W10V10U10:
+      _debug_printf("\t\t.format = SVGA3D_A2W10V10U10\n");
+      break;
+   case SVGA3D_ALPHA8:
+      _debug_printf("\t\t.format = SVGA3D_ALPHA8\n");
+      break;
+   case SVGA3D_R_S10E5:
+      _debug_printf("\t\t.format = SVGA3D_R_S10E5\n");
+      break;
+   case SVGA3D_R_S23E8:
+      _debug_printf("\t\t.format = SVGA3D_R_S23E8\n");
+      break;
+   case SVGA3D_RG_S10E5:
+      _debug_printf("\t\t.format = SVGA3D_RG_S10E5\n");
+      break;
+   case SVGA3D_RG_S23E8:
+      _debug_printf("\t\t.format = SVGA3D_RG_S23E8\n");
+      break;
+   case SVGA3D_BUFFER:
+      _debug_printf("\t\t.format = SVGA3D_BUFFER\n");
+      break;
+   case SVGA3D_Z_D24X8:
+      _debug_printf("\t\t.format = SVGA3D_Z_D24X8\n");
+      break;
+   case SVGA3D_FORMAT_MAX:
+      _debug_printf("\t\t.format = SVGA3D_FORMAT_MAX\n");
+      break;
+   default:
+      _debug_printf("\t\t.format = %i\n", (*cmd).format);
+      break;
+   }
+   _debug_printf("\t\t.face[0].numMipLevels = %u\n", (*cmd).face[0].numMipLevels);
+   _debug_printf("\t\t.face[1].numMipLevels = %u\n", (*cmd).face[1].numMipLevels);
+   _debug_printf("\t\t.face[2].numMipLevels = %u\n", (*cmd).face[2].numMipLevels);
+   _debug_printf("\t\t.face[3].numMipLevels = %u\n", (*cmd).face[3].numMipLevels);
+   _debug_printf("\t\t.face[4].numMipLevels = %u\n", (*cmd).face[4].numMipLevels);
+   _debug_printf("\t\t.face[5].numMipLevels = %u\n", (*cmd).face[5].numMipLevels);
+}
+
+static void
+dump_SVGASignedRect(const SVGASignedRect *cmd)
+{
+   _debug_printf("\t\t.left = %i\n", (*cmd).left);
+   _debug_printf("\t\t.top = %i\n", (*cmd).top);
+   _debug_printf("\t\t.right = %i\n", (*cmd).right);
+   _debug_printf("\t\t.bottom = %i\n", (*cmd).bottom);
+}
+
+static void
+dump_SVGA3dCmdBlitSurfaceToScreen(const SVGA3dCmdBlitSurfaceToScreen *cmd)
+{
+   _debug_printf("\t\t.srcImage.sid = %u\n", (*cmd).srcImage.sid);
+   _debug_printf("\t\t.srcImage.face = %u\n", (*cmd).srcImage.face);
+   _debug_printf("\t\t.srcImage.mipmap = %u\n", (*cmd).srcImage.mipmap);
+   _debug_printf("\t\t.srcRect.left = %i\n", (*cmd).srcRect.left);
+   _debug_printf("\t\t.srcRect.top = %i\n", (*cmd).srcRect.top);
+   _debug_printf("\t\t.srcRect.right = %i\n", (*cmd).srcRect.right);
+   _debug_printf("\t\t.srcRect.bottom = %i\n", (*cmd).srcRect.bottom);
+   _debug_printf("\t\t.destScreenId = %u\n", (*cmd).destScreenId);
+   _debug_printf("\t\t.destRect.left = %i\n", (*cmd).destRect.left);
+   _debug_printf("\t\t.destRect.top = %i\n", (*cmd).destRect.top);
+   _debug_printf("\t\t.destRect.right = %i\n", (*cmd).destRect.right);
+   _debug_printf("\t\t.destRect.bottom = %i\n", (*cmd).destRect.bottom);
+}
+
+
+void            
+svga_dump_command(uint32_t cmd_id, const void *data, uint32_t size)
+{
+   const uint8_t *body = (const uint8_t *)data;
+   const uint8_t *next = body + size;
+  
+   switch(cmd_id) {
+   case SVGA_3D_CMD_SURFACE_DEFINE:
+      _debug_printf("\tSVGA_3D_CMD_SURFACE_DEFINE\n");
+      {
+         const SVGA3dCmdDefineSurface *cmd = (const SVGA3dCmdDefineSurface *)body;
+         dump_SVGA3dCmdDefineSurface(cmd);
+         body = (const uint8_t *)&cmd[1];
+         while(body + sizeof(SVGA3dSize) <= next) {
+            dump_SVGA3dSize((const SVGA3dSize *)body);
+            body += sizeof(SVGA3dSize);
+         }
+      }
+      break;
+   case SVGA_3D_CMD_SURFACE_DESTROY:
+      _debug_printf("\tSVGA_3D_CMD_SURFACE_DESTROY\n");
+      {
+         const SVGA3dCmdDestroySurface *cmd = (const SVGA3dCmdDestroySurface *)body;
+         dump_SVGA3dCmdDestroySurface(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_SURFACE_COPY:
+      _debug_printf("\tSVGA_3D_CMD_SURFACE_COPY\n");
+      {
+         const SVGA3dCmdSurfaceCopy *cmd = (const SVGA3dCmdSurfaceCopy *)body;
+         dump_SVGA3dCmdSurfaceCopy(cmd);
+         body = (const uint8_t *)&cmd[1];
+         while(body + sizeof(SVGA3dCopyBox) <= next) {
+            dump_SVGA3dCopyBox((const SVGA3dCopyBox *)body);
+            body += sizeof(SVGA3dCopyBox);
+         }
+      }
+      break;
+   case SVGA_3D_CMD_SURFACE_STRETCHBLT:
+      _debug_printf("\tSVGA_3D_CMD_SURFACE_STRETCHBLT\n");
+      {
+         const SVGA3dCmdSurfaceStretchBlt *cmd = (const SVGA3dCmdSurfaceStretchBlt *)body;
+         dump_SVGA3dCmdSurfaceStretchBlt(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_SURFACE_DMA:
+      _debug_printf("\tSVGA_3D_CMD_SURFACE_DMA\n");
+      {
+         const SVGA3dCmdSurfaceDMA *cmd = (const SVGA3dCmdSurfaceDMA *)body;
+         dump_SVGA3dCmdSurfaceDMA(cmd);
+         body = (const uint8_t *)&cmd[1];
+         while(body + sizeof(SVGA3dCopyBox) <= next) {
+            dump_SVGA3dCopyBox((const SVGA3dCopyBox *)body);
+            body += sizeof(SVGA3dCopyBox);
+         }
+         while(body + sizeof(SVGA3dCmdSurfaceDMASuffix) <= next) {
+            dump_SVGA3dCmdSurfaceDMASuffix((const SVGA3dCmdSurfaceDMASuffix *)body);
+            body += sizeof(SVGA3dCmdSurfaceDMASuffix);
+         }
+      }
+      break;
+   case SVGA_3D_CMD_CONTEXT_DEFINE:
+      _debug_printf("\tSVGA_3D_CMD_CONTEXT_DEFINE\n");
+      {
+         const SVGA3dCmdDefineContext *cmd = (const SVGA3dCmdDefineContext *)body;
+         dump_SVGA3dCmdDefineContext(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_CONTEXT_DESTROY:
+      _debug_printf("\tSVGA_3D_CMD_CONTEXT_DESTROY\n");
+      {
+         const SVGA3dCmdDestroyContext *cmd = (const SVGA3dCmdDestroyContext *)body;
+         dump_SVGA3dCmdDestroyContext(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_SETTRANSFORM:
+      _debug_printf("\tSVGA_3D_CMD_SETTRANSFORM\n");
+      {
+         const SVGA3dCmdSetTransform *cmd = (const SVGA3dCmdSetTransform *)body;
+         dump_SVGA3dCmdSetTransform(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_SETZRANGE:
+      _debug_printf("\tSVGA_3D_CMD_SETZRANGE\n");
+      {
+         const SVGA3dCmdSetZRange *cmd = (const SVGA3dCmdSetZRange *)body;
+         dump_SVGA3dCmdSetZRange(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_SETRENDERSTATE:
+      _debug_printf("\tSVGA_3D_CMD_SETRENDERSTATE\n");
+      {
+         const SVGA3dCmdSetRenderState *cmd = (const SVGA3dCmdSetRenderState *)body;
+         dump_SVGA3dCmdSetRenderState(cmd);
+         body = (const uint8_t *)&cmd[1];
+         while(body + sizeof(SVGA3dRenderState) <= next) {
+            dump_SVGA3dRenderState((const SVGA3dRenderState *)body);
+            body += sizeof(SVGA3dRenderState);
+         }
+      }
+      break;
+   case SVGA_3D_CMD_SETRENDERTARGET:
+      _debug_printf("\tSVGA_3D_CMD_SETRENDERTARGET\n");
+      {
+         const SVGA3dCmdSetRenderTarget *cmd = (const SVGA3dCmdSetRenderTarget *)body;
+         dump_SVGA3dCmdSetRenderTarget(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_SETTEXTURESTATE:
+      _debug_printf("\tSVGA_3D_CMD_SETTEXTURESTATE\n");
+      {
+         const SVGA3dCmdSetTextureState *cmd = (const SVGA3dCmdSetTextureState *)body;
+         dump_SVGA3dCmdSetTextureState(cmd);
+         body = (const uint8_t *)&cmd[1];
+         while(body + sizeof(SVGA3dTextureState) <= next) {
+            dump_SVGA3dTextureState((const SVGA3dTextureState *)body);
+            body += sizeof(SVGA3dTextureState);
+         }
+      }
+      break;
+   case SVGA_3D_CMD_SETMATERIAL:
+      _debug_printf("\tSVGA_3D_CMD_SETMATERIAL\n");
+      {
+         const SVGA3dCmdSetMaterial *cmd = (const SVGA3dCmdSetMaterial *)body;
+         dump_SVGA3dCmdSetMaterial(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_SETLIGHTDATA:
+      _debug_printf("\tSVGA_3D_CMD_SETLIGHTDATA\n");
+      {
+         const SVGA3dCmdSetLightData *cmd = (const SVGA3dCmdSetLightData *)body;
+         dump_SVGA3dCmdSetLightData(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_SETLIGHTENABLED:
+      _debug_printf("\tSVGA_3D_CMD_SETLIGHTENABLED\n");
+      {
+         const SVGA3dCmdSetLightEnabled *cmd = (const SVGA3dCmdSetLightEnabled *)body;
+         dump_SVGA3dCmdSetLightEnabled(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_SETVIEWPORT:
+      _debug_printf("\tSVGA_3D_CMD_SETVIEWPORT\n");
+      {
+         const SVGA3dCmdSetViewport *cmd = (const SVGA3dCmdSetViewport *)body;
+         dump_SVGA3dCmdSetViewport(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_SETCLIPPLANE:
+      _debug_printf("\tSVGA_3D_CMD_SETCLIPPLANE\n");
+      {
+         const SVGA3dCmdSetClipPlane *cmd = (const SVGA3dCmdSetClipPlane *)body;
+         dump_SVGA3dCmdSetClipPlane(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_CLEAR:
+      _debug_printf("\tSVGA_3D_CMD_CLEAR\n");
+      {
+         const SVGA3dCmdClear *cmd = (const SVGA3dCmdClear *)body;
+         dump_SVGA3dCmdClear(cmd);
+         body = (const uint8_t *)&cmd[1];
+         while(body + sizeof(SVGA3dRect) <= next) {
+            dump_SVGA3dRect((const SVGA3dRect *)body);
+            body += sizeof(SVGA3dRect);
+         }
+      }
+      break;
+   case SVGA_3D_CMD_PRESENT:
+      _debug_printf("\tSVGA_3D_CMD_PRESENT\n");
+      {
+         const SVGA3dCmdPresent *cmd = (const SVGA3dCmdPresent *)body;
+         dump_SVGA3dCmdPresent(cmd);
+         body = (const uint8_t *)&cmd[1];
+         while(body + sizeof(SVGA3dCopyRect) <= next) {
+            dump_SVGA3dCopyRect((const SVGA3dCopyRect *)body);
+            body += sizeof(SVGA3dCopyRect);
+         }
+      }
+      break;
+   case SVGA_3D_CMD_SHADER_DEFINE:
+      _debug_printf("\tSVGA_3D_CMD_SHADER_DEFINE\n");
+      {
+         const SVGA3dCmdDefineShader *cmd = (const SVGA3dCmdDefineShader *)body;
+         dump_SVGA3dCmdDefineShader(cmd);
+         body = (const uint8_t *)&cmd[1];
+         svga_shader_dump((const uint32_t *)body, 
+                      (unsigned)(next - body)/sizeof(uint32_t),
+                      FALSE );
+         body = next;
+      }
+      break;
+   case SVGA_3D_CMD_SHADER_DESTROY:
+      _debug_printf("\tSVGA_3D_CMD_SHADER_DESTROY\n");
+      {
+         const SVGA3dCmdDestroyShader *cmd = (const SVGA3dCmdDestroyShader *)body;
+         dump_SVGA3dCmdDestroyShader(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_SET_SHADER:
+      _debug_printf("\tSVGA_3D_CMD_SET_SHADER\n");
+      {
+         const SVGA3dCmdSetShader *cmd = (const SVGA3dCmdSetShader *)body;
+         dump_SVGA3dCmdSetShader(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_SET_SHADER_CONST:
+      _debug_printf("\tSVGA_3D_CMD_SET_SHADER_CONST\n");
+      {
+         const SVGA3dCmdSetShaderConst *cmd = (const SVGA3dCmdSetShaderConst *)body;
+         dump_SVGA3dCmdSetShaderConst(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_DRAW_PRIMITIVES:
+      _debug_printf("\tSVGA_3D_CMD_DRAW_PRIMITIVES\n");
+      {
+         const SVGA3dCmdDrawPrimitives *cmd = (const SVGA3dCmdDrawPrimitives *)body;
+         unsigned i, j;
+         dump_SVGA3dCmdDrawPrimitives(cmd);
+         body = (const uint8_t *)&cmd[1];
+         for(i = 0; i < cmd->numVertexDecls; ++i) {
+            dump_SVGA3dVertexDecl((const SVGA3dVertexDecl *)body);
+            body += sizeof(SVGA3dVertexDecl);
+         }
+         for(j = 0; j < cmd->numRanges; ++j) {
+            dump_SVGA3dPrimitiveRange((const SVGA3dPrimitiveRange *)body);
+            body += sizeof(SVGA3dPrimitiveRange);
+         }
+         while(body + sizeof(SVGA3dVertexDivisor) <= next) {
+            dump_SVGA3dVertexDivisor((const SVGA3dVertexDivisor *)body);
+            body += sizeof(SVGA3dVertexDivisor);
+         }
+      }
+      break;
+   case SVGA_3D_CMD_SETSCISSORRECT:
+      _debug_printf("\tSVGA_3D_CMD_SETSCISSORRECT\n");
+      {
+         const SVGA3dCmdSetScissorRect *cmd = (const SVGA3dCmdSetScissorRect *)body;
+         dump_SVGA3dCmdSetScissorRect(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_BEGIN_QUERY:
+      _debug_printf("\tSVGA_3D_CMD_BEGIN_QUERY\n");
+      {
+         const SVGA3dCmdBeginQuery *cmd = (const SVGA3dCmdBeginQuery *)body;
+         dump_SVGA3dCmdBeginQuery(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_END_QUERY:
+      _debug_printf("\tSVGA_3D_CMD_END_QUERY\n");
+      {
+         const SVGA3dCmdEndQuery *cmd = (const SVGA3dCmdEndQuery *)body;
+         dump_SVGA3dCmdEndQuery(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_WAIT_FOR_QUERY:
+      _debug_printf("\tSVGA_3D_CMD_WAIT_FOR_QUERY\n");
+      {
+         const SVGA3dCmdWaitForQuery *cmd = (const SVGA3dCmdWaitForQuery *)body;
+         dump_SVGA3dCmdWaitForQuery(cmd);
+         body = (const uint8_t *)&cmd[1];
+      }
+      break;
+   case SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN:
+      _debug_printf("\tSVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN\n");
+      {
+         const SVGA3dCmdBlitSurfaceToScreen *cmd = (const SVGA3dCmdBlitSurfaceToScreen *)body;
+         dump_SVGA3dCmdBlitSurfaceToScreen(cmd);
+         body = (const uint8_t *)&cmd[1];
+         while(body + sizeof(SVGASignedRect) <= next) {
+            dump_SVGASignedRect((const SVGASignedRect *)body);
+            body += sizeof(SVGASignedRect);
+         }
+      }
+      break;
+   default:
+      _debug_printf("\t0x%08x\n", cmd_id);
+      break;
+   }
+
+   while(body + sizeof(uint32_t) <= next) {
+      _debug_printf("\t\t0x%08x\n", *(const uint32_t *)body);
+      body += sizeof(uint32_t);
+   }
+   while(body + sizeof(uint32_t) <= next)
+      _debug_printf("\t\t0x%02x\n", *body++);
+}
+
+
+void            
+svga_dump_commands(const void *commands, uint32_t size)
+{
+   const uint8_t *next = commands;
+   const uint8_t *last = next + size;
+   
+   assert(size % sizeof(uint32_t) == 0);
+   
+   while(next < last) {
+      const uint32_t cmd_id = *(const uint32_t *)next;
+
+      if(SVGA_3D_CMD_BASE <= cmd_id && cmd_id < SVGA_3D_CMD_MAX) {
+         const SVGA3dCmdHeader *header = (const SVGA3dCmdHeader *)next;
+         const uint8_t *body = (const uint8_t *)&header[1];
+
+         next = body + header->size;
+         if(next > last)
+            break;
+
+         svga_dump_command(cmd_id, body, header->size);
+      }
+      else if(cmd_id == SVGA_CMD_FENCE) {
+         _debug_printf("\tSVGA_CMD_FENCE\n");
+         _debug_printf("\t\t0x%08x\n", ((const uint32_t *)next)[1]);
+         next += 2*sizeof(uint32_t);
+      }
+      else {
+         _debug_printf("\t0x%08x\n", cmd_id);
+         next += sizeof(uint32_t);
+      }
+   }
+}
+
diff --git a/src/gallium/drivers/svga/svgadump/svga_dump.h b/src/gallium/drivers/svga/svgadump/svga_dump.h
new file mode 100644
index 0000000..ca01543
--- /dev/null
+++ b/src/gallium/drivers/svga/svgadump/svga_dump.h
@@ -0,0 +1,37 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_DUMP_H_
+#define SVGA_DUMP_H_
+
+#include "pipe/p_compiler.h"
+
+void            
+svga_dump_command(uint32_t cmd_id, const void *data, uint32_t size);
+
+void
+svga_dump_commands(const void *commands, uint32_t size);
+
+#endif /* SVGA_DUMP_H_ */
diff --git a/src/gallium/drivers/svga/svgadump/svga_dump.py b/src/gallium/drivers/svga/svgadump/svga_dump.py
new file mode 100755
index 0000000..0bc0b3a
--- /dev/null
+++ b/src/gallium/drivers/svga/svgadump/svga_dump.py
@@ -0,0 +1,340 @@
+#!/usr/bin/env python
+'''
+Generates dumper for the SVGA 3D command stream using pygccxml.
+
+Jose Fonseca <jfonseca@vmware.com>
+'''
+
+copyright = '''
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+ '''
+
+import os
+import sys
+
+from pygccxml import parser
+from pygccxml import declarations
+
+from pygccxml.declarations import algorithm
+from pygccxml.declarations import decl_visitor
+from pygccxml.declarations import type_traits
+from pygccxml.declarations import type_visitor
+
+
+enums = True
+
+
+class decl_dumper_t(decl_visitor.decl_visitor_t):
+
+    def __init__(self, instance = '', decl = None):
+        decl_visitor.decl_visitor_t.__init__(self)
+        self._instance = instance
+        self.decl = decl
+
+    def clone(self):
+        return decl_dumper_t(self._instance, self.decl)
+
+    def visit_class(self):
+        class_ = self.decl
+        assert self.decl.class_type in ('struct', 'union')
+
+        for variable in class_.variables():
+            if variable.name != '':
+                #print 'variable = %r' % variable.name
+                dump_type(self._instance + '.' + variable.name, variable.type)
+
+    def visit_enumeration(self):
+        if enums:
+            print '   switch(%s) {' % ("(*cmd)" + self._instance,)
+            for name, value in self.decl.values:
+                print '   case %s:' % (name,)
+                print '      _debug_printf("\\t\\t%s = %s\\n");' % (self._instance, name)
+                print '      break;'
+            print '   default:'
+            print '      _debug_printf("\\t\\t%s = %%i\\n", %s);' % (self._instance, "(*cmd)" + self._instance)
+            print '      break;'
+            print '   }'
+        else:
+            print '   _debug_printf("\\t\\t%s = %%i\\n", %s);' % (self._instance, "(*cmd)" + self._instance)
+
+
+def dump_decl(instance, decl):
+    dumper = decl_dumper_t(instance, decl)
+    algorithm.apply_visitor(dumper, decl)
+
+
+class type_dumper_t(type_visitor.type_visitor_t):
+
+    def __init__(self, instance, type_):
+        type_visitor.type_visitor_t.__init__(self)
+        self.instance = instance
+        self.type = type_
+
+    def clone(self):
+        return type_dumper_t(self.instance, self.type)
+
+    def visit_char(self):
+        self.print_instance('%i')
+        
+    def visit_unsigned_char(self):
+        self.print_instance('%u')
+
+    def visit_signed_char(self):
+        self.print_instance('%i')
+    
+    def visit_wchar(self):
+        self.print_instance('%i')
+        
+    def visit_short_int(self):
+        self.print_instance('%i')
+        
+    def visit_short_unsigned_int(self):
+        self.print_instance('%u')
+        
+    def visit_bool(self):
+        self.print_instance('%i')
+        
+    def visit_int(self):
+        self.print_instance('%i')
+        
+    def visit_unsigned_int(self):
+        self.print_instance('%u')
+        
+    def visit_long_int(self):
+        self.print_instance('%li')
+        
+    def visit_long_unsigned_int(self):
+        self.print_instance('%lu')
+        
+    def visit_long_long_int(self):
+        self.print_instance('%lli')
+        
+    def visit_long_long_unsigned_int(self):
+        self.print_instance('%llu')
+        
+    def visit_float(self):
+        self.print_instance('%f')
+        
+    def visit_double(self):
+        self.print_instance('%f')
+        
+    def visit_array(self):
+        for i in range(type_traits.array_size(self.type)):
+            dump_type(self.instance + '[%i]' % i, type_traits.base_type(self.type))
+
+    def visit_pointer(self):
+        self.print_instance('%p')
+
+    def visit_declarated(self):
+        #print 'decl = %r' % self.type.decl_string
+        decl = type_traits.remove_declarated(self.type)
+        dump_decl(self.instance, decl)
+
+    def print_instance(self, format):
+        print '   _debug_printf("\\t\\t%s = %s\\n", %s);' % (self.instance, format, "(*cmd)" + self.instance)
+
+
+def dump_type(instance, type_):
+    type_ = type_traits.remove_alias(type_)
+    visitor = type_dumper_t(instance, type_)
+    algorithm.apply_visitor(visitor, type_)
+
+
+def dump_struct(decls, class_):
+    print 'static void'
+    print 'dump_%s(const %s *cmd)' % (class_.name, class_.name)
+    print '{'
+    dump_decl('', class_)
+    print '}'
+    print ''
+
+
+cmds = [
+    ('SVGA_3D_CMD_SURFACE_DEFINE', 'SVGA3dCmdDefineSurface', (), 'SVGA3dSize'),
+    ('SVGA_3D_CMD_SURFACE_DESTROY', 'SVGA3dCmdDestroySurface', (), None),
+    ('SVGA_3D_CMD_SURFACE_COPY', 'SVGA3dCmdSurfaceCopy', (), 'SVGA3dCopyBox'),
+    ('SVGA_3D_CMD_SURFACE_STRETCHBLT', 'SVGA3dCmdSurfaceStretchBlt', (), None),
+    ('SVGA_3D_CMD_SURFACE_DMA', 'SVGA3dCmdSurfaceDMA', (), 'SVGA3dCopyBox'),
+    ('SVGA_3D_CMD_CONTEXT_DEFINE', 'SVGA3dCmdDefineContext', (), None),
+    ('SVGA_3D_CMD_CONTEXT_DESTROY', 'SVGA3dCmdDestroyContext', (), None),
+    ('SVGA_3D_CMD_SETTRANSFORM', 'SVGA3dCmdSetTransform', (), None),
+    ('SVGA_3D_CMD_SETZRANGE', 'SVGA3dCmdSetZRange', (), None),
+    ('SVGA_3D_CMD_SETRENDERSTATE', 'SVGA3dCmdSetRenderState', (), 'SVGA3dRenderState'),
+    ('SVGA_3D_CMD_SETRENDERTARGET', 'SVGA3dCmdSetRenderTarget', (), None),
+    ('SVGA_3D_CMD_SETTEXTURESTATE', 'SVGA3dCmdSetTextureState', (), 'SVGA3dTextureState'),
+    ('SVGA_3D_CMD_SETMATERIAL', 'SVGA3dCmdSetMaterial', (), None),
+    ('SVGA_3D_CMD_SETLIGHTDATA', 'SVGA3dCmdSetLightData', (), None),
+    ('SVGA_3D_CMD_SETLIGHTENABLED', 'SVGA3dCmdSetLightEnabled', (), None),
+    ('SVGA_3D_CMD_SETVIEWPORT', 'SVGA3dCmdSetViewport', (), None),
+    ('SVGA_3D_CMD_SETCLIPPLANE', 'SVGA3dCmdSetClipPlane', (), None),
+    ('SVGA_3D_CMD_CLEAR', 'SVGA3dCmdClear', (), 'SVGA3dRect'),
+    ('SVGA_3D_CMD_PRESENT', 'SVGA3dCmdPresent', (), 'SVGA3dCopyRect'),
+    ('SVGA_3D_CMD_SHADER_DEFINE', 'SVGA3dCmdDefineShader', (), None),
+    ('SVGA_3D_CMD_SHADER_DESTROY', 'SVGA3dCmdDestroyShader', (), None),
+    ('SVGA_3D_CMD_SET_SHADER', 'SVGA3dCmdSetShader', (), None),
+    ('SVGA_3D_CMD_SET_SHADER_CONST', 'SVGA3dCmdSetShaderConst', (), None),
+    ('SVGA_3D_CMD_DRAW_PRIMITIVES', 'SVGA3dCmdDrawPrimitives', (('SVGA3dVertexDecl', 'numVertexDecls'), ('SVGA3dPrimitiveRange', 'numRanges')), 'SVGA3dVertexDivisor'),
+    ('SVGA_3D_CMD_SETSCISSORRECT', 'SVGA3dCmdSetScissorRect', (), None),
+    ('SVGA_3D_CMD_BEGIN_QUERY', 'SVGA3dCmdBeginQuery', (), None),
+    ('SVGA_3D_CMD_END_QUERY', 'SVGA3dCmdEndQuery', (), None),
+    ('SVGA_3D_CMD_WAIT_FOR_QUERY', 'SVGA3dCmdWaitForQuery', (), None),
+    #('SVGA_3D_CMD_PRESENT_READBACK', None, (), None),
+    ('SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN', 'SVGA3dCmdBlitSurfaceToScreen', (), 'SVGASignedRect'),
+]
+
+def dump_cmds():
+    print r'''
+void            
+svga_dump_command(uint32_t cmd_id, const void *data, uint32_t size)
+{
+   const uint8_t *body = (const uint8_t *)data;
+   const uint8_t *next = body + size;
+'''
+    print '   switch(cmd_id) {'
+    indexes = 'ijklmn'
+    for id, header, body, footer in cmds:
+        print '   case %s:' % id
+        print '      _debug_printf("\\t%s\\n");' % id
+        print '      {'
+        print '         const %s *cmd = (const %s *)body;' % (header, header)
+        if len(body):
+            print '         unsigned ' + ', '.join(indexes[:len(body)]) + ';'
+        print '         dump_%s(cmd);' % header
+        print '         body = (const uint8_t *)&cmd[1];'
+        for i in range(len(body)):
+            struct, count = body[i]
+            idx = indexes[i]
+            print '         for(%s = 0; %s < cmd->%s; ++%s) {' % (idx, idx, count, idx)
+            print '            dump_%s((const %s *)body);' % (struct, struct)
+            print '            body += sizeof(%s);' % struct
+            print '         }'
+        if footer is not None:
+            print '         while(body + sizeof(%s) <= next) {' % footer
+            print '            dump_%s((const %s *)body);' % (footer, footer)
+            print '            body += sizeof(%s);' % footer
+            print '         }'
+        if id == 'SVGA_3D_CMD_SHADER_DEFINE':
+            print '         svga_shader_dump((const uint32_t *)body,'
+            print '                          (unsigned)(next - body)/sizeof(uint32_t),'
+            print '                          FALSE);'
+            print '         body = next;'
+        print '      }'
+        print '      break;'
+    print '   default:'
+    print '      _debug_printf("\\t0x%08x\\n", cmd_id);'
+    print '      break;'
+    print '   }'
+    print r'''
+   while(body + sizeof(uint32_t) <= next) {
+      _debug_printf("\t\t0x%08x\n", *(const uint32_t *)body);
+      body += sizeof(uint32_t);
+   }
+   while(body + sizeof(uint32_t) <= next)
+      _debug_printf("\t\t0x%02x\n", *body++);
+}
+'''
+    print r'''
+void            
+svga_dump_commands(const void *commands, uint32_t size)
+{
+   const uint8_t *next = commands;
+   const uint8_t *last = next + size;
+   
+   assert(size % sizeof(uint32_t) == 0);
+   
+   while(next < last) {
+      const uint32_t cmd_id = *(const uint32_t *)next;
+
+      if(SVGA_3D_CMD_BASE <= cmd_id && cmd_id < SVGA_3D_CMD_MAX) {
+         const SVGA3dCmdHeader *header = (const SVGA3dCmdHeader *)next;
+         const uint8_t *body = (const uint8_t *)&header[1];
+
+         next = body + header->size;
+         if(next > last)
+            break;
+
+         svga_dump_command(cmd_id, body, header->size);
+      }
+      else if(cmd_id == SVGA_CMD_FENCE) {
+         _debug_printf("\tSVGA_CMD_FENCE\n");
+         _debug_printf("\t\t0x%08x\n", ((const uint32_t *)next)[1]);
+         next += 2*sizeof(uint32_t);
+      }
+      else {
+         _debug_printf("\t0x%08x\n", cmd_id);
+         next += sizeof(uint32_t);
+      }
+   }
+}
+'''
+
+def main():
+    print copyright.strip()
+    print
+    print '/**'
+    print ' * @file'
+    print ' * Dump SVGA commands.'
+    print ' *'
+    print ' * Generated automatically from svga3d_reg.h by svga_dump.py.'
+    print ' */'
+    print
+    print '#include "svga_types.h"'
+    print '#include "svga_shader_dump.h"'
+    print '#include "svga3d_reg.h"'
+    print
+    print '#include "util/u_debug.h"'
+    print '#include "svga_dump.h"'
+    print
+
+    config = parser.config_t(
+        include_paths = ['../../../include', '../include'],
+        compiler = 'gcc',
+    )
+
+    headers = [
+        'svga_types.h', 
+        'svga3d_reg.h', 
+    ]
+
+    decls = parser.parse(headers, config, parser.COMPILATION_MODE.ALL_AT_ONCE)
+    global_ns = declarations.get_global_namespace(decls)
+
+    names = set()
+    for id, header, body, footer in cmds:
+        names.add(header)
+        for struct, count in body:
+            names.add(struct)
+        if footer is not None:
+            names.add(footer)
+
+    for class_ in global_ns.classes(lambda decl: decl.name in names):
+        dump_struct(decls, class_)
+
+    dump_cmds()
+
+
+if __name__ == '__main__':
+    main()
diff --git a/src/gallium/drivers/svga/svgadump/svga_shader.h b/src/gallium/drivers/svga/svgadump/svga_shader.h
new file mode 100644
index 0000000..9217af2
--- /dev/null
+++ b/src/gallium/drivers/svga/svgadump/svga_shader.h
@@ -0,0 +1,220 @@
+/**********************************************************
+ * Copyright 2007-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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
+ * SVGA Shader Token Definitions
+ * 
+ * @author Michal Krol <michal@vmware.com>
+ */
+
+#ifndef ST_SHADER_SVGA_H
+#define ST_SHADER_SVGA_H
+
+#include "pipe/p_compiler.h"
+
+struct sh_op
+{
+   unsigned opcode:16;
+   unsigned control:8;
+   unsigned length:4;
+   unsigned predicated:1;
+   unsigned unused:1;
+   unsigned coissue:1;
+   unsigned is_reg:1;
+};
+
+struct sh_reg
+{
+   unsigned number:11;
+   unsigned type_hi:2;
+   unsigned relative:1;
+   unsigned unused:14;
+   unsigned type_lo:3;
+   unsigned is_reg:1;
+};
+
+static INLINE unsigned
+sh_reg_type( struct sh_reg reg )
+{
+   return reg.type_lo | (reg.type_hi << 3);
+}
+
+struct sh_cdata
+{
+   float xyzw[4];
+};
+
+struct sh_def
+{
+   struct sh_op op;
+   struct sh_reg reg;
+   struct sh_cdata cdata;
+};
+
+struct sh_defb
+{
+   struct sh_op op;
+   struct sh_reg reg;
+   uint data;
+};
+
+struct sh_idata
+{
+   int xyzw[4];
+};
+
+struct sh_defi
+{
+   struct sh_op op;
+   struct sh_reg reg;
+   struct sh_idata idata;
+};
+
+#define PS_TEXTURETYPE_UNKNOWN   SVGA3DSAMP_UNKNOWN
+#define PS_TEXTURETYPE_2D        SVGA3DSAMP_2D
+#define PS_TEXTURETYPE_CUBE      SVGA3DSAMP_CUBE
+#define PS_TEXTURETYPE_VOLUME    SVGA3DSAMP_VOLUME
+
+struct ps_sampleinfo
+{
+   unsigned unused:27;
+   unsigned texture_type:4;
+   unsigned is_reg:1;
+};
+
+struct vs_semantic
+{
+   unsigned usage:5;
+   unsigned unused1:11;
+   unsigned usage_index:4;
+   unsigned unused2:12;
+};
+
+struct sh_dstreg
+{
+   unsigned number:11;
+   unsigned type_hi:2;
+   unsigned relative:1;
+   unsigned unused:2;
+   unsigned write_mask:4;
+   unsigned modifier:4;
+   unsigned shift_scale:4;
+   unsigned type_lo:3;
+   unsigned is_reg:1;
+};
+
+static INLINE unsigned
+sh_dstreg_type( struct sh_dstreg reg )
+{
+   return reg.type_lo | (reg.type_hi << 3);
+}
+
+struct sh_dcl
+{
+   struct sh_op op;
+   union {
+      struct {
+         struct ps_sampleinfo sampleinfo;
+      } ps;
+      struct {
+         struct vs_semantic semantic;
+      } vs;
+   } u;
+   struct sh_dstreg reg;
+};
+
+
+struct sh_srcreg
+{
+   unsigned number:11;
+   unsigned type_hi:2;
+   unsigned relative:1;
+   unsigned unused:2;
+   unsigned swizzle_x:2;
+   unsigned swizzle_y:2;
+   unsigned swizzle_z:2;
+   unsigned swizzle_w:2;
+   unsigned modifier:4;
+   unsigned type_lo:3;
+   unsigned is_reg:1;
+};
+
+static INLINE unsigned
+sh_srcreg_type( struct sh_srcreg reg )
+{
+   return reg.type_lo | (reg.type_hi << 3);
+}
+
+struct sh_dstop
+{
+   struct sh_op op;
+   struct sh_dstreg dst;
+};
+
+struct sh_srcop
+{
+   struct sh_op op;
+   struct sh_srcreg src;
+};
+
+struct sh_src2op
+{
+   struct sh_op op;
+   struct sh_srcreg src0;
+   struct sh_srcreg src1;
+};
+
+struct sh_unaryop
+{
+   struct sh_op op;
+   struct sh_dstreg dst;
+   struct sh_srcreg src;
+};
+
+struct sh_binaryop
+{
+   struct sh_op op;
+   struct sh_dstreg dst;
+   struct sh_srcreg src0;
+   struct sh_srcreg src1;
+};
+
+struct sh_trinaryop
+{
+   struct sh_op op;
+   struct sh_dstreg dst;
+   struct sh_srcreg src0;
+   struct sh_srcreg src1;
+   struct sh_srcreg src2;
+};
+
+struct sh_comment
+{
+   unsigned opcode:16;
+   unsigned size:16;
+};
+
+#endif /* ST_SHADER_SVGA_H */
diff --git a/src/gallium/drivers/svga/svgadump/svga_shader_dump.c b/src/gallium/drivers/svga/svgadump/svga_shader_dump.c
new file mode 100644
index 0000000..70e27d8
--- /dev/null
+++ b/src/gallium/drivers/svga/svgadump/svga_shader_dump.c
@@ -0,0 +1,654 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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
+ * SVGA Shader Dump Facilities
+ * 
+ * @author Michal Krol <michal@vmware.com>
+ */
+
+#include "svga_shader.h"
+#include "svga_shader_dump.h"
+#include "svga_shader_op.h"
+#include "util/u_debug.h"
+
+#include "../svga_hw_reg.h"
+#include "svga3d_shaderdefs.h"
+
+struct dump_info
+{
+   SVGA3dShaderVersion version;
+   boolean is_ps;
+};
+
+static void dump_op( struct sh_op op, const char *mnemonic )
+{
+   assert( op.predicated == 0 );
+   assert( op.is_reg == 0 );
+
+   if (op.coissue)
+      _debug_printf( "+" );
+   _debug_printf( "%s", mnemonic );
+   switch (op.control) {
+   case 0:
+      break;
+   case SVGA3DOPCONT_PROJECT:
+      _debug_printf( "p" );
+      break;
+   case SVGA3DOPCONT_BIAS:
+      _debug_printf( "b" );
+      break;
+   default:
+      assert( 0 );
+   }
+}
+
+
+static void dump_comp_op( struct sh_op op, const char *mnemonic )
+{
+   assert( op.is_reg == 0 );
+
+   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 );
+   }
+}
+
+
+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 );
+      break;
+
+   case SVGA3DREG_INPUT:
+      _debug_printf( "v%u", reg.number );
+      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 );
+      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 );
+      break;
+
+   case SVGA3DREG_RASTOUT:
+      switch (reg.number) {
+      case 0 /*POSITION*/:
+         _debug_printf( "oPos" );
+         break;
+      case 1 /*FOG*/:
+         _debug_printf( "oFog" );
+         break;
+      case 2 /*POINT_SIZE*/:
+         _debug_printf( "oPts" );
+         break;
+      default:
+         assert( 0 );
+         _debug_printf( "???" );
+      }
+      break;
+
+   case SVGA3DREG_ATTROUT:
+      assert( reg.number < 2 );
+      _debug_printf( "oD%u", reg.number );
+      break;
+
+   case SVGA3DREG_TEXCRDOUT:
+   /* SVGA3DREG_OUTPUT */
+      _debug_printf( "oT%u", reg.number );
+      break;
+
+   case SVGA3DREG_COLOROUT:
+      _debug_printf( "oC%u", reg.number );
+      break;
+
+   case SVGA3DREG_DEPTHOUT:
+      _debug_printf( "oD%u", reg.number );
+      break;
+
+   case SVGA3DREG_SAMPLER:
+      _debug_printf( "s%u", reg.number );
+      break;
+
+   case SVGA3DREG_CONSTBOOL:
+      assert( !reg.relative );
+      _debug_printf( "b%u", reg.number );
+      break;
+
+   case SVGA3DREG_CONSTINT:
+      assert( !reg.relative );
+      _debug_printf( "i%u", reg.number );
+      break;
+
+   case SVGA3DREG_LOOP:
+      assert( reg.number == 0 );
+      _debug_printf( "aL" );
+      break;
+
+   case SVGA3DREG_MISCTYPE:
+      switch (reg.number) {
+      case SVGA3DMISCREG_POSITION:
+         _debug_printf( "vPos" );
+         break;
+      case SVGA3DMISCREG_FACE:
+         _debug_printf( "vFace" );
+         break;
+      default:
+         assert(0);
+         break;
+      }
+      break;
+
+   case SVGA3DREG_LABEL:
+      _debug_printf( "l%u", reg.number );
+      break;
+
+   case SVGA3DREG_PREDICATE:
+      _debug_printf( "p%u", reg.number );
+      break;
+
+
+   default:
+      assert( 0 );
+      _debug_printf( "???" );
+   }
+}
+
+static void dump_cdata( struct sh_cdata cdata )
+{
+   _debug_printf( "%f, %f, %f, %f", cdata.xyzw[0], cdata.xyzw[1], cdata.xyzw[2], cdata.xyzw[3] );
+}
+
+static void dump_idata( struct sh_idata idata )
+{
+   _debug_printf( "%d, %d, %d, %d", idata.xyzw[0], idata.xyzw[1], idata.xyzw[2], idata.xyzw[3] );
+}
+
+static void dump_bdata( boolean bdata )
+{
+   _debug_printf( bdata ? "TRUE" : "FALSE" );
+}
+
+static void dump_sampleinfo( struct ps_sampleinfo sampleinfo )
+{
+   switch (sampleinfo.texture_type) {
+   case SVGA3DSAMP_2D:
+      _debug_printf( "_2d" );
+      break;
+   case SVGA3DSAMP_CUBE:
+      _debug_printf( "_cube" );
+      break;
+   case SVGA3DSAMP_VOLUME:
+      _debug_printf( "_volume" );
+      break;
+   default:
+      assert( 0 );
+   }
+}
+
+
+static void dump_usageinfo( struct vs_semantic semantic )
+{
+   switch (semantic.usage) {
+   case SVGA3D_DECLUSAGE_POSITION:
+      _debug_printf("_position" );
+      break;
+   case SVGA3D_DECLUSAGE_BLENDWEIGHT:
+      _debug_printf("_blendweight" );
+      break;
+   case SVGA3D_DECLUSAGE_BLENDINDICES:
+      _debug_printf("_blendindices" );
+      break;
+   case SVGA3D_DECLUSAGE_NORMAL:
+      _debug_printf("_normal" );
+      break;
+   case SVGA3D_DECLUSAGE_PSIZE:
+      _debug_printf("_psize" );
+      break;
+   case SVGA3D_DECLUSAGE_TEXCOORD:
+      _debug_printf("_texcoord");
+      break;
+   case SVGA3D_DECLUSAGE_TANGENT:
+      _debug_printf("_tangent" );
+      break;
+   case SVGA3D_DECLUSAGE_BINORMAL:
+      _debug_printf("_binormal" );
+      break;
+   case SVGA3D_DECLUSAGE_TESSFACTOR:
+      _debug_printf("_tessfactor" );
+      break;
+   case SVGA3D_DECLUSAGE_POSITIONT:
+      _debug_printf("_positiont" );
+      break;
+   case SVGA3D_DECLUSAGE_COLOR:
+      _debug_printf("_color" );
+      break;
+   case SVGA3D_DECLUSAGE_FOG:
+      _debug_printf("_fog" );
+      break;
+   case SVGA3D_DECLUSAGE_DEPTH:
+      _debug_printf("_depth" );
+      break;
+   case SVGA3D_DECLUSAGE_SAMPLE:
+      _debug_printf("_sample");
+      break;
+   default:
+      assert( 0 );
+      return;
+   }
+
+   if (semantic.usage_index != 0) {
+      _debug_printf("%d", semantic.usage_index );
+   }
+}
+
+static void dump_dstreg( struct sh_dstreg dstreg, const struct dump_info *di )
+{
+   union {
+      struct sh_reg reg;
+      struct sh_dstreg dstreg;
+   } u;
+
+   assert( (dstreg.modifier & (SVGA3DDSTMOD_SATURATE | SVGA3DDSTMOD_PARTIALPRECISION)) == dstreg.modifier );
+
+   if (dstreg.modifier & SVGA3DDSTMOD_SATURATE)
+      _debug_printf( "_sat" );
+   if (dstreg.modifier & SVGA3DDSTMOD_PARTIALPRECISION)
+      _debug_printf( "_pp" );
+   switch (dstreg.shift_scale) {
+   case 0:
+      break;
+   case 1:
+      _debug_printf( "_x2" );
+      break;
+   case 2:
+      _debug_printf( "_x4" );
+      break;
+   case 3:
+      _debug_printf( "_x8" );
+      break;
+   case 13:
+      _debug_printf( "_d8" );
+      break;
+   case 14:
+      _debug_printf( "_d4" );
+      break;
+   case 15:
+      _debug_printf( "_d2" );
+      break;
+   default:
+      assert( 0 );
+   }
+   _debug_printf( " " );
+
+   u.dstreg = dstreg;
+   dump_reg( u.reg, NULL, di );
+   if (dstreg.write_mask != SVGA3DWRITEMASK_ALL) {
+      _debug_printf( "." );
+      if (dstreg.write_mask & SVGA3DWRITEMASK_0)
+         _debug_printf( "x" );
+      if (dstreg.write_mask & SVGA3DWRITEMASK_1)
+         _debug_printf( "y" );
+      if (dstreg.write_mask & SVGA3DWRITEMASK_2)
+         _debug_printf( "z" );
+      if (dstreg.write_mask & SVGA3DWRITEMASK_3)
+         _debug_printf( "w" );
+   }
+}
+
+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( "-|" );
+      break;
+   case SVGA3DSRCMOD_COMP:
+      _debug_printf( "1-" );
+      break;
+   case SVGA3DSRCMOD_NOT:
+      _debug_printf( "!" );
+   }
+
+   u.srcreg = srcreg;
+   dump_reg( u.reg, 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" );
+      break;
+   case SVGA3DSRCMOD_SIGN:
+   case SVGA3DSRCMOD_SIGNNEG:
+      _debug_printf( "_bx2" );
+      break;
+   case SVGA3DSRCMOD_X2:
+   case SVGA3DSRCMOD_X2NEG:
+      _debug_printf( "_x2" );
+      break;
+   case SVGA3DSRCMOD_DZ:
+      _debug_printf( "_dz" );
+      break;
+   case SVGA3DSRCMOD_DW:
+      _debug_printf( "_dw" );
+      break;
+   default:
+      assert( 0 );
+   }
+   if (srcreg.swizzle_x != 0 || srcreg.swizzle_y != 1 || srcreg.swizzle_z != 2 || srcreg.swizzle_w != 3) {
+      _debug_printf( "." );
+      if (srcreg.swizzle_x == srcreg.swizzle_y && srcreg.swizzle_y == srcreg.swizzle_z && srcreg.swizzle_z == srcreg.swizzle_w) {
+         _debug_printf( "%c", "xyzw"[srcreg.swizzle_x] );
+      }
+      else {
+         _debug_printf( "%c", "xyzw"[srcreg.swizzle_x] );
+         _debug_printf( "%c", "xyzw"[srcreg.swizzle_y] );
+         _debug_printf( "%c", "xyzw"[srcreg.swizzle_z] );
+         _debug_printf( "%c", "xyzw"[srcreg.swizzle_w] );
+      }
+   }
+}
+
+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);
+
+   _debug_printf(
+      "%s_%u_%u\n",
+      di.is_ps ? "ps" : "vs",
+      di.version.major,
+      di.version.minor );
+
+   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 );
+            }
+            else
+               dump_usageinfo( dcl.u.vs.semantic );
+            dump_dstreg( dcl.reg, &di );
+            _debug_printf( "\n" );
+            assem += sizeof( struct sh_dcl ) / sizeof( unsigned );
+         }
+         break;
+
+      case SVGA3DOP_DEFB:
+         {
+            struct sh_defb defb = *(struct sh_defb *) assem;
+
+            _debug_printf( "defb " );
+            dump_reg( defb.reg, NULL, &di );
+            _debug_printf( ", " );
+            dump_bdata( defb.data );
+            _debug_printf( "\n" );
+            assem += sizeof( struct sh_defb ) / sizeof( unsigned );
+         }
+         break;
+
+      case SVGA3DOP_DEFI:
+         {
+            struct sh_defi defi = *(struct sh_defi *) assem;
+
+            _debug_printf( "defi " );
+            dump_reg( defi.reg, NULL, &di );
+            _debug_printf( ", " );
+            dump_idata( defi.idata );
+            _debug_printf( "\n" );
+            assem += sizeof( struct sh_defi ) / sizeof( unsigned );
+         }
+         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 );
+         }
+         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;
+
+               dump_dstreg( dstop.dst, &di );
+               assem += sizeof( struct sh_dstop ) / sizeof( unsigned );
+            }
+            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 );
+            }
+         }
+         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:
+         {
+            struct sh_def def = *(struct sh_def *) assem;
+
+            _debug_printf( "def " );
+            dump_reg( def.reg, NULL, &di );
+            _debug_printf( ", " );
+            dump_cdata( def.cdata );
+            _debug_printf( "\n" );
+            assem += sizeof( struct sh_def ) / sizeof( unsigned );
+         }
+         break;
+
+      case SVGA3DOP_PHASE:
+         _debug_printf( "phase\n" );
+         assem += sizeof( struct sh_op ) / sizeof( unsigned );
+         break;
+
+      case SVGA3DOP_COMMENT:
+         {
+            struct sh_comment comment = *(struct sh_comment *)assem;
+
+            /* Ignore comment contents. */
+            assem += sizeof(struct sh_comment) / sizeof(unsigned) + comment.size;
+         }
+         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;
+
+            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" );
+         }
+      }
+   }
+}
diff --git a/src/gallium/drivers/svga/svgadump/svga_shader_dump.h b/src/gallium/drivers/svga/svgadump/svga_shader_dump.h
new file mode 100644
index 0000000..a2657ac
--- /dev/null
+++ b/src/gallium/drivers/svga/svgadump/svga_shader_dump.h
@@ -0,0 +1,42 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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
+ * SVGA Shader Dump Facilities
+ * 
+ * @author Michal Krol <michal@vmware.com>
+ */
+
+#ifndef SVGA_SHADER_DUMP_H
+#define SVGA_SHADER_DUMP_H
+
+void
+svga_shader_dump(
+   const unsigned *assem,
+   unsigned dwords,
+   unsigned do_binary );
+
+#endif /* SVGA_SHADER_DUMP_H */
diff --git a/src/gallium/drivers/svga/svgadump/svga_shader_op.c b/src/gallium/drivers/svga/svgadump/svga_shader_op.c
new file mode 100644
index 0000000..8343bfd
--- /dev/null
+++ b/src/gallium/drivers/svga/svgadump/svga_shader_op.c
@@ -0,0 +1,168 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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
+ * SVGA Shader Token Opcode Info
+ * 
+ * @author Michal Krol <michal@vmware.com>
+ */
+
+#include "util/u_debug.h"
+#include "svga_shader_op.h"
+
+#include "../svga_hw_reg.h"
+#include "svga3d_shaderdefs.h"
+
+#define SVGA3DOP_INVALID SVGA3DOP_END
+#define TGSI_OPCODE_INVALID TGSI_OPCODE_LAST
+
+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,     },
+};
+
+const struct sh_opcode_info *svga_opcode_info( uint op )
+{
+   struct sh_opcode_info *info;
+
+   if (op >= sizeof( opcode_info ) / sizeof( opcode_info[0] )) {
+      /* The opcode is either PHASE, COMMENT, END or out of range.
+       */
+      assert( 0 );
+      return NULL;
+   }
+
+   info = &opcode_info[op];
+
+   if (info->svga_opcode == SVGA3DOP_INVALID) {
+      /* No valid information. Please provide number of dst/src registers.
+       */
+      assert( 0 );
+      return NULL;
+   }
+
+   /* Sanity check.
+    */
+   assert( op == info->svga_opcode );
+
+   return info;
+}
diff --git a/src/gallium/drivers/svga/svgadump/svga_shader_op.h b/src/gallium/drivers/svga/svgadump/svga_shader_op.h
new file mode 100644
index 0000000..e558de0
--- /dev/null
+++ b/src/gallium/drivers/svga/svgadump/svga_shader_op.h
@@ -0,0 +1,46 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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
+ * SVGA Shader Token Opcode Info
+ * 
+ * @author Michal Krol <michal@vmware.com>
+ */
+
+#ifndef SVGA_SHADER_OP_H
+#define SVGA_SHADER_OP_H
+
+struct sh_opcode_info
+{
+   const char *mnemonic;
+   unsigned num_dst:8;
+   unsigned num_src:8;
+   unsigned svga_opcode:16;
+};
+
+const struct sh_opcode_info *svga_opcode_info( unsigned op );
+
+#endif /* SVGA_SHADER_OP_H */
diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README
index 1000c31..203c385 100644
--- a/src/gallium/drivers/trace/README
+++ b/src/gallium/drivers/trace/README
@@ -24,11 +24,10 @@
 
  ldd progs/trivial/tri 
 
-== Traceing ==
+== Tracing ==
 
-For traceing then do
+For tracing then do
 
- export XMESA_TRACE=y
  GALLIUM_TRACE=tri.trace progs/trivial/tri
 
 which should create a tri.trace file, which is an XML file. You can view copying 
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index bf470b4..075e4f9 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -52,6 +52,7 @@
 
    assert(tr_buf->buffer);
    assert(tr_buf->buffer->screen == tr_scr->screen);
+   (void) tr_scr;
    return tr_buf->buffer;
 }
 
@@ -90,30 +91,12 @@
 
    assert(tr_surf->surface);
    assert(tr_surf->surface->texture->screen == tr_scr->screen);
+   (void) tr_scr;
    return tr_surf->surface;
 }
 
 
 static INLINE void
-trace_context_set_edgeflags(struct pipe_context *_pipe,
-                            const unsigned *bitfield)
-{
-   struct trace_context *tr_ctx = trace_context(_pipe);
-   struct pipe_context *pipe = tr_ctx->pipe;
-
-   trace_dump_call_begin("pipe_context", "set_edgeflags");
-
-   trace_dump_arg(ptr, pipe);
-   /* FIXME: we don't know how big this array is */
-   trace_dump_arg(ptr, bitfield);
-
-   pipe->set_edgeflags(pipe, bitfield);;
-
-   trace_dump_call_end();
-}
-
-
-static INLINE void
 trace_context_draw_block(struct trace_context *tr_ctx, int flag)
 {
    int k;
@@ -143,10 +126,16 @@
          for (k = 0; k < tr_ctx->curr.nr_cbufs; k++)
             if (tr_ctx->draw_rule.surf == tr_ctx->curr.cbufs[k])
                block = TRUE;
-      if (tr_ctx->draw_rule.tex)
+      if (tr_ctx->draw_rule.tex) {
          for (k = 0; k < tr_ctx->curr.num_texs; k++)
             if (tr_ctx->draw_rule.tex == tr_ctx->curr.tex[k])
                block = TRUE;
+         for (k = 0; k < tr_ctx->curr.num_vert_texs; k++) {
+            if (tr_ctx->draw_rule.tex == tr_ctx->curr.vert_tex[k]) {
+               block = TRUE;
+            }
+         }
+      }
 
       if (block)
          tr_ctx->draw_blocked |= (flag | 4);
@@ -172,16 +161,15 @@
    pipe_mutex_unlock(tr_ctx->draw_mutex);
 }
 
-static INLINE boolean
+static INLINE void
 trace_context_draw_arrays(struct pipe_context *_pipe,
                           unsigned mode, unsigned start, unsigned count)
 {
    struct trace_context *tr_ctx = trace_context(_pipe);
    struct pipe_context *pipe = tr_ctx->pipe;
-   boolean result;
 
    if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled)
-      return 0;
+      return;
 
    trace_context_draw_block(tr_ctx, 1);
 
@@ -192,19 +180,15 @@
    trace_dump_arg(uint, start);
    trace_dump_arg(uint, count);
 
-   result = pipe->draw_arrays(pipe, mode, start, count);;
-
-   trace_dump_ret(bool, result);
+   pipe->draw_arrays(pipe, mode, start, count);
 
    trace_dump_call_end();
 
    trace_context_draw_block(tr_ctx, 2);
-
-   return result;
 }
 
 
-static INLINE boolean
+static INLINE void
 trace_context_draw_elements(struct pipe_context *_pipe,
                           struct pipe_buffer *_indexBuffer,
                           unsigned indexSize,
@@ -214,10 +198,9 @@
    struct trace_buffer *tr_buf = trace_buffer(_indexBuffer);
    struct pipe_context *pipe = tr_ctx->pipe;
    struct pipe_buffer *indexBuffer = tr_buf->buffer;
-   boolean result;
 
    if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled)
-      return 0;
+      return;
 
    trace_context_draw_block(tr_ctx, 1);
 
@@ -232,19 +215,15 @@
    trace_dump_arg(uint, start);
    trace_dump_arg(uint, count);
 
-   result = pipe->draw_elements(pipe, indexBuffer, indexSize, mode, start, count);;
-
-   trace_dump_ret(bool, result);
+   pipe->draw_elements(pipe, indexBuffer, indexSize, mode, start, count);
 
    trace_dump_call_end();
 
    trace_context_draw_block(tr_ctx, 2);
-
-   return result;
 }
 
 
-static INLINE boolean
+static INLINE void
 trace_context_draw_range_elements(struct pipe_context *_pipe,
                                   struct pipe_buffer *_indexBuffer,
                                   unsigned indexSize,
@@ -258,10 +237,9 @@
    struct trace_buffer *tr_buf = trace_buffer(_indexBuffer);
    struct pipe_context *pipe = tr_ctx->pipe;
    struct pipe_buffer *indexBuffer = tr_buf->buffer;
-   boolean result;
 
    if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled)
-      return 0;
+      return;
 
    trace_context_draw_block(tr_ctx, 1);
 
@@ -278,18 +256,14 @@
    trace_dump_arg(uint, start);
    trace_dump_arg(uint, count);
 
-   result = pipe->draw_range_elements(pipe,
-                                      indexBuffer,
-                                      indexSize, minIndex, maxIndex,
-                                      mode, start, count);
-
-   trace_dump_ret(bool, result);
+   pipe->draw_range_elements(pipe,
+                             indexBuffer,
+                             indexSize, minIndex, maxIndex,
+                             mode, start, count);
 
    trace_dump_call_end();
 
    trace_context_draw_block(tr_ctx, 2);
-
-   return result;
 }
 
 
@@ -306,7 +280,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(uint, query_type);
 
-   result = pipe->create_query(pipe, query_type);;
+   result = pipe->create_query(pipe, query_type);
 
    trace_dump_ret(ptr, result);
 
@@ -328,7 +302,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(ptr, query);
 
-   pipe->destroy_query(pipe, query);;
+   pipe->destroy_query(pipe, query);
 
    trace_dump_call_end();
 }
@@ -346,7 +320,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(ptr, query);
 
-   pipe->begin_query(pipe, query);;
+   pipe->begin_query(pipe, query);
 
    trace_dump_call_end();
 }
@@ -385,7 +359,7 @@
 
    trace_dump_arg(ptr, pipe);
 
-   _result = pipe->get_query_result(pipe, query, wait, presult);;
+   _result = pipe->get_query_result(pipe, query, wait, presult);
    result = *presult;
 
    trace_dump_arg(uint, result);
@@ -410,7 +384,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(blend_state, state);
 
-   result = pipe->create_blend_state(pipe, state);;
+   result = pipe->create_blend_state(pipe, state);
 
    trace_dump_ret(ptr, result);
 
@@ -432,7 +406,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(ptr, state);
 
-   pipe->bind_blend_state(pipe, state);;
+   pipe->bind_blend_state(pipe, state);
 
    trace_dump_call_end();
 }
@@ -450,7 +424,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(ptr, state);
 
-   pipe->delete_blend_state(pipe, state);;
+   pipe->delete_blend_state(pipe, state);
 
    trace_dump_call_end();
 }
@@ -469,7 +443,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(sampler_state, state);
 
-   result = pipe->create_sampler_state(pipe, state);;
+   result = pipe->create_sampler_state(pipe, state);
 
    trace_dump_ret(ptr, result);
 
@@ -480,19 +454,40 @@
 
 
 static INLINE void
-trace_context_bind_sampler_states(struct pipe_context *_pipe,
-                                  unsigned num_states, void **states)
+trace_context_bind_fragment_sampler_states(struct pipe_context *_pipe,
+                                           unsigned num_states,
+                                           void **states)
 {
    struct trace_context *tr_ctx = trace_context(_pipe);
    struct pipe_context *pipe = tr_ctx->pipe;
 
-   trace_dump_call_begin("pipe_context", "bind_sampler_states");
+   trace_dump_call_begin("pipe_context", "bind_fragment_sampler_states");
 
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(uint, num_states);
    trace_dump_arg_array(ptr, states, num_states);
 
-   pipe->bind_sampler_states(pipe, num_states, states);;
+   pipe->bind_fragment_sampler_states(pipe, num_states, states);
+
+   trace_dump_call_end();
+}
+
+
+static INLINE void
+trace_context_bind_vertex_sampler_states(struct pipe_context *_pipe,
+                                         unsigned num_states,
+                                         void **states)
+{
+   struct trace_context *tr_ctx = trace_context(_pipe);
+   struct pipe_context *pipe = tr_ctx->pipe;
+
+   trace_dump_call_begin("pipe_context", "bind_vertex_sampler_states");
+
+   trace_dump_arg(ptr, pipe);
+   trace_dump_arg(uint, num_states);
+   trace_dump_arg_array(ptr, states, num_states);
+
+   pipe->bind_vertex_sampler_states(pipe, num_states, states);
 
    trace_dump_call_end();
 }
@@ -510,7 +505,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(ptr, state);
 
-   pipe->delete_sampler_state(pipe, state);;
+   pipe->delete_sampler_state(pipe, state);
 
    trace_dump_call_end();
 }
@@ -529,7 +524,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(rasterizer_state, state);
 
-   result = pipe->create_rasterizer_state(pipe, state);;
+   result = pipe->create_rasterizer_state(pipe, state);
 
    trace_dump_ret(ptr, result);
 
@@ -551,7 +546,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(ptr, state);
 
-   pipe->bind_rasterizer_state(pipe, state);;
+   pipe->bind_rasterizer_state(pipe, state);
 
    trace_dump_call_end();
 }
@@ -569,7 +564,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(ptr, state);
 
-   pipe->delete_rasterizer_state(pipe, state);;
+   pipe->delete_rasterizer_state(pipe, state);
 
    trace_dump_call_end();
 }
@@ -585,7 +580,7 @@
 
    trace_dump_call_begin("pipe_context", "create_depth_stencil_alpha_state");
 
-   result = pipe->create_depth_stencil_alpha_state(pipe, state);;
+   result = pipe->create_depth_stencil_alpha_state(pipe, state);
 
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(depth_stencil_alpha_state, state);
@@ -610,7 +605,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(ptr, state);
 
-   pipe->bind_depth_stencil_alpha_state(pipe, state);;
+   pipe->bind_depth_stencil_alpha_state(pipe, state);
 
    trace_dump_call_end();
 }
@@ -628,7 +623,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(ptr, state);
 
-   pipe->delete_depth_stencil_alpha_state(pipe, state);;
+   pipe->delete_depth_stencil_alpha_state(pipe, state);
 
    trace_dump_call_end();
 }
@@ -647,7 +642,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(shader_state, state);
 
-   result = pipe->create_fs_state(pipe, state);;
+   result = pipe->create_fs_state(pipe, state);
 
    trace_dump_ret(ptr, result);
 
@@ -750,7 +745,7 @@
    if (tr_shdr && tr_shdr->replaced)
       state = tr_shdr->replaced;
 
-   pipe->bind_vs_state(pipe, state);;
+   pipe->bind_vs_state(pipe, state);
 
    trace_dump_call_end();
 }
@@ -770,7 +765,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(ptr, state);
 
-   pipe->delete_vs_state(pipe, state);;
+   pipe->delete_vs_state(pipe, state);
 
    trace_dump_call_end();
 
@@ -790,7 +785,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(blend_color, state);
 
-   pipe->set_blend_color(pipe, state);;
+   pipe->set_blend_color(pipe, state);
 
    trace_dump_call_end();
 }
@@ -808,7 +803,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(clip_state, state);
 
-   pipe->set_clip_state(pipe, state);;
+   pipe->set_clip_state(pipe, state);
 
    trace_dump_call_end();
 }
@@ -880,7 +875,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(framebuffer_state, state);
 
-   pipe->set_framebuffer_state(pipe, state);;
+   pipe->set_framebuffer_state(pipe, state);
 
    trace_dump_call_end();
 }
@@ -898,7 +893,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(poly_stipple, state);
 
-   pipe->set_polygon_stipple(pipe, state);;
+   pipe->set_polygon_stipple(pipe, state);
 
    trace_dump_call_end();
 }
@@ -916,7 +911,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(scissor_state, state);
 
-   pipe->set_scissor_state(pipe, state);;
+   pipe->set_scissor_state(pipe, state);
 
    trace_dump_call_end();
 }
@@ -934,16 +929,16 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(viewport_state, state);
 
-   pipe->set_viewport_state(pipe, state);;
+   pipe->set_viewport_state(pipe, state);
 
    trace_dump_call_end();
 }
 
 
 static INLINE void
-trace_context_set_sampler_textures(struct pipe_context *_pipe,
-                                   unsigned num_textures,
-                                   struct pipe_texture **textures)
+trace_context_set_fragment_sampler_textures(struct pipe_context *_pipe,
+                                            unsigned num_textures,
+                                            struct pipe_texture **textures)
 {
    struct trace_context *tr_ctx = trace_context(_pipe);
    struct trace_texture *tr_tex;
@@ -959,13 +954,44 @@
    }
    textures = unwrapped_textures;
 
-   trace_dump_call_begin("pipe_context", "set_sampler_textures");
+   trace_dump_call_begin("pipe_context", "set_fragment_sampler_textures");
 
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(uint, num_textures);
    trace_dump_arg_array(ptr, textures, num_textures);
 
-   pipe->set_sampler_textures(pipe, num_textures, textures);;
+   pipe->set_fragment_sampler_textures(pipe, num_textures, textures);
+
+   trace_dump_call_end();
+}
+
+
+static INLINE void
+trace_context_set_vertex_sampler_textures(struct pipe_context *_pipe,
+                                          unsigned num_textures,
+                                          struct pipe_texture **textures)
+{
+   struct trace_context *tr_ctx = trace_context(_pipe);
+   struct trace_texture *tr_tex;
+   struct pipe_context *pipe = tr_ctx->pipe;
+   struct pipe_texture *unwrapped_textures[PIPE_MAX_VERTEX_SAMPLERS];
+   unsigned i;
+
+   tr_ctx->curr.num_vert_texs = num_textures;
+   for(i = 0; i < num_textures; ++i) {
+      tr_tex = trace_texture(textures[i]);
+      tr_ctx->curr.vert_tex[i] = tr_tex;
+      unwrapped_textures[i] = tr_tex ? tr_tex->texture : NULL;
+   }
+   textures = unwrapped_textures;
+
+   trace_dump_call_begin("pipe_context", "set_vertex_sampler_textures");
+
+   trace_dump_arg(ptr, pipe);
+   trace_dump_arg(uint, num_textures);
+   trace_dump_arg_array(ptr, textures, num_textures);
+
+   pipe->set_vertex_sampler_textures(pipe, num_textures, textures);
 
    trace_dump_call_end();
 }
@@ -1024,7 +1050,7 @@
    trace_dump_struct_array(vertex_element, elements, num_elements);
    trace_dump_arg_end();
 
-   pipe->set_vertex_elements(pipe, num_elements, elements);;
+   pipe->set_vertex_elements(pipe, num_elements, elements);
 
    trace_dump_call_end();
 }
@@ -1085,7 +1111,7 @@
    trace_dump_arg(uint, width);
    trace_dump_arg(uint, height);
 
-   pipe->surface_fill(pipe, dst, dstx, dsty, width, height, value);;
+   pipe->surface_fill(pipe, dst, dstx, dsty, width, height, value);
 
    trace_dump_call_end();
 }
@@ -1128,7 +1154,7 @@
    trace_dump_arg(ptr, pipe);
    trace_dump_arg(uint, flags);
 
-   pipe->flush(pipe, flags, fence);;
+   pipe->flush(pipe, flags, fence);
 
    if(fence)
       trace_dump_ret(ptr, *fence);
@@ -1240,7 +1266,6 @@
    tr_ctx->base.winsys = _screen->winsys;
    tr_ctx->base.screen = _screen;
    tr_ctx->base.destroy = trace_context_destroy;
-   tr_ctx->base.set_edgeflags = trace_context_set_edgeflags;
    tr_ctx->base.draw_arrays = trace_context_draw_arrays;
    tr_ctx->base.draw_elements = trace_context_draw_elements;
    tr_ctx->base.draw_range_elements = trace_context_draw_range_elements;
@@ -1253,7 +1278,8 @@
    tr_ctx->base.bind_blend_state = trace_context_bind_blend_state;
    tr_ctx->base.delete_blend_state = trace_context_delete_blend_state;
    tr_ctx->base.create_sampler_state = trace_context_create_sampler_state;
-   tr_ctx->base.bind_sampler_states = trace_context_bind_sampler_states;
+   tr_ctx->base.bind_fragment_sampler_states = trace_context_bind_fragment_sampler_states;
+   tr_ctx->base.bind_vertex_sampler_states = trace_context_bind_vertex_sampler_states;
    tr_ctx->base.delete_sampler_state = trace_context_delete_sampler_state;
    tr_ctx->base.create_rasterizer_state = trace_context_create_rasterizer_state;
    tr_ctx->base.bind_rasterizer_state = trace_context_bind_rasterizer_state;
@@ -1274,7 +1300,8 @@
    tr_ctx->base.set_polygon_stipple = trace_context_set_polygon_stipple;
    tr_ctx->base.set_scissor_state = trace_context_set_scissor_state;
    tr_ctx->base.set_viewport_state = trace_context_set_viewport_state;
-   tr_ctx->base.set_sampler_textures = trace_context_set_sampler_textures;
+   tr_ctx->base.set_fragment_sampler_textures = trace_context_set_fragment_sampler_textures;
+   tr_ctx->base.set_vertex_sampler_textures = trace_context_set_vertex_sampler_textures;
    tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers;
    tr_ctx->base.set_vertex_elements = trace_context_set_vertex_elements;
    if (pipe->surface_copy)
diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h
index 6febe4b..852b480 100644
--- a/src/gallium/drivers/trace/tr_context.h
+++ b/src/gallium/drivers/trace/tr_context.h
@@ -54,6 +54,9 @@
       struct trace_texture *tex[PIPE_MAX_SAMPLERS];
       unsigned num_texs;
 
+      struct trace_texture *vert_tex[PIPE_MAX_VERTEX_SAMPLERS];
+      unsigned num_vert_texs;
+
       unsigned nr_cbufs;
       struct trace_texture *cbufs[PIPE_MAX_COLOR_BUFS];
       struct trace_texture *zsbuf;
diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c
index 7e2ccbc..0f45e21 100644
--- a/src/gallium/drivers/trace/tr_dump.c
+++ b/src/gallium/drivers/trace/tr_dump.c
@@ -40,7 +40,7 @@
 
 #include "pipe/p_config.h"
 
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE)
 #include <stdlib.h>
 #endif
 
@@ -258,7 +258,7 @@
       trace_dump_writes("<?xml-stylesheet type='text/xsl' href='trace.xsl'?>\n");
       trace_dump_writes("<trace version='0.1'>\n");
 
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE)
       /* Linux applications rarely cleanup GL / Gallium resources so catch
        * application exit here */
       atexit(trace_dump_trace_close);
diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c
index bcf6751..86237e0 100644
--- a/src/gallium/drivers/trace/tr_dump_state.c
+++ b/src/gallium/drivers/trace/tr_dump_state.c
@@ -43,19 +43,6 @@
 }
 
 
-void trace_dump_block(const struct pipe_format_block *block)
-{
-   if (!trace_dumping_enabled_locked())
-      return;
-
-   trace_dump_struct_begin("pipe_format_block");
-   trace_dump_member(uint, block, size);
-   trace_dump_member(uint, block, width);
-   trace_dump_member(uint, block, height);
-   trace_dump_struct_end();
-}
-
-
 static void trace_dump_reference(const struct pipe_reference *reference)
 {
    if (!trace_dumping_enabled_locked())
@@ -83,19 +70,15 @@
    trace_dump_member(format, templat, format);
 
    trace_dump_member_begin("width");
-   trace_dump_array(uint, templat->width, 1);
+   trace_dump_uint(templat->width0);
    trace_dump_member_end();
 
    trace_dump_member_begin("height");
-   trace_dump_array(uint, templat->height, 1);
+   trace_dump_uint(templat->height0);
    trace_dump_member_end();
 
    trace_dump_member_begin("depth");
-   trace_dump_array(uint, templat->depth, 1);
-   trace_dump_member_end();
-
-   trace_dump_member_begin("block");
-   trace_dump_block(&templat->block);
+   trace_dump_uint(templat->depth0);
    trace_dump_member_end();
 
    trace_dump_member(uint, templat, last_level);
@@ -426,7 +409,7 @@
    trace_dump_member(uint, state, min_img_filter);
    trace_dump_member(uint, state, min_mip_filter);
    trace_dump_member(uint, state, mag_img_filter);
-   trace_dump_member(bool, state, compare_mode);
+   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, prefilter);
@@ -483,16 +466,9 @@
 
    trace_dump_struct_begin("pipe_transfer");
 
-   trace_dump_member(format, state, format);
    trace_dump_member(uint, state, width);
    trace_dump_member(uint, state, height);
 
-   trace_dump_member_begin("block");
-   trace_dump_block(&state->block);
-   trace_dump_member_end();
-
-   trace_dump_member(uint, state, nblocksx);
-   trace_dump_member(uint, state, nblocksy);
    trace_dump_member(uint, state, stride);
    trace_dump_member(uint, state, usage);
 
diff --git a/src/gallium/drivers/trace/tr_dump_state.h b/src/gallium/drivers/trace/tr_dump_state.h
index 05b821a..07ad6fb 100644
--- a/src/gallium/drivers/trace/tr_dump_state.h
+++ b/src/gallium/drivers/trace/tr_dump_state.h
@@ -35,11 +35,8 @@
 
 void trace_dump_format(enum pipe_format format);
 
-void trace_dump_block(const struct pipe_format_block *block);
-
 void trace_dump_template(const struct pipe_texture *templat);
 
-
 void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state);
 
 void trace_dump_poly_stipple(const struct pipe_poly_stipple *state);
diff --git a/src/gallium/drivers/trace/tr_rbug.c b/src/gallium/drivers/trace/tr_rbug.c
index 81e0a6f..0546aad 100644
--- a/src/gallium/drivers/trace/tr_rbug.c
+++ b/src/gallium/drivers/trace/tr_rbug.c
@@ -26,6 +26,7 @@
  **************************************************************************/
 
 
+#include "util/u_format.h"
 #include "util/u_string.h"
 #include "util/u_memory.h"
 #include "util/u_simple_list.h"
@@ -44,7 +45,7 @@
 
 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
 #  define sleep Sleep
-#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD)
+#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_APPLE)
 void usleep(int);
 #  define sleep usleep
 #else
@@ -179,7 +180,7 @@
 trace_rbug_texture_info(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
 {
    struct trace_screen *tr_scr = tr_rbug->tr_scr;
-   struct trace_texture *tr_tex;
+   struct trace_texture *tr_tex = NULL;
    struct rbug_proto_texture_info *gpti = (struct rbug_proto_texture_info *)header;
    struct tr_list *ptr;
    struct pipe_texture *t;
@@ -200,10 +201,12 @@
    t = tr_tex->texture;
    rbug_send_texture_info_reply(tr_rbug->con, serial,
                                t->target, t->format,
-                               t->width, t->last_level + 1,
-                               t->height, t->last_level + 1,
-                               t->depth, t->last_level + 1,
-                               t->block.width, t->block.height, t->block.size,
+                               &t->width0, 1,
+                               &t->height0, 1,
+                               &t->depth0, 1,
+                               util_format_get_blockwidth(t->format),
+                               util_format_get_blockheight(t->format),
+                               util_format_get_blocksize(t->format),
                                t->last_level,
                                t->nr_samples,
                                t->tex_usage,
@@ -220,7 +223,7 @@
    struct rbug_proto_texture_read *gptr = (struct rbug_proto_texture_read *)header;
 
    struct trace_screen *tr_scr = tr_rbug->tr_scr;
-   struct trace_texture *tr_tex;
+   struct trace_texture *tr_tex = NULL;
    struct tr_list *ptr;
 
    struct pipe_screen *screen = tr_scr->screen;
@@ -251,9 +254,12 @@
    map = screen->transfer_map(screen, t);
 
    rbug_send_texture_read_reply(tr_rbug->con, serial,
-                                t->format,
-                                t->block.width, t->block.height, t->block.size,
-                                (uint8_t*)map, t->stride * t->nblocksy,
+                                t->texture->format,
+                                util_format_get_blockwidth(t->texture->format),
+                                util_format_get_blockheight(t->texture->format),
+                                util_format_get_blocksize(t->texture->format),
+                                (uint8_t*)map,
+                                t->stride * util_format_get_nblocksy(t->texture->format, t->height),
                                 t->stride,
                                 NULL);
 
diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c
index 7da9bd3..117503a 100644
--- a/src/gallium/drivers/trace/tr_screen.c
+++ b/src/gallium/drivers/trace/tr_screen.c
@@ -25,6 +25,7 @@
  *
  **************************************************************************/
 
+#include "util/u_format.h"
 #include "util/u_memory.h"
 #include "util/u_simple_list.h"
 
@@ -35,6 +36,7 @@
 #include "tr_screen.h"
 
 #include "pipe/p_inlines.h"
+#include "pipe/p_format.h"
 
 
 static boolean trace = FALSE;
@@ -424,7 +426,7 @@
    struct pipe_transfer *transfer = tr_trans->transfer;
 
    if(tr_trans->map) {
-      size_t size = transfer->nblocksy * transfer->stride;
+      size_t size = util_format_get_nblocksy(transfer->texture->format, transfer->height) * transfer->stride;
 
       trace_dump_call_begin("pipe_screen", "transfer_write");
 
diff --git a/src/gallium/drivers/trace/tr_state.h b/src/gallium/drivers/trace/tr_state.h
index 1c16042..e2f981d 100644
--- a/src/gallium/drivers/trace/tr_state.h
+++ b/src/gallium/drivers/trace/tr_state.h
@@ -32,7 +32,7 @@
 enum trace_shader_type {
    TRACE_SHADER_FRAGMENT = 0,
    TRACE_SHADER_VERTEX   = 1,
-   TRACE_SHADER_GEOMETRY = 2,
+   TRACE_SHADER_GEOMETRY = 2
 };
 
 struct trace_shader
diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h
index c36286f..26a9405 100644
--- a/src/gallium/include/pipe/p_compiler.h
+++ b/src/gallium/include/pipe/p_compiler.h
@@ -52,45 +52,15 @@
 #endif /* _MSC_VER */
 
 
-#if defined(_MSC_VER)
-
-typedef __int8             int8_t;
-typedef unsigned __int8    uint8_t;
-typedef __int16            int16_t;
-typedef unsigned __int16   uint16_t;
-#ifndef __eglplatform_h_
-typedef __int32            int32_t;
-#endif
-typedef unsigned __int32   uint32_t;
-typedef __int64            int64_t;
-typedef unsigned __int64   uint64_t;
-
-#if defined(_WIN64)
-typedef __int64            intptr_t;
-typedef unsigned __int64   uintptr_t;
-#else
-typedef __int32            intptr_t;
-typedef unsigned __int32   uintptr_t;
-#endif
-
-#define INT64_C(__val) __val##i64
-#define UINT64_C(__val) __val##ui64
-
-#ifndef __cplusplus
-#define false   0
-#define true    1
-#define bool    _Bool
-typedef int     _Bool;
-#define __bool_true_false_are_defined   1
-#endif /* !__cplusplus */
-
-#else
+/*
+ * Alternative stdint.h and stdbool.h headers are supplied in include/c99 for
+ * systems that lack it.
+ */
 #ifndef __STDC_LIMIT_MACROS
 #define __STDC_LIMIT_MACROS 1
 #endif
 #include <stdint.h>
 #include <stdbool.h>
-#endif
 
 
 #ifndef __HAIKU__
@@ -99,11 +69,7 @@
 #endif
 typedef unsigned char      ubyte;
 
-#if 0
-#define boolean bool
-#else
 typedef unsigned char boolean;
-#endif
 #ifndef TRUE
 #define TRUE  true
 #endif
@@ -135,6 +101,17 @@
 #  endif
 #endif
 
+
+/* Function visibility */
+#ifndef PUBLIC
+#  if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303
+#    define PUBLIC __attribute__((visibility("default")))
+#  else
+#    define PUBLIC
+#  endif
+#endif
+
+
 /* The __FUNCTION__ gcc variable is generally only used for debugging.
  * If we're not using gcc, define __FUNCTION__ as a cpp symbol here.
  */
@@ -167,7 +144,7 @@
 #define ALIGN16_ASSIGN(NAME) NAME##___aligned
 #define ALIGN16_ATTRIB  __attribute__(( aligned( 16 ) ))
 #define ALIGN8_ATTRIB  __attribute__(( aligned( 8 ) ))
-#if __GNUC__ > 4 || (__GNUC__ == 4 &&__GNUC_MINOR__>1)
+#if (__GNUC__ > 4 || (__GNUC__ == 4 &&__GNUC_MINOR__>1)) && !defined(PIPE_ARCH_X86_64)
 #define ALIGN_STACK __attribute__((force_align_arg_pointer))
 #else
 #define ALIGN_STACK
diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h
index f6feea5..064605a 100644
--- a/src/gallium/include/pipe/p_config.h
+++ b/src/gallium/include/pipe/p_config.h
@@ -53,6 +53,7 @@
 
 #if defined(__GNUC__)
 #define PIPE_CC_GCC
+#define PIPE_CC_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
 #endif
 
 /*
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index 5569001..d2f8085 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -57,41 +57,41 @@
 
    void (*destroy)( struct pipe_context * );
 
-   
-   /* Possible interface for setting edgeflags.  These aren't really
-    * vertex elements, so don't fit there.
-    */
-   void (*set_edgeflags)( struct pipe_context *,
-                          const unsigned *bitfield );
-
-
    /**
     * VBO drawing (return false on fallbacks (temporary??))
     */
    /*@{*/
-   boolean (*draw_arrays)( struct pipe_context *pipe,
-			   unsigned mode, unsigned start, unsigned count);
+   void (*draw_arrays)( struct pipe_context *pipe,
+                        unsigned mode, unsigned start, unsigned count);
 
-   boolean (*draw_elements)( struct pipe_context *pipe,
-			     struct pipe_buffer *indexBuffer,
-			     unsigned indexSize,
-			     unsigned mode, unsigned start, unsigned count);
+   void (*draw_elements)( struct pipe_context *pipe,
+                          struct pipe_buffer *indexBuffer,
+                          unsigned indexSize,
+                          unsigned mode, unsigned start, unsigned count);
 
    /* XXX: this is (probably) a temporary entrypoint, as the range
     * information should be available from the vertex_buffer state.
     * Using this to quickly evaluate a specialized path in the draw
     * module.
     */
-   boolean (*draw_range_elements)( struct pipe_context *pipe,
-                                   struct pipe_buffer *indexBuffer,
-                                   unsigned indexSize,
-                                   unsigned minIndex,
-                                   unsigned maxIndex,
-                                   unsigned mode, 
-                                   unsigned start, 
-                                   unsigned count);
+   void (*draw_range_elements)( struct pipe_context *pipe,
+                                struct pipe_buffer *indexBuffer,
+                                unsigned indexSize,
+                                unsigned minIndex,
+                                unsigned maxIndex,
+                                unsigned mode, 
+                                unsigned start, 
+                                unsigned count);
    /*@}*/
 
+   /**
+    * Predicate subsequent rendering on occlusion query result
+    * \param query  the query predicate, or NULL if no predicate
+    * \param mode  one of PIPE_COND_RENDER_x
+    */
+   void (*render_condition)( struct pipe_context *pipe,
+                             struct pipe_query *query,
+                             uint mode );
 
    /**
     * Query objects
@@ -123,7 +123,12 @@
 
    void * (*create_sampler_state)(struct pipe_context *,
                                   const struct pipe_sampler_state *);
-   void   (*bind_sampler_states)(struct pipe_context *, unsigned num, void **);
+   void   (*bind_fragment_sampler_states)(struct pipe_context *,
+                                          unsigned num_samplers,
+                                          void **samplers);
+   void   (*bind_vertex_sampler_states)(struct pipe_context *,
+                                        unsigned num_samplers,
+                                        void **samplers);
    void   (*delete_sampler_state)(struct pipe_context *, void *);
 
    void * (*create_rasterizer_state)(struct pipe_context *,
@@ -145,6 +150,12 @@
                              const struct pipe_shader_state *);
    void   (*bind_vs_state)(struct pipe_context *, void *);
    void   (*delete_vs_state)(struct pipe_context *, void *);
+
+   void * (*create_gs_state)(struct pipe_context *,
+                             const struct pipe_shader_state *);
+   void   (*bind_gs_state)(struct pipe_context *, void *);
+   void   (*delete_gs_state)(struct pipe_context *, void *);
+
    /*@}*/
 
    /**
@@ -173,9 +184,13 @@
    void (*set_viewport_state)( struct pipe_context *,
                                const struct pipe_viewport_state * );
 
-   void (*set_sampler_textures)( struct pipe_context *,
-                                 unsigned num_textures,
-                                 struct pipe_texture ** );
+   void (*set_fragment_sampler_textures)(struct pipe_context *,
+                                         unsigned num_textures,
+                                         struct pipe_texture **);
+
+   void (*set_vertex_sampler_textures)(struct pipe_context *,
+                                       unsigned num_textures,
+                                       struct pipe_texture **);
 
    void (*set_vertex_buffers)( struct pipe_context *,
                                unsigned num_buffers,
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 6a61aea..35f3830 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -140,7 +140,8 @@
    PIPE_TEXTURE_1D   = 0,
    PIPE_TEXTURE_2D   = 1,
    PIPE_TEXTURE_3D   = 2,
-   PIPE_TEXTURE_CUBE = 3
+   PIPE_TEXTURE_CUBE = 3,
+   PIPE_MAX_TEXTURE_TYPES
 };
 
 #define PIPE_TEX_FACE_POS_X 0
@@ -170,8 +171,6 @@
  */
 #define PIPE_TEX_FILTER_NEAREST      0
 #define PIPE_TEX_FILTER_LINEAR       1
-#define PIPE_TEX_FILTER_ANISO        2 
-
 
 #define PIPE_TEX_COMPARE_NONE          0
 #define PIPE_TEX_COMPARE_R_TO_TEXTURE  1
@@ -225,9 +224,10 @@
 };
 
 
-/**
+/*
  * Buffer usage flags
  */
+
 #define PIPE_BUFFER_USAGE_CPU_READ  (1 << 0)
 #define PIPE_BUFFER_USAGE_CPU_WRITE (1 << 1)
 #define PIPE_BUFFER_USAGE_GPU_READ  (1 << 2)
@@ -236,9 +236,63 @@
 #define PIPE_BUFFER_USAGE_VERTEX    (1 << 5)
 #define PIPE_BUFFER_USAGE_INDEX     (1 << 6)
 #define PIPE_BUFFER_USAGE_CONSTANT  (1 << 7)
+
+/*
+ * CPU access flags.
+ *
+ * These flags should only be used for texture transfers or when mapping
+ * buffers.
+ *
+ * Note that the PIPE_BUFFER_USAGE_CPU_xxx flags above are also used for
+ * mapping. Either PIPE_BUFFER_USAGE_CPU_READ or PIPE_BUFFER_USAGE_CPU_WRITE
+ * must be set.
+ */
+
+/**
+ * Discards the memory within the mapped region.
+ *
+ * It should not be used with PIPE_BUFFER_USAGE_CPU_READ.
+ *
+ * See also:
+ * - OpenGL's ARB_map_buffer_range extension, MAP_INVALIDATE_RANGE_BIT flag.
+ * - Direct3D's D3DLOCK_DISCARD flag.
+ */
 #define PIPE_BUFFER_USAGE_DISCARD   (1 << 8)
+
+/**
+ * Fail if the resource cannot be mapped immediately.
+ *
+ * See also:
+ * - Direct3D's D3DLOCK_DONOTWAIT flag.
+ * - Mesa3D's MESA_MAP_NOWAIT_BIT flag.
+ * - WDDM's D3DDDICB_LOCKFLAGS.DonotWait flag.
+ */
 #define PIPE_BUFFER_USAGE_DONTBLOCK (1 << 9)
-#define PIPE_BUFFER_USAGE_FLUSH_EXPLICIT (1 << 10) /**< See pipe_screen::buffer_flush_mapped_range */
+
+/**
+ * Do not attempt to synchronize pending operations on the resource when mapping.
+ *
+ * It should not be used with PIPE_BUFFER_USAGE_CPU_READ.
+ *
+ * See also:
+ * - OpenGL's ARB_map_buffer_range extension, MAP_UNSYNCHRONIZED_BIT flag.
+ * - Direct3D's D3DLOCK_NOOVERWRITE flag.
+ * - WDDM's D3DDDICB_LOCKFLAGS.IgnoreSync flag.
+ */
+#define PIPE_BUFFER_USAGE_UNSYNCHRONIZED (1 << 10)
+
+/**
+ * Written ranges will be notified later with
+ * pipe_screen::buffer_flush_mapped_range.
+ *
+ * It should not be used with PIPE_BUFFER_USAGE_CPU_READ.
+ *
+ * See also:
+ * - pipe_screen::buffer_flush_mapped_range
+ * - OpenGL's ARB_map_buffer_range extension, MAP_FLUSH_EXPLICIT_BIT flag.
+ */
+#define PIPE_BUFFER_USAGE_FLUSH_EXPLICIT (1 << 11)
+
 /** Pipe driver custom usage flags should be greater or equal to this value */
 #define PIPE_BUFFER_USAGE_CUSTOM    (1 << 16)
 
@@ -265,23 +319,28 @@
  */
 #define PIPE_SHADER_VERTEX   0
 #define PIPE_SHADER_FRAGMENT 1
-#define PIPE_SHADER_TYPES    2
+#define PIPE_SHADER_GEOMETRY 2
+#define PIPE_SHADER_TYPES    3
 
 
 /**
  * Primitive types:
  */
-#define PIPE_PRIM_POINTS          0
-#define PIPE_PRIM_LINES           1
-#define PIPE_PRIM_LINE_LOOP       2
-#define PIPE_PRIM_LINE_STRIP      3
-#define PIPE_PRIM_TRIANGLES       4
-#define PIPE_PRIM_TRIANGLE_STRIP  5
-#define PIPE_PRIM_TRIANGLE_FAN    6
-#define PIPE_PRIM_QUADS           7
-#define PIPE_PRIM_QUAD_STRIP      8
-#define PIPE_PRIM_POLYGON         9
-#define PIPE_PRIM_MAX             10
+#define PIPE_PRIM_POINTS               0
+#define PIPE_PRIM_LINES                1
+#define PIPE_PRIM_LINE_LOOP            2
+#define PIPE_PRIM_LINE_STRIP           3
+#define PIPE_PRIM_TRIANGLES            4
+#define PIPE_PRIM_TRIANGLE_STRIP       5
+#define PIPE_PRIM_TRIANGLE_FAN         6
+#define PIPE_PRIM_QUADS                7
+#define PIPE_PRIM_QUAD_STRIP           8
+#define PIPE_PRIM_POLYGON              9
+#define PIPE_PRIM_LINES_ADJACENCY          10
+#define PIPE_PRIM_LINE_STRIP_ADJACENCY    11
+#define PIPE_PRIM_TRIANGLES_ADJACENCY      12
+#define PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY 13
+#define PIPE_PRIM_MAX                      14
 
 
 /**
@@ -294,6 +353,15 @@
 
 
 /**
+ * Conditional rendering modes
+ */
+#define PIPE_RENDER_COND_WAIT              0
+#define PIPE_RENDER_COND_NO_WAIT           1
+#define PIPE_RENDER_COND_BY_REGION_WAIT    2
+#define PIPE_RENDER_COND_BY_REGION_NO_WAIT 3
+
+
+/**
  * Point sprite coord modes
  */
 #define PIPE_SPRITE_COORD_NONE       0
@@ -335,6 +403,8 @@
 #define PIPE_CAP_BLEND_EQUATION_SEPARATE 28
 #define PIPE_CAP_SM3                     29  /*< Shader Model 3 supported */
 #define PIPE_CAP_MAX_PREDICATE_REGISTERS 30
+#define PIPE_CAP_MAX_COMBINED_SAMPLERS   31  /*< Maximum texture image units accessible from vertex
+                                                 and fragment shaders combined */
 
 
 /**
diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h
index af23080..6bfff1c 100644
--- a/src/gallium/include/pipe/p_format.h
+++ b/src/gallium/include/pipe/p_format.h
@@ -40,353 +40,133 @@
 #endif
 
 /**
- * The pipe_format enum is a 32-bit wide bitfield that encodes all the
- * information needed to uniquely describe a pixel format.
- */
-
-/**
- * Possible format layouts are encoded in the first 2 bits.
- * The interpretation of the remaining 30 bits depends on a particular
- * format layout.
- */
-#define PIPE_FORMAT_LAYOUT_RGBAZS   0
-#define PIPE_FORMAT_LAYOUT_YCBCR    1
-#define PIPE_FORMAT_LAYOUT_DXT      2  /**< XXX temporary? */
-#define PIPE_FORMAT_LAYOUT_MIXED    3
-
-static INLINE uint pf_layout(uint f)  /**< PIPE_FORMAT_LAYOUT_ */
-{
-   return f & 0x3;
-}
-
-/**
- * RGBAZS Format Layout.
- */
-
-/**
- * Format component selectors for RGBAZS & MIXED layout.
- */
-#define PIPE_FORMAT_COMP_R    0
-#define PIPE_FORMAT_COMP_G    1
-#define PIPE_FORMAT_COMP_B    2
-#define PIPE_FORMAT_COMP_A    3
-#define PIPE_FORMAT_COMP_0    4
-#define PIPE_FORMAT_COMP_1    5
-#define PIPE_FORMAT_COMP_Z    6
-#define PIPE_FORMAT_COMP_S    7
-
-/**
- * Format types for RGBAZS layout.
- */
-#define PIPE_FORMAT_TYPE_UNKNOWN 0
-#define PIPE_FORMAT_TYPE_FLOAT   1  /**< 16/32/64-bit/channel formats */
-#define PIPE_FORMAT_TYPE_UNORM   2  /**< uints, normalized to [0,1] */
-#define PIPE_FORMAT_TYPE_SNORM   3  /**< ints, normalized to [-1,1] */
-#define PIPE_FORMAT_TYPE_USCALED 4  /**< uints, not normalized */
-#define PIPE_FORMAT_TYPE_SSCALED 5  /**< ints, not normalized */
-#define PIPE_FORMAT_TYPE_SRGB    6  /**< sRGB colorspace */
-#define PIPE_FORMAT_TYPE_FIXED   7  /**< 16.16 fixed point */
-
-
-/**
- * Because the destination vector is assumed to be RGBA FLOAT, we
- * need to know how to swizzle and expand components from the source
- * vector.
- * Let's take U_A1_R5_G5_B5 as an example. X swizzle is A, X size
- * is 1 bit and type is UNORM. So we take the most significant bit
- * from source vector, convert 0 to 0.0 and 1 to 1.0 and save it
- * in the last component of the destination RGBA component.
- * Next, Y swizzle is R, Y size is 5 and type is UNORM. We normalize
- * those 5 bits into [0.0; 1.0] range and put it into second
- * component of the destination vector. Rinse and repeat for
- * components Z and W.
- * If any of size fields is zero, it means the source format contains
- * less than four components.
- * If any swizzle is 0 or 1, the corresponding destination component
- * should be filled with 0.0 and 1.0, respectively.
- */
-typedef uint pipe_format_rgbazs_t;
-
-static INLINE uint pf_get(pipe_format_rgbazs_t f, uint shift, uint mask)
-{
-   return (f >> shift) & mask;
-}
-
-#define pf_swizzle_x(f)       pf_get(f, 2, 0x7)  /**< PIPE_FORMAT_COMP_ */
-#define pf_swizzle_y(f)       pf_get(f, 5, 0x7)  /**< PIPE_FORMAT_COMP_ */
-#define pf_swizzle_z(f)       pf_get(f, 8, 0x7)  /**< PIPE_FORMAT_COMP_ */
-#define pf_swizzle_w(f)       pf_get(f, 11, 0x7) /**< PIPE_FORMAT_COMP_ */
-#define pf_swizzle_xyzw(f,i)  pf_get(f, 2+((i)*3), 0x7)
-#define pf_size_x(f)          pf_get(f, 14, 0x7) /**< Size of X */
-#define pf_size_y(f)          pf_get(f, 17, 0x7) /**< Size of Y */
-#define pf_size_z(f)          pf_get(f, 20, 0x7) /**< Size of Z */
-#define pf_size_w(f)          pf_get(f, 23, 0x7) /**< Size of W */
-#define pf_size_xyzw(f,i)     pf_get(f, 14+((i)*3), 0x7)
-#define pf_exp2(f)            pf_get(f, 26, 0x7) /**< Scale size by 2 ^ exp2 */
-#define pf_type(f)            pf_get(f, 29, 0x7) /**< PIPE_FORMAT_TYPE_ */
-
-/**
- * Helper macro to encode the above structure into a 32-bit value.
- */
-#define _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, EXP2, TYPE ) (\
-   (PIPE_FORMAT_LAYOUT_RGBAZS << 0) |\
-   ((SWZ) << 2) |\
-   ((SIZEX) << 14) |\
-   ((SIZEY) << 17) |\
-   ((SIZEZ) << 20) |\
-   ((SIZEW) << 23) |\
-   ((EXP2) << 26) |\
-   ((TYPE) << 29) )
-
-/**
- * Helper macro to encode the swizzle part of the structure above.
- */
-#define _PIPE_FORMAT_SWZ( SWZX, SWZY, SWZZ, SWZW ) (((SWZX) << 0) | ((SWZY) << 3) | ((SWZZ) << 6) | ((SWZW) << 9))
-
-/**
- * Shorthand macro for RGBAZS layout with component sizes in 1-bit units.
- */
-#define _PIPE_FORMAT_RGBAZS_1( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE )\
-   _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 0, TYPE )
-
-/**
- * Shorthand macro for RGBAZS layout with component sizes in 2-bit units.
- */
-#define _PIPE_FORMAT_RGBAZS_2( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE )\
-   _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 1, TYPE )
-
-/**
- * Shorthand macro for RGBAZS layout with component sizes in 8-bit units.
- */
-#define _PIPE_FORMAT_RGBAZS_8( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE )\
-   _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 3, TYPE )
-
-/**
- * Shorthand macro for RGBAZS layout with component sizes in 64-bit units.
- */
-#define _PIPE_FORMAT_RGBAZS_64( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE )\
-   _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 6, TYPE )
-
-typedef uint pipe_format_mixed_t;
-
-/* NOTE: Use pf_swizzle_* and pf_size_* macros for swizzles and sizes.
- */
-
-#define pf_mixed_sign_x(f)       pf_get( f, 26, 0x1 )       /*< Sign of X */
-#define pf_mixed_sign_y(f)       pf_get( f, 27, 0x1 )       /*< Sign of Y */
-#define pf_mixed_sign_z(f)       pf_get( f, 28, 0x1 )       /*< Sign of Z */
-#define pf_mixed_sign_w(f)       pf_get( f, 29, 0x1 )       /*< Sign of W */
-#define pf_mixed_sign_xyzw(f, i) pf_get( f, 26 + (i), 0x1 )
-#define pf_mixed_normalized(f)   pf_get( f, 30, 0x1 )       /*< Type is NORM (1) or SCALED (0) */
-#define pf_mixed_scale8(f)       pf_get( f, 31, 0x1 )       /*< Scale size by either one (0) or eight (1) */
-
-/**
- * Helper macro to encode the above structure into a 32-bit value.
- */
-#define _PIPE_FORMAT_MIXED( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, SIGNX, SIGNY, SIGNZ, SIGNW, NORMALIZED, SCALE8 ) (\
-   (PIPE_FORMAT_LAYOUT_MIXED << 0) |\
-   ((SWZ) << 2) |\
-   ((SIZEX) << 14) |\
-   ((SIZEY) << 17) |\
-   ((SIZEZ) << 20) |\
-   ((SIZEW) << 23) |\
-   ((SIGNX) << 26) |\
-   ((SIGNY) << 27) |\
-   ((SIGNZ) << 28) |\
-   ((SIGNW) << 29) |\
-   ((NORMALIZED) << 30) |\
-   ((SCALE8) << 31) )
-
-/**
- * Shorthand macro for common format swizzles.
- */
-#define _PIPE_FORMAT_R001 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_1 )
-#define _PIPE_FORMAT_RG01 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_1 )
-#define _PIPE_FORMAT_RGB1 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_1 )
-#define _PIPE_FORMAT_RGBA _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_A )
-#define _PIPE_FORMAT_ARGB _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_A, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B )
-#define _PIPE_FORMAT_ABGR _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_A, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R )
-#define _PIPE_FORMAT_BGRA _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_A )
-#define _PIPE_FORMAT_1RGB _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_1, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B )
-#define _PIPE_FORMAT_1BGR _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_1, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R )
-#define _PIPE_FORMAT_BGR1 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_1 )
-#define _PIPE_FORMAT_0000 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 )
-#define _PIPE_FORMAT_000R _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_R )
-#define _PIPE_FORMAT_RRR1 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_1 )
-#define _PIPE_FORMAT_RRRR _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R )
-#define _PIPE_FORMAT_RRRG _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G )
-#define _PIPE_FORMAT_Z000 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_Z, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 )
-#define _PIPE_FORMAT_0Z00 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_Z, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 )
-#define _PIPE_FORMAT_SZ00 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_S, PIPE_FORMAT_COMP_Z, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 )
-#define _PIPE_FORMAT_ZS00 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_Z, PIPE_FORMAT_COMP_S, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 )
-#define _PIPE_FORMAT_S000 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_S, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 )
-
-/**
- * YCBCR Format Layout.
- */
-
-/**
- * This only contains a flag that indicates whether the format is reversed or
- * not.
- */
-typedef uint pipe_format_ycbcr_t;
-
-/**
- * Helper macro to encode the above structure into a 32-bit value.
- */
-#define _PIPE_FORMAT_YCBCR( REV ) (\
-   (PIPE_FORMAT_LAYOUT_YCBCR << 0) |\
-   ((REV) << 2) )
-
-static INLINE uint pf_rev(pipe_format_ycbcr_t f)
-{
-   return (f >> 2) & 0x1;
-}
-
-
-/**
-  * Compresssed format layouts (this will probably change)
-  */
-#define _PIPE_FORMAT_DXT( LEVEL, RSIZE, GSIZE, BSIZE, ASIZE, TYPE ) \
-   ((PIPE_FORMAT_LAYOUT_DXT << 0) | \
-    ((LEVEL) << 2) | \
-    ((RSIZE) << 5) | \
-    ((GSIZE) << 8) | \
-    ((BSIZE) << 11) | \
-    ((ASIZE) << 14) | \
-    ((TYPE) << 29))
-
-
-
-/**
  * Texture/surface image formats (preliminary)
  */
 
 /* KW: Added lots of surface formats to support vertex element layout
- * definitions, and eventually render-to-vertex-buffer.  Could
- * consider making float/int/uint/scaled/normalized a separate
- * parameter, but on the other hand there are special cases like
- * z24s8, compressed textures, ycbcr, etc that won't fit that model.
+ * definitions, and eventually render-to-vertex-buffer.
  */
 
 enum pipe_format {
-   PIPE_FORMAT_NONE                  = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_0000, 0, 0, 0, 0, PIPE_FORMAT_TYPE_UNKNOWN ),
-   PIPE_FORMAT_A8R8G8B8_UNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_ARGB, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_X8R8G8B8_UNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_1RGB, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_B8G8R8A8_UNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_BGRA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_B8G8R8X8_UNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_BGR1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_A1R5G5B5_UNORM        = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_ARGB, 1, 5, 5, 5, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_A4R4G4B4_UNORM        = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_ARGB, 4, 4, 4, 4, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_R5G6B5_UNORM          = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_RGB1, 5, 6, 5, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_A2B10G10R10_UNORM     = _PIPE_FORMAT_RGBAZS_2 ( _PIPE_FORMAT_ABGR, 1, 5, 5, 5, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_L8_UNORM              = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte luminance */
-   PIPE_FORMAT_A8_UNORM              = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_000R, 0, 0, 0, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte alpha */
-   PIPE_FORMAT_I8_UNORM              = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRR, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte intensity */
-   PIPE_FORMAT_A8L8_UNORM            = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRG, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte alpha, luminance */
-   PIPE_FORMAT_L16_UNORM             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 2, 2, 2, 0, PIPE_FORMAT_TYPE_UNORM ), /**< ushort luminance */
-   PIPE_FORMAT_YCBCR                 = _PIPE_FORMAT_YCBCR( 0 ),
-   PIPE_FORMAT_YCBCR_REV             = _PIPE_FORMAT_YCBCR( 1 ),
-   PIPE_FORMAT_Z16_UNORM             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_Z000, 2, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_Z32_UNORM             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_Z000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_Z32_FLOAT             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_Z000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_FLOAT ),
-   PIPE_FORMAT_S8Z24_UNORM           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_SZ00, 1, 3, 0, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_Z24S8_UNORM           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_ZS00, 3, 1, 0, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_X8Z24_UNORM           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_0Z00, 1, 3, 0, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_Z24X8_UNORM           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_Z000, 3, 1, 0, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_S8_UNORM              = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_S000, 1, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte stencil */
-   PIPE_FORMAT_R64_FLOAT             = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_FLOAT ),
-   PIPE_FORMAT_R64G64_FLOAT          = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_FLOAT ),
-   PIPE_FORMAT_R64G64B64_FLOAT       = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_FLOAT ),
-   PIPE_FORMAT_R64G64B64A64_FLOAT    = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_FLOAT ),
-   PIPE_FORMAT_R32_FLOAT             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_FLOAT ),
-   PIPE_FORMAT_R32G32_FLOAT          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_FLOAT ),
-   PIPE_FORMAT_R32G32B32_FLOAT       = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_FLOAT ),
-   PIPE_FORMAT_R32G32B32A32_FLOAT    = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_FLOAT ),
-   PIPE_FORMAT_R32_UNORM             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_R32G32_UNORM          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_R32G32B32_UNORM       = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_R32G32B32A32_UNORM    = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_R32_USCALED           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_USCALED ),
-   PIPE_FORMAT_R32G32_USCALED        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_USCALED ),
-   PIPE_FORMAT_R32G32B32_USCALED     = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_USCALED ),
-   PIPE_FORMAT_R32G32B32A32_USCALED  = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_USCALED ),
-   PIPE_FORMAT_R32_SNORM             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_SNORM ),
-   PIPE_FORMAT_R32G32_SNORM          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_SNORM ),
-   PIPE_FORMAT_R32G32B32_SNORM       = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_SNORM ),
-   PIPE_FORMAT_R32G32B32A32_SNORM    = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_SNORM ),
-   PIPE_FORMAT_R32_SSCALED           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ),
-   PIPE_FORMAT_R32G32_SSCALED        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_SSCALED ),
-   PIPE_FORMAT_R32G32B32_SSCALED     = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_SSCALED ),
-   PIPE_FORMAT_R32G32B32A32_SSCALED  = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_SSCALED ),
-   PIPE_FORMAT_R16_UNORM             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 2, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_R16G16_UNORM          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 2, 2, 0, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_R16G16B16_UNORM       = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 2, 2, 2, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_R16G16B16A16_UNORM    = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 2, 2, 2, 2, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_R16_USCALED           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 2, 0, 0, 0, PIPE_FORMAT_TYPE_USCALED ),
-   PIPE_FORMAT_R16G16_USCALED        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 2, 2, 0, 0, PIPE_FORMAT_TYPE_USCALED ),
-   PIPE_FORMAT_R16G16B16_USCALED     = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 2, 2, 2, 0, PIPE_FORMAT_TYPE_USCALED ),
-   PIPE_FORMAT_R16G16B16A16_USCALED  = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 2, 2, 2, 2, PIPE_FORMAT_TYPE_USCALED ),
-   PIPE_FORMAT_R16_SNORM             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 2, 0, 0, 0, PIPE_FORMAT_TYPE_SNORM ),
-   PIPE_FORMAT_R16G16_SNORM          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 2, 2, 0, 0, PIPE_FORMAT_TYPE_SNORM ),
-   PIPE_FORMAT_R16G16B16_SNORM       = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 2, 2, 2, 0, PIPE_FORMAT_TYPE_SNORM ),
-   PIPE_FORMAT_R16G16B16A16_SNORM    = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 2, 2, 2, 2, PIPE_FORMAT_TYPE_SNORM ),
-   PIPE_FORMAT_R16_SSCALED           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 2, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ),
-   PIPE_FORMAT_R16G16_SSCALED        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 2, 2, 0, 0, PIPE_FORMAT_TYPE_SSCALED ),
-   PIPE_FORMAT_R16G16B16_SSCALED     = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 2, 2, 2, 0, PIPE_FORMAT_TYPE_SSCALED ),
-   PIPE_FORMAT_R16G16B16A16_SSCALED  = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 2, 2, 2, 2, PIPE_FORMAT_TYPE_SSCALED ),
-   PIPE_FORMAT_R8_UNORM              = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_R8G8_UNORM            = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_R8G8B8_UNORM          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_R8G8B8A8_UNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_R8G8B8X8_UNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_R8_USCALED            = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_USCALED ),
-   PIPE_FORMAT_R8G8_USCALED          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_USCALED ),
-   PIPE_FORMAT_R8G8B8_USCALED        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_USCALED ),
-   PIPE_FORMAT_R8G8B8A8_USCALED      = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_USCALED ),
-   PIPE_FORMAT_R8G8B8X8_USCALED      = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_USCALED ),
-   PIPE_FORMAT_R8_SNORM              = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_SNORM ),
-   PIPE_FORMAT_R8G8_SNORM            = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_SNORM ),
-   PIPE_FORMAT_R8G8B8_SNORM          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SNORM ),
-   PIPE_FORMAT_R8G8B8A8_SNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ),
-   PIPE_FORMAT_R8G8B8X8_SNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ),
-   PIPE_FORMAT_B6G5R5_SNORM          = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_BGR1, 6, 5, 5, 0, PIPE_FORMAT_TYPE_SNORM ),
-   PIPE_FORMAT_A8B8G8R8_SNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_BGRA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ),
-   PIPE_FORMAT_X8B8G8R8_SNORM        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_BGR1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ),
-   PIPE_FORMAT_R8_SSCALED            = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ),
-   PIPE_FORMAT_R8G8_SSCALED          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_SSCALED ),
-   PIPE_FORMAT_R8G8B8_SSCALED        = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SSCALED ),
-   PIPE_FORMAT_R8G8B8A8_SSCALED      = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SSCALED ),
-   PIPE_FORMAT_R8G8B8X8_SSCALED      = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SSCALED ),
-   PIPE_FORMAT_R32_FIXED             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_FIXED ),
-   PIPE_FORMAT_R32G32_FIXED          = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_FIXED ),
-   PIPE_FORMAT_R32G32B32_FIXED       = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_FIXED ),
-   PIPE_FORMAT_R32G32B32A32_FIXED    = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_FIXED ),
+   PIPE_FORMAT_NONE                  = 0,
+   PIPE_FORMAT_A8R8G8B8_UNORM        = 1,
+   PIPE_FORMAT_X8R8G8B8_UNORM        = 2,
+   PIPE_FORMAT_B8G8R8A8_UNORM        = 3,
+   PIPE_FORMAT_B8G8R8X8_UNORM        = 4,
+   PIPE_FORMAT_A1R5G5B5_UNORM        = 5,
+   PIPE_FORMAT_A4R4G4B4_UNORM        = 6,
+   PIPE_FORMAT_R5G6B5_UNORM          = 7,
+   PIPE_FORMAT_A2B10G10R10_UNORM     = 8,
+   PIPE_FORMAT_L8_UNORM              = 9,    /**< ubyte luminance */
+   PIPE_FORMAT_A8_UNORM              = 10,   /**< ubyte alpha */
+   PIPE_FORMAT_I8_UNORM              = 11,   /**< ubyte intensity */
+   PIPE_FORMAT_A8L8_UNORM            = 12,   /**< ubyte alpha, luminance */
+   PIPE_FORMAT_L16_UNORM             = 13,   /**< ushort luminance */
+   PIPE_FORMAT_YCBCR                 = 14,
+   PIPE_FORMAT_YCBCR_REV             = 15,
+   PIPE_FORMAT_Z16_UNORM             = 16,
+   PIPE_FORMAT_Z32_UNORM             = 17,
+   PIPE_FORMAT_Z32_FLOAT             = 18,
+   PIPE_FORMAT_S8Z24_UNORM           = 19,
+   PIPE_FORMAT_Z24S8_UNORM           = 20,
+   PIPE_FORMAT_X8Z24_UNORM           = 21,
+   PIPE_FORMAT_Z24X8_UNORM           = 22,
+   PIPE_FORMAT_S8_UNORM              = 23,   /**< ubyte stencil */
+   PIPE_FORMAT_R64_FLOAT             = 24,
+   PIPE_FORMAT_R64G64_FLOAT          = 25,
+   PIPE_FORMAT_R64G64B64_FLOAT       = 26,
+   PIPE_FORMAT_R64G64B64A64_FLOAT    = 27,
+   PIPE_FORMAT_R32_FLOAT             = 28,
+   PIPE_FORMAT_R32G32_FLOAT          = 29,
+   PIPE_FORMAT_R32G32B32_FLOAT       = 30,
+   PIPE_FORMAT_R32G32B32A32_FLOAT    = 31,
+   PIPE_FORMAT_R32_UNORM             = 32,
+   PIPE_FORMAT_R32G32_UNORM          = 33,
+   PIPE_FORMAT_R32G32B32_UNORM       = 34,
+   PIPE_FORMAT_R32G32B32A32_UNORM    = 35,
+   PIPE_FORMAT_R32_USCALED           = 36,
+   PIPE_FORMAT_R32G32_USCALED        = 37,
+   PIPE_FORMAT_R32G32B32_USCALED     = 38,
+   PIPE_FORMAT_R32G32B32A32_USCALED  = 39,
+   PIPE_FORMAT_R32_SNORM             = 40,
+   PIPE_FORMAT_R32G32_SNORM          = 41,
+   PIPE_FORMAT_R32G32B32_SNORM       = 42,
+   PIPE_FORMAT_R32G32B32A32_SNORM    = 43,
+   PIPE_FORMAT_R32_SSCALED           = 44,
+   PIPE_FORMAT_R32G32_SSCALED        = 45,
+   PIPE_FORMAT_R32G32B32_SSCALED     = 46,
+   PIPE_FORMAT_R32G32B32A32_SSCALED  = 47,
+   PIPE_FORMAT_R16_UNORM             = 48,
+   PIPE_FORMAT_R16G16_UNORM          = 49,
+   PIPE_FORMAT_R16G16B16_UNORM       = 50,
+   PIPE_FORMAT_R16G16B16A16_UNORM    = 51,
+   PIPE_FORMAT_R16_USCALED           = 52,
+   PIPE_FORMAT_R16G16_USCALED        = 53,
+   PIPE_FORMAT_R16G16B16_USCALED     = 54,
+   PIPE_FORMAT_R16G16B16A16_USCALED  = 55,
+   PIPE_FORMAT_R16_SNORM             = 56,
+   PIPE_FORMAT_R16G16_SNORM          = 57,
+   PIPE_FORMAT_R16G16B16_SNORM       = 58,
+   PIPE_FORMAT_R16G16B16A16_SNORM    = 59,
+   PIPE_FORMAT_R16_SSCALED           = 60,
+   PIPE_FORMAT_R16G16_SSCALED        = 61,
+   PIPE_FORMAT_R16G16B16_SSCALED     = 62,
+   PIPE_FORMAT_R16G16B16A16_SSCALED  = 63,
+   PIPE_FORMAT_R8_UNORM              = 64,
+   PIPE_FORMAT_R8G8_UNORM            = 65,
+   PIPE_FORMAT_R8G8B8_UNORM          = 66,
+   PIPE_FORMAT_R8G8B8A8_UNORM        = 67,
+   PIPE_FORMAT_R8G8B8X8_UNORM        = 68,
+   PIPE_FORMAT_R8_USCALED            = 69,
+   PIPE_FORMAT_R8G8_USCALED          = 70,
+   PIPE_FORMAT_R8G8B8_USCALED        = 71,
+   PIPE_FORMAT_R8G8B8A8_USCALED      = 72,
+   PIPE_FORMAT_R8G8B8X8_USCALED      = 73,
+   PIPE_FORMAT_R8_SNORM              = 74,
+   PIPE_FORMAT_R8G8_SNORM            = 75,
+   PIPE_FORMAT_R8G8B8_SNORM          = 76,
+   PIPE_FORMAT_R8G8B8A8_SNORM        = 77,
+   PIPE_FORMAT_R8G8B8X8_SNORM        = 78,
+   PIPE_FORMAT_B6G5R5_SNORM          = 79,
+   PIPE_FORMAT_A8B8G8R8_SNORM        = 80,
+   PIPE_FORMAT_X8B8G8R8_SNORM        = 81,
+   PIPE_FORMAT_R8_SSCALED            = 82,
+   PIPE_FORMAT_R8G8_SSCALED          = 83,
+   PIPE_FORMAT_R8G8B8_SSCALED        = 84,
+   PIPE_FORMAT_R8G8B8A8_SSCALED      = 85,
+   PIPE_FORMAT_R8G8B8X8_SSCALED      = 86,
+   PIPE_FORMAT_R32_FIXED             = 87,
+   PIPE_FORMAT_R32G32_FIXED          = 88,
+   PIPE_FORMAT_R32G32B32_FIXED       = 89,
+   PIPE_FORMAT_R32G32B32A32_FIXED    = 90,
    /* sRGB formats */
-   PIPE_FORMAT_L8_SRGB               = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SRGB ),
-   PIPE_FORMAT_A8L8_SRGB             = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRG, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ),
-   PIPE_FORMAT_R8G8B8_SRGB           = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SRGB ),
-   PIPE_FORMAT_R8G8B8A8_SRGB         = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ),
-   PIPE_FORMAT_R8G8B8X8_SRGB         = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ),
-   PIPE_FORMAT_A8R8G8B8_SRGB         = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_ARGB, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ),
-   PIPE_FORMAT_X8R8G8B8_SRGB         = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_1RGB, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ),
-   PIPE_FORMAT_B8G8R8A8_SRGB         = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_BGRA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ),
-   PIPE_FORMAT_B8G8R8X8_SRGB         = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_BGR1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ),
+   PIPE_FORMAT_L8_SRGB               = 91,
+   PIPE_FORMAT_A8L8_SRGB             = 92,
+   PIPE_FORMAT_R8G8B8_SRGB           = 93,
+   PIPE_FORMAT_R8G8B8A8_SRGB         = 94,
+   PIPE_FORMAT_R8G8B8X8_SRGB         = 95,
+   PIPE_FORMAT_A8R8G8B8_SRGB         = 96,
+   PIPE_FORMAT_X8R8G8B8_SRGB         = 97,
+   PIPE_FORMAT_B8G8R8A8_SRGB         = 98,
+   PIPE_FORMAT_B8G8R8X8_SRGB         = 99,
 
    /* mixed formats */
-   PIPE_FORMAT_X8UB8UG8SR8S_NORM     = _PIPE_FORMAT_MIXED( _PIPE_FORMAT_1BGR, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 ),
-   PIPE_FORMAT_B6UG5SR5S_NORM        = _PIPE_FORMAT_MIXED( _PIPE_FORMAT_BGR1, 6, 5, 5, 0, 0, 1, 1, 0, 1, 0 ),
+   PIPE_FORMAT_X8UB8UG8SR8S_NORM     = 100,
+   PIPE_FORMAT_B6UG5SR5S_NORM        = 101,
 
    /* compressed formats */
-   PIPE_FORMAT_DXT1_RGB              = _PIPE_FORMAT_DXT( 1, 8, 8, 8, 0, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_DXT1_RGBA             = _PIPE_FORMAT_DXT( 1, 8, 8, 8, 8, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_DXT3_RGBA             = _PIPE_FORMAT_DXT( 3, 8, 8, 8, 8, PIPE_FORMAT_TYPE_UNORM ),
-   PIPE_FORMAT_DXT5_RGBA             = _PIPE_FORMAT_DXT( 5, 8, 8, 8, 8, PIPE_FORMAT_TYPE_UNORM ),
+   PIPE_FORMAT_DXT1_RGB              = 102,
+   PIPE_FORMAT_DXT1_RGBA             = 103,
+   PIPE_FORMAT_DXT3_RGBA             = 104,
+   PIPE_FORMAT_DXT5_RGBA             = 105,
 
    /* sRGB, compressed */
-   PIPE_FORMAT_DXT1_SRGB             = _PIPE_FORMAT_DXT( 1, 8, 8, 8, 0, PIPE_FORMAT_TYPE_SRGB ),
-   PIPE_FORMAT_DXT1_SRGBA            = _PIPE_FORMAT_DXT( 1, 8, 8, 8, 8, PIPE_FORMAT_TYPE_SRGB ),
-   PIPE_FORMAT_DXT3_SRGBA            = _PIPE_FORMAT_DXT( 3, 8, 8, 8, 8, PIPE_FORMAT_TYPE_SRGB ),
-   PIPE_FORMAT_DXT5_SRGBA            = _PIPE_FORMAT_DXT( 5, 8, 8, 8, 8, PIPE_FORMAT_TYPE_SRGB )
+   PIPE_FORMAT_DXT1_SRGB             = 106,
+   PIPE_FORMAT_DXT1_SRGBA            = 107,
+   PIPE_FORMAT_DXT3_SRGBA            = 108,
+   PIPE_FORMAT_DXT5_SRGBA            = 109,
+
+   PIPE_FORMAT_COUNT
 };
 
 /**
@@ -394,224 +174,6 @@
  */
 extern const char *pf_name( enum pipe_format format );
 
-/**
- * Return bits for a particular component.
- * \param comp  component index, starting at 0
- */
-static INLINE uint pf_get_component_bits( enum pipe_format format, uint comp )
-{
-   uint size;
-
-   if (pf_swizzle_x(format) == comp) {
-      size = pf_size_x(format);
-   }
-   else if (pf_swizzle_y(format) == comp) {
-      size = pf_size_y(format);
-   }
-   else if (pf_swizzle_z(format) == comp) {
-      size = pf_size_z(format);
-   }
-   else if (pf_swizzle_w(format) == comp) {
-      size = pf_size_w(format);
-   }
-   else {
-      size = 0;
-   }
-   if (pf_layout( format ) == PIPE_FORMAT_LAYOUT_RGBAZS)
-      return size << pf_exp2( format );
-   return size << (pf_mixed_scale8( format ) * 3);
-}
-
-/**
- * Return total bits needed for the pixel format.
- */
-static INLINE uint pf_get_bits( enum pipe_format format )
-{
-   switch (pf_layout(format)) {
-   case PIPE_FORMAT_LAYOUT_RGBAZS:
-   case PIPE_FORMAT_LAYOUT_MIXED:
-      return
-         pf_get_component_bits( format, PIPE_FORMAT_COMP_0 ) +
-         pf_get_component_bits( format, PIPE_FORMAT_COMP_1 ) +
-         pf_get_component_bits( format, PIPE_FORMAT_COMP_R ) +
-         pf_get_component_bits( format, PIPE_FORMAT_COMP_G ) +
-         pf_get_component_bits( format, PIPE_FORMAT_COMP_B ) +
-         pf_get_component_bits( format, PIPE_FORMAT_COMP_A ) +
-         pf_get_component_bits( format, PIPE_FORMAT_COMP_Z ) +
-         pf_get_component_bits( format, PIPE_FORMAT_COMP_S );
-   case PIPE_FORMAT_LAYOUT_YCBCR:
-      assert( format == PIPE_FORMAT_YCBCR || format == PIPE_FORMAT_YCBCR_REV );
-      /* return effective bits per pixel */
-      return 16; 
-   default:
-      assert( 0 );
-      return 0;
-   }
-}
-
-/**
- * Return bytes per pixel for the given format.
- */
-static INLINE uint pf_get_size( enum pipe_format format )
-{
-   assert(pf_get_bits(format) % 8 == 0);
-   return pf_get_bits(format) / 8;
-}
-
-/**
- * Describe accurately the pixel format.
- * 
- * The chars-per-pixel concept falls apart with compressed and yuv images, where
- * more than one pixel are coded in a single data block. This structure 
- * describes that block.
- * 
- * Simple pixel formats are effectively a 1x1xcpp block.
- */
-struct pipe_format_block
-{
-   /** Block size in bytes */
-   unsigned size;
-   
-   /** Block width in pixels */
-   unsigned width;
-   
-   /** Block height in pixels */
-   unsigned height;
-};
-
-/**
- * Describe pixel format's block.   
- * 
- * @sa http://msdn2.microsoft.com/en-us/library/ms796147.aspx
- */
-static INLINE void 
-pf_get_block(enum pipe_format format, struct pipe_format_block *block)
-{
-   switch(format) {
-   case PIPE_FORMAT_DXT1_RGBA:
-   case PIPE_FORMAT_DXT1_RGB:
-   case PIPE_FORMAT_DXT1_SRGBA:
-   case PIPE_FORMAT_DXT1_SRGB:
-      block->size = 8;
-      block->width = 4;
-      block->height = 4;
-      break;
-   case PIPE_FORMAT_DXT3_RGBA:
-   case PIPE_FORMAT_DXT5_RGBA:
-   case PIPE_FORMAT_DXT3_SRGBA:
-   case PIPE_FORMAT_DXT5_SRGBA:
-      block->size = 16;
-      block->width = 4;
-      block->height = 4;
-      break;
-   case PIPE_FORMAT_YCBCR:
-   case PIPE_FORMAT_YCBCR_REV:
-      block->size = 4; /* 2*cpp */
-      block->width = 2;
-      block->height = 1;
-      break;
-   default:
-      block->size = pf_get_size(format);
-      block->width = 1;
-      block->height = 1;
-      break;
-   }
-}
-
-static INLINE unsigned
-pf_get_nblocksx(const struct pipe_format_block *block, unsigned x)
-{
-   return (x + block->width - 1)/block->width;
-}
-
-static INLINE unsigned
-pf_get_nblocksy(const struct pipe_format_block *block, unsigned y)
-{
-   return (y + block->height - 1)/block->height;
-}
-
-static INLINE unsigned
-pf_get_nblocks(const struct pipe_format_block *block, unsigned width, unsigned height)
-{
-   return pf_get_nblocksx(block, width)*pf_get_nblocksy(block, height);
-}
-
-static INLINE size_t
-pf_get_stride(const struct pipe_format_block *block, unsigned width)
-{
-   return pf_get_nblocksx(block, width)*block->size;
-}
-
-static INLINE size_t
-pf_get_2d_size(const struct pipe_format_block *block, size_t stride, unsigned height)
-{
-   return pf_get_nblocksy(block, height)*stride;
-}
-
-static INLINE boolean 
-pf_is_depth_or_stencil( enum pipe_format format )
-{
-   return (pf_get_component_bits( format, PIPE_FORMAT_COMP_Z ) +
-           pf_get_component_bits( format, PIPE_FORMAT_COMP_S )) != 0;
-}
-
-static INLINE boolean 
-pf_is_depth_and_stencil( enum pipe_format format )
-{
-   return (pf_get_component_bits( format, PIPE_FORMAT_COMP_Z ) != 0 &&
-           pf_get_component_bits( format, PIPE_FORMAT_COMP_S ) != 0);
-}
-
-/** DEPRECATED: For backwards compatibility */
-static INLINE boolean
-pf_is_depth_stencil( enum pipe_format format )
-{
-   return pf_is_depth_or_stencil( format );
-}
-
-static INLINE boolean 
-pf_is_compressed( enum pipe_format format )
-{
-   return pf_layout(format) == PIPE_FORMAT_LAYOUT_DXT ? TRUE : FALSE;
-}
-
-static INLINE boolean 
-pf_is_ycbcr( enum pipe_format format )
-{
-   return pf_layout(format) == PIPE_FORMAT_LAYOUT_YCBCR ? TRUE : FALSE;
-}
-
-static INLINE boolean 
-pf_has_alpha( enum pipe_format format )
-{
-   switch (pf_layout(format)) {
-   case PIPE_FORMAT_LAYOUT_RGBAZS:
-   case PIPE_FORMAT_LAYOUT_MIXED:
-      /* FIXME: pf_get_component_bits( PIPE_FORMAT_A8L8_UNORM, PIPE_FORMAT_COMP_A ) should not return 0 right? */
-      if(format == PIPE_FORMAT_A8_UNORM || 
-         format == PIPE_FORMAT_A8L8_UNORM || 
-         format == PIPE_FORMAT_A8L8_SRGB)
-         return TRUE;
-      return pf_get_component_bits( format, PIPE_FORMAT_COMP_A ) ? TRUE : FALSE;
-   case PIPE_FORMAT_LAYOUT_YCBCR:
-      return FALSE; 
-   case PIPE_FORMAT_LAYOUT_DXT:
-      switch (format) {
-      case PIPE_FORMAT_DXT1_RGBA:
-      case PIPE_FORMAT_DXT3_RGBA:
-      case PIPE_FORMAT_DXT5_RGBA:
-      case PIPE_FORMAT_DXT1_SRGBA:
-      case PIPE_FORMAT_DXT3_SRGBA:
-      case PIPE_FORMAT_DXT5_SRGBA:
-         return TRUE;
-      default:
-         return FALSE;
-      }
-   default:
-      assert( 0 );
-      return FALSE;
-   }
-}
 
 enum pipe_video_chroma_format
 {
diff --git a/src/gallium/include/pipe/p_refcnt.h b/src/gallium/include/pipe/p_refcnt.h
index 1f9088b..c1c7415 100644
--- a/src/gallium/include/pipe/p_refcnt.h
+++ b/src/gallium/include/pipe/p_refcnt.h
@@ -51,7 +51,7 @@
 }
 
 
-static INLINE bool
+static INLINE boolean
 pipe_is_referenced(struct pipe_reference *reference)
 {
    return p_atomic_read(&reference->count) != 0;
@@ -59,30 +59,29 @@
 
 
 /**
- * Set 'ptr' to point to 'reference' and update reference counting.
- * The old thing pointed to, if any, will be unreferenced first.
- * 'reference' may be NULL.
+ * Update reference counting.
+ * The old thing pointed to, if any, will be unreferenced.
+ * Both 'ptr' and 'reference' may be NULL.
+ * \return TRUE if the object's refcount hits zero and should be destroyed.
  */
-static INLINE bool
-pipe_reference(struct pipe_reference **ptr, struct pipe_reference *reference)
+static INLINE boolean
+pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference)
 {
-   bool destroy = FALSE;
+   boolean destroy = FALSE;
 
-   if(*ptr != reference) {
+   if(ptr != reference) {
       /* bump the reference.count first */
       if (reference) {
          assert(pipe_is_referenced(reference));
          p_atomic_inc(&reference->count);
       }
    
-      if (*ptr) {
-         assert(pipe_is_referenced(*ptr));
-         if (p_atomic_dec_zero(&(*ptr)->count)) {
+      if (ptr) {
+         assert(pipe_is_referenced(ptr));
+         if (p_atomic_dec_zero(&ptr->count)) {
             destroy = TRUE;
          }
       }
-   
-      *ptr = reference;
    }
 
    return destroy;
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index f0a4de5..b8e001a 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -266,6 +266,11 @@
 
    void (*video_surface_destroy)( struct pipe_video_surface *vsfc );
 
+   /**
+    * Do any special operations to ensure buffer size is correct
+    */
+   void (*update_buffer)( struct pipe_screen *ws,
+                          void *context_private );
 
    /**
     * Do any special operations to ensure frontbuffer contents are
diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
index d4c8aad..550e2ab 100644
--- a/src/gallium/include/pipe/p_shader_tokens.h
+++ b/src/gallium/include/pipe/p_shader_tokens.h
@@ -35,12 +35,6 @@
 
 #include "p_compiler.h"
 
-struct tgsi_version
-{
-   unsigned MajorVersion  : 8;
-   unsigned MinorVersion  : 8;
-   unsigned Padding       : 16;
-};
 
 struct tgsi_header
 {
@@ -61,26 +55,27 @@
 #define TGSI_TOKEN_TYPE_DECLARATION    0
 #define TGSI_TOKEN_TYPE_IMMEDIATE      1
 #define TGSI_TOKEN_TYPE_INSTRUCTION    2
+#define TGSI_TOKEN_TYPE_PROPERTY       3
 
 struct tgsi_token
 {
    unsigned Type       : 4;  /**< TGSI_TOKEN_TYPE_x */
    unsigned NrTokens   : 8;  /**< UINT */
-   unsigned Padding    : 19;
-   unsigned Extended   : 1;  /**< BOOL */
+   unsigned Padding    : 20;
 };
 
 enum tgsi_file_type {
-   TGSI_FILE_NULL        =0,
-   TGSI_FILE_CONSTANT    =1,
-   TGSI_FILE_INPUT       =2,
-   TGSI_FILE_OUTPUT      =3,
-   TGSI_FILE_TEMPORARY   =4,
-   TGSI_FILE_SAMPLER     =5,
-   TGSI_FILE_ADDRESS     =6,
-   TGSI_FILE_IMMEDIATE   =7,
-   TGSI_FILE_LOOP        =8,
-   TGSI_FILE_PREDICATE   =9,
+   TGSI_FILE_NULL         =0,
+   TGSI_FILE_CONSTANT     =1,
+   TGSI_FILE_INPUT        =2,
+   TGSI_FILE_OUTPUT       =3,
+   TGSI_FILE_TEMPORARY    =4,
+   TGSI_FILE_SAMPLER      =5,
+   TGSI_FILE_ADDRESS      =6,
+   TGSI_FILE_IMMEDIATE    =7,
+   TGSI_FILE_LOOP         =8,
+   TGSI_FILE_PREDICATE    =9,
+   TGSI_FILE_SYSTEM_VALUE =10,
    TGSI_FILE_COUNT      /**< how many TGSI_FILE_ types */
 };
 
@@ -117,8 +112,7 @@
    unsigned Semantic    : 1;  /**< BOOL, any semantic info? */
    unsigned Centroid    : 1;  /**< centroid sampling? */
    unsigned Invariant   : 1;  /**< invariant optimization? */
-   unsigned Padding     : 4;
-   unsigned Extended    : 1;  /**< BOOL */
+   unsigned Padding     : 5;
 };
 
 struct tgsi_declaration_range
@@ -127,37 +121,58 @@
    unsigned Last    : 16; /**< UINT */
 };
 
-#define TGSI_SEMANTIC_POSITION 0
-#define TGSI_SEMANTIC_COLOR    1
-#define TGSI_SEMANTIC_BCOLOR   2 /**< back-face color */
-#define TGSI_SEMANTIC_FOG      3
-#define TGSI_SEMANTIC_PSIZE    4
-#define TGSI_SEMANTIC_GENERIC  5
-#define TGSI_SEMANTIC_NORMAL   6
-#define TGSI_SEMANTIC_FACE     7
-#define TGSI_SEMANTIC_COUNT    8 /**< number of semantic values */
+#define TGSI_SEMANTIC_POSITION  0
+#define TGSI_SEMANTIC_COLOR     1
+#define TGSI_SEMANTIC_BCOLOR    2 /**< back-face color */
+#define TGSI_SEMANTIC_FOG       3
+#define TGSI_SEMANTIC_PSIZE     4
+#define TGSI_SEMANTIC_GENERIC   5
+#define TGSI_SEMANTIC_NORMAL    6
+#define TGSI_SEMANTIC_FACE      7
+#define TGSI_SEMANTIC_EDGEFLAG  8
+#define TGSI_SEMANTIC_PRIMID    9
+#define TGSI_SEMANTIC_COUNT    10 /**< number of semantic values */
 
 struct tgsi_declaration_semantic
 {
-   unsigned SemanticName   : 8;  /**< one of TGSI_SEMANTIC_x */
-   unsigned SemanticIndex  : 16; /**< UINT */
+   unsigned Name           : 8;  /**< one of TGSI_SEMANTIC_x */
+   unsigned Index          : 16; /**< UINT */
    unsigned Padding        : 8;
 };
 
 #define TGSI_IMM_FLOAT32   0
+#define TGSI_IMM_UINT32    1
+#define TGSI_IMM_INT32     2
 
 struct tgsi_immediate
 {
    unsigned Type       : 4;  /**< TGSI_TOKEN_TYPE_IMMEDIATE */
    unsigned NrTokens   : 8;  /**< UINT */
    unsigned DataType   : 4;  /**< one of TGSI_IMM_x */
-   unsigned Padding    : 15;
-   unsigned Extended   : 1;  /**< BOOL */
+   unsigned Padding    : 16;
 };
 
 union tgsi_immediate_data
 {
    float Float;
+   unsigned Uint;
+   int Int;
+};
+
+#define TGSI_PROPERTY_GS_INPUT_PRIM          0
+#define TGSI_PROPERTY_GS_OUTPUT_PRIM         1
+#define TGSI_PROPERTY_GS_MAX_VERTICES        2
+#define TGSI_PROPERTY_COUNT                  3
+
+struct tgsi_property {
+   unsigned Type         : 4;  /**< TGSI_TOKEN_TYPE_PROPERTY */
+   unsigned NrTokens     : 8;  /**< UINT */
+   unsigned PropertyName : 8;  /**< one of TGSI_PROPERTY */
+   unsigned Padding      : 12;
+};
+
+struct tgsi_property_data {
+   unsigned Data;
 };
 
 /* TGSI opcodes.  
@@ -253,7 +268,7 @@
 #define TGSI_OPCODE_NOT                 85
 #define TGSI_OPCODE_TRUNC               86
 #define TGSI_OPCODE_SHL                 87
-#define TGSI_OPCODE_SHR                 88
+                                /* gap */
 #define TGSI_OPCODE_AND                 89
 #define TGSI_OPCODE_OR                  90
 #define TGSI_OPCODE_MOD                 91
@@ -278,7 +293,33 @@
 #define TGSI_OPCODE_KIL                 116  /* conditional kill */
 #define TGSI_OPCODE_END                 117  /* aka HALT */
                                 /* gap */
-#define TGSI_OPCODE_LAST                119
+#define TGSI_OPCODE_F2I                 119
+#define TGSI_OPCODE_IDIV                120
+#define TGSI_OPCODE_IMAX                121
+#define TGSI_OPCODE_IMIN                122
+#define TGSI_OPCODE_INEG                123
+#define TGSI_OPCODE_ISGE                124
+#define TGSI_OPCODE_ISHR                125
+#define TGSI_OPCODE_ISLT                126
+#define TGSI_OPCODE_F2U                 127
+#define TGSI_OPCODE_U2F                 128
+#define TGSI_OPCODE_UADD                129
+#define TGSI_OPCODE_UDIV                130
+#define TGSI_OPCODE_UMAD                131
+#define TGSI_OPCODE_UMAX                132
+#define TGSI_OPCODE_UMIN                133
+#define TGSI_OPCODE_UMOD                134
+#define TGSI_OPCODE_UMUL                135
+#define TGSI_OPCODE_USEQ                136
+#define TGSI_OPCODE_USGE                137
+#define TGSI_OPCODE_USHR                138
+#define TGSI_OPCODE_USLT                139
+#define TGSI_OPCODE_USNE                140
+#define TGSI_OPCODE_SWITCH              141
+#define TGSI_OPCODE_CASE                142
+#define TGSI_OPCODE_DEFAULT             143
+#define TGSI_OPCODE_ENDSWITCH           144
+#define TGSI_OPCODE_LAST                145
 
 #define TGSI_SAT_NONE            0  /* do not saturate */
 #define TGSI_SAT_ZERO_ONE        1  /* clamp to [0,1] */
@@ -293,7 +334,7 @@
  * respectively. For a given operation code, those numbers are fixed and are
  * present here only for convenience.
  *
- * If Extended is TRUE, it is now executed.
+ * If Predicate is TRUE, tgsi_instruction_predicate token immediately follows.
  *
  * Saturate controls how are final results in destination registers modified.
  */
@@ -306,12 +347,16 @@
    unsigned Saturate   : 2;  /* TGSI_SAT_ */
    unsigned NumDstRegs : 2;  /* UINT */
    unsigned NumSrcRegs : 4;  /* UINT */
-   unsigned Padding    : 3;
-   unsigned Extended   : 1;  /* BOOL */
+   unsigned Predicate  : 1;  /* BOOL */
+   unsigned Label      : 1;
+   unsigned Texture    : 1;
+   unsigned Padding    : 1;
 };
 
 /*
- * If tgsi_instruction::Extended is TRUE, tgsi_instruction_ext follows.
+ * If tgsi_instruction::Label is TRUE, tgsi_instruction_label follows.
+ *
+ * If tgsi_instruction::Texture is TRUE, tgsi_instruction_texture follows.
  * 
  * Then, tgsi_instruction::NumDstRegs of tgsi_dst_register follow.
  * 
@@ -321,42 +366,15 @@
  * instruction, including the instruction word.
  */
 
-#define TGSI_INSTRUCTION_EXT_TYPE_LABEL     1
-#define TGSI_INSTRUCTION_EXT_TYPE_TEXTURE   2
-#define TGSI_INSTRUCTION_EXT_TYPE_PREDICATE 3
-
-struct tgsi_instruction_ext
-{
-   unsigned Type       : 4;  /* TGSI_INSTRUCTION_EXT_TYPE_ */
-   unsigned Padding    : 27;
-   unsigned Extended   : 1;  /* BOOL */
-};
-
-/*
- * If tgsi_instruction_ext::Type is TGSI_INSTRUCTION_EXT_TYPE_LABEL, it
- * should be cast to tgsi_instruction_ext_label.
- * 
- * If tgsi_instruction_ext::Type is TGSI_INSTRUCTION_EXT_TYPE_TEXTURE, it
- * should be cast to tgsi_instruction_ext_texture.
- * 
- * If tgsi_instruction_ext::Type is TGSI_INSTRUCTION_EXT_TYPE_PREDICATE, it
- * should be cast to tgsi_instruction_ext_predicate.
- * 
- * If tgsi_instruction_ext::Extended is TRUE, another tgsi_instruction_ext
- * follows.
- */
-
 #define TGSI_SWIZZLE_X      0
 #define TGSI_SWIZZLE_Y      1
 #define TGSI_SWIZZLE_Z      2
 #define TGSI_SWIZZLE_W      3
 
-struct tgsi_instruction_ext_label
+struct tgsi_instruction_label
 {
-   unsigned Type     : 4;    /* TGSI_INSTRUCTION_EXT_TYPE_LABEL */
    unsigned Label    : 24;   /* UINT */
-   unsigned Padding  : 3;
-   unsigned Extended : 1;    /* BOOL */
+   unsigned Padding  : 8;
 };
 
 #define TGSI_TEXTURE_UNKNOWN        0
@@ -370,29 +388,25 @@
 #define TGSI_TEXTURE_SHADOWRECT     8
 #define TGSI_TEXTURE_COUNT          9
 
-struct tgsi_instruction_ext_texture
+struct tgsi_instruction_texture
 {
-   unsigned Type     : 4;    /* TGSI_INSTRUCTION_EXT_TYPE_TEXTURE */
    unsigned Texture  : 8;    /* TGSI_TEXTURE_ */
-   unsigned Padding  : 19;
-   unsigned Extended : 1;    /* BOOL */
+   unsigned Padding  : 24;
 };
 
 /*
  * For SM3, the following constraint applies.
  *   - Swizzle is either set to identity or replicate.
  */
-struct tgsi_instruction_ext_predicate
+struct tgsi_instruction_predicate
 {
-   unsigned Type     : 4;  /* TGSI_INSTRUCTION_EXT_TYPE_PREDICATE */
+   int      Index    : 16; /* SINT */
    unsigned SwizzleX : 2;  /* TGSI_SWIZZLE_x */
    unsigned SwizzleY : 2;  /* TGSI_SWIZZLE_x */
    unsigned SwizzleZ : 2;  /* TGSI_SWIZZLE_x */
    unsigned SwizzleW : 2;  /* TGSI_SWIZZLE_x */
    unsigned Negate   : 1;  /* BOOL */
-   unsigned SrcIndex : 8;  /* UINT */
-   unsigned Padding  : 10;
-   unsigned Extended : 1;  /* BOOL */
+   unsigned Padding  : 7;
 };
 
 /**
@@ -409,26 +423,24 @@
  * The fetched register components are swizzled according to SwizzleX, SwizzleY,
  * SwizzleZ and SwizzleW.
  *
- * If Extended is TRUE, any further modifications to the source register are
- * made to this temporary storage.
  */
 
 struct tgsi_src_register
 {
    unsigned File        : 4;  /* TGSI_FILE_ */
+   unsigned Indirect    : 1;  /* BOOL */
+   unsigned Dimension   : 1;  /* BOOL */
+   int      Index       : 16; /* SINT */
    unsigned SwizzleX    : 2;  /* TGSI_SWIZZLE_ */
    unsigned SwizzleY    : 2;  /* TGSI_SWIZZLE_ */
    unsigned SwizzleZ    : 2;  /* TGSI_SWIZZLE_ */
    unsigned SwizzleW    : 2;  /* TGSI_SWIZZLE_ */
-   unsigned Negate      : 1;  /* BOOL */
-   unsigned Indirect    : 1;  /* BOOL */
-   unsigned Dimension   : 1;  /* BOOL */
-   int      Index       : 16; /* SINT */
-   unsigned Extended    : 1;  /* BOOL */
+   unsigned Absolute    : 1;    /* BOOL */
+   unsigned Negate      : 1;    /* BOOL */
 };
 
 /**
- * If tgsi_src_register::Extended is TRUE, tgsi_src_register_ext follows.
+ * If tgsi_src_register::Modifier is TRUE, tgsi_src_register_modifier follows.
  * 
  * Then, if tgsi_src_register::Indirect is TRUE, another tgsi_src_register
  * follows.
@@ -436,58 +448,13 @@
  * Then, if tgsi_src_register::Dimension is TRUE, tgsi_dimension follows.
  */
 
-#define TGSI_SRC_REGISTER_EXT_TYPE_MOD      1
-
-struct tgsi_src_register_ext
-{
-   unsigned Type     : 4;    /* TGSI_SRC_REGISTER_EXT_TYPE_ */
-   unsigned Padding  : 27;
-   unsigned Extended : 1;    /* BOOL */
-};
-
-/**
- * If tgsi_src_register_ext::Type is TGSI_SRC_REGISTER_EXT_TYPE_MOD,
- * it should be cast to tgsi_src_register_ext_mod.
- * 
- * If tgsi_dst_register_ext::Extended is TRUE, another tgsi_dst_register_ext
- * follows.
- */
-
-
-/**
- * Extra src register modifiers
- *
- * If Complement is TRUE, the source register is modified by subtracting it
- * from 1.0.
- *
- * If Bias is TRUE, the source register is modified by subtracting 0.5 from it.
- *
- * If Scale2X is TRUE, the source register is modified by multiplying it by 2.0.
- *
- * If Absolute is TRUE, the source register is modified by removing the sign.
- *
- * If Negate is TRUE, the source register is modified by negating it.
- */
-
-struct tgsi_src_register_ext_mod
-{
-   unsigned Type         : 4;    /* TGSI_SRC_REGISTER_EXT_TYPE_MOD */
-   unsigned Complement   : 1;    /* BOOL */
-   unsigned Bias         : 1;    /* BOOL */
-   unsigned Scale2X      : 1;    /* BOOL */
-   unsigned Absolute     : 1;    /* BOOL */
-   unsigned Negate       : 1;    /* BOOL */
-   unsigned Padding      : 22;
-   unsigned Extended     : 1;    /* BOOL */
-};
 
 struct tgsi_dimension
 {
    unsigned Indirect    : 1;  /* BOOL */
    unsigned Dimension   : 1;  /* BOOL */
-   unsigned Padding     : 13;
+   unsigned Padding     : 14;
    int      Index       : 16; /* SINT */
-   unsigned Extended    : 1;  /* BOOL */
 };
 
 struct tgsi_dst_register
@@ -497,51 +464,9 @@
    unsigned Indirect    : 1;  /* BOOL */
    unsigned Dimension   : 1;  /* BOOL */
    int      Index       : 16; /* SINT */
-   unsigned Padding     : 5;
-   unsigned Extended    : 1;  /* BOOL */
+   unsigned Padding     : 6;
 };
 
-/*
- * If tgsi_dst_register::Extended is TRUE, tgsi_dst_register_ext follows.
- * 
- * Then, if tgsi_dst_register::Indirect is TRUE, tgsi_src_register follows.
- */
-
-#define TGSI_DST_REGISTER_EXT_TYPE_MODULATE     1
-
-struct tgsi_dst_register_ext
-{
-   unsigned Type     : 4;    /* TGSI_DST_REGISTER_EXT_TYPE_ */
-   unsigned Padding  : 27;
-   unsigned Extended : 1;    /* BOOL */
-};
-
-/**
- * Extra destination register modifiers
- *
- * If tgsi_dst_register_ext::Type is TGSI_DST_REGISTER_EXT_TYPE_MODULATE,
- * it should be cast to tgsi_dst_register_ext_modulate.
- * 
- * If tgsi_dst_register_ext::Extended is TRUE, another tgsi_dst_register_ext
- * follows.
- */
-
-#define TGSI_MODULATE_1X        0
-#define TGSI_MODULATE_2X        1
-#define TGSI_MODULATE_4X        2
-#define TGSI_MODULATE_8X        3
-#define TGSI_MODULATE_HALF      4
-#define TGSI_MODULATE_QUARTER   5
-#define TGSI_MODULATE_EIGHTH    6
-#define TGSI_MODULATE_COUNT     7
-
-struct tgsi_dst_register_ext_modulate
-{
-   unsigned Type     : 4;    /* TGSI_DST_REGISTER_EXT_TYPE_MODULATE */
-   unsigned Modulate : 4;    /* TGSI_MODULATE_ */
-   unsigned Padding  : 23;
-   unsigned Extended : 1;    /* BOOL */
-};
 
 #ifdef __cplusplus
 }
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 287b424..60e96b9 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -60,6 +60,7 @@
 #define PIPE_MAX_COLOR_BUFS        8
 #define PIPE_MAX_CONSTANT         32
 #define PIPE_MAX_SAMPLERS         16
+#define PIPE_MAX_VERTEX_SAMPLERS  16
 #define PIPE_MAX_SHADER_INPUTS    16
 #define PIPE_MAX_SHADER_OUTPUTS   16
 #define PIPE_MAX_TEXTURE_LEVELS   16
@@ -315,14 +316,10 @@
  */
 struct pipe_transfer
 {
-   enum pipe_format format;      /**< PIPE_FORMAT_x */
    unsigned x;                   /**< x offset from start of texture image */
    unsigned y;                   /**< y offset from start of texture image */
    unsigned width;               /**< logical width in pixels */
    unsigned height;              /**< logical height in pixels */
-   struct pipe_format_block block;
-   unsigned nblocksx;            /**< allocated width in blocks */
-   unsigned nblocksy;            /**< allocated height in blocks */
    unsigned stride;              /**< stride in bytes between rows of blocks */
    enum pipe_transfer_usage usage; /**< PIPE_TRANSFER_*  */
 
@@ -343,13 +340,9 @@
    enum pipe_texture_target target; /**< PIPE_TEXTURE_x */
    enum pipe_format format;         /**< PIPE_FORMAT_x */
 
-   unsigned width[PIPE_MAX_TEXTURE_LEVELS];
-   unsigned height[PIPE_MAX_TEXTURE_LEVELS];
-   unsigned depth[PIPE_MAX_TEXTURE_LEVELS];
-
-   struct pipe_format_block block;
-   unsigned nblocksx[PIPE_MAX_TEXTURE_LEVELS]; /**< allocated width in blocks */
-   unsigned nblocksy[PIPE_MAX_TEXTURE_LEVELS]; /**< allocated height in blocks */
+   unsigned width0;
+   unsigned height0;
+   unsigned depth0;
 
    unsigned last_level:8;    /**< Index of last mipmap level present/defined */
 
@@ -399,8 +392,9 @@
 {
    struct pipe_buffer *old_buf = *ptr;
 
-   if (pipe_reference((struct pipe_reference **)ptr, &buf->reference))
+   if (pipe_reference(&(*ptr)->reference, &buf->reference))
       old_buf->screen->buffer_destroy(old_buf);
+   *ptr = buf;
 }
 
 static INLINE void
@@ -408,8 +402,9 @@
 {
    struct pipe_surface *old_surf = *ptr;
 
-   if (pipe_reference((struct pipe_reference **)ptr, &surf->reference))
+   if (pipe_reference(&(*ptr)->reference, &surf->reference))
       old_surf->texture->screen->tex_surface_destroy(old_surf);
+   *ptr = surf;
 }
 
 static INLINE void
@@ -417,8 +412,9 @@
 {
    struct pipe_texture *old_tex = *ptr;
 
-   if (pipe_reference((struct pipe_reference **)ptr, &tex->reference))
+   if (pipe_reference(&(*ptr)->reference, &tex->reference))
       old_tex->screen->texture_destroy(old_tex);
+   *ptr = tex;
 }
 
 
diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h
index 4da26d6..b85f01c 100644
--- a/src/gallium/include/pipe/p_video_state.h
+++ b/src/gallium/include/pipe/p_video_state.h
@@ -56,8 +56,9 @@
 {
    struct pipe_video_surface *old_surf = *ptr;
 
-   if (pipe_reference((struct pipe_reference **)ptr, &surf->reference))
+   if (pipe_reference(&(*ptr)->reference, &surf->reference))
       old_surf->screen->video_surface_destroy(old_surf);
+   *ptr = surf;
 }
 
 struct pipe_video_rect
diff --git a/src/gallium/include/state_tracker/drm_api.h b/src/gallium/include/state_tracker/drm_api.h
index 4d1259e..bb92892 100644
--- a/src/gallium/include/state_tracker/drm_api.h
+++ b/src/gallium/include/state_tracker/drm_api.h
@@ -28,6 +28,8 @@
 
 struct drm_api
 {
+        const char *name;
+
 	/**
 	 * Special buffer functions
 	 */
diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c
index 8819936..f2e5f3f 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/dri_context.c
@@ -44,9 +44,9 @@
 
 GLboolean
 dri_create_context(const __GLcontextModes * visual,
-		   __DRIcontextPrivate * cPriv, void *sharedContextPrivate)
+		   __DRIcontext * cPriv, void *sharedContextPrivate)
 {
-   __DRIscreenPrivate *sPriv = cPriv->driScreenPriv;
+   __DRIscreen *sPriv = cPriv->driScreenPriv;
    struct dri_screen *screen = dri_screen(sPriv);
    struct dri_context *ctx = NULL;
    struct st_context *st_share = NULL;
@@ -97,7 +97,7 @@
 }
 
 void
-dri_destroy_context(__DRIcontextPrivate * cPriv)
+dri_destroy_context(__DRIcontext * cPriv)
 {
    struct dri_context *ctx = dri_context(cPriv);
 
@@ -116,7 +116,7 @@
 }
 
 GLboolean
-dri_unbind_context(__DRIcontextPrivate * cPriv)
+dri_unbind_context(__DRIcontext * cPriv)
 {
    if (cPriv) {
       struct dri_context *ctx = dri_context(cPriv);
@@ -133,9 +133,9 @@
 }
 
 GLboolean
-dri_make_current(__DRIcontextPrivate * cPriv,
-		 __DRIdrawablePrivate * driDrawPriv,
-		 __DRIdrawablePrivate * driReadPriv)
+dri_make_current(__DRIcontext * cPriv,
+		 __DRIdrawable * driDrawPriv,
+		 __DRIdrawable * driReadPriv)
 {
    if (cPriv) {
       struct dri_context *ctx = dri_context(cPriv);
diff --git a/src/gallium/state_trackers/dri/dri_context.h b/src/gallium/state_trackers/dri/dri_context.h
index 4650178..13f4974 100644
--- a/src/gallium/state_trackers/dri/dri_context.h
+++ b/src/gallium/state_trackers/dri/dri_context.h
@@ -44,10 +44,10 @@
 struct dri_context
 {
    /* dri */
-   __DRIscreenPrivate *sPriv;
-   __DRIcontextPrivate *cPriv;
-   __DRIdrawablePrivate *dPriv;
-   __DRIdrawablePrivate *rPriv;
+   __DRIscreen *sPriv;
+   __DRIcontext *cPriv;
+   __DRIdrawable *dPriv;
+   __DRIdrawable *rPriv;
 
    driOptionCache optionCache;
 
@@ -67,7 +67,7 @@
 };
 
 static INLINE struct dri_context *
-dri_context(__DRIcontextPrivate * driContextPriv)
+dri_context(__DRIcontext * driContextPriv)
 {
    return (struct dri_context *)driContextPriv->driverPrivate;
 }
@@ -99,18 +99,18 @@
  */
 extern struct dri1_api_lock_funcs dri1_lf;
 
-void dri_destroy_context(__DRIcontextPrivate * driContextPriv);
+void dri_destroy_context(__DRIcontext * driContextPriv);
 
-boolean dri_unbind_context(__DRIcontextPrivate * driContextPriv);
+boolean dri_unbind_context(__DRIcontext * driContextPriv);
 
 boolean
-dri_make_current(__DRIcontextPrivate * driContextPriv,
-		 __DRIdrawablePrivate * driDrawPriv,
-		 __DRIdrawablePrivate * driReadPriv);
+dri_make_current(__DRIcontext * driContextPriv,
+		 __DRIdrawable * driDrawPriv,
+		 __DRIdrawable * driReadPriv);
 
 boolean
 dri_create_context(const __GLcontextModes * visual,
-		   __DRIcontextPrivate * driContextPriv,
+		   __DRIcontext * driContextPriv,
 		   void *sharedContextPrivate);
 
 /***********************************************************************
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index 5625ff5..f131e77 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -44,9 +44,10 @@
 #include "state_tracker/st_context.h"
 #include "state_tracker/st_cb_fbo.h"
 
+#include "util/u_format.h"
 #include "util/u_memory.h"
 #include "util/u_rect.h"
-
+ 
 static struct pipe_surface *
 dri_surface_from_handle(struct drm_api *api,
 			struct pipe_screen *screen,
@@ -62,11 +63,10 @@
    templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
    templat.target = PIPE_TEXTURE_2D;
    templat.last_level = 0;
-   templat.depth[0] = 1;
+   templat.depth0 = 1;
    templat.format = format;
-   templat.width[0] = width;
-   templat.height[0] = height;
-   pf_get_block(templat.format, &templat.block);
+   templat.width0 = width;
+   templat.height0 = height;
 
    texture = api->texture_from_shared_handle(api, screen, &templat,
                                              "dri2 buffer", pitch, handle);
@@ -118,7 +118,7 @@
  * This will be called a drawable is known to have been resized.
  */
 void
-dri_get_buffers(__DRIdrawablePrivate * dPriv)
+dri_get_buffers(__DRIdrawable * dPriv)
 {
 
    struct dri_drawable *drawable = dri_drawable(dPriv);
@@ -268,6 +268,14 @@
 }
 
 void
+dri_update_buffer(struct pipe_screen *screen, void *context_private)
+{
+   struct dri_context *ctx = (struct dri_context *)context_private;
+
+   dri_get_buffers(ctx->dPriv);
+}
+
+void
 dri_flush_frontbuffer(struct pipe_screen *screen,
 		      struct pipe_surface *surf, void *context_private)
 {
@@ -299,8 +307,8 @@
  * This is called when we need to set up GL rendering to a new X window.
  */
 boolean
-dri_create_buffer(__DRIscreenPrivate * sPriv,
-		  __DRIdrawablePrivate * dPriv,
+dri_create_buffer(__DRIscreen * sPriv,
+		  __DRIdrawable * dPriv,
 		  const __GLcontextModes * visual, boolean isPixmap)
 {
    struct dri_screen *screen = sPriv->private;
@@ -416,7 +424,7 @@
 }
 
 void
-dri_destroy_buffer(__DRIdrawablePrivate * dPriv)
+dri_destroy_buffer(__DRIdrawable * dPriv)
 {
    struct dri_drawable *drawable = dri_drawable(dPriv);
    struct pipe_fence_handle *fence;
@@ -434,8 +442,8 @@
 
 static void
 dri1_update_drawables_locked(struct dri_context *ctx,
-			     __DRIdrawablePrivate * driDrawPriv,
-			     __DRIdrawablePrivate * driReadPriv)
+			     __DRIdrawable * driDrawPriv,
+			     __DRIdrawable * driReadPriv)
 {
    if (ctx->stLostLock) {
       ctx->stLostLock = FALSE;
@@ -458,8 +466,8 @@
 static void
 dri1_propagate_drawable_change(struct dri_context *ctx)
 {
-   __DRIdrawablePrivate *dPriv = ctx->dPriv;
-   __DRIdrawablePrivate *rPriv = ctx->rPriv;
+   __DRIdrawable *dPriv = ctx->dPriv;
+   __DRIdrawable *rPriv = ctx->rPriv;
    boolean flushed = FALSE;
 
    if (dPriv && ctx->d_stamp != dPriv->lastStamp) {
@@ -532,7 +540,7 @@
 dri1_swap_copy(struct dri_context *ctx,
 	       struct pipe_surface *dst,
 	       struct pipe_surface *src,
-	       __DRIdrawablePrivate * dPriv, const struct drm_clip_rect *bbox)
+	       __DRIdrawable * dPriv, const struct drm_clip_rect *bbox)
 {
    struct pipe_context *pipe = ctx->pipe;
    struct drm_clip_rect clip;
@@ -563,7 +571,7 @@
 static void
 dri1_copy_to_front(struct dri_context *ctx,
 		   struct pipe_surface *surf,
-		   __DRIdrawablePrivate * dPriv,
+		   __DRIdrawable * dPriv,
 		   const struct drm_clip_rect *sub_box,
 		   struct pipe_fence_handle **fence)
 {
@@ -636,7 +644,7 @@
 }
 
 void
-dri_swap_buffers(__DRIdrawablePrivate * dPriv)
+dri_swap_buffers(__DRIdrawable * dPriv)
 {
    struct dri_context *ctx;
    struct pipe_surface *back_surf;
@@ -668,7 +676,7 @@
 }
 
 void
-dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
+dri_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h)
 {
    struct pipe_screen *screen = dri_screen(dPriv->driScreenPriv)->pipe_screen;
    struct drm_clip_rect sub_bbox;
diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h
index b910930..8bc59cb 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.h
+++ b/src/gallium/state_trackers/dri/dri_drawable.h
@@ -41,8 +41,8 @@
 struct dri_drawable
 {
    /* dri */
-   __DRIdrawablePrivate *dPriv;
-   __DRIscreenPrivate *sPriv;
+   __DRIdrawable *dPriv;
+   __DRIscreen *sPriv;
 
    unsigned attachments[8];
    unsigned num_attachments;
@@ -67,7 +67,7 @@
 };
 
 static INLINE struct dri_drawable *
-dri_drawable(__DRIdrawablePrivate * driDrawPriv)
+dri_drawable(__DRIdrawable * driDrawPriv)
 {
    return (struct dri_drawable *)driDrawPriv->driverPrivate;
 }
@@ -76,22 +76,25 @@
  * dri_drawable.c
  */
 boolean
-dri_create_buffer(__DRIscreenPrivate * sPriv,
-		  __DRIdrawablePrivate * dPriv,
+dri_create_buffer(__DRIscreen * sPriv,
+		  __DRIdrawable * dPriv,
 		  const __GLcontextModes * visual, boolean isPixmap);
 
 void
+dri_update_buffer(struct pipe_screen *screen, void *context_private);
+
+void
 dri_flush_frontbuffer(struct pipe_screen *screen,
 		      struct pipe_surface *surf, void *context_private);
 
-void dri_swap_buffers(__DRIdrawablePrivate * dPriv);
+void dri_swap_buffers(__DRIdrawable * dPriv);
 
 void
-dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h);
+dri_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h);
 
-void dri_get_buffers(__DRIdrawablePrivate * dPriv);
+void dri_get_buffers(__DRIdrawable * dPriv);
 
-void dri_destroy_buffer(__DRIdrawablePrivate * dPriv);
+void dri_destroy_buffer(__DRIdrawable * dPriv);
 
 void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
                           GLint glx_texture_format, __DRIdrawable *dPriv);
diff --git a/src/gallium/state_trackers/dri/dri_extensions.c b/src/gallium/state_trackers/dri/dri_extensions.c
index 78c4cd8..8b014a2 100644
--- a/src/gallium/state_trackers/dri/dri_extensions.c
+++ b/src/gallium/state_trackers/dri/dri_extensions.c
@@ -55,6 +55,7 @@
 #define need_GL_EXT_multi_draw_arrays
 #define need_GL_EXT_provoking_vertex
 #define need_GL_EXT_secondary_color
+#define need_GL_EXT_stencil_two_side
 #define need_GL_APPLE_vertex_array_object
 #define need_GL_NV_vertex_program
 #define need_GL_VERSION_2_0
@@ -84,6 +85,7 @@
    {"GL_ARB_texture_env_combine", NULL},
    {"GL_ARB_texture_env_dot3", NULL},
    {"GL_ARB_texture_mirrored_repeat", NULL},
+   {"GL_ARB_texture_non_power_of_two", NULL},
    {"GL_ARB_texture_rectangle", NULL},
    {"GL_ARB_vertex_array_object", GL_ARB_vertex_array_object_functions},
    {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
@@ -103,6 +105,7 @@
    {"GL_EXT_pixel_buffer_object", NULL},
    {"GL_EXT_provoking_vertex", GL_EXT_provoking_vertex_functions},
    {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
+   {"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions},
    {"GL_EXT_stencil_wrap", NULL},
    {"GL_EXT_texture_edge_clamp", NULL},
    {"GL_EXT_texture_env_combine", NULL},
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index cb864d4..793db08 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -202,7 +202,7 @@
  * Get information about previous buffer swaps.
  */
 static int
-dri_get_swap_info(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo)
+dri_get_swap_info(__DRIdrawable * dPriv, __DRIswapInfo * sInfo)
 {
    if (dPriv == NULL || dPriv->driverPrivate == NULL || sInfo == NULL)
       return -1;
@@ -220,7 +220,7 @@
 }
 
 static const __DRIconfig **
-dri_init_screen(__DRIscreenPrivate * sPriv)
+dri_init_screen(__DRIscreen * sPriv)
 {
    struct dri_screen *screen;
    const __DRIconfig **configs;
@@ -285,7 +285,7 @@
  * Returns the __GLcontextModes supported by this driver.
  */
 static const __DRIconfig **
-dri_init_screen2(__DRIscreenPrivate * sPriv)
+dri_init_screen2(__DRIscreen * sPriv)
 {
    struct dri_screen *screen;
    struct drm_create_screen_arg arg;
@@ -308,6 +308,7 @@
    }
 
    /* We need to hook in here */
+   screen->pipe_screen->update_buffer = dri_update_buffer;
    screen->pipe_screen->flush_frontbuffer = dri_flush_frontbuffer;
 
    driParseOptionInfo(&screen->optionCache,
@@ -319,7 +320,7 @@
 }
 
 static void
-dri_destroy_screen(__DRIscreenPrivate * sPriv)
+dri_destroy_screen(__DRIscreen * sPriv)
 {
    struct dri_screen *screen = dri_screen(sPriv);
 
@@ -346,4 +347,12 @@
    .InitScreen2 = dri_init_screen2,
 };
 
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driLegacyExtension.base,
+    &driDRI2Extension.base,
+    NULL
+};
+
 /* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h
index f6c56d0..03387a0 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/dri_screen.h
@@ -42,7 +42,7 @@
 struct dri_screen
 {
    /* dri */
-   __DRIscreenPrivate *sPriv;
+   __DRIscreen *sPriv;
 
    /**
     * Configuration cache with default values for all contexts
@@ -63,7 +63,7 @@
 
 /** cast wrapper */
 static INLINE struct dri_screen *
-dri_screen(__DRIscreenPrivate * sPriv)
+dri_screen(__DRIscreen * sPriv)
 {
    return (struct dri_screen *)sPriv->private;
 }
diff --git a/src/gallium/state_trackers/egl/egl_surface.c b/src/gallium/state_trackers/egl/egl_surface.c
index 71c0137..d55aa51 100644
--- a/src/gallium/state_trackers/egl/egl_surface.c
+++ b/src/gallium/state_trackers/egl/egl_surface.c
@@ -12,6 +12,7 @@
 
 #include "state_tracker/drm_api.h"
 
+#include "util/u_format.h"
 #include "util/u_rect.h"
 
 /*
@@ -35,34 +36,62 @@
 }
 
 static struct st_framebuffer *
-drm_create_framebuffer(const __GLcontextModes *visual,
+drm_create_framebuffer(struct pipe_screen *screen,
+                       const __GLcontextModes *visual,
                        unsigned width,
                        unsigned height,
                        void *priv)
 {
-	enum pipe_format colorFormat, depthFormat, stencilFormat;
+	enum pipe_format color_format, depth_stencil_format;
+	boolean d_depth_bits_last;
+	boolean ds_depth_bits_last;
 
-	if (visual->redBits == 5)
-		colorFormat = PIPE_FORMAT_R5G6B5_UNORM;
-	else
-		colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
+	d_depth_bits_last =
+		screen->is_format_supported(screen, PIPE_FORMAT_X8Z24_UNORM,
+		                            PIPE_TEXTURE_2D,
+		                            PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+	ds_depth_bits_last =
+		screen->is_format_supported(screen, PIPE_FORMAT_S8Z24_UNORM,
+		                            PIPE_TEXTURE_2D,
+		                            PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
 
-	if (visual->depthBits == 16)
-		depthFormat = PIPE_FORMAT_Z16_UNORM;
-	else if (visual->depthBits == 24)
-		depthFormat = PIPE_FORMAT_S8Z24_UNORM;
-	else
-		depthFormat = PIPE_FORMAT_NONE;
+	if (visual->redBits == 8) {
+		if (visual->alphaBits == 8)
+			color_format = PIPE_FORMAT_A8R8G8B8_UNORM;
+		else
+			color_format = PIPE_FORMAT_X8R8G8B8_UNORM;
+	} else {
+		color_format = PIPE_FORMAT_R5G6B5_UNORM;
+	}
 
-	if (visual->stencilBits == 8)
-		stencilFormat = PIPE_FORMAT_S8Z24_UNORM;
-	else
-		stencilFormat = PIPE_FORMAT_NONE;
+	switch(visual->depthBits) {
+		default:
+		case 0:
+			depth_stencil_format = PIPE_FORMAT_NONE;
+			break;
+		case 16:
+			depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
+			break;
+		case 24:
+			if (visual->stencilBits == 0) {
+				depth_stencil_format = (d_depth_bits_last) ?
+					PIPE_FORMAT_X8Z24_UNORM:
+					PIPE_FORMAT_Z24X8_UNORM;
+			} else {
+				depth_stencil_format = (ds_depth_bits_last) ?
+					PIPE_FORMAT_S8Z24_UNORM:
+					PIPE_FORMAT_Z24S8_UNORM;
+			}
+			break;
+		case 32:
+			depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
+			break;
+	}
 
 	return st_create_framebuffer(visual,
-	                             colorFormat,
-	                             depthFormat,
-	                             stencilFormat,
+	                             color_format,
+	                             depth_stencil_format,
+	                             depth_stencil_format,
 	                             width,
 	                             height,
 	                             priv);
@@ -86,11 +115,10 @@
 	templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
 	templat.target = PIPE_TEXTURE_2D;
 	templat.last_level = 0;
-	templat.depth[0] = 1;
+	templat.depth0 = 1;
 	templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
-	templat.width[0] = w;
-	templat.height[0] = h;
-	pf_get_block(templat.format, &templat.block);
+	templat.width0 = w;
+	templat.height0 = h;
 
 	texture = screen->texture_create(dev->screen,
 	                                 &templat);
@@ -143,9 +171,9 @@
 	drmModeSetCrtc(
 		dev->drmFD,
 		screen->crtcID,
-		0, // FD
+		0, /* FD */
 		0, 0,
-		NULL, 0, // List of output ids
+		NULL, 0, /* List of output ids */
 		NULL);
 
 	drmModeRmFB(dev->drmFD, screen->fbID);
@@ -158,6 +186,9 @@
 	screen->shown = 0;
 }
 
+/**
+ * Called by libEGL's eglCreateWindowSurface().
+ */
 _EGLSurface *
 drm_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list)
 {
@@ -165,6 +196,9 @@
 }
 
 
+/**
+ * Called by libEGL's eglCreatePixmapSurface().
+ */
 _EGLSurface *
 drm_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list)
 {
@@ -172,10 +206,14 @@
 }
 
 
+/**
+ * Called by libEGL's eglCreatePbufferSurface().
+ */
 _EGLSurface *
 drm_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
                            const EGLint *attrib_list)
 {
+	struct drm_device *dev = lookup_drm_device(dpy);
 	int i;
 	int width = -1;
 	int height = -1;
@@ -212,9 +250,8 @@
 	surf->h = height;
 
 	visual = drm_visual_from_config(conf);
-	surf->stfb = drm_create_framebuffer(visual,
-	                                    width,
-	                                    height,
+	surf->stfb = drm_create_framebuffer(dev->screen, visual,
+	                                    width, height,
 	                                    (void*)surf);
 	drm_visual_modes_destroy(visual);
 
@@ -226,6 +263,9 @@
 	return NULL;
 }
 
+/**
+ * Called by libEGL's eglCreateScreenSurfaceMESA().
+ */
 _EGLSurface *
 drm_create_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *cfg,
                                const EGLint *attrib_list)
@@ -235,6 +275,9 @@
 	return surf;
 }
 
+/**
+ * Called by libEGL's eglShowScreenSurfaceMESA().
+ */
 EGLBoolean
 drm_show_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy,
                              _EGLScreen *screen,
@@ -331,6 +374,9 @@
 	return EGL_FALSE;
 }
 
+/**
+ * Called by libEGL's eglDestroySurface().
+ */
 EGLBoolean
 drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
 {
@@ -344,6 +390,9 @@
 	return EGL_TRUE;
 }
 
+/**
+ * Called by libEGL's eglSwapBuffers().
+ */
 EGLBoolean
 drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw)
 {
diff --git a/src/gallium/state_trackers/egl/egl_tracker.c b/src/gallium/state_trackers/egl/egl_tracker.c
index 1ad0097..11583ec 100644
--- a/src/gallium/state_trackers/egl/egl_tracker.c
+++ b/src/gallium/state_trackers/egl/egl_tracker.c
@@ -22,6 +22,8 @@
  * Exported functions
  */
 
+/** Called by libEGL just prior to unloading/closing the driver.
+ */
 static void
 drm_unload(_EGLDriver *drv)
 {
@@ -31,6 +33,8 @@
 /**
  * The bootstrap function.  Return a new drm_driver object and
  * plug in API functions.
+ * libEGL finds this function with dlopen()/dlsym() and calls it from
+ * "load driver" function.
  */
 _EGLDriver *
 _eglMain(const char *args)
@@ -84,11 +88,11 @@
 	}
 
 	ret = fgets(path, sizeof( path ), file);
+	fclose(file);
 	if (!ret)
 		return;
 
 	sscanf(path, "%x", &device->deviceID);
-	fclose(file);
 }
 
 static void
@@ -148,6 +152,7 @@
 	int num_screens = 0;
 	EGLint i;
 	int fd;
+	_EGLConfig *config;
 
 	dev = (struct drm_device *) calloc(1, sizeof(struct drm_device));
 	if (!dev)
@@ -200,7 +205,7 @@
 	disp->DriverData = dev;
 
 	/* for now we only have one config */
-	_EGLConfig *config = calloc(1, sizeof(*config));
+	config = calloc(1, sizeof(*config));
 	memset(config, 1, sizeof(*config));
 	_eglInitConfig(config, 1);
 	_eglSetConfigAttrib(config, EGL_RED_SIZE, 8);
diff --git a/src/gallium/state_trackers/egl_g3d/Makefile b/src/gallium/state_trackers/egl_g3d/Makefile
new file mode 100644
index 0000000..213eb3e
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/Makefile
@@ -0,0 +1,72 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+common_INCLUDES = \
+	-I. \
+	-I$(TOP)/src/gallium/include \
+	-I$(TOP)/src/gallium/auxiliary \
+	-I$(TOP)/src/egl/main \
+	-I$(TOP)/include
+
+common_SOURCES = $(wildcard common/*.c)
+common_OBJECTS = $(common_SOURCES:.c=.o)
+
+
+x11_INCLUDES = \
+	-I$(TOP)/src/gallium/drivers \
+	-I$(TOP)/src/glx/x11 \
+	-I$(TOP)/src/mesa \
+	$(shell pkg-config --cflags-only-I libdrm)
+
+x11_SOURCES = $(wildcard x11/*.c) $(TOP)/src/glx/x11/dri2.c
+x11_OBJECTS = $(x11_SOURCES:.c=.o)
+
+
+kms_INCLUDES = $(shell pkg-config --cflags-only-I libdrm)
+kms_SOURCES = $(wildcard kms/*.c)
+kms_OBJECTS = $(kms_SOURCES:.c=.o)
+
+
+ALL_INCLUDES = $(common_INCLUDES) $(x11_INCLUDES) $(kms_INCLUDES)
+ALL_SOURCES = $(common_SOURCES) $(x11_SOURCES) $(kms_SOURCES)
+ALL_OBJECTS = $(common_OBJECTS) $(x11_OBJECTS) $(kms_OBJECTS)
+
+##### TARGETS #####
+
+EGL_DISPLAYS_MODS = $(foreach dpy, $(EGL_DISPLAYS), libegl$(dpy).a)
+
+default: depend $(EGL_DISPLAYS_MODS)
+
+
+libeglx11.a: $(x11_OBJECTS) $(common_OBJECTS) Makefile
+	$(MKLIB) -o eglx11 -static $(x11_OBJECTS) $(common_OBJECTS)
+
+libeglkms.a: $(kms_OBJECTS) $(common_OBJECTS) Makefile
+	$(MKLIB) -o eglkms -static $(kms_OBJECTS) $(common_OBJECTS)
+
+depend: 
+	rm -f depend
+	touch depend
+	$(MKDEP) $(MKDEP_OPTIONS) $(ALL_INCLUDES) $(ALL_SOURCES) 2> /dev/null
+
+clean:
+	rm -f $(ALL_OBJECTS)
+	rm -f $(EGL_DISPLAYS_MODS)
+	rm -f depend depend.bak
+
+# Dummy target
+install:
+	@echo -n ""
+
+##### RULES #####
+
+$(common_OBJECTS): %.o: %.c
+	$(CC) -c $(common_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
+
+$(x11_OBJECTS): %.o: %.c
+	$(CC) -c $(common_INCLUDES) $(x11_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
+
+$(kms_OBJECTS): %.o: %.c
+	$(CC) -c $(common_INCLUDES) $(kms_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
+
+sinclude depend
diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c
new file mode 100644
index 0000000..8b2e3b5
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c
@@ -0,0 +1,1109 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL 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 <assert.h>
+#include <string.h>
+#include "util/u_memory.h"
+#include "egldriver.h"
+#include "eglcurrent.h"
+#include "eglconfigutil.h"
+#include "egllog.h"
+
+#include "native.h"
+#include "egl_g3d.h"
+#include "egl_st.h"
+
+/**
+ * Validate the draw/read surfaces of the context.
+ */
+static void
+egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx)
+{
+   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+   struct pipe_screen *screen = gdpy->native->screen;
+   struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+   EGLint num_surfaces;
+   EGLint s, i;
+
+   /* validate draw and/or read buffers */
+   num_surfaces = (gctx->base.ReadSurface == gctx->base.DrawSurface) ? 1 : 2;
+   for (s = 0; s < num_surfaces; s++) {
+      struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
+      struct egl_g3d_surface *gsurf;
+      struct egl_g3d_buffer *gbuf;
+
+      if (s == 0) {
+         gsurf = egl_g3d_surface(gctx->base.DrawSurface);
+         gbuf = &gctx->draw;
+      }
+      else {
+         gsurf = egl_g3d_surface(gctx->base.ReadSurface);
+         gbuf = &gctx->read;
+      }
+
+      if (!gctx->force_validate) {
+         EGLint cur_w, cur_h;
+
+         cur_w = gsurf->base.Width;
+         cur_h = gsurf->base.Height;
+         gsurf->native->validate(gsurf->native,
+               gbuf->native_atts, gbuf->num_atts,
+               NULL,
+               &gsurf->base.Width, &gsurf->base.Height);
+         /* validate only when the geometry changed */
+         if (gsurf->base.Width == cur_w && gsurf->base.Height == cur_h)
+            continue;
+      }
+
+      gsurf->native->validate(gsurf->native,
+            gbuf->native_atts, gbuf->num_atts,
+            (struct pipe_texture **) textures,
+            &gsurf->base.Width, &gsurf->base.Height);
+      for (i = 0; i < gbuf->num_atts; i++) {
+         struct pipe_texture *pt = textures[i];
+         struct pipe_surface *ps;
+
+         if (pt) {
+            ps = screen->get_tex_surface(screen, pt, 0, 0, 0,
+                  PIPE_BUFFER_USAGE_GPU_READ |
+                  PIPE_BUFFER_USAGE_GPU_WRITE);
+            gctx->stapi->st_set_framebuffer_surface(gbuf->st_fb,
+                  gbuf->st_atts[i], ps);
+
+            if (gbuf->native_atts[i] == gsurf->render_att)
+               pipe_surface_reference(&gsurf->render_surface, ps);
+
+            pipe_surface_reference(&ps, NULL);
+            pipe_texture_reference(&pt, NULL);
+         }
+      }
+
+      gctx->stapi->st_resize_framebuffer(gbuf->st_fb,
+            gsurf->base.Width, gsurf->base.Height);
+   }
+
+   gctx->force_validate = EGL_FALSE;
+
+}
+
+/**
+ * Create a st_framebuffer.
+ */
+static struct st_framebuffer *
+create_framebuffer(_EGLContext *ctx, _EGLSurface *surf)
+{
+   struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+   struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config);
+
+   return gctx->stapi->st_create_framebuffer(&gconf->native->mode,
+         gconf->native->color_format, gconf->native->depth_format,
+         gconf->native->stencil_format,
+         gsurf->base.Width, gsurf->base.Height, &gsurf->base);
+}
+
+/**
+ * Update the attachments of draw/read surfaces.
+ */
+static void
+egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx)
+{
+   struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+   const uint st_att_map[NUM_NATIVE_ATTACHMENTS] = {
+      ST_SURFACE_FRONT_LEFT,
+      ST_SURFACE_BACK_LEFT,
+      ST_SURFACE_FRONT_RIGHT,
+      ST_SURFACE_BACK_RIGHT,
+   };
+   EGLint s, i;
+
+   /* route draw and read buffers' attachments */
+   for (s = 0; s < 2; s++) {
+      struct egl_g3d_surface *gsurf;
+      struct egl_g3d_buffer *gbuf;
+
+      if (s == 0) {
+         gsurf = egl_g3d_surface(gctx->base.DrawSurface);
+         gbuf = &gctx->draw;
+      }
+      else {
+         gsurf = egl_g3d_surface(gctx->base.ReadSurface);
+         gbuf = &gctx->read;
+      }
+
+      gbuf->native_atts[0] = gsurf->render_att;
+      gbuf->num_atts = 1;
+
+      for (i = 0; i < gbuf->num_atts; i++)
+         gbuf->st_atts[i] = st_att_map[gbuf->native_atts[i]];
+
+      /* FIXME OpenGL defaults to draw the front or back buffer when the
+       * context is single-buffered or double-buffered respectively.  In EGL,
+       * however, the buffer to be drawn is determined by the surface, instead
+       * of the context.  As a result, rendering to a pixmap surface with a
+       * double-buffered context does not work as expected.
+       *
+       * gctx->stapi->st_draw_front_buffer(gctx->st_ctx, natt ==
+       *    NATIVE_ATTACHMENT_FRONT_LEFT);
+       */
+
+      /*
+       * FIXME If the back buffer is asked for here, and the front buffer is
+       * later needed by the client API (e.g. glDrawBuffer is called to draw
+       * the front buffer), it will create a new pipe texture and draw there.
+       * One fix is to ask for both buffers here, but it would be a waste if
+       * the front buffer is never used.  A better fix is to add a callback to
+       * the pipe screen with context private (just like flush_frontbuffer).
+       */
+   }
+}
+
+/**
+ * Reallocate the context's framebuffers after draw/read surfaces change.
+ */
+static EGLBoolean
+egl_g3d_realloc_context(_EGLDisplay *dpy, _EGLContext *ctx)
+{
+   struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+   struct egl_g3d_surface *gdraw = egl_g3d_surface(gctx->base.DrawSurface);
+   struct egl_g3d_surface *gread = egl_g3d_surface(gctx->base.ReadSurface);
+
+   /* unreference the old framebuffers */
+   if (gctx->draw.st_fb) {
+      EGLBoolean is_equal = (gctx->draw.st_fb == gctx->read.st_fb);
+      void *priv;
+
+      priv = gctx->stapi->st_framebuffer_private(gctx->draw.st_fb);
+      if (!gdraw || priv != (void *) &gdraw->base) {
+         gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb);
+         gctx->draw.st_fb = NULL;
+         gctx->draw.num_atts = 0;
+      }
+
+      if (is_equal) {
+         gctx->read.st_fb = NULL;
+         gctx->draw.num_atts = 0;
+      }
+      else {
+         priv = gctx->stapi->st_framebuffer_private(gctx->read.st_fb);
+         if (!gread || priv != (void *) &gread->base) {
+            gctx->stapi->st_unreference_framebuffer(gctx->read.st_fb);
+            gctx->read.st_fb = NULL;
+            gctx->draw.num_atts = 0;
+         }
+      }
+   }
+
+   if (!gdraw)
+      return EGL_TRUE;
+
+   /* create the draw fb */
+   if (!gctx->draw.st_fb) {
+      gctx->draw.st_fb = create_framebuffer(&gctx->base, &gdraw->base);
+      if (!gctx->draw.st_fb)
+         return EGL_FALSE;
+   }
+
+   /* create the read fb */
+   if (!gctx->read.st_fb) {
+      if (gread != gdraw) {
+         gctx->read.st_fb = create_framebuffer(&gctx->base, &gread->base);
+         if (!gctx->read.st_fb) {
+            gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb);
+            gctx->draw.st_fb = NULL;
+            return EGL_FALSE;
+         }
+      }
+      else {
+         /* there is no st_reference_framebuffer... */
+         gctx->read.st_fb = gctx->draw.st_fb;
+      }
+   }
+
+   egl_g3d_route_context(dpy, &gctx->base);
+   gctx->force_validate = EGL_TRUE;
+
+   return EGL_TRUE;
+}
+
+/**
+ * Return the current context of the given API.
+ */
+static struct egl_g3d_context *
+egl_g3d_get_current_context(EGLint api)
+{
+   _EGLThreadInfo *t = _eglGetCurrentThread();
+   EGLint api_index = _eglConvertApiToIndex(api);
+   return egl_g3d_context(t->CurrentContexts[api_index]);
+}
+
+/**
+ * Return the state tracker for the given context.
+ */
+static const struct egl_g3d_st *
+egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
+{
+   struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+   const struct egl_g3d_st *stapi;
+   EGLint idx = -1;
+
+   switch (ctx->ClientAPI) {
+   case EGL_OPENGL_ES_API:
+      switch (ctx->ClientVersion) {
+      case 1:
+         idx = EGL_G3D_ST_OPENGL_ES;
+         break;
+      case 2:
+         idx = EGL_G3D_ST_OPENGL_ES2;
+         break;
+      default:
+         _eglLog(_EGL_WARNING, "unknown client version %d",
+               ctx->ClientVersion);
+         break;
+      }
+      break;
+   case EGL_OPENVG_API:
+      idx = EGL_G3D_ST_OPENVG;
+      break;
+   case EGL_OPENGL_API:
+      idx = EGL_G3D_ST_OPENGL;
+      break;
+   default:
+      _eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI);
+      break;
+   }
+
+   stapi = (idx >= 0) ? gdrv->stapis[idx] : NULL;
+   return stapi;
+}
+
+/**
+ * Return an API mask that consists of the state trackers that supports the
+ * given mode.
+ *
+ * FIXME add st_is_mode_supported()?
+ */
+static EGLint
+get_mode_api_mask(const __GLcontextModes *mode, EGLint api_mask)
+{
+   EGLint check;
+
+   /* OpenGL ES 1.x and 2.x are checked together */
+   check = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT;
+   if (api_mask & check) {
+      /* this is required by EGL, not by OpenGL ES */
+      if (mode->drawableType & GLX_WINDOW_BIT && !mode->doubleBufferMode)
+         api_mask &= ~check;
+   }
+
+   check = EGL_OPENVG_BIT;
+   if (api_mask & check) {
+      /* vega st needs the depth/stencil rb */
+      if (!mode->depthBits && !mode->stencilBits)
+         api_mask &= ~check;
+   }
+
+   return api_mask;
+}
+
+#ifdef EGL_MESA_screen_surface
+
+static void
+egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+   const struct native_connector **native_connectors;
+   EGLint num_connectors, i;
+
+   native_connectors =
+      gdpy->native->modeset->get_connectors(gdpy->native, &num_connectors, NULL);
+   if (!num_connectors) {
+      if (native_connectors)
+         free(native_connectors);
+      return;
+   }
+
+   for (i = 0; i < num_connectors; i++) {
+      const struct native_connector *nconn = native_connectors[i];
+      struct egl_g3d_screen *gscr;
+      const struct native_mode **native_modes;
+      EGLint num_modes, j;
+
+      /* TODO support for hotplug */
+      native_modes =
+         gdpy->native->modeset->get_modes(gdpy->native, nconn, &num_modes);
+      if (!num_modes) {
+         if (native_modes)
+            free(native_modes);
+         continue;
+      }
+
+      gscr = CALLOC_STRUCT(egl_g3d_screen);
+      if (!gscr) {
+         free(native_modes);
+         continue;
+      }
+
+      _eglInitScreen(&gscr->base);
+
+      for (j = 0; j < num_modes; j++) {
+         const struct native_mode *nmode = native_modes[j];
+         _EGLMode *mode;
+
+         mode = _eglAddNewMode(&gscr->base, nmode->width, nmode->height,
+               nmode->refresh_rate, nmode->desc);
+         if (!mode)
+            break;
+         /* gscr->native_modes and gscr->base.Modes should be consistent */
+         assert(mode == &gscr->base.Modes[j]);
+      }
+
+      gscr->native = nconn;
+      gscr->native_modes = native_modes;
+
+      _eglAddScreen(dpy, &gscr->base);
+   }
+
+   free(native_connectors);
+}
+
+#endif /* EGL_MESA_screen_surface */
+
+/**
+ * Add configs to display and return the next config ID.
+ */
+static EGLint
+egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
+{
+   struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+   const struct native_config **native_configs;
+   int num_configs, i;
+
+   native_configs = gdpy->native->get_configs(gdpy->native,
+         &num_configs);
+   if (!num_configs) {
+      if (native_configs)
+         free(native_configs);
+      return id;
+   }
+
+   for (i = 0; i < num_configs; i++) {
+      EGLint api_mask;
+      struct egl_g3d_config *gconf;
+      EGLBoolean valid;
+
+      api_mask = get_mode_api_mask(&native_configs[i]->mode, gdrv->api_mask);
+      if (!api_mask) {
+         _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
+               native_configs[i]->mode.visualID);
+         continue;
+      }
+
+      gconf = CALLOC_STRUCT(egl_g3d_config);
+      if (!gconf)
+         continue;
+
+      _eglInitConfig(&gconf->base, id);
+      valid = _eglConfigFromContextModesRec(&gconf->base,
+            &native_configs[i]->mode, api_mask, api_mask);
+      if (valid) {
+#ifdef EGL_MESA_screen_surface
+         /* check if scanout surface bit is set */
+         if (native_configs[i]->scanout_bit) {
+            EGLint val = GET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE);
+            val |= EGL_SCREEN_BIT_MESA;
+            SET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE, val);
+         }
+#endif
+         valid = _eglValidateConfig(&gconf->base, EGL_FALSE);
+      }
+      if (!valid) {
+         _eglLog(_EGL_DEBUG, "skip invalid config 0x%x",
+               native_configs[i]->mode.visualID);
+         free(gconf);
+         continue;
+      }
+
+      gconf->native = native_configs[i];
+      _eglAddConfig(dpy, &gconf->base);
+      id++;
+   }
+
+   free(native_configs);
+   return id;
+}
+
+/**
+ * Flush the front buffer of the context's draw surface.
+ */
+static void
+egl_g3d_flush_frontbuffer(void *dummy, struct pipe_surface *surf,
+                          void *context_private)
+{
+   struct egl_g3d_context *gctx = egl_g3d_context(context_private);
+   struct egl_g3d_surface *gsurf = egl_g3d_surface(gctx->base.DrawSurface);
+
+   if (gsurf) {
+      gsurf->native->flush_frontbuffer(gsurf->native);
+      egl_g3d_validate_context(gctx->base.Display, &gctx->base);
+   }
+}
+
+static EGLBoolean
+egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+   EGLint i;
+
+   _eglReleaseDisplayResources(drv, dpy);
+   _eglCleanupDisplay(dpy);
+
+   if (dpy->Screens) {
+      for (i = 0; i < dpy->NumScreens; i++) {
+         struct egl_g3d_screen *gscr = egl_g3d_screen(dpy->Screens[i]);
+         free(gscr->native_modes);
+         free(gscr);
+      }
+      free(dpy->Screens);
+   }
+
+   if (gdpy->native)
+      gdpy->native->destroy(gdpy->native);
+
+   free(gdpy);
+   dpy->DriverData = NULL;
+
+   return EGL_TRUE;
+}
+
+static EGLBoolean
+egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
+                   EGLint *major, EGLint *minor)
+{
+   struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+   struct egl_g3d_display *gdpy;
+
+   gdpy = CALLOC_STRUCT(egl_g3d_display);
+   if (!gdpy) {
+      _eglError(EGL_BAD_ALLOC, "eglInitialize");
+      goto fail;
+   }
+   dpy->DriverData = gdpy;
+
+   gdpy->native =
+      native_create_display(dpy->NativeDisplay, egl_g3d_flush_frontbuffer);
+   if (!gdpy->native) {
+      _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
+      goto fail;
+   }
+
+   dpy->ClientAPIsMask = gdrv->api_mask;
+
+   if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
+      _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
+      goto fail;
+   }
+
+#ifdef EGL_MESA_screen_surface
+   /* enable MESA_screen_surface */
+   if (gdpy->native->modeset) {
+      dpy->Extensions.MESA_screen_surface = EGL_TRUE;
+      egl_g3d_add_screens(drv, dpy);
+   }
+#endif
+
+   *major = 1;
+   *minor = 4;
+
+   return EGL_TRUE;
+
+fail:
+   if (gdpy)
+      egl_g3d_terminate(drv, dpy);
+   return EGL_FALSE;
+}
+
+static _EGLContext *
+egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+                       _EGLContext *share, const EGLint *attribs)
+{
+   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+   struct egl_g3d_context *xshare = egl_g3d_context(share);
+   struct egl_g3d_config *gconf = egl_g3d_config(conf);
+   struct egl_g3d_context *gctx;
+   const __GLcontextModes *mode;
+
+   gctx = CALLOC_STRUCT(egl_g3d_context);
+   if (!gctx) {
+      _eglError(EGL_BAD_ALLOC, "eglCreateContext");
+      return NULL;
+   }
+
+   if (!_eglInitContext(drv, &gctx->base, conf, attribs)) {
+      free(gctx);
+      return NULL;
+   }
+
+   gctx->stapi = egl_g3d_choose_st(drv, &gctx->base);
+   if (!gctx->stapi) {
+      free(gctx);
+      return NULL;
+   }
+
+   mode = &gconf->native->mode;
+   gctx->pipe =
+      gdpy->native->create_context(gdpy->native, (void *) &gctx->base);
+   gctx->st_ctx = gctx->stapi->st_create_context(gctx->pipe, mode,
+                        (xshare) ? xshare->st_ctx : NULL);
+
+   return &gctx->base;
+}
+
+static EGLBoolean
+egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
+{
+   struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+
+   if (_eglIsContextBound(&gctx->base))
+      return EGL_TRUE;
+
+   egl_g3d_realloc_context(dpy, &gctx->base);
+
+   /* it will destroy pipe context */
+   gctx->stapi->st_destroy_context(gctx->st_ctx);
+
+   free(gctx);
+
+   return EGL_TRUE;
+}
+
+static _EGLSurface *
+egl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+                              _EGLConfig *conf, EGLNativeWindowType win,
+                              const EGLint *attribs)
+{
+   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+   struct egl_g3d_config *gconf = egl_g3d_config(conf);
+   struct egl_g3d_surface *gsurf;
+
+   gsurf = CALLOC_STRUCT(egl_g3d_surface);
+   if (!gsurf) {
+      _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
+      return NULL;
+   }
+
+   if (!_eglInitSurface(drv, &gsurf->base, EGL_WINDOW_BIT, conf, attribs)) {
+      free(gsurf);
+      return NULL;
+   }
+
+   gsurf->native =
+      gdpy->native->create_window_surface(gdpy->native, win, gconf->native);
+   if (!gsurf->native) {
+      free(gsurf);
+      return NULL;
+   }
+
+   if (!gsurf->native->validate(gsurf->native, NULL, 0, NULL,
+            &gsurf->base.Width, &gsurf->base.Height)) {
+      gsurf->native->destroy(gsurf->native);
+      free(gsurf);
+      return NULL;
+   }
+
+   gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER ||
+                        !gconf->native->mode.doubleBufferMode) ?
+      NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
+
+   return &gsurf->base;
+}
+
+static _EGLSurface *
+egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+                              _EGLConfig *conf, EGLNativePixmapType pix,
+                              const EGLint *attribs)
+{
+   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+   struct egl_g3d_config *gconf = egl_g3d_config(conf);
+   struct egl_g3d_surface *gsurf;
+
+   gsurf = CALLOC_STRUCT(egl_g3d_surface);
+   if (!gsurf) {
+      _eglError(EGL_BAD_ALLOC, "eglCreatePixmapSurface");
+      return NULL;
+   }
+
+   if (!_eglInitSurface(drv, &gsurf->base, EGL_PIXMAP_BIT, conf, attribs)) {
+      free(gsurf);
+      return NULL;
+   }
+
+   gsurf->native =
+      gdpy->native->create_pixmap_surface(gdpy->native, pix, gconf->native);
+   if (!gsurf->native) {
+      free(gsurf);
+      return NULL;
+   }
+
+   if (!gsurf->native->validate(gsurf->native, NULL, 0, NULL,
+            &gsurf->base.Width, &gsurf->base.Height)) {
+      gsurf->native->destroy(gsurf->native);
+      free(gsurf);
+      return NULL;
+   }
+
+   gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT;
+
+   return &gsurf->base;
+}
+
+static _EGLSurface *
+egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+                               _EGLConfig *conf, const EGLint *attribs)
+{
+   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+   struct egl_g3d_config *gconf = egl_g3d_config(conf);
+   struct egl_g3d_surface *gsurf;
+
+   gsurf = CALLOC_STRUCT(egl_g3d_surface);
+   if (!gsurf) {
+      _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
+      return NULL;
+   }
+
+   if (!_eglInitSurface(drv, &gsurf->base, EGL_PBUFFER_BIT, conf, attribs)) {
+      free(gsurf);
+      return NULL;
+   }
+
+   gsurf->native =
+      gdpy->native->create_pbuffer_surface(gdpy->native, gconf->native,
+            gsurf->base.Width, gsurf->base.Height);
+   if (!gsurf->native) {
+      free(gsurf);
+      return NULL;
+   }
+
+   gsurf->render_att = (!gconf->native->mode.doubleBufferMode) ?
+      NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
+
+   return &gsurf->base;
+}
+
+static EGLBoolean
+egl_g3d_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
+{
+   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+
+   if (_eglIsSurfaceBound(&gsurf->base))
+         return EGL_TRUE;
+
+   pipe_surface_reference(&gsurf->render_surface, NULL);
+   gsurf->native->destroy(gsurf->native);
+   free(gsurf);
+   return EGL_TRUE;
+}
+
+static EGLBoolean
+egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
+                     _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx)
+{
+   struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+   struct egl_g3d_context *old_gctx;
+   EGLint api;
+   EGLBoolean ok = EGL_TRUE;
+
+   /* find the old context */
+   api = (gctx) ? gctx->base.ClientAPI : eglQueryAPI();
+   old_gctx = egl_g3d_get_current_context(api);
+   if (old_gctx && !_eglIsContextLinked(&old_gctx->base))
+         old_gctx = NULL;
+
+   if (!_eglMakeCurrent(drv, dpy, draw, read, ctx))
+      return EGL_FALSE;
+
+   if (old_gctx) {
+      /* flush old context */
+      old_gctx->stapi->st_flush(old_gctx->st_ctx,
+            PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+
+      /*
+       * The old context is no longer current, and egl_g3d_realloc_context()
+       * should be called to destroy the framebuffers.  However, it is possible
+       * that it will be made current again with the same draw/read surfaces.
+       * It might be better to keep it around.
+       */
+   }
+
+   if (gctx) {
+      struct egl_g3d_surface *gdraw = egl_g3d_surface(draw);
+
+      ok = egl_g3d_realloc_context(dpy, &gctx->base);
+      if (ok) {
+         ok = gctx->stapi->st_make_current(gctx->st_ctx,
+               gctx->draw.st_fb, gctx->read.st_fb);
+         if (ok) {
+            egl_g3d_validate_context(dpy, &gctx->base);
+            if (gdraw->base.Type == EGL_WINDOW_BIT) {
+               gctx->base.WindowRenderBuffer =
+                  (gdraw->render_att == NATIVE_ATTACHMENT_FRONT_LEFT) ?
+                  EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
+            }
+         }
+      }
+   }
+   else if (old_gctx) {
+      ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL);
+      old_gctx->base.WindowRenderBuffer = EGL_NONE;
+   }
+
+   return ok;
+}
+
+static EGLBoolean
+egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
+{
+   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+   _EGLContext *ctx = _eglGetCurrentContext();
+   struct egl_g3d_context *gctx = NULL;
+
+   /* no-op for pixmap or pbuffer surface */
+   if (gsurf->base.Type == EGL_PIXMAP_BIT ||
+       gsurf->base.Type == EGL_PBUFFER_BIT)
+      return EGL_TRUE;
+
+   /* or when the surface is single-buffered */
+   if (gsurf->render_att == NATIVE_ATTACHMENT_FRONT_LEFT)
+      return EGL_TRUE;
+
+   if (ctx && ctx->DrawSurface == surf)
+      gctx = egl_g3d_context(ctx);
+
+   /* flush if the surface is current */
+   if (gctx)
+      gctx->stapi->st_notify_swapbuffers(gctx->draw.st_fb);
+
+   /*
+    * We drew on the back buffer, unless there was no back buffer.
+    * In that case, we drew on the front buffer.  Either case, we call
+    * swap_buffers.
+    */
+   if (!gsurf->native->swap_buffers(gsurf->native))
+      return EGL_FALSE;
+
+   if (gctx) {
+      struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config);
+
+      /* force validation if the swap method is not copy */
+      if (gconf->native->mode.swapMethod != GLX_SWAP_COPY_OML)
+         gctx->force_validate = EGL_TRUE;
+      egl_g3d_validate_context(dpy, &gctx->base);
+   }
+
+   return EGL_TRUE;
+}
+
+static EGLBoolean
+egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
+{
+   struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+   gctx->stapi->st_finish(gctx->st_ctx);
+   return EGL_TRUE;
+}
+
+static EGLBoolean
+egl_g3d_wait_native(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine)
+{
+   _EGLSurface *surf = _eglGetCurrentSurface(EGL_DRAW);
+   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+
+   if (engine != EGL_CORE_NATIVE_ENGINE)
+      return _eglError(EGL_BAD_PARAMETER, "eglWaitNative");
+
+   if (gsurf)
+      gsurf->native->wait(gsurf->native);
+
+   return EGL_TRUE;
+}
+
+static _EGLProc
+egl_g3d_get_proc_address(const char *procname)
+{
+   /* FIXME how come _EGLDriver is not passed? */
+   const struct egl_g3d_st *stapi;
+   _EGLProc proc;
+   EGLint i;
+
+   for (i = 0; i < NUM_EGL_G3D_STS; i++) {
+      stapi = egl_g3d_get_st(i);
+      if (stapi) {
+         proc = (_EGLProc) stapi->st_get_proc_address(procname);
+         if (proc)
+            return proc;
+      }
+   }
+
+   return (_EGLProc) NULL;
+}
+
+static EGLBoolean
+egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
+                       _EGLSurface *surf, EGLint buffer)
+{
+   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+   struct egl_g3d_context *gctx;
+   enum pipe_format target_format;
+   int target;
+
+   if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT)
+      return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
+   if (buffer != EGL_BACK_BUFFER)
+      return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
+   if (gsurf->base.BoundToTexture)
+      return _eglError(EGL_BAD_ACCESS, "eglBindTexImage");
+
+   switch (gsurf->base.TextureFormat) {
+   case EGL_TEXTURE_RGB:
+      target_format = PIPE_FORMAT_R8G8B8_UNORM;
+      break;
+   case EGL_TEXTURE_RGBA:
+      target_format = PIPE_FORMAT_A8R8G8B8_UNORM;
+      break;
+   default:
+      return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+   }
+
+   switch (gsurf->base.TextureTarget) {
+   case EGL_TEXTURE_2D:
+      target = ST_TEXTURE_2D;
+      break;
+   default:
+      return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+   }
+
+   /* flush properly if the surface is bound */
+   if (gsurf->base.Binding) {
+      gctx = egl_g3d_context(gsurf->base.Binding);
+      gctx->stapi->st_flush(gctx->st_ctx,
+            PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+   }
+
+   /* XXX change to EGL_OPENGL_ES_API once OpenGL ES is merged */
+   gctx = egl_g3d_get_current_context(EGL_OPENGL_API);
+   if (gctx) {
+      if (!gsurf->render_surface)
+         return EGL_FALSE;
+
+      gctx->stapi->st_bind_texture_surface(gsurf->render_surface,
+            target, gsurf->base.MipmapLevel, target_format);
+      gsurf->base.BoundToTexture = EGL_TRUE;
+   }
+
+   return EGL_TRUE;
+}
+
+static EGLBoolean
+egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
+                          _EGLSurface *surf, EGLint buffer)
+{
+   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+
+   if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT ||
+       !gsurf->base.BoundToTexture)
+      return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
+   if (buffer != EGL_BACK_BUFFER)
+      return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
+
+   if (gsurf->render_surface) {
+      _EGLThreadInfo *t = _eglGetCurrentThread();
+      /* XXX change to EGL_OPENGL_ES_API once OpenGL ES is merged */
+      struct egl_g3d_context *gctx = egl_g3d_context(
+            t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_API)]);
+
+      /* what if the context the surface binds to is no longer current? */
+      if (gctx)
+         gctx->stapi->st_unbind_texture_surface(gsurf->render_surface,
+               ST_TEXTURE_2D, gsurf->base.MipmapLevel);
+   }
+
+   gsurf->base.BoundToTexture = EGL_FALSE;
+
+   return EGL_TRUE;
+}
+
+#ifdef EGL_MESA_screen_surface
+
+static _EGLSurface *
+egl_g3d_create_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+                              _EGLConfig *conf, const EGLint *attribs)
+{
+   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+   struct egl_g3d_config *gconf = egl_g3d_config(conf);
+   struct egl_g3d_surface *gsurf;
+
+   gsurf = CALLOC_STRUCT(egl_g3d_surface);
+   if (!gsurf) {
+      _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
+      return NULL;
+   }
+
+   if (!_eglInitSurface(drv, &gsurf->base,
+            EGL_SCREEN_BIT_MESA, conf, attribs)) {
+      free(gsurf);
+      return NULL;
+   }
+
+   gsurf->native =
+      gdpy->native->modeset->create_scanout_surface(gdpy->native,
+            gconf->native, gsurf->base.Width, gsurf->base.Height);
+   if (!gsurf->native) {
+      free(gsurf);
+      return NULL;
+   }
+
+   gsurf->render_att = (!gconf->native->mode.doubleBufferMode) ?
+      NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
+
+   return &gsurf->base;
+}
+
+static EGLBoolean
+egl_g3d_show_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+                            _EGLScreen *scr, _EGLSurface *surf,
+                            _EGLMode *mode)
+{
+   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+   struct egl_g3d_screen *gscr = egl_g3d_screen(scr);
+   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+   struct native_surface *nsurf;
+   const struct native_mode *nmode;
+   EGLBoolean changed;
+
+   if (gsurf) {
+      EGLint idx;
+
+      if (!mode)
+         return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA");
+      if (gsurf->base.Type != EGL_SCREEN_BIT_MESA)
+         return _eglError(EGL_BAD_SURFACE, "eglShowScreenSurfaceMESA");
+      if (gsurf->base.Width < mode->Width || gsurf->base.Height < mode->Height)
+         return _eglError(EGL_BAD_MATCH,
+               "eglShowSurfaceMESA(surface smaller than mode size)");
+
+      /* find the index of the mode */
+      for (idx = 0; idx < gscr->base.NumModes; idx++)
+         if (mode == &gscr->base.Modes[idx])
+            break;
+      if (idx >= gscr->base.NumModes) {
+         return _eglError(EGL_BAD_MODE_MESA,
+               "eglShowSurfaceMESA(unknown mode)");
+      }
+
+      nsurf = gsurf->native;
+      nmode = gscr->native_modes[idx];
+   }
+   else {
+      if (mode)
+         return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA");
+
+      /* disable the screen */
+      nsurf = NULL;
+      nmode = NULL;
+   }
+
+   /* TODO surface panning by CRTC choosing */
+   changed = gdpy->native->modeset->program(gdpy->native, 0, nsurf,
+         gscr->base.OriginX, gscr->base.OriginY, &gscr->native, 1, nmode);
+   if (changed) {
+      gscr->base.CurrentSurface = &gsurf->base;
+      gscr->base.CurrentMode = mode;
+   }
+
+   return changed;
+}
+
+#endif /* EGL_MESA_screen_surface */
+
+static void
+egl_g3d_unload(_EGLDriver *drv)
+{
+   struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+   free(gdrv);
+}
+
+_EGLDriver *
+_eglMain(const char *args)
+{
+   static char driver_name[64];
+   struct egl_g3d_driver *gdrv;
+   EGLint i;
+
+   snprintf(driver_name, sizeof(driver_name),
+         "Gallium/%s", native_get_name());
+
+   gdrv = CALLOC_STRUCT(egl_g3d_driver);
+   if (!gdrv)
+      return NULL;
+
+   _eglInitDriverFallbacks(&gdrv->base);
+
+   gdrv->base.API.Initialize = egl_g3d_initialize;
+   gdrv->base.API.Terminate = egl_g3d_terminate;
+   gdrv->base.API.CreateContext = egl_g3d_create_context;
+   gdrv->base.API.DestroyContext = egl_g3d_destroy_context;
+   gdrv->base.API.CreateWindowSurface = egl_g3d_create_window_surface;
+   gdrv->base.API.CreatePixmapSurface = egl_g3d_create_pixmap_surface;
+   gdrv->base.API.CreatePbufferSurface = egl_g3d_create_pbuffer_surface;
+   gdrv->base.API.DestroySurface = egl_g3d_destroy_surface;
+   gdrv->base.API.MakeCurrent = egl_g3d_make_current;
+   gdrv->base.API.SwapBuffers = egl_g3d_swap_buffers;
+   gdrv->base.API.WaitClient = egl_g3d_wait_client;
+   gdrv->base.API.WaitNative = egl_g3d_wait_native;
+   gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address;
+
+   gdrv->base.API.BindTexImage = egl_g3d_bind_tex_image;
+   gdrv->base.API.ReleaseTexImage = egl_g3d_release_tex_image;
+
+#ifdef EGL_MESA_screen_surface
+   gdrv->base.API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface;
+   gdrv->base.API.ShowScreenSurfaceMESA = egl_g3d_show_screen_surface;
+#endif
+
+   gdrv->base.Name = driver_name;
+   gdrv->base.Unload = egl_g3d_unload;
+
+   for (i = 0; i < NUM_EGL_G3D_STS; i++) {
+      gdrv->stapis[i] = egl_g3d_get_st(i);
+      if (gdrv->stapis[i])
+         gdrv->api_mask |= gdrv->stapis[i]->api_bit;
+   }
+
+   if (gdrv->api_mask)
+      _eglLog(_EGL_DEBUG, "Driver API mask: 0x%x", gdrv->api_mask);
+   else
+      _eglLog(_EGL_WARNING, "No supported client API");
+
+   return &gdrv->base;
+}
diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h
new file mode 100644
index 0000000..33894b6
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h
@@ -0,0 +1,126 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL 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.
+ */
+
+#ifndef _EGL_G3D_H_
+#define _EGL_G3D_H_
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+#include "pipe/p_format.h"
+#include "egldriver.h"
+#include "egldisplay.h"
+#include "eglcontext.h"
+#include "eglsurface.h"
+#include "eglconfig.h"
+#include "eglscreen.h"
+#include "eglmode.h"
+
+#include "native.h"
+#include "egl_st.h"
+
+struct egl_g3d_driver {
+   _EGLDriver base;
+   const struct egl_g3d_st *stapis[NUM_EGL_G3D_STS];
+   EGLint api_mask;
+};
+
+struct egl_g3d_display {
+   struct native_display *native;
+};
+
+struct egl_g3d_buffer {
+   struct st_framebuffer *st_fb;
+   EGLint num_atts;
+   enum native_attachment native_atts[NUM_NATIVE_ATTACHMENTS];
+   uint st_atts[NUM_NATIVE_ATTACHMENTS];
+};
+
+struct egl_g3d_context {
+   _EGLContext base;
+
+   const struct egl_g3d_st *stapi;
+   struct pipe_context *pipe;
+
+   struct st_context *st_ctx;
+   EGLBoolean force_validate;
+   struct egl_g3d_buffer draw, read;
+};
+
+struct egl_g3d_surface {
+   _EGLSurface base;
+   struct native_surface *native;
+   enum native_attachment render_att;
+   struct pipe_surface *render_surface;
+};
+
+struct egl_g3d_config {
+   _EGLConfig base;
+   const struct native_config *native;
+};
+
+struct egl_g3d_screen {
+   _EGLScreen base;
+   const struct native_connector *native;
+   const struct native_mode **native_modes;
+};
+
+static INLINE struct egl_g3d_driver *
+egl_g3d_driver(_EGLDriver *drv)
+{
+   return (struct egl_g3d_driver *) drv;
+}
+
+static INLINE struct egl_g3d_display *
+egl_g3d_display(_EGLDisplay *dpy)
+{
+   /* note that it is not direct casting */
+   return (struct egl_g3d_display *) dpy->DriverData;
+}
+
+static INLINE struct egl_g3d_context *
+egl_g3d_context(_EGLContext *ctx)
+{
+   return (struct egl_g3d_context *) ctx;
+}
+
+static INLINE struct egl_g3d_surface *
+egl_g3d_surface(_EGLSurface *surf)
+{
+   return (struct egl_g3d_surface *) surf;
+}
+
+static INLINE struct egl_g3d_config *
+egl_g3d_config(_EGLConfig *conf)
+{
+   return (struct egl_g3d_config *) conf;
+}
+
+static INLINE struct egl_g3d_screen *
+egl_g3d_screen(_EGLScreen *scr)
+{
+   return (struct egl_g3d_screen *) scr;
+}
+
+#endif /* _EGL_G3D_H_ */
diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_st.c b/src/gallium/state_trackers/egl_g3d/common/egl_st.c
new file mode 100644
index 0000000..a88ff91
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/common/egl_st.c
@@ -0,0 +1,131 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL 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 <dlfcn.h>
+#include "pipe/p_compiler.h"
+#include "util/u_memory.h"
+#include "egllog.h"
+#include "EGL/egl.h" /* for EGL_api_BIT */
+
+#include "egl_st.h"
+
+#ifndef HAVE_DLADDR
+#define HAVE_DLADDR 1
+#endif
+
+#if HAVE_DLADDR
+
+static const char *
+egl_g3d_st_names[] = {
+#define ST_PUBLIC(name, ...) #name,
+#include "st_public_tmp.h"
+   NULL
+};
+
+static boolean
+egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym)
+{
+   st_proc *procs = (st_proc *) stapi;
+   void *handle;
+   Dl_info info;
+   const char **name;
+
+   if (!dladdr(sym, &info))
+      return FALSE;
+   handle = dlopen(info.dli_fname, RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE);
+   if (!handle)
+      return FALSE;
+
+   for (name = egl_g3d_st_names; *name; name++) {
+      st_proc proc = (st_proc) dlsym(handle, *name);
+      if (!proc) {
+         _eglLog(_EGL_WARNING, "%s is missing in %s", *name, info.dli_fname);
+         memset(stapi, 0, sizeof(*stapi));
+         dlclose(handle);
+         return FALSE;
+      }
+      *procs++ = proc;
+   }
+
+   dlclose(handle);
+   return TRUE;
+}
+
+#else /* HAVE_DLADDR */
+
+static boolean
+egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym)
+{
+#define ST_PUBLIC(name, ...) stapi->name = name;
+#include "st_public_tmp.h"
+   return TRUE;
+}
+
+#endif /* HAVE_DLADDR */
+
+static boolean
+egl_g3d_init_st(struct egl_g3d_st *stapi, const char *api)
+{
+   void *handle, *sym;
+   boolean res = FALSE;
+
+   /* already initialized */
+   if (stapi->st_notify_swapbuffers != NULL)
+      return TRUE;
+
+   handle = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL);
+   if (!handle)
+      return FALSE;
+
+   sym = dlsym(handle, api);
+   if (sym && egl_g3d_fill_st(stapi, sym))
+      res = TRUE;
+
+   dlclose(handle);
+   return res;
+}
+
+static struct {
+   const char *symbol;
+   EGLint api_bit;
+} egl_g3d_st_info[NUM_EGL_G3D_STS] = {
+   { "st_api_OpenGL_ES1",  EGL_OPENGL_ES_BIT },
+   { "st_api_OpenVG",      EGL_OPENVG_BIT },
+   { "st_api_OpenGL_ES2",  EGL_OPENGL_ES2_BIT },
+   { "st_api_OpenGL",      EGL_OPENGL_BIT },
+};
+
+const struct egl_g3d_st *
+egl_g3d_get_st(enum egl_g3d_st_api api)
+{
+   static struct egl_g3d_st all_trackers[NUM_EGL_G3D_STS];
+
+   if (egl_g3d_init_st(&all_trackers[api], egl_g3d_st_info[api].symbol)) {
+      all_trackers[api].api_bit = egl_g3d_st_info[api].api_bit;
+      return &all_trackers[api];
+   }
+   else {
+      return NULL;
+   }
+}
diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_st.h b/src/gallium/state_trackers/egl_g3d/common/egl_st.h
new file mode 100644
index 0000000..8fb464b
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/common/egl_st.h
@@ -0,0 +1,73 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL 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.
+ */
+
+#ifndef _EGL_ST_H_
+#define _EGL_ST_H_
+
+#include "GL/gl.h" /* for GL types */
+#include "GL/internal/glcore.h"  /* for __GLcontextModes */
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_format.h"
+#include "pipe/p_context.h"
+
+/* avoid calling st functions directly */
+#if 1
+
+#define ST_SURFACE_FRONT_LEFT   0
+#define ST_SURFACE_BACK_LEFT    1
+#define ST_SURFACE_FRONT_RIGHT  2
+#define ST_SURFACE_BACK_RIGHT   3
+
+#define ST_TEXTURE_2D    0x2
+
+struct st_context;
+struct st_framebuffer;
+typedef void (*st_proc)();
+
+#else
+#include "state_tracker/st_public.h"
+#endif
+
+/* remember to update egl_g3d_get_st() when update the enums */
+enum egl_g3d_st_api {
+   EGL_G3D_ST_OPENGL_ES = 0,
+   EGL_G3D_ST_OPENVG,
+   EGL_G3D_ST_OPENGL_ES2,
+   EGL_G3D_ST_OPENGL,
+
+   NUM_EGL_G3D_STS
+};
+
+struct egl_g3d_st {
+#define ST_PUBLIC(name, ret, ...) ret (*name)(__VA_ARGS__);
+#include "st_public_tmp.h"
+   /* fields must be added here */
+   EGLint api_bit;
+};
+
+const struct egl_g3d_st *
+egl_g3d_get_st(enum egl_g3d_st_api api);
+
+#endif /* _EGL_ST_H_ */
diff --git a/src/gallium/state_trackers/egl_g3d/common/native.h b/src/gallium/state_trackers/egl_g3d/common/native.h
new file mode 100644
index 0000000..88d87c6
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/common/native.h
@@ -0,0 +1,211 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL 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.
+ */
+
+#ifndef _NATIVE_H_
+#define _NATIVE_H_
+
+#include "EGL/egl.h"  /* for EGL native types */
+#include "GL/gl.h" /* for GL types needed by __GLcontextModes */
+#include "GL/internal/glcore.h"  /* for __GLcontextModes */
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+
+/**
+ * Only color buffers are listed.  The others are allocated privately through,
+ * for example, st_renderbuffer_alloc_storage().
+ */
+enum native_attachment {
+   NATIVE_ATTACHMENT_FRONT_LEFT,
+   NATIVE_ATTACHMENT_BACK_LEFT,
+   NATIVE_ATTACHMENT_FRONT_RIGHT,
+   NATIVE_ATTACHMENT_BACK_RIGHT,
+
+   NUM_NATIVE_ATTACHMENTS
+};
+
+struct native_surface {
+   void (*destroy)(struct native_surface *nsurf);
+
+   /**
+    * Swap the front and back buffers so that the back buffer is visible.  It
+    * is no-op if the surface is single-buffered.  The contents of the back
+    * buffer after swapping may or may not be preserved.
+    */
+   boolean (*swap_buffers)(struct native_surface *nsurf);
+
+   /**
+    * Make the front buffer visible.  In some native displays, changes to the
+    * front buffer might not be visible immediately and require manual flush.
+    */
+   boolean (*flush_frontbuffer)(struct native_surface *nsurf);
+
+   /**
+    * Validate the buffers of the surface.  Those not listed in the attachments
+    * will be destroyed.  The returned textures are owned by the caller.
+    */
+   boolean (*validate)(struct native_surface *nsurf,
+                       const enum native_attachment *natts,
+                       unsigned num_natts,
+                       struct pipe_texture **textures,
+                       int *width, int *height);
+
+   /**
+    * Wait until all native commands affecting the surface has been executed.
+    */
+   void (*wait)(struct native_surface *nsurf);
+};
+
+struct native_config {
+   __GLcontextModes mode;
+   enum pipe_format color_format;
+   enum pipe_format depth_format;
+   enum pipe_format stencil_format;
+
+   /* treat it as an additional flag to mode.drawableType */
+   boolean scanout_bit;
+};
+
+struct native_connector {
+   int dummy;
+};
+
+struct native_mode {
+   const char *desc;
+   int width, height;
+   int refresh_rate;
+};
+
+struct native_display_modeset;
+
+/**
+ * A pipe winsys abstracts the OS.  A pipe screen abstracts the graphcis
+ * hardware.  A native display consists of a pipe winsys, a pipe screen, and
+ * the native display server.
+ */
+struct native_display {
+   struct pipe_screen *screen;
+   void (*destroy)(struct native_display *ndpy);
+
+   /**
+    * Get the supported configs.  The configs are owned by the display, but
+    * the returned array should be free()ed.
+    *
+    * The configs will be converted to EGL config by
+    * _eglConfigFromContextModesRec and validated by _eglValidateConfig.
+    * Those failing to pass the test will be skipped.
+    */
+   const struct native_config **(*get_configs)(struct native_display *ndpy,
+                                               int *num_configs);
+
+   /**
+    * Create a pipe context.
+    */
+   struct pipe_context *(*create_context)(struct native_display *ndpy,
+                                          void *context_private);
+
+   /**
+    * Create a window surface.  Required unless no config has GLX_WINDOW_BIT
+    * set.
+    */
+   struct native_surface *(*create_window_surface)(struct native_display *ndpy,
+                                                   EGLNativeWindowType win,
+                                                   const struct native_config *nconf);
+
+   /**
+    * Create a pixmap surface.  Required unless no config has GLX_PIXMAP_BIT
+    * set.
+    */
+   struct native_surface *(*create_pixmap_surface)(struct native_display *ndpy,
+                                                   EGLNativePixmapType pix,
+                                                   const struct native_config *nconf);
+
+   /**
+    * Create a pbuffer surface.  Required unless no config has GLX_PBUFFER_BIT
+    * set.
+    */
+   struct native_surface *(*create_pbuffer_surface)(struct native_display *ndpy,
+                                                    const struct native_config *nconf,
+                                                    uint width, uint height);
+
+   const struct native_display_modeset *modeset;
+};
+
+/**
+ * Mode setting interface of the native display.  It exposes the mode setting
+ * capabilities of the underlying graphics hardware.
+ */
+struct native_display_modeset {
+   /**
+    * Get the available physical connectors and the number of CRTCs.
+    */
+   const struct native_connector **(*get_connectors)(struct native_display *ndpy,
+                                                     int *num_connectors,
+                                                     int *num_crtcs);
+
+   /**
+    * Get the current supported modes of a connector.  The returned modes may
+    * change every time this function is called and those from previous calls
+    * might become invalid.
+    */
+   const struct native_mode **(*get_modes)(struct native_display *ndpy,
+                                           const struct native_connector *nconn,
+                                           int *num_modes);
+
+   /**
+    * Create a scan-out surface.  Required unless no config has
+    * GLX_SCREEN_BIT_MESA set.
+    */
+   struct native_surface *(*create_scanout_surface)(struct native_display *ndpy,
+                                                    const struct native_config *nconf,
+                                                    uint width, uint height);
+
+   /**
+    * Program the CRTC to output the surface to the given connectors with the
+    * given mode.  When surface is not given, the CRTC is disabled.
+    *
+    * This interface does not export a way to query capabilities of the CRTCs.
+    * The native display usually needs to dynamically map the index to a CRTC
+    * that supports the given connectors.
+    */
+   boolean (*program)(struct native_display *ndpy, int crtc_idx,
+                      struct native_surface *nsurf, uint x, uint y,
+                      const struct native_connector **nconns, int num_nconns,
+                      const struct native_mode *nmode);
+};
+
+typedef void (*native_flush_frontbuffer)(void *dummy,
+                                         struct pipe_surface *surf,
+                                         void *context_private);
+
+const char *
+native_get_name(void);
+
+struct native_display *
+native_create_display(EGLNativeDisplayType dpy,
+                      native_flush_frontbuffer flush_frontbuffer);
+
+#endif /* _NATIVE_H_ */
diff --git a/src/gallium/state_trackers/egl_g3d/common/st_public_tmp.h b/src/gallium/state_trackers/egl_g3d/common/st_public_tmp.h
new file mode 100644
index 0000000..507a0ec
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/common/st_public_tmp.h
@@ -0,0 +1,20 @@
+ST_PUBLIC(st_create_context,              struct st_context *,       struct pipe_context *pipe, const __GLcontextModes *visual, struct st_context *share)
+ST_PUBLIC(st_destroy_context,             void,                      struct st_context *st)
+ST_PUBLIC(st_copy_context_state,          void,                      struct st_context *dst, struct st_context *src, uint mask)
+ST_PUBLIC(st_create_framebuffer,          struct st_framebuffer *,   const __GLcontextModes *visual, enum pipe_format colorFormat, enum pipe_format depthFormat, enum pipe_format stencilFormat, uint width, uint height, void *privateData)
+ST_PUBLIC(st_resize_framebuffer,          void,                      struct st_framebuffer *stfb, uint width, uint height)
+ST_PUBLIC(st_set_framebuffer_surface,     void,                      struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface *surf)
+ST_PUBLIC(st_get_framebuffer_dimensions,  void,                      struct st_framebuffer *stfb, uint *width, uint *height)
+ST_PUBLIC(st_get_framebuffer_surface,     int,                       struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface **surface)
+ST_PUBLIC(st_get_framebuffer_texture,     int,                       struct st_framebuffer *stfb, uint surfIndex, struct pipe_texture **texture)
+ST_PUBLIC(st_framebuffer_private,         void *,                    struct st_framebuffer *stfb)
+ST_PUBLIC(st_unreference_framebuffer,     void,                      struct st_framebuffer *stfb)
+ST_PUBLIC(st_make_current,                GLboolean,                 struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read)
+ST_PUBLIC(st_get_current,                 struct st_context *,       void)
+ST_PUBLIC(st_flush,                       void,                      struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence)
+ST_PUBLIC(st_finish,                      void,                      struct st_context *st)
+ST_PUBLIC(st_notify_swapbuffers,          void,                      struct st_framebuffer *stfb)
+ST_PUBLIC(st_bind_texture_surface,        int,                       struct pipe_surface *ps, int target, int level, enum pipe_format format)
+ST_PUBLIC(st_unbind_texture_surface,      int,                       struct pipe_surface *ps, int target, int level)
+ST_PUBLIC(st_get_proc_address,            st_proc,                   const char *procname)
+#undef ST_PUBLIC
diff --git a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c b/src/gallium/state_trackers/egl_g3d/kms/native_kms.c
new file mode 100644
index 0000000..0e0babd
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/kms/native_kms.c
@@ -0,0 +1,866 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.8
+ *
+ * Copyright (C) 2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL 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 <string.h>
+
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+#include "egllog.h"
+
+#include "native_kms.h"
+
+static boolean
+kms_surface_validate(struct native_surface *nsurf,
+                     const enum native_attachment *natts,
+                     unsigned num_natts,
+                     struct pipe_texture **textures,
+                     int *width, int *height)
+{
+   struct kms_surface *ksurf = kms_surface(nsurf);
+   struct kms_display *kdpy = ksurf->kdpy;
+   struct pipe_screen *screen = kdpy->base.screen;
+   struct pipe_texture templ, *ptex;
+   int i;
+
+   if (num_natts) {
+      if (textures)
+         memset(textures, 0, sizeof(*textures) * num_natts);
+
+      memset(&templ, 0, sizeof(templ));
+      templ.target = PIPE_TEXTURE_2D;
+      templ.last_level = 0;
+      templ.width0 = ksurf->width;
+      templ.height0 = ksurf->height;
+      templ.depth0 = 1;
+      templ.format = ksurf->color_format;
+      templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+      if (ksurf->type == KMS_SURFACE_TYPE_SCANOUT)
+         templ.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
+   }
+
+   /* create textures */
+   for (i = 0; i < num_natts; i++) {
+      enum native_attachment natt = natts[i];
+
+      ptex = ksurf->textures[natt];
+      if (!ptex) {
+         ptex = screen->texture_create(screen, &templ);
+         ksurf->textures[natt] = ptex;
+      }
+
+      if (textures)
+         pipe_texture_reference(&textures[i], ptex);
+   }
+
+   if (width)
+      *width = ksurf->width;
+   if (height)
+      *height = ksurf->height;
+
+   return TRUE;
+}
+
+/**
+ * Add textures as DRM framebuffers.
+ */
+static boolean
+kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
+{
+   struct kms_surface *ksurf = kms_surface(nsurf);
+   struct kms_display *kdpy = ksurf->kdpy;
+   int num_framebuffers = (need_back) ? 2 : 1;
+   int i, err;
+
+   for (i = 0; i < num_framebuffers; i++) {
+      struct kms_framebuffer *fb;
+      enum native_attachment natt;
+      unsigned int handle, stride;
+      uint block_bits;
+
+      if (i == 0) {
+         fb = &ksurf->front_fb;
+         natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+      }
+      else {
+         fb = &ksurf->back_fb;
+         natt = NATIVE_ATTACHMENT_BACK_LEFT;
+      }
+
+      if (!fb->texture) {
+         /* make sure the texture has been allocated */
+         kms_surface_validate(&ksurf->base, &natt, 1, NULL, NULL, NULL);
+         if (!ksurf->textures[natt])
+            return FALSE;
+
+         pipe_texture_reference(&fb->texture, ksurf->textures[natt]);
+      }
+
+      /* already initialized */
+      if (fb->buffer_id)
+         continue;
+
+      /* TODO detect the real value */
+      fb->is_passive = TRUE;
+
+      if (!kdpy->api->local_handle_from_texture(kdpy->api,
+               kdpy->base.screen, fb->texture, &stride, &handle))
+         return FALSE;
+
+      block_bits = util_format_get_blocksizebits(ksurf->color_format);
+      err = drmModeAddFB(kdpy->fd, ksurf->width, ksurf->height,
+            block_bits, block_bits, stride, handle, &fb->buffer_id);
+      if (err) {
+         fb->buffer_id = 0;
+         return FALSE;
+      }
+   }
+
+   return TRUE;
+}
+
+static boolean
+kms_surface_flush_frontbuffer(struct native_surface *nsurf)
+{
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+   struct kms_surface *ksurf = kms_surface(nsurf);
+   struct kms_display *kdpy = ksurf->kdpy;
+
+   /* pbuffer is private */
+   if (ksurf->type == KMS_SURFACE_TYPE_PBUFFER)
+      return TRUE;
+
+   if (ksurf->front_fb.is_passive)
+      drmModeDirtyFB(kdpy->fd, ksurf->front_fb.buffer_id, NULL, 0);
+#endif
+
+   return TRUE;
+}
+
+static boolean
+kms_surface_swap_buffers(struct native_surface *nsurf)
+{
+   struct kms_surface *ksurf = kms_surface(nsurf);
+   struct kms_crtc *kcrtc = &ksurf->current_crtc;
+   struct kms_display *kdpy = ksurf->kdpy;
+   struct kms_framebuffer tmp_fb;
+   struct pipe_texture *tmp_texture;
+   int err;
+
+   /* pbuffer is private */
+   if (ksurf->type == KMS_SURFACE_TYPE_PBUFFER)
+      return TRUE;
+
+   if (!ksurf->back_fb.buffer_id) {
+      if (!kms_surface_init_framebuffers(&ksurf->base, TRUE))
+         return FALSE;
+   }
+
+   if (ksurf->is_shown && kcrtc->crtc) {
+      err = drmModeSetCrtc(kdpy->fd, kcrtc->crtc->crtc_id,
+            ksurf->back_fb.buffer_id, kcrtc->crtc->x, kcrtc->crtc->y,
+            kcrtc->connectors, kcrtc->num_connectors, &kcrtc->crtc->mode);
+      if (err)
+         return FALSE;
+   }
+
+   /* swap the buffers */
+   tmp_fb = ksurf->front_fb;
+   ksurf->front_fb = ksurf->back_fb;
+   ksurf->back_fb = tmp_fb;
+
+   tmp_texture = ksurf->textures[NATIVE_ATTACHMENT_FRONT_LEFT];
+   ksurf->textures[NATIVE_ATTACHMENT_FRONT_LEFT] =
+      ksurf->textures[NATIVE_ATTACHMENT_BACK_LEFT];
+   ksurf->textures[NATIVE_ATTACHMENT_BACK_LEFT] = tmp_texture;
+
+   return TRUE;
+}
+
+static void
+kms_surface_wait(struct native_surface *nsurf)
+{
+   /* no-op */
+}
+
+static void
+kms_surface_destroy(struct native_surface *nsurf)
+{
+   struct kms_surface *ksurf = kms_surface(nsurf);
+   int i;
+
+   if (ksurf->current_crtc.crtc)
+         drmModeFreeCrtc(ksurf->current_crtc.crtc);
+
+   if (ksurf->front_fb.buffer_id)
+      drmModeRmFB(ksurf->kdpy->fd, ksurf->front_fb.buffer_id);
+   pipe_texture_reference(&ksurf->front_fb.texture, NULL);
+
+   if (ksurf->back_fb.buffer_id)
+      drmModeRmFB(ksurf->kdpy->fd, ksurf->back_fb.buffer_id);
+   pipe_texture_reference(&ksurf->back_fb.texture, NULL);
+
+   for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
+      struct pipe_texture *ptex = ksurf->textures[i];
+      pipe_texture_reference(&ptex, NULL);
+   }
+
+   free(ksurf);
+}
+
+static struct kms_surface *
+kms_display_create_surface(struct native_display *ndpy,
+                           enum kms_surface_type type,
+                           const struct native_config *nconf,
+                           uint width, uint height)
+{
+   struct kms_display *kdpy = kms_display(ndpy);
+   struct kms_config *kconf = kms_config(nconf);
+   struct kms_surface *ksurf;
+
+   ksurf = CALLOC_STRUCT(kms_surface);
+   if (!ksurf)
+      return NULL;
+
+   ksurf->kdpy = kdpy;
+   ksurf->type = type;
+   ksurf->color_format = kconf->base.color_format;
+   ksurf->width = width;
+   ksurf->height = height;
+
+   ksurf->base.destroy = kms_surface_destroy;
+   ksurf->base.swap_buffers = kms_surface_swap_buffers;
+   ksurf->base.flush_frontbuffer = kms_surface_flush_frontbuffer;
+   ksurf->base.validate = kms_surface_validate;
+   ksurf->base.wait = kms_surface_wait;
+
+   return ksurf;
+}
+
+/**
+ * Choose a CRTC that supports all given connectors.
+ */
+static uint32_t
+kms_display_choose_crtc(struct native_display *ndpy,
+                        uint32_t *connectors, int num_connectors)
+{
+   struct kms_display *kdpy = kms_display(ndpy);
+   int idx;
+
+   for (idx = 0; idx < kdpy->resources->count_crtcs; idx++) {
+      boolean found_crtc = TRUE;
+      int i, j;
+
+      for (i = 0; i < num_connectors; i++) {
+         drmModeConnectorPtr connector;
+         int encoder_idx = -1;
+
+         connector = drmModeGetConnector(kdpy->fd, connectors[i]);
+         if (!connector) {
+            found_crtc = FALSE;
+            break;
+         }
+
+         /* find an encoder the CRTC supports */
+         for (j = 0; j < connector->count_encoders; j++) {
+            drmModeEncoderPtr encoder =
+               drmModeGetEncoder(kdpy->fd, connector->encoders[j]);
+            if (encoder->possible_crtcs & (1 << idx)) {
+               encoder_idx = j;
+               break;
+            }
+            drmModeFreeEncoder(encoder);
+         }
+
+         drmModeFreeConnector(connector);
+         if (encoder_idx < 0) {
+            found_crtc = FALSE;
+            break;
+         }
+      }
+
+      if (found_crtc)
+         break;
+   }
+
+   if (idx >= kdpy->resources->count_crtcs) {
+      _eglLog(_EGL_WARNING,
+            "failed to find a CRTC that supports the given %d connectors",
+            num_connectors);
+      return 0;
+   }
+
+   return kdpy->resources->crtcs[idx];
+}
+
+/**
+ * Remember the original CRTC status and set the CRTC
+ */
+static boolean
+kms_display_set_crtc(struct native_display *ndpy, int crtc_idx,
+                     uint32_t buffer_id, uint32_t x, uint32_t y,
+                     uint32_t *connectors, int num_connectors,
+                     drmModeModeInfoPtr mode)
+{
+   struct kms_display *kdpy = kms_display(ndpy);
+   struct kms_crtc *kcrtc = &kdpy->saved_crtcs[crtc_idx];
+   uint32_t crtc_id;
+   int err;
+
+   if (kcrtc->crtc) {
+      crtc_id = kcrtc->crtc->crtc_id;
+   }
+   else {
+      int count = 0, i;
+
+      /*
+       * Choose the CRTC once.  It could be more dynamic, but let's keep it
+       * simple for now.
+       */
+      crtc_id = kms_display_choose_crtc(&kdpy->base,
+            connectors, num_connectors);
+
+      /* save the original CRTC status */
+      kcrtc->crtc = drmModeGetCrtc(kdpy->fd, crtc_id);
+      if (!kcrtc->crtc)
+         return FALSE;
+
+      for (i = 0; i < kdpy->num_connectors; i++) {
+         struct kms_connector *kconn = &kdpy->connectors[i];
+         drmModeConnectorPtr connector = kconn->connector;
+         drmModeEncoderPtr encoder;
+
+         encoder = drmModeGetEncoder(kdpy->fd, connector->encoder_id);
+         if (encoder) {
+            if (encoder->crtc_id == crtc_id) {
+               kcrtc->connectors[count++] = connector->connector_id;
+               if (count >= Elements(kcrtc->connectors))
+                  break;
+            }
+            drmModeFreeEncoder(encoder);
+         }
+      }
+
+      kcrtc->num_connectors = count;
+   }
+
+   err = drmModeSetCrtc(kdpy->fd, crtc_id, buffer_id, x, y,
+         connectors, num_connectors, mode);
+   if (err) {
+      drmModeFreeCrtc(kcrtc->crtc);
+      kcrtc->crtc = NULL;
+      kcrtc->num_connectors = 0;
+
+      return FALSE;
+   }
+
+   return TRUE;
+}
+
+static boolean
+kms_display_program(struct native_display *ndpy, int crtc_idx,
+                    struct native_surface *nsurf, uint x, uint y,
+                    const struct native_connector **nconns, int num_nconns,
+                    const struct native_mode *nmode)
+{
+   struct kms_display *kdpy = kms_display(ndpy);
+   struct kms_surface *ksurf = kms_surface(nsurf);
+   const struct kms_mode *kmode = kms_mode(nmode);
+   uint32_t connector_ids[32];
+   uint32_t buffer_id;
+   drmModeModeInfo mode_tmp, *mode;
+   int i;
+
+   if (num_nconns > Elements(connector_ids)) {
+      _eglLog(_EGL_WARNING, "too many connectors (%d)", num_nconns);
+      num_nconns = Elements(connector_ids);
+   }
+
+   if (ksurf) {
+      if (!kms_surface_init_framebuffers(&ksurf->base, FALSE))
+         return FALSE;
+
+      buffer_id = ksurf->front_fb.buffer_id;
+      /* the mode argument of drmModeSetCrtc is not constified */
+      mode_tmp = kmode->mode;
+      mode = &mode_tmp;
+   }
+   else {
+      /* disable the CRTC */
+      buffer_id = 0;
+      mode = NULL;
+      num_nconns = 0;
+   }
+
+   for (i = 0; i < num_nconns; i++) {
+      struct kms_connector *kconn = kms_connector(nconns[i]);
+      connector_ids[i] = kconn->connector->connector_id;
+   }
+
+   if (!kms_display_set_crtc(&kdpy->base, crtc_idx, buffer_id, x, y,
+            connector_ids, num_nconns, mode)) {
+      _eglLog(_EGL_WARNING, "failed to set CRTC %d", crtc_idx);
+
+      return FALSE;
+   }
+
+   if (kdpy->shown_surfaces[crtc_idx])
+      kdpy->shown_surfaces[crtc_idx]->is_shown = FALSE;
+   kdpy->shown_surfaces[crtc_idx] = ksurf;
+
+   /* remember the settings for buffer swapping */
+   if (ksurf) {
+      uint32_t crtc_id = kdpy->saved_crtcs[crtc_idx].crtc->crtc_id;
+      struct kms_crtc *kcrtc = &ksurf->current_crtc;
+
+      if (kcrtc->crtc)
+         drmModeFreeCrtc(kcrtc->crtc);
+      kcrtc->crtc = drmModeGetCrtc(kdpy->fd, crtc_id);
+
+      assert(num_nconns < Elements(kcrtc->connectors));
+      memcpy(kcrtc->connectors, connector_ids,
+            sizeof(*connector_ids) * num_nconns);
+      kcrtc->num_connectors = num_nconns;
+
+      ksurf->is_shown = TRUE;
+   }
+
+   return TRUE;
+}
+
+static const struct native_mode **
+kms_display_get_modes(struct native_display *ndpy,
+                      const struct native_connector *nconn,
+                      int *num_modes)
+{
+   struct kms_display *kdpy = kms_display(ndpy);
+   struct kms_connector *kconn = kms_connector(nconn);
+   const struct native_mode **nmodes_return;
+   int count, i;
+
+   /* delete old data */
+   if (kconn->connector) {
+      drmModeFreeConnector(kconn->connector);
+      free(kconn->kms_modes);
+
+      kconn->connector = NULL;
+      kconn->kms_modes = NULL;
+      kconn->num_modes = 0;
+   }
+
+   /* detect again */
+   kconn->connector = drmModeGetConnector(kdpy->fd, kconn->connector_id);
+   if (!kconn->connector)
+      return NULL;
+
+   count = kconn->connector->count_modes;
+   kconn->kms_modes = calloc(count, sizeof(*kconn->kms_modes));
+   if (!kconn->kms_modes) {
+      drmModeFreeConnector(kconn->connector);
+      kconn->connector = NULL;
+
+      return NULL;
+   }
+
+   for (i = 0; i < count; i++) {
+      struct kms_mode *kmode = &kconn->kms_modes[i];
+      drmModeModeInfoPtr mode = &kconn->connector->modes[i];
+
+      kmode->mode = *mode;
+
+      kmode->base.desc = kmode->mode.name;
+      kmode->base.width = kmode->mode.hdisplay;
+      kmode->base.height = kmode->mode.vdisplay;
+      kmode->base.refresh_rate = kmode->mode.vrefresh / 1000;
+   }
+
+   nmodes_return = malloc(count * sizeof(*nmodes_return));
+   if (nmodes_return) {
+      for (i = 0; i < count; i++)
+         nmodes_return[i] = &kconn->kms_modes[i].base;
+      if (num_modes)
+         *num_modes = count;
+   }
+
+   return nmodes_return;
+}
+
+static const struct native_connector **
+kms_display_get_connectors(struct native_display *ndpy, int *num_connectors,
+                           int *num_crtc)
+{
+   struct kms_display *kdpy = kms_display(ndpy);
+   const struct native_connector **connectors;
+   int i;
+
+   if (!kdpy->connectors) {
+      kdpy->connectors =
+         calloc(kdpy->resources->count_connectors, sizeof(*kdpy->connectors));
+      if (!kdpy->connectors)
+         return NULL;
+
+      for (i = 0; i < kdpy->resources->count_connectors; i++) {
+         struct kms_connector *kconn = &kdpy->connectors[i];
+
+         kconn->connector_id = kdpy->resources->connectors[i];
+         /* kconn->connector is allocated when the modes are asked */
+      }
+
+      kdpy->num_connectors = kdpy->resources->count_connectors;
+   }
+
+   connectors = malloc(kdpy->num_connectors * sizeof(*connectors));
+   if (connectors) {
+      for (i = 0; i < kdpy->num_connectors; i++)
+         connectors[i] = &kdpy->connectors[i].base;
+      if (num_connectors)
+         *num_connectors = kdpy->num_connectors;
+   }
+
+   if (num_crtc)
+      *num_crtc = kdpy->resources->count_crtcs;
+
+   return connectors;
+}
+
+static struct native_surface *
+kms_display_create_scanout_surface(struct native_display *ndpy,
+                                   const struct native_config *nconf,
+                                   uint width, uint height)
+{
+   struct kms_surface *ksurf;
+
+   ksurf = kms_display_create_surface(ndpy,
+         KMS_SURFACE_TYPE_SCANOUT, nconf, width, height);
+   return &ksurf->base;
+}
+
+static struct native_surface *
+kms_display_create_pbuffer_surface(struct native_display *ndpy,
+                                   const struct native_config *nconf,
+                                   uint width, uint height)
+{
+   struct kms_surface *ksurf;
+
+   ksurf = kms_display_create_surface(ndpy,
+         KMS_SURFACE_TYPE_PBUFFER, nconf, width, height);
+   return &ksurf->base;
+}
+
+static struct pipe_context *
+kms_display_create_context(struct native_display *ndpy, void *context_private)
+{
+   struct kms_display *kdpy = kms_display(ndpy);
+   struct pipe_context *pctx;
+
+   pctx = kdpy->api->create_context(kdpy->api, kdpy->base.screen);
+   if (pctx)
+      pctx->priv = context_private;
+   return pctx;
+}
+
+static boolean
+kms_display_is_format_supported(struct native_display *ndpy,
+                                enum pipe_format fmt, boolean is_color)
+{
+   return ndpy->screen->is_format_supported(ndpy->screen,
+         fmt, PIPE_TEXTURE_2D,
+         (is_color) ? PIPE_TEXTURE_USAGE_RENDER_TARGET :
+         PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+}
+
+static const struct native_config **
+kms_display_get_configs(struct native_display *ndpy, int *num_configs)
+{
+   struct kms_display *kdpy = kms_display(ndpy);
+   const struct native_config **configs;
+
+   /* first time */
+   if (!kdpy->config) {
+      struct native_config *nconf;
+      enum pipe_format format;
+
+      kdpy->config = calloc(1, sizeof(*kdpy->config));
+      if (!kdpy->config)
+         return NULL;
+
+      nconf = &kdpy->config->base;
+
+      /* always double-buffered */
+      nconf->mode.doubleBufferMode = TRUE;
+
+      format = PIPE_FORMAT_A8R8G8B8_UNORM;
+      if (!kms_display_is_format_supported(&kdpy->base, format, TRUE)) {
+         format = PIPE_FORMAT_B8G8R8A8_UNORM;
+         if (!kms_display_is_format_supported(&kdpy->base, format, TRUE))
+            format = PIPE_FORMAT_NONE;
+      }
+      if (format == PIPE_FORMAT_NONE)
+         return NULL;
+
+      nconf->color_format = format;
+      nconf->mode.redBits = 8;
+      nconf->mode.greenBits = 8;
+      nconf->mode.blueBits = 8;
+      nconf->mode.alphaBits = 8;
+      nconf->mode.rgbBits = 32;
+
+      format = PIPE_FORMAT_S8Z24_UNORM;
+      if (!kms_display_is_format_supported(&kdpy->base, format, FALSE)) {
+         format = PIPE_FORMAT_Z24S8_UNORM;
+         if (!kms_display_is_format_supported(&kdpy->base, format, FALSE))
+            format = PIPE_FORMAT_NONE;
+      }
+      if (format != PIPE_FORMAT_NONE) {
+         nconf->depth_format = format;
+         nconf->stencil_format = format;
+
+         nconf->mode.depthBits = 24;
+         nconf->mode.stencilBits = 8;
+         nconf->mode.haveDepthBuffer = TRUE;
+         nconf->mode.haveStencilBuffer = TRUE;
+      }
+
+      nconf->scanout_bit = TRUE;
+      nconf->mode.drawableType = GLX_PBUFFER_BIT;
+      nconf->mode.swapMethod = GLX_SWAP_EXCHANGE_OML;
+
+      nconf->mode.visualID = 0;
+      nconf->mode.visualType = EGL_NONE;
+
+      nconf->mode.renderType = GLX_RGBA_BIT;
+      nconf->mode.rgbMode = TRUE;
+      nconf->mode.xRenderable = FALSE;
+   }
+
+   configs = malloc(sizeof(*configs));
+   if (configs) {
+      configs[0] = &kdpy->config->base;
+      if (num_configs)
+         *num_configs = 1;
+   }
+
+   return configs;
+}
+
+static void
+kms_display_destroy(struct native_display *ndpy)
+{
+   struct kms_display *kdpy = kms_display(ndpy);
+   int i;
+
+   if (kdpy->config)
+      free(kdpy->config);
+
+   if (kdpy->connectors) {
+      for (i = 0; i < kdpy->num_connectors; i++) {
+         struct kms_connector *kconn = &kdpy->connectors[i];
+         if (kconn->connector) {
+            drmModeFreeConnector(kconn->connector);
+            free(kconn->kms_modes);
+         }
+      }
+      free(kdpy->connectors);
+   }
+
+   if (kdpy->shown_surfaces)
+      free(kdpy->shown_surfaces);
+
+   if (kdpy->saved_crtcs) {
+      for (i = 0; i < kdpy->resources->count_crtcs; i++) {
+         struct kms_crtc *kcrtc = &kdpy->saved_crtcs[i];
+
+         if (kcrtc->crtc) {
+            /* restore crtc */
+            drmModeSetCrtc(kdpy->fd, kcrtc->crtc->crtc_id,
+                  kcrtc->crtc->buffer_id, kcrtc->crtc->x, kcrtc->crtc->y,
+                  kcrtc->connectors, kcrtc->num_connectors,
+                  &kcrtc->crtc->mode);
+
+            drmModeFreeCrtc(kcrtc->crtc);
+         }
+      }
+      free(kdpy->saved_crtcs);
+   }
+
+   if (kdpy->resources)
+      drmModeFreeResources(kdpy->resources);
+
+   if (kdpy->base.screen)
+      kdpy->base.screen->destroy(kdpy->base.screen);
+
+   if (kdpy->fd >= 0)
+      drmClose(kdpy->fd);
+
+   if (kdpy->api)
+      kdpy->api->destroy(kdpy->api);
+   free(kdpy);
+}
+
+/**
+ * Initialize KMS and pipe screen.
+ */
+static boolean
+kms_display_init_screen(struct native_display *ndpy)
+{
+   struct kms_display *kdpy = kms_display(ndpy);
+   struct drm_create_screen_arg arg;
+   int fd;
+
+   fd = drmOpen(kdpy->api->name, NULL);
+   if (fd < 0) {
+      _eglLog(_EGL_WARNING, "failed to open DRM device");
+      return FALSE;
+   }
+
+#if 0
+   if (drmSetMaster(fd)) {
+      _eglLog(_EGL_WARNING, "failed to become DRM master");
+      return FALSE;
+   }
+#endif
+
+   memset(&arg, 0, sizeof(arg));
+   arg.mode = DRM_CREATE_NORMAL;
+   kdpy->base.screen = kdpy->api->create_screen(kdpy->api, fd, &arg);
+   if (!kdpy->base.screen) {
+      _eglLog(_EGL_WARNING, "failed to create DRM screen");
+      drmClose(fd);
+      return FALSE;
+   }
+
+   kdpy->fd = fd;
+
+   return TRUE;
+}
+
+static struct native_display_modeset kms_display_modeset = {
+   .get_connectors = kms_display_get_connectors,
+   .get_modes = kms_display_get_modes,
+   .create_scanout_surface = kms_display_create_scanout_surface,
+   .program = kms_display_program
+};
+
+static struct native_display *
+kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api,
+                   native_flush_frontbuffer flush_frontbuffer)
+{
+   struct kms_display *kdpy;
+
+   kdpy = CALLOC_STRUCT(kms_display);
+   if (!kdpy)
+      return NULL;
+
+   kdpy->api = api;
+   if (!kdpy->api) {
+      _eglLog(_EGL_WARNING, "failed to create DRM API");
+      free(kdpy);
+      return NULL;
+   }
+
+   kdpy->fd = -1;
+   if (!kms_display_init_screen(&kdpy->base)) {
+      kms_display_destroy(&kdpy->base);
+      return NULL;
+   }
+
+   /* resources are fixed, unlike crtc, connector, or encoder */
+   kdpy->resources = drmModeGetResources(kdpy->fd);
+   if (!kdpy->resources) {
+      kms_display_destroy(&kdpy->base);
+      return NULL;
+   }
+
+   kdpy->saved_crtcs =
+      calloc(kdpy->resources->count_crtcs, sizeof(*kdpy->saved_crtcs));
+   if (!kdpy->saved_crtcs) {
+      kms_display_destroy(&kdpy->base);
+      return NULL;
+   }
+
+   kdpy->shown_surfaces =
+      calloc(kdpy->resources->count_crtcs, sizeof(*kdpy->shown_surfaces));
+   if (!kdpy->shown_surfaces) {
+      kms_display_destroy(&kdpy->base);
+      return NULL;
+   }
+
+   kdpy->base.screen->flush_frontbuffer =
+      (void (*)(struct pipe_screen *, struct pipe_surface *, void *))
+      flush_frontbuffer;
+
+   kdpy->base.destroy = kms_display_destroy;
+   kdpy->base.get_configs = kms_display_get_configs;
+   kdpy->base.create_context = kms_display_create_context;
+   kdpy->base.create_pbuffer_surface = kms_display_create_pbuffer_surface;
+
+   kdpy->base.modeset = &kms_display_modeset;
+
+   return &kdpy->base;
+}
+
+static void
+dummy_flush_frontbuffer(void *dummy, struct pipe_surface *surf,
+                        void *context_private)
+{
+   _eglLog(_EGL_WARNING, "flush_frontbuffer is not supplied");
+}
+
+/* the api is destroyed with the native display */
+static struct drm_api *drm_api;
+
+const char *
+native_get_name(void)
+{
+   static char kms_name[32];
+
+   if (!drm_api)
+      drm_api = drm_api_create();
+
+   if (drm_api)
+      snprintf(kms_name, sizeof(kms_name), "KMS/%s", drm_api->name);
+   else
+      snprintf(kms_name, sizeof(kms_name), "KMS");
+
+   return kms_name;
+}
+
+struct native_display *
+native_create_display(EGLNativeDisplayType dpy,
+                      native_flush_frontbuffer flush_frontbuffer)
+{
+   struct native_display *ndpy = NULL;
+
+   if (!drm_api)
+      drm_api = drm_api_create();
+
+   if (!flush_frontbuffer)
+      flush_frontbuffer = dummy_flush_frontbuffer;
+
+   if (drm_api)
+      ndpy = kms_create_display(dpy, drm_api, flush_frontbuffer);
+
+   return ndpy;
+}
diff --git a/src/gallium/state_trackers/egl_g3d/kms/native_kms.h b/src/gallium/state_trackers/egl_g3d/kms/native_kms.h
new file mode 100644
index 0000000..3f869b2
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/kms/native_kms.h
@@ -0,0 +1,138 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.8
+ *
+ * Copyright (C) 2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL 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.
+ */
+
+#ifndef _NATIVE_KMS_H_
+#define _NATIVE_KMS_H_
+
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#include "pipe/p_compiler.h"
+#include "util/u_format.h"
+#include "pipe/p_state.h"
+#include "state_tracker/drm_api.h"
+
+#include "common/native.h"
+
+enum kms_surface_type {
+   KMS_SURFACE_TYPE_PBUFFER,
+   KMS_SURFACE_TYPE_SCANOUT
+};
+
+struct kms_config;
+struct kms_connector;
+struct kms_mode;
+
+struct kms_crtc {
+   drmModeCrtcPtr crtc;
+   uint32_t connectors[32];
+   int num_connectors;
+};
+
+struct kms_display {
+   struct native_display base;
+
+   int fd;
+   struct drm_api *api;
+   drmModeResPtr resources;
+   struct kms_config *config;
+
+   struct kms_connector *connectors;
+   int num_connectors;
+
+   struct kms_surface **shown_surfaces;
+   /* save the original settings of the CRTCs */
+   struct kms_crtc *saved_crtcs;
+};
+
+struct kms_framebuffer {
+   struct pipe_texture *texture;
+   boolean is_passive;
+
+   uint32_t buffer_id;
+};
+
+struct kms_surface {
+   struct native_surface base;
+   enum kms_surface_type type;
+   enum pipe_format color_format;
+   struct kms_display *kdpy;
+   int width, height;
+
+   struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
+   struct kms_framebuffer front_fb, back_fb;
+
+   boolean is_shown;
+   struct kms_crtc current_crtc;
+};
+
+struct kms_config {
+   struct native_config base;
+};
+
+struct kms_connector {
+   struct native_connector base;
+
+   uint32_t connector_id;
+   drmModeConnectorPtr connector;
+   struct kms_mode *kms_modes;
+   int num_modes;
+};
+
+struct kms_mode {
+   struct native_mode base;
+   drmModeModeInfo mode;
+};
+
+static INLINE struct kms_display *
+kms_display(const struct native_display *ndpy)
+{
+   return (struct kms_display *) ndpy;
+}
+
+static INLINE struct kms_surface *
+kms_surface(const struct native_surface *nsurf)
+{
+   return (struct kms_surface *) nsurf;
+}
+
+static INLINE struct kms_config *
+kms_config(const struct native_config *nconf)
+{
+   return (struct kms_config *) nconf;
+}
+
+static INLINE struct kms_connector *
+kms_connector(const struct native_connector *nconn)
+{
+   return (struct kms_connector *) nconn;
+}
+
+static INLINE struct kms_mode *
+kms_mode(const struct native_mode *nmode)
+{
+   return (struct kms_mode *) nmode;
+}
+
+#endif /* _NATIVE_KMS_H_ */
diff --git a/src/gallium/state_trackers/egl_g3d/x11/glxinit.c b/src/gallium/state_trackers/egl_g3d/x11/glxinit.c
new file mode 100644
index 0000000..c955a90
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/x11/glxinit.c
@@ -0,0 +1,573 @@
+/**
+ * GLX initialization.  Code based on glxext.c, glx_query.c, and
+ * glcontextmodes.c under src/glx/x11/.  The major difference is that no DRI
+ * related code here.
+ *
+ */
+
+#include <assert.h>
+#include <X11/Xlib.h>
+#include <X11/Xproto.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include <sys/time.h>
+
+#include "x11_screen.h"
+#include "glxinit.h"
+
+typedef struct GLXGenericGetString
+{
+   CARD8 reqType;
+   CARD8 glxCode;
+   CARD16 length B16;
+   CARD32 for_whom B32;
+   CARD32 name B32;
+} xGLXGenericGetStringReq;
+
+#define sz_xGLXGenericGetStringReq 12
+#define X_GLXGenericGetString 0
+
+/* Extension required boiler plate */
+
+static char *__glXExtensionName = GLX_EXTENSION_NAME;
+static XExtensionInfo *__glXExtensionInfo = NULL;
+
+static /* const */ XExtensionHooks __glXExtensionHooks = { NULL };
+static
+XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo,
+                           __glXExtensionName, &__glXExtensionHooks,
+                           __GLX_NUMBER_EVENTS, NULL)
+
+static GLint
+_gl_convert_from_x_visual_type(int visualType)
+{
+#define NUM_VISUAL_TYPES   6
+   static const int glx_visual_types[NUM_VISUAL_TYPES] = {
+      GLX_STATIC_GRAY, GLX_GRAY_SCALE,
+      GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
+      GLX_TRUE_COLOR, GLX_DIRECT_COLOR
+   };
+
+   return ((unsigned) visualType < NUM_VISUAL_TYPES)
+      ? glx_visual_types[visualType] : GLX_NONE;
+}
+
+_X_HIDDEN char *
+__glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name)
+{
+   xGLXGenericGetStringReq *req;
+   xGLXSingleReply reply;
+   int length;
+   int numbytes;
+   char *buf;
+   CARD32 for_whom = screen;
+   CARD32 glxCode = X_GLXQueryServerString;
+
+
+   LockDisplay(dpy);
+
+
+   /* All of the GLX protocol requests for getting a string from the server
+    * look the same.  The exact meaning of the for_whom field is usually
+    * either the screen number (for glXQueryServerString) or the context tag
+    * (for GLXSingle).
+    */
+
+   GetReq(GLXGenericGetString, req);
+   req->reqType = opcode;
+   req->glxCode = glxCode;
+   req->for_whom = for_whom;
+   req->name = name;
+
+   _XReply(dpy, (xReply *) & reply, 0, False);
+
+   length = reply.length * 4;
+   numbytes = reply.size;
+
+   buf = (char *) Xmalloc(numbytes);
+   if (buf != NULL) {
+      _XRead(dpy, buf, numbytes);
+      length -= numbytes;
+   }
+
+   _XEatData(dpy, length);
+
+   UnlockDisplay(dpy);
+   SyncHandle();
+
+   return buf;
+}
+
+/************************************************************************/
+/*
+** Free the per screen configs data as well as the array of
+** __glXScreenConfigs.
+*/
+static void
+FreeScreenConfigs(__GLXdisplayPrivate * priv)
+{
+   __GLXscreenConfigs *psc;
+   GLint i, screens;
+
+   /* Free screen configuration information */
+   psc = priv->screenConfigs;
+   screens = ScreenCount(priv->dpy);
+   for (i = 0; i < screens; i++, psc++) {
+      if (psc->configs) {
+         x11_context_modes_destroy(psc->configs);
+         psc->configs = NULL;   /* NOTE: just for paranoia */
+      }
+      if (psc->visuals) {
+         x11_context_modes_destroy(psc->visuals);
+         psc->visuals = NULL;   /* NOTE: just for paranoia */
+      }
+      Xfree((char *) psc->serverGLXexts);
+   }
+   XFree((char *) priv->screenConfigs);
+   priv->screenConfigs = NULL;
+}
+
+/************************************************************************/
+
+/*
+** Query the version of the GLX extension.  This procedure works even if
+** the client extension is not completely set up.
+*/
+static Bool
+QueryVersion(Display * dpy, int opcode, int *major, int *minor)
+{
+   xGLXQueryVersionReq *req;
+   xGLXQueryVersionReply reply;
+
+   /* Send the glXQueryVersion request */
+   LockDisplay(dpy);
+   GetReq(GLXQueryVersion, req);
+   req->reqType = opcode;
+   req->glxCode = X_GLXQueryVersion;
+   req->majorVersion = GLX_MAJOR_VERSION;
+   req->minorVersion = GLX_MINOR_VERSION;
+   _XReply(dpy, (xReply *) & reply, 0, False);
+   UnlockDisplay(dpy);
+   SyncHandle();
+
+   if (reply.majorVersion != GLX_MAJOR_VERSION) {
+      /*
+       ** The server does not support the same major release as this
+       ** client.
+       */
+      return GL_FALSE;
+   }
+   *major = reply.majorVersion;
+   *minor = min(reply.minorVersion, GLX_MINOR_VERSION);
+   return GL_TRUE;
+}
+
+_X_HIDDEN void
+__glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count,
+                                    const INT32 * bp, Bool tagged_only,
+                                    Bool fbconfig_style_tags)
+{
+   int i;
+
+   if (!tagged_only) {
+      /* Copy in the first set of properties */
+      config->visualID = *bp++;
+
+      config->visualType = _gl_convert_from_x_visual_type(*bp++);
+
+      config->rgbMode = *bp++;
+
+      config->redBits = *bp++;
+      config->greenBits = *bp++;
+      config->blueBits = *bp++;
+      config->alphaBits = *bp++;
+      config->accumRedBits = *bp++;
+      config->accumGreenBits = *bp++;
+      config->accumBlueBits = *bp++;
+      config->accumAlphaBits = *bp++;
+
+      config->doubleBufferMode = *bp++;
+      config->stereoMode = *bp++;
+
+      config->rgbBits = *bp++;
+      config->depthBits = *bp++;
+      config->stencilBits = *bp++;
+      config->numAuxBuffers = *bp++;
+      config->level = *bp++;
+
+      count -= __GLX_MIN_CONFIG_PROPS;
+   }
+
+   /*
+    ** Additional properties may be in a list at the end
+    ** of the reply.  They are in pairs of property type
+    ** and property value.
+    */
+
+#define FETCH_OR_SET(tag) \
+    config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1
+
+   for (i = 0; i < count; i += 2) {
+      switch (*bp++) {
+      case GLX_RGBA:
+         FETCH_OR_SET(rgbMode);
+         break;
+      case GLX_BUFFER_SIZE:
+         config->rgbBits = *bp++;
+         break;
+      case GLX_LEVEL:
+         config->level = *bp++;
+         break;
+      case GLX_DOUBLEBUFFER:
+         FETCH_OR_SET(doubleBufferMode);
+         break;
+      case GLX_STEREO:
+         FETCH_OR_SET(stereoMode);
+         break;
+      case GLX_AUX_BUFFERS:
+         config->numAuxBuffers = *bp++;
+         break;
+      case GLX_RED_SIZE:
+         config->redBits = *bp++;
+         break;
+      case GLX_GREEN_SIZE:
+         config->greenBits = *bp++;
+         break;
+      case GLX_BLUE_SIZE:
+         config->blueBits = *bp++;
+         break;
+      case GLX_ALPHA_SIZE:
+         config->alphaBits = *bp++;
+         break;
+      case GLX_DEPTH_SIZE:
+         config->depthBits = *bp++;
+         break;
+      case GLX_STENCIL_SIZE:
+         config->stencilBits = *bp++;
+         break;
+      case GLX_ACCUM_RED_SIZE:
+         config->accumRedBits = *bp++;
+         break;
+      case GLX_ACCUM_GREEN_SIZE:
+         config->accumGreenBits = *bp++;
+         break;
+      case GLX_ACCUM_BLUE_SIZE:
+         config->accumBlueBits = *bp++;
+         break;
+      case GLX_ACCUM_ALPHA_SIZE:
+         config->accumAlphaBits = *bp++;
+         break;
+      case GLX_VISUAL_CAVEAT_EXT:
+         config->visualRating = *bp++;
+         break;
+      case GLX_X_VISUAL_TYPE:
+         config->visualType = *bp++;
+         break;
+      case GLX_TRANSPARENT_TYPE:
+         config->transparentPixel = *bp++;
+         break;
+      case GLX_TRANSPARENT_INDEX_VALUE:
+         config->transparentIndex = *bp++;
+         break;
+      case GLX_TRANSPARENT_RED_VALUE:
+         config->transparentRed = *bp++;
+         break;
+      case GLX_TRANSPARENT_GREEN_VALUE:
+         config->transparentGreen = *bp++;
+         break;
+      case GLX_TRANSPARENT_BLUE_VALUE:
+         config->transparentBlue = *bp++;
+         break;
+      case GLX_TRANSPARENT_ALPHA_VALUE:
+         config->transparentAlpha = *bp++;
+         break;
+      case GLX_VISUAL_ID:
+         config->visualID = *bp++;
+         break;
+      case GLX_DRAWABLE_TYPE:
+         config->drawableType = *bp++;
+         break;
+      case GLX_RENDER_TYPE:
+         config->renderType = *bp++;
+         break;
+      case GLX_X_RENDERABLE:
+         config->xRenderable = *bp++;
+         break;
+      case GLX_FBCONFIG_ID:
+         config->fbconfigID = *bp++;
+         break;
+      case GLX_MAX_PBUFFER_WIDTH:
+         config->maxPbufferWidth = *bp++;
+         break;
+      case GLX_MAX_PBUFFER_HEIGHT:
+         config->maxPbufferHeight = *bp++;
+         break;
+      case GLX_MAX_PBUFFER_PIXELS:
+         config->maxPbufferPixels = *bp++;
+         break;
+      case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
+         config->optimalPbufferWidth = *bp++;
+         break;
+      case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
+         config->optimalPbufferHeight = *bp++;
+         break;
+      case GLX_VISUAL_SELECT_GROUP_SGIX:
+         config->visualSelectGroup = *bp++;
+         break;
+      case GLX_SWAP_METHOD_OML:
+         config->swapMethod = *bp++;
+         break;
+      case GLX_SAMPLE_BUFFERS_SGIS:
+         config->sampleBuffers = *bp++;
+         break;
+      case GLX_SAMPLES_SGIS:
+         config->samples = *bp++;
+         break;
+      case GLX_BIND_TO_TEXTURE_RGB_EXT:
+         config->bindToTextureRgb = *bp++;
+         break;
+      case GLX_BIND_TO_TEXTURE_RGBA_EXT:
+         config->bindToTextureRgba = *bp++;
+         break;
+      case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
+         config->bindToMipmapTexture = *bp++;
+         break;
+      case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
+         config->bindToTextureTargets = *bp++;
+         break;
+      case GLX_Y_INVERTED_EXT:
+         config->yInverted = *bp++;
+         break;
+      case None:
+         i = count;
+         break;
+      default:
+         break;
+      }
+   }
+
+   config->renderType =
+      (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
+
+   config->haveAccumBuffer = ((config->accumRedBits +
+                               config->accumGreenBits +
+                               config->accumBlueBits +
+                               config->accumAlphaBits) > 0);
+   config->haveDepthBuffer = (config->depthBits > 0);
+   config->haveStencilBuffer = (config->stencilBits > 0);
+}
+
+static __GLcontextModes *
+createConfigsFromProperties(Display * dpy, int nvisuals, int nprops,
+                            int screen, GLboolean tagged_only)
+{
+   INT32 buf[__GLX_TOTAL_CONFIG], *props;
+   unsigned prop_size;
+   __GLcontextModes *modes, *m;
+   int i;
+
+   if (nprops == 0)
+      return NULL;
+
+   /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */
+
+   /* Check number of properties */
+   if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS)
+      return NULL;
+
+   /* Allocate memory for our config structure */
+   modes = x11_context_modes_create(nvisuals);
+   if (!modes)
+      return NULL;
+
+   prop_size = nprops * __GLX_SIZE_INT32;
+   if (prop_size <= sizeof(buf))
+      props = buf;
+   else
+      props = Xmalloc(prop_size);
+
+   /* Read each config structure and convert it into our format */
+   m = modes;
+   for (i = 0; i < nvisuals; i++) {
+      _XRead(dpy, (char *) props, prop_size);
+      /* Older X servers don't send this so we default it here. */
+      m->drawableType = GLX_WINDOW_BIT;
+      __glXInitializeVisualConfigFromTags(m, nprops, props,
+                                     tagged_only, GL_TRUE);
+      m->screen = screen;
+      m = m->next;
+   }
+
+   if (props != buf)
+      Xfree(props);
+
+   return modes;
+}
+
+static GLboolean
+getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
+{
+   xGLXGetVisualConfigsReq *req;
+   __GLXscreenConfigs *psc;
+   xGLXGetVisualConfigsReply reply;
+
+   LockDisplay(dpy);
+
+   psc = priv->screenConfigs + screen;
+   psc->visuals = NULL;
+   GetReq(GLXGetVisualConfigs, req);
+   req->reqType = priv->majorOpcode;
+   req->glxCode = X_GLXGetVisualConfigs;
+   req->screen = screen;
+
+   if (!_XReply(dpy, (xReply *) & reply, 0, False))
+      goto out;
+
+   psc->visuals = createConfigsFromProperties(dpy,
+                                              reply.numVisuals,
+                                              reply.numProps,
+                                              screen, GL_FALSE);
+
+ out:
+   UnlockDisplay(dpy);
+   return psc->visuals != NULL;
+}
+
+static GLboolean
+getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
+{
+   xGLXGetFBConfigsReq *fb_req;
+   xGLXGetFBConfigsSGIXReq *sgi_req;
+   xGLXVendorPrivateWithReplyReq *vpreq;
+   xGLXGetFBConfigsReply reply;
+   __GLXscreenConfigs *psc;
+
+   psc = priv->screenConfigs + screen;
+   psc->serverGLXexts =
+      __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS);
+
+   LockDisplay(dpy);
+
+   psc->configs = NULL;
+   if (atof(priv->serverGLXversion) >= 1.3) {
+      GetReq(GLXGetFBConfigs, fb_req);
+      fb_req->reqType = priv->majorOpcode;
+      fb_req->glxCode = X_GLXGetFBConfigs;
+      fb_req->screen = screen;
+   }
+   else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) {
+      GetReqExtra(GLXVendorPrivateWithReply,
+                  sz_xGLXGetFBConfigsSGIXReq +
+                  sz_xGLXVendorPrivateWithReplyReq, vpreq);
+      sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
+      sgi_req->reqType = priv->majorOpcode;
+      sgi_req->glxCode = X_GLXVendorPrivateWithReply;
+      sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
+      sgi_req->screen = screen;
+   }
+   else
+      goto out;
+
+   if (!_XReply(dpy, (xReply *) & reply, 0, False))
+      goto out;
+
+   psc->configs = createConfigsFromProperties(dpy,
+                                              reply.numFBConfigs,
+                                              reply.numAttribs * 2,
+                                              screen, GL_TRUE);
+
+ out:
+   UnlockDisplay(dpy);
+   return psc->configs != NULL;
+}
+
+static GLboolean
+AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
+{
+   __GLXscreenConfigs *psc;
+   GLint i, screens;
+
+   /*
+    ** First allocate memory for the array of per screen configs.
+    */
+   screens = ScreenCount(dpy);
+   psc = (__GLXscreenConfigs *) Xmalloc(screens * sizeof(__GLXscreenConfigs));
+   if (!psc) {
+      return GL_FALSE;
+   }
+   memset(psc, 0, screens * sizeof(__GLXscreenConfigs));
+   priv->screenConfigs = psc;
+
+   priv->serverGLXversion =
+      __glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION);
+   if (priv->serverGLXversion == NULL) {
+      FreeScreenConfigs(priv);
+      return GL_FALSE;
+   }
+
+   for (i = 0; i < screens; i++, psc++) {
+      getFBConfigs(dpy, priv, i);
+      getVisualConfigs(dpy, priv, i);
+      psc->scr = i;
+      psc->dpy = dpy;
+   }
+
+   SyncHandle();
+
+   return GL_TRUE;
+}
+
+_X_HIDDEN void
+__glXRelease(__GLXdisplayPrivate *dpyPriv)
+{
+   FreeScreenConfigs(dpyPriv);
+
+   if (dpyPriv->serverGLXvendor) {
+      Xfree((char *) dpyPriv->serverGLXvendor);
+      dpyPriv->serverGLXvendor = NULL;
+   }
+   if (dpyPriv->serverGLXversion) {
+      Xfree((char *) dpyPriv->serverGLXversion);
+      dpyPriv->serverGLXversion = NULL;
+   }
+
+   Xfree(dpyPriv);
+}
+
+_X_HIDDEN __GLXdisplayPrivate *
+__glXInitialize(Display * dpy)
+{
+   XExtDisplayInfo *info = __glXFindDisplay(dpy);
+   __GLXdisplayPrivate *dpyPriv;
+   int major, minor;
+
+   if (!XextHasExtension(info))
+      return NULL;
+
+   /* See if the versions are compatible */
+   if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor))
+      return NULL;
+
+   dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate));
+   if (!dpyPriv)
+      return NULL;
+
+   /*
+    ** Init the display private and then read in the screen config
+    ** structures from the server.
+    */
+   dpyPriv->majorOpcode = info->codes->major_opcode;
+   dpyPriv->majorVersion = major;
+   dpyPriv->minorVersion = minor;
+   dpyPriv->dpy = dpy;
+
+   dpyPriv->serverGLXvendor = NULL;
+   dpyPriv->serverGLXversion = NULL;
+
+   if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
+      Xfree(dpyPriv);
+      return NULL;
+   }
+
+   return dpyPriv;
+}
diff --git a/src/gallium/state_trackers/egl_g3d/x11/glxinit.h b/src/gallium/state_trackers/egl_g3d/x11/glxinit.h
new file mode 100644
index 0000000..515a825
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/x11/glxinit.h
@@ -0,0 +1,14 @@
+#ifndef GLXINIT_INCLUDED
+#define GLXINIT_INCLUDED
+
+#include <X11/Xlib.h>
+
+#ifndef GLX_DIRECT_RENDERING
+#define GLX_DIRECT_RENDERING
+#endif
+#include "glxclient.h"
+
+extern void
+__glXRelease(__GLXdisplayPrivate *dpyPriv);
+
+#endif /* GLXINIT_INCLUDED */
diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c b/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c
new file mode 100644
index 0000000..0dda786
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c
@@ -0,0 +1,693 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL 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 "util/u_memory.h"
+#include "util/u_math.h"
+#include "util/u_format.h"
+#include "pipe/p_compiler.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "state_tracker/drm_api.h"
+#include "egllog.h"
+
+#include "native_x11.h"
+#include "x11_screen.h"
+
+enum dri2_surface_type {
+   DRI2_SURFACE_TYPE_WINDOW,
+   DRI2_SURFACE_TYPE_PIXMAP,
+   DRI2_SURFACE_TYPE_PBUFFER
+};
+
+struct dri2_display {
+   struct native_display base;
+   Display *dpy;
+   boolean own_dpy;
+
+   struct drm_api *api;
+   struct x11_screen *xscr;
+   int xscr_number;
+
+   struct dri2_config *configs;
+   int num_configs;
+};
+
+struct dri2_surface {
+   struct native_surface base;
+   Drawable drawable;
+   enum dri2_surface_type type;
+   enum pipe_format color_format;
+   struct dri2_display *dri2dpy;
+
+   struct pipe_texture *pbuffer_textures[NUM_NATIVE_ATTACHMENTS];
+   boolean have_back, have_fake;
+   int width, height;
+};
+
+struct dri2_config {
+   struct native_config base;
+};
+
+static INLINE struct dri2_display *
+dri2_display(const struct native_display *ndpy)
+{
+   return (struct dri2_display *) ndpy;
+}
+
+static INLINE struct dri2_surface *
+dri2_surface(const struct native_surface *nsurf)
+{
+   return (struct dri2_surface *) nsurf;
+}
+
+static INLINE struct dri2_config *
+dri2_config(const struct native_config *nconf)
+{
+   return (struct dri2_config *) nconf;
+}
+
+static boolean
+dri2_surface_flush_frontbuffer(struct native_surface *nsurf)
+{
+   struct dri2_surface *dri2surf = dri2_surface(nsurf);
+   struct dri2_display *dri2dpy = dri2surf->dri2dpy;
+
+   /* pbuffer is private */
+   if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER)
+      return TRUE;
+
+   /* copy to real front buffer */
+   if (dri2surf->have_fake)
+      x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
+            0, 0, dri2surf->width, dri2surf->height,
+            DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
+
+   return TRUE;
+}
+
+static boolean
+dri2_surface_swap_buffers(struct native_surface *nsurf)
+{
+   struct dri2_surface *dri2surf = dri2_surface(nsurf);
+   struct dri2_display *dri2dpy = dri2surf->dri2dpy;
+
+   /* pbuffer is private */
+   if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER)
+      return TRUE;
+
+   /* copy to front buffer */
+   if (dri2surf->have_back)
+      x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
+            0, 0, dri2surf->width, dri2surf->height,
+            DRI2BufferBackLeft, DRI2BufferFrontLeft);
+
+   /* and update fake front buffer */
+   if (dri2surf->have_fake)
+      x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
+            0, 0, dri2surf->width, dri2surf->height,
+            DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
+
+   return TRUE;
+}
+
+static boolean
+dri2_surface_validate(struct native_surface *nsurf,
+                             const enum native_attachment *natts,
+                             unsigned num_natts,
+                             struct pipe_texture **textures,
+                             int *width, int *height)
+{
+   struct dri2_surface *dri2surf = dri2_surface(nsurf);
+   struct dri2_display *dri2dpy = dri2surf->dri2dpy;
+   unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS];
+   EGLint texture_indices[NUM_NATIVE_ATTACHMENTS];
+   struct pipe_texture templ;
+   struct x11_drawable_buffer *xbufs;
+   int num_ins, num_outs, i;
+
+   if (num_natts) {
+      memset(&templ, 0, sizeof(templ));
+      templ.target = PIPE_TEXTURE_2D;
+      templ.last_level = 0;
+      templ.width0 = dri2surf->width;
+      templ.height0 = dri2surf->height;
+      templ.depth0 = 1;
+      templ.format = dri2surf->color_format;
+      templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+
+      if (textures)
+         memset(textures, 0, sizeof(*textures) * num_natts);
+   }
+
+   /* create textures for pbuffer */
+   if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) {
+      struct pipe_screen *screen = dri2dpy->base.screen;
+
+      for (i = 0; i < num_natts; i++) {
+         enum native_attachment natt = natts[i];
+         struct pipe_texture *ptex = dri2surf->pbuffer_textures[natt];
+
+         if (!ptex) {
+            ptex = screen->texture_create(screen, &templ);
+            dri2surf->pbuffer_textures[natt] = ptex;
+         }
+
+         if (textures)
+            pipe_texture_reference(&textures[i], ptex);
+      }
+
+      if (width)
+         *width = dri2surf->width;
+      if (height)
+         *height = dri2surf->height;
+
+      return TRUE;
+   }
+
+   for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++)
+      texture_indices[i] = -1;
+
+   /* prepare the attachments */
+   num_ins = num_natts;
+   for (i = 0; i < num_natts; i++) {
+      unsigned int dri2att;
+
+      switch (natts[i]) {
+      case NATIVE_ATTACHMENT_FRONT_LEFT:
+         dri2att = DRI2BufferFrontLeft;
+         break;
+      case NATIVE_ATTACHMENT_BACK_LEFT:
+         dri2att = DRI2BufferBackLeft;
+         break;
+      case NATIVE_ATTACHMENT_FRONT_RIGHT:
+         dri2att = DRI2BufferFrontRight;
+         break;
+      case NATIVE_ATTACHMENT_BACK_RIGHT:
+         dri2att = DRI2BufferBackRight;
+         break;
+      default:
+         assert(0);
+         dri2att = 0;
+         break;
+      }
+      dri2atts[i] = dri2att;
+      texture_indices[natts[i]] = i;
+   }
+
+   dri2surf->have_back = FALSE;
+   dri2surf->have_fake = FALSE;
+
+   xbufs = x11_drawable_get_buffers(dri2dpy->xscr, dri2surf->drawable,
+                                    &dri2surf->width, &dri2surf->height,
+                                    dri2atts, FALSE, num_ins, &num_outs);
+   if (!xbufs)
+      return FALSE;
+
+   /* update width and height */
+   templ.width0 = dri2surf->width;
+   templ.height0 = dri2surf->height;
+
+   for (i = 0; i < num_outs; i++) {
+      struct x11_drawable_buffer *xbuf = &xbufs[i];
+      const char *desc;
+      enum native_attachment natt;
+
+      switch (xbuf->attachment) {
+      case DRI2BufferFrontLeft:
+         natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+         desc = "DRI2 Front Buffer";
+         break;
+      case DRI2BufferFakeFrontLeft:
+         natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+         desc = "DRI2 Fake Front Buffer";
+         dri2surf->have_fake = TRUE;
+         break;
+      case DRI2BufferBackLeft:
+         natt = NATIVE_ATTACHMENT_BACK_LEFT;
+         desc = "DRI2 Back Buffer";
+         dri2surf->have_back = TRUE;
+         break;
+      default:
+         desc = NULL;
+         break;
+      }
+
+      if (!desc || texture_indices[natt] < 0 ||
+          (textures && textures[texture_indices[natt]])) {
+         if (!desc)
+            _eglLog(_EGL_WARNING, "unknown buffer %d", xbuf->attachment);
+         else if (texture_indices[natt] < 0)
+            _eglLog(_EGL_WARNING, "unexpected buffer %d", xbuf->attachment);
+         else if (textures && textures[texture_indices[natt]])
+            _eglLog(_EGL_WARNING, "both real and fake front buffers are listed");
+         continue;
+      }
+
+      if (textures) {
+         struct pipe_texture *ptex =
+            dri2dpy->api->texture_from_shared_handle(dri2dpy->api,
+                  dri2dpy->base.screen, &templ,
+                  desc, xbuf->pitch, xbuf->name);
+         if (ptex) {
+            /* the caller owns the textures */
+            textures[texture_indices[natt]] = ptex;
+         }
+      }
+   }
+
+   free(xbufs);
+
+   if (width)
+      *width = dri2surf->width;
+   if (height)
+      *height = dri2surf->height;
+
+   return TRUE;
+}
+
+static void
+dri2_surface_wait(struct native_surface *nsurf)
+{
+   struct dri2_surface *dri2surf = dri2_surface(nsurf);
+   struct dri2_display *dri2dpy = dri2surf->dri2dpy;
+
+   if (dri2surf->have_fake) {
+      x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
+            0, 0, dri2surf->width, dri2surf->height,
+            DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
+   }
+}
+
+static void
+dri2_surface_destroy(struct native_surface *nsurf)
+{
+   struct dri2_surface *dri2surf = dri2_surface(nsurf);
+   int i;
+
+   for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
+      struct pipe_texture *ptex = dri2surf->pbuffer_textures[i];
+      pipe_texture_reference(&ptex, NULL);
+   }
+
+   if (dri2surf->drawable)
+      x11_drawable_enable_dri2(dri2surf->dri2dpy->xscr,
+            dri2surf->drawable, FALSE);
+   free(dri2surf);
+}
+
+static struct dri2_surface *
+dri2_display_create_surface(struct native_display *ndpy,
+                            enum dri2_surface_type type,
+                            Drawable drawable,
+                            const struct native_config *nconf)
+{
+   struct dri2_display *dri2dpy = dri2_display(ndpy);
+   struct dri2_config *dri2conf = dri2_config(nconf);
+   struct dri2_surface *dri2surf;
+
+   dri2surf = CALLOC_STRUCT(dri2_surface);
+   if (!dri2surf)
+      return NULL;
+
+   if (drawable)
+      x11_drawable_enable_dri2(dri2dpy->xscr, drawable, TRUE);
+
+   dri2surf->dri2dpy = dri2dpy;
+   dri2surf->type = type;
+   dri2surf->drawable = drawable;
+   dri2surf->color_format = dri2conf->base.color_format;
+
+   dri2surf->base.destroy = dri2_surface_destroy;
+   dri2surf->base.swap_buffers = dri2_surface_swap_buffers;
+   dri2surf->base.flush_frontbuffer = dri2_surface_flush_frontbuffer;
+   dri2surf->base.validate = dri2_surface_validate;
+   dri2surf->base.wait = dri2_surface_wait;
+
+   return dri2surf;
+}
+
+static struct native_surface *
+dri2_display_create_window_surface(struct native_display *ndpy,
+                                   EGLNativeWindowType win,
+                                   const struct native_config *nconf)
+{
+   struct dri2_surface *dri2surf;
+
+   dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_WINDOW,
+         (Drawable) win, nconf);
+   return (dri2surf) ? &dri2surf->base : NULL;
+}
+
+static struct native_surface *
+dri2_display_create_pixmap_surface(struct native_display *ndpy,
+                                   EGLNativePixmapType pix,
+                                   const struct native_config *nconf)
+{
+   struct dri2_surface *dri2surf;
+
+   dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_PIXMAP,
+         (Drawable) pix, nconf);
+   return (dri2surf) ? &dri2surf->base : NULL;
+}
+
+static struct native_surface *
+dri2_display_create_pbuffer_surface(struct native_display *ndpy,
+                                    const struct native_config *nconf,
+                                    uint width, uint height)
+{
+   struct dri2_surface *dri2surf;
+
+   dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_PBUFFER,
+         (Drawable) None, nconf);
+   if (dri2surf) {
+      dri2surf->width = width;
+      dri2surf->height = height;
+   }
+   return (dri2surf) ? &dri2surf->base : NULL;
+}
+
+static struct pipe_context *
+dri2_display_create_context(struct native_display *ndpy, void *context_private)
+{
+   struct dri2_display *dri2dpy = dri2_display(ndpy);
+   struct pipe_context *pctx;
+
+   pctx = dri2dpy->api->create_context(dri2dpy->api, dri2dpy->base.screen);
+   if (pctx)
+      pctx->priv = context_private;
+   return pctx;
+}
+
+static int
+choose_color_format(const __GLcontextModes *mode, enum pipe_format formats[32])
+{
+   int count = 0;
+
+   switch (mode->rgbBits) {
+   case 32:
+      formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
+      formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM;
+      break;
+   case 24:
+      formats[count++] = PIPE_FORMAT_X8R8G8B8_UNORM;
+      formats[count++] = PIPE_FORMAT_B8G8R8X8_UNORM;
+      formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
+      formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM;
+      break;
+   case 16:
+      formats[count++] = PIPE_FORMAT_R5G6B5_UNORM;
+      break;
+   default:
+      break;
+   }
+
+   return count;
+}
+
+static int
+choose_depth_stencil_format(const __GLcontextModes *mode,
+                            enum pipe_format formats[32])
+{
+   int count = 0;
+
+   switch (mode->depthBits) {
+   case 32:
+      formats[count++] = PIPE_FORMAT_Z32_UNORM;
+      break;
+   case 24:
+      if (mode->stencilBits) {
+         formats[count++] = PIPE_FORMAT_S8Z24_UNORM;
+         formats[count++] = PIPE_FORMAT_Z24S8_UNORM;
+      }
+      else {
+         formats[count++] = PIPE_FORMAT_X8Z24_UNORM;
+         formats[count++] = PIPE_FORMAT_Z24X8_UNORM;
+      }
+      break;
+   case 16:
+      formats[count++] = PIPE_FORMAT_Z16_UNORM;
+      break;
+   default:
+      break;
+   }
+
+   return count;
+}
+
+static boolean
+is_format_supported(struct pipe_screen *screen,
+                    enum pipe_format fmt, boolean is_color)
+{
+   return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D,
+         (is_color) ? PIPE_TEXTURE_USAGE_RENDER_TARGET :
+         PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+}
+
+static boolean
+dri2_display_convert_config(struct native_display *ndpy,
+                            const __GLcontextModes *mode,
+                            struct native_config *nconf)
+{
+   enum pipe_format formats[32];
+   int num_formats, i;
+
+   if (!(mode->renderType & GLX_RGBA_BIT) || !mode->rgbMode)
+      return FALSE;
+
+   /* skip single-buffered configs */
+   if (!mode->doubleBufferMode)
+      return FALSE;
+
+   nconf->mode = *mode;
+   nconf->mode.renderType = GLX_RGBA_BIT;
+   nconf->mode.rgbMode = TRUE;
+   /* pbuffer is allocated locally and is always supported */
+   nconf->mode.drawableType |= GLX_PBUFFER_BIT;
+   /* the swap method is always copy */
+   nconf->mode.swapMethod = GLX_SWAP_COPY_OML;
+
+   /* fix up */
+   nconf->mode.rgbBits =
+      nconf->mode.redBits + nconf->mode.greenBits +
+      nconf->mode.blueBits + nconf->mode.alphaBits;
+   if (!(nconf->mode.drawableType & GLX_WINDOW_BIT)) {
+      nconf->mode.visualID = 0;
+      nconf->mode.visualType = GLX_NONE;
+   }
+   if (!(nconf->mode.drawableType & GLX_PBUFFER_BIT)) {
+      nconf->mode.bindToTextureRgb = FALSE;
+      nconf->mode.bindToTextureRgba = FALSE;
+   }
+
+   nconf->color_format = PIPE_FORMAT_NONE;
+   nconf->depth_format = PIPE_FORMAT_NONE;
+   nconf->stencil_format = PIPE_FORMAT_NONE;
+
+   /* choose color format */
+   num_formats = choose_color_format(mode, formats);
+   for (i = 0; i < num_formats; i++) {
+      if (is_format_supported(ndpy->screen, formats[i], TRUE)) {
+         nconf->color_format = formats[i];
+         break;
+      }
+   }
+   if (nconf->color_format == PIPE_FORMAT_NONE)
+      return FALSE;
+
+   /* choose depth/stencil format */
+   num_formats = choose_depth_stencil_format(mode, formats);
+   for (i = 0; i < num_formats; i++) {
+      if (is_format_supported(ndpy->screen, formats[i], FALSE)) {
+         nconf->depth_format = formats[i];
+         nconf->stencil_format = formats[i];
+         break;
+      }
+   }
+   if ((nconf->mode.depthBits && nconf->depth_format == PIPE_FORMAT_NONE) ||
+       (nconf->mode.stencilBits && nconf->stencil_format == PIPE_FORMAT_NONE))
+      return FALSE;
+
+   return TRUE;
+}
+
+static const struct native_config **
+dri2_display_get_configs(struct native_display *ndpy, int *num_configs)
+{
+   struct dri2_display *dri2dpy = dri2_display(ndpy);
+   const struct native_config **configs;
+   int i;
+
+   /* first time */
+   if (!dri2dpy->configs) {
+      const __GLcontextModes *modes;
+      int num_modes, count;
+
+      modes = x11_screen_get_glx_configs(dri2dpy->xscr);
+      if (!modes)
+         return NULL;
+      num_modes = x11_context_modes_count(modes);
+
+      dri2dpy->configs = calloc(num_modes, sizeof(*dri2dpy->configs));
+      if (!dri2dpy->configs)
+         return NULL;
+
+      count = 0;
+      for (i = 0; i < num_modes; i++) {
+         struct native_config *nconf = &dri2dpy->configs[count].base;
+         if (dri2_display_convert_config(&dri2dpy->base, modes, nconf))
+            count++;
+         modes = modes->next;
+      }
+
+      dri2dpy->num_configs = count;
+   }
+
+   configs = malloc(dri2dpy->num_configs * sizeof(*configs));
+   if (configs) {
+      for (i = 0; i < dri2dpy->num_configs; i++)
+         configs[i] = (const struct native_config *) &dri2dpy->configs[i];
+      if (num_configs)
+         *num_configs = dri2dpy->num_configs;
+   }
+
+   return configs;
+}
+
+static void
+dri2_display_destroy(struct native_display *ndpy)
+{
+   struct dri2_display *dri2dpy = dri2_display(ndpy);
+
+   if (dri2dpy->configs)
+      free(dri2dpy->configs);
+
+   if (dri2dpy->base.screen)
+      dri2dpy->base.screen->destroy(dri2dpy->base.screen);
+
+   if (dri2dpy->xscr)
+      x11_screen_destroy(dri2dpy->xscr);
+   if (dri2dpy->own_dpy)
+      XCloseDisplay(dri2dpy->dpy);
+   if (dri2dpy->api && dri2dpy->api->destroy)
+      dri2dpy->api->destroy(dri2dpy->api);
+   free(dri2dpy);
+}
+
+/**
+ * Initialize DRI2 and pipe screen.
+ */
+static boolean
+dri2_display_init_screen(struct native_display *ndpy)
+{
+   struct dri2_display *dri2dpy = dri2_display(ndpy);
+   const char *driver = dri2dpy->api->name;
+   struct drm_create_screen_arg arg;
+   int fd;
+
+   if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) ||
+       !x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_GLX)) {
+      _eglLog(_EGL_WARNING, "GLX/DRI2 is not supported");
+      return FALSE;
+   }
+
+   fd = x11_screen_enable_dri2(dri2dpy->xscr, driver);
+   if (fd < 0)
+      return FALSE;
+
+   memset(&arg, 0, sizeof(arg));
+   arg.mode = DRM_CREATE_NORMAL;
+   dri2dpy->base.screen = dri2dpy->api->create_screen(dri2dpy->api, fd, &arg);
+   if (!dri2dpy->base.screen) {
+      _eglLog(_EGL_WARNING, "failed to create DRM screen");
+      return FALSE;
+   }
+
+   return TRUE;
+}
+
+static void
+dri2_display_flush_frontbuffer(void *dummy, struct pipe_surface *surf,
+                               void *context_private)
+{
+   /* TODO get native surface from context private, and remove the callback */
+   _eglLog(_EGL_WARNING, "flush_frontbuffer is not supplied");
+}
+
+struct native_display *
+x11_create_dri2_display(EGLNativeDisplayType dpy,
+                        struct drm_api *api,
+                        native_flush_frontbuffer flush_frontbuffer)
+{
+   struct dri2_display *dri2dpy;
+
+   dri2dpy = CALLOC_STRUCT(dri2_display);
+   if (!dri2dpy)
+      return NULL;
+
+   dri2dpy->api = api;
+   if (!dri2dpy->api) {
+      _eglLog(_EGL_WARNING, "failed to create DRM API");
+      free(dri2dpy);
+      return NULL;
+   }
+
+   dri2dpy->dpy = dpy;
+   if (!dri2dpy->dpy) {
+      dri2dpy->dpy = XOpenDisplay(NULL);
+      if (!dri2dpy->dpy) {
+         dri2_display_destroy(&dri2dpy->base);
+         return NULL;
+      }
+      dri2dpy->own_dpy = TRUE;
+   }
+
+   dri2dpy->xscr_number = DefaultScreen(dri2dpy->dpy);
+   dri2dpy->xscr = x11_screen_create(dri2dpy->dpy, dri2dpy->xscr_number);
+   if (!dri2dpy->xscr) {
+      dri2_display_destroy(&dri2dpy->base);
+      return NULL;
+   }
+
+   if (!dri2_display_init_screen(&dri2dpy->base)) {
+      dri2_display_destroy(&dri2dpy->base);
+      return NULL;
+   }
+
+   if (!flush_frontbuffer)
+      flush_frontbuffer = dri2_display_flush_frontbuffer;
+
+   dri2dpy->base.screen->flush_frontbuffer =
+      (void (*)(struct pipe_screen *, struct pipe_surface *, void *))
+      flush_frontbuffer;
+
+   dri2dpy->base.destroy = dri2_display_destroy;
+   dri2dpy->base.get_configs = dri2_display_get_configs;
+   dri2dpy->base.create_context = dri2_display_create_context;
+   dri2dpy->base.create_window_surface = dri2_display_create_window_surface;
+   dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface;
+   dri2dpy->base.create_pbuffer_surface = dri2_display_create_pbuffer_surface;
+
+   return &dri2dpy->base;
+}
diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_x11.c b/src/gallium/state_trackers/egl_g3d/x11/native_x11.c
new file mode 100644
index 0000000..a4f36e9
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/x11/native_x11.c
@@ -0,0 +1,73 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL 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 <string.h>
+#include "util/u_debug.h"
+#include "state_tracker/drm_api.h"
+#include "egllog.h"
+
+#include "native_x11.h"
+
+static struct drm_api *api;
+
+const char *
+native_get_name(void)
+{
+   static char x11_name[32];
+
+   if (!api)
+      api = drm_api_create();
+
+   if (api)
+      snprintf(x11_name, sizeof(x11_name), "X11/%s", api->name);
+   else
+      snprintf(x11_name, sizeof(x11_name), "X11");
+
+   return x11_name;
+}
+
+struct native_display *
+native_create_display(EGLNativeDisplayType dpy,
+                      native_flush_frontbuffer flush_frontbuffer)
+{
+   struct native_display *ndpy = NULL;
+   boolean force_sw;
+
+   if (!api)
+      api = drm_api_create();
+
+   force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
+   if (api && !force_sw) {
+      ndpy = x11_create_dri2_display(dpy, api, flush_frontbuffer);
+   }
+
+   if (!ndpy) {
+      EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING;
+
+      _eglLog(level, "use software fallback");
+      ndpy = x11_create_ximage_display(dpy, TRUE, flush_frontbuffer);
+   }
+
+   return ndpy;
+}
diff --git a/src/mesa/shader/grammar/grammar_mesa.h b/src/gallium/state_trackers/egl_g3d/x11/native_x11.h
similarity index 64%
rename from src/mesa/shader/grammar/grammar_mesa.h
rename to src/gallium/state_trackers/egl_g3d/x11/native_x11.h
index 6c92c58..9217eb6 100644
--- a/src/mesa/shader/grammar/grammar_mesa.h
+++ b/src/gallium/state_trackers/egl_g3d/x11/native_x11.h
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.1
+ * Version:  7.8
  *
- * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -22,22 +22,20 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#ifndef GRAMMAR_MESA_H
-#define GRAMMAR_MESA_H
+#ifndef _NATIVE_X11_H_
+#define _NATIVE_X11_H_
 
+#include "state_tracker/drm_api.h"
+#include "common/native.h"
 
-#include "main/imports.h"
-/* NOTE: include Mesa 3-D specific headers here */
+struct native_display *
+x11_create_ximage_display(EGLNativeDisplayType dpy,
+                          boolean use_xshm,
+                          native_flush_frontbuffer flush_frontbuffer);
 
+struct native_display *
+x11_create_dri2_display(EGLNativeDisplayType dpy,
+                        struct drm_api *api,
+                        native_flush_frontbuffer flush_frontbuffer);
 
-typedef GLuint grammar;
-typedef GLubyte byte;
-
-
-#define GRAMMAR_PORT_INCLUDE 1
-#include "grammar.h"
-#undef GRAMMAR_PORT_INCLUDE
-
-
-#endif
-
+#endif /* _NATIVE_X11_H_ */
diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c b/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c
new file mode 100644
index 0000000..e02faa9
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c
@@ -0,0 +1,680 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL 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 <assert.h>
+#include <sys/ipc.h>
+#include <sys/types.h>
+#include <sys/shm.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XShm.h>
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "util/u_format.h"
+#include "pipe/p_compiler.h"
+#include "pipe/internal/p_winsys_screen.h"
+#include "softpipe/sp_winsys.h"
+#include "egllog.h"
+
+#include "sw_winsys.h"
+#include "native_x11.h"
+#include "x11_screen.h"
+
+enum ximage_surface_type {
+   XIMAGE_SURFACE_TYPE_WINDOW,
+   XIMAGE_SURFACE_TYPE_PIXMAP,
+   XIMAGE_SURFACE_TYPE_PBUFFER
+};
+
+struct ximage_display {
+   struct native_display base;
+   Display *dpy;
+   boolean own_dpy;
+
+   struct x11_screen *xscr;
+   int xscr_number;
+
+   boolean use_xshm;
+
+   struct pipe_winsys *winsys;
+   struct ximage_config *configs;
+   int num_configs;
+};
+
+struct ximage_buffer {
+   XImage *ximage;
+
+   struct pipe_texture *texture;
+   struct pipe_transfer *transfer;
+   XShmSegmentInfo *shm_info;
+   boolean xshm_attached;
+};
+
+struct ximage_surface {
+   struct native_surface base;
+   Drawable drawable;
+   enum ximage_surface_type type;
+   enum pipe_format color_format;
+   XVisualInfo visual;
+   struct ximage_display *xdpy;
+
+   int width, height;
+   GC gc;
+
+   struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS];
+};
+
+struct ximage_config {
+   struct native_config base;
+   const XVisualInfo *visual;
+};
+
+static INLINE struct ximage_display *
+ximage_display(const struct native_display *ndpy)
+{
+   return (struct ximage_display *) ndpy;
+}
+
+static INLINE struct ximage_surface *
+ximage_surface(const struct native_surface *nsurf)
+{
+   return (struct ximage_surface *) nsurf;
+}
+
+static INLINE struct ximage_config *
+ximage_config(const struct native_config *nconf)
+{
+   return (struct ximage_config *) nconf;
+}
+
+static void
+ximage_surface_free_buffer(struct native_surface *nsurf,
+                           enum native_attachment which)
+{
+   struct ximage_surface *xsurf = ximage_surface(nsurf);
+   struct ximage_buffer *xbuf = &xsurf->buffers[which];
+   struct pipe_screen *screen = xsurf->xdpy->base.screen;
+
+   if (xbuf->transfer) {
+      screen->tex_transfer_destroy(xbuf->transfer);
+      xbuf->transfer = NULL;
+   }
+   pipe_texture_reference(&xbuf->texture, NULL);
+
+   if (xbuf->shm_info) {
+      if (xbuf->xshm_attached)
+         XShmDetach(xsurf->xdpy->dpy, xbuf->shm_info);
+      if (xbuf->shm_info->shmaddr != (void *) -1)
+         shmdt(xbuf->shm_info->shmaddr);
+      if (xbuf->shm_info->shmid != -1)
+         shmctl(xbuf->shm_info->shmid, IPC_RMID, 0);
+
+      xbuf->shm_info->shmaddr = (void *) -1;
+      xbuf->shm_info->shmid = -1;
+   }
+}
+
+static boolean
+ximage_surface_alloc_buffer(struct native_surface *nsurf,
+                            enum native_attachment which)
+{
+   struct ximage_surface *xsurf = ximage_surface(nsurf);
+   struct ximage_buffer *xbuf = &xsurf->buffers[which];
+   struct pipe_screen *screen = xsurf->xdpy->base.screen;
+   struct pipe_texture templ;
+
+   /* free old data */
+   if (xbuf->texture)
+      ximage_surface_free_buffer(&xsurf->base, which);
+
+   memset(&templ, 0, sizeof(templ));
+   templ.target = PIPE_TEXTURE_2D;
+   templ.format = xsurf->color_format;
+   templ.width0 = xsurf->width;
+   templ.height0 = xsurf->height;
+   templ.depth0 = 1;
+   templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+
+   if (xbuf->shm_info) {
+      struct pipe_buffer *pbuf;
+      unsigned stride, size;
+      void *addr = NULL;
+
+      stride = util_format_get_stride(xsurf->color_format, xsurf->width);
+      /* alignment should depend on visual? */
+      stride = align(stride, 4);
+      size = stride * xsurf->height;
+
+      /* create and attach shm object */
+      xbuf->shm_info->shmid = shmget(IPC_PRIVATE, size, 0755);
+      if (xbuf->shm_info->shmid != -1) {
+         xbuf->shm_info->shmaddr =
+            shmat(xbuf->shm_info->shmid, NULL, 0);
+         if (xbuf->shm_info->shmaddr != (void *) -1) {
+            if (XShmAttach(xsurf->xdpy->dpy, xbuf->shm_info)) {
+               addr = xbuf->shm_info->shmaddr;
+               xbuf->xshm_attached = TRUE;
+            }
+         }
+      }
+
+      if (addr) {
+         pbuf = screen->user_buffer_create(screen, addr, size);
+         if (pbuf) {
+            xbuf->texture =
+               screen->texture_blanket(screen, &templ, &stride, pbuf);
+            pipe_buffer_reference(&pbuf, NULL);
+         }
+      }
+   }
+   else {
+      xbuf->texture = screen->texture_create(screen, &templ);
+   }
+
+   if (xbuf->texture) {
+      xbuf->transfer = screen->get_tex_transfer(screen, xbuf->texture,
+            0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height);
+      if (!xbuf->transfer)
+         pipe_texture_reference(&xbuf->texture, NULL);
+   }
+
+   /* clean up the buffer if allocation failed */
+   if (!xbuf->texture)
+      ximage_surface_free_buffer(&xsurf->base, which);
+
+   return (xbuf->texture != NULL);
+}
+
+static boolean
+ximage_surface_draw_buffer(struct native_surface *nsurf,
+                           enum native_attachment which)
+{
+   struct ximage_surface *xsurf = ximage_surface(nsurf);
+   struct ximage_buffer *xbuf = &xsurf->buffers[which];
+   struct pipe_screen *screen = xsurf->xdpy->base.screen;
+
+   if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
+      return TRUE;
+
+   assert(xsurf->drawable && xbuf->ximage && xbuf->texture);
+
+   xbuf->ximage->data = screen->transfer_map(screen, xbuf->transfer);
+
+   if (xbuf->shm_info)
+      XShmPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
+            xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height, False);
+   else
+      XPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
+            xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height);
+
+   xbuf->ximage->data = NULL;
+   screen->transfer_unmap(screen, xbuf->transfer);
+
+   XSync(xsurf->xdpy->dpy, FALSE);
+
+   return TRUE;
+}
+
+static boolean
+ximage_surface_flush_frontbuffer(struct native_surface *nsurf)
+{
+   return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
+}
+
+static boolean
+ximage_surface_swap_buffers(struct native_surface *nsurf)
+{
+   struct ximage_surface *xsurf = ximage_surface(nsurf);
+   struct ximage_buffer *xfront, *xback, xtmp;
+
+   xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT];
+   xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT];
+
+   /* draw the back buffer directly if there is no front buffer */
+   if (!xfront->texture)
+      return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_BACK_LEFT);
+
+   /* swap the buffers */
+   xtmp = *xfront;
+   *xfront = *xback;
+   *xback = xtmp;
+
+   return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
+}
+
+static void
+ximage_surface_update_geometry(struct native_surface *nsurf)
+{
+   struct ximage_surface *xsurf = ximage_surface(nsurf);
+   Status ok;
+   Window root;
+   int x, y;
+   unsigned int w, h, border, depth;
+
+   /* pbuffer has fixed geometry */
+   if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
+      return;
+
+   ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable,
+         &root, &x, &y, &w, &h, &border, &depth);
+   if (ok) {
+      xsurf->width = w;
+      xsurf->height = h;
+   }
+}
+
+static boolean
+ximage_surface_validate(struct native_surface *nsurf,
+                               const enum native_attachment *natts,
+                               unsigned num_natts,
+                               struct pipe_texture **textures,
+                               int *width, int *height)
+{
+   struct ximage_surface *xsurf = ximage_surface(nsurf);
+   boolean error = FALSE;
+   unsigned i;
+
+   ximage_surface_update_geometry(&xsurf->base);
+
+   if (textures)
+      memset(textures, 0, sizeof(*textures) * num_natts);
+
+   for (i = 0; i < num_natts; i++) {
+      enum native_attachment natt = natts[i];
+      struct ximage_buffer *xbuf = &xsurf->buffers[natt];
+
+      if (!xbuf)
+         continue;
+
+      /* reallocate the texture */
+      if (!xbuf->texture ||
+          xsurf->width != xbuf->texture->width0 ||
+          xsurf->height != xbuf->texture->height0) {
+         if (ximage_surface_alloc_buffer(&xsurf->base, natt)) {
+            /* update ximage */
+            if (xbuf->ximage) {
+               xbuf->ximage->width = xbuf->transfer->width;
+               xbuf->ximage->height = xbuf->transfer->height;
+               xbuf->ximage->bytes_per_line = xbuf->transfer->stride;
+            }
+         }
+      }
+
+      /* allocation failed */
+      if (!xbuf->texture) {
+         unsigned j;
+         for (j = 0; j < i; j++)
+            pipe_texture_reference(&textures[j], NULL);
+         for (j = i; j < num_natts; j++)
+            textures[j] = NULL;
+         error = TRUE;
+         break;
+      }
+
+      if (textures)
+         pipe_texture_reference(&textures[i], xbuf->texture);
+   }
+
+   if (width)
+      *width = xsurf->width;
+   if (height)
+      *height = xsurf->height;
+
+   return !error;
+}
+
+static void
+ximage_surface_wait(struct native_surface *nsurf)
+{
+   struct ximage_surface *xsurf = ximage_surface(nsurf);
+   XSync(xsurf->xdpy->dpy, FALSE);
+   /* TODO XGetImage and update the front texture */
+}
+
+static void
+ximage_surface_destroy(struct native_surface *nsurf)
+{
+   struct ximage_surface *xsurf = ximage_surface(nsurf);
+   int i;
+
+   for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
+      struct ximage_buffer *xbuf = &xsurf->buffers[i];
+      ximage_surface_free_buffer(&xsurf->base, i);
+      /* xbuf->shm_info is owned by xbuf->ximage? */
+      if (xbuf->ximage) {
+         XDestroyImage(xbuf->ximage);
+         xbuf->ximage = NULL;
+      }
+   }
+
+   if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER)
+      XFreeGC(xsurf->xdpy->dpy, xsurf->gc);
+   free(xsurf);
+}
+
+static struct ximage_surface *
+ximage_display_create_surface(struct native_display *ndpy,
+                              enum ximage_surface_type type,
+                              Drawable drawable,
+                              const struct native_config *nconf)
+{
+   struct ximage_display *xdpy = ximage_display(ndpy);
+   struct ximage_config *xconf = ximage_config(nconf);
+   struct ximage_surface *xsurf;
+   int i;
+
+   xsurf = CALLOC_STRUCT(ximage_surface);
+   if (!xsurf)
+      return NULL;
+
+   xsurf->xdpy = xdpy;
+   xsurf->type = type;
+   xsurf->color_format = xconf->base.color_format;
+   xsurf->drawable = drawable;
+
+   if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) {
+      xsurf->drawable = drawable;
+      xsurf->visual = *xconf->visual;
+
+      xsurf->gc = XCreateGC(xdpy->dpy, xsurf->drawable, 0, NULL);
+      if (!xsurf->gc) {
+         free(xsurf);
+         return NULL;
+      }
+
+      for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
+         struct ximage_buffer *xbuf = &xsurf->buffers[i];
+
+         if (xdpy->use_xshm) {
+            xbuf->shm_info = calloc(1, sizeof(*xbuf->shm_info));
+            if (xbuf->shm_info) {
+               /* initialize shm info */
+               xbuf->shm_info->shmid = -1;
+               xbuf->shm_info->shmaddr = (void *) -1;
+               xbuf->shm_info->readOnly = TRUE;
+
+               xbuf->ximage = XShmCreateImage(xsurf->xdpy->dpy,
+                     xsurf->visual.visual,
+                     xsurf->visual.depth,
+                     ZPixmap, NULL,
+                     xbuf->shm_info,
+                     0, 0);
+            }
+         }
+         else {
+            xbuf->ximage = XCreateImage(xsurf->xdpy->dpy,
+                  xsurf->visual.visual,
+                  xsurf->visual.depth,
+                  ZPixmap, 0,   /* format, offset */
+                  NULL,         /* data */
+                  0, 0,         /* size */
+                  8,            /* bitmap_pad */
+                  0);           /* bytes_per_line */
+         }
+
+         if (!xbuf->ximage) {
+            XFreeGC(xdpy->dpy, xsurf->gc);
+            free(xsurf);
+            return NULL;
+         }
+      }
+   }
+
+   xsurf->base.destroy = ximage_surface_destroy;
+   xsurf->base.swap_buffers = ximage_surface_swap_buffers;
+   xsurf->base.flush_frontbuffer = ximage_surface_flush_frontbuffer;
+   xsurf->base.validate = ximage_surface_validate;
+   xsurf->base.wait = ximage_surface_wait;
+
+   return xsurf;
+}
+
+static struct native_surface *
+ximage_display_create_window_surface(struct native_display *ndpy,
+                                     EGLNativeWindowType win,
+                                     const struct native_config *nconf)
+{
+   struct ximage_surface *xsurf;
+
+   xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_WINDOW,
+         (Drawable) win, nconf);
+   return (xsurf) ? &xsurf->base : NULL;
+}
+
+static struct native_surface *
+ximage_display_create_pixmap_surface(struct native_display *ndpy,
+                                     EGLNativePixmapType pix,
+                                     const struct native_config *nconf)
+{
+   struct ximage_surface *xsurf;
+
+   xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_PIXMAP,
+         (Drawable) pix, nconf);
+   return (xsurf) ? &xsurf->base : NULL;
+}
+
+static struct native_surface *
+ximage_display_create_pbuffer_surface(struct native_display *ndpy,
+                                      const struct native_config *nconf,
+                                      uint width, uint height)
+{
+   struct ximage_surface *xsurf;
+
+   xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_PBUFFER,
+         (Drawable) None, nconf);
+   if (xsurf) {
+      xsurf->width = width;
+      xsurf->height = height;
+   }
+   return (xsurf) ? &xsurf->base : NULL;
+}
+
+static struct pipe_context *
+ximage_display_create_context(struct native_display *ndpy,
+                              void *context_private)
+{
+   struct pipe_context *pctx = softpipe_create(ndpy->screen);
+   if (pctx)
+      pctx->priv = context_private;
+   return pctx;
+}
+
+static enum pipe_format
+choose_format(const XVisualInfo *vinfo)
+{
+   enum pipe_format fmt;
+   /* TODO elaborate the formats */
+   switch (vinfo->depth) {
+   case 32:
+      fmt = PIPE_FORMAT_A8R8G8B8_UNORM;
+      break;
+   case 24:
+      fmt = PIPE_FORMAT_X8R8G8B8_UNORM;
+      break;
+   case 16:
+      fmt = PIPE_FORMAT_R5G6B5_UNORM;
+      break;
+   default:
+      fmt = PIPE_FORMAT_NONE;
+      break;
+   }
+
+   return fmt;
+}
+
+static const struct native_config **
+ximage_display_get_configs(struct native_display *ndpy, int *num_configs)
+{
+   struct ximage_display *xdpy = ximage_display(ndpy);
+   const struct native_config **configs;
+   int i;
+
+   /* first time */
+   if (!xdpy->configs) {
+      const XVisualInfo *visuals;
+      int num_visuals, count, j;
+
+      visuals = x11_screen_get_visuals(xdpy->xscr, &num_visuals);
+      if (!visuals)
+         return NULL;
+
+      /*
+       * Create two configs for each visual.
+       * One with depth/stencil buffer; one without
+       */
+      xdpy->configs = calloc(num_visuals * 2, sizeof(*xdpy->configs));
+      if (!xdpy->configs)
+         return NULL;
+
+      count = 0;
+      for (i = 0; i < num_visuals; i++) {
+         for (j = 0; j < 2; j++) {
+            struct ximage_config *xconf = &xdpy->configs[count];
+            __GLcontextModes *mode = &xconf->base.mode;
+
+            xconf->visual = &visuals[i];
+            xconf->base.color_format = choose_format(xconf->visual);
+            if (xconf->base.color_format == PIPE_FORMAT_NONE)
+               continue;
+
+            x11_screen_convert_visual(xdpy->xscr, xconf->visual, mode);
+            /* support double buffer mode */
+            mode->doubleBufferMode = TRUE;
+
+            xconf->base.depth_format = PIPE_FORMAT_NONE;
+            xconf->base.stencil_format = PIPE_FORMAT_NONE;
+            /* create the second config with depth/stencil buffer */
+            if (j == 1) {
+               xconf->base.depth_format = PIPE_FORMAT_S8Z24_UNORM;
+               xconf->base.stencil_format = PIPE_FORMAT_S8Z24_UNORM;
+               mode->depthBits = 24;
+               mode->stencilBits = 8;
+               mode->haveDepthBuffer = TRUE;
+               mode->haveStencilBuffer = TRUE;
+            }
+
+            mode->maxPbufferWidth = 4096;
+            mode->maxPbufferHeight = 4096;
+            mode->maxPbufferPixels = 4096 * 4096;
+            mode->drawableType =
+               GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
+            mode->swapMethod = GLX_SWAP_EXCHANGE_OML;
+
+            if (mode->alphaBits)
+               mode->bindToTextureRgba = TRUE;
+            else
+               mode->bindToTextureRgb = TRUE;
+
+            count++;
+         }
+      }
+
+      xdpy->num_configs = count;
+   }
+
+   configs = malloc(xdpy->num_configs * sizeof(*configs));
+   if (configs) {
+      for (i = 0; i < xdpy->num_configs; i++)
+         configs[i] = (const struct native_config *) &xdpy->configs[i];
+      if (num_configs)
+         *num_configs = xdpy->num_configs;
+   }
+   return configs;
+}
+
+static void
+ximage_display_destroy(struct native_display *ndpy)
+{
+   struct ximage_display *xdpy = ximage_display(ndpy);
+
+   if (xdpy->configs)
+      free(xdpy->configs);
+
+   xdpy->base.screen->destroy(xdpy->base.screen);
+   free(xdpy->winsys);
+
+   x11_screen_destroy(xdpy->xscr);
+   if (xdpy->own_dpy)
+      XCloseDisplay(xdpy->dpy);
+   free(xdpy);
+}
+
+static void
+ximage_display_flush_frontbuffer(void *dummy, struct pipe_surface *surf,
+                                 void *context_private)
+{
+   /* TODO get native surface from context private, and remove the callback */
+   _eglLog(_EGL_WARNING, "flush_frontbuffer is not supplied");
+}
+
+struct native_display *
+x11_create_ximage_display(EGLNativeDisplayType dpy,
+                          boolean use_xshm,
+                          native_flush_frontbuffer flush_frontbuffer)
+{
+   struct ximage_display *xdpy;
+
+   xdpy = CALLOC_STRUCT(ximage_display);
+   if (!xdpy)
+      return NULL;
+
+   xdpy->dpy = dpy;
+   if (!xdpy->dpy) {
+      xdpy->dpy = XOpenDisplay(NULL);
+      if (!xdpy->dpy) {
+         free(xdpy);
+         return NULL;
+      }
+      xdpy->own_dpy = TRUE;
+   }
+
+   xdpy->xscr_number = DefaultScreen(xdpy->dpy);
+   xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number);
+   if (!xdpy->xscr) {
+      free(xdpy);
+      return NULL;
+   }
+
+   xdpy->use_xshm =
+      (use_xshm && x11_screen_support(xdpy->xscr, X11_SCREEN_EXTENSION_XSHM));
+
+   xdpy->winsys = create_sw_winsys();
+   if (!flush_frontbuffer)
+      flush_frontbuffer = ximage_display_flush_frontbuffer;
+   xdpy->winsys->flush_frontbuffer =
+      (void (*)(struct pipe_winsys *, struct pipe_surface *, void *))
+      flush_frontbuffer;
+
+   xdpy->base.screen = softpipe_create_screen(xdpy->winsys);
+
+   xdpy->base.destroy = ximage_display_destroy;
+
+   xdpy->base.get_configs = ximage_display_get_configs;
+   xdpy->base.create_context = ximage_display_create_context;
+   xdpy->base.create_window_surface = ximage_display_create_window_surface;
+   xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface;
+   xdpy->base.create_pbuffer_surface = ximage_display_create_pbuffer_surface;
+
+   return &xdpy->base;
+}
diff --git a/src/gallium/state_trackers/egl_g3d/x11/sw_winsys.c b/src/gallium/state_trackers/egl_g3d/x11/sw_winsys.c
new file mode 100644
index 0000000..6ee3ede
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/x11/sw_winsys.c
@@ -0,0 +1,231 @@
+/**************************************************************************
+ * 
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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.
+ * 
+ **************************************************************************/
+
+/**
+ * Totally software-based winsys layer.
+ * Note that the one winsys function that we can't implement here
+ * is flush_frontbuffer().
+ * Whoever uses this code will have to provide that.
+ *
+ * Authors: Brian Paul
+ */
+
+
+#include "pipe/internal/p_winsys_screen.h"
+#include "pipe/p_state.h"
+#include "pipe/p_inlines.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "sw_winsys.h"
+
+
+
+/** Subclass of pipe_winsys */
+struct sw_pipe_winsys
+{
+   struct pipe_winsys Base;
+   /* no extra fields for now */
+};
+
+
+/** subclass of pipe_buffer */
+struct sw_pipe_buffer
+{
+   struct pipe_buffer Base;
+   boolean UserBuffer;  /** Is this a user-space buffer? */
+   void *Data;
+   void *Mapped;
+};
+
+
+/** cast wrapper */
+static INLINE struct sw_pipe_buffer *
+sw_pipe_buffer(struct pipe_buffer *b)
+{
+   return (struct sw_pipe_buffer *) b;
+}
+
+
+static const char *
+get_name(struct pipe_winsys *pws)
+{
+   return "software";
+}
+
+
+/** Create new pipe_buffer and allocate storage of given size */
+static struct pipe_buffer *
+buffer_create(struct pipe_winsys *pws, 
+              unsigned alignment, 
+              unsigned usage,
+              unsigned size)
+{
+   struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
+   if (!buffer)
+      return NULL;
+
+   pipe_reference_init(&buffer->Base.reference, 1);
+   buffer->Base.alignment = alignment;
+   buffer->Base.usage = usage;
+   buffer->Base.size = size;
+
+   /* align to 16-byte multiple for Cell */
+   buffer->Data = align_malloc(size, MAX2(alignment, 16));
+
+   return &buffer->Base;
+}
+
+
+/**
+ * Create buffer which wraps user-space data.
+ */
+static struct pipe_buffer *
+user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
+{
+   struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
+   if (!buffer)
+      return NULL;
+
+   pipe_reference_init(&buffer->Base.reference, 1);
+   buffer->Base.size = bytes;
+   buffer->UserBuffer = TRUE;
+   buffer->Data = ptr;
+
+   return &buffer->Base;
+}
+
+
+static void *
+buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned flags)
+{
+   struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
+   buffer->Mapped = buffer->Data;
+   return buffer->Mapped;
+}
+
+
+static void
+buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
+{
+   struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
+   buffer->Mapped = NULL;
+}
+
+
+static void
+buffer_destroy(struct pipe_buffer *buf)
+{
+   struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
+
+   if (buffer->Data && !buffer->UserBuffer) {
+      align_free(buffer->Data);
+      buffer->Data = NULL;
+   }
+
+   free(buffer);
+}
+
+
+static struct pipe_buffer *
+surface_buffer_create(struct pipe_winsys *winsys,
+                      unsigned width, unsigned height,
+                      enum pipe_format format, 
+                      unsigned usage,
+                      unsigned tex_usage,
+                      unsigned *stride)
+{
+   const unsigned alignment = 64;
+   unsigned nblocksy;
+
+   nblocksy = util_format_get_nblocksy(format, height);
+   *stride = align(util_format_get_stride(format, width), alignment);
+
+   return winsys->buffer_create(winsys, alignment,
+                                usage,
+                                *stride * nblocksy);
+}
+
+
+static void
+fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
+                struct pipe_fence_handle *fence)
+{
+   /* no-op */
+}
+
+
+static int
+fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
+                unsigned flag)
+{
+   /* no-op */
+   return 0;
+}
+
+
+static int
+fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
+             unsigned flag)
+{
+   /* no-op */
+   return 0;
+}
+
+
+/**
+ * Create/return a new pipe_winsys object.
+ */
+struct pipe_winsys *
+create_sw_winsys(void)
+{
+   struct sw_pipe_winsys *ws = CALLOC_STRUCT(sw_pipe_winsys);
+   if (!ws)
+      return NULL;
+
+   /* Fill in this struct with callbacks that pipe will need to
+    * communicate with the window system, buffer manager, etc. 
+    */
+   ws->Base.buffer_create = buffer_create;
+   ws->Base.user_buffer_create = user_buffer_create;
+   ws->Base.buffer_map = buffer_map;
+   ws->Base.buffer_unmap = buffer_unmap;
+   ws->Base.buffer_destroy = buffer_destroy;
+
+   ws->Base.surface_buffer_create = surface_buffer_create;
+
+   ws->Base.fence_reference = fence_reference;
+   ws->Base.fence_signalled = fence_signalled;
+   ws->Base.fence_finish = fence_finish;
+
+   ws->Base.flush_frontbuffer = NULL; /* not implemented here! */
+
+   ws->Base.get_name = get_name;
+
+   return &ws->Base;
+}
diff --git a/src/mesa/state_tracker/st_cb_get.h b/src/gallium/state_trackers/egl_g3d/x11/sw_winsys.h
similarity index 90%
rename from src/mesa/state_tracker/st_cb_get.h
rename to src/gallium/state_trackers/egl_g3d/x11/sw_winsys.h
index 8e9f3e9..f96c5a1 100644
--- a/src/mesa/state_tracker/st_cb_get.h
+++ b/src/gallium/state_trackers/egl_g3d/x11/sw_winsys.h
@@ -26,12 +26,15 @@
  **************************************************************************/
 
 
-#ifndef ST_CB_GET_H
-#define ST_CB_GET_H
+#ifndef SW_WINSYS_H
+#define SW_WINSYS_H
 
 
-extern void
-st_init_get_functions(struct dd_function_table *functions);
+struct pipe_winsys;
 
 
-#endif
+extern struct pipe_winsys *
+create_sw_winsys(void);
+
+
+#endif /* SW_WINSYS_H */
diff --git a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c
new file mode 100644
index 0000000..1e98943
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c
@@ -0,0 +1,402 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL 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 <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <X11/Xlibint.h>
+#include <X11/extensions/XShm.h>
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "xf86drm.h"
+#include "egllog.h"
+
+#include "x11_screen.h"
+#include "dri2.h"
+#include "glxinit.h"
+
+struct x11_screen {
+   Display *dpy;
+   int number;
+
+   __GLXdisplayPrivate *glx_dpy;
+
+   int dri_major, dri_minor;
+   char *dri_driver;
+   char *dri_device;
+   int dri_fd;
+
+   XVisualInfo *visuals;
+   int num_visuals;
+};
+
+
+/**
+ * Create a X11 screen.
+ */
+struct x11_screen *
+x11_screen_create(Display *dpy, int screen)
+{
+   struct x11_screen *xscr;
+
+   if (screen >= ScreenCount(dpy))
+      return NULL;
+
+   xscr = CALLOC_STRUCT(x11_screen);
+   if (xscr) {
+      xscr->dpy = dpy;
+      xscr->number = screen;
+
+      xscr->dri_major = -1;
+      xscr->dri_fd = -1;
+   }
+   return xscr;
+}
+
+/**
+ * Destroy a X11 screen.
+ */
+void
+x11_screen_destroy(struct x11_screen *xscr)
+{
+   if (xscr->dri_fd >= 0)
+      close(xscr->dri_fd);
+   if (xscr->dri_driver)
+      Xfree(xscr->dri_driver);
+   if (xscr->dri_device)
+      Xfree(xscr->dri_device);
+
+   if (xscr->glx_dpy)
+      __glXRelease(xscr->glx_dpy);
+   if (xscr->visuals)
+      XFree(xscr->visuals);
+   free(xscr);
+}
+
+static boolean
+x11_screen_init_dri2(struct x11_screen *xscr)
+{
+   if (xscr->dri_major < 0) {
+      int eventBase, errorBase;
+
+      if (!DRI2QueryExtension(xscr->dpy, &eventBase, &errorBase) ||
+          !DRI2QueryVersion(xscr->dpy, &xscr->dri_major, &xscr->dri_minor))
+         xscr->dri_major = -1;
+   }
+   return (xscr->dri_major >= 0);
+}
+
+static boolean
+x11_screen_init_glx(struct x11_screen *xscr)
+{
+   if (!xscr->glx_dpy)
+      xscr->glx_dpy = __glXInitialize(xscr->dpy);
+   return (xscr->glx_dpy != NULL);
+}
+
+/**
+ * Return true if the screen supports the extension.
+ */
+boolean
+x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext)
+{
+   boolean supported = FALSE;
+
+   switch (ext) {
+   case X11_SCREEN_EXTENSION_XSHM:
+      supported = XShmQueryExtension(xscr->dpy);
+      break;
+   case X11_SCREEN_EXTENSION_GLX:
+      supported = x11_screen_init_glx(xscr);
+      break;
+   case X11_SCREEN_EXTENSION_DRI2:
+      supported = x11_screen_init_dri2(xscr);
+      break;
+   default:
+      break;
+   }
+
+   return supported;
+}
+
+/**
+ * Return the X visuals.
+ */
+const XVisualInfo *
+x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals)
+{
+   if (!xscr->visuals) {
+      XVisualInfo vinfo_template;
+      vinfo_template.screen = xscr->number;
+      xscr->visuals = XGetVisualInfo(xscr->dpy, VisualScreenMask,
+            &vinfo_template, &xscr->num_visuals);
+   }
+
+   if (num_visuals)
+      *num_visuals = xscr->num_visuals;
+   return xscr->visuals;
+}
+
+void
+x11_screen_convert_visual(struct x11_screen *xscr, const XVisualInfo *visual,
+                          __GLcontextModes *mode)
+{
+   int r, g, b, a;
+   int visual_type;
+
+   r = util_bitcount(visual->red_mask);
+   g = util_bitcount(visual->green_mask);
+   b = util_bitcount(visual->blue_mask);
+   a = visual->depth - (r + g + b);
+#if defined(__cplusplus) || defined(c_plusplus)
+   visual_type = visual->c_class;
+#else
+   visual_type = visual->class;
+#endif
+
+   /* convert to GLX visual type */
+   switch (visual_type) {
+   case TrueColor:
+      visual_type = GLX_TRUE_COLOR;
+      break;
+   case DirectColor:
+      visual_type = GLX_DIRECT_COLOR;
+      break;
+   case PseudoColor:
+      visual_type = GLX_PSEUDO_COLOR;
+      break;
+   case StaticColor:
+      visual_type = GLX_STATIC_COLOR;
+      break;
+   case GrayScale:
+      visual_type = GLX_GRAY_SCALE;
+      break;
+   case StaticGray:
+      visual_type = GLX_STATIC_GRAY;
+      break;
+   default:
+      visual_type = GLX_NONE;
+      break;
+   }
+
+   mode->rgbBits = r + g + b + a;
+   mode->redBits = r;
+   mode->greenBits = g;
+   mode->blueBits = b;
+   mode->alphaBits = a;
+   mode->visualID = visual->visualid;
+   mode->visualType = visual_type;
+
+   /* sane defaults */
+   mode->renderType = GLX_RGBA_BIT;
+   mode->rgbMode = TRUE;
+   mode->visualRating = GLX_SLOW_CONFIG;
+   mode->xRenderable = TRUE;
+}
+
+/**
+ * Return the GLX fbconfigs.
+ */
+const __GLcontextModes *
+x11_screen_get_glx_configs(struct x11_screen *xscr)
+{
+   return (x11_screen_init_glx(xscr))
+      ? xscr->glx_dpy->screenConfigs[xscr->number].configs
+      : NULL;
+}
+
+/**
+ * Return the GLX visuals.
+ */
+const __GLcontextModes *
+x11_screen_get_glx_visuals(struct x11_screen *xscr)
+{
+   return (x11_screen_init_glx(xscr))
+      ? xscr->glx_dpy->screenConfigs[xscr->number].visuals
+      : NULL;
+}
+
+static boolean
+x11_screen_is_driver_equal(struct x11_screen *xscr, const char *driver)
+{
+   return (strcmp(xscr->dri_driver, driver) == 0);
+}
+
+/**
+ * Enable DRI2 and returns the file descriptor of the DRM device.  The file
+ * descriptor will be closed automatically when the screen is destoryed.
+ */
+int
+x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver)
+{
+   if (xscr->dri_fd < 0) {
+      int fd;
+      drm_magic_t magic;
+
+      /* get the driver name and the device name first */
+      if (!xscr->dri_driver) {
+         if (!DRI2Connect(xscr->dpy, RootWindow(xscr->dpy, xscr->number),
+                  &xscr->dri_driver, &xscr->dri_device)) {
+            xscr->dri_driver = xscr->dri_device = NULL;
+            return -1;
+         }
+      }
+
+      if (!x11_screen_is_driver_equal(xscr, driver)) {
+         _eglLog(_EGL_WARNING, "Driver mismatch: %s != %s",
+               xscr->dri_driver, driver);
+         return -1;
+      }
+
+      fd = open(xscr->dri_device, O_RDWR);
+      if (fd < 0) {
+         _eglLog(_EGL_WARNING, "failed to open %s", xscr->dri_device);
+         return -1;
+      }
+
+      memset(&magic, 0, sizeof(magic));
+      if (drmGetMagic(fd, &magic)) {
+         _eglLog(_EGL_WARNING, "failed to get magic");
+         close(fd);
+         return -1;
+      }
+
+      if (!DRI2Authenticate(xscr->dpy,
+               RootWindow(xscr->dpy, xscr->number), magic)) {
+         _eglLog(_EGL_WARNING, "failed to authenticate magic");
+         close(fd);
+         return -1;
+      }
+
+      xscr->dri_fd = fd;
+   }
+
+   return xscr->dri_fd;
+}
+
+/**
+ * Create/Destroy the DRI drawable.
+ */
+void
+x11_drawable_enable_dri2(struct x11_screen *xscr,
+                         Drawable drawable, boolean on)
+{
+   if (on)
+      DRI2CreateDrawable(xscr->dpy, drawable);
+   else
+      DRI2DestroyDrawable(xscr->dpy, drawable);
+}
+
+/**
+ * Copy between buffers of the DRI2 drawable.
+ */
+void
+x11_drawable_copy_buffers(struct x11_screen *xscr, Drawable drawable,
+                          int x, int y, int width, int height,
+                          int src_buf, int dst_buf)
+{
+   XRectangle rect;
+   XserverRegion region;
+
+   rect.x = x;
+   rect.y = y;
+   rect.width = width;
+   rect.height = height;
+
+   region = XFixesCreateRegion(xscr->dpy, &rect, 1);
+   DRI2CopyRegion(xscr->dpy, drawable, region, dst_buf, src_buf);
+   XFixesDestroyRegion(xscr->dpy, region);
+}
+
+/**
+ * Get the buffers of the DRI2 drawable.  The returned array should be freed.
+ */
+struct x11_drawable_buffer *
+x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable,
+                         int *width, int *height, unsigned int *attachments,
+                         boolean with_format, int num_ins, int *num_outs)
+{
+   DRI2Buffer *dri2bufs;
+
+   if (with_format)
+      dri2bufs = DRI2GetBuffersWithFormat(xscr->dpy, drawable, width, height,
+            attachments, num_ins, num_outs);
+   else
+      dri2bufs = DRI2GetBuffers(xscr->dpy, drawable, width, height,
+            attachments, num_ins, num_outs);
+
+   return (struct x11_drawable_buffer *) dri2bufs;
+}
+
+/**
+ * Create a mode list of the given size.
+ */
+__GLcontextModes *
+x11_context_modes_create(unsigned count)
+{
+   const size_t size = sizeof(__GLcontextModes);
+   __GLcontextModes *base = NULL;
+   __GLcontextModes **next;
+   unsigned i;
+
+   next = &base;
+   for (i = 0; i < count; i++) {
+      *next = (__GLcontextModes *) calloc(1, size);
+      if (*next == NULL) {
+         x11_context_modes_destroy(base);
+         base = NULL;
+         break;
+      }
+      next = &((*next)->next);
+   }
+
+   return base;
+}
+
+/**
+ * Destroy a mode list.
+ */
+void
+x11_context_modes_destroy(__GLcontextModes *modes)
+{
+   while (modes != NULL) {
+      __GLcontextModes *next = modes->next;
+      free(modes);
+      modes = next;
+   }
+}
+
+/**
+ * Return the number of the modes in the mode list.
+ */
+unsigned
+x11_context_modes_count(const __GLcontextModes *modes)
+{
+   const __GLcontextModes *mode;
+   int count = 0;
+   for (mode = modes; mode; mode = mode->next)
+      count++;
+   return count;
+}
diff --git a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h
new file mode 100644
index 0000000..86e8e05
--- /dev/null
+++ b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h
@@ -0,0 +1,99 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL 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.
+ */
+
+#ifndef _X11_SCREEN_H_
+#define _X11_SCREEN_H_
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/dri2tokens.h>
+#include "pipe/p_compiler.h"
+#include "common/native.h"
+
+enum x11_screen_extension {
+   X11_SCREEN_EXTENSION_XSHM,
+   X11_SCREEN_EXTENSION_GLX,
+   X11_SCREEN_EXTENSION_DRI2,
+};
+
+/* the same as DRI2Buffer */
+struct x11_drawable_buffer {
+   unsigned int attachment;
+   unsigned int name;
+   unsigned int pitch;
+   unsigned int cpp;
+   unsigned int flags;
+};
+
+struct x11_screen;
+
+struct x11_screen *
+x11_screen_create(Display *dpy, int screen);
+
+void
+x11_screen_destroy(struct x11_screen *xscr);
+
+boolean
+x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext);
+
+const XVisualInfo *
+x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals);
+
+void
+x11_screen_convert_visual(struct x11_screen *xscr, const XVisualInfo *visual,
+                          __GLcontextModes *mode);
+
+const __GLcontextModes *
+x11_screen_get_glx_configs(struct x11_screen *xscr);
+
+const __GLcontextModes *
+x11_screen_get_glx_visuals(struct x11_screen *xscr);
+
+int
+x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver);
+
+__GLcontextModes *
+x11_context_modes_create(unsigned count);
+
+void
+x11_context_modes_destroy(__GLcontextModes *modes);
+
+unsigned
+x11_context_modes_count(const __GLcontextModes *modes);
+
+void
+x11_drawable_enable_dri2(struct x11_screen *xscr,
+                         Drawable drawable, boolean on);
+
+void
+x11_drawable_copy_buffers(struct x11_screen *xscr, Drawable drawable,
+                          int x, int y, int width, int height,
+                          int src_buf, int dst_buf);
+
+struct x11_drawable_buffer *
+x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable,
+                         int *width, int *height, unsigned int *attachments,
+                         boolean with_format, int num_ins, int *num_outs);
+
+#endif /* _X11_SCREEN_H_ */
diff --git a/src/gallium/state_trackers/glx/xlib/glx_api.c b/src/gallium/state_trackers/glx/xlib/glx_api.c
index f2881b9..3caf56e 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_api.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_api.c
@@ -644,6 +644,7 @@
       XExtCodes *c = XAddExtension(dpy);
       ext = dpy->ext_procs;  /* new extension is at head of list */
       assert(c->extension == ext->codes.extension);
+      (void) c;
       ext->name = _mesa_strdup(extName);
       ext->close_display = close_display_callback;
    }
@@ -1006,7 +1007,7 @@
 }
 
 
-XVisualInfo *
+PUBLIC XVisualInfo *
 glXChooseVisual( Display *dpy, int screen, int *list )
 {
    XMesaVisual xmvis;
@@ -1028,7 +1029,7 @@
 }
 
 
-GLXContext
+PUBLIC GLXContext
 glXCreateContext( Display *dpy, XVisualInfo *visinfo,
                   GLXContext share_list, Bool direct )
 {
@@ -1083,7 +1084,7 @@
 
 
 /* GLX 1.3 and later */
-Bool
+PUBLIC Bool
 glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
                        GLXDrawable read, GLXContext ctx )
 {
@@ -1179,21 +1180,21 @@
 }
 
 
-Bool
+PUBLIC Bool
 glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
 {
    return glXMakeContextCurrent( dpy, drawable, drawable, ctx );
 }
 
 
-GLXContext
+PUBLIC GLXContext
 glXGetCurrentContext(void)
 {
    return GetCurrentContext();
 }
 
 
-Display *
+PUBLIC Display *
 glXGetCurrentDisplay(void)
 {
    GLXContext glxCtx = glXGetCurrentContext();
@@ -1202,14 +1203,14 @@
 }
 
 
-Display *
+PUBLIC Display *
 glXGetCurrentDisplayEXT(void)
 {
    return glXGetCurrentDisplay();
 }
 
 
-GLXDrawable
+PUBLIC GLXDrawable
 glXGetCurrentDrawable(void)
 {
    GLXContext gc = glXGetCurrentContext();
@@ -1217,7 +1218,7 @@
 }
 
 
-GLXDrawable
+PUBLIC GLXDrawable
 glXGetCurrentReadDrawable(void)
 {
    GLXContext gc = glXGetCurrentContext();
@@ -1225,14 +1226,14 @@
 }
 
 
-GLXDrawable
+PUBLIC GLXDrawable
 glXGetCurrentReadDrawableSGI(void)
 {
    return glXGetCurrentReadDrawable();
 }
 
 
-GLXPixmap
+PUBLIC GLXPixmap
 glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
 {
    XMesaVisual v;
@@ -1257,7 +1258,7 @@
 
 /*** GLX_MESA_pixmap_colormap ***/
 
-GLXPixmap
+PUBLIC GLXPixmap
 glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
                         Pixmap pixmap, Colormap cmap )
 {
@@ -1281,7 +1282,7 @@
 }
 
 
-void
+PUBLIC void
 glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
 {
    XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
@@ -1294,7 +1295,7 @@
 }
 
 
-void
+PUBLIC void
 glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
                 unsigned long mask )
 {
@@ -1308,7 +1309,7 @@
 }
 
 
-Bool
+PUBLIC Bool
 glXQueryExtension( Display *dpy, int *errorBase, int *eventBase )
 {
    int op, ev, err;
@@ -1323,7 +1324,7 @@
 }
 
 
-void
+PUBLIC void
 glXDestroyContext( Display *dpy, GLXContext ctx )
 {
    GLXContext glxCtx = ctx;
@@ -1339,7 +1340,7 @@
 }
 
 
-Bool
+PUBLIC Bool
 glXIsDirect( Display *dpy, GLXContext ctx )
 {
    GLXContext glxCtx = ctx;
@@ -1349,7 +1350,7 @@
 
 
 
-void
+PUBLIC void
 glXSwapBuffers( Display *dpy, GLXDrawable drawable )
 {
    XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
@@ -1376,7 +1377,7 @@
 
 /*** GLX_MESA_copy_sub_buffer ***/
 
-void
+PUBLIC void
 glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
                            int x, int y, int width, int height )
 {
@@ -1390,7 +1391,7 @@
 }
 
 
-Bool
+PUBLIC Bool
 glXQueryVersion( Display *dpy, int *maj, int *min )
 {
    (void) dpy;
@@ -1607,7 +1608,7 @@
 }
 
 
-int
+PUBLIC int
 glXGetConfig( Display *dpy, XVisualInfo *visinfo,
                    int attrib, int *value )
 {
@@ -1637,7 +1638,7 @@
 }
 
 
-void
+PUBLIC void
 glXWaitGL( void )
 {
    XMesaContext xmesa = XMesaGetCurrentContext();
@@ -1646,7 +1647,7 @@
 
 
 
-void
+PUBLIC void
 glXWaitX( void )
 {
    XMesaContext xmesa = XMesaGetCurrentContext();
@@ -1663,7 +1664,7 @@
 
 
 /* GLX 1.1 and later */
-const char *
+PUBLIC const char *
 glXQueryExtensionsString( Display *dpy, int screen )
 {
    (void) dpy;
@@ -1674,7 +1675,7 @@
 
 
 /* GLX 1.1 and later */
-const char *
+PUBLIC const char *
 glXQueryServerString( Display *dpy, int screen, int name )
 {
    static char version[1000];
@@ -1699,7 +1700,7 @@
 
 
 /* GLX 1.1 and later */
-const char *
+PUBLIC const char *
 glXGetClientString( Display *dpy, int name )
 {
    static char version[1000];
@@ -1727,7 +1728,7 @@
  */
 
 
-int
+PUBLIC int
 glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
                            int attribute, int *value )
 {
@@ -1742,7 +1743,7 @@
 }
 
 
-GLXFBConfig *
+PUBLIC GLXFBConfig *
 glXGetFBConfigs( Display *dpy, int screen, int *nelements )
 {
    XVisualInfo *visuals, visTemplate;
@@ -1768,7 +1769,7 @@
 }
 
 
-GLXFBConfig *
+PUBLIC GLXFBConfig *
 glXChooseFBConfig( Display *dpy, int screen,
                         const int *attribList, int *nitems )
 {
@@ -1797,7 +1798,7 @@
 }
 
 
-XVisualInfo *
+PUBLIC XVisualInfo *
 glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
 {
    if (dpy && config) {
@@ -1819,7 +1820,7 @@
 }
 
 
-GLXWindow
+PUBLIC GLXWindow
 glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
                       const int *attribList )
 {
@@ -1839,7 +1840,7 @@
 }
 
 
-void
+PUBLIC void
 glXDestroyWindow( Display *dpy, GLXWindow window )
 {
    XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable) window);
@@ -1850,7 +1851,7 @@
 
 
 /* XXX untested */
-GLXPixmap
+PUBLIC GLXPixmap
 glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
                       const int *attribList )
 {
@@ -1960,7 +1961,7 @@
 }
 
 
-void
+PUBLIC void
 glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
 {
    XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable)pixmap);
@@ -1970,7 +1971,7 @@
 }
 
 
-GLXPbuffer
+PUBLIC GLXPbuffer
 glXCreatePbuffer( Display *dpy, GLXFBConfig config,
                        const int *attribList )
 {
@@ -2033,7 +2034,7 @@
 }
 
 
-void
+PUBLIC void
 glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
 {
    XMesaBuffer b = XMesaFindBuffer(dpy, pbuf);
@@ -2043,7 +2044,7 @@
 }
 
 
-void
+PUBLIC void
 glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
                        unsigned int *value )
 {
@@ -2089,7 +2090,7 @@
 }
 
 
-GLXContext
+PUBLIC GLXContext
 glXCreateNewContext( Display *dpy, GLXFBConfig config,
                           int renderType, GLXContext shareList, Bool direct )
 {
@@ -2123,7 +2124,7 @@
 }
 
 
-int
+PUBLIC int
 glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
 {
    GLXContext glxCtx = ctx;
@@ -2152,7 +2153,7 @@
 }
 
 
-void
+PUBLIC void
 glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
 {
    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
@@ -2161,7 +2162,7 @@
 }
 
 
-void
+PUBLIC void
 glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
                           unsigned long *mask )
 {
@@ -2176,7 +2177,7 @@
 
 /*** GLX_SGI_swap_control ***/
 
-int
+PUBLIC int
 glXSwapIntervalSGI(int interval)
 {
    (void) interval;
@@ -2189,7 +2190,7 @@
 
 static unsigned int FrameCounter = 0;
 
-int
+PUBLIC int
 glXGetVideoSyncSGI(unsigned int *count)
 {
    /* this is a bogus implementation */
@@ -2197,7 +2198,7 @@
    return 0;
 }
 
-int
+PUBLIC int
 glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
 {
    if (divisor <= 0 || remainder < 0)
@@ -2214,7 +2215,7 @@
 
 /*** GLX_SGI_make_current_read ***/
 
-Bool
+PUBLIC Bool
 glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
 {
    return glXMakeContextCurrent( dpy, draw, read, ctx );
@@ -2232,7 +2233,7 @@
 /*** GLX_SGIX_video_source ***/
 #if defined(_VL_H)
 
-GLXVideoSourceSGIX
+PUBLIC GLXVideoSourceSGIX
 glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
 {
    (void) dpy;
@@ -2244,7 +2245,7 @@
    return 0;
 }
 
-void
+PUBLIC void
 glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
 {
    (void) dpy;
@@ -2256,21 +2257,21 @@
 
 /*** GLX_EXT_import_context ***/
 
-void
+PUBLIC void
 glXFreeContextEXT(Display *dpy, GLXContext context)
 {
    (void) dpy;
    (void) context;
 }
 
-GLXContextID
+PUBLIC GLXContextID
 glXGetContextIDEXT(const GLXContext context)
 {
    (void) context;
    return 0;
 }
 
-GLXContext
+PUBLIC GLXContext
 glXImportContextEXT(Display *dpy, GLXContextID contextID)
 {
    (void) dpy;
@@ -2278,7 +2279,7 @@
    return 0;
 }
 
-int
+PUBLIC int
 glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value)
 {
    (void) dpy;
@@ -2292,20 +2293,20 @@
 
 /*** GLX_SGIX_fbconfig ***/
 
-int
+PUBLIC int
 glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
 {
    return glXGetFBConfigAttrib(dpy, config, attribute, value);
 }
 
-GLXFBConfigSGIX *
+PUBLIC GLXFBConfigSGIX *
 glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
 {
    return (GLXFBConfig *) glXChooseFBConfig(dpy, screen, attrib_list, nelements);
 }
 
 
-GLXPixmap
+PUBLIC GLXPixmap
 glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
 {
    XMesaVisual xmvis = (XMesaVisual) config;
@@ -2314,7 +2315,7 @@
 }
 
 
-GLXContext
+PUBLIC GLXContext
 glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
 {
    XMesaVisual xmvis = (XMesaVisual) config;
@@ -2343,14 +2344,14 @@
 }
 
 
-XVisualInfo *
+PUBLIC XVisualInfo *
 glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
 {
    return glXGetVisualFromFBConfig(dpy, config);
 }
 
 
-GLXFBConfigSGIX
+PUBLIC GLXFBConfigSGIX
 glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
 {
    XMesaVisual xmvis = find_glx_visual(dpy, vis);
@@ -2366,7 +2367,7 @@
 
 /*** GLX_SGIX_pbuffer ***/
 
-GLXPbufferSGIX
+PUBLIC GLXPbufferSGIX
 glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
                              unsigned int width, unsigned int height,
                              int *attribList)
@@ -2405,7 +2406,7 @@
 }
 
 
-void
+PUBLIC void
 glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
 {
    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
@@ -2415,7 +2416,7 @@
 }
 
 
-int
+PUBLIC int
 glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
 {
    const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
@@ -2448,7 +2449,7 @@
 }
 
 
-void
+PUBLIC void
 glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
 {
    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
@@ -2459,7 +2460,7 @@
 }
 
 
-void
+PUBLIC void
 glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
 {
    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
@@ -2475,7 +2476,7 @@
 
 /*** GLX_SGI_cushion ***/
 
-void
+PUBLIC void
 glXCushionSGI(Display *dpy, Window win, float cushion)
 {
    (void) dpy;
@@ -2487,7 +2488,7 @@
 
 /*** GLX_SGIX_video_resize ***/
 
-int
+PUBLIC int
 glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
 {
    (void) dpy;
@@ -2497,7 +2498,7 @@
    return 0;
 }
 
-int
+PUBLIC int
 glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
 {
    (void) dpy;
@@ -2510,7 +2511,7 @@
    return 0;
 }
 
-int
+PUBLIC int
 glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
 {
    (void) dpy;
@@ -2523,7 +2524,7 @@
    return 0;
 }
 
-int
+PUBLIC int
 glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
 {
    (void) dpy;
@@ -2536,7 +2537,7 @@
    return 0;
 }
 
-int
+PUBLIC int
 glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
 {
    (void) dpy;
@@ -2551,7 +2552,7 @@
 /*** GLX_SGIX_dmbuffer **/
 
 #if defined(_DM_BUFFER_H_)
-Bool
+PUBLIC Bool
 glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
 {
    (void) dpy;
@@ -2565,7 +2566,7 @@
 
 /*** GLX_SGIX_swap_group ***/
 
-void
+PUBLIC void
 glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
 {
    (void) dpy;
@@ -2577,7 +2578,7 @@
 
 /*** GLX_SGIX_swap_barrier ***/
 
-void
+PUBLIC void
 glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
 {
    (void) dpy;
@@ -2585,7 +2586,7 @@
    (void) barrier;
 }
 
-Bool
+PUBLIC Bool
 glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
 {
    (void) dpy;
@@ -2598,7 +2599,7 @@
 
 /*** GLX_SUN_get_transparent_index ***/
 
-Status
+PUBLIC Status
 glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
 {
    (void) dpy;
@@ -2616,7 +2617,7 @@
  * Release the depth, stencil, accum buffers attached to a GLXDrawable
  * (a window or pixmap) prior to destroying the GLXDrawable.
  */
-Bool
+PUBLIC Bool
 glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
 {
    XMesaBuffer b = XMesaFindBuffer(dpy, d);
@@ -2629,7 +2630,7 @@
 
 /*** GLX_EXT_texture_from_pixmap ***/
 
-void
+PUBLIC void
 glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
                         const int *attrib_list)
 {
@@ -2638,7 +2639,7 @@
       XMesaBindTexImage(dpy, b, buffer, attrib_list);
 }
 
-void
+PUBLIC void
 glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
 {
    XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
diff --git a/src/gallium/state_trackers/glx/xlib/glx_getproc.c b/src/gallium/state_trackers/glx/xlib/glx_getproc.c
index ca7d88c..84d47b1 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_getproc.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_getproc.c
@@ -34,6 +34,7 @@
 #include <string.h>
 #include "GL/glx.h"
 #include "glapi/glapi.h"
+#include "pipe/p_compiler.h"
 
 
 struct name_address_pair {
@@ -208,6 +209,7 @@
 
 
 /* GLX 1.4 */
+PUBLIC
 void (*glXGetProcAddress(const GLubyte *procName))()
 {
    return glXGetProcAddressARB(procName);
diff --git a/src/gallium/state_trackers/glx/xlib/glx_usefont.c b/src/gallium/state_trackers/glx/xlib/glx_usefont.c
index acc64df..16e5ce6 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_usefont.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_usefont.c
@@ -33,6 +33,7 @@
 #include "main/context.h"
 #include "main/imports.h"
 #include <GL/glx.h>
+#include "pipe/p_compiler.h"
 
 
 /* Some debugging info.  */
@@ -210,7 +211,7 @@
 }
 
 
-void
+PUBLIC void
 glXUseXFont(Font font, int first, int count, int listbase)
 {
    Display *dpy;
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index c76dfb3..1783bc5 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -67,6 +67,10 @@
 #include "pipe/p_screen.h"
 #include "pipe/p_context.h"
 
+#include "trace/tr_screen.h"
+#include "trace/tr_context.h"
+#include "trace/tr_texture.h"
+
 #include "xm_winsys.h"
 #include <GL/glx.h>
 
@@ -87,6 +91,8 @@
  */
 pipe_mutex _xmesa_lock;
 
+static struct pipe_screen *_screen = NULL;
+static struct pipe_screen *screen = NULL;
 
 
 /**********************************************************************/
@@ -754,7 +760,7 @@
 XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
 {
    static GLboolean firstTime = GL_TRUE;
-   static struct pipe_screen *screen = NULL;
+   struct pipe_context *_pipe = NULL;
    struct pipe_context *pipe = NULL;
    XMesaContext c;
    GLcontext *mesaCtx;
@@ -762,7 +768,8 @@
 
    if (firstTime) {
       pipe_mutex_init(_xmesa_lock);
-      screen = driver.create_pipe_screen();
+      _screen = driver.create_pipe_screen();
+      screen = trace_screen_create( _screen );
       firstTime = GL_FALSE;
    }
 
@@ -781,9 +788,11 @@
    if (screen == NULL)
       goto fail;
 
-   pipe = driver.create_pipe_context(screen, (void *) c);
-   if (pipe == NULL)
+   _pipe = driver.create_pipe_context(_screen, (void *) c);
+   if (_pipe == NULL)
       goto fail;
+   pipe = trace_context_create(screen, _pipe);
+   pipe->priv = c;
 
    c->st = st_create_context(pipe, 
                              &v->mesa_visual,
@@ -1110,6 +1119,12 @@
    st_swapbuffers(b->stfb, &frontLeftSurf, NULL);
 
    if (frontLeftSurf) {
+      if (_screen != screen) {
+         struct trace_surface *tr_surf = trace_surface( frontLeftSurf );
+         struct pipe_surface *surf = tr_surf->surface;
+         frontLeftSurf = surf;
+      }
+
       driver.display_surface(b, frontLeftSurf);
    }
 
diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript
index ec385e7..8498a90 100644
--- a/src/gallium/state_trackers/python/SConscript
+++ b/src/gallium/state_trackers/python/SConscript
@@ -28,20 +28,35 @@
             'X11',
         ])
 
+    sources = [
+        'gallium.i',
+        'st_device.c',
+        'st_sample.c',
+    ]
+
+    drivers = [
+        trace
+    ]
+
+    if 'llvmpipe' in env['drivers']:
+        env.Tool('llvm')
+        sources += ['st_llvmpipe_winsys.c']
+        drivers += [llvmpipe]
+    else:
+        sources += ['st_softpipe_winsys.c']
+        drivers += [softpipe]
+
     pyst = env.ConvenienceLibrary(
         target = 'pyst',
-        source = [
-            'gallium.i',
-            'st_device.c',
-            'st_sample.c',
-            'st_softpipe_winsys.c',
-        ],
+        source = sources,
     )
 
+    env['no_import_lib'] = 1
+
     env.SharedLibrary(
         target = '_gallium',
         source = [
             'st_hardpipe_winsys.c',
         ],
-        LIBS = [pyst, softpipe, trace] + auxiliaries + env['LIBS'],
+        LIBS = [pyst] + drivers + gallium + env['LIBS'],
     )
diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i
index 3f79cc1..96b13c2 100644
--- a/src/gallium/state_trackers/python/gallium.i
+++ b/src/gallium/state_trackers/python/gallium.i
@@ -46,6 +46,7 @@
 #include "util/u_draw_quad.h"
 #include "util/u_tile.h"
 #include "util/u_math.h"
+#include "util/u_format.h"
 #include "util/u_memory.h"
 #include "tgsi/tgsi_text.h"
 #include "tgsi/tgsi_dump.h"
@@ -80,7 +81,6 @@
 %rename(Stencil) pipe_stencil_state;
 %rename(Alpha) pipe_alpha_state;
 %rename(DepthStencilAlpha) pipe_depth_stencil_alpha_state;
-%rename(FormatBlock) pipe_format_block;
 %rename(Framebuffer) pipe_framebuffer_state;
 %rename(PolyStipple) pipe_poly_stipple;
 %rename(Rasterizer) pipe_rasterizer_state;
diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i
index a40aa1e..84ce1a4 100644
--- a/src/gallium/state_trackers/python/p_context.i
+++ b/src/gallium/state_trackers/python/p_context.i
@@ -52,11 +52,16 @@
       cso_set_blend($self->cso, state);
    }
    
-   void set_sampler( unsigned index, const struct pipe_sampler_state *state ) {
+   void set_fragment_sampler( unsigned index, const struct pipe_sampler_state *state ) {
       cso_single_sampler($self->cso, index, state);
       cso_single_sampler_done($self->cso);
    }
 
+   void set_vertex_sampler( unsigned index, const struct pipe_sampler_state *state ) {
+      cso_single_vertex_sampler($self->cso, index, state);
+      cso_single_vertex_sampler_done($self->cso);
+   }
+
    void set_rasterizer( const struct pipe_rasterizer_state *state ) {
       cso_set_rasterizer($self->cso, state);
    }
@@ -103,6 +108,25 @@
       $self->vs = vs;
    }
 
+   void set_geometry_shader( const struct pipe_shader_state *state ) {
+      void *gs;
+
+      if(!state) {
+         cso_set_geometry_shader_handle($self->cso, NULL);
+         return;
+      }
+
+      gs = $self->pipe->create_gs_state($self->pipe, state);
+      if(!gs)
+         return;
+
+      if(cso_set_geometry_shader_handle($self->cso, gs) != PIPE_OK)
+         return;
+
+      cso_delete_geometry_shader($self->cso, $self->gs);
+      $self->gs = gs;
+   }
+
    /*
     * Parameter-like state (or properties)
     */
@@ -142,14 +166,24 @@
       cso_set_viewport($self->cso, state);
    }
 
-   void set_sampler_texture(unsigned index,
-                            struct pipe_texture *texture) {
+   void set_fragment_sampler_texture(unsigned index,
+                                     struct pipe_texture *texture) {
       if(!texture)
          texture = $self->default_texture;
-      pipe_texture_reference(&$self->sampler_textures[index], texture);
-      $self->pipe->set_sampler_textures($self->pipe, 
-                                        PIPE_MAX_SAMPLERS,
-                                        $self->sampler_textures);
+      pipe_texture_reference(&$self->fragment_sampler_textures[index], texture);
+      $self->pipe->set_fragment_sampler_textures($self->pipe,
+                                                 PIPE_MAX_SAMPLERS,
+                                                 $self->fragment_sampler_textures);
+   }
+
+   void set_vertex_sampler_texture(unsigned index,
+                                   struct pipe_texture *texture) {
+      if(!texture)
+         texture = $self->default_texture;
+      pipe_texture_reference(&$self->vertex_sampler_textures[index], texture);
+      $self->pipe->set_vertex_sampler_textures($self->pipe,
+                                               PIPE_MAX_VERTEX_SAMPLERS,
+                                               $self->vertex_sampler_textures);
    }
 
    void set_vertex_buffer(unsigned index,
diff --git a/src/gallium/state_trackers/python/p_device.i b/src/gallium/state_trackers/python/p_device.i
index f16fe5b..0eba488 100644
--- a/src/gallium/state_trackers/python/p_device.i
+++ b/src/gallium/state_trackers/python/p_device.i
@@ -87,6 +87,10 @@
                             enum pipe_texture_target target,
                             unsigned tex_usage, 
                             unsigned geom_flags ) {
+      /* We can't really display surfaces with the python statetracker so mask
+       * out that usage */
+      tex_usage &= ~PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+
       return $self->screen->is_format_supported( $self->screen, 
                                                  format, 
                                                  target, 
@@ -110,15 +114,20 @@
          unsigned tex_usage = 0
       ) {
       struct pipe_texture templat;
+
+      /* We can't really display surfaces with the python statetracker so mask
+       * out that usage */
+      tex_usage &= ~PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+
       memset(&templat, 0, sizeof(templat));
       templat.format = format;
-      pf_get_block(templat.format, &templat.block);
-      templat.width[0] = width;
-      templat.height[0] = height;
-      templat.depth[0] = depth;
+      templat.width0 = width;
+      templat.height0 = height;
+      templat.depth0 = depth;
       templat.last_level = last_level;
       templat.target = target;
       templat.tex_usage = tex_usage;
+
       return $self->screen->texture_create($self->screen, &templat);
    }
    
diff --git a/src/gallium/state_trackers/python/p_format.i b/src/gallium/state_trackers/python/p_format.i
index 26fb12b..68df009 100644
--- a/src/gallium/state_trackers/python/p_format.i
+++ b/src/gallium/state_trackers/python/p_format.i
@@ -152,11 +152,3 @@
    PIPE_FORMAT_DXT5_SRGBA,
 };
 
-
-struct pipe_format_block
-{
-   unsigned size;
-   unsigned width;
-   unsigned height;
-};
-
diff --git a/src/gallium/state_trackers/python/p_texture.i b/src/gallium/state_trackers/python/p_texture.i
index 1d513ab..761587d 100644
--- a/src/gallium/state_trackers/python/p_texture.i
+++ b/src/gallium/state_trackers/python/p_texture.i
@@ -59,25 +59,17 @@
    }
    
    unsigned get_width(unsigned level=0) {
-      return $self->width[level];
+      return u_minify($self->width0, level);
    }
    
    unsigned get_height(unsigned level=0) {
-      return $self->height[level];
+      return u_minify($self->height0, level);
    }
    
    unsigned get_depth(unsigned level=0) {
-      return $self->depth[level];
+      return u_minify($self->depth0, level);
    }
-   
-   unsigned get_nblocksx(unsigned level=0) {
-      return $self->nblocksx[level];
-   }
-   
-   unsigned get_nblocksy(unsigned level=0) {
-      return $self->nblocksy[level];
-   }
-   
+  
    /** Get a surface which is a "view" into a texture */
    struct st_surface *
    get_surface(unsigned face=0, unsigned level=0, unsigned zslice=0)
@@ -88,7 +80,7 @@
          SWIG_exception(SWIG_ValueError, "face out of bounds");
       if(level > $self->last_level)
          SWIG_exception(SWIG_ValueError, "level out of bounds");
-      if(zslice >= $self->depth[level])
+      if(zslice >= u_minify($self->depth0, level))
          SWIG_exception(SWIG_ValueError, "zslice out of bounds");
       
       surface = CALLOC_STRUCT(st_surface);
@@ -126,8 +118,6 @@
    unsigned format;
    unsigned width;
    unsigned height;
-   unsigned nblocksx;
-   unsigned nblocksy;
    
    ~st_surface() {
       pipe_texture_reference(&$self->texture, NULL);
@@ -142,8 +132,8 @@
       struct pipe_transfer *transfer;
       unsigned stride;
 
-      stride = pf_get_nblocksx(&texture->block, w) * texture->block.size;
-      *LENGTH = pf_get_nblocksy(&texture->block, h) * stride;
+      stride = util_format_get_stride(texture->format, w);
+      *LENGTH = util_format_get_nblocksy(texture->format, h) * stride;
       *STRING = (char *) malloc(*LENGTH);
       if(!*STRING)
          return;
@@ -169,9 +159,9 @@
       struct pipe_transfer *transfer;
      
       if(stride == 0)
-         stride = pf_get_nblocksx(&texture->block, w) * texture->block.size;
+         stride = util_format_get_stride(texture->format, w);
       
-      if(LENGTH < pf_get_nblocksy(&texture->block, h) * stride)
+      if(LENGTH < util_format_get_nblocksy(texture->format, h) * stride)
          SWIG_exception(SWIG_ValueError, "offset must be smaller than buffer size");
          
       transfer = screen->get_tex_transfer(screen,
@@ -375,25 +365,13 @@
    static unsigned
    st_surface_width_get(struct st_surface *surface)
    {
-      return surface->texture->width[surface->level];
+      return u_minify(surface->texture->width0, surface->level);
    }
    
    static unsigned
    st_surface_height_get(struct st_surface *surface)
    {
-      return surface->texture->height[surface->level];
-   }
-
-   static unsigned
-   st_surface_nblocksx_get(struct st_surface *surface)
-   {
-      return surface->texture->nblocksx[surface->level];
-   }
-   
-   static unsigned
-   st_surface_nblocksy_get(struct st_surface *surface)
-   {
-      return surface->texture->nblocksy[surface->level];
+      return u_minify(surface->texture->height0, surface->level);
    }
 %}
 
diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py
index 348f2e4..a68709f 100755
--- a/src/gallium/state_trackers/python/retrace/interpreter.py
+++ b/src/gallium/state_trackers/python/retrace/interpreter.py
@@ -52,10 +52,10 @@
         w = surface.width - x
     if h is None:
         h = surface.height - y
-    data = surface.get_tile_rgba8(0, 0, surface.width, surface.height)
+    data = surface.get_tile_rgba8(x, y, surface.width, surface.height)
 
     import Image
-    outimage = Image.fromstring('RGBA', (surface.width, surface.height), data, "raw", 'RGBA', 0, 1)
+    outimage = Image.fromstring('RGBA', (w, h), data, "raw", 'RGBA', 0, 1)
     return outimage
 
 def save_image(filename, surface, x=None, y=None, w=None, h=None):
@@ -99,7 +99,6 @@
     "pipe_stencil_state": gallium.Stencil,
     "pipe_alpha_state": gallium.Alpha,
     "pipe_depth_stencil_alpha_state": gallium.DepthStencilAlpha,
-    "pipe_format_block": gallium.FormatBlock,
     #"pipe_framebuffer_state": gallium.Framebuffer,
     "pipe_poly_stipple": gallium.PolyStipple,
     "pipe_rasterizer_state": gallium.Rasterizer,
@@ -279,9 +278,9 @@
     def texture_create(self, templat):
         return self.real.texture_create(
             format = templat.format,
-            width = templat.width[0],
-            height = templat.height[0],
-            depth = templat.depth[0],
+            width = templat.width,
+            height = templat.height,
+            depth = templat.depth,
             last_level = templat.last_level,
             target = templat.target,
             tex_usage = templat.tex_usage,
@@ -307,7 +306,7 @@
     def surface_write(self, surface, data, stride, size):
         if surface is None:
             return
-        assert surface.nblocksy * stride == size 
+#        assert surface.nblocksy * stride == size 
         surface.put_tile_raw(0, 0, surface.width, surface.height, data, stride)
 
     def get_tex_transfer(self, texture, face, level, zslice, usage, x, y, w, h):
@@ -388,9 +387,13 @@
     def delete_sampler_state(self, state):
         pass
 
-    def bind_sampler_states(self, num_states, states):
+    def bind_vertex_sampler_states(self, num_states, states):
         for i in range(num_states):
-            self.real.set_sampler(i, states[i])
+            self.real.set_vertex_sampler(i, states[i])
+        
+    def bind_fragment_sampler_states(self, num_states, states):
+        for i in range(num_states):
+            self.real.set_fragment_sampler(i, states[i])
         
     def create_rasterizer_state(self, state):
         return state
@@ -486,9 +489,13 @@
     def set_viewport_state(self, state):
         self.real.set_viewport(state)
 
-    def set_sampler_textures(self, num_textures, textures):
+    def set_fragment_sampler_textures(self, num_textures, textures):
         for i in range(num_textures):
-            self.real.set_sampler_texture(i, textures[i])
+            self.real.set_fragment_sampler_texture(i, textures[i])
+
+    def set_vertex_sampler_textures(self, num_textures, textures):
+        for i in range(num_textures):
+            self.real.set_vertex_sampler_texture(i, textures[i])
 
     def set_vertex_buffers(self, num_buffers, buffers):
         self.vbufs = buffers[0:num_buffers]
@@ -508,10 +515,6 @@
             self.real.set_vertex_element(i, elements[i])
         self.real.set_vertex_elements(num_elements)
 
-    def set_edgeflags(self, bitfield):
-        # FIXME
-        pass
-    
     def dump_vertices(self, start, count):
         if not self.interpreter.verbosity(2):
             return
diff --git a/src/gallium/state_trackers/python/samples/gs.py b/src/gallium/state_trackers/python/samples/gs.py
new file mode 100644
index 0000000..a07cf55
--- /dev/null
+++ b/src/gallium/state_trackers/python/samples/gs.py
@@ -0,0 +1,254 @@
+#!/usr/bin/env python
+##########################################################################
+#
+# Copyright 2009 VMware
+# 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.
+#
+##########################################################################
+
+
+from gallium import *
+
+
+def make_image(surface):
+    data = surface.get_tile_rgba8(0, 0, surface.width, surface.height)
+
+    import Image
+    outimage = Image.fromstring('RGBA', (surface.width, surface.height), data, "raw", 'RGBA', 0, 1)
+    return outimage
+
+def save_image(filename, surface):
+    outimage = make_image(surface)
+    outimage.save(filename, "PNG")
+
+def show_image(surface):
+    outimage = make_image(surface)
+
+    import Tkinter as tk
+    from PIL import Image, ImageTk
+    root = tk.Tk()
+
+    root.title('background image')
+
+    image1 = ImageTk.PhotoImage(outimage)
+    w = image1.width()
+    h = image1.height()
+    x = 100
+    y = 100
+    root.geometry("%dx%d+%d+%d" % (w, h, x, y))
+    panel1 = tk.Label(root, image=image1)
+    panel1.pack(side='top', fill='both', expand='yes')
+    panel1.image = image1
+    root.mainloop()
+
+
+def test(dev):
+    ctx = dev.context_create()
+
+    width = 255
+    height = 255
+    minz = 0.0
+    maxz = 1.0
+
+    # disabled blending/masking
+    blend = Blend()
+    blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
+    blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
+    blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
+    blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
+    blend.colormask = PIPE_MASK_RGBA
+    ctx.set_blend(blend)
+
+    # depth/stencil/alpha
+    depth_stencil_alpha = DepthStencilAlpha()
+    depth_stencil_alpha.depth.enabled = 1
+    depth_stencil_alpha.depth.writemask = 1
+    depth_stencil_alpha.depth.func = PIPE_FUNC_LESS
+    ctx.set_depth_stencil_alpha(depth_stencil_alpha)
+
+    # rasterizer
+    rasterizer = Rasterizer()
+    rasterizer.front_winding = PIPE_WINDING_CW
+    rasterizer.cull_mode = PIPE_WINDING_NONE
+    rasterizer.scissor = 1
+    ctx.set_rasterizer(rasterizer)
+
+    # viewport
+    viewport = Viewport()
+    scale = FloatArray(4)
+    scale[0] = width / 2.0
+    scale[1] = -height / 2.0
+    scale[2] = (maxz - minz) / 2.0
+    scale[3] = 1.0
+    viewport.scale = scale
+    translate = FloatArray(4)
+    translate[0] = width / 2.0
+    translate[1] = height / 2.0
+    translate[2] = (maxz - minz) / 2.0
+    translate[3] = 0.0
+    viewport.translate = translate
+    ctx.set_viewport(viewport)
+
+    # samplers
+    sampler = Sampler()
+    sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE
+    sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE
+    sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE
+    sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE
+    sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST
+    sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST
+    sampler.normalized_coords = 1
+    ctx.set_sampler(0, sampler)
+
+    # scissor
+    scissor = Scissor()
+    scissor.minx = 0
+    scissor.miny = 0
+    scissor.maxx = width
+    scissor.maxy = height
+    ctx.set_scissor(scissor)
+
+    clip = Clip()
+    clip.nr = 0
+    ctx.set_clip(clip)
+
+    # framebuffer
+    cbuf = dev.texture_create(
+        PIPE_FORMAT_X8R8G8B8_UNORM,
+        width, height,
+        tex_usage=PIPE_TEXTURE_USAGE_RENDER_TARGET,
+    ).get_surface()
+    zbuf = dev.texture_create(
+        PIPE_FORMAT_Z32_UNORM,
+        width, height,
+        tex_usage=PIPE_TEXTURE_USAGE_DEPTH_STENCIL,
+    ).get_surface()
+    fb = Framebuffer()
+    fb.width = width
+    fb.height = height
+    fb.nr_cbufs = 1
+    fb.set_cbuf(0, cbuf)
+    fb.set_zsbuf(zbuf)
+    ctx.set_framebuffer(fb)
+    rgba = FloatArray(4);
+    rgba[0] = 0.0
+    rgba[1] = 0.0
+    rgba[2] = 0.0
+    rgba[3] = 0.0
+    ctx.clear(PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL, rgba, 1.0, 0xff)
+
+    # vertex shader
+    vs = Shader('''
+        VERT
+        DCL IN[0], POSITION, CONSTANT
+        DCL IN[1], COLOR, CONSTANT
+        DCL OUT[0], POSITION, CONSTANT
+        DCL OUT[1], COLOR, CONSTANT
+        0:MOV OUT[0], IN[0]
+        1:MOV OUT[1], IN[1]
+        2:END
+    ''')
+    ctx.set_vertex_shader(vs)
+
+    gs = Shader('''
+        GEOM
+        PROPERTY GS_INPUT_PRIMITIVE TRIANGLES
+        PROPERTY GS_OUTPUT_PRIMITIVE TRIANGLE_STRIP
+        DCL IN[][0], POSITION, CONSTANT
+        DCL IN[][1], COLOR, CONSTANT
+        DCL OUT[0], POSITION, CONSTANT
+        DCL OUT[1], COLOR, CONSTANT
+        0:MOV OUT[0], IN[0][0]
+        1:MOV OUT[1], IN[0][1]
+        2:EMIT
+        3:MOV OUT[0], IN[1][0]
+        4:MOV OUT[1], IN[1][1]
+        5:EMIT
+        6:MOV OUT[0], IN[2][0]
+        7:MOV OUT[1], IN[2][1]
+        8:EMIT
+        9:ENDPRIM
+        10:END
+    ''')
+    ctx.set_geometry_shader(gs)
+
+    # fragment shader
+    fs = Shader('''
+        FRAG
+        DCL IN[0], COLOR, LINEAR
+        DCL OUT[0], COLOR, CONSTANT
+        0:MOV OUT[0], IN[0]
+        1:END
+    ''')
+    ctx.set_fragment_shader(fs)
+
+    nverts = 3
+    nattrs = 2
+    verts = FloatArray(nverts * nattrs * 4)
+
+    verts[ 0] =   0.0 # x1
+    verts[ 1] =   0.8 # y1
+    verts[ 2] =   0.2 # z1
+    verts[ 3] =   1.0 # w1
+    verts[ 4] =   1.0 # r1
+    verts[ 5] =   0.0 # g1
+    verts[ 6] =   0.0 # b1
+    verts[ 7] =   1.0 # a1
+    verts[ 8] =  -0.8 # x2
+    verts[ 9] =  -0.8 # y2
+    verts[10] =   0.5 # z2
+    verts[11] =   1.0 # w2
+    verts[12] =   0.0 # r2
+    verts[13] =   1.0 # g2
+    verts[14] =   0.0 # b2
+    verts[15] =   1.0 # a2
+    verts[16] =   0.8 # x3
+    verts[17] =  -0.8 # y3
+    verts[18] =   0.8 # z3
+    verts[19] =   1.0 # w3
+    verts[20] =   0.0 # r3
+    verts[21] =   0.0 # g3
+    verts[22] =   1.0 # b3
+    verts[23] =   1.0 # a3
+
+    ctx.draw_vertices(PIPE_PRIM_TRIANGLES,
+                      nverts,
+                      nattrs,
+                      verts)
+
+    ctx.flush()
+
+    show_image(cbuf)
+    #show_image(zbuf)
+    #save_image('cbuf.png', cbuf)
+    #save_image('zbuf.png', zbuf)
+
+
+
+def main():
+    dev = Device()
+    test(dev)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/src/gallium/state_trackers/python/samples/tri.py b/src/gallium/state_trackers/python/samples/tri.py
index b721e0b..e5e168b 100644
--- a/src/gallium/state_trackers/python/samples/tri.py
+++ b/src/gallium/state_trackers/python/samples/tri.py
@@ -118,7 +118,7 @@
     sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST
     sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST
     sampler.normalized_coords = 1
-    ctx.set_sampler(0, sampler)
+    ctx.set_fragment_sampler(0, sampler)
 
     # scissor
     scissor = Scissor()
@@ -136,10 +136,10 @@
     cbuf = dev.texture_create(
         PIPE_FORMAT_X8R8G8B8_UNORM, 
         width, height,
-        tex_usage=PIPE_TEXTURE_USAGE_DISPLAY_TARGET,
+        tex_usage=PIPE_TEXTURE_USAGE_RENDER_TARGET,
     ).get_surface()
     zbuf = dev.texture_create(
-        PIPE_FORMAT_Z16_UNORM, 
+        PIPE_FORMAT_Z32_UNORM,
         width, height,
         tex_usage=PIPE_TEXTURE_USAGE_DEPTH_STENCIL,
     ).get_surface()
@@ -159,7 +159,7 @@
     
     # vertex shader
     vs = Shader('''
-        VERT1.1
+        VERT
         DCL IN[0], POSITION, CONSTANT
         DCL IN[1], COLOR, CONSTANT
         DCL OUT[0], POSITION, CONSTANT
@@ -172,7 +172,7 @@
 
     # fragment shader
     fs = Shader('''
-        FRAG1.1
+        FRAG
         DCL IN[0], COLOR, LINEAR
         DCL OUT[0], COLOR, CONSTANT
         0:MOV OUT[0], IN[0]
diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c
index ea7d187..d144af2 100644
--- a/src/gallium/state_trackers/python/st_device.c
+++ b/src/gallium/state_trackers/python/st_device.c
@@ -62,8 +62,9 @@
 {
    struct st_device *old_dev = *ptr;
 
-   if (pipe_reference((struct pipe_reference **)ptr, &st_dev->reference))
+   if (pipe_reference(&(*ptr)->reference, &st_dev->reference))
       st_device_really_destroy(old_dev);
+   *ptr = st_dev;
 }
 
 
@@ -134,7 +135,9 @@
          st_ctx->pipe->destroy(st_ctx->pipe);
       
       for(i = 0; i < PIPE_MAX_SAMPLERS; ++i)
-         pipe_texture_reference(&st_ctx->sampler_textures[i], NULL);
+         pipe_texture_reference(&st_ctx->fragment_sampler_textures[i], NULL);
+      for(i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; ++i)
+         pipe_texture_reference(&st_ctx->vertex_sampler_textures[i], NULL);
       pipe_texture_reference(&st_ctx->default_texture, NULL);
 
       FREE(st_ctx);
@@ -249,12 +252,9 @@
       memset( &templat, 0, sizeof( templat ) );
       templat.target = PIPE_TEXTURE_2D;
       templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
-      templat.block.size = 4;
-      templat.block.width = 1;
-      templat.block.height = 1;
-      templat.width[0] = 1;
-      templat.height[0] = 1;
-      templat.depth[0] = 1;
+      templat.width0 = 1;
+      templat.height0 = 1;
+      templat.depth0 = 1;
       templat.last_level = 0;
    
       st_ctx->default_texture = screen->texture_create( screen, &templat );
@@ -264,8 +264,8 @@
                                              0, 0, 0,
                                              PIPE_TRANSFER_WRITE,
                                              0, 0,
-                                             st_ctx->default_texture->width[0],
-                                             st_ctx->default_texture->height[0]);
+                                             st_ctx->default_texture->width0,
+                                             st_ctx->default_texture->height0);
          if (transfer) {
             uint32_t *map;
             map = (uint32_t *) screen->transfer_map(screen, transfer);
@@ -278,9 +278,12 @@
       }
    
       for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
-         pipe_texture_reference(&st_ctx->sampler_textures[i], st_ctx->default_texture);
+         pipe_texture_reference(&st_ctx->fragment_sampler_textures[i], st_ctx->default_texture);
+      for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++)
+         pipe_texture_reference(&st_ctx->vertex_sampler_textures[i], st_ctx->default_texture);
       
-      cso_set_sampler_textures(st_ctx->cso, PIPE_MAX_SAMPLERS, st_ctx->sampler_textures);
+      cso_set_sampler_textures(st_ctx->cso, PIPE_MAX_SAMPLERS, st_ctx->fragment_sampler_textures);
+      cso_set_vertex_sampler_textures(st_ctx->cso, PIPE_MAX_VERTEX_SAMPLERS, st_ctx->vertex_sampler_textures);
    }
    
    /* vertex shader */
diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h
index a246b6a..f786e13 100644
--- a/src/gallium/state_trackers/python/st_device.h
+++ b/src/gallium/state_trackers/python/st_device.h
@@ -57,9 +57,11 @@
    
    void *vs;
    void *fs;
+   void *gs;
 
    struct pipe_texture *default_texture;
-   struct pipe_texture *sampler_textures[PIPE_MAX_SAMPLERS];
+   struct pipe_texture *fragment_sampler_textures[PIPE_MAX_SAMPLERS];
+   struct pipe_texture *vertex_sampler_textures[PIPE_MAX_VERTEX_SAMPLERS];
    
    unsigned num_vertex_buffers;
    struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
diff --git a/src/gallium/state_trackers/python/st_llvmpipe_winsys.c b/src/gallium/state_trackers/python/st_llvmpipe_winsys.c
new file mode 100644
index 0000000..0096b18
--- /dev/null
+++ b/src/gallium/state_trackers/python/st_llvmpipe_winsys.c
@@ -0,0 +1,148 @@
+/**************************************************************************
+ * 
+ * Copyright 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 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * 
+ **************************************************************************/
+
+/**
+ * @file
+ * Llvmpipe support. 
+ * 
+ * @author Jose Fonseca
+ */
+
+
+#include "pipe/p_format.h"
+#include "pipe/p_context.h"
+#include "pipe/p_inlines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "llvmpipe/lp_winsys.h"
+#include "st_winsys.h"
+
+
+static boolean
+llvmpipe_ws_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
+      enum pipe_format format )
+{
+   return FALSE;
+}
+
+
+static void *
+llvmpipe_ws_displaytarget_map(struct llvmpipe_winsys *ws,
+                              struct llvmpipe_displaytarget *dt,
+                              unsigned flags )
+{
+   assert(0);
+   return NULL;
+}
+
+
+static void
+llvmpipe_ws_displaytarget_unmap(struct llvmpipe_winsys *ws,
+                                struct llvmpipe_displaytarget *dt )
+{
+   assert(0);
+}
+
+
+static void
+llvmpipe_ws_displaytarget_destroy(struct llvmpipe_winsys *winsys,
+                                  struct llvmpipe_displaytarget *dt)
+{
+   assert(0);
+}
+
+
+static struct llvmpipe_displaytarget *
+llvmpipe_ws_displaytarget_create(struct llvmpipe_winsys *winsys,
+                                 enum pipe_format format,
+                                 unsigned width, unsigned height,
+                                 unsigned alignment,
+                                 unsigned *stride)
+{
+   return NULL;
+}
+
+
+static void
+llvmpipe_ws_displaytarget_display(struct llvmpipe_winsys *winsys,
+                                  struct llvmpipe_displaytarget *dt,
+                                  void *context_private)
+{
+   assert(0);
+}
+
+
+static void
+llvmpipe_ws_destroy(struct llvmpipe_winsys *winsys)
+{
+   FREE(winsys);
+}
+
+
+static struct pipe_screen *
+st_llvmpipe_screen_create(void)
+{
+   static struct llvmpipe_winsys *winsys;
+   struct pipe_screen *screen;
+
+   winsys = CALLOC_STRUCT(llvmpipe_winsys);
+   if (!winsys)
+      goto no_winsys;
+
+   winsys->destroy = llvmpipe_ws_destroy;
+   winsys->is_displaytarget_format_supported = llvmpipe_ws_is_displaytarget_format_supported;
+   winsys->displaytarget_create = llvmpipe_ws_displaytarget_create;
+   winsys->displaytarget_map = llvmpipe_ws_displaytarget_map;
+   winsys->displaytarget_unmap = llvmpipe_ws_displaytarget_unmap;
+   winsys->displaytarget_display = llvmpipe_ws_displaytarget_display;
+   winsys->displaytarget_destroy = llvmpipe_ws_displaytarget_destroy;
+
+   screen = llvmpipe_create_screen(winsys);
+   if (!screen)
+      goto no_screen;
+
+   return screen;
+
+no_screen:
+   FREE(winsys);
+no_winsys:
+   return NULL;
+}
+
+
+static struct pipe_context *
+st_llvmpipe_context_create(struct pipe_screen *screen)
+{
+   return llvmpipe_create(screen);
+}
+
+
+const struct st_winsys st_softpipe_winsys = {
+   &st_llvmpipe_screen_create,
+   &st_llvmpipe_context_create,
+};
diff --git a/src/gallium/state_trackers/python/st_sample.c b/src/gallium/state_trackers/python/st_sample.c
index 53a0189..9637741 100644
--- a/src/gallium/state_trackers/python/st_sample.c
+++ b/src/gallium/state_trackers/python/st_sample.c
@@ -30,6 +30,7 @@
 #include "pipe/p_format.h"
 #include "pipe/p_state.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
 #include "util/u_tile.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
@@ -423,7 +424,6 @@
 
 static INLINE void 
 st_sample_dxt_pixel_block(enum pipe_format format, 
-                          const struct pipe_format_block *block,
                           uint8_t *raw,
                           float *rgba, unsigned rgba_stride, 
                           unsigned w, unsigned h)
@@ -462,21 +462,21 @@
          for(ch = 0; ch < 4; ++ch)
             rgba[y*rgba_stride + x*4 + ch] = (float)(data[i].rgba[y*4*4 + x*4 + ch])/255.0f;
    
-   memcpy(raw, data[i].raw, block->size);
+   memcpy(raw, data[i].raw, util_format_get_blocksize(format));
 }
 
 
 static INLINE void 
 st_sample_generic_pixel_block(enum pipe_format format, 
-                              const struct pipe_format_block *block,
                               uint8_t *raw,
                               float *rgba, unsigned rgba_stride,
                               unsigned w, unsigned h)
 {
    unsigned i;
    unsigned x, y, ch;
+   int blocksize = util_format_get_blocksize(format);
    
-   for(i = 0; i < block->size; ++i)
+   for(i = 0; i < blocksize; ++i)
       raw[i] = (uint8_t)st_random();
    
    
@@ -503,7 +503,6 @@
  */
 void 
 st_sample_pixel_block(enum pipe_format format,
-                      const struct pipe_format_block *block,
                       void *raw,
                       float *rgba, unsigned rgba_stride,
                       unsigned w, unsigned h)
@@ -513,11 +512,11 @@
    case PIPE_FORMAT_DXT1_RGBA:
    case PIPE_FORMAT_DXT3_RGBA:
    case PIPE_FORMAT_DXT5_RGBA:
-      st_sample_dxt_pixel_block(format, block, raw, rgba, rgba_stride, w, h);
+      st_sample_dxt_pixel_block(format, raw, rgba, rgba_stride, w, h);
       break;
 
    default:
-      st_sample_generic_pixel_block(format, block, raw, rgba, rgba_stride, w, h);
+      st_sample_generic_pixel_block(format, raw, rgba, rgba_stride, w, h);
       break;
    }
 }
@@ -528,8 +527,8 @@
 {
    struct pipe_texture *texture = surface->texture;
    struct pipe_screen *screen = texture->screen;
-   unsigned width = texture->width[surface->level];
-   unsigned height = texture->height[surface->level];
+   unsigned width = u_minify(texture->width0, surface->level);
+   unsigned height = u_minify(texture->height0, surface->level);
    uint rgba_stride = width * 4;
    struct pipe_transfer *transfer;
    void *raw;
@@ -548,18 +547,23 @@
 
    raw = screen->transfer_map(screen, transfer);
    if (raw) {
-      const struct pipe_format_block *block = &texture->block;
+      enum pipe_format format = texture->format;
       uint x, y;
+      int nblocksx = util_format_get_nblocksx(format, width);
+      int nblocksy = util_format_get_nblocksy(format, height);
+      int blockwidth = util_format_get_blockwidth(format);
+      int blockheight = util_format_get_blockheight(format);
+      int blocksize = util_format_get_blocksize(format);
 
-      for (y = 0; y < transfer->nblocksy; ++y) {
-         for (x = 0; x < transfer->nblocksx; ++x) {
-            st_sample_pixel_block(texture->format,
-                                  block,
-                                  (uint8_t *) raw + y * transfer->stride + x * block->size,
-                                  rgba + y * block->height * rgba_stride + x * block->width * 4,
+
+      for (y = 0; y < nblocksy; ++y) {
+         for (x = 0; x < nblocksx; ++x) {
+            st_sample_pixel_block(format,
+                                  (uint8_t *) raw + y * transfer->stride + x * blocksize,
+                                  rgba + y * blockheight * rgba_stride + x * blockwidth * 4,
                                   rgba_stride,
-                                  MIN2(block->width, width - x*block->width),
-                                  MIN2(block->height, height - y*block->height));
+                                  MIN2(blockwidth, width - x*blockwidth),
+                                  MIN2(blockheight, height - y*blockheight));
          }
       }
 
diff --git a/src/gallium/state_trackers/python/st_sample.h b/src/gallium/state_trackers/python/st_sample.h
index 0a27083..888114d 100644
--- a/src/gallium/state_trackers/python/st_sample.h
+++ b/src/gallium/state_trackers/python/st_sample.h
@@ -35,7 +35,6 @@
 
 void 
 st_sample_pixel_block(enum pipe_format format,
-                      const struct pipe_format_block *block,
                       void *raw,
                       float *rgba, unsigned rgba_stride,
                       unsigned w, unsigned h);
diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c
index f0abd12..a3294e8 100644
--- a/src/gallium/state_trackers/python/st_softpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c
@@ -40,6 +40,7 @@
 #include "pipe/p_format.h"
 #include "pipe/p_context.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "softpipe/sp_winsys.h"
@@ -157,16 +158,6 @@
 }
 
 
-/**
- * Round n up to next multiple.
- */
-static INLINE unsigned
-round_up(unsigned n, unsigned multiple)
-{
-   return (n + multiple - 1) & ~(multiple - 1);
-}
-
-
 static struct pipe_buffer *
 st_softpipe_surface_buffer_create(struct pipe_winsys *winsys,
                                   unsigned width, unsigned height,
@@ -176,13 +167,10 @@
                                   unsigned *stride)
 {
    const unsigned alignment = 64;
-   struct pipe_format_block block;
-   unsigned nblocksx, nblocksy;
+   unsigned nblocksy;
 
-   pf_get_block(format, &block);
-   nblocksx = pf_get_nblocksx(&block, width);
-   nblocksy = pf_get_nblocksy(&block, height);
-   *stride = round_up(nblocksx * block.size, alignment);
+   nblocksy = util_format_get_nblocksy(format, height);
+   *stride = align(util_format_get_stride(format, width), alignment);
 
    return winsys->buffer_create(winsys, alignment,
                                 usage,
diff --git a/src/gallium/state_trackers/python/tests/base.py b/src/gallium/state_trackers/python/tests/base.py
index 202ccfc..b022d07 100755
--- a/src/gallium/state_trackers/python/tests/base.py
+++ b/src/gallium/state_trackers/python/tests/base.py
@@ -47,7 +47,7 @@
         formats[value] = name
 
 def is_depth_stencil_format(format):
-    # FIXME: make and use binding to pf_is_depth_stencil
+    # FIXME: make and use binding to util_format_is_depth_or_stencil
     return format in (
         PIPE_FORMAT_Z32_UNORM,
         PIPE_FORMAT_Z24S8_UNORM,
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-abs.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-abs.sh
index 7a0006b..103d749 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-abs.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-abs.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-add.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-add.sh
index f7836c8..bcb9420 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-add.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-add.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp3.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp3.sh
index c89cd74..b528197 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp3.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp3.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp4.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp4.sh
index 6517e3c..d59df76 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp4.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp4.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dst.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dst.sh
index 464880b..fbb20fa 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dst.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dst.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-ex2.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-ex2.sh
index 2684076..b511288 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-ex2.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-ex2.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-flr.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-flr.sh
index ad11e28..99a2f96 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-flr.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-flr.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-frc.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-frc.sh
index 4f3aa30..a54c262 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-frc.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-frc.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lg2.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lg2.sh
index 54c7c64..5f5b4be 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lg2.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lg2.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lit.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lit.sh
index 0e78ef8..6323c47 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lit.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lit.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lrp.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lrp.sh
index e9ee0f8..740809d 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lrp.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lrp.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mad.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mad.sh
index 439acd5..413b9dc 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mad.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mad.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-max.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-max.sh
index ab21b24..b69f213 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-max.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-max.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-min.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-min.sh
index 969ae73..df284f4 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-min.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-min.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mov.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mov.sh
index 612975e..64af72f 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mov.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mov.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mul.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mul.sh
index ed158b0..bdd0b00 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mul.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mul.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rcp.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rcp.sh
index cc9feef..f4b611b 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rcp.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rcp.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rsq.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rsq.sh
index 695621f..d1e9b0b 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rsq.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rsq.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sge.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sge.sh
index 9505bc3..1f33fac 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sge.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sge.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-abs.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-abs.sh
index 9cd4b68..ecd1924 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-abs.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-abs.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh
index acd6aa7..c2d99dd 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-neg.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-neg.sh
index ba1b615..a08ab6d 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-neg.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-neg.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-swz.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-swz.sh
index 192aa7b..6110647 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-swz.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-swz.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sub.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sub.sh
index 83441fa..673fca1 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sub.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sub.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-xpd.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-xpd.sh
index d6f66c4..6ec8b11 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-xpd.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-xpd.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
 
 DCL IN[0], COLOR, LINEAR
 DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py b/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py
index d60fb38..8d3bf9d 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py
@@ -96,7 +96,7 @@
     sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST
     sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST
     sampler.normalized_coords = 1
-    ctx.set_sampler(0, sampler)
+    ctx.set_fragment_sampler(0, sampler)
 
     # scissor
     scissor = Scissor()
@@ -114,7 +114,7 @@
     cbuf = dev.texture_create(
         PIPE_FORMAT_X8R8G8B8_UNORM,
         width, height,
-        tex_usage=PIPE_TEXTURE_USAGE_DISPLAY_TARGET,
+        tex_usage=PIPE_TEXTURE_USAGE_RENDER_TARGET,
     ).get_surface()
     fb = Framebuffer()
     fb.width = width
@@ -131,7 +131,7 @@
 
     # vertex shader
     vs = Shader('''
-        VERT1.1
+        VERT
         DCL IN[0], POSITION
         DCL IN[1], COLOR
         DCL OUT[0], POSITION
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-abs.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-abs.sh
index f0d0d5d..79c9ca6 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-abs.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-abs.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-add.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-add.sh
index 936c851..ca97ad0 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-add.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-add.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arl.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arl.sh
index 7638e96..321140e 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arl.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arl.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL OUT[0], POSITION
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arr.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arr.sh
index 28ce6f9..d60ea46 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arr.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arr.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL OUT[0], POSITION
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp3.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp3.sh
index b57d685..caff622 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp3.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp3.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp4.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp4.sh
index 0eb3171..3dd2fd1 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp4.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp4.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dst.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dst.sh
index dc5e0eb..da9cc18 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dst.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dst.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-ex2.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-ex2.sh
index 34057af..4637227 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-ex2.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-ex2.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-flr.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-flr.sh
index 44ad708..aa80d6e 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-flr.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-flr.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL OUT[0], POSITION
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-frc.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-frc.sh
index d179749..64d1a49 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-frc.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-frc.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL OUT[0], POSITION
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lg2.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lg2.sh
index f6e08d0..5cf16fd 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lg2.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lg2.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lit.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lit.sh
index da98f30..a4a752d 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lit.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lit.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lrp.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lrp.sh
index 8c26258..4bb5f3e 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lrp.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lrp.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mad.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mad.sh
index eb07a3b..daaa941 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mad.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mad.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-max.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-max.sh
index 2d8b1fe..af279ec 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-max.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-max.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-min.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-min.sh
index 84af0e2..46d886c 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-min.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-min.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mov.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mov.sh
index bcdec07..0ef9163 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mov.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mov.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mul.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mul.sh
index f3b57c3..d34f6cd 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mul.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mul.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rcp.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rcp.sh
index 78af589..cfb3ec3 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rcp.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rcp.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rsq.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rsq.sh
index 1675c7d..faf1e6e 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rsq.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rsq.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sge.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sge.sh
index 3d92cd5..6de1d07 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sge.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sge.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-slt.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-slt.sh
index 85c60ff..9a52422 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-slt.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-slt.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-abs.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-abs.sh
index 6db417a..dc87ce4 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-abs.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-abs.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh
index fc83238..d82eb08 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-neg.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-neg.sh
index ce4e90b..e39bebc 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-neg.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-neg.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-swz.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-swz.sh
index c03de4c..6f20552 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-swz.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-swz.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sub.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sub.sh
index a583b95..0f9678b 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sub.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sub.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-xpd.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-xpd.sh
index 8def894..39d42ae 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-xpd.sh
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-xpd.sh
@@ -1,4 +1,4 @@
-VERT1.1
+VERT
 
 DCL IN[0], POSITION
 DCL IN[1], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py
index 472769f..01bf5a3 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py
@@ -96,7 +96,7 @@
     sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST
     sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST
     sampler.normalized_coords = 1
-    ctx.set_sampler(0, sampler)
+    ctx.set_fragment_sampler(0, sampler)
 
     # scissor
     scissor = Scissor()
@@ -114,7 +114,7 @@
     cbuf = dev.texture_create(
         PIPE_FORMAT_X8R8G8B8_UNORM,
         width, height,
-        tex_usage=PIPE_TEXTURE_USAGE_DISPLAY_TARGET,
+        tex_usage=PIPE_TEXTURE_USAGE_RENDER_TARGET,
     ).get_surface()
     fb = Framebuffer()
     fb.width = width
@@ -135,7 +135,7 @@
 
     # fragment shader
     fs = Shader('''
-        FRAG1.1
+        FRAG
         DCL IN[0], COLOR, LINEAR
         DCL OUT[0], COLOR, CONSTANT
         0:MOV OUT[0], IN[0]
diff --git a/src/gallium/state_trackers/python/tests/surface_copy.py b/src/gallium/state_trackers/python/tests/surface_copy.py
index 3ceecbb..df5babb 100755
--- a/src/gallium/state_trackers/python/tests/surface_copy.py
+++ b/src/gallium/state_trackers/python/tests/surface_copy.py
@@ -98,9 +98,10 @@
         y = 0
         w = dst_surface.width
         h = dst_surface.height
-    
-        stride = dst_surface.nblocksx * dst_texture.block.size
-        size = dst_surface.nblocksy * stride
+
+        # ???
+        stride = pf_get_stride(texture->format, w)
+        size = pf_get_nblocksy(texture->format) * stride
         src_raw = os.urandom(size)
 
         src_surface.put_tile_raw(0, 0, w, h, src_raw, stride)
diff --git a/src/gallium/state_trackers/python/tests/texture_render.py b/src/gallium/state_trackers/python/tests/texture_render.py
index 0b76932..79287f2 100755
--- a/src/gallium/state_trackers/python/tests/texture_render.py
+++ b/src/gallium/state_trackers/python/tests/texture_render.py
@@ -144,8 +144,8 @@
         sampler.normalized_coords = 1
         sampler.min_lod = 0
         sampler.max_lod = PIPE_MAX_TEXTURE_LEVELS - 1
-        ctx.set_sampler(0, sampler)
-        ctx.set_sampler_texture(0, src_texture)
+        ctx.set_fragment_sampler(0, sampler)
+        ctx.set_fragment_sampler_texture(0, src_texture)
 
         #  framebuffer 
         cbuf_tex = dev.texture_create(
@@ -171,7 +171,7 @@
     
         # vertex shader
         vs = Shader('''
-            VERT1.1
+            VERT
             DCL IN[0], POSITION, CONSTANT
             DCL IN[1], GENERIC, CONSTANT
             DCL OUT[0], POSITION, CONSTANT
@@ -185,7 +185,7 @@
     
         # fragment shader
         fs = Shader('''
-            FRAG1.1
+            FRAG
             DCL IN[0], GENERIC[0], LINEAR
             DCL OUT[0], COLOR, CONSTANT
             DCL SAMP[0], CONSTANT
diff --git a/src/gallium/state_trackers/python/tests/texture_sample.py b/src/gallium/state_trackers/python/tests/texture_sample.py
index c7b78ab..520961c 100755
--- a/src/gallium/state_trackers/python/tests/texture_sample.py
+++ b/src/gallium/state_trackers/python/tests/texture_sample.py
@@ -169,7 +169,7 @@
         sampler.normalized_coords = 1
         sampler.min_lod = 0
         sampler.max_lod = PIPE_MAX_TEXTURE_LEVELS - 1
-        ctx.set_sampler(0, sampler)
+        ctx.set_fragment_sampler(0, sampler)
     
         #  texture 
         texture = dev.texture_create(
@@ -189,7 +189,7 @@
             zslice = zslice,
         ).sample_rgba(expected_rgba)
         
-        ctx.set_sampler_texture(0, texture)
+        ctx.set_fragment_sampler_texture(0, texture)
 
         #  framebuffer 
         cbuf_tex = dev.texture_create(
@@ -216,7 +216,7 @@
     
         # vertex shader
         vs = Shader('''
-            VERT1.1
+            VERT
             DCL IN[0], POSITION, CONSTANT
             DCL IN[1], GENERIC, CONSTANT
             DCL OUT[0], POSITION, CONSTANT
@@ -236,7 +236,7 @@
             PIPE_TEXTURE_CUBE: "CUBE",
         }[target]
         fs = Shader('''
-            FRAG1.1
+            FRAG
             DCL IN[0], GENERIC[0], LINEAR
             DCL OUT[0], COLOR, CONSTANT
             DCL SAMP[0], CONSTANT
@@ -359,7 +359,7 @@
         sampler.normalized_coords = 1
         sampler.min_lod = 0
         sampler.max_lod = PIPE_MAX_TEXTURE_LEVELS - 1
-        ctx.set_sampler(0, sampler)
+        ctx.set_fragment_sampler(0, sampler)
     
         #  texture 
         texture = dev.texture_create(
@@ -379,7 +379,7 @@
             zslice = zslice,
         ).sample_rgba(expected_rgba)
         
-        ctx.set_sampler_texture(0, texture)
+        ctx.set_fragment_sampler_texture(0, texture)
 
         #  framebuffer 
         cbuf_tex = dev.texture_create(
@@ -415,7 +415,7 @@
     
         # vertex shader
         vs = Shader('''
-            VERT1.1
+            VERT
             DCL IN[0], POSITION, CONSTANT
             DCL IN[1], GENERIC, CONSTANT
             DCL OUT[0], POSITION, CONSTANT
@@ -435,7 +435,7 @@
             PIPE_TEXTURE_CUBE: "CUBE",
         }[target]
         fs = Shader('''
-            FRAG1.1
+            FRAG
             DCL IN[0], GENERIC[0], LINEAR
             DCL SAMP[0], CONSTANT
             DCL OUT[0].z, POSITION
diff --git a/src/gallium/state_trackers/python/tests/texture_transfer.py b/src/gallium/state_trackers/python/tests/texture_transfer.py
index e65b425..35daca9 100755
--- a/src/gallium/state_trackers/python/tests/texture_transfer.py
+++ b/src/gallium/state_trackers/python/tests/texture_transfer.py
@@ -86,8 +86,9 @@
         
         surface = texture.get_surface(face, level, zslice)
         
-        stride = surface.nblocksx * texture.block.size
-        size = surface.nblocksy * stride
+        # ???
+        stride = pf_get_stride(texture->format, w)
+        size = pf_get_nblocksy(texture->format) * stride
 
         in_raw = os.urandom(size)
 
diff --git a/src/gallium/state_trackers/vega/Makefile b/src/gallium/state_trackers/vega/Makefile
index b8c805b..fc97bf5 100644
--- a/src/gallium/state_trackers/vega/Makefile
+++ b/src/gallium/state_trackers/vega/Makefile
@@ -61,14 +61,7 @@
 VG_TINY = 0
 
 GALLIUM_LIBS = \
-	$(GALLIUM)/src/gallium/auxiliary/pipebuffer/libpipebuffer.a \
-	$(GALLIUM)/src/gallium/auxiliary/sct/libsct.a \
-	$(GALLIUM)/src/gallium/auxiliary/draw/libdraw.a \
-	$(GALLIUM)/src/gallium/auxiliary/rtasm/librtasm.a \
-	$(GALLIUM)/src/gallium/auxiliary/translate/libtranslate.a \
-	$(GALLIUM)/src/gallium/auxiliary/cso_cache/libcso_cache.a \
-	$(GALLIUM)/src/gallium/auxiliary/util/libutil.a \
-	$(GALLIUM)/src/gallium/auxiliary/tgsi/libtgsi.a
+	$(GALLIUM)/src/gallium/auxiliary/libgallium.a
 
 .SUFFIXES : .cpp
 
diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c
index 862cbb0..2f984fb 100644
--- a/src/gallium/state_trackers/vega/api_filters.c
+++ b/src/gallium/state_trackers/vega/api_filters.c
@@ -38,6 +38,7 @@
 #include "pipe/p_screen.h"
 #include "pipe/p_shader_tokens.h"
 
+#include "util/u_format.h"
 #include "util/u_memory.h"
 
 
@@ -68,10 +69,9 @@
    templ.target = PIPE_TEXTURE_1D;
    templ.format = PIPE_FORMAT_A8R8G8B8_UNORM;
    templ.last_level = 0;
-   templ.width[0] = color_data_len;
-   templ.height[0] = 1;
-   templ.depth[0] = 1;
-   pf_get_block(PIPE_FORMAT_A8R8G8B8_UNORM, &templ.block);
+   templ.width0 = color_data_len;
+   templ.height0 = 1;
+   templ.depth0 = 1;
    templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
 
    tex = screen->texture_create(screen, &templ);
@@ -81,7 +81,7 @@
          screen->get_tex_transfer(screen, tex,
                                   0, 0, 0,
                                   PIPE_TRANSFER_READ_WRITE ,
-                                  0, 0, tex->width[0], tex->height[0]);
+                                  0, 0, tex->width0, tex->height0);
       void *map = screen->transfer_map(screen, transfer);
       memcpy(map, color_data, sizeof(VGint)*color_data_len);
       screen->transfer_unmap(screen, transfer);
diff --git a/src/gallium/state_trackers/vega/api_path.c b/src/gallium/state_trackers/vega/api_path.c
index a6b7a2b..15ac190 100644
--- a/src/gallium/state_trackers/vega/api_path.c
+++ b/src/gallium/state_trackers/vega/api_path.c
@@ -164,8 +164,7 @@
       return;
    }
    for (i = 0; i < numSegments; ++i) {
-      if (pathSegments[i] < VG_CLOSE_PATH ||
-          pathSegments[i] > VG_LCWARC_TO_REL) {
+      if (pathSegments[i] > VG_LCWARC_TO_REL) {
          vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
          return;
       }
diff --git a/src/gallium/state_trackers/vega/arc.c b/src/gallium/state_trackers/vega/arc.c
index e74c7f0..2d12340 100644
--- a/src/gallium/state_trackers/vega/arc.c
+++ b/src/gallium/state_trackers/vega/arc.c
@@ -537,8 +537,9 @@
       double d_eta = (max_eta - min_eta) / n;
       if (d_eta <= 0.5 * M_PI) {
          double eta_b = min_eta;
+         int i;
          found = VG_TRUE;
-         for (int i = 0; found && (i < n); ++i) {
+         for (i = 0; found && (i < n); ++i) {
             double etaA = eta_b;
             eta_b += d_eta;
             found = (estimate_error(arc, etaA, eta_b) <= threshold);
@@ -554,6 +555,7 @@
                            struct arc_cb cb,
                            struct matrix *matrix)
 {
+   int i;
    int n = 1;
    double d_eta, eta_b, cos_eta_b,
       sin_eta_b, a_cos_eta_b, b_sin_eta_b, a_sin_eta_b,
@@ -607,7 +609,7 @@
    t     = tan(0.5 * d_eta);
    alpha = sin(d_eta) * (sqrt(4 + 3 * t * t) - 1) / 3;
 
-   for (int i = 0; i < n; ++i) {
+   for (i = 0; i < n; ++i) {
       struct bezier bezier;
       double xA    = x_b;
       double yA    = y_b;
diff --git a/src/gallium/state_trackers/vega/asm_filters.h b/src/gallium/state_trackers/vega/asm_filters.h
index 9a49f2e..60bed19 100644
--- a/src/gallium/state_trackers/vega/asm_filters.h
+++ b/src/gallium/state_trackers/vega/asm_filters.h
@@ -28,7 +28,7 @@
 #define ASM_FILTERS_H
 
 static const char color_matrix_asm[] =
-   "FRAG1.1\n"
+   "FRAG\n"
    "DCL IN[0], GENERIC[0], PERSPECTIVE\n"
    "DCL OUT[0], COLOR, CONSTANT\n"
    "DCL CONST[0..4], CONSTANT\n"
@@ -51,7 +51,7 @@
    "END\n";
 
 static const char convolution_asm[] =
-   "FRAG1.1\n"
+   "FRAG\n"
    "DCL IN[0], GENERIC[0], PERSPECTIVE\n"
    "DCL OUT[0], COLOR, CONSTANT\n"
    "DCL TEMP[0..4], CONSTANT\n"
@@ -78,7 +78,7 @@
 
 
 static const char lookup_asm[] =
-   "FRAG1.1\n"
+   "FRAG\n"
    "DCL IN[0], GENERIC[0], PERSPECTIVE\n"
    "DCL OUT[0], COLOR, CONSTANT\n"
    "DCL TEMP[0..2], CONSTANT\n"
@@ -103,7 +103,7 @@
 
 
 static const char lookup_single_asm[] =
-   "FRAG1.1\n"
+   "FRAG\n"
    "DCL IN[0], GENERIC[0], PERSPECTIVE\n"
    "DCL OUT[0], COLOR, CONSTANT\n"
    "DCL TEMP[0..2], CONSTANT\n"
diff --git a/src/gallium/state_trackers/vega/asm_util.h b/src/gallium/state_trackers/vega/asm_util.h
index 218e1d1..903bfc8 100644
--- a/src/gallium/state_trackers/vega/asm_util.h
+++ b/src/gallium/state_trackers/vega/asm_util.h
@@ -29,7 +29,7 @@
 
 
 static const char pass_through_depth_asm[] =
-   "FRAG1.1\n"
+   "FRAG\n"
    "DCL IN[0], POSITION, LINEAR\n"
    "DCL OUT[0].z, POSITION, CONSTANT\n"
    "0: MOV OUT[0].z, IN[0].zzzz\n"
@@ -39,7 +39,7 @@
 
 /* μnew = μmask */
 static const char set_mask_asm[] =
-   "FRAG1.1\n"
+   "FRAG\n"
    "DCL IN[0], GENERIC[0], PERSPECTIVE\n"
    "DCL SAMP[0], CONSTANT\n"
    "DCL OUT[0], COLOR, CONSTANT\n"
@@ -48,7 +48,7 @@
 
 /* μnew = 1 – (1 – μmask)*(1 – μprev) */
 static const char union_mask_asm[] =
-   "FRAG1.1\n"
+   "FRAG\n"
    "DCL IN[0], GENERIC[0], PERSPECTIVE\n"
    "DCL IN[1], POSITION, LINEAR\n"
    "DCL CONST[0], CONSTANT\n"
@@ -65,7 +65,7 @@
 
 /* μnew = μmask *μprev */
 static const char intersect_mask_asm[] =
-   "FRAG1.1\n"
+   "FRAG\n"
    "DCL IN[0], GENERIC[0], PERSPECTIVE\n"
    "DCL IN[1], POSITION, LINEAR\n"
    "DCL CONST[0], CONSTANT\n"
@@ -79,7 +79,7 @@
 
 /* μnew = μprev*(1 – μmask) */
 static const char subtract_mask_asm[] =
-   "FRAG1.1\n"
+   "FRAG\n"
    "DCL IN[0], GENERIC[0], PERSPECTIVE\n"
    "DCL IN[1], POSITION, LINEAR\n"
    "DCL CONST[0], CONSTANT\n"
@@ -94,7 +94,7 @@
 
 
 static const char vs_plain_asm[] =
-   "VERT1.1\n"
+   "VERT\n"
    "DCL IN[0]\n"
    "DCL OUT[0], POSITION\n"
    "DCL TEMP[0]\n"
@@ -105,7 +105,7 @@
    "3: END\n";
 
 static const char vs_clear_asm[] =
-   "VERT1.1\n"
+   "VERT\n"
    "DCL IN[0]\n"
    "DCL IN[1]\n"
    "DCL OUT[0], POSITION\n"
@@ -120,7 +120,7 @@
 
 
 static const char vs_texture_asm[] =
-   "VERT1.1\n"
+   "VERT\n"
    "DCL IN[0]\n"
    "DCL IN[1]\n"
    "DCL OUT[0], POSITION\n"
diff --git a/src/gallium/state_trackers/vega/bezier.c b/src/gallium/state_trackers/vega/bezier.c
index 39a7ade..5769e8e 100644
--- a/src/gallium/state_trackers/vega/bezier.c
+++ b/src/gallium/state_trackers/vega/bezier.c
@@ -255,7 +255,8 @@
    const float max_dist_line = threshold*offset*offset;
    const float max_dist_normal = threshold*offset;
    const float spacing = 0.25;
-   for (float i = spacing; i < 0.99; i += spacing) {
+   float i;
+   for (i = spacing; i < 0.99; i += spacing) {
       float p1[2],p2[2], d, l;
       float normal[2];
       bezier_point_at(b1, i, p1);
@@ -330,6 +331,7 @@
                                struct bezier *shifted,
                                float offset, float threshold)
 {
+   int i;
    int map[4];
    VGboolean p1_p2_equal = (orig->x1 == orig->x2 && orig->y1 == orig->y2);
    VGboolean p2_p3_equal = (orig->x2 == orig->x3 && orig->y2 == orig->y3);
@@ -404,7 +406,7 @@
    points_shifted[0][0] = points[0][0] + offset * prev_normal[0];
    points_shifted[0][1] = points[0][1] + offset * prev_normal[1];
 
-   for (int i = 1; i < np - 1; ++i) {
+   for (i = 1; i < np - 1; ++i) {
       float normal_sum[2], r;
       float next_normal[2];
       compute_pt_normal(points[i], points[i + 1], next_normal);
diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c
index 9a72298..1112ad9 100644
--- a/src/gallium/state_trackers/vega/image.c
+++ b/src/gallium/state_trackers/vega/image.c
@@ -39,6 +39,7 @@
 #include "pipe/p_screen.h"
 #include "pipe/p_inlines.h"
 #include "util/u_blit.h"
+#include "util/u_format.h"
 #include "util/u_tile.h"
 #include "util/u_memory.h"
 #include "util/u_math.h"
@@ -93,8 +94,8 @@
    dst_loc[3] = height;
    dst_bounds[0] = 0.f;
    dst_bounds[1] = 0.f;
-   dst_bounds[2] = dst->width[0];
-   dst_bounds[3] = dst->height[0];
+   dst_bounds[2] = dst->width0;
+   dst_bounds[3] = dst->height0;
 
    src_loc[0] = sx;
    src_loc[1] = sy;
@@ -102,8 +103,8 @@
    src_loc[3] = height;
    src_bounds[0] = 0.f;
    src_bounds[1] = 0.f;
-   src_bounds[2] = src->width[0];
-   src_bounds[3] = src->height[0];
+   src_bounds[2] = src->width0;
+   src_bounds[3] = src->height0;
 
    vg_bound_rect(src_loc, src_bounds, src_shift);
    vg_bound_rect(dst_loc, dst_bounds, dst_shift);
@@ -270,11 +271,10 @@
    memset(&pt, 0, sizeof(pt));
    pt.target = PIPE_TEXTURE_2D;
    pt.format = pformat;
-   pf_get_block(pformat, &pt.block);
    pt.last_level = 0;
-   pt.width[0] = width;
-   pt.height[0] = height;
-   pt.depth[0] = 1;
+   pt.width0 = width;
+   pt.height0 = height;
+   pt.depth0 = 1;
    pt.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
 
    newtex = screen->texture_create(screen, &pt);
@@ -414,7 +414,7 @@
    { /* upload color_data */
       struct pipe_transfer *transfer = screen->get_tex_transfer(
          screen, texture, 0, 0, 0,
-         PIPE_TRANSFER_WRITE, 0, 0, texture->width[0], texture->height[0]);
+         PIPE_TRANSFER_WRITE, 0, 0, texture->width0, texture->height0);
       src += (dataStride * yoffset);
       for (i = 0; i < height; i++) {
          _vega_unpack_float_span_rgba(ctx, width, xoffset, src, dataFormat, temp);
@@ -644,7 +644,7 @@
        return PIPE_TEX_FILTER_NEAREST;
        break;
     case VG_IMAGE_QUALITY_BETTER:
-       /*return PIPE_TEX_FILTER_ANISO;*/
+       /* possibly use anisotropic filtering */
        return PIPE_TEX_FILTER_LINEAR;
        break;
     default:
diff --git a/src/gallium/state_trackers/vega/mask.c b/src/gallium/state_trackers/vega/mask.c
index 24650a3..42300bb 100644
--- a/src/gallium/state_trackers/vega/mask.c
+++ b/src/gallium/state_trackers/vega/mask.c
@@ -36,6 +36,7 @@
 #include "pipe/p_context.h"
 #include "pipe/p_screen.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
 #include "util/u_memory.h"
 
 struct vg_mask_layer {
@@ -426,7 +427,7 @@
    if (!surface)
       return;
    if (!intersect_rectangles(surface->width, surface->height,
-                             texture->width[0], texture->height[0],
+                             texture->width0, texture->height0,
                              x, y, width, height,
                              offsets, loc))
       return;
@@ -491,11 +492,10 @@
       memset(&pt, 0, sizeof(pt));
       pt.target = PIPE_TEXTURE_2D;
       pt.format = PIPE_FORMAT_A8R8G8B8_UNORM;
-      pf_get_block(PIPE_FORMAT_A8R8G8B8_UNORM, &pt.block);
       pt.last_level = 0;
-      pt.width[0] = width;
-      pt.height[0] = height;
-      pt.depth[0] = 1;
+      pt.width0 = width;
+      pt.height0 = height;
+      pt.depth0 = 1;
       pt.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
       pt.compressed = 0;
 
@@ -607,8 +607,8 @@
    struct vg_mask_layer *temp_layer;
    VGint width, height;
 
-   width = fb_buffers->alpha_mask->width[0];
-   height = fb_buffers->alpha_mask->width[0];
+   width = fb_buffers->alpha_mask->width0;
+   height = fb_buffers->alpha_mask->width0;
 
    temp_layer = mask_layer_create(width, height);
 
diff --git a/src/gallium/state_trackers/vega/paint.c b/src/gallium/state_trackers/vega/paint.c
index 04a6ba9..cc73771 100644
--- a/src/gallium/state_trackers/vega/paint.c
+++ b/src/gallium/state_trackers/vega/paint.c
@@ -34,6 +34,7 @@
 #include "pipe/p_compiler.h"
 #include "pipe/p_inlines.h"
 
+#include "util/u_format.h"
 #include "util/u_memory.h"
 #include "util/u_math.h"
 
@@ -151,10 +152,9 @@
    templ.target = PIPE_TEXTURE_1D;
    templ.format = PIPE_FORMAT_A8R8G8B8_UNORM;
    templ.last_level = 0;
-   templ.width[0] = 1024;
-   templ.height[0] = 1;
-   templ.depth[0] = 1;
-   pf_get_block(PIPE_FORMAT_A8R8G8B8_UNORM, &templ.block);
+   templ.width0 = 1024;
+   templ.height0 = 1;
+   templ.depth0 = 1;
    templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
 
    tex = screen->texture_create(screen, &templ);
@@ -328,8 +328,8 @@
 
    map[4] = 0.f;
    map[5] = 1.f;
-   map[6] = paint->pattern.texture->width[0];
-   map[7] = paint->pattern.texture->height[0];
+   map[6] = paint->pattern.texture->width0;
+   map[7] = paint->pattern.texture->height0;
    {
       struct matrix mat;
       memcpy(&mat, &ctx->state.vg.fill_paint_to_user_matrix,
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
index 396c88a..64e3a7c 100644
--- a/src/gallium/state_trackers/vega/renderer.c
+++ b/src/gallium/state_trackers/vega/renderer.c
@@ -35,6 +35,7 @@
 #include "pipe/p_shader_tokens.h"
 
 #include "util/u_draw_quad.h"
+#include "util/u_format.h"
 #include "util/u_simple_shaders.h"
 #include "util/u_memory.h"
 #include "util/u_rect.h"
@@ -56,7 +57,7 @@
 {
    struct pipe_context *pipe = ctx->pipe;
    /* fragment shader */
-   ctx->fs = util_make_fragment_tex_shader(pipe);
+   ctx->fs = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D);
 }
 
 static struct pipe_buffer *
@@ -230,13 +231,13 @@
    struct pipe_buffer *buf;
    VGfloat s0, t0, s1, t1;
 
-   assert(tex->width[0] != 0);
-   assert(tex->height[0] != 0);
+   assert(tex->width0 != 0);
+   assert(tex->height0 != 0);
 
-   s0 = x1offset / tex->width[0];
-   s1 = x2offset / tex->width[0];
-   t0 = y1offset / tex->height[0];
-   t1 = y2offset / tex->height[0];
+   s0 = x1offset / tex->width0;
+   s1 = x2offset / tex->width0;
+   t0 = y1offset / tex->height0;
+   t1 = y2offset / tex->height0;
 
    cso_save_vertex_shader(r->cso);
    /* shaders */
@@ -276,10 +277,10 @@
    struct pipe_framebuffer_state fb;
    float s0, t0, s1, t1;
 
-   assert(src->width[0] != 0);
-   assert(src->height[0] != 0);
-   assert(dst->width[0] != 0);
-   assert(dst->height[0] != 0);
+   assert(src->width0 != 0);
+   assert(src->height0 != 0);
+   assert(dst->width0 != 0);
+   assert(dst->height0 != 0);
 
 #if 0
    debug_printf("copy texture [%f, %f, %f, %f], [%f, %f, %f, %f]\n",
@@ -287,10 +288,10 @@
 #endif
 
 #if 1
-   s0 = sx1 / src->width[0];
-   s1 = sx2 / src->width[0];
-   t0 = sy1 / src->height[0];
-   t1 = sy2 / src->height[0];
+   s0 = sx1 / src->width0;
+   s1 = sx2 / src->width0;
+   t0 = sy1 / src->height0;
+   t1 = sy2 / src->height0;
 #else
    s0 = 0;
    s1 = 1;
@@ -445,10 +446,9 @@
    texTemp.target = PIPE_TEXTURE_2D;
    texTemp.format = src->format;
    texTemp.last_level = 0;
-   texTemp.width[0] = srcW;
-   texTemp.height[0] = srcH;
-   texTemp.depth[0] = 1;
-   pf_get_block(src->format, &texTemp.block);
+   texTemp.width0 = srcW;
+   texTemp.height0 = srcH;
+   texTemp.depth0 = 1;
 
    tex = screen->texture_create(screen, &texTemp);
    if (!tex)
@@ -570,13 +570,13 @@
    struct pipe_buffer *buf;
    VGfloat s0, t0, s1, t1;
 
-   assert(tex->width[0] != 0);
-   assert(tex->height[0] != 0);
+   assert(tex->width0 != 0);
+   assert(tex->height0 != 0);
 
-   s0 = x1offset / tex->width[0];
-   s1 = x2offset / tex->width[0];
-   t0 = y1offset / tex->height[0];
-   t1 = y2offset / tex->height[0];
+   s0 = x1offset / tex->width0;
+   s1 = x2offset / tex->width0;
+   t0 = y1offset / tex->height0;
+   t1 = y2offset / tex->height0;
 
    cso_save_vertex_shader(r->cso);
    /* shaders */
diff --git a/src/gallium/state_trackers/vega/shaders_cache.c b/src/gallium/state_trackers/vega/shaders_cache.c
index fd0831f..f620075 100644
--- a/src/gallium/state_trackers/vega/shaders_cache.c
+++ b/src/gallium/state_trackers/vega/shaders_cache.c
@@ -97,7 +97,7 @@
 
 /*
 static const char max_shader_preamble[] =
-   "FRAG1.1\n"
+   "FRAG\n"
    "DCL IN[0], POSITION, LINEAR\n"
    "DCL IN[1], GENERIC[0], PERSPECTIVE\n"
    "DCL OUT[0], COLOR, CONSTANT\n"
@@ -168,7 +168,7 @@
    --end_temp;
    --end_sampler;
 
-   sprintf(txt, "FRAG1.1\n");
+   sprintf(txt, "FRAG\n");
 
    if (declare_input) {
       sprintf(txt + strlen(txt), "DCL IN[0], POSITION, LINEAR\n");
diff --git a/src/gallium/state_trackers/vega/stroker.c b/src/gallium/state_trackers/vega/stroker.c
index 1b92d2b..68a5202 100644
--- a/src/gallium/state_trackers/vega/stroker.c
+++ b/src/gallium/state_trackers/vega/stroker.c
@@ -476,7 +476,7 @@
                                              const VGfloat *l2,
                                              float *intersection_point)
 {
-   VGfloat isect[2];
+   VGfloat isect[2] = { 0 };
    enum intersection_type type;
    VGboolean dx_zero, ldx_zero;
 
@@ -649,7 +649,7 @@
       VGfloat prev_line[] = {stroker->back2_x, stroker->back2_y,
                              stroker->back1_x, stroker->back1_y};
 
-      VGfloat isect[2];
+      VGfloat isect[2] = { 0 };
       enum intersection_type type = line_intersect(prev_line, next_line, isect);
 
       if (join == SquareJoin) {
diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c
index e0ff02f..00d23f5 100644
--- a/src/gallium/state_trackers/vega/vg_context.c
+++ b/src/gallium/state_trackers/vega/vg_context.c
@@ -231,6 +231,8 @@
    if (state->scissoring) {
       struct pipe_blend_state *blend = &ctx->state.g3d.blend;
       struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
+      int i;
+
       dsa->depth.writemask = 1;/*glDepthMask(TRUE);*/
       dsa->depth.func = PIPE_FUNC_ALWAYS;
       dsa->depth.enabled = 1;
@@ -254,7 +256,7 @@
       cso_set_blend(ctx->cso_context, blend);
 
       /* enable scissoring */
-      for (int i = 0; i < state->scissor_rects_num; ++i) {
+      for (i = 0; i < state->scissor_rects_num; ++i) {
          const float x      = state->scissor_rects[i * 4 + 0].f;
          const float y      = state->scissor_rects[i * 4 + 1].f;
          const float width  = state->scissor_rects[i * 4 + 2].f;
diff --git a/src/gallium/state_trackers/vega/vg_tracker.c b/src/gallium/state_trackers/vega/vg_tracker.c
index c4da01e..ff80aab 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.c
+++ b/src/gallium/state_trackers/vega/vg_tracker.c
@@ -31,8 +31,13 @@
 #include "pipe/p_context.h"
 #include "pipe/p_inlines.h"
 #include "pipe/p_screen.h"
+#include "util/u_format.h"
 #include "util/u_memory.h"
 #include "util/u_math.h"
+#include "util/u_rect.h"
+
+/* advertise OpenVG support */
+PUBLIC const int st_api_OpenVG = 1;
 
 static struct pipe_texture *
 create_texture(struct pipe_context *pipe, enum pipe_format format,
@@ -50,13 +55,12 @@
    }
 
    templ.target = PIPE_TEXTURE_2D;
-   pf_get_block(templ.format, &templ.block);
-   templ.width[0] = width;
-   templ.height[0] = height;
-   templ.depth[0] = 1;
+   templ.width0 = width;
+   templ.height0 = height;
+   templ.depth0 = 1;
    templ.last_level = 0;
 
-   if (pf_get_component_bits(format, PIPE_FORMAT_COMP_S)) {
+   if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) {
       templ.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
    } else {
       templ.tex_usage = (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
@@ -367,14 +371,15 @@
    /* FIXME */
 }
 
-void st_make_current(struct vg_context *st,
-                     struct st_framebuffer *draw,
-                     struct st_framebuffer *read)
+boolean st_make_current(struct vg_context *st,
+                        struct st_framebuffer *draw,
+                        struct st_framebuffer *read)
 {
    vg_set_current_context(st);
    if (st) {
       st->draw_buffer = draw;
    }
+   return VG_TRUE;
 }
 
 struct vg_context *st_get_current(void)
@@ -424,3 +429,8 @@
 {
    return 0;
 }
+
+st_proc st_get_proc_address(const char *procname)
+{
+   return NULL;
+}
diff --git a/src/gallium/state_trackers/vega/vg_tracker.h b/src/gallium/state_trackers/vega/vg_tracker.h
index 5457631..c119695 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.h
+++ b/src/gallium/state_trackers/vega/vg_tracker.h
@@ -45,15 +45,19 @@
 struct pipe_surface;
 
 
+PUBLIC
 struct vg_context *st_create_context(struct pipe_context *pipe,
                                      const void *visual,
                                      struct vg_context *share);
 
+PUBLIC
 void st_destroy_context( struct vg_context *st );
 
+PUBLIC
 void st_copy_context_state(struct vg_context *dst, struct vg_context *src,
                            uint mask);
 
+PUBLIC
 struct st_framebuffer *st_create_framebuffer(const void *visual,
                                              enum pipe_format colorFormat,
                                              enum pipe_format depthFormat,
@@ -61,47 +65,63 @@
                                              uint width, uint height,
                                              void *privateData);
 
+PUBLIC
 void st_resize_framebuffer(struct st_framebuffer *stfb,
                            uint width, uint height);
 
+PUBLIC
 void st_set_framebuffer_surface(struct st_framebuffer *stfb,
                                 uint surfIndex, struct pipe_surface *surf);
 
+PUBLIC
 void st_get_framebuffer_dimensions( struct st_framebuffer *stfb,
 				    uint *width, uint *height);
 
+PUBLIC
 int st_bind_texture_surface(struct pipe_surface *ps, int target, int level,
                             enum pipe_format format);
 
+PUBLIC
 int st_unbind_texture_surface(struct pipe_surface *ps, int target, int level);
 
+PUBLIC
 int st_get_framebuffer_surface(struct st_framebuffer *stfb,
                                uint surfIndex, struct pipe_surface **surf);
 
+PUBLIC
 int st_get_framebuffer_texture(struct st_framebuffer *stfb,
                                uint surfIndex, struct pipe_texture **tex);
 
+PUBLIC
 void *st_framebuffer_private(struct st_framebuffer *stfb);
 
+PUBLIC
 void st_unreference_framebuffer(struct st_framebuffer *stfb);
 
-void st_make_current(struct vg_context *st,
-                     struct st_framebuffer *draw,
-                     struct st_framebuffer *read);
+PUBLIC
+boolean st_make_current(struct vg_context *st,
+                        struct st_framebuffer *draw,
+                        struct st_framebuffer *read);
 
+PUBLIC
 struct vg_context *st_get_current(void);
 
+PUBLIC
 void st_flush(struct vg_context *st, uint pipeFlushFlags,
                struct pipe_fence_handle **fence);
+PUBLIC
 void st_finish(struct vg_context *st);
 
+PUBLIC
 void st_notify_swapbuffers(struct st_framebuffer *stfb);
+PUBLIC
 void st_notify_swapbuffers_complete(struct st_framebuffer *stfb);
 
 
 /** Generic function type */
 typedef void (*st_proc)();
 
+PUBLIC
 st_proc st_get_proc_address(const char *procname);
 
 #endif
diff --git a/src/gallium/state_trackers/vega/vg_translate.c b/src/gallium/state_trackers/vega/vg_translate.c
index 00e0764..03575ca 100644
--- a/src/gallium/state_trackers/vega/vg_translate.c
+++ b/src/gallium/state_trackers/vega/vg_translate.c
@@ -474,6 +474,7 @@
                                   VGfloat rgba[][4])
 {
    VGint i;
+   union util_color uc;
 
    switch (dataFormat) {
    case VG_sRGBX_8888: {
@@ -486,8 +487,11 @@
          b = (*src >>  8) & 0xff;
          a = 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
    }
@@ -502,8 +506,11 @@
          b = (*src >>  8) & 0xff;
          a = (*src >>  0) & 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
       return;
@@ -519,8 +526,11 @@
          b = (*src >>  8) & 0xff;
          a = (*src >>  0) & 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
       return;
@@ -536,8 +546,11 @@
          clr[2] = ((*src >>  0) & 31)/31.;
          clr[3] = 1.f;
 
-         util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                         rgba[i]);
+         util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
    }
@@ -552,8 +565,11 @@
          clr[2] = ((*src >>  1) & 31)/31.;
          clr[3] = ((*src >>  0) & 1)/1.;
 
-         util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                         rgba[i]);
+         util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
    }
@@ -568,8 +584,11 @@
          clr[2] = ((*src >>  4) & 15)/15.;
          clr[3] = ((*src >>  0) & 15)/15.;
 
-         util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                         rgba[i]);
+         util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
    }
@@ -578,8 +597,11 @@
       VGubyte *src = (VGubyte *)data;
       src += offset;
       for (i = 0; i < n; ++i) {
-         util_pack_color_ub(0xff, 0xff, 0xff, *src, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                         rgba[i]);
+         util_pack_color_ub(0xff, 0xff, 0xff, *src, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
    }
@@ -594,8 +616,11 @@
          b = (*src >>  8) & 0xff;
          a = 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
    }
@@ -610,8 +635,11 @@
          b = (*src >>  8) & 0xff;
          a = (*src >>  0) & 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
       return;
@@ -627,8 +655,11 @@
          b = (*src >>  8) & 0xff;
          a = (*src >>  0) & 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
       return;
@@ -638,8 +669,11 @@
       VGubyte *src = (VGubyte *)data;
       src += offset;
       for (i = 0; i < n; ++i) {
-         util_pack_color_ub(0xff, 0xff, 0xff, *src, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                         rgba[i]);
+         util_pack_color_ub(0xff, 0xff, 0xff, *src, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
    }
@@ -648,8 +682,11 @@
       VGubyte *src = (VGubyte *)data;
       src += offset;
       for (i = 0; i < n; ++i) {
-         util_pack_color_ub(0xff, 0xff, 0xff, *src, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(0xff, 0xff, 0xff, *src, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
    }
@@ -667,8 +704,11 @@
             clr[2] = clr[0];
             clr[3] = 1.f;
 
-            util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i+j]);
+            util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+            rgba[i+j][0] = uc.f[0];
+            rgba[i+j][1] = uc.f[1];
+            rgba[i+j][2] = uc.f[2];
+            rgba[i+j][3] = uc.f[3];
          }
          ++src;
       }
@@ -688,8 +728,11 @@
             clr[2] = 0.f;
             clr[3] = (((*src) & (1<<shift)) >> shift);
 
-            util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i+j]);
+            util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+            rgba[i+j][0] = uc.f[0];
+            rgba[i+j][1] = uc.f[1];
+            rgba[i+j][2] = uc.f[2];
+            rgba[i+j][3] = uc.f[3];
          }
          ++src;
       }
@@ -715,8 +758,11 @@
             clr[2] = 0.f;
             clr[3] = ((*src) & (bitter)) >> shift;
 
-            util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i +j]);
+            util_pack_color(clr, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+            rgba[i+j][0] = uc.f[0];
+            rgba[i+j][1] = uc.f[1];
+            rgba[i+j][2] = uc.f[2];
+            rgba[i+j][3] = uc.f[3];
          }
          ++src;
       }
@@ -735,8 +781,11 @@
          g = (*src >>  8) & 0xff;
          b = (*src >>  0) & 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
       return;
@@ -752,8 +801,11 @@
          g = (*src >>  8) & 0xff;
          b = (*src >>  0) & 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
       return;
@@ -775,8 +827,11 @@
          g = (*src >>  8) & 0xff;
          b = (*src >>  0) & 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
       return;
@@ -792,8 +847,11 @@
          g = (*src >>  8) & 0xff;
          b = (*src >>  0) & 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
       return;
@@ -811,8 +869,11 @@
          r = (*src >>  8) & 0xff;
          a = (*src >>  0) & 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
       return;
@@ -828,8 +889,11 @@
          r = (*src >>  8) & 0xff;
          a = (*src >>  0) & 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
       return;
@@ -853,8 +917,11 @@
          r = (*src >>  8) & 0xff;
          a = (*src >>  0) & 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
       return;
@@ -870,8 +937,11 @@
          r = (*src >>  8) & 0xff;
          a = (*src >>  0) & 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
       return;
@@ -889,8 +959,11 @@
          g = (*src >>  8) & 0xff;
          r = (*src >>  0) & 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
       return;
@@ -906,8 +979,11 @@
          g = (*src >>  8) & 0xff;
          r = (*src >>  0) & 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
       return;
@@ -929,8 +1005,11 @@
          g = (*src >>  8) & 0xff;
          r = (*src >>  0) & 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
       return;
@@ -946,8 +1025,11 @@
          g = (*src >>  8) & 0xff;
          r = (*src >>  0) & 0xff;
 
-         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT,
-                            rgba[i]);
+         util_pack_color_ub(r, g, b, a, PIPE_FORMAT_R32G32B32A32_FLOAT, &uc);
+         rgba[i][0] = uc.f[0];
+         rgba[i][1] = uc.f[1];
+         rgba[i][2] = uc.f[2];
+         rgba[i][3] = uc.f[3];
          ++src;
       }
       return;
diff --git a/src/gallium/state_trackers/wgl/SConscript b/src/gallium/state_trackers/wgl/SConscript
index b05944a..352c087 100644
--- a/src/gallium/state_trackers/wgl/SConscript
+++ b/src/gallium/state_trackers/wgl/SConscript
@@ -11,10 +11,11 @@
     	'.',
     ])
      
-    env.Append(CPPDEFINES = [
+    env.AppendUnique(CPPDEFINES = [
         '_GDI32_', # prevent wgl* being declared __declspec(dllimport)
         'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers 
         'WIN32_THREADS', # use Win32 thread API
+        'WIN32_LEAN_AND_MEAN', # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx
     ])
      
     sources = [
diff --git a/src/gallium/state_trackers/wgl/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c
index 985b8f0..7785aba 100644
--- a/src/gallium/state_trackers/wgl/stw_device.c
+++ b/src/gallium/state_trackers/wgl/stw_device.c
@@ -72,19 +72,7 @@
       return;
    }
 
-#if DEBUG
-   {
-      /* ensure that a random surface was not passed to us */
-      struct pipe_surface *surface2;
-
-      if(!st_get_framebuffer_surface( fb->stfb, ST_SURFACE_FRONT_LEFT, &surface2 ))
-         assert(0);
-      else
-         assert(surface2 == surface);
-   }
-#endif
-
-   stw_framebuffer_present_locked(hdc, fb, ST_SURFACE_FRONT_LEFT);
+   stw_framebuffer_present_locked(hdc, fb, surface);
 }
 
 
diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c
index 8a3e11b..129a6298 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c
@@ -30,6 +30,7 @@
 #include "main/context.h"
 #include "pipe/p_format.h"
 #include "pipe/p_screen.h"
+#include "util/u_format.h"
 #include "state_tracker/st_context.h"
 #include "state_tracker/st_public.h"
 
@@ -267,15 +268,13 @@
       enum pipe_format colorFormat, depthFormat, stencilFormat;
 
       colorFormat = pfi->color_format;
-      
-      assert(pf_layout( pfi->depth_stencil_format ) == PIPE_FORMAT_LAYOUT_RGBAZS );
-   
-      if(pf_get_component_bits( pfi->depth_stencil_format, PIPE_FORMAT_COMP_Z ))
+
+      if(util_format_get_component_bits(pfi->depth_stencil_format, UTIL_FORMAT_COLORSPACE_ZS, 0))
          depthFormat = pfi->depth_stencil_format;
       else
          depthFormat = PIPE_FORMAT_NONE;
    
-      if(pf_get_component_bits( pfi->depth_stencil_format, PIPE_FORMAT_COMP_S ))
+      if(util_format_get_component_bits(pfi->depth_stencil_format, UTIL_FORMAT_COLORSPACE_ZS, 1))
          stencilFormat = pfi->depth_stencil_format;
       else
          stencilFormat = PIPE_FORMAT_NONE;
@@ -475,8 +474,6 @@
    struct stw_framebuffer *fb;
    struct pipe_screen *screen;
    struct pipe_surface *surface;
-   unsigned surface_index;
-   BOOL ret = FALSE;
 
    fb = stw_framebuffer_from_hdc( hdc );
    if (fb == NULL)
@@ -484,9 +481,7 @@
 
    screen = stw_dev->screen;
 
-   surface_index = (unsigned)(uintptr_t)data->pPrivateData;
-   if(!st_get_framebuffer_surface( fb->stfb, surface_index, &surface ))
-      goto fail;
+   surface = (struct pipe_surface *)data->pPrivateData;
 
 #ifdef DEBUG
    if(stw_dev->trace_running) {
@@ -520,15 +515,11 @@
       stw_dev->stw_winsys->present( screen, surface, hdc );
    }
 
-   ret = TRUE;
-
-fail:
-
    stw_framebuffer_update(fb);
 
    stw_framebuffer_release(fb);
 
-   return ret;
+   return TRUE;
 }
 
 
@@ -540,7 +531,7 @@
 BOOL
 stw_framebuffer_present_locked(HDC hdc,
                                struct stw_framebuffer *fb,
-                               unsigned surface_index)
+                               struct pipe_surface *surface)
 {
    if(stw_dev->callbacks.wglCbPresentBuffers &&
       stw_dev->stw_winsys->compose) {
@@ -551,7 +542,7 @@
       data.magic2 = 0;
       data.AdapterLuid = stw_dev->AdapterLuid;
       data.rect = fb->client_rect;
-      data.pPrivateData = (void *)(uintptr_t)surface_index;
+      data.pPrivateData = (void *)surface;
 
       stw_framebuffer_release(fb);
 
@@ -559,13 +550,6 @@
    }
    else {
       struct pipe_screen *screen = stw_dev->screen;
-      struct pipe_surface *surface;
-
-      if(!st_get_framebuffer_surface( fb->stfb, surface_index, &surface )) {
-         /* FIXME: this shouldn't happen, but does on glean */
-         stw_framebuffer_release(fb);
-         return FALSE;
-      }
 
 #ifdef DEBUG
       if(stw_dev->trace_running) {
@@ -590,6 +574,7 @@
    HDC hdc )
 {
    struct stw_framebuffer *fb;
+   struct pipe_surface *surface = NULL;
 
    fb = stw_framebuffer_from_hdc( hdc );
    if (fb == NULL)
@@ -600,12 +585,9 @@
       return TRUE;
    }
 
-   /* If we're swapping the buffer associated with the current context
-    * we have to flush any pending rendering commands first.
-    */
-   st_notify_swapbuffers( fb->stfb );
+   st_swapbuffers(fb->stfb, &surface, NULL);
 
-   return stw_framebuffer_present_locked(hdc, fb, ST_SURFACE_BACK_LEFT);
+   return stw_framebuffer_present_locked(hdc, fb, surface);
 }
 
 
diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.h b/src/gallium/state_trackers/wgl/stw_framebuffer.h
index 5afbe74..b80d168 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.h
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.h
@@ -34,6 +34,7 @@
 
 #include "pipe/p_thread.h"
 
+struct pipe_surface;
 struct stw_pixelformat_info;
 
 /**
@@ -140,7 +141,7 @@
 BOOL
 stw_framebuffer_present_locked(HDC hdc,
                                struct stw_framebuffer *fb,
-                               unsigned surface_index);
+                               struct pipe_surface *surface);
 
 void
 stw_framebuffer_update(
diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c
index 7abe5d9..54cc361 100644
--- a/src/gallium/state_trackers/wgl/stw_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c
@@ -32,6 +32,7 @@
 #include "pipe/p_defines.h"
 #include "pipe/p_screen.h"
 
+#include "util/u_format.h"
 #include "util/u_debug.h"
 
 #include "stw_icd.h"
@@ -132,14 +133,12 @@
    if(stw_dev->pixelformat_extended_count >= STW_MAX_PIXELFORMATS)
       return;
 
-   assert(pf_layout( color->format ) == PIPE_FORMAT_LAYOUT_RGBAZS );
-   assert(pf_get_component_bits( color->format, PIPE_FORMAT_COMP_R ) == color->bits.red );
-   assert(pf_get_component_bits( color->format, PIPE_FORMAT_COMP_G ) == color->bits.green );
-   assert(pf_get_component_bits( color->format, PIPE_FORMAT_COMP_B ) == color->bits.blue );
-   assert(pf_get_component_bits( color->format, PIPE_FORMAT_COMP_A ) == color->bits.alpha );
-   assert(pf_layout( depth->format ) == PIPE_FORMAT_LAYOUT_RGBAZS );
-   assert(pf_get_component_bits( depth->format, PIPE_FORMAT_COMP_Z ) == depth->bits.depth );
-   assert(pf_get_component_bits( depth->format, PIPE_FORMAT_COMP_S ) == depth->bits.stencil );
+   assert(util_format_get_component_bits(color->format, UTIL_FORMAT_COLORSPACE_RGB, 0) == color->bits.red);
+   assert(util_format_get_component_bits(color->format, UTIL_FORMAT_COLORSPACE_RGB, 1) == color->bits.green);
+   assert(util_format_get_component_bits(color->format, UTIL_FORMAT_COLORSPACE_RGB, 2) == color->bits.blue);
+   assert(util_format_get_component_bits(color->format, UTIL_FORMAT_COLORSPACE_RGB, 3) == color->bits.alpha);
+   assert(util_format_get_component_bits(depth->format, UTIL_FORMAT_COLORSPACE_ZS, 0) == depth->bits.depth);
+   assert(util_format_get_component_bits(depth->format, UTIL_FORMAT_COLORSPACE_ZS, 1) == depth->bits.stencil);
    
    pfi = &stw_dev->pixelformats[stw_dev->pixelformat_extended_count];
    
diff --git a/src/gallium/state_trackers/wgl/stw_winsys.h b/src/gallium/state_trackers/wgl/stw_winsys.h
index 1ead47d..1de6e90 100644
--- a/src/gallium/state_trackers/wgl/stw_winsys.h
+++ b/src/gallium/state_trackers/wgl/stw_winsys.h
@@ -73,7 +73,7 @@
                           HANDLE hSharedSurface);
 
    /**
-    * Open a shared surface (optional).
+    * Close a shared surface (optional).
     */
    void
    (*shared_surface_close)(struct pipe_screen *screen,
diff --git a/src/gallium/state_trackers/xorg/Makefile b/src/gallium/state_trackers/xorg/Makefile
index 22c1073..cb2c3ae 100644
--- a/src/gallium/state_trackers/xorg/Makefile
+++ b/src/gallium/state_trackers/xorg/Makefile
@@ -7,6 +7,9 @@
 	-DHAVE_CONFIG_H \
 	$(shell pkg-config xextproto --atleast-version=7.0.99.1 \
 				&& echo "-DHAVE_XEXTPROTO_71") \
+	$(shell pkg-config libkms --atleast-version=1.0 \
+				&& echo "-DHAVE_LIBKMS") \
+	$(shell pkg-config libkms --silence-errors --cflags-only-I) \
 	$(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \
 	-I$(TOP)/src/gallium/include \
 	-I$(TOP)/src/gallium/auxiliary \
diff --git a/src/gallium/state_trackers/xorg/SConscript b/src/gallium/state_trackers/xorg/SConscript
index 6165bae..5d0b661 100644
--- a/src/gallium/state_trackers/xorg/SConscript
+++ b/src/gallium/state_trackers/xorg/SConscript
@@ -13,6 +13,11 @@
 
     env.ParseConfig('pkg-config --cflags --libs xorg-server')
 
+    conf = env.Configure()
+
+    if conf.CheckHeader('X11/extensions/dpmsconst.h'):
+        env.Append(CPPDEFINES = [('HAVE_XEXTPROTO_71', '1')])
+
     st_xorg = env.ConvenienceLibrary(
 	target = 'st_xorg',
 	source = [ 'xorg_composite.c',
@@ -22,6 +27,7 @@
 		'xorg_exa.c',
 		'xorg_exa_tgsi.c',
 		'xorg_output.c',
+		'xorg_renderer.c',
 		'xorg_xv.c',
 		]
     )
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index a8d779b..1c248a6 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -118,7 +118,7 @@
 {
    switch(mode) {
    case RepeatNone:
-      return PIPE_TEX_WRAP_CLAMP;
+      return PIPE_TEX_WRAP_CLAMP_TO_BORDER;
    case RepeatNormal:
       return PIPE_TEX_WRAP_REPEAT;
    case RepeatReflect:
@@ -151,8 +151,11 @@
    case PictFilterBest:
       *out_filter = PIPE_TEX_FILTER_LINEAR;
       break;
+   case PictFilterConvolution:
+      *out_filter = PIPE_TEX_FILTER_NEAREST;
+      return FALSE;
    default:
-      debug_printf("Unkown xrender filter");
+      debug_printf("Unknown xrender filter\n");
       *out_filter = PIPE_TEX_FILTER_NEAREST;
       return FALSE;
    }
@@ -199,6 +202,7 @@
                           op);
          }
       }
+
       return TRUE;
    }
    XORG_FALLBACK("Unsupported composition operation = %d", op);
@@ -227,10 +231,72 @@
    cso_set_blend(exa->renderer->cso, &blend);
 }
 
+static unsigned
+picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask,
+                      PicturePtr pDstPicture)
+{
+   boolean set_alpha = FALSE;
+   boolean swizzle = FALSE;
+   unsigned ret = 0;
+
+   if (pSrc->picture_format == pSrcPicture->format) {
+      if (pSrc->picture_format == PICT_a8) {
+         if (mask)
+            return FS_MASK_LUMINANCE;
+         else if (pDstPicture->format != PICT_a8) {
+            /* if both dst and src are luminance then
+             * we don't want to swizzle the alpha (X) of the
+             * source into W component of the dst because
+             * it will break our destination */
+            return FS_SRC_LUMINANCE;
+         }
+      }
+      return 0;
+   }
+
+   if (pSrc->picture_format != PICT_a8r8g8b8) {
+      assert(!"can not handle formats");
+      return 0;
+   }
+
+   /* pSrc->picture_format == PICT_a8r8g8b8 */
+   switch (pSrcPicture->format) {
+   case PICT_x8b8g8r8:
+   case PICT_b8g8r8:
+      set_alpha = TRUE; /* fall trough */
+   case PICT_a8b8g8r8:
+      swizzle = TRUE;
+      break;
+   case PICT_x8r8g8b8:
+   case PICT_r8g8b8:
+      set_alpha = TRUE; /* fall through */
+   case PICT_a8r8g8b8:
+      break;
+#ifdef PICT_TYPE_BGRA
+   case PICT_b8g8r8a8:
+   case PICT_b8g8r8x8:
+   case PICT_a2r10g10b10:
+   case PICT_x2r10g10b10:
+   case PICT_a2b10g10r10:
+   case PICT_x2b10g10r10:
+#endif
+   default:
+      assert(!"can not handle formats");
+      return 0;
+   }
+
+   if (set_alpha)
+      ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
+   if (swizzle)
+      ret |= mask ? FS_MASK_SWIZZLE_RGB : FS_SRC_SWIZZLE_RGB;
+
+   return ret;
+}
 
 static void
 bind_shaders(struct exa_context *exa, int op,
-             PicturePtr pSrcPicture, PicturePtr pMaskPicture)
+             PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture,
+             struct exa_pixmap_priv *pSrc, struct exa_pixmap_priv *pMask)
 {
    unsigned vs_traits = 0, fs_traits = 0;
    struct xorg_shader shader;
@@ -238,6 +304,9 @@
    exa->has_solid_color = FALSE;
 
    if (pSrcPicture) {
+      if (pSrcPicture->repeatType == RepeatNone && pSrcPicture->transform)
+         fs_traits |= FS_SRC_REPEAT_NONE;
+
       if (pSrcPicture->pSourcePict) {
          if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) {
             fs_traits |= FS_SOLID_FILL;
@@ -253,11 +322,15 @@
          fs_traits |= FS_COMPOSITE;
          vs_traits |= VS_COMPOSITE;
       }
+
+      fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE, pDstPicture);
    }
 
    if (pMaskPicture) {
       vs_traits |= VS_MASK;
       fs_traits |= FS_MASK;
+      if (pMaskPicture->repeatType == RepeatNone && pMaskPicture->transform)
+         fs_traits |= FS_MASK_REPEAT_NONE;
       if (pMaskPicture->componentAlpha) {
          struct xorg_composite_blend blend;
          blend_for_op(&blend, op,
@@ -267,6 +340,8 @@
          } else
             fs_traits |= FS_CA_FULL;
       }
+
+      fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE, pDstPicture);
    }
 
    shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
@@ -287,6 +362,14 @@
 
    exa->num_bound_samplers = 0;
 
+#if 0
+   if ((pSrc && (exa->pipe->is_texture_referenced(exa->pipe, pSrc->tex, 0, 0) &
+                 PIPE_REFERENCED_FOR_WRITE)) ||
+       (pMask && (exa->pipe->is_texture_referenced(exa->pipe, pMask->tex, 0, 0) &
+        PIPE_REFERENCED_FOR_WRITE)))
+      xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL);
+#endif
+
    memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
    memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
 
@@ -338,41 +421,8 @@
                             exa->bound_textures);
 }
 
-static void
-setup_vs_constant_buffer(struct exa_context *exa,
-                         int width, int height)
-{
-   const int param_bytes = 8 * sizeof(float);
-   float vs_consts[8] = {
-      2.f/width, 2.f/height, 1, 1,
-      -1, -1, 0, 0
-   };
-   renderer_set_constants(exa->renderer, PIPE_SHADER_VERTEX,
-                          vs_consts, param_bytes);
-}
 
 
-static void
-setup_fs_constant_buffer(struct exa_context *exa)
-{
-   const int param_bytes = 4 * sizeof(float);
-   const float fs_consts[8] = {
-      0, 0, 0, 1,
-   };
-   renderer_set_constants(exa->renderer, PIPE_SHADER_FRAGMENT,
-                          fs_consts, param_bytes);
-}
-
-static void
-setup_constant_buffers(struct exa_context *exa, struct exa_pixmap_priv *pDst)
-{
-   int width = pDst->tex->width[0];
-   int height = pDst->tex->height[0];
-
-   setup_vs_constant_buffer(exa, width, height);
-   setup_fs_constant_buffer(exa);
-}
-
 static INLINE boolean matrix_from_pict_transform(PictTransform *trans, float *matrix)
 {
    if (!trans)
@@ -420,17 +470,29 @@
                                   struct exa_pixmap_priv *pMask,
                                   struct exa_pixmap_priv *pDst)
 {
-   renderer_bind_framebuffer(exa->renderer, pDst);
-   renderer_bind_viewport(exa->renderer, pDst);
+   struct pipe_surface *dst_surf = xorg_gpu_surface(exa->scrn, pDst);
+
+   renderer_bind_destination(exa->renderer, dst_surf,
+                             pDst->width,
+                             pDst->height);
+
    bind_blend_state(exa, op, pSrcPicture, pMaskPicture, pDstPicture);
-   renderer_bind_rasterizer(exa->renderer);
-   bind_shaders(exa, op, pSrcPicture, pMaskPicture);
+   bind_shaders(exa, op, pSrcPicture, pMaskPicture, pDstPicture, pSrc, pMask);
    bind_samplers(exa, op, pSrcPicture, pMaskPicture,
                  pDstPicture, pSrc, pMask, pDst);
-   setup_constant_buffers(exa, pDst);
 
    setup_transforms(exa, pSrcPicture, pMaskPicture);
 
+   if (exa->num_bound_samplers == 0 ) { /* solid fill */
+      renderer_begin_solid(exa->renderer);
+   } else {
+      renderer_begin_textures(exa->renderer,
+                              exa->bound_textures,
+                              exa->num_bound_samplers);
+   }
+
+
+   pipe_surface_reference(&dst_surf, NULL);
    return TRUE;
 }
 
@@ -440,9 +502,9 @@
                     int dstX, int dstY, int width, int height)
 {
    if (exa->num_bound_samplers == 0 ) { /* solid fill */
-      renderer_draw_solid_rect(exa->renderer,
-                               dstX, dstY, dstX + width, dstY + height,
-                               exa->solid_color);
+      renderer_solid(exa->renderer,
+                     dstX, dstY, dstX + width, dstY + height,
+                     exa->solid_color);
    } else {
       int pos[6] = {srcX, srcY, maskX, maskY, dstX, dstY};
       float *src_matrix = NULL;
@@ -453,11 +515,11 @@
       if (exa->transform.has_mask)
          mask_matrix = exa->transform.mask;
 
-      renderer_draw_textures(exa->renderer,
-                             pos, width, height,
-                             exa->bound_textures,
-                             exa->num_bound_samplers,
-                             src_matrix, mask_matrix);
+      renderer_texture(exa->renderer,
+                       pos, width, height,
+                       exa->bound_textures,
+                       exa->num_bound_samplers,
+                       src_matrix, mask_matrix);
    }
 }
 
@@ -465,6 +527,7 @@
                               struct exa_pixmap_priv *pixmap,
                               Pixel fg)
 {
+   struct pipe_surface *dst_surf = xorg_gpu_surface(exa->scrn, pixmap);
    unsigned vs_traits, fs_traits;
    struct xorg_shader shader;
 
@@ -482,16 +545,19 @@
    vs_traits = VS_SOLID_FILL;
    fs_traits = FS_SOLID_FILL;
 
-   renderer_bind_framebuffer(exa->renderer, pixmap);
-   renderer_bind_viewport(exa->renderer, pixmap);
-   renderer_bind_rasterizer(exa->renderer);
+   renderer_bind_destination(exa->renderer, dst_surf, 
+                             pixmap->width, pixmap->height);
    bind_blend_state(exa, PictOpSrc, NULL, NULL, NULL);
-   setup_constant_buffers(exa, pixmap);
+   cso_set_samplers(exa->renderer->cso, 0, NULL);
+   cso_set_sampler_textures(exa->renderer->cso, 0, NULL);
 
    shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
    cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
    cso_set_fragment_shader_handle(exa->renderer->cso, shader.fs);
 
+   renderer_begin_solid(exa->renderer);
+
+   pipe_surface_reference(&dst_surf, NULL);
    return TRUE;
 }
 
@@ -499,7 +565,17 @@
                 struct exa_pixmap_priv *pixmap,
                 int x0, int y0, int x1, int y1)
 {
-   renderer_draw_solid_rect(exa->renderer,
-                            x0, y0, x1, y1, exa->solid_color);
+   renderer_solid(exa->renderer,
+                  x0, y0, x1, y1, exa->solid_color);
 }
 
+void
+xorg_composite_done(struct exa_context *exa)
+{
+   renderer_draw_flush(exa->renderer);
+
+   exa->transform.has_src = FALSE;
+   exa->transform.has_mask = FALSE;
+   exa->has_solid_color = FALSE;
+   exa->num_bound_samplers = 0;
+}
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.h b/src/gallium/state_trackers/xorg/xorg_composite.h
index 236addf..ec71ebf 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.h
+++ b/src/gallium/state_trackers/xorg/xorg_composite.h
@@ -29,4 +29,8 @@
                 struct exa_pixmap_priv *pixmap,
                 int x0, int y0, int x1, int y1);
 
+
+void
+xorg_composite_done(struct exa_context *exa);
+
 #endif
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index 85b9162..650d2c0 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -50,20 +50,29 @@
 #endif
 
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
 #include "util/u_rect.h"
 
+#ifdef HAVE_LIBKMS
+#include "libkms.h"
+#endif
+
 struct crtc_private
 {
     drmModeCrtcPtr drm_crtc;
 
     /* hwcursor */
     struct pipe_texture *cursor_tex;
+    struct kms_bo *cursor_bo;
+
     unsigned cursor_handle;
 };
 
 static void
 crtc_dpms(xf86CrtcPtr crtc, int mode)
 {
+    /* ScrnInfoPtr pScrn = crtc->scrn; */
+
     switch (mode) {
     case DPMSModeOn:
     case DPMSModeStandby:
@@ -114,7 +123,8 @@
     drm_mode.vrefresh = mode->VRefresh;
     if (!mode->name)
 	xf86SetModeDefaultName(mode);
-    strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN);
+    strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN - 1);
+    drm_mode.name[DRM_DISPLAY_MODE_LEN - 1] = '\0';
 
     ret = drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, ms->fb_id, x, y,
 			 &drm_connector->connector_id, 1, &drm_mode);
@@ -134,23 +144,29 @@
 crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue,
 	       int size)
 {
+    /* XXX: hockup */
 }
 
 static void *
 crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
 {
+    /* ScrnInfoPtr pScrn = crtc->scrn; */
+
     return NULL;
 }
 
 static PixmapPtr
 crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
 {
+    /* ScrnInfoPtr pScrn = crtc->scrn; */
+
     return NULL;
 }
 
 static void
 crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
 {
+    /* ScrnInfoPtr pScrn = crtc->scrn; */
 }
 
 /*
@@ -160,6 +176,7 @@
 static void
 crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg)
 {
+    /* XXX: See if this one is needed, as we only support ARGB cursors */
 }
 
 static void
@@ -170,8 +187,9 @@
 
     drmModeMoveCursor(ms->fd, crtcp->drm_crtc->crtc_id, x, y);
 }
+
 static void
-crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
+crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
 {
     unsigned char *ptr;
     modesettingPtr ms = modesettingPTR(crtc->scrn);
@@ -187,11 +205,10 @@
 	templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
 	templat.target = PIPE_TEXTURE_2D;
 	templat.last_level = 0;
-	templat.depth[0] = 1;
+	templat.depth0 = 1;
 	templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
-	templat.width[0] = 64;
-	templat.height[0] = 64;
-	pf_get_block(templat.format, &templat.block);
+	templat.width0 = 64;
+	templat.height0 = 64;
 
 	crtcp->cursor_tex = ms->screen->texture_create(ms->screen,
 						       &templat);
@@ -207,20 +224,70 @@
 					    PIPE_TRANSFER_WRITE,
 					    0, 0, 64, 64);
     ptr = ms->screen->transfer_map(ms->screen, transfer);
-    util_copy_rect(ptr, &crtcp->cursor_tex->block,
+    util_copy_rect(ptr, crtcp->cursor_tex->format,
 		   transfer->stride, 0, 0,
 		   64, 64, (void*)image, 64 * 4, 0, 0);
     ms->screen->transfer_unmap(ms->screen, transfer);
     ms->screen->tex_transfer_destroy(transfer);
 }
 
+#if HAVE_LIBKMS
+static void
+crtc_load_cursor_argb_kms(xf86CrtcPtr crtc, CARD32 * image)
+{
+    modesettingPtr ms = modesettingPTR(crtc->scrn);
+    struct crtc_private *crtcp = crtc->driver_private;
+    unsigned char *ptr;
+
+    if (!crtcp->cursor_bo) {
+	unsigned attr[8];
+
+	attr[0] = KMS_BO_TYPE;
+	attr[1] = KMS_BO_TYPE_CURSOR;
+	attr[2] = KMS_WIDTH;
+	attr[3] = 64;
+	attr[4] = KMS_HEIGHT;
+	attr[5] = 64;
+	attr[6] = 0;
+
+        if (kms_bo_create(ms->kms, attr, &crtcp->cursor_bo))
+	   return;
+
+	if (kms_bo_get_prop(crtcp->cursor_bo, KMS_HANDLE,
+			    &crtcp->cursor_handle))
+	    goto err_bo_destroy;
+    }
+
+    kms_bo_map(crtcp->cursor_bo, (void**)&ptr);
+    memcpy(ptr, image, 64*64*4);
+    kms_bo_unmap(crtcp->cursor_bo);
+
+    return;
+
+err_bo_destroy:
+    kms_bo_destroy(&crtcp->cursor_bo);
+}
+#endif
+
+static void
+crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
+{
+    modesettingPtr ms = modesettingPTR(crtc->scrn);
+    if (ms->screen)
+	crtc_load_cursor_argb_ga3d(crtc, image);
+#ifdef HAVE_LIBKMS
+    else if (ms->kms)
+	crtc_load_cursor_argb_kms(crtc, image);
+#endif
+}
+
 static void
 crtc_show_cursor(xf86CrtcPtr crtc)
 {
     modesettingPtr ms = modesettingPTR(crtc->scrn);
     struct crtc_private *crtcp = crtc->driver_private;
 
-    if (crtcp->cursor_tex)
+    if (crtcp->cursor_tex || crtcp->cursor_bo)
 	drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id,
 			 crtcp->cursor_handle, 64, 64);
 }
@@ -234,14 +301,20 @@
     drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 0, 0, 0);
 }
 
+/**
+ * Called at vt leave
+ */
 void
-crtc_cursor_destroy(xf86CrtcPtr crtc)
+xorg_crtc_cursor_destroy(xf86CrtcPtr crtc)
 {
     struct crtc_private *crtcp = crtc->driver_private;
 
-    if (crtcp->cursor_tex) {
+    if (crtcp->cursor_tex)
 	pipe_texture_reference(&crtcp->cursor_tex, NULL);
-    }
+#ifdef HAVE_LIBKMS
+    if (crtcp->cursor_bo)
+	kms_bo_destroy(&crtcp->cursor_bo);
+#endif
 }
 
 /*
@@ -253,11 +326,12 @@
 {
     struct crtc_private *crtcp = crtc->driver_private;
 
-    if (crtcp->cursor_tex)
-	pipe_texture_reference(&crtcp->cursor_tex, NULL);
+    xorg_crtc_cursor_destroy(crtc);
 
     drmModeFreeCrtc(crtcp->drm_crtc);
+
     xfree(crtcp);
+    crtc->driver_private = NULL;
 }
 
 static const xf86CrtcFuncsRec crtc_funcs = {
@@ -279,7 +353,7 @@
 };
 
 void
-crtc_init(ScrnInfoPtr pScrn)
+xorg_crtc_init(ScrnInfoPtr pScrn)
 {
     modesettingPtr ms = modesettingPTR(pScrn);
     xf86CrtcPtr crtc;
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index c41a7cd..fd82f4f 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -40,8 +40,15 @@
 #include "pipe/p_state.h"
 #include "pipe/p_inlines.h"
 
+#include "util/u_format.h"
 #include "util/u_rect.h"
 
+/* Make all the #if cases in the code esier to read */
+/* XXX can it be set to 1? */
+#ifndef DRI2INFOREC_VERSION
+#define DRI2INFOREC_VERSION 0
+#endif
+
 typedef struct {
     PixmapPtr pPixmap;
     struct pipe_texture *tex;
@@ -49,7 +56,7 @@
 } *BufferPrivatePtr;
 
 static Bool
-driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format)
+dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format)
 {
     struct pipe_texture *tex = NULL;
     ScreenPtr pScreen = pDraw->pScreen;
@@ -79,14 +86,14 @@
     case DRI2BufferFrontLeft:
 	break;
     case DRI2BufferStencil:
-#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2
+#if DRI2INFOREC_VERSION >= 3
     case DRI2BufferDepthStencil:
 #else
     /* Works on old X servers because sanity checking is for the weak */
     case 9:
 #endif
 	if (exa_priv->depth_stencil_tex &&
-	    !pf_is_depth_stencil(exa_priv->depth_stencil_tex->format))
+	    !util_format_is_depth_or_stencil(exa_priv->depth_stencil_tex->format))
 	    exa_priv->depth_stencil_tex = NULL;
         /* Fall through */
     case DRI2BufferDepth:
@@ -102,10 +109,9 @@
 	    else
 		template.format = ms->ds_depth_bits_last ?
 		    PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
-	    pf_get_block(template.format, &template.block);
-	    template.width[0] = pDraw->width;
-	    template.height[0] = pDraw->height;
-	    template.depth[0] = 1;
+	    template.width0 = pDraw->width;
+	    template.height0 = pDraw->height;
+	    template.depth0 = 1;
 	    template.last_level = 0;
 	    template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
 		PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
@@ -121,9 +127,12 @@
     }
 
     if (!tex) {
+	/* First call to make sure we have a pixmap private */
 	exaMoveInPixmap(private->pPixmap);
 	xorg_exa_set_shared_usage(private->pPixmap);
 	pScreen->ModifyPixmapHeader(private->pPixmap, 0, 0, 0, 0, 0, NULL);
+	/* Second call to make sure texture has valid contents */
+	exaMoveInPixmap(private->pPixmap);
 	tex = xorg_exa_get_texture(private->pPixmap);
     }
 
@@ -137,13 +146,18 @@
     buffer->cpp = 4;
     buffer->driverPrivate = private;
     buffer->flags = 0; /* not tiled */
+#if DRI2INFOREC_VERSION == 2
+    ((DRI2Buffer2Ptr)buffer)->format = 0;
+#elif DRI2INFOREC_VERSION >= 3
+    buffer->format = 0;
+#endif
     private->tex = tex;
 
     return TRUE;
 }
 
 static void
-driDoDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
+dri2_do_destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
 {
     ScreenPtr pScreen = pDraw->pScreen;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -157,12 +171,12 @@
     (*pScreen->DestroyPixmap)(private->pPixmap);
 }
 
-#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2
+#if DRI2INFOREC_VERSION >= 2
 
-static DRI2BufferPtr
-driCreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format)
+static DRI2Buffer2Ptr
+dri2_create_buffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format)
 {
-    DRI2BufferPtr buffer;
+    DRI2Buffer2Ptr buffer;
     BufferPrivatePtr private;
 
     buffer = xcalloc(1, sizeof *buffer);
@@ -177,7 +191,8 @@
     buffer->attachment = attachment;
     buffer->driverPrivate = private;
 
-    if (driDoCreateBuffer(pDraw, buffer, format))
+    /* So far it is safe to downcast a DRI2Buffer2Ptr to DRI2BufferPtr */
+    if (dri2_do_create_buffer(pDraw, (DRI2BufferPtr)buffer, format))
 	return buffer;
 
     xfree(private);
@@ -187,18 +202,19 @@
 }
 
 static void
-driDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
+dri2_destroy_buffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer)
 {
-    driDoDestroyBuffer(pDraw, buffer);
+    /* So far it is safe to downcast a DRI2Buffer2Ptr to DRI2BufferPtr */
+    dri2_do_destroy_buffer(pDraw, (DRI2BufferPtr)buffer);
 
     xfree(buffer->driverPrivate);
     xfree(buffer);
 }
 
-#else /* DRI2INFOREC_VERSION <= 2 */
+#else /* DRI2INFOREC_VERSION < 2 */
 
 static DRI2BufferPtr
-driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
+dri2_create_buffers(DrawablePtr pDraw, unsigned int *attachments, int count)
 {
     BufferPrivatePtr privates;
     DRI2BufferPtr buffers;
@@ -216,7 +232,7 @@
 	buffers[i].attachment = attachments[i];
 	buffers[i].driverPrivate = &privates[i];
 
-	if (!driDoCreateBuffer(pDraw, &buffers[i], 0))
+	if (!dri2_do_create_buffer(pDraw, &buffers[i], 0))
 	    goto fail;
     }
 
@@ -231,12 +247,12 @@
 }
 
 static void
-driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
+dri2_destroy_buffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
 {
     int i;
 
     for (i = 0; i < count; i++) {
-	driDoDestroyBuffer(pDraw, &buffers[i]);
+	dri2_do_destroy_buffer(pDraw, &buffers[i]);
     }
 
     if (buffers) {
@@ -245,21 +261,22 @@
     }
 }
 
-#endif /* DRI2INFOREC_VERSION */
+#endif /* DRI2INFOREC_VERSION >= 2 */
 
 static void
-driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
-              DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer)
+dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
+                 DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer)
 {
     ScreenPtr pScreen = pDraw->pScreen;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
     BufferPrivatePtr dst_priv = pDestBuffer->driverPrivate;
     BufferPrivatePtr src_priv = pSrcBuffer->driverPrivate;
-    PixmapPtr src_pixmap;
-    PixmapPtr dst_pixmap;
+    DrawablePtr src_draw;
+    DrawablePtr dst_draw;
     GCPtr gc;
     RegionPtr copy_clip;
+    Bool save_accel;
 
     /*
      * In driCreateBuffers we dewrap windows into the
@@ -267,12 +284,10 @@
      * We need to use the real drawable in CopyArea
      * so that cliprects and offsets are correct.
      */
-    src_pixmap = src_priv->pPixmap;
-    dst_pixmap = dst_priv->pPixmap;
-    if (pSrcBuffer->attachment == DRI2BufferFrontLeft)
-	src_pixmap = (PixmapPtr)pDraw;
-    if (pDestBuffer->attachment == DRI2BufferFrontLeft)
-	dst_pixmap = (PixmapPtr)pDraw;
+    src_draw = (pSrcBuffer->attachment == DRI2BufferFrontLeft) ? pDraw :
+       &src_priv->pPixmap->drawable;
+    dst_draw = (pDestBuffer->attachment == DRI2BufferFrontLeft) ? pDraw :
+       &dst_priv->pPixmap->drawable;
 
     /*
      * The clients implements glXWaitX with a copy front to fake and then
@@ -291,7 +306,7 @@
      * must in the glXWaitGL case but we don't know if this is a glXWaitGL
      * or a glFlush/glFinish call.
      */
-    if (dst_pixmap == src_pixmap) {
+    if (dst_priv->pPixmap == src_priv->pPixmap) {
 	/* pixmap glXWaitX */
 	if (pSrcBuffer->attachment == DRI2BufferFrontLeft &&
 	    pDestBuffer->attachment == DRI2BufferFakeFrontLeft) {
@@ -312,7 +327,7 @@
     copy_clip = REGION_CREATE(pScreen, NULL, 0);
     REGION_COPY(pScreen, copy_clip, pRegion);
     (*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0);
-    ValidateGC(&dst_pixmap->drawable, gc);
+    ValidateGC(dst_draw, gc);
 
     /* If this is a full buffer swap, throttle on the previous one */
     if (dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
@@ -325,8 +340,21 @@
 	}
     }
 
-    (*gc->ops->CopyArea)(&src_pixmap->drawable, &dst_pixmap->drawable, gc,
+    /* Try to make sure the blit will be accelerated */
+    save_accel = ms->exa->accel;
+    ms->exa->accel = TRUE;
+
+    /* In case it won't be though, make sure the GPU copy contents of the
+     * source pixmap will be used for the software fallback - presumably the
+     * client modified them before calling in here.
+     */
+    exaMoveInPixmap(src_priv->pPixmap);
+    DamageRegionAppend(src_draw, pRegion);
+    DamageRegionProcessPending(src_draw);
+
+    (*gc->ops->CopyArea)(src_draw, dst_draw, gc,
 			 0, 0, pDraw->width, pDraw->height, 0, 0);
+    ms->exa->accel = save_accel;
 
     FreeScratchGC(gc);
 
@@ -336,13 +364,13 @@
 }
 
 Bool
-driScreenInit(ScreenPtr pScreen)
+xorg_dri2_init(ScreenPtr pScreen)
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
     DRI2InfoRec dri2info;
 
-#if defined(DRI2INFOREC_VERSION)
+#if DRI2INFOREC_VERSION >= 2
     dri2info.version = DRI2INFOREC_VERSION;
 #else
     dri2info.version = 1;
@@ -352,14 +380,14 @@
     dri2info.driverName = pScrn->driverName;
     dri2info.deviceName = "/dev/dri/card0"; /* FIXME */
 
-#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2
-    dri2info.CreateBuffer = driCreateBuffer;
-    dri2info.DestroyBuffer = driDestroyBuffer;
+#if DRI2INFOREC_VERSION >= 2
+    dri2info.CreateBuffer = dri2_create_buffer;
+    dri2info.DestroyBuffer = dri2_destroy_buffer;
 #else
-    dri2info.CreateBuffers = driCreateBuffers;
-    dri2info.DestroyBuffers = driDestroyBuffers;
+    dri2info.CreateBuffers = dri2_create_buffers;
+    dri2info.DestroyBuffers = dri2_destroy_buffers;
 #endif
-    dri2info.CopyRegion = driCopyRegion;
+    dri2info.CopyRegion = dri2_copy_region;
     dri2info.Wait = NULL;
 
     ms->d_depth_bits_last =
@@ -375,7 +403,7 @@
 }
 
 void
-driCloseScreen(ScreenPtr pScreen)
+xorg_dri2_close(ScreenPtr pScreen)
 {
     DRI2CloseScreen(pScreen);
 }
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index 26cf2dd..b02fe68 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -56,32 +56,38 @@
 #include "xorg_tracker.h"
 #include "xorg_winsys.h"
 
-static void AdjustFrame(int scrnIndex, int x, int y, int flags);
-static Bool CloseScreen(int scrnIndex, ScreenPtr pScreen);
-static Bool EnterVT(int scrnIndex, int flags);
-static Bool SaveHWState(ScrnInfoPtr pScrn);
-static Bool RestoreHWState(ScrnInfoPtr pScrn);
+#ifdef HAVE_LIBKMS
+#include "libkms.h"
+#endif
 
+/*
+ * Functions and symbols exported to Xorg via pointers.
+ */
 
-static ModeStatus ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
-			    int flags);
-static void FreeScreen(int scrnIndex, int flags);
-static void LeaveVT(int scrnIndex, int flags);
-static Bool SwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
-static Bool ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
-		       char **argv);
-static Bool PreInit(ScrnInfoPtr pScrn, int flags);
+static Bool drv_pre_init(ScrnInfoPtr pScrn, int flags);
+static Bool drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc,
+			    char **argv);
+static Bool drv_switch_mode(int scrnIndex, DisplayModePtr mode, int flags);
+static void drv_adjust_frame(int scrnIndex, int x, int y, int flags);
+static Bool drv_enter_vt(int scrnIndex, int flags);
+static void drv_leave_vt(int scrnIndex, int flags);
+static void drv_free_screen(int scrnIndex, int flags);
+static ModeStatus drv_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+			         int flags);
 
 typedef enum
 {
     OPTION_SW_CURSOR,
-} modesettingOpts;
+    OPTION_2D_ACCEL,
+} drv_option_enums;
 
-static const OptionInfoRec Options[] = {
+static const OptionInfoRec drv_options[] = {
     {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
+    {OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE},
     {-1, NULL, OPTV_NONE, {0}, FALSE}
 };
 
+
 /*
  * Exported Xorg driver functions to winsys
  */
@@ -89,28 +95,39 @@
 const OptionInfoRec *
 xorg_tracker_available_options(int chipid, int busid)
 {
-    return Options;
+    return drv_options;
 }
 
 void
 xorg_tracker_set_functions(ScrnInfoPtr scrn)
 {
-    scrn->PreInit = PreInit;
-    scrn->ScreenInit = ScreenInit;
-    scrn->SwitchMode = SwitchMode;
-    scrn->AdjustFrame = AdjustFrame;
-    scrn->EnterVT = EnterVT;
-    scrn->LeaveVT = LeaveVT;
-    scrn->FreeScreen = FreeScreen;
-    scrn->ValidMode = ValidMode;
+    scrn->PreInit = drv_pre_init;
+    scrn->ScreenInit = drv_screen_init;
+    scrn->SwitchMode = drv_switch_mode;
+    scrn->AdjustFrame = drv_adjust_frame;
+    scrn->EnterVT = drv_enter_vt;
+    scrn->LeaveVT = drv_leave_vt;
+    scrn->FreeScreen = drv_free_screen;
+    scrn->ValidMode = drv_valid_mode;
 }
 
+
 /*
- * Static Xorg funtctions
+ * Internal function definitions
+ */
+
+static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn);
+static Bool drv_close_screen(int scrnIndex, ScreenPtr pScreen);
+static Bool drv_save_hw_state(ScrnInfoPtr pScrn);
+static Bool drv_restore_hw_state(ScrnInfoPtr pScrn);
+
+
+/*
+ * Internal functions
  */
 
 static Bool
-GetRec(ScrnInfoPtr pScrn)
+drv_get_rec(ScrnInfoPtr pScrn)
 {
     if (pScrn->driverPrivate)
 	return TRUE;
@@ -121,7 +138,7 @@
 }
 
 static void
-FreeRec(ScrnInfoPtr pScrn)
+drv_free_rec(ScrnInfoPtr pScrn)
 {
     if (!pScrn)
 	return;
@@ -135,88 +152,21 @@
 }
 
 static void
-ProbeDDC(ScrnInfoPtr pScrn, int index)
+drv_probe_ddc(ScrnInfoPtr pScrn, int index)
 {
     ConfiguredMonitor = NULL;
 }
 
 static Bool
-CreateFrontBuffer(ScrnInfoPtr pScrn)
+drv_crtc_resize(ScrnInfoPtr pScrn, int width, int height)
 {
     modesettingPtr ms = modesettingPTR(pScrn);
-    unsigned handle, stride;
-    struct pipe_texture *tex;
-
-    ms->noEvict = TRUE;
-
-    tex = xorg_exa_create_root_texture(pScrn, pScrn->virtualX, pScrn->virtualY,
-				       pScrn->depth, pScrn->bitsPerPixel);
-
-    if (!tex)
-	return FALSE;
-
-    if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
-					    tex,
-					    &stride,
-					    &handle))
-	return FALSE;
-
-    drmModeAddFB(ms->fd,
-		 pScrn->virtualX,
-		 pScrn->virtualY,
-		 pScrn->depth,
-		 pScrn->bitsPerPixel,
-		 stride,
-		 handle,
-                 &ms->fb_id);
-
-    pScrn->frameX0 = 0;
-    pScrn->frameY0 = 0;
-    AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
-    pipe_texture_reference(&ms->root_texture, tex);
-    pipe_texture_reference(&tex, NULL);
-    return TRUE;
-}
-
-static Bool
-BindTextureToRoot(ScrnInfoPtr pScrn)
-{
-    modesettingPtr ms = modesettingPTR(pScrn);
-    ScreenPtr pScreen = pScrn->pScreen;
-    struct pipe_texture *check;
-    PixmapPtr rootPixmap;
-
-    rootPixmap = pScreen->GetScreenPixmap(pScreen);
-
-    xorg_exa_set_displayed_usage(rootPixmap);
-    xorg_exa_set_shared_usage(rootPixmap);
-    xorg_exa_set_texture(rootPixmap, ms->root_texture);
-    if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
-	FatalError("Couldn't adjust screen pixmap\n");
-
-    check = xorg_exa_get_texture(rootPixmap);
-    if (ms->root_texture != check)
-	FatalError("Created new root texture\n");
-
-    pipe_texture_reference(&check, NULL);
-
-    return TRUE;
-}
-
-static Bool
-crtc_resize(ScrnInfoPtr pScrn, int width, int height)
-{
-    modesettingPtr ms = modesettingPTR(pScrn);
-    unsigned handle, stride;
     PixmapPtr rootPixmap;
     ScreenPtr pScreen = pScrn->pScreen;
 
     if (width == pScrn->virtualX && height == pScrn->virtualY)
 	return TRUE;
 
-    ErrorF("RESIZING TO %dx%d\n", width, height);
-
     pScrn->virtualX = width;
     pScrn->virtualY = height;
 
@@ -224,44 +174,25 @@
      * Remove the old framebuffer & texture.
      */
     drmModeRmFB(ms->fd, ms->fb_id);
-    pipe_texture_reference(&ms->root_texture, NULL);
-
+    if (!ms->destroy_front_buffer(pScrn))
+	FatalError("failed to destroy front buffer\n");
 
     rootPixmap = pScreen->GetScreenPixmap(pScreen);
     if (!pScreen->ModifyPixmapHeader(rootPixmap, width, height, -1, -1, -1, NULL))
 	return FALSE;
 
-    /* takes one ref */
-    ms->root_texture = xorg_exa_get_texture(rootPixmap);
-
-    if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
-					    ms->root_texture,
-					    &stride,
-					    &handle))
-	FatalError("Could not get handle and stride from texture\n");
-
-    drmModeAddFB(ms->fd,
-		 pScrn->virtualX,
-		 pScrn->virtualY,
-		 pScrn->depth,
-		 pScrn->bitsPerPixel,
-		 stride,
-		 handle,
-                 &ms->fb_id);
-
-    /* HW dependent - FIXME */
-    pScrn->displayWidth = pScrn->virtualX;
+    pScrn->displayWidth = rootPixmap->devKind / (rootPixmap->drawable.bitsPerPixel / 8);
 
     /* now create new frontbuffer */
-    return CreateFrontBuffer(pScrn) && BindTextureToRoot(pScrn);
+    return ms->create_front_buffer(pScrn) && ms->bind_front_buffer(pScrn);
 }
 
 static const xf86CrtcConfigFuncsRec crtc_config_funcs = {
-    crtc_resize
+    .resize = drv_crtc_resize
 };
 
 static Bool
-InitDRM(ScrnInfoPtr pScrn)
+drv_init_drm(ScrnInfoPtr pScrn)
 {
     modesettingPtr ms = modesettingPTR(pScrn);
 
@@ -281,18 +212,77 @@
 	    return FALSE;
     }
 
-    if (!ms->api) {
-	ms->api = drm_api_create();
+    return TRUE;
+}
 
-	if (!ms->api)
-	    return FALSE;
+static Bool
+drv_init_resource_management(ScrnInfoPtr pScrn)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+    /*
+    ScreenPtr pScreen = pScrn->pScreen;
+    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+    Bool fbAccessDisabled;
+    CARD8 *fbstart;
+     */
+
+    if (ms->screen || ms->kms)
+	return TRUE;
+
+    ms->api = drm_api_create();
+    if (ms->api) {
+	ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL);
+
+	if (ms->screen)
+	    return TRUE;
+
+	if (ms->api->destroy)
+	    ms->api->destroy(ms->api);
+
+	ms->api = NULL;
     }
 
+#ifdef HAVE_LIBKMS
+    if (!kms_create(ms->fd, &ms->kms))
+	return TRUE;
+#endif
+
+    return FALSE;
+}
+
+static Bool
+drv_close_resource_management(ScrnInfoPtr pScrn)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+    int i;
+
+    if (ms->screen) {
+	assert(ms->ctx == NULL);
+
+	for (i = 0; i < XORG_NR_FENCES; i++) {
+	    if (ms->fence[i]) {
+		ms->screen->fence_finish(ms->screen, ms->fence[i], 0);
+		ms->screen->fence_reference(ms->screen, &ms->fence[i], NULL);
+	    }
+	}
+	ms->screen->destroy(ms->screen);
+    }
+    ms->screen = NULL;
+
+    if (ms->api && ms->api->destroy)
+	ms->api->destroy(ms->api);
+    ms->api = NULL;
+
+#ifdef HAVE_LIBKMS
+    if (ms->kms)
+	kms_destroy(&ms->kms);
+#endif
+
     return TRUE;
 }
 
 static Bool
-PreInit(ScrnInfoPtr pScrn, int flags)
+drv_pre_init(ScrnInfoPtr pScrn, int flags)
 {
     xf86CrtcConfigPtr xf86_config;
     modesettingPtr ms;
@@ -307,12 +297,12 @@
     pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
 
     if (flags & PROBE_DETECT) {
-	ProbeDDC(pScrn, pEnt->index);
+	drv_probe_ddc(pScrn, pEnt->index);
 	return TRUE;
     }
 
     /* Allocate driverPrivate */
-    if (!GetRec(pScrn))
+    if (!drv_get_rec(pScrn))
 	return FALSE;
 
     ms = modesettingPTR(pScrn);
@@ -349,7 +339,7 @@
 
     ms->fd = -1;
     ms->api = NULL;
-    if (!InitDRM(pScrn))
+    if (!drv_init_drm(pScrn))
 	return FALSE;
 
     pScrn->monitor = pScrn->confScreen->monitor;
@@ -381,9 +371,9 @@
 
     /* Process the options */
     xf86CollectOptions(pScrn, NULL);
-    if (!(ms->Options = xalloc(sizeof(Options))))
+    if (!(ms->Options = xalloc(sizeof(drv_options))))
 	return FALSE;
-    memcpy(ms->Options, Options, sizeof(Options));
+    memcpy(ms->Options, drv_options, sizeof(drv_options));
     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options);
 
     /* Allocate an xf86CrtcConfig */
@@ -398,18 +388,18 @@
 	ms->SWCursor = TRUE;
     }
 
-    SaveHWState(pScrn);
+    drv_save_hw_state(pScrn);
 
-    crtc_init(pScrn);
-    output_init(pScrn);
+    xorg_crtc_init(pScrn);
+    xorg_output_init(pScrn);
 
     if (!xf86InitialConfiguration(pScrn, TRUE)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
-	RestoreHWState(pScrn);
+	drv_restore_hw_state(pScrn);
 	return FALSE;
     }
 
-    RestoreHWState(pScrn);
+    drv_restore_hw_state(pScrn);
 
     /*
      * If the driver can do gamma correction, it should call xf86SetGamma() here.
@@ -433,21 +423,23 @@
     xf86SetDpi(pScrn, 0, 0);
 
     /* Load the required sub modules */
-    if (!xf86LoadSubModule(pScrn, "fb")) {
+    if (!xf86LoadSubModule(pScrn, "fb"))
 	return FALSE;
-    }
 
-    xf86LoadSubModule(pScrn, "exa");
+    /* XXX: these aren't needed when we are using libkms */
+    if (!xf86LoadSubModule(pScrn, "exa"))
+	return FALSE;
 
 #ifdef DRI2
-    xf86LoadSubModule(pScrn, "dri2");
+    if (!xf86LoadSubModule(pScrn, "dri2"))
+	return FALSE;
 #endif
 
     return TRUE;
 }
 
 static Bool
-SaveHWState(ScrnInfoPtr pScrn)
+drv_save_hw_state(ScrnInfoPtr pScrn)
 {
     /*xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);*/
 
@@ -455,24 +447,45 @@
 }
 
 static Bool
-RestoreHWState(ScrnInfoPtr pScrn)
+drv_restore_hw_state(ScrnInfoPtr pScrn)
 {
     /*xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);*/
 
     return TRUE;
 }
 
-static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout,
-                             pointer pReadmask)
+static void drv_block_handler(int i, pointer blockData, pointer pTimeout,
+                              pointer pReadmask)
 {
     ScreenPtr pScreen = screenInfo.screens[i];
     modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]);
 
     pScreen->BlockHandler = ms->blockHandler;
     pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
-    pScreen->BlockHandler = xorgBlockHandler;
+    pScreen->BlockHandler = drv_block_handler;
 
-    ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+    if (ms->ctx) {
+       int j;
+
+       ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, &ms->fence[XORG_NR_FENCES-1]);
+       
+       if (ms->fence[0])
+          ms->ctx->screen->fence_finish(ms->ctx->screen, ms->fence[0], 0);
+  
+       /* The amount of rendering generated by a block handler can be
+        * quite small.  Let us get a fair way ahead of hardware before
+        * throttling.
+        */
+       for (j = 0; j < XORG_NR_FENCES - 1; j++)
+          ms->screen->fence_reference(ms->screen,
+                                      &ms->fence[j],
+                                      ms->fence[j+1]);
+
+       ms->screen->fence_reference(ms->screen,
+                                   &ms->fence[XORG_NR_FENCES-1],
+                                   NULL);
+    }
+        
 
 #ifdef DRM_MODE_FEATURE_DIRTYFB
     {
@@ -482,7 +495,7 @@
 	if (num_cliprects) {
 	    drmModeClip *clip = alloca(num_cliprects * sizeof(drmModeClip));
 	    BoxPtr rect = REGION_RECTS(dirty);
-	    int i;
+	    int i, ret;
 
 	    /* XXX no need for copy? */
 	    for (i = 0; i < num_cliprects; i++, rect++) {
@@ -493,7 +506,11 @@
 	    }
 
 	    /* TODO query connector property to see if this is needed */
-	    drmModeDirtyFB(ms->fd, ms->fb_id, clip, num_cliprects);
+	    ret = drmModeDirtyFB(ms->fd, ms->fb_id, clip, num_cliprects);
+	    if (ret) {
+		debug_printf("%s: failed to send dirty (%i, %s)\n",
+			     __func__, ret, strerror(-ret));
+	    }
 
 	    DamageEmpty(ms->damage);
 	}
@@ -502,7 +519,7 @@
 }
 
 static Bool
-CreateScreenResources(ScreenPtr pScreen)
+drv_create_screen_resources(ScreenPtr pScreen)
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
@@ -513,13 +530,13 @@
 
     pScreen->CreateScreenResources = ms->createScreenResources;
     ret = pScreen->CreateScreenResources(pScreen);
-    pScreen->CreateScreenResources = CreateScreenResources;
+    pScreen->CreateScreenResources = drv_create_screen_resources;
 
-    BindTextureToRoot(pScrn);
+    ms->bind_front_buffer(pScrn);
 
     ms->noEvict = FALSE;
 
-    AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+    drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
 
 #ifdef DRM_MODE_FEATURE_DIRTYFB
     rootPixmap = pScreen->GetScreenPixmap(pScreen);
@@ -543,22 +560,25 @@
 }
 
 static Bool
-ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
     VisualPtr visual;
 
-    if (!InitDRM(pScrn))
+    if (!drv_init_drm(pScrn)) {
+	FatalError("Could not init DRM");
 	return FALSE;
+    }
 
-    if (!ms->screen) {
-	ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL);
+    if (!drv_init_resource_management(pScrn)) {
+	FatalError("Could not init resource management (!pipe_screen && !libkms)");
+	return FALSE;
+    }
 
-	if (!ms->screen) {
-	    FatalError("Could not init pipe_screen\n");
-	    return FALSE;
-	}
+    if (!drv_init_front_buffer_functions(pScrn)) {
+	FatalError("Could not init front buffer manager");
+	return FALSE;
     }
 
     pScrn->pScreen = pScreen;
@@ -603,16 +623,22 @@
     fbPictureInit(pScreen, NULL, 0);
 
     ms->blockHandler = pScreen->BlockHandler;
-    pScreen->BlockHandler = xorgBlockHandler;
+    pScreen->BlockHandler = drv_block_handler;
     ms->createScreenResources = pScreen->CreateScreenResources;
-    pScreen->CreateScreenResources = CreateScreenResources;
+    pScreen->CreateScreenResources = drv_create_screen_resources;
 
     xf86SetBlackWhitePixels(pScreen);
 
-    ms->exa = xorg_exa_init(pScrn);
-    ms->debug_fallback = debug_get_bool_option("XORG_DEBUG_FALLBACK", TRUE);
+    if (ms->screen) {
+	ms->exa = xorg_exa_init(pScrn, xf86ReturnOptValBool(ms->Options,
+							    OPTION_2D_ACCEL, TRUE));
+	ms->debug_fallback = debug_get_bool_option("XORG_DEBUG_FALLBACK", TRUE);
 
-    xorg_init_video(pScreen);
+	xorg_xv_init(pScreen);
+#ifdef DRI2
+	xorg_dri2_init(pScreen);
+#endif
+    }
 
     miInitializeBackingStore(pScreen);
     xf86SetBackingStore(pScreen);
@@ -631,7 +657,7 @@
 
     pScreen->SaveScreen = xf86SaveScreen;
     ms->CloseScreen = pScreen->CloseScreen;
-    pScreen->CloseScreen = CloseScreen;
+    pScreen->CloseScreen = drv_close_screen;
 
     if (!xf86CrtcScreenInit(pScreen))
 	return FALSE;
@@ -644,17 +670,14 @@
     if (serverGeneration == 1)
 	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
 
-#if 1
-#ifdef DRI2
-    driScreenInit(pScreen);
-#endif
-#endif
+    if (ms->winsys_screen_init)
+	ms->winsys_screen_init(pScrn);
 
-    return EnterVT(scrnIndex, 1);
+    return drv_enter_vt(scrnIndex, 1);
 }
 
 static void
-AdjustFrame(int scrnIndex, int x, int y, int flags)
+drv_adjust_frame(int scrnIndex, int x, int y, int flags)
 {
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
@@ -670,23 +693,26 @@
 }
 
 static void
-FreeScreen(int scrnIndex, int flags)
+drv_free_screen(int scrnIndex, int flags)
 {
-    FreeRec(xf86Screens[scrnIndex]);
+    drv_free_rec(xf86Screens[scrnIndex]);
 }
 
 static void
-LeaveVT(int scrnIndex, int flags)
+drv_leave_vt(int scrnIndex, int flags)
 {
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     modesettingPtr ms = modesettingPTR(pScrn);
     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
     int o;
 
+    if (ms->winsys_leave_vt)
+	ms->winsys_leave_vt(pScrn);
+
     for (o = 0; o < config->num_crtc; o++) {
 	xf86CrtcPtr crtc = config->crtc[o];
 
-	crtc_cursor_destroy(crtc);
+	xorg_crtc_cursor_destroy(crtc);
 
 	if (crtc->rotatedPixmap || crtc->rotatedData) {
 	    crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
@@ -698,7 +724,7 @@
 
     drmModeRmFB(ms->fd, ms->fb_id);
 
-    RestoreHWState(pScrn);
+    drv_restore_hw_state(pScrn);
 
     if (drmDropMaster(ms->fd))
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -711,7 +737,7 @@
  * This gets called when gaining control of the VT, and from ScreenInit().
  */
 static Bool
-EnterVT(int scrnIndex, int flags)
+drv_enter_vt(int scrnIndex, int flags)
 {
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     modesettingPtr ms = modesettingPTR(pScrn);
@@ -733,23 +759,26 @@
      */
     if (ms->SaveGeneration != serverGeneration) {
 	ms->SaveGeneration = serverGeneration;
-	SaveHWState(pScrn);
+	drv_save_hw_state(pScrn);
     }
 
-    if (!CreateFrontBuffer(pScrn))
+    if (!ms->create_front_buffer(pScrn))
 	return FALSE;
 
-    if (!flags && !BindTextureToRoot(pScrn))
+    if (!flags && !ms->bind_front_buffer(pScrn))
 	return FALSE;
 
     if (!xf86SetDesiredModes(pScrn))
 	return FALSE;
 
+    if (ms->winsys_enter_vt)
+	ms->winsys_enter_vt(pScrn);
+
     return TRUE;
 }
 
 static Bool
-SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+drv_switch_mode(int scrnIndex, DisplayModePtr mode, int flags)
 {
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
 
@@ -757,16 +786,21 @@
 }
 
 static Bool
-CloseScreen(int scrnIndex, ScreenPtr pScreen)
+drv_close_screen(int scrnIndex, ScreenPtr pScreen)
 {
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     modesettingPtr ms = modesettingPTR(pScrn);
 
     if (pScrn->vtSema) {
-	LeaveVT(scrnIndex, 0);
+	drv_leave_vt(scrnIndex, 0);
     }
+
+    if (ms->winsys_screen_close)
+	ms->winsys_screen_close(pScrn);
+
 #ifdef DRI2
-    driCloseScreen(pScreen);
+    if (ms->screen)
+	xorg_dri2_close(pScreen);
 #endif
 
     pScreen->BlockHandler = ms->blockHandler;
@@ -780,14 +814,14 @@
     }
 #endif
 
-    pipe_texture_reference(&ms->root_texture, NULL);
+    drmModeRmFB(ms->fd, ms->fb_id);
+    ms->destroy_front_buffer(pScrn);
 
     if (ms->exa)
 	xorg_exa_close(pScrn);
+    ms->exa = NULL;
 
-    if (ms->api && ms->api->destroy)
-	ms->api->destroy(ms->api);
-    ms->api = NULL;
+    drv_close_resource_management(pScrn);
 
     drmClose(ms->fd);
     ms->fd = -1;
@@ -798,9 +832,217 @@
 }
 
 static ModeStatus
-ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+drv_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
 {
     return MODE_OK;
 }
 
+
+/*
+ * Front buffer backing store functions.
+ */
+
+static Bool
+drv_destroy_front_buffer_ga3d(ScrnInfoPtr pScrn)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+    pipe_texture_reference(&ms->root_texture, NULL);
+    return TRUE;
+}
+
+static Bool
+drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+    unsigned handle, stride;
+    struct pipe_texture *tex;
+    int ret;
+
+    ms->noEvict = TRUE;
+
+    tex = xorg_exa_create_root_texture(pScrn, pScrn->virtualX, pScrn->virtualY,
+				       pScrn->depth, pScrn->bitsPerPixel);
+
+    if (!tex)
+	return FALSE;
+
+    if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
+					    tex,
+					    &stride,
+					    &handle))
+	goto err_destroy;
+
+    ret = drmModeAddFB(ms->fd,
+		       pScrn->virtualX,
+		       pScrn->virtualY,
+		       pScrn->depth,
+		       pScrn->bitsPerPixel,
+		       stride,
+		       handle,
+		       &ms->fb_id);
+    if (ret) {
+	debug_printf("%s: failed to create framebuffer (%i, %s)",
+		     __func__, ret, strerror(-ret));
+	goto err_destroy;
+    }
+
+    pScrn->frameX0 = 0;
+    pScrn->frameY0 = 0;
+    drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+    pipe_texture_reference(&ms->root_texture, tex);
+    pipe_texture_reference(&tex, NULL);
+
+    return TRUE;
+
+err_destroy:
+    pipe_texture_reference(&tex, NULL);
+    return FALSE;
+}
+
+static Bool
+drv_bind_front_buffer_ga3d(ScrnInfoPtr pScrn)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+    ScreenPtr pScreen = pScrn->pScreen;
+    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+    struct pipe_texture *check;
+
+    xorg_exa_set_displayed_usage(rootPixmap);
+    xorg_exa_set_shared_usage(rootPixmap);
+    xorg_exa_set_texture(rootPixmap, ms->root_texture);
+    if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
+	FatalError("Couldn't adjust screen pixmap\n");
+
+    check = xorg_exa_get_texture(rootPixmap);
+    if (ms->root_texture != check)
+	FatalError("Created new root texture\n");
+
+    pipe_texture_reference(&check, NULL);
+    return TRUE;
+}
+
+#ifdef HAVE_LIBKMS
+static Bool
+drv_destroy_front_buffer_kms(ScrnInfoPtr pScrn)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+    ScreenPtr pScreen = pScrn->pScreen;
+    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+
+    /* XXX Do something with the rootPixmap.
+     * This currently works fine but if we are getting crashes in
+     * the fb functions after VT switches maybe look more into it.
+     */
+    (void)rootPixmap;
+
+    if (!ms->root_bo)
+	return TRUE;
+
+    kms_bo_unmap(ms->root_bo);
+    kms_bo_destroy(&ms->root_bo);
+    return TRUE;
+}
+
+static Bool
+drv_create_front_buffer_kms(ScrnInfoPtr pScrn)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+    unsigned handle, stride;
+    struct kms_bo *bo;
+    unsigned attr[8];
+    int ret;
+
+    attr[0] = KMS_BO_TYPE;
+    attr[1] = KMS_BO_TYPE_SCANOUT;
+    attr[2] = KMS_WIDTH;
+    attr[3] = pScrn->virtualX;
+    attr[4] = KMS_HEIGHT;
+    attr[5] = pScrn->virtualY;
+    attr[6] = 0;
+
+    if (kms_bo_create(ms->kms, attr, &bo))
+	return FALSE;
+
+    if (kms_bo_get_prop(bo, KMS_PITCH, &stride))
+	goto err_destroy;
+
+    if (kms_bo_get_prop(bo, KMS_HANDLE, &handle))
+	goto err_destroy;
+
+    ret = drmModeAddFB(ms->fd,
+		       pScrn->virtualX,
+		       pScrn->virtualY,
+		       pScrn->depth,
+		       pScrn->bitsPerPixel,
+		       stride,
+		       handle,
+		       &ms->fb_id);
+    if (ret) {
+	debug_printf("%s: failed to create framebuffer (%i, %s)",
+		     __func__, ret, strerror(-ret));
+	goto err_destroy;
+    }
+
+    pScrn->frameX0 = 0;
+    pScrn->frameY0 = 0;
+    drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+    ms->root_bo = bo;
+
+    return TRUE;
+
+err_destroy:
+    kms_bo_destroy(&bo);
+    return FALSE;
+}
+
+static Bool
+drv_bind_front_buffer_kms(ScrnInfoPtr pScrn)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+    ScreenPtr pScreen = pScrn->pScreen;
+    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+    unsigned stride;
+    void *ptr;
+
+    if (kms_bo_get_prop(ms->root_bo, KMS_PITCH, &stride))
+	return FALSE;
+
+    if (kms_bo_map(ms->root_bo, &ptr))
+	goto err_destroy;
+
+    pScreen->ModifyPixmapHeader(rootPixmap,
+				pScreen->width,
+				pScreen->height,
+				pScreen->rootDepth,
+				pScrn->bitsPerPixel,
+				stride,
+				ptr);
+    return TRUE;
+
+err_destroy:
+    kms_bo_destroy(&ms->root_bo);
+    return FALSE;
+}
+#endif /* HAVE_LIBKMS */
+
+static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+    if (ms->screen) {
+	ms->destroy_front_buffer = drv_destroy_front_buffer_ga3d;
+	ms->create_front_buffer = drv_create_front_buffer_ga3d;
+	ms->bind_front_buffer = drv_bind_front_buffer_ga3d;
+#ifdef HAVE_LIBKMS
+    } else if (ms->kms) {
+	ms->destroy_front_buffer = drv_destroy_front_buffer_kms;
+	ms->create_front_buffer = drv_create_front_buffer_kms;
+	ms->bind_front_buffer = drv_bind_front_buffer_kms;
+#endif
+    } else
+	return FALSE;
+
+    return TRUE;
+}
+
 /* vim: set sw=4 ts=8 sts=4: */
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index bd97baa..d9432ba 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -43,38 +43,104 @@
 #include "pipe/p_state.h"
 #include "pipe/p_inlines.h"
 
+#include "util/u_format.h"
 #include "util/u_rect.h"
+#include "util/u_math.h"
+#include "util/u_debug.h"
 
 #define DEBUG_PRINT 0
-#define DEBUG_SOLID 0
-#define ACCEL_ENABLED TRUE
+#define ROUND_UP_TEXTURES 1
 
 /*
  * Helper functions
  */
+struct render_format_str {
+   int format;
+   const char *name;
+};
+static const struct render_format_str formats_info[] =
+{
+   {PICT_a8r8g8b8, "PICT_a8r8g8b8"},
+   {PICT_x8r8g8b8, "PICT_x8r8g8b8"},
+   {PICT_a8b8g8r8, "PICT_a8b8g8r8"},
+   {PICT_x8b8g8r8, "PICT_x8b8g8r8"},
+#ifdef PICT_TYPE_BGRA
+   {PICT_b8g8r8a8, "PICT_b8g8r8a8"},
+   {PICT_b8g8r8x8, "PICT_b8g8r8x8"},
+   {PICT_a2r10g10b10, "PICT_a2r10g10b10"},
+   {PICT_x2r10g10b10, "PICT_x2r10g10b10"},
+   {PICT_a2b10g10r10, "PICT_a2b10g10r10"},
+   {PICT_x2b10g10r10, "PICT_x2b10g10r10"},
+#endif
+   {PICT_r8g8b8, "PICT_r8g8b8"},
+   {PICT_b8g8r8, "PICT_b8g8r8"},
+   {PICT_r5g6b5, "PICT_r5g6b5"},
+   {PICT_b5g6r5, "PICT_b5g6r5"},
+   {PICT_a1r5g5b5, "PICT_a1r5g5b5"},
+   {PICT_x1r5g5b5, "PICT_x1r5g5b5"},
+   {PICT_a1b5g5r5, "PICT_a1b5g5r5"},
+   {PICT_x1b5g5r5, "PICT_x1b5g5r5"},
+   {PICT_a4r4g4b4, "PICT_a4r4g4b4"},
+   {PICT_x4r4g4b4, "PICT_x4r4g4b4"},
+   {PICT_a4b4g4r4, "PICT_a4b4g4r4"},
+   {PICT_x4b4g4r4, "PICT_x4b4g4r4"},
+   {PICT_a8, "PICT_a8"},
+   {PICT_r3g3b2, "PICT_r3g3b2"},
+   {PICT_b2g3r3, "PICT_b2g3r3"},
+   {PICT_a2r2g2b2, "PICT_a2r2g2b2"},
+   {PICT_a2b2g2r2, "PICT_a2b2g2r2"},
+   {PICT_c8, "PICT_c8"},
+   {PICT_g8, "PICT_g8"},
+   {PICT_x4a4, "PICT_x4a4"},
+   {PICT_x4c4, "PICT_x4c4"},
+   {PICT_x4g4, "PICT_x4g4"},
+   {PICT_a4, "PICT_a4"},
+   {PICT_r1g2b1, "PICT_r1g2b1"},
+   {PICT_b1g2r1, "PICT_b1g2r1"},
+   {PICT_a1r1g1b1, "PICT_a1r1g1b1"},
+   {PICT_a1b1g1r1, "PICT_a1b1g1r1"},
+   {PICT_c4, "PICT_c4"},
+   {PICT_g4, "PICT_g4"},
+   {PICT_a1, "PICT_a1"},
+   {PICT_g1, "PICT_g1"}
+};
+static const char *render_format_name(int format)
+{
+   int i = 0;
+   for (i = 0; i < sizeof(formats_info)/sizeof(formats_info[0]); ++i) {
+      if (formats_info[i].format == format)
+         return formats_info[i].name;
+   }
+   return NULL;
+}
 
 static void
-exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp)
+exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp, int *picture_format)
 {
     switch (depth) {
     case 32:
 	*format = PIPE_FORMAT_A8R8G8B8_UNORM;
+	*picture_format = PICT_a8r8g8b8;
 	assert(*bbp == 32);
 	break;
     case 24:
 	*format = PIPE_FORMAT_X8R8G8B8_UNORM;
+	*picture_format = PICT_x8r8g8b8;
 	assert(*bbp == 32);
 	break;
     case 16:
 	*format = PIPE_FORMAT_R5G6B5_UNORM;
+	*picture_format = PICT_r5g6b5;
 	assert(*bbp == 16);
 	break;
     case 15:
 	*format = PIPE_FORMAT_A1R5G5B5_UNORM;
+	*picture_format = PICT_x1r5g5b5;
 	assert(*bbp == 16);
 	break;
     case 8:
 	*format = PIPE_FORMAT_L8_UNORM;
+	*picture_format = PICT_a8;
 	assert(*bbp == 8);
 	break;
     case 4:
@@ -87,16 +153,6 @@
     }
 }
 
-static void
-xorg_exa_common_done(struct exa_context *exa)
-{
-   exa->copy.src = NULL;
-   exa->copy.dst = NULL;
-   exa->transform.has_src = FALSE;
-   exa->transform.has_mask = FALSE;
-   exa->has_solid_color = FALSE;
-   exa->num_bound_samplers = 0;
-}
 
 /*
  * Static exported EXA functions
@@ -105,15 +161,7 @@
 static void
 ExaWaitMarker(ScreenPtr pScreen, int marker)
 {
-   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-   modesettingPtr ms = modesettingPTR(pScrn);
-   struct exa_context *exa = ms->exa;
-
-#if 0
-   xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL);
-#else
-   xorg_exa_finish(exa);
-#endif
+   /* Nothing to do, handled in the PrepareAccess hook */
 }
 
 static int
@@ -122,6 +170,11 @@
    return 1;
 }
 
+
+/***********************************************************************
+ * Screen upload/download
+ */
+
 static Bool
 ExaDownloadFromScreen(PixmapPtr pPix, int x,  int y, int w,  int h, char *dst,
 		      int dst_pitch)
@@ -150,7 +203,7 @@
                  x, y, w, h, dst_pitch);
 #endif
 
-    util_copy_rect((unsigned char*)dst, &priv->tex->block, dst_pitch, 0, 0,
+    util_copy_rect((unsigned char*)dst, priv->tex->format, dst_pitch, 0, 0,
 		   w, h, exa->scrn->transfer_map(exa->scrn, transfer),
 		   transfer->stride, 0, 0);
 
@@ -174,6 +227,11 @@
     if (!priv || !priv->tex)
 	return FALSE;
 
+    /* make sure that any pending operations are flushed to hardware */
+    if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) &
+	(PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE))
+	xorg_exa_flush(exa, 0, NULL);
+
     transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
 					   PIPE_TRANSFER_WRITE, x, y, w, h);
     if (!transfer)
@@ -185,7 +243,7 @@
 #endif
 
     util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
-		   &priv->tex->block, transfer->stride, 0, 0, w, h,
+		   priv->tex->format, transfer->stride, 0, 0, w, h,
 		   (unsigned char*)src, src_pitch, 0, 0);
 
     exa->scrn->transfer_unmap(exa->scrn, transfer);
@@ -217,13 +275,18 @@
 	    PIPE_REFERENCED_FOR_WRITE)
 	    exa->pipe->flush(exa->pipe, 0, NULL);
 
+        assert(pPix->drawable.width <= priv->tex->width0);
+        assert(pPix->drawable.height <= priv->tex->height0);
+
 	priv->map_transfer =
 	    exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
 #ifdef EXA_MIXED_PIXMAPS
 					PIPE_TRANSFER_MAP_DIRECTLY |
 #endif
 					PIPE_TRANSFER_READ_WRITE,
-					0, 0, priv->tex->width[0], priv->tex->height[0]);
+					0, 0, 
+                                        pPix->drawable.width,
+                                        pPix->drawable.height );
 	if (!priv->map_transfer)
 #ifdef EXA_MIXED_PIXMAPS
 	    return FALSE;
@@ -266,29 +329,9 @@
     }
 }
 
-static void
-ExaDone(PixmapPtr pPixmap)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
-    modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
-    struct exa_context *exa = ms->exa;
-
-    if (!priv)
-	return;
-
-    xorg_exa_common_done(exa);
-}
-
-static void
-ExaDoneComposite(PixmapPtr pPixmap)
-{
-   ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
-   modesettingPtr ms = modesettingPTR(pScrn);
-   struct exa_context *exa = ms->exa;
-
-   xorg_exa_common_done(exa);
-}
+/***********************************************************************
+ * Solid Fills
+ */
 
 static Bool
 ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
@@ -301,6 +344,9 @@
 #if DEBUG_PRINT
     debug_printf("ExaPrepareSolid(0x%x)\n", fg);
 #endif
+    if (!exa->accel)
+	return FALSE;
+
     if (!exa->pipe)
 	XORG_FALLBACK("accle not enabled");
 
@@ -319,11 +365,7 @@
 	XORG_FALLBACK("format %s", pf_name(priv->tex->format));
     }
 
-#if DEBUG_SOLID
-    fg = 0xffff0000;
-#endif
-
-    return ACCEL_ENABLED && xorg_solid_bind_state(exa, priv, fg);
+    return xorg_solid_bind_state(exa, priv, fg);
 }
 
 static void
@@ -338,48 +380,34 @@
     debug_printf("\tExaSolid(%d, %d, %d, %d)\n", x0, y0, x1, y1);
 #endif
 
-#if 0
     if (x0 == 0 && y0 == 0 &&
-        x1 == priv->tex->width[0] &&
-        y1 == priv->tex->height[0]) {
-       exa->ctx->clear(exa->pipe, PIPE_CLEAR_COLOR,
-                       exa->solid_color, 1., 0);
-    } else
-#endif
+        x1 == pPixmap->drawable.width && y1 == pPixmap->drawable.height) {
+       exa->pipe->clear(exa->pipe, PIPE_CLEAR_COLOR, exa->solid_color, 0.0, 0);
+       return;
+    }
 
-#if DEBUG_SOLID
-       exa->solid_color[0] = 0.f;
-       exa->solid_color[1] = 1.f;
-       exa->solid_color[2] = 0.f;
-       exa->solid_color[3] = 1.f;
-    xorg_solid(exa, priv, 0, 0, 1024, 768);
-       exa->solid_color[0] = 1.f;
-       exa->solid_color[1] = 0.f;
-       exa->solid_color[2] = 0.f;
-       exa->solid_color[3] = 1.f;
-       xorg_solid(exa, priv, 0, 0, 300, 300);
-       xorg_solid(exa, priv, 300, 300, 350, 350);
-       xorg_solid(exa, priv, 350, 350, 500, 500);
-
-       xorg_solid(exa, priv,
-               priv->tex->width[0] - 10,
-               priv->tex->height[0] - 10,
-               priv->tex->width[0],
-               priv->tex->height[0]);
-
-    exa->solid_color[0] = 0.f;
-    exa->solid_color[1] = 0.f;
-    exa->solid_color[2] = 1.f;
-    exa->solid_color[3] = 1.f;
-
-    exa->has_solid_color = FALSE;
-    ExaPrepareCopy(pPixmap, pPixmap, 0, 0, GXcopy, 0xffffffff);
-    ExaCopy(pPixmap, 0, 0, 50, 50, 500, 500);
-#else
     xorg_solid(exa, priv, x0, y0, x1, y1) ;
-#endif
 }
 
+
+static void
+ExaDoneSolid(PixmapPtr pPixmap)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+    modesettingPtr ms = modesettingPTR(pScrn);
+    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
+    struct exa_context *exa = ms->exa;
+
+    if (!priv)
+	return;
+   
+    xorg_composite_done(exa);
+}
+
+/***********************************************************************
+ * Copy Blits
+ */
+
 static Bool
 ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
 	       int ydir, int alu, Pixel planeMask)
@@ -393,6 +421,10 @@
 #if DEBUG_PRINT
     debug_printf("ExaPrepareCopy\n");
 #endif
+
+    if (!exa->accel)
+	return FALSE;
+
     if (!exa->pipe)
 	XORG_FALLBACK("accle not enabled");
 
@@ -421,7 +453,52 @@
     exa->copy.src = src_priv;
     exa->copy.dst = priv;
 
-    return ACCEL_ENABLED;
+    /* For same-surface copies, the pipe->surface_copy path is clearly
+     * superior, providing it is implemented.  In other cases it's not
+     * clear what the better path would be, and eventually we'd
+     * probably want to gather timings and choose dynamically.
+     */
+    if (exa->pipe->surface_copy &&
+        exa->copy.src == exa->copy.dst) {
+
+       exa->copy.use_surface_copy = TRUE;
+       
+       exa->copy.src_surface =
+          exa->scrn->get_tex_surface( exa->scrn,
+                                      exa->copy.src->tex,
+                                      0, 0, 0,
+                                      PIPE_BUFFER_USAGE_GPU_READ);
+
+       exa->copy.dst_surface =
+          exa->scrn->get_tex_surface( exa->scrn, 
+                                      exa->copy.dst->tex,
+                                      0, 0, 0, 
+                                      PIPE_BUFFER_USAGE_GPU_WRITE );
+    }
+    else {
+       exa->copy.use_surface_copy = FALSE;
+
+       if (exa->copy.dst == exa->copy.src)
+          exa->copy.src_texture = renderer_clone_texture( exa->renderer,
+                                                          exa->copy.src->tex );
+       else
+          pipe_texture_reference(&exa->copy.src_texture,
+                                 exa->copy.src->tex);
+
+       exa->copy.dst_surface =
+          exa->scrn->get_tex_surface(exa->scrn,
+                                     exa->copy.dst->tex,
+                                     0, 0, 0,
+                                     PIPE_BUFFER_USAGE_GPU_WRITE);
+
+
+       renderer_copy_prepare(exa->renderer, 
+                             exa->copy.dst_surface,
+                             exa->copy.src_texture );
+    }
+
+
+    return TRUE;
 }
 
 static void
@@ -439,12 +516,113 @@
 #endif
 
    debug_assert(priv == exa->copy.dst);
+   (void) priv;
 
-   renderer_copy_pixmap(exa->renderer, exa->copy.dst, dstX, dstY,
-                        exa->copy.src, srcX, srcY,
-                        width, height);
+   if (exa->copy.use_surface_copy) {
+      /* XXX: consider exposing >1 box in surface_copy interface.
+       */
+      exa->pipe->surface_copy( exa->pipe,
+                             exa->copy.dst_surface,
+                             dstX, dstY,
+                             exa->copy.src_surface,
+                             srcX, srcY,
+                             width, height );
+   }
+   else {
+      renderer_copy_pixmap(exa->renderer, 
+                           dstX, dstY,
+                           srcX, srcY,
+                           width, height,
+                           exa->copy.src_texture->width0,
+                           exa->copy.src_texture->height0);
+   }
 }
 
+static void
+ExaDoneCopy(PixmapPtr pPixmap)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+    modesettingPtr ms = modesettingPTR(pScrn);
+    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
+    struct exa_context *exa = ms->exa;
+
+    if (!priv)
+	return;
+
+   renderer_draw_flush(exa->renderer);
+
+   exa->copy.src = NULL;
+   exa->copy.dst = NULL;
+   pipe_surface_reference(&exa->copy.src_surface, NULL);
+   pipe_surface_reference(&exa->copy.dst_surface, NULL);
+   pipe_texture_reference(&exa->copy.src_texture, NULL);
+}
+
+
+
+static Bool
+picture_check_formats(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture)
+{
+   if (pSrc->picture_format == pSrcPicture->format)
+      return TRUE;
+
+   if (pSrc->picture_format != PICT_a8r8g8b8)
+      return FALSE;
+
+   /* pSrc->picture_format == PICT_a8r8g8b8 */
+   switch (pSrcPicture->format) {
+   case PICT_a8r8g8b8:
+   case PICT_x8r8g8b8:
+   case PICT_a8b8g8r8:
+   case PICT_x8b8g8r8:
+   /* just treat these two as x8... */
+   case PICT_r8g8b8:
+   case PICT_b8g8r8:
+      return TRUE;
+#ifdef PICT_TYPE_BGRA
+   case PICT_b8g8r8a8:
+   case PICT_b8g8r8x8:
+      return FALSE; /* does not support swizzleing the alpha channel yet */
+   case PICT_a2r10g10b10:
+   case PICT_x2r10g10b10:
+   case PICT_a2b10g10r10:
+   case PICT_x2b10g10r10:
+      return FALSE;
+#endif
+   default:
+      return FALSE;
+   }
+   return FALSE;
+}
+
+/***********************************************************************
+ * Composite entrypoints
+ */
+
+static Bool
+ExaCheckComposite(int op,
+		  PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+		  PicturePtr pDstPicture)
+{
+   ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum];
+   modesettingPtr ms = modesettingPTR(pScrn);
+   struct exa_context *exa = ms->exa;
+
+#if DEBUG_PRINT
+   debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n",
+                op, pSrcPicture, pMaskPicture, pDstPicture, accelerated);
+#endif
+
+   if (!exa->accel)
+       return FALSE;
+
+   return xorg_composite_accelerated(op,
+				     pSrcPicture,
+				     pMaskPicture,
+				     pDstPicture);
+}
+
+
 static Bool
 ExaPrepareComposite(int op, PicturePtr pSrcPicture,
 		    PicturePtr pMaskPicture, PicturePtr pDstPicture,
@@ -455,9 +633,16 @@
    struct exa_context *exa = ms->exa;
    struct exa_pixmap_priv *priv;
 
+   if (!exa->accel)
+       return FALSE;
+
 #if DEBUG_PRINT
    debug_printf("ExaPrepareComposite(%d, src=0x%p, mask=0x%p, dst=0x%p)\n",
                 op, pSrcPicture, pMaskPicture, pDstPicture);
+   debug_printf("\tFormats: src(%s), mask(%s), dst(%s)\n",
+                pSrcPicture ? render_format_name(pSrcPicture->format) : "none",
+                pMaskPicture ? render_format_name(pMaskPicture->format) : "none",
+                pDstPicture ? render_format_name(pDstPicture->format) : "none");
 #endif
    if (!exa->pipe)
       XORG_FALLBACK("accle not enabled");
@@ -471,6 +656,11 @@
                                        PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
       XORG_FALLBACK("pDst format: %s", pf_name(priv->tex->format));
 
+   if (priv->picture_format != pDstPicture->format)
+      XORG_FALLBACK("pDst pic_format: %s != %s",
+                    render_format_name(priv->picture_format),
+                    render_format_name(pDstPicture->format));
+
    if (pSrc) {
       priv = exaGetPixmapDriverPrivate(pSrc);
       if (!priv || !priv->tex)
@@ -480,6 +670,12 @@
                                           priv->tex->target,
                                           PIPE_TEXTURE_USAGE_SAMPLER, 0))
          XORG_FALLBACK("pSrc format: %s", pf_name(priv->tex->format));
+
+      if (!picture_check_formats(priv, pSrcPicture))
+         XORG_FALLBACK("pSrc pic_format: %s != %s",
+                       render_format_name(priv->picture_format),
+                       render_format_name(pSrcPicture->format));
+
    }
 
    if (pMask) {
@@ -491,10 +687,14 @@
                                           priv->tex->target,
                                           PIPE_TEXTURE_USAGE_SAMPLER, 0))
          XORG_FALLBACK("pMask format: %s", pf_name(priv->tex->format));
+
+      if (!picture_check_formats(priv, pMaskPicture))
+         XORG_FALLBACK("pMask pic_format: %s != %s",
+                       render_format_name(priv->picture_format),
+                       render_format_name(pMaskPicture->format));
    }
 
-   return ACCEL_ENABLED &&
-          xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture,
+   return xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture,
                                     pDstPicture,
                                     pSrc ? exaGetPixmapDriverPrivate(pSrc) : NULL,
                                     pMask ? exaGetPixmapDriverPrivate(pMask) : NULL,
@@ -521,22 +721,23 @@
                   dstX, dstY, width, height);
 }
 
-static Bool
-ExaCheckComposite(int op,
-		  PicturePtr pSrcPicture, PicturePtr pMaskPicture,
-		  PicturePtr pDstPicture)
+
+
+static void
+ExaDoneComposite(PixmapPtr pPixmap)
 {
-   boolean accelerated = xorg_composite_accelerated(op,
-                                                    pSrcPicture,
-                                                    pMaskPicture,
-                                                    pDstPicture);
-#if DEBUG_PRINT
-   debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n",
-                op, pSrcPicture, pMaskPicture, pDstPicture, accelerated);
-#endif
-   return ACCEL_ENABLED && accelerated;
+   ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+   modesettingPtr ms = modesettingPTR(pScrn);
+   struct exa_context *exa = ms->exa;
+
+   xorg_composite_done(exa);
 }
 
+
+/***********************************************************************
+ * Pixmaps
+ */
+
 static void *
 ExaCreatePixmap(ScreenPtr pScreen, int size, int align)
 {
@@ -610,33 +811,22 @@
     return 0;
 }
 
-unsigned
-xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
+
+
+static Bool
+size_match( int width, int tex_width )
 {
-    ScreenPtr pScreen = pPixmap->drawable.pScreen;
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    modesettingPtr ms = modesettingPTR(pScrn);
-    struct exa_pixmap_priv *priv;
-    unsigned handle;
-    unsigned stride;
+#if ROUND_UP_TEXTURES
+   if (width > tex_width)
+      return FALSE;
 
-    if (!ms->exa) {
-	FatalError("NO MS->EXA\n");
-	return 0;
-    }
+   if (width * 2 < tex_width)
+      return FALSE;
 
-    priv = exaGetPixmapDriverPrivate(pPixmap);
-
-    if (!priv) {
-	FatalError("NO PIXMAP PRIVATE\n");
-	return 0;
-    }
-
-    ms->api->local_handle_from_texture(ms->api, ms->screen, priv->tex, &stride, &handle);
-    if (stride_out)
-	*stride_out = stride;
-
-    return handle;
+   return TRUE;
+#else
+   return width == tex_width;
+#endif
 }
 
 static Bool
@@ -653,6 +843,17 @@
     if (!priv || pPixData)
 	return FALSE;
 
+    if (0) {
+       debug_printf("%s pixmap %p sz %dx%dx%d devKind %d\n",
+                    __FUNCTION__, pPixmap, width, height, bitsPerPixel, devKind);
+       
+       if (priv->tex)
+          debug_printf("  ==> old texture %dx%d\n",
+                       priv->tex->width0, 
+                       priv->tex->height0);
+    }
+
+
     if (depth <= 0)
 	depth = pPixmap->drawable.depth;
 
@@ -671,21 +872,31 @@
     miModifyPixmapHeader(pPixmap, width, height, depth,
 			     bitsPerPixel, devKind, NULL);
 
+    priv->width = width;
+    priv->height = height;
+
     /* Deal with screen resize */
-    if (!priv->tex ||
-        (priv->tex->width[0] != width ||
-         priv->tex->height[0] != height ||
+    if ((exa->accel || priv->flags) &&
+        (!priv->tex ||
+         !size_match(width, priv->tex->width0) ||
+         !size_match(height, priv->tex->height0) ||
          priv->tex_flags != priv->flags)) {
 	struct pipe_texture *texture = NULL;
 	struct pipe_texture template;
 
 	memset(&template, 0, sizeof(template));
 	template.target = PIPE_TEXTURE_2D;
-	exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
-	pf_get_block(template.format, &template.block);
-	template.width[0] = width;
-	template.height[0] = height;
-	template.depth[0] = 1;
+	exa_get_pipe_format(depth, &template.format, &bitsPerPixel, &priv->picture_format);
+        if (ROUND_UP_TEXTURES && priv->flags == 0) {
+           template.width0 = util_next_power_of_two(width);
+           template.height0 = util_next_power_of_two(height);
+        }
+        else {
+           template.width0 = width;
+           template.height0 = height;
+        }
+
+	template.depth0 = 1;
 	template.last_level = 0;
 	template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags;
 	priv->tex_flags = priv->flags;
@@ -698,15 +909,15 @@
 	    dst_surf = exa->scrn->get_tex_surface(
 		exa->scrn, texture, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);
 	    src_surf = xorg_gpu_surface(exa->pipe->screen, priv);
-        if (exa->pipe->surface_copy) {
-            exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf,
-                        0, 0, min(width, texture->width[0]),
-                        min(height, texture->height[0]));
-        } else {
-            util_surface_copy(exa->pipe, FALSE, dst_surf, 0, 0, src_surf,
-                        0, 0, min(width, texture->width[0]),
-                        min(height, texture->height[0]));
-        }
+            if (exa->pipe->surface_copy) {
+               exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf,
+                                       0, 0, min(width, texture->width0),
+                                       min(height, texture->height0));
+            } else {
+               util_surface_copy(exa->pipe, FALSE, dst_surf, 0, 0, src_surf,
+                                 0, 0, min(width, texture->width0),
+                                 min(height, texture->height0));
+            }
 	    exa->scrn->tex_surface_destroy(dst_surf);
 	    exa->scrn->tex_surface_destroy(src_surf);
 	}
@@ -738,8 +949,8 @@
     if (!priv)
 	return FALSE;
 
-    if (pPixmap->drawable.width != tex->width[0] ||
-	pPixmap->drawable.height != tex->height[0])
+    if (pPixmap->drawable.width != tex->width0 ||
+	pPixmap->drawable.height != tex->height0)
 	return FALSE;
 
     pipe_texture_reference(&priv->tex, tex);
@@ -756,14 +967,14 @@
     modesettingPtr ms = modesettingPTR(pScrn);
     struct exa_context *exa = ms->exa;
     struct pipe_texture template;
+    int dummy;
 
     memset(&template, 0, sizeof(template));
     template.target = PIPE_TEXTURE_2D;
-    exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
-    pf_get_block(template.format, &template.block);
-    template.width[0] = width;
-    template.height[0] = height;
-    template.depth[0] = 1;
+    exa_get_pipe_format(depth, &template.format, &bitsPerPixel, &dummy);
+    template.width0 = width;
+    template.height0 = height;
+    template.depth0 = 1;
     template.last_level = 0;
     template.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
     template.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
@@ -782,6 +993,9 @@
 
    if (exa->pipe)
       exa->pipe->destroy(exa->pipe);
+   exa->pipe = NULL;
+   /* Since this was shared be proper with the pointer */
+   ms->ctx = NULL;
 
    exaDriverFini(pScrn->pScreen);
    xfree(exa);
@@ -789,7 +1003,7 @@
 }
 
 void *
-xorg_exa_init(ScrnInfoPtr pScrn)
+xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
 {
    modesettingPtr ms = modesettingPTR(pScrn);
    struct exa_context *exa;
@@ -827,10 +1041,10 @@
    pExa->MarkSync           = ExaMarkSync;
    pExa->PrepareSolid       = ExaPrepareSolid;
    pExa->Solid              = ExaSolid;
-   pExa->DoneSolid          = ExaDone;
+   pExa->DoneSolid          = ExaDoneSolid;
    pExa->PrepareCopy        = ExaPrepareCopy;
    pExa->Copy               = ExaCopy;
-   pExa->DoneCopy           = ExaDone;
+   pExa->DoneCopy           = ExaDoneCopy;
    pExa->CheckComposite     = ExaCheckComposite;
    pExa->PrepareComposite   = ExaPrepareComposite;
    pExa->Composite          = ExaComposite;
@@ -854,6 +1068,7 @@
    ms->ctx = exa->pipe;
 
    exa->renderer = renderer_create(exa->pipe);
+   exa->accel = accel;
 
    return (void *)exa;
 
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h
index 45f88d9..f2cefe2 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.h
+++ b/src/gallium/state_trackers/xorg/xorg_exa.h
@@ -24,6 +24,8 @@
    float solid_color[4];
    boolean has_solid_color;
 
+   boolean accel;
+
    /* float[9] projective matrix bound to pictures */
    struct {
       float    src[9];
@@ -33,16 +35,27 @@
    } transform;
 
    struct {
+      boolean use_surface_copy;
+
       struct exa_pixmap_priv *src;
       struct exa_pixmap_priv *dst;
+
+      struct pipe_surface *src_surface;
+      struct pipe_surface *dst_surface;
+
+      struct pipe_texture *src_texture;
    } copy;
 };
 
 struct exa_pixmap_priv
 {
+   int width, height;
+
    int flags;
    int tex_flags;
 
+   int picture_format;
+
    struct pipe_texture *tex;
    struct pipe_texture *depth_stencil_tex;
 
diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
index 83cc12f..bed17ca 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
@@ -43,6 +43,38 @@
  * OUT[0] = color
  */
 
+static void
+print_fs_traits(int fs_traits)
+{
+   const char *strings[] = {
+      "FS_COMPOSITE",       /* = 1 << 0, */
+      "FS_MASK",            /* = 1 << 1, */
+      "FS_SOLID_FILL",      /* = 1 << 2, */
+      "FS_LINGRAD_FILL",    /* = 1 << 3, */
+      "FS_RADGRAD_FILL",    /* = 1 << 4, */
+      "FS_CA_FULL",         /* = 1 << 5, */ /* src.rgba * mask.rgba */
+      "FS_CA_SRCALPHA",     /* = 1 << 6, */ /* src.aaaa * mask.rgba */
+      "FS_YUV",             /* = 1 << 7, */
+      "FS_SRC_REPEAT_NONE", /* = 1 << 8, */
+      "FS_MASK_REPEAT_NONE",/* = 1 << 9, */
+      "FS_SRC_SWIZZLE_RGB", /* = 1 << 10, */
+      "FS_MASK_SWIZZLE_RGB",/* = 1 << 11, */
+      "FS_SRC_SET_ALPHA",   /* = 1 << 12, */
+      "FS_MASK_SET_ALPHA",  /* = 1 << 13, */
+      "FS_SRC_LUMINANCE",   /* = 1 << 14, */
+      "FS_MASK_LUMINANCE",  /* = 1 << 15, */
+   };
+   int i, k;
+   debug_printf("%s: ", __func__);
+
+   for (i = 0, k = 1; k < (1 << 16); i++, k <<= 1) {
+      if (fs_traits & k)
+         debug_printf("%s, ", strings[i]);
+   }
+
+   debug_printf("\n");
+}
+
 struct xorg_shaders {
    struct xorg_renderer *r;
 
@@ -55,7 +87,8 @@
             struct ureg_dst dst,
             struct ureg_src src,
             struct ureg_src mask,
-            int component_alpha)
+            unsigned component_alpha,
+            unsigned mask_luminance)
 {
    if (component_alpha == FS_CA_FULL) {
       ureg_MUL(ureg, dst, src, mask);
@@ -64,8 +97,12 @@
                ureg_scalar(src, TGSI_SWIZZLE_W), mask);
    }
    else {
-      ureg_MUL(ureg, dst, src,
-               ureg_scalar(mask, TGSI_SWIZZLE_X));
+      if (mask_luminance)
+         ureg_MUL(ureg, dst, src,
+                  ureg_scalar(mask, TGSI_SWIZZLE_X));
+      else
+         ureg_MUL(ureg, dst, src,
+                  ureg_scalar(mask, TGSI_SWIZZLE_W));
    }
 }
 
@@ -233,10 +270,10 @@
    struct ureg_src src;
    struct ureg_dst dst;
    struct ureg_src const0, const1;
-   boolean is_fill = vs_traits & VS_FILL;
-   boolean is_composite = vs_traits & VS_COMPOSITE;
-   boolean has_mask = vs_traits & VS_MASK;
-   boolean is_yuv = vs_traits & VS_YUV;
+   boolean is_fill = (vs_traits & VS_FILL) != 0;
+   boolean is_composite = (vs_traits & VS_COMPOSITE) != 0;
+   boolean has_mask = (vs_traits & VS_MASK) != 0;
+   boolean is_yuv = (vs_traits & VS_YUV) != 0;
    unsigned input_slot = 0;
 
    ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
@@ -353,6 +390,69 @@
    return ureg_create_shader_and_destroy(ureg, pipe);
 }
 
+
+static INLINE void
+xrender_tex(struct ureg_program *ureg,
+            struct ureg_dst dst,
+            struct ureg_src coords,
+            struct ureg_src sampler,
+            struct ureg_src imm0,
+            boolean repeat_none,
+            boolean swizzle,
+            boolean set_alpha)
+{
+   if (repeat_none) {
+      struct ureg_dst tmp0 = ureg_DECL_temporary(ureg);
+      struct ureg_dst tmp1 = ureg_DECL_temporary(ureg);
+      ureg_SGT(ureg, tmp1, ureg_swizzle(coords,
+                                        TGSI_SWIZZLE_X,
+                                        TGSI_SWIZZLE_Y,
+                                        TGSI_SWIZZLE_X,
+                                        TGSI_SWIZZLE_Y),
+               ureg_scalar(imm0, TGSI_SWIZZLE_X));
+      ureg_SLT(ureg, tmp0, ureg_swizzle(coords,
+                                        TGSI_SWIZZLE_X,
+                                        TGSI_SWIZZLE_Y,
+                                        TGSI_SWIZZLE_X,
+                                        TGSI_SWIZZLE_Y),
+               ureg_scalar(imm0, TGSI_SWIZZLE_W));
+      ureg_MIN(ureg, tmp0, ureg_src(tmp0), ureg_src(tmp1));
+      ureg_MIN(ureg, tmp0, ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_X),
+               ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_Y));
+      ureg_TEX(ureg, tmp1, TGSI_TEXTURE_2D, coords, sampler);
+      if (swizzle)
+         ureg_MOV(ureg, tmp1, ureg_swizzle(ureg_src(tmp1),
+                                           TGSI_SWIZZLE_Z,
+                                           TGSI_SWIZZLE_Y,
+                                           TGSI_SWIZZLE_X,
+                                           TGSI_SWIZZLE_W));
+      if (set_alpha)
+         ureg_MOV(ureg,
+                  ureg_writemask(tmp1, TGSI_WRITEMASK_W),
+                  ureg_scalar(imm0, TGSI_SWIZZLE_W));
+      ureg_MUL(ureg, dst, ureg_src(tmp1), ureg_src(tmp0));
+      ureg_release_temporary(ureg, tmp0);
+      ureg_release_temporary(ureg, tmp1);
+   } else {
+      if (swizzle) {
+         struct ureg_dst tmp = ureg_DECL_temporary(ureg);
+         ureg_TEX(ureg, tmp, TGSI_TEXTURE_2D, coords, sampler);
+         ureg_MOV(ureg, dst, ureg_swizzle(ureg_src(tmp),
+                                          TGSI_SWIZZLE_Z,
+                                          TGSI_SWIZZLE_Y,
+                                          TGSI_SWIZZLE_X,
+                                          TGSI_SWIZZLE_W));
+         ureg_release_temporary(ureg, tmp);
+      } else {
+         ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler);
+      }
+      if (set_alpha)
+         ureg_MOV(ureg,
+                  ureg_writemask(dst, TGSI_WRITEMASK_W),
+                  ureg_scalar(imm0, TGSI_SWIZZLE_W));
+   }
+}
+
 static void *
 create_fs(struct pipe_context *pipe,
           unsigned fs_traits)
@@ -362,14 +462,29 @@
    struct ureg_src /*dst_pos,*/ src_input, mask_pos;
    struct ureg_dst src, mask;
    struct ureg_dst out;
-   boolean has_mask = fs_traits & FS_MASK;
-   boolean is_fill = fs_traits & FS_FILL;
-   boolean is_composite = fs_traits & FS_COMPOSITE;
-   boolean is_solid   = fs_traits & FS_SOLID_FILL;
-   boolean is_lingrad = fs_traits & FS_LINGRAD_FILL;
-   boolean is_radgrad = fs_traits & FS_RADGRAD_FILL;
-   unsigned comp_alpha = fs_traits & FS_COMPONENT_ALPHA;
-   boolean is_yuv = fs_traits & FS_YUV;
+   struct ureg_src imm0 = { 0 };
+   unsigned has_mask = (fs_traits & FS_MASK) != 0;
+   unsigned is_fill = (fs_traits & FS_FILL) != 0;
+   unsigned is_composite = (fs_traits & FS_COMPOSITE) != 0;
+   unsigned is_solid   = (fs_traits & FS_SOLID_FILL) != 0;
+   unsigned is_lingrad = (fs_traits & FS_LINGRAD_FILL) != 0;
+   unsigned is_radgrad = (fs_traits & FS_RADGRAD_FILL) != 0;
+   unsigned comp_alpha_mask = fs_traits & FS_COMPONENT_ALPHA;
+   unsigned is_yuv = (fs_traits & FS_YUV) != 0;
+   unsigned src_repeat_none = (fs_traits & FS_SRC_REPEAT_NONE) != 0;
+   unsigned mask_repeat_none = (fs_traits & FS_MASK_REPEAT_NONE) != 0;
+   unsigned src_swizzle = (fs_traits & FS_SRC_SWIZZLE_RGB) != 0;
+   unsigned mask_swizzle = (fs_traits & FS_MASK_SWIZZLE_RGB) != 0;
+   unsigned src_set_alpha = (fs_traits & FS_SRC_SET_ALPHA) != 0;
+   unsigned mask_set_alpha = (fs_traits & FS_MASK_SET_ALPHA) != 0;
+   unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0;
+   unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0;
+
+#if 0
+   print_fs_traits(fs_traits);
+#else
+   (void)print_fs_traits;
+#endif
 
    ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
    if (ureg == NULL)
@@ -377,11 +492,17 @@
 
    /* it has to be either a fill, a composite op or a yuv conversion */
    debug_assert((is_fill ^ is_composite) ^ is_yuv);
+   (void) is_yuv;
 
    out = ureg_DECL_output(ureg,
                           TGSI_SEMANTIC_COLOR,
                           0);
 
+   if (src_repeat_none || mask_repeat_none ||
+       src_set_alpha || mask_set_alpha ||
+       src_luminance) {
+      imm0 = ureg_imm4f(ureg, 0, 0, 0, 1);
+   }
    if (is_composite) {
       src_sampler = ureg_DECL_sampler(ureg, 0);
       src_input = ureg_DECL_fs_input(ureg,
@@ -420,16 +541,17 @@
                                 TGSI_INTERPOLATE_PERSPECTIVE);
 #endif
 
+
    if (is_composite) {
-      if (has_mask)
+      if (has_mask || src_luminance)
          src = ureg_DECL_temporary(ureg);
       else
          src = out;
-      ureg_TEX(ureg, src,
-               TGSI_TEXTURE_2D, src_input, src_sampler);
+      xrender_tex(ureg, src, src_input, src_sampler, imm0,
+                  src_repeat_none, src_swizzle, src_set_alpha);
    } else if (is_fill) {
       if (is_solid) {
-         if (has_mask)
+         if (has_mask || src_luminance)
             src = ureg_dst(src_input);
          else
             ureg_MOV(ureg, out, src_input);
@@ -437,7 +559,7 @@
          struct ureg_src coords, const0124,
             matrow0, matrow1, matrow2;
 
-         if (has_mask)
+         if (has_mask || src_luminance)
             src = ureg_DECL_temporary(ureg);
          else
             src = out;
@@ -462,13 +584,22 @@
       } else
          debug_assert(!"Unknown fill type!");
    }
+   if (src_luminance) {
+      ureg_MOV(ureg, src,
+               ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X));
+      ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ),
+               ureg_scalar(imm0, TGSI_SWIZZLE_X));
+      if (!has_mask)
+         ureg_MOV(ureg, out, ureg_src(src));
+   }
 
    if (has_mask) {
       mask = ureg_DECL_temporary(ureg);
-      ureg_TEX(ureg, mask,
-               TGSI_TEXTURE_2D, mask_pos, mask_sampler);
+      xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0,
+                  mask_repeat_none, mask_swizzle, mask_set_alpha);
       /* src IN mask */
-      src_in_mask(ureg, out, ureg_src(src), ureg_src(mask), comp_alpha);
+      src_in_mask(ureg, out, ureg_src(src), ureg_src(mask),
+                  comp_alpha_mask, mask_luminance);
       ureg_release_temporary(ureg, mask);
    }
 
diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h
index d3bfa30..6f2a361 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h
+++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h
@@ -25,7 +25,15 @@
    FS_RADGRAD_FILL     = 1 << 4,
    FS_CA_FULL          = 1 << 5, /* src.rgba * mask.rgba */
    FS_CA_SRCALPHA      = 1 << 6, /* src.aaaa * mask.rgba */
-   FS_YUV              = 1<<  7,
+   FS_YUV              = 1 << 7,
+   FS_SRC_REPEAT_NONE  = 1 << 8,
+   FS_MASK_REPEAT_NONE = 1 << 9,
+   FS_SRC_SWIZZLE_RGB  = 1 << 10,
+   FS_MASK_SWIZZLE_RGB = 1 << 11,
+   FS_SRC_SET_ALPHA    = 1 << 12,
+   FS_MASK_SET_ALPHA   = 1 << 13,
+   FS_SRC_LUMINANCE    = 1 << 14,
+   FS_MASK_LUMINANCE   = 1 << 15,
 
    FS_FILL             = (FS_SOLID_FILL |
                           FS_LINGRAD_FILL |
diff --git a/src/gallium/state_trackers/xorg/xorg_output.c b/src/gallium/state_trackers/xorg/xorg_output.c
index bfeddc5..251f331 100644
--- a/src/gallium/state_trackers/xorg/xorg_output.c
+++ b/src/gallium/state_trackers/xorg/xorg_output.c
@@ -53,7 +53,7 @@
 
 #include "xorg_tracker.h"
 
-static char *connector_enum_list[] = {
+static char *output_enum_list[] = {
     "Unknown",
     "VGA",
     "DVI",
@@ -70,19 +70,19 @@
 };
 
 static void
-create_resources(xf86OutputPtr output)
+output_create_resources(xf86OutputPtr output)
 {
 #ifdef RANDR_12_INTERFACE
 #endif /* RANDR_12_INTERFACE */
 }
 
 static void
-dpms(xf86OutputPtr output, int mode)
+output_dpms(xf86OutputPtr output, int mode)
 {
 }
 
 static xf86OutputStatus
-detect(xf86OutputPtr output)
+output_detect(xf86OutputPtr output)
 {
     drmModeConnectorPtr drm_connector = output->driver_private;
 
@@ -97,7 +97,7 @@
 }
 
 static DisplayModePtr
-get_modes(xf86OutputPtr output)
+output_get_modes(xf86OutputPtr output)
 {
     drmModeConnectorPtr drm_connector = output->driver_private;
     drmModeModeInfoPtr drm_mode = NULL;
@@ -110,7 +110,6 @@
 	    mode = xcalloc(1, sizeof(DisplayModeRec));
 	    if (!mode)
 		continue;
-	    mode->type = 0;
 	    mode->Clock = drm_mode->clock;
 	    mode->HDisplay = drm_mode->hdisplay;
 	    mode->HSyncStart = drm_mode->hsync_start;
@@ -125,6 +124,11 @@
 	    mode->VScan = drm_mode->vscan;
 	    mode->VRefresh = xf86ModeVRefresh(mode);
 	    mode->Private = (void *)drm_mode;
+	    mode->type = 0;
+	    if (drm_mode->type & DRM_MODE_TYPE_PREFERRED)
+		mode->type |= M_T_PREFERRED;
+	    if (drm_mode->type & DRM_MODE_TYPE_DRIVER)
+		mode->type |= M_T_DRIVER;
 	    xf86SetModeDefaultName(mode);
 	    modes = xf86ModesAdd(modes, mode);
 	    xf86PrintModeline(0, mode);
@@ -135,14 +139,14 @@
 }
 
 static int
-mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
+output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
 {
     return MODE_OK;
 }
 
 #ifdef RANDR_12_INTERFACE
 static Bool
-set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value)
+output_set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value)
 {
     return TRUE;
 }
@@ -150,36 +154,36 @@
 
 #ifdef RANDR_13_INTERFACE
 static Bool
-get_property(xf86OutputPtr output, Atom property)
+output_get_property(xf86OutputPtr output, Atom property)
 {
     return TRUE;
 }
 #endif /* RANDR_13_INTERFACE */
 
 static void
-destroy(xf86OutputPtr output)
+output_destroy(xf86OutputPtr output)
 {
     drmModeFreeConnector(output->driver_private);
 }
 
 static const xf86OutputFuncsRec output_funcs = {
-    .create_resources = create_resources,
+    .create_resources = output_create_resources,
 #ifdef RANDR_12_INTERFACE
-    .set_property = set_property,
+    .set_property = output_set_property,
 #endif
 #ifdef RANDR_13_INTERFACE
-    .get_property = get_property,
+    .get_property = output_get_property,
 #endif
-    .dpms = dpms,
-    .detect = detect,
+    .dpms = output_dpms,
+    .detect = output_detect,
 
-    .get_modes = get_modes,
-    .mode_valid = mode_valid,
-    .destroy = destroy,
+    .get_modes = output_get_modes,
+    .mode_valid = output_mode_valid,
+    .destroy = output_destroy,
 };
 
 void
-output_init(ScrnInfoPtr pScrn)
+xorg_output_init(ScrnInfoPtr pScrn)
 {
     modesettingPtr ms = modesettingPTR(pScrn);
     xf86OutputPtr output;
@@ -220,7 +224,7 @@
 #endif
 
 	snprintf(name, 32, "%s%d",
-		 connector_enum_list[drm_connector->connector_type],
+		 output_enum_list[drm_connector->connector_type],
 		 drm_connector->connector_type_id);
 
 
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index ac2c493..d80f341 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -5,6 +5,7 @@
 
 #include "cso_cache/cso_context.h"
 #include "util/u_draw_quad.h"
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "util/u_rect.h"
@@ -13,14 +14,11 @@
 
 #include <math.h>
 
-enum AxisOrientation {
-   Y0_BOTTOM,
-   Y0_TOP
-};
-
 #define floatsEqual(x, y) (fabs(x - y) <= 0.00001f * MIN2(fabs(x), fabs(y)))
 #define floatIsZero(x) (floatsEqual((x) + 1, 1))
 
+#define NUM_COMPONENTS 4
+
 static INLINE boolean is_affine(float *matrix)
 {
    return floatIsZero(matrix[2]) && floatIsZero(matrix[5])
@@ -44,131 +42,187 @@
    }
 }
 
+static INLINE struct pipe_buffer *
+renderer_buffer_create(struct xorg_renderer *r)
+{
+   struct pipe_buffer *buf =
+      pipe_user_buffer_create(r->pipe->screen,
+                              r->buffer,
+                              sizeof(float)*
+                              r->buffer_size);
+   r->buffer_size = 0;
+
+   return buf;
+}
+
+static INLINE void
+renderer_draw(struct xorg_renderer *r)
+{
+   struct pipe_context *pipe = r->pipe;
+   struct pipe_buffer *buf = 0;
+   int num_verts = r->buffer_size/(r->attrs_per_vertex * NUM_COMPONENTS);
+
+   if (!r->buffer_size)
+      return;
+
+   buf = renderer_buffer_create(r);
+
+
+   if (buf) {
+      util_draw_vertex_buffer(pipe, buf, 0,
+                              PIPE_PRIM_QUADS,
+                              num_verts,  /* verts */
+                              r->attrs_per_vertex); /* attribs/vert */
+
+      pipe_buffer_reference(&buf, NULL);
+   }
+}
+
+static INLINE void
+renderer_draw_conditional(struct xorg_renderer *r,
+                          int next_batch)
+{
+   if (r->buffer_size + next_batch >= BUF_SIZE ||
+       (next_batch == 0 && r->buffer_size)) {
+      renderer_draw(r);
+   }
+}
+
 static void
 renderer_init_state(struct xorg_renderer *r)
 {
    struct pipe_depth_stencil_alpha_state dsa;
+   struct pipe_rasterizer_state raster;
 
    /* set common initial clip state */
    memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
    cso_set_depth_stencil_alpha(r->cso, &dsa);
+
+
+   /* XXX: move to renderer_init_state? */
+   memset(&raster, 0, sizeof(struct pipe_rasterizer_state));
+   raster.gl_rasterization_rules = 1;
+   cso_set_rasterizer(r->cso, &raster);
+
 }
 
 
 static INLINE void
-setup_vertex0(float vertex[2][4], float x, float y,
-              float color[4])
+add_vertex_color(struct xorg_renderer *r,
+                 float x, float y,
+                 float color[4])
 {
-   vertex[0][0] = x;
-   vertex[0][1] = y;
-   vertex[0][2] = 0.f; /*z*/
-   vertex[0][3] = 1.f; /*w*/
+   float *vertex = r->buffer + r->buffer_size;
 
-   vertex[1][0] = color[0]; /*r*/
-   vertex[1][1] = color[1]; /*g*/
-   vertex[1][2] = color[2]; /*b*/
-   vertex[1][3] = color[3]; /*a*/
+   vertex[0] = x;
+   vertex[1] = y;
+   vertex[2] = 0.f; /*z*/
+   vertex[3] = 1.f; /*w*/
+
+   vertex[4] = color[0]; /*r*/
+   vertex[5] = color[1]; /*g*/
+   vertex[6] = color[2]; /*b*/
+   vertex[7] = color[3]; /*a*/
+
+   r->buffer_size += 8;
 }
 
 static INLINE void
-setup_vertex1(float vertex[2][4], float x, float y, float s, float t)
+add_vertex_1tex(struct xorg_renderer *r,
+                float x, float y, float s, float t)
 {
-   vertex[0][0] = x;
-   vertex[0][1] = y;
-   vertex[0][2] = 0.f; /*z*/
-   vertex[0][3] = 1.f; /*w*/
+   float *vertex = r->buffer + r->buffer_size;
 
-   vertex[1][0] = s;   /*s*/
-   vertex[1][1] = t;   /*t*/
-   vertex[1][2] = 0.f; /*r*/
-   vertex[1][3] = 1.f; /*q*/
+   vertex[0] = x;
+   vertex[1] = y;
+   vertex[2] = 0.f; /*z*/
+   vertex[3] = 1.f; /*w*/
+
+   vertex[4] = s;   /*s*/
+   vertex[5] = t;   /*t*/
+   vertex[6] = 0.f; /*r*/
+   vertex[7] = 1.f; /*q*/
+
+   r->buffer_size += 8;
 }
 
-static struct pipe_buffer *
-setup_vertex_data1(struct xorg_renderer *r,
-                   float srcX, float srcY,  float dstX, float dstY,
-                   float width, float height,
-                   struct pipe_texture *src, float *src_matrix)
+static void
+add_vertex_data1(struct xorg_renderer *r,
+                 float srcX, float srcY,  float dstX, float dstY,
+                 float width, float height,
+                 struct pipe_texture *src, float *src_matrix)
 {
-   float s0, t0, s1, t1;
-   float pt0[2], pt1[2];
+   float s0, t0, s1, t1, s2, t2, s3, t3;
+   float pt0[2], pt1[2], pt2[2], pt3[2];
 
    pt0[0] = srcX;
    pt0[1] = srcY;
    pt1[0] = (srcX + width);
-   pt1[1] = (srcY + height);
+   pt1[1] = srcY;
+   pt2[0] = (srcX + width);
+   pt2[1] = (srcY + height);
+   pt3[0] = srcX;
+   pt3[1] = (srcY + height);
 
    if (src_matrix) {
       map_point(src_matrix, pt0[0], pt0[1], &pt0[0], &pt0[1]);
       map_point(src_matrix, pt1[0], pt1[1], &pt1[0], &pt1[1]);
+      map_point(src_matrix, pt2[0], pt2[1], &pt2[0], &pt2[1]);
+      map_point(src_matrix, pt3[0], pt3[1], &pt3[0], &pt3[1]);
    }
 
-   s0 =  pt0[0] / src->width[0];
-   s1 =  pt1[0] / src->width[0];
-   t0 =  pt0[1] / src->height[0];
-   t1 =  pt1[1] / src->height[0];
+   s0 =  pt0[0] / src->width0;
+   s1 =  pt1[0] / src->width0;
+   s2 =  pt2[0] / src->width0;
+   s3 =  pt3[0] / src->width0;
+   t0 =  pt0[1] / src->height0;
+   t1 =  pt1[1] / src->height0;
+   t2 =  pt2[1] / src->height0;
+   t3 =  pt3[1] / src->height0;
 
    /* 1st vertex */
-   setup_vertex1(r->vertices2[0], dstX, dstY, s0, t0);
+   add_vertex_1tex(r, dstX, dstY, s0, t0);
    /* 2nd vertex */
-   setup_vertex1(r->vertices2[1], dstX + width, dstY, s1, t0);
+   add_vertex_1tex(r, dstX + width, dstY, s1, t1);
    /* 3rd vertex */
-   setup_vertex1(r->vertices2[2], dstX + width, dstY + height, s1, t1);
+   add_vertex_1tex(r, dstX + width, dstY + height, s2, t2);
    /* 4th vertex */
-   setup_vertex1(r->vertices2[3], dstX, dstY + height, s0, t1);
-
-   return pipe_user_buffer_create(r->pipe->screen,
-                                  r->vertices2,
-                                  sizeof(r->vertices2));
+   add_vertex_1tex(r, dstX, dstY + height, s3, t3);
 }
 
-static struct pipe_buffer *
-setup_vertex_data_tex(struct xorg_renderer *r,
-                      float x0, float y0, float x1, float y1,
-                      float s0, float t0, float s1, float t1,
-                      float z)
-{
-   /* 1st vertex */
-   setup_vertex1(r->vertices2[0], x0, y0, s0, t0);
-   /* 2nd vertex */
-   setup_vertex1(r->vertices2[1], x1, y0, s1, t0);
-   /* 3rd vertex */
-   setup_vertex1(r->vertices2[2], x1, y1, s1, t1);
-   /* 4th vertex */
-   setup_vertex1(r->vertices2[3], x0, y1, s0, t1);
-
-   return pipe_user_buffer_create(r->pipe->screen,
-                                  r->vertices2,
-                                  sizeof(r->vertices2));
-}
 
 static INLINE void
-setup_vertex2(float vertex[3][4], float x, float y,
-              float s0, float t0, float s1, float t1)
+add_vertex_2tex(struct xorg_renderer *r,
+                float x, float y,
+                float s0, float t0, float s1, float t1)
 {
-   vertex[0][0] = x;
-   vertex[0][1] = y;
-   vertex[0][2] = 0.f; /*z*/
-   vertex[0][3] = 1.f; /*w*/
+   float *vertex = r->buffer + r->buffer_size;
 
-   vertex[1][0] = s0;  /*s*/
-   vertex[1][1] = t0;  /*t*/
-   vertex[1][2] = 0.f; /*r*/
-   vertex[1][3] = 1.f; /*q*/
+   vertex[0] = x;
+   vertex[1] = y;
+   vertex[2] = 0.f; /*z*/
+   vertex[3] = 1.f; /*w*/
 
-   vertex[2][0] = s1;  /*s*/
-   vertex[2][1] = t1;  /*t*/
-   vertex[2][2] = 0.f; /*r*/
-   vertex[2][3] = 1.f; /*q*/
+   vertex[4] = s0;  /*s*/
+   vertex[5] = t0;  /*t*/
+   vertex[6] = 0.f; /*r*/
+   vertex[7] = 1.f; /*q*/
+
+   vertex[8] = s1;  /*s*/
+   vertex[9] = t1;  /*t*/
+   vertex[10] = 0.f; /*r*/
+   vertex[11] = 1.f; /*q*/
+
+   r->buffer_size += 12;
 }
 
-static struct pipe_buffer *
-setup_vertex_data2(struct xorg_renderer *r,
-                   float srcX, float srcY, float maskX, float maskY,
-                   float dstX, float dstY, float width, float height,
-                   struct pipe_texture *src,
-                   struct pipe_texture *mask,
-                   float *src_matrix, float *mask_matrix)
+static void
+add_vertex_data2(struct xorg_renderer *r,
+                 float srcX, float srcY, float maskX, float maskY,
+                 float dstX, float dstY, float width, float height,
+                 struct pipe_texture *src,
+                 struct pipe_texture *mask,
+                 float *src_matrix, float *mask_matrix)
 {
    float src_s0, src_t0, src_s1, src_t1;
    float mask_s0, mask_t0, mask_s1, mask_t1;
@@ -195,33 +249,28 @@
       map_point(mask_matrix, mpt1[0], mpt1[1], &mpt1[0], &mpt1[1]);
    }
 
-   src_s0 = spt0[0] / src->width[0];
-   src_t0 = spt0[1] / src->height[0];
-   src_s1 = spt1[0] / src->width[0];
-   src_t1 = spt1[1] / src->height[0];
+   src_s0 = spt0[0] / src->width0;
+   src_t0 = spt0[1] / src->height0;
+   src_s1 = spt1[0] / src->width0;
+   src_t1 = spt1[1] / src->height0;
 
-   mask_s0 = mpt0[0] / mask->width[0];
-   mask_t0 = mpt0[1] / mask->height[0];
-   mask_s1 = mpt1[0] / mask->width[0];
-   mask_t1 = mpt1[1] / mask->height[0];
+   mask_s0 = mpt0[0] / mask->width0;
+   mask_t0 = mpt0[1] / mask->height0;
+   mask_s1 = mpt1[0] / mask->width0;
+   mask_t1 = mpt1[1] / mask->height0;
 
    /* 1st vertex */
-   setup_vertex2(r->vertices3[0], dstX, dstY,
-                 src_s0, src_t0, mask_s0, mask_t0);
+   add_vertex_2tex(r, dstX, dstY,
+                   src_s0, src_t0, mask_s0, mask_t0);
    /* 2nd vertex */
-   setup_vertex2(r->vertices3[1], dstX + width, dstY,
-                 src_s1, src_t0, mask_s1, mask_t0);
+   add_vertex_2tex(r, dstX + width, dstY,
+                   src_s1, src_t0, mask_s1, mask_t0);
    /* 3rd vertex */
-   setup_vertex2(r->vertices3[2], dstX + width, dstY + height,
-                 src_s1, src_t1, mask_s1, mask_t1);
+   add_vertex_2tex(r, dstX + width, dstY + height,
+                   src_s1, src_t1, mask_s1, mask_t1);
    /* 4th vertex */
-   setup_vertex2(r->vertices3[3], dstX, dstY + height,
-                 src_s0, src_t1, mask_s0, mask_t1);
-
-
-   return pipe_user_buffer_create(r->pipe->screen,
-                                  r->vertices3,
-                                  sizeof(r->vertices3));
+   add_vertex_2tex(r, dstX, dstY + height,
+                   src_s0, src_t1, mask_s0, mask_t1);
 }
 
 static struct pipe_buffer *
@@ -238,40 +287,54 @@
    spt1[0] = srcX + srcW;
    spt1[1] = srcY + srcH;
 
-   s0 = spt0[0] / tex[0]->width[0];
-   t0 = spt0[1] / tex[0]->height[0];
-   s1 = spt1[0] / tex[0]->width[0];
-   t1 = spt1[1] / tex[0]->height[0];
+   s0 = spt0[0] / tex[0]->width0;
+   t0 = spt0[1] / tex[0]->height0;
+   s1 = spt1[0] / tex[0]->width0;
+   t1 = spt1[1] / tex[0]->height0;
 
    /* 1st vertex */
-   setup_vertex1(r->vertices2[0], dstX, dstY, s0, t0);
+   add_vertex_1tex(r, dstX, dstY, s0, t0);
    /* 2nd vertex */
-   setup_vertex1(r->vertices2[1], dstX + dstW, dstY,
-                 s1, t0);
+   add_vertex_1tex(r, dstX + dstW, dstY,
+                   s1, t0);
    /* 3rd vertex */
-   setup_vertex1(r->vertices2[2], dstX + dstW, dstY + dstH,
-                 s1, t1);
+   add_vertex_1tex(r, dstX + dstW, dstY + dstH,
+                   s1, t1);
    /* 4th vertex */
-   setup_vertex1(r->vertices2[3], dstX, dstY + dstH,
-                 s0, t1);
+   add_vertex_1tex(r, dstX, dstY + dstH,
+                   s0, t1);
 
-
-   return pipe_user_buffer_create(r->pipe->screen,
-                                  r->vertices2,
-                                  sizeof(r->vertices2));
+   return renderer_buffer_create(r);
 }
 
 
 
-static void
-set_viewport(struct xorg_renderer *r, int width, int height,
-             enum AxisOrientation orientation)
+/* Set up framebuffer, viewport and vertex shader constant buffer
+ * state for a particular destinaton surface.  In all our rendering,
+ * these concepts are linked.
+ */
+void renderer_bind_destination(struct xorg_renderer *r,
+                               struct pipe_surface *surface,
+                               int width,
+                               int height )
 {
-   struct pipe_viewport_state viewport;
-   float y_scale = (orientation == Y0_BOTTOM) ? -2.f : 2.f;
 
+   struct pipe_framebuffer_state fb;
+   struct pipe_viewport_state viewport;
+
+   /* Framebuffer uses actual surface width/height
+    */
+   memset(&fb, 0, sizeof fb);
+   fb.width  = surface->width;
+   fb.height = surface->height;
+   fb.nr_cbufs = 1;
+   fb.cbufs[0] = surface;
+   fb.zsbuf = 0;
+
+   /* Viewport just touches the bit we're interested in:
+    */
    viewport.scale[0] =  width / 2.f;
-   viewport.scale[1] =  height / y_scale;
+   viewport.scale[1] =  height / 2.f;
    viewport.scale[2] =  1.0;
    viewport.scale[3] =  1.0;
    viewport.translate[0] = width / 2.f;
@@ -279,11 +342,28 @@
    viewport.translate[2] = 0.0;
    viewport.translate[3] = 0.0;
 
+   /* Constant buffer set up to match viewport dimensions:
+    */
+   if (r->fb_width != width ||
+       r->fb_height != height) 
+   {
+      float vs_consts[8] = {
+         2.f/width, 2.f/height, 1, 1,
+         -1, -1, 0, 0
+      };
+
+      r->fb_width = width;
+      r->fb_height = height;
+
+      renderer_set_constants(r, PIPE_SHADER_VERTEX,
+                             vs_consts, sizeof vs_consts);
+   }
+
+   cso_set_framebuffer(r->cso, &fb);
    cso_set_viewport(r->cso, &viewport);
 }
 
 
-
 struct xorg_renderer * renderer_create(struct pipe_context *pipe)
 {
    struct xorg_renderer *renderer = CALLOC_STRUCT(xorg_renderer);
@@ -320,51 +400,9 @@
    }
 }
 
-void renderer_bind_framebuffer(struct xorg_renderer *r,
-                               struct exa_pixmap_priv *priv)
-{
-   unsigned i;
-   struct pipe_framebuffer_state state;
-   struct pipe_surface *surface = xorg_gpu_surface(r->pipe->screen, priv);
-   memset(&state, 0, sizeof(struct pipe_framebuffer_state));
 
-   state.width  = priv->tex->width[0];
-   state.height = priv->tex->height[0];
 
-   state.nr_cbufs = 1;
-   state.cbufs[0] = surface;
-   for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
-      state.cbufs[i] = 0;
 
-   /* currently we don't use depth/stencil */
-   state.zsbuf = 0;
-
-   cso_set_framebuffer(r->cso, &state);
-
-   /* we do fire and forget for the framebuffer, this is the forget part */
-   pipe_surface_reference(&surface, NULL);
-}
-
-void renderer_bind_viewport(struct xorg_renderer *r,
-                            struct exa_pixmap_priv *dst)
-{
-   int width = dst->tex->width[0];
-   int height = dst->tex->height[0];
-
-   /*debug_printf("Bind viewport (%d, %d)\n", width, height);*/
-
-   set_viewport(r, width, height, Y0_TOP);
-}
-
-void renderer_bind_rasterizer(struct xorg_renderer *r)
-{
-   struct pipe_rasterizer_state raster;
-
-   /* XXX: move to renderer_init_state? */
-   memset(&raster, 0, sizeof(struct pipe_rasterizer_state));
-   raster.gl_rasterization_rules = 1;
-   cso_set_rasterizer(r->cso, &raster);
-}
 
 void renderer_set_constants(struct xorg_renderer *r,
                             int shader_type,
@@ -387,181 +425,20 @@
    r->pipe->set_constant_buffer(r->pipe, shader_type, 0, cbuf);
 }
 
-static void
-setup_vs_constant_buffer(struct xorg_renderer *r,
-                         int width, int height)
-{
-   const int param_bytes = 8 * sizeof(float);
-   float vs_consts[8] = {
-      2.f/width, 2.f/height, 1, 1,
-      -1, -1, 0, 0
-   };
-   renderer_set_constants(r, PIPE_SHADER_VERTEX,
-                          vs_consts, param_bytes);
-}
 
-static void
-setup_fs_constant_buffer(struct xorg_renderer *r)
-{
-   const int param_bytes = 4 * sizeof(float);
-   const float fs_consts[8] = {
-      0, 0, 0, 1,
-   };
-   renderer_set_constants(r, PIPE_SHADER_FRAGMENT,
-                          fs_consts, param_bytes);
-}
-
-static INLINE void shift_rectx(float coords[4],
-                               const float *bounds,
-                               const float shift)
-{
-   coords[0] += shift;
-   coords[2] -= shift;
-   if (bounds) {
-      coords[2] = MIN2(coords[2], bounds[2]);
-      /* bound x/y + width/height */
-      if ((coords[0] + coords[2]) > (bounds[0] + bounds[2])) {
-         coords[2] = (bounds[0] + bounds[2]) - coords[0];
-      }
-   }
-}
-
-static INLINE void shift_recty(float coords[4],
-                               const float *bounds,
-                               const float shift)
-{
-   coords[1] += shift;
-   coords[3] -= shift;
-   if (bounds) {
-      coords[3] = MIN2(coords[3], bounds[3]);
-      if ((coords[1] + coords[3]) > (bounds[1] + bounds[3])) {
-         coords[3] = (bounds[1] + bounds[3]) - coords[1];
-      }
-   }
-}
-
-static INLINE void bound_rect(float coords[4],
-                              const float bounds[4],
-                              float shift[4])
-{
-   /* if outside the bounds */
-   if (coords[0] > (bounds[0] + bounds[2]) ||
-       coords[1] > (bounds[1] + bounds[3]) ||
-       (coords[0] + coords[2]) < bounds[0] ||
-       (coords[1] + coords[3]) < bounds[1]) {
-      coords[0] = 0.f;
-      coords[1] = 0.f;
-      coords[2] = 0.f;
-      coords[3] = 0.f;
-      shift[0] = 0.f;
-      shift[1] = 0.f;
-      return;
-   }
-
-   /* bound x */
-   if (coords[0] < bounds[0]) {
-      shift[0] = bounds[0] - coords[0];
-      coords[2] -= shift[0];
-      coords[0] = bounds[0];
-   } else
-      shift[0] = 0.f;
-
-   /* bound y */
-   if (coords[1] < bounds[1]) {
-      shift[1] = bounds[1] - coords[1];
-      coords[3] -= shift[1];
-      coords[1] = bounds[1];
-   } else
-      shift[1] = 0.f;
-
-   shift[2] = bounds[2] - coords[2];
-   shift[3] = bounds[3] - coords[3];
-   /* bound width/height */
-   coords[2] = MIN2(coords[2], bounds[2]);
-   coords[3] = MIN2(coords[3], bounds[3]);
-
-   /* bound x/y + width/height */
-   if ((coords[0] + coords[2]) > (bounds[0] + bounds[2])) {
-      coords[2] = (bounds[0] + bounds[2]) - coords[0];
-   }
-   if ((coords[1] + coords[3]) > (bounds[1] + bounds[3])) {
-      coords[3] = (bounds[1] + bounds[3]) - coords[1];
-   }
-
-   /* if outside the bounds */
-   if ((coords[0] + coords[2]) < bounds[0] ||
-       (coords[1] + coords[3]) < bounds[1]) {
-      coords[0] = 0.f;
-      coords[1] = 0.f;
-      coords[2] = 0.f;
-      coords[3] = 0.f;
-      return;
-   }
-}
-
-static INLINE void sync_size(float *src_loc, float *dst_loc)
-{
-   src_loc[2] = MIN2(src_loc[2], dst_loc[2]);
-   src_loc[3] = MIN2(src_loc[3], dst_loc[3]);
-   dst_loc[2] = src_loc[2];
-   dst_loc[3] = src_loc[3];
-}
-
-static void renderer_copy_texture(struct xorg_renderer *r,
-                                  struct pipe_texture *src,
-                                  float sx1, float sy1,
-                                  float sx2, float sy2,
-                                  struct pipe_texture *dst,
-                                  float dx1, float dy1,
-                                  float dx2, float dy2)
+void renderer_copy_prepare(struct xorg_renderer *r,
+                           struct pipe_surface *dst_surface,
+                           struct pipe_texture *src_texture)
 {
    struct pipe_context *pipe = r->pipe;
    struct pipe_screen *screen = pipe->screen;
-   struct pipe_buffer *buf;
-   struct pipe_surface *dst_surf = screen->get_tex_surface(
-      screen, dst, 0, 0, 0,
-      PIPE_BUFFER_USAGE_GPU_WRITE);
-   struct pipe_framebuffer_state fb;
-   float s0, t0, s1, t1;
    struct xorg_shader shader;
 
-   assert(src->width[0] != 0);
-   assert(src->height[0] != 0);
-   assert(dst->width[0] != 0);
-   assert(dst->height[0] != 0);
-
-#if 1
-   s0 = sx1 / src->width[0];
-   s1 = sx2 / src->width[0];
-   t0 = sy1 / src->height[0];
-   t1 = sy2 / src->height[0];
-#else
-   s0 = 0;
-   s1 = 1;
-   t0 = 0;
-   t1 = 1;
-#endif
-
-#if 0
-   debug_printf("copy texture src=[%f, %f, %f, %f], dst=[%f, %f, %f, %f], tex=[%f, %f, %f, %f]\n",
-                sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2,
-                s0, t0, s1, t1);
-#endif
-
-   assert(screen->is_format_supported(screen, dst_surf->format,
+   assert(screen->is_format_supported(screen, dst_surface->format,
                                       PIPE_TEXTURE_2D,
                                       PIPE_TEXTURE_USAGE_RENDER_TARGET,
                                       0));
-
-   /* save state (restored below) */
-   cso_save_blend(r->cso);
-   cso_save_samplers(r->cso);
-   cso_save_sampler_textures(r->cso);
-   cso_save_framebuffer(r->cso);
-   cso_save_fragment_shader(r->cso);
-   cso_save_vertex_shader(r->cso);
-
-   cso_save_viewport(r->cso);
+   (void) screen;
 
 
    /* set misc state we care about */
@@ -591,12 +468,12 @@
       cso_single_sampler_done(r->cso);
    }
 
-   set_viewport(r, dst_surf->width, dst_surf->height, Y0_TOP);
+   renderer_bind_destination(r, dst_surface, 
+                             dst_surface->width,
+                             dst_surface->height);
 
    /* texture */
-   cso_set_sampler_textures(r->cso, 1, &src);
-
-   renderer_bind_rasterizer(r);
+   cso_set_sampler_textures(r->cso, 1, &src_texture);
 
    /* shaders */
    shader = xorg_shaders_get(r->shaders,
@@ -605,51 +482,12 @@
    cso_set_vertex_shader_handle(r->cso, shader.vs);
    cso_set_fragment_shader_handle(r->cso, shader.fs);
 
-   /* drawing dest */
-   memset(&fb, 0, sizeof(fb));
-   fb.width = dst_surf->width;
-   fb.height = dst_surf->height;
-   fb.nr_cbufs = 1;
-   fb.cbufs[0] = dst_surf;
-   {
-      int i;
-      for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
-         fb.cbufs[i] = 0;
-   }
-   cso_set_framebuffer(r->cso, &fb);
-   setup_vs_constant_buffer(r, fb.width, fb.height);
-   setup_fs_constant_buffer(r);
-
-   /* draw quad */
-   buf = setup_vertex_data_tex(r,
-                               dx1, dy1,
-                               dx2, dy2,
-                               s0, t0, s1, t1,
-                               0.0f);
-
-   if (buf) {
-      util_draw_vertex_buffer(r->pipe, buf, 0,
-                              PIPE_PRIM_TRIANGLE_FAN,
-                              4,  /* verts */
-                              2); /* attribs/vert */
-
-      pipe_buffer_reference(&buf, NULL);
-   }
-
-   /* restore state we changed */
-   cso_restore_blend(r->cso);
-   cso_restore_samplers(r->cso);
-   cso_restore_sampler_textures(r->cso);
-   cso_restore_framebuffer(r->cso);
-   cso_restore_vertex_shader(r->cso);
-   cso_restore_fragment_shader(r->cso);
-   cso_restore_viewport(r->cso);
-
-   pipe_surface_reference(&dst_surf, NULL);
+   r->buffer_size = 0;
+   r->attrs_per_vertex = 2;
 }
 
-static struct pipe_texture *
-create_sampler_texture(struct xorg_renderer *r,
+struct pipe_texture *
+renderer_clone_texture(struct xorg_renderer *r,
                        struct pipe_texture *src)
 {
    enum pipe_format format;
@@ -658,7 +496,9 @@
    struct pipe_texture *pt;
    struct pipe_texture templ;
 
-   pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+   if (pipe->is_texture_referenced(pipe, src, 0, 0) &
+       PIPE_REFERENCED_FOR_WRITE)
+      pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
 
    /* the coming in texture should already have that invariance */
    debug_assert(screen->is_format_supported(screen, src->format,
@@ -671,10 +511,9 @@
    templ.target = PIPE_TEXTURE_2D;
    templ.format = format;
    templ.last_level = 0;
-   templ.width[0] = src->width[0];
-   templ.height[0] = src->height[0];
-   templ.depth[0] = 1;
-   pf_get_block(format, &templ.block);
+   templ.width0 = src->width0;
+   templ.height0 = src->height0;
+   templ.depth0 = 1;
    templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
 
    pt = screen->texture_create(screen, &templ);
@@ -695,13 +534,13 @@
                 ps_tex, /* dest */
                 0, 0, /* destx/y */
                 ps_read,
-                0, 0, src->width[0], src->height[0]);
+                0, 0, src->width0, src->height0);
       } else {
           util_surface_copy(pipe, FALSE,
                 ps_tex, /* dest */
                 0, 0, /* destx/y */
                 ps_read,
-                0, 0, src->width[0], src->height[0]);
+                0, 0, src->width0, src->height0);
       }
       pipe_surface_reference(&ps_read, NULL);
       pipe_surface_reference(&ps_tex, NULL);
@@ -712,174 +551,39 @@
 
 
 void renderer_copy_pixmap(struct xorg_renderer *r,
-                          struct exa_pixmap_priv *dst_priv, int dx, int dy,
-                          struct exa_pixmap_priv *src_priv, int sx, int sy,
-                          int width, int height)
+                          int dx, int dy,
+                          int sx, int sy,
+                          int width, int height,
+                          float src_width,
+                          float src_height)
 {
-   float dst_loc[4], src_loc[4];
-   float dst_bounds[4], src_bounds[4];
-   float src_shift[4], dst_shift[4], shift[4];
-   struct pipe_texture *dst = dst_priv->tex;
-   struct pipe_texture *src = src_priv->tex;
+   float s0, t0, s1, t1;
+   float x0, y0, x1, y1;
 
-   if (r->pipe->is_texture_referenced(r->pipe, src, 0, 0) &
-       PIPE_REFERENCED_FOR_WRITE)
-      r->pipe->flush(r->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
 
-   dst_loc[0] = dx;
-   dst_loc[1] = dy;
-   dst_loc[2] = width;
-   dst_loc[3] = height;
-   dst_bounds[0] = 0.f;
-   dst_bounds[1] = 0.f;
-   dst_bounds[2] = dst->width[0];
-   dst_bounds[3] = dst->height[0];
+   /* XXX: could put the texcoord scaling calculation into the vertex
+    * shader.
+    */
+   s0 = sx            / src_width;
+   s1 = (sx + width)  / src_width;
+   t0 = sy            / src_height;
+   t1 = (sy + height) / src_height;
 
-   src_loc[0] = sx;
-   src_loc[1] = sy;
-   src_loc[2] = width;
-   src_loc[3] = height;
-   src_bounds[0] = 0.f;
-   src_bounds[1] = 0.f;
-   src_bounds[2] = src->width[0];
-   src_bounds[3] = src->height[0];
+   x0 = dx;
+   x1 = dx + width;
+   y0 = dy;
+   y1 = dy + height;
 
-   bound_rect(src_loc, src_bounds, src_shift);
-   bound_rect(dst_loc, dst_bounds, dst_shift);
-   shift[0] = src_shift[0] - dst_shift[0];
-   shift[1] = src_shift[1] - dst_shift[1];
-
-   if (shift[0] < 0)
-      shift_rectx(src_loc, src_bounds, -shift[0]);
-   else
-      shift_rectx(dst_loc, dst_bounds, shift[0]);
-
-   if (shift[1] < 0)
-      shift_recty(src_loc, src_bounds, -shift[1]);
-   else
-      shift_recty(dst_loc, dst_bounds, shift[1]);
-
-   sync_size(src_loc, dst_loc);
-
-   if (src_loc[2] >= 0 && src_loc[3] >= 0 &&
-       dst_loc[2] >= 0 && dst_loc[3] >= 0) {
-      struct pipe_texture *temp_src = src;
-
-      if (src == dst)
-         temp_src = create_sampler_texture(r, src);
-
-      renderer_copy_texture(r,
-                            temp_src,
-                            src_loc[0],
-                            src_loc[1],
-                            src_loc[0] + src_loc[2],
-                            src_loc[1] + src_loc[3],
-                            dst,
-                            dst_loc[0],
-                            dst_loc[1],
-                            dst_loc[0] + dst_loc[2],
-                            dst_loc[1] + dst_loc[3]);
-
-      if (src == dst)
-         pipe_texture_reference(&temp_src, NULL);
-   }
+   /* draw quad */
+   renderer_draw_conditional(r, 4*8);
+   add_vertex_1tex(r, x0, y0, s0, t0);
+   add_vertex_1tex(r, x1, y0, s1, t0);
+   add_vertex_1tex(r, x1, y1, s1, t1);
+   add_vertex_1tex(r, x0, y1, s0, t1);
 }
 
-void renderer_draw_solid_rect(struct xorg_renderer *r,
-                              int x0, int y0,
-                              int x1, int y1,
-                              float *color)
-{
-   struct pipe_context *pipe = r->pipe;
-   struct pipe_buffer *buf = 0;
-
-   /*
-   debug_printf("solid rect[(%d, %d), (%d, %d)], rgba[%f, %f, %f, %f]\n",
-   x0, y0, x1, y1, color[0], color[1], color[2], color[3]);*/
-   /* 1st vertex */
-   setup_vertex0(r->vertices2[0], x0, y0, color);
-   /* 2nd vertex */
-   setup_vertex0(r->vertices2[1], x1, y0, color);
-   /* 3rd vertex */
-   setup_vertex0(r->vertices2[2], x1, y1, color);
-   /* 4th vertex */
-   setup_vertex0(r->vertices2[3], x0, y1, color);
-
-   buf = pipe_user_buffer_create(pipe->screen,
-                                 r->vertices2,
-                                 sizeof(r->vertices2));
 
 
-   if (buf) {
-      util_draw_vertex_buffer(pipe, buf, 0,
-                              PIPE_PRIM_TRIANGLE_FAN,
-                              4,  /* verts */
-                              2); /* attribs/vert */
-
-      pipe_buffer_reference(&buf, NULL);
-   }
-}
-
-void renderer_draw_textures(struct xorg_renderer *r,
-                            int *pos,
-                            int width, int height,
-                            struct pipe_texture **textures,
-                            int num_textures,
-                            float *src_matrix, float *mask_matrix)
-{
-   struct pipe_context *pipe = r->pipe;
-   struct pipe_buffer *buf = 0;
-
-#if 0
-   if (src_matrix) {
-      debug_printf("src_matrix = \n");
-      debug_printf("%f, %f, %f\n", src_matrix[0], src_matrix[1], src_matrix[2]);
-      debug_printf("%f, %f, %f\n", src_matrix[3], src_matrix[4], src_matrix[5]);
-      debug_printf("%f, %f, %f\n", src_matrix[6], src_matrix[7], src_matrix[8]);
-   }
-   if (mask_matrix) {
-      debug_printf("mask_matrix = \n");
-      debug_printf("%f, %f, %f\n", mask_matrix[0], mask_matrix[1], mask_matrix[2]);
-      debug_printf("%f, %f, %f\n", mask_matrix[3], mask_matrix[4], mask_matrix[5]);
-      debug_printf("%f, %f, %f\n", mask_matrix[6], mask_matrix[7], mask_matrix[8]);
-   }
-#endif
-
-   switch(num_textures) {
-   case 1:
-      buf = setup_vertex_data1(r,
-                               pos[0], pos[1], /* src */
-                               pos[4], pos[5], /* dst */
-                               width, height,
-                               textures[0], src_matrix);
-      break;
-   case 2:
-      buf = setup_vertex_data2(r,
-                               pos[0], pos[1], /* src */
-                               pos[2], pos[3], /* mask */
-                               pos[4], pos[5], /* dst */
-                               width, height,
-                               textures[0], textures[1],
-                               src_matrix, mask_matrix);
-      break;
-   case 3:
-   default:
-      debug_assert(!"Unsupported number of textures");
-      break;
-   }
-
-   if (buf) {
-      int num_attribs = 1; /*pos*/
-      num_attribs += num_textures;
-
-      util_draw_vertex_buffer(pipe, buf, 0,
-                              PIPE_PRIM_TRIANGLE_FAN,
-                              4,  /* verts */
-                              num_attribs); /* attribs/vert */
-
-      pipe_buffer_reference(&buf, NULL);
-   }
-}
 
 void renderer_draw_yuv(struct xorg_renderer *r,
                        int src_x, int src_y, int src_w, int src_h,
@@ -898,10 +602,99 @@
       const int num_attribs = 2; /*pos + tex coord*/
 
       util_draw_vertex_buffer(pipe, buf, 0,
-                              PIPE_PRIM_TRIANGLE_FAN,
+                              PIPE_PRIM_QUADS,
                               4,  /* verts */
                               num_attribs); /* attribs/vert */
 
       pipe_buffer_reference(&buf, NULL);
    }
 }
+
+void renderer_begin_solid(struct xorg_renderer *r)
+{
+   r->buffer_size = 0;
+   r->attrs_per_vertex = 2;
+}
+
+void renderer_solid(struct xorg_renderer *r,
+                    int x0, int y0,
+                    int x1, int y1,
+                    float *color)
+{
+   /*
+   debug_printf("solid rect[(%d, %d), (%d, %d)], rgba[%f, %f, %f, %f]\n",
+   x0, y0, x1, y1, color[0], color[1], color[2], color[3]);*/
+
+   renderer_draw_conditional(r, 4 * 8);
+
+   /* 1st vertex */
+   add_vertex_color(r, x0, y0, color);
+   /* 2nd vertex */
+   add_vertex_color(r, x1, y0, color);
+   /* 3rd vertex */
+   add_vertex_color(r, x1, y1, color);
+   /* 4th vertex */
+   add_vertex_color(r, x0, y1, color);
+}
+
+void renderer_draw_flush(struct xorg_renderer *r)
+{
+   renderer_draw_conditional(r, 0);
+}
+
+void renderer_begin_textures(struct xorg_renderer *r,
+                             struct pipe_texture **textures,
+                             int num_textures)
+{
+   r->attrs_per_vertex = 1 + num_textures;
+   r->buffer_size = 0;
+}
+
+void renderer_texture(struct xorg_renderer *r,
+                      int *pos,
+                      int width, int height,
+                      struct pipe_texture **textures,
+                      int num_textures,
+                      float *src_matrix,
+                      float *mask_matrix)
+{
+
+#if 0
+   if (src_matrix) {
+      debug_printf("src_matrix = \n");
+      debug_printf("%f, %f, %f\n", src_matrix[0], src_matrix[1], src_matrix[2]);
+      debug_printf("%f, %f, %f\n", src_matrix[3], src_matrix[4], src_matrix[5]);
+      debug_printf("%f, %f, %f\n", src_matrix[6], src_matrix[7], src_matrix[8]);
+   }
+   if (mask_matrix) {
+      debug_printf("mask_matrix = \n");
+      debug_printf("%f, %f, %f\n", mask_matrix[0], mask_matrix[1], mask_matrix[2]);
+      debug_printf("%f, %f, %f\n", mask_matrix[3], mask_matrix[4], mask_matrix[5]);
+      debug_printf("%f, %f, %f\n", mask_matrix[6], mask_matrix[7], mask_matrix[8]);
+   }
+#endif
+
+   switch(r->attrs_per_vertex) {
+   case 2:
+      renderer_draw_conditional(r, 4 * 8);
+      add_vertex_data1(r,
+                       pos[0], pos[1], /* src */
+                       pos[4], pos[5], /* dst */
+                       width, height,
+                       textures[0], src_matrix);
+      break;
+   case 3:
+      renderer_draw_conditional(r, 4 * 12);
+      add_vertex_data2(r,
+                       pos[0], pos[1], /* src */
+                       pos[2], pos[3], /* mask */
+                       pos[4], pos[5], /* dst */
+                       width, height,
+                       textures[0], textures[1],
+                       src_matrix, mask_matrix);
+      break;
+   default:
+      debug_assert(!"Unsupported number of textures");
+      break;
+   }
+}
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.h b/src/gallium/state_trackers/xorg/xorg_renderer.h
index 34c9ee4..5272cde 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.h
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.h
@@ -7,54 +7,89 @@
 struct xorg_shaders;
 struct exa_pixmap_priv;
 
+/* max number of vertices *
+ * max number of attributes per vertex *
+ * max number of components per attribute
+ *
+ * currently the max is 100 quads
+ */
+#define BUF_SIZE (100 * 4 * 3 * 4)
+
 struct xorg_renderer {
    struct pipe_context *pipe;
 
    struct cso_context *cso;
    struct xorg_shaders *shaders;
 
+   int fb_width;
+   int fb_height;
    struct pipe_constant_buffer vs_const_buffer;
    struct pipe_constant_buffer fs_const_buffer;
 
-   /* we should combine these three */
-   float vertices2[4][2][4];
-   float vertices3[4][3][4];
+   float buffer[BUF_SIZE];
+   int buffer_size;
+
+   /* number of attributes per vertex for the current
+    * draw operation */
+   int attrs_per_vertex;
 };
 
 struct xorg_renderer *renderer_create(struct pipe_context *pipe);
 void renderer_destroy(struct xorg_renderer *renderer);
 
+void renderer_bind_destination(struct xorg_renderer *r,
+                               struct pipe_surface *surface,
+                               int width,
+                               int height );
+
 void renderer_bind_framebuffer(struct xorg_renderer *r,
                                struct exa_pixmap_priv *priv);
 void renderer_bind_viewport(struct xorg_renderer *r,
                             struct exa_pixmap_priv *dst);
-void renderer_bind_rasterizer(struct xorg_renderer *r);
 void renderer_set_constants(struct xorg_renderer *r,
                             int shader_type,
                             const float *buffer,
                             int size);
-void renderer_copy_pixmap(struct xorg_renderer *r,
-                          struct exa_pixmap_priv *dst_priv, int dx, int dy,
-                          struct exa_pixmap_priv *src_priv, int sx, int sy,
-                          int width, int height);
 
-void renderer_draw_solid_rect(struct xorg_renderer *r,
-                              int x0, int y0,
-                              int x1, int y1,
-                              float *color);
-
-void renderer_draw_textures(struct xorg_renderer *r,
-                            int *pos,
-                            int width, int height,
-                            struct pipe_texture **textures,
-                            int num_textures,
-                            float *src_matrix,
-                            float *mask_matrix);
 
 void renderer_draw_yuv(struct xorg_renderer *r,
                        int src_x, int src_y, int src_w, int src_h,
                        int dst_x, int dst_y, int dst_w, int dst_h,
                        struct pipe_texture **textures);
 
+void renderer_begin_solid(struct xorg_renderer *r);
+void renderer_solid(struct xorg_renderer *r,
+                    int x0, int y0,
+                    int x1, int y1,
+                    float *color);
+
+void renderer_begin_textures(struct xorg_renderer *r,
+                             struct pipe_texture **textures,
+                             int num_textures);
+void renderer_texture(struct xorg_renderer *r,
+                      int *pos,
+                      int width, int height,
+                      struct pipe_texture **textures,
+                      int num_textures,
+                      float *src_matrix,
+                      float *mask_matrix);
+
+void renderer_draw_flush(struct xorg_renderer *r);
+
+struct pipe_texture *
+renderer_clone_texture(struct xorg_renderer *r,
+                       struct pipe_texture *src);
+
+void renderer_copy_prepare(struct xorg_renderer *r,
+                           struct pipe_surface *dst_surface,
+                           struct pipe_texture *src_texture);
+
+void renderer_copy_pixmap(struct xorg_renderer *r,
+                          int dx, int dy,
+                          int sx, int sy,
+                          int width, int height,
+                          float src_width,
+                          float src_height);
+
 
 #endif
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index 6130cf6..4d5d478 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -51,6 +51,8 @@
 
 #define DRV_ERROR(msg)	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg);
 
+struct kms_bo;
+struct kms_driver;
 struct exa_context;
 
 typedef struct
@@ -61,6 +63,8 @@
     ScrnInfoPtr pScrn_2;
 } EntRec, *EntPtr;
 
+#define XORG_NR_FENCES 3
+
 typedef struct _modesettingRec
 {
     /* drm */
@@ -84,8 +88,19 @@
     unsigned int SaveGeneration;
 
     void (*blockHandler)(int, pointer, pointer, pointer);
+    struct pipe_fence_handle *fence[XORG_NR_FENCES];
+
     CreateScreenResourcesProcPtr createScreenResources;
 
+    /* for frontbuffer backing store */
+    Bool (*destroy_front_buffer)(ScrnInfoPtr pScrn);
+    Bool (*create_front_buffer)(ScrnInfoPtr pScrn);
+    Bool (*bind_front_buffer)(ScrnInfoPtr pScrn);
+
+    /* kms */
+    struct kms_driver *kms;
+    struct kms_bo *root_bo;
+
     /* gallium */
     struct drm_api *api;
     struct pipe_screen *screen;
@@ -99,6 +114,13 @@
     Bool noEvict;
     Bool debug_fallback;
 
+    /* winsys hocks */
+    Bool (*winsys_screen_init)(ScrnInfoPtr pScr);
+    Bool (*winsys_screen_close)(ScrnInfoPtr pScr);
+    Bool (*winsys_enter_vt)(ScrnInfoPtr pScr);
+    Bool (*winsys_leave_vt)(ScrnInfoPtr pScr);
+    void *winsys_priv;
+
 #ifdef DRM_MODE_FEATURE_DIRTYFB
     DamagePtr damage;
 #endif
@@ -113,9 +135,6 @@
 struct pipe_texture *
 xorg_exa_get_texture(PixmapPtr pPixmap);
 
-unsigned
-xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride);
-
 int
 xorg_exa_set_displayed_usage(PixmapPtr pPixmap);
 
@@ -131,7 +150,7 @@
 			     int depth, int bpp);
 
 void *
-xorg_exa_init(ScrnInfoPtr pScrn);
+xorg_exa_init(ScrnInfoPtr pScrn, Bool accel);
 
 void
 xorg_exa_close(ScrnInfoPtr pScrn);
@@ -141,33 +160,34 @@
  * xorg_dri2.c
  */
 Bool
-driScreenInit(ScreenPtr pScreen);
+xorg_dri2_init(ScreenPtr pScreen);
 
 void
-driCloseScreen(ScreenPtr pScreen);
+xorg_dri2_close(ScreenPtr pScreen);
 
 
 /***********************************************************************
  * xorg_crtc.c
  */
 void
-crtc_init(ScrnInfoPtr pScrn);
+xorg_crtc_init(ScrnInfoPtr pScrn);
 
 void
-crtc_cursor_destroy(xf86CrtcPtr crtc);
+xorg_crtc_cursor_destroy(xf86CrtcPtr crtc);
 
 
 /***********************************************************************
  * xorg_output.c
  */
 void
-output_init(ScrnInfoPtr pScrn);
+xorg_output_init(ScrnInfoPtr pScrn);
+
 
 /***********************************************************************
  * xorg_xv.c
  */
 void
-xorg_init_video(ScreenPtr pScreen);
+xorg_xv_init(ScreenPtr pScreen);
 
 
 #endif /* _XORG_TRACKER_H_ */
diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c
index 2b935c0..6b5a41a 100644
--- a/src/gallium/state_trackers/xorg/xorg_xv.c
+++ b/src/gallium/state_trackers/xorg/xorg_xv.c
@@ -13,6 +13,8 @@
 #include "pipe/p_screen.h"
 #include "pipe/p_inlines.h"
 
+#include "util/u_format.h"
+
 /*XXX get these from pipe's texture limits */
 #define IMAGE_MAX_WIDTH		2048
 #define IMAGE_MAX_HEIGHT	2048
@@ -73,10 +75,11 @@
    }
 };
 
-#define NUM_IMAGES 2
+#define NUM_IMAGES 3
 static XF86ImageRec Images[NUM_IMAGES] = {
    XVIMAGE_UYVY,
    XVIMAGE_YUY2,
+   XVIMAGE_YV12,
 };
 
 struct xorg_xv_port_priv {
@@ -166,10 +169,9 @@
    templ.target = PIPE_TEXTURE_2D;
    templ.format = PIPE_FORMAT_L8_UNORM;
    templ.last_level = 0;
-   templ.width[0] = width;
-   templ.height[0] = height;
-   templ.depth[0] = 1;
-   pf_get_block(PIPE_FORMAT_L8_UNORM, &templ.block);
+   templ.width0 = width;
+   templ.height0 = height;
+   templ.depth0 = 1;
    templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
 
    tex = screen->texture_create(screen, &templ);
@@ -182,18 +184,18 @@
 {
    struct pipe_texture **dst = priv->yuv[priv->current_set];
    if (!dst[0] ||
-       dst[0]->width[0] != width ||
-       dst[0]->height[0] != height) {
+       dst[0]->width0 != width ||
+       dst[0]->height0 != height) {
       pipe_texture_reference(&dst[0], NULL);
    }
    if (!dst[1] ||
-       dst[1]->width[0] != width ||
-       dst[1]->height[0] != height) {
+       dst[1]->width0 != width ||
+       dst[1]->height0 != height) {
       pipe_texture_reference(&dst[1], NULL);
    }
    if (!dst[2] ||
-       dst[2]->width[0] != width ||
-       dst[2]->height[0] != height) {
+       dst[2]->width0 != width ||
+       dst[2]->height0 != height) {
       pipe_texture_reference(&dst[2], NULL);
    }
 
@@ -212,17 +214,67 @@
    return Success;
 }
 
+static int
+query_image_attributes(ScrnInfoPtr pScrn,
+                       int id,
+                       unsigned short *w, unsigned short *h,
+                       int *pitches, int *offsets)
+{
+   int size, tmp;
+
+   if (*w > IMAGE_MAX_WIDTH)
+      *w = IMAGE_MAX_WIDTH;
+   if (*h > IMAGE_MAX_HEIGHT)
+      *h = IMAGE_MAX_HEIGHT;
+
+   *w = (*w + 1) & ~1;
+   if (offsets)
+      offsets[0] = 0;
+
+   switch (id) {
+   case FOURCC_YV12:
+      *h = (*h + 1) & ~1;
+      size = (*w + 3) & ~3;
+      if (pitches) {
+         pitches[0] = size;
+      }
+      size *= *h;
+      if (offsets) {
+         offsets[1] = size;
+      }
+      tmp = ((*w >> 1) + 3) & ~3;
+      if (pitches) {
+         pitches[1] = pitches[2] = tmp;
+      }
+      tmp *= (*h >> 1);
+      size += tmp;
+      if (offsets) {
+         offsets[2] = size;
+      }
+      size += tmp;
+      break;
+   case FOURCC_UYVY:
+   case FOURCC_YUY2:
+   default:
+      size = *w << 1;
+      if (pitches)
+	 pitches[0] = size;
+      size *= *h;
+      break;
+   }
+
+   return size;
+}
+
 static void
 copy_packed_data(ScrnInfoPtr pScrn,
                  struct xorg_xv_port_priv *port,
                  int id,
                  unsigned char *buf,
-                 int srcPitch,
                  int left,
                  int top,
-                 int w, int h)
+                 unsigned short w, unsigned short h)
 {
-   unsigned char *src;
    int i, j;
    struct pipe_texture **dst = port->yuv[port->current_set];
    struct pipe_transfer *ytrans, *utrans, *vtrans;
@@ -232,8 +284,6 @@
    int yidx, uidx, vidx;
    int y_array_size = w * h;
 
-   src = buf + (top * srcPitch) + (left << 1);
-
    ytrans = screen->get_tex_transfer(screen, dst[0],
                                      0, 0, 0,
                                      PIPE_TRANSFER_WRITE,
@@ -255,15 +305,22 @@
 
    switch (id) {
    case FOURCC_YV12: {
-      for (i = 0; i < w; ++i) {
-         for (j = 0; i < h; ++j) {
-            /*XXX use src? */
-            y1  = buf[j*w + i];
-            u   = buf[(j/2) * (w/2) + i/2 + y_array_size];
-            v   = buf[(j/2) * (w/2) + i/2 + y_array_size + y_array_size/4];
-            ymap[yidx++] = y1;
-            umap[uidx++] = u;
-            vmap[vidx++] = v;
+      int pitches[3], offsets[3];
+      unsigned char *y, *u, *v;
+      query_image_attributes(pScrn, FOURCC_YV12,
+                             &w, &h, pitches, offsets);
+
+      y = buf + offsets[0];
+      v = buf + offsets[1];
+      u = buf + offsets[2];
+      for (i = 0; i < h; ++i) {
+         for (j = 0; j < w; ++j) {
+            int yoffset = (w*i+j);
+            int ii = (i|1), jj = (j|1);
+            int vuoffset = (w/2)*(ii/2) + (jj/2);
+            ymap[yidx++] = y[yoffset];
+            umap[uidx++] = u[vuoffset];
+            vmap[vidx++] = v[vuoffset];
          }
       }
    }
@@ -318,21 +375,6 @@
 
 
 static void
-setup_vs_video_constants(struct xorg_renderer *r, struct exa_pixmap_priv *dst)
-{
-   int width = dst->tex->width[0];
-   int height = dst->tex->height[0];
-   const int param_bytes = 8 * sizeof(float);
-   float vs_consts[8] = {
-      2.f/width, 2.f/height, 1, 1,
-      -1, -1, 0, 0
-   };
-
-   renderer_set_constants(r, PIPE_SHADER_VERTEX,
-                          vs_consts, param_bytes);
-}
-
-static void
 setup_fs_video_constants(struct xorg_renderer *r, boolean hdtv)
 {
    const int param_bytes = 12 * sizeof(float);
@@ -445,6 +487,12 @@
    Bool hdtv;
    int x, y, w, h;
    struct exa_pixmap_priv *dst = exaGetPixmapDriverPrivate(pPixmap);
+   struct pipe_surface *dst_surf = xorg_gpu_surface(pPriv->r->pipe->screen, dst);
+
+   if (dst && !dst->tex) {
+	xorg_exa_set_shared_usage(pPixmap);
+	pScrn->pScreen->ModifyPixmapHeader(pPixmap, 0, 0, 0, 0, 0, NULL);
+   }
 
    if (!dst || !dst->tex)
       XORG_FALLBACK("Xv destination %s", !dst ? "!dst" : "!dst->tex");
@@ -460,15 +508,17 @@
    pbox = REGION_RECTS(dstRegion);
    nbox = REGION_NUM_RECTS(dstRegion);
 
-   renderer_bind_framebuffer(pPriv->r, dst);
-   renderer_bind_viewport(pPriv->r, dst);
+   renderer_bind_destination(pPriv->r, dst_surf, 
+                             dst_surf->width, dst_surf->height);
+
    bind_blend_state(pPriv);
-   renderer_bind_rasterizer(pPriv->r);
    bind_shaders(pPriv);
    bind_samplers(pPriv);
-   setup_vs_video_constants(pPriv->r, dst);
    setup_fs_video_constants(pPriv->r, hdtv);
 
+   exaMoveInPixmap(pPixmap);
+   DamageDamageRegion(&pPixmap->drawable, dstRegion);
+
    while (nbox--) {
       int box_x1 = pbox->x1;
       int box_y1 = pbox->y1;
@@ -476,8 +526,8 @@
       int box_y2 = pbox->y2;
       float diff_x = (float)src_w / (float)dst_w;
       float diff_y = (float)src_h / (float)dst_h;
-      int offset_x = box_x1 - dstX;
-      int offset_y = box_y1 - dstY;
+      int offset_x = box_x1 - dstX + pPixmap->screen_x;
+      int offset_y = box_y1 - dstY + pPixmap->screen_y;
       int offset_w;
       int offset_h;
 
@@ -495,7 +545,9 @@
 
       pbox++;
    }
-   DamageDamageRegion(&pPixmap->drawable, dstRegion);
+   DamageRegionProcessPending(&pPixmap->drawable);
+
+   pipe_surface_reference(&dst_surf, NULL);
 
    return TRUE;
 }
@@ -515,7 +567,6 @@
    ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
    PixmapPtr pPixmap;
    INT32 x1, x2, y1, y2;
-   int srcPitch;
    BoxRec dstBox;
    int ret;
 
@@ -534,20 +585,12 @@
 			      width, height))
       return Success;
 
-   switch (id) {
-   case FOURCC_UYVY:
-   case FOURCC_YUY2:
-   default:
-      srcPitch = width << 1;
-      break;
-   }
-
    ret = check_yuv_textures(pPriv, width, height);
 
    if (ret)
       return ret;
 
-   copy_packed_data(pScrn, pPriv, id, buf, srcPitch,
+   copy_packed_data(pScrn, pPriv, id, buf,
                     src_x, src_y, width, height);
 
    if (pDraw->type == DRAWABLE_WINDOW) {
@@ -565,37 +608,6 @@
    return Success;
 }
 
-static int
-query_image_attributes(ScrnInfoPtr pScrn,
-                       int id,
-                       unsigned short *w, unsigned short *h,
-                       int *pitches, int *offsets)
-{
-   int size;
-
-   if (*w > IMAGE_MAX_WIDTH)
-      *w = IMAGE_MAX_WIDTH;
-   if (*h > IMAGE_MAX_HEIGHT)
-      *h = IMAGE_MAX_HEIGHT;
-
-   *w = (*w + 1) & ~1;
-   if (offsets)
-      offsets[0] = 0;
-
-   switch (id) {
-   case FOURCC_UYVY:
-   case FOURCC_YUY2:
-   default:
-      size = *w << 1;
-      if (pitches)
-	 pitches[0] = size;
-      size *= *h;
-      break;
-   }
-
-   return size;
-}
-
 static struct xorg_xv_port_priv *
 port_priv_create(struct xorg_renderer *r)
 {
@@ -678,7 +690,7 @@
 }
 
 void
-xorg_init_video(ScreenPtr pScreen)
+xorg_xv_init(ScreenPtr pScreen)
 {
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    /*modesettingPtr ms = modesettingPTR(pScrn);*/
diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c
index bf9038f..0e39a39 100644
--- a/src/gallium/state_trackers/xorg/xvmc/surface.c
+++ b/src/gallium/state_trackers/xorg/xvmc/surface.c
@@ -1,8 +1,8 @@
 /**************************************************************************
- * 
+ *
  * Copyright 2009 Younes Manton.
  * 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,11 +10,11 @@
  * 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.
@@ -22,7 +22,7 @@
  * 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 <assert.h>
@@ -103,10 +103,9 @@
    /* XXX: Needs to match the drawable's format? */
    template.format = PIPE_FORMAT_X8R8G8B8_UNORM;
    template.last_level = 0;
-   template.width[0] = width;
-   template.height[0] = height;
-   template.depth[0] = 1;
-   pf_get_block(template.format, &template.block);
+   template.width0 = width;
+   template.height0 = height;
+   template.depth0 = 1;
    template.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
 
    tex = vpipe->screen->texture_create(vpipe->screen, &template);
diff --git a/src/gallium/winsys/drm/Makefile.egl_g3d b/src/gallium/winsys/drm/Makefile.egl_g3d
new file mode 100644
index 0000000..3ce2725
--- /dev/null
+++ b/src/gallium/winsys/drm/Makefile.egl_g3d
@@ -0,0 +1,64 @@
+# src/gallium/winsys/drm/Makefile.egl_g3d
+
+# The driver Makefile should define
+#
+#   EGL_DRIVER_NAME, the name of the driver
+#   EGL_DRIVER_SOURCES, the sources of the driver
+#   EGL_DRIVER_LIBS, extra libraries needed by the driver
+#   EGL_DRIVER_PIPES, the pipe drivers of the driver
+#
+# before including this file.
+
+EGL_DRIVER_OBJECTS = $(EGL_DRIVER_SOURCES:.c=.o)
+
+common_LIBS = -ldrm -lm -ldl
+
+x11_ST = $(TOP)/src/gallium/state_trackers/egl_g3d/libeglx11.a
+x11_LIBS = $(common_LIBS) -lX11 -lXext -lXfixes
+
+kms_ST = $(TOP)/src/gallium/state_trackers/egl_g3d/libeglkms.a
+kms_LIBS = $(common_LIBS)
+
+##### RULES #####
+
+.c.o:
+	$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+
+##### TARGETS #####
+
+EGL_DISPLAY_DRIVERS = $(foreach dpy, $(EGL_DISPLAYS), egl_$(dpy)_$(EGL_DRIVER_NAME).so)
+
+LIB_GALLIUM_DIR = $(TOP)/$(LIB_DIR)/gallium
+EGL_DISPLAY_LIBS = $(foreach drv, $(EGL_DISPLAY_DRIVERS), $(LIB_GALLIUM_DIR)/$(drv))
+
+default: $(EGL_DISPLAY_LIBS)
+
+$(EGL_DISPLAY_LIBS): $(LIB_GALLIUM_DIR)/%.so: %.so
+	@mkdir -p $(LIB_GALLIUM_DIR)
+	$(INSTALL) $^ $(LIB_GALLIUM_DIR)
+
+define mklib-egl
+$(MKLIB) -noprefix -o $@ $(EGL_DRIVER_OBJECTS) \
+	-Wl,--whole-archive $($(1)_ST) -Wl,--no-whole-archive \
+	$(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) $($(1)_LIBS) $(EGL_DRIVER_LIBS)
+endef
+
+egl_x11_$(EGL_DRIVER_NAME).so: $(EGL_DRIVER_OBJECTS) $(x11_ST) $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) Makefile
+	$(call mklib-egl,x11)
+
+egl_kms_$(EGL_DRIVER_NAME).so: $(EGL_DRIVER_OBJECTS) $(kms_ST) $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) Makefile
+	$(call mklib-egl,kms)
+
+clean:
+	-rm -f $(EGL_DRIVER_OBJECTS)
+	-rm -f $(EGL_DISPLAY_DRIVERS)
+
+install: $(EGL_DISPLAY_LIBS)
+	@$(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
+	@echo "Install $(EGL_DISPLAY_DRIVERS)"
+	@for lib in "$(EGL_DISPLAY_LIBS)"; do \
+		$(MINSTALL) -m 755 "$$lib" $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR); \
+	done
+
+depend:
diff --git a/src/gallium/winsys/drm/SConscript b/src/gallium/winsys/drm/SConscript
index a9e9f26..66b73a8 100644
--- a/src/gallium/winsys/drm/SConscript
+++ b/src/gallium/winsys/drm/SConscript
@@ -48,11 +48,21 @@
 	#	$(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR)
 	#	$(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR)
 
+	if 'vmware' in env['winsys']:
+		SConscript([
+			'vmware/SConscript',
+		])
+
 	if 'intel' in env['winsys']:
 		SConscript([
 			'intel/SConscript',
 		])
 
+	if 'i965' in env['winsys']:
+		SConscript([
+			'i965/SConscript',
+		])
+
 	if 'radeon' in env['winsys']:
 		SConscript([
 			'radeon/SConscript',
diff --git a/src/gallium/winsys/drm/i965/Makefile b/src/gallium/winsys/drm/i965/Makefile
new file mode 100644
index 0000000..d8feef6
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/Makefile
@@ -0,0 +1,12 @@
+# src/gallium/winsys/drm/intel/Makefile
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+SUBDIRS = gem $(GALLIUM_STATE_TRACKERS_DIRS)
+
+default install clean:
+	@for dir in $(SUBDIRS) ; do \
+		if [ -d $$dir ] ; then \
+			(cd $$dir && $(MAKE) $@) || exit 1; \
+		fi \
+	done
diff --git a/src/gallium/winsys/drm/i965/SConscript b/src/gallium/winsys/drm/i965/SConscript
new file mode 100644
index 0000000..50d7b75
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/SConscript
@@ -0,0 +1,7 @@
+Import('*')
+
+SConscript(['gem/SConscript',])
+
+if 'mesa' in env['statetrackers']:
+
+    SConscript(['dri/SConscript'])
diff --git a/src/gallium/winsys/drm/i965/dri/Makefile b/src/gallium/winsys/drm/i965/dri/Makefile
new file mode 100644
index 0000000..f7e81ee
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/dri/Makefile
@@ -0,0 +1,26 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = i965_dri.so
+
+PIPE_DRIVERS = \
+	$(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
+	$(TOP)/src/gallium/winsys/drm/i965/gem/libi965drm.a \
+	$(TOP)/src/gallium/drivers/trace/libtrace.a \
+	$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+	$(TOP)/src/gallium/drivers/identity/libidentity.a \
+	$(TOP)/src/gallium/drivers/i965/libi965.a
+
+
+DRIVER_SOURCES =
+
+C_SOURCES = \
+	$(COMMON_GALLIUM_SOURCES) \
+	$(DRIVER_SOURCES)
+
+include ../../Makefile.template
+
+DRI_LIB_DEPS += -ldrm_intel
+
+symlinks: $(TOP)/$(LIB_DIR)/gallium
+	@rm -f $(TOP)/$(LIB_DIR)/gallium/i965_dri.so
diff --git a/src/gallium/winsys/drm/i965/dri/SConscript b/src/gallium/winsys/drm/i965/dri/SConscript
new file mode 100644
index 0000000..a99533f
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/dri/SConscript
@@ -0,0 +1,19 @@
+Import('*')
+
+env = drienv.Clone()
+
+env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
+
+drivers = [
+    st_dri,
+    i965drm,
+    i965,
+    trace,
+]
+
+env.LoadableModule(
+    target ='i965_dri.so',
+    source = COMMON_GALLIUM_SOURCES,
+    LIBS = drivers + mesa + gallium + env['LIBS'],
+    SHLIBPREFIX = '',
+)
diff --git a/src/gallium/winsys/drm/i965/egl/Makefile b/src/gallium/winsys/drm/i965/egl/Makefile
new file mode 100644
index 0000000..a1b32eb
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/egl/Makefile
@@ -0,0 +1,29 @@
+TOP = ../../../../../..
+GALLIUMDIR = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = EGL_i965.so
+
+PIPE_DRIVERS = \
+	$(TOP)/src/gallium/state_trackers/egl/libegldrm.a \
+	$(GALLIUMDIR)/winsys/drm/i965/gem/libi965drm.a \
+	$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+	$(TOP)/src/gallium/drivers/trace/libtrace.a \
+	$(TOP)/src/gallium/drivers/i965/libi965.a
+
+DRIVER_SOURCES =
+
+C_SOURCES = \
+	$(COMMON_GALLIUM_SOURCES) \
+	$(DRIVER_SOURCES)
+
+DRIVER_EXTRAS = -ldrm_intel
+
+ASM_SOURCES = 
+
+DRIVER_DEFINES = -I../gem $(shell pkg-config libdrm --atleast-version=2.3.1 \
+				&& echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
+
+include ../../Makefile.template
+
+symlinks:
diff --git a/src/gallium/winsys/drm/i965/egl_g3d/Makefile b/src/gallium/winsys/drm/i965/egl_g3d/Makefile
new file mode 100644
index 0000000..dd2efe2
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/egl_g3d/Makefile
@@ -0,0 +1,14 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+EGL_DRIVER_NAME = i965
+EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_LIBS = -ldrm_intel
+
+EGL_DRIVER_PIPES = \
+	$(TOP)/src/gallium/winsys/drm/i965/gem/libi965drm.a \
+	$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+	$(TOP)/src/gallium/drivers/trace/libtrace.a \
+	$(TOP)/src/gallium/drivers/i965/libi965.a
+
+include ../../Makefile.egl_g3d
diff --git a/src/gallium/winsys/drm/i965/egl_g3d/dummy.c b/src/gallium/winsys/drm/i965/egl_g3d/dummy.c
new file mode 100644
index 0000000..4a1bc28
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/egl_g3d/dummy.c
@@ -0,0 +1 @@
+/* mklib expects at least one object file */
diff --git a/src/gallium/winsys/drm/i965/gem/Makefile b/src/gallium/winsys/drm/i965/gem/Makefile
new file mode 100644
index 0000000..6a7497b
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/gem/Makefile
@@ -0,0 +1,14 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = i965drm
+
+C_SOURCES = \
+	i965_drm_buffer.c \
+	i965_drm_api.c
+
+LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I)
+
+LIBRARY_DEFINES = $(shell pkg-config libdrm --cflags-only-other)
+
+include ../../../../Makefile.template
diff --git a/src/gallium/winsys/drm/i965/gem/SConscript b/src/gallium/winsys/drm/i965/gem/SConscript
new file mode 100644
index 0000000..6256ec6
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/gem/SConscript
@@ -0,0 +1,15 @@
+Import('*')
+
+env = drienv.Clone()
+
+i965drm_sources = [
+    'i965_drm_api.c',
+    'i965_drm_buffer.c',
+]
+
+i965drm = env.ConvenienceLibrary(
+    target ='i965drm',
+    source = i965drm_sources,
+)
+
+Export('i965drm')
diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_api.c b/src/gallium/winsys/drm/i965/gem/i965_drm_api.c
new file mode 100644
index 0000000..9a2203f
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/gem/i965_drm_api.c
@@ -0,0 +1,244 @@
+
+#include <stdio.h>
+#include "state_tracker/drm_api.h"
+
+#include "i965_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i965/brw_context.h"        /* XXX: shouldn't be doing this */
+#include "i965/brw_screen.h"         /* XXX: shouldn't be doing this */
+
+#include "trace/tr_drm.h"
+
+/*
+ * Helper functions
+ */
+
+
+static void
+i965_libdrm_get_device_id(unsigned int *device_id)
+{
+   char path[512];
+   FILE *file;
+   void *shutup_gcc;
+
+   /*
+    * FIXME: Fix this up to use a drm ioctl or whatever.
+    */
+
+   snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
+   file = fopen(path, "r");
+   if (!file) {
+      return;
+   }
+
+   shutup_gcc = fgets(path, sizeof(path), file);
+   sscanf(path, "%x", device_id);
+   fclose(file);
+}
+
+static struct i965_libdrm_buffer *
+i965_libdrm_buffer_from_handle(struct i965_libdrm_winsys *idws,
+                               const char* name, unsigned handle)
+{
+   struct i965_libdrm_buffer *buf = CALLOC_STRUCT(i965_libdrm_buffer);
+   uint32_t swizzle = 0;
+
+   if (BRW_DUMP)
+      debug_printf("%s\n", __FUNCTION__);
+
+   if (!buf)
+      return NULL;
+   pipe_reference_init(&buf->base.reference, 1);
+   buf->bo = drm_intel_bo_gem_create_from_name(idws->gem, name, handle);
+   buf->base.size = buf->bo->size;
+   buf->base.sws = &idws->base;
+   buf->flinked = TRUE;
+   buf->flink = handle;
+
+
+   if (!buf->bo)
+      goto err;
+
+   drm_intel_bo_get_tiling(buf->bo, &buf->tiling, &swizzle);
+   if (buf->tiling != 0)
+      buf->map_gtt = TRUE;
+
+   return buf;
+
+err:
+   FREE(buf);
+   return NULL;
+}
+
+
+/*
+ * Exported functions
+ */
+
+
+static struct pipe_texture *
+i965_libdrm_texture_from_shared_handle(struct drm_api *api,
+                                       struct pipe_screen *screen,
+                                       struct pipe_texture *template,
+                                       const char* name,
+                                       unsigned pitch,
+                                       unsigned handle)
+{
+   /* XXX: this is silly -- there should be a way to get directly from
+    * the "drm_api" struct to ourselves, without peering into
+    * unrelated code:
+    */
+   struct i965_libdrm_winsys *idws = i965_libdrm_winsys(brw_screen(screen)->sws);
+   struct i965_libdrm_buffer *buffer;
+
+   if (BRW_DUMP)
+      debug_printf("%s %s pitch %d handle 0x%x\n", __FUNCTION__,
+		   name, pitch, handle);
+
+   buffer = i965_libdrm_buffer_from_handle(idws, name, handle);
+   if (!buffer)
+      return NULL;
+
+   return brw_texture_blanket_winsys_buffer(screen, template, pitch,
+					    buffer->tiling,
+					    &buffer->base);
+}
+
+
+static boolean
+i965_libdrm_shared_handle_from_texture(struct drm_api *api,
+                                       struct pipe_screen *screen,
+                                       struct pipe_texture *texture,
+                                       unsigned *pitch,
+                                       unsigned *handle)
+{
+   struct i965_libdrm_buffer *buf = NULL;
+   struct brw_winsys_buffer *buffer = NULL;
+
+   if (BRW_DUMP)
+      debug_printf("%s\n", __FUNCTION__);
+
+   if (!brw_texture_get_winsys_buffer(texture, &buffer, pitch))
+      return FALSE;
+
+   buf = i965_libdrm_buffer(buffer);
+   if (!buf->flinked) {
+      if (drm_intel_bo_flink(buf->bo, &buf->flink))
+         return FALSE;
+      buf->flinked = TRUE;
+   }
+
+   *handle = buf->flink;
+
+   if (BRW_DUMP)
+      debug_printf("   -> pitch %d handle 0x%x\n", *pitch, *handle);
+
+   return TRUE;
+}
+
+static boolean
+i965_libdrm_local_handle_from_texture(struct drm_api *api,
+                                      struct pipe_screen *screen,
+                                      struct pipe_texture *texture,
+                                      unsigned *pitch,
+                                      unsigned *handle)
+{
+   struct brw_winsys_buffer *buffer = NULL;
+
+   if (BRW_DUMP)
+      debug_printf("%s\n", __FUNCTION__);
+
+   if (!brw_texture_get_winsys_buffer(texture, &buffer, pitch))
+      return FALSE;
+
+   *handle = i965_libdrm_buffer(buffer)->bo->handle;
+
+   if (BRW_DUMP)
+      debug_printf("   -> pitch %d handle 0x%x\n", *pitch, *handle);
+
+   return TRUE;
+}
+
+static void
+i965_libdrm_winsys_destroy(struct brw_winsys_screen *iws)
+{
+   struct i965_libdrm_winsys *idws = i965_libdrm_winsys(iws);
+
+   if (BRW_DUMP)
+      debug_printf("%s\n", __FUNCTION__);
+
+   drm_intel_bufmgr_destroy(idws->gem);
+
+   FREE(idws);
+}
+
+static struct pipe_screen *
+i965_libdrm_create_screen(struct drm_api *api, int drmFD,
+                          struct drm_create_screen_arg *arg)
+{
+   struct i965_libdrm_winsys *idws;
+   unsigned int deviceID;
+
+   debug_printf("%s\n", __FUNCTION__);
+
+   if (arg != NULL) {
+      switch(arg->mode) {
+      case DRM_CREATE_NORMAL:
+         break;
+      default:
+         return NULL;
+      }
+   }
+
+   idws = CALLOC_STRUCT(i965_libdrm_winsys);
+   if (!idws)
+      return NULL;
+
+   i965_libdrm_get_device_id(&deviceID);
+
+   i965_libdrm_winsys_init_buffer_functions(idws);
+
+   idws->fd = drmFD;
+   idws->id = deviceID;
+
+   idws->base.destroy = i965_libdrm_winsys_destroy;
+
+   idws->gem = drm_intel_bufmgr_gem_init(idws->fd, BRW_BATCH_SIZE);
+   drm_intel_bufmgr_gem_enable_reuse(idws->gem);
+
+   idws->send_cmd = !debug_get_bool_option("BRW_NO_HW", FALSE);
+
+   return brw_create_screen(&idws->base, deviceID);
+}
+
+static struct pipe_context *
+i965_libdrm_create_context(struct drm_api *api, struct pipe_screen *screen)
+{
+   return brw_create_context(screen);
+}
+
+static void
+destroy(struct drm_api *api)
+{
+   if (BRW_DUMP)
+      debug_printf("%s\n", __FUNCTION__);
+
+}
+
+struct drm_api i965_libdrm_api =
+{
+   .name = "i965",
+   .create_context = i965_libdrm_create_context,
+   .create_screen = i965_libdrm_create_screen,
+   .texture_from_shared_handle = i965_libdrm_texture_from_shared_handle,
+   .shared_handle_from_texture = i965_libdrm_shared_handle_from_texture,
+   .local_handle_from_texture = i965_libdrm_local_handle_from_texture,
+   .destroy = destroy,
+};
+
+struct drm_api *
+drm_api_create()
+{
+   return trace_drm_create(&i965_libdrm_api);
+}
diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c b/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c
new file mode 100644
index 0000000..a4a72b3
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c
@@ -0,0 +1,427 @@
+
+#include "i965_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i915_drm.h"
+#include "intel_bufmgr.h"
+
+
+
+const char *names[BRW_BUFFER_TYPE_MAX] = {
+   "TEXTURE",
+   "SCANOUT",
+   "VERTEX",
+   "CURBE",
+   "QUERY",
+   "SHADER_CONSTANTS",
+   "WM_SCRATCH",
+   "BATCH",
+   "GENERAL_STATE",
+   "SURFACE_STATE",
+   "PIXEL",
+   "GENERIC",
+};
+
+const char *usages[BRW_USAGE_MAX] = {
+   "STATE",
+   "QUERY_RESULT",
+   "RENDER_TARGET",
+   "DEPTH_BUFFER",
+   "BLIT_SOURCE",
+   "BLIT_DEST",
+   "SAMPLER",
+   "VERTEX",
+   "SCRATCH"
+};
+
+
+const char *data_types[BRW_DATA_MAX] =
+{
+   "GS: CC_VP",
+   "GS: CC_UNIT",
+   "GS: WM_PROG",
+   "GS: SAMPLER_DEFAULT_COLOR",
+   "GS: SAMPLER",
+   "GS: WM_UNIT",
+   "GS: SF_PROG",
+   "GS: SF_VP",
+   "GS: SF_UNIT",
+   "GS: VS_UNIT",
+   "GS: VS_PROG",
+   "GS: GS_UNIT",
+   "GS: GS_PROG",
+   "GS: CLIP_VP",
+   "GS: CLIP_UNIT",
+   "GS: CLIP_PROG",
+   "SS: SURFACE",
+   "SS: SURF_BIND",
+   "CONSTANT DATA",
+   "BATCH DATA",
+   "(untyped)"
+};
+
+static enum pipe_error 
+i965_libdrm_bo_alloc(struct brw_winsys_screen *sws,
+                     enum brw_buffer_type type,
+                     unsigned size,
+                     unsigned alignment,
+                     struct brw_winsys_buffer **bo_out)
+{
+   struct i965_libdrm_winsys *idws = i965_libdrm_winsys(sws);
+   struct i965_libdrm_buffer *buf;
+
+   if (BRW_DUMP)
+      debug_printf("%s type %s sz %d align %d\n",
+		   __FUNCTION__, names[type], size, alignment );
+
+   buf = CALLOC_STRUCT(i965_libdrm_buffer);
+   if (!buf)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   switch (type) {
+   case BRW_BUFFER_TYPE_TEXTURE:
+/* case BRW_BUFFER_TYPE_SCANOUT:*/
+   case BRW_BUFFER_TYPE_VERTEX:
+   case BRW_BUFFER_TYPE_CURBE:
+   case BRW_BUFFER_TYPE_QUERY:
+   case BRW_BUFFER_TYPE_SHADER_CONSTANTS:
+   case BRW_BUFFER_TYPE_SHADER_SCRATCH:
+   case BRW_BUFFER_TYPE_BATCH:
+   case BRW_BUFFER_TYPE_GENERAL_STATE:
+   case BRW_BUFFER_TYPE_SURFACE_STATE:
+   case BRW_BUFFER_TYPE_PIXEL:
+   case BRW_BUFFER_TYPE_GENERIC:
+      break;
+   case BRW_BUFFER_TYPE_SCANOUT:
+      buf->map_gtt = TRUE;
+      break;
+   default:
+      assert(0);
+      break;
+   }
+
+   buf->bo = drm_intel_bo_alloc(idws->gem, 
+                                names[type], 
+                                size, 
+                                alignment);
+
+   if (!buf->bo)
+      goto err;
+
+   pipe_reference_init(&buf->base.reference, 1);
+   buf->base.size = size;
+   buf->base.sws = sws;
+
+   *bo_out = &buf->base;
+   return PIPE_OK;
+
+err:
+   assert(0);
+   FREE(buf);
+   return PIPE_ERROR_OUT_OF_MEMORY;
+}
+
+static void 
+i965_libdrm_bo_destroy(struct brw_winsys_buffer *buffer)
+{
+   struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+
+   if (BRW_DUMP)
+      debug_printf("%s\n", __FUNCTION__);
+
+   drm_intel_bo_unreference(buf->bo);
+   FREE(buffer);
+}
+
+static enum pipe_error
+i965_libdrm_bo_emit_reloc(struct brw_winsys_buffer *buffer,
+                          enum brw_buffer_usage usage,
+                          unsigned delta,
+                          unsigned offset,
+                          struct brw_winsys_buffer *buffer2)
+{
+   struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+   struct i965_libdrm_buffer *buf2 = i965_libdrm_buffer(buffer2);
+   int read, write;
+   int ret;
+
+   if (BRW_DUMP)
+      debug_printf("%s buf %p offset %x delta %x buf2 %p/%s/%s\n",
+		   __FUNCTION__, (void *)buffer, 
+		   offset, delta,
+		   (void *)buffer2, names[buf2->data_type], usages[usage]);
+
+   switch (usage) {
+   case BRW_USAGE_STATE:
+      read = I915_GEM_DOMAIN_INSTRUCTION;
+      write = 0;
+      break;
+   case BRW_USAGE_QUERY_RESULT:
+      read = I915_GEM_DOMAIN_INSTRUCTION;
+      write = I915_GEM_DOMAIN_INSTRUCTION;
+      break;
+   case BRW_USAGE_RENDER_TARGET:
+      read = I915_GEM_DOMAIN_RENDER;
+      write = 0;
+      break;
+   case BRW_USAGE_DEPTH_BUFFER:
+      read = I915_GEM_DOMAIN_RENDER;
+      write = I915_GEM_DOMAIN_RENDER;
+      break;
+   case BRW_USAGE_BLIT_SOURCE:
+      read = 0;
+      write = I915_GEM_DOMAIN_RENDER;
+      break;
+   case BRW_USAGE_BLIT_DEST:
+      read = I915_GEM_DOMAIN_RENDER;
+      write = I915_GEM_DOMAIN_RENDER;
+      break;
+   case BRW_USAGE_SAMPLER:
+      read = I915_GEM_DOMAIN_SAMPLER;
+      write = 0;
+      break;
+   case BRW_USAGE_VERTEX:
+      read = I915_GEM_DOMAIN_VERTEX;
+      write = 0;
+      break;
+   case BRW_USAGE_SCRATCH:
+      read = 0;
+      write = 0;
+      break;
+   default:
+      assert(0);
+      return -1;
+   }
+
+   /* Needed??
+   ((uint32_t *)buf->bo->virtual)[offset/4] = (delta +
+					       buf2->bo->offset);
+    */
+
+   ret = dri_bo_emit_reloc( buf->bo, read, write, delta, offset, buf2->bo );
+   if (ret)
+      return -1;
+
+   return 0;
+}
+
+static enum pipe_error 
+i965_libdrm_bo_exec(struct brw_winsys_buffer *buffer,
+                    unsigned bytes_used)
+{
+   struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+   struct i965_libdrm_winsys *idws = i965_libdrm_winsys(buffer->sws);
+   int ret;
+
+   if (BRW_DUMP)
+      debug_printf("execute buffer %p, bytes %d\n", (void *)buffer, bytes_used);
+
+   if (idws->send_cmd) {
+      ret = dri_bo_exec(buf->bo, bytes_used, NULL, 0, 0);
+      if (ret)
+         return PIPE_ERROR;
+   }
+
+   return PIPE_OK;
+}
+
+static enum pipe_error
+i965_libdrm_bo_subdata(struct brw_winsys_buffer *buffer,
+                       enum brw_buffer_data_type data_type,
+                       size_t offset,
+                       size_t size,
+                       const void *data,
+                       const struct brw_winsys_reloc *reloc,
+                       unsigned nr_reloc)
+{
+   struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+   struct i965_libdrm_winsys *idws = i965_libdrm_winsys(buffer->sws);
+   int ret, i;
+
+   (void)data_type;
+
+   if (BRW_DUMP)
+      debug_printf("%s buf %p off %d sz %d %s relocs: %d\n", 
+		   __FUNCTION__, 
+		   (void *)buffer, offset, size, 
+		   data_types[data_type],
+		   nr_reloc);
+
+   if (BRW_DUMP)
+      brw_dump_data( idws->id,
+		     data_type,
+		     buf->bo->offset + offset, 
+		     data, size );
+
+   /* XXX: use bo_map_gtt/memcpy/unmap_gtt under some circumstances???
+    */
+   ret = drm_intel_bo_subdata(buf->bo, offset, size, (void*)data);
+   if (ret)
+      return PIPE_ERROR;
+  
+   for (i = 0; i < nr_reloc; i++) {
+      i965_libdrm_bo_emit_reloc(buffer, reloc[i].usage, reloc[i].delta,
+                                reloc[i].offset, reloc[i].bo);
+   }
+
+   return PIPE_OK;
+}
+
+static boolean 
+i965_libdrm_bo_is_busy(struct brw_winsys_buffer *buffer)
+{
+   struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+   boolean ret;
+
+   if (BRW_DUMP)
+      debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
+
+   ret = drm_intel_bo_busy(buf->bo);
+
+   if (BRW_DUMP)
+      debug_printf("  --> %d\n", ret);
+
+   return ret;
+}
+
+static boolean 
+i965_libdrm_bo_references(struct brw_winsys_buffer *a,
+                          struct brw_winsys_buffer *b)
+{
+   struct i965_libdrm_buffer *bufa = i965_libdrm_buffer(a);
+   struct i965_libdrm_buffer *bufb = i965_libdrm_buffer(b);
+   boolean ret;
+
+   if (BRW_DUMP)
+      debug_printf("%s %p %p\n", __FUNCTION__, (void *)a, (void *)b);
+
+   ret = drm_intel_bo_references(bufa->bo, bufb->bo);
+
+   if (BRW_DUMP)
+      debug_printf("  --> %d\n", ret);
+
+   return ret;
+}
+
+/* XXX: couldn't this be handled by returning true/false on
+ * bo_emit_reloc?
+ */
+static enum pipe_error
+i965_libdrm_check_aperture_space(struct brw_winsys_screen *iws,
+                                 struct brw_winsys_buffer **buffers,
+                                 unsigned count)
+{
+   static drm_intel_bo *bos[128];
+   int i;
+   int ret;
+
+   if (BRW_DUMP)
+      debug_printf("%s\n", __FUNCTION__);
+
+   if (count > Elements(bos)) {
+      assert(0);
+      return FALSE;
+   }
+
+   for (i = 0; i < count; i++)
+      bos[i] = i965_libdrm_buffer(buffers[i])->bo;
+
+   /* XXX: converting from ??? to pipe_error:
+    */
+   ret = dri_bufmgr_check_aperture_space(bos, count);
+
+   if (BRW_DUMP)
+      debug_printf("  --> %d (ok == %d)\n", ret, PIPE_OK);
+
+   return ret;
+}
+
+static void *
+i965_libdrm_bo_map(struct brw_winsys_buffer *buffer,
+                   enum brw_buffer_data_type data_type,
+                   unsigned offset,
+                   unsigned length,
+                   boolean write,
+                   boolean discard,
+                   boolean flush_explicit)
+{
+   struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+   int ret;
+
+
+   if (BRW_DUMP)
+      debug_printf("%s %p %s %s\n", __FUNCTION__, (void *)buffer, 
+		   write ? "read/write" : "read",
+		   write ? data_types[data_type] : "");
+
+   if (!buf->map_count) {
+      if (buf->map_gtt) {
+         ret = drm_intel_gem_bo_map_gtt(buf->bo);
+         if (ret)
+            return NULL;
+      }
+      else {
+         ret = drm_intel_bo_map(buf->bo, write);
+         if (ret)
+            return NULL;
+      }
+   }
+
+   buf->data_type = data_type;
+   buf->map_count++;
+   return buf->bo->virtual;
+}
+
+static void
+i965_libdrm_bo_flush_range(struct brw_winsys_buffer *buffer,
+                           unsigned offset,
+                           unsigned length)
+{
+   struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+   struct i965_libdrm_winsys *idws = i965_libdrm_winsys(buffer->sws);
+
+   if (BRW_DUMP)
+      debug_printf("%s %s offset %d len %d\n", __FUNCTION__,
+		   data_types[buf->data_type],
+		   offset, length);
+
+   if (BRW_DUMP)
+      brw_dump_data( idws->id,
+		     buf->data_type,
+		     buf->bo->offset + offset, 
+		     buf->bo->virtual + offset, 
+		     length );
+}
+
+static void 
+i965_libdrm_bo_unmap(struct brw_winsys_buffer *buffer)
+{
+   struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+
+   if (BRW_DUMP)
+      debug_printf("%s\n", __FUNCTION__);
+
+   if (--buf->map_count > 0)
+      return;
+
+   if (buf->map_gtt)
+      drm_intel_gem_bo_unmap_gtt(buf->bo);
+   else
+      drm_intel_bo_unmap(buf->bo);
+}
+
+void
+i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws)
+{
+   idws->base.bo_alloc             = i965_libdrm_bo_alloc;
+   idws->base.bo_destroy           = i965_libdrm_bo_destroy;
+   idws->base.bo_emit_reloc        = i965_libdrm_bo_emit_reloc;
+   idws->base.bo_exec              = i965_libdrm_bo_exec;
+   idws->base.bo_subdata           = i965_libdrm_bo_subdata;
+   idws->base.bo_is_busy           = i965_libdrm_bo_is_busy;
+   idws->base.bo_references        = i965_libdrm_bo_references;
+   idws->base.check_aperture_space = i965_libdrm_check_aperture_space;
+   idws->base.bo_map               = i965_libdrm_bo_map;
+   idws->base.bo_flush_range       = i965_libdrm_bo_flush_range;
+   idws->base.bo_unmap             = i965_libdrm_bo_unmap;
+}
diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h b/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h
new file mode 100644
index 0000000..c6a7d4a
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h
@@ -0,0 +1,64 @@
+
+#ifndef INTEL_DRM_WINSYS_H
+#define INTEL_DRM_WINSYS_H
+
+#include "i965/brw_winsys.h"
+
+#include "drm.h"
+#include "intel_bufmgr.h"
+
+
+
+/*
+ * Winsys
+ */
+
+
+struct i965_libdrm_winsys
+{
+   struct brw_winsys_screen base;
+   drm_intel_bufmgr *gem;
+
+   boolean send_cmd;
+
+   int fd; /**< Drm file discriptor */
+
+   unsigned id;
+};
+
+static INLINE struct i965_libdrm_winsys *
+i965_libdrm_winsys(struct brw_winsys_screen *iws)
+{
+   return (struct i965_libdrm_winsys *)iws;
+}
+
+struct i965_libdrm_winsys *i965_libdrm_winsys_create(int fd, unsigned pci_id);
+
+void i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws);
+
+
+/* Buffer.  
+ */
+struct i965_libdrm_buffer {
+   struct brw_winsys_buffer base;
+
+   drm_intel_bo *bo;
+
+   void *ptr;
+   unsigned map_count;
+   unsigned data_type;		/* valid while mapped */
+   unsigned tiling;
+
+   boolean map_gtt;
+   boolean flinked;
+   unsigned flink;
+};
+
+static INLINE struct i965_libdrm_buffer *
+i965_libdrm_buffer(struct brw_winsys_buffer *buffer)
+{
+   return (struct i965_libdrm_buffer *)buffer;
+}
+
+
+#endif
diff --git a/src/gallium/winsys/drm/i965/xlib/Makefile b/src/gallium/winsys/drm/i965/xlib/Makefile
new file mode 100644
index 0000000..0efa0ca
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/xlib/Makefile
@@ -0,0 +1,97 @@
+# src/gallium/winsys/xlib/Makefile
+
+# This makefile produces a "stand-alone" libGL.so which is based on
+# Xlib (no DRI HW acceleration)
+
+
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+
+GL_MAJOR = 1
+GL_MINOR = 5
+GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY)
+
+
+INCLUDE_DIRS = \
+	-I$(TOP)/include \
+	-I$(TOP)/src/mesa \
+	-I$(TOP)/src/mesa/main \
+	-I$(TOP)/src/gallium/include \
+	-I$(TOP)/src/gallium/drivers \
+	-I$(TOP)/src/gallium/drivers/i965 \
+	-I$(TOP)/src/gallium/drivers/i965/include \
+	-I$(TOP)/src/gallium/state_trackers/glx/xlib \
+	-I$(TOP)/src/gallium/auxiliary \
+	-I/usr/include/drm
+
+XLIB_WINSYS_SOURCES = \
+	xlib_i965.c \
+
+
+
+XLIB_WINSYS_OBJECTS = $(XLIB_WINSYS_SOURCES:.c=.o)
+
+
+
+LIBS = \
+	$(TOP)/src/gallium/drivers/i965/libi965.a \
+	$(TOP)/src/gallium/drivers/trace/libtrace.a \
+	$(TOP)/src/gallium/state_trackers/glx/xlib/libxlib.a \
+	$(TOP)/src/mesa/libglapi.a \
+	$(TOP)/src/mesa/libmesagallium.a \
+	$(GALLIUM_AUXILIARIES) 
+
+#	$(TOP)/src/gallium/drivers/i965/lib/libi9xx.a \
+
+.SUFFIXES : .cpp
+
+.c.o:
+	$(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@
+
+.cpp.o:
+	$(CXX) -c $(INCLUDE_DIRS) $(DEFINES) $(CXXFLAGS) $< -o $@
+
+
+
+default: $(TOP)/$(LIB_DIR)/gallium $(TOP)/$(LIB_DIR)/gallium/$(GL_LIB_NAME)
+
+$(TOP)/$(LIB_DIR)/gallium:
+	@ mkdir -p $(TOP)/$(LIB_DIR)/gallium
+
+# Make the libGL.so library
+$(TOP)/$(LIB_DIR)/gallium/$(GL_LIB_NAME): $(XLIB_WINSYS_OBJECTS) $(LIBS) Makefile
+	$(TOP)/bin/mklib -o $(GL_LIB) \
+		-linker "$(CC)" \
+		-major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \
+		-install $(TOP)/$(LIB_DIR)/gallium \
+		$(MKLIB_OPTIONS) $(XLIB_WINSYS_OBJECTS) \
+		-Wl,--start-group $(LIBS) -Wl,--end-group $(GL_LIB_DEPS)
+
+
+depend: $(XLIB_WINSYS_SOURCES)
+	@ echo "running $(MKDEP)"
+	@ rm -f depend  # workaround oops on gutsy?!?
+	@ touch depend
+	$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(XLIB_WINSYS_SOURCES) \
+		> /dev/null 2>/dev/null
+
+
+install: default
+	$(INSTALL) -d $(INSTALL_DIR)/include/GL
+	$(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR)
+	$(INSTALL) -m 644 $(TOP)/include/GL/*.h $(INSTALL_DIR)/include/GL
+	@if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \
+		$(MINSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \
+	fi
+
+
+# Emacs tags
+tags:
+	etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h
+
+clean:
+	-rm -f *.o
+
+
+include depend
diff --git a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c
new file mode 100644
index 0000000..d2b9a1a
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c
@@ -0,0 +1,522 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * 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 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * 
+ **************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell
+ *   Brian Paul
+ */
+
+
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "pipe/p_error.h"
+#include "pipe/p_context.h"
+
+#include "xm_winsys.h"
+
+#include "i965/brw_winsys.h"
+#include "i965/brw_screen.h"
+#include "i965/brw_reg.h"
+#include "i965/brw_structs_dump.h"
+
+#define MAX_VRAM (128*1024*1024)
+
+
+
+extern int brw_disasm (FILE *file, 
+                       const struct brw_instruction *inst,
+                       unsigned count );
+
+extern int intel_decode(const uint32_t *data, 
+                        int count,
+                        uint32_t hw_offset,
+                        uint32_t devid);
+
+struct xlib_brw_buffer
+{
+   struct brw_winsys_buffer base;
+   char *virtual;
+   unsigned offset;
+   unsigned type;
+   int map_count;
+   boolean modified;
+};
+
+
+/**
+ * Subclass of brw_winsys_screen for Xlib winsys
+ */
+struct xlib_brw_winsys
+{
+   struct brw_winsys_screen base;
+   struct brw_chipset chipset;
+
+   unsigned size;
+   unsigned used;
+};
+
+static struct xlib_brw_winsys *
+xlib_brw_winsys( struct brw_winsys_screen *screen )
+{
+   return (struct xlib_brw_winsys *)screen;
+}
+
+
+static struct xlib_brw_buffer *
+xlib_brw_buffer( struct brw_winsys_buffer *buffer )
+{
+   return (struct xlib_brw_buffer *)buffer;
+}
+
+
+
+const char *names[BRW_BUFFER_TYPE_MAX] = {
+   "TEXTURE",
+   "SCANOUT",
+   "VERTEX",
+   "CURBE",
+   "QUERY",
+   "SHADER_CONSTANTS",
+   "WM_SCRATCH",
+   "BATCH",
+   "GENERAL_STATE",
+   "SURFACE_STATE",
+   "PIXEL",
+   "GENERIC",
+};
+
+const char *usages[BRW_USAGE_MAX] = {
+   "STATE",
+   "QUERY_RESULT",
+   "RENDER_TARGET",
+   "DEPTH_BUFFER",
+   "BLIT_SOURCE",
+   "BLIT_DEST",
+   "SAMPLER",
+   "VERTEX",
+   "SCRATCH"
+};
+
+
+const char *data_types[BRW_DATA_MAX] =
+{
+   "GS: CC_VP",
+   "GS: CC_UNIT",
+   "GS: WM_PROG",
+   "GS: SAMPLER_DEFAULT_COLOR",
+   "GS: SAMPLER",
+   "GS: WM_UNIT",
+   "GS: SF_PROG",
+   "GS: SF_VP",
+   "GS: SF_UNIT",
+   "GS: VS_UNIT",
+   "GS: VS_PROG",
+   "GS: GS_UNIT",
+   "GS: GS_PROG",
+   "GS: CLIP_VP",
+   "GS: CLIP_UNIT",
+   "GS: CLIP_PROG",
+   "SS: SURFACE",
+   "SS: SURF_BIND",
+   "CONSTANT DATA",
+   "BATCH DATA",
+   "(untyped)"
+};
+
+
+static enum pipe_error
+xlib_brw_bo_alloc( struct brw_winsys_screen *sws,
+                   enum brw_buffer_type type,
+                   unsigned size,
+                   unsigned alignment,
+                   struct brw_winsys_buffer **bo_out )
+{
+   struct xlib_brw_winsys *xbw = xlib_brw_winsys(sws);
+   struct xlib_brw_buffer *buf;
+
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s type %s sz %d align %d\n",
+                   __FUNCTION__, names[type], size, alignment );
+
+   buf = CALLOC_STRUCT(xlib_brw_buffer);
+   if (!buf)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   pipe_reference_init(&buf->base.reference, 1);
+
+   buf->offset = align(xbw->used, alignment);
+   buf->type = type;
+   buf->virtual = MALLOC(size);
+   buf->base.size = size;
+   buf->base.sws = sws;
+
+   xbw->used = align(xbw->used, alignment) + size;
+   if (xbw->used > MAX_VRAM)
+      goto err;
+
+   /* XXX: possibly rentrant call to bo_destroy:
+    */
+   bo_reference(bo_out, &buf->base);
+   return PIPE_OK;
+
+err:
+   assert(0);
+   FREE(buf->virtual);
+   FREE(buf);
+   return PIPE_ERROR_OUT_OF_MEMORY;
+}
+
+static void 
+xlib_brw_bo_destroy( struct brw_winsys_buffer *buffer )
+{
+   struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
+
+   FREE(buf);
+}
+
+static int 
+xlib_brw_bo_emit_reloc( struct brw_winsys_buffer *buffer,
+                        enum brw_buffer_usage usage,
+                        unsigned delta,
+                        unsigned offset,
+                        struct brw_winsys_buffer *buffer2)
+{
+   struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
+   struct xlib_brw_buffer *buf2 = xlib_brw_buffer(buffer2);
+
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s buf %p offset %x val %x + %x buf2 %p/%s/%s\n",
+                   __FUNCTION__, (void *)buffer, offset,
+                   buf2->offset, delta,
+                   (void *)buffer2, names[buf2->type], usages[usage]);
+
+   *(uint32_t *)(buf->virtual + offset) = buf2->offset + delta;
+
+   return 0;
+}
+
+static int 
+xlib_brw_bo_exec( struct brw_winsys_buffer *buffer,
+		     unsigned bytes_used )
+{
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("execute buffer %p, bytes %d\n", (void *)buffer, bytes_used);
+
+   return 0;
+}
+
+
+
+
+static int
+xlib_brw_bo_subdata(struct brw_winsys_buffer *buffer,
+                    enum brw_buffer_data_type data_type,
+                    size_t offset,
+                    size_t size,
+                    const void *data,
+                    const struct brw_winsys_reloc *reloc,
+                    unsigned nr_relocs)
+{
+   struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
+   struct xlib_brw_winsys *xbw = xlib_brw_winsys(buffer->sws);
+   unsigned i;
+
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s buf %p off %d sz %d %s relocs: %d\n", 
+                   __FUNCTION__, 
+                   (void *)buffer, offset, size, 
+                   data_types[data_type],
+                   nr_relocs);
+
+   assert(buf->base.size >= offset + size);
+   memcpy(buf->virtual + offset, data, size);
+
+   /* Apply the relocations:
+    */
+   for (i = 0; i < nr_relocs; i++) {
+      if (BRW_DEBUG & DEBUG_WINSYS)
+         debug_printf("\treloc[%d] usage %s off %d value %x+%x\n", 
+                      i, usages[reloc[i].usage], reloc[i].offset,
+                      xlib_brw_buffer(reloc[i].bo)->offset, reloc[i].delta);
+
+      *(unsigned *)(buf->virtual + offset + reloc[i].offset) = 
+         xlib_brw_buffer(reloc[i].bo)->offset + reloc[i].delta;
+   }
+
+   if (BRW_DUMP)
+      brw_dump_data( xbw->chipset.pci_id,
+		     data_type,
+		     buf->offset + offset, 
+		     buf->virtual + offset, size );
+
+
+   return 0;
+}
+
+
+static boolean 
+xlib_brw_bo_is_busy(struct brw_winsys_buffer *buffer)
+{
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
+   return TRUE;
+}
+
+static boolean 
+xlib_brw_bo_references(struct brw_winsys_buffer *a,
+			  struct brw_winsys_buffer *b)
+{
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s %p %p\n", __FUNCTION__, (void *)a, (void *)b);
+   return TRUE;
+}
+
+static enum pipe_error
+xlib_brw_check_aperture_space( struct brw_winsys_screen *iws,
+                                struct brw_winsys_buffer **buffers,
+                                unsigned count )
+{
+   unsigned tot_size = 0;
+   unsigned i;
+
+   for (i = 0; i < count; i++)
+      tot_size += buffers[i]->size;
+
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s %d bufs, tot_size: %d kb\n", 
+                   __FUNCTION__, count, 
+                   (tot_size + 1023) / 1024);
+
+   return PIPE_OK;
+}
+
+static void *
+xlib_brw_bo_map(struct brw_winsys_buffer *buffer,
+                enum brw_buffer_data_type data_type,
+                unsigned offset,
+                unsigned length,
+                boolean write,
+                boolean discard,
+                boolean explicit)
+{
+   struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
+
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s %p %s %s\n", __FUNCTION__, (void *)buffer, 
+                   write ? "read/write" : "read",
+                   write ? data_types[data_type] : "");
+
+   if (write)
+      buf->modified = 1;
+
+   buf->map_count++;
+   return buf->virtual;
+}
+
+
+static void
+xlib_brw_bo_flush_range( struct brw_winsys_buffer *buffer,
+                         unsigned offset,
+                         unsigned length )
+{
+}
+
+
+static void 
+xlib_brw_bo_unmap(struct brw_winsys_buffer *buffer)
+{
+   struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
+
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
+
+   --buf->map_count;
+   assert(buf->map_count >= 0);
+
+   if (buf->map_count == 0 &&
+       buf->modified) {
+
+      buf->modified = 0;
+      
+      /* Consider dumping new buffer contents here, using the
+       * flush-range info to minimize verbosity.
+       */
+   }
+}
+
+
+static void
+xlib_brw_bo_wait_idle( struct brw_winsys_buffer *buffer )
+{
+}
+
+
+static void
+xlib_brw_winsys_destroy( struct brw_winsys_screen *sws )
+{
+   struct xlib_brw_winsys *xbw = xlib_brw_winsys(sws);
+
+   FREE(xbw);
+}
+
+static struct brw_winsys_screen *
+xlib_create_brw_winsys_screen( void )
+{
+   struct xlib_brw_winsys *ws;
+
+   ws = CALLOC_STRUCT(xlib_brw_winsys);
+   if (!ws)
+      return NULL;
+
+   ws->used = 0;
+
+   ws->base.destroy              = xlib_brw_winsys_destroy;
+   ws->base.bo_alloc             = xlib_brw_bo_alloc;
+   ws->base.bo_destroy           = xlib_brw_bo_destroy;
+   ws->base.bo_emit_reloc        = xlib_brw_bo_emit_reloc;
+   ws->base.bo_exec              = xlib_brw_bo_exec;
+   ws->base.bo_subdata           = xlib_brw_bo_subdata;
+   ws->base.bo_is_busy           = xlib_brw_bo_is_busy;
+   ws->base.bo_references        = xlib_brw_bo_references;
+   ws->base.check_aperture_space = xlib_brw_check_aperture_space;
+   ws->base.bo_map               = xlib_brw_bo_map;
+   ws->base.bo_flush_range       = xlib_brw_bo_flush_range;
+   ws->base.bo_unmap             = xlib_brw_bo_unmap;
+   ws->base.bo_wait_idle         = xlib_brw_bo_wait_idle;
+
+   return &ws->base;
+}
+
+
+/***********************************************************************
+ * Implementation of Xlib co-state-tracker's winsys interface
+ */
+
+static void
+xlib_i965_display_surface(struct xmesa_buffer *xm_buffer,
+                          struct pipe_surface *surf)
+{
+   struct brw_surface *surface = brw_surface(surf);
+   struct xlib_brw_buffer *bo = xlib_brw_buffer(surface->bo);
+
+   if (BRW_DEBUG & DEBUG_WINSYS)
+      debug_printf("%s offset %x+%x sz %dx%d\n", __FUNCTION__, 
+                   bo->offset,
+                   surface->draw_offset,
+                   surf->width,
+                   surf->height);
+}
+
+static void
+xlib_i965_flush_frontbuffer(struct pipe_screen *screen,
+			    struct pipe_surface *surf,
+			    void *context_private)
+{
+   xlib_i965_display_surface(NULL, surf);
+}
+
+
+static struct pipe_screen *
+xlib_create_i965_screen( void )
+{
+   struct brw_winsys_screen *winsys;
+   struct pipe_screen *screen;
+
+   winsys = xlib_create_brw_winsys_screen();
+   if (winsys == NULL)
+      return NULL;
+
+   screen = brw_create_screen(winsys, PCI_CHIP_GM45_GM);
+   if (screen == NULL)
+      goto fail;
+
+   xlib_brw_winsys(winsys)->chipset = brw_screen(screen)->chipset;
+
+   screen->flush_frontbuffer = xlib_i965_flush_frontbuffer;
+   return screen;
+
+fail:
+   if (winsys)
+      winsys->destroy( winsys );
+
+   return NULL;
+}
+
+
+static struct pipe_context *
+xlib_create_i965_context( struct pipe_screen *screen,
+                          void *context_private )
+{
+   struct pipe_context *pipe;
+   
+   pipe = brw_create_context(screen);
+   if (pipe == NULL)
+      goto fail;
+
+   pipe->priv = context_private;
+   return pipe;
+
+fail:
+   /* Free stuff here */
+   return NULL;
+}
+
+
+
+
+struct xm_driver xlib_i965_driver = 
+{
+   .create_pipe_screen = xlib_create_i965_screen,
+   .create_pipe_context = xlib_create_i965_context,
+   .display_surface = xlib_i965_display_surface
+};
+
+
+/* Register this driver at library load: 
+ */
+static void _init( void ) __attribute__((constructor));
+static void _init( void )
+{
+   xmesa_set_driver( &xlib_i965_driver );
+}
+
+
+
+/***********************************************************************
+ *
+ * Butt-ugly hack to convince the linker not to throw away public GL
+ * symbols (they are all referenced from getprocaddress, I guess).
+ */
+extern void (*linker_foo(const unsigned char *procName))();
+extern void (*glXGetProcAddress(const unsigned char *procName))();
+
+extern void (*linker_foo(const unsigned char *procName))()
+{
+   return glXGetProcAddress(procName);
+}
diff --git a/src/gallium/winsys/drm/i965/xorg/Makefile b/src/gallium/winsys/drm/i965/xorg/Makefile
new file mode 100644
index 0000000..d91d000
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/xorg/Makefile
@@ -0,0 +1,57 @@
+TARGET     = modesetting_drv.so
+CFILES     = $(wildcard ./*.c)
+OBJECTS    = $(patsubst ./%.c,./%.o,$(CFILES))
+TOP        = ../../../../../..
+
+include $(TOP)/configs/current
+
+INCLUDES = \
+	$(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \
+	-I../gem \
+	-I$(TOP)/src/gallium/include \
+	-I$(TOP)/src/gallium/drivers \
+	-I$(TOP)/src/gallium/auxiliary \
+	-I$(TOP)/src/mesa \
+	-I$(TOP)/include \
+	-I$(TOP)/src/egl/main
+
+LIBS = \
+	$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
+	$(TOP)/src/gallium/winsys/drm/i965/gem/libi965drm.a \
+	$(TOP)/src/gallium/drivers/i965/libi965.a \
+	$(TOP)/src/gallium/drivers/trace/libtrace.a \
+	$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+	$(GALLIUM_AUXILIARIES)
+
+DRIVER_DEFINES = \
+	-DHAVE_CONFIG_H
+
+
+#############################################
+
+
+
+all default: $(TARGET)
+
+$(TARGET): $(OBJECTS) Makefile $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a $(LIBS)
+	$(TOP)/bin/mklib -noprefix -o $@ \
+	$(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_intel
+
+clean:
+	rm -rf $(OBJECTS) $(TARGET)
+
+install:
+	$(INSTALL) -d $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
+	$(MINSTALL) -m 755 $(TARGET) $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
+
+
+##############################################
+
+
+.c.o:
+	$(CC) -c $(CFLAGS) $(INCLUDES) $(DRIVER_DEFINES) $< -o $@
+
+
+##############################################
+
+.PHONY	= all clean install
diff --git a/src/gallium/winsys/drm/i965/xorg/intel_xorg.c b/src/gallium/winsys/drm/i965/xorg/intel_xorg.c
new file mode 100644
index 0000000..ac691cb
--- /dev/null
+++ b/src/gallium/winsys/drm/i965/xorg/intel_xorg.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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.
+ *
+ *
+ * Author: Alan Hourihane <alanh@tungstengraphics.com>
+ * Author: Jakob Bornecrantz <wallbraker@gmail.com>
+ *
+ */
+
+#include "../../../../state_trackers/xorg/xorg_winsys.h"
+
+static void intel_xorg_identify(int flags);
+static Bool intel_xorg_pci_probe(DriverPtr driver,
+				 int entity_num,
+				 struct pci_device *device,
+				 intptr_t match_data);
+
+static const struct pci_id_match intel_xorg_device_match[] = {
+    {0x8086, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0},
+    {0, 0, 0},
+};
+
+static SymTabRec intel_xorg_chipsets[] = {
+    {PCI_MATCH_ANY, "Intel Graphics Device"},
+    {-1, NULL}
+};
+
+static PciChipsets intel_xorg_pci_devices[] = {
+    {PCI_MATCH_ANY, PCI_MATCH_ANY, NULL},
+    {-1, -1, NULL}
+};
+
+static XF86ModuleVersionInfo intel_xorg_version = {
+    "modesetting",
+    MODULEVENDORSTRING,
+    MODINFOSTRING1,
+    MODINFOSTRING2,
+    XORG_VERSION_CURRENT,
+    0, 1, 0, /* major, minor, patch */
+    ABI_CLASS_VIDEODRV,
+    ABI_VIDEODRV_VERSION,
+    MOD_CLASS_VIDEODRV,
+    {0, 0, 0, 0}
+};
+
+/*
+ * Xorg driver exported structures
+ */
+
+_X_EXPORT DriverRec modesetting = {
+    1,
+    "modesetting",
+    intel_xorg_identify,
+    NULL,
+    xorg_tracker_available_options,
+    NULL,
+    0,
+    NULL,
+    intel_xorg_device_match,
+    intel_xorg_pci_probe
+};
+
+static MODULESETUPPROTO(intel_xorg_setup);
+
+_X_EXPORT XF86ModuleData modesettingModuleData = {
+    &intel_xorg_version,
+    intel_xorg_setup,
+    NULL
+};
+
+/*
+ * Xorg driver functions
+ */
+
+static pointer
+intel_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+    static Bool setupDone = 0;
+
+    /* This module should be loaded only once, but check to be sure.
+     */
+    if (!setupDone) {
+	setupDone = 1;
+	xf86AddDriver(&modesetting, module, HaveDriverFuncs);
+
+	/*
+	 * The return value must be non-NULL on success even though there
+	 * is no TearDownProc.
+	 */
+	return (pointer) 1;
+    } else {
+	if (errmaj)
+	    *errmaj = LDR_ONCEONLY;
+	return NULL;
+    }
+}
+
+static void
+intel_xorg_identify(int flags)
+{
+    xf86PrintChipsets("modesetting", "Driver for Modesetting Kernel Drivers",
+		      intel_xorg_chipsets);
+}
+
+static Bool
+intel_xorg_pci_probe(DriverPtr driver,
+	  int entity_num, struct pci_device *device, intptr_t match_data)
+{
+    ScrnInfoPtr scrn = NULL;
+    EntityInfoPtr entity;
+
+    scrn = xf86ConfigPciEntity(scrn, 0, entity_num, intel_xorg_pci_devices,
+			       NULL, NULL, NULL, NULL, NULL);
+    if (scrn != NULL) {
+	scrn->driverVersion = 1;
+	scrn->driverName = "i965";
+	scrn->name = "modesetting";
+	scrn->Probe = NULL;
+
+	entity = xf86GetEntityInfo(entity_num);
+
+	/* Use all the functions from the xorg tracker */
+	xorg_tracker_set_functions(scrn);
+    }
+    return scrn != NULL;
+}
diff --git a/src/gallium/winsys/drm/intel/dri/Makefile b/src/gallium/winsys/drm/intel/dri/Makefile
index c0ecd96..26aae41 100644
--- a/src/gallium/winsys/drm/intel/dri/Makefile
+++ b/src/gallium/winsys/drm/intel/dri/Makefile
@@ -24,4 +24,3 @@
 
 symlinks: $(TOP)/$(LIB_DIR)/gallium
 	@rm -f $(TOP)/$(LIB_DIR)/gallium/i965_dri.so
-	ln -s i915_dri.so $(TOP)/$(LIB_DIR)/gallium/i965_dri.so
diff --git a/src/gallium/winsys/drm/intel/dri/SConscript b/src/gallium/winsys/drm/intel/dri/SConscript
index b1b654d..104e987 100644
--- a/src/gallium/winsys/drm/intel/dri/SConscript
+++ b/src/gallium/winsys/drm/intel/dri/SConscript
@@ -15,6 +15,6 @@
 env.LoadableModule(
     target ='i915_dri.so',
     source = COMMON_GALLIUM_SOURCES,
-    LIBS = drivers + mesa + auxiliaries + env['LIBS'],
+    LIBS = drivers + mesa + gallium + env['LIBS'],
     SHLIBPREFIX = '',
 )
diff --git a/src/gallium/winsys/drm/intel/egl_g3d/Makefile b/src/gallium/winsys/drm/intel/egl_g3d/Makefile
new file mode 100644
index 0000000..cdbb680
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/egl_g3d/Makefile
@@ -0,0 +1,14 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+EGL_DRIVER_NAME = i915
+EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_LIBS = -ldrm_intel
+
+EGL_DRIVER_PIPES = \
+	$(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \
+	$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+	$(TOP)/src/gallium/drivers/trace/libtrace.a \
+	$(TOP)/src/gallium/drivers/i915/libi915.a
+
+include ../../Makefile.egl_g3d
diff --git a/src/gallium/winsys/drm/intel/egl_g3d/dummy.c b/src/gallium/winsys/drm/intel/egl_g3d/dummy.c
new file mode 100644
index 0000000..4a1bc28
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/egl_g3d/dummy.c
@@ -0,0 +1 @@
+/* mklib expects at least one object file */
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
index 9ed570f..450ae09 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
@@ -32,6 +32,7 @@
    }
 
    shutup_gcc = fgets(path, sizeof(path), file);
+   (void) shutup_gcc;
    sscanf(path, "%x", device_id);
    fclose(file);
 }
@@ -194,6 +195,7 @@
 
 struct drm_api intel_drm_api =
 {
+   .name = "i915",
    .create_context = intel_drm_create_context,
    .create_screen = intel_drm_create_screen,
    .texture_from_shared_handle = intel_drm_texture_from_shared_handle,
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c b/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c
index e70bfe7..e8b5874 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c
@@ -39,11 +39,12 @@
    struct intel_drm_fence *old = (struct intel_drm_fence *)*ptr;
    struct intel_drm_fence *f = (struct intel_drm_fence *)fence;
 
-   if (pipe_reference((struct pipe_reference**)ptr, &f->reference)) {
+   if (pipe_reference(&((struct intel_drm_fence *)(*ptr))->reference, &f->reference)) {
       if (old->bo)
          drm_intel_bo_unreference(old->bo);
       FREE(old);
    }
+   *ptr = fence;
 }
 
 static int
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
index 317dc44..4b2c6a1 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
@@ -1,5 +1,6 @@
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
+#include "util/u_format.h"
 #include "util/u_memory.h"
 
 #include "nouveau_drm_api.h"
@@ -24,11 +25,10 @@
 	tmpl.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY;
 	tmpl.target = PIPE_TEXTURE_2D;
 	tmpl.last_level = 0;
-	tmpl.depth[0] = 1;
+	tmpl.depth0 = 1;
 	tmpl.format = format;
-	tmpl.width[0] = width;
-	tmpl.height[0] = height;
-	pf_get_block(tmpl.format, &tmpl.block);
+	tmpl.width0 = width;
+	tmpl.height0 = height;
 
 	pt = api->texture_from_shared_handle(api, pscreen, &tmpl,
 					     "front buffer", pitch, handle);
@@ -87,6 +87,7 @@
 	case 0x60:
 		init = nv40_screen_create;
 		break;
+	case 0x50:
 	case 0x80:
 	case 0x90:
 	case 0xa0:
@@ -164,6 +165,7 @@
 	case 0x60:
 		init = nv40_create;
 		break;
+	case 0x50:
 	case 0x80:
 	case 0x90:
 	case 0xa0:
@@ -247,11 +249,12 @@
 		return false;
 
 	*handle = mt->bo->handle;
-	*stride = mt->base.nblocksx[0] * mt->base.block.size;
+	*stride = util_format_get_stride(mt->base.format, mt->base.width0);
 	return true;
 }
 
 struct drm_api drm_api_hooks = {
+	.name = "nouveau",
 	.create_screen = nouveau_drm_create_screen,
 	.create_context = nouveau_drm_create_context,
 	.texture_from_shared_handle = nouveau_drm_pt_from_name,
diff --git a/src/gallium/winsys/drm/nouveau/egl_g3d/Makefile b/src/gallium/winsys/drm/nouveau/egl_g3d/Makefile
new file mode 100644
index 0000000..865a5d5
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/egl_g3d/Makefile
@@ -0,0 +1,19 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+EGL_DRIVER_NAME = nouveau
+EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_LIBS = -ldrm_nouveau
+
+EGL_DRIVER_PIPES = \
+	$(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
+	$(TOP)/src/gallium/drivers/nv04/libnv04.a \
+	$(TOP)/src/gallium/drivers/nv10/libnv10.a \
+	$(TOP)/src/gallium/drivers/nv20/libnv20.a \
+	$(TOP)/src/gallium/drivers/nv30/libnv30.a \
+	$(TOP)/src/gallium/drivers/nv40/libnv40.a \
+	$(TOP)/src/gallium/drivers/nv50/libnv50.a \
+	$(TOP)/src/gallium/drivers/nouveau/libnouveau.a \
+	$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
+
+include ../../Makefile.egl_g3d
diff --git a/src/gallium/winsys/drm/nouveau/egl_g3d/dummy.c b/src/gallium/winsys/drm/nouveau/egl_g3d/dummy.c
new file mode 100644
index 0000000..4a1bc28
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/egl_g3d/dummy.c
@@ -0,0 +1 @@
+/* mklib expects at least one object file */
diff --git a/src/gallium/winsys/drm/radeon/core/Makefile b/src/gallium/winsys/drm/radeon/core/Makefile
index 42a6f4a..860cbb6 100644
--- a/src/gallium/winsys/drm/radeon/core/Makefile
+++ b/src/gallium/winsys/drm/radeon/core/Makefile
@@ -7,8 +7,7 @@
 C_SOURCES = \
 	radeon_buffer.c \
 	radeon_drm.c \
-	radeon_r300.c \
-	radeon_winsys_softpipe.c
+	radeon_r300.c
 
 LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/r300 \
 		   $(shell pkg-config libdrm --cflags-only-I)
diff --git a/src/gallium/winsys/drm/radeon/core/SConscript b/src/gallium/winsys/drm/radeon/core/SConscript
index 2ad68e4..f4e9c39 100644
--- a/src/gallium/winsys/drm/radeon/core/SConscript
+++ b/src/gallium/winsys/drm/radeon/core/SConscript
@@ -6,7 +6,6 @@
     'radeon_buffer.c',
     'radeon_drm.c',
     'radeon_r300.c',
-    'radeon_winsys_softpipe.c',
 ]
 
 env.Append(CPPPATH = '#/src/gallium/drivers/r300')
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
index 81cd9dc..385fa85 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
@@ -35,7 +35,10 @@
 #include "radeon_bo_gem.h"
 #include "softpipe/sp_texture.h"
 #include "r300_context.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
 #include <X11/Xutil.h>
+
 struct radeon_vl_context
 {
     Display *display;
@@ -113,17 +116,13 @@
                                                         unsigned tex_usage,
                                                         unsigned *stride)
 {
-    struct pipe_format_block block;
-    unsigned nblocksx, nblocksy, size;
-
-    pf_get_block(format, &block);
-
-    nblocksx = pf_get_nblocksx(&block, width);
-    nblocksy = pf_get_nblocksy(&block, height);
-
     /* Radeons enjoy things in multiples of 32. */
     /* XXX this can be 32 when POT */
-    *stride = (nblocksx * block.size + 63) & ~63;
+    const unsigned alignment = 64;
+    unsigned nblocksy, size;
+
+    nblocksy = util_format_get_nblocksy(format, height);
+    *stride = align(util_format_get_stride(format, width), alignment);
     size = *stride * nblocksy;
 
     return radeon_buffer_create(ws, 64, usage, size);
@@ -142,6 +141,7 @@
                                struct pipe_buffer *buffer,
                                unsigned flags)
 {
+    struct radeon_winsys_priv *priv = ((struct radeon_winsys *)ws)->priv;
     struct radeon_pipe_buffer *radeon_buffer =
         (struct radeon_pipe_buffer*)buffer;
     int write = 0;
@@ -152,6 +152,11 @@
         if (radeon_bo_is_busy(radeon_buffer->bo, &domain))
             return NULL;
     }
+
+    if (radeon_bo_is_referenced_by_cs(radeon_buffer->bo, priv->cs)) {
+        priv->flush_cb(priv->flush_data);
+    }
+
     if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) {
         write = 1;
     }
@@ -276,61 +281,3 @@
 
     return radeon_ws;
 }
-#if 0
-static struct pipe_buffer *radeon_buffer_from_handle(struct radeon_screen *radeon_screen,
-                                                  uint32_t handle)
-{
-    struct radeon_pipe_buffer *radeon_buffer;
-    struct radeon_bo *bo = NULL;
-
-    bo = radeon_bo_open(radeon_screen->bom, handle, 0, 0, 0, 0);
-    if (bo == NULL) {
-        return NULL;
-    }
-    radeon_buffer = calloc(1, sizeof(struct radeon_pipe_buffer));
-    if (radeon_buffer == NULL) {
-        radeon_bo_unref(bo);
-        return NULL;
-    }
-    pipe_reference_init(&radeon_buffer->base.reference, 1);
-    radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL;
-    radeon_buffer->bo = bo;
-    return &radeon_buffer->base;
-}
-
-struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context,
-                                             uint32_t handle,
-                                             enum pipe_format format,
-                                             int w, int h, int pitch)
-{
-    struct pipe_screen *pipe_screen = radeon_context->pipe_screen;
-    struct pipe_winsys *pipe_winsys = radeon_context->pipe_winsys;
-    struct pipe_texture tmpl;
-    struct pipe_surface *ps;
-    struct pipe_texture *pt;
-    struct pipe_buffer *pb;
-
-    pb = radeon_buffer_from_handle(radeon_context->radeon_screen, handle);
-    if (pb == NULL) {
-        return NULL;
-    }
-    memset(&tmpl, 0, sizeof(tmpl));
-    tmpl.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
-    tmpl.target = PIPE_TEXTURE_2D;
-    tmpl.width[0] = w;
-    tmpl.height[0] = h;
-    tmpl.depth[0] = 1;
-    tmpl.format = format;
-    pf_get_block(tmpl.format, &tmpl.block);
-    tmpl.nblocksx[0] = pf_get_nblocksx(&tmpl.block, w);
-    tmpl.nblocksy[0] = pf_get_nblocksy(&tmpl.block, h);
-
-    pt = pipe_screen->texture_blanket(pipe_screen, &tmpl, &pitch, pb);
-    if (pt == NULL) {
-        pipe_buffer_reference(&pb, NULL);
-    }
-    ps = pipe_screen->get_tex_surface(pipe_screen, pt, 0, 0, 0,
-                                      PIPE_BUFFER_USAGE_GPU_WRITE);
-    return ps;
-}
-#endif
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
index f5153b0..d7f1756 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
@@ -45,6 +45,8 @@
 
 #include "radeon_drm.h"
 
+#include "radeon_winsys.h"
+
 struct radeon_pipe_buffer {
     struct pipe_buffer  base;
     struct radeon_bo    *bo;
@@ -66,14 +68,10 @@
 
     /* Current CS. */
     struct radeon_cs* cs;
-};
 
-struct radeon_winsys {
-    /* Parent class. */
-    struct pipe_winsys base;
-
-    /* This corresponds to void* radeon_winsys in r300_winsys. */
-    struct radeon_winsys_priv* priv;
+    /* Flush CB */
+    void (*flush_cb)(void *);
+    void *flush_data;
 };
 
 struct radeon_winsys* radeon_pipe_winsys(int fb);
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
index 69f14e5..851c223 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
@@ -29,21 +29,95 @@
  *      Joakim Sindholt <opensource@zhasha.com>
  */
 
+#include "softpipe/sp_winsys.h"
+
 #include "radeon_drm.h"
 
+/* Helper function to do the ioctls needed for setup and init. */
+static void do_ioctls(int fd, struct radeon_winsys* winsys)
+{
+    struct drm_radeon_gem_info gem_info = {0};
+    struct drm_radeon_info info = {0};
+    int target = 0;
+    int retval;
+
+    info.value = (unsigned long)&target;
+
+    /* We do things in a specific order here.
+     *
+     * First, the PCI ID. This is essential and should return usable numbers
+     * for all Radeons. If this fails, we probably got handed an FD for some
+     * non-Radeon card.
+     *
+     * The GB and Z pipe requests should always succeed, but they might not
+     * return sensical values for all chipsets, but that's alright because
+     * the pipe drivers already know that.
+     *
+     * The GEM info is actually bogus on the kernel side, as well as our side
+     * (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because
+     * we don't actually use the info for anything yet.
+     * XXX update the above when we can safely use vram_size instead of vram_visible */
+    info.request = RADEON_INFO_DEVICE_ID;
+    retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
+    if (retval) {
+        fprintf(stderr, "%s: Failed to get PCI ID, "
+                "error number %d\n", __FUNCTION__, retval);
+        exit(1);
+    }
+    winsys->pci_id = target;
+
+    info.request = RADEON_INFO_NUM_GB_PIPES;
+    retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
+    if (retval) {
+        fprintf(stderr, "%s: Failed to get GB pipe count, "
+                "error number %d\n", __FUNCTION__, retval);
+        exit(1);
+    }
+    winsys->gb_pipes = target;
+
+    info.request = RADEON_INFO_NUM_Z_PIPES;
+    retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
+    if (retval) {
+        fprintf(stderr, "%s: Failed to get Z pipe count, "
+                "error number %d\n", __FUNCTION__, retval);
+        exit(1);
+    }
+    winsys->z_pipes = target;
+
+    retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO,
+            &gem_info, sizeof(gem_info));
+    if (retval) {
+        fprintf(stderr, "%s: Failed to get MM info, error number %d\n",
+                __FUNCTION__, retval);
+        exit(1);
+    }
+    winsys->gart_size = gem_info.gart_size;
+    /* XXX */
+    winsys->vram_size = gem_info.vram_visible;
+}
+
+/* Guess at whether this chipset should use r300g.
+ *
+ * I believe that this check is valid, but I haven't been exhaustive. */
+static boolean is_r3xx(int pciid)
+{
+    return (pciid > 0x3150) && (pciid < 0x796f);
+}
+
 /* Create a pipe_screen. */
 struct pipe_screen* radeon_create_screen(struct drm_api* api,
                                          int drmFB,
                                          struct drm_create_screen_arg *arg)
 {
-    struct radeon_winsys* winsys = radeon_pipe_winsys(drmFB);
+    struct radeon_winsys* rwinsys = radeon_pipe_winsys(drmFB);
+    do_ioctls(drmFB, rwinsys);
 
-    if (debug_get_bool_option("RADEON_SOFTPIPE", FALSE)) {
-        return softpipe_create_screen((struct pipe_winsys*)winsys);
+    if (!is_r3xx(rwinsys->pci_id) ||
+        debug_get_bool_option("RADEON_SOFTPIPE", FALSE)) {
+        return softpipe_create_screen((struct pipe_winsys*)rwinsys);
     } else {
-        struct r300_winsys* r300 = radeon_create_r300_winsys(drmFB, winsys);
-        FREE(winsys);
-        return r300_create_screen(r300);
+        radeon_setup_winsys(drmFB, rwinsys);
+        return r300_create_screen(rwinsys);
     }
 }
 
@@ -51,11 +125,13 @@
 struct pipe_context* radeon_create_context(struct drm_api* api,
                                            struct pipe_screen* screen)
 {
-    if (debug_get_bool_option("RADEON_SOFTPIPE", FALSE)) {
-        return radeon_create_softpipe(screen->winsys);
+    struct radeon_winsys* rwinsys = (struct radeon_winsys*)screen->winsys;
+
+    if (!is_r3xx(rwinsys->pci_id) ||
+        debug_get_bool_option("RADEON_SOFTPIPE", FALSE)) {
+        return softpipe_create(screen);
     } else {
-        return r300_create_context(screen,
-                                   (struct r300_winsys*)screen->winsys);
+        return r300_create_context(screen, rwinsys);
     }
 }
 
@@ -130,7 +206,7 @@
     int retval, fd;
     struct drm_gem_flink flink;
     struct radeon_pipe_buffer* radeon_buffer;
-    struct pipe_buffer *buffer;
+    struct pipe_buffer *buffer = NULL;
 
     if (!radeon_buffer_from_texture(api, texture, &buffer, stride)) {
         return FALSE;
@@ -163,7 +239,7 @@
                                                 unsigned *stride,
                                                 unsigned *handle)
 {
-    struct pipe_buffer *buffer;
+    struct pipe_buffer *buffer = NULL;
     if (!radeon_buffer_from_texture(api, texture, &buffer, stride)) {
         return FALSE;
     }
@@ -176,6 +252,7 @@
 }
 
 struct drm_api drm_api_hooks = {
+    .name = "radeon",
     .create_screen = radeon_create_screen,
     .create_context = radeon_create_context,
     .texture_from_shared_handle = radeon_texture_from_shared_handle,
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h
index 9a789ec..bf0e781 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h
@@ -44,7 +44,6 @@
 
 #include "radeon_buffer.h"
 #include "radeon_r300.h"
-#include "radeon_winsys_softpipe.h"
 
 /* XXX */
 #include "r300_screen.h"
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
index 7ea5d1f..0875ee4 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
@@ -22,36 +22,29 @@
 
 #include "radeon_r300.h"
 
-static void radeon_r300_set_flush_cb(struct r300_winsys *winsys,
-				     void (*flush_cb)(void *),
-				     void *data)
+static void radeon_set_flush_cb(struct radeon_winsys *winsys,
+                                void (*flush_cb)(void *),
+                                void *data)
 {
-    struct radeon_winsys_priv* priv =
-        (struct radeon_winsys_priv*)winsys->radeon_winsys;
-
-    radeon_cs_space_set_flush(priv->cs, flush_cb,
-			      data);
+    winsys->priv->flush_cb = flush_cb;
+    winsys->priv->flush_data = data;
+    radeon_cs_space_set_flush(winsys->priv->cs, flush_cb, data);
 }
 
-static boolean radeon_r300_add_buffer(struct r300_winsys* winsys,
-                                      struct pipe_buffer* pbuffer,
-                                      uint32_t rd,
-                                      uint32_t wd)
+static boolean radeon_add_buffer(struct radeon_winsys* winsys,
+                                 struct pipe_buffer* pbuffer,
+                                 uint32_t rd,
+                                 uint32_t wd)
 {
-    struct radeon_winsys_priv* priv =
-        (struct radeon_winsys_priv*)winsys->radeon_winsys;
     struct radeon_bo* bo = ((struct radeon_pipe_buffer*)pbuffer)->bo;
 
-    radeon_cs_space_add_persistent_bo(priv->cs, bo, rd, wd);
+    radeon_cs_space_add_persistent_bo(winsys->priv->cs, bo, rd, wd);
     return TRUE;
 }
 
-static boolean radeon_r300_validate(struct r300_winsys* winsys)
+static boolean radeon_validate(struct radeon_winsys* winsys)
 {
-    struct radeon_winsys_priv* priv =
-        (struct radeon_winsys_priv*)winsys->radeon_winsys;
-
-    if (radeon_cs_space_check(priv->cs) < 0) {
+    if (radeon_cs_space_check(winsys->priv->cs) < 0) {
         return FALSE;
     }
 
@@ -59,45 +52,37 @@
     return TRUE;
 }
 
-static boolean radeon_r300_check_cs(struct r300_winsys* winsys, int size)
+static boolean radeon_check_cs(struct radeon_winsys* winsys, int size)
 {
-    /* XXX check size here, lazy ass! */
-    /* XXX also validate buffers */
-    return TRUE;
+    struct radeon_cs* cs = winsys->priv->cs;
+
+    return radeon_validate(winsys) && cs->cdw + size <= cs->ndw;
 }
 
-static void radeon_r300_begin_cs(struct r300_winsys* winsys,
-                                 int size,
-                                 const char* file,
-                                 const char* function,
-                                 int line)
+static void radeon_begin_cs(struct radeon_winsys* winsys,
+                            int size,
+                            const char* file,
+                            const char* function,
+                            int line)
 {
-    struct radeon_winsys_priv* priv =
-        (struct radeon_winsys_priv*)winsys->radeon_winsys;
-
-    radeon_cs_begin(priv->cs, size, file, function, line);
+    radeon_cs_begin(winsys->priv->cs, size, file, function, line);
 }
 
-static void radeon_r300_write_cs_dword(struct r300_winsys* winsys,
-                                       uint32_t dword)
+static void radeon_write_cs_dword(struct radeon_winsys* winsys,
+                                  uint32_t dword)
 {
-    struct radeon_winsys_priv* priv =
-        (struct radeon_winsys_priv*)winsys->radeon_winsys;
-
-    radeon_cs_write_dword(priv->cs, dword);
+    radeon_cs_write_dword(winsys->priv->cs, dword);
 }
 
-static void radeon_r300_write_cs_reloc(struct r300_winsys* winsys,
-                                       struct pipe_buffer* pbuffer,
-                                       uint32_t rd,
-                                       uint32_t wd,
-                                       uint32_t flags)
+static void radeon_write_cs_reloc(struct radeon_winsys* winsys,
+                                  struct pipe_buffer* pbuffer,
+                                  uint32_t rd,
+                                  uint32_t wd,
+                                  uint32_t flags)
 {
-    struct radeon_winsys_priv* priv =
-        (struct radeon_winsys_priv*)winsys->radeon_winsys;
     int retval = 0;
 
-    retval = radeon_cs_write_reloc(priv->cs,
+    retval = radeon_cs_write_reloc(winsys->priv->cs,
             ((struct radeon_pipe_buffer*)pbuffer)->bo, rd, wd, flags);
 
     if (retval) {
@@ -106,132 +91,60 @@
     }
 }
 
-static void radeon_r300_reset_bos(struct r300_winsys *winsys)
+static void radeon_reset_bos(struct radeon_winsys *winsys)
 {
-    struct radeon_winsys_priv* priv =
-        (struct radeon_winsys_priv*)winsys->radeon_winsys;
-    radeon_cs_space_reset_bos(priv->cs);
+    radeon_cs_space_reset_bos(winsys->priv->cs);
 }
 
-static void radeon_r300_end_cs(struct r300_winsys* winsys,
-                               const char* file,
-                               const char* function,
-                               int line)
+static void radeon_end_cs(struct radeon_winsys* winsys,
+                          const char* file,
+                          const char* function,
+                          int line)
 {
-    struct radeon_winsys_priv* priv =
-        (struct radeon_winsys_priv*)winsys->radeon_winsys;
-
-    radeon_cs_end(priv->cs, file, function, line);
+    radeon_cs_end(winsys->priv->cs, file, function, line);
 }
 
-static void radeon_r300_flush_cs(struct r300_winsys* winsys)
+static void radeon_flush_cs(struct radeon_winsys* winsys)
 {
-    struct radeon_winsys_priv* priv =
-        (struct radeon_winsys_priv*)winsys->radeon_winsys;
     int retval;
 
     /* Emit the CS. */
-    retval = radeon_cs_emit(priv->cs);
+    retval = radeon_cs_emit(winsys->priv->cs);
     if (retval) {
         debug_printf("radeon: Bad CS, dumping...\n");
-        radeon_cs_print(priv->cs, stderr);
+        radeon_cs_print(winsys->priv->cs, stderr);
     }
 
     /* Reset CS.
      * Someday, when we care about performance, we should really find a way
      * to rotate between two or three CS objects so that the GPU can be
      * spinning through one CS while another one is being filled. */
-    radeon_cs_erase(priv->cs);
+    radeon_cs_erase(winsys->priv->cs);
 }
 
-/* Helper function to do the ioctls needed for setup and init. */
-static void do_ioctls(struct r300_winsys* winsys, int fd)
+void
+radeon_setup_winsys(int fd, struct radeon_winsys* winsys)
 {
-    struct drm_radeon_gem_info gem_info = {0};
-    struct drm_radeon_info info = {0};
-    int target = 0;
-    int retval;
-
-    info.value = (unsigned long)&target;
-
-    /* First, get the number of pixel pipes */
-    info.request = RADEON_INFO_NUM_GB_PIPES;
-    retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
-    if (retval) {
-        fprintf(stderr, "%s: Failed to get GB pipe count, "
-                "error number %d\n", __FUNCTION__, retval);
-        exit(1);
-    }
-    winsys->gb_pipes = target;
-
-    /* get Z pipes */
-    info.request = RADEON_INFO_NUM_Z_PIPES;
-    retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
-    if (retval) {
-        fprintf(stderr, "%s: Failed to get GB pipe count, "
-                "error number %d\n", __FUNCTION__, retval);
-        exit(1);
-    }
-    winsys->z_pipes = target;
-
-    /* Then, get PCI ID */
-    info.request = RADEON_INFO_DEVICE_ID;
-    retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
-    if (retval) {
-        fprintf(stderr, "%s: Failed to get PCI ID, "
-                "error number %d\n", __FUNCTION__, retval);
-        exit(1);
-    }
-    winsys->pci_id = target;
-
-    /* Finally, retrieve MM info */
-    retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO,
-            &gem_info, sizeof(gem_info));
-    if (retval) {
-        fprintf(stderr, "%s: Failed to get MM info, error number %d\n",
-                __FUNCTION__, retval);
-        exit(1);
-    }
-    winsys->gart_size = gem_info.gart_size;
-    /* XXX */
-    winsys->vram_size = gem_info.vram_visible;
-}
-
-struct r300_winsys*
-radeon_create_r300_winsys(int fd, struct radeon_winsys* old_winsys)
-{
-    struct r300_winsys* winsys = CALLOC_STRUCT(r300_winsys);
-    struct radeon_winsys_priv* priv;
-
-    if (winsys == NULL) {
-        return NULL;
-    }
-
-    priv = old_winsys->priv;
-
-    do_ioctls(winsys, fd);
+    struct radeon_winsys_priv* priv = winsys->priv;
 
     priv->csm = radeon_cs_manager_gem_ctor(fd);
 
+    /* Size limit on IBs is 64 kibibytes. */
     priv->cs = radeon_cs_create(priv->csm, 1024 * 64 / 4);
     radeon_cs_set_limit(priv->cs,
             RADEON_GEM_DOMAIN_GTT, winsys->gart_size);
     radeon_cs_set_limit(priv->cs,
             RADEON_GEM_DOMAIN_VRAM, winsys->vram_size);
 
-    winsys->add_buffer = radeon_r300_add_buffer;
-    winsys->validate = radeon_r300_validate;
+    winsys->add_buffer = radeon_add_buffer;
+    winsys->validate = radeon_validate;
 
-    winsys->check_cs = radeon_r300_check_cs;
-    winsys->begin_cs = radeon_r300_begin_cs;
-    winsys->write_cs_dword = radeon_r300_write_cs_dword;
-    winsys->write_cs_reloc = radeon_r300_write_cs_reloc;
-    winsys->end_cs = radeon_r300_end_cs;
-    winsys->flush_cs = radeon_r300_flush_cs;
-    winsys->reset_bos = radeon_r300_reset_bos;
-    winsys->set_flush_cb = radeon_r300_set_flush_cb;
-
-    memcpy(winsys, old_winsys, sizeof(struct radeon_winsys));
-
-    return winsys;
+    winsys->check_cs = radeon_check_cs;
+    winsys->begin_cs = radeon_begin_cs;
+    winsys->write_cs_dword = radeon_write_cs_dword;
+    winsys->write_cs_reloc = radeon_write_cs_reloc;
+    winsys->end_cs = radeon_end_cs;
+    winsys->flush_cs = radeon_flush_cs;
+    winsys->reset_bos = radeon_reset_bos;
+    winsys->set_flush_cb = radeon_set_flush_cb;
 }
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/drm/radeon/core/radeon_r300.h
index 775d793..cfbdb30 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.h
@@ -34,9 +34,6 @@
 
 #include "radeon_buffer.h"
 
-struct radeon_winsys;
-
-struct r300_winsys*
-radeon_create_r300_winsys(int fd, struct radeon_winsys* old_winsys);
+void radeon_setup_winsys(int fd, struct radeon_winsys* winsys);
 
 #endif /* RADEON_R300_H */
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
new file mode 100644
index 0000000..9edc9e0
--- /dev/null
+++ b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright © 2009 Corbin Simpson
+ * 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 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 THE COPYRIGHT HOLDERS, AUTHORS
+ * 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ *      Corbin Simpson <MostAwesomeDude@gmail.com>
+ */
+#ifndef RADEON_WINSYS_H
+#define RADEON_WINSYS_H
+
+#include "pipe/internal/p_winsys_screen.h"
+
+struct radeon_winsys_priv;
+
+struct radeon_winsys {
+    /* Parent class. */
+    struct pipe_winsys base;
+
+    /* Winsys private */
+    struct radeon_winsys_priv* priv;
+
+    /* PCI ID */
+    uint32_t pci_id;
+
+    /* GB pipe count */
+    uint32_t gb_pipes;
+
+    /* Z pipe count (rv530 only) */
+    uint32_t z_pipes;
+
+    /* GART size. */
+    uint32_t gart_size;
+
+    /* VRAM size. */
+    uint32_t vram_size;
+
+    /* Add a pipe_buffer to the list of buffer objects to validate. */
+    boolean (*add_buffer)(struct radeon_winsys* winsys,
+                          struct pipe_buffer* pbuffer,
+                          uint32_t rd,
+                          uint32_t wd);
+
+    /* Revalidate all currently setup pipe_buffers.
+     * Returns TRUE if a flush is required. */
+    boolean (*validate)(struct radeon_winsys* winsys);
+
+    /* Check to see if there's room for commands. */
+    boolean (*check_cs)(struct radeon_winsys* winsys, int size);
+
+    /* Start a command emit. */
+    void (*begin_cs)(struct radeon_winsys* winsys,
+                     int size,
+                     const char* file,
+                     const char* function,
+                     int line);
+
+    /* Write a dword to the command buffer. */
+    void (*write_cs_dword)(struct radeon_winsys* winsys, uint32_t dword);
+
+    /* Write a relocated dword to the command buffer. */
+    void (*write_cs_reloc)(struct radeon_winsys* winsys,
+                           struct pipe_buffer* bo,
+                           uint32_t rd,
+                           uint32_t wd,
+                           uint32_t flags);
+
+    /* Finish a command emit. */
+    void (*end_cs)(struct radeon_winsys* winsys,
+                   const char* file,
+                   const char* function,
+                   int line);
+
+    /* Flush the CS. */
+    void (*flush_cs)(struct radeon_winsys* winsys);
+
+    /* winsys flush - callback from winsys when flush required */
+    void (*set_flush_cb)(struct radeon_winsys *winsys,
+			 void (*flush_cb)(void *), void *data);
+
+    void (*reset_bos)(struct radeon_winsys *winsys);
+};
+
+#endif
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.h b/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.h
deleted file mode 100644
index 04740e4..0000000
--- a/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* 
- * Copyright © 2008 Jérôme Glisse
- * 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 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 THE COPYRIGHT HOLDERS, AUTHORS
- * 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.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- */
-/*
- * Authors:
- *      Jérôme Glisse <glisse@freedesktop.org>
- */
-#ifndef RADEON_WINSYS_SOFTPIPE_H
-#define RADEON_WINSYS_SOFTPIPE_H
-
-#include <stdio.h>
-
-#include "pipe/p_defines.h"
-#include "pipe/p_format.h"
-
-#include "softpipe/sp_winsys.h"
-
-#include "util/u_memory.h"
-
-struct pipe_context *radeon_create_softpipe(struct pipe_winsys* winsys);
-
-#endif
diff --git a/src/gallium/winsys/drm/radeon/dri/SConscript b/src/gallium/winsys/drm/radeon/dri/SConscript
index aea987a..c4989d1 100644
--- a/src/gallium/winsys/drm/radeon/dri/SConscript
+++ b/src/gallium/winsys/drm/radeon/dri/SConscript
@@ -13,5 +13,5 @@
 env.SharedLibrary(
     target ='radeon_dri.so',
     source = COMMON_GALLIUM_SOURCES,
-    LIBS = st_dri + radeonwinsys + mesa + drivers + auxiliaries + env['LIBS'],
+    LIBS = st_dri + radeonwinsys + mesa + drivers + gallium + env['LIBS'],
 )
diff --git a/src/gallium/winsys/drm/radeon/egl_g3d/Makefile b/src/gallium/winsys/drm/radeon/egl_g3d/Makefile
new file mode 100644
index 0000000..9027a5f
--- /dev/null
+++ b/src/gallium/winsys/drm/radeon/egl_g3d/Makefile
@@ -0,0 +1,14 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+EGL_DRIVER_NAME = r300
+EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_LIBS = -ldrm_radeon
+
+EGL_DRIVER_PIPES = \
+	$(TOP)/src/gallium/winsys/drm/radeon/core/libradeonwinsys.a \
+	$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+	$(TOP)/src/gallium/drivers/trace/libtrace.a \
+	$(TOP)/src/gallium/drivers/r300/libr300.a
+
+include ../../Makefile.egl_g3d
diff --git a/src/gallium/winsys/drm/radeon/egl_g3d/dummy.c b/src/gallium/winsys/drm/radeon/egl_g3d/dummy.c
new file mode 100644
index 0000000..4a1bc28
--- /dev/null
+++ b/src/gallium/winsys/drm/radeon/egl_g3d/dummy.c
@@ -0,0 +1 @@
+/* mklib expects at least one object file */
diff --git a/src/gallium/winsys/drm/radeon/python/SConscript b/src/gallium/winsys/drm/radeon/python/SConscript
index 3200fd8..91cae98 100644
--- a/src/gallium/winsys/drm/radeon/python/SConscript
+++ b/src/gallium/winsys/drm/radeon/python/SConscript
@@ -29,5 +29,5 @@
     env.SharedLibrary(
         target ='_gallium',
         source = sources,
-        LIBS = [pyst] + drivers + auxiliaries + env['LIBS'],
+        LIBS = [pyst] + drivers + gallium + env['LIBS'],
     )
diff --git a/src/gallium/winsys/drm/radeon/xorg/Makefile b/src/gallium/winsys/drm/radeon/xorg/Makefile
index 9fa16da..0eb1b39 100644
--- a/src/gallium/winsys/drm/radeon/xorg/Makefile
+++ b/src/gallium/winsys/drm/radeon/xorg/Makefile
@@ -1,11 +1,16 @@
-TARGET     = modesetting_drv.so
-CFILES     = $(wildcard ./*.c)
-OBJECTS    = $(patsubst ./%.c,./%.o,$(CFILES))
-GALLIUMDIR = ../../../..
 TOP        = ../../../../../..
 
+
+GALLIUMDIR = $(TOP)/src/gallium
+
+TARGET     = radeong_drv.so
+
+CFILES     = $(wildcard ./*.c)
+
 include ${TOP}/configs/current
 
+OBJECTS    = $(patsubst ./%.c,./%.o,$(CFILES))
+
 CFLAGS = -DHAVE_CONFIG_H \
          -g -Wall -Wimplicit-function-declaration -fPIC \
          $(shell pkg-config --cflags pixman-1 xorg-server libdrm xproto) \
@@ -24,16 +29,21 @@
 	$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
 	$(GALLIUM_AUXILIARIES)
 
+TARGET_STAGING = $(TOP)/$(LIB_DIR)/gallium/$(TARGET)
 #############################################
 
+all default: $(TARGET) $(TARGET_STAGING)
 
-
-all default: $(TARGET)
-
-$(TARGET): $(OBJECTS) Makefile $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a
+$(TARGET): $(OBJECTS) Makefile $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a $(LIBS)
 	$(TOP)/bin/mklib -noprefix -o $@ \
 	$(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_radeon
 
+$(TOP)/$(LIB_DIR)/gallium:
+	mkdir -p $@
+
+$(TARGET_STAGING): $(TARGET) $(TOP)/$(LIB_DIR)/gallium
+	$(INSTALL) $(TARGET) $(TOP)/$(LIB_DIR)/gallium
+
 clean:
 	rm -rf $(OBJECTS) $(TARGET)
 
diff --git a/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c b/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c
index 837f2aa..bb76cc0 100644
--- a/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c
+++ b/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c
@@ -53,7 +53,7 @@
 };
 
 static XF86ModuleVersionInfo radeon_xorg_version = {
-    "modesetting",
+    "radeong",
     MODULEVENDORSTRING,
     MODINFOSTRING1,
     MODINFOSTRING2,
@@ -69,9 +69,9 @@
  * Xorg driver exported structures
  */
 
-_X_EXPORT DriverRec modesetting = {
+_X_EXPORT DriverRec radeong = {
     1,
-    "modesetting",
+    "radeong",
     radeon_xorg_identify,
     NULL,
     xorg_tracker_available_options,
@@ -84,7 +84,7 @@
 
 static MODULESETUPPROTO(radeon_xorg_setup);
 
-_X_EXPORT XF86ModuleData modesettingModuleData = {
+_X_EXPORT XF86ModuleData radeongModuleData = {
     &radeon_xorg_version,
     radeon_xorg_setup,
     NULL
@@ -103,7 +103,7 @@
      */
     if (!setupDone) {
 	setupDone = 1;
-	xf86AddDriver(&modesetting, module, HaveDriverFuncs);
+	xf86AddDriver(&radeong, module, HaveDriverFuncs);
 
 	/*
 	 * The return value must be non-NULL on success even though there
@@ -120,7 +120,7 @@
 static void
 radeon_xorg_identify(int flags)
 {
-    xf86PrintChipsets("modesetting", "Driver for Modesetting Kernel Drivers",
+    xf86PrintChipsets("radeong", "Driver for Radeon Gallium with KMS",
 		      radeon_xorg_chipsets);
 }
 
@@ -135,8 +135,8 @@
 			       NULL, NULL, NULL, NULL, NULL);
     if (scrn != NULL) {
 	scrn->driverVersion = 1;
-	scrn->driverName = "radeon";
-	scrn->name = "modesetting";
+	scrn->driverName = "radeong";
+	scrn->name = "radeong";
 	scrn->Probe = NULL;
 
 	entity = xf86GetEntityInfo(entity_num);
diff --git a/src/gallium/winsys/drm/vmware/Makefile b/src/gallium/winsys/drm/vmware/Makefile
new file mode 100644
index 0000000..2ae6dea
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/Makefile
@@ -0,0 +1,12 @@
+# src/gallium/winsys/drm/vmware/Makefile
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+SUBDIRS = core $(GALLIUM_STATE_TRACKERS_DIRS)
+
+default install clean:
+	@for dir in $(SUBDIRS) ; do \
+		if [ -d $$dir ] ; then \
+			(cd $$dir && $(MAKE) $@) || exit 1; \
+		fi \
+	done
diff --git a/src/gallium/winsys/drm/vmware/SConscript b/src/gallium/winsys/drm/vmware/SConscript
new file mode 100644
index 0000000..06e6d5b
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/SConscript
@@ -0,0 +1,11 @@
+Import('*')
+
+SConscript(['core/SConscript',])
+
+if 'mesa' in env['statetrackers']:
+
+    SConscript(['dri/SConscript'])
+
+if 'xorg' in env['statetrackers']:
+
+    SConscript(['xorg/SConscript'])
diff --git a/src/gallium/winsys/drm/vmware/core/Makefile b/src/gallium/winsys/drm/vmware/core/Makefile
new file mode 100644
index 0000000..a52957c
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/Makefile
@@ -0,0 +1,35 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = svgadrm
+
+C_SOURCES = \
+        vmw_buffer.c \
+        vmw_context.c  \
+        vmw_fence.c  \
+        vmw_screen.c  \
+        vmw_screen_dri.c  \
+        vmw_screen_ioctl.c  \
+        vmw_screen_pools.c  \
+        vmw_screen_svga.c  \
+        vmw_surface.c
+
+LIBRARY_INCLUDES = \
+       -I$(TOP)/src/gallium/drivers/svga \
+       -I$(TOP)/src/gallium/drivers/svga/include \
+       -I$(GALLIUM)/src/mesa/drivers/dri/common \
+       -I$(GALLIUM)/include \
+       -I$(GALLIUM)/include/GL/internal \
+       -I$(GALLIUM)/src/mesa \
+       -I$(GALLIUM)/src/mesa/main \
+       -I$(GALLIUM)/src/mesa/glapi \
+       -I$(GALLIUM)/src/egl/main \
+       -I$(GALLIUM)/src/egl/drivers/dri \
+       $(shell pkg-config libdrm --cflags-only-I)
+
+LIBRARY_DEFINES = \
+       -std=gnu99 -fvisibility=hidden \
+       -DHAVE_STDINT_H -D_FILE_OFFSET_BITS=64 \
+       $(shell pkg-config libdrm --cflags-only-other)
+
+include ../../../../Makefile.template
diff --git a/src/gallium/winsys/drm/vmware/core/SConscript b/src/gallium/winsys/drm/vmware/core/SConscript
new file mode 100644
index 0000000..edaf945
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/SConscript
@@ -0,0 +1,39 @@
+Import('*')
+
+env = env.Clone()
+
+if env['gcc']:
+	env.Append(CCFLAGS = ['-fvisibility=hidden'])
+	env.Append(CPPDEFINES = [
+		'HAVE_STDINT_H', 
+		'HAVE_SYS_TYPES_H',
+                '-D_FILE_OFFSET_BITS=64',
+	])
+	
+env.Prepend(CPPPATH = [
+	'include',
+        '#/src/gallium/drivers/svga',
+        '#/src/gallium/drivers/svga/include',
+])
+
+env.Append(CPPDEFINES = [
+])
+
+sources = [
+        'vmw_buffer.c',
+        'vmw_context.c',
+        'vmw_fence.c',
+        'vmw_screen.c',
+        'vmw_screen_dri.c',
+        'vmw_screen_ioctl.c',
+        'vmw_screen_pools.c',
+        'vmw_screen_svga.c',
+        'vmw_surface.c',
+]
+
+svgadrm = env.ConvenienceLibrary(
+	target = 'svgadrm',
+	source = sources,
+)
+
+Export('svgadrm')
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_buffer.c b/src/gallium/winsys/drm/vmware/core/vmw_buffer.c
new file mode 100644
index 0000000..b812fb5
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_buffer.c
@@ -0,0 +1,274 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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
+ * SVGA buffer manager for Guest Memory Regions (GMRs).
+ * 
+ * GMRs are used for pixel and vertex data upload/download to/from the virtual
+ * SVGA hardware. There is a limited number of GMRs available, and 
+ * creating/destroying them is also a slow operation so we must suballocate 
+ * them.
+ * 
+ * This file implements a pipebuffer library's buffer manager, so that we can
+ * use pipepbuffer's suballocation, fencing, and debugging facilities with GMRs. 
+ * 
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include "svga_cmd.h"
+
+#include "pipe/p_inlines.h"
+#include "util/u_memory.h"
+#include "pipebuffer/pb_buffer.h"
+#include "pipebuffer/pb_bufmgr.h"
+
+#include "svga_winsys.h"
+
+#include "vmw_screen.h"
+#include "vmw_buffer.h"
+
+
+struct vmw_gmr_bufmgr;
+
+
+struct vmw_gmr_buffer
+{
+   struct pb_buffer base;
+   
+   struct vmw_gmr_bufmgr *mgr;
+   
+   struct vmw_region *region;
+   void *map;
+   
+#ifdef DEBUG
+   struct pipe_fence_handle *last_fence;
+#endif
+};
+
+
+extern const struct pb_vtbl vmw_gmr_buffer_vtbl;
+
+
+static INLINE struct vmw_gmr_buffer *
+vmw_gmr_buffer(struct pb_buffer *buf)
+{
+   assert(buf);
+   assert(buf->vtbl == &vmw_gmr_buffer_vtbl);
+   return (struct vmw_gmr_buffer *)buf;
+}
+
+
+struct vmw_gmr_bufmgr
+{
+   struct pb_manager base;
+   
+   struct vmw_winsys_screen *vws;
+};
+
+
+static INLINE struct vmw_gmr_bufmgr *
+vmw_gmr_bufmgr(struct pb_manager *mgr)
+{
+   assert(mgr);
+   return (struct vmw_gmr_bufmgr *)mgr;
+}
+
+
+static void
+vmw_gmr_buffer_destroy(struct pb_buffer *_buf)
+{
+   struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
+
+#ifdef DEBUG
+   if(buf->last_fence) {
+      struct svga_winsys_screen *sws = &buf->mgr->vws->base;
+      assert(sws->fence_signalled(sws, buf->last_fence, 0) == 0);
+   }
+#endif
+
+   vmw_ioctl_region_unmap(buf->region);
+   
+   vmw_ioctl_region_destroy(buf->region);
+
+   FREE(buf);
+}
+
+
+static void *
+vmw_gmr_buffer_map(struct pb_buffer *_buf,
+               unsigned flags)
+{
+   struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
+   return buf->map;
+}
+
+
+static void
+vmw_gmr_buffer_unmap(struct pb_buffer *_buf)
+{
+   /* Do nothing */
+   (void)_buf;
+}
+
+
+static void
+vmw_gmr_buffer_get_base_buffer(struct pb_buffer *buf,
+                           struct pb_buffer **base_buf,
+                           unsigned *offset)
+{
+   *base_buf = buf;
+   *offset = 0;
+}
+
+
+static enum pipe_error
+vmw_gmr_buffer_validate( struct pb_buffer *_buf, 
+                         struct pb_validate *vl,
+                         unsigned flags )
+{
+   /* Always pinned */
+   return PIPE_OK;
+}
+
+
+static void
+vmw_gmr_buffer_fence( struct pb_buffer *_buf, 
+                      struct pipe_fence_handle *fence )
+{
+   /* We don't need to do anything, as the pipebuffer library
+    * will take care of delaying the destruction of fenced buffers */  
+#ifdef DEBUG
+   struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
+   if(fence)
+      buf->last_fence = fence;
+#endif
+}
+
+
+const struct pb_vtbl vmw_gmr_buffer_vtbl = {
+   vmw_gmr_buffer_destroy,
+   vmw_gmr_buffer_map,
+   vmw_gmr_buffer_unmap,
+   vmw_gmr_buffer_validate,
+   vmw_gmr_buffer_fence,
+   vmw_gmr_buffer_get_base_buffer
+};
+
+
+static struct pb_buffer *
+vmw_gmr_bufmgr_create_buffer(struct pb_manager *_mgr,
+                         pb_size size,
+                         const struct pb_desc *desc) 
+{
+   struct vmw_gmr_bufmgr *mgr = vmw_gmr_bufmgr(_mgr);
+   struct vmw_winsys_screen *vws = mgr->vws;
+   struct vmw_gmr_buffer *buf;
+   
+   buf = CALLOC_STRUCT(vmw_gmr_buffer);
+   if(!buf)
+      goto error1;
+
+   pipe_reference_init(&buf->base.base.reference, 1);
+   buf->base.base.alignment = desc->alignment;
+   buf->base.base.usage = desc->usage;
+   buf->base.base.size = size;
+   buf->base.vtbl = &vmw_gmr_buffer_vtbl;
+   buf->mgr = mgr;
+
+   buf->region = vmw_ioctl_region_create(vws, size);
+   if(!buf->region)
+      goto error2;
+	 
+   buf->map = vmw_ioctl_region_map(buf->region);
+   if(!buf->map)
+      goto error3;
+
+   return &buf->base;
+
+error3:
+   vmw_ioctl_region_destroy(buf->region);
+error2:
+   FREE(buf);
+error1:
+   return NULL;
+}
+
+
+static void
+vmw_gmr_bufmgr_flush(struct pb_manager *mgr) 
+{
+   /* No-op */
+}
+
+
+static void
+vmw_gmr_bufmgr_destroy(struct pb_manager *_mgr) 
+{
+   struct vmw_gmr_bufmgr *mgr = vmw_gmr_bufmgr(_mgr);
+   FREE(mgr);
+}
+
+
+struct pb_manager *
+vmw_gmr_bufmgr_create(struct vmw_winsys_screen *vws) 
+{
+   struct vmw_gmr_bufmgr *mgr;
+   
+   mgr = CALLOC_STRUCT(vmw_gmr_bufmgr);
+   if(!mgr)
+      return NULL;
+
+   mgr->base.destroy = vmw_gmr_bufmgr_destroy;
+   mgr->base.create_buffer = vmw_gmr_bufmgr_create_buffer;
+   mgr->base.flush = vmw_gmr_bufmgr_flush;
+   
+   mgr->vws = vws;
+   
+   return &mgr->base;
+}
+
+
+boolean
+vmw_gmr_bufmgr_region_ptr(struct pb_buffer *buf, 
+                          struct SVGAGuestPtr *ptr)
+{
+   struct pb_buffer *base_buf;
+   unsigned offset = 0;
+   struct vmw_gmr_buffer *gmr_buf;
+   
+   pb_get_base_buffer( buf, &base_buf, &offset );
+   
+   gmr_buf = vmw_gmr_buffer(base_buf);
+   if(!gmr_buf)
+      return FALSE;
+   
+   *ptr = vmw_ioctl_region_ptr(gmr_buf->region);
+   
+   ptr->offset += offset;
+   
+   return TRUE;
+}
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_buffer.h b/src/gallium/winsys/drm/vmware/core/vmw_buffer.h
new file mode 100644
index 0000000..634bdca
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_buffer.h
@@ -0,0 +1,65 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+
+#ifndef VMW_BUFFER_H_
+#define VMW_BUFFER_H_
+
+
+#include "pipe/p_compiler.h"
+
+struct SVGAGuestPtr;
+struct pb_buffer;
+struct pb_manager;
+struct svga_winsys_buffer;
+struct svga_winsys_surface;
+struct vmw_winsys_screen;
+
+
+static INLINE struct pb_buffer *
+vmw_pb_buffer(struct svga_winsys_buffer *buffer)
+{
+   assert(buffer);
+   return (struct pb_buffer *)buffer;
+}
+
+
+static INLINE struct svga_winsys_buffer *
+vmw_svga_winsys_buffer(struct pb_buffer *buffer)
+{
+   assert(buffer);
+   return (struct svga_winsys_buffer *)buffer;
+}
+
+
+struct pb_manager *
+vmw_gmr_bufmgr_create(struct vmw_winsys_screen *vws);
+
+boolean
+vmw_gmr_bufmgr_region_ptr(struct pb_buffer *buf, 
+                          struct SVGAGuestPtr *ptr);
+
+
+#endif /* VMW_BUFFER_H_ */
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_context.c b/src/gallium/winsys/drm/vmware/core/vmw_context.c
new file mode 100644
index 0000000..b699758
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_context.c
@@ -0,0 +1,297 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "svga_cmd.h"
+
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+#include "util/u_debug_stack.h"
+#include "pipebuffer/pb_buffer.h"
+#include "pipebuffer/pb_validate.h"
+
+#include "svga_winsys.h"
+#include "vmw_context.h"
+#include "vmw_screen.h"
+#include "vmw_buffer.h"
+#include "vmw_surface.h"
+#include "vmw_fence.h"
+
+#define VMW_COMMAND_SIZE (64*1024)
+#define VMW_SURFACE_RELOCS (1024)
+
+#define VMW_MUST_FLUSH_STACK 8
+
+struct vmw_svga_winsys_context
+{
+   struct svga_winsys_context base;
+
+   struct vmw_winsys_screen *vws;
+
+#ifdef DEBUG
+   boolean must_flush;
+   struct debug_stack_frame must_flush_stack[VMW_MUST_FLUSH_STACK];
+#endif
+
+   struct {
+      uint8_t buffer[VMW_COMMAND_SIZE];
+      uint32_t size;
+      uint32_t used;
+      uint32_t reserved;
+   } command;
+
+   struct {
+      struct vmw_svga_winsys_surface *handles[VMW_SURFACE_RELOCS];
+      uint32_t size;
+      uint32_t used;
+      uint32_t staged;
+      uint32_t reserved;
+   } surface;
+
+   struct pb_validate *validate;
+
+   uint32_t last_fence;
+};
+
+
+static INLINE struct vmw_svga_winsys_context *
+vmw_svga_winsys_context(struct svga_winsys_context *swc)
+{
+   assert(swc);
+   return (struct vmw_svga_winsys_context *)swc;
+}
+
+
+static enum pipe_error
+vmw_swc_flush(struct svga_winsys_context *swc,
+              struct pipe_fence_handle **pfence)
+{
+   struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+   struct pipe_fence_handle *fence = NULL;
+   unsigned i;
+   enum pipe_error ret;
+
+   ret = pb_validate_validate(vswc->validate);
+   assert(ret == PIPE_OK);
+   if(ret == PIPE_OK) {
+
+      if (vswc->command.used)
+         vmw_ioctl_command(vswc->vws,
+                           vswc->command.buffer,
+                           vswc->command.used,
+                           &vswc->last_fence);
+
+      fence = vmw_pipe_fence(vswc->last_fence);
+
+      pb_validate_fence(vswc->validate, fence);
+   }
+
+   vswc->command.used = 0;
+   vswc->command.reserved = 0;
+
+   for(i = 0; i < vswc->surface.used + vswc->surface.staged; ++i) {
+      struct vmw_svga_winsys_surface *vsurf =
+	 vswc->surface.handles[i];
+      p_atomic_dec(&vsurf->validated);
+      vmw_svga_winsys_surface_reference(&vswc->surface.handles[i], NULL);
+   }
+
+   vswc->surface.used = 0;
+   vswc->surface.reserved = 0;
+
+#ifdef DEBUG
+   vswc->must_flush = FALSE;
+#endif
+
+   if(pfence)
+      *pfence = fence;
+
+   return ret;
+}
+
+
+static void *
+vmw_swc_reserve(struct svga_winsys_context *swc,
+                uint32_t nr_bytes, uint32_t nr_relocs )
+{
+   struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+
+#ifdef DEBUG
+   /* Check if somebody forgot to check the previous failure */
+   if(vswc->must_flush) {
+      debug_printf("Forgot to flush:\n");
+      debug_backtrace_dump(vswc->must_flush_stack, VMW_MUST_FLUSH_STACK);
+      assert(!vswc->must_flush);
+   }
+#endif
+
+   assert(nr_bytes <= vswc->command.size);
+   if(nr_bytes > vswc->command.size)
+      return NULL;
+
+   if(vswc->command.used + nr_bytes > vswc->command.size ||
+      vswc->surface.used + nr_relocs > vswc->surface.size) {
+#ifdef DEBUG
+      vswc->must_flush = TRUE;
+      debug_backtrace_capture(vswc->must_flush_stack, 1,
+                              VMW_MUST_FLUSH_STACK);
+#endif
+      return NULL;
+   }
+
+   assert(vswc->command.used + nr_bytes <= vswc->command.size);
+   assert(vswc->surface.used + nr_relocs <= vswc->surface.size);
+
+   vswc->command.reserved = nr_bytes;
+   vswc->surface.reserved = nr_relocs;
+   vswc->surface.staged = 0;
+
+   return vswc->command.buffer + vswc->command.used;
+}
+
+
+static void
+vmw_swc_surface_relocation(struct svga_winsys_context *swc,
+                           uint32 *where,
+                           struct svga_winsys_surface *surface,
+                           unsigned flags)
+{
+   struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+   struct vmw_svga_winsys_surface *vsurf;
+
+   if(!surface) {
+      *where = SVGA3D_INVALID_ID;
+      return;
+   }
+
+   assert(vswc->surface.staged < vswc->surface.reserved);
+
+   vsurf = vmw_svga_winsys_surface(surface);
+
+   *where = vsurf->sid;
+
+   vmw_svga_winsys_surface_reference(&vswc->surface.handles[vswc->surface.used + vswc->surface.staged], vsurf);
+   p_atomic_inc(&vsurf->validated);
+   ++vswc->surface.staged;
+}
+
+
+static void
+vmw_swc_region_relocation(struct svga_winsys_context *swc,
+                          struct SVGAGuestPtr *where,
+                          struct svga_winsys_buffer *buffer,
+                          uint32 offset,
+                          unsigned flags)
+{
+   struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+   struct SVGAGuestPtr ptr;
+   struct pb_buffer *buf = vmw_pb_buffer(buffer);
+   enum pipe_error ret;
+
+   if(!vmw_gmr_bufmgr_region_ptr(buf, &ptr))
+      assert(0);
+
+   ptr.offset += offset;
+
+   *where = ptr;
+
+   ret = pb_validate_add_buffer(vswc->validate, buf, flags);
+   /* TODO: Update pipebuffer to reserve buffers and not fail here */
+   assert(ret == PIPE_OK);
+}
+
+
+static void
+vmw_swc_commit(struct svga_winsys_context *swc)
+{
+   struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+
+   assert(vswc->command.reserved);
+   assert(vswc->command.used + vswc->command.reserved <= vswc->command.size);
+   vswc->command.used += vswc->command.reserved;
+   vswc->command.reserved = 0;
+
+   assert(vswc->surface.staged <= vswc->surface.reserved);
+   assert(vswc->surface.used + vswc->surface.staged <= vswc->surface.size);
+   vswc->surface.used += vswc->surface.staged;
+   vswc->surface.staged = 0;
+   vswc->surface.reserved = 0;
+}
+
+
+static void
+vmw_swc_destroy(struct svga_winsys_context *swc)
+{
+   struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+   unsigned i;
+   for(i = 0; i < vswc->surface.used; ++i) {
+      p_atomic_dec(&vswc->surface.handles[i]->validated);
+      vmw_svga_winsys_surface_reference(&vswc->surface.handles[i], NULL);
+   }
+   pb_validate_destroy(vswc->validate);
+   vmw_ioctl_context_destroy(vswc->vws, swc->cid);
+   FREE(vswc);
+}
+
+
+struct svga_winsys_context *
+vmw_svga_winsys_context_create(struct svga_winsys_screen *sws)
+{
+   struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+   struct vmw_svga_winsys_context *vswc;
+
+   vswc = CALLOC_STRUCT(vmw_svga_winsys_context);
+   if(!vswc)
+      return NULL;
+
+   vswc->base.destroy = vmw_swc_destroy;
+   vswc->base.reserve = vmw_swc_reserve;
+   vswc->base.surface_relocation = vmw_swc_surface_relocation;
+   vswc->base.region_relocation = vmw_swc_region_relocation;
+   vswc->base.commit = vmw_swc_commit;
+   vswc->base.flush = vmw_swc_flush;
+
+   vswc->base.cid = vmw_ioctl_context_create(vws);
+
+   vswc->vws = vws;
+
+   vswc->command.size = VMW_COMMAND_SIZE;
+   vswc->surface.size = VMW_SURFACE_RELOCS;
+
+   vswc->validate = pb_validate_create();
+   if(!vswc->validate) {
+      FREE(vswc);
+      return NULL;
+   }
+
+   return &vswc->base;
+}
+
+
+struct pipe_context *
+vmw_svga_context_create(struct pipe_screen *screen)
+{
+   return svga_context_create(screen);
+}
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_context.h b/src/gallium/winsys/drm/vmware/core/vmw_context.h
new file mode 100644
index 0000000..305ce9b
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_context.h
@@ -0,0 +1,59 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+/**
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#ifndef VMW_CONTEXT_H_
+#define VMW_CONTEXT_H_
+
+#include "pipe/p_compiler.h"
+
+struct svga_winsys_screen;
+struct svga_winsys_context;
+struct pipe_context;
+struct pipe_screen;
+
+#define VMW_DEBUG 0
+
+#if VMW_DEBUG
+#define vmw_printf debug_printf
+#define VMW_FUNC  debug_printf("%s\n", __FUNCTION__)
+#else
+#define VMW_FUNC
+#define vmw_printf(...)
+#endif
+
+
+struct svga_winsys_context *
+vmw_svga_winsys_context_create(struct svga_winsys_screen *sws);
+
+struct pipe_context *
+vmw_svga_context_create(struct pipe_screen *screen);
+
+
+#endif /* VMW_CONTEXT_H_ */
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_fence.c b/src/gallium/winsys/drm/vmware/core/vmw_fence.c
new file mode 100644
index 0000000..873dd51
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_fence.c
@@ -0,0 +1,108 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "util/u_memory.h"
+#include "pipebuffer/pb_buffer_fenced.h"
+
+#include "vmw_screen.h"
+#include "vmw_fence.h"
+
+
+
+struct vmw_fence_ops 
+{
+   struct pb_fence_ops base;
+
+   struct vmw_winsys_screen *vws;
+};
+
+
+static INLINE struct vmw_fence_ops *
+vmw_fence_ops(struct pb_fence_ops *ops)
+{
+   assert(ops);
+   return (struct vmw_fence_ops *)ops;
+}
+
+
+static void
+vmw_fence_ops_fence_reference(struct pb_fence_ops *ops,
+                              struct pipe_fence_handle **ptr,
+                              struct pipe_fence_handle *fence)
+{
+   *ptr = fence;
+}
+
+
+static int
+vmw_fence_ops_fence_signalled(struct pb_fence_ops *ops,
+                              struct pipe_fence_handle *fence,
+                              unsigned flag)
+{
+   struct vmw_winsys_screen *vws = vmw_fence_ops(ops)->vws;
+   (void)flag;
+   return vmw_ioctl_fence_signalled(vws, vmw_fence(fence));
+}
+
+
+static int
+vmw_fence_ops_fence_finish(struct pb_fence_ops *ops,
+                           struct pipe_fence_handle *fence,
+                           unsigned flag)
+{
+   struct vmw_winsys_screen *vws = vmw_fence_ops(ops)->vws;
+   (void)flag;
+   return vmw_ioctl_fence_finish(vws, vmw_fence(fence));
+}
+
+
+static void
+vmw_fence_ops_destroy(struct pb_fence_ops *ops)
+{
+   FREE(ops);
+}
+
+
+struct pb_fence_ops *
+vmw_fence_ops_create(struct vmw_winsys_screen *vws) 
+{
+   struct vmw_fence_ops *ops;
+
+   ops = CALLOC_STRUCT(vmw_fence_ops);
+   if(!ops)
+      return NULL;
+
+   ops->base.destroy = &vmw_fence_ops_destroy;
+   ops->base.fence_reference = &vmw_fence_ops_fence_reference;
+   ops->base.fence_signalled = &vmw_fence_ops_fence_signalled;
+   ops->base.fence_finish = &vmw_fence_ops_fence_finish;
+
+   ops->vws = vws;
+
+   return &ops->base;
+}
+
+
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_fence.h b/src/gallium/winsys/drm/vmware/core/vmw_fence.h
new file mode 100644
index 0000000..5357b4f
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_fence.h
@@ -0,0 +1,59 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+
+#ifndef VMW_FENCE_H_
+#define VMW_FENCE_H_
+
+
+#include "pipe/p_compiler.h"
+
+
+struct pipe_fence_handle;
+struct pb_fence_ops;
+struct vmw_winsys_screen;
+
+
+/** Cast from a pipe_fence_handle pointer into a SVGA fence */
+static INLINE uint32_t
+vmw_fence( struct pipe_fence_handle *fence )
+{
+   return (uint32_t)(uintptr_t)fence;
+}
+
+
+/** Cast from a SVGA fence number to pipe_fence_handle pointer */
+static INLINE struct pipe_fence_handle *
+vmw_pipe_fence( uint32_t fence )
+{
+   return (struct pipe_fence_handle *)(uintptr_t)fence;
+}
+
+
+struct pb_fence_ops *
+vmw_fence_ops_create(struct vmw_winsys_screen *vws); 
+
+
+#endif /* VMW_FENCE_H_ */
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen.c b/src/gallium/winsys/drm/vmware/core/vmw_screen.c
new file mode 100644
index 0000000..911eec5
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen.c
@@ -0,0 +1,74 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "vmw_screen.h"
+
+#include "vmw_context.h"
+
+#include "util/u_memory.h"
+#include "pipe/p_compiler.h"
+
+
+/* Called from vmw_drm_create_screen(), creates and initializes the
+ * vmw_winsys_screen structure, which is the main entity in this
+ * module.
+ */
+struct vmw_winsys_screen *
+vmw_winsys_create( int fd )
+{
+   struct vmw_winsys_screen *vws = CALLOC_STRUCT(vmw_winsys_screen);
+   if (!vws)
+      goto out_no_vws;
+
+   vws->ioctl.drm_fd = fd;
+
+   if (!vmw_ioctl_init(vws))
+      goto out_no_ioctl;
+
+   if(!vmw_pools_init(vws))
+      goto out_no_pools;
+
+   if (!vmw_winsys_screen_init_svga(vws))
+      goto out_no_svga;
+
+   return vws;
+out_no_svga:
+   vmw_pools_cleanup(vws);
+out_no_pools:
+   vmw_ioctl_cleanup(vws);
+out_no_ioctl:
+   FREE(vws);
+out_no_vws:
+   return NULL;
+}
+
+void
+vmw_winsys_destroy(struct vmw_winsys_screen *vws)
+{
+   vmw_pools_cleanup(vws);
+   vmw_ioctl_cleanup(vws);
+   FREE(vws);
+}
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen.h b/src/gallium/winsys/drm/vmware/core/vmw_screen.h
new file mode 100644
index 0000000..a875107
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen.h
@@ -0,0 +1,134 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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
+ * Common definitions for the VMware SVGA winsys.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#ifndef VMW_SCREEN_H_
+#define VMW_SCREEN_H_
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+
+#include "svga_winsys.h"
+
+struct pb_manager;
+struct vmw_region;
+
+
+struct vmw_winsys_screen
+{
+   struct svga_winsys_screen base;
+
+   struct {
+      volatile uint32_t *fifo_map;
+      uint64_t last_fence;
+      int drm_fd;
+   } ioctl;
+
+   struct {
+      struct pb_manager *gmr;
+      struct pb_manager *gmr_mm;
+      struct pb_manager *gmr_fenced;
+   } pools;
+};
+
+
+static INLINE struct vmw_winsys_screen *
+vmw_winsys_screen(struct svga_winsys_screen *base)
+{
+   return (struct vmw_winsys_screen *)base;
+}
+
+/*  */
+uint32
+vmw_ioctl_context_create(struct vmw_winsys_screen *vws);
+
+void
+vmw_ioctl_context_destroy(struct vmw_winsys_screen *vws,
+                          uint32 cid);
+
+uint32
+vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
+                              SVGA3dSurfaceFlags flags,
+                              SVGA3dSurfaceFormat format,
+                              SVGA3dSize size,
+                              uint32 numFaces,
+                              uint32 numMipLevels);
+
+void
+vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws,
+                          uint32 sid);
+
+void
+vmw_ioctl_command(struct vmw_winsys_screen *vws,
+                       void *commands,
+                       uint32_t size,
+                       uint32_t *fence);
+
+struct vmw_region *
+vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size);
+
+void
+vmw_ioctl_region_destroy(struct vmw_region *region);
+
+struct SVGAGuestPtr
+vmw_ioctl_region_ptr(struct vmw_region *region);
+
+void *
+vmw_ioctl_region_map(struct vmw_region *region);
+void
+vmw_ioctl_region_unmap(struct vmw_region *region);
+
+
+int
+vmw_ioctl_fence_finish(struct vmw_winsys_screen *vws,
+                       uint32_t fence);
+
+int
+vmw_ioctl_fence_signalled(struct vmw_winsys_screen *vws,
+                          uint32_t fence);
+
+
+/* Initialize parts of vmw_winsys_screen at startup:
+ */
+boolean vmw_ioctl_init(struct vmw_winsys_screen *vws);
+boolean vmw_pools_init(struct vmw_winsys_screen *vws);
+boolean vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws);
+
+void vmw_ioctl_cleanup(struct vmw_winsys_screen *vws);
+void vmw_pools_cleanup(struct vmw_winsys_screen *vws);
+
+struct vmw_winsys_screen *vmw_winsys_create(int fd);
+void vmw_winsys_destroy(struct vmw_winsys_screen *sws);
+
+
+#endif /* VMW_SCREEN_H_ */
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c b/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
new file mode 100644
index 0000000..4f5ccea
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
@@ -0,0 +1,372 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "pipe/p_inlines.h"
+#include "util/u_memory.h"
+#include "vmw_screen.h"
+
+#include "trace/tr_drm.h"
+
+#include "vmw_screen.h"
+#include "vmw_surface.h"
+#include "vmw_fence.h"
+#include "vmw_context.h"
+
+#include <state_tracker/dri1_api.h>
+#include <state_tracker/drm_api.h>
+#include <vmwgfx_drm.h>
+#include <xf86drm.h>
+
+#include <stdio.h>
+
+static struct dri1_api dri1_api_hooks;
+static struct dri1_api_version ddx_required = { 0, 1, 0 };
+static struct dri1_api_version ddx_compat = { 0, 0, 0 };
+static struct dri1_api_version dri_required = { 4, 0, 0 };
+static struct dri1_api_version dri_compat = { 4, 0, 0 };
+static struct dri1_api_version drm_required = { 0, 1, 0 };
+static struct dri1_api_version drm_compat = { 0, 0, 0 };
+
+static boolean
+vmw_dri1_check_version(const struct dri1_api_version *cur,
+		       const struct dri1_api_version *required,
+		       const struct dri1_api_version *compat,
+		       const char component[])
+{
+   if (cur->major > required->major && cur->major <= compat->major)
+      return TRUE;
+   if (cur->major == required->major && cur->minor >= required->minor)
+      return TRUE;
+
+   fprintf(stderr, "%s version failure.\n", component);
+   fprintf(stderr, "%s version is %d.%d.%d and this driver can only work\n"
+	   "with versions %d.%d.x through %d.x.x.\n",
+	   component,
+	   cur->major,
+	   cur->minor,
+	   cur->patch_level, required->major, required->minor, compat->major);
+   return FALSE;
+}
+
+/* This is actually the entrypoint to the entire driver, called by the
+ * libGL (or EGL, or ...) code via the drm_api_hooks table at the
+ * bottom of the file.
+ */
+static struct pipe_screen *
+vmw_drm_create_screen(struct drm_api *drm_api,
+                      int fd,
+                      struct drm_create_screen_arg *arg)
+{
+   struct vmw_winsys_screen *vws;
+   struct pipe_screen *screen;
+   struct dri1_create_screen_arg *dri1;
+
+   if (arg != NULL) {
+      switch (arg->mode) {
+      case DRM_CREATE_NORMAL:
+	 break;
+      case DRM_CREATE_DRI1:
+	 dri1 = (struct dri1_create_screen_arg *)arg;
+	 if (!vmw_dri1_check_version(&dri1->ddx_version, &ddx_required,
+				     &ddx_compat, "ddx - driver api"))
+	    return NULL;
+	 if (!vmw_dri1_check_version(&dri1->dri_version, &dri_required,
+				     &dri_compat, "dri info"))
+	    return NULL;
+	 if (!vmw_dri1_check_version(&dri1->drm_version, &drm_required,
+				     &drm_compat, "vmwgfx drm driver"))
+	    return NULL;
+	 dri1->api = &dri1_api_hooks;
+	 break;
+      default:
+	 return NULL;
+      }
+   }
+
+   vws = vmw_winsys_create( fd );
+   if (!vws)
+      goto out_no_vws;
+
+   screen = svga_screen_create( &vws->base );
+   if (!screen)
+      goto out_no_screen;
+
+   return screen;
+
+   /* Failure cases:
+    */
+out_no_screen:
+   vmw_winsys_destroy( vws );
+
+out_no_vws:
+   return NULL;
+}
+
+static INLINE boolean
+vmw_dri1_intersect_src_bbox(struct drm_clip_rect *dst,
+			    int dst_x,
+			    int dst_y,
+			    const struct drm_clip_rect *src,
+			    const struct drm_clip_rect *bbox)
+{
+   int xy1;
+   int xy2;
+
+   xy1 = ((int)src->x1 > (int)bbox->x1 + dst_x) ? src->x1 :
+      (int)bbox->x1 + dst_x;
+   xy2 = ((int)src->x2 < (int)bbox->x2 + dst_x) ? src->x2 :
+      (int)bbox->x2 + dst_x;
+   if (xy1 >= xy2 || xy1 < 0)
+      return FALSE;
+
+   dst->x1 = xy1;
+   dst->x2 = xy2;
+
+   xy1 = ((int)src->y1 > (int)bbox->y1 + dst_y) ? src->y1 :
+      (int)bbox->y1 + dst_y;
+   xy2 = ((int)src->y2 < (int)bbox->y2 + dst_y) ? src->y2 :
+      (int)bbox->y2 + dst_y;
+   if (xy1 >= xy2 || xy1 < 0)
+      return FALSE;
+
+   dst->y1 = xy1;
+   dst->y2 = xy2;
+   return TRUE;
+}
+
+/**
+ * No fancy get-surface-from-sarea stuff here.
+ * Just use the present blit.
+ */
+
+static void
+vmw_dri1_present_locked(struct pipe_context *locked_pipe,
+			struct pipe_surface *surf,
+			const struct drm_clip_rect *rect,
+			unsigned int num_clip,
+			int x_draw, int y_draw,
+			const struct drm_clip_rect *bbox,
+			struct pipe_fence_handle **p_fence)
+{
+   struct svga_winsys_surface *srf =
+      svga_screen_texture_get_winsys_surface(surf->texture);
+   struct vmw_svga_winsys_surface *vsrf = vmw_svga_winsys_surface(srf);
+   struct vmw_winsys_screen *vws =
+      vmw_winsys_screen(svga_winsys_screen(locked_pipe->screen));
+   struct drm_clip_rect clip;
+   int i;
+   struct
+   {
+      SVGA3dCmdHeader header;
+      SVGA3dCmdPresent body;
+      SVGA3dCopyRect rect;
+   } cmd;
+   boolean visible = FALSE;
+   uint32_t fence_seq = 0;
+
+   VMW_FUNC;
+   cmd.header.id = SVGA_3D_CMD_PRESENT;
+   cmd.header.size = sizeof cmd.body + sizeof cmd.rect;
+   cmd.body.sid = vsrf->sid;
+
+   for (i = 0; i < num_clip; ++i) {
+      if (!vmw_dri1_intersect_src_bbox(&clip, x_draw, y_draw, rect++, bbox))
+	 continue;
+
+      cmd.rect.x = clip.x1;
+      cmd.rect.y = clip.y1;
+      cmd.rect.w = clip.x2 - clip.x1;
+      cmd.rect.h = clip.y2 - clip.y1;
+      cmd.rect.srcx = (int)clip.x1 - x_draw;
+      cmd.rect.srcy = (int)clip.y1 - y_draw;
+
+      vmw_printf("%s: Clip %d x %d y %d w %d h %d srcx %d srcy %d\n",
+		   __FUNCTION__,
+		   i,
+		   cmd.rect.x,
+		   cmd.rect.y,
+		   cmd.rect.w, cmd.rect.h, cmd.rect.srcx, cmd.rect.srcy);
+
+      vmw_ioctl_command(vws, &cmd, sizeof cmd.header + cmd.header.size,
+                        &fence_seq);
+      visible = TRUE;
+   }
+
+   *p_fence = (visible) ? vmw_pipe_fence(fence_seq) : NULL;
+   vmw_svga_winsys_surface_reference(&vsrf, NULL);
+}
+
+/**
+ * FIXME: We'd probably want to cache these buffers in the
+ * screen, based on handle.
+ */
+
+static struct pipe_buffer *
+vmw_drm_buffer_from_handle(struct drm_api *drm_api,
+                           struct pipe_screen *screen,
+			   const char *name,
+			   unsigned handle)
+{
+    struct vmw_svga_winsys_surface *vsrf;
+    struct svga_winsys_surface *ssrf;
+    struct vmw_winsys_screen *vws =
+	vmw_winsys_screen(svga_winsys_screen(screen));
+    struct pipe_buffer *buf;
+    union drm_vmw_surface_reference_arg arg;
+    struct drm_vmw_surface_arg *req = &arg.req;
+    struct drm_vmw_surface_create_req *rep = &arg.rep;
+    int ret;
+    int i;
+
+    /**
+     * The vmware device specific handle is the hardware SID.
+     * FIXME: We probably want to move this to the ioctl implementations.
+     */
+
+    memset(&arg, 0, sizeof(arg));
+    req->sid = handle;
+
+    ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_REF_SURFACE,
+			      &arg, sizeof(arg));
+
+    if (ret) {
+	fprintf(stderr, "Failed referencing shared surface. SID %d.\n"
+		"Error %d (%s).\n",
+		handle, ret, strerror(-ret));
+	return NULL;
+    }
+
+    if (rep->mip_levels[0] != 1) {
+	fprintf(stderr, "Incorrect number of mipmap levels on shared surface."
+		" SID %d, levels %d\n",
+		handle, rep->mip_levels[0]);
+	goto out_mip;
+    }
+
+    for (i=1; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
+	if (rep->mip_levels[i] != 0) {
+	    fprintf(stderr, "Incorrect number of faces levels on shared surface."
+		    " SID %d, face %d present.\n",
+		    handle, i);
+	    goto out_mip;
+	}
+    }
+
+    vsrf = CALLOC_STRUCT(vmw_svga_winsys_surface);
+    if (!vsrf)
+	goto out_mip;
+
+    pipe_reference_init(&vsrf->refcnt, 1);
+    p_atomic_set(&vsrf->validated, 0);
+    vsrf->sid = handle;
+    ssrf = svga_winsys_surface(vsrf);
+    buf = svga_screen_buffer_wrap_surface(screen, rep->format, ssrf);
+    if (!buf)
+	vmw_svga_winsys_surface_reference(&vsrf, NULL);
+
+    return buf;
+  out_mip:
+    vmw_ioctl_surface_destroy(vws, handle);
+    return NULL;
+}
+
+static struct pipe_texture *
+vmw_drm_texture_from_handle(struct drm_api *drm_api,
+			    struct pipe_screen *screen,
+			    struct pipe_texture *templat,
+			    const char *name,
+			    unsigned stride,
+			    unsigned handle)
+{
+    struct pipe_buffer *buffer;
+    buffer = vmw_drm_buffer_from_handle(drm_api, screen, name, handle);
+
+    if (!buffer)
+	return NULL;
+
+    return screen->texture_blanket(screen, templat, &stride, buffer);
+}
+
+static boolean
+vmw_drm_handle_from_buffer(struct drm_api *drm_api,
+                           struct pipe_screen *screen,
+			   struct pipe_buffer *buffer,
+			   unsigned *handle)
+{
+    struct svga_winsys_surface *surface =
+	svga_screen_buffer_get_winsys_surface(buffer);
+    struct vmw_svga_winsys_surface *vsrf;
+
+    if (!surface)
+	return FALSE;
+
+    vsrf = vmw_svga_winsys_surface(surface);
+    *handle = vsrf->sid;
+    vmw_svga_winsys_surface_reference(&vsrf, NULL);
+    return TRUE;
+}
+
+static boolean
+vmw_drm_handle_from_texture(struct drm_api *drm_api,
+			    struct pipe_screen *screen,
+			    struct pipe_texture *texture,
+			    unsigned *stride,
+			    unsigned *handle)
+{
+    struct pipe_buffer *buffer;
+
+    if (!svga_screen_buffer_from_texture(texture, &buffer, stride))
+	return FALSE;
+
+    return vmw_drm_handle_from_buffer(drm_api, screen, buffer, handle);
+}
+
+static struct pipe_context*
+vmw_drm_create_context(struct drm_api *drm_api,
+                       struct pipe_screen *screen)
+{
+   return vmw_svga_context_create(screen);
+}
+
+static struct dri1_api dri1_api_hooks = {
+   .front_srf_locked = NULL,
+   .present_locked = vmw_dri1_present_locked
+};
+
+static struct drm_api vmw_drm_api_hooks = {
+   .name = "vmwgfx",
+   .create_screen = vmw_drm_create_screen,
+   .create_context = vmw_drm_create_context,
+   .texture_from_shared_handle = vmw_drm_texture_from_handle,
+   .shared_handle_from_texture = vmw_drm_handle_from_texture,
+   .local_handle_from_texture = vmw_drm_handle_from_texture,
+};
+
+struct drm_api* drm_api_create()
+{
+   return trace_drm_create(&vmw_drm_api_hooks);
+}
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c b/src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c
new file mode 100644
index 0000000..ccd0b41
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c
@@ -0,0 +1,513 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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
+ *
+ * Wrappers for DRM ioctl functionlaity used by the rest of the vmw
+ * drm winsys.
+ *
+ * Based on svgaicd_escape.c
+ */
+
+
+#include "svga_cmd.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "svgadump/svga_dump.h"
+#include "vmw_screen.h"
+#include "vmw_context.h"
+#include "xf86drm.h"
+#include "vmwgfx_drm.h"
+
+#include <sys/mman.h>
+#include <errno.h>
+#include <unistd.h>
+
+struct vmw_region
+{
+   SVGAGuestPtr ptr;
+   uint32_t handle;
+   uint64_t map_handle;
+   void *data;
+   uint32_t map_count;
+   int drm_fd;
+   uint32_t size;
+};
+
+static void
+vmw_check_last_cmd(struct vmw_winsys_screen *vws)
+{
+   static uint32_t buffer[16384];
+   struct drm_vmw_fifo_debug_arg arg;
+   int ret;
+
+   return;
+   memset(&arg, 0, sizeof(arg));
+   arg.debug_buffer = (unsigned long)buffer;
+   arg.debug_buffer_size = 65536;
+
+   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_FIFO_DEBUG,
+			     &arg, sizeof(arg));
+
+   if (ret) {
+      debug_printf("%s Ioctl error: \"%s\".\n", __FUNCTION__, strerror(-ret));
+      return;
+   }
+
+   if (arg.did_not_fit) {
+      debug_printf("%s Command did not fit completely.\n", __FUNCTION__);
+   }
+
+   svga_dump_commands(buffer, arg.used_size);
+}
+
+static void
+vmw_ioctl_fifo_unmap(struct vmw_winsys_screen *vws, void *mapping)
+{
+   VMW_FUNC;
+   (void)munmap(mapping, getpagesize());
+}
+
+
+static void *
+vmw_ioctl_fifo_map(struct vmw_winsys_screen *vws,
+                   uint32_t fifo_offset )
+{
+   void *map;
+
+   VMW_FUNC;
+
+   map = mmap(NULL, getpagesize(), PROT_READ, MAP_SHARED,
+	      vws->ioctl.drm_fd, fifo_offset);
+
+   if (map == MAP_FAILED) {
+      debug_printf("Map failed %s\n", strerror(errno));
+      return NULL;
+   }
+
+   vmw_printf("Fifo (min) is 0x%08x\n", ((uint32_t *) map)[SVGA_FIFO_MIN]);
+
+   return map;
+}
+
+uint32
+vmw_ioctl_context_create(struct vmw_winsys_screen *vws)
+{
+   struct drm_vmw_context_arg c_arg;
+   int ret;
+
+   VMW_FUNC;
+
+   ret = drmCommandRead(vws->ioctl.drm_fd, DRM_VMW_CREATE_CONTEXT,
+			&c_arg, sizeof(c_arg));
+
+   if (ret)
+      return -1;
+
+   vmw_check_last_cmd(vws);
+   vmw_printf("Context id is %d\n", c_arg.cid);
+
+   return c_arg.cid;
+}
+
+void
+vmw_ioctl_context_destroy(struct vmw_winsys_screen *vws, uint32 cid)
+{
+   struct drm_vmw_context_arg c_arg;
+
+   VMW_FUNC;
+
+   memset(&c_arg, 0, sizeof(c_arg));
+   c_arg.cid = cid;
+
+   (void)drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_UNREF_CONTEXT,
+			 &c_arg, sizeof(c_arg));
+
+   vmw_check_last_cmd(vws);
+}
+
+uint32
+vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
+			      SVGA3dSurfaceFlags flags,
+			      SVGA3dSurfaceFormat format,
+			      SVGA3dSize size,
+			      uint32_t numFaces, uint32_t numMipLevels)
+{
+   union drm_vmw_surface_create_arg s_arg;
+   struct drm_vmw_surface_create_req *req = &s_arg.req;
+   struct drm_vmw_surface_arg *rep = &s_arg.rep;
+   struct drm_vmw_size sizes[DRM_VMW_MAX_SURFACE_FACES*
+			     DRM_VMW_MAX_MIP_LEVELS];
+   struct drm_vmw_size *cur_size;
+   uint32_t iFace;
+   uint32_t iMipLevel;
+   int ret;
+
+   vmw_printf("%s flags %d format %d\n", __FUNCTION__, flags, format);
+
+   memset(&s_arg, 0, sizeof(s_arg));
+   req->flags = (uint32_t) flags;
+   req->format = (uint32_t) format;
+   req->shareable = 1;
+
+   assert(numFaces * numMipLevels < DRM_VMW_MAX_SURFACE_FACES*
+	  DRM_VMW_MAX_MIP_LEVELS);
+   cur_size = sizes;
+   for (iFace = 0; iFace < numFaces; ++iFace) {
+      SVGA3dSize mipSize = size;
+
+      req->mip_levels[iFace] = numMipLevels;
+      for (iMipLevel = 0; iMipLevel < numMipLevels; ++iMipLevel) {
+	 cur_size->width = mipSize.width;
+	 cur_size->height = mipSize.height;
+	 cur_size->depth = mipSize.depth;
+	 mipSize.width = MAX2(mipSize.width >> 1, 1);
+	 mipSize.height = MAX2(mipSize.height >> 1, 1);
+	 mipSize.depth = MAX2(mipSize.depth >> 1, 1);
+	 cur_size++;
+      }
+   }
+   for (iFace = numFaces; iFace < SVGA3D_MAX_SURFACE_FACES; ++iFace) {
+      req->mip_levels[iFace] = 0;
+   }
+
+   req->size_addr = (unsigned long)&sizes;
+
+   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_CREATE_SURFACE,
+			     &s_arg, sizeof(s_arg));
+
+   if (ret)
+      return -1;
+
+   vmw_printf("Surface id is %d\n", rep->sid);
+   vmw_check_last_cmd(vws);
+
+   return rep->sid;
+}
+
+void
+vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws, uint32 sid)
+{
+   struct drm_vmw_surface_arg s_arg;
+
+   VMW_FUNC;
+
+   memset(&s_arg, 0, sizeof(s_arg));
+   s_arg.sid = sid;
+
+   (void)drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_UNREF_SURFACE,
+			 &s_arg, sizeof(s_arg));
+   vmw_check_last_cmd(vws);
+
+}
+
+void
+vmw_ioctl_command(struct vmw_winsys_screen *vws, void *commands, uint32_t size,
+		       uint32_t * pfence)
+{
+   struct drm_vmw_execbuf_arg arg;
+   struct drm_vmw_fence_rep rep;
+   int ret;
+
+#ifdef DEBUG
+   {
+      static boolean firsttime = TRUE;
+      static boolean debug = FALSE;
+      static boolean skip = FALSE;
+      if (firsttime) {
+         debug = debug_get_bool_option("SVGA_DUMP_CMD", FALSE);
+         skip = debug_get_bool_option("SVGA_SKIP_CMD", FALSE);
+      }
+      if (debug) {
+         VMW_FUNC;
+         svga_dump_commands(commands, size);
+      }
+      firsttime = FALSE;
+      if (skip) {
+         size = 0;
+      }
+   }
+#endif
+
+   memset(&arg, 0, sizeof(arg));
+   memset(&rep, 0, sizeof(rep));
+
+   rep.error = -EFAULT;
+   arg.fence_rep = (unsigned long)&rep;
+   arg.commands = (unsigned long)commands;
+   arg.command_size = size;
+
+   do {
+       ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg));
+   } while(ret == -ERESTART);
+   if (ret) {
+      debug_printf("%s error %s.\n", __FUNCTION__, strerror(-ret));
+   }
+   if (rep.error) {
+
+      /*
+       * Kernel has synced and put the last fence sequence in the FIFO
+       * register.
+       */
+
+      if (rep.error == -EFAULT)
+	 rep.fence_seq = vws->ioctl.fifo_map[SVGA_FIFO_FENCE];
+
+      debug_printf("%s Fence error %s.\n", __FUNCTION__,
+		   strerror(-rep.error));
+   }
+
+   vws->ioctl.last_fence = rep.fence_seq;
+
+   if (pfence)
+      *pfence = rep.fence_seq;
+   vmw_check_last_cmd(vws);
+
+}
+
+
+struct vmw_region *
+vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size)
+{
+   struct vmw_region *region;
+   union drm_vmw_alloc_dmabuf_arg arg;
+   struct drm_vmw_alloc_dmabuf_req *req = &arg.req;
+   struct drm_vmw_dmabuf_rep *rep = &arg.rep;
+   int ret;
+
+   vmw_printf("%s: size = %u\n", __FUNCTION__, size);
+
+   region = CALLOC_STRUCT(vmw_region);
+   if (!region)
+      goto out_err1;
+
+   memset(&arg, 0, sizeof(arg));
+   req->size = size;
+   do {
+      ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_ALLOC_DMABUF, &arg,
+				sizeof(arg));
+   } while (ret == -ERESTART);
+
+   if (ret) {
+      debug_printf("IOCTL failed %d: %s\n", ret, strerror(-ret));
+      goto out_err1;
+   }
+
+   region->ptr.gmrId = rep->cur_gmr_id;
+   region->ptr.offset = rep->cur_gmr_offset;
+   region->data = NULL;
+   region->handle = rep->handle;
+   region->map_handle = rep->map_handle;
+   region->map_count = 0;
+   region->size = size;
+   region->drm_fd = vws->ioctl.drm_fd;
+
+   vmw_printf("   gmrId = %u, offset = %u\n",
+              region->ptr.gmrId, region->ptr.offset);
+
+   return region;
+
+ out_err1:
+   FREE(region);
+   return NULL;
+}
+
+void
+vmw_ioctl_region_destroy(struct vmw_region *region)
+{
+   struct drm_vmw_unref_dmabuf_arg arg;
+
+   vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
+              region->ptr.gmrId, region->ptr.offset);
+
+   if (region->data) {
+      munmap(region->data, region->size);
+      region->data = NULL;
+   }
+
+   memset(&arg, 0, sizeof(arg));
+   arg.handle = region->handle;
+   drmCommandWrite(region->drm_fd, DRM_VMW_UNREF_DMABUF, &arg, sizeof(arg));
+
+   FREE(region);
+}
+
+SVGAGuestPtr
+vmw_ioctl_region_ptr(struct vmw_region *region)
+{
+   return region->ptr;
+}
+
+void *
+vmw_ioctl_region_map(struct vmw_region *region)
+{
+   void *map;
+
+   vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
+              region->ptr.gmrId, region->ptr.offset);
+
+   if (region->data == NULL) {
+      map = mmap(NULL, region->size, PROT_READ | PROT_WRITE, MAP_SHARED,
+		 region->drm_fd, region->map_handle);
+      if (map == MAP_FAILED) {
+	 debug_printf("%s: Map failed.\n", __FUNCTION__);
+	 return NULL;
+      }
+
+      region->data = map;
+   }
+
+   ++region->map_count;
+
+   return region->data;
+}
+
+void
+vmw_ioctl_region_unmap(struct vmw_region *region)
+{
+   vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
+              region->ptr.gmrId, region->ptr.offset);
+   --region->map_count;
+}
+
+
+int
+vmw_ioctl_fence_signalled(struct vmw_winsys_screen *vws,
+                          uint32_t fence)
+{
+   uint32_t expected;
+   uint32_t current;
+   
+   assert(fence);
+   if(!fence)
+      return 0;
+   
+   expected = fence;
+   current = vws->ioctl.fifo_map[SVGA_FIFO_FENCE];
+   
+   if ((int32)(current - expected) >= 0)
+      return 0; /* fence passed */
+   else
+      return -1;
+}
+
+
+static void
+vmw_ioctl_sync(struct vmw_winsys_screen *vws, 
+		    uint32_t fence)
+{
+   uint32_t cur_fence;
+   struct drm_vmw_fence_wait_arg arg;
+   int ret;
+
+   vmw_printf("%s: fence = %lu\n", __FUNCTION__,
+              (unsigned long)fence);
+
+   cur_fence = vws->ioctl.fifo_map[SVGA_FIFO_FENCE];
+   vmw_printf("%s: Fence id read is 0x%08x\n", __FUNCTION__,
+              (unsigned int)cur_fence);
+
+   if ((cur_fence - fence) < (1 << 24))
+      return;
+
+   memset(&arg, 0, sizeof(arg));
+   arg.sequence = fence;
+
+   do {
+       ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_FENCE_WAIT, &arg,
+				 sizeof(arg));
+   } while (ret == -ERESTART);
+}
+
+
+int
+vmw_ioctl_fence_finish(struct vmw_winsys_screen *vws,
+                       uint32_t fence)
+{
+   assert(fence);
+   
+   if(fence) {
+      if(vmw_ioctl_fence_signalled(vws, fence) != 0) {
+         vmw_ioctl_sync(vws, fence);
+      }
+   }
+   
+   return 0;
+}
+
+
+boolean
+vmw_ioctl_init(struct vmw_winsys_screen *vws)
+{
+   struct drm_vmw_getparam_arg gp_arg;
+   int ret;
+
+   VMW_FUNC;
+
+   memset(&gp_arg, 0, sizeof(gp_arg));
+   gp_arg.param = DRM_VMW_PARAM_3D;
+   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
+			     &gp_arg, sizeof(gp_arg));
+   if (ret || gp_arg.value == 0) {
+      debug_printf("No 3D enabled (%i, %s)\n", ret, strerror(-ret));
+      goto out_err1;
+   }
+
+   memset(&gp_arg, 0, sizeof(gp_arg));
+   gp_arg.param = DRM_VMW_PARAM_FIFO_OFFSET;
+   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
+			     &gp_arg, sizeof(gp_arg));
+
+   if (ret) {
+      debug_printf("GET_PARAM on %d returned %d: %s\n",
+		   vws->ioctl.drm_fd, ret, strerror(-ret));
+      goto out_err1;
+   }
+
+   vmw_printf("Offset to map is 0x%08llx\n",
+              (unsigned long long)gp_arg.value);
+
+   vws->ioctl.fifo_map = vmw_ioctl_fifo_map(vws, gp_arg.value);
+   if (vws->ioctl.fifo_map == NULL)
+      goto out_err1;
+
+   vmw_printf("%s OK\n", __FUNCTION__);
+   return TRUE;
+
+ out_err1:
+   debug_printf("%s Failed\n", __FUNCTION__);
+   return FALSE;
+}
+
+
+
+void
+vmw_ioctl_cleanup(struct vmw_winsys_screen *vws)
+{
+   VMW_FUNC;
+
+   vmw_ioctl_fifo_unmap(vws, (void *)vws->ioctl.fifo_map);
+}
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c b/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c
new file mode 100644
index 0000000..b1c24b0
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c
@@ -0,0 +1,79 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "vmw_screen.h"
+
+#include "vmw_buffer.h"
+#include "vmw_fence.h"
+
+#include "pipebuffer/pb_buffer.h"
+#include "pipebuffer/pb_bufmgr.h"
+
+void
+vmw_pools_cleanup(struct vmw_winsys_screen *vws)
+{
+   if(vws->pools.gmr_fenced)
+      vws->pools.gmr_fenced->destroy(vws->pools.gmr_fenced);
+
+   /* gmr_mm pool is already destroyed above */
+
+   if(vws->pools.gmr)
+      vws->pools.gmr->destroy(vws->pools.gmr);
+}
+
+
+boolean
+vmw_pools_init(struct vmw_winsys_screen *vws)
+{
+   vws->pools.gmr = vmw_gmr_bufmgr_create(vws);
+   if(!vws->pools.gmr)
+      goto error;
+
+   vws->pools.gmr_mm = mm_bufmgr_create(vws->pools.gmr,
+                                        16*1024*1024,
+                                        12 /* 4096 alignment */);
+   if(!vws->pools.gmr_mm)
+      goto error;
+
+   vws->pools.gmr_fenced = fenced_bufmgr_create(
+      vws->pools.gmr_mm,
+      vmw_fence_ops_create(vws));
+
+#ifdef DEBUG
+   vws->pools.gmr_fenced = pb_debug_manager_create(vws->pools.gmr_fenced,
+						   4096,
+						   4096);
+#endif
+   if(!vws->pools.gmr_fenced)
+      goto error;
+
+   return TRUE;
+
+error:
+   vmw_pools_cleanup(vws);
+   return FALSE;
+}
+
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c b/src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c
new file mode 100644
index 0000000..d7d0088
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c
@@ -0,0 +1,295 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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
+ * This file implements the SVGA interface into this winsys, defined
+ * in drivers/svga/svga_winsys.h.
+ *
+ * @author Keith Whitwell
+ * @author Jose Fonseca
+ */
+
+
+#include "svga_cmd.h"
+#include "svga3d_caps.h"
+
+#include "pipe/p_inlines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "pipebuffer/pb_buffer.h"
+#include "pipebuffer/pb_bufmgr.h"
+#include "svga_winsys.h"
+#include "vmw_context.h"
+#include "vmw_screen.h"
+#include "vmw_surface.h"
+#include "vmw_buffer.h"
+#include "vmw_fence.h"
+
+
+static struct svga_winsys_buffer *
+vmw_svga_winsys_buffer_create(struct svga_winsys_screen *sws,
+                              unsigned alignment,
+                              unsigned usage,
+                              unsigned size)
+{
+   struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+   struct pb_desc desc;
+   struct pb_manager *provider;
+   struct pb_buffer *buffer;
+
+   memset(&desc, 0, sizeof desc);
+   desc.alignment = alignment;
+   desc.usage = usage;
+
+   provider = vws->pools.gmr_fenced;
+
+   assert(provider);
+   buffer = provider->create_buffer(provider, size, &desc);
+   if(!buffer)
+      return NULL;
+
+   return vmw_svga_winsys_buffer(buffer);
+}
+
+
+static void *
+vmw_svga_winsys_buffer_map(struct svga_winsys_screen *sws,
+                           struct svga_winsys_buffer *buf,
+                           unsigned flags)
+{
+   (void)sws;
+   return pb_map(vmw_pb_buffer(buf), flags);
+}
+
+
+static void
+vmw_svga_winsys_buffer_unmap(struct svga_winsys_screen *sws,
+                             struct svga_winsys_buffer *buf)
+{
+   (void)sws;
+   pb_unmap(vmw_pb_buffer(buf));
+}
+
+
+static void
+vmw_svga_winsys_buffer_destroy(struct svga_winsys_screen *sws,
+                               struct svga_winsys_buffer *buf)
+{
+   struct pb_buffer *pbuf = vmw_pb_buffer(buf);
+   (void)sws;
+   pb_reference(&pbuf, NULL);
+}
+
+
+static void
+vmw_svga_winsys_fence_reference(struct svga_winsys_screen *sws,
+                                struct pipe_fence_handle **pdst,
+                                struct pipe_fence_handle *src)
+{
+   (void)sws;
+   *pdst = src;
+}
+
+
+static int
+vmw_svga_winsys_fence_signalled(struct svga_winsys_screen *sws,
+                                struct pipe_fence_handle *fence,
+                                unsigned flag)
+{
+   struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+   (void)flag;
+   return vmw_ioctl_fence_signalled(vws, vmw_fence(fence));
+}
+
+
+static int
+vmw_svga_winsys_fence_finish(struct svga_winsys_screen *sws,
+                             struct pipe_fence_handle *fence,
+                             unsigned flag)
+{
+   struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+   (void)flag;
+   return vmw_ioctl_fence_finish(vws, vmw_fence(fence));
+}
+
+
+
+static struct svga_winsys_surface *
+vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
+                               SVGA3dSurfaceFlags flags,
+                               SVGA3dSurfaceFormat format,
+                               SVGA3dSize size,
+                               uint32 numFaces,
+                               uint32 numMipLevels)
+{
+   struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+   struct vmw_svga_winsys_surface *surface;
+
+   surface = CALLOC_STRUCT(vmw_svga_winsys_surface);
+   if(!surface)
+      goto no_surface;
+
+   pipe_reference_init(&surface->refcnt, 1);
+   p_atomic_set(&surface->validated, 0);
+   surface->screen = vws;
+   surface->sid = vmw_ioctl_surface_create(vws,
+                                           flags, format, size,
+                                           numFaces, numMipLevels);
+   if(surface->sid == SVGA3D_INVALID_ID)
+      goto no_sid;
+
+   return svga_winsys_surface(surface);
+
+no_sid:
+   FREE(surface);
+no_surface:
+   return NULL;
+}
+
+
+static boolean
+vmw_svga_winsys_surface_is_flushed(struct svga_winsys_screen *sws,
+                                   struct svga_winsys_surface *surface)
+{
+   struct vmw_svga_winsys_surface *vsurf = vmw_svga_winsys_surface(surface);
+   return (p_atomic_read(&vsurf->validated) == 0);
+}
+
+
+static void
+vmw_svga_winsys_surface_ref(struct svga_winsys_screen *sws,
+			    struct svga_winsys_surface **pDst,
+			    struct svga_winsys_surface *src)
+{
+   struct vmw_svga_winsys_surface *d_vsurf = vmw_svga_winsys_surface(*pDst);
+   struct vmw_svga_winsys_surface *s_vsurf = vmw_svga_winsys_surface(src);
+
+   vmw_svga_winsys_surface_reference(&d_vsurf, s_vsurf);
+   *pDst = svga_winsys_surface(d_vsurf);
+}
+
+
+static void
+vmw_svga_winsys_destroy(struct svga_winsys_screen *sws)
+{
+   struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+
+   vmw_winsys_destroy(vws);
+}
+
+
+static boolean
+vmw_svga_winsys_get_cap(struct svga_winsys_screen *sws,
+                        SVGA3dDevCapIndex index,
+                        SVGA3dDevCapResult *result)
+{
+   struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+   const uint32 *capsBlock;
+   const SVGA3dCapsRecord *capsRecord = NULL;
+   uint32 offset;
+   const SVGA3dCapPair *capArray;
+   int numCaps, first, last;
+
+   if(!vws->ioctl.fifo_map)
+      return FALSE;
+
+   if(vws->ioctl.fifo_map[SVGA_FIFO_3D_HWVERSION] < SVGA3D_HWVERSION_WS6_B1)
+      return FALSE;
+
+   /*
+    * Search linearly through the caps block records for the specified type.
+    */
+   capsBlock = (const uint32 *)&vws->ioctl.fifo_map[SVGA_FIFO_3D_CAPS];
+   for (offset = 0; capsBlock[offset] != 0; offset += capsBlock[offset]) {
+      const SVGA3dCapsRecord *record;
+      assert(offset < SVGA_FIFO_3D_CAPS_SIZE);
+      record = (const SVGA3dCapsRecord *) (capsBlock + offset);
+      if ((record->header.type >= SVGA3DCAPS_RECORD_DEVCAPS_MIN) &&
+          (record->header.type <= SVGA3DCAPS_RECORD_DEVCAPS_MAX) &&
+          (!capsRecord || (record->header.type > capsRecord->header.type))) {
+         capsRecord = record;
+      }
+   }
+
+   if(!capsRecord)
+      return FALSE;
+
+   /*
+    * Calculate the number of caps from the size of the record.
+    */
+   capArray = (const SVGA3dCapPair *) capsRecord->data;
+   numCaps = (int) ((capsRecord->header.length * sizeof(uint32) -
+                     sizeof capsRecord->header) / (2 * sizeof(uint32)));
+
+   /*
+    * Binary-search for the cap with the specified index.
+    */
+   for (first = 0, last = numCaps - 1; first <= last; ) {
+      int mid = (first + last) / 2;
+
+      if ((SVGA3dDevCapIndex) capArray[mid][0] == index) {
+         /*
+          * Found it.
+          */
+         result->u = capArray[mid][1];
+         return TRUE;
+      }
+
+      /*
+       * Divide and conquer.
+       */
+      if ((SVGA3dDevCapIndex) capArray[mid][0] > index) {
+         last = mid - 1;
+      } else {
+         first = mid + 1;
+      }
+   }
+
+   return FALSE;
+}
+
+
+boolean
+vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws)
+{
+   vws->base.destroy = vmw_svga_winsys_destroy;
+   vws->base.get_cap = vmw_svga_winsys_get_cap;
+   vws->base.context_create = vmw_svga_winsys_context_create;
+   vws->base.surface_create = vmw_svga_winsys_surface_create;
+   vws->base.surface_is_flushed = vmw_svga_winsys_surface_is_flushed;
+   vws->base.surface_reference = vmw_svga_winsys_surface_ref;
+   vws->base.buffer_create = vmw_svga_winsys_buffer_create;
+   vws->base.buffer_map = vmw_svga_winsys_buffer_map;
+   vws->base.buffer_unmap = vmw_svga_winsys_buffer_unmap;
+   vws->base.buffer_destroy = vmw_svga_winsys_buffer_destroy;
+   vws->base.fence_reference = vmw_svga_winsys_fence_reference;
+   vws->base.fence_signalled = vmw_svga_winsys_fence_signalled;
+   vws->base.fence_finish = vmw_svga_winsys_fence_finish;
+
+   return TRUE;
+}
+
+
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_surface.c b/src/gallium/winsys/drm/vmware/core/vmw_surface.c
new file mode 100644
index 0000000..5f1b9ad
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_surface.c
@@ -0,0 +1,61 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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 "svga_cmd.h"
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+
+#include "vmw_surface.h"
+#include "vmw_screen.h"
+
+void
+vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface **pdst,
+                                  struct vmw_svga_winsys_surface *src)
+{
+   struct pipe_reference *src_ref;
+   struct pipe_reference *dst_ref;
+   struct vmw_svga_winsys_surface *dst;
+
+   if(pdst == NULL || *pdst == src)
+      return;
+
+   dst = *pdst;
+
+   src_ref = src ? &src->refcnt : NULL;
+   dst_ref = dst ? &dst->refcnt : NULL;
+
+   if (pipe_reference(dst_ref, src_ref)) {
+      vmw_ioctl_surface_destroy(dst->screen, dst->sid);
+#ifdef DEBUG
+      /* to detect dangling pointers */
+      assert(p_atomic_read(&dst->validated) == 0);
+      dst->sid = SVGA3D_INVALID_ID;
+#endif
+      FREE(dst);
+   }
+
+   *pdst = src;
+}
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_surface.h b/src/gallium/winsys/drm/vmware/core/vmw_surface.h
new file mode 100644
index 0000000..340cc15
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmw_surface.h
@@ -0,0 +1,79 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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
+ * Surfaces for VMware SVGA winsys.
+ * 
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#ifndef VMW_SURFACE_H_
+#define VMW_SURFACE_H_
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_atomic.h"
+#include "pipe/p_refcnt.h"
+
+#define VMW_MAX_PRESENTS 3
+
+
+
+struct vmw_svga_winsys_surface
+{
+   struct pipe_atomic validated;
+   struct pipe_reference refcnt;
+
+   struct vmw_winsys_screen *screen;
+   uint32_t sid;
+
+   /* FIXME: make this thread safe */
+   unsigned next_present_no;
+   uint32_t present_fences[VMW_MAX_PRESENTS];
+};
+
+
+static INLINE struct svga_winsys_surface *
+svga_winsys_surface(struct vmw_svga_winsys_surface *surf)
+{
+   assert(!surf || surf->sid != SVGA3D_INVALID_ID);
+   return (struct svga_winsys_surface *)surf;
+}
+
+
+static INLINE struct vmw_svga_winsys_surface *
+vmw_svga_winsys_surface(struct svga_winsys_surface *surf)
+{
+   return (struct vmw_svga_winsys_surface *)surf;
+}
+
+
+void
+vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface **pdst,
+                                  struct vmw_svga_winsys_surface *src);
+
+#endif /* VMW_SURFACE_H_ */
diff --git a/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h b/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h
new file mode 100644
index 0000000..2be7e12
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h
@@ -0,0 +1,574 @@
+/**************************************************************************
+ *
+ * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA
+ * 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ **************************************************************************/
+
+#ifndef __VMWGFX_DRM_H__
+#define __VMWGFX_DRM_H__
+
+#define DRM_VMW_MAX_SURFACE_FACES 6
+#define DRM_VMW_MAX_MIP_LEVELS 24
+
+#define DRM_VMW_EXT_NAME_LEN 128
+
+#define DRM_VMW_GET_PARAM            0
+#define DRM_VMW_ALLOC_DMABUF         1
+#define DRM_VMW_UNREF_DMABUF         2
+#define DRM_VMW_CURSOR_BYPASS        3
+/* guarded by DRM_VMW_PARAM_NUM_STREAMS != 0*/
+#define DRM_VMW_CONTROL_STREAM       4
+#define DRM_VMW_CLAIM_STREAM         5
+#define DRM_VMW_UNREF_STREAM         6
+/* guarded by DRM_VMW_PARAM_3D == 1 */
+#define DRM_VMW_CREATE_CONTEXT       7
+#define DRM_VMW_UNREF_CONTEXT        8
+#define DRM_VMW_CREATE_SURFACE       9
+#define DRM_VMW_UNREF_SURFACE        10
+#define DRM_VMW_REF_SURFACE          11
+#define DRM_VMW_EXECBUF              12
+#define DRM_VMW_FIFO_DEBUG           13
+#define DRM_VMW_FENCE_WAIT           14
+
+
+/*************************************************************************/
+/**
+ * DRM_VMW_GET_PARAM - get device information.
+ *
+ * DRM_VMW_PARAM_FIFO_OFFSET:
+ * Offset to use to map the first page of the FIFO read-only.
+ * The fifo is mapped using the mmap() system call on the drm device.
+ *
+ * DRM_VMW_PARAM_OVERLAY_IOCTL:
+ * Does the driver support the overlay ioctl.
+ */
+
+#define DRM_VMW_PARAM_NUM_STREAMS      0
+#define DRM_VMW_PARAM_NUM_FREE_STREAMS 1
+#define DRM_VMW_PARAM_3D               2
+#define DRM_VMW_PARAM_FIFO_OFFSET      3
+
+
+/**
+ * struct drm_vmw_getparam_arg
+ *
+ * @value: Returned value. //Out
+ * @param: Parameter to query. //In.
+ *
+ * Argument to the DRM_VMW_GET_PARAM Ioctl.
+ */
+
+struct drm_vmw_getparam_arg {
+	uint64_t value;
+	uint32_t param;
+	uint32_t pad64;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_EXTENSION - Query device extensions.
+ */
+
+/**
+ * struct drm_vmw_extension_rep
+ *
+ * @exists: The queried extension exists.
+ * @driver_ioctl_offset: Ioctl number of the first ioctl in the extension.
+ * @driver_sarea_offset: Offset to any space in the DRI SAREA
+ * used by the extension.
+ * @major: Major version number of the extension.
+ * @minor: Minor version number of the extension.
+ * @pl: Patch level version number of the extension.
+ *
+ * Output argument to the DRM_VMW_EXTENSION Ioctl.
+ */
+
+struct drm_vmw_extension_rep {
+	int32_t exists;
+	uint32_t driver_ioctl_offset;
+	uint32_t driver_sarea_offset;
+	uint32_t major;
+	uint32_t minor;
+	uint32_t pl;
+	uint32_t pad64;
+};
+
+/**
+ * union drm_vmw_extension_arg
+ *
+ * @extension - Ascii name of the extension to be queried. //In
+ * @rep - Reply as defined above. //Out
+ *
+ * Argument to the DRM_VMW_EXTENSION Ioctl.
+ */
+
+union drm_vmw_extension_arg {
+	char extension[DRM_VMW_EXT_NAME_LEN];
+	struct drm_vmw_extension_rep rep;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_CREATE_CONTEXT - Create a host context.
+ *
+ * Allocates a device unique context id, and queues a create context command
+ * for the host. Does not wait for host completion.
+ */
+
+/**
+ * struct drm_vmw_context_arg
+ *
+ * @cid: Device unique context ID.
+ *
+ * Output argument to the DRM_VMW_CREATE_CONTEXT Ioctl.
+ * Input argument to the DRM_VMW_UNREF_CONTEXT Ioctl.
+ */
+
+struct drm_vmw_context_arg {
+	int32_t cid;
+	uint32_t pad64;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_UNREF_CONTEXT - Create a host context.
+ *
+ * Frees a global context id, and queues a destroy host command for the host.
+ * Does not wait for host completion. The context ID can be used directly
+ * in the command stream and shows up as the same context ID on the host.
+ */
+
+/*************************************************************************/
+/**
+ * DRM_VMW_CREATE_SURFACE - Create a host suface.
+ *
+ * Allocates a device unique surface id, and queues a create surface command
+ * for the host. Does not wait for host completion. The surface ID can be
+ * used directly in the command stream and shows up as the same surface
+ * ID on the host.
+ */
+
+/**
+ * struct drm_wmv_surface_create_req
+ *
+ * @flags: Surface flags as understood by the host.
+ * @format: Surface format as understood by the host.
+ * @mip_levels: Number of mip levels for each face.
+ * An unused face should have 0 encoded.
+ * @size_addr: Address of a user-space array of sruct drm_vmw_size
+ * cast to an uint64_t for 32-64 bit compatibility.
+ * The size of the array should equal the total number of mipmap levels.
+ * @shareable: Boolean whether other clients (as identified by file descriptors)
+ * may reference this surface.
+ *
+ * Input data to the DRM_VMW_CREATE_SURFACE Ioctl.
+ * Output data from the DRM_VMW_REF_SURFACE Ioctl.
+ */
+
+struct drm_vmw_surface_create_req {
+	uint32_t flags;
+	uint32_t format;
+	uint32_t mip_levels[DRM_VMW_MAX_SURFACE_FACES];
+	uint64_t size_addr;
+	int32_t shareable;
+	uint32_t pad64;
+};
+
+/**
+ * struct drm_wmv_surface_arg
+ *
+ * @sid: Surface id of created surface or surface to destroy or reference.
+ *
+ * Output data from the DRM_VMW_CREATE_SURFACE Ioctl.
+ * Input argument to the DRM_VMW_UNREF_SURFACE Ioctl.
+ * Input argument to the DRM_VMW_REF_SURFACE Ioctl.
+ */
+
+struct drm_vmw_surface_arg {
+	int32_t sid;
+	uint32_t pad64;
+};
+
+/**
+ * struct drm_vmw_size ioctl.
+ *
+ * @width - mip level width
+ * @height - mip level height
+ * @depth - mip level depth
+ *
+ * Description of a mip level.
+ * Input data to the DRM_WMW_CREATE_SURFACE Ioctl.
+ */
+
+struct drm_vmw_size {
+	uint32_t width;
+	uint32_t height;
+	uint32_t depth;
+	uint32_t pad64;
+};
+
+/**
+ * union drm_vmw_surface_create_arg
+ *
+ * @rep: Output data as described above.
+ * @req: Input data as described above.
+ *
+ * Argument to the DRM_VMW_CREATE_SURFACE Ioctl.
+ */
+
+union drm_vmw_surface_create_arg {
+	struct drm_vmw_surface_arg rep;
+	struct drm_vmw_surface_create_req req;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_REF_SURFACE - Reference a host surface.
+ *
+ * Puts a reference on a host surface with a give sid, as previously
+ * returned by the DRM_VMW_CREATE_SURFACE ioctl.
+ * A reference will make sure the surface isn't destroyed while we hold
+ * it and will allow the calling client to use the surface ID in the command
+ * stream.
+ *
+ * On successful return, the Ioctl returns the surface information given
+ * in the DRM_VMW_CREATE_SURFACE ioctl.
+ */
+
+/**
+ * union drm_vmw_surface_reference_arg
+ *
+ * @rep: Output data as described above.
+ * @req: Input data as described above.
+ *
+ * Argument to the DRM_VMW_REF_SURFACE Ioctl.
+ */
+
+union drm_vmw_surface_reference_arg {
+	struct drm_vmw_surface_create_req rep;
+	struct drm_vmw_surface_arg req;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_UNREF_SURFACE - Unreference a host surface.
+ *
+ * Clear a reference previously put on a host surface.
+ * When all references are gone, including the one implicitly placed
+ * on creation,
+ * a destroy surface command will be queued for the host.
+ * Does not wait for completion.
+ */
+
+/*************************************************************************/
+/**
+ * DRM_VMW_EXECBUF
+ *
+ * Submit a command buffer for execution on the host, and return a
+ * fence sequence that when signaled, indicates that the command buffer has
+ * executed.
+ */
+
+/**
+ * struct drm_vmw_execbuf_arg
+ *
+ * @commands: User-space address of a command buffer cast to an uint64_t.
+ * @command-size: Size in bytes of the command buffer.
+ * @fence_rep: User-space address of a struct drm_vmw_fence_rep cast to an
+ * uint64_t.
+ *
+ * Argument to the DRM_VMW_EXECBUF Ioctl.
+ */
+
+struct drm_vmw_execbuf_arg {
+	uint64_t commands;
+	uint32_t command_size;
+	uint32_t pad64;
+	uint64_t fence_rep;
+};
+
+/**
+ * struct drm_vmw_fence_rep
+ *
+ * @fence_seq: Fence sequence associated with a command submission.
+ * @error: This member should've been set to -EFAULT on submission.
+ * The following actions should be take on completion:
+ * error == -EFAULT: Fence communication failed. The host is synchronized.
+ * Use the last fence id read from the FIFO fence register.
+ * error != 0 && error != -EFAULT:
+ * Fence submission failed. The host is synchronized. Use the fence_seq member.
+ * error == 0: All is OK, The host may not be synchronized.
+ * Use the fence_seq member.
+ *
+ * Input / Output data to the DRM_VMW_EXECBUF Ioctl.
+ */
+
+struct drm_vmw_fence_rep {
+	uint64_t fence_seq;
+	int32_t error;
+	uint32_t pad64;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_ALLOC_DMABUF
+ *
+ * Allocate a DMA buffer that is visible also to the host.
+ * NOTE: The buffer is
+ * identified by a handle and an offset, which are private to the guest, but
+ * useable in the command stream. The guest kernel may translate these
+ * and patch up the command stream accordingly. In the future, the offset may
+ * be zero at all times, or it may disappear from the interface before it is
+ * fixed.
+ *
+ * The DMA buffer may stay user-space mapped in the guest at all times,
+ * and is thus suitable for sub-allocation.
+ *
+ * DMA buffers are mapped using the mmap() syscall on the drm device.
+ */
+
+/**
+ * struct drm_vmw_alloc_dmabuf_req
+ *
+ * @size: Required minimum size of the buffer.
+ *
+ * Input data to the DRM_VMW_ALLOC_DMABUF Ioctl.
+ */
+
+struct drm_vmw_alloc_dmabuf_req {
+	uint32_t size;
+	uint32_t pad64;
+};
+
+/**
+ * struct drm_vmw_dmabuf_rep
+ *
+ * @map_handle: Offset to use in the mmap() call used to map the buffer.
+ * @handle: Handle unique to this buffer. Used for unreferencing.
+ * @cur_gmr_id: GMR id to use in the command stream when this buffer is
+ * referenced. See not above.
+ * @cur_gmr_offset: Offset to use in the command stream when this buffer is
+ * referenced. See note above.
+ *
+ * Output data from the DRM_VMW_ALLOC_DMABUF Ioctl.
+ */
+
+struct drm_vmw_dmabuf_rep {
+	uint64_t map_handle;
+	uint32_t handle;
+	uint32_t cur_gmr_id;
+	uint32_t cur_gmr_offset;
+	uint32_t pad64;
+};
+
+/**
+ * union drm_vmw_dmabuf_arg
+ *
+ * @req: Input data as described above.
+ * @rep: Output data as described above.
+ *
+ * Argument to the DRM_VMW_ALLOC_DMABUF Ioctl.
+ */
+
+union drm_vmw_alloc_dmabuf_arg {
+	struct drm_vmw_alloc_dmabuf_req req;
+	struct drm_vmw_dmabuf_rep rep;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_UNREF_DMABUF - Free a DMA buffer.
+ *
+ */
+
+/**
+ * struct drm_vmw_unref_dmabuf_arg
+ *
+ * @handle: Handle indicating what buffer to free. Obtained from the
+ * DRM_VMW_ALLOC_DMABUF Ioctl.
+ *
+ * Argument to the DRM_VMW_UNREF_DMABUF Ioctl.
+ */
+
+struct drm_vmw_unref_dmabuf_arg {
+	uint32_t handle;
+	uint32_t pad64;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_FIFO_DEBUG - Get last FIFO submission.
+ *
+ * This IOCTL copies the last FIFO submission directly out of the FIFO buffer.
+ */
+
+/**
+ * struct drm_vmw_fifo_debug_arg
+ *
+ * @debug_buffer: User space address of a debug_buffer cast to an uint64_t //In
+ * @debug_buffer_size: Size in bytes of debug buffer //In
+ * @used_size: Number of bytes copied to the buffer // Out
+ * @did_not_fit: Boolean indicating that the fifo contents did not fit. //Out
+ *
+ * Argument to the DRM_VMW_FIFO_DEBUG Ioctl.
+ */
+
+struct drm_vmw_fifo_debug_arg {
+	uint64_t debug_buffer;
+	uint32_t debug_buffer_size;
+	uint32_t used_size;
+	int32_t did_not_fit;
+	uint32_t pad64;
+};
+
+struct drm_vmw_fence_wait_arg {
+	uint64_t sequence;
+	uint64_t kernel_cookie;
+	int32_t cookie_valid;
+	int32_t pad64;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_CONTROL_STREAM - Control overlays, aka streams.
+ *
+ * This IOCTL controls the overlay units of the svga device.
+ * The SVGA overlay units does not work like regular hardware units in
+ * that they do not automaticaly read back the contents of the given dma
+ * buffer. But instead only read back for each call to this ioctl, and
+ * at any point between this call being made and a following call that
+ * either changes the buffer or disables the stream.
+ */
+
+/**
+ * struct drm_vmw_rect
+ *
+ * Defines a rectangle. Used in the overlay ioctl to define
+ * source and destination rectangle.
+ */
+
+struct drm_vmw_rect {
+	int32_t x;
+	int32_t y;
+	uint32_t w;
+	uint32_t h;
+};
+
+/**
+ * struct drm_vmw_control_stream_arg
+ *
+ * @stream_id: Stearm to control
+ * @enabled: If false all following arguments are ignored.
+ * @handle: Handle to buffer for getting data from.
+ * @format: Format of the overlay as understood by the host.
+ * @width: Width of the overlay.
+ * @height: Height of the overlay.
+ * @size: Size of the overlay in bytes.
+ * @pitch: Array of pitches, the two last are only used for YUV12 formats.
+ * @offset: Offset from start of dma buffer to overlay.
+ * @src: Source rect, must be within the defined area above.
+ * @dst: Destination rect, x and y may be negative.
+ *
+ * Argument to the DRM_VMW_CONTROL_STREAM Ioctl.
+ */
+
+struct drm_vmw_control_stream_arg {
+	uint32_t stream_id;
+	uint32_t enabled;
+
+	uint32_t flags;
+	uint32_t color_key;
+
+	uint32_t handle;
+	uint32_t offset;
+	int32_t format;
+	uint32_t size;
+	uint32_t width;
+	uint32_t height;
+	uint32_t pitch[3];
+
+	uint32_t pad64;
+	struct drm_vmw_rect src;
+	struct drm_vmw_rect dst;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_CURSOR_BYPASS - Give extra information about cursor bypass.
+ *
+ */
+
+#define DRM_VMW_CURSOR_BYPASS_ALL    (1 << 0)
+#define DRM_VMW_CURSOR_BYPASS_FLAGS       (1)
+
+/**
+ * struct drm_vmw_cursor_bypass_arg
+ *
+ * @flags: Flags.
+ * @crtc_id: Crtc id, only used if DMR_CURSOR_BYPASS_ALL isn't passed.
+ * @xpos: X position of cursor.
+ * @ypos: Y position of cursor.
+ * @xhot: X hotspot.
+ * @yhot: Y hotspot.
+ *
+ * Argument to the DRM_VMW_CURSOR_BYPASS Ioctl.
+ */
+
+struct drm_vmw_cursor_bypass_arg {
+	uint32_t flags;
+	uint32_t crtc_id;
+	int32_t xpos;
+	int32_t ypos;
+	int32_t xhot;
+	int32_t yhot;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_CLAIM_STREAM - Claim a single stream.
+ */
+
+/**
+ * struct drm_vmw_context_arg
+ *
+ * @stream_id: Device unique context ID.
+ *
+ * Output argument to the DRM_VMW_CREATE_CONTEXT Ioctl.
+ * Input argument to the DRM_VMW_UNREF_CONTEXT Ioctl.
+ */
+
+struct drm_vmw_stream_arg {
+	uint32_t stream_id;
+	uint32_t pad64;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_UNREF_STREAM - Unclaim a stream.
+ *
+ * Return a single stream that was claimed by this process. Also makes
+ * sure that the stream has been stopped.
+ */
+
+#endif
diff --git a/src/gallium/winsys/drm/vmware/dri/Makefile b/src/gallium/winsys/drm/vmware/dri/Makefile
new file mode 100644
index 0000000..8a39e23
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/dri/Makefile
@@ -0,0 +1,18 @@
+
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = vmwgfx_dri.so
+
+PIPE_DRIVERS = \
+	$(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
+	$(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
+	$(TOP)/src/gallium/drivers/trace/libtrace.a \
+	$(TOP)/src/gallium/drivers/svga/libsvga.a
+
+C_SOURCES = \
+	$(COMMON_GALLIUM_SOURCES)
+
+include ../../Makefile.template
+
+symlinks:
diff --git a/src/gallium/winsys/drm/vmware/dri/SConscript b/src/gallium/winsys/drm/vmware/dri/SConscript
new file mode 100644
index 0000000..84319f9
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/dri/SConscript
@@ -0,0 +1,62 @@
+import os
+import os.path
+
+Import('*')
+
+if env['platform'] == 'linux':
+
+   if env['dri']:
+      env = env.Clone()
+
+      sources = [
+        '#/src/mesa/drivers/dri/common/utils.c',
+        '#/src/mesa/drivers/dri/common/vblank.c',
+        '#/src/mesa/drivers/dri/common/dri_util.c',
+        '#/src/mesa/drivers/dri/common/xmlconfig.c',
+         ]
+   
+      
+      env.ParseConfig('pkg-config --cflags --libs libdrm')
+      
+      env.Prepend(CPPPATH = [
+            '#/src/mesa/state_tracker',
+            '#/src/mesa/drivers/dri/common',
+            '#/src/mesa/main',
+            '#/src/mesa/glapi',
+            '#/src/mesa',
+            '#/include',
+            '#/src/gallium/drivers/svga',
+            '#/src/gallium/drivers/svga/include',
+            ])
+      
+      env.Append(CPPDEFINES = [
+            'HAVE_STDINT_H', 
+            'HAVE_SYS_TYPES_H',
+            ])
+
+      env.Append(CFLAGS = [
+            '-std=gnu99',
+            '-D_FILE_OFFSET_BITS=64',
+            ])
+      
+      env.Prepend(LIBPATH = [
+            ])
+      
+      env.Prepend(LIBS = [
+            trace,
+            st_dri,
+            svgadrm,
+            svga,
+            mesa,
+            gallium,
+            ])
+      
+      # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
+      env.LoadableModule(
+         target ='vmwgfx_dri.so',
+         source = sources,
+         LIBS = env['LIBS'],
+         SHLIBPREFIX = '',
+         )
+      
+
diff --git a/src/gallium/winsys/drm/vmware/egl/Makefile b/src/gallium/winsys/drm/vmware/egl/Makefile
new file mode 100644
index 0000000..8e2980c
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/egl/Makefile
@@ -0,0 +1,18 @@
+
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = EGL_svga.so
+
+PIPE_DRIVERS = \
+	$(TOP)/src/gallium/state_trackers/egl/libegldrm.a \
+	$(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
+	$(TOP)/src/gallium/drivers/trace/libtrace.a \
+	$(TOP)/src/gallium/drivers/svga/libsvga.a
+
+C_SOURCES = \
+	$(COMMON_GALLIUM_SOURCES)
+
+include ../../Makefile.template
+
+symlinks:
diff --git a/src/gallium/winsys/drm/vmware/egl_g3d/Makefile b/src/gallium/winsys/drm/vmware/egl_g3d/Makefile
new file mode 100644
index 0000000..3cf7992
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/egl_g3d/Makefile
@@ -0,0 +1,14 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+EGL_DRIVER_NAME = vmwgfx
+EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_LIBS =
+
+EGL_DRIVER_PIPES = \
+	$(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
+	$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+	$(TOP)/src/gallium/drivers/trace/libtrace.a \
+	$(TOP)/src/gallium/drivers/svga/libsvga.a
+
+include ../../Makefile.egl_g3d
diff --git a/src/gallium/winsys/drm/vmware/egl_g3d/dummy.c b/src/gallium/winsys/drm/vmware/egl_g3d/dummy.c
new file mode 100644
index 0000000..4a1bc28
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/egl_g3d/dummy.c
@@ -0,0 +1 @@
+/* mklib expects at least one object file */
diff --git a/src/gallium/winsys/drm/vmware/xorg/Makefile b/src/gallium/winsys/drm/vmware/xorg/Makefile
new file mode 100644
index 0000000..49e28ae
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/xorg/Makefile
@@ -0,0 +1,71 @@
+TOP        = ../../../../../..
+
+include $(TOP)/configs/current
+
+TARGET = vmwgfx_drv.so
+
+CFILES = \
+	vmw_xorg.c \
+	vmw_video.c \
+	vmw_ioctl.c \
+	vmw_screen.c
+
+OBJECTS = $(patsubst %.c,%.o,$(CFILES))
+
+INCLUDES = \
+	$(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \
+	-I$(TOP)/src/gallium/include \
+	-I$(TOP)/src/gallium/drivers \
+	-I$(TOP)/src/gallium/auxiliary \
+	-I$(TOP)/src/gallium
+
+LIBS = \
+	$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
+	$(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
+	$(TOP)/src/gallium/drivers/trace/libtrace.a \
+	$(TOP)/src/gallium/drivers/svga/libsvga.a \
+	$(GALLIUM_AUXILIARIES)
+
+LINKS = \
+	$(shell pkg-config --libs --silence-errors libkms) \
+	$(shell pkg-config --libs libdrm)
+
+DRIVER_DEFINES = \
+	-std=gnu99 \
+	-DHAVE_CONFIG_H
+
+TARGET_STAGING = $(TOP)/$(LIB_DIR)/gallium/$(TARGET)
+
+#############################################
+
+
+
+all default: $(TARGET) $(TARGET_STAGING)
+
+$(TARGET): $(OBJECTS) Makefile $(LIBS)
+	$(MKLIB) -noprefix -o $@ $(OBJECTS) $(LIBS) $(LINKS)
+
+$(TOP)/$(LIB_DIR)/gallium:
+	mkdir -p $@
+
+$(TARGET_STAGING): $(TARGET) $(TOP)/$(LIB_DIR)/gallium
+	$(INSTALL) $(TARGET) $(TOP)/$(LIB_DIR)/gallium
+
+clean:
+	rm -rf $(OBJECTS) $(TARGET)
+
+install:
+	$(INSTALL) -d $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
+	$(MINSTALL) -m 755 $(TARGET) $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
+
+
+##############################################
+
+
+.c.o:
+	$(CC) -c $(CFLAGS) $(INCLUDES) $(DRIVER_DEFINES) $< -o $@
+
+
+##############################################
+
+.PHONY	= all clean install
diff --git a/src/gallium/winsys/drm/vmware/xorg/SConscript b/src/gallium/winsys/drm/vmware/xorg/SConscript
new file mode 100644
index 0000000..1e5d8ff
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/xorg/SConscript
@@ -0,0 +1,57 @@
+import os.path
+
+Import('*')
+
+if env['platform'] == 'linux':
+
+	env = env.Clone()
+
+	env.ParseConfig('pkg-config --cflags --libs libdrm xorg-server')
+
+	env.Prepend(CPPPATH = [
+		'#/include',
+		'#/src/gallium',
+		'#/src/mesa',
+		'#/src/gallium/drivers/svga',
+		'#/src/gallium/drivers/svga/include',
+	])
+
+	env.Append(CPPDEFINES = [
+	])
+
+	if env['gcc']:
+		env.Append(CPPDEFINES = [
+			'HAVE_STDINT_H',
+			'HAVE_SYS_TYPES_H',
+		])
+
+	env.Append(CFLAGS = [
+		'-std=gnu99',
+		'-D_FILE_OFFSET_BITS=64',
+	])
+
+	env.Prepend(LIBPATH = [
+	])
+
+	env.Prepend(LIBS = [
+		trace,
+		st_xorg,
+		svgadrm,
+		svga,
+                gallium,
+	])
+
+	sources = [
+		'vmw_ioctl.c',
+		'vmw_screen.c',
+		'vmw_video.c',
+		'vmw_xorg.c',
+	]
+
+	# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
+	env.LoadableModule(
+		target ='vmwgfx_drv.so',
+		source = sources,
+		LIBS = env['LIBS'],
+		SHLIBPREFIX = '',
+	)
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_driver.h b/src/gallium/winsys/drm/vmware/xorg/vmw_driver.h
new file mode 100644
index 0000000..3efe851
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/xorg/vmw_driver.h
@@ -0,0 +1,101 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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
+ * Contains the shared resources for VMware Xorg driver
+ * that sits ontop of the Xorg State Traker.
+ *
+ * It is initialized in vmw_screen.c.
+ *
+ * @author Jakob Bornecrantz <jakob@vmware.com>
+ */
+
+#ifndef VMW_DRIVER_H_
+#define VMW_DRIVER_H_
+
+#include "state_trackers/xorg/xorg_tracker.h"
+
+struct vmw_dma_buffer;
+
+struct vmw_driver
+{
+    int fd;
+
+    void *cursor_priv;
+
+    /* vmw_video.c */
+    void *video_priv;
+};
+
+static INLINE struct vmw_driver *
+vmw_driver(ScrnInfoPtr pScrn)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+    return ms ? (struct vmw_driver *)ms->winsys_priv : NULL;
+}
+
+
+/***********************************************************************
+ * vmw_video.c
+ */
+
+Bool vmw_video_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
+
+Bool vmw_video_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
+
+void vmw_video_stop_all(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
+
+
+/***********************************************************************
+ * vmw_ioctl.c
+ */
+
+int vmw_ioctl_cursor_bypass(struct vmw_driver *vmw, int xhot, int yhot);
+
+struct vmw_dma_buffer * vmw_ioctl_buffer_create(struct vmw_driver *vmw,
+						uint32_t size,
+						unsigned *handle);
+
+void * vmw_ioctl_buffer_map(struct vmw_driver *vmw,
+			    struct vmw_dma_buffer *buf);
+
+void vmw_ioctl_buffer_unmap(struct vmw_driver *vmw,
+			    struct vmw_dma_buffer *buf);
+
+void vmw_ioctl_buffer_destroy(struct vmw_driver *vmw,
+			      struct vmw_dma_buffer *buf);
+
+int vmw_ioctl_supports_streams(struct vmw_driver *vmw);
+
+int vmw_ioctl_num_streams(struct vmw_driver *vmw,
+			  uint32_t *ntot, uint32_t *nfree);
+
+int vmw_ioctl_unref_stream(struct vmw_driver *vmw, uint32_t stream_id);
+
+int vmw_ioctl_claim_stream(struct vmw_driver *vmw, uint32_t *out);
+
+
+#endif
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_hook.h b/src/gallium/winsys/drm/vmware/xorg/vmw_hook.h
new file mode 100644
index 0000000..224a2d9
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/xorg/vmw_hook.h
@@ -0,0 +1,39 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef VMW_HOOK_H_
+#define VMW_HOOK_H_
+
+#include "state_trackers/xorg/xorg_winsys.h"
+
+
+/***********************************************************************
+ * vmw_screen.c
+ */
+
+void vmw_screen_set_functions(ScrnInfoPtr pScrn);
+
+
+#endif
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c b/src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c
new file mode 100644
index 0000000..ab2b5fa
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c
@@ -0,0 +1,242 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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
+ * Contains the functions for creating dma buffers by calling
+ * the kernel via driver specific ioctls.
+ *
+ * @author Jakob Bornecrantz <jakob@vmware.com>
+ */
+
+#ifndef HAVE_STDINT_H
+#define HAVE_STDINT_H 1
+#endif
+#define _FILE_OFFSET_BITS 64
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/mman.h>
+#include "xf86drm.h"
+#include "../core/vmwgfx_drm.h"
+
+#include "vmw_driver.h"
+#include "util/u_debug.h"
+
+struct vmw_dma_buffer
+{
+    void *data;
+    unsigned handle;
+    uint64_t map_handle;
+    unsigned map_count;
+    uint32_t size;
+};
+
+static int
+vmw_ioctl_get_param(struct vmw_driver *vmw, uint32_t param, uint64_t *out)
+{
+    struct drm_vmw_getparam_arg gp_arg;
+    int ret;
+
+    memset(&gp_arg, 0, sizeof(gp_arg));
+    gp_arg.param = param;
+    ret = drmCommandWriteRead(vmw->fd, DRM_VMW_GET_PARAM,
+	    &gp_arg, sizeof(gp_arg));
+
+    if (ret == 0) {
+	*out = gp_arg.value;
+    }
+
+    return ret;
+}
+
+int
+vmw_ioctl_supports_streams(struct vmw_driver *vmw)
+{
+    uint64_t value;
+    int ret;
+
+    ret = vmw_ioctl_get_param(vmw, DRM_VMW_PARAM_NUM_STREAMS, &value);
+    if (ret)
+	return ret;
+
+    return value ? 0 : -ENOSYS;
+}
+
+int
+vmw_ioctl_num_streams(struct vmw_driver *vmw,
+		      uint32_t *ntot, uint32_t *nfree)
+{
+    uint64_t v1, v2;
+    int ret;
+
+    ret = vmw_ioctl_get_param(vmw, DRM_VMW_PARAM_NUM_STREAMS, &v1);
+    if (ret)
+	return ret;
+
+    ret = vmw_ioctl_get_param(vmw, DRM_VMW_PARAM_NUM_FREE_STREAMS, &v2);
+    if (ret)
+	return ret;
+
+    *ntot = (uint32_t)v1;
+    *nfree = (uint32_t)v2;
+
+    return 0;
+}
+
+int
+vmw_ioctl_claim_stream(struct vmw_driver *vmw, uint32_t *out)
+{
+    struct drm_vmw_stream_arg s_arg;
+    int ret;
+
+    ret = drmCommandRead(vmw->fd, DRM_VMW_CLAIM_STREAM,
+			 &s_arg, sizeof(s_arg));
+
+    if (ret)
+	return -1;
+
+    *out = s_arg.stream_id;
+    return 0;
+}
+
+int
+vmw_ioctl_unref_stream(struct vmw_driver *vmw, uint32_t stream_id)
+{
+    struct drm_vmw_stream_arg s_arg;
+    int ret;
+
+    memset(&s_arg, 0, sizeof(s_arg));
+    s_arg.stream_id = stream_id;
+
+    ret = drmCommandRead(vmw->fd, DRM_VMW_CLAIM_STREAM,
+			 &s_arg, sizeof(s_arg));
+
+    return 0;
+}
+
+int
+vmw_ioctl_cursor_bypass(struct vmw_driver *vmw, int xhot, int yhot)
+{
+    struct drm_vmw_cursor_bypass_arg arg;
+    int ret;
+
+    memset(&arg, 0, sizeof(arg));
+    arg.flags = DRM_VMW_CURSOR_BYPASS_ALL;
+    arg.xhot = xhot;
+    arg.yhot = yhot;
+
+    ret = drmCommandWrite(vmw->fd, DRM_VMW_CURSOR_BYPASS,
+			  &arg, sizeof(arg));
+
+    return ret;
+}
+
+struct vmw_dma_buffer *
+vmw_ioctl_buffer_create(struct vmw_driver *vmw, uint32_t size, unsigned *handle)
+{
+    struct vmw_dma_buffer *buf;
+    union drm_vmw_alloc_dmabuf_arg arg;
+    struct drm_vmw_alloc_dmabuf_req *req = &arg.req;
+    struct drm_vmw_dmabuf_rep *rep = &arg.rep;
+    int ret;
+
+    buf = xcalloc(1, sizeof(*buf));
+    if (!buf)
+	goto err;
+
+    memset(&arg, 0, sizeof(arg));
+    req->size = size;
+    do {
+	ret = drmCommandWriteRead(vmw->fd, DRM_VMW_ALLOC_DMABUF, &arg, sizeof(arg));
+    } while (ret == -ERESTART);
+
+    if (ret) {
+	debug_printf("IOCTL failed %d: %s\n", ret, strerror(-ret));
+	goto err_free;
+    }
+
+
+    buf->data = NULL;
+    buf->handle = rep->handle;
+    buf->map_handle = rep->map_handle;
+    buf->map_count = 0;
+    buf->size = size;
+
+    *handle = rep->handle;
+
+    return buf;
+
+err_free:
+    xfree(buf);
+err:
+    return NULL;
+}
+
+void
+vmw_ioctl_buffer_destroy(struct vmw_driver *vmw, struct vmw_dma_buffer *buf) 
+{ 
+    struct drm_vmw_unref_dmabuf_arg arg; 
+
+    if (buf->data) { 
+	munmap(buf->data, buf->size); 
+	buf->data = NULL; 
+    } 
+
+    memset(&arg, 0, sizeof(arg)); 
+    arg.handle = buf->handle; 
+    drmCommandWrite(vmw->fd, DRM_VMW_UNREF_DMABUF, &arg, sizeof(arg)); 
+
+    xfree(buf); 
+} 
+
+void *
+vmw_ioctl_buffer_map(struct vmw_driver *vmw, struct vmw_dma_buffer *buf)
+{
+    void *map;
+
+    if (buf->data == NULL) {
+	map = mmap(NULL, buf->size, PROT_READ | PROT_WRITE, MAP_SHARED,
+		   vmw->fd, buf->map_handle);
+	if (map == MAP_FAILED) {
+	    debug_printf("%s: Map failed.\n", __FUNCTION__);
+	    return NULL;
+	}
+
+	buf->data = map;
+    }
+
+    ++buf->map_count;
+
+    return buf->data;
+}
+
+void
+vmw_ioctl_buffer_unmap(struct vmw_driver *vmw, struct vmw_dma_buffer *buf)
+{
+    --buf->map_count;
+}
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_screen.c b/src/gallium/winsys/drm/vmware/xorg/vmw_screen.c
new file mode 100644
index 0000000..7c9757c
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/xorg/vmw_screen.c
@@ -0,0 +1,178 @@
+/**********************************************************
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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
+ * Contains the init code for the VMware Xorg driver.
+ *
+ * @author Jakob Bornecrantz <jakob@vmware.com>
+ */
+
+#include "vmw_hook.h"
+#include "vmw_driver.h"
+
+#include "cursorstr.h"
+
+/* modified version of crtc functions */
+xf86CrtcFuncsRec vmw_screen_crtc_funcs;
+
+static void
+vmw_screen_cursor_load_argb(xf86CrtcPtr crtc, CARD32 *image)
+{
+    struct vmw_driver *vmw = modesettingPTR(crtc->scrn)->winsys_priv;
+    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+    xf86CrtcFuncsPtr funcs = vmw->cursor_priv;
+    CursorPtr c = config->cursor;
+
+    /* Run the ioctl before uploading the image */
+    vmw_ioctl_cursor_bypass(vmw, c->bits->xhot, c->bits->yhot);
+
+    funcs->load_cursor_argb(crtc, image);
+}
+
+static void
+vmw_screen_cursor_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
+{
+    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int i;
+
+    /* XXX assume that all crtc's have the same function struct */
+
+    /* Save old struct need to call the old functions as well */
+    vmw->cursor_priv = (void*)(config->crtc[0]->funcs);
+    memcpy(&vmw_screen_crtc_funcs, vmw->cursor_priv, sizeof(xf86CrtcFuncsRec));
+    vmw_screen_crtc_funcs.load_cursor_argb = vmw_screen_cursor_load_argb;
+
+    for (i = 0; i < config->num_crtc; i++)
+	config->crtc[i]->funcs = &vmw_screen_crtc_funcs;
+}
+
+static void
+vmw_screen_cursor_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
+{
+    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int i;
+
+    vmw_ioctl_cursor_bypass(vmw, 0, 0);
+
+    for (i = 0; i < config->num_crtc; i++)
+	config->crtc[i]->funcs = vmw->cursor_priv;
+}
+
+static Bool
+vmw_screen_init(ScrnInfoPtr pScrn)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+    struct vmw_driver *vmw;
+
+    vmw = xnfcalloc(sizeof(*vmw), 1);
+    if (!vmw)
+	return FALSE;
+
+    vmw->fd = ms->fd;
+    ms->winsys_priv = vmw;
+
+    vmw_screen_cursor_init(pScrn, vmw);
+
+    /* if gallium is used then we don't need to do anything more. */
+    if (ms->screen)
+	return TRUE;
+
+    vmw_video_init(pScrn, vmw);
+
+    return TRUE;
+}
+
+static Bool
+vmw_screen_close(ScrnInfoPtr pScrn)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+    struct vmw_driver *vmw = vmw_driver(pScrn);
+
+    if (!vmw)
+	return TRUE;
+
+    vmw_screen_cursor_close(pScrn, vmw);
+
+    vmw_video_close(pScrn, vmw);
+
+    ms->winsys_priv = NULL;
+    xfree(vmw);
+
+    return TRUE;
+}
+
+static Bool
+vmw_screen_enter_vt(ScrnInfoPtr pScrn)
+{
+    debug_printf("%s: enter\n", __func__);
+
+    return TRUE;
+}
+
+static Bool
+vmw_screen_leave_vt(ScrnInfoPtr pScrn)
+{
+    struct vmw_driver *vmw = vmw_driver(pScrn);
+
+    debug_printf("%s: enter\n", __func__);
+
+    vmw_video_stop_all(pScrn, vmw);
+
+    return TRUE;
+}
+
+/*
+ * Functions for setting up hooks into the xorg state tracker
+ */
+
+static Bool (*vmw_screen_pre_init_saved)(ScrnInfoPtr pScrn, int flags) = NULL;
+
+static Bool
+vmw_screen_pre_init(ScrnInfoPtr pScrn, int flags)
+{
+    modesettingPtr ms;
+
+    pScrn->PreInit = vmw_screen_pre_init_saved;
+    if (!pScrn->PreInit(pScrn, flags))
+	return FALSE;
+
+    ms = modesettingPTR(pScrn);
+    ms->winsys_screen_init = vmw_screen_init;
+    ms->winsys_screen_close = vmw_screen_close;
+    ms->winsys_enter_vt = vmw_screen_enter_vt;
+    ms->winsys_leave_vt = vmw_screen_leave_vt;
+
+    return TRUE;
+}
+
+void
+vmw_screen_set_functions(ScrnInfoPtr pScrn)
+{
+    assert(!vmw_screen_pre_init_saved);
+
+    vmw_screen_pre_init_saved = pScrn->PreInit;
+    pScrn->PreInit = vmw_screen_pre_init;
+}
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_video.c b/src/gallium/winsys/drm/vmware/xorg/vmw_video.c
new file mode 100644
index 0000000..b065b96
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/xorg/vmw_video.c
@@ -0,0 +1,1068 @@
+/*
+ * Copyright 2007 by VMware, Inc.
+ *
+ * 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, sublicense,
+ * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * vmwarevideo.c --
+ *
+ *      Xv extension support.
+ *      See http://www.xfree86.org/current/DESIGN16.html
+ *
+ */
+
+
+#include "xf86xv.h"
+#include "fourcc.h"
+
+#include "pipe/p_compiler.h"
+/*
+ * We can't incude svga_types.h due to conflicting types for Bool.
+ */
+typedef int64_t int64;
+typedef uint64_t uint64;
+
+typedef int32_t int32;
+typedef uint32_t uint32;
+
+typedef int16_t int16;
+typedef uint16_t uint16;
+
+typedef int8_t int8;
+typedef uint8_t uint8;
+
+#include "svga/include/svga_reg.h"
+#include "svga/include/svga_escape.h"
+#include "svga/include/svga_overlay.h"
+
+#include "vmw_driver.h"
+
+#include <X11/extensions/Xv.h>
+
+#include "xf86drm.h"
+#include "../core/vmwgfx_drm.h"
+
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+/*
+ * Number of videos that can be played simultaneously
+ */
+#define VMWARE_VID_NUM_PORTS 1
+
+/*
+ * Using a dark shade as the default colorKey
+ */
+#define VMWARE_VIDEO_COLORKEY 0x100701
+
+/*
+ * Maximum dimensions
+ */
+#define VMWARE_VID_MAX_WIDTH    2048
+#define VMWARE_VID_MAX_HEIGHT   2048
+
+#define VMWARE_VID_NUM_ENCODINGS 1
+static XF86VideoEncodingRec vmwareVideoEncodings[] =
+{
+    {
+       0,
+       "XV_IMAGE",
+       VMWARE_VID_MAX_WIDTH, VMWARE_VID_MAX_HEIGHT,
+       {1, 1}
+    }
+};
+
+#define VMWARE_VID_NUM_FORMATS 2
+static XF86VideoFormatRec vmwareVideoFormats[] =
+{
+    { 16, TrueColor},
+    { 24, TrueColor}
+};
+
+#define VMWARE_VID_NUM_IMAGES 3
+static XF86ImageRec vmwareVideoImages[] =
+{
+    XVIMAGE_YV12,
+    XVIMAGE_YUY2,
+    XVIMAGE_UYVY
+};
+
+#define VMWARE_VID_NUM_ATTRIBUTES 2
+static XF86AttributeRec vmwareVideoAttributes[] =
+{
+    {
+        XvGettable | XvSettable,
+        0x000000,
+        0xffffff,
+        "XV_COLORKEY"
+    },
+    {
+        XvGettable | XvSettable,
+        0,
+        1,
+        "XV_AUTOPAINT_COLORKEY"
+    }
+};
+
+/*
+ * Video frames are stored in a circular list of buffers.
+ * Must be power or two, See vmw_video_port_play.
+ */
+#define VMWARE_VID_NUM_BUFFERS 1
+
+/*
+ * Defines the structure used to hold and pass video data to the host
+ */
+struct vmw_video_buffer
+{
+    unsigned handle;
+    int size;
+    void *data;
+    void *extra_data;
+    struct vmw_dma_buffer *buf;
+};
+
+
+/**
+ * Structure representing a single video stream, aka port.
+ *
+ * Ports maps one to one to a SVGA stream. Port is just
+ * what Xv calls a SVGA stream.
+ */
+struct vmw_video_port
+{
+    /*
+     * Function prototype same as XvPutImage.
+     *
+     * This is either set to vmw_video_port_init or vmw_video_port_play.
+     * At init this function is set to port_init. In port_init we set it
+     * to port_play and call it, after initializing the struct.
+     */
+    int (*play)(ScrnInfoPtr, struct vmw_video_port *,
+                short, short, short, short, short,
+                short, short, short, int, unsigned char*,
+                short, short, RegionPtr);
+
+    /* values to go into the SVGAOverlayUnit */
+    uint32 streamId;
+    uint32 colorKey;
+    uint32 flags;
+
+    /* round robin of buffers */
+    unsigned currBuf;
+    struct vmw_video_buffer bufs[VMWARE_VID_NUM_BUFFERS];
+
+    /* properties that applies to all buffers */
+    int size;
+    int pitches[3];
+    int offsets[3];
+
+    /* things for X */
+    RegionRec clipBoxes;
+    Bool isAutoPaintColorkey;
+};
+
+
+/**
+ * Structure holding all the infromation for video.
+ */
+struct vmw_video_private
+{
+    int fd;
+
+    /** ports */
+    struct vmw_video_port port[VMWARE_VID_NUM_PORTS];
+
+    /** Used to store port pointers pointers */
+    DevUnion port_ptr[VMWARE_VID_NUM_PORTS];
+};
+
+
+/*
+ * Callback functions exported to Xv, prefixed with vmw_xv_*.
+ */
+static int vmw_xv_put_image(ScrnInfoPtr pScrn, short src_x, short src_y,
+                            short drw_x, short drw_y, short src_w, short src_h,
+                            short drw_w, short drw_h, int image,
+                            unsigned char *buf, short width, short height,
+                            Bool sync, RegionPtr clipBoxes, pointer data,
+                            DrawablePtr dst);
+static void vmw_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool Cleanup);
+static int vmw_xv_query_image_attributes(ScrnInfoPtr pScrn, int format,
+                                         unsigned short *width,
+                                         unsigned short *height, int *pitches,
+                                         int *offsets);
+static int vmw_xv_set_port_attribute(ScrnInfoPtr pScrn, Atom attribute,
+                                     INT32 value, pointer data);
+static int vmw_xv_get_port_attribute(ScrnInfoPtr pScrn, Atom attribute,
+                                     INT32 *value, pointer data);
+static void vmw_xv_query_best_size(ScrnInfoPtr pScrn, Bool motion,
+                                short vid_w, short vid_h, short drw_w,
+                                short drw_h, unsigned int *p_w,
+                                unsigned int *p_h, pointer data);
+
+
+/*
+ * Local functions.
+ */
+static XF86VideoAdaptorPtr vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
+
+static int vmw_video_port_init(ScrnInfoPtr pScrn,
+                               struct vmw_video_port *port,
+                               short src_x, short src_y, short drw_x,
+                               short drw_y, short src_w, short src_h,
+                               short drw_w, short drw_h, int format,
+                               unsigned char *buf, short width,
+                               short height, RegionPtr clipBoxes);
+static int vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port,
+                               short src_x, short src_y, short drw_x,
+                               short drw_y, short src_w, short src_h,
+                               short drw_w, short drw_h, int format,
+                               unsigned char *buf, short width,
+                               short height, RegionPtr clipBoxes);
+static void vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmw_video_port *port);
+
+static int vmw_video_buffer_alloc(struct vmw_driver *vmw, int size,
+                                  struct vmw_video_buffer *out);
+static int vmw_video_buffer_free(struct vmw_driver *vmw,
+                                 struct vmw_video_buffer *out);
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmw_video_init --
+ *
+ *    Initializes Xv support.
+ *
+ * Results:
+ *    TRUE on success, FALSE on error.
+ *
+ * Side effects:
+ *    Xv support is initialized. Memory is allocated for all supported
+ *    video streams.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+vmw_video_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
+{
+    ScreenPtr pScreen = pScrn->pScreen;
+    XF86VideoAdaptorPtr *overlayAdaptors, *newAdaptors = NULL;
+    XF86VideoAdaptorPtr newAdaptor = NULL;
+    int numAdaptors;
+    unsigned int ntot, nfree;
+
+    debug_printf("%s: enter\n", __func__);
+
+    if (vmw_ioctl_num_streams(vmw, &ntot, &nfree) != 0) {
+        debug_printf("No stream ioctl support\n");
+        return FALSE;
+    }
+
+    if (nfree == 0) {
+        debug_printf("No free streams\n");
+        return FALSE;
+    }
+
+    numAdaptors = xf86XVListGenericAdaptors(pScrn, &overlayAdaptors);
+
+    newAdaptor = vmw_video_init_adaptor(pScrn, vmw);
+    if (!newAdaptor) {
+        debug_printf("Failed to initialize Xv extension\n");
+        return FALSE;
+    }
+
+    if (!numAdaptors) {
+        numAdaptors = 1;
+        overlayAdaptors = &newAdaptor;
+    } else {
+         newAdaptors = xalloc((numAdaptors + 1) *
+                              sizeof(XF86VideoAdaptorPtr*));
+         if (!newAdaptors) {
+            xf86XVFreeVideoAdaptorRec(newAdaptor);
+            return FALSE;
+         }
+
+         memcpy(newAdaptors, overlayAdaptors,
+                numAdaptors * sizeof(XF86VideoAdaptorPtr));
+         newAdaptors[numAdaptors++] = newAdaptor;
+         overlayAdaptors = newAdaptors;
+    }
+
+    if (!xf86XVScreenInit(pScreen, overlayAdaptors, numAdaptors)) {
+        debug_printf("Failed to initialize Xv extension\n");
+        xf86XVFreeVideoAdaptorRec(newAdaptor);
+        return FALSE;
+    }
+
+    if (newAdaptors) {
+        xfree(newAdaptors);
+    }
+
+    debug_printf("Initialized VMware Xv extension successfully\n");
+
+    return TRUE;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmw_video_close --
+ *
+ *    Unitializes video.
+ *
+ * Results:
+ *    TRUE.
+ *
+ * Side effects:
+ *    vmw->video_priv = NULL
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+vmw_video_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
+{
+    struct vmw_video_private *video;
+    int i;
+
+    debug_printf("%s: enter\n", __func__);
+
+    video = vmw->video_priv;
+    if (!video)
+	return TRUE;
+
+    for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) {
+	/* make sure the port is stoped as well */
+	vmw_xv_stop_video(pScrn, &video->port[i], TRUE);
+	vmw_ioctl_unref_stream(vmw, video->port[i].streamId);
+    }
+
+    /* XXX: I'm sure this function is missing code for turning off Xv */
+
+    free(vmw->video_priv);
+    vmw->video_priv = NULL;
+
+    return TRUE;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmw_video_stop_all --
+ *
+ *    Stop all video streams from playing.
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects:
+ *    All buffers are freed.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void vmw_video_stop_all(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
+{
+    struct vmw_video_private *video = vmw->video_priv;
+    int i;
+
+    debug_printf("%s: enter\n", __func__);
+
+    if (!video)
+	return;
+
+    for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) {
+	vmw_xv_stop_video(pScrn, &video->port[i], TRUE);
+    }
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmw_video_init_adaptor --
+ *
+ *    Initializes a XF86VideoAdaptor structure with the capabilities and
+ *    functions supported by this video driver.
+ *
+ * Results:
+ *    On success initialized XF86VideoAdaptor struct or NULL on error
+ *
+ * Side effects:
+ *    None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static XF86VideoAdaptorPtr
+vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
+{
+    XF86VideoAdaptorPtr adaptor;
+    struct vmw_video_private *video;
+    int i;
+
+    debug_printf("%s: enter \n", __func__);
+
+    adaptor = xf86XVAllocateVideoAdaptorRec(pScrn);
+    if (!adaptor) {
+        debug_printf("Not enough memory\n");
+        return NULL;
+    }
+
+    video = xcalloc(1, sizeof(*video));
+    if (!video) {
+        debug_printf("Not enough memory.\n");
+        xf86XVFreeVideoAdaptorRec(adaptor);
+        return NULL;
+    }
+
+    vmw->video_priv = video;
+
+    adaptor->type = XvInputMask | XvImageMask | XvWindowMask;
+    adaptor->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+    adaptor->name = "VMware Video Engine";
+    adaptor->nEncodings = VMWARE_VID_NUM_ENCODINGS;
+    adaptor->pEncodings = vmwareVideoEncodings;
+    adaptor->nFormats = VMWARE_VID_NUM_FORMATS;
+    adaptor->pFormats = vmwareVideoFormats;
+    adaptor->nPorts = VMWARE_VID_NUM_PORTS;
+    adaptor->pPortPrivates = video->port_ptr;
+
+    for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) {
+        vmw_ioctl_claim_stream(vmw, &video->port[i].streamId);
+        video->port[i].play = vmw_video_port_init;
+        video->port[i].flags = SVGA_VIDEO_FLAG_COLORKEY;
+        video->port[i].colorKey = VMWARE_VIDEO_COLORKEY;
+        video->port[i].isAutoPaintColorkey = TRUE;
+        adaptor->pPortPrivates[i].ptr = &video->port[i];
+    }
+
+    adaptor->nAttributes = VMWARE_VID_NUM_ATTRIBUTES;
+    adaptor->pAttributes = vmwareVideoAttributes;
+
+    adaptor->nImages = VMWARE_VID_NUM_IMAGES;
+    adaptor->pImages = vmwareVideoImages;
+
+    adaptor->PutVideo = NULL;
+    adaptor->PutStill = NULL;
+    adaptor->GetVideo = NULL;
+    adaptor->GetStill = NULL;
+    adaptor->StopVideo = vmw_xv_stop_video;
+    adaptor->SetPortAttribute = vmw_xv_set_port_attribute;
+    adaptor->GetPortAttribute = vmw_xv_get_port_attribute;
+    adaptor->QueryBestSize = vmw_xv_query_best_size;
+    adaptor->PutImage = vmw_xv_put_image;
+    adaptor->QueryImageAttributes = vmw_xv_query_image_attributes;
+
+    debug_printf("%s: done %p\n", __func__, adaptor);
+
+    return adaptor;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmw_video_port_init --
+ *
+ *    Initializes a video stream in response to the first PutImage() on a
+ *    video stream. The process goes as follows:
+ *    - Figure out characteristics according to format
+ *    - Allocate offscreen memory
+ *    - Pass on video to Play() functions
+ *
+ * Results:
+ *    Success or XvBadAlloc on failure.
+ *
+ * Side effects:
+ *    Video stream is initialized and its first frame sent to the host
+ *    (done by VideoPlay() function called at the end)
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+vmw_video_port_init(ScrnInfoPtr pScrn, struct vmw_video_port *port,
+                    short src_x, short src_y, short drw_x,
+                    short drw_y, short src_w, short src_h,
+                    short drw_w, short drw_h, int format,
+                    unsigned char *buf, short width,
+                    short height, RegionPtr clipBoxes)
+{
+    struct vmw_driver *vmw = vmw_driver(pScrn);
+    unsigned short w, h;
+    int i, ret;
+
+    debug_printf("\t%s: id %d, format %d\n", __func__, port->streamId, format);
+
+    w = width;
+    h = height;
+    /* init all the format attributes, used for buffers */
+    port->size = vmw_xv_query_image_attributes(pScrn, format, &w, &h,
+                                               port->pitches, port->offsets);
+
+    if (port->size == -1)
+        return XvBadAlloc;
+
+    port->play = vmw_video_port_play;
+
+    for (i = 0; i < VMWARE_VID_NUM_BUFFERS; ++i) {
+	ret = vmw_video_buffer_alloc(vmw, port->size, &port->bufs[i]);
+	if (ret != Success)
+	    break;
+    }
+
+    /* Free all allocated buffers on failure */
+    if (ret != Success) {
+	for (--i; i >= 0; --i) {
+	    vmw_video_buffer_free(vmw, &port->bufs[i]);
+	}
+	return ret;
+    }
+
+    port->currBuf = 0;
+
+    REGION_COPY(pScrn->pScreen, &port->clipBoxes, clipBoxes);
+
+    if (port->isAutoPaintColorkey)
+        xf86XVFillKeyHelper(pScrn->pScreen, port->colorKey, clipBoxes);
+
+    return port->play(pScrn, port, src_x, src_y, drw_x, drw_y, src_w, src_h,
+                      drw_w, drw_h, format, buf, width, height, clipBoxes);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmw_video_port_play --
+ *
+ *    Sends all the attributes associated with the video frame using the
+ *    FIFO ESCAPE mechanism to the host.
+ *
+ * Results:
+ *    Always returns Success.
+ *
+ * Side effects:
+ *    None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port,
+                    short src_x, short src_y, short drw_x,
+                    short drw_y, short src_w, short src_h,
+                    short drw_w, short drw_h, int format,
+                    unsigned char *buf, short width,
+                    short height, RegionPtr clipBoxes)
+{
+    struct vmw_driver *vmw = vmw_driver(pScrn);
+    struct drm_vmw_control_stream_arg arg;
+    unsigned short w, h;
+    int size;
+    int ret;
+
+    debug_printf("\t%s: enter\n", __func__);
+
+    w = width;
+    h = height;
+
+    /* we don't update the ports size */
+    size = vmw_xv_query_image_attributes(pScrn, format, &w, &h,
+                                         port->pitches, port->offsets);
+
+    if (size > port->size) {
+        debug_printf("\t%s: Increase in size of Xv video frame streamId:%d.\n",
+                     __func__, port->streamId);
+        vmw_xv_stop_video(pScrn, port, TRUE);
+        return port->play(pScrn, port, src_x, src_y, drw_x, drw_y, src_w,
+                          src_h, drw_w, drw_h, format, buf, width, height,
+                          clipBoxes);
+    }
+
+    memcpy(port->bufs[port->currBuf].data, buf, port->size);
+
+    memset(&arg, 0, sizeof(arg));
+
+    arg.stream_id = port->streamId;
+    arg.enabled = TRUE;
+    arg.flags = port->flags;
+    arg.color_key = port->colorKey;
+    arg.handle = port->bufs[port->currBuf].handle;
+    arg.format = format;
+    arg.size = port->size;
+    arg.width = w;
+    arg.height = h;
+    arg.src.x = src_x;
+    arg.src.y = src_y;
+    arg.src.w = src_w;
+    arg.src.h = src_h;
+    arg.dst.x = drw_x;
+    arg.dst.y = drw_y;
+    arg.dst.w = drw_w;
+    arg.dst.h = drw_h;
+    arg.pitch[0] = port->pitches[0];
+    arg.pitch[1] = port->pitches[1];
+    arg.pitch[2] = port->pitches[2];
+    arg.offset = 0;
+
+    /*
+     *  Update the clipList and paint the colorkey, if required.
+     */
+    if (!REGION_EQUAL(pScrn->pScreen, &port->clipBoxes, clipBoxes)) {
+        REGION_COPY(pScrn->pScreen, &port->clipBoxes, clipBoxes);
+        if (port->isAutoPaintColorkey) {
+            xf86XVFillKeyHelper(pScrn->pScreen, port->colorKey, clipBoxes);
+        }
+    }
+
+    ret = drmCommandWrite(vmw->fd, DRM_VMW_CONTROL_STREAM, &arg, sizeof(arg));
+    if (ret) {
+	vmw_video_port_cleanup(pScrn, port);
+	return XvBadAlloc;
+    }
+
+    port->currBuf = ++port->currBuf & (VMWARE_VID_NUM_BUFFERS - 1);
+
+    return Success;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmw_video_port_cleanup --
+ *
+ *    Frees up all resources (if any) taken by a video stream.
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects:
+ *    Same as above.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmw_video_port *port)
+{
+    struct vmw_driver *vmw = vmw_driver(pScrn);
+    uint32 id, colorKey, flags;
+    Bool isAutoPaintColorkey;
+    int i;
+
+    debug_printf("\t%s: enter\n", __func__);
+
+    for (i = 0; i < VMWARE_VID_NUM_BUFFERS; i++) {
+	vmw_video_buffer_free(vmw, &port->bufs[i]);
+    }
+
+    /*
+     * reset stream for next video
+     */
+    id = port->streamId;
+    colorKey = port->colorKey;
+    flags = port->flags;
+    isAutoPaintColorkey = port->isAutoPaintColorkey;
+
+    memset(port, 0, sizeof(*port));
+
+    port->streamId = id;
+    port->play = vmw_video_port_init;
+    port->colorKey = colorKey;
+    port->flags = flags;
+    port->isAutoPaintColorkey = isAutoPaintColorkey;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmw_video_buffer_alloc --
+ *
+ *    Allocates and map a kernel buffer to be used as data storage.
+ *
+ * Results:
+ *    XvBadAlloc on failure, otherwise Success.
+ *
+ * Side effects:
+ *    Calls into the kernel, sets members of out.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+vmw_video_buffer_alloc(struct vmw_driver *vmw, int size,
+                       struct vmw_video_buffer *out)
+{
+    out->buf = vmw_ioctl_buffer_create(vmw, size, &out->handle);
+    if (!out->buf)
+	return XvBadAlloc;
+
+    out->data = vmw_ioctl_buffer_map(vmw, out->buf);
+    if (!out->data) {
+	vmw_ioctl_buffer_destroy(vmw, out->buf);
+
+	out->handle = 0;
+	out->buf = NULL;
+
+	return XvBadAlloc;
+    }
+
+    out->size = size;
+    out->extra_data = xcalloc(1, size);
+
+    debug_printf("\t\t%s: allocated buffer %p of size %i\n", __func__, out, size);
+
+    return Success;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmw_video_buffer_free --
+ *
+ *    Frees and unmaps an allocated kernel buffer.
+ *
+ * Results:
+ *    Success.
+ *
+ * Side effects:
+ *    Calls into the kernel, sets members of out to 0.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+vmw_video_buffer_free(struct vmw_driver *vmw,
+                      struct vmw_video_buffer *out)
+{
+    if (out->size == 0)
+	return Success;
+
+    xfree(out->extra_data);
+    vmw_ioctl_buffer_unmap(vmw, out->buf);
+    vmw_ioctl_buffer_destroy(vmw, out->buf);
+
+    out->buf = NULL;
+    out->data = NULL;
+    out->handle = 0;
+    out->size = 0;
+
+    debug_printf("\t\t%s: freed buffer %p\n", __func__, out);
+
+    return Success;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmw_xv_put_image --
+ *
+ *    Main video playback function. It copies the passed data which is in
+ *    the specified format (e.g. FOURCC_YV12) into the overlay.
+ *
+ *    If sync is TRUE the driver should not return from this
+ *    function until it is through reading the data from buf.
+ *
+ * Results:
+ *    Success or XvBadAlloc on failure
+ *
+ * Side effects:
+ *    Video port will be played(initialized if 1st frame) on success
+ *    or will fail on error.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+vmw_xv_put_image(ScrnInfoPtr pScrn, short src_x, short src_y,
+                 short drw_x, short drw_y, short src_w, short src_h,
+                 short drw_w, short drw_h, int format,
+                 unsigned char *buf, short width, short height,
+                 Bool sync, RegionPtr clipBoxes, pointer data,
+                 DrawablePtr dst)
+{
+    struct vmw_driver *vmw = vmw_driver(pScrn);
+    struct vmw_video_port *port = data;
+
+    debug_printf("%s: enter (%u, %u) (%ux%u) (%u, %u) (%ux%u) (%ux%u)\n", __func__,
+		 src_x, src_y, src_w, src_h,
+		 drw_x, drw_y, drw_w, drw_h,
+		 width, height);
+
+    if (!vmw->video_priv)
+        return XvBadAlloc;
+
+    return port->play(pScrn, port, src_x, src_y, drw_x, drw_y, src_w, src_h,
+                      drw_w, drw_h, format, buf, width, height, clipBoxes);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmw_xv_stop_video --
+ *
+ *    Called when we should stop playing video for a particular stream. If
+ *    Cleanup is FALSE, the "stop" operation is only temporary, and thus we
+ *    don't do anything. If Cleanup is TRUE we kill the video port by
+ *    sending a message to the host and freeing up the stream.
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects:
+ *    See above.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+vmw_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
+{
+    struct vmw_driver *vmw = vmw_driver(pScrn);
+    struct vmw_video_port *port = data;
+    struct drm_vmw_control_stream_arg arg;
+    int ret;
+
+    debug_printf("%s: cleanup is %s\n", __func__, cleanup ? "TRUE" : "FALSE");
+
+    if (!vmw->video_priv)
+        return;
+
+    if (!cleanup)
+        return;
+
+
+    memset(&arg, 0, sizeof(arg));
+    arg.stream_id = port->streamId;
+    arg.enabled = FALSE;
+
+    ret = drmCommandWrite(vmw->fd, DRM_VMW_CONTROL_STREAM, &arg, sizeof(arg));
+    assert(ret == 0);
+
+    vmw_video_port_cleanup(pScrn, port);
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmw_xv_query_image_attributes --
+ *
+ *    From the spec: This function is called to let the driver specify how data
+ *    for a particular image of size width by height should be stored.
+ *    Sometimes only the size and corrected width and height are needed. In
+ *    that case pitches and offsets are NULL.
+ *
+ * Results:
+ *    The size of the memory required for the image, or -1 on error.
+ *
+ * Side effects:
+ *    None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+vmw_xv_query_image_attributes(ScrnInfoPtr pScrn, int format,
+                              unsigned short *width, unsigned short *height,
+                              int *pitches, int *offsets)
+{
+    INT32 size, tmp;
+
+    if (*width > VMWARE_VID_MAX_WIDTH) {
+        *width = VMWARE_VID_MAX_WIDTH;
+    }
+    if (*height > VMWARE_VID_MAX_HEIGHT) {
+        *height = VMWARE_VID_MAX_HEIGHT;
+    }
+
+    *width = (*width + 1) & ~1;
+    if (offsets != NULL) {
+        offsets[0] = 0;
+    }
+
+    switch (format) {
+       case FOURCC_YV12:
+           *height = (*height + 1) & ~1;
+           size = (*width + 3) & ~3;
+           if (pitches) {
+               pitches[0] = size;
+           }
+           size *= *height;
+           if (offsets) {
+               offsets[1] = size;
+           }
+           tmp = ((*width >> 1) + 3) & ~3;
+           if (pitches) {
+                pitches[1] = pitches[2] = tmp;
+           }
+           tmp *= (*height >> 1);
+           size += tmp;
+           if (offsets) {
+               offsets[2] = size;
+           }
+           size += tmp;
+           break;
+       case FOURCC_UYVY:
+       case FOURCC_YUY2:
+           size = *width * 2;
+           if (pitches) {
+               pitches[0] = size;
+           }
+           size *= *height;
+           break;
+       default:
+           debug_printf("Query for invalid video format %d\n", format);
+           return -1;
+    }
+    return size;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmw_xv_set_port_attribute --
+ *
+ *    From the spec: A port may have particular attributes such as colorKey, hue,
+ *    saturation, brightness or contrast. Xv clients set these
+ *    attribute values by sending attribute strings (Atoms) to the server.
+ *
+ * Results:
+ *    Success if the attribute exists and XvBadAlloc otherwise.
+ *
+ * Side effects:
+ *    The respective attribute gets the new value.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+vmw_xv_set_port_attribute(ScrnInfoPtr pScrn, Atom attribute,
+                          INT32 value, pointer data)
+{
+    struct vmw_video_port *port = data;
+    Atom xvColorKey = MAKE_ATOM("XV_COLORKEY");
+    Atom xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
+
+    if (attribute == xvColorKey) {
+        debug_printf("%s: Set colorkey:0x%x\n", __func__, (unsigned)value);
+        port->colorKey = value;
+    } else if (attribute == xvAutoPaint) {
+        debug_printf("%s: Set autoPaint: %s\n", __func__, value? "TRUE": "FALSE");
+        port->isAutoPaintColorkey = value;
+    } else {
+        return XvBadAlloc;
+    }
+
+    return Success;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmw_xv_get_port_attribute --
+ *
+ *    From the spec: A port may have particular attributes such as hue,
+ *    saturation, brightness or contrast. Xv clients get these
+ *    attribute values by sending attribute strings (Atoms) to the server
+ *
+ * Results:
+ *    Success if the attribute exists and XvBadAlloc otherwise.
+ *
+ * Side effects:
+ *    "value" contains the requested attribute on success.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+vmw_xv_get_port_attribute(ScrnInfoPtr pScrn, Atom attribute,
+                          INT32 *value, pointer data)
+{
+    struct vmw_video_port *port = data;
+    Atom xvColorKey = MAKE_ATOM("XV_COLORKEY");
+    Atom xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
+
+    if (attribute == xvColorKey) {
+        *value = port->colorKey;
+    } else if (attribute == xvAutoPaint) {
+        *value = port->isAutoPaintColorkey;
+    } else {
+        return XvBadAlloc;
+    }
+
+    return Success;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmw_xv_query_best_size --
+ *
+ *    From the spec: QueryBestSize provides the client with a way to query what
+ *    the destination dimensions would end up being if they were to request
+ *    that an area vid_w by vid_h from the video stream be scaled to rectangle
+ *    of drw_w by drw_h on the screen. Since it is not expected that all
+ *    hardware will be able to get the target dimensions exactly, it is
+ *    important that the driver provide this function.
+ *
+ *    This function seems to never be called, but to be on the safe side
+ *    we apply the same logic that QueryImageAttributes has for width
+ *    and height.
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects:
+ *    None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+vmw_xv_query_best_size(ScrnInfoPtr pScrn, Bool motion,
+                       short vid_w, short vid_h, short drw_w,
+                       short drw_h, unsigned int *p_w,
+                       unsigned int *p_h, pointer data)
+{
+    *p_w = (drw_w + 1) & ~1;
+    *p_h = drw_h;
+
+    return;
+}
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c b/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c
new file mode 100644
index 0000000..4b20871
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c
@@ -0,0 +1,152 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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
+ * Glue file for Xorg State Tracker.
+ *
+ * @author Alan Hourihane <alanh@tungstengraphics.com>
+ * @author Jakob Bornecrantz <wallbraker@gmail.com>
+ */
+
+#include "vmw_hook.h"
+
+static void vmw_xorg_identify(int flags);
+static Bool vmw_xorg_pci_probe(DriverPtr driver,
+			       int entity_num,
+			       struct pci_device *device,
+			       intptr_t match_data);
+
+static const struct pci_id_match vmw_xorg_device_match[] = {
+    {0x15ad, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, 0},
+};
+
+static SymTabRec vmw_xorg_chipsets[] = {
+    {PCI_MATCH_ANY, "VMware SVGA Device"},
+    {-1, NULL}
+};
+
+static PciChipsets vmw_xorg_pci_devices[] = {
+    {PCI_MATCH_ANY, PCI_MATCH_ANY, NULL},
+    {-1, -1, NULL}
+};
+
+static XF86ModuleVersionInfo vmw_xorg_version = {
+    "vmwgfx",
+    MODULEVENDORSTRING,
+    MODINFOSTRING1,
+    MODINFOSTRING2,
+    XORG_VERSION_CURRENT,
+    0, 1, 0, /* major, minor, patch */
+    ABI_CLASS_VIDEODRV,
+    ABI_VIDEODRV_VERSION,
+    MOD_CLASS_VIDEODRV,
+    {0, 0, 0, 0}
+};
+
+/*
+ * Xorg driver exported structures
+ */
+
+_X_EXPORT DriverRec vmwgfx = {
+    1,
+    "vmwgfx",
+    vmw_xorg_identify,
+    NULL,
+    xorg_tracker_available_options,
+    NULL,
+    0,
+    NULL,
+    vmw_xorg_device_match,
+    vmw_xorg_pci_probe
+};
+
+static MODULESETUPPROTO(vmw_xorg_setup);
+
+_X_EXPORT XF86ModuleData vmwgfxModuleData = {
+    &vmw_xorg_version,
+    vmw_xorg_setup,
+    NULL
+};
+
+/*
+ * Xorg driver functions
+ */
+
+static pointer
+vmw_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+    static Bool setupDone = 0;
+
+    /* This module should be loaded only once, but check to be sure.
+     */
+    if (!setupDone) {
+	setupDone = 1;
+	xf86AddDriver(&vmwgfx, module, HaveDriverFuncs);
+
+	/*
+	 * The return value must be non-NULL on success even though there
+	 * is no TearDownProc.
+	 */
+	return (pointer) 1;
+    } else {
+	if (errmaj)
+	    *errmaj = LDR_ONCEONLY;
+	return NULL;
+    }
+}
+
+static void
+vmw_xorg_identify(int flags)
+{
+    xf86PrintChipsets("vmwgfx", "Driver for VMware SVGA device",
+		      vmw_xorg_chipsets);
+}
+
+static Bool
+vmw_xorg_pci_probe(DriverPtr driver,
+	  int entity_num, struct pci_device *device, intptr_t match_data)
+{
+    ScrnInfoPtr scrn = NULL;
+    EntityInfoPtr entity;
+
+    scrn = xf86ConfigPciEntity(scrn, 0, entity_num, vmw_xorg_pci_devices,
+			       NULL, NULL, NULL, NULL, NULL);
+    if (scrn != NULL) {
+	scrn->driverVersion = 1;
+	scrn->driverName = "vmwgfx";
+	scrn->name = "vmwgfx";
+	scrn->Probe = NULL;
+
+	entity = xf86GetEntityInfo(entity_num);
+
+	/* Use all the functions from the xorg tracker */
+	xorg_tracker_set_functions(scrn);
+
+	vmw_screen_set_functions(scrn);
+    }
+    return scrn != NULL;
+}
diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c
index d02f825..420dccc 100644
--- a/src/gallium/winsys/egl_xlib/egl_xlib.c
+++ b/src/gallium/winsys/egl_xlib/egl_xlib.c
@@ -41,6 +41,7 @@
 #include "pipe/p_state.h"
 #include "pipe/internal/p_winsys_screen.h"
 #include "util/u_memory.h"
+#include "util/u_math.h"
 #include "softpipe/sp_winsys.h"
 #include "softpipe/sp_texture.h"
 
@@ -138,17 +139,6 @@
 }
 
 
-static unsigned int
-bitcount(unsigned int n)
-{
-   unsigned int bits;
-   for (bits = 0; n > 0; n = n >> 1) {
-      bits += (n & 1);
-   }
-   return bits;
-}
-
-
 /**
  * Create the EGLConfigs.  (one per X visual)
  */
@@ -174,9 +164,9 @@
    for (i = 0; i < num_visuals; i++) {
       _EGLConfig *config = calloc(1, sizeof(_EGLConfig));
       int id = i + 1;
-      int rbits = bitcount(visInfo[i].red_mask);
-      int gbits = bitcount(visInfo[i].green_mask);
-      int bbits = bitcount(visInfo[i].blue_mask);
+      int rbits = util_bitcount(visInfo[i].red_mask);
+      int gbits = util_bitcount(visInfo[i].green_mask);
+      int bbits = util_bitcount(visInfo[i].blue_mask);
       int abits = bbits == 8 ? 8 : 0;
       int zbits = 24;
       int sbits = 8;
@@ -761,24 +751,18 @@
 static EGLBoolean
 xlib_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw)
 {
-   /* error checking step: */
-   if (!_eglSwapBuffers(drv, dpy, draw))
-      return EGL_FALSE;
+   struct xlib_egl_surface *xsurf = lookup_surface(draw);
+   struct pipe_winsys *pws = xsurf->winsys;
+   struct pipe_surface *psurf;
 
-   {
-      struct xlib_egl_surface *xsurf = lookup_surface(draw);
-      struct pipe_winsys *pws = xsurf->winsys;
-      struct pipe_surface *psurf;
+   st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT,
+         &psurf);
 
-      st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT,
-                                 &psurf);
+   st_notify_swapbuffers(xsurf->Framebuffer);
 
-      st_notify_swapbuffers(xsurf->Framebuffer);
+   display_surface(pws, psurf, xsurf);
 
-      display_surface(pws, psurf, xsurf);
-
-      check_and_update_buffer_size(xsurf);
-   }
+   check_and_update_buffer_size(xsurf);
 
    return EGL_TRUE;
 }
diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c
index 79ff2cc..6ee3ede 100644
--- a/src/gallium/winsys/egl_xlib/sw_winsys.c
+++ b/src/gallium/winsys/egl_xlib/sw_winsys.c
@@ -38,6 +38,7 @@
 #include "pipe/internal/p_winsys_screen.h"
 #include "pipe/p_state.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 
@@ -71,16 +72,6 @@
 }
 
 
-/**
- * Round n up to next multiple.
- */
-static INLINE unsigned
-round_up(unsigned n, unsigned multiple)
-{
-   return (n + multiple - 1) & ~(multiple - 1);
-}
-
-
 static const char *
 get_name(struct pipe_winsys *pws)
 {
@@ -170,13 +161,10 @@
                       unsigned *stride)
 {
    const unsigned alignment = 64;
-   struct pipe_format_block block;
-   unsigned nblocksx, nblocksy;
+   unsigned nblocksy;
 
-   pf_get_block(format, &block);
-   nblocksx = pf_get_nblocksx(&block, width);
-   nblocksy = pf_get_nblocksy(&block, height);
-   *stride = round_up(nblocksx * block.size, alignment);
+   nblocksy = util_format_get_nblocksy(format, height);
+   *stride = align(util_format_get_stride(format, width), alignment);
 
    return winsys->buffer_create(winsys, alignment,
                                 usage,
diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile
index 2997f6b..3965bd9 100644
--- a/src/gallium/winsys/g3dvl/nouveau/Makefile
+++ b/src/gallium/winsys/g3dvl/nouveau/Makefile
@@ -19,11 +19,7 @@
 LDFLAGS		+= -L${DRMDIR}/lib				\
 		   -L${DRIDIR}/lib				\
 		   -L${GALLIUMDIR}/winsys/drm/nouveau/common	\
-		   -L${GALLIUMDIR}/auxiliary/draw		\
-		   -L${GALLIUMDIR}/auxiliary/tgsi		\
-		   -L${GALLIUMDIR}/auxiliary/translate		\
-		   -L${GALLIUMDIR}/auxiliary/rtasm		\
-		   -L${GALLIUMDIR}/auxiliary/cso_cache		\
+		   -L${GALLIUMDIR}/auxiliary			\
 		   -L${GALLIUMDIR}/drivers/nv04			\
 		   -L${GALLIUMDIR}/drivers/nv10			\
 		   -L${GALLIUMDIR}/drivers/nv20			\
@@ -31,7 +27,7 @@
 		   -L${GALLIUMDIR}/drivers/nv40			\
 		   -L${GALLIUMDIR}/drivers/nv50
 
-LIBS		+= -lnouveaudrm -ldriclient -ldrm_nouveau -ldrm -lnv04 -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm
+LIBS		+= -lnouveaudrm -ldriclient -ldrm_nouveau -ldrm -lnv04 -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -lgallium -lm
 
 #############################################
 
diff --git a/src/gallium/winsys/g3dvl/xlib/Makefile b/src/gallium/winsys/g3dvl/xlib/Makefile
index cf765ef..9877660 100644
--- a/src/gallium/winsys/g3dvl/xlib/Makefile
+++ b/src/gallium/winsys/g3dvl/xlib/Makefile
@@ -25,13 +25,7 @@
 OBJECTS = $(SOURCES:.c=.o) $(TOP)/src/gallium/state_trackers/xorg/xvmc/*.o
 
 LIBS = $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
-       $(TOP)/src/gallium/auxiliary/vl/libvl.a \
-       $(TOP)/src/gallium/auxiliary/tgsi/libtgsi.a \
-       $(TOP)/src/gallium/auxiliary/draw/libdraw.a \
-       $(TOP)/src/gallium/auxiliary/translate/libtranslate.a \
-       $(TOP)/src/gallium/auxiliary/cso_cache/libcso_cache.a \
-       $(TOP)/src/gallium/auxiliary/rtasm/librtasm.a \
-       $(TOP)/src/gallium/auxiliary/util/libutil.a
+       $(TOP)/src/gallium/auxiliary/libgallium.a
 
 .c.o:
 	$(CC) -c $(INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
diff --git a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c
index 08067aa..f15bcd3 100644
--- a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c
+++ b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c
@@ -30,6 +30,7 @@
 #include <pipe/internal/p_winsys_screen.h>
 #include <pipe/p_state.h>
 #include <pipe/p_inlines.h>
+#include <util/u_format.h>
 #include <util/u_memory.h>
 #include <util/u_math.h>
 #include <softpipe/sp_winsys.h>
@@ -138,13 +139,10 @@
 )
 {
    const unsigned int ALIGNMENT = 1;
-   struct pipe_format_block block;
-   unsigned nblocksx, nblocksy;
+   unsigned nblocksy;
 
-   pf_get_block(format, &block);
-   nblocksx = pf_get_nblocksx(&block, width);
-   nblocksy = pf_get_nblocksy(&block, height);
-   *stride = align(nblocksx * block.size, ALIGNMENT);
+   nblocksy = util_format_get_nblocksy(format, height);
+   *stride = align(util_format_get_stride(format, width), ALIGNMENT);
 
    return pws->buffer_create(pws, ALIGNMENT, usage,
                              *stride * nblocksy);
diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript
index 8f556da..4cbc86f 100644
--- a/src/gallium/winsys/gdi/SConscript
+++ b/src/gallium/winsys/gdi/SConscript
@@ -42,8 +42,10 @@
         
     drivers += [trace]
 
+    env['no_import_lib'] = 1
+
     env.SharedLibrary(
         target ='opengl32',
         source = sources,
-        LIBS = wgl + glapi + mesa + drivers + auxiliaries + env['LIBS'],
+        LIBS = wgl + glapi + mesa + drivers + gallium + glsl + env['LIBS'],
     )
diff --git a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c b/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c
index e8bc0f5..7d076be 100644
--- a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c
+++ b/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c
@@ -39,6 +39,7 @@
 #include "pipe/p_format.h"
 #include "pipe/p_context.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "llvmpipe/lp_winsys.h"
@@ -49,7 +50,6 @@
 struct gdi_llvmpipe_displaytarget
 {
    enum pipe_format format;
-   struct pipe_format_block block;
    unsigned width;
    unsigned height;
    unsigned stride;
@@ -118,16 +118,6 @@
 }
 
 
-/**
- * Round n up to next multiple.
- */
-static INLINE unsigned
-round_up(unsigned n, unsigned multiple)
-{
-   return (n + multiple - 1) & ~(multiple - 1);
-}
-
-
 static struct llvmpipe_displaytarget *
 gdi_llvmpipe_displaytarget_create(struct llvmpipe_winsys *winsys,
                                   enum pipe_format format,
@@ -147,10 +137,10 @@
    gdt->width = width;
    gdt->height = height;
 
-   bpp = pf_get_bits(format);
-   cpp = pf_get_size(format);
+   bpp = util_format_get_blocksizebits(format);
+   cpp = util_format_get_blocksize(format);
    
-   gdt->stride = round_up(width * cpp, alignment);
+   gdt->stride = align(width * cpp, alignment);
    gdt->size = gdt->stride * height;
    
    gdt->data = align_malloc(gdt->size, alignment);
diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c
index 5e0ccf3..2ad794c 100644
--- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c
+++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c
@@ -42,6 +42,7 @@
 #include "pipe/p_format.h"
 #include "pipe/p_context.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "softpipe/sp_winsys.h"
@@ -151,16 +152,6 @@
 }
 
 
-/**
- * Round n up to next multiple.
- */
-static INLINE unsigned
-round_up(unsigned n, unsigned multiple)
-{
-   return (n + multiple - 1) & ~(multiple - 1);
-}
-
-
 static struct pipe_buffer *
 gdi_softpipe_surface_buffer_create(struct pipe_winsys *winsys,
                                    unsigned width, unsigned height,
@@ -170,13 +161,10 @@
                                    unsigned *stride)
 {
    const unsigned alignment = 64;
-   struct pipe_format_block block;
-   unsigned nblocksx, nblocksy;
+   unsigned nblocksy;
 
-   pf_get_block(format, &block);
-   nblocksx = pf_get_nblocksx(&block, width);
-   nblocksy = pf_get_nblocksy(&block, height);
-   *stride = round_up(nblocksx * block.size, alignment);
+   nblocksy = util_format_get_nblocksy(format, height);
+   *stride = align(util_format_get_stride(format, width), alignment);
 
    return winsys->buffer_create(winsys, alignment,
                                 usage,
@@ -283,10 +271,10 @@
 
     memset(&bmi, 0, sizeof(BITMAPINFO));
     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-    bmi.bmiHeader.biWidth = texture->stride[surface->level] / pf_get_size(surface->format);
+    bmi.bmiHeader.biWidth = texture->stride[surface->level] / util_format_get_blocksize(surface->format);
     bmi.bmiHeader.biHeight= -(long)surface->height;
     bmi.bmiHeader.biPlanes = 1;
-    bmi.bmiHeader.biBitCount = pf_get_bits(surface->format);
+    bmi.bmiHeader.biBitCount = util_format_get_blocksizebits(surface->format);
     bmi.bmiHeader.biCompression = BI_RGB;
     bmi.bmiHeader.biSizeImage = 0;
     bmi.bmiHeader.biXPelsPerMeter = 0;
diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile
index 3dc38a7..9482e8f 100644
--- a/src/gallium/winsys/xlib/Makefile
+++ b/src/gallium/winsys/xlib/Makefile
@@ -23,17 +23,14 @@
 	-I$(TOP)/src/gallium/auxiliary
 
 DEFINES += \
-	-DGALLIUM_SOFTPIPE \
-	-DGALLIUM_TRACE \
-	-DGALLIUM_BRW
+	-DGALLIUM_SOFTPIPE
 #-DGALLIUM_CELL will be defined by the config */
 
 XLIB_WINSYS_SOURCES = \
 	xlib.c \
 	xlib_cell.c \
 	xlib_llvmpipe.c \
-	xlib_softpipe.c \
-	xlib_trace.c 
+	xlib_softpipe.c
 
 
 XLIB_WINSYS_OBJECTS = $(XLIB_WINSYS_SOURCES:.c=.o)
@@ -84,11 +81,11 @@
 
 
 install: default
-	$(INSTALL) -d $(INSTALL_DIR)/include/GL
-	$(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR)
-	$(INSTALL) -m 644 $(TOP)/include/GL/*.h $(INSTALL_DIR)/include/GL
+	$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GL
+	$(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+	$(INSTALL) -m 644 $(TOP)/include/GL/*.h $(DESTDIR)$(INSTALL_DIR)/include/GL
 	@if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \
-		$(MINSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \
+		$(MINSTALL) $(TOP)/$(LIB_DIR)/libGL* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \
 	fi
 
 
diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript
index dfe550f..a4dabb7 100644
--- a/src/gallium/winsys/xlib/SConscript
+++ b/src/gallium/winsys/xlib/SConscript
@@ -3,55 +3,66 @@
 
 Import('*')
 
-if env['platform'] == 'linux' \
-        and 'mesa' in env['statetrackers'] \
-        and set(('softpipe', 'llvmpipe', 'i915', 'trace')).intersection(env['drivers']) \
-        and not env['dri']:
+if env['platform'] != 'linux':
+    Return()
 
-    env = env.Clone()
+if 'mesa' not in env['statetrackers']:
+    print 'warning: Mesa state tracker disabled: skipping build of xlib libGL.so'
+    Return()
 
-    env.Append(CPPPATH = [
-        '#/src/mesa',
-        '#/src/mesa/main',
-        '#src/gallium/state_trackers/glx/xlib',
-    ])
+if env['dri']:
+    print 'warning: DRI enabled: skipping build of xlib libGL.so'
+    Return()
 
-    env.Append(CPPDEFINES = ['USE_XSHM'])
+if 'trace' not in env['drivers']:
+    print 'warning: trace pipe driver disabled: skipping build of xlib libGL.so'
+    Return()
 
-    sources = [
-        'xlib.c',
-    ]
+if not set(('softpipe', 'llvmpipe', 'trace')).intersection(env['drivers']):
+    print 'warning: no supported pipe driver: skipping build of xlib libGL.so'
+    Return()
 
-    drivers = []
-        
-    if 'softpipe' in env['drivers']:
-        env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE')
-        sources += ['xlib_softpipe.c']
-        drivers += [softpipe]
+env = env.Clone()
 
-    if 'llvmpipe' in env['drivers']:
-        env.Tool('llvm')
-        if 'LLVM_VERSION' in env:
-            env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE')
-            env.Tool('udis86')
-            sources += ['xlib_llvmpipe.c']
-            drivers += [llvmpipe]
-        
-    if 'cell' in env['drivers']:
-        env.Append(CPPDEFINES = 'GALLIUM_CELL')
-        sources += ['xlib_cell.c']
-        drivers += [cell]
+env.Append(CPPPATH = [
+    '#/src/mesa',
+    '#/src/mesa/main',
+    '#src/gallium/state_trackers/glx/xlib',
+])
 
-    if 'trace' in env['drivers']:
-        env.Append(CPPDEFINES = 'GALLIUM_TRACE')
-        sources += ['xlib_trace.c']
-        drivers += [trace]
+env.Append(CPPDEFINES = ['USE_XSHM'])
 
-    # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
-    libgl = env.SharedLibrary(
-        target ='GL',
-        source = sources,
-        LIBS = st_xlib + glapi + mesa + drivers + auxiliaries + env['LIBS'],
-    )
+sources = [
+    'xlib.c',
+]
 
+drivers = [trace]
+    
+if 'softpipe' in env['drivers']:
+    env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE')
+    sources += ['xlib_softpipe.c']
+    drivers += [softpipe]
+
+if 'llvmpipe' in env['drivers']:
+    env.Tool('llvm')
+    if 'LLVM_VERSION' in env:
+        env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE')
+        env.Tool('udis86')
+        sources += ['xlib_llvmpipe.c']
+        drivers += [llvmpipe]
+    
+if 'cell' in env['drivers']:
+    env.Append(CPPDEFINES = 'GALLIUM_CELL')
+    sources += ['xlib_cell.c']
+    drivers += [cell]
+
+# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
+libgl = env.SharedLibrary(
+    target ='GL',
+    source = sources,
+    LIBS = st_xlib + glapi + mesa + glsl + drivers + gallium + env['LIBS'],
+)
+
+if not env['dri']:
+    # Only install this libGL.so if DRI not enabled
     env.InstallSharedLibrary(libgl, version=(1, 5))
diff --git a/src/gallium/winsys/xlib/xlib.c b/src/gallium/winsys/xlib/xlib.c
index bf2fb23..541ea7a 100644
--- a/src/gallium/winsys/xlib/xlib.c
+++ b/src/gallium/winsys/xlib/xlib.c
@@ -42,18 +42,16 @@
  */
 
 enum mode {
-   MODE_TRACE,
    MODE_CELL,
    MODE_LLVMPIPE,
    MODE_SOFTPIPE
 };
 
+/* advertise OpenGL support */
+PUBLIC const int st_api_OpenGL = 1;
 
 static enum mode get_mode()
 {
-   if (getenv("XMESA_TRACE"))
-      return MODE_TRACE;
-
 #ifdef GALLIUM_CELL
    if (!getenv("GALLIUM_NOCELL")) 
       return MODE_CELL;
@@ -73,11 +71,6 @@
    enum mode xlib_mode = get_mode();
 
    switch (xlib_mode) {
-   case MODE_TRACE:
-#if defined(GALLIUM_TRACE) && defined(GALLIUM_SOFTPIPE)
-      xmesa_set_driver( &xlib_trace_driver );
-#endif
-      break;
    case MODE_CELL:
 #if defined(GALLIUM_CELL)
       xmesa_set_driver( &xlib_cell_driver );
diff --git a/src/gallium/winsys/xlib/xlib.h b/src/gallium/winsys/xlib/xlib.h
index f085503..8e091d0 100644
--- a/src/gallium/winsys/xlib/xlib.h
+++ b/src/gallium/winsys/xlib/xlib.h
@@ -5,7 +5,6 @@
 #include "pipe/p_compiler.h"
 #include "xm_winsys.h"
 
-extern struct xm_driver xlib_trace_driver;
 extern struct xm_driver xlib_softpipe_driver;
 extern struct xm_driver xlib_llvmpipe_driver;
 extern struct xm_driver xlib_cell_driver;
diff --git a/src/gallium/winsys/xlib/xlib_brw_context.c b/src/gallium/winsys/xlib/xlib_brw_context.c
new file mode 100644
index 0000000..fc9addd
--- /dev/null
+++ b/src/gallium/winsys/xlib/xlib_brw_context.c
@@ -0,0 +1,209 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * 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 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * 
+ **************************************************************************/
+
+/*
+ * Authors:
+ *   Keith Whitwell
+ *   Brian Paul
+ */
+
+
+/* #include "glxheader.h" */
+/* #include "xmesaP.h" */
+
+#include "pipe/internal/p_winsys_screen.h"
+#include "pipe/p_inlines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "i965simple/brw_winsys.h"
+#include "xlib_brw_aub.h"
+#include "xlib_brw.h"
+
+
+
+
+#define XBCWS_BATCHBUFFER_SIZE 1024
+
+
+/* The backend to the brw driver (ie struct brw_winsys) is actually a
+ * per-context entity.
+ */
+struct xlib_brw_context_winsys {
+   struct brw_winsys brw_context_winsys;   /**< batch buffer funcs */
+   struct aub_context *aub;
+                         
+   struct pipe_winsys *pipe_winsys;
+
+   unsigned batch_data[XBCWS_BATCHBUFFER_SIZE];
+   unsigned batch_nr;
+   unsigned batch_size;
+   unsigned batch_alloc;
+};
+
+
+/* Turn a brw_winsys into an xlib_brw_context_winsys:
+ */
+static inline struct xlib_brw_context_winsys *
+xlib_brw_context_winsys( struct brw_winsys *sws )
+{
+   return (struct xlib_brw_context_winsys *)sws;
+}
+
+
+/* Simple batchbuffer interface:
+ */
+
+static unsigned *xbcws_batch_start( struct brw_winsys *sws,
+					 unsigned dwords,
+					 unsigned relocs )
+{
+   struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
+
+   if (xbcws->batch_size < xbcws->batch_nr + dwords)
+      return NULL;
+
+   xbcws->batch_alloc = xbcws->batch_nr + dwords;
+   return (void *)1;			/* not a valid pointer! */
+}
+
+static void xbcws_batch_dword( struct brw_winsys *sws,
+				    unsigned dword )
+{
+   struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
+
+   assert(xbcws->batch_nr < xbcws->batch_alloc);
+   xbcws->batch_data[xbcws->batch_nr++] = dword;
+}
+
+static void xbcws_batch_reloc( struct brw_winsys *sws,
+			     struct pipe_buffer *buf,
+			     unsigned access_flags,
+			     unsigned delta )
+{
+   struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
+
+   assert(xbcws->batch_nr < xbcws->batch_alloc);
+   xbcws->batch_data[xbcws->batch_nr++] = 
+      ( xlib_brw_get_buffer_offset( NULL, buf, access_flags ) +
+        delta );
+}
+
+static void xbcws_batch_end( struct brw_winsys *sws )
+{
+   struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
+
+   assert(xbcws->batch_nr <= xbcws->batch_alloc);
+   xbcws->batch_alloc = 0;
+}
+
+static void xbcws_batch_flush( struct brw_winsys *sws,
+				    struct pipe_fence_handle **fence )
+{
+   struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
+   assert(xbcws->batch_nr <= xbcws->batch_size);
+
+   if (xbcws->batch_nr) {
+      xlib_brw_commands_aub( xbcws->pipe_winsys,
+                             xbcws->batch_data,
+                             xbcws->batch_nr );
+   }
+
+   xbcws->batch_nr = 0;
+}
+
+  
+
+/* Really a per-device function, just pass through:
+ */
+static unsigned xbcws_get_buffer_offset( struct brw_winsys *sws,
+                                         struct pipe_buffer *buf,
+                                         unsigned access_flags )
+{
+   struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
+
+   return xlib_brw_get_buffer_offset( xbcws->pipe_winsys,
+                                      buf,
+                                      access_flags );
+}
+
+
+/* Really a per-device function, just pass through:
+ */
+static void xbcws_buffer_subdata_typed( struct brw_winsys *sws,
+                                       struct pipe_buffer *buf,
+                                       unsigned long offset, 
+                                       unsigned long size, 
+                                       const void *data,
+                                       unsigned data_type )
+{
+   struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
+
+   xlib_brw_buffer_subdata_typed( xbcws->pipe_winsys,
+                                  buf,
+                                  offset,
+                                  size,
+                                  data,
+                                  data_type );
+}
+
+
+/**
+ * Create i965 hardware rendering context, but plugged into a
+ * dump-to-aubfile backend.
+ */
+struct pipe_context *
+xlib_create_brw_context( struct pipe_screen *screen,
+                         void *unused )
+{
+   struct xlib_brw_context_winsys *xbcws = CALLOC_STRUCT( xlib_brw_context_winsys );
+   
+   /* Fill in this struct with callbacks that i965simple will need to
+    * communicate with the window system, buffer manager, etc. 
+    */
+   xbcws->brw_context_winsys.batch_start = xbcws_batch_start;
+   xbcws->brw_context_winsys.batch_dword = xbcws_batch_dword;
+   xbcws->brw_context_winsys.batch_reloc = xbcws_batch_reloc;
+   xbcws->brw_context_winsys.batch_end = xbcws_batch_end;
+   xbcws->brw_context_winsys.batch_flush = xbcws_batch_flush;
+   xbcws->brw_context_winsys.buffer_subdata_typed = xbcws_buffer_subdata_typed;
+   xbcws->brw_context_winsys.get_buffer_offset = xbcws_get_buffer_offset;
+
+   xbcws->pipe_winsys = screen->winsys; /* redundant */
+
+   xbcws->batch_size = XBCWS_BATCHBUFFER_SIZE;
+
+   /* Create the i965simple context:
+    */
+#ifdef GALLIUM_CELL
+   return NULL;
+#else
+   return brw_create( screen,
+		      &xbcws->brw_context_winsys,
+		      0 );
+#endif
+}
diff --git a/src/gallium/winsys/xlib/xlib_cell.c b/src/gallium/winsys/xlib/xlib_cell.c
index 13e609f..47ae051 100644
--- a/src/gallium/winsys/xlib/xlib_cell.c
+++ b/src/gallium/winsys/xlib/xlib_cell.c
@@ -45,6 +45,7 @@
 #include "pipe/p_format.h"
 #include "pipe/p_context.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 
@@ -277,35 +278,24 @@
 
 
 
-/**
- * Round n up to next multiple.
- */
-static INLINE unsigned
-round_up(unsigned n, unsigned multiple)
-{
-   return (n + multiple - 1) & ~(multiple - 1);
-}
-
 static struct pipe_buffer *
 xm_surface_buffer_create(struct pipe_winsys *winsys,
                          unsigned width, unsigned height,
                          enum pipe_format format,
                          unsigned usage,
+                         unsigned tex_usage,
                          unsigned *stride)
 {
    const unsigned alignment = 64;
-   struct pipe_format_block block;
-   unsigned nblocksx, nblocksy;
+   unsigned nblocksy;
 
-   pf_get_block(format, &block);
-   nblocksx = pf_get_nblocksx(&block, width);
-   nblocksy = pf_get_nblocksy(&block, height);
-   *stride = round_up(nblocksx * block.size, alignment);
+   nblocksy = util_format_get_nblocksy(format, height);
+   *stride = align(util_format_get_stride(format, width), alignment);
 
    return winsys->buffer_create(winsys, alignment,
                                 usage,
                                 /* XXX a bit of a hack */
-                                *stride * round_up(nblocksy, TILE_SIZE));
+                                *stride * align(nblocksy, TILE_SIZE));
 }
 
 
diff --git a/src/gallium/winsys/xlib/xlib_llvmpipe.c b/src/gallium/winsys/xlib/xlib_llvmpipe.c
index 3dd15e0..2a434b5 100644
--- a/src/gallium/winsys/xlib/xlib_llvmpipe.c
+++ b/src/gallium/winsys/xlib/xlib_llvmpipe.c
@@ -44,6 +44,7 @@
 #include "pipe/p_format.h"
 #include "pipe/p_context.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "llvmpipe/lp_winsys.h"
@@ -58,7 +59,6 @@
 struct xm_displaytarget
 {
    enum pipe_format format;
-   struct pipe_format_block block;
    unsigned width;
    unsigned height;
    unsigned stride;
@@ -262,10 +262,10 @@
    {
       if (xm_dt->tempImage == NULL)
       {
-         assert(xm_dt->block.width == 1);
-         assert(xm_dt->block.height == 1);
+         assert(util_format_get_blockwidth(xm_dt->format) == 1);
+         assert(util_format_get_blockheight(xm_dt->format) == 1);
          alloc_shm_ximage(xm_dt, xm_buffer,
-                          xm_dt->stride / xm_dt->block.size,
+                          xm_dt->stride / util_format_get_blocksize(xm_dt->format),
                           xm_dt->height);
       }
 
@@ -321,7 +321,7 @@
                         unsigned *stride)
 {
    struct xm_displaytarget *xm_dt = CALLOC_STRUCT(xm_displaytarget);
-   unsigned nblocksx, nblocksy, size;
+   unsigned nblocksy, size;
 
    xm_dt = CALLOC_STRUCT(xm_displaytarget);
    if(!xm_dt)
@@ -331,10 +331,8 @@
    xm_dt->width = width;
    xm_dt->height = height;
 
-   pf_get_block(format, &xm_dt->block);
-   nblocksx = pf_get_nblocksx(&xm_dt->block, width);
-   nblocksy = pf_get_nblocksy(&xm_dt->block, height);
-   xm_dt->stride = align(nblocksx * xm_dt->block.size, alignment);
+   nblocksy = util_format_get_nblocksy(format, height);
+   xm_dt->stride = align(util_format_get_stride(format, width), alignment);
    size = xm_dt->stride * nblocksy;
 
 #ifdef USE_XSHM
diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c
index 260b39e..f7c0099 100644
--- a/src/gallium/winsys/xlib/xlib_softpipe.c
+++ b/src/gallium/winsys/xlib/xlib_softpipe.c
@@ -42,6 +42,7 @@
 #include "pipe/p_format.h"
 #include "pipe/p_context.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "softpipe/sp_winsys.h"
@@ -254,10 +255,10 @@
    {
       if (xm_buf->tempImage == NULL) 
       {
-         assert(surf->texture->block.width == 1);
-         assert(surf->texture->block.height == 1);
+         assert(util_format_get_blockwidth(surf->texture->format) == 1);
+         assert(util_format_get_blockheight(surf->texture->format) == 1);
          alloc_shm_ximage(xm_buf, b, spt->stride[surf->level] /
-                          surf->texture->block.size, surf->height);
+                          util_format_get_blocksize(surf->texture->format), surf->height);
       }
 
       ximage = xm_buf->tempImage;
@@ -360,13 +361,10 @@
                          unsigned *stride)
 {
    const unsigned alignment = 64;
-   struct pipe_format_block block;
-   unsigned nblocksx, nblocksy, size;
+   unsigned nblocksy, size;
 
-   pf_get_block(format, &block);
-   nblocksx = pf_get_nblocksx(&block, width);
-   nblocksy = pf_get_nblocksy(&block, height);
-   *stride = align(nblocksx * block.size, alignment);
+   nblocksy = util_format_get_nblocksy(format, height);
+   *stride = align(util_format_get_stride(format, width), alignment);
    size = *stride * nblocksy;
 
 #ifdef USE_XSHM
diff --git a/src/gallium/winsys/xlib/xlib_trace.c b/src/gallium/winsys/xlib/xlib_trace.c
deleted file mode 100644
index dbea655..0000000
--- a/src/gallium/winsys/xlib/xlib_trace.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
- * 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 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
- * THE COPYRIGHT HOLDERS, AUTHORS 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.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * 
- **************************************************************************/
-
-/*
- * Authors:
- *   Keith Whitwell
- *   Brian Paul
- */
-
-
-#include "xlib.h"
-
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
-#include "trace/tr_texture.h"
-
-#include "pipe/p_screen.h"
-
-
-
-static struct pipe_screen *
-xlib_create_trace_screen( void )
-{
-   struct pipe_screen *screen, *trace_screen;
-
-   screen = xlib_softpipe_driver.create_pipe_screen();
-   if (screen == NULL)
-      goto fail;
-
-   /* Wrap it:
-    */
-   trace_screen = trace_screen_create(screen);
-   if (trace_screen == NULL)
-      goto fail;
-
-   return trace_screen;
-
-fail:
-   if (screen)
-      screen->destroy( screen );
-   return NULL;
-}
-
-static struct pipe_context *
-xlib_create_trace_context( struct pipe_screen *_screen,
-                           void *priv )
-{
-   struct trace_screen *tr_scr = trace_screen( _screen );
-   struct pipe_screen *screen = tr_scr->screen;
-   struct pipe_context *pipe, *trace_pipe;
-   
-   pipe = xlib_softpipe_driver.create_pipe_context( screen, priv );
-   if (pipe == NULL)
-      goto fail;
-
-   /* Wrap it:
-    */
-   trace_pipe = trace_context_create(_screen, pipe);
-   if (trace_pipe == NULL)
-      goto fail;
-
-   trace_pipe->priv = priv;
-
-   return trace_pipe;
-
-fail:
-   if (pipe)
-      pipe->destroy( pipe );
-   return NULL;
-}
-
-static void
-xlib_trace_display_surface( struct xmesa_buffer *buffer,
-                            struct pipe_surface *_surf )
-{
-   struct trace_surface *tr_surf = trace_surface( _surf );
-   struct pipe_surface *surf = tr_surf->surface;
-
-   xlib_softpipe_driver.display_surface( buffer, surf );
-}
-
-
-struct xm_driver xlib_trace_driver = 
-{
-   .create_pipe_screen = xlib_create_trace_screen,
-   .create_pipe_context = xlib_create_trace_context,
-   .display_surface = xlib_trace_display_surface,
-};
diff --git a/src/glew/SConscript b/src/glew/SConscript
index 1161be6..ce6e71e 100644
--- a/src/glew/SConscript
+++ b/src/glew/SConscript
@@ -1,29 +1,12 @@
 Import('*')
 
-if env['platform'] not in ['windows', 'linux']:
-    Return()
-
+# Shared environment settings
 env = env.Clone()
 
-env.Append(CPPDEFINES = [
-    'GLEW_BUILD',
-    'GLEW_STATIC',
-    #'GLEW_MX', # Multiple Rendering Contexts support
-])
-
 env.PrependUnique(CPPPATH = [
     '#/include',
 ])
 
-glew = env.StaticLibrary(
-    target = 'glew',
-    source = [
-        'glew.c',
-    ],
-)
-
-env = env.Clone()
-
 if env['platform'] == 'windows':
     env.PrependUnique(LIBS = [
         'glu32', 
@@ -37,14 +20,46 @@
         'GL',
         'X11',
     ])
-env.Prepend(LIBS = [glew])
 
-env.Program(
+# Library specific environment settings
+lib_env = env.Clone()
+
+lib_env.Append(CPPDEFINES = [
+    'GLEW_BUILD',
+    #'GLEW_MX', # Multiple Rendering Contexts support
+])
+
+if lib_env['platform'] == 'windows':
+    target = 'glew'
+else:
+    target = 'GLEW'
+
+source = [
+    'glew.c',
+]
+
+if lib_env['platform'] == 'windows':
+    glew = lib_env.SharedLibrary(target = target, source = source) 
+    env.InstallSharedLibrary(glew, version=(1, 5, 2))
+    glew = lib_env.FindIxes(glew, 'LIBPREFIX', 'LIBSUFFIX')
+else:
+    # Use static library on Unices to avoid binary compatability issues
+    lib_env.Append(CPPDEFINES = ['GLEW_STATIC'])
+    glew = lib_env.StaticLibrary(target = target, source = source) 
+
+# Program specific environment settings
+prog_env = env.Clone()
+
+prog_env.Prepend(LIBS = [glew])
+
+prog_env.Program(
     target = 'glewinfo',
     source = ['glewinfo.c'],
 )
 
-env.Program(
+prog_env.Program(
     target = 'visualinfo',
     source = ['visualinfo.c'],
 )
+
+Export('glew')
diff --git a/src/glew/glew.c b/src/glew/glew.c
index aa2278f..624222f 100644
--- a/src/glew/glew.c
+++ b/src/glew/glew.c
@@ -66,9 +66,26 @@
 #endif /* GLEW_MX */
 
 #if defined(__APPLE__)
-#include <mach-o/dyld.h>
 #include <stdlib.h>
 #include <string.h>
+#include <AvailabilityMacros.h>
+
+#ifdef MAC_OS_X_VERSION_10_3
+
+#include <dlfcn.h>
+
+void* NSGLGetProcAddress (const GLubyte *name)
+{
+  static void* image = NULL;
+  if (NULL == image) 
+  {
+    image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
+  }
+  return image ? dlsym(image, (const char*)name) : NULL;
+}
+#else
+
+#include <mach-o/dyld.h>
 
 void* NSGLGetProcAddress (const GLubyte *name)
 {
@@ -90,6 +107,7 @@
   free(symbolName);
   return symbol ? NSAddressOfSymbol(symbol) : NULL;
 }
+#endif /* MAC_OS_X_VERSION_10_3 */
 #endif /* __APPLE__ */
 
 #if defined(__sgi) || defined (__sun)
@@ -444,8 +462,6 @@
 
 PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender = NULL;
 PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback = NULL;
-PFNGLBINDBUFFERBASEPROC __glewBindBufferBase = NULL;
-PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange = NULL;
 PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation = NULL;
 PFNGLCLAMPCOLORPROC __glewClampColor = NULL;
 PFNGLCLEARBUFFERFIPROC __glewClearBufferfi = NULL;
@@ -459,7 +475,6 @@
 PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback = NULL;
 PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v = NULL;
 PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation = NULL;
-PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v = NULL;
 PFNGLGETSTRINGIPROC __glewGetStringi = NULL;
 PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv = NULL;
 PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv = NULL;
@@ -501,8 +516,37 @@
 PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv = NULL;
 PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer = NULL;
 
+PFNGLDRAWARRAYSINSTANCEDPROC __glewDrawArraysInstanced = NULL;
+PFNGLDRAWELEMENTSINSTANCEDPROC __glewDrawElementsInstanced = NULL;
+PFNGLPRIMITIVERESTARTINDEXPROC __glewPrimitiveRestartIndex = NULL;
+PFNGLTEXBUFFERPROC __glewTexBuffer = NULL;
+
+PFNGLFRAMEBUFFERTEXTUREPROC __glewFramebufferTexture = NULL;
+PFNGLGETBUFFERPARAMETERI64VPROC __glewGetBufferParameteri64v = NULL;
+PFNGLGETINTEGER64I_VPROC __glewGetInteger64i_v = NULL;
+
 PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX = NULL;
 
+PFNGLBLENDEQUATIONINDEXEDAMDPROC __glewBlendEquationIndexedAMD = NULL;
+PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC __glewBlendEquationSeparateIndexedAMD = NULL;
+PFNGLBLENDFUNCINDEXEDAMDPROC __glewBlendFuncIndexedAMD = NULL;
+PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC __glewBlendFuncSeparateIndexedAMD = NULL;
+
+PFNGLBEGINPERFMONITORAMDPROC __glewBeginPerfMonitorAMD = NULL;
+PFNGLDELETEPERFMONITORSAMDPROC __glewDeletePerfMonitorsAMD = NULL;
+PFNGLENDPERFMONITORAMDPROC __glewEndPerfMonitorAMD = NULL;
+PFNGLGENPERFMONITORSAMDPROC __glewGenPerfMonitorsAMD = NULL;
+PFNGLGETPERFMONITORCOUNTERDATAAMDPROC __glewGetPerfMonitorCounterDataAMD = NULL;
+PFNGLGETPERFMONITORCOUNTERINFOAMDPROC __glewGetPerfMonitorCounterInfoAMD = NULL;
+PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC __glewGetPerfMonitorCounterStringAMD = NULL;
+PFNGLGETPERFMONITORCOUNTERSAMDPROC __glewGetPerfMonitorCountersAMD = NULL;
+PFNGLGETPERFMONITORGROUPSTRINGAMDPROC __glewGetPerfMonitorGroupStringAMD = NULL;
+PFNGLGETPERFMONITORGROUPSAMDPROC __glewGetPerfMonitorGroupsAMD = NULL;
+PFNGLSELECTPERFMONITORCOUNTERSAMDPROC __glewSelectPerfMonitorCountersAMD = NULL;
+
+PFNGLTESSELLATIONFACTORAMDPROC __glewTessellationFactorAMD = NULL;
+PFNGLTESSELLATIONMODEAMDPROC __glewTessellationModeAMD = NULL;
+
 PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE = NULL;
 PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE = NULL;
 PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE = NULL;
@@ -521,6 +565,10 @@
 PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE = NULL;
 PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE = NULL;
 
+PFNGLGETOBJECTPARAMETERIVAPPLEPROC __glewGetObjectParameterivAPPLE = NULL;
+PFNGLOBJECTPURGEABLEAPPLEPROC __glewObjectPurgeableAPPLE = NULL;
+PFNGLOBJECTUNPURGEABLEAPPLEPROC __glewObjectUnpurgeableAPPLE = NULL;
+
 PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE = NULL;
 PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE = NULL;
 
@@ -533,10 +581,30 @@
 PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE = NULL;
 PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE = NULL;
 
+PFNGLDISABLEVERTEXATTRIBAPPLEPROC __glewDisableVertexAttribAPPLE = NULL;
+PFNGLENABLEVERTEXATTRIBAPPLEPROC __glewEnableVertexAttribAPPLE = NULL;
+PFNGLISVERTEXATTRIBENABLEDAPPLEPROC __glewIsVertexAttribEnabledAPPLE = NULL;
+PFNGLMAPVERTEXATTRIB1DAPPLEPROC __glewMapVertexAttrib1dAPPLE = NULL;
+PFNGLMAPVERTEXATTRIB1FAPPLEPROC __glewMapVertexAttrib1fAPPLE = NULL;
+PFNGLMAPVERTEXATTRIB2DAPPLEPROC __glewMapVertexAttrib2dAPPLE = NULL;
+PFNGLMAPVERTEXATTRIB2FAPPLEPROC __glewMapVertexAttrib2fAPPLE = NULL;
+
 PFNGLCLAMPCOLORARBPROC __glewClampColorARB = NULL;
 
+PFNGLCOPYBUFFERSUBDATAPROC __glewCopyBufferSubData = NULL;
+
 PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB = NULL;
 
+PFNGLBLENDEQUATIONSEPARATEIARBPROC __glewBlendEquationSeparateiARB = NULL;
+PFNGLBLENDEQUATIONIARBPROC __glewBlendEquationiARB = NULL;
+PFNGLBLENDFUNCSEPARATEIARBPROC __glewBlendFuncSeparateiARB = NULL;
+PFNGLBLENDFUNCIARBPROC __glewBlendFunciARB = NULL;
+
+PFNGLDRAWELEMENTSBASEVERTEXPROC __glewDrawElementsBaseVertex = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC __glewDrawElementsInstancedBaseVertex = NULL;
+PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC __glewDrawRangeElementsBaseVertex = NULL;
+PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC __glewMultiDrawElementsBaseVertex = NULL;
+
 PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB = NULL;
 PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB = NULL;
 
@@ -547,10 +615,10 @@
 PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers = NULL;
 PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers = NULL;
 PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer = NULL;
-PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer = NULL;
 PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D = NULL;
 PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D = NULL;
 PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D = NULL;
+PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer = NULL;
 PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers = NULL;
 PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers = NULL;
 PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap = NULL;
@@ -659,6 +727,10 @@
 PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB = NULL;
 PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB = NULL;
 
+PFNGLPROVOKINGVERTEXPROC __glewProvokingVertex = NULL;
+
+PFNGLMINSAMPLESHADINGARBPROC __glewMinSampleShadingARB = NULL;
+
 PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB = NULL;
 PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB = NULL;
 PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB = NULL;
@@ -699,6 +771,14 @@
 PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB = NULL;
 PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB = NULL;
 
+PFNGLCLIENTWAITSYNCPROC __glewClientWaitSync = NULL;
+PFNGLDELETESYNCPROC __glewDeleteSync = NULL;
+PFNGLFENCESYNCPROC __glewFenceSync = NULL;
+PFNGLGETINTEGER64VPROC __glewGetInteger64v = NULL;
+PFNGLGETSYNCIVPROC __glewGetSynciv = NULL;
+PFNGLISSYNCPROC __glewIsSync = NULL;
+PFNGLWAITSYNCPROC __glewWaitSync = NULL;
+
 PFNGLTEXBUFFERARBPROC __glewTexBufferARB = NULL;
 
 PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB = NULL;
@@ -709,11 +789,27 @@
 PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB = NULL;
 PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB = NULL;
 
+PFNGLGETMULTISAMPLEFVPROC __glewGetMultisamplefv = NULL;
+PFNGLSAMPLEMASKIPROC __glewSampleMaski = NULL;
+PFNGLTEXIMAGE2DMULTISAMPLEPROC __glewTexImage2DMultisample = NULL;
+PFNGLTEXIMAGE3DMULTISAMPLEPROC __glewTexImage3DMultisample = NULL;
+
 PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB = NULL;
 PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB = NULL;
 PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB = NULL;
 PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB = NULL;
 
+PFNGLBINDBUFFERBASEPROC __glewBindBufferBase = NULL;
+PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange = NULL;
+PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC __glewGetActiveUniformBlockName = NULL;
+PFNGLGETACTIVEUNIFORMBLOCKIVPROC __glewGetActiveUniformBlockiv = NULL;
+PFNGLGETACTIVEUNIFORMNAMEPROC __glewGetActiveUniformName = NULL;
+PFNGLGETACTIVEUNIFORMSIVPROC __glewGetActiveUniformsiv = NULL;
+PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v = NULL;
+PFNGLGETUNIFORMBLOCKINDEXPROC __glewGetUniformBlockIndex = NULL;
+PFNGLGETUNIFORMINDICESPROC __glewGetUniformIndices = NULL;
+PFNGLUNIFORMBLOCKBINDINGPROC __glewUniformBlockBinding = NULL;
+
 PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray = NULL;
 PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays = NULL;
 PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays = NULL;
@@ -988,7 +1084,14 @@
 PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT = NULL;
 PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT = NULL;
 PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT = NULL;
+PFNGLDISABLECLIENTSTATEIEXTPROC __glewDisableClientStateiEXT = NULL;
+PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC __glewDisableVertexArrayAttribEXT = NULL;
+PFNGLDISABLEVERTEXARRAYEXTPROC __glewDisableVertexArrayEXT = NULL;
 PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT = NULL;
+PFNGLENABLECLIENTSTATEIEXTPROC __glewEnableClientStateiEXT = NULL;
+PFNGLENABLEVERTEXARRAYATTRIBEXTPROC __glewEnableVertexArrayAttribEXT = NULL;
+PFNGLENABLEVERTEXARRAYEXTPROC __glewEnableVertexArrayEXT = NULL;
+PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC __glewFlushMappedNamedBufferRangeEXT = NULL;
 PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT = NULL;
 PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT = NULL;
 PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT = NULL;
@@ -997,7 +1100,9 @@
 PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT = NULL;
 PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT = NULL;
 PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT = NULL;
+PFNGLGETDOUBLEI_VEXTPROC __glewGetDoublei_vEXT = NULL;
 PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT = NULL;
+PFNGLGETFLOATI_VEXTPROC __glewGetFloati_vEXT = NULL;
 PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT = NULL;
 PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT = NULL;
 PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT = NULL;
@@ -1023,6 +1128,7 @@
 PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT = NULL;
 PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT = NULL;
 PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT = NULL;
+PFNGLGETPOINTERI_VEXTPROC __glewGetPointeri_vEXT = NULL;
 PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT = NULL;
 PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT = NULL;
 PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT = NULL;
@@ -1030,7 +1136,12 @@
 PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT = NULL;
 PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT = NULL;
 PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT = NULL;
+PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC __glewGetVertexArrayIntegeri_vEXT = NULL;
+PFNGLGETVERTEXARRAYINTEGERVEXTPROC __glewGetVertexArrayIntegervEXT = NULL;
+PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC __glewGetVertexArrayPointeri_vEXT = NULL;
+PFNGLGETVERTEXARRAYPOINTERVEXTPROC __glewGetVertexArrayPointervEXT = NULL;
 PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT = NULL;
+PFNGLMAPNAMEDBUFFERRANGEEXTPROC __glewMapNamedBufferRangeEXT = NULL;
 PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT = NULL;
 PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT = NULL;
 PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT = NULL;
@@ -1077,6 +1188,7 @@
 PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT = NULL;
 PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT = NULL;
 PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT = NULL;
+PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC __glewNamedCopyBufferSubDataEXT = NULL;
 PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT = NULL;
 PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT = NULL;
 PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT = NULL;
@@ -1148,6 +1260,17 @@
 PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT = NULL;
 PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT = NULL;
 PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT = NULL;
+PFNGLVERTEXARRAYCOLOROFFSETEXTPROC __glewVertexArrayColorOffsetEXT = NULL;
+PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC __glewVertexArrayEdgeFlagOffsetEXT = NULL;
+PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC __glewVertexArrayFogCoordOffsetEXT = NULL;
+PFNGLVERTEXARRAYINDEXOFFSETEXTPROC __glewVertexArrayIndexOffsetEXT = NULL;
+PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC __glewVertexArrayMultiTexCoordOffsetEXT = NULL;
+PFNGLVERTEXARRAYNORMALOFFSETEXTPROC __glewVertexArrayNormalOffsetEXT = NULL;
+PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC __glewVertexArraySecondaryColorOffsetEXT = NULL;
+PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC __glewVertexArrayTexCoordOffsetEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC __glewVertexArrayVertexAttribIOffsetEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC __glewVertexArrayVertexAttribOffsetEXT = NULL;
+PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC __glewVertexArrayVertexOffsetEXT = NULL;
 
 PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT = NULL;
 PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT = NULL;
@@ -1293,6 +1416,8 @@
 
 PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT = NULL;
 
+PFNGLPROVOKINGVERTEXEXTPROC __glewProvokingVertexEXT = NULL;
+
 PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT = NULL;
 PFNGLENDSCENEEXTPROC __glewEndSceneEXT = NULL;
 
@@ -1314,6 +1439,10 @@
 PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT = NULL;
 PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT = NULL;
 
+PFNGLACTIVEPROGRAMEXTPROC __glewActiveProgramEXT = NULL;
+PFNGLCREATESHADERPROGRAMEXTPROC __glewCreateShaderProgramEXT = NULL;
+PFNGLUSESHADERPROGRAMEXTPROC __glewUseShaderProgramEXT = NULL;
+
 PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT = NULL;
 
 PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT = NULL;
@@ -1475,6 +1604,8 @@
 PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV = NULL;
 PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV = NULL;
 
+PFNGLCOPYIMAGESUBDATANVPROC __glewCopyImageSubDataNV = NULL;
+
 PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV = NULL;
 PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV = NULL;
 PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV = NULL;
@@ -1596,7 +1727,6 @@
 PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV = NULL;
 PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV = NULL;
 PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV = NULL;
-PFNGLVIDEOPARAMETERIVNVPROC __glewVideoParameterivNV = NULL;
 
 PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV = NULL;
 PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV = NULL;
@@ -1618,6 +1748,23 @@
 PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV = NULL;
 PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV = NULL;
 
+PFNGLGETBUFFERPARAMETERUI64VNVPROC __glewGetBufferParameterui64vNV = NULL;
+PFNGLGETINTEGERUI64VNVPROC __glewGetIntegerui64vNV = NULL;
+PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC __glewGetNamedBufferParameterui64vNV = NULL;
+PFNGLGETUNIFORMUI64VNVPROC __glewGetUniformui64vNV = NULL;
+PFNGLISBUFFERRESIDENTNVPROC __glewIsBufferResidentNV = NULL;
+PFNGLISNAMEDBUFFERRESIDENTNVPROC __glewIsNamedBufferResidentNV = NULL;
+PFNGLMAKEBUFFERNONRESIDENTNVPROC __glewMakeBufferNonResidentNV = NULL;
+PFNGLMAKEBUFFERRESIDENTNVPROC __glewMakeBufferResidentNV = NULL;
+PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC __glewMakeNamedBufferNonResidentNV = NULL;
+PFNGLMAKENAMEDBUFFERRESIDENTNVPROC __glewMakeNamedBufferResidentNV = NULL;
+PFNGLPROGRAMUNIFORMUI64NVPROC __glewProgramUniformui64NV = NULL;
+PFNGLPROGRAMUNIFORMUI64VNVPROC __glewProgramUniformui64vNV = NULL;
+PFNGLUNIFORMUI64NVPROC __glewUniformui64NV = NULL;
+PFNGLUNIFORMUI64VNVPROC __glewUniformui64vNV = NULL;
+
+PFNGLTEXTUREBARRIERNVPROC __glewTextureBarrierNV = NULL;
+
 PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV = NULL;
 PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV = NULL;
 PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV = NULL;
@@ -1630,9 +1777,30 @@
 PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV = NULL;
 PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV = NULL;
 
+PFNGLBINDTRANSFORMFEEDBACKNVPROC __glewBindTransformFeedbackNV = NULL;
+PFNGLDELETETRANSFORMFEEDBACKSNVPROC __glewDeleteTransformFeedbacksNV = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKNVPROC __glewDrawTransformFeedbackNV = NULL;
+PFNGLGENTRANSFORMFEEDBACKSNVPROC __glewGenTransformFeedbacksNV = NULL;
+PFNGLISTRANSFORMFEEDBACKNVPROC __glewIsTransformFeedbackNV = NULL;
+PFNGLPAUSETRANSFORMFEEDBACKNVPROC __glewPauseTransformFeedbackNV = NULL;
+PFNGLRESUMETRANSFORMFEEDBACKNVPROC __glewResumeTransformFeedbackNV = NULL;
+
 PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV = NULL;
 PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV = NULL;
 
+PFNGLBUFFERADDRESSRANGENVPROC __glewBufferAddressRangeNV = NULL;
+PFNGLCOLORFORMATNVPROC __glewColorFormatNV = NULL;
+PFNGLEDGEFLAGFORMATNVPROC __glewEdgeFlagFormatNV = NULL;
+PFNGLFOGCOORDFORMATNVPROC __glewFogCoordFormatNV = NULL;
+PFNGLGETINTEGERUI64I_VNVPROC __glewGetIntegerui64i_vNV = NULL;
+PFNGLINDEXFORMATNVPROC __glewIndexFormatNV = NULL;
+PFNGLNORMALFORMATNVPROC __glewNormalFormatNV = NULL;
+PFNGLSECONDARYCOLORFORMATNVPROC __glewSecondaryColorFormatNV = NULL;
+PFNGLTEXCOORDFORMATNVPROC __glewTexCoordFormatNV = NULL;
+PFNGLVERTEXATTRIBFORMATNVPROC __glewVertexAttribFormatNV = NULL;
+PFNGLVERTEXATTRIBIFORMATNVPROC __glewVertexAttribIFormatNV = NULL;
+PFNGLVERTEXFORMATNVPROC __glewVertexFormatNV = NULL;
+
 PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV = NULL;
 PFNGLBINDPROGRAMNVPROC __glewBindProgramNV = NULL;
 PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV = NULL;
@@ -1849,26 +2017,43 @@
 GLboolean __GLEW_VERSION_2_0 = GL_FALSE;
 GLboolean __GLEW_VERSION_2_1 = GL_FALSE;
 GLboolean __GLEW_VERSION_3_0 = GL_FALSE;
+GLboolean __GLEW_VERSION_3_1 = GL_FALSE;
+GLboolean __GLEW_VERSION_3_2 = GL_FALSE;
 GLboolean __GLEW_3DFX_multisample = GL_FALSE;
 GLboolean __GLEW_3DFX_tbuffer = GL_FALSE;
 GLboolean __GLEW_3DFX_texture_compression_FXT1 = GL_FALSE;
+GLboolean __GLEW_AMD_draw_buffers_blend = GL_FALSE;
+GLboolean __GLEW_AMD_performance_monitor = GL_FALSE;
+GLboolean __GLEW_AMD_texture_texture4 = GL_FALSE;
+GLboolean __GLEW_AMD_vertex_shader_tessellator = GL_FALSE;
+GLboolean __GLEW_APPLE_aux_depth_stencil = GL_FALSE;
 GLboolean __GLEW_APPLE_client_storage = GL_FALSE;
 GLboolean __GLEW_APPLE_element_array = GL_FALSE;
 GLboolean __GLEW_APPLE_fence = GL_FALSE;
 GLboolean __GLEW_APPLE_float_pixels = GL_FALSE;
 GLboolean __GLEW_APPLE_flush_buffer_range = GL_FALSE;
+GLboolean __GLEW_APPLE_object_purgeable = GL_FALSE;
 GLboolean __GLEW_APPLE_pixel_buffer = GL_FALSE;
+GLboolean __GLEW_APPLE_rgb_422 = GL_FALSE;
+GLboolean __GLEW_APPLE_row_bytes = GL_FALSE;
 GLboolean __GLEW_APPLE_specular_vector = GL_FALSE;
 GLboolean __GLEW_APPLE_texture_range = GL_FALSE;
 GLboolean __GLEW_APPLE_transform_hint = GL_FALSE;
 GLboolean __GLEW_APPLE_vertex_array_object = GL_FALSE;
 GLboolean __GLEW_APPLE_vertex_array_range = GL_FALSE;
+GLboolean __GLEW_APPLE_vertex_program_evaluators = GL_FALSE;
 GLboolean __GLEW_APPLE_ycbcr_422 = GL_FALSE;
 GLboolean __GLEW_ARB_color_buffer_float = GL_FALSE;
+GLboolean __GLEW_ARB_compatibility = GL_FALSE;
+GLboolean __GLEW_ARB_copy_buffer = GL_FALSE;
 GLboolean __GLEW_ARB_depth_buffer_float = GL_FALSE;
+GLboolean __GLEW_ARB_depth_clamp = GL_FALSE;
 GLboolean __GLEW_ARB_depth_texture = GL_FALSE;
 GLboolean __GLEW_ARB_draw_buffers = GL_FALSE;
+GLboolean __GLEW_ARB_draw_buffers_blend = GL_FALSE;
+GLboolean __GLEW_ARB_draw_elements_base_vertex = GL_FALSE;
 GLboolean __GLEW_ARB_draw_instanced = GL_FALSE;
+GLboolean __GLEW_ARB_fragment_coord_conventions = GL_FALSE;
 GLboolean __GLEW_ARB_fragment_program = GL_FALSE;
 GLboolean __GLEW_ARB_fragment_program_shadow = GL_FALSE;
 GLboolean __GLEW_ARB_fragment_shader = GL_FALSE;
@@ -1887,25 +2072,36 @@
 GLboolean __GLEW_ARB_pixel_buffer_object = GL_FALSE;
 GLboolean __GLEW_ARB_point_parameters = GL_FALSE;
 GLboolean __GLEW_ARB_point_sprite = GL_FALSE;
+GLboolean __GLEW_ARB_provoking_vertex = GL_FALSE;
+GLboolean __GLEW_ARB_sample_shading = GL_FALSE;
+GLboolean __GLEW_ARB_seamless_cube_map = GL_FALSE;
 GLboolean __GLEW_ARB_shader_objects = GL_FALSE;
+GLboolean __GLEW_ARB_shader_texture_lod = GL_FALSE;
 GLboolean __GLEW_ARB_shading_language_100 = GL_FALSE;
 GLboolean __GLEW_ARB_shadow = GL_FALSE;
 GLboolean __GLEW_ARB_shadow_ambient = GL_FALSE;
+GLboolean __GLEW_ARB_sync = GL_FALSE;
 GLboolean __GLEW_ARB_texture_border_clamp = GL_FALSE;
 GLboolean __GLEW_ARB_texture_buffer_object = GL_FALSE;
 GLboolean __GLEW_ARB_texture_compression = GL_FALSE;
 GLboolean __GLEW_ARB_texture_compression_rgtc = GL_FALSE;
 GLboolean __GLEW_ARB_texture_cube_map = GL_FALSE;
+GLboolean __GLEW_ARB_texture_cube_map_array = GL_FALSE;
 GLboolean __GLEW_ARB_texture_env_add = GL_FALSE;
 GLboolean __GLEW_ARB_texture_env_combine = GL_FALSE;
 GLboolean __GLEW_ARB_texture_env_crossbar = GL_FALSE;
 GLboolean __GLEW_ARB_texture_env_dot3 = GL_FALSE;
 GLboolean __GLEW_ARB_texture_float = GL_FALSE;
+GLboolean __GLEW_ARB_texture_gather = GL_FALSE;
 GLboolean __GLEW_ARB_texture_mirrored_repeat = GL_FALSE;
+GLboolean __GLEW_ARB_texture_multisample = GL_FALSE;
 GLboolean __GLEW_ARB_texture_non_power_of_two = GL_FALSE;
+GLboolean __GLEW_ARB_texture_query_lod = GL_FALSE;
 GLboolean __GLEW_ARB_texture_rectangle = GL_FALSE;
 GLboolean __GLEW_ARB_texture_rg = GL_FALSE;
 GLboolean __GLEW_ARB_transpose_matrix = GL_FALSE;
+GLboolean __GLEW_ARB_uniform_buffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_array_bgra = GL_FALSE;
 GLboolean __GLEW_ARB_vertex_array_object = GL_FALSE;
 GLboolean __GLEW_ARB_vertex_blend = GL_FALSE;
 GLboolean __GLEW_ARB_vertex_buffer_object = GL_FALSE;
@@ -1921,6 +2117,7 @@
 GLboolean __GLEW_ATI_envmap_bumpmap = GL_FALSE;
 GLboolean __GLEW_ATI_fragment_shader = GL_FALSE;
 GLboolean __GLEW_ATI_map_object_buffer = GL_FALSE;
+GLboolean __GLEW_ATI_meminfo = GL_FALSE;
 GLboolean __GLEW_ATI_pn_triangles = GL_FALSE;
 GLboolean __GLEW_ATI_separate_stencil = GL_FALSE;
 GLboolean __GLEW_ATI_shader_texture_lod = GL_FALSE;
@@ -1983,9 +2180,11 @@
 GLboolean __GLEW_EXT_pixel_transform_color_table = GL_FALSE;
 GLboolean __GLEW_EXT_point_parameters = GL_FALSE;
 GLboolean __GLEW_EXT_polygon_offset = GL_FALSE;
+GLboolean __GLEW_EXT_provoking_vertex = GL_FALSE;
 GLboolean __GLEW_EXT_rescale_normal = GL_FALSE;
 GLboolean __GLEW_EXT_scene_marker = GL_FALSE;
 GLboolean __GLEW_EXT_secondary_color = GL_FALSE;
+GLboolean __GLEW_EXT_separate_shader_objects = GL_FALSE;
 GLboolean __GLEW_EXT_separate_specular_color = GL_FALSE;
 GLboolean __GLEW_EXT_shadow_funcs = GL_FALSE;
 GLboolean __GLEW_EXT_shared_texture_palette = GL_FALSE;
@@ -2016,6 +2215,7 @@
 GLboolean __GLEW_EXT_texture_rectangle = GL_FALSE;
 GLboolean __GLEW_EXT_texture_sRGB = GL_FALSE;
 GLboolean __GLEW_EXT_texture_shared_exponent = GL_FALSE;
+GLboolean __GLEW_EXT_texture_snorm = GL_FALSE;
 GLboolean __GLEW_EXT_texture_swizzle = GL_FALSE;
 GLboolean __GLEW_EXT_timer_query = GL_FALSE;
 GLboolean __GLEW_EXT_transform_feedback = GL_FALSE;
@@ -2048,6 +2248,7 @@
 GLboolean __GLEW_NV_blend_square = GL_FALSE;
 GLboolean __GLEW_NV_conditional_render = GL_FALSE;
 GLboolean __GLEW_NV_copy_depth_to_color = GL_FALSE;
+GLboolean __GLEW_NV_copy_image = GL_FALSE;
 GLboolean __GLEW_NV_depth_buffer_float = GL_FALSE;
 GLboolean __GLEW_NV_depth_clamp = GL_FALSE;
 GLboolean __GLEW_NV_depth_range_unclamped = GL_FALSE;
@@ -2070,14 +2271,17 @@
 GLboolean __GLEW_NV_occlusion_query = GL_FALSE;
 GLboolean __GLEW_NV_packed_depth_stencil = GL_FALSE;
 GLboolean __GLEW_NV_parameter_buffer_object = GL_FALSE;
+GLboolean __GLEW_NV_parameter_buffer_object2 = GL_FALSE;
 GLboolean __GLEW_NV_pixel_data_range = GL_FALSE;
 GLboolean __GLEW_NV_point_sprite = GL_FALSE;
 GLboolean __GLEW_NV_present_video = GL_FALSE;
 GLboolean __GLEW_NV_primitive_restart = GL_FALSE;
 GLboolean __GLEW_NV_register_combiners = GL_FALSE;
 GLboolean __GLEW_NV_register_combiners2 = GL_FALSE;
+GLboolean __GLEW_NV_shader_buffer_load = GL_FALSE;
 GLboolean __GLEW_NV_texgen_emboss = GL_FALSE;
 GLboolean __GLEW_NV_texgen_reflection = GL_FALSE;
+GLboolean __GLEW_NV_texture_barrier = GL_FALSE;
 GLboolean __GLEW_NV_texture_compression_vtc = GL_FALSE;
 GLboolean __GLEW_NV_texture_env_combine4 = GL_FALSE;
 GLboolean __GLEW_NV_texture_expand_normal = GL_FALSE;
@@ -2086,8 +2290,10 @@
 GLboolean __GLEW_NV_texture_shader2 = GL_FALSE;
 GLboolean __GLEW_NV_texture_shader3 = GL_FALSE;
 GLboolean __GLEW_NV_transform_feedback = GL_FALSE;
+GLboolean __GLEW_NV_transform_feedback2 = GL_FALSE;
 GLboolean __GLEW_NV_vertex_array_range = GL_FALSE;
 GLboolean __GLEW_NV_vertex_array_range2 = GL_FALSE;
+GLboolean __GLEW_NV_vertex_buffer_unified_memory = GL_FALSE;
 GLboolean __GLEW_NV_vertex_program = GL_FALSE;
 GLboolean __GLEW_NV_vertex_program1_1 = GL_FALSE;
 GLboolean __GLEW_NV_vertex_program2 = GL_FALSE;
@@ -2463,8 +2669,6 @@
 
   r = ((glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRender")) == NULL) || r;
   r = ((glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedback")) == NULL) || r;
-  r = ((glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBase")) == NULL) || r;
-  r = ((glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRange")) == NULL) || r;
   r = ((glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocation")) == NULL) || r;
   r = ((glClampColor = (PFNGLCLAMPCOLORPROC)glewGetProcAddress((const GLubyte*)"glClampColor")) == NULL) || r;
   r = ((glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)glewGetProcAddress((const GLubyte*)"glClearBufferfi")) == NULL) || r;
@@ -2478,7 +2682,6 @@
   r = ((glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedback")) == NULL) || r;
   r = ((glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)glewGetProcAddress((const GLubyte*)"glGetBooleani_v")) == NULL) || r;
   r = ((glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataLocation")) == NULL) || r;
-  r = ((glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)glewGetProcAddress((const GLubyte*)"glGetIntegeri_v")) == NULL) || r;
   r = ((glGetStringi = (PFNGLGETSTRINGIPROC)glewGetProcAddress((const GLubyte*)"glGetStringi")) == NULL) || r;
   r = ((glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIiv")) == NULL) || r;
   r = ((glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIuiv")) == NULL) || r;
@@ -2525,6 +2728,37 @@
 
 #endif /* GL_VERSION_3_0 */
 
+#ifdef GL_VERSION_3_1
+
+static GLboolean _glewInit_GL_VERSION_3_1 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstanced")) == NULL) || r;
+  r = ((glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstanced")) == NULL) || r;
+  r = ((glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartIndex")) == NULL) || r;
+  r = ((glTexBuffer = (PFNGLTEXBUFFERPROC)glewGetProcAddress((const GLubyte*)"glTexBuffer")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_VERSION_3_1 */
+
+#ifdef GL_VERSION_3_2
+
+static GLboolean _glewInit_GL_VERSION_3_2 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture")) == NULL) || r;
+  r = ((glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameteri64v")) == NULL) || r;
+  r = ((glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)glewGetProcAddress((const GLubyte*)"glGetInteger64i_v")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_VERSION_3_2 */
+
 #ifdef GL_3DFX_multisample
 
 #endif /* GL_3DFX_multisample */
@@ -2546,6 +2780,67 @@
 
 #endif /* GL_3DFX_texture_compression_FXT1 */
 
+#ifdef GL_AMD_draw_buffers_blend
+
+static GLboolean _glewInit_GL_AMD_draw_buffers_blend (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationIndexedAMD")) == NULL) || r;
+  r = ((glBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateIndexedAMD")) == NULL) || r;
+  r = ((glBlendFuncIndexedAMD = (PFNGLBLENDFUNCINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncIndexedAMD")) == NULL) || r;
+  r = ((glBlendFuncSeparateIndexedAMD = (PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateIndexedAMD")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_AMD_draw_buffers_blend */
+
+#ifdef GL_AMD_performance_monitor
+
+static GLboolean _glewInit_GL_AMD_performance_monitor (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glBeginPerfMonitorAMD = (PFNGLBEGINPERFMONITORAMDPROC)glewGetProcAddress((const GLubyte*)"glBeginPerfMonitorAMD")) == NULL) || r;
+  r = ((glDeletePerfMonitorsAMD = (PFNGLDELETEPERFMONITORSAMDPROC)glewGetProcAddress((const GLubyte*)"glDeletePerfMonitorsAMD")) == NULL) || r;
+  r = ((glEndPerfMonitorAMD = (PFNGLENDPERFMONITORAMDPROC)glewGetProcAddress((const GLubyte*)"glEndPerfMonitorAMD")) == NULL) || r;
+  r = ((glGenPerfMonitorsAMD = (PFNGLGENPERFMONITORSAMDPROC)glewGetProcAddress((const GLubyte*)"glGenPerfMonitorsAMD")) == NULL) || r;
+  r = ((glGetPerfMonitorCounterDataAMD = (PFNGLGETPERFMONITORCOUNTERDATAAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCounterDataAMD")) == NULL) || r;
+  r = ((glGetPerfMonitorCounterInfoAMD = (PFNGLGETPERFMONITORCOUNTERINFOAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCounterInfoAMD")) == NULL) || r;
+  r = ((glGetPerfMonitorCounterStringAMD = (PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCounterStringAMD")) == NULL) || r;
+  r = ((glGetPerfMonitorCountersAMD = (PFNGLGETPERFMONITORCOUNTERSAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCountersAMD")) == NULL) || r;
+  r = ((glGetPerfMonitorGroupStringAMD = (PFNGLGETPERFMONITORGROUPSTRINGAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorGroupStringAMD")) == NULL) || r;
+  r = ((glGetPerfMonitorGroupsAMD = (PFNGLGETPERFMONITORGROUPSAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorGroupsAMD")) == NULL) || r;
+  r = ((glSelectPerfMonitorCountersAMD = (PFNGLSELECTPERFMONITORCOUNTERSAMDPROC)glewGetProcAddress((const GLubyte*)"glSelectPerfMonitorCountersAMD")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_AMD_performance_monitor */
+
+#ifdef GL_AMD_texture_texture4
+
+#endif /* GL_AMD_texture_texture4 */
+
+#ifdef GL_AMD_vertex_shader_tessellator
+
+static GLboolean _glewInit_GL_AMD_vertex_shader_tessellator (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glTessellationFactorAMD = (PFNGLTESSELLATIONFACTORAMDPROC)glewGetProcAddress((const GLubyte*)"glTessellationFactorAMD")) == NULL) || r;
+  r = ((glTessellationModeAMD = (PFNGLTESSELLATIONMODEAMDPROC)glewGetProcAddress((const GLubyte*)"glTessellationModeAMD")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_AMD_vertex_shader_tessellator */
+
+#ifdef GL_APPLE_aux_depth_stencil
+
+#endif /* GL_APPLE_aux_depth_stencil */
+
 #ifdef GL_APPLE_client_storage
 
 #endif /* GL_APPLE_client_storage */
@@ -2605,10 +2900,33 @@
 
 #endif /* GL_APPLE_flush_buffer_range */
 
+#ifdef GL_APPLE_object_purgeable
+
+static GLboolean _glewInit_GL_APPLE_object_purgeable (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glGetObjectParameterivAPPLE = (PFNGLGETOBJECTPARAMETERIVAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterivAPPLE")) == NULL) || r;
+  r = ((glObjectPurgeableAPPLE = (PFNGLOBJECTPURGEABLEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glObjectPurgeableAPPLE")) == NULL) || r;
+  r = ((glObjectUnpurgeableAPPLE = (PFNGLOBJECTUNPURGEABLEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glObjectUnpurgeableAPPLE")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_APPLE_object_purgeable */
+
 #ifdef GL_APPLE_pixel_buffer
 
 #endif /* GL_APPLE_pixel_buffer */
 
+#ifdef GL_APPLE_rgb_422
+
+#endif /* GL_APPLE_rgb_422 */
+
+#ifdef GL_APPLE_row_bytes
+
+#endif /* GL_APPLE_row_bytes */
+
 #ifdef GL_APPLE_specular_vector
 
 #endif /* GL_APPLE_specular_vector */
@@ -2662,6 +2980,25 @@
 
 #endif /* GL_APPLE_vertex_array_range */
 
+#ifdef GL_APPLE_vertex_program_evaluators
+
+static GLboolean _glewInit_GL_APPLE_vertex_program_evaluators (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glDisableVertexAttribAPPLE = (PFNGLDISABLEVERTEXATTRIBAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribAPPLE")) == NULL) || r;
+  r = ((glEnableVertexAttribAPPLE = (PFNGLENABLEVERTEXATTRIBAPPLEPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribAPPLE")) == NULL) || r;
+  r = ((glIsVertexAttribEnabledAPPLE = (PFNGLISVERTEXATTRIBENABLEDAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsVertexAttribEnabledAPPLE")) == NULL) || r;
+  r = ((glMapVertexAttrib1dAPPLE = (PFNGLMAPVERTEXATTRIB1DAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib1dAPPLE")) == NULL) || r;
+  r = ((glMapVertexAttrib1fAPPLE = (PFNGLMAPVERTEXATTRIB1FAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib1fAPPLE")) == NULL) || r;
+  r = ((glMapVertexAttrib2dAPPLE = (PFNGLMAPVERTEXATTRIB2DAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib2dAPPLE")) == NULL) || r;
+  r = ((glMapVertexAttrib2fAPPLE = (PFNGLMAPVERTEXATTRIB2FAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib2fAPPLE")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_APPLE_vertex_program_evaluators */
+
 #ifdef GL_APPLE_ycbcr_422
 
 #endif /* GL_APPLE_ycbcr_422 */
@@ -2679,10 +3016,31 @@
 
 #endif /* GL_ARB_color_buffer_float */
 
+#ifdef GL_ARB_compatibility
+
+#endif /* GL_ARB_compatibility */
+
+#ifdef GL_ARB_copy_buffer
+
+static GLboolean _glewInit_GL_ARB_copy_buffer (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glCopyBufferSubData")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_ARB_copy_buffer */
+
 #ifdef GL_ARB_depth_buffer_float
 
 #endif /* GL_ARB_depth_buffer_float */
 
+#ifdef GL_ARB_depth_clamp
+
+#endif /* GL_ARB_depth_clamp */
+
 #ifdef GL_ARB_depth_texture
 
 #endif /* GL_ARB_depth_texture */
@@ -2700,6 +3058,38 @@
 
 #endif /* GL_ARB_draw_buffers */
 
+#ifdef GL_ARB_draw_buffers_blend
+
+static GLboolean _glewInit_GL_ARB_draw_buffers_blend (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glBlendEquationSeparateiARB = (PFNGLBLENDEQUATIONSEPARATEIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateiARB")) == NULL) || r;
+  r = ((glBlendEquationiARB = (PFNGLBLENDEQUATIONIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationiARB")) == NULL) || r;
+  r = ((glBlendFuncSeparateiARB = (PFNGLBLENDFUNCSEPARATEIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateiARB")) == NULL) || r;
+  r = ((glBlendFunciARB = (PFNGLBLENDFUNCIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendFunciARB")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_ARB_draw_buffers_blend */
+
+#ifdef GL_ARB_draw_elements_base_vertex
+
+static GLboolean _glewInit_GL_ARB_draw_elements_base_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsBaseVertex")) == NULL) || r;
+  r = ((glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseVertex")) == NULL) || r;
+  r = ((glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementsBaseVertex")) == NULL) || r;
+  r = ((glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsBaseVertex")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_ARB_draw_elements_base_vertex */
+
 #ifdef GL_ARB_draw_instanced
 
 static GLboolean _glewInit_GL_ARB_draw_instanced (GLEW_CONTEXT_ARG_DEF_INIT)
@@ -2714,6 +3104,10 @@
 
 #endif /* GL_ARB_draw_instanced */
 
+#ifdef GL_ARB_fragment_coord_conventions
+
+#endif /* GL_ARB_fragment_coord_conventions */
+
 #ifdef GL_ARB_fragment_program
 
 #endif /* GL_ARB_fragment_program */
@@ -2739,10 +3133,10 @@
   r = ((glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteFramebuffers")) == NULL) || r;
   r = ((glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteRenderbuffers")) == NULL) || r;
   r = ((glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferRenderbuffer")) == NULL) || r;
-  r = ((glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayer")) == NULL) || r;
   r = ((glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture1D")) == NULL) || r;
   r = ((glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2D")) == NULL) || r;
   r = ((glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture3D")) == NULL) || r;
+  r = ((glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayer")) == NULL) || r;
   r = ((glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenFramebuffers")) == NULL) || r;
   r = ((glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenRenderbuffers")) == NULL) || r;
   r = ((glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)glewGetProcAddress((const GLubyte*)"glGenerateMipmap")) == NULL) || r;
@@ -2976,6 +3370,36 @@
 
 #endif /* GL_ARB_point_sprite */
 
+#ifdef GL_ARB_provoking_vertex
+
+static GLboolean _glewInit_GL_ARB_provoking_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)glewGetProcAddress((const GLubyte*)"glProvokingVertex")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_ARB_provoking_vertex */
+
+#ifdef GL_ARB_sample_shading
+
+static GLboolean _glewInit_GL_ARB_sample_shading (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glMinSampleShadingARB = (PFNGLMINSAMPLESHADINGARBPROC)glewGetProcAddress((const GLubyte*)"glMinSampleShadingARB")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_ARB_sample_shading */
+
+#ifdef GL_ARB_seamless_cube_map
+
+#endif /* GL_ARB_seamless_cube_map */
+
 #ifdef GL_ARB_shader_objects
 
 static GLboolean _glewInit_GL_ARB_shader_objects (GLEW_CONTEXT_ARG_DEF_INIT)
@@ -3027,6 +3451,10 @@
 
 #endif /* GL_ARB_shader_objects */
 
+#ifdef GL_ARB_shader_texture_lod
+
+#endif /* GL_ARB_shader_texture_lod */
+
 #ifdef GL_ARB_shading_language_100
 
 #endif /* GL_ARB_shading_language_100 */
@@ -3039,6 +3467,25 @@
 
 #endif /* GL_ARB_shadow_ambient */
 
+#ifdef GL_ARB_sync
+
+static GLboolean _glewInit_GL_ARB_sync (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)glewGetProcAddress((const GLubyte*)"glClientWaitSync")) == NULL) || r;
+  r = ((glDeleteSync = (PFNGLDELETESYNCPROC)glewGetProcAddress((const GLubyte*)"glDeleteSync")) == NULL) || r;
+  r = ((glFenceSync = (PFNGLFENCESYNCPROC)glewGetProcAddress((const GLubyte*)"glFenceSync")) == NULL) || r;
+  r = ((glGetInteger64v = (PFNGLGETINTEGER64VPROC)glewGetProcAddress((const GLubyte*)"glGetInteger64v")) == NULL) || r;
+  r = ((glGetSynciv = (PFNGLGETSYNCIVPROC)glewGetProcAddress((const GLubyte*)"glGetSynciv")) == NULL) || r;
+  r = ((glIsSync = (PFNGLISSYNCPROC)glewGetProcAddress((const GLubyte*)"glIsSync")) == NULL) || r;
+  r = ((glWaitSync = (PFNGLWAITSYNCPROC)glewGetProcAddress((const GLubyte*)"glWaitSync")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_ARB_sync */
+
 #ifdef GL_ARB_texture_border_clamp
 
 #endif /* GL_ARB_texture_border_clamp */
@@ -3083,6 +3530,10 @@
 
 #endif /* GL_ARB_texture_cube_map */
 
+#ifdef GL_ARB_texture_cube_map_array
+
+#endif /* GL_ARB_texture_cube_map_array */
+
 #ifdef GL_ARB_texture_env_add
 
 #endif /* GL_ARB_texture_env_add */
@@ -3103,14 +3554,38 @@
 
 #endif /* GL_ARB_texture_float */
 
+#ifdef GL_ARB_texture_gather
+
+#endif /* GL_ARB_texture_gather */
+
 #ifdef GL_ARB_texture_mirrored_repeat
 
 #endif /* GL_ARB_texture_mirrored_repeat */
 
+#ifdef GL_ARB_texture_multisample
+
+static GLboolean _glewInit_GL_ARB_texture_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)glewGetProcAddress((const GLubyte*)"glGetMultisamplefv")) == NULL) || r;
+  r = ((glSampleMaski = (PFNGLSAMPLEMASKIPROC)glewGetProcAddress((const GLubyte*)"glSampleMaski")) == NULL) || r;
+  r = ((glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexImage2DMultisample")) == NULL) || r;
+  r = ((glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DMultisample")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_ARB_texture_multisample */
+
 #ifdef GL_ARB_texture_non_power_of_two
 
 #endif /* GL_ARB_texture_non_power_of_two */
 
+#ifdef GL_ARB_texture_query_lod
+
+#endif /* GL_ARB_texture_query_lod */
+
 #ifdef GL_ARB_texture_rectangle
 
 #endif /* GL_ARB_texture_rectangle */
@@ -3135,6 +3610,32 @@
 
 #endif /* GL_ARB_transpose_matrix */
 
+#ifdef GL_ARB_uniform_buffer_object
+
+static GLboolean _glewInit_GL_ARB_uniform_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBase")) == NULL) || r;
+  r = ((glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRange")) == NULL) || r;
+  r = ((glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformBlockName")) == NULL) || r;
+  r = ((glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformBlockiv")) == NULL) || r;
+  r = ((glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformName")) == NULL) || r;
+  r = ((glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformsiv")) == NULL) || r;
+  r = ((glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)glewGetProcAddress((const GLubyte*)"glGetIntegeri_v")) == NULL) || r;
+  r = ((glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetUniformBlockIndex")) == NULL) || r;
+  r = ((glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)glewGetProcAddress((const GLubyte*)"glGetUniformIndices")) == NULL) || r;
+  r = ((glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)glewGetProcAddress((const GLubyte*)"glUniformBlockBinding")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_ARB_uniform_buffer_object */
+
+#ifdef GL_ARB_vertex_array_bgra
+
+#endif /* GL_ARB_vertex_array_bgra */
+
 #ifdef GL_ARB_vertex_array_object
 
 static GLboolean _glewInit_GL_ARB_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT)
@@ -3413,6 +3914,10 @@
 
 #endif /* GL_ATI_map_object_buffer */
 
+#ifdef GL_ATI_meminfo
+
+#endif /* GL_ATI_meminfo */
+
 #ifdef GL_ATI_pn_triangles
 
 static GLboolean _glewInit_GL_ATI_pn_triangles (GLEW_CONTEXT_ARG_DEF_INIT)
@@ -3795,7 +4300,14 @@
   r = ((glCopyTextureSubImage2DEXT = (PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage2DEXT")) == NULL) || r;
   r = ((glCopyTextureSubImage3DEXT = (PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage3DEXT")) == NULL) || r;
   r = ((glDisableClientStateIndexedEXT = (PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableClientStateIndexedEXT")) == NULL) || r;
+  r = ((glDisableClientStateiEXT = (PFNGLDISABLECLIENTSTATEIEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableClientStateiEXT")) == NULL) || r;
+  r = ((glDisableVertexArrayAttribEXT = (PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexArrayAttribEXT")) == NULL) || r;
+  r = ((glDisableVertexArrayEXT = (PFNGLDISABLEVERTEXARRAYEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexArrayEXT")) == NULL) || r;
   r = ((glEnableClientStateIndexedEXT = (PFNGLENABLECLIENTSTATEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableClientStateIndexedEXT")) == NULL) || r;
+  r = ((glEnableClientStateiEXT = (PFNGLENABLECLIENTSTATEIEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableClientStateiEXT")) == NULL) || r;
+  r = ((glEnableVertexArrayAttribEXT = (PFNGLENABLEVERTEXARRAYATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexArrayAttribEXT")) == NULL) || r;
+  r = ((glEnableVertexArrayEXT = (PFNGLENABLEVERTEXARRAYEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexArrayEXT")) == NULL) || r;
+  r = ((glFlushMappedNamedBufferRangeEXT = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedNamedBufferRangeEXT")) == NULL) || r;
   r = ((glFramebufferDrawBufferEXT = (PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferDrawBufferEXT")) == NULL) || r;
   r = ((glFramebufferDrawBuffersEXT = (PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferDrawBuffersEXT")) == NULL) || r;
   r = ((glFramebufferReadBufferEXT = (PFNGLFRAMEBUFFERREADBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferReadBufferEXT")) == NULL) || r;
@@ -3804,7 +4316,9 @@
   r = ((glGetCompressedMultiTexImageEXT = (PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedMultiTexImageEXT")) == NULL) || r;
   r = ((glGetCompressedTextureImageEXT = (PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTextureImageEXT")) == NULL) || r;
   r = ((glGetDoubleIndexedvEXT = (PFNGLGETDOUBLEINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetDoubleIndexedvEXT")) == NULL) || r;
+  r = ((glGetDoublei_vEXT = (PFNGLGETDOUBLEI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetDoublei_vEXT")) == NULL) || r;
   r = ((glGetFloatIndexedvEXT = (PFNGLGETFLOATINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFloatIndexedvEXT")) == NULL) || r;
+  r = ((glGetFloati_vEXT = (PFNGLGETFLOATI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFloati_vEXT")) == NULL) || r;
   r = ((glGetFramebufferParameterivEXT = (PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferParameterivEXT")) == NULL) || r;
   r = ((glGetMultiTexEnvfvEXT = (PFNGLGETMULTITEXENVFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexEnvfvEXT")) == NULL) || r;
   r = ((glGetMultiTexEnvivEXT = (PFNGLGETMULTITEXENVIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexEnvivEXT")) == NULL) || r;
@@ -3830,6 +4344,7 @@
   r = ((glGetNamedProgramivEXT = (PFNGLGETNAMEDPROGRAMIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramivEXT")) == NULL) || r;
   r = ((glGetNamedRenderbufferParameterivEXT = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedRenderbufferParameterivEXT")) == NULL) || r;
   r = ((glGetPointerIndexedvEXT = (PFNGLGETPOINTERINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPointerIndexedvEXT")) == NULL) || r;
+  r = ((glGetPointeri_vEXT = (PFNGLGETPOINTERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPointeri_vEXT")) == NULL) || r;
   r = ((glGetTextureImageEXT = (PFNGLGETTEXTUREIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureImageEXT")) == NULL) || r;
   r = ((glGetTextureLevelParameterfvEXT = (PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameterfvEXT")) == NULL) || r;
   r = ((glGetTextureLevelParameterivEXT = (PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameterivEXT")) == NULL) || r;
@@ -3837,7 +4352,12 @@
   r = ((glGetTextureParameterIuivEXT = (PFNGLGETTEXTUREPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIuivEXT")) == NULL) || r;
   r = ((glGetTextureParameterfvEXT = (PFNGLGETTEXTUREPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterfvEXT")) == NULL) || r;
   r = ((glGetTextureParameterivEXT = (PFNGLGETTEXTUREPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterivEXT")) == NULL) || r;
+  r = ((glGetVertexArrayIntegeri_vEXT = (PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayIntegeri_vEXT")) == NULL) || r;
+  r = ((glGetVertexArrayIntegervEXT = (PFNGLGETVERTEXARRAYINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayIntegervEXT")) == NULL) || r;
+  r = ((glGetVertexArrayPointeri_vEXT = (PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayPointeri_vEXT")) == NULL) || r;
+  r = ((glGetVertexArrayPointervEXT = (PFNGLGETVERTEXARRAYPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayPointervEXT")) == NULL) || r;
   r = ((glMapNamedBufferEXT = (PFNGLMAPNAMEDBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBufferEXT")) == NULL) || r;
+  r = ((glMapNamedBufferRangeEXT = (PFNGLMAPNAMEDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBufferRangeEXT")) == NULL) || r;
   r = ((glMatrixFrustumEXT = (PFNGLMATRIXFRUSTUMEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixFrustumEXT")) == NULL) || r;
   r = ((glMatrixLoadIdentityEXT = (PFNGLMATRIXLOADIDENTITYEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadIdentityEXT")) == NULL) || r;
   r = ((glMatrixLoadTransposedEXT = (PFNGLMATRIXLOADTRANSPOSEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadTransposedEXT")) == NULL) || r;
@@ -3884,6 +4404,7 @@
   r = ((glMultiTexSubImage3DEXT = (PFNGLMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage3DEXT")) == NULL) || r;
   r = ((glNamedBufferDataEXT = (PFNGLNAMEDBUFFERDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferDataEXT")) == NULL) || r;
   r = ((glNamedBufferSubDataEXT = (PFNGLNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferSubDataEXT")) == NULL) || r;
+  r = ((glNamedCopyBufferSubDataEXT = (PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedCopyBufferSubDataEXT")) == NULL) || r;
   r = ((glNamedFramebufferRenderbufferEXT = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferRenderbufferEXT")) == NULL) || r;
   r = ((glNamedFramebufferTexture1DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture1DEXT")) == NULL) || r;
   r = ((glNamedFramebufferTexture2DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture2DEXT")) == NULL) || r;
@@ -3955,6 +4476,17 @@
   r = ((glTextureSubImage2DEXT = (PFNGLTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage2DEXT")) == NULL) || r;
   r = ((glTextureSubImage3DEXT = (PFNGLTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage3DEXT")) == NULL) || r;
   r = ((glUnmapNamedBufferEXT = (PFNGLUNMAPNAMEDBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glUnmapNamedBufferEXT")) == NULL) || r;
+  r = ((glVertexArrayColorOffsetEXT = (PFNGLVERTEXARRAYCOLOROFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayColorOffsetEXT")) == NULL) || r;
+  r = ((glVertexArrayEdgeFlagOffsetEXT = (PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayEdgeFlagOffsetEXT")) == NULL) || r;
+  r = ((glVertexArrayFogCoordOffsetEXT = (PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayFogCoordOffsetEXT")) == NULL) || r;
+  r = ((glVertexArrayIndexOffsetEXT = (PFNGLVERTEXARRAYINDEXOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayIndexOffsetEXT")) == NULL) || r;
+  r = ((glVertexArrayMultiTexCoordOffsetEXT = (PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayMultiTexCoordOffsetEXT")) == NULL) || r;
+  r = ((glVertexArrayNormalOffsetEXT = (PFNGLVERTEXARRAYNORMALOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayNormalOffsetEXT")) == NULL) || r;
+  r = ((glVertexArraySecondaryColorOffsetEXT = (PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArraySecondaryColorOffsetEXT")) == NULL) || r;
+  r = ((glVertexArrayTexCoordOffsetEXT = (PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayTexCoordOffsetEXT")) == NULL) || r;
+  r = ((glVertexArrayVertexAttribIOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribIOffsetEXT")) == NULL) || r;
+  r = ((glVertexArrayVertexAttribOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribOffsetEXT")) == NULL) || r;
+  r = ((glVertexArrayVertexOffsetEXT = (PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexOffsetEXT")) == NULL) || r;
 
   return r;
 }
@@ -4372,6 +4904,19 @@
 
 #endif /* GL_EXT_polygon_offset */
 
+#ifdef GL_EXT_provoking_vertex
+
+static GLboolean _glewInit_GL_EXT_provoking_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glProvokingVertexEXT = (PFNGLPROVOKINGVERTEXEXTPROC)glewGetProcAddress((const GLubyte*)"glProvokingVertexEXT")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_EXT_provoking_vertex */
+
 #ifdef GL_EXT_rescale_normal
 
 #endif /* GL_EXT_rescale_normal */
@@ -4419,6 +4964,21 @@
 
 #endif /* GL_EXT_secondary_color */
 
+#ifdef GL_EXT_separate_shader_objects
+
+static GLboolean _glewInit_GL_EXT_separate_shader_objects (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glActiveProgramEXT = (PFNGLACTIVEPROGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glActiveProgramEXT")) == NULL) || r;
+  r = ((glCreateShaderProgramEXT = (PFNGLCREATESHADERPROGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glCreateShaderProgramEXT")) == NULL) || r;
+  r = ((glUseShaderProgramEXT = (PFNGLUSESHADERPROGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glUseShaderProgramEXT")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_EXT_separate_shader_objects */
+
 #ifdef GL_EXT_separate_specular_color
 
 #endif /* GL_EXT_separate_specular_color */
@@ -4614,6 +5174,10 @@
 
 #endif /* GL_EXT_texture_shared_exponent */
 
+#ifdef GL_EXT_texture_snorm
+
+#endif /* GL_EXT_texture_snorm */
+
 #ifdef GL_EXT_texture_swizzle
 
 #endif /* GL_EXT_texture_swizzle */
@@ -4989,6 +5553,19 @@
 
 #endif /* GL_NV_copy_depth_to_color */
 
+#ifdef GL_NV_copy_image
+
+static GLboolean _glewInit_GL_NV_copy_image (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glCopyImageSubDataNV = (PFNGLCOPYIMAGESUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glCopyImageSubDataNV")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_NV_copy_image */
+
 #ifdef GL_NV_depth_buffer_float
 
 static GLboolean _glewInit_GL_NV_depth_buffer_float (GLEW_CONTEXT_ARG_DEF_INIT)
@@ -5263,6 +5840,10 @@
 
 #endif /* GL_NV_parameter_buffer_object */
 
+#ifdef GL_NV_parameter_buffer_object2
+
+#endif /* GL_NV_parameter_buffer_object2 */
+
 #ifdef GL_NV_pixel_data_range
 
 static GLboolean _glewInit_GL_NV_pixel_data_range (GLEW_CONTEXT_ARG_DEF_INIT)
@@ -5303,7 +5884,6 @@
   r = ((glGetVideouivNV = (PFNGLGETVIDEOUIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideouivNV")) == NULL) || r;
   r = ((glPresentFrameDualFillNV = (PFNGLPRESENTFRAMEDUALFILLNVPROC)glewGetProcAddress((const GLubyte*)"glPresentFrameDualFillNV")) == NULL) || r;
   r = ((glPresentFrameKeyedNV = (PFNGLPRESENTFRAMEKEYEDNVPROC)glewGetProcAddress((const GLubyte*)"glPresentFrameKeyedNV")) == NULL) || r;
-  r = ((glVideoParameterivNV = (PFNGLVIDEOPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glVideoParameterivNV")) == NULL) || r;
 
   return r;
 }
@@ -5363,6 +5943,32 @@
 
 #endif /* GL_NV_register_combiners2 */
 
+#ifdef GL_NV_shader_buffer_load
+
+static GLboolean _glewInit_GL_NV_shader_buffer_load (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glGetBufferParameterui64vNV = (PFNGLGETBUFFERPARAMETERUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameterui64vNV")) == NULL) || r;
+  r = ((glGetIntegerui64vNV = (PFNGLGETINTEGERUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetIntegerui64vNV")) == NULL) || r;
+  r = ((glGetNamedBufferParameterui64vNV = (PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferParameterui64vNV")) == NULL) || r;
+  r = ((glGetUniformui64vNV = (PFNGLGETUNIFORMUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformui64vNV")) == NULL) || r;
+  r = ((glIsBufferResidentNV = (PFNGLISBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsBufferResidentNV")) == NULL) || r;
+  r = ((glIsNamedBufferResidentNV = (PFNGLISNAMEDBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsNamedBufferResidentNV")) == NULL) || r;
+  r = ((glMakeBufferNonResidentNV = (PFNGLMAKEBUFFERNONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeBufferNonResidentNV")) == NULL) || r;
+  r = ((glMakeBufferResidentNV = (PFNGLMAKEBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeBufferResidentNV")) == NULL) || r;
+  r = ((glMakeNamedBufferNonResidentNV = (PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeNamedBufferNonResidentNV")) == NULL) || r;
+  r = ((glMakeNamedBufferResidentNV = (PFNGLMAKENAMEDBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeNamedBufferResidentNV")) == NULL) || r;
+  r = ((glProgramUniformui64NV = (PFNGLPROGRAMUNIFORMUI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformui64NV")) == NULL) || r;
+  r = ((glProgramUniformui64vNV = (PFNGLPROGRAMUNIFORMUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformui64vNV")) == NULL) || r;
+  r = ((glUniformui64NV = (PFNGLUNIFORMUI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniformui64NV")) == NULL) || r;
+  r = ((glUniformui64vNV = (PFNGLUNIFORMUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniformui64vNV")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_NV_shader_buffer_load */
+
 #ifdef GL_NV_texgen_emboss
 
 #endif /* GL_NV_texgen_emboss */
@@ -5371,6 +5977,19 @@
 
 #endif /* GL_NV_texgen_reflection */
 
+#ifdef GL_NV_texture_barrier
+
+static GLboolean _glewInit_GL_NV_texture_barrier (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glTextureBarrierNV = (PFNGLTEXTUREBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glTextureBarrierNV")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_NV_texture_barrier */
+
 #ifdef GL_NV_texture_compression_vtc
 
 #endif /* GL_NV_texture_compression_vtc */
@@ -5422,6 +6041,25 @@
 
 #endif /* GL_NV_transform_feedback */
 
+#ifdef GL_NV_transform_feedback2
+
+static GLboolean _glewInit_GL_NV_transform_feedback2 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glBindTransformFeedbackNV = (PFNGLBINDTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glBindTransformFeedbackNV")) == NULL) || r;
+  r = ((glDeleteTransformFeedbacksNV = (PFNGLDELETETRANSFORMFEEDBACKSNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteTransformFeedbacksNV")) == NULL) || r;
+  r = ((glDrawTransformFeedbackNV = (PFNGLDRAWTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackNV")) == NULL) || r;
+  r = ((glGenTransformFeedbacksNV = (PFNGLGENTRANSFORMFEEDBACKSNVPROC)glewGetProcAddress((const GLubyte*)"glGenTransformFeedbacksNV")) == NULL) || r;
+  r = ((glIsTransformFeedbackNV = (PFNGLISTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glIsTransformFeedbackNV")) == NULL) || r;
+  r = ((glPauseTransformFeedbackNV = (PFNGLPAUSETRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glPauseTransformFeedbackNV")) == NULL) || r;
+  r = ((glResumeTransformFeedbackNV = (PFNGLRESUMETRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glResumeTransformFeedbackNV")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_NV_transform_feedback2 */
+
 #ifdef GL_NV_vertex_array_range
 
 static GLboolean _glewInit_GL_NV_vertex_array_range (GLEW_CONTEXT_ARG_DEF_INIT)
@@ -5440,6 +6078,30 @@
 
 #endif /* GL_NV_vertex_array_range2 */
 
+#ifdef GL_NV_vertex_buffer_unified_memory
+
+static GLboolean _glewInit_GL_NV_vertex_buffer_unified_memory (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glBufferAddressRangeNV = (PFNGLBUFFERADDRESSRANGENVPROC)glewGetProcAddress((const GLubyte*)"glBufferAddressRangeNV")) == NULL) || r;
+  r = ((glColorFormatNV = (PFNGLCOLORFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glColorFormatNV")) == NULL) || r;
+  r = ((glEdgeFlagFormatNV = (PFNGLEDGEFLAGFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagFormatNV")) == NULL) || r;
+  r = ((glFogCoordFormatNV = (PFNGLFOGCOORDFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordFormatNV")) == NULL) || r;
+  r = ((glGetIntegerui64i_vNV = (PFNGLGETINTEGERUI64I_VNVPROC)glewGetProcAddress((const GLubyte*)"glGetIntegerui64i_vNV")) == NULL) || r;
+  r = ((glIndexFormatNV = (PFNGLINDEXFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glIndexFormatNV")) == NULL) || r;
+  r = ((glNormalFormatNV = (PFNGLNORMALFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glNormalFormatNV")) == NULL) || r;
+  r = ((glSecondaryColorFormatNV = (PFNGLSECONDARYCOLORFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorFormatNV")) == NULL) || r;
+  r = ((glTexCoordFormatNV = (PFNGLTEXCOORDFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordFormatNV")) == NULL) || r;
+  r = ((glVertexAttribFormatNV = (PFNGLVERTEXATTRIBFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribFormatNV")) == NULL) || r;
+  r = ((glVertexAttribIFormatNV = (PFNGLVERTEXATTRIBIFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIFormatNV")) == NULL) || r;
+  r = ((glVertexFormatNV = (PFNGLVERTEXFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexFormatNV")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GL_NV_vertex_buffer_unified_memory */
+
 #ifdef GL_NV_vertex_program
 
 static GLboolean _glewInit_GL_NV_vertex_program (GLEW_CONTEXT_ARG_DEF_INIT)
@@ -6153,81 +6815,37 @@
 GLenum glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST)
 {
   const GLubyte* s;
-  GLuint dot, major, minor;
+  GLuint dot;
+  GLint major, minor;
   /* query opengl version */
   s = glGetString(GL_VERSION);
   dot = _glewStrCLen(s, '.');
-  major = dot-1;
-  minor = dot+1;
-  if (dot == 0 || s[minor] == '\0')
+  if (dot == 0)
     return GLEW_ERROR_NO_GL_VERSION;
-  if (s[major] == '1' && s[minor] == '0')
+  
+  major = s[dot-1]-'0';
+  minor = s[dot+1]-'0';
+
+  if (minor < 0 || minor > 9)
+    minor = 0;
+  if (major<0 || major>9)
+    return GLEW_ERROR_NO_GL_VERSION;
+  
+
+  if (major == 1 && minor == 0)
   {
-	return GLEW_ERROR_GL_VERSION_10_ONLY;
+    return GLEW_ERROR_GL_VERSION_10_ONLY;
   }
   else
   {
-    CONST_CAST(GLEW_VERSION_1_1) = GL_TRUE;
-	if (s[major] >= '2')
-	{
-      CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE;
-      CONST_CAST(GLEW_VERSION_1_3) = GL_TRUE;
-      CONST_CAST(GLEW_VERSION_1_4) = GL_TRUE;
-	  CONST_CAST(GLEW_VERSION_1_5) = GL_TRUE;
-	  CONST_CAST(GLEW_VERSION_2_0) = GL_TRUE;
-	  if (s[minor] >= '1')
-	  {
-	    CONST_CAST(GLEW_VERSION_2_1) = GL_TRUE;
-      }
-	}
-	else
-	{
-	  if (s[minor] >= '5')
-	  {
-		CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE;
-		CONST_CAST(GLEW_VERSION_1_3) = GL_TRUE;
-		CONST_CAST(GLEW_VERSION_1_4) = GL_TRUE;
-		CONST_CAST(GLEW_VERSION_1_5) = GL_TRUE;
-		CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE;
-		CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE;
-	  }
-	  if (s[minor] == '4')
-	  {
-		CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE;
-		CONST_CAST(GLEW_VERSION_1_3) = GL_TRUE;
-		CONST_CAST(GLEW_VERSION_1_4) = GL_TRUE;
-		CONST_CAST(GLEW_VERSION_1_5) = GL_FALSE;
-		CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE;
-		CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE;
-	  }
-	  if (s[minor] == '3')
-	  {
-		CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE;
-		CONST_CAST(GLEW_VERSION_1_3) = GL_TRUE;
-		CONST_CAST(GLEW_VERSION_1_4) = GL_FALSE;
-		CONST_CAST(GLEW_VERSION_1_5) = GL_FALSE;
-		CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE;
-		CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE;
-	  }
-	  if (s[minor] == '2')
-	  {
-		CONST_CAST(GLEW_VERSION_1_2) = GL_TRUE;
-		CONST_CAST(GLEW_VERSION_1_3) = GL_FALSE;
-		CONST_CAST(GLEW_VERSION_1_4) = GL_FALSE;
-		CONST_CAST(GLEW_VERSION_1_5) = GL_FALSE;
-		CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE;
-		CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE;
-	  }
-	  if (s[minor] < '2')
-	  {
-		CONST_CAST(GLEW_VERSION_1_2) = GL_FALSE;
-		CONST_CAST(GLEW_VERSION_1_3) = GL_FALSE;
-		CONST_CAST(GLEW_VERSION_1_4) = GL_FALSE;
-		CONST_CAST(GLEW_VERSION_1_5) = GL_FALSE;
-		CONST_CAST(GLEW_VERSION_2_0) = GL_FALSE;
-		CONST_CAST(GLEW_VERSION_2_1) = GL_FALSE;
-	  }
-	}
+    CONST_CAST(GLEW_VERSION_3_0) =                                ( major >= 3               ) ? GL_TRUE : GL_FALSE;
+    CONST_CAST(GLEW_VERSION_2_1) = GLEW_VERSION_3_0 == GL_TRUE || ( major == 2 && minor >= 1 ) ? GL_TRUE : GL_FALSE;    
+    CONST_CAST(GLEW_VERSION_2_0) = GLEW_VERSION_2_1 == GL_TRUE || ( major == 2               ) ? GL_TRUE : GL_FALSE;
+    CONST_CAST(GLEW_VERSION_1_5) = GLEW_VERSION_2_0 == GL_TRUE || ( major == 1 && minor >= 5 ) ? GL_TRUE : GL_FALSE;
+    CONST_CAST(GLEW_VERSION_1_4) = GLEW_VERSION_1_5 == GL_TRUE || ( major == 1 && minor >= 4 ) ? GL_TRUE : GL_FALSE;
+    CONST_CAST(GLEW_VERSION_1_3) = GLEW_VERSION_1_4 == GL_TRUE || ( major == 1 && minor >= 3 ) ? GL_TRUE : GL_FALSE;
+    CONST_CAST(GLEW_VERSION_1_2) = GLEW_VERSION_1_3 == GL_TRUE || ( major == 1 && minor >= 2 ) ? GL_TRUE : GL_FALSE;
+    CONST_CAST(GLEW_VERSION_1_1) = GLEW_VERSION_1_2 == GL_TRUE || ( major == 1 && minor >= 1 ) ? GL_TRUE : GL_FALSE;
   }
   /* initialize extensions */
 #ifdef GL_VERSION_1_2
@@ -6251,6 +6869,12 @@
 #ifdef GL_VERSION_3_0
   if (glewExperimental || GLEW_VERSION_3_0) CONST_CAST(GLEW_VERSION_3_0) = !_glewInit_GL_VERSION_3_0(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* GL_VERSION_3_0 */
+#ifdef GL_VERSION_3_1
+  if (glewExperimental || GLEW_VERSION_3_1) CONST_CAST(GLEW_VERSION_3_1) = !_glewInit_GL_VERSION_3_1(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_VERSION_3_1 */
+#ifdef GL_VERSION_3_2
+  if (glewExperimental || GLEW_VERSION_3_2) CONST_CAST(GLEW_VERSION_3_2) = !_glewInit_GL_VERSION_3_2(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_VERSION_3_2 */
 #ifdef GL_3DFX_multisample
   CONST_CAST(GLEW_3DFX_multisample) = glewGetExtension("GL_3DFX_multisample");
 #endif /* GL_3DFX_multisample */
@@ -6261,6 +6885,24 @@
 #ifdef GL_3DFX_texture_compression_FXT1
   CONST_CAST(GLEW_3DFX_texture_compression_FXT1) = glewGetExtension("GL_3DFX_texture_compression_FXT1");
 #endif /* GL_3DFX_texture_compression_FXT1 */
+#ifdef GL_AMD_draw_buffers_blend
+  CONST_CAST(GLEW_AMD_draw_buffers_blend) = glewGetExtension("GL_AMD_draw_buffers_blend");
+  if (glewExperimental || GLEW_AMD_draw_buffers_blend) CONST_CAST(GLEW_AMD_draw_buffers_blend) = !_glewInit_GL_AMD_draw_buffers_blend(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_AMD_draw_buffers_blend */
+#ifdef GL_AMD_performance_monitor
+  CONST_CAST(GLEW_AMD_performance_monitor) = glewGetExtension("GL_AMD_performance_monitor");
+  if (glewExperimental || GLEW_AMD_performance_monitor) CONST_CAST(GLEW_AMD_performance_monitor) = !_glewInit_GL_AMD_performance_monitor(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_AMD_performance_monitor */
+#ifdef GL_AMD_texture_texture4
+  CONST_CAST(GLEW_AMD_texture_texture4) = glewGetExtension("GL_AMD_texture_texture4");
+#endif /* GL_AMD_texture_texture4 */
+#ifdef GL_AMD_vertex_shader_tessellator
+  CONST_CAST(GLEW_AMD_vertex_shader_tessellator) = glewGetExtension("GL_AMD_vertex_shader_tessellator");
+  if (glewExperimental || GLEW_AMD_vertex_shader_tessellator) CONST_CAST(GLEW_AMD_vertex_shader_tessellator) = !_glewInit_GL_AMD_vertex_shader_tessellator(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_AMD_vertex_shader_tessellator */
+#ifdef GL_APPLE_aux_depth_stencil
+  CONST_CAST(GLEW_APPLE_aux_depth_stencil) = glewGetExtension("GL_APPLE_aux_depth_stencil");
+#endif /* GL_APPLE_aux_depth_stencil */
 #ifdef GL_APPLE_client_storage
   CONST_CAST(GLEW_APPLE_client_storage) = glewGetExtension("GL_APPLE_client_storage");
 #endif /* GL_APPLE_client_storage */
@@ -6279,9 +6921,19 @@
   CONST_CAST(GLEW_APPLE_flush_buffer_range) = glewGetExtension("GL_APPLE_flush_buffer_range");
   if (glewExperimental || GLEW_APPLE_flush_buffer_range) CONST_CAST(GLEW_APPLE_flush_buffer_range) = !_glewInit_GL_APPLE_flush_buffer_range(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* GL_APPLE_flush_buffer_range */
+#ifdef GL_APPLE_object_purgeable
+  CONST_CAST(GLEW_APPLE_object_purgeable) = glewGetExtension("GL_APPLE_object_purgeable");
+  if (glewExperimental || GLEW_APPLE_object_purgeable) CONST_CAST(GLEW_APPLE_object_purgeable) = !_glewInit_GL_APPLE_object_purgeable(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_APPLE_object_purgeable */
 #ifdef GL_APPLE_pixel_buffer
   CONST_CAST(GLEW_APPLE_pixel_buffer) = glewGetExtension("GL_APPLE_pixel_buffer");
 #endif /* GL_APPLE_pixel_buffer */
+#ifdef GL_APPLE_rgb_422
+  CONST_CAST(GLEW_APPLE_rgb_422) = glewGetExtension("GL_APPLE_rgb_422");
+#endif /* GL_APPLE_rgb_422 */
+#ifdef GL_APPLE_row_bytes
+  CONST_CAST(GLEW_APPLE_row_bytes) = glewGetExtension("GL_APPLE_row_bytes");
+#endif /* GL_APPLE_row_bytes */
 #ifdef GL_APPLE_specular_vector
   CONST_CAST(GLEW_APPLE_specular_vector) = glewGetExtension("GL_APPLE_specular_vector");
 #endif /* GL_APPLE_specular_vector */
@@ -6300,6 +6952,10 @@
   CONST_CAST(GLEW_APPLE_vertex_array_range) = glewGetExtension("GL_APPLE_vertex_array_range");
   if (glewExperimental || GLEW_APPLE_vertex_array_range) CONST_CAST(GLEW_APPLE_vertex_array_range) = !_glewInit_GL_APPLE_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* GL_APPLE_vertex_array_range */
+#ifdef GL_APPLE_vertex_program_evaluators
+  CONST_CAST(GLEW_APPLE_vertex_program_evaluators) = glewGetExtension("GL_APPLE_vertex_program_evaluators");
+  if (glewExperimental || GLEW_APPLE_vertex_program_evaluators) CONST_CAST(GLEW_APPLE_vertex_program_evaluators) = !_glewInit_GL_APPLE_vertex_program_evaluators(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_APPLE_vertex_program_evaluators */
 #ifdef GL_APPLE_ycbcr_422
   CONST_CAST(GLEW_APPLE_ycbcr_422) = glewGetExtension("GL_APPLE_ycbcr_422");
 #endif /* GL_APPLE_ycbcr_422 */
@@ -6307,9 +6963,19 @@
   CONST_CAST(GLEW_ARB_color_buffer_float) = glewGetExtension("GL_ARB_color_buffer_float");
   if (glewExperimental || GLEW_ARB_color_buffer_float) CONST_CAST(GLEW_ARB_color_buffer_float) = !_glewInit_GL_ARB_color_buffer_float(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* GL_ARB_color_buffer_float */
+#ifdef GL_ARB_compatibility
+  CONST_CAST(GLEW_ARB_compatibility) = glewGetExtension("GL_ARB_compatibility");
+#endif /* GL_ARB_compatibility */
+#ifdef GL_ARB_copy_buffer
+  CONST_CAST(GLEW_ARB_copy_buffer) = glewGetExtension("GL_ARB_copy_buffer");
+  if (glewExperimental || GLEW_ARB_copy_buffer) CONST_CAST(GLEW_ARB_copy_buffer) = !_glewInit_GL_ARB_copy_buffer(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_copy_buffer */
 #ifdef GL_ARB_depth_buffer_float
   CONST_CAST(GLEW_ARB_depth_buffer_float) = glewGetExtension("GL_ARB_depth_buffer_float");
 #endif /* GL_ARB_depth_buffer_float */
+#ifdef GL_ARB_depth_clamp
+  CONST_CAST(GLEW_ARB_depth_clamp) = glewGetExtension("GL_ARB_depth_clamp");
+#endif /* GL_ARB_depth_clamp */
 #ifdef GL_ARB_depth_texture
   CONST_CAST(GLEW_ARB_depth_texture) = glewGetExtension("GL_ARB_depth_texture");
 #endif /* GL_ARB_depth_texture */
@@ -6317,10 +6983,21 @@
   CONST_CAST(GLEW_ARB_draw_buffers) = glewGetExtension("GL_ARB_draw_buffers");
   if (glewExperimental || GLEW_ARB_draw_buffers) CONST_CAST(GLEW_ARB_draw_buffers) = !_glewInit_GL_ARB_draw_buffers(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* GL_ARB_draw_buffers */
+#ifdef GL_ARB_draw_buffers_blend
+  CONST_CAST(GLEW_ARB_draw_buffers_blend) = glewGetExtension("GL_ARB_draw_buffers_blend");
+  if (glewExperimental || GLEW_ARB_draw_buffers_blend) CONST_CAST(GLEW_ARB_draw_buffers_blend) = !_glewInit_GL_ARB_draw_buffers_blend(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_draw_buffers_blend */
+#ifdef GL_ARB_draw_elements_base_vertex
+  CONST_CAST(GLEW_ARB_draw_elements_base_vertex) = glewGetExtension("GL_ARB_draw_elements_base_vertex");
+  if (glewExperimental || GLEW_ARB_draw_elements_base_vertex) CONST_CAST(GLEW_ARB_draw_elements_base_vertex) = !_glewInit_GL_ARB_draw_elements_base_vertex(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_draw_elements_base_vertex */
 #ifdef GL_ARB_draw_instanced
   CONST_CAST(GLEW_ARB_draw_instanced) = glewGetExtension("GL_ARB_draw_instanced");
   if (glewExperimental || GLEW_ARB_draw_instanced) CONST_CAST(GLEW_ARB_draw_instanced) = !_glewInit_GL_ARB_draw_instanced(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* GL_ARB_draw_instanced */
+#ifdef GL_ARB_fragment_coord_conventions
+  CONST_CAST(GLEW_ARB_fragment_coord_conventions) = glewGetExtension("GL_ARB_fragment_coord_conventions");
+#endif /* GL_ARB_fragment_coord_conventions */
 #ifdef GL_ARB_fragment_program
   CONST_CAST(GLEW_ARB_fragment_program) = glewGetExtension("GL_ARB_fragment_program");
 #endif /* GL_ARB_fragment_program */
@@ -6385,10 +7062,24 @@
 #ifdef GL_ARB_point_sprite
   CONST_CAST(GLEW_ARB_point_sprite) = glewGetExtension("GL_ARB_point_sprite");
 #endif /* GL_ARB_point_sprite */
+#ifdef GL_ARB_provoking_vertex
+  CONST_CAST(GLEW_ARB_provoking_vertex) = glewGetExtension("GL_ARB_provoking_vertex");
+  if (glewExperimental || GLEW_ARB_provoking_vertex) CONST_CAST(GLEW_ARB_provoking_vertex) = !_glewInit_GL_ARB_provoking_vertex(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_provoking_vertex */
+#ifdef GL_ARB_sample_shading
+  CONST_CAST(GLEW_ARB_sample_shading) = glewGetExtension("GL_ARB_sample_shading");
+  if (glewExperimental || GLEW_ARB_sample_shading) CONST_CAST(GLEW_ARB_sample_shading) = !_glewInit_GL_ARB_sample_shading(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_sample_shading */
+#ifdef GL_ARB_seamless_cube_map
+  CONST_CAST(GLEW_ARB_seamless_cube_map) = glewGetExtension("GL_ARB_seamless_cube_map");
+#endif /* GL_ARB_seamless_cube_map */
 #ifdef GL_ARB_shader_objects
   CONST_CAST(GLEW_ARB_shader_objects) = glewGetExtension("GL_ARB_shader_objects");
   if (glewExperimental || GLEW_ARB_shader_objects) CONST_CAST(GLEW_ARB_shader_objects) = !_glewInit_GL_ARB_shader_objects(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* GL_ARB_shader_objects */
+#ifdef GL_ARB_shader_texture_lod
+  CONST_CAST(GLEW_ARB_shader_texture_lod) = glewGetExtension("GL_ARB_shader_texture_lod");
+#endif /* GL_ARB_shader_texture_lod */
 #ifdef GL_ARB_shading_language_100
   CONST_CAST(GLEW_ARB_shading_language_100) = glewGetExtension("GL_ARB_shading_language_100");
 #endif /* GL_ARB_shading_language_100 */
@@ -6398,6 +7089,10 @@
 #ifdef GL_ARB_shadow_ambient
   CONST_CAST(GLEW_ARB_shadow_ambient) = glewGetExtension("GL_ARB_shadow_ambient");
 #endif /* GL_ARB_shadow_ambient */
+#ifdef GL_ARB_sync
+  CONST_CAST(GLEW_ARB_sync) = glewGetExtension("GL_ARB_sync");
+  if (glewExperimental || GLEW_ARB_sync) CONST_CAST(GLEW_ARB_sync) = !_glewInit_GL_ARB_sync(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_sync */
 #ifdef GL_ARB_texture_border_clamp
   CONST_CAST(GLEW_ARB_texture_border_clamp) = glewGetExtension("GL_ARB_texture_border_clamp");
 #endif /* GL_ARB_texture_border_clamp */
@@ -6415,6 +7110,9 @@
 #ifdef GL_ARB_texture_cube_map
   CONST_CAST(GLEW_ARB_texture_cube_map) = glewGetExtension("GL_ARB_texture_cube_map");
 #endif /* GL_ARB_texture_cube_map */
+#ifdef GL_ARB_texture_cube_map_array
+  CONST_CAST(GLEW_ARB_texture_cube_map_array) = glewGetExtension("GL_ARB_texture_cube_map_array");
+#endif /* GL_ARB_texture_cube_map_array */
 #ifdef GL_ARB_texture_env_add
   CONST_CAST(GLEW_ARB_texture_env_add) = glewGetExtension("GL_ARB_texture_env_add");
 #endif /* GL_ARB_texture_env_add */
@@ -6430,12 +7128,22 @@
 #ifdef GL_ARB_texture_float
   CONST_CAST(GLEW_ARB_texture_float) = glewGetExtension("GL_ARB_texture_float");
 #endif /* GL_ARB_texture_float */
+#ifdef GL_ARB_texture_gather
+  CONST_CAST(GLEW_ARB_texture_gather) = glewGetExtension("GL_ARB_texture_gather");
+#endif /* GL_ARB_texture_gather */
 #ifdef GL_ARB_texture_mirrored_repeat
   CONST_CAST(GLEW_ARB_texture_mirrored_repeat) = glewGetExtension("GL_ARB_texture_mirrored_repeat");
 #endif /* GL_ARB_texture_mirrored_repeat */
+#ifdef GL_ARB_texture_multisample
+  CONST_CAST(GLEW_ARB_texture_multisample) = glewGetExtension("GL_ARB_texture_multisample");
+  if (glewExperimental || GLEW_ARB_texture_multisample) CONST_CAST(GLEW_ARB_texture_multisample) = !_glewInit_GL_ARB_texture_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_texture_multisample */
 #ifdef GL_ARB_texture_non_power_of_two
   CONST_CAST(GLEW_ARB_texture_non_power_of_two) = glewGetExtension("GL_ARB_texture_non_power_of_two");
 #endif /* GL_ARB_texture_non_power_of_two */
+#ifdef GL_ARB_texture_query_lod
+  CONST_CAST(GLEW_ARB_texture_query_lod) = glewGetExtension("GL_ARB_texture_query_lod");
+#endif /* GL_ARB_texture_query_lod */
 #ifdef GL_ARB_texture_rectangle
   CONST_CAST(GLEW_ARB_texture_rectangle) = glewGetExtension("GL_ARB_texture_rectangle");
 #endif /* GL_ARB_texture_rectangle */
@@ -6446,6 +7154,13 @@
   CONST_CAST(GLEW_ARB_transpose_matrix) = glewGetExtension("GL_ARB_transpose_matrix");
   if (glewExperimental || GLEW_ARB_transpose_matrix) CONST_CAST(GLEW_ARB_transpose_matrix) = !_glewInit_GL_ARB_transpose_matrix(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* GL_ARB_transpose_matrix */
+#ifdef GL_ARB_uniform_buffer_object
+  CONST_CAST(GLEW_ARB_uniform_buffer_object) = glewGetExtension("GL_ARB_uniform_buffer_object");
+  if (glewExperimental || GLEW_ARB_uniform_buffer_object) CONST_CAST(GLEW_ARB_uniform_buffer_object) = !_glewInit_GL_ARB_uniform_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_uniform_buffer_object */
+#ifdef GL_ARB_vertex_array_bgra
+  CONST_CAST(GLEW_ARB_vertex_array_bgra) = glewGetExtension("GL_ARB_vertex_array_bgra");
+#endif /* GL_ARB_vertex_array_bgra */
 #ifdef GL_ARB_vertex_array_object
   CONST_CAST(GLEW_ARB_vertex_array_object) = glewGetExtension("GL_ARB_vertex_array_object");
   if (glewExperimental || GLEW_ARB_vertex_array_object) CONST_CAST(GLEW_ARB_vertex_array_object) = !_glewInit_GL_ARB_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT);
@@ -6502,6 +7217,9 @@
   CONST_CAST(GLEW_ATI_map_object_buffer) = glewGetExtension("GL_ATI_map_object_buffer");
   if (glewExperimental || GLEW_ATI_map_object_buffer) CONST_CAST(GLEW_ATI_map_object_buffer) = !_glewInit_GL_ATI_map_object_buffer(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* GL_ATI_map_object_buffer */
+#ifdef GL_ATI_meminfo
+  CONST_CAST(GLEW_ATI_meminfo) = glewGetExtension("GL_ATI_meminfo");
+#endif /* GL_ATI_meminfo */
 #ifdef GL_ATI_pn_triangles
   CONST_CAST(GLEW_ATI_pn_triangles) = glewGetExtension("GL_ATI_pn_triangles");
   if (glewExperimental || GLEW_ATI_pn_triangles) CONST_CAST(GLEW_ATI_pn_triangles) = !_glewInit_GL_ATI_pn_triangles(GLEW_CONTEXT_ARG_VAR_INIT);
@@ -6727,6 +7445,10 @@
   CONST_CAST(GLEW_EXT_polygon_offset) = glewGetExtension("GL_EXT_polygon_offset");
   if (glewExperimental || GLEW_EXT_polygon_offset) CONST_CAST(GLEW_EXT_polygon_offset) = !_glewInit_GL_EXT_polygon_offset(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* GL_EXT_polygon_offset */
+#ifdef GL_EXT_provoking_vertex
+  CONST_CAST(GLEW_EXT_provoking_vertex) = glewGetExtension("GL_EXT_provoking_vertex");
+  if (glewExperimental || GLEW_EXT_provoking_vertex) CONST_CAST(GLEW_EXT_provoking_vertex) = !_glewInit_GL_EXT_provoking_vertex(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_provoking_vertex */
 #ifdef GL_EXT_rescale_normal
   CONST_CAST(GLEW_EXT_rescale_normal) = glewGetExtension("GL_EXT_rescale_normal");
 #endif /* GL_EXT_rescale_normal */
@@ -6738,6 +7460,10 @@
   CONST_CAST(GLEW_EXT_secondary_color) = glewGetExtension("GL_EXT_secondary_color");
   if (glewExperimental || GLEW_EXT_secondary_color) CONST_CAST(GLEW_EXT_secondary_color) = !_glewInit_GL_EXT_secondary_color(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* GL_EXT_secondary_color */
+#ifdef GL_EXT_separate_shader_objects
+  CONST_CAST(GLEW_EXT_separate_shader_objects) = glewGetExtension("GL_EXT_separate_shader_objects");
+  if (glewExperimental || GLEW_EXT_separate_shader_objects) CONST_CAST(GLEW_EXT_separate_shader_objects) = !_glewInit_GL_EXT_separate_shader_objects(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_separate_shader_objects */
 #ifdef GL_EXT_separate_specular_color
   CONST_CAST(GLEW_EXT_separate_specular_color) = glewGetExtension("GL_EXT_separate_specular_color");
 #endif /* GL_EXT_separate_specular_color */
@@ -6835,6 +7561,9 @@
 #ifdef GL_EXT_texture_shared_exponent
   CONST_CAST(GLEW_EXT_texture_shared_exponent) = glewGetExtension("GL_EXT_texture_shared_exponent");
 #endif /* GL_EXT_texture_shared_exponent */
+#ifdef GL_EXT_texture_snorm
+  CONST_CAST(GLEW_EXT_texture_snorm) = glewGetExtension("GL_EXT_texture_snorm");
+#endif /* GL_EXT_texture_snorm */
 #ifdef GL_EXT_texture_swizzle
   CONST_CAST(GLEW_EXT_texture_swizzle) = glewGetExtension("GL_EXT_texture_swizzle");
 #endif /* GL_EXT_texture_swizzle */
@@ -6947,6 +7676,10 @@
 #ifdef GL_NV_copy_depth_to_color
   CONST_CAST(GLEW_NV_copy_depth_to_color) = glewGetExtension("GL_NV_copy_depth_to_color");
 #endif /* GL_NV_copy_depth_to_color */
+#ifdef GL_NV_copy_image
+  CONST_CAST(GLEW_NV_copy_image) = glewGetExtension("GL_NV_copy_image");
+  if (glewExperimental || GLEW_NV_copy_image) CONST_CAST(GLEW_NV_copy_image) = !_glewInit_GL_NV_copy_image(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_copy_image */
 #ifdef GL_NV_depth_buffer_float
   CONST_CAST(GLEW_NV_depth_buffer_float) = glewGetExtension("GL_NV_depth_buffer_float");
   if (glewExperimental || GLEW_NV_depth_buffer_float) CONST_CAST(GLEW_NV_depth_buffer_float) = !_glewInit_GL_NV_depth_buffer_float(GLEW_CONTEXT_ARG_VAR_INIT);
@@ -7024,6 +7757,9 @@
   CONST_CAST(GLEW_NV_parameter_buffer_object) = glewGetExtension("GL_NV_parameter_buffer_object");
   if (glewExperimental || GLEW_NV_parameter_buffer_object) CONST_CAST(GLEW_NV_parameter_buffer_object) = !_glewInit_GL_NV_parameter_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* GL_NV_parameter_buffer_object */
+#ifdef GL_NV_parameter_buffer_object2
+  CONST_CAST(GLEW_NV_parameter_buffer_object2) = glewGetExtension("GL_NV_parameter_buffer_object2");
+#endif /* GL_NV_parameter_buffer_object2 */
 #ifdef GL_NV_pixel_data_range
   CONST_CAST(GLEW_NV_pixel_data_range) = glewGetExtension("GL_NV_pixel_data_range");
   if (glewExperimental || GLEW_NV_pixel_data_range) CONST_CAST(GLEW_NV_pixel_data_range) = !_glewInit_GL_NV_pixel_data_range(GLEW_CONTEXT_ARG_VAR_INIT);
@@ -7048,12 +7784,20 @@
   CONST_CAST(GLEW_NV_register_combiners2) = glewGetExtension("GL_NV_register_combiners2");
   if (glewExperimental || GLEW_NV_register_combiners2) CONST_CAST(GLEW_NV_register_combiners2) = !_glewInit_GL_NV_register_combiners2(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* GL_NV_register_combiners2 */
+#ifdef GL_NV_shader_buffer_load
+  CONST_CAST(GLEW_NV_shader_buffer_load) = glewGetExtension("GL_NV_shader_buffer_load");
+  if (glewExperimental || GLEW_NV_shader_buffer_load) CONST_CAST(GLEW_NV_shader_buffer_load) = !_glewInit_GL_NV_shader_buffer_load(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_shader_buffer_load */
 #ifdef GL_NV_texgen_emboss
   CONST_CAST(GLEW_NV_texgen_emboss) = glewGetExtension("GL_NV_texgen_emboss");
 #endif /* GL_NV_texgen_emboss */
 #ifdef GL_NV_texgen_reflection
   CONST_CAST(GLEW_NV_texgen_reflection) = glewGetExtension("GL_NV_texgen_reflection");
 #endif /* GL_NV_texgen_reflection */
+#ifdef GL_NV_texture_barrier
+  CONST_CAST(GLEW_NV_texture_barrier) = glewGetExtension("GL_NV_texture_barrier");
+  if (glewExperimental || GLEW_NV_texture_barrier) CONST_CAST(GLEW_NV_texture_barrier) = !_glewInit_GL_NV_texture_barrier(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_texture_barrier */
 #ifdef GL_NV_texture_compression_vtc
   CONST_CAST(GLEW_NV_texture_compression_vtc) = glewGetExtension("GL_NV_texture_compression_vtc");
 #endif /* GL_NV_texture_compression_vtc */
@@ -7079,6 +7823,10 @@
   CONST_CAST(GLEW_NV_transform_feedback) = glewGetExtension("GL_NV_transform_feedback");
   if (glewExperimental || GLEW_NV_transform_feedback) CONST_CAST(GLEW_NV_transform_feedback) = !_glewInit_GL_NV_transform_feedback(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* GL_NV_transform_feedback */
+#ifdef GL_NV_transform_feedback2
+  CONST_CAST(GLEW_NV_transform_feedback2) = glewGetExtension("GL_NV_transform_feedback2");
+  if (glewExperimental || GLEW_NV_transform_feedback2) CONST_CAST(GLEW_NV_transform_feedback2) = !_glewInit_GL_NV_transform_feedback2(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_transform_feedback2 */
 #ifdef GL_NV_vertex_array_range
   CONST_CAST(GLEW_NV_vertex_array_range) = glewGetExtension("GL_NV_vertex_array_range");
   if (glewExperimental || GLEW_NV_vertex_array_range) CONST_CAST(GLEW_NV_vertex_array_range) = !_glewInit_GL_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT);
@@ -7086,6 +7834,10 @@
 #ifdef GL_NV_vertex_array_range2
   CONST_CAST(GLEW_NV_vertex_array_range2) = glewGetExtension("GL_NV_vertex_array_range2");
 #endif /* GL_NV_vertex_array_range2 */
+#ifdef GL_NV_vertex_buffer_unified_memory
+  CONST_CAST(GLEW_NV_vertex_buffer_unified_memory) = glewGetExtension("GL_NV_vertex_buffer_unified_memory");
+  if (glewExperimental || GLEW_NV_vertex_buffer_unified_memory) CONST_CAST(GLEW_NV_vertex_buffer_unified_memory) = !_glewInit_GL_NV_vertex_buffer_unified_memory(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_vertex_buffer_unified_memory */
 #ifdef GL_NV_vertex_program
   CONST_CAST(GLEW_NV_vertex_program) = glewGetExtension("GL_NV_vertex_program");
   if (glewExperimental || GLEW_NV_vertex_program) CONST_CAST(GLEW_NV_vertex_program) = !_glewInit_GL_NV_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT);
@@ -7352,6 +8104,16 @@
 
 PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL = NULL;
 
+PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC __wglewBlitContextFramebufferAMD = NULL;
+PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC __wglewCreateAssociatedContextAMD = NULL;
+PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __wglewCreateAssociatedContextAttribsAMD = NULL;
+PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC __wglewDeleteAssociatedContextAMD = NULL;
+PFNWGLGETCONTEXTGPUIDAMDPROC __wglewGetContextGPUIDAMD = NULL;
+PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC __wglewGetCurrentAssociatedContextAMD = NULL;
+PFNWGLGETGPUIDSAMDPROC __wglewGetGPUIDsAMD = NULL;
+PFNWGLGETGPUINFOAMDPROC __wglewGetGPUInfoAMD = NULL;
+PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __wglewMakeAssociatedContextCurrentAMD = NULL;
+
 PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB = NULL;
 PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB = NULL;
 PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB = NULL;
@@ -7437,6 +8199,8 @@
 PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D = NULL;
 PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D = NULL;
 
+PFNWGLCOPYIMAGESUBDATANVPROC __wglewCopyImageSubDataNV = NULL;
+
 PFNWGLCREATEAFFINITYDCNVPROC __wglewCreateAffinityDCNV = NULL;
 PFNWGLDELETEDCNVPROC __wglewDeleteDCNV = NULL;
 PFNWGLENUMGPUDEVICESNVPROC __wglewEnumGpuDevicesNV = NULL;
@@ -7472,8 +8236,10 @@
 PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML = NULL;
 GLboolean __WGLEW_3DFX_multisample = GL_FALSE;
 GLboolean __WGLEW_3DL_stereo_control = GL_FALSE;
+GLboolean __WGLEW_AMD_gpu_association = GL_FALSE;
 GLboolean __WGLEW_ARB_buffer_region = GL_FALSE;
 GLboolean __WGLEW_ARB_create_context = GL_FALSE;
+GLboolean __WGLEW_ARB_create_context_profile = GL_FALSE;
 GLboolean __WGLEW_ARB_extensions_string = GL_FALSE;
 GLboolean __WGLEW_ARB_framebuffer_sRGB = GL_FALSE;
 GLboolean __WGLEW_ARB_make_current_read = GL_FALSE;
@@ -7500,6 +8266,7 @@
 GLboolean __WGLEW_I3D_image_buffer = GL_FALSE;
 GLboolean __WGLEW_I3D_swap_frame_lock = GL_FALSE;
 GLboolean __WGLEW_I3D_swap_frame_usage = GL_FALSE;
+GLboolean __WGLEW_NV_copy_image = GL_FALSE;
 GLboolean __WGLEW_NV_float_buffer = GL_FALSE;
 GLboolean __WGLEW_NV_gpu_affinity = GL_FALSE;
 GLboolean __WGLEW_NV_present_video = GL_FALSE;
@@ -7529,6 +8296,27 @@
 
 #endif /* WGL_3DL_stereo_control */
 
+#ifdef WGL_AMD_gpu_association
+
+static GLboolean _glewInit_WGL_AMD_gpu_association (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((wglBlitContextFramebufferAMD = (PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC)glewGetProcAddress((const GLubyte*)"wglBlitContextFramebufferAMD")) == NULL) || r;
+  r = ((wglCreateAssociatedContextAMD = (PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"wglCreateAssociatedContextAMD")) == NULL) || r;
+  r = ((wglCreateAssociatedContextAttribsAMD = (PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC)glewGetProcAddress((const GLubyte*)"wglCreateAssociatedContextAttribsAMD")) == NULL) || r;
+  r = ((wglDeleteAssociatedContextAMD = (PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"wglDeleteAssociatedContextAMD")) == NULL) || r;
+  r = ((wglGetContextGPUIDAMD = (PFNWGLGETCONTEXTGPUIDAMDPROC)glewGetProcAddress((const GLubyte*)"wglGetContextGPUIDAMD")) == NULL) || r;
+  r = ((wglGetCurrentAssociatedContextAMD = (PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"wglGetCurrentAssociatedContextAMD")) == NULL) || r;
+  r = ((wglGetGPUIDsAMD = (PFNWGLGETGPUIDSAMDPROC)glewGetProcAddress((const GLubyte*)"wglGetGPUIDsAMD")) == NULL) || r;
+  r = ((wglGetGPUInfoAMD = (PFNWGLGETGPUINFOAMDPROC)glewGetProcAddress((const GLubyte*)"wglGetGPUInfoAMD")) == NULL) || r;
+  r = ((wglMakeAssociatedContextCurrentAMD = (PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC)glewGetProcAddress((const GLubyte*)"wglMakeAssociatedContextCurrentAMD")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* WGL_AMD_gpu_association */
+
 #ifdef WGL_ARB_buffer_region
 
 static GLboolean _glewInit_WGL_ARB_buffer_region (WGLEW_CONTEXT_ARG_DEF_INIT)
@@ -7558,6 +8346,10 @@
 
 #endif /* WGL_ARB_create_context */
 
+#ifdef WGL_ARB_create_context_profile
+
+#endif /* WGL_ARB_create_context_profile */
+
 #ifdef WGL_ARB_extensions_string
 
 static GLboolean _glewInit_WGL_ARB_extensions_string (WGLEW_CONTEXT_ARG_DEF_INIT)
@@ -7859,6 +8651,19 @@
 
 #endif /* WGL_I3D_swap_frame_usage */
 
+#ifdef WGL_NV_copy_image
+
+static GLboolean _glewInit_WGL_NV_copy_image (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((wglCopyImageSubDataNV = (PFNWGLCOPYIMAGESUBDATANVPROC)glewGetProcAddress((const GLubyte*)"wglCopyImageSubDataNV")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* WGL_NV_copy_image */
+
 #ifdef WGL_NV_float_buffer
 
 #endif /* WGL_NV_float_buffer */
@@ -8014,6 +8819,10 @@
   CONST_CAST(WGLEW_3DL_stereo_control) = wglewGetExtension("WGL_3DL_stereo_control");
   if (glewExperimental || WGLEW_3DL_stereo_control|| crippled) CONST_CAST(WGLEW_3DL_stereo_control)= !_glewInit_WGL_3DL_stereo_control(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* WGL_3DL_stereo_control */
+#ifdef WGL_AMD_gpu_association
+  CONST_CAST(WGLEW_AMD_gpu_association) = wglewGetExtension("WGL_AMD_gpu_association");
+  if (glewExperimental || WGLEW_AMD_gpu_association|| crippled) CONST_CAST(WGLEW_AMD_gpu_association)= !_glewInit_WGL_AMD_gpu_association(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_AMD_gpu_association */
 #ifdef WGL_ARB_buffer_region
   CONST_CAST(WGLEW_ARB_buffer_region) = wglewGetExtension("WGL_ARB_buffer_region");
   if (glewExperimental || WGLEW_ARB_buffer_region|| crippled) CONST_CAST(WGLEW_ARB_buffer_region)= !_glewInit_WGL_ARB_buffer_region(GLEW_CONTEXT_ARG_VAR_INIT);
@@ -8022,6 +8831,9 @@
   CONST_CAST(WGLEW_ARB_create_context) = wglewGetExtension("WGL_ARB_create_context");
   if (glewExperimental || WGLEW_ARB_create_context|| crippled) CONST_CAST(WGLEW_ARB_create_context)= !_glewInit_WGL_ARB_create_context(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* WGL_ARB_create_context */
+#ifdef WGL_ARB_create_context_profile
+  CONST_CAST(WGLEW_ARB_create_context_profile) = wglewGetExtension("WGL_ARB_create_context_profile");
+#endif /* WGL_ARB_create_context_profile */
 #ifdef WGL_ARB_extensions_string
   CONST_CAST(WGLEW_ARB_extensions_string) = wglewGetExtension("WGL_ARB_extensions_string");
   if (glewExperimental || WGLEW_ARB_extensions_string|| crippled) CONST_CAST(WGLEW_ARB_extensions_string)= !_glewInit_WGL_ARB_extensions_string(GLEW_CONTEXT_ARG_VAR_INIT);
@@ -8117,6 +8929,10 @@
   CONST_CAST(WGLEW_I3D_swap_frame_usage) = wglewGetExtension("WGL_I3D_swap_frame_usage");
   if (glewExperimental || WGLEW_I3D_swap_frame_usage|| crippled) CONST_CAST(WGLEW_I3D_swap_frame_usage)= !_glewInit_WGL_I3D_swap_frame_usage(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* WGL_I3D_swap_frame_usage */
+#ifdef WGL_NV_copy_image
+  CONST_CAST(WGLEW_NV_copy_image) = wglewGetExtension("WGL_NV_copy_image");
+  if (glewExperimental || WGLEW_NV_copy_image|| crippled) CONST_CAST(WGLEW_NV_copy_image)= !_glewInit_WGL_NV_copy_image(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_NV_copy_image */
 #ifdef WGL_NV_float_buffer
   CONST_CAST(WGLEW_NV_float_buffer) = wglewGetExtension("WGL_NV_float_buffer");
 #endif /* WGL_NV_float_buffer */
@@ -8187,6 +9003,8 @@
 PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT = NULL;
 PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT = NULL;
 
+PFNGLXSWAPINTERVALEXTPROC __glewXSwapIntervalEXT = NULL;
+
 PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT = NULL;
 PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT = NULL;
 
@@ -8200,6 +9018,8 @@
 
 PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA = NULL;
 
+PFNGLXCOPYIMAGESUBDATANVPROC __glewXCopyImageSubDataNV = NULL;
+
 PFNGLXBINDVIDEODEVICENVPROC __glewXBindVideoDeviceNV = NULL;
 PFNGLXENUMERATEVIDEODEVICESNVPROC __glewXEnumerateVideoDevicesNV = NULL;
 
@@ -8285,6 +9105,7 @@
 GLboolean __GLXEW_VERSION_1_4 = GL_FALSE;
 GLboolean __GLXEW_3DFX_multisample = GL_FALSE;
 GLboolean __GLXEW_ARB_create_context = GL_FALSE;
+GLboolean __GLXEW_ARB_create_context_profile = GL_FALSE;
 GLboolean __GLXEW_ARB_fbconfig_float = GL_FALSE;
 GLboolean __GLXEW_ARB_framebuffer_sRGB = GL_FALSE;
 GLboolean __GLXEW_ARB_get_proc_address = GL_FALSE;
@@ -8295,6 +9116,7 @@
 GLboolean __GLXEW_EXT_framebuffer_sRGB = GL_FALSE;
 GLboolean __GLXEW_EXT_import_context = GL_FALSE;
 GLboolean __GLXEW_EXT_scene_marker = GL_FALSE;
+GLboolean __GLXEW_EXT_swap_control = GL_FALSE;
 GLboolean __GLXEW_EXT_texture_from_pixmap = GL_FALSE;
 GLboolean __GLXEW_EXT_visual_info = GL_FALSE;
 GLboolean __GLXEW_EXT_visual_rating = GL_FALSE;
@@ -8303,6 +9125,7 @@
 GLboolean __GLXEW_MESA_pixmap_colormap = GL_FALSE;
 GLboolean __GLXEW_MESA_release_buffers = GL_FALSE;
 GLboolean __GLXEW_MESA_set_3dfx_mode = GL_FALSE;
+GLboolean __GLXEW_NV_copy_image = GL_FALSE;
 GLboolean __GLXEW_NV_float_buffer = GL_FALSE;
 GLboolean __GLXEW_NV_present_video = GL_FALSE;
 GLboolean __GLXEW_NV_swap_group = GL_FALSE;
@@ -8395,6 +9218,10 @@
 
 #endif /* GLX_ARB_create_context */
 
+#ifdef GLX_ARB_create_context_profile
+
+#endif /* GLX_ARB_create_context_profile */
+
 #ifdef GLX_ARB_fbconfig_float
 
 #endif /* GLX_ARB_fbconfig_float */
@@ -8458,6 +9285,19 @@
 
 #endif /* GLX_EXT_scene_marker */
 
+#ifdef GLX_EXT_swap_control
+
+static GLboolean _glewInit_GLX_EXT_swap_control (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glewGetProcAddress((const GLubyte*)"glXSwapIntervalEXT")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GLX_EXT_swap_control */
+
 #ifdef GLX_EXT_texture_from_pixmap
 
 static GLboolean _glewInit_GLX_EXT_texture_from_pixmap (GLXEW_CONTEXT_ARG_DEF_INIT)
@@ -8545,6 +9385,19 @@
 
 #endif /* GLX_MESA_set_3dfx_mode */
 
+#ifdef GLX_NV_copy_image
+
+static GLboolean _glewInit_GLX_NV_copy_image (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+  GLboolean r = GL_FALSE;
+
+  r = ((glXCopyImageSubDataNV = (PFNGLXCOPYIMAGESUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glXCopyImageSubDataNV")) == NULL) || r;
+
+  return r;
+}
+
+#endif /* GLX_NV_copy_image */
+
 #ifdef GLX_NV_float_buffer
 
 #endif /* GLX_NV_float_buffer */
@@ -8841,10 +9694,10 @@
 {    
   GLubyte* p;
   GLubyte* end;
-  GLuint len = _glewStrLen((const GLubyte*)name);
-/*   if (glXQueryExtensionsString == NULL || glXGetCurrentDisplay == NULL) return GL_FALSE; */
-/*   p = (GLubyte*)glXQueryExtensionsString(glXGetCurrentDisplay(), DefaultScreen(glXGetCurrentDisplay())); */
-  if (glXGetClientString == NULL || glXGetCurrentDisplay == NULL) return GL_FALSE;
+  GLuint len;
+
+  if (glXGetCurrentDisplay == NULL) return GL_FALSE;
+  len = _glewStrLen((const GLubyte*)name);
   p = (GLubyte*)glXGetClientString(glXGetCurrentDisplay(), GLX_EXTENSIONS);
   if (0 == p) return GL_FALSE;
   end = p + _glewStrLen(p);
@@ -8897,6 +9750,9 @@
   CONST_CAST(GLXEW_ARB_create_context) = glxewGetExtension("GLX_ARB_create_context");
   if (glewExperimental || GLXEW_ARB_create_context) CONST_CAST(GLXEW_ARB_create_context) = !_glewInit_GLX_ARB_create_context(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* GLX_ARB_create_context */
+#ifdef GLX_ARB_create_context_profile
+  CONST_CAST(GLXEW_ARB_create_context_profile) = glxewGetExtension("GLX_ARB_create_context_profile");
+#endif /* GLX_ARB_create_context_profile */
 #ifdef GLX_ARB_fbconfig_float
   CONST_CAST(GLXEW_ARB_fbconfig_float) = glxewGetExtension("GLX_ARB_fbconfig_float");
 #endif /* GLX_ARB_fbconfig_float */
@@ -8929,6 +9785,10 @@
 #ifdef GLX_EXT_scene_marker
   CONST_CAST(GLXEW_EXT_scene_marker) = glxewGetExtension("GLX_EXT_scene_marker");
 #endif /* GLX_EXT_scene_marker */
+#ifdef GLX_EXT_swap_control
+  CONST_CAST(GLXEW_EXT_swap_control) = glxewGetExtension("GLX_EXT_swap_control");
+  if (glewExperimental || GLXEW_EXT_swap_control) CONST_CAST(GLXEW_EXT_swap_control) = !_glewInit_GLX_EXT_swap_control(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_EXT_swap_control */
 #ifdef GLX_EXT_texture_from_pixmap
   CONST_CAST(GLXEW_EXT_texture_from_pixmap) = glxewGetExtension("GLX_EXT_texture_from_pixmap");
   if (glewExperimental || GLXEW_EXT_texture_from_pixmap) CONST_CAST(GLXEW_EXT_texture_from_pixmap) = !_glewInit_GLX_EXT_texture_from_pixmap(GLEW_CONTEXT_ARG_VAR_INIT);
@@ -8959,6 +9819,10 @@
   CONST_CAST(GLXEW_MESA_set_3dfx_mode) = glxewGetExtension("GLX_MESA_set_3dfx_mode");
   if (glewExperimental || GLXEW_MESA_set_3dfx_mode) CONST_CAST(GLXEW_MESA_set_3dfx_mode) = !_glewInit_GLX_MESA_set_3dfx_mode(GLEW_CONTEXT_ARG_VAR_INIT);
 #endif /* GLX_MESA_set_3dfx_mode */
+#ifdef GLX_NV_copy_image
+  CONST_CAST(GLXEW_NV_copy_image) = glxewGetExtension("GLX_NV_copy_image");
+  if (glewExperimental || GLXEW_NV_copy_image) CONST_CAST(GLXEW_NV_copy_image) = !_glewInit_GLX_NV_copy_image(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_NV_copy_image */
 #ifdef GLX_NV_float_buffer
   CONST_CAST(GLXEW_NV_float_buffer) = glxewGetExtension("GLX_NV_float_buffer");
 #endif /* GLX_NV_float_buffer */
@@ -9076,10 +9940,10 @@
   static const GLubyte* _glewString[] =
   {
     (const GLubyte*)NULL,
-    (const GLubyte*)"1.5.1",
+    (const GLubyte*)"1.5.2",
     (const GLubyte*)"1",
     (const GLubyte*)"5",
-    (const GLubyte*)"1"
+    (const GLubyte*)"2"
   };
   const int max_string = sizeof(_glewString)/sizeof(*_glewString) - 1;
   return _glewString[(int)name > max_string ? 0 : (int)name];
@@ -9175,6 +10039,20 @@
           continue;
         }
 #endif
+#ifdef GL_VERSION_3_1
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_1", 3))
+        {
+          ret = GLEW_VERSION_3_1;
+          continue;
+        }
+#endif
+#ifdef GL_VERSION_3_2
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_2", 3))
+        {
+          ret = GLEW_VERSION_3_2;
+          continue;
+        }
+#endif
       }
       if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5))
       {
@@ -9200,8 +10078,46 @@
         }
 #endif
       }
+      if (_glewStrSame2(&pos, &len, (const GLubyte*)"AMD_", 4))
+      {
+#ifdef GL_AMD_draw_buffers_blend
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers_blend", 18))
+        {
+          ret = GLEW_AMD_draw_buffers_blend;
+          continue;
+        }
+#endif
+#ifdef GL_AMD_performance_monitor
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"performance_monitor", 19))
+        {
+          ret = GLEW_AMD_performance_monitor;
+          continue;
+        }
+#endif
+#ifdef GL_AMD_texture_texture4
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_texture4", 16))
+        {
+          ret = GLEW_AMD_texture_texture4;
+          continue;
+        }
+#endif
+#ifdef GL_AMD_vertex_shader_tessellator
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_tessellator", 25))
+        {
+          ret = GLEW_AMD_vertex_shader_tessellator;
+          continue;
+        }
+#endif
+      }
       if (_glewStrSame2(&pos, &len, (const GLubyte*)"APPLE_", 6))
       {
+#ifdef GL_APPLE_aux_depth_stencil
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"aux_depth_stencil", 17))
+        {
+          ret = GLEW_APPLE_aux_depth_stencil;
+          continue;
+        }
+#endif
 #ifdef GL_APPLE_client_storage
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"client_storage", 14))
         {
@@ -9237,6 +10153,13 @@
           continue;
         }
 #endif
+#ifdef GL_APPLE_object_purgeable
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"object_purgeable", 16))
+        {
+          ret = GLEW_APPLE_object_purgeable;
+          continue;
+        }
+#endif
 #ifdef GL_APPLE_pixel_buffer
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer", 12))
         {
@@ -9244,6 +10167,20 @@
           continue;
         }
 #endif
+#ifdef GL_APPLE_rgb_422
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"rgb_422", 7))
+        {
+          ret = GLEW_APPLE_rgb_422;
+          continue;
+        }
+#endif
+#ifdef GL_APPLE_row_bytes
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"row_bytes", 9))
+        {
+          ret = GLEW_APPLE_row_bytes;
+          continue;
+        }
+#endif
 #ifdef GL_APPLE_specular_vector
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"specular_vector", 15))
         {
@@ -9279,6 +10216,13 @@
           continue;
         }
 #endif
+#ifdef GL_APPLE_vertex_program_evaluators
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program_evaluators", 25))
+        {
+          ret = GLEW_APPLE_vertex_program_evaluators;
+          continue;
+        }
+#endif
 #ifdef GL_APPLE_ycbcr_422
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycbcr_422", 9))
         {
@@ -9296,6 +10240,20 @@
           continue;
         }
 #endif
+#ifdef GL_ARB_compatibility
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"compatibility", 13))
+        {
+          ret = GLEW_ARB_compatibility;
+          continue;
+        }
+#endif
+#ifdef GL_ARB_copy_buffer
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_buffer", 11))
+        {
+          ret = GLEW_ARB_copy_buffer;
+          continue;
+        }
+#endif
 #ifdef GL_ARB_depth_buffer_float
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_buffer_float", 18))
         {
@@ -9303,6 +10261,13 @@
           continue;
         }
 #endif
+#ifdef GL_ARB_depth_clamp
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_clamp", 11))
+        {
+          ret = GLEW_ARB_depth_clamp;
+          continue;
+        }
+#endif
 #ifdef GL_ARB_depth_texture
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13))
         {
@@ -9317,6 +10282,20 @@
           continue;
         }
 #endif
+#ifdef GL_ARB_draw_buffers_blend
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers_blend", 18))
+        {
+          ret = GLEW_ARB_draw_buffers_blend;
+          continue;
+        }
+#endif
+#ifdef GL_ARB_draw_elements_base_vertex
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_elements_base_vertex", 25))
+        {
+          ret = GLEW_ARB_draw_elements_base_vertex;
+          continue;
+        }
+#endif
 #ifdef GL_ARB_draw_instanced
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_instanced", 14))
         {
@@ -9324,6 +10303,13 @@
           continue;
         }
 #endif
+#ifdef GL_ARB_fragment_coord_conventions
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_coord_conventions", 26))
+        {
+          ret = GLEW_ARB_fragment_coord_conventions;
+          continue;
+        }
+#endif
 #ifdef GL_ARB_fragment_program
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program", 16))
         {
@@ -9450,6 +10436,27 @@
           continue;
         }
 #endif
+#ifdef GL_ARB_provoking_vertex
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"provoking_vertex", 16))
+        {
+          ret = GLEW_ARB_provoking_vertex;
+          continue;
+        }
+#endif
+#ifdef GL_ARB_sample_shading
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"sample_shading", 14))
+        {
+          ret = GLEW_ARB_sample_shading;
+          continue;
+        }
+#endif
+#ifdef GL_ARB_seamless_cube_map
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"seamless_cube_map", 17))
+        {
+          ret = GLEW_ARB_seamless_cube_map;
+          continue;
+        }
+#endif
 #ifdef GL_ARB_shader_objects
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_objects", 14))
         {
@@ -9457,6 +10464,13 @@
           continue;
         }
 #endif
+#ifdef GL_ARB_shader_texture_lod
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_texture_lod", 18))
+        {
+          ret = GLEW_ARB_shader_texture_lod;
+          continue;
+        }
+#endif
 #ifdef GL_ARB_shading_language_100
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_100", 20))
         {
@@ -9478,6 +10492,13 @@
           continue;
         }
 #endif
+#ifdef GL_ARB_sync
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync", 4))
+        {
+          ret = GLEW_ARB_sync;
+          continue;
+        }
+#endif
 #ifdef GL_ARB_texture_border_clamp
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20))
         {
@@ -9513,6 +10534,13 @@
           continue;
         }
 #endif
+#ifdef GL_ARB_texture_cube_map_array
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map_array", 22))
+        {
+          ret = GLEW_ARB_texture_cube_map_array;
+          continue;
+        }
+#endif
 #ifdef GL_ARB_texture_env_add
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_add", 15))
         {
@@ -9548,6 +10576,13 @@
           continue;
         }
 #endif
+#ifdef GL_ARB_texture_gather
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_gather", 14))
+        {
+          ret = GLEW_ARB_texture_gather;
+          continue;
+        }
+#endif
 #ifdef GL_ARB_texture_mirrored_repeat
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirrored_repeat", 23))
         {
@@ -9555,6 +10590,13 @@
           continue;
         }
 #endif
+#ifdef GL_ARB_texture_multisample
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_multisample", 19))
+        {
+          ret = GLEW_ARB_texture_multisample;
+          continue;
+        }
+#endif
 #ifdef GL_ARB_texture_non_power_of_two
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_non_power_of_two", 24))
         {
@@ -9562,6 +10604,13 @@
           continue;
         }
 #endif
+#ifdef GL_ARB_texture_query_lod
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_query_lod", 17))
+        {
+          ret = GLEW_ARB_texture_query_lod;
+          continue;
+        }
+#endif
 #ifdef GL_ARB_texture_rectangle
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17))
         {
@@ -9583,6 +10632,20 @@
           continue;
         }
 #endif
+#ifdef GL_ARB_uniform_buffer_object
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"uniform_buffer_object", 21))
+        {
+          ret = GLEW_ARB_uniform_buffer_object;
+          continue;
+        }
+#endif
+#ifdef GL_ARB_vertex_array_bgra
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_bgra", 17))
+        {
+          ret = GLEW_ARB_vertex_array_bgra;
+          continue;
+        }
+#endif
 #ifdef GL_ARB_vertex_array_object
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19))
         {
@@ -9694,6 +10757,13 @@
           continue;
         }
 #endif
+#ifdef GL_ATI_meminfo
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"meminfo", 7))
+        {
+          ret = GLEW_ATI_meminfo;
+          continue;
+        }
+#endif
 #ifdef GL_ATI_pn_triangles
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"pn_triangles", 12))
         {
@@ -10131,6 +11201,13 @@
           continue;
         }
 #endif
+#ifdef GL_EXT_provoking_vertex
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"provoking_vertex", 16))
+        {
+          ret = GLEW_EXT_provoking_vertex;
+          continue;
+        }
+#endif
 #ifdef GL_EXT_rescale_normal
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"rescale_normal", 14))
         {
@@ -10152,6 +11229,13 @@
           continue;
         }
 #endif
+#ifdef GL_EXT_separate_shader_objects
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_shader_objects", 23))
+        {
+          ret = GLEW_EXT_separate_shader_objects;
+          continue;
+        }
+#endif
 #ifdef GL_EXT_separate_specular_color
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_specular_color", 23))
         {
@@ -10362,6 +11446,13 @@
           continue;
         }
 #endif
+#ifdef GL_EXT_texture_snorm
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_snorm", 13))
+        {
+          ret = GLEW_EXT_texture_snorm;
+          continue;
+        }
+#endif
 #ifdef GL_EXT_texture_swizzle
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_swizzle", 15))
         {
@@ -10613,6 +11704,13 @@
           continue;
         }
 #endif
+#ifdef GL_NV_copy_image
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10))
+        {
+          ret = GLEW_NV_copy_image;
+          continue;
+        }
+#endif
 #ifdef GL_NV_depth_buffer_float
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_buffer_float", 18))
         {
@@ -10767,6 +11865,13 @@
           continue;
         }
 #endif
+#ifdef GL_NV_parameter_buffer_object2
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"parameter_buffer_object2", 24))
+        {
+          ret = GLEW_NV_parameter_buffer_object2;
+          continue;
+        }
+#endif
 #ifdef GL_NV_pixel_data_range
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_data_range", 16))
         {
@@ -10809,6 +11914,13 @@
           continue;
         }
 #endif
+#ifdef GL_NV_shader_buffer_load
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_buffer_load", 18))
+        {
+          ret = GLEW_NV_shader_buffer_load;
+          continue;
+        }
+#endif
 #ifdef GL_NV_texgen_emboss
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"texgen_emboss", 13))
         {
@@ -10823,6 +11935,13 @@
           continue;
         }
 #endif
+#ifdef GL_NV_texture_barrier
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_barrier", 15))
+        {
+          ret = GLEW_NV_texture_barrier;
+          continue;
+        }
+#endif
 #ifdef GL_NV_texture_compression_vtc
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_vtc", 23))
         {
@@ -10879,6 +11998,13 @@
           continue;
         }
 #endif
+#ifdef GL_NV_transform_feedback2
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback2", 19))
+        {
+          ret = GLEW_NV_transform_feedback2;
+          continue;
+        }
+#endif
 #ifdef GL_NV_vertex_array_range
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18))
         {
@@ -10893,6 +12019,13 @@
           continue;
         }
 #endif
+#ifdef GL_NV_vertex_buffer_unified_memory
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_buffer_unified_memory", 28))
+        {
+          ret = GLEW_NV_vertex_buffer_unified_memory;
+          continue;
+        }
+#endif
 #ifdef GL_NV_vertex_program
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program", 14))
         {
@@ -11507,6 +12640,16 @@
         }
 #endif
       }
+      if (_glewStrSame2(&pos, &len, (const GLubyte*)"AMD_", 4))
+      {
+#ifdef WGL_AMD_gpu_association
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_association", 15))
+        {
+          ret = WGLEW_AMD_gpu_association;
+          continue;
+        }
+#endif
+      }
       if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4))
       {
 #ifdef WGL_ARB_buffer_region
@@ -11523,6 +12666,13 @@
           continue;
         }
 #endif
+#ifdef WGL_ARB_create_context_profile
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_profile", 22))
+        {
+          ret = WGLEW_ARB_create_context_profile;
+          continue;
+        }
+#endif
 #ifdef WGL_ARB_extensions_string
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"extensions_string", 17))
         {
@@ -11717,6 +12867,13 @@
       }
       if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3))
       {
+#ifdef WGL_NV_copy_image
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10))
+        {
+          ret = WGLEW_NV_copy_image;
+          continue;
+        }
+#endif
 #ifdef WGL_NV_float_buffer
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12))
         {
@@ -11848,6 +13005,13 @@
           continue;
         }
 #endif
+#ifdef GLX_ARB_create_context_profile
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_profile", 22))
+        {
+          ret = GLXEW_ARB_create_context_profile;
+          continue;
+        }
+#endif
 #ifdef GLX_ARB_fbconfig_float
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig_float", 14))
         {
@@ -11924,6 +13088,13 @@
           continue;
         }
 #endif
+#ifdef GLX_EXT_swap_control
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12))
+        {
+          ret = GLXEW_EXT_swap_control;
+          continue;
+        }
+#endif
 #ifdef GLX_EXT_texture_from_pixmap
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_from_pixmap", 19))
         {
@@ -11986,6 +13157,13 @@
       }
       if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3))
       {
+#ifdef GLX_NV_copy_image
+        if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10))
+        {
+          ret = GLXEW_NV_copy_image;
+          continue;
+        }
+#endif
 #ifdef GLX_NV_float_buffer
         if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12))
         {
diff --git a/src/glew/glewinfo.c b/src/glew/glewinfo.c
index da2b241..6847cbb 100644
--- a/src/glew/glewinfo.c
+++ b/src/glew/glewinfo.c
@@ -389,8 +389,6 @@
 
   glewInfoFunc("glBeginConditionalRender", glBeginConditionalRender == NULL);
   glewInfoFunc("glBeginTransformFeedback", glBeginTransformFeedback == NULL);
-  glewInfoFunc("glBindBufferBase", glBindBufferBase == NULL);
-  glewInfoFunc("glBindBufferRange", glBindBufferRange == NULL);
   glewInfoFunc("glBindFragDataLocation", glBindFragDataLocation == NULL);
   glewInfoFunc("glClampColor", glClampColor == NULL);
   glewInfoFunc("glClearBufferfi", glClearBufferfi == NULL);
@@ -404,7 +402,6 @@
   glewInfoFunc("glEndTransformFeedback", glEndTransformFeedback == NULL);
   glewInfoFunc("glGetBooleani_v", glGetBooleani_v == NULL);
   glewInfoFunc("glGetFragDataLocation", glGetFragDataLocation == NULL);
-  glewInfoFunc("glGetIntegeri_v", glGetIntegeri_v == NULL);
   glewInfoFunc("glGetStringi", glGetStringi == NULL);
   glewInfoFunc("glGetTexParameterIiv", glGetTexParameterIiv == NULL);
   glewInfoFunc("glGetTexParameterIuiv", glGetTexParameterIuiv == NULL);
@@ -449,6 +446,33 @@
 
 #endif /* GL_VERSION_3_0 */
 
+#ifdef GL_VERSION_3_1
+
+static void _glewInfo_GL_VERSION_3_1 (void)
+{
+  glewPrintExt("GL_VERSION_3_1", GLEW_VERSION_3_1, GLEW_VERSION_3_1, GLEW_VERSION_3_1);
+
+  glewInfoFunc("glDrawArraysInstanced", glDrawArraysInstanced == NULL);
+  glewInfoFunc("glDrawElementsInstanced", glDrawElementsInstanced == NULL);
+  glewInfoFunc("glPrimitiveRestartIndex", glPrimitiveRestartIndex == NULL);
+  glewInfoFunc("glTexBuffer", glTexBuffer == NULL);
+}
+
+#endif /* GL_VERSION_3_1 */
+
+#ifdef GL_VERSION_3_2
+
+static void _glewInfo_GL_VERSION_3_2 (void)
+{
+  glewPrintExt("GL_VERSION_3_2", GLEW_VERSION_3_2, GLEW_VERSION_3_2, GLEW_VERSION_3_2);
+
+  glewInfoFunc("glFramebufferTexture", glFramebufferTexture == NULL);
+  glewInfoFunc("glGetBufferParameteri64v", glGetBufferParameteri64v == NULL);
+  glewInfoFunc("glGetInteger64i_v", glGetInteger64i_v == NULL);
+}
+
+#endif /* GL_VERSION_3_2 */
+
 #ifdef GL_3DFX_multisample
 
 static void _glewInfo_GL_3DFX_multisample (void)
@@ -478,6 +502,71 @@
 
 #endif /* GL_3DFX_texture_compression_FXT1 */
 
+#ifdef GL_AMD_draw_buffers_blend
+
+static void _glewInfo_GL_AMD_draw_buffers_blend (void)
+{
+  glewPrintExt("GL_AMD_draw_buffers_blend", GLEW_AMD_draw_buffers_blend, glewIsSupported("GL_AMD_draw_buffers_blend"), glewGetExtension("GL_AMD_draw_buffers_blend"));
+
+  glewInfoFunc("glBlendEquationIndexedAMD", glBlendEquationIndexedAMD == NULL);
+  glewInfoFunc("glBlendEquationSeparateIndexedAMD", glBlendEquationSeparateIndexedAMD == NULL);
+  glewInfoFunc("glBlendFuncIndexedAMD", glBlendFuncIndexedAMD == NULL);
+  glewInfoFunc("glBlendFuncSeparateIndexedAMD", glBlendFuncSeparateIndexedAMD == NULL);
+}
+
+#endif /* GL_AMD_draw_buffers_blend */
+
+#ifdef GL_AMD_performance_monitor
+
+static void _glewInfo_GL_AMD_performance_monitor (void)
+{
+  glewPrintExt("GL_AMD_performance_monitor", GLEW_AMD_performance_monitor, glewIsSupported("GL_AMD_performance_monitor"), glewGetExtension("GL_AMD_performance_monitor"));
+
+  glewInfoFunc("glBeginPerfMonitorAMD", glBeginPerfMonitorAMD == NULL);
+  glewInfoFunc("glDeletePerfMonitorsAMD", glDeletePerfMonitorsAMD == NULL);
+  glewInfoFunc("glEndPerfMonitorAMD", glEndPerfMonitorAMD == NULL);
+  glewInfoFunc("glGenPerfMonitorsAMD", glGenPerfMonitorsAMD == NULL);
+  glewInfoFunc("glGetPerfMonitorCounterDataAMD", glGetPerfMonitorCounterDataAMD == NULL);
+  glewInfoFunc("glGetPerfMonitorCounterInfoAMD", glGetPerfMonitorCounterInfoAMD == NULL);
+  glewInfoFunc("glGetPerfMonitorCounterStringAMD", glGetPerfMonitorCounterStringAMD == NULL);
+  glewInfoFunc("glGetPerfMonitorCountersAMD", glGetPerfMonitorCountersAMD == NULL);
+  glewInfoFunc("glGetPerfMonitorGroupStringAMD", glGetPerfMonitorGroupStringAMD == NULL);
+  glewInfoFunc("glGetPerfMonitorGroupsAMD", glGetPerfMonitorGroupsAMD == NULL);
+  glewInfoFunc("glSelectPerfMonitorCountersAMD", glSelectPerfMonitorCountersAMD == NULL);
+}
+
+#endif /* GL_AMD_performance_monitor */
+
+#ifdef GL_AMD_texture_texture4
+
+static void _glewInfo_GL_AMD_texture_texture4 (void)
+{
+  glewPrintExt("GL_AMD_texture_texture4", GLEW_AMD_texture_texture4, glewIsSupported("GL_AMD_texture_texture4"), glewGetExtension("GL_AMD_texture_texture4"));
+}
+
+#endif /* GL_AMD_texture_texture4 */
+
+#ifdef GL_AMD_vertex_shader_tessellator
+
+static void _glewInfo_GL_AMD_vertex_shader_tessellator (void)
+{
+  glewPrintExt("GL_AMD_vertex_shader_tessellator", GLEW_AMD_vertex_shader_tessellator, glewIsSupported("GL_AMD_vertex_shader_tessellator"), glewGetExtension("GL_AMD_vertex_shader_tessellator"));
+
+  glewInfoFunc("glTessellationFactorAMD", glTessellationFactorAMD == NULL);
+  glewInfoFunc("glTessellationModeAMD", glTessellationModeAMD == NULL);
+}
+
+#endif /* GL_AMD_vertex_shader_tessellator */
+
+#ifdef GL_APPLE_aux_depth_stencil
+
+static void _glewInfo_GL_APPLE_aux_depth_stencil (void)
+{
+  glewPrintExt("GL_APPLE_aux_depth_stencil", GLEW_APPLE_aux_depth_stencil, glewIsSupported("GL_APPLE_aux_depth_stencil"), glewGetExtension("GL_APPLE_aux_depth_stencil"));
+}
+
+#endif /* GL_APPLE_aux_depth_stencil */
+
 #ifdef GL_APPLE_client_storage
 
 static void _glewInfo_GL_APPLE_client_storage (void)
@@ -541,6 +630,19 @@
 
 #endif /* GL_APPLE_flush_buffer_range */
 
+#ifdef GL_APPLE_object_purgeable
+
+static void _glewInfo_GL_APPLE_object_purgeable (void)
+{
+  glewPrintExt("GL_APPLE_object_purgeable", GLEW_APPLE_object_purgeable, glewIsSupported("GL_APPLE_object_purgeable"), glewGetExtension("GL_APPLE_object_purgeable"));
+
+  glewInfoFunc("glGetObjectParameterivAPPLE", glGetObjectParameterivAPPLE == NULL);
+  glewInfoFunc("glObjectPurgeableAPPLE", glObjectPurgeableAPPLE == NULL);
+  glewInfoFunc("glObjectUnpurgeableAPPLE", glObjectUnpurgeableAPPLE == NULL);
+}
+
+#endif /* GL_APPLE_object_purgeable */
+
 #ifdef GL_APPLE_pixel_buffer
 
 static void _glewInfo_GL_APPLE_pixel_buffer (void)
@@ -550,6 +652,24 @@
 
 #endif /* GL_APPLE_pixel_buffer */
 
+#ifdef GL_APPLE_rgb_422
+
+static void _glewInfo_GL_APPLE_rgb_422 (void)
+{
+  glewPrintExt("GL_APPLE_rgb_422", GLEW_APPLE_rgb_422, glewIsSupported("GL_APPLE_rgb_422"), glewGetExtension("GL_APPLE_rgb_422"));
+}
+
+#endif /* GL_APPLE_rgb_422 */
+
+#ifdef GL_APPLE_row_bytes
+
+static void _glewInfo_GL_APPLE_row_bytes (void)
+{
+  glewPrintExt("GL_APPLE_row_bytes", GLEW_APPLE_row_bytes, glewIsSupported("GL_APPLE_row_bytes"), glewGetExtension("GL_APPLE_row_bytes"));
+}
+
+#endif /* GL_APPLE_row_bytes */
+
 #ifdef GL_APPLE_specular_vector
 
 static void _glewInfo_GL_APPLE_specular_vector (void)
@@ -607,6 +727,23 @@
 
 #endif /* GL_APPLE_vertex_array_range */
 
+#ifdef GL_APPLE_vertex_program_evaluators
+
+static void _glewInfo_GL_APPLE_vertex_program_evaluators (void)
+{
+  glewPrintExt("GL_APPLE_vertex_program_evaluators", GLEW_APPLE_vertex_program_evaluators, glewIsSupported("GL_APPLE_vertex_program_evaluators"), glewGetExtension("GL_APPLE_vertex_program_evaluators"));
+
+  glewInfoFunc("glDisableVertexAttribAPPLE", glDisableVertexAttribAPPLE == NULL);
+  glewInfoFunc("glEnableVertexAttribAPPLE", glEnableVertexAttribAPPLE == NULL);
+  glewInfoFunc("glIsVertexAttribEnabledAPPLE", glIsVertexAttribEnabledAPPLE == NULL);
+  glewInfoFunc("glMapVertexAttrib1dAPPLE", glMapVertexAttrib1dAPPLE == NULL);
+  glewInfoFunc("glMapVertexAttrib1fAPPLE", glMapVertexAttrib1fAPPLE == NULL);
+  glewInfoFunc("glMapVertexAttrib2dAPPLE", glMapVertexAttrib2dAPPLE == NULL);
+  glewInfoFunc("glMapVertexAttrib2fAPPLE", glMapVertexAttrib2fAPPLE == NULL);
+}
+
+#endif /* GL_APPLE_vertex_program_evaluators */
+
 #ifdef GL_APPLE_ycbcr_422
 
 static void _glewInfo_GL_APPLE_ycbcr_422 (void)
@@ -627,6 +764,26 @@
 
 #endif /* GL_ARB_color_buffer_float */
 
+#ifdef GL_ARB_compatibility
+
+static void _glewInfo_GL_ARB_compatibility (void)
+{
+  glewPrintExt("GL_ARB_compatibility", GLEW_ARB_compatibility, glewIsSupported("GL_ARB_compatibility"), glewGetExtension("GL_ARB_compatibility"));
+}
+
+#endif /* GL_ARB_compatibility */
+
+#ifdef GL_ARB_copy_buffer
+
+static void _glewInfo_GL_ARB_copy_buffer (void)
+{
+  glewPrintExt("GL_ARB_copy_buffer", GLEW_ARB_copy_buffer, glewIsSupported("GL_ARB_copy_buffer"), glewGetExtension("GL_ARB_copy_buffer"));
+
+  glewInfoFunc("glCopyBufferSubData", glCopyBufferSubData == NULL);
+}
+
+#endif /* GL_ARB_copy_buffer */
+
 #ifdef GL_ARB_depth_buffer_float
 
 static void _glewInfo_GL_ARB_depth_buffer_float (void)
@@ -636,6 +793,15 @@
 
 #endif /* GL_ARB_depth_buffer_float */
 
+#ifdef GL_ARB_depth_clamp
+
+static void _glewInfo_GL_ARB_depth_clamp (void)
+{
+  glewPrintExt("GL_ARB_depth_clamp", GLEW_ARB_depth_clamp, glewIsSupported("GL_ARB_depth_clamp"), glewGetExtension("GL_ARB_depth_clamp"));
+}
+
+#endif /* GL_ARB_depth_clamp */
+
 #ifdef GL_ARB_depth_texture
 
 static void _glewInfo_GL_ARB_depth_texture (void)
@@ -656,6 +822,34 @@
 
 #endif /* GL_ARB_draw_buffers */
 
+#ifdef GL_ARB_draw_buffers_blend
+
+static void _glewInfo_GL_ARB_draw_buffers_blend (void)
+{
+  glewPrintExt("GL_ARB_draw_buffers_blend", GLEW_ARB_draw_buffers_blend, glewIsSupported("GL_ARB_draw_buffers_blend"), glewGetExtension("GL_ARB_draw_buffers_blend"));
+
+  glewInfoFunc("glBlendEquationSeparateiARB", glBlendEquationSeparateiARB == NULL);
+  glewInfoFunc("glBlendEquationiARB", glBlendEquationiARB == NULL);
+  glewInfoFunc("glBlendFuncSeparateiARB", glBlendFuncSeparateiARB == NULL);
+  glewInfoFunc("glBlendFunciARB", glBlendFunciARB == NULL);
+}
+
+#endif /* GL_ARB_draw_buffers_blend */
+
+#ifdef GL_ARB_draw_elements_base_vertex
+
+static void _glewInfo_GL_ARB_draw_elements_base_vertex (void)
+{
+  glewPrintExt("GL_ARB_draw_elements_base_vertex", GLEW_ARB_draw_elements_base_vertex, glewIsSupported("GL_ARB_draw_elements_base_vertex"), glewGetExtension("GL_ARB_draw_elements_base_vertex"));
+
+  glewInfoFunc("glDrawElementsBaseVertex", glDrawElementsBaseVertex == NULL);
+  glewInfoFunc("glDrawElementsInstancedBaseVertex", glDrawElementsInstancedBaseVertex == NULL);
+  glewInfoFunc("glDrawRangeElementsBaseVertex", glDrawRangeElementsBaseVertex == NULL);
+  glewInfoFunc("glMultiDrawElementsBaseVertex", glMultiDrawElementsBaseVertex == NULL);
+}
+
+#endif /* GL_ARB_draw_elements_base_vertex */
+
 #ifdef GL_ARB_draw_instanced
 
 static void _glewInfo_GL_ARB_draw_instanced (void)
@@ -668,6 +862,15 @@
 
 #endif /* GL_ARB_draw_instanced */
 
+#ifdef GL_ARB_fragment_coord_conventions
+
+static void _glewInfo_GL_ARB_fragment_coord_conventions (void)
+{
+  glewPrintExt("GL_ARB_fragment_coord_conventions", GLEW_ARB_fragment_coord_conventions, glewIsSupported("GL_ARB_fragment_coord_conventions"), glewGetExtension("GL_ARB_fragment_coord_conventions"));
+}
+
+#endif /* GL_ARB_fragment_coord_conventions */
+
 #ifdef GL_ARB_fragment_program
 
 static void _glewInfo_GL_ARB_fragment_program (void)
@@ -708,10 +911,10 @@
   glewInfoFunc("glDeleteFramebuffers", glDeleteFramebuffers == NULL);
   glewInfoFunc("glDeleteRenderbuffers", glDeleteRenderbuffers == NULL);
   glewInfoFunc("glFramebufferRenderbuffer", glFramebufferRenderbuffer == NULL);
-  glewInfoFunc("glFramebufferTextureLayer", glFramebufferTextureLayer == NULL);
   glewInfoFunc("glFramebufferTexture1D", glFramebufferTexture1D == NULL);
   glewInfoFunc("glFramebufferTexture2D", glFramebufferTexture2D == NULL);
   glewInfoFunc("glFramebufferTexture3D", glFramebufferTexture3D == NULL);
+  glewInfoFunc("glFramebufferTextureLayer", glFramebufferTextureLayer == NULL);
   glewInfoFunc("glGenFramebuffers", glGenFramebuffers == NULL);
   glewInfoFunc("glGenRenderbuffers", glGenRenderbuffers == NULL);
   glewInfoFunc("glGenerateMipmap", glGenerateMipmap == NULL);
@@ -950,6 +1153,37 @@
 
 #endif /* GL_ARB_point_sprite */
 
+#ifdef GL_ARB_provoking_vertex
+
+static void _glewInfo_GL_ARB_provoking_vertex (void)
+{
+  glewPrintExt("GL_ARB_provoking_vertex", GLEW_ARB_provoking_vertex, glewIsSupported("GL_ARB_provoking_vertex"), glewGetExtension("GL_ARB_provoking_vertex"));
+
+  glewInfoFunc("glProvokingVertex", glProvokingVertex == NULL);
+}
+
+#endif /* GL_ARB_provoking_vertex */
+
+#ifdef GL_ARB_sample_shading
+
+static void _glewInfo_GL_ARB_sample_shading (void)
+{
+  glewPrintExt("GL_ARB_sample_shading", GLEW_ARB_sample_shading, glewIsSupported("GL_ARB_sample_shading"), glewGetExtension("GL_ARB_sample_shading"));
+
+  glewInfoFunc("glMinSampleShadingARB", glMinSampleShadingARB == NULL);
+}
+
+#endif /* GL_ARB_sample_shading */
+
+#ifdef GL_ARB_seamless_cube_map
+
+static void _glewInfo_GL_ARB_seamless_cube_map (void)
+{
+  glewPrintExt("GL_ARB_seamless_cube_map", GLEW_ARB_seamless_cube_map, glewIsSupported("GL_ARB_seamless_cube_map"), glewGetExtension("GL_ARB_seamless_cube_map"));
+}
+
+#endif /* GL_ARB_seamless_cube_map */
+
 #ifdef GL_ARB_shader_objects
 
 static void _glewInfo_GL_ARB_shader_objects (void)
@@ -999,6 +1233,15 @@
 
 #endif /* GL_ARB_shader_objects */
 
+#ifdef GL_ARB_shader_texture_lod
+
+static void _glewInfo_GL_ARB_shader_texture_lod (void)
+{
+  glewPrintExt("GL_ARB_shader_texture_lod", GLEW_ARB_shader_texture_lod, glewIsSupported("GL_ARB_shader_texture_lod"), glewGetExtension("GL_ARB_shader_texture_lod"));
+}
+
+#endif /* GL_ARB_shader_texture_lod */
+
 #ifdef GL_ARB_shading_language_100
 
 static void _glewInfo_GL_ARB_shading_language_100 (void)
@@ -1026,6 +1269,23 @@
 
 #endif /* GL_ARB_shadow_ambient */
 
+#ifdef GL_ARB_sync
+
+static void _glewInfo_GL_ARB_sync (void)
+{
+  glewPrintExt("GL_ARB_sync", GLEW_ARB_sync, glewIsSupported("GL_ARB_sync"), glewGetExtension("GL_ARB_sync"));
+
+  glewInfoFunc("glClientWaitSync", glClientWaitSync == NULL);
+  glewInfoFunc("glDeleteSync", glDeleteSync == NULL);
+  glewInfoFunc("glFenceSync", glFenceSync == NULL);
+  glewInfoFunc("glGetInteger64v", glGetInteger64v == NULL);
+  glewInfoFunc("glGetSynciv", glGetSynciv == NULL);
+  glewInfoFunc("glIsSync", glIsSync == NULL);
+  glewInfoFunc("glWaitSync", glWaitSync == NULL);
+}
+
+#endif /* GL_ARB_sync */
+
 #ifdef GL_ARB_texture_border_clamp
 
 static void _glewInfo_GL_ARB_texture_border_clamp (void)
@@ -1081,6 +1341,15 @@
 
 #endif /* GL_ARB_texture_cube_map */
 
+#ifdef GL_ARB_texture_cube_map_array
+
+static void _glewInfo_GL_ARB_texture_cube_map_array (void)
+{
+  glewPrintExt("GL_ARB_texture_cube_map_array", GLEW_ARB_texture_cube_map_array, glewIsSupported("GL_ARB_texture_cube_map_array"), glewGetExtension("GL_ARB_texture_cube_map_array"));
+}
+
+#endif /* GL_ARB_texture_cube_map_array */
+
 #ifdef GL_ARB_texture_env_add
 
 static void _glewInfo_GL_ARB_texture_env_add (void)
@@ -1126,6 +1395,15 @@
 
 #endif /* GL_ARB_texture_float */
 
+#ifdef GL_ARB_texture_gather
+
+static void _glewInfo_GL_ARB_texture_gather (void)
+{
+  glewPrintExt("GL_ARB_texture_gather", GLEW_ARB_texture_gather, glewIsSupported("GL_ARB_texture_gather"), glewGetExtension("GL_ARB_texture_gather"));
+}
+
+#endif /* GL_ARB_texture_gather */
+
 #ifdef GL_ARB_texture_mirrored_repeat
 
 static void _glewInfo_GL_ARB_texture_mirrored_repeat (void)
@@ -1135,6 +1413,20 @@
 
 #endif /* GL_ARB_texture_mirrored_repeat */
 
+#ifdef GL_ARB_texture_multisample
+
+static void _glewInfo_GL_ARB_texture_multisample (void)
+{
+  glewPrintExt("GL_ARB_texture_multisample", GLEW_ARB_texture_multisample, glewIsSupported("GL_ARB_texture_multisample"), glewGetExtension("GL_ARB_texture_multisample"));
+
+  glewInfoFunc("glGetMultisamplefv", glGetMultisamplefv == NULL);
+  glewInfoFunc("glSampleMaski", glSampleMaski == NULL);
+  glewInfoFunc("glTexImage2DMultisample", glTexImage2DMultisample == NULL);
+  glewInfoFunc("glTexImage3DMultisample", glTexImage3DMultisample == NULL);
+}
+
+#endif /* GL_ARB_texture_multisample */
+
 #ifdef GL_ARB_texture_non_power_of_two
 
 static void _glewInfo_GL_ARB_texture_non_power_of_two (void)
@@ -1144,6 +1436,15 @@
 
 #endif /* GL_ARB_texture_non_power_of_two */
 
+#ifdef GL_ARB_texture_query_lod
+
+static void _glewInfo_GL_ARB_texture_query_lod (void)
+{
+  glewPrintExt("GL_ARB_texture_query_lod", GLEW_ARB_texture_query_lod, glewIsSupported("GL_ARB_texture_query_lod"), glewGetExtension("GL_ARB_texture_query_lod"));
+}
+
+#endif /* GL_ARB_texture_query_lod */
+
 #ifdef GL_ARB_texture_rectangle
 
 static void _glewInfo_GL_ARB_texture_rectangle (void)
@@ -1176,6 +1477,35 @@
 
 #endif /* GL_ARB_transpose_matrix */
 
+#ifdef GL_ARB_uniform_buffer_object
+
+static void _glewInfo_GL_ARB_uniform_buffer_object (void)
+{
+  glewPrintExt("GL_ARB_uniform_buffer_object", GLEW_ARB_uniform_buffer_object, glewIsSupported("GL_ARB_uniform_buffer_object"), glewGetExtension("GL_ARB_uniform_buffer_object"));
+
+  glewInfoFunc("glBindBufferBase", glBindBufferBase == NULL);
+  glewInfoFunc("glBindBufferRange", glBindBufferRange == NULL);
+  glewInfoFunc("glGetActiveUniformBlockName", glGetActiveUniformBlockName == NULL);
+  glewInfoFunc("glGetActiveUniformBlockiv", glGetActiveUniformBlockiv == NULL);
+  glewInfoFunc("glGetActiveUniformName", glGetActiveUniformName == NULL);
+  glewInfoFunc("glGetActiveUniformsiv", glGetActiveUniformsiv == NULL);
+  glewInfoFunc("glGetIntegeri_v", glGetIntegeri_v == NULL);
+  glewInfoFunc("glGetUniformBlockIndex", glGetUniformBlockIndex == NULL);
+  glewInfoFunc("glGetUniformIndices", glGetUniformIndices == NULL);
+  glewInfoFunc("glUniformBlockBinding", glUniformBlockBinding == NULL);
+}
+
+#endif /* GL_ARB_uniform_buffer_object */
+
+#ifdef GL_ARB_vertex_array_bgra
+
+static void _glewInfo_GL_ARB_vertex_array_bgra (void)
+{
+  glewPrintExt("GL_ARB_vertex_array_bgra", GLEW_ARB_vertex_array_bgra, glewIsSupported("GL_ARB_vertex_array_bgra"), glewGetExtension("GL_ARB_vertex_array_bgra"));
+}
+
+#endif /* GL_ARB_vertex_array_bgra */
+
 #ifdef GL_ARB_vertex_array_object
 
 static void _glewInfo_GL_ARB_vertex_array_object (void)
@@ -1452,6 +1782,15 @@
 
 #endif /* GL_ATI_map_object_buffer */
 
+#ifdef GL_ATI_meminfo
+
+static void _glewInfo_GL_ATI_meminfo (void)
+{
+  glewPrintExt("GL_ATI_meminfo", GLEW_ATI_meminfo, glewIsSupported("GL_ATI_meminfo"), glewGetExtension("GL_ATI_meminfo"));
+}
+
+#endif /* GL_ATI_meminfo */
+
 #ifdef GL_ATI_pn_triangles
 
 static void _glewInfo_GL_ATI_pn_triangles (void)
@@ -1870,7 +2209,14 @@
   glewInfoFunc("glCopyTextureSubImage2DEXT", glCopyTextureSubImage2DEXT == NULL);
   glewInfoFunc("glCopyTextureSubImage3DEXT", glCopyTextureSubImage3DEXT == NULL);
   glewInfoFunc("glDisableClientStateIndexedEXT", glDisableClientStateIndexedEXT == NULL);
+  glewInfoFunc("glDisableClientStateiEXT", glDisableClientStateiEXT == NULL);
+  glewInfoFunc("glDisableVertexArrayAttribEXT", glDisableVertexArrayAttribEXT == NULL);
+  glewInfoFunc("glDisableVertexArrayEXT", glDisableVertexArrayEXT == NULL);
   glewInfoFunc("glEnableClientStateIndexedEXT", glEnableClientStateIndexedEXT == NULL);
+  glewInfoFunc("glEnableClientStateiEXT", glEnableClientStateiEXT == NULL);
+  glewInfoFunc("glEnableVertexArrayAttribEXT", glEnableVertexArrayAttribEXT == NULL);
+  glewInfoFunc("glEnableVertexArrayEXT", glEnableVertexArrayEXT == NULL);
+  glewInfoFunc("glFlushMappedNamedBufferRangeEXT", glFlushMappedNamedBufferRangeEXT == NULL);
   glewInfoFunc("glFramebufferDrawBufferEXT", glFramebufferDrawBufferEXT == NULL);
   glewInfoFunc("glFramebufferDrawBuffersEXT", glFramebufferDrawBuffersEXT == NULL);
   glewInfoFunc("glFramebufferReadBufferEXT", glFramebufferReadBufferEXT == NULL);
@@ -1879,7 +2225,9 @@
   glewInfoFunc("glGetCompressedMultiTexImageEXT", glGetCompressedMultiTexImageEXT == NULL);
   glewInfoFunc("glGetCompressedTextureImageEXT", glGetCompressedTextureImageEXT == NULL);
   glewInfoFunc("glGetDoubleIndexedvEXT", glGetDoubleIndexedvEXT == NULL);
+  glewInfoFunc("glGetDoublei_vEXT", glGetDoublei_vEXT == NULL);
   glewInfoFunc("glGetFloatIndexedvEXT", glGetFloatIndexedvEXT == NULL);
+  glewInfoFunc("glGetFloati_vEXT", glGetFloati_vEXT == NULL);
   glewInfoFunc("glGetFramebufferParameterivEXT", glGetFramebufferParameterivEXT == NULL);
   glewInfoFunc("glGetMultiTexEnvfvEXT", glGetMultiTexEnvfvEXT == NULL);
   glewInfoFunc("glGetMultiTexEnvivEXT", glGetMultiTexEnvivEXT == NULL);
@@ -1905,6 +2253,7 @@
   glewInfoFunc("glGetNamedProgramivEXT", glGetNamedProgramivEXT == NULL);
   glewInfoFunc("glGetNamedRenderbufferParameterivEXT", glGetNamedRenderbufferParameterivEXT == NULL);
   glewInfoFunc("glGetPointerIndexedvEXT", glGetPointerIndexedvEXT == NULL);
+  glewInfoFunc("glGetPointeri_vEXT", glGetPointeri_vEXT == NULL);
   glewInfoFunc("glGetTextureImageEXT", glGetTextureImageEXT == NULL);
   glewInfoFunc("glGetTextureLevelParameterfvEXT", glGetTextureLevelParameterfvEXT == NULL);
   glewInfoFunc("glGetTextureLevelParameterivEXT", glGetTextureLevelParameterivEXT == NULL);
@@ -1912,7 +2261,12 @@
   glewInfoFunc("glGetTextureParameterIuivEXT", glGetTextureParameterIuivEXT == NULL);
   glewInfoFunc("glGetTextureParameterfvEXT", glGetTextureParameterfvEXT == NULL);
   glewInfoFunc("glGetTextureParameterivEXT", glGetTextureParameterivEXT == NULL);
+  glewInfoFunc("glGetVertexArrayIntegeri_vEXT", glGetVertexArrayIntegeri_vEXT == NULL);
+  glewInfoFunc("glGetVertexArrayIntegervEXT", glGetVertexArrayIntegervEXT == NULL);
+  glewInfoFunc("glGetVertexArrayPointeri_vEXT", glGetVertexArrayPointeri_vEXT == NULL);
+  glewInfoFunc("glGetVertexArrayPointervEXT", glGetVertexArrayPointervEXT == NULL);
   glewInfoFunc("glMapNamedBufferEXT", glMapNamedBufferEXT == NULL);
+  glewInfoFunc("glMapNamedBufferRangeEXT", glMapNamedBufferRangeEXT == NULL);
   glewInfoFunc("glMatrixFrustumEXT", glMatrixFrustumEXT == NULL);
   glewInfoFunc("glMatrixLoadIdentityEXT", glMatrixLoadIdentityEXT == NULL);
   glewInfoFunc("glMatrixLoadTransposedEXT", glMatrixLoadTransposedEXT == NULL);
@@ -1959,6 +2313,7 @@
   glewInfoFunc("glMultiTexSubImage3DEXT", glMultiTexSubImage3DEXT == NULL);
   glewInfoFunc("glNamedBufferDataEXT", glNamedBufferDataEXT == NULL);
   glewInfoFunc("glNamedBufferSubDataEXT", glNamedBufferSubDataEXT == NULL);
+  glewInfoFunc("glNamedCopyBufferSubDataEXT", glNamedCopyBufferSubDataEXT == NULL);
   glewInfoFunc("glNamedFramebufferRenderbufferEXT", glNamedFramebufferRenderbufferEXT == NULL);
   glewInfoFunc("glNamedFramebufferTexture1DEXT", glNamedFramebufferTexture1DEXT == NULL);
   glewInfoFunc("glNamedFramebufferTexture2DEXT", glNamedFramebufferTexture2DEXT == NULL);
@@ -2030,6 +2385,17 @@
   glewInfoFunc("glTextureSubImage2DEXT", glTextureSubImage2DEXT == NULL);
   glewInfoFunc("glTextureSubImage3DEXT", glTextureSubImage3DEXT == NULL);
   glewInfoFunc("glUnmapNamedBufferEXT", glUnmapNamedBufferEXT == NULL);
+  glewInfoFunc("glVertexArrayColorOffsetEXT", glVertexArrayColorOffsetEXT == NULL);
+  glewInfoFunc("glVertexArrayEdgeFlagOffsetEXT", glVertexArrayEdgeFlagOffsetEXT == NULL);
+  glewInfoFunc("glVertexArrayFogCoordOffsetEXT", glVertexArrayFogCoordOffsetEXT == NULL);
+  glewInfoFunc("glVertexArrayIndexOffsetEXT", glVertexArrayIndexOffsetEXT == NULL);
+  glewInfoFunc("glVertexArrayMultiTexCoordOffsetEXT", glVertexArrayMultiTexCoordOffsetEXT == NULL);
+  glewInfoFunc("glVertexArrayNormalOffsetEXT", glVertexArrayNormalOffsetEXT == NULL);
+  glewInfoFunc("glVertexArraySecondaryColorOffsetEXT", glVertexArraySecondaryColorOffsetEXT == NULL);
+  glewInfoFunc("glVertexArrayTexCoordOffsetEXT", glVertexArrayTexCoordOffsetEXT == NULL);
+  glewInfoFunc("glVertexArrayVertexAttribIOffsetEXT", glVertexArrayVertexAttribIOffsetEXT == NULL);
+  glewInfoFunc("glVertexArrayVertexAttribOffsetEXT", glVertexArrayVertexAttribOffsetEXT == NULL);
+  glewInfoFunc("glVertexArrayVertexOffsetEXT", glVertexArrayVertexOffsetEXT == NULL);
 }
 
 #endif /* GL_EXT_direct_state_access */
@@ -2448,6 +2814,17 @@
 
 #endif /* GL_EXT_polygon_offset */
 
+#ifdef GL_EXT_provoking_vertex
+
+static void _glewInfo_GL_EXT_provoking_vertex (void)
+{
+  glewPrintExt("GL_EXT_provoking_vertex", GLEW_EXT_provoking_vertex, glewIsSupported("GL_EXT_provoking_vertex"), glewGetExtension("GL_EXT_provoking_vertex"));
+
+  glewInfoFunc("glProvokingVertexEXT", glProvokingVertexEXT == NULL);
+}
+
+#endif /* GL_EXT_provoking_vertex */
+
 #ifdef GL_EXT_rescale_normal
 
 static void _glewInfo_GL_EXT_rescale_normal (void)
@@ -2496,6 +2873,19 @@
 
 #endif /* GL_EXT_secondary_color */
 
+#ifdef GL_EXT_separate_shader_objects
+
+static void _glewInfo_GL_EXT_separate_shader_objects (void)
+{
+  glewPrintExt("GL_EXT_separate_shader_objects", GLEW_EXT_separate_shader_objects, glewIsSupported("GL_EXT_separate_shader_objects"), glewGetExtension("GL_EXT_separate_shader_objects"));
+
+  glewInfoFunc("glActiveProgramEXT", glActiveProgramEXT == NULL);
+  glewInfoFunc("glCreateShaderProgramEXT", glCreateShaderProgramEXT == NULL);
+  glewInfoFunc("glUseShaderProgramEXT", glUseShaderProgramEXT == NULL);
+}
+
+#endif /* GL_EXT_separate_shader_objects */
+
 #ifdef GL_EXT_separate_specular_color
 
 static void _glewInfo_GL_EXT_separate_specular_color (void)
@@ -2792,6 +3182,15 @@
 
 #endif /* GL_EXT_texture_shared_exponent */
 
+#ifdef GL_EXT_texture_snorm
+
+static void _glewInfo_GL_EXT_texture_snorm (void)
+{
+  glewPrintExt("GL_EXT_texture_snorm", GLEW_EXT_texture_snorm, glewIsSupported("GL_EXT_texture_snorm"), glewGetExtension("GL_EXT_texture_snorm"));
+}
+
+#endif /* GL_EXT_texture_snorm */
+
 #ifdef GL_EXT_texture_swizzle
 
 static void _glewInfo_GL_EXT_texture_swizzle (void)
@@ -3215,6 +3614,17 @@
 
 #endif /* GL_NV_copy_depth_to_color */
 
+#ifdef GL_NV_copy_image
+
+static void _glewInfo_GL_NV_copy_image (void)
+{
+  glewPrintExt("GL_NV_copy_image", GLEW_NV_copy_image, glewIsSupported("GL_NV_copy_image"), glewGetExtension("GL_NV_copy_image"));
+
+  glewInfoFunc("glCopyImageSubDataNV", glCopyImageSubDataNV == NULL);
+}
+
+#endif /* GL_NV_copy_image */
+
 #ifdef GL_NV_depth_buffer_float
 
 static void _glewInfo_GL_NV_depth_buffer_float (void)
@@ -3522,6 +3932,15 @@
 
 #endif /* GL_NV_parameter_buffer_object */
 
+#ifdef GL_NV_parameter_buffer_object2
+
+static void _glewInfo_GL_NV_parameter_buffer_object2 (void)
+{
+  glewPrintExt("GL_NV_parameter_buffer_object2", GLEW_NV_parameter_buffer_object2, glewIsSupported("GL_NV_parameter_buffer_object2"), glewGetExtension("GL_NV_parameter_buffer_object2"));
+}
+
+#endif /* GL_NV_parameter_buffer_object2 */
+
 #ifdef GL_NV_pixel_data_range
 
 static void _glewInfo_GL_NV_pixel_data_range (void)
@@ -3558,7 +3977,6 @@
   glewInfoFunc("glGetVideouivNV", glGetVideouivNV == NULL);
   glewInfoFunc("glPresentFrameDualFillNV", glPresentFrameDualFillNV == NULL);
   glewInfoFunc("glPresentFrameKeyedNV", glPresentFrameKeyedNV == NULL);
-  glewInfoFunc("glVideoParameterivNV", glVideoParameterivNV == NULL);
 }
 
 #endif /* GL_NV_present_video */
@@ -3610,6 +4028,30 @@
 
 #endif /* GL_NV_register_combiners2 */
 
+#ifdef GL_NV_shader_buffer_load
+
+static void _glewInfo_GL_NV_shader_buffer_load (void)
+{
+  glewPrintExt("GL_NV_shader_buffer_load", GLEW_NV_shader_buffer_load, glewIsSupported("GL_NV_shader_buffer_load"), glewGetExtension("GL_NV_shader_buffer_load"));
+
+  glewInfoFunc("glGetBufferParameterui64vNV", glGetBufferParameterui64vNV == NULL);
+  glewInfoFunc("glGetIntegerui64vNV", glGetIntegerui64vNV == NULL);
+  glewInfoFunc("glGetNamedBufferParameterui64vNV", glGetNamedBufferParameterui64vNV == NULL);
+  glewInfoFunc("glGetUniformui64vNV", glGetUniformui64vNV == NULL);
+  glewInfoFunc("glIsBufferResidentNV", glIsBufferResidentNV == NULL);
+  glewInfoFunc("glIsNamedBufferResidentNV", glIsNamedBufferResidentNV == NULL);
+  glewInfoFunc("glMakeBufferNonResidentNV", glMakeBufferNonResidentNV == NULL);
+  glewInfoFunc("glMakeBufferResidentNV", glMakeBufferResidentNV == NULL);
+  glewInfoFunc("glMakeNamedBufferNonResidentNV", glMakeNamedBufferNonResidentNV == NULL);
+  glewInfoFunc("glMakeNamedBufferResidentNV", glMakeNamedBufferResidentNV == NULL);
+  glewInfoFunc("glProgramUniformui64NV", glProgramUniformui64NV == NULL);
+  glewInfoFunc("glProgramUniformui64vNV", glProgramUniformui64vNV == NULL);
+  glewInfoFunc("glUniformui64NV", glUniformui64NV == NULL);
+  glewInfoFunc("glUniformui64vNV", glUniformui64vNV == NULL);
+}
+
+#endif /* GL_NV_shader_buffer_load */
+
 #ifdef GL_NV_texgen_emboss
 
 static void _glewInfo_GL_NV_texgen_emboss (void)
@@ -3628,6 +4070,17 @@
 
 #endif /* GL_NV_texgen_reflection */
 
+#ifdef GL_NV_texture_barrier
+
+static void _glewInfo_GL_NV_texture_barrier (void)
+{
+  glewPrintExt("GL_NV_texture_barrier", GLEW_NV_texture_barrier, glewIsSupported("GL_NV_texture_barrier"), glewGetExtension("GL_NV_texture_barrier"));
+
+  glewInfoFunc("glTextureBarrierNV", glTextureBarrierNV == NULL);
+}
+
+#endif /* GL_NV_texture_barrier */
+
 #ifdef GL_NV_texture_compression_vtc
 
 static void _glewInfo_GL_NV_texture_compression_vtc (void)
@@ -3712,6 +4165,23 @@
 
 #endif /* GL_NV_transform_feedback */
 
+#ifdef GL_NV_transform_feedback2
+
+static void _glewInfo_GL_NV_transform_feedback2 (void)
+{
+  glewPrintExt("GL_NV_transform_feedback2", GLEW_NV_transform_feedback2, glewIsSupported("GL_NV_transform_feedback2"), glewGetExtension("GL_NV_transform_feedback2"));
+
+  glewInfoFunc("glBindTransformFeedbackNV", glBindTransformFeedbackNV == NULL);
+  glewInfoFunc("glDeleteTransformFeedbacksNV", glDeleteTransformFeedbacksNV == NULL);
+  glewInfoFunc("glDrawTransformFeedbackNV", glDrawTransformFeedbackNV == NULL);
+  glewInfoFunc("glGenTransformFeedbacksNV", glGenTransformFeedbacksNV == NULL);
+  glewInfoFunc("glIsTransformFeedbackNV", glIsTransformFeedbackNV == NULL);
+  glewInfoFunc("glPauseTransformFeedbackNV", glPauseTransformFeedbackNV == NULL);
+  glewInfoFunc("glResumeTransformFeedbackNV", glResumeTransformFeedbackNV == NULL);
+}
+
+#endif /* GL_NV_transform_feedback2 */
+
 #ifdef GL_NV_vertex_array_range
 
 static void _glewInfo_GL_NV_vertex_array_range (void)
@@ -3733,6 +4203,28 @@
 
 #endif /* GL_NV_vertex_array_range2 */
 
+#ifdef GL_NV_vertex_buffer_unified_memory
+
+static void _glewInfo_GL_NV_vertex_buffer_unified_memory (void)
+{
+  glewPrintExt("GL_NV_vertex_buffer_unified_memory", GLEW_NV_vertex_buffer_unified_memory, glewIsSupported("GL_NV_vertex_buffer_unified_memory"), glewGetExtension("GL_NV_vertex_buffer_unified_memory"));
+
+  glewInfoFunc("glBufferAddressRangeNV", glBufferAddressRangeNV == NULL);
+  glewInfoFunc("glColorFormatNV", glColorFormatNV == NULL);
+  glewInfoFunc("glEdgeFlagFormatNV", glEdgeFlagFormatNV == NULL);
+  glewInfoFunc("glFogCoordFormatNV", glFogCoordFormatNV == NULL);
+  glewInfoFunc("glGetIntegerui64i_vNV", glGetIntegerui64i_vNV == NULL);
+  glewInfoFunc("glIndexFormatNV", glIndexFormatNV == NULL);
+  glewInfoFunc("glNormalFormatNV", glNormalFormatNV == NULL);
+  glewInfoFunc("glSecondaryColorFormatNV", glSecondaryColorFormatNV == NULL);
+  glewInfoFunc("glTexCoordFormatNV", glTexCoordFormatNV == NULL);
+  glewInfoFunc("glVertexAttribFormatNV", glVertexAttribFormatNV == NULL);
+  glewInfoFunc("glVertexAttribIFormatNV", glVertexAttribIFormatNV == NULL);
+  glewInfoFunc("glVertexFormatNV", glVertexFormatNV == NULL);
+}
+
+#endif /* GL_NV_vertex_buffer_unified_memory */
+
 #ifdef GL_NV_vertex_program
 
 static void _glewInfo_GL_NV_vertex_program (void)
@@ -4652,6 +5144,25 @@
 
 #endif /* WGL_3DL_stereo_control */
 
+#ifdef WGL_AMD_gpu_association
+
+static void _glewInfo_WGL_AMD_gpu_association (void)
+{
+  glewPrintExt("WGL_AMD_gpu_association", WGLEW_AMD_gpu_association, wglewIsSupported("WGL_AMD_gpu_association"), wglewGetExtension("WGL_AMD_gpu_association"));
+
+  glewInfoFunc("wglBlitContextFramebufferAMD", wglBlitContextFramebufferAMD == NULL);
+  glewInfoFunc("wglCreateAssociatedContextAMD", wglCreateAssociatedContextAMD == NULL);
+  glewInfoFunc("wglCreateAssociatedContextAttribsAMD", wglCreateAssociatedContextAttribsAMD == NULL);
+  glewInfoFunc("wglDeleteAssociatedContextAMD", wglDeleteAssociatedContextAMD == NULL);
+  glewInfoFunc("wglGetContextGPUIDAMD", wglGetContextGPUIDAMD == NULL);
+  glewInfoFunc("wglGetCurrentAssociatedContextAMD", wglGetCurrentAssociatedContextAMD == NULL);
+  glewInfoFunc("wglGetGPUIDsAMD", wglGetGPUIDsAMD == NULL);
+  glewInfoFunc("wglGetGPUInfoAMD", wglGetGPUInfoAMD == NULL);
+  glewInfoFunc("wglMakeAssociatedContextCurrentAMD", wglMakeAssociatedContextCurrentAMD == NULL);
+}
+
+#endif /* WGL_AMD_gpu_association */
+
 #ifdef WGL_ARB_buffer_region
 
 static void _glewInfo_WGL_ARB_buffer_region (void)
@@ -4677,6 +5188,15 @@
 
 #endif /* WGL_ARB_create_context */
 
+#ifdef WGL_ARB_create_context_profile
+
+static void _glewInfo_WGL_ARB_create_context_profile (void)
+{
+  glewPrintExt("WGL_ARB_create_context_profile", WGLEW_ARB_create_context_profile, wglewIsSupported("WGL_ARB_create_context_profile"), wglewGetExtension("WGL_ARB_create_context_profile"));
+}
+
+#endif /* WGL_ARB_create_context_profile */
+
 #ifdef WGL_ARB_extensions_string
 
 static void _glewInfo_WGL_ARB_extensions_string (void)
@@ -4989,6 +5509,17 @@
 
 #endif /* WGL_I3D_swap_frame_usage */
 
+#ifdef WGL_NV_copy_image
+
+static void _glewInfo_WGL_NV_copy_image (void)
+{
+  glewPrintExt("WGL_NV_copy_image", WGLEW_NV_copy_image, wglewIsSupported("WGL_NV_copy_image"), wglewGetExtension("WGL_NV_copy_image"));
+
+  glewInfoFunc("wglCopyImageSubDataNV", wglCopyImageSubDataNV == NULL);
+}
+
+#endif /* WGL_NV_copy_image */
+
 #ifdef WGL_NV_float_buffer
 
 static void _glewInfo_WGL_NV_float_buffer (void)
@@ -5173,6 +5704,15 @@
 
 #endif /* GLX_ARB_create_context */
 
+#ifdef GLX_ARB_create_context_profile
+
+static void _glewInfo_GLX_ARB_create_context_profile (void)
+{
+  glewPrintExt("GLX_ARB_create_context_profile", GLXEW_ARB_create_context_profile, glxewIsSupported("GLX_ARB_create_context_profile"), glxewGetExtension("GLX_ARB_create_context_profile"));
+}
+
+#endif /* GLX_ARB_create_context_profile */
+
 #ifdef GLX_ARB_fbconfig_float
 
 static void _glewInfo_GLX_ARB_fbconfig_float (void)
@@ -5272,6 +5812,17 @@
 
 #endif /* GLX_EXT_scene_marker */
 
+#ifdef GLX_EXT_swap_control
+
+static void _glewInfo_GLX_EXT_swap_control (void)
+{
+  glewPrintExt("GLX_EXT_swap_control", GLXEW_EXT_swap_control, glxewIsSupported("GLX_EXT_swap_control"), glxewGetExtension("GLX_EXT_swap_control"));
+
+  glewInfoFunc("glXSwapIntervalEXT", glXSwapIntervalEXT == NULL);
+}
+
+#endif /* GLX_EXT_swap_control */
+
 #ifdef GLX_EXT_texture_from_pixmap
 
 static void _glewInfo_GLX_EXT_texture_from_pixmap (void)
@@ -5357,6 +5908,17 @@
 
 #endif /* GLX_MESA_set_3dfx_mode */
 
+#ifdef GLX_NV_copy_image
+
+static void _glewInfo_GLX_NV_copy_image (void)
+{
+  glewPrintExt("GLX_NV_copy_image", GLXEW_NV_copy_image, glxewIsSupported("GLX_NV_copy_image"), glxewGetExtension("GLX_NV_copy_image"));
+
+  glewInfoFunc("glXCopyImageSubDataNV", glXCopyImageSubDataNV == NULL);
+}
+
+#endif /* GLX_NV_copy_image */
+
 #ifdef GLX_NV_float_buffer
 
 static void _glewInfo_GLX_NV_float_buffer (void)
@@ -5678,6 +6240,12 @@
 #ifdef GL_VERSION_3_0
   _glewInfo_GL_VERSION_3_0();
 #endif /* GL_VERSION_3_0 */
+#ifdef GL_VERSION_3_1
+  _glewInfo_GL_VERSION_3_1();
+#endif /* GL_VERSION_3_1 */
+#ifdef GL_VERSION_3_2
+  _glewInfo_GL_VERSION_3_2();
+#endif /* GL_VERSION_3_2 */
 #ifdef GL_3DFX_multisample
   _glewInfo_GL_3DFX_multisample();
 #endif /* GL_3DFX_multisample */
@@ -5687,6 +6255,21 @@
 #ifdef GL_3DFX_texture_compression_FXT1
   _glewInfo_GL_3DFX_texture_compression_FXT1();
 #endif /* GL_3DFX_texture_compression_FXT1 */
+#ifdef GL_AMD_draw_buffers_blend
+  _glewInfo_GL_AMD_draw_buffers_blend();
+#endif /* GL_AMD_draw_buffers_blend */
+#ifdef GL_AMD_performance_monitor
+  _glewInfo_GL_AMD_performance_monitor();
+#endif /* GL_AMD_performance_monitor */
+#ifdef GL_AMD_texture_texture4
+  _glewInfo_GL_AMD_texture_texture4();
+#endif /* GL_AMD_texture_texture4 */
+#ifdef GL_AMD_vertex_shader_tessellator
+  _glewInfo_GL_AMD_vertex_shader_tessellator();
+#endif /* GL_AMD_vertex_shader_tessellator */
+#ifdef GL_APPLE_aux_depth_stencil
+  _glewInfo_GL_APPLE_aux_depth_stencil();
+#endif /* GL_APPLE_aux_depth_stencil */
 #ifdef GL_APPLE_client_storage
   _glewInfo_GL_APPLE_client_storage();
 #endif /* GL_APPLE_client_storage */
@@ -5702,9 +6285,18 @@
 #ifdef GL_APPLE_flush_buffer_range
   _glewInfo_GL_APPLE_flush_buffer_range();
 #endif /* GL_APPLE_flush_buffer_range */
+#ifdef GL_APPLE_object_purgeable
+  _glewInfo_GL_APPLE_object_purgeable();
+#endif /* GL_APPLE_object_purgeable */
 #ifdef GL_APPLE_pixel_buffer
   _glewInfo_GL_APPLE_pixel_buffer();
 #endif /* GL_APPLE_pixel_buffer */
+#ifdef GL_APPLE_rgb_422
+  _glewInfo_GL_APPLE_rgb_422();
+#endif /* GL_APPLE_rgb_422 */
+#ifdef GL_APPLE_row_bytes
+  _glewInfo_GL_APPLE_row_bytes();
+#endif /* GL_APPLE_row_bytes */
 #ifdef GL_APPLE_specular_vector
   _glewInfo_GL_APPLE_specular_vector();
 #endif /* GL_APPLE_specular_vector */
@@ -5720,24 +6312,45 @@
 #ifdef GL_APPLE_vertex_array_range
   _glewInfo_GL_APPLE_vertex_array_range();
 #endif /* GL_APPLE_vertex_array_range */
+#ifdef GL_APPLE_vertex_program_evaluators
+  _glewInfo_GL_APPLE_vertex_program_evaluators();
+#endif /* GL_APPLE_vertex_program_evaluators */
 #ifdef GL_APPLE_ycbcr_422
   _glewInfo_GL_APPLE_ycbcr_422();
 #endif /* GL_APPLE_ycbcr_422 */
 #ifdef GL_ARB_color_buffer_float
   _glewInfo_GL_ARB_color_buffer_float();
 #endif /* GL_ARB_color_buffer_float */
+#ifdef GL_ARB_compatibility
+  _glewInfo_GL_ARB_compatibility();
+#endif /* GL_ARB_compatibility */
+#ifdef GL_ARB_copy_buffer
+  _glewInfo_GL_ARB_copy_buffer();
+#endif /* GL_ARB_copy_buffer */
 #ifdef GL_ARB_depth_buffer_float
   _glewInfo_GL_ARB_depth_buffer_float();
 #endif /* GL_ARB_depth_buffer_float */
+#ifdef GL_ARB_depth_clamp
+  _glewInfo_GL_ARB_depth_clamp();
+#endif /* GL_ARB_depth_clamp */
 #ifdef GL_ARB_depth_texture
   _glewInfo_GL_ARB_depth_texture();
 #endif /* GL_ARB_depth_texture */
 #ifdef GL_ARB_draw_buffers
   _glewInfo_GL_ARB_draw_buffers();
 #endif /* GL_ARB_draw_buffers */
+#ifdef GL_ARB_draw_buffers_blend
+  _glewInfo_GL_ARB_draw_buffers_blend();
+#endif /* GL_ARB_draw_buffers_blend */
+#ifdef GL_ARB_draw_elements_base_vertex
+  _glewInfo_GL_ARB_draw_elements_base_vertex();
+#endif /* GL_ARB_draw_elements_base_vertex */
 #ifdef GL_ARB_draw_instanced
   _glewInfo_GL_ARB_draw_instanced();
 #endif /* GL_ARB_draw_instanced */
+#ifdef GL_ARB_fragment_coord_conventions
+  _glewInfo_GL_ARB_fragment_coord_conventions();
+#endif /* GL_ARB_fragment_coord_conventions */
 #ifdef GL_ARB_fragment_program
   _glewInfo_GL_ARB_fragment_program();
 #endif /* GL_ARB_fragment_program */
@@ -5792,9 +6405,21 @@
 #ifdef GL_ARB_point_sprite
   _glewInfo_GL_ARB_point_sprite();
 #endif /* GL_ARB_point_sprite */
+#ifdef GL_ARB_provoking_vertex
+  _glewInfo_GL_ARB_provoking_vertex();
+#endif /* GL_ARB_provoking_vertex */
+#ifdef GL_ARB_sample_shading
+  _glewInfo_GL_ARB_sample_shading();
+#endif /* GL_ARB_sample_shading */
+#ifdef GL_ARB_seamless_cube_map
+  _glewInfo_GL_ARB_seamless_cube_map();
+#endif /* GL_ARB_seamless_cube_map */
 #ifdef GL_ARB_shader_objects
   _glewInfo_GL_ARB_shader_objects();
 #endif /* GL_ARB_shader_objects */
+#ifdef GL_ARB_shader_texture_lod
+  _glewInfo_GL_ARB_shader_texture_lod();
+#endif /* GL_ARB_shader_texture_lod */
 #ifdef GL_ARB_shading_language_100
   _glewInfo_GL_ARB_shading_language_100();
 #endif /* GL_ARB_shading_language_100 */
@@ -5804,6 +6429,9 @@
 #ifdef GL_ARB_shadow_ambient
   _glewInfo_GL_ARB_shadow_ambient();
 #endif /* GL_ARB_shadow_ambient */
+#ifdef GL_ARB_sync
+  _glewInfo_GL_ARB_sync();
+#endif /* GL_ARB_sync */
 #ifdef GL_ARB_texture_border_clamp
   _glewInfo_GL_ARB_texture_border_clamp();
 #endif /* GL_ARB_texture_border_clamp */
@@ -5819,6 +6447,9 @@
 #ifdef GL_ARB_texture_cube_map
   _glewInfo_GL_ARB_texture_cube_map();
 #endif /* GL_ARB_texture_cube_map */
+#ifdef GL_ARB_texture_cube_map_array
+  _glewInfo_GL_ARB_texture_cube_map_array();
+#endif /* GL_ARB_texture_cube_map_array */
 #ifdef GL_ARB_texture_env_add
   _glewInfo_GL_ARB_texture_env_add();
 #endif /* GL_ARB_texture_env_add */
@@ -5834,12 +6465,21 @@
 #ifdef GL_ARB_texture_float
   _glewInfo_GL_ARB_texture_float();
 #endif /* GL_ARB_texture_float */
+#ifdef GL_ARB_texture_gather
+  _glewInfo_GL_ARB_texture_gather();
+#endif /* GL_ARB_texture_gather */
 #ifdef GL_ARB_texture_mirrored_repeat
   _glewInfo_GL_ARB_texture_mirrored_repeat();
 #endif /* GL_ARB_texture_mirrored_repeat */
+#ifdef GL_ARB_texture_multisample
+  _glewInfo_GL_ARB_texture_multisample();
+#endif /* GL_ARB_texture_multisample */
 #ifdef GL_ARB_texture_non_power_of_two
   _glewInfo_GL_ARB_texture_non_power_of_two();
 #endif /* GL_ARB_texture_non_power_of_two */
+#ifdef GL_ARB_texture_query_lod
+  _glewInfo_GL_ARB_texture_query_lod();
+#endif /* GL_ARB_texture_query_lod */
 #ifdef GL_ARB_texture_rectangle
   _glewInfo_GL_ARB_texture_rectangle();
 #endif /* GL_ARB_texture_rectangle */
@@ -5849,6 +6489,12 @@
 #ifdef GL_ARB_transpose_matrix
   _glewInfo_GL_ARB_transpose_matrix();
 #endif /* GL_ARB_transpose_matrix */
+#ifdef GL_ARB_uniform_buffer_object
+  _glewInfo_GL_ARB_uniform_buffer_object();
+#endif /* GL_ARB_uniform_buffer_object */
+#ifdef GL_ARB_vertex_array_bgra
+  _glewInfo_GL_ARB_vertex_array_bgra();
+#endif /* GL_ARB_vertex_array_bgra */
 #ifdef GL_ARB_vertex_array_object
   _glewInfo_GL_ARB_vertex_array_object();
 #endif /* GL_ARB_vertex_array_object */
@@ -5894,6 +6540,9 @@
 #ifdef GL_ATI_map_object_buffer
   _glewInfo_GL_ATI_map_object_buffer();
 #endif /* GL_ATI_map_object_buffer */
+#ifdef GL_ATI_meminfo
+  _glewInfo_GL_ATI_meminfo();
+#endif /* GL_ATI_meminfo */
 #ifdef GL_ATI_pn_triangles
   _glewInfo_GL_ATI_pn_triangles();
 #endif /* GL_ATI_pn_triangles */
@@ -6080,6 +6729,9 @@
 #ifdef GL_EXT_polygon_offset
   _glewInfo_GL_EXT_polygon_offset();
 #endif /* GL_EXT_polygon_offset */
+#ifdef GL_EXT_provoking_vertex
+  _glewInfo_GL_EXT_provoking_vertex();
+#endif /* GL_EXT_provoking_vertex */
 #ifdef GL_EXT_rescale_normal
   _glewInfo_GL_EXT_rescale_normal();
 #endif /* GL_EXT_rescale_normal */
@@ -6089,6 +6741,9 @@
 #ifdef GL_EXT_secondary_color
   _glewInfo_GL_EXT_secondary_color();
 #endif /* GL_EXT_secondary_color */
+#ifdef GL_EXT_separate_shader_objects
+  _glewInfo_GL_EXT_separate_shader_objects();
+#endif /* GL_EXT_separate_shader_objects */
 #ifdef GL_EXT_separate_specular_color
   _glewInfo_GL_EXT_separate_specular_color();
 #endif /* GL_EXT_separate_specular_color */
@@ -6179,6 +6834,9 @@
 #ifdef GL_EXT_texture_shared_exponent
   _glewInfo_GL_EXT_texture_shared_exponent();
 #endif /* GL_EXT_texture_shared_exponent */
+#ifdef GL_EXT_texture_snorm
+  _glewInfo_GL_EXT_texture_snorm();
+#endif /* GL_EXT_texture_snorm */
 #ifdef GL_EXT_texture_swizzle
   _glewInfo_GL_EXT_texture_swizzle();
 #endif /* GL_EXT_texture_swizzle */
@@ -6275,6 +6933,9 @@
 #ifdef GL_NV_copy_depth_to_color
   _glewInfo_GL_NV_copy_depth_to_color();
 #endif /* GL_NV_copy_depth_to_color */
+#ifdef GL_NV_copy_image
+  _glewInfo_GL_NV_copy_image();
+#endif /* GL_NV_copy_image */
 #ifdef GL_NV_depth_buffer_float
   _glewInfo_GL_NV_depth_buffer_float();
 #endif /* GL_NV_depth_buffer_float */
@@ -6341,6 +7002,9 @@
 #ifdef GL_NV_parameter_buffer_object
   _glewInfo_GL_NV_parameter_buffer_object();
 #endif /* GL_NV_parameter_buffer_object */
+#ifdef GL_NV_parameter_buffer_object2
+  _glewInfo_GL_NV_parameter_buffer_object2();
+#endif /* GL_NV_parameter_buffer_object2 */
 #ifdef GL_NV_pixel_data_range
   _glewInfo_GL_NV_pixel_data_range();
 #endif /* GL_NV_pixel_data_range */
@@ -6359,12 +7023,18 @@
 #ifdef GL_NV_register_combiners2
   _glewInfo_GL_NV_register_combiners2();
 #endif /* GL_NV_register_combiners2 */
+#ifdef GL_NV_shader_buffer_load
+  _glewInfo_GL_NV_shader_buffer_load();
+#endif /* GL_NV_shader_buffer_load */
 #ifdef GL_NV_texgen_emboss
   _glewInfo_GL_NV_texgen_emboss();
 #endif /* GL_NV_texgen_emboss */
 #ifdef GL_NV_texgen_reflection
   _glewInfo_GL_NV_texgen_reflection();
 #endif /* GL_NV_texgen_reflection */
+#ifdef GL_NV_texture_barrier
+  _glewInfo_GL_NV_texture_barrier();
+#endif /* GL_NV_texture_barrier */
 #ifdef GL_NV_texture_compression_vtc
   _glewInfo_GL_NV_texture_compression_vtc();
 #endif /* GL_NV_texture_compression_vtc */
@@ -6389,12 +7059,18 @@
 #ifdef GL_NV_transform_feedback
   _glewInfo_GL_NV_transform_feedback();
 #endif /* GL_NV_transform_feedback */
+#ifdef GL_NV_transform_feedback2
+  _glewInfo_GL_NV_transform_feedback2();
+#endif /* GL_NV_transform_feedback2 */
 #ifdef GL_NV_vertex_array_range
   _glewInfo_GL_NV_vertex_array_range();
 #endif /* GL_NV_vertex_array_range */
 #ifdef GL_NV_vertex_array_range2
   _glewInfo_GL_NV_vertex_array_range2();
 #endif /* GL_NV_vertex_array_range2 */
+#ifdef GL_NV_vertex_buffer_unified_memory
+  _glewInfo_GL_NV_vertex_buffer_unified_memory();
+#endif /* GL_NV_vertex_buffer_unified_memory */
 #ifdef GL_NV_vertex_program
   _glewInfo_GL_NV_vertex_program();
 #endif /* GL_NV_vertex_program */
@@ -6640,12 +7316,18 @@
 #ifdef WGL_3DL_stereo_control
   _glewInfo_WGL_3DL_stereo_control();
 #endif /* WGL_3DL_stereo_control */
+#ifdef WGL_AMD_gpu_association
+  _glewInfo_WGL_AMD_gpu_association();
+#endif /* WGL_AMD_gpu_association */
 #ifdef WGL_ARB_buffer_region
   _glewInfo_WGL_ARB_buffer_region();
 #endif /* WGL_ARB_buffer_region */
 #ifdef WGL_ARB_create_context
   _glewInfo_WGL_ARB_create_context();
 #endif /* WGL_ARB_create_context */
+#ifdef WGL_ARB_create_context_profile
+  _glewInfo_WGL_ARB_create_context_profile();
+#endif /* WGL_ARB_create_context_profile */
 #ifdef WGL_ARB_extensions_string
   _glewInfo_WGL_ARB_extensions_string();
 #endif /* WGL_ARB_extensions_string */
@@ -6724,6 +7406,9 @@
 #ifdef WGL_I3D_swap_frame_usage
   _glewInfo_WGL_I3D_swap_frame_usage();
 #endif /* WGL_I3D_swap_frame_usage */
+#ifdef WGL_NV_copy_image
+  _glewInfo_WGL_NV_copy_image();
+#endif /* WGL_NV_copy_image */
 #ifdef WGL_NV_float_buffer
   _glewInfo_WGL_NV_float_buffer();
 #endif /* WGL_NV_float_buffer */
@@ -6772,6 +7457,9 @@
 #ifdef GLX_ARB_create_context
   _glewInfo_GLX_ARB_create_context();
 #endif /* GLX_ARB_create_context */
+#ifdef GLX_ARB_create_context_profile
+  _glewInfo_GLX_ARB_create_context_profile();
+#endif /* GLX_ARB_create_context_profile */
 #ifdef GLX_ARB_fbconfig_float
   _glewInfo_GLX_ARB_fbconfig_float();
 #endif /* GLX_ARB_fbconfig_float */
@@ -6802,6 +7490,9 @@
 #ifdef GLX_EXT_scene_marker
   _glewInfo_GLX_EXT_scene_marker();
 #endif /* GLX_EXT_scene_marker */
+#ifdef GLX_EXT_swap_control
+  _glewInfo_GLX_EXT_swap_control();
+#endif /* GLX_EXT_swap_control */
 #ifdef GLX_EXT_texture_from_pixmap
   _glewInfo_GLX_EXT_texture_from_pixmap();
 #endif /* GLX_EXT_texture_from_pixmap */
@@ -6826,6 +7517,9 @@
 #ifdef GLX_MESA_set_3dfx_mode
   _glewInfo_GLX_MESA_set_3dfx_mode();
 #endif /* GLX_MESA_set_3dfx_mode */
+#ifdef GLX_NV_copy_image
+  _glewInfo_GLX_NV_copy_image();
+#endif /* GLX_NV_copy_image */
 #ifdef GLX_NV_float_buffer
   _glewInfo_GLX_NV_float_buffer();
 #endif /* GLX_NV_float_buffer */
@@ -7071,7 +7765,7 @@
 void glewDestroyContext ()
 {
   if (NULL != rc) wglMakeCurrent(NULL, NULL);
-  if (NULL != rc) wglDeleteContext(wglGetCurrentContext());
+  if (NULL != rc) wglDeleteContext(rc);
   if (NULL != wnd && NULL != dc) ReleaseDC(wnd, dc);
   if (NULL != wnd) DestroyWindow(wnd);
   UnregisterClass("GLEW", GetModuleHandle(NULL));
@@ -7100,7 +7794,7 @@
   aglDestroyPixelFormat(pf);
   /*aglSetDrawable(ctx, GetWindowPort(wnd));*/
   octx = aglGetCurrentContext();
-  if (NULL == aglSetCurrentContext(ctx)) return GL_TRUE;
+  if (GL_FALSE == aglSetCurrentContext(ctx)) return GL_TRUE;
   return GL_FALSE;
 }
 
diff --git a/src/glew/visualinfo.c b/src/glew/visualinfo.c
index 384313d..f3ae91f 100644
--- a/src/glew/visualinfo.c
+++ b/src/glew/visualinfo.c
@@ -1056,7 +1056,7 @@
   aglDestroyPixelFormat(pf);
   /*aglSetDrawable(ctx, GetWindowPort(wnd));*/
   ctx->octx = aglGetCurrentContext();
-  if (NULL == aglSetCurrentContext(ctx->ctx)) return GL_TRUE;
+  if (GL_FALSE == aglSetCurrentContext(ctx->ctx)) return GL_TRUE;
   return GL_FALSE;
 }
 
diff --git a/src/glsl/Makefile b/src/glsl/Makefile
new file mode 100644
index 0000000..ca7f2d2
--- /dev/null
+++ b/src/glsl/Makefile
@@ -0,0 +1,15 @@
+# src/glsl/Makefile
+
+TOP = ../..
+
+include $(TOP)/configs/current
+
+SUBDIRS = pp cl apps
+
+default install clean:
+	@for dir in $(SUBDIRS) ; do \
+		if [ -d $$dir ] ; then \
+			(cd $$dir && $(MAKE) $@) || exit 1; \
+		fi \
+	done
+
diff --git a/src/glsl/Makefile.template b/src/glsl/Makefile.template
new file mode 100644
index 0000000..974987a
--- /dev/null
+++ b/src/glsl/Makefile.template
@@ -0,0 +1,50 @@
+# src/glsl/Makefile.template
+
+# Template makefile for glsl libraries.
+#
+# Usage:
+#   The minimum that the including makefile needs to define
+#   is TOP, LIBNAME and one of of the *_SOURCES.
+#
+# Optional defines:
+#   LIBRARY_INCLUDES are appended to the list of includes directories.
+#   LIBRARY_DEFINES is not used for makedepend, but for compilation.
+
+
+### Basic defines ###
+
+OBJECTS = $(C_SOURCES:.c=.o)
+
+INCLUDES = \
+	-I. \
+	$(LIBRARY_INCLUDES)
+
+
+##### TARGETS #####
+
+default: depend lib$(LIBNAME).a
+
+lib$(LIBNAME).a: $(OBJECTS) Makefile $(TOP)/src/glsl/Makefile.template
+	$(MKLIB) -o $(LIBNAME) -static $(OBJECTS)
+
+depend: $(C_SOURCES)
+	rm -f depend
+	touch depend
+	$(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(C_SOURCES) 2> /dev/null
+
+# Remove .o and backup files
+clean:
+	rm -f $(OBJECTS) lib$(LIBNAME).a depend depend.bak
+
+# Dummy target
+install:
+	@echo -n ""
+
+
+##### RULES #####
+
+.c.o:
+	$(CC) -c $(INCLUDES) $(CFLAGS) $(LIBRARY_DEFINES) $< -o $@
+
+-include depend
+
diff --git a/src/glsl/SConscript b/src/glsl/SConscript
new file mode 100644
index 0000000..8e18626
--- /dev/null
+++ b/src/glsl/SConscript
@@ -0,0 +1,69 @@
+import common
+
+Import('*')
+
+env = env.Clone()
+
+sources = [
+    'pp/sl_pp_context.c',
+    'pp/sl_pp_define.c',
+    'pp/sl_pp_dict.c',
+    'pp/sl_pp_error.c',
+    'pp/sl_pp_expression.c',
+    'pp/sl_pp_extension.c',
+    'pp/sl_pp_if.c',
+    'pp/sl_pp_line.c',
+    'pp/sl_pp_macro.c',
+    'pp/sl_pp_pragma.c',
+    'pp/sl_pp_process.c',
+    'pp/sl_pp_purify.c',
+    'pp/sl_pp_token.c',
+    'pp/sl_pp_token_util.c',
+    'pp/sl_pp_version.c',
+    'cl/sl_cl_parse.c',
+]
+
+glsl = env.ConvenienceLibrary(
+    target = 'glsl',
+    source = sources,
+)
+
+Export('glsl')
+
+env = env.Clone()
+
+if env['platform'] == 'windows':
+    env.PrependUnique(LIBS = [
+        'user32',
+    ])
+
+env.Prepend(LIBS = [glsl])
+
+env.Program(
+    target = 'purify',
+    source = ['apps/purify.c'],
+)
+
+env.Program(
+    target = 'tokenise',
+    source = ['apps/tokenise.c'],
+)
+
+env.Program(
+    target = 'version',
+    source = ['apps/version.c'],
+)
+
+env.Program(
+    target = 'process',
+    source = ['apps/process.c'],
+)
+
+glsl_compile = env.Program(
+    target = 'compile',
+    source = ['apps/compile.c'],
+)
+
+if env['platform'] == common.default_platform:
+    # Only export the GLSL compiler when building for the host platform
+    Export('glsl_compile')
diff --git a/src/glsl/apps/.gitignore b/src/glsl/apps/.gitignore
new file mode 100644
index 0000000..7e011ce
--- /dev/null
+++ b/src/glsl/apps/.gitignore
@@ -0,0 +1,5 @@
+compile
+process
+purify
+tokenise
+version
diff --git a/src/glsl/apps/Makefile b/src/glsl/apps/Makefile
new file mode 100644
index 0000000..39a0df7
--- /dev/null
+++ b/src/glsl/apps/Makefile
@@ -0,0 +1,43 @@
+# src/glsl/apps/Makefile
+
+TOP = ../../..
+
+include $(TOP)/configs/current
+
+LIBS = \
+	$(TOP)/src/glsl/pp/libglslpp.a \
+	$(TOP)/src/glsl/cl/libglslcl.a
+
+SOURCES = \
+	compile.c \
+	process.c \
+	purify.c \
+	tokenise.c \
+	version.c
+
+APPS = $(SOURCES:%.c=%)
+
+INCLUDES = -I.
+
+
+##### RULES #####
+
+.SUFFIXES:
+.SUFFIXES: .c
+
+.c:
+	$(APP_CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@
+
+.c.o:
+	$(APP_CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+
+##### TARGETS #####
+
+default: $(APPS)
+
+install:
+
+clean:
+	-rm -f $(APPS)
+	-rm -f *.o
diff --git a/src/glsl/apps/compile.c b/src/glsl/apps/compile.c
new file mode 100644
index 0000000..c9a830b
--- /dev/null
+++ b/src/glsl/apps/compile.c
@@ -0,0 +1,191 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "../pp/sl_pp_public.h"
+#include "../cl/sl_cl_parse.h"
+
+
+static void
+usage(void)
+{
+   printf("Usage:\n");
+   printf("  compile fragment|vertex <source> <output>\n");
+}
+
+int
+main(int argc,
+     char *argv[])
+{
+   FILE *in;
+   long size;
+   char *inbuf;
+   struct sl_pp_purify_options options;
+   char errmsg[100] = "";
+   struct sl_pp_context *context;
+   unsigned int version;
+   FILE *out;
+   unsigned char *outbytes;
+   unsigned int cboutbytes;
+   unsigned int shader_type;
+
+   if (argc != 4) {
+      usage();
+      return 1;
+   }
+
+   if (!strcmp(argv[1], "fragment")) {
+      shader_type = 1;
+   } else if (!strcmp(argv[1], "vertex")) {
+      shader_type = 2;
+   } else {
+      usage();
+      return 1;
+   }
+
+   in = fopen(argv[2], "rb");
+   if (!in) {
+      printf("Could not open `%s' for read.\n", argv[2]);
+      usage();
+      return 1;
+   }
+
+   fseek(in, 0, SEEK_END);
+   size = ftell(in);
+   fseek(in, 0, SEEK_SET);
+
+   out = fopen(argv[3], "w");
+   if (!out) {
+      fclose(in);
+      printf("Could not open `%s' for write.\n", argv[3]);
+      usage();
+      return 1;
+   }
+
+   inbuf = malloc(size + 1);
+   if (!inbuf) {
+      fprintf(out, "$OOMERROR\n");
+
+      fclose(out);
+      fclose(in);
+      printf("Out of memory.\n");
+      return 0;
+   }
+
+   if (fread(inbuf, 1, size, in) != size) {
+      fprintf(out, "$READERROR\n");
+
+      free(inbuf);
+      fclose(out);
+      fclose(in);
+      printf("Could not read from `%s'.\n", argv[2]);
+      return 0;
+   }
+   inbuf[size] = '\0';
+
+   fclose(in);
+
+   memset(&options, 0, sizeof(options));
+
+   context = sl_pp_context_create(inbuf, &options);
+   if (!context) {
+      fprintf(out, "$CONTEXERROR\n");
+
+      free(inbuf);
+      fclose(out);
+      printf("Could not create parse context.\n");
+      return 0;
+   }
+
+   if (sl_pp_version(context, &version)) {
+      fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
+
+      printf("Error: %s\n", sl_pp_context_error_message(context));
+      sl_pp_context_destroy(context);
+      free(inbuf);
+      fclose(out);
+      return 0;
+   }
+
+   if (sl_pp_context_add_extension(context, "ARB_draw_buffers", "GL_ARB_draw_buffers") ||
+       sl_pp_context_add_extension(context, "ARB_texture_rectangle", "GL_ARB_texture_rectangle")) {
+      fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
+
+      printf("Error: %s\n", sl_pp_context_error_message(context));
+      sl_pp_context_destroy(context);
+      free(inbuf);
+      fclose(out);
+      return 0;
+   }
+
+   if (sl_cl_compile(context, shader_type, 1, &outbytes, &cboutbytes, errmsg, sizeof(errmsg)) == 0) {
+      unsigned int i;
+      unsigned int line = 0;
+
+      fprintf(out, "\n/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE FOLLOWING FILE: */");
+      fprintf(out, "\n/* %s */", argv[2]);
+      fprintf(out, "\n\n");
+
+      for (i = 0; i < cboutbytes; i++) {
+         unsigned int a;
+
+         if (outbytes[i] < 10) {
+            a = 1;
+         } else if (outbytes[i] < 100) {
+            a = 2;
+         } else {
+            a = 3;
+         }
+         if (i < cboutbytes - 1) {
+            a++;
+         }
+         if (line + a >= 100) {
+            fprintf (out, "\n");
+            line = 0;
+         }
+         line += a;
+         fprintf (out, "%u", outbytes[i]);
+         if (i < cboutbytes - 1) {
+            fprintf (out, ",");
+         }
+      }
+      fprintf (out, "\n");
+      free(outbytes);
+   } else {
+      fprintf(out, "$SYNTAXERROR: `%s'\n", errmsg);
+
+      printf("Error: %s\n", errmsg);
+   }
+
+   sl_pp_context_destroy(context);
+   free(inbuf);
+   fclose(out);
+   return 0;
+}
diff --git a/src/glsl/apps/process.c b/src/glsl/apps/process.c
new file mode 100644
index 0000000..5698902
--- /dev/null
+++ b/src/glsl/apps/process.c
@@ -0,0 +1,381 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "../pp/sl_pp_public.h"
+
+
+int
+main(int argc,
+     char *argv[])
+{
+   FILE *in;
+   long size;
+   char *inbuf;
+   struct sl_pp_purify_options options;
+   struct sl_pp_context *context;
+   unsigned int version;
+   struct sl_pp_token_info *outtokens;
+   FILE *out;
+   unsigned int i;
+
+   if (argc != 3) {
+      return 1;
+   }
+
+   in = fopen(argv[1], "rb");
+   if (!in) {
+      return 1;
+   }
+
+   fseek(in, 0, SEEK_END);
+   size = ftell(in);
+   fseek(in, 0, SEEK_SET);
+
+   out = fopen(argv[2], "wb");
+   if (!out) {
+      fclose(in);
+      return 1;
+   }
+
+   inbuf = malloc(size + 1);
+   if (!inbuf) {
+      fprintf(out, "$OOMERROR\n");
+
+      fclose(out);
+      fclose(in);
+      return 1;
+   }
+
+   if (fread(inbuf, 1, size, in) != size) {
+      fprintf(out, "$READERROR\n");
+
+      free(inbuf);
+      fclose(out);
+      fclose(in);
+      return 1;
+   }
+   inbuf[size] = '\0';
+
+   fclose(in);
+
+   memset(&options, 0, sizeof(options));
+
+   context = sl_pp_context_create(inbuf, &options);
+   if (!context) {
+      fprintf(out, "$CONTEXERROR\n");
+
+      free(inbuf);
+      fclose(out);
+      return 1;
+   }
+
+   if (sl_pp_version(context, &version)) {
+      fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
+
+      sl_pp_context_destroy(context);
+      free(inbuf);
+      fclose(out);
+      return -1;
+   }
+
+   if (sl_pp_context_add_extension(context, "ARB_draw_buffers", "GL_ARB_draw_buffers") ||
+       sl_pp_context_add_extension(context, "ARB_texture_rectangle", "GL_ARB_texture_rectangle")) {
+      fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
+
+      printf("Error: %s\n", sl_pp_context_error_message(context));
+      sl_pp_context_destroy(context);
+      free(inbuf);
+      fclose(out);
+      return 0;
+   }
+
+   if (sl_pp_context_add_predefined(context, "__GLSL_PP_PREDEFINED_MACRO_TEST", "1")) {
+      fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
+
+      printf("Error: %s\n", sl_pp_context_error_message(context));
+      sl_pp_context_destroy(context);
+      free(inbuf);
+      fclose(out);
+      return 0;
+   }
+
+   if (sl_pp_process(context, &outtokens)) {
+      fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
+
+      sl_pp_context_destroy(context);
+      free(inbuf);
+      fclose(out);
+      return -1;
+   }
+
+   free(inbuf);
+
+   for (i = 0; outtokens[i].token != SL_PP_EOF; i++) {
+      switch (outtokens[i].token) {
+      case SL_PP_NEWLINE:
+         fprintf(out, "\n");
+         break;
+
+      case SL_PP_COMMA:
+         fprintf(out, ", ");
+         break;
+
+      case SL_PP_SEMICOLON:
+         fprintf(out, "; ");
+         break;
+
+      case SL_PP_LBRACE:
+         fprintf(out, "{ ");
+         break;
+
+      case SL_PP_RBRACE:
+         fprintf(out, "} ");
+         break;
+
+      case SL_PP_LPAREN:
+         fprintf(out, "( ");
+         break;
+
+      case SL_PP_RPAREN:
+         fprintf(out, ") ");
+         break;
+
+      case SL_PP_LBRACKET:
+         fprintf(out, "[ ");
+         break;
+
+      case SL_PP_RBRACKET:
+         fprintf(out, "] ");
+         break;
+
+      case SL_PP_DOT:
+         fprintf(out, ". ");
+         break;
+
+      case SL_PP_INCREMENT:
+         fprintf(out, "++ ");
+         break;
+
+      case SL_PP_ADDASSIGN:
+         fprintf(out, "+= ");
+         break;
+
+      case SL_PP_PLUS:
+         fprintf(out, "+ ");
+         break;
+
+      case SL_PP_DECREMENT:
+         fprintf(out, "-- ");
+         break;
+
+      case SL_PP_SUBASSIGN:
+         fprintf(out, "-= ");
+         break;
+
+      case SL_PP_MINUS:
+         fprintf(out, "- ");
+         break;
+
+      case SL_PP_BITNOT:
+         fprintf(out, "~ ");
+         break;
+
+      case SL_PP_NOTEQUAL:
+         fprintf(out, "!= ");
+         break;
+
+      case SL_PP_NOT:
+         fprintf(out, "! ");
+         break;
+
+      case SL_PP_MULASSIGN:
+         fprintf(out, "*= ");
+         break;
+
+      case SL_PP_STAR:
+         fprintf(out, "* ");
+         break;
+
+      case SL_PP_DIVASSIGN:
+         fprintf(out, "/= ");
+         break;
+
+      case SL_PP_SLASH:
+         fprintf(out, "/ ");
+         break;
+
+      case SL_PP_MODASSIGN:
+         fprintf(out, "%%= ");
+         break;
+
+      case SL_PP_MODULO:
+         fprintf(out, "%% ");
+         break;
+
+      case SL_PP_LSHIFTASSIGN:
+         fprintf(out, "<<= ");
+         break;
+
+      case SL_PP_LSHIFT:
+         fprintf(out, "<< ");
+         break;
+
+      case SL_PP_LESSEQUAL:
+         fprintf(out, "<= ");
+         break;
+
+      case SL_PP_LESS:
+         fprintf(out, "< ");
+         break;
+
+      case SL_PP_RSHIFTASSIGN:
+         fprintf(out, ">>= ");
+         break;
+
+      case SL_PP_RSHIFT:
+         fprintf(out, ">> ");
+         break;
+
+      case SL_PP_GREATEREQUAL:
+         fprintf(out, ">= ");
+         break;
+
+      case SL_PP_GREATER:
+         fprintf(out, "> ");
+         break;
+
+      case SL_PP_EQUAL:
+         fprintf(out, "== ");
+         break;
+
+      case SL_PP_ASSIGN:
+         fprintf(out, "= ");
+         break;
+
+      case SL_PP_AND:
+         fprintf(out, "&& ");
+         break;
+
+      case SL_PP_BITANDASSIGN:
+         fprintf(out, "&= ");
+         break;
+
+      case SL_PP_BITAND:
+         fprintf(out, "& ");
+         break;
+
+      case SL_PP_XOR:
+         fprintf(out, "^^ ");
+         break;
+
+      case SL_PP_BITXORASSIGN:
+         fprintf(out, "^= ");
+         break;
+
+      case SL_PP_BITXOR:
+         fprintf(out, "^ ");
+         break;
+
+      case SL_PP_OR:
+         fprintf(out, "|| ");
+         break;
+
+      case SL_PP_BITORASSIGN:
+         fprintf(out, "|= ");
+         break;
+
+      case SL_PP_BITOR:
+         fprintf(out, "| ");
+         break;
+
+      case SL_PP_QUESTION:
+         fprintf(out, "? ");
+         break;
+
+      case SL_PP_COLON:
+         fprintf(out, ": ");
+         break;
+
+      case SL_PP_IDENTIFIER:
+         fprintf(out, "%s ", sl_pp_context_cstr(context, outtokens[i].data.identifier));
+         break;
+
+      case SL_PP_UINT:
+         fprintf(out, "%s ", sl_pp_context_cstr(context, outtokens[i].data._uint));
+         break;
+
+      case SL_PP_FLOAT:
+         fprintf(out, "%s ", sl_pp_context_cstr(context, outtokens[i].data._float));
+         break;
+
+      case SL_PP_OTHER:
+         fprintf(out, "%c", outtokens[i].data.other);
+         break;
+
+      case SL_PP_PRAGMA_OPTIMIZE:
+         fprintf(out, "#pragma optimize(%s)", outtokens[i].data.pragma ? "on" : "off");
+         break;
+
+      case SL_PP_PRAGMA_DEBUG:
+         fprintf(out, "#pragma debug(%s)", outtokens[i].data.pragma ? "on" : "off");
+         break;
+
+      case SL_PP_EXTENSION_REQUIRE:
+         fprintf(out, "#extension %s : require", sl_pp_context_cstr(context, outtokens[i].data.extension));
+         break;
+
+      case SL_PP_EXTENSION_ENABLE:
+         fprintf(out, "#extension %s : enable", sl_pp_context_cstr(context, outtokens[i].data.extension));
+         break;
+
+      case SL_PP_EXTENSION_WARN:
+         fprintf(out, "#extension %s : warn", sl_pp_context_cstr(context, outtokens[i].data.extension));
+         break;
+
+      case SL_PP_EXTENSION_DISABLE:
+         fprintf(out, "#extension %s : disable", sl_pp_context_cstr(context, outtokens[i].data.extension));
+         break;
+
+      case SL_PP_LINE:
+         fprintf(out, "#line %u %u", outtokens[i].data.line.lineno, outtokens[i].data.line.fileno);
+         break;
+
+      default:
+         assert(0);
+      }
+   }
+
+   sl_pp_context_destroy(context);
+   free(outtokens);
+   fclose(out);
+
+   return 0;
+}
diff --git a/src/glsl/apps/purify.c b/src/glsl/apps/purify.c
new file mode 100644
index 0000000..8c01f4f
--- /dev/null
+++ b/src/glsl/apps/purify.c
@@ -0,0 +1,105 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "../pp/sl_pp_public.h"
+
+
+int
+main(int argc,
+     char *argv[])
+{
+   FILE *in;
+   long size;
+   char *inbuf;
+   struct sl_pp_purify_options options;
+   char *outbuf;
+   char errmsg[100] = "";
+   unsigned int errline = 0;
+   FILE *out;
+
+   if (argc != 3) {
+      return 1;
+   }
+
+   in = fopen(argv[1], "rb");
+   if (!in) {
+      return 1;
+   }
+
+   fseek(in, 0, SEEK_END);
+   size = ftell(in);
+   fseek(in, 0, SEEK_SET);
+
+   out = fopen(argv[2], "wb");
+   if (!out) {
+      fclose(in);
+      return 1;
+   }
+
+   inbuf = malloc(size + 1);
+   if (!inbuf) {
+      fprintf(out, "$OOMERROR\n");
+
+      fclose(out);
+      fclose(in);
+      return 1;
+   }
+
+   if (fread(inbuf, 1, size, in) != size) {
+      fprintf(out, "$READERROR\n");
+
+      free(inbuf);
+      fclose(out);
+      fclose(in);
+      return 1;
+   }
+   inbuf[size] = '\0';
+
+   fclose(in);
+
+   memset(&options, 0, sizeof(options));
+
+   if (sl_pp_purify(inbuf, &options, &outbuf, errmsg, sizeof(errmsg), &errline)) {
+      fprintf(out, "$PURIFYERROR %u: %s\n", errline, errmsg);
+
+      free(inbuf);
+      fclose(out);
+      return 1;
+   }
+
+   free(inbuf);
+
+   fwrite(outbuf, 1, strlen(outbuf), out);
+
+   free(outbuf);
+   fclose(out);
+
+   return 0;
+}
diff --git a/src/glsl/apps/tokenise.c b/src/glsl/apps/tokenise.c
new file mode 100644
index 0000000..9ff7315
--- /dev/null
+++ b/src/glsl/apps/tokenise.c
@@ -0,0 +1,333 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "../pp/sl_pp_public.h"
+
+
+int
+main(int argc,
+     char *argv[])
+{
+   FILE *in;
+   long size;
+   char *inbuf;
+   struct sl_pp_purify_options options;
+   struct sl_pp_context *context;
+   struct sl_pp_token_info *tokens;
+   FILE *out;
+   unsigned int i;
+
+   if (argc != 3) {
+      return 1;
+   }
+
+   in = fopen(argv[1], "rb");
+   if (!in) {
+      return 1;
+   }
+
+   fseek(in, 0, SEEK_END);
+   size = ftell(in);
+   fseek(in, 0, SEEK_SET);
+
+   out = fopen(argv[2], "wb");
+   if (!out) {
+      fclose(in);
+      return 1;
+   }
+
+   inbuf = malloc(size + 1);
+   if (!inbuf) {
+      fprintf(out, "$OOMERROR\n");
+
+      fclose(out);
+      fclose(in);
+      return 1;
+   }
+
+   if (fread(inbuf, 1, size, in) != size) {
+      fprintf(out, "$READERROR\n");
+
+      free(inbuf);
+      fclose(out);
+      fclose(in);
+      return 1;
+   }
+   inbuf[size] = '\0';
+
+   fclose(in);
+
+   memset(&options, 0, sizeof(options));
+
+   context = sl_pp_context_create(inbuf, &options);
+   if (!context) {
+      fprintf(out, "$CONTEXERROR\n");
+
+      free(inbuf);
+      fclose(out);
+      return 1;
+   }
+
+   if (sl_pp_tokenise(context, &tokens)) {
+      fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
+
+      sl_pp_context_destroy(context);
+      free(inbuf);
+      fclose(out);
+      return 1;
+   }
+
+   free(inbuf);
+
+   for (i = 0; tokens[i].token != SL_PP_EOF; i++) {
+      switch (tokens[i].token) {
+      case SL_PP_WHITESPACE:
+         break;
+
+      case SL_PP_NEWLINE:
+         fprintf(out, "\n");
+         break;
+
+      case SL_PP_HASH:
+         fprintf(out, "# ");
+         break;
+
+      case SL_PP_COMMA:
+         fprintf(out, ", ");
+         break;
+
+      case SL_PP_SEMICOLON:
+         fprintf(out, "; ");
+         break;
+
+      case SL_PP_LBRACE:
+         fprintf(out, "{ ");
+         break;
+
+      case SL_PP_RBRACE:
+         fprintf(out, "} ");
+         break;
+
+      case SL_PP_LPAREN:
+         fprintf(out, "( ");
+         break;
+
+      case SL_PP_RPAREN:
+         fprintf(out, ") ");
+         break;
+
+      case SL_PP_LBRACKET:
+         fprintf(out, "[ ");
+         break;
+
+      case SL_PP_RBRACKET:
+         fprintf(out, "] ");
+         break;
+
+      case SL_PP_DOT:
+         fprintf(out, ". ");
+         break;
+
+      case SL_PP_INCREMENT:
+         fprintf(out, "++ ");
+         break;
+
+      case SL_PP_ADDASSIGN:
+         fprintf(out, "+= ");
+         break;
+
+      case SL_PP_PLUS:
+         fprintf(out, "+ ");
+         break;
+
+      case SL_PP_DECREMENT:
+         fprintf(out, "-- ");
+         break;
+
+      case SL_PP_SUBASSIGN:
+         fprintf(out, "-= ");
+         break;
+
+      case SL_PP_MINUS:
+         fprintf(out, "- ");
+         break;
+
+      case SL_PP_BITNOT:
+         fprintf(out, "~ ");
+         break;
+
+      case SL_PP_NOTEQUAL:
+         fprintf(out, "!= ");
+         break;
+
+      case SL_PP_NOT:
+         fprintf(out, "! ");
+         break;
+
+      case SL_PP_MULASSIGN:
+         fprintf(out, "*= ");
+         break;
+
+      case SL_PP_STAR:
+         fprintf(out, "* ");
+         break;
+
+      case SL_PP_DIVASSIGN:
+         fprintf(out, "/= ");
+         break;
+
+      case SL_PP_SLASH:
+         fprintf(out, "/ ");
+         break;
+
+      case SL_PP_MODASSIGN:
+         fprintf(out, "%%= ");
+         break;
+
+      case SL_PP_MODULO:
+         fprintf(out, "%% ");
+         break;
+
+      case SL_PP_LSHIFTASSIGN:
+         fprintf(out, "<<= ");
+         break;
+
+      case SL_PP_LSHIFT:
+         fprintf(out, "<< ");
+         break;
+
+      case SL_PP_LESSEQUAL:
+         fprintf(out, "<= ");
+         break;
+
+      case SL_PP_LESS:
+         fprintf(out, "< ");
+         break;
+
+      case SL_PP_RSHIFTASSIGN:
+         fprintf(out, ">>= ");
+         break;
+
+      case SL_PP_RSHIFT:
+         fprintf(out, ">> ");
+         break;
+
+      case SL_PP_GREATEREQUAL:
+         fprintf(out, ">= ");
+         break;
+
+      case SL_PP_GREATER:
+         fprintf(out, "> ");
+         break;
+
+      case SL_PP_EQUAL:
+         fprintf(out, "== ");
+         break;
+
+      case SL_PP_ASSIGN:
+         fprintf(out, "= ");
+         break;
+
+      case SL_PP_AND:
+         fprintf(out, "&& ");
+         break;
+
+      case SL_PP_BITANDASSIGN:
+         fprintf(out, "&= ");
+         break;
+
+      case SL_PP_BITAND:
+         fprintf(out, "& ");
+         break;
+
+      case SL_PP_XOR:
+         fprintf(out, "^^ ");
+         break;
+
+      case SL_PP_BITXORASSIGN:
+         fprintf(out, "^= ");
+         break;
+
+      case SL_PP_BITXOR:
+         fprintf(out, "^ ");
+         break;
+
+      case SL_PP_OR:
+         fprintf(out, "|| ");
+         break;
+
+      case SL_PP_BITORASSIGN:
+         fprintf(out, "|= ");
+         break;
+
+      case SL_PP_BITOR:
+         fprintf(out, "| ");
+         break;
+
+      case SL_PP_QUESTION:
+         fprintf(out, "? ");
+         break;
+
+      case SL_PP_COLON:
+         fprintf(out, ": ");
+         break;
+
+      case SL_PP_IDENTIFIER:
+         fprintf(out, "%s ", sl_pp_context_cstr(context, tokens[i].data.identifier));
+         break;
+
+      case SL_PP_UINT:
+         fprintf(out, "(%s) ", sl_pp_context_cstr(context, tokens[i].data._uint));
+         break;
+
+      case SL_PP_FLOAT:
+         fprintf(out, "(%s) ", sl_pp_context_cstr(context, tokens[i].data._float));
+         break;
+
+      case SL_PP_OTHER:
+         if (tokens[i].data.other == '\'') {
+            fprintf(out, "'\\'' ");
+         } else {
+            fprintf(out, "'%c' ", tokens[i].data.other);
+         }
+         break;
+
+      default:
+         assert(0);
+      }
+   }
+
+   sl_pp_context_destroy(context);
+   free(tokens);
+   fclose(out);
+
+   return 0;
+}
diff --git a/src/glsl/apps/version.c b/src/glsl/apps/version.c
new file mode 100644
index 0000000..40a4a06
--- /dev/null
+++ b/src/glsl/apps/version.c
@@ -0,0 +1,115 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "../pp/sl_pp_public.h"
+
+
+int
+main(int argc,
+     char *argv[])
+{
+   FILE *in;
+   long size;
+   char *inbuf;
+   struct sl_pp_purify_options options;
+   struct sl_pp_context *context;
+   unsigned int version;
+   FILE *out;
+
+   if (argc != 3) {
+      return 1;
+   }
+
+   in = fopen(argv[1], "rb");
+   if (!in) {
+      return 1;
+   }
+
+   fseek(in, 0, SEEK_END);
+   size = ftell(in);
+   fseek(in, 0, SEEK_SET);
+
+   out = fopen(argv[2], "wb");
+   if (!out) {
+      fclose(in);
+      return 1;
+   }
+
+   inbuf = malloc(size + 1);
+   if (!inbuf) {
+      fprintf(out, "$OOMERROR\n");
+
+      fclose(out);
+      fclose(in);
+      return 1;
+   }
+
+   if (fread(inbuf, 1, size, in) != size) {
+      fprintf(out, "$READERROR\n");
+
+      free(inbuf);
+      fclose(out);
+      fclose(in);
+      return 1;
+   }
+   inbuf[size] = '\0';
+
+   fclose(in);
+
+   memset(&options, 0, sizeof(options));
+
+   context = sl_pp_context_create(inbuf, &options);
+   if (!context) {
+      fprintf(out, "$CONTEXERROR\n");
+
+      free(inbuf);
+      fclose(out);
+      return 1;
+   }
+
+   if (sl_pp_version(context, &version)) {
+      fprintf(out, "$ERROR: `%s'\n", sl_pp_context_error_message(context));
+
+      sl_pp_context_destroy(context);
+      free(inbuf);
+      fclose(out);
+      return -1;
+   }
+
+   sl_pp_context_destroy(context);
+   free(inbuf);
+
+   fprintf(out, "%u\n", version);
+
+   fclose(out);
+
+   return 0;
+}
diff --git a/src/glsl/cl/Makefile b/src/glsl/cl/Makefile
new file mode 100644
index 0000000..04a52df
--- /dev/null
+++ b/src/glsl/cl/Makefile
@@ -0,0 +1,13 @@
+#src/glsl/cl/Makefile
+
+TOP = ../../..
+
+include $(TOP)/configs/current
+
+LIBNAME = glslcl
+
+C_SOURCES = \
+	sl_cl_parse.c
+
+include ../Makefile.template
+
diff --git a/src/glsl/cl/sl_cl_parse.c b/src/glsl/cl/sl_cl_parse.c
new file mode 100644
index 0000000..e9b3707
--- /dev/null
+++ b/src/glsl/cl/sl_cl_parse.c
@@ -0,0 +1,2825 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "../pp/sl_pp_public.h"
+#include "sl_cl_parse.h"
+
+
+/* revision number - increment after each change affecting emitted output */
+#define REVISION                                   5
+
+/* external declaration (or precision or invariant stmt) */
+#define EXTERNAL_NULL                              0
+#define EXTERNAL_FUNCTION_DEFINITION               1
+#define EXTERNAL_DECLARATION                       2
+#define DEFAULT_PRECISION                          3
+#define INVARIANT_STMT                             4
+
+/* precision */
+#define PRECISION_DEFAULT                          0
+#define PRECISION_LOW                              1
+#define PRECISION_MEDIUM                           2
+#define PRECISION_HIGH                             3
+
+/* declaration */
+#define DECLARATION_FUNCTION_PROTOTYPE             1
+#define DECLARATION_INIT_DECLARATOR_LIST           2
+
+/* function type */
+#define FUNCTION_ORDINARY                          0
+#define FUNCTION_CONSTRUCTOR                       1
+#define FUNCTION_OPERATOR                          2
+
+/* function call type */
+#define FUNCTION_CALL_NONARRAY                     0
+#define FUNCTION_CALL_ARRAY                        1
+
+/* operator type */
+#define OPERATOR_ADDASSIGN                         1
+#define OPERATOR_SUBASSIGN                         2
+#define OPERATOR_MULASSIGN                         3
+#define OPERATOR_DIVASSIGN                         4
+/*#define OPERATOR_MODASSIGN                         5*/
+/*#define OPERATOR_LSHASSIGN                         6*/
+/*#define OPERATOR_RSHASSIGN                         7*/
+/*#define OPERATOR_ORASSIGN                          8*/
+/*#define OPERATOR_XORASSIGN                         9*/
+/*#define OPERATOR_ANDASSIGN                         10*/
+#define OPERATOR_LOGICALXOR                        11
+/*#define OPERATOR_BITOR                             12*/
+/*#define OPERATOR_BITXOR                            13*/
+/*#define OPERATOR_BITAND                            14*/
+#define OPERATOR_LESS                              15
+#define OPERATOR_GREATER                           16
+#define OPERATOR_LESSEQUAL                         17
+#define OPERATOR_GREATEREQUAL                      18
+/*#define OPERATOR_LSHIFT                            19*/
+/*#define OPERATOR_RSHIFT                            20*/
+#define OPERATOR_MULTIPLY                          21
+#define OPERATOR_DIVIDE                            22
+/*#define OPERATOR_MODULUS                           23*/
+#define OPERATOR_INCREMENT                         24
+#define OPERATOR_DECREMENT                         25
+#define OPERATOR_PLUS                              26
+#define OPERATOR_MINUS                             27
+/*#define OPERATOR_COMPLEMENT                        28*/
+#define OPERATOR_NOT                               29
+
+/* init declarator list */
+#define DECLARATOR_NONE                            0
+#define DECLARATOR_NEXT                            1
+
+/* variable declaration */
+#define VARIABLE_NONE                              0
+#define VARIABLE_IDENTIFIER                        1
+#define VARIABLE_INITIALIZER                       2
+#define VARIABLE_ARRAY_EXPLICIT                    3
+#define VARIABLE_ARRAY_UNKNOWN                     4
+
+/* type qualifier */
+#define TYPE_QUALIFIER_NONE                        0
+#define TYPE_QUALIFIER_CONST                       1
+#define TYPE_QUALIFIER_ATTRIBUTE                   2
+#define TYPE_QUALIFIER_VARYING                     3
+#define TYPE_QUALIFIER_UNIFORM                     4
+#define TYPE_QUALIFIER_FIXEDOUTPUT                 5
+#define TYPE_QUALIFIER_FIXEDINPUT                  6
+
+/* invariant qualifier */
+#define TYPE_VARIANT                               90
+#define TYPE_INVARIANT                             91
+
+/* centroid qualifier */
+#define TYPE_CENTER                                95
+#define TYPE_CENTROID                              96
+
+/* type specifier */
+#define TYPE_SPECIFIER_VOID                        0
+#define TYPE_SPECIFIER_BOOL                        1
+#define TYPE_SPECIFIER_BVEC2                       2
+#define TYPE_SPECIFIER_BVEC3                       3
+#define TYPE_SPECIFIER_BVEC4                       4
+#define TYPE_SPECIFIER_INT                         5
+#define TYPE_SPECIFIER_IVEC2                       6
+#define TYPE_SPECIFIER_IVEC3                       7
+#define TYPE_SPECIFIER_IVEC4                       8
+#define TYPE_SPECIFIER_FLOAT                       9
+#define TYPE_SPECIFIER_VEC2                        10
+#define TYPE_SPECIFIER_VEC3                        11
+#define TYPE_SPECIFIER_VEC4                        12
+#define TYPE_SPECIFIER_MAT2                        13
+#define TYPE_SPECIFIER_MAT3                        14
+#define TYPE_SPECIFIER_MAT4                        15
+#define TYPE_SPECIFIER_SAMPLER1D                   16
+#define TYPE_SPECIFIER_SAMPLER2D                   17
+#define TYPE_SPECIFIER_SAMPLER3D                   18
+#define TYPE_SPECIFIER_SAMPLERCUBE                 19
+#define TYPE_SPECIFIER_SAMPLER1DSHADOW             20
+#define TYPE_SPECIFIER_SAMPLER2DSHADOW             21
+#define TYPE_SPECIFIER_SAMPLER2DRECT               22
+#define TYPE_SPECIFIER_SAMPLER2DRECTSHADOW         23
+#define TYPE_SPECIFIER_STRUCT                      24
+#define TYPE_SPECIFIER_TYPENAME                    25
+
+/* OpenGL 2.1 */
+#define TYPE_SPECIFIER_MAT23                       26
+#define TYPE_SPECIFIER_MAT32                       27
+#define TYPE_SPECIFIER_MAT24                       28
+#define TYPE_SPECIFIER_MAT42                       29
+#define TYPE_SPECIFIER_MAT34                       30
+#define TYPE_SPECIFIER_MAT43                       31
+
+/* type specifier array */
+#define TYPE_SPECIFIER_NONARRAY                    0
+#define TYPE_SPECIFIER_ARRAY                       1
+
+/* structure field */
+#define FIELD_NONE                                 0
+#define FIELD_NEXT                                 1
+#define FIELD_ARRAY                                2
+
+/* operation */
+#define OP_END                                     0
+#define OP_BLOCK_BEGIN_NO_NEW_SCOPE                1
+#define OP_BLOCK_BEGIN_NEW_SCOPE                   2
+#define OP_DECLARE                                 3
+#define OP_ASM                                     4
+#define OP_BREAK                                   5
+#define OP_CONTINUE                                6
+#define OP_DISCARD                                 7
+#define OP_RETURN                                  8
+#define OP_EXPRESSION                              9
+#define OP_IF                                      10
+#define OP_WHILE                                   11
+#define OP_DO                                      12
+#define OP_FOR                                     13
+#define OP_PUSH_VOID                               14
+#define OP_PUSH_BOOL                               15
+#define OP_PUSH_INT                                16
+#define OP_PUSH_FLOAT                              17
+#define OP_PUSH_IDENTIFIER                         18
+#define OP_SEQUENCE                                19
+#define OP_ASSIGN                                  20
+#define OP_ADDASSIGN                               21
+#define OP_SUBASSIGN                               22
+#define OP_MULASSIGN                               23
+#define OP_DIVASSIGN                               24
+/*#define OP_MODASSIGN                               25*/
+/*#define OP_LSHASSIGN                               26*/
+/*#define OP_RSHASSIGN                               27*/
+/*#define OP_ORASSIGN                                28*/
+/*#define OP_XORASSIGN                               29*/
+/*#define OP_ANDASSIGN                               30*/
+#define OP_SELECT                                  31
+#define OP_LOGICALOR                               32
+#define OP_LOGICALXOR                              33
+#define OP_LOGICALAND                              34
+/*#define OP_BITOR                                   35*/
+/*#define OP_BITXOR                                  36*/
+/*#define OP_BITAND                                  37*/
+#define OP_EQUAL                                   38
+#define OP_NOTEQUAL                                39
+#define OP_LESS                                    40
+#define OP_GREATER                                 41
+#define OP_LESSEQUAL                               42
+#define OP_GREATEREQUAL                            43
+/*#define OP_LSHIFT                                  44*/
+/*#define OP_RSHIFT                                  45*/
+#define OP_ADD                                     46
+#define OP_SUBTRACT                                47
+#define OP_MULTIPLY                                48
+#define OP_DIVIDE                                  49
+/*#define OP_MODULUS                                 50*/
+#define OP_PREINCREMENT                            51
+#define OP_PREDECREMENT                            52
+#define OP_PLUS                                    53
+#define OP_MINUS                                   54
+/*#define OP_COMPLEMENT                              55*/
+#define OP_NOT                                     56
+#define OP_SUBSCRIPT                               57
+#define OP_CALL                                    58
+#define OP_FIELD                                   59
+#define OP_POSTINCREMENT                           60
+#define OP_POSTDECREMENT                           61
+#define OP_PRECISION                               62
+#define OP_METHOD                                  63
+
+/* parameter qualifier */
+#define PARAM_QUALIFIER_IN                         0
+#define PARAM_QUALIFIER_OUT                        1
+#define PARAM_QUALIFIER_INOUT                      2
+
+/* function parameter */
+#define PARAMETER_NONE                             0
+#define PARAMETER_NEXT                             1
+
+/* function parameter array presence */
+#define PARAMETER_ARRAY_NOT_PRESENT                0
+#define PARAMETER_ARRAY_PRESENT                    1
+
+
+struct parse_dict {
+   int _void;
+   int _float;
+   int _int;
+   int _bool;
+   int vec2;
+   int vec3;
+   int vec4;
+   int bvec2;
+   int bvec3;
+   int bvec4;
+   int ivec2;
+   int ivec3;
+   int ivec4;
+   int mat2;
+   int mat3;
+   int mat4;
+   int mat2x3;
+   int mat3x2;
+   int mat2x4;
+   int mat4x2;
+   int mat3x4;
+   int mat4x3;
+   int sampler1D;
+   int sampler2D;
+   int sampler3D;
+   int samplerCube;
+   int sampler1DShadow;
+   int sampler2DShadow;
+   int sampler2DRect;
+   int sampler2DRectShadow;
+
+   int invariant;
+
+   int centroid;
+
+   int precision;
+   int lowp;
+   int mediump;
+   int highp;
+
+   int _const;
+   int attribute;
+   int varying;
+   int uniform;
+   int __fixed_output;
+   int __fixed_input;
+
+   int in;
+   int out;
+   int inout;
+
+   int _struct;
+
+   int __constructor;
+   int __operator;
+   int ___asm;
+
+   int _if;
+   int _else;
+   int _for;
+   int _while;
+   int _do;
+
+   int _continue;
+   int _break;
+   int _return;
+   int discard;
+
+   int _false;
+   int _true;
+};
+
+
+struct parse_context {
+   struct sl_pp_context *context;
+
+   struct parse_dict dict;
+
+   struct sl_pp_token_info *tokens;
+   unsigned int tokens_read;
+   unsigned int tokens_cap;
+
+   unsigned char *out_buf;
+   unsigned int out_cap;
+
+   unsigned int shader_type;
+   unsigned int parsing_builtin;
+
+   char error[256];
+   int process_error;
+};
+
+
+struct parse_state {
+   unsigned int in;
+   unsigned int out;
+};
+
+
+static __inline unsigned int
+_emit(struct parse_context *ctx,
+      unsigned int *out,
+      unsigned char b)
+{
+   if (*out == ctx->out_cap) {
+      ctx->out_cap += 4096;
+      ctx->out_buf = (unsigned char *)realloc(ctx->out_buf, ctx->out_cap * sizeof(unsigned char));
+   }
+   ctx->out_buf[*out] = b;
+   return (*out)++;
+}
+
+
+static void
+_update(struct parse_context *ctx,
+        unsigned int out,
+        unsigned char b)
+{
+   ctx->out_buf[out] = b;
+}
+
+
+static void
+_error(struct parse_context *ctx,
+       const char *msg)
+{
+   if (ctx->error[0] == '\0') {
+      strcpy(ctx->error, msg);
+   }
+}
+
+
+static const struct sl_pp_token_info *
+_fetch_token(struct parse_context *ctx,
+             unsigned int pos)
+{
+   if (ctx->process_error) {
+      return NULL;
+   }
+
+   while (pos >= ctx->tokens_read) {
+      if (ctx->tokens_read == ctx->tokens_cap) {
+         ctx->tokens_cap += 1024;
+         ctx->tokens = realloc(ctx->tokens,
+                               ctx->tokens_cap * sizeof(struct sl_pp_token_info));
+         if (!ctx->tokens) {
+            _error(ctx, "out of memory");
+            ctx->process_error = 1;
+            return NULL;
+         }
+      }
+      if (sl_pp_process_get(ctx->context, &ctx->tokens[ctx->tokens_read])) {
+         _error(ctx, sl_pp_context_error_message(ctx->context));
+         ctx->process_error = 1;
+         return NULL;
+      }
+      switch (ctx->tokens[ctx->tokens_read].token) {
+      case SL_PP_COMMA:
+      case SL_PP_SEMICOLON:
+      case SL_PP_LBRACE:
+      case SL_PP_RBRACE:
+      case SL_PP_LPAREN:
+      case SL_PP_RPAREN:
+      case SL_PP_LBRACKET:
+      case SL_PP_RBRACKET:
+      case SL_PP_DOT:
+      case SL_PP_INCREMENT:
+      case SL_PP_ADDASSIGN:
+      case SL_PP_PLUS:
+      case SL_PP_DECREMENT:
+      case SL_PP_SUBASSIGN:
+      case SL_PP_MINUS:
+      case SL_PP_BITNOT:
+      case SL_PP_NOTEQUAL:
+      case SL_PP_NOT:
+      case SL_PP_MULASSIGN:
+      case SL_PP_STAR:
+      case SL_PP_DIVASSIGN:
+      case SL_PP_SLASH:
+      case SL_PP_MODASSIGN:
+      case SL_PP_MODULO:
+      case SL_PP_LSHIFTASSIGN:
+      case SL_PP_LSHIFT:
+      case SL_PP_LESSEQUAL:
+      case SL_PP_LESS:
+      case SL_PP_RSHIFTASSIGN:
+      case SL_PP_RSHIFT:
+      case SL_PP_GREATEREQUAL:
+      case SL_PP_GREATER:
+      case SL_PP_EQUAL:
+      case SL_PP_ASSIGN:
+      case SL_PP_AND:
+      case SL_PP_BITANDASSIGN:
+      case SL_PP_BITAND:
+      case SL_PP_XOR:
+      case SL_PP_BITXORASSIGN:
+      case SL_PP_BITXOR:
+      case SL_PP_OR:
+      case SL_PP_BITORASSIGN:
+      case SL_PP_BITOR:
+      case SL_PP_QUESTION:
+      case SL_PP_COLON:
+      case SL_PP_IDENTIFIER:
+      case SL_PP_UINT:
+      case SL_PP_FLOAT:
+      case SL_PP_EOF:
+         ctx->tokens_read++;
+         break;
+      default:
+         ; /* no-op */
+      }
+   }
+   return &ctx->tokens[pos];
+}
+
+
+static int
+_parse_token(struct parse_context *ctx,
+             enum sl_pp_token token,
+             struct parse_state *ps)
+{
+   const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in);
+
+   if (input && input->token == token) {
+      ps->in++;
+      return 0;
+   }
+   return -1;
+}
+
+
+static int
+_parse_id(struct parse_context *ctx,
+          int id,
+          struct parse_state *ps)
+{
+   const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in);
+
+   if (input && input->token == SL_PP_IDENTIFIER && input->data.identifier == id) {
+      ps->in++;
+      return 0;
+   }
+   return -1;
+}
+
+
+static int
+_parse_identifier(struct parse_context *ctx,
+                  struct parse_state *ps)
+{
+   const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in);
+
+   if (input && input->token == SL_PP_IDENTIFIER) {
+      const char *cstr = sl_pp_context_cstr(ctx->context, input->data.identifier);
+
+      do {
+         _emit(ctx, &ps->out, *cstr);
+      } while (*cstr++);
+      ps->in++;
+      return 0;
+   }
+   return -1;
+}
+
+
+static int
+_parse_float(struct parse_context *ctx,
+             struct parse_state *ps)
+{
+   const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in);
+
+   if (input && input->token == SL_PP_FLOAT) {
+      const char *cstr = sl_pp_context_cstr(ctx->context, input->data._float);
+
+      _emit(ctx, &ps->out, 1);
+      do {
+         _emit(ctx, &ps->out, *cstr);
+      } while (*cstr++);
+      ps->in++;
+      return 0;
+   }
+   return -1;
+}
+
+
+static int
+_parse_uint(struct parse_context *ctx,
+            struct parse_state *ps)
+{
+   const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in);
+
+   if (input && input->token == SL_PP_UINT) {
+      const char *cstr = sl_pp_context_cstr(ctx->context, input->data._uint);
+
+      _emit(ctx, &ps->out, 1);
+      do {
+         _emit(ctx, &ps->out, *cstr);
+      } while (*cstr++);
+      ps->in++;
+      return 0;
+   }
+   return -1;
+}
+
+
+/**************************************/
+
+
+static int
+_parse_unary_expression(struct parse_context *ctx,
+                        struct parse_state *ps);
+
+static int
+_parse_conditional_expression(struct parse_context *ctx,
+                              struct parse_state *ps);
+
+
+static int
+_parse_constant_expression(struct parse_context *ctx,
+                           struct parse_state *ps);
+
+
+static int
+_parse_primary_expression(struct parse_context *ctx,
+                          struct parse_state *ps);
+
+
+static int
+_parse_statement(struct parse_context *ctx,
+                 struct parse_state *ps);
+
+
+static int
+_parse_type_specifier(struct parse_context *ctx,
+                      struct parse_state *ps);
+
+
+static int
+_parse_declaration(struct parse_context *ctx,
+                   struct parse_state *ps);
+
+
+static int
+_parse_statement_list(struct parse_context *ctx,
+                      struct parse_state *ps);
+
+
+static int
+_parse_assignment_expression(struct parse_context *ctx,
+                             struct parse_state *ps);
+
+
+static int
+_parse_precision(struct parse_context *ctx,
+                 struct parse_state *ps);
+
+
+static int
+_parse_overriden_operator(struct parse_context *ctx,
+                          struct parse_state *ps)
+{
+   unsigned int op;
+
+   if (_parse_token(ctx, SL_PP_INCREMENT, ps) == 0) {
+      op = OPERATOR_INCREMENT;
+   } else if (_parse_token(ctx, SL_PP_ADDASSIGN, ps) == 0) {
+      op = OPERATOR_ADDASSIGN;
+   } else if (_parse_token(ctx, SL_PP_PLUS, ps) == 0) {
+      op = OPERATOR_PLUS;
+   } else if (_parse_token(ctx, SL_PP_DECREMENT, ps) == 0) {
+      op = OPERATOR_DECREMENT;
+   } else if (_parse_token(ctx, SL_PP_SUBASSIGN, ps) == 0) {
+      op = OPERATOR_SUBASSIGN;
+   } else if (_parse_token(ctx, SL_PP_MINUS, ps) == 0) {
+      op = OPERATOR_MINUS;
+   } else if (_parse_token(ctx, SL_PP_NOT, ps) == 0) {
+      op = OPERATOR_NOT;
+   } else if (_parse_token(ctx, SL_PP_MULASSIGN, ps) == 0) {
+      op = OPERATOR_MULASSIGN;
+   } else if (_parse_token(ctx, SL_PP_STAR, ps) == 0) {
+      op = OPERATOR_MULTIPLY;
+   } else if (_parse_token(ctx, SL_PP_DIVASSIGN, ps) == 0) {
+      op = OPERATOR_DIVASSIGN;
+   } else if (_parse_token(ctx, SL_PP_SLASH, ps) == 0) {
+      op = OPERATOR_DIVIDE;
+   } else if (_parse_token(ctx, SL_PP_LESSEQUAL, ps) == 0) {
+      op = OPERATOR_LESSEQUAL;
+   } else if (_parse_token(ctx, SL_PP_LESS, ps) == 0) {
+      op = OPERATOR_LESS;
+   } else if (_parse_token(ctx, SL_PP_GREATEREQUAL, ps) == 0) {
+      op = OPERATOR_GREATEREQUAL;
+   } else if (_parse_token(ctx, SL_PP_GREATER, ps) == 0) {
+      op = OPERATOR_GREATER;
+   } else if (_parse_token(ctx, SL_PP_XOR, ps) == 0) {
+      op = OPERATOR_LOGICALXOR;
+   } else {
+      return -1;
+   }
+
+   _emit(ctx, &ps->out, op);
+   return 0;
+}
+
+
+static int
+_parse_function_decl_identifier(struct parse_context *ctx,
+                                struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+   unsigned int e = _emit(ctx, &p.out, 0);
+
+   if (ctx->parsing_builtin && _parse_id(ctx, ctx->dict.__constructor, &p) == 0) {
+      _update(ctx, e, FUNCTION_CONSTRUCTOR);
+      *ps = p;
+      return 0;
+   }
+
+   if (ctx->parsing_builtin && _parse_id(ctx, ctx->dict.__operator, &p) == 0) {
+      _update(ctx, e, FUNCTION_OPERATOR);
+      if (_parse_overriden_operator(ctx, &p) == 0) {
+         *ps = p;
+         return 0;
+      }
+      return -1;
+   }
+
+   if (_parse_identifier(ctx, &p) == 0) {
+      _update(ctx, e, FUNCTION_ORDINARY);
+      *ps = p;
+      return 0;
+   }
+
+   return -1;
+}
+
+
+static int
+_parse_invariant_qualifier(struct parse_context *ctx,
+                           struct parse_state *ps)
+{
+   if (_parse_id(ctx, ctx->dict.invariant, ps)) {
+      return -1;
+   }
+   _emit(ctx, &ps->out, TYPE_INVARIANT);
+   return 0;
+}
+
+
+static int
+_parse_centroid_qualifier(struct parse_context *ctx,
+                          struct parse_state *ps)
+{
+   if (_parse_id(ctx, ctx->dict.centroid, ps)) {
+      return -1;
+   }
+   _emit(ctx, &ps->out, TYPE_CENTROID);
+   return 0;
+}
+
+
+static int
+_parse_type_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);
+   unsigned int e = _emit(ctx, &p.out, 0);
+   int id;
+
+   if (!input || input->token != SL_PP_IDENTIFIER) {
+      return -1;
+   }
+   id = input->data.identifier;
+
+   if (id == ctx->dict._const) {
+      _update(ctx, e, TYPE_QUALIFIER_CONST);
+   } else if (ctx->shader_type == 2 && id == ctx->dict.attribute) {
+      _update(ctx, e, TYPE_QUALIFIER_ATTRIBUTE);
+   } else if (id == ctx->dict.varying) {
+      _update(ctx, e, TYPE_QUALIFIER_VARYING);
+   } else if (id == ctx->dict.uniform) {
+      _update(ctx, e, TYPE_QUALIFIER_UNIFORM);
+   } else if (ctx->parsing_builtin && id == ctx->dict.__fixed_output) {
+      _update(ctx, e, TYPE_QUALIFIER_FIXEDOUTPUT);
+   } else if (ctx->parsing_builtin && id == ctx->dict.__fixed_input) {
+      _update(ctx, e, TYPE_QUALIFIER_FIXEDINPUT);
+   } else {
+      return -1;
+   }
+   _parse_token(ctx, SL_PP_IDENTIFIER, &p);
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_struct_declarator(struct parse_context *ctx,
+                         struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+   unsigned int e;
+
+   if (_parse_identifier(ctx, &p)) {
+      return -1;
+   }
+   e = _emit(ctx, &p.out, FIELD_NONE);
+   *ps = p;
+
+   if (_parse_token(ctx, SL_PP_LBRACKET, &p)) {
+      return 0;
+   }
+   if (_parse_constant_expression(ctx, &p)) {
+      _error(ctx, "expected constant integral expression");
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_RBRACKET, &p)) {
+      _error(ctx, "expected `]'");
+      return -1;
+   }
+   _update(ctx, e, FIELD_ARRAY);
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_struct_declarator_list(struct parse_context *ctx,
+                              struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_struct_declarator(ctx, &p)) {
+      return -1;
+   }
+
+   for (;;) {
+      *ps = p;
+      _emit(ctx, &p.out, FIELD_NEXT);
+      if (_parse_token(ctx, SL_PP_COMMA, &p)) {
+         return 0;
+      }
+      if (_parse_struct_declarator(ctx, &p)) {
+         return 0;
+      }
+   }
+}
+
+
+static int
+_parse_struct_declaration(struct parse_context *ctx,
+                          struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_type_specifier(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_struct_declarator_list(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_SEMICOLON, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, FIELD_NONE);
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_struct_declaration_list(struct parse_context *ctx,
+                               struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_struct_declaration(ctx, &p)) {
+      return -1;
+   }
+
+   for (;;) {
+      *ps = p;
+      _emit(ctx, &p.out, FIELD_NEXT);
+      if (_parse_struct_declaration(ctx, &p)) {
+         return 0;
+      }
+   }
+}
+
+
+static int
+_parse_struct_specifier(struct parse_context *ctx,
+                        struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_id(ctx, ctx->dict._struct, &p)) {
+      return -1;
+   }
+   if (_parse_identifier(ctx, &p)) {
+      _emit(ctx, &p.out, '\0');
+   }
+   if (_parse_token(ctx, SL_PP_LBRACE, &p)) {
+      _error(ctx, "expected `{'");
+      return -1;
+   }
+   if (_parse_struct_declaration_list(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_RBRACE, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, FIELD_NONE);
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_type_specifier_nonarray(struct parse_context *ctx,
+                               struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+   unsigned int e = _emit(ctx, &p.out, 0);
+   const struct sl_pp_token_info *input;
+   int id;
+
+   if (_parse_struct_specifier(ctx, &p) == 0) {
+      _update(ctx, e, TYPE_SPECIFIER_STRUCT);
+      *ps = p;
+      return 0;
+   }
+
+   input = _fetch_token(ctx, p.in);
+   if (!input || input->token != SL_PP_IDENTIFIER) {
+      return -1;
+   }
+   id = input->data.identifier;
+
+   if (id == ctx->dict._void) {
+      _update(ctx, e, TYPE_SPECIFIER_VOID);
+   } else if (id == ctx->dict._float) {
+      _update(ctx, e, TYPE_SPECIFIER_FLOAT);
+   } else if (id == ctx->dict._int) {
+      _update(ctx, e, TYPE_SPECIFIER_INT);
+   } else if (id == ctx->dict._bool) {
+      _update(ctx, e, TYPE_SPECIFIER_BOOL);
+   } else if (id == ctx->dict.vec2) {
+      _update(ctx, e, TYPE_SPECIFIER_VEC2);
+   } else if (id == ctx->dict.vec3) {
+      _update(ctx, e, TYPE_SPECIFIER_VEC3);
+   } else if (id == ctx->dict.vec4) {
+      _update(ctx, e, TYPE_SPECIFIER_VEC4);
+   } else if (id == ctx->dict.bvec2) {
+      _update(ctx, e, TYPE_SPECIFIER_BVEC2);
+   } else if (id == ctx->dict.bvec3) {
+      _update(ctx, e, TYPE_SPECIFIER_BVEC3);
+   } else if (id == ctx->dict.bvec4) {
+      _update(ctx, e, TYPE_SPECIFIER_BVEC4);
+   } else if (id == ctx->dict.ivec2) {
+      _update(ctx, e, TYPE_SPECIFIER_IVEC2);
+   } else if (id == ctx->dict.ivec3) {
+      _update(ctx, e, TYPE_SPECIFIER_IVEC3);
+   } else if (id == ctx->dict.ivec4) {
+      _update(ctx, e, TYPE_SPECIFIER_IVEC4);
+   } else if (id == ctx->dict.mat2) {
+      _update(ctx, e, TYPE_SPECIFIER_MAT2);
+   } else if (id == ctx->dict.mat3) {
+      _update(ctx, e, TYPE_SPECIFIER_MAT3);
+   } else if (id == ctx->dict.mat4) {
+      _update(ctx, e, TYPE_SPECIFIER_MAT4);
+   } else if (id == ctx->dict.mat2x3) {
+      _update(ctx, e, TYPE_SPECIFIER_MAT23);
+   } else if (id == ctx->dict.mat3x2) {
+      _update(ctx, e, TYPE_SPECIFIER_MAT32);
+   } else if (id == ctx->dict.mat2x4) {
+      _update(ctx, e, TYPE_SPECIFIER_MAT24);
+   } else if (id == ctx->dict.mat4x2) {
+      _update(ctx, e, TYPE_SPECIFIER_MAT42);
+   } else if (id == ctx->dict.mat3x4) {
+      _update(ctx, e, TYPE_SPECIFIER_MAT34);
+   } else if (id == ctx->dict.mat4x3) {
+      _update(ctx, e, TYPE_SPECIFIER_MAT43);
+   } else if (id == ctx->dict.sampler1D) {
+      _update(ctx, e, TYPE_SPECIFIER_SAMPLER1D);
+   } else if (id == ctx->dict.sampler2D) {
+      _update(ctx, e, TYPE_SPECIFIER_SAMPLER2D);
+   } else if (id == ctx->dict.sampler3D) {
+      _update(ctx, e, TYPE_SPECIFIER_SAMPLER3D);
+   } else if (id == ctx->dict.samplerCube) {
+      _update(ctx, e, TYPE_SPECIFIER_SAMPLERCUBE);
+   } else if (id == ctx->dict.sampler1DShadow) {
+      _update(ctx, e, TYPE_SPECIFIER_SAMPLER1DSHADOW);
+   } else if (id == ctx->dict.sampler2DShadow) {
+      _update(ctx, e, TYPE_SPECIFIER_SAMPLER2DSHADOW);
+   } else if (id == ctx->dict.sampler2DRect) {
+      _update(ctx, e, TYPE_SPECIFIER_SAMPLER2DRECT);
+   } else if (id == ctx->dict.sampler2DRectShadow) {
+      _update(ctx, e, TYPE_SPECIFIER_SAMPLER2DRECTSHADOW);
+   } else if (_parse_identifier(ctx, &p) == 0) {
+      _update(ctx, e, TYPE_SPECIFIER_TYPENAME);
+      *ps = p;
+      return 0;
+   } else {
+      return -1;
+   }
+
+   _parse_token(ctx, SL_PP_IDENTIFIER, &p);
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_type_specifier_array(struct parse_context *ctx,
+                            struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_token(ctx, SL_PP_LBRACKET, &p)) {
+      return -1;
+   }
+   if (_parse_constant_expression(ctx, &p)) {
+      _error(ctx, "expected constant integral expression");
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_RBRACKET, &p)) {
+      _error(ctx, "expected `]'");
+      return -1;
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_type_specifier(struct parse_context *ctx,
+                      struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+   unsigned int e;
+
+   if (_parse_type_specifier_nonarray(ctx, &p)) {
+      return -1;
+   }
+
+   e = _emit(ctx, &p.out, TYPE_SPECIFIER_ARRAY);
+   if (_parse_type_specifier_array(ctx, &p)) {
+      _update(ctx, e, TYPE_SPECIFIER_NONARRAY);
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_fully_specified_type(struct parse_context *ctx,
+                            struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   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)) {
+      _emit(ctx, &p.out, TYPE_QUALIFIER_NONE);
+   }
+   if (_parse_precision(ctx, &p)) {
+      _emit(ctx, &p.out, PRECISION_DEFAULT);
+   }
+   if (_parse_type_specifier(ctx, &p)) {
+      return -1;
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_function_header(struct parse_context *ctx,
+                       struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_fully_specified_type(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_function_decl_identifier(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_LPAREN, &p)) {
+      return -1;
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_parameter_qualifier(struct parse_context *ctx,
+                           struct parse_state *ps)
+{
+   unsigned int e = _emit(ctx, &ps->out, PARAM_QUALIFIER_IN);
+
+   if (_parse_id(ctx, ctx->dict.out, ps) == 0) {
+      _update(ctx, e, PARAM_QUALIFIER_OUT);
+   } else if (_parse_id(ctx, ctx->dict.inout, ps) == 0) {
+      _update(ctx, e, PARAM_QUALIFIER_INOUT);
+   } else {
+      _parse_id(ctx, ctx->dict.in, ps);
+   }
+   return 0;
+}
+
+
+static int
+_parse_function_identifier(struct parse_context *ctx,
+                           struct parse_state *ps)
+{
+   struct parse_state p;
+   unsigned int e;
+
+   if (_parse_identifier(ctx, ps)) {
+      return -1;
+   }
+   e = _emit(ctx, &ps->out, FUNCTION_CALL_NONARRAY);
+
+   p = *ps;
+   if (_parse_token(ctx, SL_PP_LBRACKET, &p)) {
+      return 0;
+   }
+   if (_parse_constant_expression(ctx, &p)) {
+      _error(ctx, "expected constant integral expression");
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_RBRACKET, &p)) {
+      _error(ctx, "expected `]'");
+      return -1;
+   }
+   _update(ctx, e, FUNCTION_CALL_ARRAY);
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_function_call_header(struct parse_context *ctx,
+                            struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_function_identifier(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_LPAREN, &p)) {
+      return -1;
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_assign_expression(struct parse_context *ctx,
+                         struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+   unsigned int op;
+
+   if (_parse_unary_expression(ctx, &p)) {
+      return -1;
+   }
+
+   if (_parse_token(ctx, SL_PP_ASSIGN, &p) == 0) {
+      op = OP_ASSIGN;
+   } else if (_parse_token(ctx, SL_PP_MULASSIGN, &p) == 0) {
+      op = OP_MULASSIGN;
+   } else if (_parse_token(ctx, SL_PP_DIVASSIGN, &p) == 0) {
+      op = OP_DIVASSIGN;
+   } else if (_parse_token(ctx, SL_PP_ADDASSIGN, &p) == 0) {
+      op = OP_ADDASSIGN;
+   } else if (_parse_token(ctx, SL_PP_SUBASSIGN, &p) == 0) {
+      op = OP_SUBASSIGN;
+   } else {
+      return -1;
+   }
+
+   if (_parse_assignment_expression(ctx, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, op);
+
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_assignment_expression(struct parse_context *ctx,
+                             struct parse_state *ps)
+{
+   if (_parse_assign_expression(ctx, ps) == 0) {
+      return 0;
+   }
+
+   if (_parse_conditional_expression(ctx, ps) == 0) {
+      return 0;
+   }
+
+   return -1;
+}
+
+
+static int
+_parse_function_call_header_with_parameters(struct parse_context *ctx,
+                                            struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_function_call_header(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_assignment_expression(ctx, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, OP_END);
+   for (;;) {
+      *ps = p;
+      if (_parse_token(ctx, SL_PP_COMMA, &p)) {
+         return 0;
+      }
+      if (_parse_assignment_expression(ctx, &p)) {
+         return 0;
+      }
+      _emit(ctx, &p.out, OP_END);
+   }
+}
+
+
+static int
+_parse_function_call_header_no_parameters(struct parse_context *ctx,
+                                          struct parse_state *ps)
+{
+   if (_parse_function_call_header(ctx, ps)) {
+      return -1;
+   }
+   _parse_id(ctx, ctx->dict._void, ps);
+   return 0;
+}
+
+
+static int
+_parse_function_call_generic(struct parse_context *ctx,
+                             struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_function_call_header_with_parameters(ctx, &p) == 0) {
+      if (_parse_token(ctx, SL_PP_RPAREN, &p) == 0) {
+         *ps = p;
+         return 0;
+      }
+      _error(ctx, "expected `)'");
+      return -1;
+   }
+
+   p = *ps;
+   if (_parse_function_call_header_no_parameters(ctx, &p) == 0) {
+      if (_parse_token(ctx, SL_PP_RPAREN, &p) == 0) {
+         *ps = p;
+         return 0;
+      }
+      _error(ctx, "expected `)'");
+      return -1;
+   }
+
+   return -1;
+}
+
+
+static int
+_parse_method_call(struct parse_context *ctx,
+                   struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   _emit(ctx, &p.out, OP_METHOD);
+   if (_parse_identifier(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_DOT, &p)) {
+      return -1;
+   }
+   if (_parse_function_call_generic(ctx, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, OP_END);
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_regular_function_call(struct parse_context *ctx,
+                             struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   _emit(ctx, &p.out, OP_CALL);
+   if (_parse_function_call_generic(ctx, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, OP_END);
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_function_call(struct parse_context *ctx,
+                     struct parse_state *ps)
+{
+   if (_parse_regular_function_call(ctx, ps) == 0) {
+      return 0;
+   }
+
+   if (_parse_method_call(ctx, ps) == 0) {
+      return 0;
+   }
+
+   return -1;
+}
+
+
+static int
+_parse_expression(struct parse_context *ctx,
+                  struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_assignment_expression(ctx, &p)) {
+      return -1;
+   }
+
+   for (;;) {
+      *ps = p;
+      if (_parse_token(ctx, SL_PP_COMMA, &p)) {
+         return 0;
+      }
+      if (_parse_assignment_expression(ctx, &p)) {
+         return 0;
+      }
+      _emit(ctx, &p.out, OP_SEQUENCE);
+   }
+}
+
+
+static int
+_parse_postfix_expression(struct parse_context *ctx,
+                          struct parse_state *ps)
+{
+   struct parse_state p;
+
+   if (_parse_function_call(ctx, ps)) {
+      if (_parse_primary_expression(ctx, ps)) {
+         return -1;
+      }
+   }
+
+   for (p = *ps;;) {
+      *ps = p;
+      if (_parse_token(ctx, SL_PP_INCREMENT, &p) == 0) {
+         _emit(ctx, &p.out, OP_POSTINCREMENT);
+      } else if (_parse_token(ctx, SL_PP_DECREMENT, &p) == 0) {
+         _emit(ctx, &p.out, OP_POSTDECREMENT);
+      } else if (_parse_token(ctx, SL_PP_LBRACKET, &p) == 0) {
+         if (_parse_expression(ctx, &p)) {
+            _error(ctx, "expected an integral expression");
+            return -1;
+         }
+         if (_parse_token(ctx, SL_PP_RBRACKET, &p)) {
+            _error(ctx, "expected `]'");
+            return -1;
+         }
+         _emit(ctx, &p.out, OP_SUBSCRIPT);
+      } else if (_parse_token(ctx, SL_PP_DOT, &p) == 0) {
+         _emit(ctx, &p.out, OP_FIELD);
+         if (_parse_identifier(ctx, &p)) {
+            return 0;
+         }
+      } else {
+         return 0;
+      }
+   }
+}
+
+
+static int
+_parse_unary_expression(struct parse_context *ctx,
+                        struct parse_state *ps)
+{
+   struct parse_state p;
+   unsigned int op;
+
+   if (_parse_postfix_expression(ctx, ps) == 0) {
+      return 0;
+   }
+
+   p = *ps;
+   if (_parse_token(ctx, SL_PP_INCREMENT, &p) == 0) {
+      op = OP_PREINCREMENT;
+   } else if (_parse_token(ctx, SL_PP_DECREMENT, &p) == 0) {
+      op = OP_PREDECREMENT;
+   } else if (_parse_token(ctx, SL_PP_PLUS, &p) == 0) {
+      op = OP_PLUS;
+   } else if (_parse_token(ctx, SL_PP_MINUS, &p) == 0) {
+      op = OP_MINUS;
+   } else if (_parse_token(ctx, SL_PP_NOT, &p) == 0) {
+      op = OP_NOT;
+   } else {
+      return -1;
+   }
+
+   if (_parse_unary_expression(ctx, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, op);
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_multiplicative_expression(struct parse_context *ctx,
+                                 struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_unary_expression(ctx, &p)) {
+      return -1;
+   }
+   for (;;) {
+      unsigned int op;
+
+      *ps = p;
+      if (_parse_token(ctx, SL_PP_STAR, &p) == 0) {
+         op = OP_MULTIPLY;
+      } else if (_parse_token(ctx, SL_PP_SLASH, &p) == 0) {
+         op = OP_DIVIDE;
+      } else {
+         return 0;
+      }
+      if (_parse_unary_expression(ctx, &p)) {
+         return 0;
+      }
+      _emit(ctx, &p.out, op);
+   }
+}
+
+
+static int
+_parse_additive_expression(struct parse_context *ctx,
+                           struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_multiplicative_expression(ctx, &p)) {
+      return -1;
+   }
+   for (;;) {
+      unsigned int op;
+
+      *ps = p;
+      if (_parse_token(ctx, SL_PP_PLUS, &p) == 0) {
+         op = OP_ADD;
+      } else if (_parse_token(ctx, SL_PP_MINUS, &p) == 0) {
+         op = OP_SUBTRACT;
+      } else {
+         return 0;
+      }
+      if (_parse_multiplicative_expression(ctx, &p)) {
+         return 0;
+      }
+      _emit(ctx, &p.out, op);
+   }
+}
+
+
+static int
+_parse_relational_expression(struct parse_context *ctx,
+                             struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_additive_expression(ctx, &p)) {
+      return -1;
+   }
+   for (;;) {
+      unsigned int op;
+
+      *ps = p;
+      if (_parse_token(ctx, SL_PP_LESS, &p) == 0) {
+         op = OP_LESS;
+      } else if (_parse_token(ctx, SL_PP_GREATER, &p) == 0) {
+         op = OP_GREATER;
+      } else if (_parse_token(ctx, SL_PP_LESSEQUAL, &p) == 0) {
+         op = OP_LESSEQUAL;
+      } else if (_parse_token(ctx, SL_PP_GREATEREQUAL, &p) == 0) {
+         op = OP_GREATEREQUAL;
+      } else {
+         return 0;
+      }
+      if (_parse_additive_expression(ctx, &p)) {
+         return 0;
+      }
+      _emit(ctx, &p.out, op);
+   }
+}
+
+
+static int
+_parse_equality_expression(struct parse_context *ctx,
+                           struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_relational_expression(ctx, &p)) {
+      return -1;
+   }
+   for (;;) {
+      unsigned int op;
+
+      *ps = p;
+      if (_parse_token(ctx, SL_PP_EQUAL, &p) == 0) {
+         op = OP_EQUAL;
+      } else if (_parse_token(ctx, SL_PP_NOTEQUAL, &p) == 0) {
+         op = OP_NOTEQUAL;
+      } else {
+         return 0;
+      }
+      if (_parse_relational_expression(ctx, &p)) {
+         return -1;
+      }
+      _emit(ctx, &p.out, op);
+   }
+}
+
+
+static int
+_parse_logical_and_expression(struct parse_context *ctx,
+                              struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_equality_expression(ctx, &p)) {
+      return -1;
+   }
+   for (;;) {
+      *ps = p;
+      if (_parse_token(ctx, SL_PP_AND, &p)) {
+         return 0;
+      }
+      if (_parse_equality_expression(ctx, &p)) {
+         return 0;
+      }
+      _emit(ctx, &p.out, OP_LOGICALAND);
+   }
+}
+
+
+static int
+_parse_logical_xor_expression(struct parse_context *ctx,
+                              struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_logical_and_expression(ctx, &p)) {
+      return -1;
+   }
+   for (;;) {
+      *ps = p;
+      if (_parse_token(ctx, SL_PP_XOR, &p)) {
+         return 0;
+      }
+      if (_parse_logical_and_expression(ctx, &p)) {
+         return 0;
+      }
+      _emit(ctx, &p.out, OP_LOGICALXOR);
+   }
+}
+
+
+static int
+_parse_logical_or_expression(struct parse_context *ctx,
+                             struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_logical_xor_expression(ctx, &p)) {
+      return -1;
+   }
+   for (;;) {
+      *ps = p;
+      if (_parse_token(ctx, SL_PP_OR, &p)) {
+         return 0;
+      }
+      if (_parse_logical_xor_expression(ctx, &p)) {
+         return 0;
+      }
+      _emit(ctx, &p.out, OP_LOGICALOR);
+   }
+}
+
+
+static int
+_parse_conditional_expression(struct parse_context *ctx,
+                              struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_logical_or_expression(ctx, &p)) {
+      return -1;
+   }
+   for (;;) {
+      *ps = p;
+      if (_parse_token(ctx, SL_PP_QUESTION, &p)) {
+         return 0;
+      }
+      if (_parse_expression(ctx, &p)) {
+         return 0;
+      }
+      if (_parse_token(ctx, SL_PP_COLON, &p)) {
+         return 0;
+      }
+      if (_parse_conditional_expression(ctx, &p)) {
+         return 0;
+      }
+      _emit(ctx, &p.out, OP_SELECT);
+   }
+}
+
+
+static int
+_parse_constant_expression(struct parse_context *ctx,
+                           struct parse_state *ps)
+{
+   if (_parse_conditional_expression(ctx, ps)) {
+      return -1;
+   }
+   _emit(ctx, &ps->out, OP_END);
+   return 0;
+}
+
+
+static int
+_parse_parameter_declarator_array(struct parse_context *ctx,
+                                  struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_token(ctx, SL_PP_LBRACKET, &p)) {
+      return -1;
+   }
+   if (_parse_constant_expression(ctx, &p)) {
+      _error(ctx, "expected constant integral expression");
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_RBRACKET, &p)) {
+      _error(ctx, "expected `]'");
+      return -1;
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_parameter_declarator(struct parse_context *ctx,
+                            struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+   unsigned int e;
+
+   if (_parse_type_specifier(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_identifier(ctx, &p)) {
+      return -1;
+   }
+   e = _emit(ctx, &p.out, PARAMETER_ARRAY_PRESENT);
+   if (_parse_parameter_declarator_array(ctx, &p)) {
+      _update(ctx, e, PARAMETER_ARRAY_NOT_PRESENT);
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_parameter_type_specifier_array(struct parse_context *ctx,
+                                      struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_token(ctx, SL_PP_LBRACKET, &p)) {
+      return -1;
+   }
+   if (_parse_constant_expression(ctx, &p)) {
+      _error(ctx, "expected constant integral expression");
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_RBRACKET, &p)) {
+      _error(ctx, "expected `]'");
+      return -1;
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_parameter_type_specifier(struct parse_context *ctx,
+                                struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+   unsigned int e;
+
+   if (_parse_type_specifier(ctx, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, '\0');
+
+   e = _emit(ctx, &p.out, PARAMETER_ARRAY_PRESENT);
+   if (_parse_parameter_type_specifier_array(ctx, &p)) {
+      _update(ctx, e, PARAMETER_ARRAY_NOT_PRESENT);
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_parameter_declaration(struct parse_context *ctx,
+                             struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+   unsigned int e = _emit(ctx, &p.out, PARAMETER_NEXT);
+
+   (void) e;
+
+   if (_parse_type_qualifier(ctx, &p)) {
+      _emit(ctx, &p.out, TYPE_QUALIFIER_NONE);
+   }
+   _parse_parameter_qualifier(ctx, &p);
+   if (_parse_precision(ctx, &p)) {
+      _emit(ctx, &p.out, PRECISION_DEFAULT);
+   }
+   if (_parse_parameter_declarator(ctx, &p) == 0) {
+      *ps = p;
+      return 0;
+   }
+   if (_parse_parameter_type_specifier(ctx, &p) == 0) {
+      *ps = p;
+      return 0;
+   }
+
+   return -1;
+}
+
+
+static int
+_parse_function_header_with_parameters(struct parse_context *ctx,
+                                       struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_function_header(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_parameter_declaration(ctx, &p)) {
+      return -1;
+   }
+
+   for (;;) {
+      *ps = p;
+      if (_parse_token(ctx, SL_PP_COMMA, &p)) {
+         return 0;
+      }
+      if (_parse_parameter_declaration(ctx, &p)) {
+         return 0;
+      }
+   }
+}
+
+
+static int
+_parse_function_declarator(struct parse_context *ctx,
+                           struct parse_state *ps)
+{
+   if (_parse_function_header_with_parameters(ctx, ps) == 0) {
+      return 0;
+   }
+
+   if (_parse_function_header(ctx, ps) == 0) {
+      return 0;
+   }
+
+   return -1;
+}
+
+
+static int
+_parse_function_prototype(struct parse_context *ctx,
+                          struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_function_header(ctx, &p) == 0) {
+      if (_parse_id(ctx, ctx->dict._void, &p) == 0) {
+         if (_parse_token(ctx, SL_PP_RPAREN, &p) == 0) {
+            _emit(ctx, &p.out, PARAMETER_NONE);
+            *ps = p;
+            return 0;
+         }
+         _error(ctx, "expected `)'");
+         return -1;
+      }
+   }
+
+   p = *ps;
+   if (_parse_function_declarator(ctx, &p) == 0) {
+      if (_parse_token(ctx, SL_PP_RPAREN, &p) == 0) {
+         _emit(ctx, &p.out, PARAMETER_NONE);
+         *ps = p;
+         return 0;
+      }
+      _error(ctx, "expected `)'");
+      return -1;
+   }
+
+   return -1;
+}
+
+
+static int
+_parse_precision(struct parse_context *ctx,
+                 struct parse_state *ps)
+{
+   const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in);
+   int id;
+   unsigned int precision;
+
+   if (!input || input->token != SL_PP_IDENTIFIER) {
+      return -1;
+   }
+   id = input->data.identifier;
+
+   if (id == ctx->dict.lowp) {
+      precision = PRECISION_LOW;
+   } else if (id == ctx->dict.mediump) {
+      precision = PRECISION_MEDIUM;
+   } else if (id == ctx->dict.highp) {
+      precision = PRECISION_HIGH;
+   } else {
+      return -1;
+   }
+
+   _parse_token(ctx, SL_PP_IDENTIFIER, ps);
+   _emit(ctx, &ps->out, precision);
+   return 0;
+}
+
+
+static int
+_parse_prectype(struct parse_context *ctx,
+                 struct parse_state *ps)
+{
+   const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in);
+   int id;
+   unsigned int type;
+
+   if (!input || input->token != SL_PP_IDENTIFIER) {
+      return -1;
+   }
+   id = input->data.identifier;
+
+   if (id == ctx->dict._int) {
+      type = TYPE_SPECIFIER_INT;
+   } else if (id == ctx->dict._float) {
+      type = TYPE_SPECIFIER_FLOAT;
+   } else if (id == ctx->dict.sampler1D) {
+      type = TYPE_SPECIFIER_SAMPLER1D;
+   } else if (id == ctx->dict.sampler2D) {
+      type = TYPE_SPECIFIER_SAMPLER2D;
+   } else if (id == ctx->dict.sampler3D) {
+      type = TYPE_SPECIFIER_SAMPLER3D;
+   } else if (id == ctx->dict.samplerCube) {
+      type = TYPE_SPECIFIER_SAMPLERCUBE;
+   } else if (id == ctx->dict.sampler1DShadow) {
+      type = TYPE_SPECIFIER_SAMPLER1DSHADOW;
+   } else if (id == ctx->dict.sampler2DShadow) {
+      type = TYPE_SPECIFIER_SAMPLER2DSHADOW;
+   } else if (id == ctx->dict.sampler2DRect) {
+      type = TYPE_SPECIFIER_SAMPLER2DRECT;
+   } else if (id == ctx->dict.sampler2DRectShadow) {
+      type = TYPE_SPECIFIER_SAMPLER2DRECTSHADOW;
+   } else {
+      return -1;
+   }
+
+   _parse_token(ctx, SL_PP_IDENTIFIER, ps);
+   _emit(ctx, &ps->out, type);
+   return 0;
+}
+
+
+static int
+_parse_precision_stmt(struct parse_context *ctx,
+                      struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_id(ctx, ctx->dict.precision, &p)) {
+      return -1;
+   }
+   if (_parse_precision(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_prectype(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_SEMICOLON, &p)) {
+      return -1;
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_floatconstant(struct parse_context *ctx,
+                     struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   _emit(ctx, &p.out, OP_PUSH_FLOAT);
+   if (_parse_float(ctx, &p)) {
+      return -1;
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_intconstant(struct parse_context *ctx,
+                   struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   _emit(ctx, &p.out, OP_PUSH_INT);
+   if (_parse_uint(ctx, &p)) {
+      return -1;
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_boolconstant(struct parse_context *ctx,
+                    struct parse_state *ps)
+{
+   if (_parse_id(ctx, ctx->dict._false, ps) == 0) {
+      _emit(ctx, &ps->out, OP_PUSH_BOOL);
+      _emit(ctx, &ps->out, 2);  /* radix */
+      _emit(ctx, &ps->out, '0');
+      _emit(ctx, &ps->out, '\0');
+      return 0;
+   }
+
+   if (_parse_id(ctx, ctx->dict._true, ps) == 0) {
+      _emit(ctx, &ps->out, OP_PUSH_BOOL);
+      _emit(ctx, &ps->out, 2);  /* radix */
+      _emit(ctx, &ps->out, '1');
+      _emit(ctx, &ps->out, '\0');
+      return 0;
+   }
+
+   return -1;
+}
+
+
+static int
+_parse_variable_identifier(struct parse_context *ctx,
+                           struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   _emit(ctx, &p.out, OP_PUSH_IDENTIFIER);
+   if (_parse_identifier(ctx, &p)) {
+      return -1;
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_primary_expression(struct parse_context *ctx,
+                          struct parse_state *ps)
+{
+   struct parse_state p;
+
+   if (_parse_floatconstant(ctx, ps) == 0) {
+      return 0;
+   }
+   if (_parse_boolconstant(ctx, ps) == 0) {
+      return 0;
+   }
+   if (_parse_intconstant(ctx, ps) == 0) {
+      return 0;
+   }
+   if (_parse_variable_identifier(ctx, ps) == 0) {
+      return 0;
+   }
+
+   p = *ps;
+   if (_parse_token(ctx, SL_PP_LPAREN, &p)) {
+      return -1;
+   }
+   if (_parse_expression(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_RPAREN, &p)) {
+      return -1;
+   }
+
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_asm_argument(struct parse_context *ctx,
+                    struct parse_state *ps)
+{
+   if (_parse_variable_identifier(ctx, ps) == 0) {
+      struct parse_state p = *ps;
+
+      if (_parse_token(ctx, SL_PP_DOT, &p)) {
+         return 0;
+      }
+      _emit(ctx, &p.out, OP_FIELD);
+      if (_parse_identifier(ctx, &p)) {
+         return 0;
+      }
+      *ps = p;
+      return 0;
+   }
+
+   if (_parse_floatconstant(ctx, ps) == 0) {
+      return 0;
+   }
+
+   return -1;
+}
+
+
+static int
+_parse_asm_arguments(struct parse_context *ctx,
+                     struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_asm_argument(ctx, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, OP_END);
+
+   for (;;) {
+      *ps = p;
+      if (_parse_token(ctx, SL_PP_COMMA, &p)) {
+         return 0;
+      }
+      if (_parse_asm_argument(ctx, &p)) {
+         return 0;
+      }
+      _emit(ctx, &p.out, OP_END);
+   }
+}
+
+
+static int
+_parse_asm_statement(struct parse_context *ctx,
+                     struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_id(ctx, ctx->dict.___asm, &p)) {
+      return -1;
+   }
+   if (_parse_identifier(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_asm_arguments(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_SEMICOLON, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, OP_END);
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_selection_statement(struct parse_context *ctx,
+                           struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   _emit(ctx, &p.out, OP_IF);
+   if (_parse_id(ctx, ctx->dict._if, &p)) {
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_LPAREN, &p)) {
+      _error(ctx, "expected `('");
+      return -1;
+   }
+   if (_parse_expression(ctx, &p)) {
+      _error(ctx, "expected an expression");
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_RPAREN, &p)) {
+      _error(ctx, "expected `)'");
+      return -1;
+   }
+   _emit(ctx, &p.out, OP_END);
+   if (_parse_statement(ctx, &p)) {
+      return -1;
+   }
+
+   *ps = p;
+   if (_parse_id(ctx, ctx->dict._else, &p) == 0) {
+      if (_parse_statement(ctx, &p) == 0) {
+         *ps = p;
+         return 0;
+      }
+   }
+
+   _emit(ctx, &ps->out, OP_EXPRESSION);
+   _emit(ctx, &ps->out, OP_PUSH_VOID);
+   _emit(ctx, &ps->out, OP_END);
+   return 0;
+}
+
+
+static int
+_parse_expression_statement(struct parse_context *ctx,
+                            struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_expression(ctx, &p)) {
+      _emit(ctx, &p.out, OP_PUSH_VOID);
+   }
+   if (_parse_token(ctx, SL_PP_SEMICOLON, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, OP_END);
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_for_init_statement(struct parse_context *ctx,
+                          struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+   unsigned int e = _emit(ctx, &p.out, OP_EXPRESSION);
+
+   if (_parse_expression_statement(ctx, &p) == 0) {
+      *ps = p;
+      return 0;
+   }
+
+   if (_parse_declaration(ctx, &p) == 0) {
+      _update(ctx, e, OP_DECLARE);
+      *ps = p;
+      return 0;
+   }
+
+   return -1;
+}
+
+
+static int
+_parse_initializer(struct parse_context *ctx,
+                   struct parse_state *ps)
+{
+   if (_parse_assignment_expression(ctx, ps) == 0) {
+      _emit(ctx, &ps->out, OP_END);
+      return 0;
+   }
+   return -1;
+}
+
+
+static int
+_parse_condition_initializer(struct parse_context *ctx,
+                             struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   _emit(ctx, &p.out, OP_DECLARE);
+   _emit(ctx, &p.out, DECLARATION_INIT_DECLARATOR_LIST);
+   if (_parse_fully_specified_type(ctx, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, VARIABLE_IDENTIFIER);
+   if (_parse_identifier(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_ASSIGN, &p)) {
+      _error(ctx, "expected `='");
+      return -1;
+   }
+   _emit(ctx, &p.out, VARIABLE_INITIALIZER);
+   if (_parse_initializer(ctx, &p)) {
+      _error(ctx, "expected an initialiser");
+      return -1;
+   }
+   _emit(ctx, &p.out, DECLARATOR_NONE);
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_condition(struct parse_context *ctx,
+                 struct parse_state *ps)
+{
+   struct parse_state p;
+
+   if (_parse_condition_initializer(ctx, ps) == 0) {
+      return 0;
+   }
+
+   p = *ps;
+   _emit(ctx, &p.out, OP_EXPRESSION);
+   if (_parse_expression(ctx, &p) == 0) {
+      _emit(ctx, &p.out, OP_END);
+      *ps = p;
+      return 0;
+   }
+
+   return -1;
+}
+
+
+static int
+_parse_for_rest_statement(struct parse_context *ctx,
+                          struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_condition(ctx, &p)) {
+      _emit(ctx, &p.out, OP_EXPRESSION);
+      _emit(ctx, &p.out, OP_PUSH_BOOL);
+      _emit(ctx, &p.out, 2);
+      _emit(ctx, &p.out, '1');
+      _emit(ctx, &p.out, '\0');
+      _emit(ctx, &p.out, OP_END);
+   }
+   if (_parse_token(ctx, SL_PP_SEMICOLON, &p)) {
+      return -1;
+   }
+   if (_parse_expression(ctx, &p)) {
+      _emit(ctx, &p.out, OP_PUSH_VOID);
+   }
+   _emit(ctx, &p.out, OP_END);
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_iteration_statement(struct parse_context *ctx,
+                           struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_id(ctx, ctx->dict._while, &p) == 0) {
+      _emit(ctx, &p.out, OP_WHILE);
+      if (_parse_token(ctx, SL_PP_LPAREN, &p)) {
+         _error(ctx, "expected `('");
+         return -1;
+      }
+      if (_parse_condition(ctx, &p)) {
+         _error(ctx, "expected an expression");
+         return -1;
+      }
+      if (_parse_token(ctx, SL_PP_RPAREN, &p)) {
+         _error(ctx, "expected `)'");
+         return -1;
+      }
+      if (_parse_statement(ctx, &p)) {
+         return -1;
+      }
+      *ps = p;
+      return 0;
+   }
+
+   if (_parse_id(ctx, ctx->dict._do, &p) == 0) {
+      _emit(ctx, &p.out, OP_DO);
+      if (_parse_statement(ctx, &p)) {
+         return -1;
+      }
+      if (_parse_id(ctx, ctx->dict._while, &p)) {
+         return -1;
+      }
+      if (_parse_token(ctx, SL_PP_LPAREN, &p)) {
+         _error(ctx, "expected `('");
+         return -1;
+      }
+      if (_parse_expression(ctx, &p)) {
+         _error(ctx, "expected an expression");
+         return -1;
+      }
+      if (_parse_token(ctx, SL_PP_RPAREN, &p)) {
+         _error(ctx, "expected `)'");
+         return -1;
+      }
+      _emit(ctx, &p.out, OP_END);
+      if (_parse_token(ctx, SL_PP_SEMICOLON, &p)) {
+         _error(ctx, "expected `;'");
+         return -1;
+      }
+      *ps = p;
+      return 0;
+   }
+
+   if (_parse_id(ctx, ctx->dict._for, &p) == 0) {
+      _emit(ctx, &p.out, OP_FOR);
+      if (_parse_token(ctx, SL_PP_LPAREN, &p)) {
+         _error(ctx, "expected `('");
+         return -1;
+      }
+      if (_parse_for_init_statement(ctx, &p)) {
+         return -1;
+      }
+      if (_parse_for_rest_statement(ctx, &p)) {
+         return -1;
+      }
+      if (_parse_token(ctx, SL_PP_RPAREN, &p)) {
+         _error(ctx, "expected `)'");
+         return -1;
+      }
+      if (_parse_statement(ctx, &p)) {
+         return -1;
+      }
+      *ps = p;
+      return 0;
+   }
+
+   return -1;
+}
+
+
+static int
+_parse_jump_statement(struct parse_context *ctx,
+                      struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+   unsigned int e = _emit(ctx, &p.out, 0);
+
+   if (_parse_id(ctx, ctx->dict._continue, &p) == 0) {
+      _update(ctx, e, OP_CONTINUE);
+   } else if (_parse_id(ctx, ctx->dict._break, &p) == 0) {
+      _update(ctx, e, OP_BREAK);
+   } else if (_parse_id(ctx, ctx->dict._return, &p) == 0) {
+      _update(ctx, e, OP_RETURN);
+      if (_parse_expression(ctx, &p)) {
+         _emit(ctx, &p.out, OP_PUSH_VOID);
+      }
+      _emit(ctx, &p.out, OP_END);
+   } else if (ctx->shader_type == 1 && _parse_id(ctx, ctx->dict.discard, &p) == 0) {
+      _update(ctx, e, OP_DISCARD);
+   } else {
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_SEMICOLON, &p)) {
+      return -1;
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_simple_statement(struct parse_context *ctx,
+                        struct parse_state *ps)
+{
+   struct parse_state p;
+   unsigned int e;
+
+   if (_parse_selection_statement(ctx, ps) == 0) {
+      return 0;
+   }
+
+   if (_parse_iteration_statement(ctx, ps) == 0) {
+      return 0;
+   }
+
+   if (_parse_jump_statement(ctx, ps) == 0) {
+      return 0;
+   }
+
+   p = *ps;
+   e = _emit(ctx, &p.out, OP_EXPRESSION);
+   if (_parse_expression_statement(ctx, &p) == 0) {
+      *ps = p;
+      return 0;
+   }
+
+   if (_parse_precision_stmt(ctx, &p) == 0) {
+      _update(ctx, e, OP_PRECISION);
+      *ps = p;
+      return 0;
+   }
+
+   if (ctx->parsing_builtin && _parse_asm_statement(ctx, &p) == 0) {
+      _update(ctx, e, OP_ASM);
+      *ps = p;
+      return 0;
+   }
+
+   if (_parse_declaration(ctx, &p) == 0) {
+      _update(ctx, e, OP_DECLARE);
+      *ps = p;
+      return 0;
+   }
+
+   return -1;
+}
+
+
+static int
+_parse_compound_statement(struct parse_context *ctx,
+                          struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_token(ctx, SL_PP_LBRACE, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, OP_BLOCK_BEGIN_NEW_SCOPE);
+   _parse_statement_list(ctx, &p);
+   if (_parse_token(ctx, SL_PP_RBRACE, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, OP_END);
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_statement(struct parse_context *ctx,
+                 struct parse_state *ps)
+{
+   if (_parse_compound_statement(ctx, ps) == 0) {
+      return 0;
+   }
+
+   if (_parse_simple_statement(ctx, ps) == 0) {
+      return 0;
+   }
+
+   return -1;
+}
+
+
+static int
+_parse_statement_list(struct parse_context *ctx,
+                      struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_statement(ctx, &p)) {
+      return -1;
+   }
+
+   for (;;) {
+      *ps = p;
+      if (_parse_statement(ctx, &p)) {
+         return 0;
+      }
+   }
+}
+
+
+static int
+_parse_compound_statement_no_new_scope(struct parse_context *ctx,
+                                       struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_token(ctx, SL_PP_LBRACE, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, OP_BLOCK_BEGIN_NO_NEW_SCOPE);
+   _parse_statement_list(ctx, &p);
+   if (_parse_token(ctx, SL_PP_RBRACE, &p)) {
+      return -1;
+   }
+   _emit(ctx, &p.out, OP_END);
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_function_definition(struct parse_context *ctx,
+                           struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_function_prototype(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_compound_statement_no_new_scope(ctx, &p)) {
+      return -1;
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_invariant_stmt(struct parse_context *ctx,
+                      struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_id(ctx, ctx->dict.invariant, &p)) {
+      return -1;
+   }
+   if (_parse_identifier(ctx, &p)) {
+      return -1;
+   }
+   if (_parse_token(ctx, SL_PP_SEMICOLON, &p)) {
+      return -1;
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_single_declaration(struct parse_context *ctx,
+                          struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+   unsigned int e;
+
+   if (_parse_fully_specified_type(ctx, &p)) {
+      return -1;
+   }
+
+   e = _emit(ctx, &p.out, VARIABLE_IDENTIFIER);
+   if (_parse_identifier(ctx, &p)) {
+      _update(ctx, e, VARIABLE_NONE);
+      *ps = p;
+      return 0;
+   }
+
+   e = _emit(ctx, &p.out, VARIABLE_NONE);
+   *ps = p;
+
+   if (_parse_token(ctx, SL_PP_ASSIGN, &p) == 0) {
+      _update(ctx, e, VARIABLE_INITIALIZER);
+      if (_parse_initializer(ctx, &p) == 0) {
+         *ps = p;
+         return 0;
+      }
+      _error(ctx, "expected an initialiser");
+      return -1;
+   }
+   p = *ps;
+
+   if (_parse_token(ctx, SL_PP_LBRACKET, &p) == 0) {
+      if (_parse_constant_expression(ctx, &p)) {
+         _update(ctx, e, VARIABLE_ARRAY_UNKNOWN);
+      } else {
+         _update(ctx, e, VARIABLE_ARRAY_EXPLICIT);
+      }
+      if (_parse_token(ctx, SL_PP_RBRACKET, &p) == 0) {
+         *ps = p;
+         return 0;
+      }
+      _error(ctx, "expected `]'");
+      return -1;
+   }
+   return 0;
+}
+
+
+static int
+_parse_init_declarator_list(struct parse_context *ctx,
+                            struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+
+   if (_parse_single_declaration(ctx, &p)) {
+      return -1;
+   }
+
+   for (;;) {
+      unsigned int e;
+
+      *ps = p;
+      if (_parse_token(ctx, SL_PP_COMMA, &p)) {
+         break;
+      }
+      _emit(ctx, &p.out, DECLARATOR_NEXT);
+      _emit(ctx, &p.out, VARIABLE_IDENTIFIER);
+      if (_parse_identifier(ctx, &p)) {
+         break;
+      }
+
+      e = _emit(ctx, &p.out, VARIABLE_NONE);
+      *ps = p;
+
+      if (_parse_token(ctx, SL_PP_ASSIGN, &p) == 0) {
+         if (_parse_initializer(ctx, &p) == 0) {
+            _update(ctx, e, VARIABLE_INITIALIZER);
+            *ps = p;
+            continue;
+         }
+         _error(ctx, "expected an initialiser");
+         break;
+      }
+      p = *ps;
+
+      if (_parse_token(ctx, SL_PP_LBRACKET, &p) == 0) {
+         unsigned int arr;
+
+         if (_parse_constant_expression(ctx, &p)) {
+            arr = VARIABLE_ARRAY_UNKNOWN;
+         } else {
+            arr = VARIABLE_ARRAY_EXPLICIT;
+         }
+         if (_parse_token(ctx, SL_PP_RBRACKET, &p) == 0) {
+            _update(ctx, e, arr);
+            *ps = p;
+            continue;
+         }
+         _error(ctx, "expected `]'");
+         break;
+      }
+      p = *ps;
+   }
+
+   _emit(ctx, &ps->out, DECLARATOR_NONE);
+   return 0;
+}
+
+
+static int
+_parse_declaration(struct parse_context *ctx,
+                   struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+   unsigned int e = _emit(ctx, &p.out, DECLARATION_FUNCTION_PROTOTYPE);
+
+   if (_parse_function_prototype(ctx, &p)) {
+      if (_parse_init_declarator_list(ctx, &p)) {
+         return -1;
+      }
+      _update(ctx, e, DECLARATION_INIT_DECLARATOR_LIST);
+   }
+   if (_parse_token(ctx, SL_PP_SEMICOLON, &p)) {
+      _error(ctx, "expected `;'");
+      return -1;
+   }
+   *ps = p;
+   return 0;
+}
+
+
+static int
+_parse_external_declaration(struct parse_context *ctx,
+                            struct parse_state *ps)
+{
+   struct parse_state p = *ps;
+   unsigned int e = _emit(ctx, &p.out, 0);
+
+   if (_parse_precision_stmt(ctx, &p) == 0) {
+      _update(ctx, e, DEFAULT_PRECISION);
+      *ps = p;
+      return 0;
+   }
+
+   if (_parse_function_definition(ctx, &p) == 0) {
+      _update(ctx, e, EXTERNAL_FUNCTION_DEFINITION);
+      *ps = p;
+      return 0;
+   }
+
+   if (_parse_invariant_stmt(ctx, &p) == 0) {
+      _update(ctx, e, INVARIANT_STMT);
+      *ps = p;
+      return 0;
+   }
+
+   if (_parse_declaration(ctx, &p) == 0) {
+      _update(ctx, e, EXTERNAL_DECLARATION);
+      *ps = p;
+      return 0;
+   }
+
+   _error(ctx, "expected an identifier");
+   return -1;
+}
+
+
+static int
+_parse_translation_unit(struct parse_context *ctx,
+                        struct parse_state *ps)
+{
+   _emit(ctx, &ps->out, REVISION);
+   if (_parse_external_declaration(ctx, ps)) {
+      return -1;
+   }
+   while (_parse_external_declaration(ctx, ps) == 0) {
+   }
+   _emit(ctx, &ps->out, EXTERNAL_NULL);
+   if (_parse_token(ctx, SL_PP_EOF, ps)) {
+      return -1;
+   }
+   return 0;
+}
+
+
+#define ADD_NAME_STR(CTX, NAME, STR)\
+   do {\
+      (CTX).dict.NAME = sl_pp_context_add_unique_str((CTX).context, (STR));\
+      if ((CTX).dict.NAME == -1) {\
+         return -1;\
+      }\
+   } while (0)
+
+#define ADD_NAME(CTX, NAME) ADD_NAME_STR(CTX, NAME, #NAME)
+
+
+int
+sl_cl_compile(struct sl_pp_context *context,
+              unsigned int shader_type,
+              unsigned int parsing_builtin,
+              unsigned char **output,
+              unsigned int *cboutput,
+              char *error,
+              unsigned int cberror)
+{
+   struct parse_context ctx;
+   struct parse_state ps;
+
+   ctx.context = context;
+
+   ADD_NAME_STR(ctx, _void, "void");
+   ADD_NAME_STR(ctx, _float, "float");
+   ADD_NAME_STR(ctx, _int, "int");
+   ADD_NAME_STR(ctx, _bool, "bool");
+   ADD_NAME(ctx, vec2);
+   ADD_NAME(ctx, vec3);
+   ADD_NAME(ctx, vec4);
+   ADD_NAME(ctx, bvec2);
+   ADD_NAME(ctx, bvec3);
+   ADD_NAME(ctx, bvec4);
+   ADD_NAME(ctx, ivec2);
+   ADD_NAME(ctx, ivec3);
+   ADD_NAME(ctx, ivec4);
+   ADD_NAME(ctx, mat2);
+   ADD_NAME(ctx, mat3);
+   ADD_NAME(ctx, mat4);
+   ADD_NAME(ctx, mat2x3);
+   ADD_NAME(ctx, mat3x2);
+   ADD_NAME(ctx, mat2x4);
+   ADD_NAME(ctx, mat4x2);
+   ADD_NAME(ctx, mat3x4);
+   ADD_NAME(ctx, mat4x3);
+   ADD_NAME(ctx, sampler1D);
+   ADD_NAME(ctx, sampler2D);
+   ADD_NAME(ctx, sampler3D);
+   ADD_NAME(ctx, samplerCube);
+   ADD_NAME(ctx, sampler1DShadow);
+   ADD_NAME(ctx, sampler2DShadow);
+   ADD_NAME(ctx, sampler2DRect);
+   ADD_NAME(ctx, sampler2DRectShadow);
+
+   ADD_NAME(ctx, invariant);
+
+   ADD_NAME(ctx, centroid);
+
+   ADD_NAME(ctx, precision);
+   ADD_NAME(ctx, lowp);
+   ADD_NAME(ctx, mediump);
+   ADD_NAME(ctx, highp);
+
+   ADD_NAME_STR(ctx, _const, "const");
+   ADD_NAME(ctx, attribute);
+   ADD_NAME(ctx, varying);
+   ADD_NAME(ctx, uniform);
+   ADD_NAME(ctx, __fixed_output);
+   ADD_NAME(ctx, __fixed_input);
+
+   ADD_NAME(ctx, in);
+   ADD_NAME(ctx, out);
+   ADD_NAME(ctx, inout);
+
+   ADD_NAME_STR(ctx, _struct, "struct");
+
+   ADD_NAME(ctx, __constructor);
+   ADD_NAME(ctx, __operator);
+   ADD_NAME_STR(ctx, ___asm, "__asm");
+
+   ADD_NAME_STR(ctx, _if, "if");
+   ADD_NAME_STR(ctx, _else, "else");
+   ADD_NAME_STR(ctx, _for, "for");
+   ADD_NAME_STR(ctx, _while, "while");
+   ADD_NAME_STR(ctx, _do, "do");
+
+   ADD_NAME_STR(ctx, _continue, "continue");
+   ADD_NAME_STR(ctx, _break, "break");
+   ADD_NAME_STR(ctx, _return, "return");
+   ADD_NAME(ctx, discard);
+
+   ADD_NAME_STR(ctx, _false, "false");
+   ADD_NAME_STR(ctx, _true, "true");
+
+   ctx.out_buf = NULL;
+   ctx.out_cap = 0;
+
+   ctx.shader_type = shader_type;
+   ctx.parsing_builtin = 1;
+
+   ctx.error[0] = '\0';
+   ctx.process_error = 0;
+
+   ctx.tokens_cap = 1024;
+   ctx.tokens_read = 0;
+   ctx.tokens = malloc(ctx.tokens_cap * sizeof(struct sl_pp_token_info));
+   if (!ctx.tokens) {
+      strncpy(error, "out of memory", cberror);
+      return -1;
+   }
+
+   ps.in = 0;
+   ps.out = 0;
+
+   if (_parse_translation_unit(&ctx, &ps)) {
+      strncpy(error, ctx.error, cberror);
+      free(ctx.tokens);
+      return -1;
+   }
+
+   *output = ctx.out_buf;
+   *cboutput = ps.out;
+   free(ctx.tokens);
+   return 0;
+}
diff --git a/src/mesa/state_tracker/st_cb_get.h b/src/glsl/cl/sl_cl_parse.h
similarity index 77%
copy from src/mesa/state_tracker/st_cb_get.h
copy to src/glsl/cl/sl_cl_parse.h
index 8e9f3e9..dd5791d 100644
--- a/src/mesa/state_tracker/st_cb_get.h
+++ b/src/glsl/cl/sl_cl_parse.h
@@ -1,6 +1,6 @@
 /**************************************************************************
  * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009 VMware, Inc.
  * All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -25,13 +25,16 @@
  * 
  **************************************************************************/
 
+#ifndef SL_CL_PARSE_H
+#define SL_CL_PARSE_H
 
-#ifndef ST_CB_GET_H
-#define ST_CB_GET_H
+int
+sl_cl_compile(struct sl_pp_context *context,
+              unsigned int shader_type,
+              unsigned int parsing_builtin,
+              unsigned char **output,
+              unsigned int *cboutput,
+              char *error,
+              unsigned int cberror);
 
-
-extern void
-st_init_get_functions(struct dd_function_table *functions);
-
-
-#endif
+#endif /* SL_CL_PARSE_H */
diff --git a/src/glsl/pp/Makefile b/src/glsl/pp/Makefile
new file mode 100644
index 0000000..fda1c42
--- /dev/null
+++ b/src/glsl/pp/Makefile
@@ -0,0 +1,27 @@
+#src/glsl/pp/Makefile
+
+TOP = ../../..
+
+include $(TOP)/configs/current
+
+LIBNAME = glslpp
+
+C_SOURCES = \
+	sl_pp_context.c \
+	sl_pp_define.c \
+	sl_pp_dict.c \
+	sl_pp_error.c \
+	sl_pp_expression.c \
+	sl_pp_extension.c \
+	sl_pp_if.c \
+	sl_pp_line.c \
+	sl_pp_macro.c \
+	sl_pp_pragma.c \
+	sl_pp_process.c \
+	sl_pp_purify.c \
+	sl_pp_token.c \
+	sl_pp_token_util.c \
+	sl_pp_version.c
+
+include ../Makefile.template
+
diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c
new file mode 100644
index 0000000..74a9bdd
--- /dev/null
+++ b/src/glsl/pp/sl_pp_context.c
@@ -0,0 +1,182 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "sl_pp_public.h"
+#include "sl_pp_context.h"
+
+
+struct sl_pp_context *
+sl_pp_context_create(const char *input,
+                     const struct sl_pp_purify_options *options)
+{
+   struct sl_pp_context *context;
+
+   context = calloc(1, sizeof(struct sl_pp_context));
+   if (!context) {
+      return NULL;
+   }
+
+   if (sl_pp_dict_init(context)) {
+      sl_pp_context_destroy(context);
+      return NULL;
+   }
+
+   context->getc_buf_capacity = 64;
+   context->getc_buf = malloc(context->getc_buf_capacity * sizeof(char));
+   if (!context->getc_buf) {
+      sl_pp_context_destroy(context);
+      return NULL;
+   }
+
+   if (sl_pp_token_buffer_init(&context->tokens, context)) {
+      sl_pp_context_destroy(context);
+      return NULL;
+   }
+
+   context->macro_tail = &context->macro;
+   context->if_ptr = SL_PP_MAX_IF_NESTING;
+   context->if_value = 1;
+   memset(context->error_msg, 0, sizeof(context->error_msg));
+   context->error_line = 1;
+   context->line = 1;
+   context->file = 0;
+
+   sl_pp_purify_state_init(&context->pure, input, options);
+
+   memset(&context->process_state, 0, sizeof(context->process_state));
+
+   return context;
+}
+
+void
+sl_pp_context_destroy(struct sl_pp_context *context)
+{
+   if (context) {
+      free(context->cstr_pool);
+      sl_pp_macro_free(context->macro);
+      free(context->getc_buf);
+      sl_pp_token_buffer_destroy(&context->tokens);
+      free(context->process_state.out);
+      free(context);
+   }
+}
+
+const char *
+sl_pp_context_error_message(const struct sl_pp_context *context)
+{
+   return context->error_msg;
+}
+
+void
+sl_pp_context_error_position(const struct sl_pp_context *context,
+                             unsigned int *file,
+                             unsigned int *line)
+{
+   if (file) {
+      *file = 0;
+   }
+   if (line) {
+      *line = context->error_line;
+   }
+}
+
+int
+sl_pp_context_add_predefined(struct sl_pp_context *context,
+                             const char *name,
+                             const char *value)
+{
+   struct sl_pp_predefined pre;
+
+   if (context->num_predefined == SL_PP_MAX_PREDEFINED) {
+      return -1;
+   }
+
+   pre.name = sl_pp_context_add_unique_str(context, name);
+   if (pre.name == -1) {
+      return -1;
+   }
+
+   pre.value = sl_pp_context_add_unique_str(context, value);
+   if (pre.value == -1) {
+      return -1;
+   }
+
+   context->predefined[context->num_predefined++] = pre;
+   return 0;
+}
+
+int
+sl_pp_context_add_unique_str(struct sl_pp_context *context,
+                             const char *str)
+{
+   unsigned int size;
+   unsigned int offset = 0;
+
+   size = strlen(str) + 1;
+
+   /* Find out if this is a unique string. */
+   while (offset < context->cstr_pool_len) {
+      const char *str2;
+      unsigned int size2;
+
+      str2 = &context->cstr_pool[offset];
+      size2 = strlen(str2) + 1;
+      if (size == size2 && !memcmp(str, str2, size - 1)) {
+         return offset;
+      }
+
+      offset += size2;
+   }
+
+   if (context->cstr_pool_len + size > context->cstr_pool_max) {
+      context->cstr_pool_max = (context->cstr_pool_len + size + 0xffff) & ~0xffff;
+      context->cstr_pool = realloc(context->cstr_pool, context->cstr_pool_max);
+   }
+
+   if (!context->cstr_pool) {
+      strcpy(context->error_msg, "out of memory");
+      return -1;
+   }
+
+   offset = context->cstr_pool_len;
+   memcpy(&context->cstr_pool[offset], str, size);
+   context->cstr_pool_len += size;
+
+   return offset;
+}
+
+const char *
+sl_pp_context_cstr(const struct sl_pp_context *context,
+                   int offset)
+{
+   if (offset == -1) {
+      return NULL;
+   }
+   return &context->cstr_pool[offset];
+}
diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h
new file mode 100644
index 0000000..3eada38
--- /dev/null
+++ b/src/glsl/pp/sl_pp_context.h
@@ -0,0 +1,92 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#ifndef SL_PP_CONTEXT_H
+#define SL_PP_CONTEXT_H
+
+#include "sl_pp_dict.h"
+#include "sl_pp_macro.h"
+#include "sl_pp_process.h"
+#include "sl_pp_purify.h"
+#include "sl_pp_token_util.h"
+
+
+#define SL_PP_MAX_IF_NESTING  64
+
+#define SL_PP_MAX_ERROR_MSG   1024
+
+#define SL_PP_MAX_EXTENSIONS  16
+
+#define SL_PP_MAX_PREDEFINED  16
+
+struct sl_pp_extension {
+   int name;         /*< VENDOR_extension_name */
+   int name_string;  /*< GL_VENDOR_extension_name */
+};
+
+struct sl_pp_predefined {
+   int name;
+   int value;
+};
+
+struct sl_pp_context {
+   char *cstr_pool;
+   unsigned int cstr_pool_max;
+   unsigned int cstr_pool_len;
+   struct sl_pp_dict dict;
+
+   struct sl_pp_macro *macro;
+   struct sl_pp_macro **macro_tail;
+
+   struct sl_pp_extension extensions[SL_PP_MAX_EXTENSIONS];
+   unsigned int num_extensions;
+
+   struct sl_pp_predefined predefined[SL_PP_MAX_PREDEFINED];
+   unsigned int num_predefined;
+
+   unsigned int if_stack[SL_PP_MAX_IF_NESTING];
+   unsigned int if_ptr;
+   unsigned int if_value;
+
+   char error_msg[SL_PP_MAX_ERROR_MSG];
+   unsigned int error_line;
+
+   unsigned int line;
+   unsigned int file;
+
+   struct sl_pp_purify_state pure;
+
+   char *getc_buf;
+   unsigned int getc_buf_size;
+   unsigned int getc_buf_capacity;
+
+   struct sl_pp_token_buffer tokens;
+
+   struct sl_pp_process_state process_state;
+};
+
+#endif /* SL_PP_CONTEXT_H */
diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c
new file mode 100644
index 0000000..808a6a0
--- /dev/null
+++ b/src/glsl/pp/sl_pp_define.c
@@ -0,0 +1,238 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "sl_pp_context.h"
+#include "sl_pp_process.h"
+#include "sl_pp_public.h"
+
+
+static void
+skip_whitespace(const struct sl_pp_token_info *input,
+                unsigned int *first,
+                unsigned int last)
+{
+   while (*first < last && input[*first].token == SL_PP_WHITESPACE) {
+      (*first)++;
+   }
+}
+
+
+static int
+_parse_formal_args(struct sl_pp_context *context,
+                   const struct sl_pp_token_info *input,
+                   unsigned int *first,
+                   unsigned int last,
+                   struct sl_pp_macro *macro)
+{
+   struct sl_pp_macro_formal_arg **arg;
+
+   macro->num_args = 0;
+
+   skip_whitespace(input, first, last);
+   if (*first < last) {
+      if (input[*first].token == SL_PP_RPAREN) {
+         (*first)++;
+         return 0;
+      }
+   } else {
+      strcpy(context->error_msg, "expected either macro formal argument or `)'");
+      return -1;
+   }
+
+   arg = &macro->arg;
+
+   for (;;) {
+      if (*first < last && input[*first].token != SL_PP_IDENTIFIER) {
+         strcpy(context->error_msg, "expected macro formal argument");
+         return -1;
+      }
+
+      *arg = malloc(sizeof(struct sl_pp_macro_formal_arg));
+      if (!*arg) {
+         strcpy(context->error_msg, "out of memory");
+         return -1;
+      }
+
+      (**arg).name = input[*first].data.identifier;
+      (*first)++;
+
+      (**arg).next = NULL;
+      arg = &(**arg).next;
+
+      macro->num_args++;
+
+      skip_whitespace(input, first, last);
+      if (*first < last) {
+         if (input[*first].token == SL_PP_COMMA) {
+            (*first)++;
+            skip_whitespace(input, first, last);
+         } else if (input[*first].token == SL_PP_RPAREN) {
+            (*first)++;
+            return 0;
+         } else {
+            strcpy(context->error_msg, "expected either `,' or `)'");
+            return -1;
+         }
+      } else {
+         strcpy(context->error_msg, "expected either `,' or `)'");
+         return -1;
+      }
+   }
+
+   /* Should not gete here. */
+}
+
+
+int
+sl_pp_process_define(struct sl_pp_context *context,
+                     const struct sl_pp_token_info *input,
+                     unsigned int first,
+                     unsigned int last)
+{
+   int macro_name = -1;
+   struct sl_pp_macro *macro;
+   unsigned int i;
+   unsigned int body_len;
+   unsigned int j;
+
+   if (first < last && input[first].token == SL_PP_IDENTIFIER) {
+      macro_name = input[first].data.identifier;
+      first++;
+   }
+   if (macro_name == -1) {
+      strcpy(context->error_msg, "expected macro name");
+      return -1;
+   }
+
+   /* Check for reserved macro names */
+   {
+      const char *name = sl_pp_context_cstr(context, macro_name);
+
+      if (strstr(name, "__")) {
+         strcpy(context->error_msg, "macro names containing `__' are reserved");
+         return 1;
+      }
+      if (name[0] == 'G' && name[1] == 'L' && name[2] == '_') {
+         strcpy(context->error_msg, "macro names prefixed with `GL_' are reserved");
+         return 1;
+      }
+   }
+
+   for (macro = context->macro; macro; macro = macro->next) {
+      if (macro->name == macro_name) {
+         break;
+      }
+   }
+
+   if (!macro) {
+      macro = sl_pp_macro_new();
+      if (!macro) {
+         strcpy(context->error_msg, "out of memory");
+         return -1;
+      }
+
+      *context->macro_tail = macro;
+      context->macro_tail = &macro->next;
+   } else {
+      sl_pp_macro_reset(macro);
+   }
+
+   macro->name = macro_name;
+
+   /*
+    * If there is no whitespace between macro name and left paren, a macro
+    * formal argument list follows. This is the only place where the presence
+    * of a whitespace matters and it's the only reason why we are dealing
+    * with whitespace at this level.
+    */
+   if (first < last && input[first].token == SL_PP_LPAREN) {
+      first++;
+      if (_parse_formal_args(context, input, &first, last, macro)) {
+         return -1;
+      }
+   }
+
+   /* Calculate body size, trim out whitespace, make room for EOF. */
+   body_len = 1;
+   for (i = first; i < last; i++) {
+      if (input[i].token != SL_PP_WHITESPACE) {
+         body_len++;
+      }
+   }
+
+   macro->body = malloc(sizeof(struct sl_pp_token_info) * body_len);
+   if (!macro->body) {
+      strcpy(context->error_msg, "out of memory");
+      return -1;
+   }
+
+   for (j = 0, i = first; i < last; i++) {
+      if (input[i].token != SL_PP_WHITESPACE) {
+         macro->body[j++] = input[i];
+      }
+   }
+   macro->body[j++].token = SL_PP_EOF;
+
+   return 0;
+}
+
+
+int
+sl_pp_process_undef(struct sl_pp_context *context,
+                    const struct sl_pp_token_info *input,
+                    unsigned int first,
+                    unsigned int last)
+{
+   int macro_name = -1;
+   struct sl_pp_macro **pmacro;
+   struct sl_pp_macro *macro;
+
+   if (first < last && input[first].token == SL_PP_IDENTIFIER) {
+      macro_name = input[first].data.identifier;
+   }
+   if (macro_name == -1) {
+      return 0;
+   }
+
+   for (pmacro = &context->macro; *pmacro; pmacro = &(**pmacro).next) {
+      if ((**pmacro).name == macro_name) {
+         break;
+      }
+   }
+   if (!*pmacro) {
+      return 0;
+   }
+
+   macro = *pmacro;
+   *pmacro = macro->next;
+   macro->next = NULL;
+   sl_pp_macro_free(macro);
+
+   return 0;
+}
diff --git a/src/glsl/pp/sl_pp_dict.c b/src/glsl/pp/sl_pp_dict.c
new file mode 100644
index 0000000..062139e
--- /dev/null
+++ b/src/glsl/pp/sl_pp_dict.c
@@ -0,0 +1,85 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include "sl_pp_public.h"
+#include "sl_pp_context.h"
+#include "sl_pp_dict.h"
+
+
+#define ADD_NAME_STR(CTX, NAME, STR)\
+   do {\
+      (CTX)->dict.NAME = sl_pp_context_add_unique_str((CTX), (STR));\
+      if ((CTX)->dict.NAME == -1) {\
+         return -1;\
+      }\
+   } while (0)
+
+#define ADD_NAME(CTX, NAME) ADD_NAME_STR(CTX, NAME, #NAME)
+
+
+int
+sl_pp_dict_init(struct sl_pp_context *context)
+{
+   ADD_NAME(context, all);
+
+   ADD_NAME(context, require);
+   ADD_NAME(context, enable);
+   ADD_NAME(context, warn);
+   ADD_NAME(context, disable);
+
+   ADD_NAME(context, defined);
+
+   ADD_NAME_STR(context, ___LINE__, "__LINE__");
+   ADD_NAME_STR(context, ___FILE__, "__FILE__");
+   ADD_NAME_STR(context, ___VERSION__, "__VERSION__");
+
+   ADD_NAME(context, optimize);
+   ADD_NAME(context, debug);
+
+   ADD_NAME(context, off);
+   ADD_NAME(context, on);
+
+   ADD_NAME(context, define);
+   ADD_NAME(context, elif);
+   ADD_NAME_STR(context, _else, "else");
+   ADD_NAME(context, endif);
+   ADD_NAME(context, error);
+   ADD_NAME(context, extension);
+   ADD_NAME_STR(context, _if, "if");
+   ADD_NAME(context, ifdef);
+   ADD_NAME(context, ifndef);
+   ADD_NAME(context, line);
+   ADD_NAME(context, pragma);
+   ADD_NAME(context, undef);
+
+   ADD_NAME(context, version);
+
+   ADD_NAME_STR(context, _0, "0");
+   ADD_NAME_STR(context, _1, "1");
+
+   return 0;
+}
diff --git a/src/mesa/state_tracker/st_cb_get.h b/src/glsl/pp/sl_pp_dict.h
similarity index 67%
copy from src/mesa/state_tracker/st_cb_get.h
copy to src/glsl/pp/sl_pp_dict.h
index 8e9f3e9..875217b 100644
--- a/src/mesa/state_tracker/st_cb_get.h
+++ b/src/glsl/pp/sl_pp_dict.h
@@ -1,6 +1,6 @@
 /**************************************************************************
  * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009 VMware, Inc.
  * All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -25,13 +25,53 @@
  * 
  **************************************************************************/
 
-
-#ifndef ST_CB_GET_H
-#define ST_CB_GET_H
+#ifndef SL_PP_DICT_H
+#define SL_PP_DICT_H
 
 
-extern void
-st_init_get_functions(struct dd_function_table *functions);
+struct sl_pp_context;
+
+struct sl_pp_dict {
+   int all;
+
+   int require;
+   int enable;
+   int warn;
+   int disable;
+
+   int defined;
+
+   int ___LINE__;
+   int ___FILE__;
+   int ___VERSION__;
+
+   int optimize;
+   int debug;
+
+   int off;
+   int on;
+
+   int define;
+   int elif;
+   int _else;
+   int endif;
+   int error;
+   int extension;
+   int _if;
+   int ifdef;
+   int ifndef;
+   int line;
+   int pragma;
+   int undef;
+
+   int version;
+
+   int _0;
+   int _1;
+};
 
 
-#endif
+int
+sl_pp_dict_init(struct sl_pp_context *context);
+
+#endif /* SL_PP_DICT_H */
diff --git a/src/glsl/pp/sl_pp_error.c b/src/glsl/pp/sl_pp_error.c
new file mode 100644
index 0000000..b628e37
--- /dev/null
+++ b/src/glsl/pp/sl_pp_error.c
@@ -0,0 +1,270 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "sl_pp_context.h"
+#include "sl_pp_process.h"
+#include "sl_pp_public.h"
+
+
+void
+sl_pp_process_error(struct sl_pp_context *context,
+                    const struct sl_pp_token_info *input,
+                    unsigned int first,
+                    unsigned int last)
+{
+   unsigned int out_len = 0;
+   unsigned int i;
+
+   for (i = first; i < last; i++) {
+      const char *s = NULL;
+      char buf[2];
+
+      switch (input[i].token) {
+      case SL_PP_WHITESPACE:
+         s = " ";
+         break;
+
+      case SL_PP_NEWLINE:
+         s = "\n";
+         break;
+
+      case SL_PP_HASH:
+         s = "#";
+         break;
+
+      case SL_PP_COMMA:
+         s = ",";
+         break;
+
+      case SL_PP_SEMICOLON:
+         s = ";";
+         break;
+
+      case SL_PP_LBRACE:
+         s = "{";
+         break;
+
+      case SL_PP_RBRACE:
+         s = "}";
+         break;
+
+      case SL_PP_LPAREN:
+         s = "(";
+         break;
+
+      case SL_PP_RPAREN:
+         s = ")";
+         break;
+
+      case SL_PP_LBRACKET:
+         s = "[";
+         break;
+
+      case SL_PP_RBRACKET:
+         s = "]";
+         break;
+
+      case SL_PP_DOT:
+         s = ".";
+         break;
+
+      case SL_PP_INCREMENT:
+         s = "++";
+         break;
+
+      case SL_PP_ADDASSIGN:
+         s = "+=";
+         break;
+
+      case SL_PP_PLUS:
+         s = "+";
+         break;
+
+      case SL_PP_DECREMENT:
+         s = "--";
+         break;
+
+      case SL_PP_SUBASSIGN:
+         s = "-=";
+         break;
+
+      case SL_PP_MINUS:
+         s = "-";
+         break;
+
+      case SL_PP_BITNOT:
+         s = "~";
+         break;
+
+      case SL_PP_NOTEQUAL:
+         s = "!=";
+         break;
+
+      case SL_PP_NOT:
+         s = "!";
+         break;
+
+      case SL_PP_MULASSIGN:
+         s = "*=";
+         break;
+
+      case SL_PP_STAR:
+         s = "*";
+         break;
+
+      case SL_PP_DIVASSIGN:
+         s = "/=";
+         break;
+
+      case SL_PP_SLASH:
+         s = "/";
+         break;
+
+      case SL_PP_MODASSIGN:
+         s = "%=";
+         break;
+
+      case SL_PP_MODULO:
+         s = "%";
+         break;
+
+      case SL_PP_LSHIFTASSIGN:
+         s = "<<=";
+         break;
+
+      case SL_PP_LSHIFT:
+         s = "<<";
+         break;
+
+      case SL_PP_LESSEQUAL:
+         s = "<=";
+         break;
+
+      case SL_PP_LESS:
+         s = "<";
+         break;
+
+      case SL_PP_RSHIFTASSIGN:
+         s = ">>=";
+         break;
+
+      case SL_PP_RSHIFT:
+         s = ">>";
+         break;
+
+      case SL_PP_GREATEREQUAL:
+         s = ">=";
+         break;
+
+      case SL_PP_GREATER:
+         s = ">";
+         break;
+
+      case SL_PP_EQUAL:
+         s = "==";
+         break;
+
+      case SL_PP_ASSIGN:
+         s = "=";
+         break;
+
+      case SL_PP_AND:
+         s = "&&";
+         break;
+
+      case SL_PP_BITANDASSIGN:
+         s = "&=";
+         break;
+
+      case SL_PP_BITAND:
+         s = "&";
+         break;
+
+      case SL_PP_XOR:
+         s = "^^";
+         break;
+
+      case SL_PP_BITXORASSIGN:
+         s = "^=";
+         break;
+
+      case SL_PP_BITXOR:
+         s = "^";
+         break;
+
+      case SL_PP_OR:
+         s = "||";
+         break;
+
+      case SL_PP_BITORASSIGN:
+         s = "|=";
+         break;
+
+      case SL_PP_BITOR:
+         s = "|";
+         break;
+
+      case SL_PP_QUESTION:
+         s = "?";
+         break;
+
+      case SL_PP_COLON:
+         s = ":";
+         break;
+
+      case SL_PP_IDENTIFIER:
+         s = sl_pp_context_cstr(context, input[i].data.identifier);
+         break;
+
+      case SL_PP_UINT:
+         s = sl_pp_context_cstr(context, input[i].data._uint);
+         break;
+
+      case SL_PP_FLOAT:
+         s = sl_pp_context_cstr(context, input[i].data._float);
+         break;
+
+      case SL_PP_OTHER:
+         buf[0] = input[i].data.other;
+         buf[1] = '\0';
+         s = buf;
+         break;
+
+      default:
+         strcpy(context->error_msg, "internal error");
+         return;
+      }
+
+      while (*s != '\0' && out_len < sizeof(context->error_msg) - 1) {
+         context->error_msg[out_len++] = *s++;
+      }
+   }
+
+   context->error_msg[out_len] = '\0';
+}
diff --git a/src/glsl/pp/sl_pp_expression.c b/src/glsl/pp/sl_pp_expression.c
new file mode 100644
index 0000000..ec90478
--- /dev/null
+++ b/src/glsl/pp/sl_pp_expression.c
@@ -0,0 +1,411 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "sl_pp_expression.h"
+#include "sl_pp_public.h"
+
+
+struct parse_context {
+   struct sl_pp_context *context;
+   const struct sl_pp_token_info *input;
+};
+
+static int
+_parse_or(struct parse_context *ctx,
+          int *result);
+
+static int
+_parse_primary(struct parse_context *ctx,
+               int *result)
+{
+   if (ctx->input->token == SL_PP_UINT) {
+      *result = atoi(sl_pp_context_cstr(ctx->context, ctx->input->data._uint));
+      ctx->input++;
+   } else {
+      if (ctx->input->token != SL_PP_LPAREN) {
+         strcpy(ctx->context->error_msg, "expected `('");
+         return -1;
+      }
+      ctx->input++;
+      if (_parse_or(ctx, result)) {
+         return -1;
+      }
+      if (ctx->input->token != SL_PP_RPAREN) {
+         strcpy(ctx->context->error_msg, "expected `)'");
+         return -1;
+      }
+      ctx->input++;
+   }
+   return 0;
+}
+
+static int
+_parse_unary(struct parse_context *ctx,
+             int *result)
+{
+   if (!_parse_primary(ctx, result)) {
+      return 0;
+   }
+
+   switch (ctx->input->token) {
+   case SL_PP_PLUS:
+      ctx->input++;
+      if (_parse_unary(ctx, result)) {
+         return -1;
+      }
+      *result = +*result;
+      break;
+
+   case SL_PP_MINUS:
+      ctx->input++;
+      if (_parse_unary(ctx, result)) {
+         return -1;
+      }
+      *result = -*result;
+      break;
+
+   case SL_PP_NOT:
+      ctx->input++;
+      if (_parse_unary(ctx, result)) {
+         return -1;
+      }
+      *result = !*result;
+      break;
+
+   case SL_PP_BITNOT:
+      ctx->input++;
+      if (_parse_unary(ctx, result)) {
+         return -1;
+      }
+      *result = ~*result;
+      break;
+
+   default:
+      return -1;
+   }
+
+   return 0;
+}
+
+static int
+_parse_multiplicative(struct parse_context *ctx,
+                      int *result)
+{
+   if (_parse_unary(ctx, result)) {
+      return -1;
+   }
+   for (;;) {
+      int right;
+
+      switch (ctx->input->token) {
+      case SL_PP_STAR:
+         ctx->input++;
+         if (_parse_unary(ctx, &right)) {
+            return -1;
+         }
+         *result = *result * right;
+         break;
+
+      case SL_PP_SLASH:
+         ctx->input++;
+         if (_parse_unary(ctx, &right)) {
+            return -1;
+         }
+         *result = *result / right;
+         break;
+
+      case SL_PP_MODULO:
+         ctx->input++;
+         if (_parse_unary(ctx, &right)) {
+            return -1;
+         }
+         *result = *result % right;
+         break;
+
+      default:
+         return 0;
+      }
+   }
+}
+
+static int
+_parse_additive(struct parse_context *ctx,
+                int *result)
+{
+   if (_parse_multiplicative(ctx, result)) {
+      return -1;
+   }
+   for (;;) {
+      int right;
+
+      switch (ctx->input->token) {
+      case SL_PP_PLUS:
+         ctx->input++;
+         if (_parse_multiplicative(ctx, &right)) {
+            return -1;
+         }
+         *result = *result + right;
+         break;
+
+      case SL_PP_MINUS:
+         ctx->input++;
+         if (_parse_multiplicative(ctx, &right)) {
+            return -1;
+         }
+         *result = *result - right;
+         break;
+
+      default:
+         return 0;
+      }
+   }
+}
+
+static int
+_parse_shift(struct parse_context *ctx,
+             int *result)
+{
+   if (_parse_additive(ctx, result)) {
+      return -1;
+   }
+   for (;;) {
+      int right;
+
+      switch (ctx->input->token) {
+      case SL_PP_LSHIFT:
+         ctx->input++;
+         if (_parse_additive(ctx, &right)) {
+            return -1;
+         }
+         *result = *result << right;
+         break;
+
+      case SL_PP_RSHIFT:
+         ctx->input++;
+         if (_parse_additive(ctx, &right)) {
+            return -1;
+         }
+         *result = *result >> right;
+         break;
+
+      default:
+         return 0;
+      }
+   }
+}
+
+static int
+_parse_relational(struct parse_context *ctx,
+                  int *result)
+{
+   if (_parse_shift(ctx, result)) {
+      return -1;
+   }
+   for (;;) {
+      int right;
+
+      switch (ctx->input->token) {
+      case SL_PP_LESSEQUAL:
+         ctx->input++;
+         if (_parse_shift(ctx, &right)) {
+            return -1;
+         }
+         *result = *result <= right;
+         break;
+
+      case SL_PP_GREATEREQUAL:
+         ctx->input++;
+         if (_parse_shift(ctx, &right)) {
+            return -1;
+         }
+         *result = *result >= right;
+         break;
+
+      case SL_PP_LESS:
+         ctx->input++;
+         if (_parse_shift(ctx, &right)) {
+            return -1;
+         }
+         *result = *result < right;
+         break;
+
+      case SL_PP_GREATER:
+         ctx->input++;
+         if (_parse_shift(ctx, &right)) {
+            return -1;
+         }
+         *result = *result > right;
+         break;
+
+      default:
+         return 0;
+      }
+   }
+}
+
+static int
+_parse_equality(struct parse_context *ctx,
+                int *result)
+{
+   if (_parse_relational(ctx, result)) {
+      return -1;
+   }
+   for (;;) {
+      int right;
+
+      switch (ctx->input->token) {
+      case SL_PP_EQUAL:
+         ctx->input++;
+         if (_parse_relational(ctx, &right)) {
+            return -1;
+         }
+         *result = *result == right;
+         break;
+
+      case SL_PP_NOTEQUAL:
+         ctx->input++;
+         if (_parse_relational(ctx, &right)) {
+            return -1;
+         }
+         *result = *result != right;
+         break;
+
+      default:
+         return 0;
+      }
+   }
+}
+
+static int
+_parse_bitand(struct parse_context *ctx,
+              int *result)
+{
+   if (_parse_equality(ctx, result)) {
+      return -1;
+   }
+   while (ctx->input->token == SL_PP_BITAND) {
+      int right;
+
+      ctx->input++;
+      if (_parse_equality(ctx, &right)) {
+         return -1;
+      }
+      *result = *result & right;
+   }
+   return 0;
+}
+
+static int
+_parse_xor(struct parse_context *ctx,
+           int *result)
+{
+   if (_parse_bitand(ctx, result)) {
+      return -1;
+   }
+   while (ctx->input->token == SL_PP_XOR) {
+      int right;
+
+      ctx->input++;
+      if (_parse_bitand(ctx, &right)) {
+         return -1;
+      }
+      *result = *result ^ right;
+   }
+   return 0;
+}
+
+static int
+_parse_bitor(struct parse_context *ctx,
+             int *result)
+{
+   if (_parse_xor(ctx, result)) {
+      return -1;
+   }
+   while (ctx->input->token == SL_PP_BITOR) {
+      int right;
+
+      ctx->input++;
+      if (_parse_xor(ctx, &right)) {
+         return -1;
+      }
+      *result = *result | right;
+   }
+   return 0;
+}
+
+static int
+_parse_and(struct parse_context *ctx,
+           int *result)
+{
+   if (_parse_bitor(ctx, result)) {
+      return -1;
+   }
+   while (ctx->input->token == SL_PP_AND) {
+      int right;
+
+      ctx->input++;
+      if (_parse_bitor(ctx, &right)) {
+         return -1;
+      }
+      *result = *result && right;
+   }
+   return 0;
+}
+
+static int
+_parse_or(struct parse_context *ctx,
+          int *result)
+{
+   if (_parse_and(ctx, result)) {
+      return -1;
+   }
+   while (ctx->input->token == SL_PP_OR) {
+      int right;
+
+      ctx->input++;
+      if (_parse_and(ctx, &right)) {
+         return -1;
+      }
+      *result = *result || right;
+   }
+   return 0;
+}
+
+int
+sl_pp_execute_expression(struct sl_pp_context *context,
+                         const struct sl_pp_token_info *input,
+                         int *result)
+{
+   struct parse_context ctx;
+
+   ctx.context = context;
+   ctx.input = input;
+
+   return _parse_or(&ctx, result);
+}
diff --git a/src/mesa/state_tracker/st_cb_get.h b/src/glsl/pp/sl_pp_expression.h
similarity index 79%
copy from src/mesa/state_tracker/st_cb_get.h
copy to src/glsl/pp/sl_pp_expression.h
index 8e9f3e9..377d5b4 100644
--- a/src/mesa/state_tracker/st_cb_get.h
+++ b/src/glsl/pp/sl_pp_expression.h
@@ -1,6 +1,6 @@
 /**************************************************************************
  * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009 VMware, Inc.
  * All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -25,13 +25,16 @@
  * 
  **************************************************************************/
 
+#ifndef SL_PP_EXPRESSION_H
+#define SL_PP_EXPRESSION_H
 
-#ifndef ST_CB_GET_H
-#define ST_CB_GET_H
+#include "sl_pp_context.h"
+#include "sl_pp_token.h"
 
 
-extern void
-st_init_get_functions(struct dd_function_table *functions);
+int
+sl_pp_execute_expression(struct sl_pp_context *context,
+                         const struct sl_pp_token_info *input,
+                         int *result);
 
-
-#endif
+#endif /* SL_PP_EXPRESSION_H */
diff --git a/src/glsl/pp/sl_pp_extension.c b/src/glsl/pp/sl_pp_extension.c
new file mode 100644
index 0000000..8af5731
--- /dev/null
+++ b/src/glsl/pp/sl_pp_extension.c
@@ -0,0 +1,171 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "sl_pp_context.h"
+#include "sl_pp_process.h"
+#include "sl_pp_public.h"
+
+
+int
+sl_pp_context_add_extension(struct sl_pp_context *context,
+                            const char *name,
+                            const char *name_string)
+{
+   struct sl_pp_extension ext;
+
+   if (context->num_extensions == SL_PP_MAX_EXTENSIONS) {
+      return -1;
+   }
+
+   ext.name = sl_pp_context_add_unique_str(context, name);
+   if (ext.name == -1) {
+      return -1;
+   }
+
+   ext.name_string = sl_pp_context_add_unique_str(context, name_string);
+   if (ext.name_string == -1) {
+      return -1;
+   }
+
+   context->extensions[context->num_extensions++] = ext;
+   return 0;
+}
+
+int
+sl_pp_process_extension(struct sl_pp_context *context,
+                        const struct sl_pp_token_info *input,
+                        unsigned int first,
+                        unsigned int last,
+                        struct sl_pp_process_state *state)
+{
+   int extension_name = -1;
+   int behavior = -1;
+   struct sl_pp_token_info out;
+
+   /* Grab the extension name. */
+   if (first < last && input[first].token == SL_PP_IDENTIFIER) {
+      extension_name = input[first].data.identifier;
+      first++;
+   }
+   if (extension_name == -1) {
+      strcpy(context->error_msg, "expected identifier after `#extension'");
+      return -1;
+   }
+
+   /* Make sure the extension is supported. */
+   if (extension_name == context->dict.all) {
+      out.data.extension = extension_name;
+   } else {
+      unsigned int i;
+
+      out.data.extension = -1;
+      for (i = 0; i < context->num_extensions; i++) {
+         if (extension_name == context->extensions[i].name_string) {
+            out.data.extension = extension_name;
+            break;
+         }
+      }
+   }
+
+   /* Grab the colon separating the extension name and behavior. */
+   while (first < last && input[first].token == SL_PP_WHITESPACE) {
+      first++;
+   }
+   if (first < last && input[first].token == SL_PP_COLON) {
+      first++;
+   } else {
+      strcpy(context->error_msg, "expected `:' after extension name");
+      return -1;
+   }
+   while (first < last && input[first].token == SL_PP_WHITESPACE) {
+      first++;
+   }
+
+   /* Grab the behavior name. */
+   if (first < last && input[first].token == SL_PP_IDENTIFIER) {
+      behavior = input[first].data.identifier;
+      first++;
+   }
+   if (behavior == -1) {
+      strcpy(context->error_msg, "expected identifier after `:'");
+      return -1;
+   }
+
+   if (behavior == context->dict.require) {
+      if (out.data.extension == -1) {
+         strcpy(context->error_msg, "the required extension is not supported");
+         return -1;
+      }
+      if (out.data.extension == context->dict.all) {
+         strcpy(context->error_msg, "invalid behavior for `all' extension: `require'");
+         return -1;
+      }
+      out.token = SL_PP_EXTENSION_REQUIRE;
+   } else if (behavior == context->dict.enable) {
+      if (out.data.extension == -1) {
+         /* Warning: the extension cannot be enabled. */
+         return 0;
+      }
+      if (out.data.extension == context->dict.all) {
+         strcpy(context->error_msg, "invalid behavior for `all' extension: `enable'");
+         return -1;
+      }
+      out.token = SL_PP_EXTENSION_ENABLE;
+   } 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;
+   } 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;
+   } else {
+      strcpy(context->error_msg, "unrecognised behavior name");
+      return -1;
+   }
+
+   /* Grab the end of line. */
+   while (first < last && input[first].token == SL_PP_WHITESPACE) {
+      first++;
+   }
+   if (first < last) {
+      strcpy(context->error_msg, "expected end of line after behavior name");
+      return -1;
+   }
+
+   if (sl_pp_process_out(state, &out)) {
+      return -1;
+   }
+
+   return 0;
+}
diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c
new file mode 100644
index 0000000..f12f0f1
--- /dev/null
+++ b/src/glsl/pp/sl_pp_if.c
@@ -0,0 +1,344 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "sl_pp_expression.h"
+#include "sl_pp_process.h"
+
+
+static int
+_parse_defined(struct sl_pp_context *context,
+               struct sl_pp_token_buffer *buffer,
+               struct sl_pp_process_state *state)
+{
+   struct sl_pp_token_info input;
+   int parens = 0;
+   int macro_name;
+   struct sl_pp_macro *macro;
+   int defined = 0;
+   struct sl_pp_token_info result;
+
+   if (sl_pp_token_buffer_skip_white(buffer, &input)) {
+      return -1;
+   }
+
+   if (input.token == SL_PP_LPAREN) {
+      if (sl_pp_token_buffer_skip_white(buffer, &input)) {
+         return -1;
+      }
+      parens = 1;
+   }
+
+   if (input.token != SL_PP_IDENTIFIER) {
+      strcpy(context->error_msg, "expected an identifier");
+      return -1;
+   }
+
+   macro_name = input.data.identifier;
+   for (macro = context->macro; macro; macro = macro->next) {
+      if (macro->name == macro_name) {
+         defined = 1;
+         break;
+      }
+   }
+
+   if (parens) {
+      if (sl_pp_token_buffer_skip_white(buffer, &input)) {
+         return -1;
+      }
+      if (input.token != SL_PP_RPAREN) {
+         strcpy(context->error_msg, "expected `)'");
+         return -1;
+      }
+   }
+
+   result.token = SL_PP_UINT;
+   result.data._uint = (defined ? context->dict._1 : context->dict._0);
+
+   if (sl_pp_process_out(state, &result)) {
+      strcpy(context->error_msg, "out of memory");
+      return -1;
+   }
+
+   return 0;
+}
+
+static unsigned int
+_evaluate_if_stack(struct sl_pp_context *context)
+{
+   unsigned int i;
+
+   for (i = context->if_ptr; i < SL_PP_MAX_IF_NESTING; i++) {
+      if (!(context->if_stack[i] & 1)) {
+         return 0;
+      }
+   }
+   return 1;
+}
+
+static int
+_parse_if(struct sl_pp_context *context,
+          struct sl_pp_token_buffer *buffer)
+{
+   struct sl_pp_process_state state;
+   int found_end = 0;
+   struct sl_pp_token_info eof;
+   int result;
+
+   if (!context->if_ptr) {
+      strcpy(context->error_msg, "`#if' nesting too deep");
+      return -1;
+   }
+
+   memset(&state, 0, sizeof(state));
+   while (!found_end) {
+      struct sl_pp_token_info input;
+
+      sl_pp_token_buffer_get(buffer, &input);
+      switch (input.token) {
+      case SL_PP_WHITESPACE:
+         break;
+
+      case SL_PP_IDENTIFIER:
+         if (input.data.identifier == context->dict.defined) {
+            if (_parse_defined(context, buffer, &state)) {
+               free(state.out);
+               return -1;
+            }
+         } else {
+            sl_pp_token_buffer_unget(buffer, &input);
+            if (sl_pp_macro_expand(context, buffer, NULL, &state, sl_pp_macro_expand_unknown_to_0)) {
+               free(state.out);
+               return -1;
+            }
+         }
+         break;
+
+      case SL_PP_NEWLINE:
+      case SL_PP_EOF:
+         found_end = 1;
+         break;
+
+      default:
+         if (sl_pp_process_out(&state, &input)) {
+            strcpy(context->error_msg, "out of memory");
+            free(state.out);
+            return -1;
+         }
+      }
+   }
+
+   eof.token = SL_PP_EOF;
+   if (sl_pp_process_out(&state, &eof)) {
+      strcpy(context->error_msg, "out of memory");
+      free(state.out);
+      return -1;
+   }
+
+   if (sl_pp_execute_expression(context, state.out, &result)) {
+      free(state.out);
+      return -1;
+   }
+
+   free(state.out);
+
+   context->if_ptr--;
+   context->if_stack[context->if_ptr] = result ? 1 : 0;
+   context->if_value = _evaluate_if_stack(context);
+
+   return 0;
+}
+
+static int
+_parse_else(struct sl_pp_context *context)
+{
+   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) {
+      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;
+   context->if_value = _evaluate_if_stack(context);
+
+   return 0;
+}
+
+int
+sl_pp_process_if(struct sl_pp_context *context,
+                 struct sl_pp_token_buffer *buffer)
+{
+   return _parse_if(context, buffer);
+}
+
+int
+sl_pp_process_ifdef(struct sl_pp_context *context,
+                    const struct sl_pp_token_info *input,
+                    unsigned int first,
+                    unsigned int last)
+{
+   unsigned int i;
+
+   if (!context->if_ptr) {
+      strcpy(context->error_msg, "`#if' nesting too deep");
+      return -1;
+   }
+
+   for (i = first; i < last; i++) {
+      switch (input[i].token) {
+      case SL_PP_IDENTIFIER:
+         {
+            struct sl_pp_macro *macro;
+            int macro_name = input[i].data.identifier;
+            int defined = 0;
+
+            for (macro = context->macro; macro; macro = macro->next) {
+               if (macro->name == macro_name) {
+                  defined = 1;
+                  break;
+               }
+            }
+
+            context->if_ptr--;
+            context->if_stack[context->if_ptr] = defined ? 1 : 0;
+            context->if_value = _evaluate_if_stack(context);
+         }
+         return 0;
+
+      case SL_PP_WHITESPACE:
+         break;
+
+      default:
+         strcpy(context->error_msg, "expected an identifier");
+         return -1;
+      }
+   }
+
+   strcpy(context->error_msg, "expected an identifier");
+   return -1;
+}
+
+int
+sl_pp_process_ifndef(struct sl_pp_context *context,
+                     const struct sl_pp_token_info *input,
+                     unsigned int first,
+                     unsigned int last)
+{
+   unsigned int i;
+
+   if (!context->if_ptr) {
+      strcpy(context->error_msg, "`#if' nesting too deep");
+      return -1;
+   }
+
+   for (i = first; i < last; i++) {
+      switch (input[i].token) {
+      case SL_PP_IDENTIFIER:
+         {
+            struct sl_pp_macro *macro;
+            int macro_name = input[i].data.identifier;
+            int defined = 0;
+
+            for (macro = context->macro; macro; macro = macro->next) {
+               if (macro->name == macro_name) {
+                  defined = 1;
+                  break;
+               }
+            }
+
+            context->if_ptr--;
+            context->if_stack[context->if_ptr] = defined ? 0 : 1;
+            context->if_value = _evaluate_if_stack(context);
+         }
+         return 0;
+
+      case SL_PP_WHITESPACE:
+         break;
+
+      default:
+         strcpy(context->error_msg, "expected an identifier");
+         return -1;
+      }
+   }
+
+   strcpy(context->error_msg, "expected an identifier");
+   return -1;
+}
+
+int
+sl_pp_process_elif(struct sl_pp_context *context,
+                   struct sl_pp_token_buffer *buffer)
+{
+   if (_parse_else(context)) {
+      return -1;
+   }
+
+   if (context->if_stack[context->if_ptr] & 1) {
+      context->if_ptr++;
+      if (_parse_if(context, buffer)) {
+         return -1;
+      }
+   }
+
+   /* We are still in the #if block. */
+   context->if_stack[context->if_ptr] = context->if_stack[context->if_ptr] & ~2;
+
+   return 0;
+}
+
+int
+sl_pp_process_else(struct sl_pp_context *context,
+                   const struct sl_pp_token_info *input,
+                   unsigned int first,
+                   unsigned int last)
+{
+   return _parse_else(context);
+}
+
+int
+sl_pp_process_endif(struct sl_pp_context *context,
+                    const struct sl_pp_token_info *input,
+                    unsigned int first,
+                    unsigned int last)
+{
+   if (context->if_ptr == SL_PP_MAX_IF_NESTING) {
+      strcpy(context->error_msg, "no matching `#if'");
+      return -1;
+   }
+
+   context->if_ptr++;
+   context->if_value = _evaluate_if_stack(context);
+
+   return 0;
+}
diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c
new file mode 100644
index 0000000..6f7e9eb
--- /dev/null
+++ b/src/glsl/pp/sl_pp_line.c
@@ -0,0 +1,127 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "sl_pp_context.h"
+#include "sl_pp_public.h"
+#include "sl_pp_process.h"
+
+
+int
+sl_pp_process_line(struct sl_pp_context *context,
+                   struct sl_pp_token_buffer *buffer,
+                   struct sl_pp_process_state *pstate)
+{
+   struct sl_pp_process_state state;
+   int found_end = 0;
+   int line_number = -1;
+   int file_number = -1;
+   unsigned int line;
+   unsigned int file;
+
+   memset(&state, 0, sizeof(state));
+   while (!found_end) {
+      struct sl_pp_token_info input;
+
+      sl_pp_token_buffer_get(buffer, &input);
+      switch (input.token) {
+      case SL_PP_WHITESPACE:
+         break;
+
+      case SL_PP_IDENTIFIER:
+         sl_pp_token_buffer_unget(buffer, &input);
+         if (sl_pp_macro_expand(context, buffer, NULL, &state, sl_pp_macro_expand_normal)) {
+            free(state.out);
+            return -1;
+         }
+         break;
+
+      case SL_PP_NEWLINE:
+      case SL_PP_EOF:
+         found_end = 1;
+         break;
+
+      default:
+         if (sl_pp_process_out(&state, &input)) {
+            strcpy(context->error_msg, "out of memory");
+            free(state.out);
+            return -1;
+         }
+      }
+   }
+
+   if (state.out_len > 0 && state.out[0].token == SL_PP_UINT) {
+      line_number = state.out[0].data._uint;
+   } else {
+      strcpy(context->error_msg, "expected a number after `#line'");
+      free(state.out);
+      return -1;
+   }
+
+   if (state.out_len > 1) {
+      if (state.out[1].token == SL_PP_UINT) {
+         file_number = state.out[1].data._uint;
+      } else {
+         strcpy(context->error_msg, "expected a number after line number");
+         free(state.out);
+         return -1;
+      }
+
+      if (state.out_len > 2) {
+         strcpy(context->error_msg, "expected an end of line after file number");
+         free(state.out);
+         return -1;
+      }
+   }
+
+   free(state.out);
+
+   line = atoi(sl_pp_context_cstr(context, line_number));
+   if (file_number != -1) {
+      file = atoi(sl_pp_context_cstr(context, file_number));
+   } else {
+      file = context->file;
+   }
+
+   if (context->line != line || context->file != file) {
+      struct sl_pp_token_info ti;
+
+      ti.token = SL_PP_LINE;
+      ti.data.line.lineno = line;
+      ti.data.line.fileno = file;
+      if (sl_pp_process_out(pstate, &ti)) {
+         strcpy(context->error_msg, "out of memory");
+         return -1;
+      }
+
+      context->line = line;
+      context->file = file;
+   }
+
+   return 0;
+}
diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c
new file mode 100644
index 0000000..9f520b8
--- /dev/null
+++ b/src/glsl/pp/sl_pp_macro.c
@@ -0,0 +1,414 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "sl_pp_context.h"
+#include "sl_pp_public.h"
+#include "sl_pp_macro.h"
+#include "sl_pp_process.h"
+
+
+static void
+_macro_init(struct sl_pp_macro *macro)
+{
+   macro->name = -1;
+   macro->num_args = -1;
+   macro->arg = NULL;
+   macro->body = NULL;
+}
+
+struct sl_pp_macro *
+sl_pp_macro_new(void)
+{
+   struct sl_pp_macro *macro;
+
+   macro = calloc(1, sizeof(struct sl_pp_macro));
+   if (macro) {
+      _macro_init(macro);
+   }
+   return macro;
+}
+
+static void
+_macro_destroy(struct sl_pp_macro *macro)
+{
+   struct sl_pp_macro_formal_arg *arg = macro->arg;
+
+   while (arg) {
+      struct sl_pp_macro_formal_arg *next_arg = arg->next;
+
+      free(arg);
+      arg = next_arg;
+   }
+
+   free(macro->body);
+}
+
+void
+sl_pp_macro_free(struct sl_pp_macro *macro)
+{
+   while (macro) {
+      struct sl_pp_macro *next_macro = macro->next;
+
+      _macro_destroy(macro);
+      free(macro);
+      macro = next_macro;
+   }
+}
+
+void
+sl_pp_macro_reset(struct sl_pp_macro *macro)
+{
+   _macro_destroy(macro);
+   _macro_init(macro);
+}
+
+static int
+_out_number(struct sl_pp_context *context,
+            struct sl_pp_process_state *state,
+            unsigned int number)
+{
+   char buf[32];
+   struct sl_pp_token_info ti;
+
+   sprintf(buf, "%u", number);
+
+   ti.token = SL_PP_UINT;
+   ti.data._uint = sl_pp_context_add_unique_str(context, buf);
+   if (sl_pp_process_out(state, &ti)) {
+      strcpy(context->error_msg, "out of memory");
+      return -1;
+   }
+
+   return 0;
+}
+
+int
+sl_pp_macro_expand(struct sl_pp_context *context,
+                   struct sl_pp_token_buffer *tokens,
+                   struct sl_pp_macro *local,
+                   struct sl_pp_process_state *state,
+                   enum sl_pp_macro_expand_behaviour behaviour)
+{
+   int mute = (behaviour == sl_pp_macro_expand_mute);
+   struct sl_pp_token_info input;
+   int macro_name;
+   struct sl_pp_macro *macro = NULL;
+   struct sl_pp_macro *actual_arg = NULL;
+   unsigned int j;
+
+   if (sl_pp_token_buffer_get(tokens, &input)) {
+      return -1;
+   }
+
+   if (input.token != SL_PP_IDENTIFIER) {
+      strcpy(context->error_msg, "expected an identifier");
+      return -1;
+   }
+
+   macro_name = input.data.identifier;
+
+   /* First look for predefined macros.
+    */
+
+   if (macro_name == context->dict.___LINE__) {
+      if (!mute && _out_number(context, state, context->line)) {
+         return -1;
+      }
+      return 0;
+   }
+   if (macro_name == context->dict.___FILE__) {
+      if (!mute && _out_number(context, state, context->file)) {
+         return -1;
+      }
+      return 0;
+   }
+   if (macro_name == context->dict.___VERSION__) {
+      if (!mute && _out_number(context, state, 110)) {
+         return -1;
+      }
+      return 0;
+   }
+
+   for (j = 0; j < context->num_predefined; j++) {
+      if (macro_name == context->predefined[j].name) {
+         if (!mute) {
+            struct sl_pp_token_info ti;
+
+            ti.token = SL_PP_UINT;
+            ti.data._uint = context->predefined[j].value;
+            if (sl_pp_process_out(state, &ti)) {
+               strcpy(context->error_msg, "out of memory");
+               return -1;
+            }
+         }
+         return 0;
+      }
+   }
+
+   /* Replace extension names with 1.
+    */
+   for (j = 0; j < context->num_extensions; j++) {
+      if (macro_name == context->extensions[j].name) {
+         if (!mute && _out_number(context, state, 1)) {
+            return -1;
+         }
+         return 0;
+      }
+   }
+
+   if (local) {
+      for (macro = local; macro; macro = macro->next) {
+         if (macro->name == macro_name) {
+            break;
+         }
+      }
+   }
+
+   if (!macro) {
+      for (macro = context->macro; macro; macro = macro->next) {
+         if (macro->name == macro_name) {
+            break;
+         }
+      }
+   }
+
+   if (!macro) {
+      if (behaviour == sl_pp_macro_expand_unknown_to_0) {
+         if (_out_number(context, state, 0)) {
+            strcpy(context->error_msg, "out of memory");
+            return -1;
+         }
+      } else if (!mute) {
+         if (sl_pp_process_out(state, &input)) {
+            strcpy(context->error_msg, "out of memory");
+            return -1;
+         }
+      }
+      return 0;
+   }
+
+   if (macro->num_args >= 0) {
+      if (sl_pp_token_buffer_skip_white(tokens, &input)) {
+         return -1;
+      }
+      if (input.token != SL_PP_LPAREN) {
+         strcpy(context->error_msg, "expected `('");
+         return -1;
+      }
+      if (sl_pp_token_buffer_skip_white(tokens, &input)) {
+         return -1;
+      }
+      sl_pp_token_buffer_unget(tokens, &input);
+   }
+
+   if (macro->num_args > 0) {
+      struct sl_pp_macro_formal_arg *formal_arg = macro->arg;
+      struct sl_pp_macro **pmacro = &actual_arg;
+
+      for (j = 0; j < (unsigned int)macro->num_args; j++) {
+         struct sl_pp_process_state arg_state;
+         int done = 0;
+         unsigned int paren_nesting = 0;
+         struct sl_pp_token_info eof;
+
+         memset(&arg_state, 0, sizeof(arg_state));
+
+         while (!done) {
+            if (sl_pp_token_buffer_get(tokens, &input)) {
+               goto fail_arg;
+            }
+            switch (input.token) {
+            case SL_PP_WHITESPACE:
+               break;
+
+            case SL_PP_COMMA:
+               if (!paren_nesting) {
+                  if (j < (unsigned int)macro->num_args - 1) {
+                     done = 1;
+                  } else {
+                     strcpy(context->error_msg, "too many actual macro arguments");
+                     goto fail_arg;
+                  }
+               } else {
+                  if (sl_pp_process_out(&arg_state, &input)) {
+                     strcpy(context->error_msg, "out of memory");
+                     goto fail_arg;
+                  }
+               }
+               break;
+
+            case SL_PP_LPAREN:
+               paren_nesting++;
+               if (sl_pp_process_out(&arg_state, &input)) {
+                  goto oom_arg;
+               }
+               break;
+
+            case SL_PP_RPAREN:
+               if (!paren_nesting) {
+                  if (j == (unsigned int)macro->num_args - 1) {
+                     done = 1;
+                  } else {
+                     strcpy(context->error_msg, "too few actual macro arguments");
+                     goto fail_arg;
+                  }
+               } else {
+                  paren_nesting--;
+                  if (sl_pp_process_out(&arg_state, &input)) {
+                     goto oom_arg;
+                  }
+               }
+               break;
+
+            case SL_PP_IDENTIFIER:
+               sl_pp_token_buffer_unget(tokens, &input);
+               if (sl_pp_macro_expand(context, tokens, local, &arg_state, sl_pp_macro_expand_normal)) {
+                  goto fail_arg;
+               }
+               break;
+
+            case SL_PP_EOF:
+               strcpy(context->error_msg, "too few actual macro arguments");
+               goto fail_arg;
+
+            default:
+               if (sl_pp_process_out(&arg_state, &input)) {
+                  goto oom_arg;
+               }
+            }
+         }
+
+         eof.token = SL_PP_EOF;
+         if (sl_pp_process_out(&arg_state, &eof)) {
+            goto oom_arg;
+         }
+
+         *pmacro = sl_pp_macro_new();
+         if (!*pmacro) {
+            goto oom_arg;
+         }
+
+         (**pmacro).name = formal_arg->name;
+         (**pmacro).body = arg_state.out;
+
+         formal_arg = formal_arg->next;
+         pmacro = &(**pmacro).next;
+
+         continue;
+
+oom_arg:
+         strcpy(context->error_msg, "out of memory");
+fail_arg:
+         free(arg_state.out);
+         goto fail;
+      }
+   }
+
+   /* Right paren for non-empty argument list has already been eaten. */
+   if (macro->num_args == 0) {
+      if (sl_pp_token_buffer_skip_white(tokens, &input)) {
+         goto fail;
+      }
+      if (input.token != SL_PP_RPAREN) {
+         strcpy(context->error_msg, "expected `)'");
+         goto fail;
+      }
+   }
+
+   /* XXX: This is all wrong, we should be ungetting all tokens
+    *      back to the main token buffer.
+    */
+   {
+      struct sl_pp_token_buffer buffer;
+
+      /* Seek to the end.
+       */
+      for (j = 0; macro->body[j].token != SL_PP_EOF; j++) {
+      }
+      j++;
+
+      /* Create a context-less token buffer since we are not going to underrun
+       * its internal buffer.
+       */
+      if (sl_pp_token_buffer_init(&buffer, NULL)) {
+         strcpy(context->error_msg, "out of memory");
+         goto fail;
+      }
+
+      /* Unget the tokens in reverse order so later they will be fetched correctly.
+       */
+      for (; j > 0; j--) {
+         sl_pp_token_buffer_unget(&buffer, &macro->body[j - 1]);
+      }
+
+      /* Expand.
+       */
+      for (;;) {
+         struct sl_pp_token_info input;
+
+         sl_pp_token_buffer_get(&buffer, &input);
+         switch (input.token) {
+         case SL_PP_NEWLINE:
+            if (sl_pp_process_out(state, &input)) {
+               strcpy(context->error_msg, "out of memory");
+               sl_pp_token_buffer_destroy(&buffer);
+               goto fail;
+            }
+            break;
+
+         case SL_PP_IDENTIFIER:
+            sl_pp_token_buffer_unget(&buffer, &input);
+            if (sl_pp_macro_expand(context, &buffer, actual_arg, state, behaviour)) {
+               sl_pp_token_buffer_destroy(&buffer);
+               goto fail;
+            }
+            break;
+
+         case SL_PP_EOF:
+            sl_pp_token_buffer_destroy(&buffer);
+            sl_pp_macro_free(actual_arg);
+            return 0;
+
+         default:
+            if (!mute) {
+               if (sl_pp_process_out(state, &input)) {
+                  strcpy(context->error_msg, "out of memory");
+                  sl_pp_token_buffer_destroy(&buffer);
+                  goto fail;
+               }
+            }
+         }
+      }
+   }
+
+fail:
+   sl_pp_macro_free(actual_arg);
+   return -1;
+}
diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h
new file mode 100644
index 0000000..1d21068
--- /dev/null
+++ b/src/glsl/pp/sl_pp_macro.h
@@ -0,0 +1,73 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#ifndef SL_PP_MACRO_H
+#define SL_PP_MACRO_H
+
+#include "sl_pp_token.h"
+
+
+struct sl_pp_context;
+struct sl_pp_process_state;
+struct sl_pp_token_buffer;
+
+struct sl_pp_macro_formal_arg {
+   int name;
+   struct sl_pp_macro_formal_arg *next;
+};
+
+struct sl_pp_macro {
+   int name;
+   int num_args;                       /* -1 means no args, 0 means `()' */
+   struct sl_pp_macro_formal_arg *arg;
+   struct sl_pp_token_info *body;
+   struct sl_pp_macro *next;
+};
+
+struct sl_pp_macro *
+sl_pp_macro_new(void);
+
+void
+sl_pp_macro_free(struct sl_pp_macro *macro);
+
+void
+sl_pp_macro_reset(struct sl_pp_macro *macro);
+
+enum sl_pp_macro_expand_behaviour {
+   sl_pp_macro_expand_normal,
+   sl_pp_macro_expand_mute,
+   sl_pp_macro_expand_unknown_to_0
+};
+
+int
+sl_pp_macro_expand(struct sl_pp_context *context,
+                   struct sl_pp_token_buffer *tokens,
+                   struct sl_pp_macro *local,
+                   struct sl_pp_process_state *state,
+                   enum sl_pp_macro_expand_behaviour behaviour);
+
+#endif /* SL_PP_MACRO_H */
diff --git a/src/glsl/pp/sl_pp_pragma.c b/src/glsl/pp/sl_pp_pragma.c
new file mode 100644
index 0000000..caf4c63
--- /dev/null
+++ b/src/glsl/pp/sl_pp_pragma.c
@@ -0,0 +1,109 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "sl_pp_context.h"
+#include "sl_pp_process.h"
+
+
+int
+sl_pp_process_pragma(struct sl_pp_context *context,
+                     const struct sl_pp_token_info *input,
+                     unsigned int first,
+                     unsigned int last,
+                     struct sl_pp_process_state *state)
+{
+   int pragma_name = -1;
+   struct sl_pp_token_info out;
+   int arg_name = -1;
+
+   if (first < last && input[first].token == SL_PP_IDENTIFIER) {
+      pragma_name = input[first].data.identifier;
+      first++;
+   }
+   if (pragma_name == -1) {
+      return 0;
+   }
+
+   if (pragma_name == context->dict.optimize) {
+      out.token = SL_PP_PRAGMA_OPTIMIZE;
+   } else if (pragma_name == context->dict.debug) {
+      out.token = SL_PP_PRAGMA_DEBUG;
+   } else {
+      return 0;
+   }
+
+   while (first < last && input[first].token == SL_PP_WHITESPACE) {
+      first++;
+   }
+
+   if (first < last && input[first].token == SL_PP_LPAREN) {
+      first++;
+   } else {
+      return 0;
+   }
+
+   while (first < last && input[first].token == SL_PP_WHITESPACE) {
+      first++;
+   }
+
+   if (first < last && input[first].token == SL_PP_IDENTIFIER) {
+      arg_name = input[first].data.identifier;
+      first++;
+   }
+   if (arg_name == -1) {
+      return 0;
+   }
+
+   if (arg_name == context->dict.off) {
+      out.data.pragma = 0;
+   } else if (arg_name == context->dict.on) {
+      out.data.pragma = 1;
+   } else {
+      return 0;
+   }
+
+   while (first < last && input[first].token == SL_PP_WHITESPACE) {
+      first++;
+   }
+
+   if (first < last && input[first].token == SL_PP_RPAREN) {
+      first++;
+   } else {
+      return 0;
+   }
+
+   /* Ignore the tokens that follow. */
+
+   if (sl_pp_process_out(state, &out)) {
+      strcpy(context->error_msg, "out of memory");
+      return -1;
+   }
+
+   return 0;
+}
diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c
new file mode 100644
index 0000000..f89986d
--- /dev/null
+++ b/src/glsl/pp/sl_pp_process.c
@@ -0,0 +1,327 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "sl_pp_context.h"
+#include "sl_pp_process.h"
+#include "sl_pp_public.h"
+
+
+int
+sl_pp_process_out(struct sl_pp_process_state *state,
+                  const struct sl_pp_token_info *token)
+{
+   if (state->out_len >= state->out_max) {
+      unsigned int new_max = state->out_max;
+
+      if (new_max < 0x100) {
+         new_max = 0x100;
+      } else if (new_max < 0x10000) {
+         new_max *= 2;
+      } else {
+         new_max += 0x10000;
+      }
+
+      state->out = realloc(state->out, new_max * sizeof(struct sl_pp_token_info));
+      if (!state->out) {
+         return -1;
+      }
+      state->out_max = new_max;
+   }
+
+   state->out[state->out_len++] = *token;
+   return 0;
+}
+
+int
+sl_pp_process_get(struct sl_pp_context *context,
+                  struct sl_pp_token_info *output)
+{
+   if (!context->process_state.out) {
+      if (context->line > 1) {
+         struct sl_pp_token_info ti;
+
+         ti.token = SL_PP_LINE;
+         ti.data.line.lineno = context->line - 1;
+         ti.data.line.fileno = context->file;
+         if (sl_pp_process_out(&context->process_state, &ti)) {
+            strcpy(context->error_msg, "out of memory");
+            return -1;
+         }
+
+         ti.token = SL_PP_NEWLINE;
+         if (sl_pp_process_out(&context->process_state, &ti)) {
+            strcpy(context->error_msg, "out of memory");
+            return -1;
+         }
+      }
+   }
+
+   for (;;) {
+      struct sl_pp_token_info input;
+      int found_eof = 0;
+
+      if (context->process_state.out_len) {
+         *output = context->process_state.out[0];
+
+         if (context->process_state.out_len > 1) {
+            unsigned int i;
+
+            for (i = 1; i < context->process_state.out_len; i++) {
+               context->process_state.out[i - 1] = context->process_state.out[i];
+            }
+         }
+         context->process_state.out_len--;
+
+         return 0;
+      }
+
+      if (sl_pp_token_buffer_skip_white(&context->tokens, &input)) {
+         return -1;
+      }
+      if (input.token == SL_PP_HASH) {
+         if (sl_pp_token_buffer_skip_white(&context->tokens, &input)) {
+            return -1;
+         }
+         switch (input.token) {
+         case SL_PP_IDENTIFIER:
+            {
+               int name;
+               int found_eol = 0;
+               struct sl_pp_token_info endof;
+               struct sl_pp_token_peek peek;
+               int result = 0;
+
+               /* Directive name. */
+               name = input.data.identifier;
+
+               if (sl_pp_token_buffer_skip_white(&context->tokens, &input)) {
+                  return -1;
+               }
+               sl_pp_token_buffer_unget(&context->tokens, &input);
+
+               if (sl_pp_token_peek_init(&peek, &context->tokens)) {
+                  return -1;
+               }
+
+               while (!found_eol) {
+                  if (sl_pp_token_peek_get(&peek, &input)) {
+                     sl_pp_token_peek_destroy(&peek);
+                     return -1;
+                  }
+                  switch (input.token) {
+                  case SL_PP_NEWLINE:
+                     /* Preserve newline just for the sake of line numbering. */
+                     endof = input;
+                     found_eol = 1;
+                     break;
+
+                  case SL_PP_EOF:
+                     endof = input;
+                     found_eof = 1;
+                     found_eol = 1;
+                     break;
+
+                  default:
+                     break;
+                  }
+               }
+
+               if (name == context->dict._if) {
+                  struct sl_pp_token_buffer buffer;
+
+                  result = sl_pp_token_peek_to_buffer(&peek, &buffer);
+                  if (result == 0) {
+                     result = sl_pp_process_if(context, &buffer);
+                     sl_pp_token_buffer_destroy(&buffer);
+                  }
+               } else if (name == context->dict.ifdef) {
+                  result = sl_pp_process_ifdef(context, peek.tokens, 0, peek.size - 1);
+               } else if (name == context->dict.ifndef) {
+                  result = sl_pp_process_ifndef(context, peek.tokens, 0, peek.size - 1);
+               } else if (name == context->dict.elif) {
+                  struct sl_pp_token_buffer buffer;
+
+                  result = sl_pp_token_peek_to_buffer(&peek, &buffer);
+                  if (result == 0) {
+                     result = sl_pp_process_elif(context, &buffer);
+                     sl_pp_token_buffer_destroy(&buffer);
+                  }
+               } else if (name == context->dict._else) {
+                  result = sl_pp_process_else(context, peek.tokens, 0, peek.size - 1);
+               } else if (name == context->dict.endif) {
+                  result = sl_pp_process_endif(context, peek.tokens, 0, peek.size - 1);
+               } else if (context->if_value) {
+                  if (name == context->dict.define) {
+                     result = sl_pp_process_define(context, peek.tokens, 0, peek.size - 1);
+                  } else if (name == context->dict.error) {
+                     sl_pp_process_error(context, peek.tokens, 0, peek.size - 1);
+                     result = -1;
+                  } else if (name == context->dict.extension) {
+                     result = sl_pp_process_extension(context, peek.tokens, 0, peek.size - 1, &context->process_state);
+                  } else if (name == context->dict.line) {
+                     struct sl_pp_token_buffer buffer;
+
+                     result = sl_pp_token_peek_to_buffer(&peek, &buffer);
+                     if (result == 0) {
+                        result = sl_pp_process_line(context, &buffer, &context->process_state);
+                        sl_pp_token_buffer_destroy(&buffer);
+                     }
+                  } else if (name == context->dict.pragma) {
+                     result = sl_pp_process_pragma(context, peek.tokens, 0, peek.size - 1, &context->process_state);
+                  } else if (name == context->dict.undef) {
+                     result = sl_pp_process_undef(context, peek.tokens, 0, peek.size - 1);
+                  } else {
+                     strcpy(context->error_msg, "unrecognised directive name");
+                     result = -1;
+                  }
+               }
+
+               sl_pp_token_peek_commit(&peek);
+               sl_pp_token_peek_destroy(&peek);
+
+               if (result) {
+                  return result;
+               }
+
+               if (sl_pp_process_out(&context->process_state, &endof)) {
+                  strcpy(context->error_msg, "out of memory");
+                  return -1;
+               }
+               context->line++;
+            }
+            break;
+
+         case SL_PP_NEWLINE:
+            /* Empty directive. */
+            if (sl_pp_process_out(&context->process_state, &input)) {
+               strcpy(context->error_msg, "out of memory");
+               return -1;
+            }
+            context->line++;
+            break;
+
+         case SL_PP_EOF:
+            /* Empty directive. */
+            if (sl_pp_process_out(&context->process_state, &input)) {
+               strcpy(context->error_msg, "out of memory");
+               return -1;
+            }
+            found_eof = 1;
+            break;
+
+         default:
+            strcpy(context->error_msg, "expected a directive name");
+            return -1;
+         }
+      } else {
+         int found_eol = 0;
+
+         sl_pp_token_buffer_unget(&context->tokens, &input);
+
+         while (!found_eol) {
+            if (sl_pp_token_buffer_get(&context->tokens, &input)) {
+               return -1;
+            }
+
+            switch (input.token) {
+            case SL_PP_WHITESPACE:
+               /* Drop whitespace all together at this point. */
+               break;
+
+            case SL_PP_NEWLINE:
+               /* Preserve newline just for the sake of line numbering. */
+               if (sl_pp_process_out(&context->process_state, &input)) {
+                  strcpy(context->error_msg, "out of memory");
+                  return -1;
+               }
+               context->line++;
+               found_eol = 1;
+               break;
+
+            case SL_PP_EOF:
+               if (sl_pp_process_out(&context->process_state, &input)) {
+                  strcpy(context->error_msg, "out of memory");
+                  return -1;
+               }
+               found_eof = 1;
+               found_eol = 1;
+               break;
+
+            case SL_PP_IDENTIFIER:
+               sl_pp_token_buffer_unget(&context->tokens, &input);
+               if (sl_pp_macro_expand(context, &context->tokens, NULL, &context->process_state,
+                                      context->if_value ? sl_pp_macro_expand_normal : sl_pp_macro_expand_mute)) {
+                  return -1;
+               }
+               break;
+
+            default:
+               if (context->if_value) {
+                  if (sl_pp_process_out(&context->process_state, &input)) {
+                     strcpy(context->error_msg, "out of memory");
+                     return -1;
+                  }
+               }
+            }
+         }
+      }
+
+      if (found_eof) {
+         if (context->if_ptr != SL_PP_MAX_IF_NESTING) {
+            strcpy(context->error_msg, "expected `#endif' directive");
+            return -1;
+         }
+      }
+   }
+}
+
+int
+sl_pp_process(struct sl_pp_context *context,
+              struct sl_pp_token_info **output)
+{
+   struct sl_pp_process_state state;
+
+   memset(&state, 0, sizeof(state));
+   for (;;) {
+      struct sl_pp_token_info input;
+
+      if (sl_pp_process_get(context, &input)) {
+         free(state.out);
+         return -1;
+      }
+      if (sl_pp_process_out(&state, &input)) {
+         free(state.out);
+         return -1;
+      }
+      if (input.token == SL_PP_EOF) {
+         *output = state.out;
+         return 0;
+      }
+   }
+}
diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h
new file mode 100644
index 0000000..fe6ff0d
--- /dev/null
+++ b/src/glsl/pp/sl_pp_process.h
@@ -0,0 +1,116 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#ifndef SL_PP_PROCESS_H
+#define SL_PP_PROCESS_H
+
+#include "sl_pp_macro.h"
+#include "sl_pp_token.h"
+
+
+struct sl_pp_context;
+
+struct sl_pp_process_state {
+   struct sl_pp_token_info *out;
+   unsigned int out_len;
+   unsigned int out_max;
+};
+
+int
+sl_pp_process_define(struct sl_pp_context *context,
+                     const struct sl_pp_token_info *input,
+                     unsigned int first,
+                     unsigned int last);
+
+int
+sl_pp_process_undef(struct sl_pp_context *context,
+                    const struct sl_pp_token_info *input,
+                    unsigned int first,
+                    unsigned int last);
+
+int
+sl_pp_process_if(struct sl_pp_context *context,
+                 struct sl_pp_token_buffer *input);
+
+int
+sl_pp_process_ifdef(struct sl_pp_context *context,
+                    const struct sl_pp_token_info *input,
+                    unsigned int first,
+                    unsigned int last);
+
+int
+sl_pp_process_ifndef(struct sl_pp_context *context,
+                     const struct sl_pp_token_info *input,
+                     unsigned int first,
+                     unsigned int last);
+
+int
+sl_pp_process_elif(struct sl_pp_context *context,
+                   struct sl_pp_token_buffer *buffer);
+
+int
+sl_pp_process_else(struct sl_pp_context *context,
+                   const struct sl_pp_token_info *input,
+                   unsigned int first,
+                   unsigned int last);
+
+int
+sl_pp_process_endif(struct sl_pp_context *context,
+                    const struct sl_pp_token_info *input,
+                    unsigned int first,
+                    unsigned int last);
+
+void
+sl_pp_process_error(struct sl_pp_context *context,
+                    const struct sl_pp_token_info *input,
+                    unsigned int first,
+                    unsigned int last);
+
+int
+sl_pp_process_pragma(struct sl_pp_context *context,
+                     const struct sl_pp_token_info *input,
+                     unsigned int first,
+                     unsigned int last,
+                     struct sl_pp_process_state *state);
+
+int
+sl_pp_process_extension(struct sl_pp_context *context,
+                        const struct sl_pp_token_info *input,
+                        unsigned int first,
+                        unsigned int last,
+                        struct sl_pp_process_state *state);
+
+int
+sl_pp_process_line(struct sl_pp_context *context,
+                   struct sl_pp_token_buffer *buffer,
+                   struct sl_pp_process_state *state);
+
+int
+sl_pp_process_out(struct sl_pp_process_state *state,
+                  const struct sl_pp_token_info *token);
+
+#endif /* SL_PP_PROCESS_H */
diff --git a/src/glsl/pp/sl_pp_public.h b/src/glsl/pp/sl_pp_public.h
new file mode 100644
index 0000000..12528d6
--- /dev/null
+++ b/src/glsl/pp/sl_pp_public.h
@@ -0,0 +1,84 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#ifndef SL_PP_PUBLIC_H
+#define SL_PP_PUBLIC_H
+
+
+struct sl_pp_context;
+
+
+#include "sl_pp_purify.h"
+#include "sl_pp_token.h"
+
+
+struct sl_pp_context *
+sl_pp_context_create(const char *input,
+                     const struct sl_pp_purify_options *options);
+
+void
+sl_pp_context_destroy(struct sl_pp_context *context);
+
+const char *
+sl_pp_context_error_message(const struct sl_pp_context *context);
+
+void
+sl_pp_context_error_position(const struct sl_pp_context *context,
+                             unsigned int *file,
+                             unsigned int *line);
+
+int
+sl_pp_context_add_extension(struct sl_pp_context *context,
+                            const char *name,
+                            const char *name_string);
+
+int
+sl_pp_context_add_predefined(struct sl_pp_context *context,
+                             const char *name,
+                             const char *value);
+
+int
+sl_pp_context_add_unique_str(struct sl_pp_context *context,
+                             const char *str);
+
+const char *
+sl_pp_context_cstr(const struct sl_pp_context *context,
+                   int offset);
+
+int
+sl_pp_version(struct sl_pp_context *context,
+              unsigned int *version);
+
+int
+sl_pp_process_get(struct sl_pp_context *context,
+                  struct sl_pp_token_info *output);
+
+int
+sl_pp_process(struct sl_pp_context *context,
+              struct sl_pp_token_info **output);
+
+#endif /* SL_PP_PUBLIC_H */
diff --git a/src/glsl/pp/sl_pp_purify.c b/src/glsl/pp/sl_pp_purify.c
new file mode 100644
index 0000000..b50f819
--- /dev/null
+++ b/src/glsl/pp/sl_pp_purify.c
@@ -0,0 +1,302 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include "sl_pp_purify.h"
+
+
+/*
+ * Preprocessor purifier performs the following tasks.
+ * - Convert all variants of newlines into a Unix newline.
+ * - Merge continued lines into a single long line.
+ * - Remove line comments and replace block comments with whitespace.
+ */
+
+
+static unsigned int
+_purify_newline(const char *input,
+                char *out,
+                unsigned int *current_line)
+{
+   if (input[0] == '\n') {
+      *out = '\n';
+      (*current_line)++;
+      if (input[1] == '\r') {
+         /*
+          * The GLSL spec is not explicit about whether this
+          * combination is a valid newline or not.
+          * Let's assume it is acceptable.
+          */
+         return 2;
+      }
+      return 1;
+   }
+   if (input[0] == '\r') {
+      *out = '\n';
+      (*current_line)++;
+      if (input[1] == '\n') {
+         return 2;
+      }
+      return 1;
+   }
+   *out = input[0];
+   return 1;
+}
+
+
+static unsigned int
+_purify_backslash(const char *input,
+                  char *out,
+                  unsigned int *current_line)
+{
+   unsigned int eaten = 0;
+
+   for (;;) {
+      if (input[0] == '\\') {
+         char next;
+         unsigned int next_eaten;
+         unsigned int next_line = *current_line;
+
+         eaten++;
+         input++;
+
+         next_eaten = _purify_newline(input, &next, &next_line);
+         if (next == '\n') {
+            /*
+             * If this is really a line continuation sequence, eat
+             * it and do not exit the loop.
+             */
+            eaten += next_eaten;
+            input += next_eaten;
+            *current_line = next_line;
+         } else {
+            /*
+             * It is an error to put anything between a backslash
+             * and a newline and still expect it to behave like a line
+             * continuation sequence.
+             * Even if it is an innocent whitespace.
+             */
+            *out = '\\';
+            break;
+         }
+      } else {
+         eaten += _purify_newline(input, out, current_line);
+         break;
+      }
+   }
+   return eaten;
+}
+
+
+static void
+_report_error(char *buf,
+              unsigned int cbbuf,
+              const char *msg,
+              ...)
+{
+   va_list args;
+
+   va_start(args, msg);
+   vsnprintf(buf, cbbuf, msg, args);
+   va_end(args);
+}
+
+
+void
+sl_pp_purify_state_init(struct sl_pp_purify_state *state,
+                        const char *input,
+                        const struct sl_pp_purify_options *options)
+{
+   state->options = *options;
+   state->input = input;
+   state->current_line = 1;
+   state->inside_c_comment = 0;
+}
+
+
+unsigned int
+_purify_comment(struct sl_pp_purify_state *state,
+                char *output,
+                unsigned int *current_line,
+                char *errormsg,
+                unsigned int cberrormsg)
+{
+   for (;;) {
+      unsigned int eaten;
+      char next;
+
+      eaten = _purify_backslash(state->input, &next, current_line);
+      state->input += eaten;
+      while (next == '*') {
+         eaten = _purify_backslash(state->input, &next, current_line);
+         state->input += eaten;
+         if (next == '/') {
+            *output = ' ';
+            state->inside_c_comment = 0;
+            return 1;
+         }
+      }
+      if (next == '\n') {
+         *output = '\n';
+         state->inside_c_comment = 1;
+         return 1;
+      }
+      if (next == '\0') {
+         _report_error(errormsg, cberrormsg, "expected `*/' but end of translation unit found");
+         return 0;
+      }
+   }
+}
+
+
+unsigned int
+sl_pp_purify_getc(struct sl_pp_purify_state *state,
+                  char *output,
+                  unsigned int *current_line,
+                  char *errormsg,
+                  unsigned int cberrormsg)
+{
+   unsigned int eaten;
+
+   if (state->inside_c_comment) {
+      return _purify_comment(state, output, current_line, errormsg, cberrormsg);
+   }
+
+   eaten = _purify_backslash(state->input, output, current_line);
+   state->input += eaten;
+   if (*output == '/') {
+      char next;
+      unsigned int next_line = *current_line;
+
+      eaten = _purify_backslash(state->input, &next, &next_line);
+      if (next == '/') {
+         state->input += eaten;
+         *current_line = next_line;
+
+         /* Replace a line comment with either a newline or nil. */
+         for (;;) {
+            eaten = _purify_backslash(state->input, &next, current_line);
+            state->input += eaten;
+            if (next == '\n' || next == '\0') {
+               *output = next;
+               return eaten;
+            }
+         }
+      } else if (next == '*') {
+         state->input += eaten;
+         *current_line = next_line;
+
+         return _purify_comment(state, output, current_line, errormsg, cberrormsg);
+      }
+   }
+   return eaten;
+}
+
+
+struct out_buf {
+   char *out;
+   unsigned int len;
+   unsigned int capacity;
+   unsigned int current_line;
+   char *errormsg;
+   unsigned int cberrormsg;
+};
+
+
+static int
+_out_buf_putc(struct out_buf *obuf,
+              char c)
+{
+   if (obuf->len >= obuf->capacity) {
+      unsigned int new_max = obuf->capacity;
+
+      if (new_max < 0x100) {
+         new_max = 0x100;
+      } else if (new_max < 0x10000) {
+         new_max *= 2;
+      } else {
+         new_max += 0x10000;
+      }
+
+      obuf->out = realloc(obuf->out, new_max);
+      if (!obuf->out) {
+         _report_error(obuf->errormsg, obuf->cberrormsg, "out of memory");
+         return -1;
+      }
+      obuf->capacity = new_max;
+   }
+
+   obuf->out[obuf->len++] = c;
+
+   return 0;
+}
+
+
+int
+sl_pp_purify(const char *input,
+             const struct sl_pp_purify_options *options,
+             char **output,
+             char *errormsg,
+             unsigned int cberrormsg,
+             unsigned int *errorline)
+{
+   struct out_buf obuf;
+   struct sl_pp_purify_state state;
+
+   obuf.out = NULL;
+   obuf.len = 0;
+   obuf.capacity = 0;
+   obuf.current_line = 1;
+   obuf.errormsg = errormsg;
+   obuf.cberrormsg = cberrormsg;
+
+   sl_pp_purify_state_init(&state, input, options);
+
+   for (;;) {
+      unsigned int eaten;
+      char c;
+
+      eaten = sl_pp_purify_getc(&state, &c, &obuf.current_line, errormsg, cberrormsg);
+      if (!eaten) {
+         *errorline = obuf.current_line;
+         return -1;
+      }
+      if (_out_buf_putc(&obuf, c)) {
+         *errorline = obuf.current_line;
+         return -1;
+      }
+
+      if (c == '\0') {
+         break;
+      }
+   }
+
+   *output = obuf.out;
+   return 0;
+}
diff --git a/src/glsl/pp/sl_pp_purify.h b/src/glsl/pp/sl_pp_purify.h
new file mode 100644
index 0000000..c0f55cb
--- /dev/null
+++ b/src/glsl/pp/sl_pp_purify.h
@@ -0,0 +1,63 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#ifndef SL_PP_PURIFY_H
+#define SL_PP_PURIFY_H
+
+struct sl_pp_purify_options {
+   unsigned int preserve_columns:1;
+   unsigned int tab_width:4;
+};
+
+int
+sl_pp_purify(const char *input,
+             const struct sl_pp_purify_options *options,
+             char **output,
+             char *errormsg,
+             unsigned int cberrormsg,
+             unsigned int *errorline);
+
+struct sl_pp_purify_state {
+   struct sl_pp_purify_options options;
+   const char *input;
+   unsigned int current_line;
+   unsigned int inside_c_comment:1;
+};
+
+void
+sl_pp_purify_state_init(struct sl_pp_purify_state *state,
+                        const char *input,
+                        const struct sl_pp_purify_options *options);
+
+unsigned int
+sl_pp_purify_getc(struct sl_pp_purify_state *state,
+                  char *output,
+                  unsigned int *current_line,
+                  char *errormsg,
+                  unsigned int cberrormsg);
+
+#endif /* SL_PP_PURIFY_H */
diff --git a/src/glsl/pp/sl_pp_token.c b/src/glsl/pp/sl_pp_token.c
new file mode 100644
index 0000000..a708978
--- /dev/null
+++ b/src/glsl/pp/sl_pp_token.c
@@ -0,0 +1,854 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "sl_pp_public.h"
+#include "sl_pp_context.h"
+#include "sl_pp_token.h"
+
+
+#define PURE_ERROR 256
+
+static int
+_pure_getc(struct sl_pp_context *context)
+{
+   char c;
+
+   if (context->getc_buf_size) {
+      return context->getc_buf[--context->getc_buf_size];
+   }
+
+   if (sl_pp_purify_getc(&context->pure, &c, &context->error_line, context->error_msg, sizeof(context->error_msg)) == 0) {
+      return PURE_ERROR;
+   }
+   return c;
+}
+
+
+static void
+_pure_ungetc(struct sl_pp_context *context,
+             int c)
+{
+   assert(c != PURE_ERROR);
+
+   if (context->getc_buf_size == context->getc_buf_capacity) {
+      context->getc_buf_capacity += 64;
+      context->getc_buf = realloc(context->getc_buf, context->getc_buf_capacity * sizeof(char));
+      assert(context->getc_buf);                            
+   }
+
+   context->getc_buf[context->getc_buf_size++] = (char)c;
+}
+
+
+struct lookahead_state {
+   char buf[256];
+   unsigned int pos;
+   struct sl_pp_context *context;
+};
+
+
+static void
+_lookahead_init(struct lookahead_state *lookahead,
+                struct sl_pp_context *context)
+{
+   lookahead->pos = 0;
+   lookahead->context = context;
+}
+
+
+static unsigned int
+_lookahead_tell(const struct lookahead_state *lookahead)
+{
+   return lookahead->pos;
+}
+
+
+static const void *
+_lookahead_buf(const struct lookahead_state *lookahead)
+{
+   return lookahead->buf;
+}
+
+
+static void
+_lookahead_revert(struct lookahead_state *lookahead,
+                  unsigned int pos)
+{
+   assert(pos <= lookahead->pos);
+
+   while (lookahead->pos > pos) {
+      _pure_ungetc(lookahead->context, lookahead->buf[--lookahead->pos]);
+   }
+}
+
+
+static int
+_lookahead_getc(struct lookahead_state *lookahead)
+{
+   int c;
+
+   assert(lookahead->pos < sizeof(lookahead->buf) / sizeof(lookahead->buf[0]));
+
+   c = _pure_getc(lookahead->context);
+   if (c != PURE_ERROR) {
+      lookahead->buf[lookahead->pos++] = (char)c;
+   }
+   return c;
+}
+
+
+static int
+_is_identifier_char(char c)
+{
+   return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
+}
+
+
+static int
+_tokenise_identifier(struct sl_pp_context *context,
+                     struct sl_pp_token_info *out)
+{
+   int c;
+   char identifier[256];   /* XXX: Remove this artifical limit. */
+   unsigned int i = 0;
+
+   out->token = SL_PP_IDENTIFIER;
+   out->data.identifier = -1;
+
+   c = _pure_getc(context);
+   if (c == PURE_ERROR) {
+      return -1;
+   }
+   identifier[i++] = (char)c;
+   for (;;) {
+      c = _pure_getc(context);
+      if (c == PURE_ERROR) {
+         return -1;
+      }
+
+      if (_is_identifier_char((char)c)) {
+         if (i >= sizeof(identifier) / sizeof(char) - 1) {
+            strcpy(context->error_msg, "out of memory");
+            _pure_ungetc(context, c);
+            while (i) {
+               _pure_ungetc(context, identifier[--i]);
+            }
+            return -1;
+         }
+         identifier[i++] = (char)c;
+      } else {
+         _pure_ungetc(context, c);
+         break;
+      }
+   }
+   identifier[i] = '\0';
+
+   out->data.identifier = sl_pp_context_add_unique_str(context, identifier);
+   if (out->data.identifier == -1) {
+      while (i) {
+         _pure_ungetc(context, identifier[--i]);
+      }
+      return -1;
+   }
+
+   return 0;
+}
+
+
+/*
+ * Return the number of consecutive decimal digits in the input stream.
+ */
+static unsigned int
+_parse_float_digits(struct lookahead_state *lookahead)
+{
+   unsigned int eaten;
+
+   for (eaten = 0;; eaten++) {
+      unsigned int pos = _lookahead_tell(lookahead);
+      char c = _lookahead_getc(lookahead);
+
+      if (c < '0' || c > '9') {
+         _lookahead_revert(lookahead, pos);
+         break;
+      }
+   }
+   return eaten;
+}
+
+
+/*
+ * Try to match one of the following patterns for the fractional part
+ * of a floating point number.
+ *
+ * digits . [digits]
+ * . digits
+ *
+ * Return 0 if the pattern could not be matched, otherwise the number
+ * of eaten characters from the input stream.
+ */
+static unsigned int
+_parse_float_frac(struct lookahead_state *lookahead)
+{
+   unsigned int pos;
+   int c;
+   unsigned int eaten;
+
+   pos = _lookahead_tell(lookahead);
+   c = _lookahead_getc(lookahead);
+   if (c == '.') {
+      eaten = _parse_float_digits(lookahead);
+      if (eaten) {
+         return eaten + 1;
+      }
+      _lookahead_revert(lookahead, pos);
+      return 0;
+   }
+
+   _lookahead_revert(lookahead, pos);
+   eaten = _parse_float_digits(lookahead);
+   if (eaten) {
+      c = _lookahead_getc(lookahead);
+      if (c == '.') {
+         return eaten + 1 + _parse_float_digits(lookahead);
+      }
+   }
+
+   _lookahead_revert(lookahead, pos);
+   return 0;
+}
+
+
+/*
+ * Try to match the following pattern for the exponential part
+ * of a floating point number.
+ *
+ * (e|E) [(+|-)] digits
+ *
+ * Return 0 if the pattern could not be matched, otherwise the number
+ * of eaten characters from the input stream.
+ */
+static unsigned int
+_parse_float_exp(struct lookahead_state *lookahead)
+{
+   unsigned int pos, pos2;
+   int c;
+   unsigned int eaten, digits;
+
+   pos = _lookahead_tell(lookahead);
+   c = _lookahead_getc(lookahead);
+   if (c != 'e' && c != 'E') {
+      _lookahead_revert(lookahead, pos);
+      return 0;
+   }
+
+   pos2 = _lookahead_tell(lookahead);
+   c = _lookahead_getc(lookahead);
+   if (c == '-' || c == '+') {
+      eaten = 2;
+   } else {
+      _lookahead_revert(lookahead, pos2);
+      eaten = 1;
+   }
+
+   digits = _parse_float_digits(lookahead);
+   if (!digits) {
+      _lookahead_revert(lookahead, pos);
+      return 0;
+   }
+
+   return eaten + digits;
+}
+
+
+/*
+ * Try to match one of the following patterns for a floating point number.
+ *
+ * fract [exp] [(f|F)]
+ * digits exp [(f|F)]
+ *
+ * Return 0 if the pattern could not be matched, otherwise the number
+ * of eaten characters from the input stream.
+ */
+static unsigned int
+_parse_float(struct lookahead_state *lookahead)
+{
+   unsigned int eaten;
+
+   eaten = _parse_float_frac(lookahead);
+   if (eaten) {
+      unsigned int pos;
+      int c;
+
+      eaten += _parse_float_exp(lookahead);
+
+      pos = _lookahead_tell(lookahead);
+      c = _lookahead_getc(lookahead);
+      if (c == 'f' || c == 'F') {
+         eaten++;
+      } else {
+         _lookahead_revert(lookahead, pos);
+      }
+
+      return eaten;
+   }
+
+   eaten = _parse_float_digits(lookahead);
+   if (eaten) {
+      unsigned int exponent;
+
+      exponent = _parse_float_exp(lookahead);
+      if (exponent) {
+         unsigned int pos;
+         int c;
+
+         eaten += exponent;
+
+         pos = _lookahead_tell(lookahead);
+         c = _lookahead_getc(lookahead);
+         if (c == 'f' || c == 'F') {
+            eaten++;
+         } else {
+            _lookahead_revert(lookahead, pos);
+         }
+
+         return eaten;
+      }
+   }
+
+   _lookahead_revert(lookahead, 0);
+   return 0;
+}
+
+
+static unsigned int
+_parse_hex(struct lookahead_state *lookahead)
+{
+   int c;
+   unsigned int n;
+
+   c = _lookahead_getc(lookahead);
+   if (c != '0') {
+      _lookahead_revert(lookahead, 0);
+      return 0;
+   }
+
+   c = _lookahead_getc(lookahead);
+   if (c != 'x' && c != 'X') {
+      _lookahead_revert(lookahead, 0);
+      return 0;
+   }
+
+   for (n = 2;;) {
+      unsigned int pos = _lookahead_tell(lookahead);
+
+      c = _lookahead_getc(lookahead);
+      if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
+         n++;
+      } else {
+         _lookahead_revert(lookahead, pos);
+         break;
+      }
+   }
+
+   if (n > 2) {
+      return n;
+   }
+
+   _lookahead_revert(lookahead, 0);
+   return 0;
+}
+
+
+static unsigned int
+_parse_oct(struct lookahead_state *lookahead)
+{
+   int c;
+   unsigned int n;
+
+   c = _lookahead_getc(lookahead);
+   if (c != '0') {
+      _lookahead_revert(lookahead, 0);
+      return 0;
+   }
+
+   for (n = 1;;) {
+      unsigned int pos = _lookahead_tell(lookahead);
+
+      c = _lookahead_getc(lookahead);
+      if ((c >= '0' && c <= '7')) {
+         n++;
+      } else {
+         _lookahead_revert(lookahead, pos);
+         break;
+      }
+   }
+
+   return n;
+}
+
+
+static unsigned int
+_parse_dec(struct lookahead_state *lookahead)
+{
+   unsigned int n = 0;
+
+   for (;;) {
+      unsigned int pos = _lookahead_tell(lookahead);
+      int c = _lookahead_getc(lookahead);
+
+      if ((c >= '0' && c <= '9')) {
+         n++;
+      } else {
+         _lookahead_revert(lookahead, pos);
+         break;
+      }
+   }
+
+   return n;
+}
+
+
+static int
+_tokenise_number(struct sl_pp_context *context,
+                 struct sl_pp_token_info *out)
+{
+   struct lookahead_state lookahead;
+   unsigned int eaten;
+   unsigned int is_float = 0;
+   unsigned int pos;
+   int c;
+   char number[256];   /* XXX: Remove this artifical limit. */
+
+   _lookahead_init(&lookahead, context);
+
+   eaten = _parse_float(&lookahead);
+   if (!eaten) {
+      eaten = _parse_hex(&lookahead);
+      if (!eaten) {
+         eaten = _parse_oct(&lookahead);
+         if (!eaten) {
+            eaten = _parse_dec(&lookahead);
+         }
+      }
+   } else {
+      is_float = 1;
+   }
+
+   if (!eaten) {
+      strcpy(context->error_msg, "expected a number");
+      return -1;
+   }
+
+   pos = _lookahead_tell(&lookahead);
+   c = _lookahead_getc(&lookahead);
+   _lookahead_revert(&lookahead, pos);
+
+   if (_is_identifier_char(c)) {
+      strcpy(context->error_msg, "expected a number");
+      _lookahead_revert(&lookahead, 0);
+      return -1;
+   }
+
+   if (eaten > sizeof(number) - 1) {
+      strcpy(context->error_msg, "out of memory");
+      _lookahead_revert(&lookahead, 0);
+      return -1;
+   }
+
+   assert(_lookahead_tell(&lookahead) == eaten);
+
+   memcpy(number, _lookahead_buf(&lookahead), eaten);
+   number[eaten] = '\0';
+
+   if (is_float) {
+      out->token = SL_PP_FLOAT;
+      out->data._float = sl_pp_context_add_unique_str(context, number);
+      if (out->data._float == -1) {
+         _lookahead_revert(&lookahead, 0);
+         return -1;
+      }
+   } else {
+      out->token = SL_PP_UINT;
+      out->data._uint = sl_pp_context_add_unique_str(context, number);
+      if (out->data._uint == -1) {
+         _lookahead_revert(&lookahead, 0);
+         return -1;
+      }
+   }
+
+   return 0;
+}
+
+
+int
+sl_pp_token_get(struct sl_pp_context *context,
+                struct sl_pp_token_info *out)
+{
+   int c = _pure_getc(context);
+
+   switch (c) {
+   case ' ':
+   case '\t':
+      out->token = SL_PP_WHITESPACE;
+      break;
+
+   case '\n':
+      out->token = SL_PP_NEWLINE;
+      break;
+
+   case '#':
+      out->token = SL_PP_HASH;
+      break;
+
+   case ',':
+      out->token = SL_PP_COMMA;
+      break;
+
+   case ';':
+      out->token = SL_PP_SEMICOLON;
+      break;
+
+   case '{':
+      out->token = SL_PP_LBRACE;
+      break;
+
+   case '}':
+      out->token = SL_PP_RBRACE;
+      break;
+
+   case '(':
+      out->token = SL_PP_LPAREN;
+      break;
+
+   case ')':
+      out->token = SL_PP_RPAREN;
+      break;
+
+   case '[':
+      out->token = SL_PP_LBRACKET;
+      break;
+
+   case ']':
+      out->token = SL_PP_RBRACKET;
+      break;
+
+   case '.':
+      {
+         int c2 = _pure_getc(context);
+
+         if (c2 == PURE_ERROR) {
+            return -1;
+         }
+         if (c2 >= '0' && c2 <= '9') {
+            _pure_ungetc(context, c2);
+            _pure_ungetc(context, c);
+            if (_tokenise_number(context, out)) {
+               return -1;
+            }
+         } else {
+            _pure_ungetc(context, c2);
+            out->token = SL_PP_DOT;
+         }
+      }
+      break;
+
+   case '+':
+      c = _pure_getc(context);
+      if (c == PURE_ERROR) {
+         return -1;
+      }
+      if (c == '+') {
+         out->token = SL_PP_INCREMENT;
+      } else if (c == '=') {
+         out->token = SL_PP_ADDASSIGN;
+      } else {
+         _pure_ungetc(context, c);
+         out->token = SL_PP_PLUS;
+      }
+      break;
+
+   case '-':
+      c = _pure_getc(context);
+      if (c == PURE_ERROR) {
+         return -1;
+      }
+      if (c == '-') {
+         out->token = SL_PP_DECREMENT;
+      } else if (c == '=') {
+         out->token = SL_PP_SUBASSIGN;
+      } else {
+         _pure_ungetc(context, c);
+         out->token = SL_PP_MINUS;
+      }
+      break;
+
+   case '~':
+      out->token = SL_PP_BITNOT;
+      break;
+
+   case '!':
+      c = _pure_getc(context);
+      if (c == PURE_ERROR) {
+         return -1;
+      }
+      if (c == '=') {
+         out->token = SL_PP_NOTEQUAL;
+      } else {
+         _pure_ungetc(context, c);
+         out->token = SL_PP_NOT;
+      }
+      break;
+
+   case '*':
+      c = _pure_getc(context);
+      if (c == PURE_ERROR) {
+         return -1;
+      }
+      if (c == '=') {
+         out->token = SL_PP_MULASSIGN;
+      } else {
+         _pure_ungetc(context, c);
+         out->token = SL_PP_STAR;
+      }
+      break;
+
+   case '/':
+      c = _pure_getc(context);
+      if (c == PURE_ERROR) {
+         return -1;
+      }
+      if (c == '=') {
+         out->token = SL_PP_DIVASSIGN;
+      } else {
+         _pure_ungetc(context, c);
+         out->token = SL_PP_SLASH;
+      }
+      break;
+
+   case '%':
+      c = _pure_getc(context);
+      if (c == PURE_ERROR) {
+         return -1;
+      }
+      if (c == '=') {
+         out->token = SL_PP_MODASSIGN;
+      } else {
+         _pure_ungetc(context, c);
+         out->token = SL_PP_MODULO;
+      }
+      break;
+
+   case '<':
+      c = _pure_getc(context);
+      if (c == PURE_ERROR) {
+         return -1;
+      }
+      if (c == '<') {
+         c = _pure_getc(context);
+         if (c == PURE_ERROR) {
+            return -1;
+         }
+         if (c == '=') {
+            out->token = SL_PP_LSHIFTASSIGN;
+         } else {
+            _pure_ungetc(context, c);
+            out->token = SL_PP_LSHIFT;
+         }
+      } else if (c == '=') {
+         out->token = SL_PP_LESSEQUAL;
+      } else {
+         _pure_ungetc(context, c);
+         out->token = SL_PP_LESS;
+      }
+      break;
+
+   case '>':
+      c = _pure_getc(context);
+      if (c == PURE_ERROR) {
+         return -1;
+      }
+      if (c == '>') {
+         c = _pure_getc(context);
+         if (c == PURE_ERROR) {
+            return -1;
+         }
+         if (c == '=') {
+            out->token = SL_PP_RSHIFTASSIGN;
+         } else {
+            _pure_ungetc(context, c);
+            out->token = SL_PP_RSHIFT;
+         }
+      } else if (c == '=') {
+         out->token = SL_PP_GREATEREQUAL;
+      } else {
+         _pure_ungetc(context, c);
+         out->token = SL_PP_GREATER;
+      }
+      break;
+
+   case '=':
+      c = _pure_getc(context);
+      if (c == PURE_ERROR) {
+         return -1;
+      }
+      if (c == '=') {
+         out->token = SL_PP_EQUAL;
+      } else {
+         _pure_ungetc(context, c);
+         out->token = SL_PP_ASSIGN;
+      }
+      break;
+
+   case '&':
+      c = _pure_getc(context);
+      if (c == PURE_ERROR) {
+         return -1;
+      }
+      if (c == '&') {
+         out->token = SL_PP_AND;
+      } else if (c == '=') {
+         out->token = SL_PP_BITANDASSIGN;
+      } else {
+         _pure_ungetc(context, c);
+         out->token = SL_PP_BITAND;
+      }
+      break;
+
+   case '^':
+      c = _pure_getc(context);
+      if (c == PURE_ERROR) {
+         return -1;
+      }
+      if (c == '^') {
+         out->token = SL_PP_XOR;
+      } else if (c == '=') {
+         out->token = SL_PP_BITXORASSIGN;
+      } else {
+         _pure_ungetc(context, c);
+         out->token = SL_PP_BITXOR;
+      }
+      break;
+
+   case '|':
+      c = _pure_getc(context);
+      if (c == PURE_ERROR) {
+         return -1;
+      }
+      if (c == '|') {
+         out->token = SL_PP_OR;
+      } else if (c == '=') {
+         out->token = SL_PP_BITORASSIGN;
+      } else {
+         _pure_ungetc(context, c);
+         out->token = SL_PP_BITOR;
+      }
+      break;
+
+   case '?':
+      out->token = SL_PP_QUESTION;
+      break;
+
+   case ':':
+      out->token = SL_PP_COLON;
+      break;
+
+   case '\0':
+      out->token = SL_PP_EOF;
+      break;
+
+   case PURE_ERROR:
+      return -1;
+
+   default:
+      if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') {
+         _pure_ungetc(context, c);
+         if (_tokenise_identifier(context, out)) {
+            return -1;
+         }
+      } else if (c >= '0' && c <= '9') {
+         _pure_ungetc(context, c);
+         if (_tokenise_number(context, out)) {
+            return -1;
+         }
+      } else {
+         out->data.other = c;
+         out->token = SL_PP_OTHER;
+      }
+   }
+
+   return 0;
+}
+
+
+int
+sl_pp_tokenise(struct sl_pp_context *context,
+               struct sl_pp_token_info **output)
+{
+   struct sl_pp_token_info *out = NULL;
+   unsigned int out_len = 0;
+   unsigned int out_max = 0;
+
+   for (;;) {
+      struct sl_pp_token_info info;
+
+      if (sl_pp_token_buffer_get(&context->tokens, &info)) {
+         free(out);
+         return -1;
+      }
+
+      if (out_len >= out_max) {
+         unsigned int new_max = out_max;
+
+         if (new_max < 0x100) {
+            new_max = 0x100;
+         } else if (new_max < 0x10000) {
+            new_max *= 2;
+         } else {
+            new_max += 0x10000;
+         }
+
+         out = realloc(out, new_max * sizeof(struct sl_pp_token_info));
+         if (!out) {
+            strcpy(context->error_msg, "out of memory");
+            return -1;
+         }
+         out_max = new_max;
+      }
+
+      out[out_len++] = info;
+
+      if (info.token == SL_PP_EOF) {
+         break;
+      }
+   }
+
+   *output = out;
+   return 0;
+}
diff --git a/src/glsl/pp/sl_pp_token.h b/src/glsl/pp/sl_pp_token.h
new file mode 100644
index 0000000..a12b193
--- /dev/null
+++ b/src/glsl/pp/sl_pp_token.h
@@ -0,0 +1,133 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#ifndef SL_PP_TOKEN_H
+#define SL_PP_TOKEN_H
+
+
+struct sl_pp_context;
+
+enum sl_pp_token {
+   SL_PP_WHITESPACE,
+   SL_PP_NEWLINE,
+   SL_PP_HASH,             /* #   */
+
+   SL_PP_COMMA,            /* ,   */
+   SL_PP_SEMICOLON,        /* ;   */
+   SL_PP_LBRACE,           /* {   */
+   SL_PP_RBRACE,           /* }   */
+   SL_PP_LPAREN,           /* (   */
+   SL_PP_RPAREN,           /* )   */
+   SL_PP_LBRACKET,         /* [   */
+   SL_PP_RBRACKET,         /* ]   */
+   SL_PP_DOT,              /* .   */
+   SL_PP_INCREMENT,        /* ++  */
+   SL_PP_ADDASSIGN,        /* +=  */
+   SL_PP_PLUS,             /* +   */
+   SL_PP_DECREMENT,        /* --  */
+   SL_PP_SUBASSIGN,        /* -=  */
+   SL_PP_MINUS,            /* -   */
+   SL_PP_BITNOT,           /* ~   */
+   SL_PP_NOTEQUAL,         /* !=  */
+   SL_PP_NOT,              /* !   */
+   SL_PP_MULASSIGN,        /* *=  */
+   SL_PP_STAR,             /* *   */
+   SL_PP_DIVASSIGN,        /* /=  */
+   SL_PP_SLASH,            /* /   */
+   SL_PP_MODASSIGN,        /* %=  */
+   SL_PP_MODULO,           /* %   */
+   SL_PP_LSHIFTASSIGN,     /* <<= */
+   SL_PP_LSHIFT,           /* <<  */
+   SL_PP_LESSEQUAL,        /* <=  */
+   SL_PP_LESS,             /* <   */
+   SL_PP_RSHIFTASSIGN,     /* >>= */
+   SL_PP_RSHIFT,           /* >>  */
+   SL_PP_GREATEREQUAL,     /* >=  */
+   SL_PP_GREATER,          /* >   */
+   SL_PP_EQUAL,            /* ==  */
+   SL_PP_ASSIGN,           /* =   */
+   SL_PP_AND,              /* &&  */
+   SL_PP_BITANDASSIGN,     /* &=  */
+   SL_PP_BITAND,           /* &   */
+   SL_PP_XOR,              /* ^^  */
+   SL_PP_BITXORASSIGN,     /* ^=  */
+   SL_PP_BITXOR,           /* ^   */
+   SL_PP_OR,               /* ||  */
+   SL_PP_BITORASSIGN,      /* |=  */
+   SL_PP_BITOR,            /* |   */
+   SL_PP_QUESTION,         /* ?   */
+   SL_PP_COLON,            /* :   */
+
+   SL_PP_IDENTIFIER,
+
+   SL_PP_UINT,
+   SL_PP_FLOAT,
+
+   SL_PP_OTHER,
+
+   SL_PP_PRAGMA_OPTIMIZE,
+   SL_PP_PRAGMA_DEBUG,
+
+   SL_PP_EXTENSION_REQUIRE,
+   SL_PP_EXTENSION_ENABLE,
+   SL_PP_EXTENSION_WARN,
+   SL_PP_EXTENSION_DISABLE,
+
+   SL_PP_LINE,
+
+   SL_PP_EOF
+};
+
+union sl_pp_token_data {
+   int identifier;
+   int _uint;
+   int _float;
+   char other;
+   int pragma;
+   int extension;
+   struct {
+      unsigned int lineno: 24;
+      unsigned int fileno: 8;
+   } line;
+};
+
+struct sl_pp_token_info {
+   enum sl_pp_token token;
+   union sl_pp_token_data data;
+};
+
+struct sl_pp_purify_options;
+
+int
+sl_pp_token_get(struct sl_pp_context *context,
+                struct sl_pp_token_info *out);
+
+int
+sl_pp_tokenise(struct sl_pp_context *context,
+               struct sl_pp_token_info **output);
+
+#endif /* SL_PP_TOKEN_H */
diff --git a/src/glsl/pp/sl_pp_token_util.c b/src/glsl/pp/sl_pp_token_util.c
new file mode 100644
index 0000000..c85263d
--- /dev/null
+++ b/src/glsl/pp/sl_pp_token_util.c
@@ -0,0 +1,182 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <assert.h>
+#include <stdlib.h>
+#include "sl_pp_token_util.h"
+
+
+int
+sl_pp_token_buffer_init(struct sl_pp_token_buffer *buffer,
+                        struct sl_pp_context *context)
+{
+   buffer->context = context;
+   buffer->size = 0;
+   buffer->capacity = 64;
+   buffer->tokens = malloc(buffer->capacity * sizeof(struct sl_pp_token_info));
+   if (!buffer->tokens) {
+      return -1;
+   }
+   return 0;
+}
+
+void
+sl_pp_token_buffer_destroy(struct sl_pp_token_buffer *buffer)
+{
+   free(buffer->tokens);
+}
+
+int
+sl_pp_token_buffer_get(struct sl_pp_token_buffer *buffer,
+                       struct sl_pp_token_info *out)
+{
+   /* Pop from stack first if not empty. */
+   if (buffer->size) {
+      *out = buffer->tokens[--buffer->size];
+      return 0;
+   }
+
+   assert(buffer->context);
+   return sl_pp_token_get(buffer->context, out);
+}
+
+void
+sl_pp_token_buffer_unget(struct sl_pp_token_buffer *buffer,
+                         const struct sl_pp_token_info *in)
+{
+   /* Resize if needed. */
+   if (buffer->size == buffer->capacity) {
+      buffer->capacity += 64;
+      buffer->tokens = realloc(buffer->tokens,
+                               buffer->capacity * sizeof(struct sl_pp_token_info));
+      assert(buffer->tokens);
+   }
+
+   /* Push token on stack. */
+   buffer->tokens[buffer->size++] = *in;
+}
+
+int
+sl_pp_token_buffer_skip_white(struct sl_pp_token_buffer *buffer,
+                              struct sl_pp_token_info *out)
+{
+   if (sl_pp_token_buffer_get(buffer, out)) {
+      return -1;
+   }
+
+   while (out->token == SL_PP_WHITESPACE) {
+      if (sl_pp_token_buffer_get(buffer, out)) {
+         return -1;
+      }
+   }
+
+   return 0;
+}
+
+
+
+int
+sl_pp_token_peek_init(struct sl_pp_token_peek *peek,
+                      struct sl_pp_token_buffer *buffer)
+{
+   peek->buffer = buffer;
+   peek->size = 0;
+   peek->capacity = 64;
+   peek->tokens = malloc(peek->capacity * sizeof(struct sl_pp_token_info));
+   if (!peek->tokens) {
+      return -1;
+   }
+   return 0;
+}
+
+void
+sl_pp_token_peek_destroy(struct sl_pp_token_peek *peek)
+{
+   /* Abort. */
+   while (peek->size) {
+      sl_pp_token_buffer_unget(peek->buffer, &peek->tokens[--peek->size]);
+   }
+   free(peek->tokens);
+}
+
+int
+sl_pp_token_peek_get(struct sl_pp_token_peek *peek,
+                     struct sl_pp_token_info *out)
+{
+   /* Get token from buffer. */
+   if (sl_pp_token_buffer_get(peek->buffer, out)) {
+      return -1;
+   }
+
+   /* Save it. */
+   if (peek->size == peek->capacity) {
+      peek->capacity += 64;
+      peek->tokens = realloc(peek->tokens,
+                             peek->capacity * sizeof(struct sl_pp_token_info));
+      assert(peek->tokens);
+   }
+   peek->tokens[peek->size++] = *out;
+   return 0;
+}
+
+void
+sl_pp_token_peek_commit(struct sl_pp_token_peek *peek)
+{
+   peek->size = 0;
+}
+
+int
+sl_pp_token_peek_to_buffer(const struct sl_pp_token_peek *peek,
+                           struct sl_pp_token_buffer *buffer)
+{
+   unsigned int i;
+
+   if (sl_pp_token_buffer_init(buffer, NULL)) {
+      return -1;
+   }
+   for (i = peek->size; i > 0; i--) {
+      sl_pp_token_buffer_unget(buffer, &peek->tokens[i - 1]);
+   }
+   return 0;
+}
+
+int
+sl_pp_token_peek_skip_white(struct sl_pp_token_peek *peek,
+                            struct sl_pp_token_info *out)
+{
+   if (sl_pp_token_peek_get(peek, out)) {
+      return -1;
+   }
+
+   while (out->token == SL_PP_WHITESPACE) {
+      if (sl_pp_token_peek_get(peek, out)) {
+         return -1;
+      }
+   }
+
+   return 0;
+}
diff --git a/src/glsl/pp/sl_pp_token_util.h b/src/glsl/pp/sl_pp_token_util.h
new file mode 100644
index 0000000..2a668ad
--- /dev/null
+++ b/src/glsl/pp/sl_pp_token_util.h
@@ -0,0 +1,103 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#ifndef SL_PP_TOKEN_UTIL_H
+#define SL_PP_TOKEN_UTIL_H
+
+#include <assert.h>
+#include <stdlib.h>
+#include "sl_pp_token.h"
+
+
+struct sl_pp_context;
+
+/*
+ * A token buffer allows one to get and unget a token
+ * from a preprocessor context.
+ */
+struct sl_pp_token_buffer {
+   struct sl_pp_context *context;
+   unsigned int size;
+   unsigned int capacity;
+   struct sl_pp_token_info *tokens;
+};
+
+int
+sl_pp_token_buffer_init(struct sl_pp_token_buffer *buffer,
+                        struct sl_pp_context *context);
+
+void
+sl_pp_token_buffer_destroy(struct sl_pp_token_buffer *buffer);
+
+int
+sl_pp_token_buffer_get(struct sl_pp_token_buffer *buffer,
+                       struct sl_pp_token_info *out);
+
+void
+sl_pp_token_buffer_unget(struct sl_pp_token_buffer *buffer,
+                         const struct sl_pp_token_info *in);
+
+int
+sl_pp_token_buffer_skip_white(struct sl_pp_token_buffer *buffer,
+                              struct sl_pp_token_info *out);
+
+
+/*
+ * A token peek allows one to get a number of tokens from a buffer
+ * and then either commit the operation or abort it,
+ * effectively ungetting the peeked tokens.
+ */
+struct sl_pp_token_peek {
+   struct sl_pp_token_buffer *buffer;
+   unsigned int size;
+   unsigned int capacity;
+   struct sl_pp_token_info *tokens;
+};
+
+int
+sl_pp_token_peek_init(struct sl_pp_token_peek *peek,
+                      struct sl_pp_token_buffer *buffer);
+
+void
+sl_pp_token_peek_destroy(struct sl_pp_token_peek *peek);
+
+int
+sl_pp_token_peek_get(struct sl_pp_token_peek *peek,
+                     struct sl_pp_token_info *out);
+
+void
+sl_pp_token_peek_commit(struct sl_pp_token_peek *peek);
+
+int
+sl_pp_token_peek_to_buffer(const struct sl_pp_token_peek *peek,
+                           struct sl_pp_token_buffer *buffer);
+
+int
+sl_pp_token_peek_skip_white(struct sl_pp_token_peek *peek,
+                            struct sl_pp_token_info *out);
+
+#endif /* SL_PP_TOKEN_UTIL_H */
diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c
new file mode 100644
index 0000000..3c995b7
--- /dev/null
+++ b/src/glsl/pp/sl_pp_version.c
@@ -0,0 +1,161 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "sl_pp_public.h"
+#include "sl_pp_context.h"
+
+
+int
+sl_pp_version(struct sl_pp_context *context,
+              unsigned int *version)
+{
+   struct sl_pp_token_peek peek;
+   unsigned int line = context->line;
+
+   /* Default values if `#version' is not present. */
+   *version = 110;
+
+   if (sl_pp_token_peek_init(&peek, &context->tokens)) {
+      return -1;
+   }
+
+   /* There can be multiple `#version' directives present.
+    * Accept the value of the last one.
+    */
+   for (;;) {
+      struct sl_pp_token_info input;
+      int found_hash = 0;
+      int found_version = 0;
+      int found_number = 0;
+      int found_end = 0;
+
+      /* Skip whitespace and newlines and seek for hash. */
+      while (!found_hash) {
+         if (sl_pp_token_peek_get(&peek, &input)) {
+            sl_pp_token_peek_destroy(&peek);
+            return -1;
+         }
+
+         switch (input.token) {
+         case SL_PP_NEWLINE:
+            line++;
+            break;
+
+         case SL_PP_WHITESPACE:
+            break;
+
+         case SL_PP_HASH:
+            found_hash = 1;
+            break;
+
+         default:
+            sl_pp_token_peek_destroy(&peek);
+            return 0;
+         }
+      }
+
+      /* Skip whitespace and seek for `version'. */
+      while (!found_version) {
+         if (sl_pp_token_peek_get(&peek, &input)) {
+            sl_pp_token_peek_destroy(&peek);
+            return -1;
+         }
+
+         switch (input.token) {
+         case SL_PP_WHITESPACE:
+            break;
+
+         case SL_PP_IDENTIFIER:
+            if (input.data.identifier != context->dict.version) {
+               sl_pp_token_peek_destroy(&peek);
+               return 0;
+            }
+            found_version = 1;
+            break;
+
+         default:
+            sl_pp_token_peek_destroy(&peek);
+            return 0;
+         }
+      }
+
+      sl_pp_token_peek_commit(&peek);
+
+      /* Skip whitespace and seek for version number. */
+      while (!found_number) {
+         if (sl_pp_token_buffer_get(&context->tokens, &input)) {
+            sl_pp_token_peek_destroy(&peek);
+            return -1;
+         }
+
+         switch (input.token) {
+         case SL_PP_WHITESPACE:
+            break;
+
+         case SL_PP_UINT:
+            *version = atoi(sl_pp_context_cstr(context, input.data._uint));
+            found_number = 1;
+            break;
+
+         default:
+            strcpy(context->error_msg, "expected version number after `#version'");
+            sl_pp_token_peek_destroy(&peek);
+            return -1;
+         }
+      }
+
+      /* Skip whitespace and seek for either newline or eof. */
+      while (!found_end) {
+         if (sl_pp_token_buffer_get(&context->tokens, &input)) {
+            sl_pp_token_peek_destroy(&peek);
+            return -1;
+         }
+
+         switch (input.token) {
+         case SL_PP_WHITESPACE:
+            break;
+
+         case SL_PP_NEWLINE:
+            line++;
+            /* pass thru */
+         case SL_PP_EOF:
+            context->line = line;
+            found_end = 1;
+            break;
+
+         default:
+            strcpy(context->error_msg, "expected end of line after version number");
+            sl_pp_token_peek_destroy(&peek);
+            return -1;
+         }
+      }
+   }
+
+   /* Should not get here. */
+}
diff --git a/src/glu/sgi/libnurbs/internals/arcsorter.h b/src/glu/sgi/libnurbs/internals/arcsorter.h
index d72dd1e..a55df92 100644
--- a/src/glu/sgi/libnurbs/internals/arcsorter.h
+++ b/src/glu/sgi/libnurbs/internals/arcsorter.h
@@ -37,7 +37,6 @@
 #define __gluarcsorter_h_
 
 #include "sorter.h"
-#include "arcsorter.h"
 
 class Arc;
 class Subdivider;
diff --git a/src/glu/sgi/libnurbs/internals/displaylist.h b/src/glu/sgi/libnurbs/internals/displaylist.h
index 22cbec3..d009a42 100644
--- a/src/glu/sgi/libnurbs/internals/displaylist.h
+++ b/src/glu/sgi/libnurbs/internals/displaylist.h
@@ -59,6 +59,7 @@
     work = _work;
     arg = _arg;
     cleanup = _cleanup;
+    next = 0;
 }
 
 class DisplayList {
diff --git a/src/glu/sgi/libnurbs/internals/gridvertex.h b/src/glu/sgi/libnurbs/internals/gridvertex.h
index 36a65c7..2e27436 100644
--- a/src/glu/sgi/libnurbs/internals/gridvertex.h
+++ b/src/glu/sgi/libnurbs/internals/gridvertex.h
@@ -38,7 +38,7 @@
 
 struct GridVertex {
     long 		gparam[2];
-			GridVertex( void ) {}
+			GridVertex( void ) { gparam[0] = 0, gparam[1] = 0; }
 			GridVertex( long u, long v ) { gparam[0] = u, gparam[1] = v; }
     void		set( long u, long v ) { gparam[0] = u, gparam[1] = v; }
     long		nextu() { return gparam[0]++; }
diff --git a/src/glu/sgi/libnurbs/internals/knotvector.cc b/src/glu/sgi/libnurbs/internals/knotvector.cc
index 9eb5cba..dcbf006 100644
--- a/src/glu/sgi/libnurbs/internals/knotvector.cc
+++ b/src/glu/sgi/libnurbs/internals/knotvector.cc
@@ -61,6 +61,9 @@
 
 Knotvector::Knotvector( void )
 {
+    knotcount = 0;
+    stride = 0;
+    order = 0;
     knotlist = 0;
 }
 
diff --git a/src/glu/sgi/libnurbs/internals/reader.h b/src/glu/sgi/libnurbs/internals/reader.h
index 8a8dceb..cae6cad 100644
--- a/src/glu/sgi/libnurbs/internals/reader.h
+++ b/src/glu/sgi/libnurbs/internals/reader.h
@@ -64,7 +64,7 @@
     int			save;		/* 1 if in display list		*/
     long		nuid;
     			O_curve() { next = 0; used = 0; owner = 0; 
-				    curve.o_pwlcurve = 0; }
+				    curve.o_pwlcurve = 0; curvetype = ct_none; save = 0; nuid = 0; }
     };
 
 struct O_nurbscurve : public PooledObj {
@@ -77,7 +77,7 @@
     int			save;		/* 1 if in display list		*/
     O_curve *		owner;		/* owning curve 		*/
 			O_nurbscurve( long _type ) 
-			   { type = _type; owner = 0; next = 0; used = 0; }
+			   { bezier_curves = 0; type = _type; tesselation = 0; method = 0; next = 0; used = 0; save = 0; owner = 0; }
     };
  
 class O_pwlcurve : public PooledObj {
@@ -95,7 +95,7 @@
     O_curve		*o_curve;	/* closed trim loop	 	*/
     O_trim *		next;		/* next loop along trim 	*/
     int			save;		/* 1 if in display list		*/
-			O_trim() { next = 0; o_curve = 0; }
+			O_trim() { next = 0; o_curve = 0; save = 0; }
     };
 
 struct O_nurbssurface : public PooledObj {
@@ -106,7 +106,7 @@
     int			save;		/* 1 if in display list		*/
     int			used;		/* 1 if prev called in block	*/
 			O_nurbssurface( long _type ) 
-			   { type = _type; owner = 0; next = 0; used = 0; }
+			   { bezier_patches = 0; type = _type; owner = 0; next = 0; save = 0; used = 0; }
     };
 
 struct O_surface : public PooledObj {
@@ -114,7 +114,7 @@
     O_trim *		o_trim;		/* list of trim loops		*/
     int			save;		/* 1 if in display list		*/
     long		nuid;
-			O_surface() { o_trim = 0; o_nurbssurface = 0; }
+			O_surface() { o_trim = 0; o_nurbssurface = 0; save = 0; nuid = 0; }
     };
 
 struct Property : public PooledObj {
@@ -123,9 +123,9 @@
     REAL		value;
     int			save;		/* 1 if in display list		*/
 			Property( long _type, long _tag, INREAL _value )
-			{ type = _type; tag = _tag; value = (REAL) _value; }
+			{ type = _type; tag = _tag; value = (REAL) _value; save = 0; }
 			Property( long _tag, INREAL _value )
-			{ type = 0; tag = _tag; value = (REAL) _value; }
+			{ type = 0; tag = _tag; value = (REAL) _value; save = 0; }
     };
 
 class NurbsTessellator;
diff --git a/src/glu/sgi/libnurbs/internals/subdivider.cc b/src/glu/sgi/libnurbs/internals/subdivider.cc
index cc0b514..ccddc27 100644
--- a/src/glu/sgi/libnurbs/internals/subdivider.cc
+++ b/src/glu/sgi/libnurbs/internals/subdivider.cc
@@ -531,16 +531,18 @@
 		     patchlist.pspec[param].range[1] ) * 0.5;
 	split( source, left, right, param, mid );
 	Patchlist subpatchlist( patchlist, param, mid );
-	if( left.isnonempty() )
+	if( left.isnonempty() ) {
 	    if( subpatchlist.cullCheck() == CULL_TRIVIAL_REJECT ) 
 		freejarcs( left );
 	    else
 	        nonSamplingSplit( left, subpatchlist, subdivisions-1, param );
-	if( right.isnonempty() ) 
+	}
+	if( right.isnonempty() ) {
 	    if( patchlist.cullCheck() == CULL_TRIVIAL_REJECT ) 
 		freejarcs( right );
 	    else
 	        nonSamplingSplit( right, patchlist, subdivisions-1, param );
+	}
 
     } else {
 	// make bbox calls
diff --git a/src/glu/sgi/libnurbs/internals/varray.cc b/src/glu/sgi/libnurbs/internals/varray.cc
index 31cc73a..1cb2354 100644
--- a/src/glu/sgi/libnurbs/internals/varray.cc
+++ b/src/glu/sgi/libnurbs/internals/varray.cc
@@ -53,8 +53,16 @@
 
 Varray::Varray( void )
 {
+    int i;
+
     varray = 0;
     size = 0;
+    numquads = 0;
+
+    for (i = 0; i < 1000; i++) {
+        vval[i] = 0;
+        voffset[i] = 0;
+    }
 }
 
 Varray::~Varray( void )
diff --git a/src/glu/sgi/libnurbs/nurbtess/directedLine.cc b/src/glu/sgi/libnurbs/nurbtess/directedLine.cc
index 7445035..d942db7 100644
--- a/src/glu/sgi/libnurbs/nurbtess/directedLine.cc
+++ b/src/glu/sgi/libnurbs/nurbtess/directedLine.cc
@@ -309,6 +309,8 @@
   nextPolygon = NULL;
   rootBit = 0;/*important to initilzae to 0 meaning not root yet*/
   rootLink = NULL;
+  direction = INCREASING;
+  sline = NULL;
 }
 
 directedLine::~directedLine()
@@ -791,22 +793,30 @@
 {
   Int i,j;
   FILE* fp = fopen(filename, "r");
-  assert(fp);
   Int nPolygons;
-  fscanf(fp, "%i", &nPolygons);
+  int result;
+
+  assert(fp);
+  result = fscanf(fp, "%i", &nPolygons);
+  assert(result != EOF);
   directedLine *ret = NULL;
 
   for(i=0; i<nPolygons; i++)
     {
       Int nEdges;
-      fscanf(fp, "%i", &nEdges);
-      Real vert[2][2];
+      result = fscanf(fp, "%i", &nEdges);
+      assert(result != EOF);
+      Real vert[2][2] = { { 0 } };
       Real VV[2][2];
       /*the first two vertices*/
-      fscanf(fp, "%f", &(vert[0][0]));
-      fscanf(fp, "%f", &(vert[0][1]));
-      fscanf(fp, "%f", &(vert[1][0]));
-      fscanf(fp, "%f", &(vert[1][1]));
+      result = fscanf(fp, "%f", &(vert[0][0]));
+      assert(result != EOF);
+      result = fscanf(fp, "%f", &(vert[0][1]));
+      assert(result != EOF);
+      result = fscanf(fp, "%f", &(vert[1][0]));
+      assert(result != EOF);
+      result = fscanf(fp, "%f", &(vert[1][1]));
+      assert(result != EOF);
       VV[1][0] = vert[0][0];
       VV[1][1] = vert[0][1];
       sampledLine *sLine = new sampledLine(2, vert);
@@ -818,8 +828,10 @@
 	{
 	  vert[0][0]=vert[1][0];
 	  vert[0][1]=vert[1][1];
-	  fscanf(fp, "%f", &(vert[1][0]));
-	  fscanf(fp, "%f", &(vert[1][1]));
+	  result = fscanf(fp, "%f", &(vert[1][0]));
+	  assert(result != EOF);
+	  result = fscanf(fp, "%f", &(vert[1][1]));
+	  assert(result != EOF);
 	  sLine = new sampledLine(2,vert);
 	  dLine = new directedLine(INCREASING, sLine);
 dLine->rootLinkSet(thisPoly);
diff --git a/src/glu/sgi/libnurbs/nurbtess/monoChain.cc b/src/glu/sgi/libnurbs/nurbtess/monoChain.cc
index 814bf32..b17b940 100644
--- a/src/glu/sgi/libnurbs/nurbtess/monoChain.cc
+++ b/src/glu/sgi/libnurbs/nurbtess/monoChain.cc
@@ -127,6 +127,7 @@
     current = chainTail;
 
   isKey = 0;
+  keyY = 0;
 }
 
 //insert a new line between prev and this
diff --git a/src/glu/sgi/libnurbs/nurbtess/partitionY.cc b/src/glu/sgi/libnurbs/nurbtess/partitionY.cc
index 297c629..e097461 100644
--- a/src/glu/sgi/libnurbs/nurbtess/partitionY.cc
+++ b/src/glu/sgi/libnurbs/nurbtess/partitionY.cc
@@ -111,8 +111,8 @@
   else if(A[1] > B[1] && C[1] > B[1])
     return 1;
 
-  if(isAbove(v, v) && isAbove(v, v->getPrev()) ||
-     isBelow(v, v) && isBelow(v, v->getPrev()))
+  if((isAbove(v, v) && isAbove(v, v->getPrev())) ||
+     (isBelow(v, v) && isBelow(v, v->getPrev())))
     return 1;
   else
     return 0;
diff --git a/src/glu/sgi/libnurbs/nurbtess/sampleCompBot.cc b/src/glu/sgi/libnurbs/nurbtess/sampleCompBot.cc
index e12f88b..2e70f83 100644
--- a/src/glu/sgi/libnurbs/nurbtess/sampleCompBot.cc
+++ b/src/glu/sgi/libnurbs/nurbtess/sampleCompBot.cc
@@ -207,7 +207,7 @@
     return;
   }
 
-  Int segIndexMono, segIndexPass;
+  Int segIndexMono = 0, segIndexPass;
   findBotRightSegment(rightChain,
 		      rightEnd,
 		      rightCorner,
@@ -293,7 +293,7 @@
     return;
   }
 
-  Int segIndexPass, segIndexMono;
+  Int segIndexPass, segIndexMono = 0;
   findBotLeftSegment(leftChain, leftEnd, leftCorner, grid->get_u_value(leftU), segIndexMono, segIndexPass);
 
   sampleBotLeftWithGridLinePost(botVertex,
diff --git a/src/glu/sgi/libnurbs/nurbtess/sampleCompTop.cc b/src/glu/sgi/libnurbs/nurbtess/sampleCompTop.cc
index b7b9296..951e937 100644
--- a/src/glu/sgi/libnurbs/nurbtess/sampleCompTop.cc
+++ b/src/glu/sgi/libnurbs/nurbtess/sampleCompTop.cc
@@ -172,7 +172,7 @@
     return;
   }
 
-  Int segIndexSmall, segIndexLarge;
+  Int segIndexSmall = 0, segIndexLarge;
   findTopRightSegment(rightChain,
                       rightStart,
                       rightEnd,
@@ -294,7 +294,7 @@
                                 primStream* pStream
                                 )
 {
-  Int segIndexSmall, segIndexLarge;
+  Int segIndexSmall = 0, segIndexLarge;
   //if left chain is empty, then there is only one top vertex with one grid 
   //  line
   if(leftEnd < leftStart) {
diff --git a/src/glu/sgi/libnurbs/nurbtess/sampledLine.cc b/src/glu/sgi/libnurbs/nurbtess/sampledLine.cc
index 6253a7c..89f6c6e 100644
--- a/src/glu/sgi/libnurbs/nurbtess/sampledLine.cc
+++ b/src/glu/sgi/libnurbs/nurbtess/sampledLine.cc
@@ -107,6 +107,9 @@
 //needs tp call init to setup
 sampledLine::sampledLine()
 {
+  npoints = 0;
+  points = NULL;
+  next = NULL;
 }
 
 //warning: ONLY pointer is copies!!!
diff --git a/src/glu/sgi/libtess/mesh.c b/src/glu/sgi/libtess/mesh.c
index ae861f8..95f87cd 100644
--- a/src/glu/sgi/libtess/mesh.c
+++ b/src/glu/sgi/libtess/mesh.c
@@ -284,7 +284,12 @@
   } 
 
   e = MakeEdge( &mesh->eHead );
-  if (e == NULL) return NULL;
+  if (e == NULL) {
+     memFree(newVertex1);
+     memFree(newVertex2);
+     memFree(newFace);
+     return NULL;
+  }
 
   MakeVertex( newVertex1, e, &mesh->vHead );
   MakeVertex( newVertex2, e->Sym, &mesh->vHead );
diff --git a/src/glu/sgi/libutil/mipmap.c b/src/glu/sgi/libutil/mipmap.c
index af647af..d1fd5a7 100644
--- a/src/glu/sgi/libutil/mipmap.c
+++ b/src/glu/sgi/libutil/mipmap.c
@@ -3526,6 +3526,8 @@
     afterImage =
 	malloc(image_size(widthout, heightout, format, GL_UNSIGNED_SHORT));
     if (beforeImage == NULL || afterImage == NULL) {
+	free(beforeImage);
+	free(afterImage);
 	return GLU_OUT_OF_MEMORY;
     }
 
@@ -3606,6 +3608,7 @@
 		    glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
 		    glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
 		    glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
+		    free(newImage);
 		    return GLU_OUT_OF_MEMORY;
 		}
 	    }
@@ -3760,6 +3763,7 @@
 		    glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
 		    glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
 		    glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
+		    free(newImage);
 		    return GLU_OUT_OF_MEMORY;
 		}
 	    }
@@ -4104,6 +4108,7 @@
 	  glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
 	  glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
 	  glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
+	  free(srcImage);
 	  return GLU_OUT_OF_MEMORY;
 	}
 	/* level userLevel+1 is in srcImage; level userLevel already saved */
@@ -4346,6 +4351,7 @@
 	    glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
 	    glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
 	    glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
+	    free(srcImage);
 	    return GLU_OUT_OF_MEMORY;
 	  }
 	}
@@ -7382,6 +7388,8 @@
    afterImage = malloc(imageSize3D(widthOut, heightOut, depthOut, format,
 				   GL_UNSIGNED_SHORT));
    if (beforeImage == NULL || afterImage == NULL) {
+       free(beforeImage);
+       free(afterImage);
        return GLU_OUT_OF_MEMORY;
    }
    retrieveStoreModes3D(&psm);
@@ -8093,6 +8101,7 @@
 	 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
 	 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
 	 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
+	 free(srcImage);
 	 return GLU_OUT_OF_MEMORY;
        }
        /* level userLevel+1 is in srcImage; level userLevel already saved */
@@ -8227,6 +8236,7 @@
 	   glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
 	   glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
 	   glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
+	   free(srcImage);
 	   return GLU_OUT_OF_MEMORY;
 	 }
        }
diff --git a/src/glut/glx/SConscript b/src/glut/glx/SConscript
index 938fec0..5234e6d 100644
--- a/src/glut/glx/SConscript
+++ b/src/glut/glx/SConscript
@@ -2,11 +2,6 @@
 
 env = env.Clone()
 
-if env['platform'] != 'windows':
-    Return()
-
-target = 'glut32'
-
 env.Replace(CPPDEFINES = [
     'BUILD_GLUT32', 
     'GLUT_BUILDING_LIB', 
@@ -18,14 +13,6 @@
     '#/include',
 ])
 
-env.PrependUnique(LIBS = [
-    'winmm', 
-    'gdi32', 
-    'user32', 
-    'opengl32', 
-    'glu32',
-])
-
 sources = [
     'glut_bitmap.c',
     'glut_bwidth.c',
@@ -61,12 +48,6 @@
     'glut_warp.c',
     'glut_win.c',
     'glut_winmisc.c',
-
-    'win32_glx.c',
-    'win32_menu.c',
-    'win32_util.c',
-    'win32_winproc.c',
-    'win32_x11.c',
     
     'glut_8x13.c',
     'glut_9x15.c',
@@ -77,11 +58,52 @@
     'glut_roman.c',
     'glut_tr10.c',
     'glut_tr24.c',
-
-    'glut.def',
 ]
 
-env.SharedLibrary(
+if env['platform'] == 'windows':
+    env.PrependUnique(LIBS = [
+        'winmm', 
+        'gdi32', 
+        'user32', 
+        'opengl32', 
+        'glu32',
+    ])
+    target = 'glut32'
+    sources += [
+        'win32_glx.c',
+        'win32_menu.c',
+        'win32_util.c',
+        'win32_winproc.c',
+        'win32_x11.c',
+        'glut.def',
+    ]
+else:
+    env.PrependUnique(LIBS = [
+        'GLU',
+        'GL',
+        'X11',
+        'Xext',
+        'Xmu',
+        'Xi',
+    ])
+    target = 'glut'
+    sources += [
+        'glut_fcb.c',
+        'glut_menu.c',
+        'glut_menu2.c',
+        'glut_glxext.c',
+        'layerutil.c',
+    ]
+
+
+glut = env.SharedLibrary(
     target = target,
     source = sources,
 )
+
+env.InstallSharedLibrary(glut, version=(3, 7, 1))
+
+if env['platform'] == 'windows':
+    glut = env.FindIxes(glut, 'LIBPREFIX', 'LIBSUFFIX')
+
+Export('glut')
diff --git a/src/glut/glx/capturexfont.c b/src/glut/glx/capturexfont.c
index b99e793..fd63fb7 100644
--- a/src/glut/glx/capturexfont.c
+++ b/src/glut/glx/capturexfont.c
@@ -321,6 +321,7 @@
     }
   }
   printf("};\n\n");
+  printf("GLUTAPI const BitmapFontRec %s;\n", name);
   printf("const BitmapFontRec %s = {\n", name);
   printf("\"%s\",\n", xfont);
   printf("%d,\n", last - first + 1);
diff --git a/src/glut/glx/glut_8x13.c b/src/glut/glx/glut_8x13.c
index 843c63d..f4e18eb 100644
--- a/src/glut/glx/glut_8x13.c
+++ b/src/glut/glx/glut_8x13.c
@@ -2064,6 +2064,7 @@
 &ch255,
 };
 
+GLUTAPI const BitmapFontRec glutBitmap8By13;
 const BitmapFontRec glutBitmap8By13 = {
 "-misc-fixed-medium-r-normal--13-120-75-75-C-80-iso8859-1",
 256,
diff --git a/src/glut/glx/glut_9x15.c b/src/glut/glx/glut_9x15.c
index 2d5c004..7dbec12 100644
--- a/src/glut/glx/glut_9x15.c
+++ b/src/glut/glx/glut_9x15.c
@@ -2066,6 +2066,7 @@
 &ch255,
 };
 
+GLUTAPI const BitmapFontRec glutBitmap9By15;
 const BitmapFontRec glutBitmap9By15 = {
 "-misc-fixed-medium-r-normal--15-140-75-75-C-90-iso8859-1",
 256,
diff --git a/src/glut/glx/glut_hel10.c b/src/glut/glx/glut_hel10.c
index 703cef3..3de1750 100644
--- a/src/glut/glx/glut_hel10.c
+++ b/src/glut/glx/glut_hel10.c
@@ -1769,6 +1769,7 @@
 &ch255,
 };
 
+GLUTAPI const BitmapFontRec glutBitmapHelvetica10;
 const BitmapFontRec glutBitmapHelvetica10 = {
 "-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1",
 224,
diff --git a/src/glut/glx/glut_hel12.c b/src/glut/glx/glut_hel12.c
index 68aed8a..e6f1bbb 100644
--- a/src/glut/glx/glut_hel12.c
+++ b/src/glut/glx/glut_hel12.c
@@ -1779,6 +1779,7 @@
 &ch255,
 };
 
+GLUTAPI const BitmapFontRec glutBitmapHelvetica12;
 const BitmapFontRec glutBitmapHelvetica12 = {
 "-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1",
 224,
diff --git a/src/glut/glx/glut_hel18.c b/src/glut/glx/glut_hel18.c
index f080084..3ddcefd 100644
--- a/src/glut/glx/glut_hel18.c
+++ b/src/glut/glx/glut_hel18.c
@@ -1888,6 +1888,7 @@
 &ch255,
 };
 
+GLUTAPI const BitmapFontRec glutBitmapHelvetica18;
 const BitmapFontRec glutBitmapHelvetica18 = {
 "-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1",
 224,
diff --git a/src/glut/glx/glut_menu.c b/src/glut/glx/glut_menu.c
index 4c4a5ae..d136823 100644
--- a/src/glut/glx/glut_menu.c
+++ b/src/glut/glx/glut_menu.c
@@ -225,6 +225,7 @@
             if (!status) {
               XFreeColormap(__glutDisplay, menuColormap);
               free(placeHolders);
+              placeHolders = NULL;
               continue;
             }
           }
@@ -241,6 +242,7 @@
             XFreeColormap(__glutDisplay, menuColormap);
             if (placeHolders) {
               free(placeHolders);
+              placeHolders = NULL;
             }
             continue;
           }
@@ -252,6 +254,7 @@
             XFreeColormap(__glutDisplay, menuColormap);
             if (placeHolders) {
               free(placeHolders);
+              placeHolders = NULL;
             }
             continue;
           }
@@ -263,6 +266,7 @@
             XFreeColormap(__glutDisplay, menuColormap);
             if (placeHolders) {
               free(placeHolders);
+              placeHolders = NULL;
             }
             continue;
           }
@@ -271,6 +275,7 @@
             XFreeColors(__glutDisplay, menuColormap,
               placeHolders, numPlaceHolders, 0);
             free(placeHolders);
+            placeHolders = NULL;
           }
           menuWhite = color.pixel;
           menuVisual = visual->vinfo.visual;
diff --git a/src/glut/glx/glut_mroman.c b/src/glut/glx/glut_mroman.c
index a29f043..08f879a 100644
--- a/src/glut/glx/glut_mroman.c
+++ b/src/glut/glx/glut_mroman.c
@@ -1,7 +1,9 @@
 
 /* GENERATED FILE -- DO NOT MODIFY */
 
+#define glutStrokeMonoRoman XXX
 #include "glutstroke.h"
+#undef glutStrokeMonoRoman
 
 /* char: 33 '!' */
 
@@ -2447,5 +2449,6 @@
     { 2, char127, 52.381, 104.762 },
 };
 
-StrokeFontRec glutStrokeMonoRoman = { "Roman", 128, chars, 119.048, -33.3333 };
+GLUTAPI const StrokeFontRec glutStrokeMonoRoman;
+const StrokeFontRec glutStrokeMonoRoman = { "Roman", 128, chars, 119.048, -33.3333 };
 
diff --git a/src/glut/glx/glut_roman.c b/src/glut/glx/glut_roman.c
index af2b4ec..95b9f81 100644
--- a/src/glut/glx/glut_roman.c
+++ b/src/glut/glx/glut_roman.c
@@ -1,7 +1,9 @@
 
 /* GENERATED FILE -- DO NOT MODIFY */
 
+#define glutStrokeRoman XXX
 #include "glutstroke.h"
+#undef glutStrokeRoman
 
 /* char: 33 '!' */
 
@@ -2447,5 +2449,6 @@
     { 2, char127, 33.3333, 66.6667 },
 };
 
-StrokeFontRec glutStrokeRoman = { "Roman", 128, chars, 119.048, -33.3333 };
+GLUTAPI const StrokeFontRec glutStrokeRoman;
+const StrokeFontRec glutStrokeRoman = { "Roman", 128, chars, 119.048, -33.3333 };
 
diff --git a/src/glut/glx/glut_tr10.c b/src/glut/glx/glut_tr10.c
index 0fac807..dbf5ebd 100644
--- a/src/glut/glx/glut_tr10.c
+++ b/src/glut/glx/glut_tr10.c
@@ -1768,6 +1768,7 @@
 &ch255,
 };
 
+GLUTAPI const BitmapFontRec glutBitmapTimesRoman10;
 const BitmapFontRec glutBitmapTimesRoman10 = {
 "-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1",
 224,
diff --git a/src/glut/glx/glut_tr24.c b/src/glut/glx/glut_tr24.c
index 22b0e51..5db9d36 100644
--- a/src/glut/glx/glut_tr24.c
+++ b/src/glut/glx/glut_tr24.c
@@ -2051,6 +2051,7 @@
 &ch255,
 };
 
+GLUTAPI const BitmapFontRec glutBitmapTimesRoman24;
 const BitmapFontRec glutBitmapTimesRoman24 = {
 "-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1",
 224,
diff --git a/src/glut/glx/glutstroke.h b/src/glut/glx/glutstroke.h
index 74b6031..d6eac7a 100644
--- a/src/glut/glx/glutstroke.h
+++ b/src/glut/glx/glutstroke.h
@@ -7,6 +7,10 @@
    and is provided without guarantee or warrantee expressed or 
    implied. This program is -not- in the public domain. */
 
+#define GLUT_NO_LIB_PRAGMA  /* Avoid auto library linking when building
+                               the GLUT library itself. */
+#include <GL/glut.h>
+
 #if defined(_MSC_VER)
 #pragma warning (disable:4244)  /* disable bogus conversion warnings */
 #pragma warning (disable:4305)  /* VC++ 5.0 version of above warning. */
diff --git a/src/glut/glx/win32_menu.c b/src/glut/glx/win32_menu.c
index 5ce264d..d8e336c 100644
--- a/src/glut/glx/win32_menu.c
+++ b/src/glut/glx/win32_menu.c
@@ -97,7 +97,7 @@
 mapMenu(GLUTmenu * menu, int x, int y)
 {
   TrackPopupMenu((HMENU) menu->win, TPM_LEFTALIGN |
-    (__glutMenuButton == TPM_RIGHTBUTTON) ? TPM_RIGHTBUTTON : TPM_LEFTBUTTON,
+    ((__glutMenuButton == TPM_RIGHTBUTTON) ? TPM_RIGHTBUTTON : TPM_LEFTBUTTON),
     x, y, 0, __glutCurrentWindow->win, NULL);
 }
 
diff --git a/src/glx/mini/miniglx.c b/src/glx/mini/miniglx.c
index 874b88b..e9a10b4 100644
--- a/src/glx/mini/miniglx.c
+++ b/src/glx/mini/miniglx.c
@@ -2278,14 +2278,14 @@
         int fbconfigID, void *contextID, drm_context_t *hHWContext)
 {
     __DRIscreen *pDRIScreen;
-    __DRIscreenPrivate *psp;
+    __DRIscreen *psp;
 
     pDRIScreen = __glXFindDRIScreen(dpy, screen);
     if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
         return GL_FALSE;
     }
 
-    psp = (__DRIscreenPrivate *) pDRIScreen->private;
+    psp = (__DRIscreen *) pDRIScreen->private;
 
     if (psp->fd) {
         if (drmCreateContext(psp->fd, hHWContext)) {
@@ -2310,9 +2310,9 @@
     GLXDrawable drawable = (GLXDrawable) draw;
     drm_clip_rect_t * cliprect;
     Display* display = (Display*)dpy;
-    __DRIscreenPrivate *psp = display->driScreen.private;
-    __DRIcontextPrivate *pcp = (__DRIcontextPrivate *)CurrentContext->driContext.private;
-    __DRIdrawablePrivate *pdp = pcp->driDrawablePriv;
+    __DRIscreen *psp = display->driScreen.private;
+    __DRIcontext *pcp = (__DRIcontext *)CurrentContext->driContext.private;
+    __DRIdrawable *pdp = pcp->driDrawablePriv;
     if (drawable == 0) {
         return GL_FALSE;
     }
@@ -2357,7 +2357,7 @@
 {
 
   Display *display = (Display *)dpy;
-  __DRIscreenPrivate *psp = display->driScreen.private;
+  __DRIscreen *psp = display->driScreen.private;
   int ret;
   ret = drmCreateDrawable(psp->fd, hHWDrawable);
   
diff --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c
index e144ed3..2cb5d34 100644
--- a/src/glx/x11/dri2.c
+++ b/src/glx/x11/dri2.c
@@ -31,13 +31,18 @@
  */
 
 
+#ifdef GLX_DIRECT_RENDERING
+
 #define NEED_REPLIES
+#include <stdio.h>
 #include <X11/Xlibint.h>
 #include <X11/extensions/Xext.h>
 #include <X11/extensions/extutil.h>
 #include <X11/extensions/dri2proto.h>
 #include "xf86drm.h"
 #include "dri2.h"
+#include "glxclient.h"
+#include "GL/glxext.h"
 
 /* Allow the build to work with an older versions of dri2proto.h and
  * dri2tokens.h.
@@ -53,6 +58,11 @@
 static XExtensionInfo *dri2Info;
 static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info)
 
+static Bool
+DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire);
+static Status
+DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire);
+
 static /* const */ XExtensionHooks dri2ExtensionHooks = {
   NULL,                   /* create_gc */
   NULL,                   /* copy_gc */
@@ -61,8 +71,8 @@
   NULL,                   /* create_font */
   NULL,                   /* free_font */
   DRI2CloseDisplay,       /* close_display */
-  NULL,                   /* wire_to_event */
-  NULL,                   /* event_to_wire */
+  DRI2WireToEvent,        /* wire_to_event */
+  DRI2EventToWire,        /* event_to_wire */
   NULL,                   /* error */
   NULL,                   /* error_string */
 };
@@ -73,6 +83,65 @@
                                    &dri2ExtensionHooks,
                                    0, NULL)
 
+static Bool
+DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
+{
+   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+
+   XextCheckExtension(dpy, info, dri2ExtensionName, False);
+
+   switch ((wire->u.u.type & 0x7f) - info->codes->first_event) {
+   case DRI2_BufferSwapComplete:
+   {
+      GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
+      xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire;
+      switch (awire->type) {
+      case DRI2_EXCHANGE_COMPLETE:
+	 aevent->event_type = GLX_EXCHANGE_COMPLETE;
+	 break;
+      case DRI2_BLIT_COMPLETE:
+	 aevent->event_type = GLX_BLIT_COMPLETE;
+	 break;
+      case DRI2_FLIP_COMPLETE:
+	 aevent->event_type = GLX_FLIP_COMPLETE;
+	 break;
+      default:
+	 /* unknown swap completion type */
+	 return False;
+      }
+      aevent->drawable = awire->drawable;
+      aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
+      aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
+      aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo;
+      return True;
+   }
+   default:
+      /* client doesn't support server event */
+      break;
+   }
+
+   return False;
+}
+
+/* We don't actually support this.  It doesn't make sense for clients to
+ * send each other DRI2 events.
+ */
+static Status
+DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire)
+{
+   XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+
+   XextCheckExtension(dpy, info, dri2ExtensionName, False);
+
+   switch (event->type) {
+   default:
+      /* client doesn't support server event */
+      break;
+   }
+
+   return Success;
+}
+
 Bool
 DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase)
 {
@@ -377,3 +446,178 @@
    UnlockDisplay(dpy);
    SyncHandle();
 }
+
+static void
+load_swap_req(xDRI2SwapBuffersReq *req, CARD64 target, CARD64 divisor,
+	     CARD64 remainder)
+{
+    req->target_msc_hi = target >> 32;
+    req->target_msc_lo = target & 0xffffffff;
+    req->divisor_hi = divisor >> 32;
+    req->divisor_lo = divisor & 0xffffffff;
+    req->remainder_hi = remainder >> 32;
+    req->remainder_lo = remainder & 0xffffffff;
+}
+
+static CARD64
+vals_to_card64(CARD32 lo, CARD32 hi)
+{
+    return (CARD64)hi << 32 | lo;
+}
+
+void DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc,
+		     CARD64 divisor, CARD64 remainder, CARD64 *count)
+{
+    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+    xDRI2SwapBuffersReq *req;
+    xDRI2SwapBuffersReply rep;
+
+    XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
+
+    LockDisplay(dpy);
+    GetReq(DRI2SwapBuffers, req);
+    req->reqType = info->codes->major_opcode;
+    req->dri2ReqType = X_DRI2SwapBuffers;
+    req->drawable = drawable;
+    load_swap_req(req, target_msc, divisor, remainder);
+
+    _XReply(dpy, (xReply *)&rep, 0, xFalse);
+
+    *count = vals_to_card64(rep.swap_lo, rep.swap_hi);
+
+    UnlockDisplay(dpy);
+    SyncHandle();
+}
+
+Bool DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc,
+		CARD64 *sbc)
+{
+    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+    xDRI2GetMSCReq *req;
+    xDRI2MSCReply rep;
+
+    XextCheckExtension (dpy, info, dri2ExtensionName, False);
+
+    LockDisplay(dpy);
+    GetReq(DRI2GetMSC, req);
+    req->reqType = info->codes->major_opcode;
+    req->dri2ReqType = X_DRI2GetMSC;
+    req->drawable = drawable;
+
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+	return False;
+    }
+
+    *ust = vals_to_card64(rep.ust_lo, rep.ust_hi);
+    *msc = vals_to_card64(rep.msc_lo, rep.msc_hi);
+    *sbc = vals_to_card64(rep.sbc_lo, rep.sbc_hi);
+
+    UnlockDisplay(dpy);
+    SyncHandle();
+
+    return True;
+}
+
+static void
+load_msc_req(xDRI2WaitMSCReq *req, CARD64 target, CARD64 divisor,
+	     CARD64 remainder)
+{
+    req->target_msc_hi = target >> 32;
+    req->target_msc_lo = target & 0xffffffff;
+    req->divisor_hi = divisor >> 32;
+    req->divisor_lo = divisor & 0xffffffff;
+    req->remainder_hi = remainder >> 32;
+    req->remainder_lo = remainder & 0xffffffff;
+}
+
+Bool DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor,
+		 CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc)
+{
+    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+    xDRI2WaitMSCReq *req;
+    xDRI2MSCReply rep;
+
+    XextCheckExtension (dpy, info, dri2ExtensionName, False);
+
+    LockDisplay(dpy);
+    GetReq(DRI2WaitMSC, req);
+    req->reqType = info->codes->major_opcode;
+    req->dri2ReqType = X_DRI2WaitMSC;
+    req->drawable = drawable;
+    load_msc_req(req, target_msc, divisor, remainder);
+
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+	return False;
+    }
+
+    *ust = ((CARD64)rep.ust_hi << 32) | (CARD64)rep.ust_lo;
+    *msc = ((CARD64)rep.msc_hi << 32) | (CARD64)rep.msc_lo;
+    *sbc = ((CARD64)rep.sbc_hi << 32) | (CARD64)rep.sbc_lo;
+
+    UnlockDisplay(dpy);
+    SyncHandle();
+
+    return True;
+}
+
+static void
+load_sbc_req(xDRI2WaitSBCReq *req, CARD64 target)
+{
+    req->target_sbc_hi = target >> 32;
+    req->target_sbc_lo = target & 0xffffffff;
+}
+
+Bool DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust,
+		 CARD64 *msc, CARD64 *sbc)
+{
+    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+    xDRI2WaitSBCReq *req;
+    xDRI2MSCReply rep;
+
+    XextCheckExtension (dpy, info, dri2ExtensionName, False);
+
+    LockDisplay(dpy);
+    GetReq(DRI2WaitSBC, req);
+    req->reqType = info->codes->major_opcode;
+    req->dri2ReqType = X_DRI2WaitSBC;
+    req->drawable = drawable;
+    load_sbc_req(req, target_sbc);
+
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+	UnlockDisplay(dpy);
+	SyncHandle();
+	return False;
+    }
+
+    *ust = ((CARD64)rep.ust_hi << 32) | rep.ust_lo;
+    *msc = ((CARD64)rep.msc_hi << 32) | rep.msc_lo;
+    *sbc = ((CARD64)rep.sbc_hi << 32) | rep.sbc_lo;
+
+    UnlockDisplay(dpy);
+    SyncHandle();
+
+    return True;
+}
+
+void DRI2SwapInterval(Display *dpy, XID drawable, int interval)
+{
+    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+    xDRI2SwapIntervalReq *req;
+
+    XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
+
+    LockDisplay(dpy);
+    GetReq(DRI2SwapInterval, req);
+    req->reqType = info->codes->major_opcode;
+    req->dri2ReqType = X_DRI2SwapInterval;
+    req->drawable = drawable;
+    req->interval = interval;
+    UnlockDisplay(dpy);
+    SyncHandle();
+}
+
+#endif /* GLX_DIRECT_RENDERING */
diff --git a/src/glx/x11/dri2.h b/src/glx/x11/dri2.h
index a6fe66e..114e9f8 100644
--- a/src/glx/x11/dri2.h
+++ b/src/glx/x11/dri2.h
@@ -85,4 +85,22 @@
                XserverRegion region,
                CARD32 dest, CARD32 src);
 
+extern void
+DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor,
+		CARD64 remainder, CARD64 *count);
+
+extern Bool
+DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc, CARD64 *sbc);
+
+extern Bool
+DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor,
+	    CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc);
+
+extern Bool
+DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust,
+	    CARD64 *msc, CARD64 *sbc);
+
+extern void
+DRI2SwapInterval(Display *dpy, XID drawable, int interval);
+
 #endif
diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c
index 89efe3a..8314906 100644
--- a/src/glx/x11/dri2_glx.c
+++ b/src/glx/x11/dri2_glx.c
@@ -35,6 +35,7 @@
 #include <X11/Xlib.h>
 #include <X11/extensions/Xfixes.h>
 #include <X11/extensions/Xdamage.h>
+#include "glapi.h"
 #include "glxclient.h"
 #include "glcontextmodes.h"
 #include "xf86dri.h"
@@ -46,6 +47,7 @@
 #include "xf86drm.h"
 #include "dri2.h"
 #include "dri_common.h"
+#include "../../mesa/drivers/dri/common/dri_util.h"
 
 #undef DRI2_MINOR
 #define DRI2_MINOR 1
@@ -64,6 +66,7 @@
    int driMajor;
    int driMinor;
    int driPatch;
+   int swapAvailable;
 };
 
 struct __GLXDRIcontextPrivateRec
@@ -81,6 +84,7 @@
    int width, height;
    int have_back;
    int have_fake_front;
+   int swap_interval;
 };
 
 static void dri2WaitX(__GLXDRIdrawable * pdraw);
@@ -197,9 +201,31 @@
    return &pdraw->base;
 }
 
+static int
+dri2DrawableGetMSC(__GLXscreenConfigs *psc, __GLXDRIdrawable *pdraw,
+		   int64_t *ust, int64_t *msc, int64_t *sbc)
+{
+   return DRI2GetMSC(psc->dpy, pdraw->drawable, ust, msc, sbc);
+}
+
+static int
+dri2WaitForMSC(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
+	       int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
+{
+   return DRI2WaitMSC(pdraw->psc->dpy, pdraw->drawable, target_msc, divisor,
+		      remainder, ust, msc, sbc);
+}
+
+static int
+dri2WaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
+	       int64_t *msc, int64_t *sbc)
+{
+   return DRI2WaitSBC(pdraw->psc->dpy, pdraw->drawable, target_sbc, ust, msc,
+		      sbc);
+}
+
 static void
-dri2CopySubBuffer(__GLXDRIdrawable * pdraw,
-                  int x, int y, int width, int height)
+dri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y, int width, int height)
 {
    __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
    XRectangle xrect;
@@ -232,15 +258,7 @@
 }
 
 static void
-dri2SwapBuffers(__GLXDRIdrawable * pdraw)
-{
-   __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
-
-   dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
-}
-
-static void
-dri2WaitX(__GLXDRIdrawable * pdraw)
+dri2WaitX(__GLXDRIdrawable *pdraw)
 {
    __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
    XRectangle xrect;
@@ -342,6 +360,38 @@
 
 }
 
+static int64_t
+dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
+		int64_t remainder)
+{
+    __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
+    __GLXdisplayPrivate *dpyPriv = __glXInitialize(priv->base.psc->dpy);
+    __GLXDRIdisplayPrivate *pdp =
+	(__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;
+    int64_t ret;
+
+#ifdef __DRI2_FLUSH
+    if (pdraw->psc->f)
+    	(*pdraw->psc->f->flush)(pdraw->driDrawable);
+#endif
+
+    /* Old servers can't handle swapbuffers */
+    if (!pdp->swapAvailable) {
+       dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
+       return 0;
+    }
+
+    DRI2SwapBuffers(pdraw->psc->dpy, pdraw->drawable, target_msc, divisor,
+		    remainder, &ret);
+
+#if __DRI2_FLUSH_VERSION >= 2
+    if (pdraw->psc->f)
+       (*pdraw->psc->f->flushInvalidate)(pdraw->driDrawable);
+#endif
+
+    return ret;
+}
+
 static __DRIbuffer *
 dri2GetBuffers(__DRIdrawable * driDrawable,
                int *width, int *height,
@@ -390,6 +440,23 @@
    return pdraw->buffers;
 }
 
+static void
+dri2SetSwapInterval(__GLXDRIdrawable *pdraw, int interval)
+{
+   __GLXDRIdrawablePrivate *priv =  (__GLXDRIdrawablePrivate *) pdraw;
+
+   DRI2SwapInterval(priv->base.psc->dpy, pdraw->xDrawable, interval);
+   priv->swap_interval = interval;
+}
+
+static unsigned int
+dri2GetSwapInterval(__GLXDRIdrawable *pdraw)
+{
+   __GLXDRIdrawablePrivate *priv =  (__GLXDRIdrawablePrivate *) pdraw;
+
+  return priv->swap_interval;
+}
+
 static const __DRIdri2LoaderExtension dri2LoaderExtension = {
    {__DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION},
    dri2GetBuffers,
@@ -437,7 +504,7 @@
    psc->ext_list_first_time = GL_TRUE;
 
    if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen),
-                    &driverName, &deviceName))
+		    &driverName, &deviceName))
       return NULL;
 
    psc->driver = driOpenDriver(driverName);
@@ -454,9 +521,9 @@
 
    for (i = 0; extensions[i]; i++) {
       if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
-         psc->core = (__DRIcoreExtension *) extensions[i];
+	 psc->core = (__DRIcoreExtension *) extensions[i];
       if (strcmp(extensions[i]->name, __DRI_DRI2) == 0)
-         psc->dri2 = (__DRIdri2Extension *) extensions[i];
+	 psc->dri2 = (__DRIdri2Extension *) extensions[i];
    }
 
    if (psc->core == NULL || psc->dri2 == NULL) {
@@ -485,16 +552,17 @@
     */
    psc->__driScreen =
       psc->dri2->createNewScreen(screen, psc->fd, ((pdp->driMinor < 1)
-                                                   ? loader_extensions_old
-                                                   : loader_extensions),
-                                 &driver_configs, psc);
+						   ? loader_extensions_old
+						   : loader_extensions),
+				 &driver_configs, psc);
 
    if (psc->__driScreen == NULL) {
       ErrorMessageF("failed to create dri screen\n");
       return NULL;
    }
 
-   driBindExtensions(psc, 1);
+   driBindCommonExtensions(psc);
+   dri2BindExtensions(psc);
 
    psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
    psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
@@ -507,6 +575,11 @@
    psp->swapBuffers = dri2SwapBuffers;
    psp->waitGL = dri2WaitGL;
    psp->waitX = dri2WaitX;
+   psp->getDrawableMSC = dri2DrawableGetMSC;
+   psp->waitForMSC = dri2WaitForMSC;
+   psp->waitForSBC = dri2WaitForSBC;
+   psp->setSwapInterval = dri2SetSwapInterval;
+   psp->getSwapInterval = dri2GetSwapInterval;
 
    /* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always
     * available.*/
@@ -518,7 +591,7 @@
 
    return psp;
 
- handle_error:
+handle_error:
    Xfree(driverName);
    Xfree(deviceName);
 
@@ -559,6 +632,9 @@
    }
 
    pdp->driPatch = 0;
+   pdp->swapAvailable = 0;
+   if (pdp->driMinor >= 2)
+      pdp->swapAvailable = 1;
 
    pdp->base.destroyDisplay = dri2DestroyDisplay;
    pdp->base.createScreen = dri2CreateScreen;
diff --git a/src/glx/x11/dri_common.c b/src/glx/x11/dri_common.c
index 9c825ad..e403416 100644
--- a/src/glx/x11/dri_common.c
+++ b/src/glx/x11/dri_common.c
@@ -336,8 +336,9 @@
    return head.next;
 }
 
+/* Bind DRI1 specific extensions */
 _X_HIDDEN void
-driBindExtensions(__GLXscreenConfigs * psc, int dri2)
+driBindExtensions(__GLXscreenConfigs *psc)
 {
    const __DRIextension **extensions;
    int i;
@@ -345,35 +346,13 @@
    extensions = psc->core->getExtensions(psc->__driScreen);
 
    for (i = 0; extensions[i]; i++) {
-#ifdef __DRI_COPY_SUB_BUFFER
-      if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
-         psc->driCopySubBuffer =
-            (__DRIcopySubBufferExtension *) extensions[i];
-         __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer");
-      }
-#endif
-
 #ifdef __DRI_SWAP_CONTROL
       /* No DRI2 support for swap_control at the moment, since SwapBuffers
        * is done by the X server */
-      if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0 && !dri2) {
-         psc->swapControl = (__DRIswapControlExtension *) extensions[i];
-         __glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
-         __glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
-      }
-#endif
-
-#ifdef __DRI_ALLOCATE
-      if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) {
-         psc->allocate = (__DRIallocateExtension *) extensions[i];
-         __glXEnableDirectExtension(psc, "GLX_MESA_allocate_memory");
-      }
-#endif
-
-#ifdef __DRI_FRAME_TRACKING
-      if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) {
-         psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i];
-         __glXEnableDirectExtension(psc, "GLX_MESA_swap_frame_usage");
+      if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
+	 psc->swapControl = (__DRIswapControlExtension *) extensions[i];
+	 __glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
+	 __glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
       }
 #endif
 
@@ -390,23 +369,77 @@
        * GLX_OML_sync_control if implemented. */
 #endif
 
-#ifdef __DRI_READ_DRAWABLE
-      if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
-         __glXEnableDirectExtension(psc, "GLX_SGI_make_current_read");
+      /* Ignore unknown extensions */
+   }
+}
+
+/* Bind DRI2 specific extensions */
+_X_HIDDEN void
+dri2BindExtensions(__GLXscreenConfigs *psc)
+{
+   const __DRIextension **extensions;
+   int i;
+
+   extensions = psc->core->getExtensions(psc->__driScreen);
+
+   for (i = 0; extensions[i]; i++) {
+#ifdef __DRI_TEX_BUFFER
+      if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) {
+	 psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
+	 __glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap");
       }
 #endif
 
-#ifdef __DRI_TEX_BUFFER
-      if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) && dri2) {
-         psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
-         __glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap");
-      }
-#endif
+      __glXEnableDirectExtension(psc, "GLX_SGI_video_sync");
+      __glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
+      __glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
+
+      /* FIXME: if DRI2 version supports it... */
+      __glXEnableDirectExtension(psc, "INTEL_swap_event");
 
 #ifdef __DRI2_FLUSH
-      if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0) && dri2) {
-         psc->f = (__DRI2flushExtension *) extensions[i];
-         /* internal driver extension, no GL extension exposed */
+      if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) {
+	 psc->f = (__DRI2flushExtension *) extensions[i];
+	 /* internal driver extension, no GL extension exposed */
+      }
+#endif
+   }
+}
+
+/* Bind extensions common to DRI1 and DRI2 */
+_X_HIDDEN void
+driBindCommonExtensions(__GLXscreenConfigs *psc)
+{
+   const __DRIextension **extensions;
+   int i;
+
+   extensions = psc->core->getExtensions(psc->__driScreen);
+
+   for (i = 0; extensions[i]; i++) {
+#ifdef __DRI_COPY_SUB_BUFFER
+      if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
+	 psc->driCopySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
+	 __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer");
+      }
+#endif
+
+#ifdef __DRI_ALLOCATE
+      if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) {
+	 psc->allocate = (__DRIallocateExtension *) extensions[i];
+	 __glXEnableDirectExtension(psc, "GLX_MESA_allocate_memory");
+      }
+#endif
+
+#ifdef __DRI_FRAME_TRACKING
+      if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) {
+	 psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i];
+	 __glXEnableDirectExtension(psc, "GLX_MESA_swap_frame_usage");
+      }
+#endif
+
+#ifdef __DRI_READ_DRAWABLE
+      if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
+	 __glXEnableDirectExtension(psc, "GLX_SGI_make_current_read");
       }
 #endif
 
diff --git a/src/glx/x11/dri_common.h b/src/glx/x11/dri_common.h
index 61ac9c6..bb178db 100644
--- a/src/glx/x11/dri_common.h
+++ b/src/glx/x11/dri_common.h
@@ -56,6 +56,8 @@
 
 extern void *driOpenDriver(const char *driverName);
 
-extern void driBindExtensions(__GLXscreenConfigs * psc, int dri2);
+extern void driBindExtensions(__GLXscreenConfigs * psc);
+extern void dri2BindExtensions(__GLXscreenConfigs * psc);
+extern void driBindCommonExtensions(__GLXscreenConfigs * psc);
 
 #endif /* _DRI_COMMON_H */
diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c
index 4f7acb6..e658644 100644
--- a/src/glx/x11/dri_glx.c
+++ b/src/glx/x11/dri_glx.c
@@ -280,8 +280,6 @@
    NULL
 };
 
-#ifndef GLX_USE_APPLEGL
-
 /**
  * Perform the required libGL-side initialization and call the client-side
  * driver's \c __driCreateNewScreen function.
@@ -292,7 +290,7 @@
  * \param driDpy DRI display information.
  * \param createNewScreen  Pointer to the client-side driver's
  *               \c __driCreateNewScreen function.
- * \returns A pointer to the \c __DRIscreenPrivate structure returned by
+ * \returns A pointer to the \c __DRIscreen structure returned by
  *          the client-side driver on success, or \c NULL on failure.
  */
 static void *
@@ -475,17 +473,6 @@
    return NULL;
 }
 
-#else /* !GLX_USE_APPLEGL */
-
-static void *
-CallCreateNewScreen(Display * dpy, int scrn, __GLXscreenConfigs * psc,
-                    __GLXDRIdisplayPrivate * driDpy)
-{
-   return NULL;
-}
-
-#endif /* !GLX_USE_APPLEGL */
-
 static void
 driDestroyContext(__GLXDRIcontext * context,
                   __GLXscreenConfigs * psc, Display * dpy)
@@ -620,10 +607,12 @@
    return pdraw;
 }
 
-static void
-driSwapBuffers(__GLXDRIdrawable * pdraw)
+static int64_t
+driSwapBuffers(__GLXDRIdrawable * pdraw, int64_t unused1, int64_t unused2,
+	       int64_t unused3)
 {
    (*pdraw->psc->core->swapBuffers) (pdraw->driDrawable);
+   return 0;
 }
 
 static void
@@ -683,9 +672,9 @@
 
    for (i = 0; extensions[i]; i++) {
       if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
-         psc->core = (__DRIcoreExtension *) extensions[i];
+	 psc->core = (__DRIcoreExtension *) extensions[i];
       if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0)
-         psc->legacy = (__DRIlegacyExtension *) extensions[i];
+	 psc->legacy = (__DRIlegacyExtension *) extensions[i];
    }
 
    if (psc->core == NULL || psc->legacy == NULL) {
@@ -701,7 +690,9 @@
       return NULL;
    }
 
-   driBindExtensions(psc, 0);
+   driBindExtensions(psc);
+   driBindCommonExtensions(psc);
+
    if (psc->driCopySubBuffer)
       psp->copySubBuffer = driCopySubBuffer;
 
diff --git a/src/glx/x11/drisw_glx.c b/src/glx/x11/drisw_glx.c
index 15e1586..6a51d74 100644
--- a/src/glx/x11/drisw_glx.c
+++ b/src/glx/x11/drisw_glx.c
@@ -250,12 +250,14 @@
 {
    __GLXDRIcontextPrivate *pcp, *pcp_shared;
    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
-   const __DRIcoreExtension *core = psc->core;
+   const __DRIcoreExtension *core;
    __DRIcontext *shared = NULL;
 
    if (!psc || !psc->driScreen)
       return NULL;
 
+   core = psc->core;
+
    if (shareList) {
       pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
       shared = pcp_shared->driContext;
@@ -396,7 +398,8 @@
       goto handle_error;
    }
 
-   driBindExtensions(psc, 0);
+   driBindExtensions(psc);
+   driBindCommonExtensions(psc);
 
    psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
    psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h
index 00ee14f..ded4f5a 100644
--- a/src/glx/x11/glxclient.h
+++ b/src/glx/x11/glxclient.h
@@ -121,26 +121,35 @@
                                     __GLXdisplayPrivate * priv);
 };
 
-struct __GLXDRIscreenRec
-{
+struct __GLXDRIscreenRec {
 
-   void (*destroyScreen) (__GLXscreenConfigs * psc);
+   void (*destroyScreen)(__GLXscreenConfigs *psc);
 
-   __GLXDRIcontext *(*createContext) (__GLXscreenConfigs * psc,
-                                      const __GLcontextModes * mode,
-                                      GLXContext gc,
-                                      GLXContext shareList, int renderType);
+   __GLXDRIcontext *(*createContext)(__GLXscreenConfigs *psc,
+				     const __GLcontextModes *mode,
+				     GLXContext gc,
+				     GLXContext shareList, int renderType);
 
-   __GLXDRIdrawable *(*createDrawable) (__GLXscreenConfigs * psc,
-                                        XID drawable,
-                                        GLXDrawable glxDrawable,
-                                        const __GLcontextModes * modes);
+   __GLXDRIdrawable *(*createDrawable)(__GLXscreenConfigs *psc,
+				       XID drawable,
+				       GLXDrawable glxDrawable,
+				       const __GLcontextModes *modes);
 
-   void (*swapBuffers) (__GLXDRIdrawable * pdraw);
-   void (*copySubBuffer) (__GLXDRIdrawable * pdraw,
-                          int x, int y, int width, int height);
-   void (*waitX) (__GLXDRIdrawable * pdraw);
-   void (*waitGL) (__GLXDRIdrawable * pdraw);
+   int64_t (*swapBuffers)(__GLXDRIdrawable *pdraw, int64_t target_msc,
+			  int64_t divisor, int64_t remainder);
+   void (*copySubBuffer)(__GLXDRIdrawable *pdraw,
+			 int x, int y, int width, int height);
+   void (*waitX)(__GLXDRIdrawable *pdraw);
+   void (*waitGL)(__GLXDRIdrawable *pdraw);
+   int (*getDrawableMSC)(__GLXscreenConfigs *psc, __GLXDRIdrawable *pdraw,
+			 int64_t *ust, int64_t *msc, int64_t *sbc);
+   int (*waitForMSC)(__GLXDRIdrawable *pdraw, int64_t target_msc,
+		     int64_t divisor, int64_t remainder, int64_t *ust,
+		     int64_t *msc, int64_t *sbc);
+   int (*waitForSBC)(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
+		     int64_t *msc, int64_t *sbc);
+   void (*setSwapInterval)(__GLXDRIdrawable *pdraw, int interval);
+   int (*getSwapInterval)(__GLXDRIdrawable *pdraw);
 };
 
 struct __GLXDRIcontextRec
diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c
index c63116b..c3be974 100644
--- a/src/glx/x11/glxcmds.c
+++ b/src/glx/x11/glxcmds.c
@@ -50,7 +50,7 @@
 #include <xcb/glx.h>
 #endif
 
-static const char __glXGLXClientVendorName[] = "SGI";
+static const char __glXGLXClientVendorName[] = "Mesa Project and SGI";
 static const char __glXGLXClientVersion[] = "1.4";
 
 
@@ -982,7 +982,7 @@
 
    if (pdraw != NULL) {
       glFlush();
-      (*pdraw->psc->driScreen->swapBuffers) (pdraw);
+      (*pdraw->psc->driScreen->swapBuffers)(pdraw, 0, 0, 0);
       return;
    }
 #endif
@@ -1884,6 +1884,7 @@
 {
    xGLXVendorPrivateReq *req;
    GLXContext gc = __glXGetCurrentContext();
+   __GLXscreenConfigs *psc;
    Display *dpy;
    CARD32 *interval_ptr;
    CARD8 opcode;
@@ -1898,20 +1899,30 @@
 
 #ifdef __DRI_SWAP_CONTROL
    if (gc->driContext) {
-      __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
-                                                          gc->screen);
+      __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
+							    gc->screen );
       __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
-                                                  gc->currentDrawable,
-                                                  NULL);
+						  gc->currentDrawable,
+						  NULL);
       if (psc->swapControl != NULL && pdraw != NULL) {
-         psc->swapControl->setSwapInterval(pdraw->driDrawable, interval);
-         return 0;
+	 psc->swapControl->setSwapInterval(pdraw->driDrawable, interval);
+	 return 0;
       }
-      else {
-         return GLX_BAD_CONTEXT;
+      else if (pdraw == NULL) {
+	 return GLX_BAD_CONTEXT;
       }
    }
 #endif
+   psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
+
+   if (gc->driContext && psc->driScreen && psc->driScreen->setSwapInterval) {
+      __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
+						  gc->currentDrawable,
+						  NULL);
+      psc->driScreen->setSwapInterval(pdraw, interval);
+      return 0;
+   }
+
    dpy = gc->currentDpy;
    opcode = __glXSetupForCommand(dpy);
    if (!opcode) {
@@ -1943,13 +1954,13 @@
 static int
 __glXSwapIntervalMESA(unsigned int interval)
 {
-#ifdef __DRI_SWAP_CONTROL
    GLXContext gc = __glXGetCurrentContext();
 
    if (interval < 0) {
       return GLX_BAD_VALUE;
    }
 
+#ifdef __DRI_SWAP_CONTROL
    if (gc != NULL && gc->driContext) {
       __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
                                                           gc->screen);
@@ -1963,10 +1974,20 @@
          }
       }
    }
-#else
-   (void) interval;
 #endif
 
+   if (gc != NULL && gc->driContext) {
+      __GLXscreenConfigs *psc;
+
+      psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
+      if (psc->driScreen && psc->driScreen->setSwapInterval) {
+         __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
+						     gc->currentDrawable, NULL);
+	 psc->driScreen->setSwapInterval(pdraw, interval);
+	 return 0;
+      }
+   }
+
    return GLX_BAD_CONTEXT;
 }
 
@@ -1990,6 +2011,16 @@
       }
    }
 #endif
+   if (gc != NULL && gc->driContext) {
+      __GLXscreenConfigs *psc;
+
+      psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
+      if (psc->driScreen && psc->driScreen->getSwapInterval) {
+         __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
+						     gc->currentDrawable, NULL);
+	 return psc->driScreen->getSwapInterval(pdraw);
+      }
+   }
 
    return 0;
 }
@@ -2102,64 +2133,73 @@
 static int
 __glXGetVideoSyncSGI(unsigned int *count)
 {
+   int64_t ust, msc, sbc;
+   int ret;
+   GLXContext gc = __glXGetCurrentContext();
+   __GLXscreenConfigs *psc;
+   __GLXDRIdrawable *pdraw;
+
+   if (!gc || !gc->driContext)
+      return GLX_BAD_CONTEXT;
+
+   psc = GetGLXScreenConfigs(gc->currentDpy, gc->screen);
+   pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+
    /* FIXME: Looking at the GLX_SGI_video_sync spec in the extension registry,
     * FIXME: there should be a GLX encoding for this call.  I can find no
     * FIXME: documentation for the GLX encoding.
     */
 #ifdef __DRI_MEDIA_STREAM_COUNTER
-   GLXContext gc = __glXGetCurrentContext();
+   if ( psc->msc && psc->driScreen ) {
+      ret = (*psc->msc->getDrawableMSC)(psc->__driScreen,
+					pdraw->driDrawable, &msc);
+      *count = (unsigned) msc;
 
-
-   if (gc != NULL && gc->driContext) {
-      __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
-                                                          gc->screen);
-      if (psc->msc && psc->driScreen) {
-         __GLXDRIdrawable *pdraw =
-            GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
-         int64_t temp;
-         int ret;
-
-         ret = (*psc->msc->getDrawableMSC) (psc->__driScreen,
-                                            pdraw->driDrawable, &temp);
-         *count = (unsigned) temp;
-
-         return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
-      }
+      return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
    }
-#else
-   (void) count;
 #endif
+   if (psc->driScreen && psc->driScreen->getDrawableMSC) {
+      ret = psc->driScreen->getDrawableMSC(psc, pdraw, &ust, &msc, &sbc);
+      *count = (unsigned) msc;
+      return (ret == True) ? 0 : GLX_BAD_CONTEXT;
+   }
+
    return GLX_BAD_CONTEXT;
 }
 
 static int
 __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
 {
-#ifdef __DRI_MEDIA_STREAM_COUNTER
    GLXContext gc = __glXGetCurrentContext();
+   __GLXscreenConfigs *psc;
+   __GLXDRIdrawable *pdraw;
+   int64_t ust, msc, sbc;
+   int ret;
 
    if (divisor <= 0 || remainder < 0)
       return GLX_BAD_VALUE;
 
-   if (gc != NULL && gc->driContext) {
-      __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
-                                                          gc->screen);
-      if (psc->msc != NULL && psc->driScreen) {
-         __GLXDRIdrawable *pdraw =
-            GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
-         int ret;
-         int64_t msc;
-         int64_t sbc;
+   if (!gc || !gc->driContext)
+      return GLX_BAD_CONTEXT;
 
-         ret = (*psc->msc->waitForMSC) (pdraw->driDrawable, 0,
-                                        divisor, remainder, &msc, &sbc);
-         *count = (unsigned) msc;
-         return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
-      }
+   psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
+   pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+
+#ifdef __DRI_MEDIA_STREAM_COUNTER
+   if (psc->msc != NULL && psc->driScreen ) {
+      ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, 0,
+				    divisor, remainder, &msc, &sbc);
+      *count = (unsigned) msc;
+      return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
    }
-#else
-   (void) count;
 #endif
+   if (psc->driScreen && psc->driScreen->waitForMSC) {
+      ret = psc->driScreen->waitForMSC(pdraw, 0, divisor, remainder, &ust, &msc,
+				       &sbc);
+      *count = (unsigned) msc;
+      return (ret == True) ? 0 : GLX_BAD_CONTEXT;
+   }
+
    return GLX_BAD_CONTEXT;
 }
 
@@ -2312,27 +2352,29 @@
 __glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable,
                       int64_t * ust, int64_t * msc, int64_t * sbc)
 {
+   __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
+   int i, ret;
+   __GLXDRIdrawable *pdraw;
+   __GLXscreenConfigs *psc;
+
+   if (!priv)
+      return False;
+
+   pdraw = GetGLXDRIDrawable(dpy, drawable, &i);
+   psc = &priv->screenConfigs[i];
+
 #if defined(__DRI_SWAP_BUFFER_COUNTER) && defined(__DRI_MEDIA_STREAM_COUNTER)
-   __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
-
-   if (priv != NULL) {
-      int i;
-      __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &i);
-      __GLXscreenConfigs *const psc = &priv->screenConfigs[i];
-
-      assert((pdraw == NULL) || (i != -1));
-      return ((pdraw && psc->sbc && psc->msc)
-              && ((*psc->msc->getMSC) (psc->driScreen, msc) == 0)
-              && ((*psc->sbc->getSBC) (pdraw->driDrawable, sbc) == 0)
-              && (__glXGetUST(ust) == 0));
-   }
-#else
-   (void) dpy;
-   (void) drawable;
-   (void) ust;
-   (void) msc;
-   (void) sbc;
+   if (pdraw && psc->sbc && psc->sbc)
+      return ( (pdraw && psc->sbc && psc->msc)
+	       && ((*psc->msc->getMSC)(psc->driScreen, msc) == 0)
+	       && ((*psc->sbc->getSBC)(pdraw->driDrawable, sbc) == 0)
+	       && (__glXGetUST(ust) == 0) );
 #endif
+   if (pdraw && psc && psc->driScreen && psc->driScreen->getDrawableMSC) {
+      ret = psc->driScreen->getDrawableMSC(psc, pdraw, ust, msc, sbc);
+      return ret;
+   }
+
    return False;
 }
 
@@ -2440,11 +2482,14 @@
 __glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable,
                        int64_t target_msc, int64_t divisor, int64_t remainder)
 {
-#ifdef __DRI_SWAP_BUFFER_COUNTER
+   GLXContext gc = __glXGetCurrentContext();
    int screen;
    __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
    __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
 
+   if (!pdraw || !gc->driContext) /* no GLX for this */
+      return -1;
+
    /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
     * error", but it also says "It [glXSwapBuffersMscOML] will return a value
     * of -1 if the function failed because of errors detected in the input
@@ -2455,18 +2500,19 @@
    if (divisor > 0 && remainder >= divisor)
       return -1;
 
-   if (pdraw != NULL && psc->counters != NULL)
-      return (*psc->sbc->swapBuffersMSC) (pdraw->driDrawable, target_msc,
-                                          divisor, remainder);
-
-#else
-   (void) dpy;
-   (void) drawable;
-   (void) target_msc;
-   (void) divisor;
-   (void) remainder;
+#ifdef __DRI_SWAP_BUFFER_COUNTER
+   if (psc->counters != NULL)
+      return (*psc->sbc->swapBuffersMSC)(pdraw->driDrawable, target_msc,
+					 divisor, remainder);
 #endif
-   return 0;
+
+#ifdef GLX_DIRECT_RENDERING
+   if (psc->driScreen && psc->driScreen->swapBuffers)
+      return (*psc->driScreen->swapBuffers)(pdraw, target_msc, divisor,
+					    remainder);
+#endif
+
+   return -1;
 }
 
 
@@ -2476,12 +2522,14 @@
                    int64_t remainder, int64_t * ust,
                    int64_t * msc, int64_t * sbc)
 {
-#ifdef __DRI_MEDIA_STREAM_COUNTER
-   int screen = 0;
+   int screen;
    __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
-   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
+   __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
    int ret;
 
+   fprintf(stderr, "waitmsc: %lld, %lld, %lld\n", target_msc, divisor,
+	   remainder);
+
    /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
     * error", but the return type in the spec is Bool.
     */
@@ -2490,7 +2538,9 @@
    if (divisor > 0 && remainder >= divisor)
       return False;
 
+#ifdef __DRI_MEDIA_STREAM_COUNTER
    if (pdraw != NULL && psc->msc != NULL) {
+      fprintf(stderr, "dri1 msc\n");
       ret = (*psc->msc->waitForMSC) (pdraw->driDrawable, target_msc,
                                      divisor, remainder, msc, sbc);
 
@@ -2499,16 +2549,14 @@
        */
       return ((ret == 0) && (__glXGetUST(ust) == 0));
    }
-#else
-   (void) dpy;
-   (void) drawable;
-   (void) target_msc;
-   (void) divisor;
-   (void) remainder;
-   (void) ust;
-   (void) msc;
-   (void) sbc;
 #endif
+   if (pdraw && psc->driScreen && psc->driScreen->waitForMSC) {
+      ret = psc->driScreen->waitForMSC(pdraw, target_msc, divisor, remainder,
+				       ust, msc, sbc);
+      return ret;
+   }
+
+   fprintf(stderr, "no drawable??\n");
    return False;
 }
 
@@ -2518,7 +2566,6 @@
                    int64_t target_sbc, int64_t * ust,
                    int64_t * msc, int64_t * sbc)
 {
-#ifdef __DRI_SWAP_BUFFER_COUNTER
    int screen;
    __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
    __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
@@ -2529,7 +2576,7 @@
     */
    if (target_sbc < 0)
       return False;
-
+#ifdef __DRI_SWAP_BUFFER_COUNTER
    if (pdraw != NULL && psc->sbc != NULL) {
       ret =
          (*psc->sbc->waitForSBC) (pdraw->driDrawable, target_sbc, msc, sbc);
@@ -2539,14 +2586,11 @@
        */
       return ((ret == 0) && (__glXGetUST(ust) == 0));
    }
-#else
-   (void) dpy;
-   (void) drawable;
-   (void) target_sbc;
-   (void) ust;
-   (void) msc;
-   (void) sbc;
 #endif
+   if (pdraw && psc->driScreen && psc->driScreen->waitForMSC) {
+      ret = psc->driScreen->waitForSBC(pdraw, target_sbc, ust, msc, sbc);
+      return ret;
+   }
    return False;
 }
 
@@ -2575,7 +2619,7 @@
    (void) readFreq;
    (void) writeFreq;
    (void) priority;
-#endif /* GLX_DIRECT_RENDERING */
+#endif /* __DRI_ALLOCATE */
 
    return NULL;
 }
@@ -2594,7 +2638,7 @@
    (void) dpy;
    (void) scrn;
    (void) pointer;
-#endif /* GLX_DIRECT_RENDERING */
+#endif /* __DRI_ALLOCATE */
 }
 
 
diff --git a/src/glx/x11/glxcurrent.c b/src/glx/x11/glxcurrent.c
index f1e3e16..fae1bd9 100644
--- a/src/glx/x11/glxcurrent.c
+++ b/src/glx/x11/glxcurrent.c
@@ -475,13 +475,6 @@
                IndirectAPI = __glXNewIndirectAPI();
             _glapi_set_dispatch(IndirectAPI);
 
-#ifdef GLX_USE_APPLEGL
-            do {
-               extern void XAppleDRIUseIndirectDispatch(void);
-               XAppleDRIUseIndirectDispatch();
-            } while (0);
-#endif
-
             state = (__GLXattribute *) (gc->client_state_private);
 
             gc->currentContextTag = reply.contextTag;
diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c
index e5553cb..fe65216 100644
--- a/src/glx/x11/glxext.c
+++ b/src/glx/x11/glxext.c
@@ -101,6 +101,10 @@
 static
 XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName,
                            __GLX_NUMBER_ERRORS, error_list)
+static Bool
+__glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire);
+static Status
+__glXEventToWire(Display *dpy, XEvent *event, xEvent *wire);
 
 static /* const */ XExtensionHooks __glXExtensionHooks = {
   NULL,                   /* create_gc */
@@ -110,8 +114,8 @@
   NULL,                   /* create_font */
   NULL,                   /* free_font */
   __glXCloseDisplay,      /* close_display */
-  NULL,                   /* wire_to_event */
-  NULL,                   /* event_to_wire */
+  __glXWireToEvent,       /* wire_to_event */
+  __glXEventToWire,       /* event_to_wire */
   NULL,                   /* error */
   __glXErrorString,       /* error_string */
 };
@@ -121,6 +125,89 @@
                            __glXExtensionName, &__glXExtensionHooks,
                            __GLX_NUMBER_EVENTS, NULL)
 
+/*
+ * GLX events are a bit funky.  We don't stuff the X event code into
+ * our user exposed (via XNextEvent) structure.  Instead we use the GLX
+ * private event code namespace (and hope it doesn't conflict).  Clients
+ * have to know that bit 15 in the event type field means they're getting
+ * a GLX event, and then handle the various sub-event types there, rather
+ * than simply checking the event code and handling it directly.
+ */
+
+static Bool
+__glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
+{
+   XExtDisplayInfo *info = __glXFindDisplay(dpy);
+
+   XextCheckExtension(dpy, info, __glXExtensionName, False);
+
+   switch ((wire->u.u.type & 0x7f) - info->codes->first_event) {
+   case GLX_PbufferClobber:
+   {
+      GLXPbufferClobberEvent *aevent = (GLXPbufferClobberEvent *)event;
+      xGLXPbufferClobberEvent *awire = (xGLXPbufferClobberEvent *)wire;
+      aevent->event_type = awire->type;
+      aevent->serial = awire->sequenceNumber;
+      aevent->event_type = awire->event_type;
+      aevent->draw_type = awire->draw_type;
+      aevent->drawable = awire->drawable;
+      aevent->buffer_mask = awire->buffer_mask;
+      aevent->aux_buffer = awire->aux_buffer;
+      aevent->x = awire->x;
+      aevent->y = awire->y;
+      aevent->width = awire->width;
+      aevent->height = awire->height;
+      aevent->count = awire->count;
+      return True;
+   }
+   case GLX_BufferSwapComplete:
+   {
+      GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
+      xGLXBufferSwapComplete *awire = (xGLXBufferSwapComplete *)wire;
+      aevent->event_type = awire->event_type;
+      aevent->drawable = awire->drawable;
+      aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
+      aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
+      aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo;
+      return True;
+   }
+   default:
+      /* client doesn't support server event */
+      break;
+   }
+
+   return False;
+}
+
+/* We don't actually support this.  It doesn't make sense for clients to
+ * send each other GLX events.
+ */
+static Status
+__glXEventToWire(Display *dpy, XEvent *event, xEvent *wire)
+{
+   XExtDisplayInfo *info = __glXFindDisplay(dpy);
+
+   XextCheckExtension(dpy, info, __glXExtensionName, False);
+
+   switch (event->type) {
+   case GLX_DAMAGED:
+      break;
+   case GLX_SAVED:
+      break;
+   case GLX_EXCHANGE_COMPLETE:
+      break;
+   case GLX_BLIT_COMPLETE:
+      break;
+   case GLX_FLIP_COMPLETE:
+      break;
+   default:
+      /* client doesn't support server event */
+      break;
+   }
+
+   return Success;
+}
+
 /************************************************************************/
 /*
 ** Free the per screen configs data as well as the array of
@@ -150,8 +237,9 @@
 
 #ifdef GLX_DIRECT_RENDERING
       if (psc->driver_configs) {
-         for (unsigned int i = 0; psc->driver_configs[i]; i++)
-            free((__DRIconfig *) psc->driver_configs[i]);
+         unsigned int j;
+         for (j = 0; psc->driver_configs[j]; j++)
+            free((__DRIconfig *) psc->driver_configs[j]);
          free(psc->driver_configs);
          psc->driver_configs = NULL;
       }
diff --git a/src/glx/x11/glxextensions.c b/src/glx/x11/glxextensions.c
index 473f46d..25a5c49 100644
--- a/src/glx/x11/glxextensions.c
+++ b/src/glx/x11/glxextensions.c
@@ -104,6 +104,7 @@
    { GLX(SGIX_swap_group),             VER(0,0), N, N, N, N },
    { GLX(SGIX_visual_select_group),    VER(0,0), Y, Y, N, N },
    { GLX(EXT_texture_from_pixmap),     VER(0,0), Y, N, N, N },
+   { GLX(INTEL_swap_event),            VER(1,4), Y, Y, N, N },
    { NULL }
 };
 
@@ -112,6 +113,7 @@
    { GL(ARB_draw_buffers),               VER(0,0), Y, N, N, N },
    { GL(ARB_fragment_program),           VER(0,0), Y, N, N, N },
    { GL(ARB_fragment_program_shadow),    VER(0,0), Y, N, N, N },
+   { GL(ARB_framebuffer_object),         VER(0,0), Y, N, N, N },
    { GL(ARB_imaging),                    VER(0,0), Y, N, N, N },
    { GL(ARB_multisample),                VER(1,3), Y, N, N, N },
    { GL(ARB_multitexture),               VER(1,3), Y, N, N, N },
@@ -150,8 +152,11 @@
    { GL(EXT_depth_bounds_test),          VER(0,0), N, N, N, N },
    { GL(EXT_draw_range_elements),        VER(1,2), Y, N, Y, N },
    { GL(EXT_fog_coord),                  VER(1,4), Y, N, N, N },
+   { GL(EXT_framebuffer_blit),           VER(0,0), Y, N, N, N },
+   { GL(EXT_framebuffer_multisample),    VER(0,0), Y, N, N, N },
    { GL(EXT_framebuffer_object),         VER(0,0), Y, N, N, N },
    { GL(EXT_multi_draw_arrays),          VER(1,4), Y, N, Y, N },
+   { GL(EXT_packed_depth_stencil),       VER(0,0), Y, N, N, N },
    { GL(EXT_packed_pixels),              VER(1,2), Y, N, N, N },
    { GL(EXT_paletted_texture),           VER(0,0), Y, N, N, N },
    { GL(EXT_pixel_buffer_object),        VER(0,0), N, N, N, N },
@@ -209,6 +214,7 @@
    { GL(NV_fragment_program2),           VER(0,0), Y, N, N, N },
    { GL(NV_light_max_exponent),          VER(0,0), Y, N, N, N },
    { GL(NV_multisample_filter_hint),     VER(0,0), Y, N, N, N },
+   { GL(NV_packed_depth_stencil),        VER(0,0), Y, N, N, N },
    { GL(NV_point_sprite),                VER(0,0), Y, N, N, N },
    { GL(NV_texgen_reflection),           VER(0,0), Y, N, N, N },
    { GL(NV_texture_compression_vtc),     VER(0,0), Y, N, N, N },
diff --git a/src/glx/x11/glxextensions.h b/src/glx/x11/glxextensions.h
index 9f1c697..f556b12 100644
--- a/src/glx/x11/glxextensions.h
+++ b/src/glx/x11/glxextensions.h
@@ -65,7 +65,8 @@
    SGIX_swap_barrier_bit,
    SGIX_swap_group_bit,
    SGIX_visual_select_group_bit,
-   EXT_texture_from_pixmap_bit
+   EXT_texture_from_pixmap_bit,
+   INTEL_swap_event_bit,
 };
 
 enum
@@ -74,6 +75,7 @@
    GL_ARB_draw_buffers_bit,
    GL_ARB_fragment_program_bit,
    GL_ARB_fragment_program_shadow_bit,
+   GL_ARB_framebuffer_object_bit,
    GL_ARB_imaging_bit,
    GL_ARB_multisample_bit,
    GL_ARB_multitexture_bit,
@@ -112,8 +114,11 @@
    GL_EXT_depth_bounds_test_bit,
    GL_EXT_draw_range_elements_bit,
    GL_EXT_fog_coord_bit,
+   GL_EXT_framebuffer_blit_bit,
+   GL_EXT_framebuffer_multisample_bit,
    GL_EXT_framebuffer_object_bit,
    GL_EXT_multi_draw_arrays_bit,
+   GL_EXT_packed_depth_stencil_bit,
    GL_EXT_packed_pixels_bit,
    GL_EXT_paletted_texture_bit,
    GL_EXT_pixel_buffer_object_bit,
@@ -164,6 +169,7 @@
    GL_NV_fragment_program2_bit,
    GL_NV_light_max_exponent_bit,
    GL_NV_multisample_filter_hint_bit,
+   GL_NV_packed_depth_stencil_bit,
    GL_NV_point_sprite_bit,
    GL_NV_texgen_reflection_bit,
    GL_NV_texture_compression_vtc_bit,
diff --git a/src/glx/x11/indirect.c b/src/glx/x11/indirect.c
index e0cafd4..ea90ce4 100644
--- a/src/glx/x11/indirect.c
+++ b/src/glx/x11/indirect.c
@@ -8604,6 +8604,26 @@
     }
 }
 
+#define X_GLrop_RenderbufferStorageMultisample 4331
+void
+__indirect_glRenderbufferStorageMultisample(GLenum target, GLsizei samples,
+                                            GLenum internalformat,
+                                            GLsizei width, GLsizei height)
+{
+    __GLXcontext *const gc = __glXGetCurrentContext();
+    const GLuint cmdlen = 24;
+    emit_header(gc->pc, X_GLrop_RenderbufferStorageMultisample, cmdlen);
+    (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4);
+    (void) memcpy((void *) (gc->pc + 8), (void *) (&samples), 4);
+    (void) memcpy((void *) (gc->pc + 12), (void *) (&internalformat), 4);
+    (void) memcpy((void *) (gc->pc + 16), (void *) (&width), 4);
+    (void) memcpy((void *) (gc->pc + 20), (void *) (&height), 4);
+    gc->pc += cmdlen;
+    if (__builtin_expect(gc->pc > gc->limit, 0)) {
+        (void) __glXFlushRenderBuffer(gc, gc->pc);
+    }
+}
+
 #define X_GLrop_SampleMaskSGIS 2048
 void
 __indirect_glSampleMaskSGIS(GLclampf value, GLboolean invert)
@@ -10597,6 +10617,52 @@
     }
 }
 
+#define X_GLrop_BlitFramebufferEXT 4330
+void
+__indirect_glBlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1,
+                                GLint srcY1, GLint dstX0, GLint dstY0,
+                                GLint dstX1, GLint dstY1, GLbitfield mask,
+                                GLenum filter)
+{
+    __GLXcontext *const gc = __glXGetCurrentContext();
+    const GLuint cmdlen = 44;
+    emit_header(gc->pc, X_GLrop_BlitFramebufferEXT, cmdlen);
+    (void) memcpy((void *) (gc->pc + 4), (void *) (&srcX0), 4);
+    (void) memcpy((void *) (gc->pc + 8), (void *) (&srcY0), 4);
+    (void) memcpy((void *) (gc->pc + 12), (void *) (&srcX1), 4);
+    (void) memcpy((void *) (gc->pc + 16), (void *) (&srcY1), 4);
+    (void) memcpy((void *) (gc->pc + 20), (void *) (&dstX0), 4);
+    (void) memcpy((void *) (gc->pc + 24), (void *) (&dstY0), 4);
+    (void) memcpy((void *) (gc->pc + 28), (void *) (&dstX1), 4);
+    (void) memcpy((void *) (gc->pc + 32), (void *) (&dstY1), 4);
+    (void) memcpy((void *) (gc->pc + 36), (void *) (&mask), 4);
+    (void) memcpy((void *) (gc->pc + 40), (void *) (&filter), 4);
+    gc->pc += cmdlen;
+    if (__builtin_expect(gc->pc > gc->limit, 0)) {
+        (void) __glXFlushRenderBuffer(gc, gc->pc);
+    }
+}
+
+#define X_GLrop_FramebufferTextureLayerEXT 237
+void
+__indirect_glFramebufferTextureLayerEXT(GLenum target, GLenum attachment,
+                                        GLuint texture, GLint level,
+                                        GLint layer)
+{
+    __GLXcontext *const gc = __glXGetCurrentContext();
+    const GLuint cmdlen = 24;
+    emit_header(gc->pc, X_GLrop_FramebufferTextureLayerEXT, cmdlen);
+    (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4);
+    (void) memcpy((void *) (gc->pc + 8), (void *) (&attachment), 4);
+    (void) memcpy((void *) (gc->pc + 12), (void *) (&texture), 4);
+    (void) memcpy((void *) (gc->pc + 16), (void *) (&level), 4);
+    (void) memcpy((void *) (gc->pc + 20), (void *) (&layer), 4);
+    gc->pc += cmdlen;
+    if (__builtin_expect(gc->pc > gc->limit, 0)) {
+        (void) __glXFlushRenderBuffer(gc, gc->pc);
+    }
+}
+
 
 #  undef FASTCALL
 #  undef NOINLINE
diff --git a/src/glx/x11/indirect.h b/src/glx/x11/indirect.h
index 0719a1b..19a8c0d 100644
--- a/src/glx/x11/indirect.h
+++ b/src/glx/x11/indirect.h
@@ -572,6 +572,7 @@
 extern HIDDEN void __indirect_glGetQueryivARB(GLenum target, GLenum pname, GLint * params);
 extern HIDDEN GLboolean __indirect_glIsQueryARB(GLuint id);
 extern HIDDEN void __indirect_glDrawBuffersARB(GLsizei n, const GLenum * bufs);
+extern HIDDEN void __indirect_glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
 extern HIDDEN void __indirect_glSampleMaskSGIS(GLclampf value, GLboolean invert);
 extern HIDDEN void __indirect_glSamplePatternSGIS(GLenum pattern);
 extern HIDDEN void __indirect_glColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer);
@@ -710,6 +711,8 @@
 extern HIDDEN GLboolean __indirect_glIsFramebufferEXT(GLuint framebuffer);
 extern HIDDEN GLboolean __indirect_glIsRenderbufferEXT(GLuint renderbuffer);
 extern HIDDEN void __indirect_glRenderbufferStorageEXT(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+extern HIDDEN void __indirect_glBlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+extern HIDDEN void __indirect_glFramebufferTextureLayerEXT(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
 
 #  undef HIDDEN
 #  undef FASTCALL
diff --git a/src/glx/x11/indirect_init.c b/src/glx/x11/indirect_init.c
index 852fe71..73ca993 100644
--- a/src/glx/x11/indirect_init.c
+++ b/src/glx/x11/indirect_init.c
@@ -588,6 +588,10 @@
 
     glAPI->DrawBuffersARB = __indirect_glDrawBuffersARB;
 
+    /*  45. GL_ARB_framebuffer_object */
+
+    glAPI->RenderbufferStorageMultisample = __indirect_glRenderbufferStorageMultisample;
+
     /*  25. GL_SGIS_multisample */
 
     glAPI->SampleMaskSGIS = __indirect_glSampleMaskSGIS;
@@ -768,6 +772,14 @@
     glAPI->IsRenderbufferEXT = __indirect_glIsRenderbufferEXT;
     glAPI->RenderbufferStorageEXT = __indirect_glRenderbufferStorageEXT;
 
+    /* 316. GL_EXT_framebuffer_blit */
+
+    glAPI->BlitFramebufferEXT = __indirect_glBlitFramebufferEXT;
+
+    /* 329. GL_EXT_texture_array */
+
+    glAPI->FramebufferTextureLayerEXT = __indirect_glFramebufferTextureLayerEXT;
+
     return glAPI;
 }
 
diff --git a/src/glx/x11/xf86dri.h b/src/glx/x11/xf86dri.h
index f2d0dd5..ba26600 100644
--- a/src/glx/x11/xf86dri.h
+++ b/src/glx/x11/xf86dri.h
@@ -115,6 +115,10 @@
                           int *fbSize, int *fbStride, int *devPrivateSize,
                           void **pDevPrivate);
 
+Bool XF86DRIOpenFullScreen(Display * dpy, int screen, Drawable drawable);
+
+Bool XF86DRICloseFullScreen(Display * dpy, int screen, Drawable drawable);
+
 _XFUNCPROTOEND
 #endif /* _XF86DRI_SERVER_ */
 #endif /* _XF86DRI_H_ */
diff --git a/src/mesa/Makefile b/src/mesa/Makefile
index 6f58ad6..f845d93 100644
--- a/src/mesa/Makefile
+++ b/src/mesa/Makefile
@@ -18,11 +18,10 @@
 
 
 
-
-# Default: build dependencies, then asm_subdirs, then convenience
-# libs (.a) and finally the device drivers:
-default: depend asm_subdirs libmesa.a libmesagallium.a libglapi.a \
-	driver_subdirs
+# Default: build dependencies, then asm_subdirs, GLSL built-in lib,
+# then convenience libs (.a) and finally the device drivers:
+default: depend asm_subdirs glsl_builtin libmesa.a libmesagallium.a \
+	libglapi.a driver_subdirs
 
 
 
@@ -30,12 +29,12 @@
 # Helper libraries used by many drivers:
 
 # Make archive of core mesa object files
-libmesa.a: $(MESA_OBJECTS)
-	@ $(MKLIB) -o mesa -static $(MESA_OBJECTS)
+libmesa.a: $(MESA_OBJECTS) $(GLSL_LIBS)
+	@ $(MKLIB) -o mesa -static $(MESA_OBJECTS) $(GLSL_LIBS)
 
 # Make archive of subset of core mesa object files for gallium
-libmesagallium.a: $(MESA_GALLIUM_OBJECTS)
-	@ $(MKLIB) -o mesagallium -static $(MESA_GALLIUM_OBJECTS)
+libmesagallium.a: $(MESA_GALLIUM_OBJECTS) $(GLSL_LIBS)
+	@ $(MKLIB) -o mesagallium -static $(MESA_GALLIUM_OBJECTS) $(GLSL_LIBS)
 
 # Make archive of gl* API dispatcher functions only
 libglapi.a: $(GLAPI_OBJECTS)
@@ -43,7 +42,7 @@
 
 ######################################################################
 # Device drivers
-driver_subdirs: libmesa.a libglapi.a
+driver_subdirs: libmesa.a libglapi.a libmesagallium.a
 	@ (cd drivers && $(MAKE))
 
 
@@ -60,6 +59,12 @@
 
 
 ######################################################################
+# GLSL built-in library
+glsl_builtin:
+	(cd shader/slang/library && $(MAKE)) || exit 1 ;
+
+
+######################################################################
 # Dependency generation
 
 depend: $(ALL_SOURCES)
@@ -152,6 +157,7 @@
 	-rm -f depend depend.bak libmesa.a libglapi.a
 	-rm -f drivers/*/*.o
 	-rm -f *.pc
+	-rm -f shader/slang/library/*_gc.h
 	-@cd drivers/dri && $(MAKE) clean
 	-@cd drivers/x11 && $(MAKE) clean
 	-@cd drivers/osmesa && $(MAKE) clean
diff --git a/src/mesa/Makefile.mgw b/src/mesa/Makefile.mgw
index 097c390..e894c62 100644
--- a/src/mesa/Makefile.mgw
+++ b/src/mesa/Makefile.mgw
@@ -218,7 +218,6 @@
 	-$(call UNLINK,vbo/*.o)
 	-$(call UNLINK,shader/*.o)
 	-$(call UNLINK,shader/slang/*.o)
-	-$(call UNLINK,shader/grammar/*.o)
 	-$(call UNLINK,sparc/*.o)
 	-$(call UNLINK,ppc/*.o)
 	-$(call UNLINK,swrast/*.o)
diff --git a/src/mesa/SConscript b/src/mesa/SConscript
index 309e0e5..bdcfffe 100644
--- a/src/mesa/SConscript
+++ b/src/mesa/SConscript
@@ -38,6 +38,7 @@
 		'main/clear.c',
 		'main/clip.c',
 		'main/colortab.c',
+		'main/condrender.c',
 		'main/context.c',
 		'main/convolve.c',
 		'main/cpuinfo.c',
@@ -103,6 +104,7 @@
 		'main/texstate.c',
 		'main/texstore.c',
 		'main/varray.c',
+		'main/version.c',
 		'main/viewport.c',
 		'main/vtxfmt.c',
 	]
@@ -161,10 +163,10 @@
 		'state_tracker/st_cb_blit.c',
 		'state_tracker/st_cb_bufferobjects.c',
 		'state_tracker/st_cb_clear.c',
+		'state_tracker/st_cb_condrender.c',
 		'state_tracker/st_cb_flush.c',
 		'state_tracker/st_cb_drawpixels.c',
 		'state_tracker/st_cb_fbo.c',
-		'state_tracker/st_cb_get.c',
 		'state_tracker/st_cb_feedback.c',
 		'state_tracker/st_cb_program.c',
 		'state_tracker/st_cb_queryobj.c',
@@ -190,7 +192,6 @@
 		'shader/arbprogparse.c',
 		'shader/arbprogram.c',
 		'shader/atifragshader.c',
-		'shader/grammar/grammar_mesa.c',
 		'shader/hash_table.c',
 		'shader/lex.yy.c',
 		'shader/nvfragparse.c',
@@ -228,7 +229,6 @@
 		'shader/slang/slang_link.c',
 		'shader/slang/slang_log.c',
 		'shader/slang/slang_mem.c',
-		'shader/slang/slang_preprocess.c',
 		'shader/slang/slang_print.c',
 		'shader/slang/slang_simplify.c',
 		'shader/slang/slang_storage.c',
@@ -339,7 +339,9 @@
 		# Add the dir containing the generated header (somewhere inside  the
 		# build dir) to the include path  
 		env.Append(CPPPATH = [matypes[0].dir])
-	
+
+	SConscript('shader/slang/library/SConscript')
+
 	#
 	# Libraries
 	# 
diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
index e5aab02..5c5e178 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -124,7 +124,6 @@
    driver->UnmapTexture = NULL;
    driver->TextureMemCpy = _mesa_memcpy; 
    driver->IsTextureResident = NULL;
-   driver->ActiveTexture = NULL;
    driver->UpdateTexturePalette = NULL;
 
    /* imaging */
@@ -183,19 +182,6 @@
    driver->TexParameter = NULL;
    driver->Viewport = NULL;
 
-   /* vertex arrays */
-   driver->VertexPointer = NULL;
-   driver->NormalPointer = NULL;
-   driver->ColorPointer = NULL;
-   driver->FogCoordPointer = NULL;
-   driver->IndexPointer = NULL;
-   driver->SecondaryColorPointer = NULL;
-   driver->TexCoordPointer = NULL;
-   driver->EdgeFlagPointer = NULL;
-   driver->VertexAttribPointer = NULL;
-   driver->LockArraysEXT = NULL;
-   driver->UnlockArraysEXT = NULL;
-
    /* state queries */
    driver->GetBooleanv = NULL;
    driver->GetDoublev = NULL;
@@ -278,11 +264,23 @@
                                  ctx->Color.BlendDstRGB,
                                  ctx->Color.BlendSrcA, ctx->Color.BlendDstA);
 
-   ctx->Driver.ColorMask(ctx,
-                         ctx->Color.ColorMask[RCOMP],
-                         ctx->Color.ColorMask[GCOMP],
-                         ctx->Color.ColorMask[BCOMP],
-                         ctx->Color.ColorMask[ACOMP]);
+   if (ctx->Driver.ColorMaskIndexed) {
+      GLuint i;
+      for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
+         ctx->Driver.ColorMaskIndexed(ctx, i,
+                                      ctx->Color.ColorMask[0][RCOMP],
+                                      ctx->Color.ColorMask[0][GCOMP],
+                                      ctx->Color.ColorMask[0][BCOMP],
+                                      ctx->Color.ColorMask[0][ACOMP]);
+      }
+   }
+   else {
+      ctx->Driver.ColorMask(ctx,
+                            ctx->Color.ColorMask[0][RCOMP],
+                            ctx->Color.ColorMask[0][GCOMP],
+                            ctx->Color.ColorMask[0][BCOMP],
+                            ctx->Color.ColorMask[0][ACOMP]);
+   }
 
    ctx->Driver.CullFace(ctx, ctx->Polygon.CullFaceMode);
    ctx->Driver.DepthFunc(ctx, ctx->Depth.Func);
diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index a431519..e500359 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -107,11 +107,11 @@
    GLboolean AlphaEnabled;
 
    /** META_BLEND */
-   GLboolean BlendEnabled;
+   GLbitfield BlendEnabled;
    GLboolean ColorLogicOpEnabled;
 
    /** META_COLOR_MASK */
-   GLubyte ColorMask[4];
+   GLubyte ColorMask[MAX_DRAW_BUFFERS][4];
 
    /** META_DEPTH_TEST */
    struct gl_depthbuffer_attrib Depth;
@@ -335,19 +335,29 @@
 
    if (state & META_BLEND) {
       save->BlendEnabled = ctx->Color.BlendEnabled;
-      if (ctx->Color.BlendEnabled)
-         _mesa_set_enable(ctx, GL_BLEND, GL_FALSE);
+      if (ctx->Color.BlendEnabled) {
+         if (ctx->Extensions.EXT_draw_buffers2) {
+            GLuint i;
+            for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
+               _mesa_set_enablei(ctx, GL_BLEND, i, GL_FALSE);
+            }
+         }
+         else {
+            _mesa_set_enable(ctx, GL_BLEND, GL_FALSE);
+         }
+      }
       save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled;
       if (ctx->Color.ColorLogicOpEnabled)
          _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE);
    }
 
    if (state & META_COLOR_MASK) {
-      COPY_4V(save->ColorMask, ctx->Color.ColorMask);
-      if (!ctx->Color.ColorMask[0] ||
-          !ctx->Color.ColorMask[1] ||
-          !ctx->Color.ColorMask[2] ||
-          !ctx->Color.ColorMask[3])
+      memcpy(save->ColorMask, ctx->Color.ColorMask,
+             sizeof(ctx->Color.ColorMask));
+      if (!ctx->Color.ColorMask[0][0] ||
+          !ctx->Color.ColorMask[0][1] ||
+          !ctx->Color.ColorMask[0][2] ||
+          !ctx->Color.ColorMask[0][3])
          _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    }
 
@@ -500,9 +510,9 @@
       _mesa_LoadIdentity();
       _mesa_MatrixMode(GL_PROJECTION);
       _mesa_LoadIdentity();
-      _mesa_Ortho(0.0F, ctx->DrawBuffer->Width,
-                  0.0F, ctx->DrawBuffer->Height,
-                  -1.0F, 1.0F);
+      _mesa_Ortho(0.0, ctx->DrawBuffer->Width,
+                  0.0, ctx->DrawBuffer->Height,
+                  -1.0, 1.0);
       save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled;
       if (ctx->Transform.ClipPlanesEnabled) {
          GLuint i;
@@ -566,16 +576,38 @@
    }
 
    if (state & META_BLEND) {
-      if (ctx->Color.BlendEnabled != save->BlendEnabled)
-         _mesa_set_enable(ctx, GL_BLEND, save->BlendEnabled);
+      if (ctx->Color.BlendEnabled != save->BlendEnabled) {
+         if (ctx->Extensions.EXT_draw_buffers2) {
+            GLuint i;
+            for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
+               _mesa_set_enablei(ctx, GL_BLEND, i, (save->BlendEnabled >> i) & 1);
+            }
+         }
+         else {
+            _mesa_set_enable(ctx, GL_BLEND, (save->BlendEnabled & 1));
+         }
+      }
       if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled)
          _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled);
    }
 
    if (state & META_COLOR_MASK) {
-      if (!TEST_EQ_4V(ctx->Color.ColorMask, save->ColorMask))
-         _mesa_ColorMask(save->ColorMask[0], save->ColorMask[1],
-                         save->ColorMask[2], save->ColorMask[3]);
+      GLuint i;
+      for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
+         if (!TEST_EQ_4V(ctx->Color.ColorMask[i], save->ColorMask[i])) {
+            if (i == 0) {
+               _mesa_ColorMask(save->ColorMask[i][0], save->ColorMask[i][1],
+                               save->ColorMask[i][2], save->ColorMask[i][3]);
+            }
+            else {
+               _mesa_ColorMaskIndexed(i,
+                                      save->ColorMask[i][0],
+                                      save->ColorMask[i][1],
+                                      save->ColorMask[i][2],
+                                      save->ColorMask[i][3]);
+            }
+         }
+      }
    }
 
    if (state & META_DEPTH_TEST) {
@@ -2149,6 +2181,7 @@
    const GLenum wrapTSave = texObj->WrapT;
    const GLenum wrapRSave = texObj->WrapR;
    const GLuint fboSave = ctx->DrawBuffer->Name;
+   const GLuint original_active_unit = ctx->Texture.CurrentUnit;
    GLenum faceTarget;
    GLuint dstLevel;
    GLuint border = 0;
@@ -2169,6 +2202,9 @@
 
    _mesa_meta_begin(ctx, META_ALL);
 
+   if (original_active_unit != 0)
+      _mesa_BindTexture(target, texObj->Name);
+
    if (mipmap->ArrayObj == 0) {
       /* one-time setup */
 
@@ -2285,6 +2321,26 @@
 
    _mesa_set_enable(ctx, target, GL_TRUE);
 
+   /* setup vertex positions */
+   {
+      verts[0].x = 0.0F;
+      verts[0].y = 0.0F;
+      verts[1].x = 1.0F;
+      verts[1].y = 0.0F;
+      verts[2].x = 1.0F;
+      verts[2].y = 1.0F;
+      verts[3].x = 0.0F;
+      verts[3].y = 1.0F;
+      
+      /* upload new vertex data */
+      _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
+   }
+
+   /* setup projection matrix */
+   _mesa_MatrixMode(GL_PROJECTION);
+   _mesa_LoadIdentity();
+   _mesa_Ortho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
+
    /* texture is already locked, unlock now */
    _mesa_unlock_texture(ctx, texObj);
 
@@ -2351,21 +2407,6 @@
          }
       }
 
-      /* setup vertex positions */
-      {
-         verts[0].x = 0.0F;
-         verts[0].y = 0.0F;
-         verts[1].x = (GLfloat) dstWidth;
-         verts[1].y = 0.0F;
-         verts[2].x = (GLfloat) dstWidth;
-         verts[2].y = (GLfloat) dstHeight;
-         verts[3].x = 0.0F;
-         verts[3].y = (GLfloat) dstHeight;
-
-         /* upload new vertex data */
-         _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
-      }
-
       /* limit sampling to src level */
       _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, srcLevel);
       _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel);
@@ -2404,6 +2445,12 @@
          break;
       }
 
+      assert(dstWidth == ctx->DrawBuffer->Width);
+      assert(dstHeight == ctx->DrawBuffer->Height);
+
+      /* setup viewport */
+      _mesa_set_viewport(ctx, 0, 0, dstWidth, dstHeight);
+
       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
    }
 
diff --git a/src/mesa/drivers/directfb/idirectfbgl_mesa.c b/src/mesa/drivers/directfb/idirectfbgl_mesa.c
index 9359340..62a3269 100644
--- a/src/mesa/drivers/directfb/idirectfbgl_mesa.c
+++ b/src/mesa/drivers/directfb/idirectfbgl_mesa.c
@@ -407,10 +407,10 @@
 #define BUFFER_BIT_MASK (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT | \
                          BUFFER_BIT_BACK_LEFT  | BUFFER_BIT_BACK_RIGHT  )
      if (mask & BUFFER_BIT_MASK  &&
-         ctx->Color.ColorMask[0] &&
-         ctx->Color.ColorMask[1] &&
-         ctx->Color.ColorMask[2] &&
-         ctx->Color.ColorMask[3])
+         ctx->Color.ColorMask[0][0] &&
+         ctx->Color.ColorMask[0][1] &&
+         ctx->Color.ColorMask[0][2] &&
+         ctx->Color.ColorMask[0][3])
      {
           DFBRegion clip;
           GLubyte   a, r, g, b;
diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template
index 1ce9315..39d25ce 100644
--- a/src/mesa/drivers/dri/Makefile.template
+++ b/src/mesa/drivers/dri/Makefile.template
@@ -60,9 +60,13 @@
 
 ##### TARGETS #####
 
-default: symlinks subdirs depend $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME)
+default: subdirs lib
 
 
+.PHONY: lib
+lib: symlinks subdirs depend
+	@$(MAKE) $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME)
+
 $(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(EXTRA_MODULES) $(WINOBJ) Makefile \
 		$(TOP)/src/mesa/drivers/dri/Makefile.template
 	$(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index e48e10d..3649c29 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -97,7 +97,7 @@
  * 
  * \internal
  * This function calls __DriverAPIRec::UnbindContext, and then decrements
- * __DRIdrawablePrivateRec::refcount which must be non-zero for a successful
+ * __DRIdrawableRec::refcount which must be non-zero for a successful
  * return.
  * 
  * While casting the opaque private pointers associated with the parameters
@@ -167,11 +167,12 @@
 			  __DRIdrawable *pdp,
 			  __DRIdrawable *prp)
 {
-    __DRIscreenPrivate *psp = pcp->driScreenPriv;
+    __DRIscreen *psp = NULL;
 
     /* Bind the drawable to the context */
 
     if (pcp) {
+	psp = pcp->driScreenPriv;
 	pcp->driDrawablePriv = pdp;
 	pcp->driReadablePriv = prp;
 	if (pdp) {
@@ -219,7 +220,7 @@
  *
  * \param pdp pointer to the private drawable information to update.
  * 
- * This function basically updates the __DRIdrawablePrivate struct's
+ * This function basically updates the __DRIdrawable struct's
  * cliprect information by calling \c __DRIinterfaceMethods::getDrawableInfo.
  * This is usually called by the DRI_VALIDATE_DRAWABLE_INFO macro which
  * compares the __DRIdrwablePrivate pStamp and lastStamp values.  If
@@ -227,10 +228,10 @@
  * info.
  */
 void
-__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
+__driUtilUpdateDrawableInfo(__DRIdrawable *pdp)
 {
-    __DRIscreenPrivate *psp = pdp->driScreenPriv;
-    __DRIcontextPrivate *pcp = pdp->driContextPriv;
+    __DRIscreen *psp = pdp->driScreenPriv;
+    __DRIcontext *pcp = pdp->driContextPriv;
     
     if (!pcp 
 	|| ((pdp != pcp->driDrawablePriv) && (pdp != pcp->driReadablePriv))) {
@@ -308,7 +309,7 @@
  * \param drawablePrivate opaque pointer to the per-drawable private info.
  * 
  * \internal
- * This function calls __DRIdrawablePrivate::swapBuffers.
+ * This function calls __DRIdrawable::swapBuffers.
  * 
  * Is called directly from glXSwapBuffers().
  */
@@ -453,6 +454,7 @@
 
     pdp->driScreenPriv = psp;
     pdp->driContextPriv = &psp->dummyContextPriv;
+    pdp->validBuffers = GL_FALSE;
 
     if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes,
 					renderType == GLX_PIXMAP_BIT)) {
@@ -496,13 +498,13 @@
 	
 static void dri_put_drawable(__DRIdrawable *pdp)
 {
-    __DRIscreenPrivate *psp;
-
-    pdp->refcount--;
-    if (pdp->refcount)
-	return;
+    __DRIscreen *psp;
 
     if (pdp) {
+	pdp->refcount--;
+	if (pdp->refcount)
+	    return;
+
 	psp = pdp->driScreenPriv;
         (*psp->DriverAPI.DestroyBuffer)(pdp);
 	if (pdp->pClipRects) {
@@ -559,7 +561,7 @@
  *          success, or \c NULL on failure.
  * 
  * \internal
- * This function allocates and fills a __DRIcontextPrivateRec structure.  It
+ * This function allocates and fills a __DRIcontextRec structure.  It
  * performs some device independent initialization and passes all the
  * relevent information to __DriverAPIRec::CreateContext to create the
  * context.
@@ -840,7 +842,7 @@
     driCreateNewContext,
 };
 
-/** Legacy DRI interface */
+/** DRI2 interface */
 const __DRIdri2Extension driDRI2Extension = {
     { __DRI_DRI2, __DRI_DRI2_VERSION },
     dri2CreateNewScreen,
@@ -848,14 +850,6 @@
     dri2CreateNewContext,
 };
 
-/* This is the table of extensions that the loader will dlsym() for. */
-PUBLIC const __DRIextension *__driDriverExtensions[] = {
-    &driCoreExtension.base,
-    &driLegacyExtension.base,
-    &driDRI2Extension.base,
-    NULL
-};
-
 static int
 driFrameTracking(__DRIdrawable *drawable, GLboolean enable)
 {
@@ -870,7 +864,7 @@
    __DRIswapInfo   sInfo;
    int             status;
    int64_t         ust;
-   __DRIscreenPrivate *psp = dpriv->driScreenPriv;
+   __DRIscreen *psp = dpriv->driScreenPriv;
 
    status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo );
    if ( status == 0 ) {
@@ -920,14 +914,14 @@
  *       be possible to cache the sync rate?
  */
 float
-driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust,
+driCalculateSwapUsage( __DRIdrawable *dPriv, int64_t last_swap_ust,
 		       int64_t current_ust )
 {
    int32_t   n;
    int32_t   d;
    int       interval;
    float     usage = 1.0;
-   __DRIscreenPrivate *psp = dPriv->driScreenPriv;
+   __DRIscreen *psp = dPriv->driScreenPriv;
 
    if ( (*psp->systemTime->getMSCRate)(dPriv, &n, &d, dPriv->loaderPrivate) ) {
       interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1;
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index c95a5c8..95df702 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -59,16 +59,12 @@
 
 typedef struct __DRIswapInfoRec        __DRIswapInfo;
 
-/* Typedefs to avoid rewriting the world. */
-typedef struct __DRIscreenRec	__DRIscreenPrivate;
-typedef struct __DRIdrawableRec	__DRIdrawablePrivate;
-typedef struct __DRIcontextRec	__DRIcontextPrivate;
-
 /**
  * Extensions.
  */
 extern const __DRIlegacyExtension driLegacyExtension;
 extern const __DRIcoreExtension driCoreExtension;
+extern const __DRIdri2Extension driDRI2Extension;
 extern const __DRIextension driReadDrawableExtension;
 extern const __DRIcopySubBufferExtension driCopySubBufferExtension;
 extern const __DRIswapControlExtension driSwapControlExtension;
@@ -380,6 +376,8 @@
      * GLX_MESA_swap_control.
      */
     unsigned int swap_interval;
+
+    GLboolean validBuffers;
 };
 
 /**
diff --git a/src/mesa/drivers/dri/common/drirenderbuffer.c b/src/mesa/drivers/dri/common/drirenderbuffer.c
index 4e7e92c..3126ea8 100644
--- a/src/mesa/drivers/dri/common/drirenderbuffer.c
+++ b/src/mesa/drivers/dri/common/drirenderbuffer.c
@@ -56,7 +56,7 @@
 driRenderbuffer *
 driNewRenderbuffer(gl_format format, GLvoid *addr,
                    GLint cpp, GLint offset, GLint pitch,
-                   __DRIdrawablePrivate *dPriv)
+                   __DRIdrawable *dPriv)
 {
    driRenderbuffer *drb;
 
@@ -196,7 +196,7 @@
  * gl_framebuffer object.
  */
 void
-driUpdateFramebufferSize(GLcontext *ctx, const __DRIdrawablePrivate *dPriv)
+driUpdateFramebufferSize(GLcontext *ctx, const __DRIdrawable *dPriv)
 {
    struct gl_framebuffer *fb = (struct gl_framebuffer *) dPriv->driverPrivate;
    if (fb && (dPriv->w != fb->Width || dPriv->h != fb->Height)) {
diff --git a/src/mesa/drivers/dri/common/drirenderbuffer.h b/src/mesa/drivers/dri/common/drirenderbuffer.h
index 3a5cbcd..6775113 100644
--- a/src/mesa/drivers/dri/common/drirenderbuffer.h
+++ b/src/mesa/drivers/dri/common/drirenderbuffer.h
@@ -43,10 +43,10 @@
    GLint flippedPitch;
    GLvoid *flippedData;  /* mmap'd address of buffer memory, if used */
 
-   /* Pointer to corresponding __DRIdrawablePrivate.  This is used to compute
+   /* Pointer to corresponding __DRIdrawable.  This is used to compute
     * the window's position within the framebuffer.
     */
-   __DRIdrawablePrivate *dPriv;
+   __DRIdrawable *dPriv;
 
    /* XXX this is for radeon/r200 only.  We should really create a new
     * r200Renderbuffer class, derived from this class...  not a huge deal.
@@ -66,14 +66,14 @@
 extern driRenderbuffer *
 driNewRenderbuffer(gl_format format, GLvoid *addr,
                    GLint cpp, GLint offset, GLint pitch,
-                   __DRIdrawablePrivate *dPriv);
+                   __DRIdrawable *dPriv);
 
 extern void
 driFlipRenderbuffers(struct gl_framebuffer *fb, GLboolean flipped);
 
 
 extern void
-driUpdateFramebufferSize(GLcontext *ctx, const __DRIdrawablePrivate *dPriv);
+driUpdateFramebufferSize(GLcontext *ctx, const __DRIdrawable *dPriv);
 
 
 #endif /* DRIRENDERBUFFER_H */
diff --git a/src/mesa/drivers/dri/common/spantmp2.h b/src/mesa/drivers/dri/common/spantmp2.h
index 89c8157..447f3d1 100644
--- a/src/mesa/drivers/dri/common/spantmp2.h
+++ b/src/mesa/drivers/dri/common/spantmp2.h
@@ -82,6 +82,72 @@
       rgba[3] = 0xff;							\
    } while (0)
 
+#elif (SPANTMP_PIXEL_FMT == GL_RGB)  && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_5_6_5_REV)
+
+/**
+ ** GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV
+ **/
+
+#ifndef GET_VALUE
+#ifndef GET_PTR
+#define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch)
+#endif
+
+#define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y))
+#define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v)
+#endif /* GET_VALUE */
+
+#define INIT_MONO_PIXEL(p, color) \
+  p = PACK_COLOR_565_REV( color[0], color[1], color[2] )
+
+#define WRITE_RGBA( _x, _y, r, g, b, a )				\
+   PUT_VALUE(_x, _y, PACK_COLOR_565_REV( r, g, b ))
+
+#define WRITE_PIXEL( _x, _y, p ) PUT_VALUE(_x, _y, p)
+
+#define READ_RGBA( rgba, _x, _y )					\
+   do {									\
+      GLushort p = GET_VALUE(_x, _y);					\
+      p = p << 8 | p >> 8;						\
+      rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8;				\
+      rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc;				\
+      rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8;				\
+      rgba[3] = 0xff;							\
+   } while (0)
+
+#elif (SPANTMP_PIXEL_FMT == GL_BGRA)  && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_4_4_4_4)
+
+/**
+ ** GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4
+ **/
+
+#ifndef GET_VALUE
+#ifndef GET_PTR
+#define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch)
+#endif
+
+#define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y))
+#define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v)
+#endif /* GET_VALUE */
+
+#define INIT_MONO_PIXEL(p, color) \
+   p = PACK_COLOR_4444_REV(color[3], color[0], color[1], color[2])
+
+#define WRITE_RGBA( _x, _y, r, g, b, a )				\
+   PUT_VALUE(_x, _y, PACK_COLOR_4444_REV(a, r, g, b))			\
+
+#define WRITE_PIXEL( _x, _y, p ) PUT_VALUE(_x, _y, p)
+
+#define READ_RGBA( rgba, _x, _y )					\
+   do {									\
+      GLushort p = GET_VALUE(_x, _y);					\
+      rgba[0] = ((p >> 0) & 0xf) * 0x11;				\
+      rgba[1] = ((p >> 12) & 0xf) * 0x11;				\
+      rgba[2] = ((p >> 4) & 0xf) * 0x11;				\
+      rgba[3] = ((p >> 8) & 0xf) * 0x11;				\
+   } while (0)
+
+
 #elif (SPANTMP_PIXEL_FMT == GL_BGRA)  && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_4_4_4_4_REV)
 
 /**
@@ -147,6 +213,39 @@
       rgba[3] = ((p >> 15) & 0x1) * 0xff;				\
    } while (0)
 
+#elif (SPANTMP_PIXEL_FMT == GL_BGRA)  && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_1_5_5_5)
+
+/**
+ ** GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5
+ **/
+
+#ifndef GET_VALUE
+#ifndef GET_PTR
+#define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch)
+#endif
+
+#define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y))
+#define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v)
+#endif /* GET_VALUE */
+
+#define INIT_MONO_PIXEL(p, color) \
+   p = PACK_COLOR_1555_REV(color[3], color[0], color[1], color[2])
+
+#define WRITE_RGBA( _x, _y, r, g, b, a )				\
+   PUT_VALUE(_x, _y, PACK_COLOR_1555_REV(a, r, g, b))			\
+
+#define WRITE_PIXEL( _x, _y, p ) PUT_VALUE(_x, _y, p)
+
+#define READ_RGBA( rgba, _x, _y )					\
+   do {									\
+      GLushort p = GET_VALUE(_x, _y);					\
+      p = p << 8 | p >> 8;						\
+      rgba[0] = ((p >> 7) & 0xf8) * 255 / 0xf8;				\
+      rgba[1] = ((p >> 2) & 0xf8) * 255 / 0xf8;				\
+      rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8;				\
+      rgba[3] = ((p >> 15) & 0x1) * 0xff;				\
+   } while (0)
+
 #elif (SPANTMP_PIXEL_FMT == GL_BGRA) && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV)
 
 /**
@@ -202,6 +301,118 @@
      } while (0)
 # endif
 
+#elif (SPANTMP_PIXEL_FMT == GL_BGRA) && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8)
+
+/**
+ ** GL_BGRA, GL_UNSIGNED_INT_8_8_8_8
+ **/
+
+#ifndef GET_VALUE
+#ifndef GET_PTR
+#define GET_PTR(_x, _y) (     buf + (_x) * 4 + (_y) * pitch)
+#endif
+
+#define GET_VALUE(_x, _y) *(volatile GLuint *)(GET_PTR(_x, _y))
+#define PUT_VALUE(_x, _y, _v) *(volatile GLuint *)(GET_PTR(_x, _y)) = (_v)
+#endif /* GET_VALUE */
+
+# define INIT_MONO_PIXEL(p, color)                       \
+     p = PACK_COLOR_8888(color[2], color[1], color[0], color[3]) 
+
+# define WRITE_RGBA(_x, _y, r, g, b, a)                                 \
+   PUT_VALUE(_x, _y, ((r << 8) |					\
+		      (g << 16) |					\
+		      (b << 24) |					\
+		      (a << 0)))
+
+#define WRITE_PIXEL(_x, _y, p) PUT_VALUE(_x, _y, p)
+
+# if defined( USE_X86_ASM )
+#  define READ_RGBA(rgba, _x, _y)                                       \
+    do {                                                                \
+       GLuint p = GET_VALUE(_x, _y);					\
+       __asm__ __volatile__( "rorl $8, %0"				\
+				: "=r" (p) : "0" (p) );                 \
+       ((GLuint *)rgba)[0] = p;                                         \
+    } while (0)
+# elif defined( MESA_BIG_ENDIAN )
+    /* On PowerPC with GCC 3.4.2 the shift madness below becomes a single
+     * rotlwi instruction.  It also produces good code on SPARC.
+     */
+#  define READ_RGBA( rgba, _x, _y )				        \
+     do {								\
+        GLuint p = CPU_TO_LE32(GET_VALUE(_x, _y));                      \
+        GLuint t = p;                                                   \
+        *((uint32_t *) rgba) = (t >> 24) | (p << 8);                    \
+     } while (0)
+# else
+#  define READ_RGBA( rgba, _x, _y )				        \
+     do {								\
+        GLuint p = GET_VALUE(_x, _y);					\
+	rgba[0] = (p >>  8) & 0xff;					\
+	rgba[1] = (p >> 16) & 0xff;					\
+	rgba[2] = (p >> 24) & 0xff;					\
+	rgba[3] = (p >>  0) & 0xff;					\
+     } while (0)
+# endif
+
+#elif (SPANTMP_PIXEL_FMT == GL_BGR) && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV)
+
+/**
+ ** GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV
+ **
+ ** This is really for MESA_FORMAT_XRGB8888.  The spantmp code needs to be
+ ** kicked to the curb, and we need to just code-gen this.
+ **/
+
+#ifndef GET_VALUE
+#ifndef GET_PTR
+#define GET_PTR(_x, _y) (     buf + (_x) * 4 + (_y) * pitch)
+#endif
+
+#define GET_VALUE(_x, _y) *(volatile GLuint *)(GET_PTR(_x, _y))
+#define PUT_VALUE(_x, _y, _v) *(volatile GLuint *)(GET_PTR(_x, _y)) = (_v)
+#endif /* GET_VALUE */
+
+# define INIT_MONO_PIXEL(p, color)                       \
+     p = PACK_COLOR_8888(0xff, color[0], color[1], color[2])
+
+# define WRITE_RGBA(_x, _y, r, g, b, a)					\
+   PUT_VALUE(_x, _y, ((r << 16) |					\
+		      (g << 8) |					\
+		      (b << 0) |					\
+		      (0xff << 24)))
+
+#define WRITE_PIXEL(_x, _y, p) PUT_VALUE(_x, _y, p)
+
+# if defined( USE_X86_ASM )
+#  define READ_RGBA(rgba, _x, _y)                                       \
+    do {                                                                \
+       GLuint p = GET_VALUE(_x, _y);					\
+       __asm__ __volatile__( "bswap	%0; rorl $8, %0"                \
+				: "=r" (p) : "0" (p) );                 \
+       ((GLuint *)rgba)[0] = p | 0xff000000;				\
+    } while (0)
+# elif defined( MESA_BIG_ENDIAN )
+    /* On PowerPC with GCC 3.4.2 the shift madness below becomes a single
+     * rotlwi instruction.  It also produces good code on SPARC.
+     */
+#  define READ_RGBA( rgba, _x, _y )				        \
+     do {								\
+        GLuint p = GET_VALUE(_x, _y);					\
+        *((uint32_t *) rgba) = (t << 8) | 0xff;				\
+     } while (0)
+# else
+#  define READ_RGBA( rgba, _x, _y )				        \
+     do {								\
+        GLuint p = GET_VALUE(_x, _y);					\
+	rgba[0] = (p >> 16) & 0xff;					\
+	rgba[1] = (p >>  8) & 0xff;					\
+	rgba[2] = (p >>  0) & 0xff;					\
+	rgba[3] = 0xff;							\
+     } while (0)
+# endif
+
 #else
 #error SPANTMP_PIXEL_FMT must be set to a valid value!
 #endif
diff --git a/src/mesa/drivers/dri/common/vblank.c b/src/mesa/drivers/dri/common/vblank.c
index 12aeaa1..49b22a2 100644
--- a/src/mesa/drivers/dri/common/vblank.c
+++ b/src/mesa/drivers/dri/common/vblank.c
@@ -34,12 +34,12 @@
 #include "vblank.h"
 #include "xmlpool.h"
 
-static unsigned int msc_to_vblank(__DRIdrawablePrivate * dPriv, int64_t msc)
+static unsigned int msc_to_vblank(__DRIdrawable * dPriv, int64_t msc)
 {
    return (unsigned int)(msc - dPriv->msc_base + dPriv->vblank_base);
 }
 
-static int64_t vblank_to_msc(__DRIdrawablePrivate * dPriv, unsigned int vblank)
+static int64_t vblank_to_msc(__DRIdrawable * dPriv, unsigned int vblank)
 {
    return (int64_t)(vblank - dPriv->vblank_base + dPriv->msc_base);
 }
@@ -64,8 +64,8 @@
  * \return       Zero is returned on success.  A negative errno value
  *               is returned on failure.
  */
-int driDrawableGetMSC32( __DRIscreenPrivate * priv,
-			 __DRIdrawablePrivate * dPriv,
+int driDrawableGetMSC32( __DRIscreen * priv,
+			 __DRIdrawable * dPriv,
 			 int64_t * count)
 {
    drmVBlank vbl;
@@ -122,7 +122,7 @@
  * \return            Zero on success or \c GLX_BAD_CONTEXT on failure.
  */
 
-int driWaitForMSC32( __DRIdrawablePrivate *priv,
+int driWaitForMSC32( __DRIdrawable *priv,
 		     int64_t target_msc, int64_t divisor, int64_t remainder,
 		     int64_t * msc )
 {
@@ -278,7 +278,7 @@
  */
 
 static unsigned
-driGetDefaultVBlankInterval( const  __DRIdrawablePrivate *priv )
+driGetDefaultVBlankInterval( const  __DRIdrawable *priv )
 {
    if ( (priv->vblFlags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) {
       return 1;
@@ -295,7 +295,7 @@
  * direct rendering context.
  */
 
-void driDrawableInitVBlank( __DRIdrawablePrivate *priv )
+void driDrawableInitVBlank( __DRIdrawable *priv )
 {
    if ( priv->swap_interval == (unsigned)-1 &&
 	!( priv->vblFlags & VBLANK_FLAG_NO_IRQ ) ) {
@@ -320,7 +320,7 @@
  */
 
 unsigned
-driGetVBlankInterval( const  __DRIdrawablePrivate *priv )
+driGetVBlankInterval( const  __DRIdrawable *priv )
 {
    if ( (priv->vblFlags & VBLANK_FLAG_INTERVAL) != 0 ) {
       /* this must have been initialized when the drawable was first bound
@@ -340,7 +340,7 @@
  */
 
 void
-driGetCurrentVBlank( __DRIdrawablePrivate *priv )
+driGetCurrentVBlank( __DRIdrawable *priv )
 {
    drmVBlank vbl;
 
@@ -366,7 +366,7 @@
  */
 
 int
-driWaitForVBlank( __DRIdrawablePrivate *priv, GLboolean * missed_deadline )
+driWaitForVBlank( __DRIdrawable *priv, GLboolean * missed_deadline )
 {
    drmVBlank vbl;
    unsigned   original_seq;
diff --git a/src/mesa/drivers/dri/common/vblank.h b/src/mesa/drivers/dri/common/vblank.h
index 8b2c761..29d1ad8 100644
--- a/src/mesa/drivers/dri/common/vblank.h
+++ b/src/mesa/drivers/dri/common/vblank.h
@@ -44,17 +44,17 @@
 #define VBLANK_FLAG_SECONDARY (1U << 8)  /* Wait for secondary vblank.
 					  */
 
-extern int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count );
-extern int driDrawableGetMSC32( __DRIscreenPrivate * priv,
-				__DRIdrawablePrivate * drawablePrivate,
+extern int driGetMSC32( __DRIscreen * priv, int64_t * count );
+extern int driDrawableGetMSC32( __DRIscreen * priv,
+				__DRIdrawable * drawablePrivate,
 				int64_t * count);
-extern int driWaitForMSC32( __DRIdrawablePrivate *priv,
+extern int driWaitForMSC32( __DRIdrawable *priv,
     int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc );
 extern GLuint driGetDefaultVBlankFlags( const driOptionCache *optionCache );
-extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv );
-extern unsigned driGetVBlankInterval( const  __DRIdrawablePrivate *priv );
-extern void driGetCurrentVBlank( __DRIdrawablePrivate *priv );
-extern int driWaitForVBlank( __DRIdrawablePrivate *priv,
+extern void driDrawableInitVBlank ( __DRIdrawable *priv );
+extern unsigned driGetVBlankInterval( const  __DRIdrawable *priv );
+extern void driGetCurrentVBlank( __DRIdrawable *priv );
+extern int driWaitForVBlank( __DRIdrawable *priv,
 			     GLboolean * missed_deadline );
 
 #undef usleep
diff --git a/src/mesa/drivers/dri/fb/fb_dri.c b/src/mesa/drivers/dri/fb/fb_dri.c
index fd869b2..f37241d 100644
--- a/src/mesa/drivers/dri/fb/fb_dri.c
+++ b/src/mesa/drivers/dri/fb/fb_dri.c
@@ -64,9 +64,9 @@
    GLcontext *glCtx;		/* Mesa context */
 
    struct {
-      __DRIcontextPrivate *context;	
-      __DRIscreenPrivate *screen;	
-      __DRIdrawablePrivate *drawable; /* drawable bound to this ctx */
+      __DRIcontext *context;	
+      __DRIscreen *screen;	
+      __DRIdrawable *drawable; /* drawable bound to this ctx */
    } dri;
    
 } fbContext, *fbContextPtr;
@@ -313,14 +313,14 @@
 /* Initialize the driver specific screen private data.
  */
 static GLboolean
-fbInitDriver( __DRIscreenPrivate *sPriv )
+fbInitDriver( __DRIscreen *sPriv )
 {
    sPriv->private = NULL;
    return GL_TRUE;
 }
 
 static void
-fbDestroyScreen( __DRIscreenPrivate *sPriv )
+fbDestroyScreen( __DRIscreen *sPriv )
 {
 }
 
@@ -329,7 +329,7 @@
  */
 static GLboolean
 fbCreateContext( const __GLcontextModes *glVisual,
-		 __DRIcontextPrivate *driContextPriv,
+		 __DRIcontext *driContextPriv,
 		 void *sharedContextPrivate)
 {
    fbContextPtr fbmesa;
@@ -384,7 +384,7 @@
 
 
 static void
-fbDestroyContext( __DRIcontextPrivate *driContextPriv )
+fbDestroyContext( __DRIcontext *driContextPriv )
 {
    GET_CURRENT_CONTEXT(ctx);
    fbContextPtr fbmesa = (fbContextPtr) driContextPriv->driverPrivate;
@@ -415,8 +415,8 @@
  * data.
  */
 static GLboolean
-fbCreateBuffer( __DRIscreenPrivate *driScrnPriv,
-		__DRIdrawablePrivate *driDrawPriv,
+fbCreateBuffer( __DRIscreen *driScrnPriv,
+		__DRIdrawable *driDrawPriv,
 		const __GLcontextModes *mesaVis,
 		GLboolean isPixmap )
 {
@@ -478,7 +478,7 @@
 
 
 static void
-fbDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+fbDestroyBuffer(__DRIdrawable *driDrawPriv)
 {
    _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
 }
@@ -488,7 +488,7 @@
 /* If the backbuffer is on a videocard, this is extraordinarily slow!
  */
 static void
-fbSwapBuffers( __DRIdrawablePrivate *dPriv )
+fbSwapBuffers( __DRIdrawable *dPriv )
 {
    struct gl_framebuffer *mesa_framebuffer = (struct gl_framebuffer *)dPriv->driverPrivate;
    struct gl_renderbuffer * front_renderbuffer = mesa_framebuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
@@ -532,9 +532,9 @@
  * buffer `b'.
  */
 static GLboolean
-fbMakeCurrent( __DRIcontextPrivate *driContextPriv,
-	       __DRIdrawablePrivate *driDrawPriv,
-	       __DRIdrawablePrivate *driReadPriv )
+fbMakeCurrent( __DRIcontext *driContextPriv,
+	       __DRIdrawable *driDrawPriv,
+	       __DRIdrawable *driReadPriv )
 {
    if ( driContextPriv ) {
       fbContextPtr newFbCtx = 
@@ -556,7 +556,7 @@
 /* Force the context `c' to be unbound from its buffer.
  */
 static GLboolean
-fbUnbindContext( __DRIcontextPrivate *driContextPriv )
+fbUnbindContext( __DRIcontext *driContextPriv )
 {
    return GL_TRUE;
 }
@@ -657,7 +657,7 @@
 };
 
 static __GLcontextModes *
-fbFillInModes( __DRIscreenPrivate *psp,
+fbFillInModes( __DRIscreen *psp,
 	       unsigned pixel_bits, unsigned depth_bits,
 	       unsigned stencil_bits, GLboolean have_back_buffer )
 {
@@ -745,7 +745,7 @@
  * with the \c __GLcontextModes that the driver can support for windows or
  * pbuffers.
  * 
- * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on 
+ * \return A pointer to a \c __DRIscreen on success, or \c NULL on 
  *         failure.
  */
 PUBLIC
@@ -759,7 +759,7 @@
                                    int internal_api_version,
                                    __GLcontextModes ** driver_modes )
 {
-   __DRIscreenPrivate *psp;
+   __DRIscreen *psp;
    static const __DRIversion ddx_expected = { 4, 0, 0 };
    static const __DRIversion dri_expected = { 4, 0, 0 };
    static const __DRIversion drm_expected = { 1, 5, 0 };
@@ -785,3 +785,10 @@
 
           return (void *) psp;
 }
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driLegacyExtension.base,
+    NULL
+};
diff --git a/src/mesa/drivers/dri/fb/fb_egl.c b/src/mesa/drivers/dri/fb/fb_egl.c
index eb7adf8..02e44bb 100644
--- a/src/mesa/drivers/dri/fb/fb_egl.c
+++ b/src/mesa/drivers/dri/fb/fb_egl.c
@@ -84,9 +84,9 @@
    _EGLContext Base;  /* base class/object */
    GLcontext *glCtx;
    struct {
-      __DRIcontextPrivate *context;	
-      __DRIscreenPrivate *screen;	
-      __DRIdrawablePrivate *drawable; /* drawable bound to this ctx */
+      __DRIcontext *context;	
+      __DRIscreen *screen;	
+      __DRIdrawable *drawable; /* drawable bound to this ctx */
    } dri;
 } fbContext, *fbContextPtr;
 
diff --git a/src/mesa/drivers/dri/ffb/ffb_bitmap.c b/src/mesa/drivers/dri/ffb/ffb_bitmap.c
index f89c041..611afdd 100644
--- a/src/mesa/drivers/dri/ffb/ffb_bitmap.c
+++ b/src/mesa/drivers/dri/ffb/ffb_bitmap.c
@@ -46,7 +46,7 @@
 {
 	ffbContextPtr fmesa = FFB_CONTEXT(ctx);
 	ffb_fbcPtr ffb = fmesa->regs;
-	__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
+	__DRIdrawable *dPriv = fmesa->driDrawable;
 	unsigned int ppc, pixel;
 	GLint row, col, row_stride;
 	const GLubyte *src;
diff --git a/src/mesa/drivers/dri/ffb/ffb_clear.c b/src/mesa/drivers/dri/ffb/ffb_clear.c
index 776fb48..dfe60f3 100644
--- a/src/mesa/drivers/dri/ffb/ffb_clear.c
+++ b/src/mesa/drivers/dri/ffb/ffb_clear.c
@@ -123,7 +123,7 @@
 }
 
 static void
-ffb_do_clear(GLcontext *ctx, __DRIdrawablePrivate *dPriv)
+ffb_do_clear(GLcontext *ctx, __DRIdrawable *dPriv)
 {
 	ffbContextPtr fmesa = FFB_CONTEXT(ctx);
 	FFBDRIPtr gDRIPriv = (FFBDRIPtr) fmesa->driScreen->pDevPriv;
@@ -252,7 +252,7 @@
 void ffbDDClear(GLcontext *ctx, GLbitfield mask)
 {
 	ffbContextPtr fmesa = FFB_CONTEXT(ctx);
-	__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
+	__DRIdrawable *dPriv = fmesa->driDrawable;
 	unsigned int stcmask = BUFFER_BIT_STENCIL;
 
 #ifdef CLEAR_TRACE
diff --git a/src/mesa/drivers/dri/ffb/ffb_context.h b/src/mesa/drivers/dri/ffb/ffb_context.h
index 77f87d4..4d1d53f 100644
--- a/src/mesa/drivers/dri/ffb/ffb_context.h
+++ b/src/mesa/drivers/dri/ffb/ffb_context.h
@@ -273,8 +273,8 @@
 	unsigned int		setupnewinputs;
 	unsigned int		new_gl_state;
 
-	__DRIdrawablePrivate	*driDrawable;
-	__DRIscreenPrivate	*driScreen;
+	__DRIdrawable	*driDrawable;
+	__DRIscreen	*driScreen;
 	ffbScreenPrivate	*ffbScreen;
 	ffb_dri_state_t		*ffb_sarea;
 } ffbContextRec, *ffbContextPtr;
diff --git a/src/mesa/drivers/dri/ffb/ffb_depth.c b/src/mesa/drivers/dri/ffb/ffb_depth.c
index 71f204d..5d509ff 100644
--- a/src/mesa/drivers/dri/ffb/ffb_depth.c
+++ b/src/mesa/drivers/dri/ffb/ffb_depth.c
@@ -49,7 +49,7 @@
 #endif
 	if (ctx->Depth.Mask) {
 		ffbContextPtr fmesa = FFB_CONTEXT(ctx);
-		__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
+		__DRIdrawable *dPriv = fmesa->driDrawable;
 		GLuint *zptr;
 		GLuint i;
 
@@ -110,7 +110,7 @@
 #endif
 	if (ctx->Depth.Mask) {
 		ffbContextPtr fmesa = FFB_CONTEXT(ctx);
-		__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
+		__DRIdrawable *dPriv = fmesa->driDrawable;
 		char *zbase;
 		GLuint i;
 
@@ -153,7 +153,7 @@
 {
         GLuint *depth = (GLuint *) values;
 	ffbContextPtr fmesa = FFB_CONTEXT(ctx);
-	__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
+	__DRIdrawable *dPriv = fmesa->driDrawable;
 	GLuint *zptr;
 	GLuint i;
 
@@ -194,7 +194,7 @@
 {
         GLuint *depth = (GLuint *) values;
 	ffbContextPtr fmesa = FFB_CONTEXT(ctx);
-	__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
+	__DRIdrawable *dPriv = fmesa->driDrawable;
 	char *zbase;
 	GLuint i;
 
diff --git a/src/mesa/drivers/dri/ffb/ffb_span.c b/src/mesa/drivers/dri/ffb/ffb_span.c
index 0d3d604..8ec33a1 100644
--- a/src/mesa/drivers/dri/ffb/ffb_span.c
+++ b/src/mesa/drivers/dri/ffb/ffb_span.c
@@ -45,7 +45,7 @@
 		UNLOCK_HARDWARE(fmesa); \
 
 #define LOCAL_VARS						\
-	__DRIdrawablePrivate *dPriv = fmesa->driDrawable;	\
+	__DRIdrawable *dPriv = fmesa->driDrawable;	\
 	GLuint height = dPriv->h;				\
         GLuint p;						\
 	char *buf; 						\
diff --git a/src/mesa/drivers/dri/ffb/ffb_state.c b/src/mesa/drivers/dri/ffb/ffb_state.c
index 5eb8f41..6f8a46d 100644
--- a/src/mesa/drivers/dri/ffb/ffb_state.c
+++ b/src/mesa/drivers/dri/ffb/ffb_state.c
@@ -384,7 +384,7 @@
 static void ffbCalcViewportRegs(GLcontext *ctx)
 {
 	ffbContextPtr fmesa = FFB_CONTEXT(ctx);
-	__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
+	__DRIdrawable *dPriv = fmesa->driDrawable;
 	GLuint xmin, xmax, ymin, ymax, zmin, zmax;
 	unsigned int vcmin, vcmax;
 
@@ -430,7 +430,7 @@
 	ffbContextPtr fmesa = FFB_CONTEXT(ctx);
 	const GLfloat *v = ctx->Viewport._WindowMap.m;
 	GLfloat *m = fmesa->hw_viewport;
-	__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
+	__DRIdrawable *dPriv = fmesa->driDrawable;
 
 	m[MAT_SX] =   v[MAT_SX];
 	m[MAT_TX] =   v[MAT_TX] + dPriv->x + SUBPIXEL_X;
@@ -762,7 +762,7 @@
 
 void ffbXformAreaPattern(ffbContextPtr fmesa, const GLubyte *mask)
 {
-	__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
+	__DRIdrawable *dPriv = fmesa->driDrawable;
 	int i, lines, xoff;
 
 	lines = 0;
diff --git a/src/mesa/drivers/dri/ffb/ffb_stencil.c b/src/mesa/drivers/dri/ffb/ffb_stencil.c
index 921a83d..ce8ef43 100644
--- a/src/mesa/drivers/dri/ffb/ffb_stencil.c
+++ b/src/mesa/drivers/dri/ffb/ffb_stencil.c
@@ -48,7 +48,7 @@
 #endif
 	if (ctx->Depth.Mask) {
 		ffbContextPtr fmesa = FFB_CONTEXT(ctx);
-		__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
+		__DRIdrawable *dPriv = fmesa->driDrawable;
 		GLuint *zptr;
 		GLuint i;
 
@@ -93,7 +93,7 @@
 #endif
 	if (ctx->Depth.Mask) {
 		ffbContextPtr fmesa = FFB_CONTEXT(ctx);
-		__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
+		__DRIdrawable *dPriv = fmesa->driDrawable;
 		char *zbase;
 		GLuint i;
 
@@ -136,7 +136,7 @@
 {
         GLubyte *stencil = (GLubyte *) values;
 	ffbContextPtr fmesa = FFB_CONTEXT(ctx);
-	__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
+	__DRIdrawable *dPriv = fmesa->driDrawable;
 	GLuint *zptr;
 	GLuint i;
 
@@ -176,7 +176,7 @@
 {
         GLubyte *stencil = (GLubyte *) values;
 	ffbContextPtr fmesa = FFB_CONTEXT(ctx);
-	__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
+	__DRIdrawable *dPriv = fmesa->driDrawable;
 	char *zbase;
 	GLuint i;
 
diff --git a/src/mesa/drivers/dri/ffb/ffb_tris.c b/src/mesa/drivers/dri/ffb/ffb_tris.c
index d785c15..8bf5ae4 100644
--- a/src/mesa/drivers/dri/ffb/ffb_tris.c
+++ b/src/mesa/drivers/dri/ffb/ffb_tris.c
@@ -351,8 +351,8 @@
 
 #define LOCAL_VARS(n)				\
    ffbContextPtr fmesa = FFB_CONTEXT(ctx);	\
-   __DRIdrawablePrivate *dPriv = fmesa->driDrawable; \
-   ffb_color color[n];				\
+   __DRIdrawable *dPriv = fmesa->driDrawable; \
+   ffb_color color[n] = { { 0 } };		\
    (void) color; (void) dPriv;
 
 /***********************************************************************
diff --git a/src/mesa/drivers/dri/ffb/ffb_vbtmp.h b/src/mesa/drivers/dri/ffb/ffb_vbtmp.h
index 0495d0e..c548ef3 100644
--- a/src/mesa/drivers/dri/ffb/ffb_vbtmp.h
+++ b/src/mesa/drivers/dri/ffb/ffb_vbtmp.h
@@ -38,11 +38,11 @@
 #endif
 
 #if (IND & (FFB_VB_RGBA_BIT))
-	col0 = VB->ColorPtr[0]->data;
-	col0_stride = VB->ColorPtr[0]->stride;
+	col0 = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;
+	col0_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride;
 #if (IND & (FFB_VB_TWOSIDE_BIT))
-	col1 = VB->ColorPtr[1]->data;
-	col1_stride = VB->ColorPtr[1]->stride;
+	col1 = VB->BackfaceColorPtr->data;
+	col1_stride = VB->BackfaceColorPtr->stride;
 #endif
 #endif
 
diff --git a/src/mesa/drivers/dri/ffb/ffb_xmesa.c b/src/mesa/drivers/dri/ffb/ffb_xmesa.c
index 09cc26d..88285f4 100644
--- a/src/mesa/drivers/dri/ffb/ffb_xmesa.c
+++ b/src/mesa/drivers/dri/ffb/ffb_xmesa.c
@@ -62,7 +62,7 @@
 #include "drirenderbuffer.h"
 
 static GLboolean
-ffbInitDriver(__DRIscreenPrivate *sPriv)
+ffbInitDriver(__DRIscreen *sPriv)
 {
 	ffbScreenPrivate *ffbScreen;
 	FFBDRIPtr gDRIPriv = (FFBDRIPtr) sPriv->pDevPriv;
@@ -154,7 +154,7 @@
 
 
 static void
-ffbDestroyScreen(__DRIscreenPrivate *sPriv)
+ffbDestroyScreen(__DRIscreen *sPriv)
 {
 	ffbScreenPrivate *ffbScreen = sPriv->private;
 	FFBDRIPtr gDRIPriv = (FFBDRIPtr) sPriv->pDevPriv;
@@ -183,12 +183,12 @@
 /* Create and initialize the Mesa and driver specific context data */
 static GLboolean
 ffbCreateContext(const __GLcontextModes *mesaVis,
-                 __DRIcontextPrivate *driContextPriv,
+                 __DRIcontext *driContextPriv,
                  void *sharedContextPrivate)
 {
 	ffbContextPtr fmesa;
 	GLcontext *ctx, *shareCtx;
-	__DRIscreenPrivate *sPriv;
+	__DRIscreen *sPriv;
 	ffbScreenPrivate *ffbScreen;
 	char *debug;
 	struct dd_function_table functions;
@@ -306,7 +306,7 @@
 }
 
 static void
-ffbDestroyContext(__DRIcontextPrivate *driContextPriv)
+ffbDestroyContext(__DRIcontext *driContextPriv)
 {
 	ffbContextPtr fmesa = (ffbContextPtr) driContextPriv->driverPrivate;
 
@@ -328,8 +328,8 @@
 
 /* Create and initialize the Mesa and driver specific pixmap buffer data */
 static GLboolean
-ffbCreateBuffer(__DRIscreenPrivate *driScrnPriv,
-                __DRIdrawablePrivate *driDrawPriv,
+ffbCreateBuffer(__DRIscreen *driScrnPriv,
+                __DRIdrawable *driDrawPriv,
                 const __GLcontextModes *mesaVis,
                 GLboolean isPixmap )
 {
@@ -392,7 +392,7 @@
 
 
 static void
-ffbDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+ffbDestroyBuffer(__DRIdrawable *driDrawPriv)
 {
    _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
 }
@@ -401,7 +401,7 @@
 #define USE_FAST_SWAP
 
 static void
-ffbSwapBuffers( __DRIdrawablePrivate *dPriv )
+ffbSwapBuffers( __DRIdrawable *dPriv )
 {
 	ffbContextPtr fmesa = (ffbContextPtr) dPriv->driContextPriv->driverPrivate;
 	unsigned int fbc, wid, wid_reg_val, dac_db_bit;
@@ -532,9 +532,9 @@
 /* Force the context `c' to be the current context and associate with it
    buffer `b' */
 static GLboolean
-ffbMakeCurrent(__DRIcontextPrivate *driContextPriv,
-               __DRIdrawablePrivate *driDrawPriv,
-               __DRIdrawablePrivate *driReadPriv)
+ffbMakeCurrent(__DRIcontext *driContextPriv,
+               __DRIdrawable *driDrawPriv,
+               __DRIdrawable *driReadPriv)
 {
 	if (driContextPriv) {
 		ffbContextPtr fmesa = (ffbContextPtr) driContextPriv->driverPrivate;
@@ -581,15 +581,15 @@
 
 /* Force the context `c' to be unbound from its buffer */
 static GLboolean
-ffbUnbindContext(__DRIcontextPrivate *driContextPriv)
+ffbUnbindContext(__DRIcontext *driContextPriv)
 {
 	return GL_TRUE;
 }
 
 void ffbXMesaUpdateState(ffbContextPtr fmesa)
 {
-	__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
-	__DRIscreenPrivate *sPriv = fmesa->driScreen;
+	__DRIdrawable *dPriv = fmesa->driDrawable;
+	__DRIscreen *sPriv = fmesa->driScreen;
 	int stamp = dPriv->lastStamp;
 
 	DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
@@ -607,7 +607,7 @@
 }
 
 static const __DRIconfig **
-ffbFillInModes( __DRIscreenPrivate *psp,
+ffbFillInModes( __DRIscreen *psp,
 		unsigned pixel_bits, unsigned depth_bits,
 		unsigned stencil_bits, GLboolean have_back_buffer )
 {
@@ -722,3 +722,10 @@
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
 };
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driLegacyExtension.base,
+    NULL
+};
diff --git a/src/mesa/drivers/dri/ffb/ffb_xmesa.h b/src/mesa/drivers/dri/ffb/ffb_xmesa.h
index 255da4c..2b1740d 100644
--- a/src/mesa/drivers/dri/ffb/ffb_xmesa.h
+++ b/src/mesa/drivers/dri/ffb/ffb_xmesa.h
@@ -11,7 +11,7 @@
 #include "ffb_fifo.h"
 
 typedef struct {
-	__DRIscreenPrivate		*sPriv;
+	__DRIscreen		*sPriv;
 	ffb_fbcPtr			regs;
 	ffb_dacPtr			dac;
 	volatile char			*sfb8r;
diff --git a/src/mesa/drivers/dri/gamma/gamma_context.c b/src/mesa/drivers/dri/gamma/gamma_context.c
index b0ac299..bab5b69 100644
--- a/src/mesa/drivers/dri/gamma/gamma_context.c
+++ b/src/mesa/drivers/dri/gamma/gamma_context.c
@@ -68,11 +68,11 @@
 };
 
 GLboolean gammaCreateContext( const __GLcontextModes *glVisual,
-			     __DRIcontextPrivate *driContextPriv,
+			     __DRIcontext *driContextPriv,
                      	     void *sharedContextPrivate)
 {
    GLcontext *ctx, *shareCtx;
-   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
    gammaContextPtr gmesa;
    gammaScreenPtr gammascrn;
    GLINTSAREADRIPtr saPriv=(GLINTSAREADRIPtr)(((char*)sPriv->pSAREA)+
diff --git a/src/mesa/drivers/dri/gamma/gamma_context.h b/src/mesa/drivers/dri/gamma/gamma_context.h
index a32ccb6..c386aa3 100644
--- a/src/mesa/drivers/dri/gamma/gamma_context.h
+++ b/src/mesa/drivers/dri/gamma/gamma_context.h
@@ -58,10 +58,10 @@
 #define MAX_TEXTURE_STACK       2
 
 extern void	  gammaDDUpdateHWState(GLcontext *ctx);
-extern gammaScreenPtr	  gammaCreateScreen(__DRIscreenPrivate *sPriv);
-extern void	  gammaDestroyScreen(__DRIscreenPrivate *sPriv);
+extern gammaScreenPtr	  gammaCreateScreen(__DRIscreen *sPriv);
+extern void	  gammaDestroyScreen(__DRIscreen *sPriv);
 extern GLboolean gammaCreateContext( const __GLcontextModes *glVisual,
-                                     __DRIcontextPrivate *driContextPriv,
+                                     __DRIcontext *driContextPriv,
                                      void *sharedContextPrivate);
 
 #define GAMMA_UPLOAD_ALL	0xffffffff
@@ -230,9 +230,9 @@
 struct gamma_context {
 	GLcontext 		*glCtx;		/* Mesa context */
 
-	__DRIcontextPrivate	*driContext;
-	__DRIscreenPrivate	*driScreen;
-	__DRIdrawablePrivate	*driDrawable;
+	__DRIcontext	*driContext;
+	__DRIscreen	*driScreen;
+	__DRIdrawable	*driDrawable;
 
 	GLuint 			new_gl_state;
 	GLuint 			new_state;
diff --git a/src/mesa/drivers/dri/gamma/gamma_lock.c b/src/mesa/drivers/dri/gamma/gamma_lock.c
index 8f2d016..cd4acef 100644
--- a/src/mesa/drivers/dri/gamma/gamma_lock.c
+++ b/src/mesa/drivers/dri/gamma/gamma_lock.c
@@ -19,8 +19,8 @@
  */
 void gammaGetLock( gammaContextPtr gmesa, GLuint flags )
 {
-   __DRIdrawablePrivate *dPriv = gmesa->driDrawable;
-   __DRIscreenPrivate *sPriv = gmesa->driScreen;
+   __DRIdrawable *dPriv = gmesa->driDrawable;
+   __DRIscreen *sPriv = gmesa->driScreen;
 
    drmGetLock( gmesa->driFd, gmesa->hHWContext, flags );
 
diff --git a/src/mesa/drivers/dri/gamma/gamma_macros.h b/src/mesa/drivers/dri/gamma/gamma_macros.h
index c15483b..d962dcd 100644
--- a/src/mesa/drivers/dri/gamma/gamma_macros.h
+++ b/src/mesa/drivers/dri/gamma/gamma_macros.h
@@ -245,8 +245,8 @@
 #ifdef DO_VALIDATE
 #define VALIDATE_DRAWABLE_INFO_NO_LOCK(gcp)                                \
 do {                                                                       \
-    /*__DRIscreenPrivate *psp = gcp->driScreen;*/                          \
-    __DRIdrawablePrivate *pdp = gcp->driDrawable;                          \
+    /*__DRIscreen *psp = gcp->driScreen;*/                          \
+    __DRIdrawable *pdp = gcp->driDrawable;                          \
                                                                            \
     if (*(pdp->pStamp) != pdp->lastStamp) {                                \
 	int old_index = pdp->index;                                        \
@@ -301,7 +301,7 @@
 
 #define VALIDATE_DRAWABLE_INFO(gcp)                                    \
 do {                                                                       \
-    __DRIscreenPrivate *psp = gcp->driScreen;                          \
+    __DRIscreen *psp = gcp->driScreen;                          \
 if (gcp->driDrawable) { \
     DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);            \
     VALIDATE_DRAWABLE_INFO_NO_LOCK(gcp);                               \
diff --git a/src/mesa/drivers/dri/gamma/gamma_render.c b/src/mesa/drivers/dri/gamma/gamma_render.c
index 1b9fd16..a03a93d 100644
--- a/src/mesa/drivers/dri/gamma/gamma_render.c
+++ b/src/mesa/drivers/dri/gamma/gamma_render.c
@@ -53,13 +53,13 @@
    GLfloat (*tc0)[4] = 0;
    GLuint tc0_size = 0;
 
-   col = VB->ColorPtr[0]->data;
-   col_stride = VB->ColorPtr[0]->stride;
+   col = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;
+   col_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride;
 
    if (ctx->Texture.Unit[0]._ReallyEnabled) {
-      tc0_stride = VB->TexCoordPtr[0]->stride;
-      tc0 = VB->TexCoordPtr[0]->data;
-      tc0_size = VB->TexCoordPtr[0]->size;
+      tc0_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0]->stride;
+      tc0 = VB->AttribPtr[_TNL_ATTRIB_TEX0]->data;
+      tc0_size = VB->AttribPtr[_TNL_ATTRIB_TEX0]->size;
       coord = VB->ClipPtr->data;
       coord_stride = VB->ClipPtr->stride;
    } else {
diff --git a/src/mesa/drivers/dri/gamma/gamma_screen.c b/src/mesa/drivers/dri/gamma/gamma_screen.c
index f899ebe..f72a4a5 100644
--- a/src/mesa/drivers/dri/gamma/gamma_screen.c
+++ b/src/mesa/drivers/dri/gamma/gamma_screen.c
@@ -29,7 +29,7 @@
 
 #include "main/imports.h"
 
-gammaScreenPtr gammaCreateScreen( __DRIscreenPrivate *sPriv )
+gammaScreenPtr gammaCreateScreen( __DRIscreen *sPriv )
 {
    gammaScreenPtr gammaScreen;
    GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)sPriv->pDevPriv;
@@ -129,7 +129,7 @@
 
 /* Destroy the device specific screen private data struct.
  */
-void gammaDestroyScreen( __DRIscreenPrivate *sPriv )
+void gammaDestroyScreen( __DRIscreen *sPriv )
 {
     gammaScreenPtr gammaScreen = (gammaScreenPtr)sPriv->private;
 
diff --git a/src/mesa/drivers/dri/gamma/gamma_screen.h b/src/mesa/drivers/dri/gamma/gamma_screen.h
index 7f0ed6f..c716ea8 100644
--- a/src/mesa/drivers/dri/gamma/gamma_screen.h
+++ b/src/mesa/drivers/dri/gamma/gamma_screen.h
@@ -11,7 +11,7 @@
 
     drmBufMapPtr  bufs;              /* Map of DMA buffers */
 
-    __DRIscreenPrivate *driScreen; /* Back pointer to DRI screen */
+    __DRIscreen *driScreen; /* Back pointer to DRI screen */
 
     int		cpp;
     int		frontPitch;
diff --git a/src/mesa/drivers/dri/gamma/gamma_span.c b/src/mesa/drivers/dri/gamma/gamma_span.c
index cdaaac3..3f0b818 100644
--- a/src/mesa/drivers/dri/gamma/gamma_span.c
+++ b/src/mesa/drivers/dri/gamma/gamma_span.c
@@ -10,8 +10,8 @@
 #define LOCAL_VARS							\
    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);				\
    gammaScreenPtr gammascrn = gmesa->gammaScreen;			\
-   __DRIscreenPrivate *sPriv = gmesa->driScreen;			\
-   __DRIdrawablePrivate *dPriv = gmesa->driDrawable;			\
+   __DRIscreen *sPriv = gmesa->driScreen;			\
+   __DRIdrawable *dPriv = gmesa->driDrawable;			\
    GLuint pitch = sPriv->fbWidth * gammascrn->cpp;		\
    GLuint height = dPriv->h;						\
    char *buf = (char *)(sPriv->pFB +					\
@@ -24,8 +24,8 @@
 /* FIXME! Depth/Stencil read/writes don't work ! */
 #define LOCAL_DEPTH_VARS				\
    gammaScreenPtr gammascrn = gmesa->gammaScreen;	\
-   __DRIdrawablePrivate *dPriv = gmesa->driDrawable;	\
-   __DRIscreenPrivate *sPriv = gmesa->driScreen;	\
+   __DRIdrawable *dPriv = gmesa->driDrawable;	\
+   __DRIscreen *sPriv = gmesa->driScreen;	\
    GLuint pitch = gammascrn->depthPitch;		\
    GLuint height = dPriv->h;				\
    char *buf = (char *)(sPriv->pFB +			\
diff --git a/src/mesa/drivers/dri/gamma/gamma_state.c b/src/mesa/drivers/dri/gamma/gamma_state.c
index 59272f9..47df374 100644
--- a/src/mesa/drivers/dri/gamma/gamma_state.c
+++ b/src/mesa/drivers/dri/gamma/gamma_state.c
@@ -813,10 +813,10 @@
 
 
    GLuint mask = gammaPackColor( gmesa->gammaScreen->cpp,
-				ctx->Color.ColorMask[RCOMP],
-				ctx->Color.ColorMask[GCOMP],
-				ctx->Color.ColorMask[BCOMP],
-				ctx->Color.ColorMask[ACOMP] );
+				ctx->Color.ColorMask[0][RCOMP],
+				ctx->Color.ColorMask[0][GCOMP],
+				ctx->Color.ColorMask[0][BCOMP],
+				ctx->Color.ColorMask[0][ACOMP] );
 
    if (gmesa->gammaScreen->cpp == 2) mask |= mask << 16;
 
@@ -1070,7 +1070,7 @@
 void gammaUpdateWindow( GLcontext *ctx )
 {
    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = gmesa->driDrawable;
+   __DRIdrawable *dPriv = gmesa->driDrawable;
    GLfloat xoffset = (GLfloat)dPriv->x;
    GLfloat yoffset = gmesa->driScreen->fbHeight - (GLfloat)dPriv->y - dPriv->h;
    const GLfloat *v = ctx->Viewport._WindowMap.m;
@@ -1109,7 +1109,7 @@
 void gammaUpdateViewportOffset( GLcontext *ctx )
 {
    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = gmesa->driDrawable;
+   __DRIdrawable *dPriv = gmesa->driDrawable;
    GLfloat xoffset = (GLfloat)dPriv->x;
    GLfloat yoffset = gmesa->driScreen->fbHeight - (GLfloat)dPriv->y - dPriv->h;
    const GLfloat *v = ctx->Viewport._WindowMap.m;
diff --git a/src/mesa/drivers/dri/gamma/gamma_tex.c b/src/mesa/drivers/dri/gamma/gamma_tex.c
index 0dad250..694e5eb 100644
--- a/src/mesa/drivers/dri/gamma/gamma_tex.c
+++ b/src/mesa/drivers/dri/gamma/gamma_tex.c
@@ -145,7 +145,7 @@
       break;
   
    case GL_TEXTURE_BORDER_COLOR:
-      gammaSetTexBorderColor( gmesa, t, tObj->BorderColor );
+      gammaSetTexBorderColor( gmesa, t, tObj->BorderColor.f );
       break;
 
    case GL_TEXTURE_BASE_LEVEL:
@@ -349,7 +349,7 @@
 
 	 gammaSetTexWrapping( t, tObj->WrapS, tObj->WrapT );
 	 gammaSetTexFilter( gmesa, t, tObj->MinFilter, tObj->MagFilter, bias );
-	 gammaSetTexBorderColor( gmesa, t, tObj->BorderColor );
+	 gammaSetTexBorderColor( gmesa, t, tObj->BorderColor.f );
       }
 }
 
diff --git a/src/mesa/drivers/dri/gamma/gamma_xmesa.c b/src/mesa/drivers/dri/gamma/gamma_xmesa.c
index 7b5b535..e49ab5b 100644
--- a/src/mesa/drivers/dri/gamma/gamma_xmesa.c
+++ b/src/mesa/drivers/dri/gamma/gamma_xmesa.c
@@ -36,7 +36,7 @@
 #include "vbo/vbo.h"
 
 static GLboolean 
-gammaInitDriver(__DRIscreenPrivate *sPriv)
+gammaInitDriver(__DRIscreen *sPriv)
 {
     sPriv->private = (void *) gammaCreateScreen( sPriv );
 
@@ -49,7 +49,7 @@
 }
 
 static void 
-gammaDestroyContext(__DRIcontextPrivate *driContextPriv)
+gammaDestroyContext(__DRIcontext *driContextPriv)
 {
     gammaContextPtr gmesa = (gammaContextPtr)driContextPriv->driverPrivate;
 
@@ -72,8 +72,8 @@
 
 
 static GLboolean
-gammaCreateBuffer( __DRIscreenPrivate *driScrnPriv,
-                   __DRIdrawablePrivate *driDrawPriv,
+gammaCreateBuffer( __DRIscreen *driScrnPriv,
+                   __DRIdrawable *driDrawPriv,
                    const __GLcontextModes *mesaVis,
                    GLboolean isPixmap )
 {
@@ -94,17 +94,17 @@
 
 
 static void
-gammaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+gammaDestroyBuffer(__DRIdrawable *driDrawPriv)
 {
    _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
 }
 
 static void
-gammaSwapBuffers( __DRIdrawablePrivate *dPriv )
+gammaSwapBuffers( __DRIdrawable *dPriv )
 {
    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
     gammaContextPtr gmesa;
-    __DRIscreenPrivate *driScrnPriv;
+    __DRIscreen *driScrnPriv;
     GLcontext *ctx;
 
     gmesa = (gammaContextPtr) dPriv->driContextPriv->driverPrivate;
@@ -127,7 +127,7 @@
 	int i;
 	int nRect = dPriv->numClipRects;
 	drm_clip_rect_t *pRect = dPriv->pClipRects;
-	__DRIscreenPrivate *driScrnPriv = gmesa->driScreen;
+	__DRIscreen *driScrnPriv = gmesa->driScreen;
    	GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)driScrnPriv->pDevPriv;
 
 	CHECK_DMA_BUFFER(gmesa, 2);
@@ -193,9 +193,9 @@
 }
 
 static GLboolean 
-gammaMakeCurrent(__DRIcontextPrivate *driContextPriv,
-		 __DRIdrawablePrivate *driDrawPriv,
-		 __DRIdrawablePrivate *driReadPriv)
+gammaMakeCurrent(__DRIcontext *driContextPriv,
+		 __DRIdrawable *driDrawPriv,
+		 __DRIdrawable *driReadPriv)
 {
     if (driContextPriv) {
 	GET_CURRENT_CONTEXT(ctx);
@@ -232,7 +232,7 @@
 
 
 static GLboolean 
-gammaUnbindContext( __DRIcontextPrivate *driContextPriv )
+gammaUnbindContext( __DRIcontext *driContextPriv )
 {
    return GL_TRUE;
 }
@@ -254,12 +254,19 @@
 /*
  * This is the bootstrap function for the driver.
  * The __driCreateScreen name is the symbol that libGL.so fetches.
- * Return:  pointer to a __DRIscreenPrivate.
+ * Return:  pointer to a __DRIscreen.
  */
 void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
                         int numConfigs, __GLXvisualConfig *config)
 {
-   __DRIscreenPrivate *psp;
+   __DRIscreen *psp;
    psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &gammaAPI);
    return (void *) psp;
 }
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driLegacyExtension.base,
+    NULL
+};
diff --git a/src/mesa/drivers/dri/i810/i810context.c b/src/mesa/drivers/dri/i810/i810context.c
index 7311b2e..bd9cfe5 100644
--- a/src/mesa/drivers/dri/i810/i810context.c
+++ b/src/mesa/drivers/dri/i810/i810context.c
@@ -170,12 +170,12 @@
 
 GLboolean
 i810CreateContext( const __GLcontextModes *mesaVis,
-                   __DRIcontextPrivate *driContextPriv,
+                   __DRIcontext *driContextPriv,
                    void *sharedContextPrivate )
 {
    GLcontext *ctx, *shareCtx;
    i810ContextPtr imesa;
-   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
    i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private;
    I810SAREAPtr saPriv = (I810SAREAPtr)
       (((GLubyte *)sPriv->pSAREA) + i810Screen->sarea_priv_offset);
@@ -337,7 +337,7 @@
 }
 
 void
-i810DestroyContext(__DRIcontextPrivate *driContextPriv)
+i810DestroyContext(__DRIcontext *driContextPriv)
 {
    i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate;
 
@@ -378,7 +378,7 @@
 
 void i810XMesaSetFrontClipRects( i810ContextPtr imesa )
 {
-   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+   __DRIdrawable *dPriv = imesa->driDrawable;
 
    imesa->numClipRects = dPriv->numClipRects;
    imesa->pClipRects = dPriv->pClipRects;
@@ -392,7 +392,7 @@
 
 void i810XMesaSetBackClipRects( i810ContextPtr imesa )
 {
-   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+   __DRIdrawable *dPriv = imesa->driDrawable;
 
    if (imesa->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0)
    {
@@ -430,7 +430,7 @@
 
 
 GLboolean
-i810UnbindContext(__DRIcontextPrivate *driContextPriv)
+i810UnbindContext(__DRIcontext *driContextPriv)
 {
    i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate;
    if (imesa) {
@@ -444,9 +444,9 @@
 
 
 GLboolean
-i810MakeCurrent(__DRIcontextPrivate *driContextPriv,
-                __DRIdrawablePrivate *driDrawPriv,
-                __DRIdrawablePrivate *driReadPriv)
+i810MakeCurrent(__DRIcontext *driContextPriv,
+                __DRIdrawable *driDrawPriv,
+                __DRIdrawable *driReadPriv)
 {
    if (driContextPriv) {
       i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate;
@@ -504,8 +504,8 @@
 
 void i810GetLock( i810ContextPtr imesa, GLuint flags )
 {
-   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
-   __DRIscreenPrivate *sPriv = imesa->driScreen;
+   __DRIdrawable *dPriv = imesa->driDrawable;
+   __DRIscreen *sPriv = imesa->driScreen;
    I810SAREAPtr sarea = imesa->sarea;
    int me = imesa->hHWContext;
    unsigned i;
@@ -551,7 +551,7 @@
 
 
 void
-i810SwapBuffers( __DRIdrawablePrivate *dPriv )
+i810SwapBuffers( __DRIdrawable *dPriv )
 {
    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
       i810ContextPtr imesa;
diff --git a/src/mesa/drivers/dri/i810/i810context.h b/src/mesa/drivers/dri/i810/i810context.h
index 4b8c71d..19529db 100644
--- a/src/mesa/drivers/dri/i810/i810context.h
+++ b/src/mesa/drivers/dri/i810/i810context.h
@@ -170,8 +170,8 @@
    drm_hw_lock_t *driHwLock;
    int driFd;
 
-   __DRIdrawablePrivate *driDrawable;
-   __DRIscreenPrivate *driScreen;
+   __DRIdrawable *driDrawable;
+   __DRIscreen *driScreen;
    i810ScreenPrivate *i810Screen; 
    I810SAREAPtr sarea;
 };
diff --git a/src/mesa/drivers/dri/i810/i810ioctl.c b/src/mesa/drivers/dri/i810/i810ioctl.c
index 3df9c2a..c631543 100644
--- a/src/mesa/drivers/dri/i810/i810ioctl.c
+++ b/src/mesa/drivers/dri/i810/i810ioctl.c
@@ -50,8 +50,8 @@
 static void i810Clear( GLcontext *ctx, GLbitfield mask )
 {
    i810ContextPtr imesa = I810_CONTEXT( ctx );
-   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
-   const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
+   __DRIdrawable *dPriv = imesa->driDrawable;
+   const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask[0]);
    drmI810Clear clear;
    unsigned int i;
 
@@ -149,7 +149,7 @@
 /*
  * Copy the back buffer to the front buffer. 
  */
-void i810CopyBuffer( const __DRIdrawablePrivate *dPriv ) 
+void i810CopyBuffer( const __DRIdrawable *dPriv ) 
 {
    i810ContextPtr imesa;
    drm_clip_rect_t *pbox;
@@ -197,7 +197,7 @@
 /*
  * XXX implement when full-screen extension is done.
  */
-void i810PageFlip( const __DRIdrawablePrivate *dPriv ) 
+void i810PageFlip( const __DRIdrawable *dPriv ) 
 {
   i810ContextPtr imesa;
   int tmp, ret;
diff --git a/src/mesa/drivers/dri/i810/i810ioctl.h b/src/mesa/drivers/dri/i810/i810ioctl.h
index dfd6e21..926e38c 100644
--- a/src/mesa/drivers/dri/i810/i810ioctl.h
+++ b/src/mesa/drivers/dri/i810/i810ioctl.h
@@ -14,8 +14,8 @@
 void i810DmaFinish( i810ContextPtr imesa );
 void i810RegetLockQuiescent( i810ContextPtr imesa );
 void i810InitIoctlFuncs( struct dd_function_table *functions );
-void i810CopyBuffer( const __DRIdrawablePrivate *dpriv );
-void i810PageFlip( const __DRIdrawablePrivate *dpriv );
+void i810CopyBuffer( const __DRIdrawable *dpriv );
+void i810PageFlip( const __DRIdrawable *dpriv );
 int i810_check_copy(int fd);
 
 #define I810_STATECHANGE(imesa, flag)				\
diff --git a/src/mesa/drivers/dri/i810/i810screen.c b/src/mesa/drivers/dri/i810/i810screen.c
index 2f6b863..2a30782 100644
--- a/src/mesa/drivers/dri/i810/i810screen.c
+++ b/src/mesa/drivers/dri/i810/i810screen.c
@@ -54,7 +54,7 @@
 #include "GL/internal/dri_interface.h"
 
 static const __DRIconfig **
-i810FillInModes( __DRIscreenPrivate *psp,
+i810FillInModes( __DRIscreen *psp,
 		 unsigned pixel_bits, unsigned depth_bits,
 		 unsigned stencil_bits, GLboolean have_back_buffer )
 {
@@ -255,7 +255,7 @@
 }
 
 static void
-i810DestroyScreen(__DRIscreenPrivate *sPriv)
+i810DestroyScreen(__DRIscreen *sPriv)
 {
    i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private;
 
@@ -274,8 +274,8 @@
  * Create a buffer which corresponds to the window.
  */
 static GLboolean
-i810CreateBuffer( __DRIscreenPrivate *driScrnPriv,
-                  __DRIdrawablePrivate *driDrawPriv,
+i810CreateBuffer( __DRIscreen *driScrnPriv,
+                  __DRIdrawable *driDrawPriv,
                   const __GLcontextModes *mesaVis,
                   GLboolean isPixmap )
 {
@@ -335,7 +335,7 @@
 
 
 static void
-i810DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+i810DestroyBuffer(__DRIdrawable *driDrawPriv)
 {
    _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
 }
@@ -356,3 +356,10 @@
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
 };
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driLegacyExtension.base,
+    NULL
+};
diff --git a/src/mesa/drivers/dri/i810/i810screen.h b/src/mesa/drivers/dri/i810/i810screen.h
index b299376..734e2fb 100644
--- a/src/mesa/drivers/dri/i810/i810screen.h
+++ b/src/mesa/drivers/dri/i810/i810screen.h
@@ -71,7 +71,7 @@
    int textureSize;
    int logTextureGranularity;
 
-   __DRIscreenPrivate *driScrnPriv;
+   __DRIscreen *driScrnPriv;
    drmBufMapPtr  bufs;
    unsigned int sarea_priv_offset;
 } i810ScreenPrivate;
@@ -79,21 +79,21 @@
 
 extern GLboolean
 i810CreateContext( const __GLcontextModes *mesaVis,
-                   __DRIcontextPrivate *driContextPriv,
+                   __DRIcontext *driContextPriv,
                    void *sharedContextPrivate );
 
 extern void
-i810DestroyContext(__DRIcontextPrivate *driContextPriv);
+i810DestroyContext(__DRIcontext *driContextPriv);
 
 extern GLboolean
-i810UnbindContext(__DRIcontextPrivate *driContextPriv);
+i810UnbindContext(__DRIcontext *driContextPriv);
 
 extern GLboolean
-i810MakeCurrent(__DRIcontextPrivate *driContextPriv,
-                __DRIdrawablePrivate *driDrawPriv,
-                __DRIdrawablePrivate *driReadPriv);
+i810MakeCurrent(__DRIcontext *driContextPriv,
+                __DRIdrawable *driDrawPriv,
+                __DRIdrawable *driReadPriv);
 
 extern void
-i810SwapBuffers(__DRIdrawablePrivate *driDrawPriv);
+i810SwapBuffers(__DRIdrawable *driDrawPriv);
 
 #endif
diff --git a/src/mesa/drivers/dri/i810/i810span.c b/src/mesa/drivers/dri/i810/i810span.c
index 510723f..6576f67 100644
--- a/src/mesa/drivers/dri/i810/i810span.c
+++ b/src/mesa/drivers/dri/i810/i810span.c
@@ -15,7 +15,7 @@
 
 #define LOCAL_VARS					\
    i810ContextPtr imesa = I810_CONTEXT(ctx);	        \
-   __DRIdrawablePrivate *dPriv = imesa->driDrawable;	\
+   __DRIdrawable *dPriv = imesa->driDrawable;	\
    driRenderbuffer *drb = (driRenderbuffer *) rb;	\
    GLuint pitch = drb->pitch;				\
    GLuint height = dPriv->h;				\
@@ -27,7 +27,7 @@
 
 #define LOCAL_DEPTH_VARS				\
    i810ContextPtr imesa = I810_CONTEXT(ctx);	        \
-   __DRIdrawablePrivate *dPriv = imesa->driDrawable;	\
+   __DRIdrawable *dPriv = imesa->driDrawable;	\
    driRenderbuffer *drb = (driRenderbuffer *) rb;	\
    GLuint pitch = drb->pitch;				\
    GLuint height = dPriv->h;				\
diff --git a/src/mesa/drivers/dri/i810/i810state.c b/src/mesa/drivers/dri/i810/i810state.c
index 1e7a6cf..642245c 100644
--- a/src/mesa/drivers/dri/i810/i810state.c
+++ b/src/mesa/drivers/dri/i810/i810state.c
@@ -641,7 +641,7 @@
 
 void i810EmitDrawingRectangle( i810ContextPtr imesa )
 {
-   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+   __DRIdrawable *dPriv = imesa->driDrawable;
    i810ScreenPrivate *i810Screen = imesa->i810Screen;
    int x0 = imesa->drawX;
    int y0 = imesa->drawY;
diff --git a/src/mesa/drivers/dri/i810/i810tex.c b/src/mesa/drivers/dri/i810/i810tex.c
index 2f6978f..e764644 100644
--- a/src/mesa/drivers/dri/i810/i810tex.c
+++ b/src/mesa/drivers/dri/i810/i810tex.c
@@ -210,7 +210,7 @@
       i810SetTexWrapping( t, texObj->WrapS, texObj->WrapT );
       /*i830SetTexMaxAnisotropy( t, texObj->MaxAnisotropy );*/
       i810SetTexFilter( imesa, t, texObj->MinFilter, texObj->MagFilter, bias );
-      i810SetTexBorderColor( t, texObj->BorderColor );
+      i810SetTexBorderColor( t, texObj->BorderColor.f );
    }
 
    return t;
@@ -251,7 +251,7 @@
       break;
   
    case GL_TEXTURE_BORDER_COLOR:
-      i810SetTexBorderColor( t, tObj->BorderColor );
+      i810SetTexBorderColor( t, tObj->BorderColor.f );
       break;
 
    case GL_TEXTURE_BASE_LEVEL:
diff --git a/src/mesa/drivers/dri/i810/i810tex.h b/src/mesa/drivers/dri/i810/i810tex.h
index d980927..28958dc 100644
--- a/src/mesa/drivers/dri/i810/i810tex.h
+++ b/src/mesa/drivers/dri/i810/i810tex.h
@@ -29,7 +29,6 @@
 #include "main/mtypes.h"
 #include "main/mm.h"
 
-#include "i810context.h"
 #include "i810_3d_reg.h"
 #include "texmem.h"
 
diff --git a/src/mesa/drivers/dri/i810/i810tris.c b/src/mesa/drivers/dri/i810/i810tris.c
index b508496..213ba54 100644
--- a/src/mesa/drivers/dri/i810/i810tris.c
+++ b/src/mesa/drivers/dri/i810/i810tris.c
@@ -270,7 +270,8 @@
 
 #define LOCAL_VARS(n)							\
    i810ContextPtr imesa = I810_CONTEXT(ctx);				\
-   GLuint color[n], spec[n];						\
+   GLuint color[n] = { 0 };						\
+   GLuint spec[n] = { 0 };						\
    GLuint coloroffset = (imesa->vertex_size == 4 ? 3 : 4);		\
    GLboolean havespec = (imesa->vertex_size > 4);			\
    (void) color; (void) spec; (void) coloroffset; (void) havespec;
diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile
index 37f15aa..cf32476 100644
--- a/src/mesa/drivers/dri/i915/Makefile
+++ b/src/mesa/drivers/dri/i915/Makefile
@@ -34,7 +34,6 @@
 	intel_pixel_read.c \
 	intel_buffers.c \
 	intel_blit.c \
-	intel_swapbuffers.c \
 	i915_tex_layout.c \
 	i915_texstate.c \
 	i915_context.c \
@@ -64,7 +63,8 @@
 	$(shell pkg-config libdrm --atleast-version=2.3.1 \
 				&& echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
 
-DRI_LIB_DEPS += -ldrm_intel
+INCLUDES += $(INTEL_CFLAGS)
+DRI_LIB_DEPS += $(INTEL_LIBS)
 
 include ../Makefile.template
 
diff --git a/src/mesa/drivers/dri/i915/i830_context.c b/src/mesa/drivers/dri/i915/i830_context.c
index 840946f..4cb6305 100644
--- a/src/mesa/drivers/dri/i915/i830_context.c
+++ b/src/mesa/drivers/dri/i915/i830_context.c
@@ -53,7 +53,7 @@
 
 GLboolean
 i830CreateContext(const __GLcontextModes * mesaVis,
-                  __DRIcontextPrivate * driContextPriv,
+                  __DRIcontext * driContextPriv,
                   void *sharedContextPrivate)
 {
    struct dd_function_table functions;
diff --git a/src/mesa/drivers/dri/i915/i830_context.h b/src/mesa/drivers/dri/i915/i830_context.h
index f73cbbf..592ae53 100644
--- a/src/mesa/drivers/dri/i915/i830_context.h
+++ b/src/mesa/drivers/dri/i915/i830_context.h
@@ -178,7 +178,7 @@
  */
 extern GLboolean
 i830CreateContext(const __GLcontextModes * mesaVis,
-                  __DRIcontextPrivate * driContextPriv,
+                  __DRIcontext * driContextPriv,
                   void *sharedContextPrivate);
 
 /* i830_tex.c, i830_texstate.c
diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c
index 645ebe3..acda7e7 100644
--- a/src/mesa/drivers/dri/i915/i830_state.c
+++ b/src/mesa/drivers/dri/i915/i830_state.c
@@ -620,7 +620,7 @@
    DBG("%s\n", __FUNCTION__);
    
    width = (int) (widthf * 2);
-   CLAMP_SELF(width, 1, 15);
+   width = CLAMP(width, 1, 15);
 
    state5 = i830->state.Ctx[I830_CTXREG_STATE5] & ~FIXED_LINE_WIDTH_MASK;
    state5 |= (ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(width));
@@ -639,7 +639,7 @@
 
    DBG("%s\n", __FUNCTION__);
    
-   CLAMP_SELF(point_size, 1, 256);
+   point_size = CLAMP(point_size, 1, 256);
    I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    i830->state.Ctx[I830_CTXREG_STATE5] &= ~FIXED_POINT_WIDTH_MASK;
    i830->state.Ctx[I830_CTXREG_STATE5] |= (ENABLE_FIXED_POINT_WIDTH |
diff --git a/src/mesa/drivers/dri/i915/i830_texstate.c b/src/mesa/drivers/dri/i915/i830_texstate.c
index f4bbb53..7525f9f 100644
--- a/src/mesa/drivers/dri/i915/i830_texstate.c
+++ b/src/mesa/drivers/dri/i915/i830_texstate.c
@@ -27,6 +27,7 @@
 
 #include "main/mtypes.h"
 #include "main/enums.h"
+#include "main/colormac.h"
 
 #include "intel_mipmap_tree.h"
 #include "intel_tex.h"
@@ -55,10 +56,7 @@
    case MESA_FORMAT_ARGB4444:
       return MAPSURF_16BIT | MT_16BIT_ARGB4444;
    case MESA_FORMAT_ARGB8888:
-      if (internal_format == GL_RGB)
-	 return MAPSURF_32BIT | MT_32BIT_XRGB8888;
-      else
-	 return MAPSURF_32BIT | MT_32BIT_ARGB8888;
+      return MAPSURF_32BIT | MT_32BIT_ARGB8888;
    case MESA_FORMAT_XRGB8888:
       return MAPSURF_32BIT | MT_32BIT_XRGB8888;
    case MESA_FORMAT_YCBCR_REV:
@@ -306,16 +304,15 @@
    }
 
    /* convert border color from float to ubyte */
-   CLAMPED_FLOAT_TO_UBYTE(border[0], tObj->BorderColor[0]);
-   CLAMPED_FLOAT_TO_UBYTE(border[1], tObj->BorderColor[1]);
-   CLAMPED_FLOAT_TO_UBYTE(border[2], tObj->BorderColor[2]);
-   CLAMPED_FLOAT_TO_UBYTE(border[3], tObj->BorderColor[3]);
+   CLAMPED_FLOAT_TO_UBYTE(border[0], tObj->BorderColor.f[0]);
+   CLAMPED_FLOAT_TO_UBYTE(border[1], tObj->BorderColor.f[1]);
+   CLAMPED_FLOAT_TO_UBYTE(border[2], tObj->BorderColor.f[2]);
+   CLAMPED_FLOAT_TO_UBYTE(border[3], tObj->BorderColor.f[3]);
 
-   state[I830_TEXREG_TM0S4] = INTEL_PACKCOLOR8888(border[0],
-                                                  border[1],
-                                                  border[2],
-                                                  border[3]);
-
+   state[I830_TEXREG_TM0S4] = PACK_COLOR_8888(border[3],
+					      border[0],
+					      border[1],
+					      border[2]);
 
    I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(unit), GL_TRUE);
    /* memcmp was already disabled, but definitely won't work as the
diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c
index 4133696..4471ca2 100644
--- a/src/mesa/drivers/dri/i915/i830_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i830_vtbl.c
@@ -126,7 +126,7 @@
 
       for (i = 0; i < I830_TEX_UNITS; i++) {
          if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_TEX(i))) {
-            GLuint sz = VB->TexCoordPtr[i]->size;
+            GLuint sz = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size;
             GLuint emit;
             GLuint mcs = (i830->state.Tex[i][I830_TEXREG_MCS] &
                           ~TEXCOORDTYPE_MASK);
@@ -298,7 +298,7 @@
 {
    BATCH_LOCALS;
 
-   BEGIN_BATCH(29, IGNORE_CLIPRECTS);
+   BEGIN_BATCH(29);
 
    OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
    OUT_BATCH(0);
@@ -366,7 +366,7 @@
 
 
 #define emit( intel, state, size )			\
-   intel_batchbuffer_data(intel->batch, state, size, IGNORE_CLIPRECTS )
+   intel_batchbuffer_data(intel->batch, state, size )
 
 static GLuint
 get_dirty(struct i830_hw_state *state)
@@ -429,13 +429,9 @@
     * It might be better to talk about explicit places where
     * scheduling is allowed, rather than assume that it is whenever a
     * batchbuffer fills up.
-    *
-    * Set the space as LOOP_CLIPRECTS now, since that's what our primitives
-    * will be emitted under.
     */
    intel_batchbuffer_require_space(intel->batch,
-				   get_state_size(state) + INTEL_PRIM_EMIT_SIZE,
-				   LOOP_CLIPRECTS);
+				   get_state_size(state) + INTEL_PRIM_EMIT_SIZE);
    count = 0;
  again:
    aper_count = 0;
@@ -491,17 +487,14 @@
    }
 
    if (dirty & I830_UPLOAD_BUFFERS) {
-      GLuint count = 9; 
+      GLuint count = 15;
 
       DBG("I830_UPLOAD_BUFFERS:\n");
 
       if (state->depth_region)
           count += 3;
 
-      if (intel->constant_cliprect)
-          count += 6;
-
-      BEGIN_BATCH(count, IGNORE_CLIPRECTS);
+      BEGIN_BATCH(count);
       OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR0]);
       OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR1]);
       OUT_RELOC(state->draw_region->buffer,
@@ -523,15 +516,13 @@
       OUT_BATCH(state->Buffer[I830_DESTREG_SR1]);
       OUT_BATCH(state->Buffer[I830_DESTREG_SR2]);
 
-      if (intel->constant_cliprect) {
-	 assert(state->Buffer[I830_DESTREG_DRAWRECT0] != MI_NOOP);
-	 OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT0]);
-	 OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT1]);
-	 OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT2]);
-	 OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT3]);
-	 OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT4]);
-	 OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT5]);
-      }
+      assert(state->Buffer[I830_DESTREG_DRAWRECT0] != MI_NOOP);
+      OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT0]);
+      OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT1]);
+      OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT2]);
+      OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT3]);
+      OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT4]);
+      OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT5]);
       ADVANCE_BATCH();
    }
    
@@ -544,7 +535,7 @@
       if ((dirty & I830_UPLOAD_TEX(i))) {
          DBG("I830_UPLOAD_TEX(%d):\n", i);
 
-         BEGIN_BATCH(I830_TEX_SETUP_SIZE + 1, IGNORE_CLIPRECTS);
+         BEGIN_BATCH(I830_TEX_SETUP_SIZE + 1);
          OUT_BATCH(state->Tex[i][I830_TEXREG_TM0LI]);
 
          if (state->tex_buffer[i]) {
@@ -645,7 +636,7 @@
             DSTORG_VERT_BIAS(0x8) | DEPTH_IS_Z);    /* .5 */
 
    if (irb != NULL) {
-      switch (irb->texformat) {
+      switch (irb->Base.Format) {
       case MESA_FORMAT_ARGB8888:
       case MESA_FORMAT_XRGB8888:
 	 value |= DV_PF_8888;
@@ -661,7 +652,7 @@
 	 break;
       default:
 	 _mesa_problem(ctx, "Bad renderbuffer format: %d\n",
-		       irb->texformat);
+		       irb->Base.Format);
       }
    }
 
@@ -673,23 +664,14 @@
    }
    state->Buffer[I830_DESTREG_DV1] = value;
 
-   if (intel->constant_cliprect) {
-      state->Buffer[I830_DESTREG_DRAWRECT0] = _3DSTATE_DRAWRECT_INFO;
-      state->Buffer[I830_DESTREG_DRAWRECT1] = 0;
-      state->Buffer[I830_DESTREG_DRAWRECT2] = 0; /* xmin, ymin */
-      state->Buffer[I830_DESTREG_DRAWRECT3] =
-	 (ctx->DrawBuffer->Width & 0xffff) |
-	 (ctx->DrawBuffer->Height << 16);
-      state->Buffer[I830_DESTREG_DRAWRECT4] = 0; /* xoff, yoff */
-      state->Buffer[I830_DESTREG_DRAWRECT5] = 0;
-   } else {
-      state->Buffer[I830_DESTREG_DRAWRECT0] = MI_NOOP;
-      state->Buffer[I830_DESTREG_DRAWRECT1] = MI_NOOP;
-      state->Buffer[I830_DESTREG_DRAWRECT2] = MI_NOOP;
-      state->Buffer[I830_DESTREG_DRAWRECT3] = MI_NOOP;
-      state->Buffer[I830_DESTREG_DRAWRECT4] = MI_NOOP;
-      state->Buffer[I830_DESTREG_DRAWRECT5] = MI_NOOP;
-   }
+   state->Buffer[I830_DESTREG_DRAWRECT0] = _3DSTATE_DRAWRECT_INFO;
+   state->Buffer[I830_DESTREG_DRAWRECT1] = 0;
+   state->Buffer[I830_DESTREG_DRAWRECT2] = 0; /* xmin, ymin */
+   state->Buffer[I830_DESTREG_DRAWRECT3] =
+      (ctx->DrawBuffer->Width & 0xffff) |
+      (ctx->DrawBuffer->Height << 16);
+   state->Buffer[I830_DESTREG_DRAWRECT4] = 0; /* xoff, yoff */
+   state->Buffer[I830_DESTREG_DRAWRECT5] = 0;
 
    I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS);
 
@@ -714,20 +696,8 @@
 {
    struct i830_context *i830 = i830_context(&intel->ctx);
    i830->state.emitted = 0;
-
-   /* Check that we didn't just wrap our batchbuffer at a bad time. */
-   assert(!intel->no_batch_wrap);
 }
 
-
-
-static GLuint
-i830_flush_cmd(void)
-{
-   return MI_FLUSH | FLUSH_MAP_CACHE;
-}
-
-
 static void 
 i830_assert_not_dirty( struct intel_context *intel )
 {
@@ -753,7 +723,6 @@
    i830->intel.vtbl.reduced_primitive_state = i830_reduced_primitive_state;
    i830->intel.vtbl.set_draw_region = i830_set_draw_region;
    i830->intel.vtbl.update_texture_state = i830UpdateTextureState;
-   i830->intel.vtbl.flush_cmd = i830_flush_cmd;
    i830->intel.vtbl.render_start = i830_render_start;
    i830->intel.vtbl.render_prevalidate = i830_render_prevalidate;
    i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty;
diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c
index 7d4c7cf..7c7711d 100644
--- a/src/mesa/drivers/dri/i915/i915_context.c
+++ b/src/mesa/drivers/dri/i915/i915_context.c
@@ -100,7 +100,7 @@
 
 GLboolean
 i915CreateContext(const __GLcontextModes * mesaVis,
-                  __DRIcontextPrivate * driContextPriv,
+                  __DRIcontext * driContextPriv,
                   void *sharedContextPrivate)
 {
    struct dd_function_table functions;
@@ -143,6 +143,9 @@
    ctx->Const.MaxTextureImageUnits = I915_TEX_UNITS;
    ctx->Const.MaxTextureCoordUnits = I915_TEX_UNITS;
    ctx->Const.MaxVarying = I915_TEX_UNITS;
+   ctx->Const.MaxCombinedTextureImageUnits =
+      ctx->Const.MaxVertexTextureImageUnits +
+      ctx->Const.MaxTextureImageUnits;
 
    /* Advertise the full hardware capabilities.  The new memory
     * manager should cope much better with overload situations:
diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h
index 082d614..f55b551 100644
--- a/src/mesa/drivers/dri/i915/i915_context.h
+++ b/src/mesa/drivers/dri/i915/i915_context.h
@@ -39,6 +39,7 @@
 #define I915_FALLBACK_LOGICOP		 0x20000
 #define I915_FALLBACK_POLYGON_SMOOTH	 0x40000
 #define I915_FALLBACK_POINT_SMOOTH	 0x80000
+#define I915_FALLBACK_POINT_SPRITE_COORD_ORIGIN	 0x100000
 
 #define I915_UPLOAD_CTX              0x1
 #define I915_UPLOAD_BUFFERS          0x2
@@ -317,7 +318,7 @@
  * i915_context.c
  */
 extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis,
-                                   __DRIcontextPrivate * driContextPriv,
+                                   __DRIcontext * driContextPriv,
                                    void *sharedContextPrivate);
 
 
diff --git a/src/mesa/drivers/dri/i915/i915_debug.c b/src/mesa/drivers/dri/i915/i915_debug.c
index f7bb7ea..fecfac3 100644
--- a/src/mesa/drivers/dri/i915/i915_debug.c
+++ b/src/mesa/drivers/dri/i915/i915_debug.c
@@ -806,6 +806,7 @@
       default:
 	 return debug(stream, "", 0);
       }
+      break;
    default:
       assert(0);
       return 0;
diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c
index d9c6144..a273bd2 100644
--- a/src/mesa/drivers/dri/i915/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915/i915_fragprog.c
@@ -663,7 +663,7 @@
 			 A0_MOV,
 			 get_result_vector(p, inst),
 			 get_result_flags(inst), 0,
-			 swizzle(src0, ZERO, ZERO, ZERO, ZERO), 0, 0);
+			 swizzle(tmp, ZERO, ZERO, ZERO, ZERO), 0, 0);
 
       case OPCODE_POW:
          src0 = src_vector(p, &inst->SrcReg[0], program);
@@ -1301,7 +1301,7 @@
 
    for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) {
       if (inputsRead & FRAG_BIT_TEX(i)) {
-         int sz = VB->TexCoordPtr[i]->size;
+         int sz = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size;
 
          s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
          s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz));
diff --git a/src/mesa/drivers/dri/i915/i915_program.c b/src/mesa/drivers/dri/i915/i915_program.c
index e7908bd..3902c69 100644
--- a/src/mesa/drivers/dri/i915/i915_program.c
+++ b/src/mesa/drivers/dri/i915/i915_program.c
@@ -245,7 +245,7 @@
    }
    else {
       assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
-      assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
+      assert(dest == UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
       /* Can't use unsaved temps for coords, as the phase boundary would result
        * in the contents becoming undefined.
        */
diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c
index b60efea..9d7a9e1 100644
--- a/src/mesa/drivers/dri/i915/i915_state.c
+++ b/src/mesa/drivers/dri/i915/i915_state.c
@@ -571,7 +571,7 @@
    DBG("%s\n", __FUNCTION__);
    
    width = (int) (widthf * 2);
-   CLAMP_SELF(width, 1, 0xf);
+   width = CLAMP(width, 1, 0xf);
    lis4 |= width << S4_LINE_WIDTH_SHIFT;
 
    if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) {
@@ -585,11 +585,11 @@
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
    int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK;
-   GLint point_size = (int) size;
+   GLint point_size = (int) round(size);
 
    DBG("%s\n", __FUNCTION__);
    
-   CLAMP_SELF(point_size, 1, 255);
+   point_size = CLAMP(point_size, 1, 255);
    lis4 |= point_size << S4_POINT_WIDTH_SHIFT;
 
    if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) {
@@ -599,6 +599,24 @@
 }
 
 
+static void
+i915PointParameterfv(GLcontext * ctx, GLenum pname, const GLfloat *params)
+{
+   struct i915_context *i915 = I915_CONTEXT(ctx);
+
+   switch (pname) {
+   case GL_POINT_SPRITE_COORD_ORIGIN:
+      /* This could be supported, but it would require modifying the fragment
+       * program to invert the y component of the texture coordinate by
+       * inserting a 'SUB tc.y, {1.0}.xxxx, tc' instruction.
+       */
+      FALLBACK(&i915->intel, I915_FALLBACK_POINT_SPRITE_COORD_ORIGIN,
+	       (params[0] != GL_UPPER_LEFT));
+      break;
+   }
+}
+
+
 /* =============================================================
  * Color masks
  */
@@ -939,6 +957,17 @@
    case GL_POLYGON_SMOOTH:
       break;
 
+   case GL_POINT_SPRITE:
+      /* This state change is handled in i915_reduced_primitive_state because
+       * the hardware bit should only be set when rendering points.
+       */
+      I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+      if (state)
+	 i915->state.Ctx[I915_CTXREG_LIS4] |= S4_SPRITE_POINT_ENABLE;
+      else
+	 i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_SPRITE_POINT_ENABLE;
+      break;
+
    case GL_POINT_SMOOTH:
       break;
 
@@ -1108,6 +1137,7 @@
    functions->LineWidth = i915LineWidth;
    functions->LogicOpcode = i915LogicOp;
    functions->PointSize = i915PointSize;
+   functions->PointParameterfv = i915PointParameterfv;
    functions->PolygonStipple = i915PolygonStipple;
    functions->Scissor = i915Scissor;
    functions->ShadeModel = i915ShadeModel;
diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c
index d6689af..3ee4c86 100644
--- a/src/mesa/drivers/dri/i915/i915_texstate.c
+++ b/src/mesa/drivers/dri/i915/i915_texstate.c
@@ -28,6 +28,7 @@
 #include "main/mtypes.h"
 #include "main/enums.h"
 #include "main/macros.h"
+#include "main/colormac.h"
 
 #include "intel_mipmap_tree.h"
 #include "intel_tex.h"
@@ -56,10 +57,7 @@
    case MESA_FORMAT_ARGB4444:
       return MAPSURF_16BIT | MT_16BIT_ARGB4444;
    case MESA_FORMAT_ARGB8888:
-      if (internal_format == GL_RGB)
-	 return MAPSURF_32BIT | MT_32BIT_XRGB8888;
-      else
-	 return MAPSURF_32BIT | MT_32BIT_ARGB8888;
+      return MAPSURF_32BIT | MT_32BIT_ARGB8888;
    case MESA_FORMAT_XRGB8888:
       return MAPSURF_32BIT | MT_32BIT_XRGB8888;
    case MESA_FORMAT_YCBCR_REV:
@@ -141,6 +139,7 @@
    GLuint *state = i915->state.Tex[unit], format, pitch;
    GLint lodbias, aniso = 0;
    GLubyte border[4];
+   GLfloat maxlod;
 
    memset(state, 0, sizeof(state));
 
@@ -178,18 +177,9 @@
 
       pitch = intelObj->pitchOverride;
    } else {
-      GLuint dst_x, dst_y;
-
-      intel_miptree_get_image_offset(intelObj->mt, intelObj->firstLevel, 0, 0,
-				     &dst_x, &dst_y);
-
       dri_bo_reference(intelObj->mt->region->buffer);
       i915->state.tex_buffer[unit] = intelObj->mt->region->buffer;
-      /* XXX: This calculation is probably broken for tiled images with
-       * a non-page-aligned offset.
-       */
-      i915->state.tex_offset[unit] = (dst_x + dst_y * intelObj->mt->pitch) *
-	 intelObj->mt->cpp;
+      i915->state.tex_offset[unit] = 0; /* Always the origin of the miptree */
 
       format = translate_texture_format(firstImage->TexFormat,
 					firstImage->InternalFormat,
@@ -207,10 +197,15 @@
 	 state[I915_TEXREG_MS3] |= MS3_TILE_WALK;
    }
 
+   /* We get one field with fraction bits for the maximum addressable
+    * (lowest resolution) LOD.  Use it to cover both MAX_LEVEL and
+    * MAX_LOD.
+    */
+   maxlod = MIN2(tObj->MaxLod, tObj->_MaxLevel - tObj->BaseLevel);
    state[I915_TEXREG_MS4] =
       ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) |
        MS4_CUBE_FACE_ENA_MASK |
-       (U_FIXED(CLAMP(tObj->MaxLod, 0.0, 11.0), 2) << MS4_MAX_LOD_SHIFT) |
+       (U_FIXED(CLAMP(maxlod, 0.0, 11.0), 2) << MS4_MAX_LOD_SHIFT) |
        ((firstImage->Depth - 1) << MS4_VOLUME_DEPTH_SHIFT));
 
 
@@ -353,25 +348,25 @@
    }
 
    /* convert border color from float to ubyte */
-   CLAMPED_FLOAT_TO_UBYTE(border[0], tObj->BorderColor[0]);
-   CLAMPED_FLOAT_TO_UBYTE(border[1], tObj->BorderColor[1]);
-   CLAMPED_FLOAT_TO_UBYTE(border[2], tObj->BorderColor[2]);
-   CLAMPED_FLOAT_TO_UBYTE(border[3], tObj->BorderColor[3]);
+   CLAMPED_FLOAT_TO_UBYTE(border[0], tObj->BorderColor.f[0]);
+   CLAMPED_FLOAT_TO_UBYTE(border[1], tObj->BorderColor.f[1]);
+   CLAMPED_FLOAT_TO_UBYTE(border[2], tObj->BorderColor.f[2]);
+   CLAMPED_FLOAT_TO_UBYTE(border[3], tObj->BorderColor.f[3]);
 
    if (firstImage->_BaseFormat == GL_DEPTH_COMPONENT) {
       /* GL specs that border color for depth textures is taken from the
        * R channel, while the hardware uses A.  Spam R into all the channels
        * for safety.
        */
-      state[I915_TEXREG_SS4] = INTEL_PACKCOLOR8888(border[0],
-						   border[0],
-						   border[0],
-						   border[0]);
+      state[I915_TEXREG_SS4] = PACK_COLOR_8888(border[0],
+					       border[0],
+					       border[0],
+					       border[0]);
    } else {
-      state[I915_TEXREG_SS4] = INTEL_PACKCOLOR8888(border[0],
-						   border[1],
-						   border[2],
-						   border[3]);
+      state[I915_TEXREG_SS4] = PACK_COLOR_8888(border[3],
+					       border[0],
+					       border[1],
+					       border[2]);
    }
 
 
diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c
index 3c1b2dd..266e684 100644
--- a/src/mesa/drivers/dri/i915/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i915_vtbl.c
@@ -174,7 +174,7 @@
 {
    BATCH_LOCALS;
 
-   BEGIN_BATCH(17, IGNORE_CLIPRECTS);
+   BEGIN_BATCH(17);
 
    OUT_BATCH(_3DSTATE_AA_CMD |
              AA_LINE_ECAAR_WIDTH_ENABLE |
@@ -220,7 +220,7 @@
 
 
 #define emit(intel, state, size )		     \
-   intel_batchbuffer_data(intel->batch, state, size, IGNORE_CLIPRECTS )
+   intel_batchbuffer_data(intel->batch, state, size)
 
 static GLuint
 get_dirty(struct i915_hw_state *state)
@@ -301,13 +301,9 @@
     * It might be better to talk about explicit places where
     * scheduling is allowed, rather than assume that it is whenever a
     * batchbuffer fills up.
-    *
-    * Set the space as LOOP_CLIPRECTS now, since that's what our primitives
-    * will be emitted under.
     */
    intel_batchbuffer_require_space(intel->batch,
-				   get_state_size(state) + INTEL_PRIM_EMIT_SIZE,
-				   LOOP_CLIPRECTS);
+				   get_state_size(state) + INTEL_PRIM_EMIT_SIZE);
    count = 0;
  again:
    aper_count = 0;
@@ -373,7 +369,7 @@
    }
 
    if (dirty & I915_UPLOAD_BUFFERS) {
-      GLuint count = 9;
+      GLuint count = 15;
 
       if (INTEL_DEBUG & DEBUG_STATE)
          fprintf(stderr, "I915_UPLOAD_BUFFERS:\n");
@@ -381,10 +377,7 @@
       if (state->depth_region)
           count += 3;
 
-      if (intel->constant_cliprect)
-          count += 6;
-
-      BEGIN_BATCH(count, IGNORE_CLIPRECTS);
+      BEGIN_BATCH(count);
       OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]);
       OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]);
       OUT_RELOC(state->draw_region->buffer,
@@ -406,15 +399,13 @@
       OUT_BATCH(state->Buffer[I915_DESTREG_SR1]);
       OUT_BATCH(state->Buffer[I915_DESTREG_SR2]);
 
-      if (intel->constant_cliprect) {
-	 assert(state->Buffer[I915_DESTREG_DRAWRECT0] != MI_NOOP);
-	 OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT0]);
-	 OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT1]);
-	 OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT2]);
-	 OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT3]);
-	 OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT4]);
-	 OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT5]);
-      }
+      assert(state->Buffer[I915_DESTREG_DRAWRECT0] != MI_NOOP);
+      OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT0]);
+      OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT1]);
+      OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT2]);
+      OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT3]);
+      OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT4]);
+      OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT5]);
 
       ADVANCE_BATCH();
    }
@@ -441,7 +432,7 @@
          if (dirty & I915_UPLOAD_TEX(i))
             nr++;
 
-      BEGIN_BATCH(2 + nr * 3, IGNORE_CLIPRECTS);
+      BEGIN_BATCH(2 + nr * 3);
       OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr));
       OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT);
       for (i = 0; i < I915_TEX_UNITS; i++)
@@ -465,7 +456,7 @@
          }
       ADVANCE_BATCH();
 
-      BEGIN_BATCH(2 + nr * 3, IGNORE_CLIPRECTS);
+      BEGIN_BATCH(2 + nr * 3);
       OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * nr));
       OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT);
       for (i = 0; i < I915_TEX_UNITS; i++)
@@ -587,7 +578,7 @@
             DSTORG_VERT_BIAS(0x8) |     /* .5 */
             LOD_PRECLAMP_OGL | TEX_DEFAULT_COLOR_OGL);
    if (irb != NULL) {
-      switch (irb->texformat) {
+      switch (irb->Base.Format) {
       case MESA_FORMAT_ARGB8888:
       case MESA_FORMAT_XRGB8888:
 	 value |= DV_PF_8888;
@@ -603,7 +594,7 @@
 	 break;
       default:
 	 _mesa_problem(ctx, "Bad renderbuffer format: %d\n",
-		       irb->texformat);
+		       irb->Base.Format);
       }
    }
 
@@ -611,7 +602,7 @@
     * the value of this bit, the pipeline needs to be MI_FLUSHed.  And it
     * can only be set when a depth buffer is already defined.
     */
-   if (IS_945(intel->intelScreen->deviceID) && intel->use_early_z &&
+   if (intel->is_945 && intel->use_early_z &&
        depth_region->tiling != I915_TILING_NONE)
       value |= CLASSIC_EARLY_DEPTH;
 
@@ -623,23 +614,14 @@
    }
    state->Buffer[I915_DESTREG_DV1] = value;
 
-   if (intel->constant_cliprect) {
-      state->Buffer[I915_DESTREG_DRAWRECT0] = _3DSTATE_DRAWRECT_INFO;
-      state->Buffer[I915_DESTREG_DRAWRECT1] = 0;
-      state->Buffer[I915_DESTREG_DRAWRECT2] = 0; /* xmin, ymin */
-      state->Buffer[I915_DESTREG_DRAWRECT3] =
-	 (ctx->DrawBuffer->Width & 0xffff) |
-	 (ctx->DrawBuffer->Height << 16);
-      state->Buffer[I915_DESTREG_DRAWRECT4] = 0; /* xoff, yoff */
-      state->Buffer[I915_DESTREG_DRAWRECT5] = 0;
-   } else {
-      state->Buffer[I915_DESTREG_DRAWRECT0] = MI_NOOP;
-      state->Buffer[I915_DESTREG_DRAWRECT1] = MI_NOOP;
-      state->Buffer[I915_DESTREG_DRAWRECT2] = MI_NOOP;
-      state->Buffer[I915_DESTREG_DRAWRECT3] = MI_NOOP;
-      state->Buffer[I915_DESTREG_DRAWRECT4] = MI_NOOP;
-      state->Buffer[I915_DESTREG_DRAWRECT5] = MI_NOOP;
-   }
+   state->Buffer[I915_DESTREG_DRAWRECT0] = _3DSTATE_DRAWRECT_INFO;
+   state->Buffer[I915_DESTREG_DRAWRECT1] = 0;
+   state->Buffer[I915_DESTREG_DRAWRECT2] = 0; /* xmin, ymin */
+   state->Buffer[I915_DESTREG_DRAWRECT3] =
+      (ctx->DrawBuffer->Width & 0xffff) |
+      (ctx->DrawBuffer->Height << 16);
+   state->Buffer[I915_DESTREG_DRAWRECT4] = 0; /* xoff, yoff */
+   state->Buffer[I915_DESTREG_DRAWRECT5] = 0;
 
    I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS);
 }
@@ -667,15 +649,6 @@
     * difficulties associated with them (physical address requirements).
     */
    i915->state.emitted = 0;
-
-   /* Check that we didn't just wrap our batchbuffer at a bad time. */
-   assert(!intel->no_batch_wrap);
-}
-
-static GLuint
-i915_flush_cmd(void)
-{
-   return MI_FLUSH | FLUSH_MAP_CACHE;
 }
 
 static void 
@@ -699,7 +672,6 @@
    i915->intel.vtbl.render_prevalidate = i915_render_prevalidate;
    i915->intel.vtbl.set_draw_region = i915_set_draw_region;
    i915->intel.vtbl.update_texture_state = i915UpdateTextureState;
-   i915->intel.vtbl.flush_cmd = i915_flush_cmd;
    i915->intel.vtbl.assert_not_dirty = i915_assert_not_dirty;
    i915->intel.vtbl.finish_batch = intel_finish_vb;
 }
diff --git a/src/mesa/drivers/dri/i915/intel_render.c b/src/mesa/drivers/dri/i915/intel_render.c
index 410052b..ec20939 100644
--- a/src/mesa/drivers/dri/i915/intel_render.c
+++ b/src/mesa/drivers/dri/i915/intel_render.c
@@ -117,7 +117,7 @@
    intel_set_prim(intel, hw_prim[prim]);
 }
 
-static inline GLuint intel_get_vb_max(struct intel_context *intel)
+static INLINE GLuint intel_get_vb_max(struct intel_context *intel)
 {
    GLuint ret;
 
@@ -129,7 +129,7 @@
    return ret;
 }
 
-static inline GLuint intel_get_current_max(struct intel_context *intel)
+static INLINE GLuint intel_get_current_max(struct intel_context *intel)
 {
 
    if (intel->intelScreen->no_vbo)
diff --git a/src/mesa/drivers/dri/i915/intel_swapbuffers.c b/src/mesa/drivers/dri/i915/intel_swapbuffers.c
deleted file mode 120000
index 148d521..0000000
--- a/src/mesa/drivers/dri/i915/intel_swapbuffers.c
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_swapbuffers.c
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c
index bc527aa..e99baf8 100644
--- a/src/mesa/drivers/dri/i915/intel_tris.c
+++ b/src/mesa/drivers/dri/i915/intel_tris.c
@@ -89,7 +89,6 @@
 
 static void intel_start_inline(struct intel_context *intel, uint32_t prim)
 {
-   uint32_t batch_flags = LOOP_CLIPRECTS;
    BATCH_LOCALS;
 
    intel->vtbl.emit_state(intel);
@@ -101,7 +100,7 @@
    /* Emit a slot which will be filled with the inline primitive
     * command later.
     */
-   BEGIN_BATCH(2, batch_flags);
+   BEGIN_BATCH(2);
    OUT_BATCH(0);
 
    assert((intel->batch->dirty_state & (1<<1)) == 0);
@@ -221,7 +220,7 @@
    intel->prim.count = 0;
    offset = intel->prim.start_offset;
    intel->prim.start_offset = intel->prim.current_offset;
-   if (!IS_9XX(intel->intelScreen->deviceID))
+   if (!intel->gen >= 3)
       intel->prim.start_offset = ALIGN(intel->prim.start_offset, 128);
    intel->prim.flush = NULL;
 
@@ -251,8 +250,8 @@
 	  intel->vertex_size * 4);
 #endif
 
-   if (IS_9XX(intel->intelScreen->deviceID)) {
-      BEGIN_BATCH(5, LOOP_CLIPRECTS);
+   if (intel->gen >= 3) {
+      BEGIN_BATCH(5);
       OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
 		I1_LOAD_S(0) | I1_LOAD_S(1) | 1);
       assert((offset & !S0_VB_OFFSET_MASK) == 0);
@@ -270,7 +269,7 @@
    } else {
       struct i830_context *i830 = i830_context(&intel->ctx);
 
-      BEGIN_BATCH(5, LOOP_CLIPRECTS);
+      BEGIN_BATCH(5);
       OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
 		I1_LOAD_S(0) | I1_LOAD_S(2) | 1);
       /* S0 */
@@ -1250,81 +1249,6 @@
    GLint i;
 };
 
-
-/**********************************************************************/
-/*             Used only with the metaops callbacks.                  */
-/**********************************************************************/
-static void
-intel_meta_draw_poly(struct intel_context *intel,
-                     GLuint n,
-                     GLfloat xy[][2],
-                     GLfloat z, GLuint color, GLfloat tex[][2])
-{
-   union fi *vb;
-   GLint i;
-   unsigned int saved_vertex_size = intel->vertex_size;
-
-   LOCK_HARDWARE(intel);
-
-   intel->vertex_size = 6;
-
-   /* All 3d primitives should be emitted with LOOP_CLIPRECTS,
-    * otherwise the drawing origin (DR4) might not be set correctly.
-    */
-   intel_set_prim(intel, PRIM3D_TRIFAN);
-   vb = (union fi *) intel_get_prim_space(intel, n);
-
-   for (i = 0; i < n; i++) {
-      vb[0].f = xy[i][0];
-      vb[1].f = xy[i][1];
-      vb[2].f = z;
-      vb[3].i = color;
-      vb[4].f = tex[i][0];
-      vb[5].f = tex[i][1];
-      vb += 6;
-   }
-
-   INTEL_FIREVERTICES(intel);
-
-   intel->vertex_size = saved_vertex_size;
-
-   UNLOCK_HARDWARE(intel);
-}
-
-static void
-intel_meta_draw_quad(struct intel_context *intel,
-                     GLfloat x0, GLfloat x1,
-                     GLfloat y0, GLfloat y1,
-                     GLfloat z,
-                     GLuint color,
-                     GLfloat s0, GLfloat s1, GLfloat t0, GLfloat t1)
-{
-   GLfloat xy[4][2];
-   GLfloat tex[4][2];
-
-   xy[0][0] = x0;
-   xy[0][1] = y0;
-   xy[1][0] = x1;
-   xy[1][1] = y0;
-   xy[2][0] = x1;
-   xy[2][1] = y1;
-   xy[3][0] = x0;
-   xy[3][1] = y1;
-
-   tex[0][0] = s0;
-   tex[0][1] = t0;
-   tex[1][0] = s1;
-   tex[1][1] = t0;
-   tex[2][0] = s1;
-   tex[2][1] = t1;
-   tex[3][0] = s0;
-   tex[3][1] = t1;
-
-   intel_meta_draw_poly(intel, 4, xy, z, color, tex);
-}
-
-
-
 /**********************************************************************/
 /*                            Initialization.                         */
 /**********************************************************************/
@@ -1333,7 +1257,6 @@
 void
 intelInitTriFuncs(GLcontext * ctx)
 {
-   struct intel_context *intel = intel_context(ctx);
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    static int firsttime = 1;
 
@@ -1350,6 +1273,4 @@
    tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
    tnl->Driver.Render.CopyPV = _tnl_copy_pv;
    tnl->Driver.Render.Interp = _tnl_interp;
-
-   intel->vtbl.meta_draw_quad = intel_meta_draw_quad;
 }
diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile
index 7a55333..7758a79 100644
--- a/src/mesa/drivers/dri/i965/Makefile
+++ b/src/mesa/drivers/dri/i965/Makefile
@@ -24,7 +24,6 @@
 	intel_pixel_draw.c \
 	intel_pixel_read.c \
 	intel_state.c \
-	intel_swapbuffers.c \
 	intel_syncobj.c \
 	intel_tex.c \
 	intel_tex_copy.c \
@@ -96,7 +95,8 @@
 
 DRIVER_DEFINES = -I../intel -I../intel/server
 
-DRI_LIB_DEPS += -ldrm_intel
+INCLUDES += $(INTEL_CFLAGS)
+DRI_LIB_DEPS += $(INTEL_LIBS)
 
 include ../Makefile.template
 
diff --git a/src/mesa/drivers/dri/i965/brw_cc.c b/src/mesa/drivers/dri/i965/brw_cc.c
index 5cca605..bac1c3a 100644
--- a/src/mesa/drivers/dri/i965/brw_cc.c
+++ b/src/mesa/drivers/dri/i965/brw_cc.c
@@ -34,6 +34,7 @@
 #include "brw_state.h"
 #include "brw_defines.h"
 #include "brw_util.h"
+#include "intel_fbo.h"
 #include "main/macros.h"
 #include "main/enums.h"
 
@@ -55,7 +56,8 @@
    }
 
    dri_bo_unreference(brw->cc.vp_bo);
-   brw->cc.vp_bo = brw_cache_data( &brw->cache, BRW_CC_VP, &ccv, NULL, 0 );
+   brw->cc.vp_bo = brw_cache_data(&brw->cache, BRW_CC_VP, &ccv, sizeof(ccv),
+				  NULL, 0);
 }
 
 const struct brw_tracked_state brw_cc_vp = {
@@ -88,6 +90,28 @@
    GLenum depth_func;
 };
 
+/**
+ * Modify blend function to force destination alpha to 1.0
+ *
+ * If \c function specifies a blend function that uses destination alpha,
+ * replace it with a function that hard-wires destination alpha to 1.0.  This
+ * is used when rendering to xRGB targets.
+ */
+static GLenum
+fix_xRGB_alpha(GLenum function)
+{
+   switch (function) {
+   case GL_DST_ALPHA:
+      return GL_ONE;
+
+   case GL_ONE_MINUS_DST_ALPHA:
+   case GL_SRC_ALPHA_SATURATE:
+      return GL_ZERO;
+   }
+
+   return function;
+}
+
 static void
 cc_unit_populate_key(struct brw_context *brw, struct brw_cc_unit_key *key)
 {
@@ -131,6 +155,17 @@
       key->blend_dst_rgb = ctx->Color.BlendDstRGB;
       key->blend_src_a = ctx->Color.BlendSrcA;
       key->blend_dst_a = ctx->Color.BlendDstA;
+
+      /* If the renderbuffer is XRGB, we have to frob the blend function to
+       * force the destination alpha to 1.0.  This means replacing GL_DST_ALPHA
+       * with GL_ONE and GL_ONE_MINUS_DST_ALPHA with GL_ZERO.
+       */
+      if (ctx->DrawBuffer->Visual.alphaBits == 0) {
+	 key->blend_src_rgb = fix_xRGB_alpha(key->blend_src_rgb);
+	 key->blend_src_a   = fix_xRGB_alpha(key->blend_src_a);
+	 key->blend_dst_rgb = fix_xRGB_alpha(key->blend_dst_rgb);
+	 key->blend_dst_a   = fix_xRGB_alpha(key->blend_dst_a);
+      }
    }
 
    key->alpha_enabled = ctx->Color.AlphaEnabled;
diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c
index 20a927c..af1d975 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.c
+++ b/src/mesa/drivers/dri/i965/brw_clip.c
@@ -50,6 +50,7 @@
 static void compile_clip_prog( struct brw_context *brw,
 			     struct brw_clip_prog_key *key )
 {
+   struct intel_context *intel = &brw->intel;
    struct brw_clip_compile c;
    const GLuint *program;
    GLuint program_size;
@@ -65,27 +66,26 @@
    c.func.single_program_flow = 1;
 
    c.key = *key;
-   c.need_ff_sync = BRW_IS_IGDNG(brw);
 
    /* Need to locate the two positions present in vertex + header.
     * These are currently hardcoded:
     */
    c.header_position_offset = ATTR_SIZE;
 
-   if (BRW_IS_IGDNG(brw))
+   if (intel->is_ironlake)
        delta = 3 * REG_SIZE;
    else
        delta = REG_SIZE;
 
    for (i = 0; i < VERT_RESULT_MAX; i++)
-      if (c.key.attrs & (1<<i)) {
+      if (c.key.attrs & BITFIELD64_BIT(i)) {
 	 c.offset[i] = delta;
 	 delta += ATTR_SIZE;
       }
 
    c.nr_attrs = brw_count_bits(c.key.attrs);
    
-   if (BRW_IS_IGDNG(brw))
+   if (intel->is_ironlake)
        c.nr_regs = (c.nr_attrs + 1) / 2 + 3;  /* are vertices packed, or reg-aligned? */
    else
        c.nr_regs = (c.nr_attrs + 1) / 2 + 1;  /* are vertices packed, or reg-aligned? */
@@ -143,7 +143,8 @@
  */
 static void upload_clip_prog(struct brw_context *brw)
 {
-   GLcontext *ctx = &brw->intel.ctx;
+   struct intel_context *intel = &brw->intel;
+   GLcontext *ctx = &intel->ctx;
    struct brw_clip_prog_key key;
 
    memset(&key, 0, sizeof(key));
@@ -156,10 +157,11 @@
    key.attrs = brw->vs.prog_data->outputs_written;
    /* _NEW_LIGHT */
    key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT);
+   key.pv_first = (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION);
    /* _NEW_TRANSFORM */
    key.nr_userclip = brw_count_bits(ctx->Transform.ClipPlanesEnabled);
 
-   if (BRW_IS_IGDNG(brw))
+   if (intel->is_ironlake)
        key.clip_mode = BRW_CLIPMODE_KERNEL_CLIP;
    else
        key.clip_mode = BRW_CLIPMODE_NORMAL;
diff --git a/src/mesa/drivers/dri/i965/brw_clip.h b/src/mesa/drivers/dri/i965/brw_clip.h
index 957df44..d71bac7 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.h
+++ b/src/mesa/drivers/dri/i965/brw_clip.h
@@ -42,22 +42,21 @@
  * up polygon offset and flatshading at this point:
  */
 struct brw_clip_prog_key {
-   GLuint attrs:32;		
+   GLbitfield64 attrs;
    GLuint primitive:4;
    GLuint nr_userclip:3;
    GLuint do_flat_shading:1;
+   GLuint pv_first:1;
    GLuint do_unfilled:1;
    GLuint fill_cw:2;		/* includes cull information */
    GLuint fill_ccw:2;		/* includes cull information */
    GLuint offset_cw:1;
    GLuint offset_ccw:1;
-   GLuint pad0:17;
-
    GLuint copy_bfc_cw:1;
    GLuint copy_bfc_ccw:1;
    GLuint clip_mode:3;
-   GLuint pad1:27;
-   
+   GLuint pad0:11;
+
    GLfloat offset_factor;
    GLfloat offset_units;
 };
@@ -119,7 +118,6 @@
 
    GLuint header_position_offset;
    GLuint offset[VERT_ATTRIB_MAX];
-   GLboolean need_ff_sync;
 };
 
 #define ATTR_SIZE  (4*4)
diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c
index 048ca62..afc0b11 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_line.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_line.c
@@ -46,6 +46,7 @@
 
 static void brw_clip_line_alloc_regs( struct brw_clip_compile *c )
 {
+   struct intel_context *intel = &c->func.brw->intel;
    GLuint i = 0,j;
 
    /* Register usage is static, precompute here:
@@ -85,7 +86,7 @@
       i++;
    }
 
-   if (c->need_ff_sync) {
+   if (intel->needs_ff_sync) {
       c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
       i++;
    }
@@ -126,6 +127,7 @@
 static void clip_and_emit_line( struct brw_clip_compile *c )
 {
    struct brw_compile *p = &c->func;
+   struct brw_context *brw = p->brw;
    struct brw_indirect vtx0     = brw_indirect(0, 0);
    struct brw_indirect vtx1      = brw_indirect(1, 0);
    struct brw_indirect newvtx0   = brw_indirect(2, 0);
@@ -152,7 +154,7 @@
    brw_clip_init_clipmask(c);
 
    /* -ve rhw workaround */
-   if (BRW_IS_965(p->brw)) {
+   if (brw->has_negative_rhw_bug) {
       brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
       brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
               brw_imm_ud(1<<20));
@@ -189,7 +191,7 @@
               * Both can be negative on GM965/G965 due to RHW workaround
               * if so, this object should be rejected.
               */
-             if (BRW_IS_965(p->brw)) {
+             if (brw->has_negative_rhw_bug) {
                  brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, c->reg.dp0, brw_imm_f(0.0));
                  is_neg2 = brw_IF(p, BRW_EXECUTE_1);
                  {
@@ -214,7 +216,7 @@
 
              /* If both are positive, do nothing */
              /* Only on GM965/G965 */
-             if (BRW_IS_965(p->brw)) {
+             if (brw->has_negative_rhw_bug) {
                  brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0));
                  is_neg2 = brw_IF(p, BRW_EXECUTE_1);
              }
@@ -229,7 +231,7 @@
                  brw_set_predicate_control(p, BRW_PREDICATE_NONE);
              }
 
-             if (BRW_IS_965(p->brw)) {
+             if (brw->has_negative_rhw_bug) {
                  brw_ENDIF(p, is_neg2);
              }
          }
@@ -269,8 +271,12 @@
    brw_clip_line_alloc_regs(c);
    brw_clip_init_ff_sync(c);
 
-   if (c->key.do_flat_shading)
-      brw_clip_copy_colors(c, 0, 1);
+   if (c->key.do_flat_shading) {
+      if (c->key.pv_first)
+         brw_clip_copy_colors(c, 1, 0);
+      else
+         brw_clip_copy_colors(c, 0, 1);
+   }
                 
    clip_and_emit_line(c);
 }
diff --git a/src/mesa/drivers/dri/i965/brw_clip_state.c b/src/mesa/drivers/dri/i965/brw_clip_state.c
index 234b374..c8f24a9 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_state.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_state.c
@@ -74,6 +74,7 @@
 clip_unit_create_from_key(struct brw_context *brw,
 			  struct brw_clip_unit_key *key)
 {
+   struct intel_context *intel = &brw->intel;
    struct brw_clip_unit_state clip;
    dri_bo *bo;
 
@@ -105,7 +106,7 @@
       /* Although up to 16 concurrent Clip threads are allowed on IGDNG, 
        * only 2 threads can output VUEs at a time.
        */
-      if (BRW_IS_IGDNG(brw))
+      if (intel->is_ironlake)
          clip.thread4.max_threads = 16 - 1;        
       else
          clip.thread4.max_threads = 2 - 1;
@@ -130,7 +131,7 @@
    clip.clip5.api_mode = BRW_CLIP_API_OGL;
    clip.clip5.clip_mode = key->clip_mode;
 
-   if (BRW_IS_G4X(brw))
+   if (intel->is_g4x)
       clip.clip5.negative_w_clip_test = 1;
 
    clip.clip6.clipper_viewport_state_ptr = 0;
diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c
index 0efd772..cfbb8f2 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_tri.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c
@@ -51,6 +51,7 @@
 void brw_clip_tri_alloc_regs( struct brw_clip_compile *c, 
 			      GLuint nr_verts )
 {
+   struct intel_context *intel = &c->func.brw->intel;
    GLuint i = 0,j;
 
    /* Register usage is static, precompute here:
@@ -78,7 +79,7 @@
       for (j = 0; j < 3; j++) {
 	 GLuint delta = c->nr_attrs*16 + 32;
 
-         if (BRW_IS_IGDNG(c->func.brw))
+         if (intel->is_ironlake)
              delta = c->nr_attrs * 16 + 32 * 3;
 
 	 brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0));
@@ -119,7 +120,7 @@
       i++;
    }
 
-   if (c->need_ff_sync) {
+   if (intel->needs_ff_sync) {
       c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
       i++;
    }
@@ -188,14 +189,20 @@
 	   brw_imm_ud(_3DPRIM_POLYGON));
 
    is_poly = brw_IF(p, BRW_EXECUTE_1);
-   {   
+   {
       brw_clip_copy_colors(c, 1, 0);
       brw_clip_copy_colors(c, 2, 0);
    }
    is_poly = brw_ELSE(p, is_poly);
    {
-      brw_clip_copy_colors(c, 0, 2);
-      brw_clip_copy_colors(c, 1, 2);
+      if (c->key.pv_first) {
+         brw_clip_copy_colors(c, 1, 0);
+         brw_clip_copy_colors(c, 2, 0);
+      }
+      else {
+         brw_clip_copy_colors(c, 0, 2);
+         brw_clip_copy_colors(c, 1, 2);
+      }
    }
    brw_ENDIF(p, is_poly);
 }
@@ -565,6 +572,7 @@
 {
    struct brw_instruction *neg_rhw;
    struct brw_compile *p = &c->func;
+   struct brw_context *brw = p->brw;
    brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
    brw_clip_tri_init_vertices(c);
    brw_clip_init_clipmask(c);
@@ -572,7 +580,7 @@
 
    /* if -ve rhw workaround bit is set, 
       do cliptest */
-   if (BRW_IS_965(p->brw)) {
+   if (brw->has_negative_rhw_bug) {
       brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
       brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), 
               brw_imm_ud(1<<20));
diff --git a/src/mesa/drivers/dri/i965/brw_clip_util.c b/src/mesa/drivers/dri/i965/brw_clip_util.c
index 5a73abd..86fed59 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_util.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_util.c
@@ -135,6 +135,7 @@
 			     GLboolean force_edgeflag)
 {
    struct brw_compile *p = &c->func;
+   struct intel_context *intel = &p->brw->intel;
    struct brw_reg tmp = get_tmp(c);
    GLuint i;
 
@@ -142,7 +143,7 @@
     */
    /*
     * After CLIP stage, only first 256 bits of the VUE are read
-    * back on IGDNG, so needn't change it
+    * back on Ironlake, so needn't change it
     */
    brw_copy_indirect_to_indirect(p, dest_ptr, v0_ptr, 1);
       
@@ -151,7 +152,7 @@
    for (i = 0; i < c->nr_attrs; i++) {
       GLuint delta = i*16 + 32;
 
-      if (BRW_IS_IGDNG(p->brw))
+      if (intel->is_ironlake)
           delta = i * 16 + 32 * 3;
 
       if (delta == c->offset[VERT_RESULT_EDGE]) {
@@ -185,7 +186,7 @@
    if (i & 1) {
       GLuint delta = i*16 + 32;
 
-      if (BRW_IS_IGDNG(p->brw))
+      if (intel->is_ironlake)
           delta = i * 16 + 32 * 3;
 
       brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0));
@@ -359,7 +360,9 @@
 
 void brw_clip_ff_sync(struct brw_clip_compile *c)
 {
-    if (c->need_ff_sync) {
+    struct intel_context *intel = &c->func.brw->intel;
+
+    if (intel->needs_ff_sync) {
         struct brw_compile *p = &c->func;
         struct brw_instruction *need_ff_sync;
 
@@ -388,7 +391,9 @@
 
 void brw_clip_init_ff_sync(struct brw_clip_compile *c)
 {
-    if (c->need_ff_sync) {
+    struct intel_context *intel = &c->func.brw->intel;
+
+    if (intel->needs_ff_sync) {
 	struct brw_compile *p = &c->func;
         
         brw_MOV(p, c->reg.ff_sync, brw_imm_ud(0));
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 48685c0..7bb1595 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -77,7 +77,7 @@
 }
 
 GLboolean brwCreateContext( const __GLcontextModes *mesaVis,
-			    __DRIcontextPrivate *driContextPriv,
+			    __DRIcontext *driContextPriv,
 			    void *sharedContextPrivate)
 {
    struct dd_function_table functions;
@@ -111,6 +111,9 @@
    ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits,
                                      ctx->Const.MaxTextureImageUnits);
    ctx->Const.MaxVertexTextureImageUnits = 0; /* no vertex shader textures */
+   ctx->Const.MaxCombinedTextureImageUnits =
+      ctx->Const.MaxVertexTextureImageUnits +
+      ctx->Const.MaxTextureImageUnits;
 
    /* Mesa limits textures to 4kx4k; it would be nice to fix that someday
     */
@@ -155,6 +158,38 @@
       MIN2(ctx->Const.FragmentProgram.MaxNativeParameters,
 	   ctx->Const.FragmentProgram.MaxEnvParams);
 
+   if (intel->is_ironlake || intel->is_g4x) {
+      brw->CMD_VF_STATISTICS = CMD_VF_STATISTICS_GM45;
+      brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_GM45;
+      brw->has_surface_tile_offset = GL_TRUE;
+      brw->has_compr4 = GL_TRUE;
+      brw->has_aa_line_parameters = GL_TRUE;
+  } else {
+      brw->CMD_VF_STATISTICS = CMD_VF_STATISTICS_965;
+      brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_965;
+   }
+
+   /* WM maximum threads is number of EUs times number of threads per EU. */
+   if (intel->is_ironlake) {
+      brw->urb.size = 1024;
+      brw->vs_max_threads = 72;
+      brw->wm_max_threads = 12 * 6;
+   } else if (intel->is_g4x) {
+      brw->urb.size = 384;
+      brw->vs_max_threads = 32;
+      brw->wm_max_threads = 10 * 5;
+   } else {
+      brw->urb.size = 256;
+      brw->vs_max_threads = 16;
+      brw->wm_max_threads = 8 * 4;
+      brw->has_negative_rhw_bug = GL_TRUE;
+   }
+
+   if (INTEL_DEBUG & DEBUG_SINGLE_THREAD) {
+      brw->vs_max_threads = 1;
+      brw->wm_max_threads = 1;
+   }
+
    brw_init_state( brw );
 
    brw->state.dirty.mesa = ~0;
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 59f9475..0dd3087 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -172,8 +172,8 @@
    GLuint id;  /**< serial no. to identify frag progs, never re-used */
    GLboolean isGLSL;  /**< really, any IF/LOOP/CONT/BREAK instructions */
 
-   dri_bo *const_buffer;    /** Program constant buffer/surface */
    GLboolean use_const_buffer;
+   dri_bo *const_buffer;    /** Program constant buffer/surface */
 
    /** for debugging, which texture units are referenced */
    GLbitfield tex_units_used;
@@ -231,7 +231,7 @@
    GLuint curb_read_length;
    GLuint urb_read_length;
    GLuint total_grf;
-   GLuint outputs_written;
+   GLbitfield64 outputs_written;
    GLuint nr_params;       /**< number of float params/constants */
 
    GLuint inputs_read;
@@ -320,7 +320,6 @@
    GLuint nr_reloc_bufs;
 
    dri_bo *bo;
-   GLuint data_size;
 
    struct brw_cache_item *next;
 };   
@@ -333,7 +332,6 @@
    struct brw_cache_item **items;
    GLuint size, n_items;
 
-   GLuint key_size[BRW_MAX_CACHE];		/* for fixed-size keys */
    GLuint aux_size[BRW_MAX_CACHE];
    char *name[BRW_MAX_CACHE];
 
@@ -413,23 +411,6 @@
    GLuint sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[VERT_ATTRIB_MAX] */
 };
 
-
-
-
-/* Cache for TNL programs.
- */
-struct brw_tnl_cache_item {
-   GLuint hash;
-   void *key;
-   void *data;
-   struct brw_tnl_cache_item *next;
-};
-
-struct brw_tnl_cache {
-   struct brw_tnl_cache_item **items;
-   GLuint size, n_items;
-};
-
 struct brw_query_object {
    struct gl_query_object Base;
 
@@ -457,8 +438,11 @@
    GLuint primitive;
 
    GLboolean emit_state_always;
-   GLboolean no_batch_wrap;
-
+   GLboolean has_surface_tile_offset;
+   GLboolean has_compr4;
+   GLboolean has_negative_rhw_bug;
+   GLboolean has_aa_line_parameters;
+;
    struct {
       struct brw_state_flags dirty;
 
@@ -534,6 +518,12 @@
     */
    GLuint next_free_page;
 
+   /* hw-dependent 3DSTATE_VF_STATISTICS opcode */
+   uint32_t CMD_VF_STATISTICS;
+   /* hw-dependent 3DSTATE_PIPELINE_SELECT opcode */
+   uint32_t CMD_PIPELINE_SELECT;
+   int vs_max_threads;
+   int wm_max_threads;
 
    /* BRW_NEW_URB_ALLOCATIONS:
     */
@@ -561,6 +551,7 @@
       GLuint clip_start;
       GLuint sf_start;
       GLuint cs_start;
+      GLuint size; /* Hardware URB size, in KB. */
    } urb;
 
    
@@ -688,7 +679,7 @@
  * brw_context.c
  */
 GLboolean brwCreateContext( const __GLcontextModes *mesaVis,
-			    __DRIcontextPrivate *driContextPriv,
+			    __DRIcontext *driContextPriv,
 			    void *sharedContextPrivate);
 
 /*======================================================================
@@ -761,9 +752,5 @@
    return (const struct brw_fragment_program *) p;
 }
 
-
-
-#define DO_SETUP_BITS ((1<<(FRAG_ATTRIB_MAX)) - 1)
-
 #endif
 
diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c
index 4be6c77..190310a 100644
--- a/src/mesa/drivers/dri/i965/brw_curbe.c
+++ b/src/mesa/drivers/dri/i965/brw_curbe.c
@@ -130,7 +130,7 @@
 const struct brw_tracked_state brw_curbe_offsets = {
    .dirty = {
       .mesa = _NEW_TRANSFORM,
-      .brw  = BRW_NEW_VERTEX_PROGRAM,
+      .brw  = BRW_NEW_VERTEX_PROGRAM | BRW_NEW_CONTEXT,
       .cache = CACHE_NEW_WM_PROG
    },
    .prepare = calculate_curbe_offsets
@@ -340,7 +340,7 @@
    struct intel_context *intel = &brw->intel;
    GLuint sz = brw->curbe.total_size;
 
-   BEGIN_BATCH(2, IGNORE_CLIPRECTS);
+   BEGIN_BATCH(2);
    if (sz == 0) {
       OUT_BATCH((CMD_CONST_BUFFER << 16) | (2 - 2));
       OUT_BATCH(0);
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index 78d457a..ea0d7e0 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -673,18 +673,10 @@
 #define BRW_SAMPLER_MESSAGE_SIMD8_LD                  3
 #define BRW_SAMPLER_MESSAGE_SIMD16_LD                 3
 
-#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_IGDNG            0
-#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_IGDNG          0
-#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_IGDNG           0
-#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_BIAS_IGDNG       1
-#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_BIAS_IGDNG     1
-#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS_IGDNG      1
-#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_LOD_IGDNG        2
-#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD_IGDNG      2
-#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD_IGDNG       2
-#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_COMPARE_IGDNG    3
-#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE_IGDNG  3
-#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE_IGDNG   3
+#define BRW_SAMPLER_MESSAGE_SAMPLE_IGDNG            0
+#define BRW_SAMPLER_MESSAGE_SAMPLE_BIAS_IGDNG       1
+#define BRW_SAMPLER_MESSAGE_SAMPLE_LOD_IGDNG        2
+#define BRW_SAMPLER_MESSAGE_SAMPLE_COMPARE_IGDNG    3
 
 /* for IGDNG only */
 #define BRW_SAMPLER_SIMD_MODE_SIMD4X2                   0
@@ -840,12 +832,4 @@
 
 #include "intel_chipset.h"
 
-#define BRW_IS_G4X(brw)         (IS_G4X((brw)->intel.intelScreen->deviceID))
-#define BRW_IS_IGDNG(brw)         (IS_IGDNG((brw)->intel.intelScreen->deviceID))
-#define BRW_IS_965(brw)         (!(BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)))
-#define CMD_PIPELINE_SELECT(brw)        ((BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? CMD_PIPELINE_SELECT_GM45 : CMD_PIPELINE_SELECT_965)
-#define CMD_VF_STATISTICS(brw)          ((BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? CMD_VF_STATISTICS_GM45 : CMD_VF_STATISTICS_965)
-#define URB_SIZES(brw)                  (BRW_IS_IGDNG(brw) ? 1024 : \
-                                         (BRW_IS_G4X(brw) ? 384 : 256))  /* 512 bit units */
-
 #endif
diff --git a/src/mesa/drivers/dri/i965/brw_disasm.c b/src/mesa/drivers/dri/i965/brw_disasm.c
index 9fef230..a8f6b99 100644
--- a/src/mesa/drivers/dri/i965/brw_disasm.c
+++ b/src/mesa/drivers/dri/i965/brw_disasm.c
@@ -239,7 +239,7 @@
     [2] = "UW",
     [3] = "W",
     [5] = "VF",
-    [5] = "V",
+    [6] = "V",
     [7] = "F"
 };
 
@@ -365,6 +365,7 @@
     va_start (args, format);
 
     vsnprintf (buf, sizeof (buf) - 1, format, args);
+    va_end (args);
     string (f, buf);
     return 0;
 }
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index 44bb7bd..df281b2 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -145,7 +145,7 @@
    prim_packet.base_vert_location = prim->basevertex;
 
    /* Can't wrap here, since we rely on the validated state. */
-   brw->no_batch_wrap = GL_TRUE;
+   intel->no_batch_wrap = GL_TRUE;
 
    /* If we're set to always flush, do it before and after the primitive emit.
     * We want to catch both missed flushes that hurt instruction/state cache
@@ -153,21 +153,17 @@
     * the besides the draw code.
     */
    if (intel->always_flush_cache) {
-      BEGIN_BATCH(1, IGNORE_CLIPRECTS);
-      OUT_BATCH(intel->vtbl.flush_cmd());
-      ADVANCE_BATCH();
+      intel_batchbuffer_emit_mi_flush(intel->batch);
    }
    if (prim_packet.verts_per_instance) {
       intel_batchbuffer_data( brw->intel.batch, &prim_packet,
-			      sizeof(prim_packet), LOOP_CLIPRECTS);
+			      sizeof(prim_packet));
    }
    if (intel->always_flush_cache) {
-      BEGIN_BATCH(1, IGNORE_CLIPRECTS);
-      OUT_BATCH(intel->vtbl.flush_cmd());
-      ADVANCE_BATCH();
+      intel_batchbuffer_emit_mi_flush(intel->batch);
    }
 
-   brw->no_batch_wrap = GL_FALSE;
+   intel->no_batch_wrap = GL_FALSE;
 }
 
 static void brw_merge_inputs( struct brw_context *brw,
@@ -343,13 +339,6 @@
     * so can't access it earlier.
     */
 
-   LOCK_HARDWARE(intel);
-
-   if (!intel->constant_cliprect && intel->driDrawable->numClipRects == 0) {
-      UNLOCK_HARDWARE(intel);
-      return GL_TRUE;
-   }
-
    for (i = 0; i < nr_prims; i++) {
       uint32_t hw_prim;
 
@@ -360,8 +349,7 @@
        * an upper bound of how much we might emit in a single
        * brw_try_draw_prims().
        */
-      intel_batchbuffer_require_space(intel->batch, intel->batch->size / 4,
-				      LOOP_CLIPRECTS);
+      intel_batchbuffer_require_space(intel->batch, intel->batch->size / 4);
 
       hw_prim = brw_set_prim(brw, prim[i].mode);
 
@@ -408,7 +396,6 @@
    if (intel->always_flush_batch)
       intel_batchbuffer_flush(intel->batch);
  out:
-   UNLOCK_HARDWARE(intel);
 
    brw_state_cache_check_size(brw);
 
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index 0fefbd9..c773b71 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -243,14 +243,6 @@
       dri_bo_unreference(brw->vb.upload.bo);
    brw->vb.upload.bo = dri_bo_alloc(brw->intel.bufmgr, "temporary VBO",
 				    size, 1);
-
-   /* Set the internal VBO\ to no-backing-store.  We only use them as a
-    * temporary within a brw_try_draw_prims while the lock is held.
-    */
-   /* DON'T DO THIS AS IF WE HAVE TO RE-ORG MEMORY WE NEED SOMEWHERE WITH
-      FAKE TO PUSH THIS STUFF */
-//   if (!brw->intel.ttm)
-//      dri_bo_fake_disable_backing_store(brw->vb.upload.bo, NULL, NULL);
 }
 
 static void get_space( struct brw_context *brw,
@@ -502,7 +494,7 @@
     * a VE loads from them.
     */
    if (brw->vb.nr_enabled == 0) {
-      BEGIN_BATCH(3, IGNORE_CLIPRECTS);
+      BEGIN_BATCH(3);
       OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | 1);
       OUT_BATCH((0 << BRW_VE0_INDEX_SHIFT) |
 		BRW_VE0_VALID |
@@ -522,7 +514,7 @@
     * are interleaved or from the same VBO.  TBD if this makes a
     * performance difference.
     */
-   BEGIN_BATCH(1 + brw->vb.nr_enabled * 4, IGNORE_CLIPRECTS);
+   BEGIN_BATCH(1 + brw->vb.nr_enabled * 4);
    OUT_BATCH((CMD_VERTEX_BUFFER << 16) |
 	     ((1 + brw->vb.nr_enabled * 4) - 2));
 
@@ -535,24 +527,17 @@
       OUT_RELOC(input->bo,
 		I915_GEM_DOMAIN_VERTEX, 0,
 		input->offset);
-      if (BRW_IS_IGDNG(brw)) {
-          if (input->stride) {
-              OUT_RELOC(input->bo,
-                        I915_GEM_DOMAIN_VERTEX, 0,
-                        input->offset + input->stride * input->count - 1);
-          } else {
-              assert(input->count == 1);
-              OUT_RELOC(input->bo,
-                        I915_GEM_DOMAIN_VERTEX, 0,
-                        input->offset + input->element_size - 1);
-          }
+      if (intel->is_ironlake) {
+	 OUT_RELOC(input->bo,
+		   I915_GEM_DOMAIN_VERTEX, 0,
+		   input->bo->size - 1);
       } else
           OUT_BATCH(input->stride ? input->count : 0);
       OUT_BATCH(0); /* Instance data step rate */
    }
    ADVANCE_BATCH();
 
-   BEGIN_BATCH(1 + brw->vb.nr_enabled * 2, IGNORE_CLIPRECTS);
+   BEGIN_BATCH(1 + brw->vb.nr_enabled * 2);
    OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | ((1 + brw->vb.nr_enabled * 2) - 2));
    for (i = 0; i < brw->vb.nr_enabled; i++) {
       struct brw_vertex_element *input = brw->vb.enabled[i];
@@ -578,7 +563,7 @@
 		(format << BRW_VE0_FORMAT_SHIFT) |
 		(0 << BRW_VE0_SRC_OFFSET_SHIFT));
 
-      if (BRW_IS_IGDNG(brw))
+      if (intel->is_ironlake)
           OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
                     (comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
                     (comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
@@ -719,7 +704,7 @@
       ib.header.bits.index_format = get_index_type(index_buffer->type);
       ib.header.bits.cut_index_enable = 0;
 
-      BEGIN_BATCH(4, IGNORE_CLIPRECTS);
+      BEGIN_BATCH(4);
       OUT_BATCH( ib.header.dword );
       OUT_RELOC(brw->ib.bo,
 		I915_GEM_DOMAIN_VERTEX, 0,
diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index 30603bd..39eb88d 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_eu.h
@@ -170,11 +170,11 @@
                                       GLuint writemask )
 {
    struct brw_reg reg;
-   if (type == BRW_GENERAL_REGISTER_FILE)
+   if (file == BRW_GENERAL_REGISTER_FILE)
       assert(nr < BRW_MAX_GRF);
-   else if (type == BRW_MESSAGE_REGISTER_FILE)
-      assert(nr < BRW_MAX_MRF);
-   else if (type == BRW_ARCHITECTURE_REGISTER_FILE)
+   else if (file == BRW_MESSAGE_REGISTER_FILE)
+      assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
+   else if (file == BRW_ARCHITECTURE_REGISTER_FILE)
       assert(nr <= BRW_ARF_IP);
 
    reg.type = type;
@@ -538,7 +538,7 @@
 
 static INLINE struct brw_reg brw_message_reg( GLuint nr )
 {
-   assert(nr < BRW_MAX_MRF);
+   assert((nr & ~(1 << 7)) < BRW_MAX_MRF);
    return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE,
 		       nr,
 		       0);
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 241cdc3..8d6ac00 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -55,7 +55,8 @@
 static void brw_set_dest( struct brw_instruction *insn,
 			  struct brw_reg dest )
 {
-   if (dest.type != BRW_ARCHITECTURE_REGISTER_FILE)
+   if (dest.file != BRW_ARCHITECTURE_REGISTER_FILE &&
+       dest.file != BRW_MESSAGE_REGISTER_FILE)
       assert(dest.nr < 128);
 
    insn->bits1.da1.dest_reg_file = dest.file;
@@ -198,7 +199,7 @@
        * in the future:
        */
       assert (reg.address_mode == BRW_ADDRESS_DIRECT);
-      //assert (reg.file == BRW_GENERAL_REGISTER_FILE);
+      /* assert (reg.file == BRW_GENERAL_REGISTER_FILE); */
 
       if (insn->header.access_mode == BRW_ALIGN_1) {
 	 insn->bits3.da1.src1_subreg_nr = reg.subnr;
@@ -251,9 +252,10 @@
 				  GLboolean saturate,
 				  GLuint dataType )
 {
+   struct intel_context *intel = &brw->intel;
    brw_set_src1(insn, brw_imm_d(0));
 
-   if (BRW_IS_IGDNG(brw)) {
+   if (intel->is_ironlake) {
        insn->bits3.math_igdng.function = function;
        insn->bits3.math_igdng.int_type = integer_type;
        insn->bits3.math_igdng.precision = low_precision;
@@ -318,9 +320,10 @@
 				 GLuint offset,
 				 GLuint swizzle_control )
 {
+    struct intel_context *intel = &brw->intel;
     brw_set_src1(insn, brw_imm_d(0));
 
-    if (BRW_IS_IGDNG(brw)) {
+    if (intel->is_ironlake) {
         insn->bits3.urb_igdng.opcode = 0;	/* ? */
         insn->bits3.urb_igdng.offset = offset;
         insn->bits3.urb_igdng.swizzle_control = swizzle_control;
@@ -357,9 +360,10 @@
 				      GLuint response_length,
 				      GLuint end_of_thread )
 {
+   struct intel_context *intel = &brw->intel;
    brw_set_src1(insn, brw_imm_d(0));
 
-   if (BRW_IS_IGDNG(brw)) {
+   if (intel->is_ironlake) {
        insn->bits3.dp_write_igdng.binding_table_index = binding_table_index;
        insn->bits3.dp_write_igdng.msg_control = msg_control;
        insn->bits3.dp_write_igdng.pixel_scoreboard_clear = pixel_scoreboard_clear;
@@ -394,9 +398,10 @@
 				      GLuint response_length,
 				      GLuint end_of_thread )
 {
+   struct intel_context *intel = &brw->intel;
    brw_set_src1(insn, brw_imm_d(0));
 
-   if (BRW_IS_IGDNG(brw)) {
+   if (intel->is_ironlake) {
        insn->bits3.dp_read_igdng.binding_table_index = binding_table_index;
        insn->bits3.dp_read_igdng.msg_control = msg_control;
        insn->bits3.dp_read_igdng.msg_type = msg_type;
@@ -432,10 +437,11 @@
                                     GLuint header_present,
                                     GLuint simd_mode)
 {
+   struct intel_context *intel = &brw->intel;
    assert(eot == 0);
    brw_set_src1(insn, brw_imm_d(0));
 
-   if (BRW_IS_IGDNG(brw)) {
+   if (intel->is_ironlake) {
       insn->bits3.sampler_igdng.binding_table_index = binding_table_index;
       insn->bits3.sampler_igdng.sampler = sampler;
       insn->bits3.sampler_igdng.msg_type = msg_type;
@@ -446,7 +452,7 @@
       insn->bits3.sampler_igdng.end_of_thread = eot;
       insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_SAMPLER;
       insn->bits2.send_igdng.end_of_thread = eot;
-   } else if (BRW_IS_G4X(brw)) {
+   } else if (intel->is_g4x) {
       insn->bits3.sampler_g4x.binding_table_index = binding_table_index;
       insn->bits3.sampler_g4x.sampler = sampler;
       insn->bits3.sampler_g4x.msg_type = msg_type;
@@ -647,10 +653,11 @@
 struct brw_instruction *brw_ELSE(struct brw_compile *p, 
 				 struct brw_instruction *if_insn)
 {
+   struct intel_context *intel = &p->brw->intel;
    struct brw_instruction *insn;
    GLuint br = 1;
 
-   if (BRW_IS_IGDNG(p->brw))
+   if (intel->is_ironlake)
       br = 2;
 
    if (p->single_program_flow) {
@@ -689,9 +696,10 @@
 void brw_ENDIF(struct brw_compile *p, 
 	       struct brw_instruction *patch_insn)
 {
+   struct intel_context *intel = &p->brw->intel;
    GLuint br = 1;
 
-   if (BRW_IS_IGDNG(p->brw))
+   if (intel->is_ironlake)
       br = 2; 
  
    if (p->single_program_flow) {
@@ -802,10 +810,11 @@
 struct brw_instruction *brw_WHILE(struct brw_compile *p, 
                                   struct brw_instruction *do_insn)
 {
+   struct intel_context *intel = &p->brw->intel;
    struct brw_instruction *insn;
    GLuint br = 1;
 
-   if (BRW_IS_IGDNG(p->brw))
+   if (intel->is_ironlake)
       br = 2;
 
    if (p->single_program_flow)
@@ -845,14 +854,15 @@
 void brw_land_fwd_jump(struct brw_compile *p, 
 		       struct brw_instruction *jmp_insn)
 {
+   struct intel_context *intel = &p->brw->intel;
    struct brw_instruction *landing = &p->store[p->nr_insn];
    GLuint jmpi = 1;
 
-   if (BRW_IS_IGDNG(p->brw))
+   if (intel->is_ironlake)
        jmpi = 2;
 
    assert(jmp_insn->header.opcode == BRW_OPCODE_JMPI);
-   assert(jmp_insn->bits1.da1.src1_reg_file = BRW_IMMEDIATE_VALUE);
+   assert(jmp_insn->bits1.da1.src1_reg_file == BRW_IMMEDIATE_VALUE);
 
    jmp_insn->bits3.ud = jmpi * ((landing - jmp_insn) - 1);
 }
diff --git a/src/mesa/drivers/dri/i965/brw_fallback.c b/src/mesa/drivers/dri/i965/brw_fallback.c
index 562a178..fe5c1ae 100644
--- a/src/mesa/drivers/dri/i965/brw_fallback.c
+++ b/src/mesa/drivers/dri/i965/brw_fallback.c
@@ -47,7 +47,6 @@
 
 static GLboolean do_check_fallback(struct brw_context *brw)
 {
-   struct intel_context *intel = &brw->intel;
    GLcontext *ctx = &brw->intel.ctx;
    GLuint i;
 
@@ -86,8 +85,7 @@
    }
 
    /* _NEW_BUFFERS */
-   if (IS_965(intel->intelScreen->deviceID) &&
-       !IS_G4X(intel->intelScreen->deviceID)) {
+   if (!brw->has_surface_tile_offset) {
       for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
 	 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
 	 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c
index 48c2b9a..1bc3ecc 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.c
+++ b/src/mesa/drivers/dri/i965/brw_gs.c
@@ -47,6 +47,7 @@
 static void compile_gs_prog( struct brw_context *brw,
 			     struct brw_gs_prog_key *key )
 {
+   struct intel_context *intel = &brw->intel;
    struct brw_gs_compile c;
    const GLuint *program;
    GLuint program_size;
@@ -54,13 +55,12 @@
    memset(&c, 0, sizeof(c));
    
    c.key = *key;
-   c.need_ff_sync = BRW_IS_IGDNG(brw);
    /* Need to locate the two positions present in vertex + header.
     * These are currently hardcoded:
     */
    c.nr_attrs = brw_count_bits(c.key.attrs);
 
-   if (BRW_IS_IGDNG(brw))
+   if (intel->is_ironlake)
        c.nr_regs = (c.nr_attrs + 1) / 2 + 3;  /* are vertices packed, or reg-aligned? */
    else
        c.nr_regs = (c.nr_attrs + 1) / 2 + 1;  /* are vertices packed, or reg-aligned? */
@@ -85,10 +85,10 @@
     */
    switch (key->primitive) {
    case GL_QUADS:
-      brw_gs_quads( &c ); 
+      brw_gs_quads( &c, key );
       break;
    case GL_QUAD_STRIP:
-      brw_gs_quad_strip( &c );
+      brw_gs_quad_strip( &c, key );
       break;
    case GL_LINE_LOOP:
       brw_gs_lines( &c );
@@ -149,6 +149,7 @@
 static void populate_key( struct brw_context *brw,
 			  struct brw_gs_prog_key *key )
 {
+   GLcontext *ctx = &brw->intel.ctx;
    memset(key, 0, sizeof(*key));
 
    /* CACHE_NEW_VS_PROG */
@@ -158,6 +159,9 @@
    key->primitive = gs_prim[brw->primitive];
 
    key->hint_gs_always = 0;	/* debug code? */
+   
+   /* _NEW_LIGHT */
+   key->pv_first = (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION);
 
    key->need_gs_prog = (key->hint_gs_always ||
 			brw->primitive == GL_QUADS ||
@@ -193,7 +197,7 @@
 
 const struct brw_tracked_state brw_gs_prog = {
    .dirty = {
-      .mesa  = 0,
+      .mesa  = _NEW_LIGHT,
       .brw   = BRW_NEW_PRIMITIVE,
       .cache = CACHE_NEW_VS_PROG
    },
diff --git a/src/mesa/drivers/dri/i965/brw_gs.h b/src/mesa/drivers/dri/i965/brw_gs.h
index bbb991e..813b8d4 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.h
+++ b/src/mesa/drivers/dri/i965/brw_gs.h
@@ -40,11 +40,12 @@
 #define MAX_GS_VERTS (4)	     
 
 struct brw_gs_prog_key {
-   GLuint attrs:32;
+   GLbitfield64 attrs;
    GLuint primitive:4;
    GLuint hint_gs_always:1;
+   GLuint pv_first:1;
    GLuint need_gs_prog:1;
-   GLuint pad:26;
+   GLuint pad:25;
 };
 
 struct brw_gs_compile {
@@ -62,13 +63,12 @@
    GLuint nr_attrs;
    GLuint nr_regs;
    GLuint nr_bytes;
-   GLboolean need_ff_sync;
 };
 
 #define ATTR_SIZE  (4*4)
 
-void brw_gs_quads( struct brw_gs_compile *c );
-void brw_gs_quad_strip( struct brw_gs_compile *c );
+void brw_gs_quads( struct brw_gs_compile *c, struct brw_gs_prog_key *key );
+void brw_gs_quad_strip( struct brw_gs_compile *c, struct brw_gs_prog_key *key );
 void brw_gs_tris( struct brw_gs_compile *c );
 void brw_gs_lines( struct brw_gs_compile *c );
 void brw_gs_points( struct brw_gs_compile *c );
diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c b/src/mesa/drivers/dri/i965/brw_gs_emit.c
index a9b2aa2..a81b972 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c
@@ -120,38 +120,60 @@
 }
 
 
-void brw_gs_quads( struct brw_gs_compile *c )
+void brw_gs_quads( struct brw_gs_compile *c, struct brw_gs_prog_key *key )
 {
+   struct intel_context *intel = &c->func.brw->intel;
+
    brw_gs_alloc_regs(c, 4);
    
    /* Use polygons for correct edgeflag behaviour. Note that vertex 3
     * is the PV for quads, but vertex 0 for polygons:
     */
-   if (c->need_ff_sync)
-	   brw_gs_ff_sync(c, 1);    
-   brw_gs_emit_vue(c, c->reg.vertex[3], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START));
-   brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2));
-   brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_POLYGON << 2)); 
-   brw_gs_emit_vue(c, c->reg.vertex[2], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END));
+   if (intel->needs_ff_sync)
+	   brw_gs_ff_sync(c, 1);
+   if (key->pv_first) {
+      brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START));
+      brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_POLYGON << 2));
+      brw_gs_emit_vue(c, c->reg.vertex[2], 0, (_3DPRIM_POLYGON << 2));
+      brw_gs_emit_vue(c, c->reg.vertex[3], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END));
+   }
+   else {
+      brw_gs_emit_vue(c, c->reg.vertex[3], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START));
+      brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2));
+      brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_POLYGON << 2));
+      brw_gs_emit_vue(c, c->reg.vertex[2], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END));
+   }
 }
 
-void brw_gs_quad_strip( struct brw_gs_compile *c )
+void brw_gs_quad_strip( struct brw_gs_compile *c, struct brw_gs_prog_key *key )
 {
+   struct intel_context *intel = &c->func.brw->intel;
+
    brw_gs_alloc_regs(c, 4);
    
-   if (c->need_ff_sync)
+   if (intel->needs_ff_sync)
 	   brw_gs_ff_sync(c, 1);      
-   brw_gs_emit_vue(c, c->reg.vertex[2], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START));
-   brw_gs_emit_vue(c, c->reg.vertex[3], 0, (_3DPRIM_POLYGON << 2));
-   brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2)); 
-   brw_gs_emit_vue(c, c->reg.vertex[1], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END));
+   if (key->pv_first) {
+      brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START));
+      brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_POLYGON << 2));
+      brw_gs_emit_vue(c, c->reg.vertex[2], 0, (_3DPRIM_POLYGON << 2));
+      brw_gs_emit_vue(c, c->reg.vertex[3], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END));
+   }
+   else {
+      brw_gs_emit_vue(c, c->reg.vertex[2], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START));
+      brw_gs_emit_vue(c, c->reg.vertex[3], 0, (_3DPRIM_POLYGON << 2));
+      brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2));
+      brw_gs_emit_vue(c, c->reg.vertex[1], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END));
+   }
 }
 
 void brw_gs_tris( struct brw_gs_compile *c )
 {
+   struct intel_context *intel = &c->func.brw->intel;
+
    brw_gs_alloc_regs(c, 3);
 
-   if (c->need_ff_sync)
+   if (intel->needs_ff_sync)
 	   brw_gs_ff_sync(c, 1);      
    brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_TRILIST << 2) | R02_PRIM_START));
    brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_TRILIST << 2));
@@ -160,9 +182,11 @@
 
 void brw_gs_lines( struct brw_gs_compile *c )
 {
+   struct intel_context *intel = &c->func.brw->intel;
+
    brw_gs_alloc_regs(c, 2);
 
-   if (c->need_ff_sync)
+   if (intel->needs_ff_sync)
 	   brw_gs_ff_sync(c, 1);      
    brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_LINESTRIP << 2) | R02_PRIM_START));
    brw_gs_emit_vue(c, c->reg.vertex[1], 1, ((_3DPRIM_LINESTRIP << 2) | R02_PRIM_END));
@@ -170,9 +194,11 @@
 
 void brw_gs_points( struct brw_gs_compile *c )
 {
+   struct intel_context *intel = &c->func.brw->intel;
+
    brw_gs_alloc_regs(c, 1);
 
-   if (c->need_ff_sync)
+   if (intel->needs_ff_sync)
 	   brw_gs_ff_sync(c, 1);      
    brw_gs_emit_vue(c, c->reg.vertex[0], 1, ((_3DPRIM_POINTLIST << 2) | R02_PRIM_START | R02_PRIM_END));
 }
diff --git a/src/mesa/drivers/dri/i965/brw_gs_state.c b/src/mesa/drivers/dri/i965/brw_gs_state.c
index ed9d2ff..1af5790 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_state.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_state.c
@@ -72,6 +72,7 @@
 static dri_bo *
 gs_unit_create_from_key(struct brw_context *brw, struct brw_gs_unit_key *key)
 {
+   struct intel_context *intel = &brw->intel;
    struct brw_gs_unit_state gs;
    dri_bo *bo;
 
@@ -98,7 +99,7 @@
    else
       gs.thread4.max_threads = 0;
 
-   if (BRW_IS_IGDNG(brw))
+   if (intel->is_ironlake)
       gs.thread4.rendering_enable = 1;
 
    if (INTEL_DEBUG & DEBUG_STATS)
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index ea71857..7b70f78 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -66,7 +66,7 @@
 const struct brw_tracked_state brw_blend_constant_color = {
    .dirty = {
       .mesa = _NEW_COLOR,
-      .brw = 0,
+      .brw = BRW_NEW_CONTEXT,
       .cache = 0
    },
    .emit = upload_blend_constant_color
@@ -78,10 +78,7 @@
    struct intel_context *intel = &brw->intel;
    GLcontext *ctx = &intel->ctx;
 
-   if (!intel->constant_cliprect)
-      return;
-
-   BEGIN_BATCH(4, NO_LOOP_CLIPRECTS);
+   BEGIN_BATCH(4);
    OUT_BATCH(_3DSTATE_DRAWRECT_INFO_I965);
    OUT_BATCH(0); /* xmin, ymin */
    OUT_BATCH(((ctx->DrawBuffer->Width - 1) & 0xffff) |
@@ -93,7 +90,7 @@
 const struct brw_tracked_state brw_drawing_rect = {
    .dirty = {
       .mesa = _NEW_BUFFERS,
-      .brw = 0,
+      .brw = BRW_NEW_CONTEXT,
       .cache = 0
    },
    .emit = upload_drawing_rect
@@ -116,7 +113,7 @@
 {
    struct intel_context *intel = &brw->intel;
 
-   BEGIN_BATCH(6, IGNORE_CLIPRECTS);
+   BEGIN_BATCH(6);
    OUT_BATCH(CMD_BINDING_TABLE_PTRS << 16 | (6 - 2));
    if (brw->vs.bind_bo != NULL)
       OUT_RELOC(brw->vs.bind_bo, I915_GEM_DOMAIN_SAMPLER, 0, 0); /* vs */
@@ -150,7 +147,7 @@
 {
    struct intel_context *intel = &brw->intel;
 
-   BEGIN_BATCH(7, IGNORE_CLIPRECTS);
+   BEGIN_BATCH(7);
    OUT_BATCH(CMD_PIPELINED_STATE_POINTERS << 16 | (7 - 2));
    OUT_RELOC(brw->vs.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
    if (brw->gs.prog_active)
@@ -212,10 +209,10 @@
 {
    struct intel_context *intel = &brw->intel;
    struct intel_region *region = brw->state.depth_region;
-   unsigned int len = (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? 6 : 5;
+   unsigned int len = (intel->is_g4x || intel->is_ironlake) ? 6 : 5;
 
    if (region == NULL) {
-      BEGIN_BATCH(len, IGNORE_CLIPRECTS);
+      BEGIN_BATCH(len);
       OUT_BATCH(CMD_DEPTH_BUFFER << 16 | (len - 2));
       OUT_BATCH((BRW_DEPTHFORMAT_D32_FLOAT << 18) |
 		(BRW_SURFACE_NULL << 29));
@@ -223,7 +220,7 @@
       OUT_BATCH(0);
       OUT_BATCH(0);
 
-      if (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw))
+      if (intel->is_g4x || intel->is_ironlake)
          OUT_BATCH(0);
 
       ADVANCE_BATCH();
@@ -247,7 +244,7 @@
 
       assert(region->tiling != I915_TILING_X);
 
-      BEGIN_BATCH(len, IGNORE_CLIPRECTS);
+      BEGIN_BATCH(len);
       OUT_BATCH(CMD_DEPTH_BUFFER << 16 | (len - 2));
       OUT_BATCH(((region->pitch * region->cpp) - 1) |
 		(format << 18) |
@@ -262,7 +259,7 @@
 		((region->height - 1) << 19));
       OUT_BATCH(0);
 
-      if (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw))
+      if (intel->is_g4x || intel->is_ironlake)
          OUT_BATCH(0);
 
       ADVANCE_BATCH();
@@ -317,7 +314,7 @@
 const struct brw_tracked_state brw_polygon_stipple = {
    .dirty = {
       .mesa = _NEW_POLYGONSTIPPLE,
-      .brw = 0,
+      .brw = BRW_NEW_CONTEXT,
       .cache = 0
    },
    .emit = upload_polygon_stipple
@@ -330,7 +327,7 @@
 
 static void upload_polygon_stipple_offset(struct brw_context *brw)
 {
-   __DRIdrawablePrivate *dPriv = brw->intel.driDrawable;
+   __DRIdrawable *dPriv = brw->intel.driDrawable;
    struct brw_polygon_stipple_offset bpso;
 
    memset(&bpso, 0, sizeof(bpso));
@@ -362,7 +359,7 @@
 const struct brw_tracked_state brw_polygon_stipple_offset = {
    .dirty = {
       .mesa = _NEW_WINDOW_POS,
-      .brw = 0,
+      .brw = BRW_NEW_CONTEXT,
       .cache = 0
    },
    .emit = upload_polygon_stipple_offset
@@ -374,8 +371,8 @@
 static void upload_aa_line_parameters(struct brw_context *brw)
 {
    struct brw_aa_line_parameters balp;
-   
-   if (BRW_IS_965(brw))
+
+   if (!brw->has_aa_line_parameters)
       return;
 
    /* use legacy aa line coverage computation */
@@ -425,7 +422,7 @@
 const struct brw_tracked_state brw_line_stipple = {
    .dirty = {
       .mesa = _NEW_LINE,
-      .brw = 0,
+      .brw = BRW_NEW_CONTEXT,
       .cache = 0
    },
    .emit = upload_line_stipple
@@ -444,7 +441,7 @@
       struct brw_pipeline_select ps;
 
       memset(&ps, 0, sizeof(ps));
-      ps.header.opcode = CMD_PIPELINE_SELECT(brw);
+      ps.header.opcode = brw->CMD_PIPELINE_SELECT;
       ps.header.pipeline_select = 0;
       BRW_BATCH_STRUCT(brw, &ps);
    }
@@ -480,7 +477,7 @@
       struct brw_vf_statistics vfs;
       memset(&vfs, 0, sizeof(vfs));
 
-      vfs.opcode = CMD_VF_STATISTICS(brw);
+      vfs.opcode = brw->CMD_VF_STATISTICS;
       if (INTEL_DEBUG & DEBUG_STATS)
 	 vfs.statistics_enable = 1; 
 
@@ -512,8 +509,8 @@
    /* Output the structure (brw_state_base_address) directly to the
     * batchbuffer, so we can emit relocations inline.
     */
-   if (BRW_IS_IGDNG(brw)) {
-       BEGIN_BATCH(8, IGNORE_CLIPRECTS);
+   if (intel->is_ironlake) {
+       BEGIN_BATCH(8);
        OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (8 - 2));
        OUT_BATCH(1); /* General state base address */
        OUT_BATCH(1); /* Surface state base address */
@@ -524,7 +521,7 @@
        OUT_BATCH(1); /* Instruction access upper bound */
        ADVANCE_BATCH();
    } else {
-       BEGIN_BATCH(6, IGNORE_CLIPRECTS);
+       BEGIN_BATCH(6);
        OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (6 - 2));
        OUT_BATCH(1); /* General state base address */
        OUT_BATCH(1); /* Surface state base address */
diff --git a/src/mesa/drivers/dri/i965/brw_queryobj.c b/src/mesa/drivers/dri/i965/brw_queryobj.c
index a195bc3..5399a74 100644
--- a/src/mesa/drivers/dri/i965/brw_queryobj.c
+++ b/src/mesa/drivers/dri/i965/brw_queryobj.c
@@ -188,7 +188,7 @@
    if (brw->query.active || is_empty_list(&brw->query.active_head))
       return;
 
-   BEGIN_BATCH(4, IGNORE_CLIPRECTS);
+   BEGIN_BATCH(4);
    OUT_BATCH(_3DSTATE_PIPE_CONTROL |
 	     PIPE_CONTROL_DEPTH_STALL |
 	     PIPE_CONTROL_WRITE_DEPTH_COUNT);
@@ -227,7 +227,7 @@
    if (!brw->query.active)
       return;
 
-   BEGIN_BATCH(4, IGNORE_CLIPRECTS);
+   BEGIN_BATCH(4);
    OUT_BATCH(_3DSTATE_PIPE_CONTROL |
 	     PIPE_CONTROL_DEPTH_STALL |
 	     PIPE_CONTROL_WRITE_DEPTH_COUNT);
diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c
index f350cbd..968890f 100644
--- a/src/mesa/drivers/dri/i965/brw_sf.c
+++ b/src/mesa/drivers/dri/i965/brw_sf.c
@@ -61,7 +61,7 @@
    c.key = *key;
    c.nr_attrs = brw_count_bits(c.key.attrs);
    c.nr_attr_regs = (c.nr_attrs+1)/2;
-   c.nr_setup_attrs = brw_count_bits(c.key.attrs & DO_SETUP_BITS);
+   c.nr_setup_attrs = brw_count_bits(c.key.attrs);
    c.nr_setup_regs = (c.nr_setup_attrs+1)/2;
 
    c.prog_data.urb_read_length = c.nr_attr_regs;
@@ -70,7 +70,7 @@
    /* Construct map from attribute number to position in the vertex.
     */
    for (i = idx = 0; i < VERT_RESULT_MAX; i++) 
-      if (c.key.attrs & (1<<i)) {
+      if (c.key.attrs & BITFIELD64_BIT(i)) {
 	 c.attr_to_idx[i] = idx;
 	 c.idx_to_attr[idx] = i;
 	 if (i >= VERT_RESULT_TEX0 && i <= VERT_RESULT_TEX7) {
@@ -147,7 +147,7 @@
        * edgeflag testing here, it is already done in the clip
        * program.
        */
-      if (key.attrs & (1<<VERT_RESULT_EDGE))
+      if (key.attrs & BITFIELD64_BIT(VERT_RESULT_EDGE))
 	 key.primitive = SF_UNFILLED_TRIS;
       else
 	 key.primitive = SF_TRIANGLES;
diff --git a/src/mesa/drivers/dri/i965/brw_sf.h b/src/mesa/drivers/dri/i965/brw_sf.h
index e835229..0ba731f 100644
--- a/src/mesa/drivers/dri/i965/brw_sf.h
+++ b/src/mesa/drivers/dri/i965/brw_sf.h
@@ -45,7 +45,7 @@
 #define SF_UNFILLED_TRIS   3
 
 struct brw_sf_prog_key {
-   GLuint attrs:32;
+   GLbitfield64 attrs;
    GLuint primitive:2;
    GLuint do_twoside_color:1;
    GLuint do_flat_shading:1;
diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c
index 561fcd5..bb08055 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c
@@ -56,7 +56,7 @@
 static GLboolean have_attr(struct brw_sf_compile *c,
 			   GLuint attr)
 {
-   return (c->key.attrs & (1<<attr)) ? 1 : 0;
+   return (c->key.attrs & BITFIELD64_BIT(attr)) ? 1 : 0;
 }
 
 /*********************************************************************** 
@@ -122,8 +122,8 @@
  * Flat shading
  */
 
-#define VERT_RESULT_COLOR_BITS ((1<<VERT_RESULT_COL0) | \
-                                 (1<<VERT_RESULT_COL1))
+#define VERT_RESULT_COLOR_BITS (BITFIELD64_BIT(VERT_RESULT_COL0) | \
+				BITFIELD64_BIT(VERT_RESULT_COL1))
 
 static void copy_colors( struct brw_sf_compile *c,
 		     struct brw_reg dst,
@@ -149,6 +149,7 @@
 static void do_flatshade_triangle( struct brw_sf_compile *c )
 {
    struct brw_compile *p = &c->func;
+   struct intel_context *intel = &p->brw->intel;
    struct brw_reg ip = brw_ip_reg();
    GLuint nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS);
    GLuint jmpi = 1;
@@ -161,7 +162,7 @@
    if (c->key.primitive == SF_UNFILLED_TRIS)
       return;
 
-   if (BRW_IS_IGDNG(p->brw))
+   if (intel->is_ironlake)
        jmpi = 2;
 
    brw_push_insn_state(p);
@@ -187,6 +188,7 @@
 static void do_flatshade_line( struct brw_sf_compile *c )
 {
    struct brw_compile *p = &c->func;
+   struct intel_context *intel = &p->brw->intel;
    struct brw_reg ip = brw_ip_reg();
    GLuint nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS);
    GLuint jmpi = 1;
@@ -199,7 +201,7 @@
    if (c->key.primitive == SF_UNFILLED_TRIS)
       return;
 
-   if (BRW_IS_IGDNG(p->brw))
+   if (intel->is_ironlake)
        jmpi = 2;
 
    brw_push_insn_state(p);
@@ -312,8 +314,8 @@
 				  GLushort *pc_linear)
 {
    GLboolean is_last_attr = (reg == c->nr_setup_regs - 1);
-   GLuint persp_mask;
-   GLuint linear_mask;
+   GLbitfield64 persp_mask;
+   GLbitfield64 linear_mask;
 
    if (c->key.do_flat_shading || c->key.linear_color)
       persp_mask = c->key.attrs & ~(FRAG_BIT_WPOS |
@@ -331,10 +333,10 @@
    *pc_linear = 0;
    *pc = 0xf;
       
-   if (persp_mask & (1 << c->idx_to_attr[reg*2])) 
+   if (persp_mask & BITFIELD64_BIT(c->idx_to_attr[reg*2]))
       *pc_persp = 0xf;
 
-   if (linear_mask & (1 << c->idx_to_attr[reg*2])) 
+   if (linear_mask & BITFIELD64_BIT(c->idx_to_attr[reg*2]))
       *pc_linear = 0xf;
 
    /* Maybe only processs one attribute on the final round:
@@ -342,10 +344,10 @@
    if (reg*2+1 < c->nr_setup_attrs) {
       *pc |= 0xf0;
 
-      if (persp_mask & (1 << c->idx_to_attr[reg*2+1])) 
+      if (persp_mask & BITFIELD64_BIT(c->idx_to_attr[reg*2+1]))
 	 *pc_persp |= 0xf0;
 
-      if (linear_mask & (1 << c->idx_to_attr[reg*2+1])) 
+      if (linear_mask & BITFIELD64_BIT(c->idx_to_attr[reg*2+1]))
 	 *pc_linear |= 0xf0;
    }
 
diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c
index bc0f076..09223b7 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_state.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_state.c
@@ -93,7 +93,8 @@
    }
 
    dri_bo_unreference(brw->sf.vp_bo);
-   brw->sf.vp_bo = brw_cache_data( &brw->cache, BRW_SF_VP, &sfv, NULL, 0 );
+   brw->sf.vp_bo = brw_cache_data(&brw->cache, BRW_SF_VP, &sfv, sizeof(sfv),
+				  NULL, 0);
 }
 
 const struct brw_tracked_state brw_sf_vp = {
@@ -113,7 +114,8 @@
 
    unsigned int nr_urb_entries, urb_size, sfsize;
 
-   GLenum front_face, cull_face, provoking_vertex;
+   GLenum front_face, cull_face;
+   unsigned pv_first:1;
    unsigned scissor:1;
    unsigned line_smooth:1;
    unsigned point_sprite:1;
@@ -154,7 +156,7 @@
    key->point_attenuated = ctx->Point._Attenuated;
 
    /* _NEW_LIGHT */
-   key->provoking_vertex = ctx->Light.ProvokingVertex;
+   key->pv_first = (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION);
 
    key->render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
 }
@@ -163,6 +165,7 @@
 sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
 			dri_bo **reloc_bufs)
 {
+   struct intel_context *intel = &brw->intel;
    struct brw_sf_unit_state sf;
    dri_bo *bo;
    int chipset_max_threads;
@@ -175,7 +178,7 @@
 
    sf.thread3.dispatch_grf_start_reg = 3;
 
-   if (BRW_IS_IGDNG(brw))
+   if (intel->is_ironlake)
        sf.thread3.urb_entry_read_offset = 3;
    else
        sf.thread3.urb_entry_read_offset = 1;
@@ -185,10 +188,10 @@
    sf.thread4.nr_urb_entries = key->nr_urb_entries;
    sf.thread4.urb_entry_allocation_size = key->sfsize - 1;
 
-   /* Each SF thread produces 1 PUE, and there can be up to 24(Pre-IGDNG) or 
-    * 48(IGDNG) threads 
+   /* Each SF thread produces 1 PUE, and there can be up to 24 (Pre-Ironlake) or
+    * 48 (Ironlake) threads.
     */
-   if (BRW_IS_IGDNG(brw))
+   if (intel->is_ironlake)
       chipset_max_threads = 48;
    else
       chipset_max_threads = 24;
@@ -287,7 +290,7 @@
 
    /* might be BRW_NEW_PRIMITIVE if we have to adjust pv for polygons:
     */
-   if (key->provoking_vertex == GL_LAST_VERTEX_CONVENTION) {
+   if (!key->pv_first) {
       sf.sf7.trifan_pv = 2;
       sf.sf7.linestrip_pv = 1;
       sf.sf7.tristrip_pv = 2;
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index d639656..9c9d145 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -35,7 +35,7 @@
 
 #include "brw_context.h"
 
-static inline void
+static INLINE void
 brw_add_validated_bo(struct brw_context *brw, dri_bo *bo)
 {
    assert(brw->state.validated_bo_count < ARRAY_SIZE(brw->state.validated_bos));
@@ -112,6 +112,7 @@
 void brw_upload_state(struct brw_context *brw);
 void brw_init_state(struct brw_context *brw);
 void brw_destroy_state(struct brw_context *brw);
+void brw_clear_validated_bos(struct brw_context *brw);
 
 /***********************************************************************
  * brw_state_cache.c
@@ -119,16 +120,10 @@
 dri_bo *brw_cache_data(struct brw_cache *cache,
 		       enum brw_cache_id cache_id,
 		       const void *data,
+		       GLuint size,
 		       dri_bo **reloc_bufs,
 		       GLuint nr_reloc_bufs);
 
-dri_bo *brw_cache_data_sz(struct brw_cache *cache,
-			  enum brw_cache_id cache_id,
-			  const void *data,
-			  GLuint data_size,
-			  dri_bo **reloc_bufs,
-			  GLuint nr_reloc_bufs);
-
 dri_bo *brw_upload_cache( struct brw_cache *cache,
 			  enum brw_cache_id cache_id,
 			  const void *key,
@@ -156,7 +151,7 @@
 /***********************************************************************
  * brw_state_batch.c
  */
-#define BRW_BATCH_STRUCT(brw, s) intel_batchbuffer_data( brw->intel.batch, (s), sizeof(*(s)), IGNORE_CLIPRECTS)
+#define BRW_BATCH_STRUCT(brw, s) intel_batchbuffer_data( brw->intel.batch, (s), sizeof(*(s)))
 #define BRW_CACHED_BATCH_STRUCT(brw, s) brw_cached_batch_struct( brw, (s), sizeof(*(s)) )
 
 GLboolean brw_cached_batch_struct( struct brw_context *brw,
diff --git a/src/mesa/drivers/dri/i965/brw_state_batch.c b/src/mesa/drivers/dri/i965/brw_state_batch.c
index 7821898..ed8120d 100644
--- a/src/mesa/drivers/dri/i965/brw_state_batch.c
+++ b/src/mesa/drivers/dri/i965/brw_state_batch.c
@@ -48,7 +48,7 @@
    struct header *newheader = (struct header *)data;
 
    if (brw->emit_state_always) {
-      intel_batchbuffer_data(brw->intel.batch, data, sz, IGNORE_CLIPRECTS);
+      intel_batchbuffer_data(brw->intel.batch, data, sz);
       return GL_TRUE;
    }
 
@@ -75,7 +75,7 @@
 
  emit:
    memcpy(item->header, newheader, sz);
-   intel_batchbuffer_data(brw->intel.batch, data, sz, IGNORE_CLIPRECTS);
+   intel_batchbuffer_data(brw->intel.batch, data, sz);
    return GL_TRUE;
 }
 
diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c
index c262e1d..e4c9ba7 100644
--- a/src/mesa/drivers/dri/i965/brw_state_cache.c
+++ b/src/mesa/drivers/dri/i965/brw_state_cache.c
@@ -245,7 +245,6 @@
 
    item->bo = bo;
    dri_bo_reference(bo);
-   item->data_size = data_size;
 
    if (cache->n_items > cache->size * 1.5)
       rehash(cache);
@@ -275,15 +274,22 @@
 
 
 /**
- * This doesn't really work with aux data.  Use search/upload instead
+ * Wrapper around brw_cache_data_sz using the cache_id's canonical key size.
+ *
+ * If nr_reloc_bufs is nonzero, brw_search_cache()/brw_upload_cache() would be
+ * better to use, as the potentially changing offsets in the data-used-as-key
+ * will result in excessive cache misses.
+ *
+ * If aux data is involved, use search/upload instead.
+
  */
 dri_bo *
-brw_cache_data_sz(struct brw_cache *cache,
-		  enum brw_cache_id cache_id,
-		  const void *data,
-		  GLuint data_size,
-		  dri_bo **reloc_bufs,
-		  GLuint nr_reloc_bufs)
+brw_cache_data(struct brw_cache *cache,
+	       enum brw_cache_id cache_id,
+	       const void *data,
+	       GLuint data_size,
+	       dri_bo **reloc_bufs,
+	       GLuint nr_reloc_bufs)
 {
    dri_bo *bo;
    struct brw_cache_item *item;
@@ -306,25 +312,6 @@
    return bo;
 }
 
-
-/**
- * Wrapper around brw_cache_data_sz using the cache_id's canonical key size.
- *
- * If nr_reloc_bufs is nonzero, brw_search_cache()/brw_upload_cache() would be
- * better to use, as the potentially changing offsets in the data-used-as-key
- * will result in excessive cache misses.
- */
-dri_bo *
-brw_cache_data(struct brw_cache *cache,
-	       enum brw_cache_id cache_id,
-	       const void *data,
-	       dri_bo **reloc_bufs,
-	       GLuint nr_reloc_bufs)
-{
-   return brw_cache_data_sz(cache, cache_id, data, cache->key_size[cache_id],
-			    reloc_bufs, nr_reloc_bufs);
-}
-
 enum pool_type {
    DW_SURFACE_STATE,
    DW_GENERAL_STATE
@@ -335,11 +322,9 @@
 brw_init_cache_id(struct brw_cache *cache,
                   const char *name,
                   enum brw_cache_id id,
-                  GLuint key_size,
                   GLuint aux_size)
 {
    cache->name[id] = strdup(name);
-   cache->key_size[id] = key_size;
    cache->aux_size[id] = aux_size;
 }
 
@@ -359,91 +344,76 @@
    brw_init_cache_id(cache,
 		     "CC_VP",
 		     BRW_CC_VP,
-		     sizeof(struct brw_cc_viewport),
 		     0);
 
    brw_init_cache_id(cache,
 		     "CC_UNIT",
 		     BRW_CC_UNIT,
-		     sizeof(struct brw_cc_unit_state),
 		     0);
 
    brw_init_cache_id(cache,
 		     "WM_PROG",
 		     BRW_WM_PROG,
-		     sizeof(struct brw_wm_prog_key),
 		     sizeof(struct brw_wm_prog_data));
 
    brw_init_cache_id(cache,
 		     "SAMPLER_DEFAULT_COLOR",
 		     BRW_SAMPLER_DEFAULT_COLOR,
-		     sizeof(struct brw_sampler_default_color),
 		     0);
 
    brw_init_cache_id(cache,
 		     "SAMPLER",
 		     BRW_SAMPLER,
-		     0,		/* variable key/data size */
 		     0);
 
    brw_init_cache_id(cache,
 		     "WM_UNIT",
 		     BRW_WM_UNIT,
-		     sizeof(struct brw_wm_unit_state),
 		     0);
 
    brw_init_cache_id(cache,
 		     "SF_PROG",
 		     BRW_SF_PROG,
-		     sizeof(struct brw_sf_prog_key),
 		     sizeof(struct brw_sf_prog_data));
 
    brw_init_cache_id(cache,
 		     "SF_VP",
 		     BRW_SF_VP,
-		     sizeof(struct brw_sf_viewport),
 		     0);
 
    brw_init_cache_id(cache,
 		     "SF_UNIT",
 		     BRW_SF_UNIT,
-		     sizeof(struct brw_sf_unit_state),
 		     0);
 
    brw_init_cache_id(cache,
 		     "VS_UNIT",
 		     BRW_VS_UNIT,
-		     sizeof(struct brw_vs_unit_state),
 		     0);
 
    brw_init_cache_id(cache,
 		     "VS_PROG",
 		     BRW_VS_PROG,
-		     sizeof(struct brw_vs_prog_key),
 		     sizeof(struct brw_vs_prog_data));
 
    brw_init_cache_id(cache,
 		     "CLIP_UNIT",
 		     BRW_CLIP_UNIT,
-		     sizeof(struct brw_clip_unit_state),
 		     0);
 
    brw_init_cache_id(cache,
 		     "CLIP_PROG",
 		     BRW_CLIP_PROG,
-		     sizeof(struct brw_clip_prog_key),
 		     sizeof(struct brw_clip_prog_data));
 
    brw_init_cache_id(cache,
 		     "GS_UNIT",
 		     BRW_GS_UNIT,
-		     sizeof(struct brw_gs_unit_state),
 		     0);
 
    brw_init_cache_id(cache,
 		     "GS_PROG",
 		     BRW_GS_PROG,
-		     sizeof(struct brw_gs_prog_key),
 		     sizeof(struct brw_gs_prog_data));
 }
 
@@ -463,13 +433,11 @@
    brw_init_cache_id(cache,
 		     "SS_SURFACE",
 		     BRW_SS_SURFACE,
-		     sizeof(struct brw_surface_state),
 		     0);
 
    brw_init_cache_id(cache,
 		     "SS_SURF_BIND",
 		     BRW_SS_SURF_BIND,
-		     0,
 		     0);
 }
 
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index f4283bd..af8dfb4 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -143,7 +143,7 @@
    result->cache = a->cache ^ b->cache;
 }
 
-static void
+void
 brw_clear_validated_bos(struct brw_context *brw)
 {
    int i;
diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index e59e52e..64a9535 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -49,7 +49,7 @@
 
    switch (mt->target) {
    case GL_TEXTURE_CUBE_MAP:
-      if (IS_IGDNG(intel->intelScreen->deviceID)) {
+      if (intel->is_ironlake) {
           GLuint align_h = 2, align_w = 4;
           GLuint level;
           GLuint x = 0;
diff --git a/src/mesa/drivers/dri/i965/brw_urb.c b/src/mesa/drivers/dri/i965/brw_urb.c
index 8c6f435..f2cdb20 100644
--- a/src/mesa/drivers/dri/i965/brw_urb.c
+++ b/src/mesa/drivers/dri/i965/brw_urb.c
@@ -105,7 +105,8 @@
    brw->urb.sf_start = brw->urb.clip_start + brw->urb.nr_clip_entries * brw->urb.vsize;
    brw->urb.cs_start = brw->urb.sf_start + brw->urb.nr_sf_entries * brw->urb.sfsize;
 
-   return brw->urb.cs_start + brw->urb.nr_cs_entries * brw->urb.csize <= URB_SIZES(brw);
+   return brw->urb.cs_start + brw->urb.nr_cs_entries *
+      brw->urb.csize <= brw->urb.size;
 }
 
 /* Most minimal update, forces re-emit of URB fence packet after GS
@@ -113,6 +114,7 @@
  */
 static void recalculate_urb_fence( struct brw_context *brw )
 {
+   struct intel_context *intel = &brw->intel;
    GLuint csize = brw->curbe.total_size;
    GLuint vsize = brw->vs.prog_data->urb_entry_size;
    GLuint sfsize = brw->sf.prog_data->urb_entry_size;
@@ -146,7 +148,7 @@
 
       brw->urb.constrained = 0;
 
-      if (BRW_IS_IGDNG(brw)) {
+      if (intel->is_ironlake) {
          brw->urb.nr_vs_entries = 128;
          brw->urb.nr_sf_entries = 48;
          if (check_urb_layout(brw)) {
@@ -156,7 +158,7 @@
             brw->urb.nr_vs_entries = limits[VS].preferred_nr_entries;
             brw->urb.nr_sf_entries = limits[SF].preferred_nr_entries;
          }
-      } else if (BRW_IS_G4X(brw)) {
+      } else if (intel->is_g4x) {
 	 brw->urb.nr_vs_entries = 64;
 	 if (check_urb_layout(brw)) {
 	    goto done;
@@ -200,7 +202,7 @@
 		      brw->urb.clip_start,
 		      brw->urb.sf_start,
 		      brw->urb.cs_start, 
-		      URB_SIZES(brw));
+		      brw->urb.size);
       
       brw->state.dirty.brw |= BRW_NEW_URB_FENCE;
    }
@@ -244,7 +246,7 @@
    uf.bits0.gs_fence  = brw->urb.clip_start; 
    uf.bits0.clp_fence = brw->urb.sf_start; 
    uf.bits1.sf_fence  = brw->urb.cs_start; 
-   uf.bits1.cs_fence  = URB_SIZES(brw);
+   uf.bits1.cs_fence  = brw->urb.size;
 
    BRW_BATCH_STRUCT(brw, &uf);
 }
diff --git a/src/mesa/drivers/dri/i965/brw_util.c b/src/mesa/drivers/dri/i965/brw_util.c
index ce21aa4..bba9249 100644
--- a/src/mesa/drivers/dri/i965/brw_util.c
+++ b/src/mesa/drivers/dri/i965/brw_util.c
@@ -35,7 +35,7 @@
 #include "brw_util.h"
 #include "brw_defines.h"
 
-GLuint brw_count_bits( GLuint val )
+GLuint brw_count_bits(uint64_t val)
 {
    GLuint i;
    for (i = 0; val ; val >>= 1)
diff --git a/src/mesa/drivers/dri/i965/brw_util.h b/src/mesa/drivers/dri/i965/brw_util.h
index 33e7cd8..04f3175 100644
--- a/src/mesa/drivers/dri/i965/brw_util.h
+++ b/src/mesa/drivers/dri/i965/brw_util.h
@@ -35,7 +35,7 @@
 
 #include "main/mtypes.h"
 
-extern GLuint brw_count_bits( GLuint val );
+extern GLuint brw_count_bits(uint64_t val);
 extern GLuint brw_parameter_list_state_flags(struct gl_program_parameter_list *paramList);
 extern GLuint brw_translate_blend_factor( GLenum factor );
 extern GLuint brw_translate_blend_equation( GLenum mode );
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index f0c79ef..fd055e2 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -56,7 +56,7 @@
    c.prog_data.inputs_read = vp->program.Base.InputsRead;
 
    if (c.key.copy_edgeflag) {
-      c.prog_data.outputs_written |= 1<<VERT_RESULT_EDGE;
+      c.prog_data.outputs_written |= BITFIELD64_BIT(VERT_RESULT_EDGE);
       c.prog_data.inputs_read |= 1<<VERT_ATTRIB_EDGEFLAG;
    }
 
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index 1638ef8..1b84dd5 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -67,6 +67,7 @@
  */
 static void brw_vs_alloc_regs( struct brw_vs_compile *c )
 {
+   struct intel_context *intel = &c->func.brw->intel;
    GLuint i, reg = 0, mrf;
    int attributes_in_vue;
 
@@ -141,13 +142,13 @@
    c->first_output = reg;
    c->first_overflow_output = 0;
 
-   if (BRW_IS_IGDNG(c->func.brw))
+   if (intel->is_ironlake)
        mrf = 8;
    else
        mrf = 4;
 
    for (i = 0; i < VERT_RESULT_MAX; i++) {
-      if (c->prog_data.outputs_written & (1 << i)) {
+      if (c->prog_data.outputs_written & BITFIELD64_BIT(i)) {
 	 c->nr_outputs++;
          assert(i < Elements(c->regs[PROGRAM_OUTPUT]));
 	 if (i == VERT_RESULT_HPOS) {
@@ -238,7 +239,7 @@
     */
    attributes_in_vue = MAX2(c->nr_outputs, c->nr_inputs);
 
-   if (BRW_IS_IGDNG(c->func.brw))
+   if (intel->is_ironlake)
        c->prog_data.urb_entry_size = (attributes_in_vue + 6 + 3) / 4;
    else
        c->prog_data.urb_entry_size = (attributes_in_vue + 2 + 3) / 4;
@@ -331,63 +332,76 @@
    }
 }
 
-static void emit_sop( struct brw_compile *p,
+static void emit_sop( struct brw_vs_compile *c,
                       struct brw_reg dst,
                       struct brw_reg arg0,
                       struct brw_reg arg1, 
 		      GLuint cond)
 {
+   struct brw_compile *p = &c->func;
+
    brw_MOV(p, dst, brw_imm_f(0.0f));
    brw_CMP(p, brw_null_reg(), cond, arg0, arg1);
    brw_MOV(p, dst, brw_imm_f(1.0f));
    brw_set_predicate_control_flag_value(p, 0xff);
 }
 
-static void emit_seq( struct brw_compile *p,
+static void emit_seq( struct brw_vs_compile *c,
                       struct brw_reg dst,
                       struct brw_reg arg0,
                       struct brw_reg arg1 )
 {
-   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_EQ);
+   emit_sop(c, dst, arg0, arg1, BRW_CONDITIONAL_EQ);
 }
 
-static void emit_sne( struct brw_compile *p,
+static void emit_sne( struct brw_vs_compile *c,
                       struct brw_reg dst,
                       struct brw_reg arg0,
                       struct brw_reg arg1 )
 {
-   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_NEQ);
+   emit_sop(c, dst, arg0, arg1, BRW_CONDITIONAL_NEQ);
 }
-static void emit_slt( struct brw_compile *p, 
+static void emit_slt( struct brw_vs_compile *c,
 		      struct brw_reg dst,
 		      struct brw_reg arg0,
 		      struct brw_reg arg1 )
 {
-   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_L);
+   emit_sop(c, dst, arg0, arg1, BRW_CONDITIONAL_L);
 }
 
-static void emit_sle( struct brw_compile *p, 
+static void emit_sle( struct brw_vs_compile *c,
 		      struct brw_reg dst,
 		      struct brw_reg arg0,
 		      struct brw_reg arg1 )
 {
-   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_LE);
+   emit_sop(c, dst, arg0, arg1, BRW_CONDITIONAL_LE);
 }
 
-static void emit_sgt( struct brw_compile *p, 
+static void emit_sgt( struct brw_vs_compile *c,
 		      struct brw_reg dst,
 		      struct brw_reg arg0,
 		      struct brw_reg arg1 )
 {
-   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_G);
+   emit_sop(c, dst, arg0, arg1, BRW_CONDITIONAL_G);
 }
 
-static void emit_sge( struct brw_compile *p, 
+static void emit_sge( struct brw_vs_compile *c,
 		      struct brw_reg dst,
 		      struct brw_reg arg0,
 		      struct brw_reg arg1 )
 {
-  emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_GE);
+  emit_sop(c, dst, arg0, arg1, BRW_CONDITIONAL_GE);
+}
+
+static void emit_cmp( struct brw_compile *p,
+		      struct brw_reg dst,
+		      struct brw_reg arg0,
+		      struct brw_reg arg1,
+		      struct brw_reg arg2 )
+{
+   brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0, brw_imm_f(0));
+   brw_SEL(p, dst, arg1, arg2);
+   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
 }
 
 static void emit_max( struct brw_compile *p, 
@@ -912,6 +926,7 @@
    case PROGRAM_CONSTANT:
    case PROGRAM_UNIFORM:
    case PROGRAM_ENV_PARAM:
+   case PROGRAM_LOCAL_PARAM:
       if (c->vp->use_const_buffer) {
          return get_constant(c, inst, argIndex);
       }
@@ -930,7 +945,6 @@
       /* this is a normal case since we loop over all three src args */
       return brw_null_reg();
 
-   case PROGRAM_LOCAL_PARAM: 
    case PROGRAM_WRITE_ONLY:
    default:
       assert(0);
@@ -1100,6 +1114,8 @@
 static void emit_vertex_write( struct brw_vs_compile *c)
 {
    struct brw_compile *p = &c->func;
+   struct brw_context *brw = p->brw;
+   struct intel_context *intel = &brw->intel;
    struct brw_reg m0 = brw_message_reg(0);
    struct brw_reg pos = c->regs[PROGRAM_OUTPUT][VERT_RESULT_HPOS];
    struct brw_reg ndc;
@@ -1122,8 +1138,8 @@
    /* Update the header for point size, user clipping flags, and -ve rhw
     * workaround.
     */
-   if ((c->prog_data.outputs_written & (1<<VERT_RESULT_PSIZ)) ||
-       c->key.nr_userclip || BRW_IS_965(p->brw))
+   if ((c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_PSIZ)) ||
+       c->key.nr_userclip || brw->has_negative_rhw_bug)
    {
       struct brw_reg header1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
       GLuint i;
@@ -1132,7 +1148,7 @@
 
       brw_set_access_mode(p, BRW_ALIGN_16);	
 
-      if (c->prog_data.outputs_written & (1<<VERT_RESULT_PSIZ)) {
+      if (c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_PSIZ)) {
 	 struct brw_reg psiz = c->regs[PROGRAM_OUTPUT][VERT_RESULT_PSIZ];
 	 brw_MUL(p, brw_writemask(header1, WRITEMASK_W), brw_swizzle1(psiz, 0), brw_imm_f(1<<11));
 	 brw_AND(p, brw_writemask(header1, WRITEMASK_W), header1, brw_imm_ud(0x7ff<<8));
@@ -1154,7 +1170,7 @@
        * Later, clipping will detect ucp[6] and ensure the primitive is
        * clipped against all fixed planes.
        */
-      if (BRW_IS_965(p->brw)) {
+      if (brw->has_negative_rhw_bug) {
 	 brw_CMP(p,
 		 vec8(brw_null_reg()),
 		 BRW_CONDITIONAL_L,
@@ -1182,8 +1198,8 @@
    brw_set_access_mode(p, BRW_ALIGN_1);
    brw_MOV(p, offset(m0, 2), ndc);
 
-   if (BRW_IS_IGDNG(p->brw)) {
-       /* There are 20 DWs (D0-D19) in VUE vertex header on IGDNG */
+   if (intel->is_ironlake) {
+       /* There are 20 DWs (D0-D19) in VUE vertex header on Ironlake */
        brw_MOV(p, offset(m0, 3), pos); /* a portion of vertex header */
        /* m4, m5 contain the distances from vertex to the user clip planeXXX. 
         * Seems it is useless for us.
@@ -1222,7 +1238,7 @@
        */
       GLuint i, mrf = 0;
       for (i = c->first_overflow_output; i < VERT_RESULT_MAX; i++) {
-         if (c->prog_data.outputs_written & (1 << i)) {
+         if (c->prog_data.outputs_written & BITFIELD64_BIT(i)) {
             /* move from GRF to MRF */
             brw_MOV(p, brw_message_reg(4+mrf), c->regs[PROGRAM_OUTPUT][i]);
             mrf++;
@@ -1269,6 +1285,38 @@
    }
 }
 
+static GLboolean
+accumulator_contains(struct brw_vs_compile *c, struct brw_reg val)
+{
+   struct brw_compile *p = &c->func;
+   struct brw_instruction *prev_insn = &p->store[p->nr_insn - 1];
+
+   if (p->nr_insn == 0)
+      return GL_FALSE;
+
+   if (val.address_mode != BRW_ADDRESS_DIRECT)
+      return GL_FALSE;
+
+   switch (prev_insn->header.opcode) {
+   case BRW_OPCODE_MOV:
+   case BRW_OPCODE_MAC:
+   case BRW_OPCODE_MUL:
+      if (prev_insn->header.access_mode == BRW_ALIGN_16 &&
+	  prev_insn->header.execution_size == val.width &&
+	  prev_insn->bits1.da1.dest_reg_file == val.file &&
+	  prev_insn->bits1.da1.dest_reg_type == val.type &&
+	  prev_insn->bits1.da1.dest_address_mode == val.address_mode &&
+	  prev_insn->bits1.da1.dest_reg_nr == val.nr &&
+	  prev_insn->bits1.da16.dest_subreg_nr == val.subnr / 16 &&
+	  prev_insn->bits1.da16.dest_writemask == 0xf)
+	 return GL_TRUE;
+      else
+	 return GL_FALSE;
+   default:
+      return GL_FALSE;
+   }
+}
+
 static uint32_t
 get_predicate(const struct prog_instruction *inst)
 {
@@ -1314,6 +1362,7 @@
 #define MAX_LOOP_DEPTH 32
    struct brw_compile *p = &c->func;
    struct brw_context *brw = p->brw;
+   struct intel_context *intel = &brw->intel;
    const GLuint nr_insns = c->vp->program.Base.NumInstructions;
    GLuint insn, if_depth = 0, loop_depth = 0;
    GLuint end_offset = 0;
@@ -1447,9 +1496,13 @@
 	 unalias3(c, dst, args[0], args[1], args[2], emit_lrp_noalias);
 	 break;
       case OPCODE_MAD:
-	 brw_MOV(p, brw_acc_reg(), args[2]);
+	 if (!accumulator_contains(c, args[2]))
+	    brw_MOV(p, brw_acc_reg(), args[2]);
 	 brw_MAC(p, dst, args[0], args[1]);
 	 break;
+      case OPCODE_CMP:
+	 emit_cmp(p, dst, args[0], args[1], args[2]);
+	 break;
       case OPCODE_MAX:
 	 emit_max(p, dst, args[0], args[1]);
 	 break;
@@ -1473,25 +1526,25 @@
 	 break;
 
       case OPCODE_SEQ:
-         emit_seq(p, dst, args[0], args[1]);
+         unalias2(c, dst, args[0], args[1], emit_seq);
          break;
       case OPCODE_SIN:
 	 emit_math1(c, BRW_MATH_FUNCTION_SIN, dst, args[0], BRW_MATH_PRECISION_FULL);
 	 break;
       case OPCODE_SNE:
-         emit_sne(p, dst, args[0], args[1]);
+         unalias2(c, dst, args[0], args[1], emit_sne);
          break;
       case OPCODE_SGE:
-	 emit_sge(p, dst, args[0], args[1]);
+         unalias2(c, dst, args[0], args[1], emit_sge);
 	 break;
       case OPCODE_SGT:
-         emit_sgt(p, dst, args[0], args[1]);
+         unalias2(c, dst, args[0], args[1], emit_sgt);
          break;
       case OPCODE_SLT:
-	 emit_slt(p, dst, args[0], args[1]);
+         unalias2(c, dst, args[0], args[1], emit_slt);
 	 break;
       case OPCODE_SLE:
-         emit_sle(p, dst, args[0], args[1]);
+         unalias2(c, dst, args[0], args[1], emit_sle);
          break;
       case OPCODE_SUB:
 	 brw_ADD(p, dst, args[0], negate(args[1]));
@@ -1543,7 +1596,7 @@
 
             loop_depth--;
 
-	    if (BRW_IS_IGDNG(brw))
+	    if (intel->is_ironlake)
 	       br = 2;
 
             inst0 = inst1 = brw_WHILE(p, loop_inst[loop_depth]);
diff --git a/src/mesa/drivers/dri/i965/brw_vs_state.c b/src/mesa/drivers/dri/i965/brw_vs_state.c
index d790ab6..345ffa7 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_state.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_state.c
@@ -82,9 +82,9 @@
 static dri_bo *
 vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key)
 {
+   struct intel_context *intel = &brw->intel;
    struct brw_vs_unit_state vs;
    dri_bo *bo;
-   int chipset_max_threads;
 
    memset(&vs, 0, sizeof(vs));
 
@@ -98,7 +98,7 @@
     */
    vs.thread1.single_program_flow = 0;
 
-   if (BRW_IS_IGDNG(brw))
+   if (intel->is_ironlake)
       vs.thread1.binding_table_entry_count = 0; /* hardware requirement */
    else
       vs.thread1.binding_table_entry_count = key->nr_surfaces;
@@ -109,24 +109,44 @@
    vs.thread3.urb_entry_read_offset = 0;
    vs.thread3.const_urb_entry_read_offset = key->curbe_offset * 2;
 
-   if (BRW_IS_IGDNG(brw))
-       vs.thread4.nr_urb_entries = key->nr_urb_entries >> 2;
-   else
-       vs.thread4.nr_urb_entries = key->nr_urb_entries;
+   if (intel->is_ironlake) {
+      switch (key->nr_urb_entries) {
+      case 8:
+      case 12:
+      case 16:
+      case 32:
+      case 64:
+      case 96:
+      case 128:
+      case 168:
+      case 192:
+      case 224:
+      case 256:
+	 vs.thread4.nr_urb_entries = key->nr_urb_entries >> 2;
+	 break;
+      default:
+	 assert(0);
+      }
+   } else {
+      switch (key->nr_urb_entries) {
+      case 8:
+      case 12:
+      case 16:
+      case 32:
+	 break;
+      case 64:
+	 assert(intel->is_g4x);
+	 break;
+      default:
+	 assert(0);
+      }
+      vs.thread4.nr_urb_entries = key->nr_urb_entries;
+   }
 
    vs.thread4.urb_entry_allocation_size = key->urb_size - 1;
 
-   if (BRW_IS_IGDNG(brw))
-      chipset_max_threads = 72;
-   else if (BRW_IS_G4X(brw))
-      chipset_max_threads = 32;
-   else
-      chipset_max_threads = 16;
    vs.thread4.max_threads = CLAMP(key->nr_urb_entries / 2,
-				  1, chipset_max_threads) - 1;
-
-   if (INTEL_DEBUG & DEBUG_SINGLE_THREAD)
-      vs.thread4.max_threads = 0;
+				  1, brw->vs_max_threads) - 1;
 
    /* No samplers for ARB_vp programs:
     */
diff --git a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
index 4fa3269..3bc9840 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
@@ -52,6 +52,7 @@
    const struct gl_program_parameter_list *params = vp->program.Base.Parameters;
    const int size = params->NumParameters * 4 * sizeof(GLfloat);
    drm_intel_bo *const_buffer;
+   int i;
 
    /* BRW_NEW_VERTEX_PROGRAM */
    if (!vp->use_const_buffer)
@@ -61,7 +62,19 @@
 				     size, 64);
 
    /* _NEW_PROGRAM_CONSTANTS */
-   dri_bo_subdata(const_buffer, 0, size, params->ParameterValues);
+
+   /* Updates the ParamaterValues[i] pointers for all parameters of the
+    * basic type of PROGRAM_STATE_VAR.
+    */
+   _mesa_load_state_parameters(&brw->intel.ctx, vp->program.Base.Parameters);
+
+   intel_bo_map_gtt_preferred(intel, const_buffer, GL_TRUE);
+   for (i = 0; i < params->NumParameters; i++) {
+      memcpy(const_buffer->virtual + i * 4 * sizeof(float),
+	     params->ParameterValues[i],
+	     4 * sizeof(float));
+   }
+   intel_bo_unmap_gtt_preferred(intel, const_buffer);
 
    return const_buffer;
 }
diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c
index 124fde2..72749b3 100644
--- a/src/mesa/drivers/dri/i965/brw_vtbl.c
+++ b/src/mesa/drivers/dri/i965/brw_vtbl.c
@@ -46,7 +46,7 @@
 #include "brw_state.h"
 #include "brw_fallback.h"
 #include "brw_vs.h"
-
+#include "brw_wm.h"
 
 static void
 dri_bo_release(dri_bo **bo)
@@ -66,8 +66,14 @@
 
    brw_destroy_state(brw);
    brw_draw_destroy( brw );
-
-   _mesa_free(brw->wm.compile_data);
+   brw_clear_validated_bos(brw);
+   if (brw->wm.compile_data) {
+      _mesa_free(brw->wm.compile_data->instruction);
+      _mesa_free(brw->wm.compile_data->vreg);
+      _mesa_free(brw->wm.compile_data->refs);
+      _mesa_free(brw->wm.compile_data->prog_instructions);
+      _mesa_free(brw->wm.compile_data);
+   }
 
    for (i = 0; i < brw->state.nr_color_regions; i++)
       intel_region_release(&brw->state.color_regions[i]);
@@ -144,9 +150,6 @@
 {
    struct brw_context *brw = brw_context(&intel->ctx);
 
-   /* Check that we didn't just wrap our batchbuffer at a bad time. */
-   assert(!brw->no_batch_wrap);
-
    brw->curbe.need_new_bo = GL_TRUE;
 
    /* Mark all context state as needing to be re-emitted.
@@ -175,20 +178,6 @@
    brw_context(&intel->ctx)->state.dirty.brw |= BRW_NEW_FENCE;
 }
 
-/* called from intelWaitForIdle() and intelFlush()
- *
- * For now, just flush everything.  Could be smarter later.
- */
-static GLuint brw_flush_cmd( void )
-{
-   struct brw_mi_flush flush;
-   flush.opcode = CMD_MI_FLUSH;
-   flush.pad = 0;
-   flush.flags = BRW_FLUSH_STATE_CACHE;
-   return *(GLuint *)&flush;
-}
-
-
 static void brw_invalidate_state( struct intel_context *intel, GLuint new_state )
 {
    /* nothing */
@@ -209,6 +198,5 @@
    brw->intel.vtbl.finish_batch = brw_finish_batch;
    brw->intel.vtbl.destroy = brw_destroy_context;
    brw->intel.vtbl.set_draw_region = brw_set_draw_region;
-   brw->intel.vtbl.flush_cmd = brw_flush_cmd;
    brw->intel.vtbl.debug_batch = brw_debug_batch;
 }
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 964ee10..6895f64 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -152,8 +152,21 @@
           */
          return;
       }
+      c->instruction = _mesa_calloc(BRW_WM_MAX_INSN * sizeof(*c->instruction));
+      c->prog_instructions = _mesa_calloc(BRW_WM_MAX_INSN *
+					  sizeof(*c->prog_instructions));
+      c->vreg = _mesa_calloc(BRW_WM_MAX_VREG * sizeof(*c->vreg));
+      c->refs = _mesa_calloc(BRW_WM_MAX_REF * sizeof(*c->refs));
    } else {
+      void *instruction = c->instruction;
+      void *prog_instructions = c->prog_instructions;
+      void *vreg = c->vreg;
+      void *refs = c->refs;
       memset(c, 0, sizeof(*brw->wm.compile_data));
+      c->instruction = instruction;
+      c->prog_instructions = prog_instructions;
+      c->vreg = vreg;
+      c->refs = refs;
    }
    memcpy(&c->key, key, sizeof(*key));
 
@@ -217,7 +230,7 @@
        ctx->Color.AlphaEnabled)
       lookup |= IZ_PS_KILL_ALPHATEST_BIT;
 
-   if (fp->program.Base.OutputsWritten & (1<<FRAG_RESULT_DEPTH))
+   if (fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
       lookup |= IZ_PS_COMPUTES_DEPTH_BIT;
 
    /* _NEW_DEPTH */
@@ -333,7 +346,7 @@
    key->nr_color_regions = brw->state.nr_color_regions;
 
    /* CACHE_NEW_VS_PROG */
-   key->vp_outputs_written = brw->vs.prog_data->outputs_written & DO_SETUP_BITS;
+   key->vp_outputs_written = brw->vs.prog_data->outputs_written;
 
    /* The unique fragment program ID */
    key->program_string_id = fp->id;
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index 47aa4da..b9b987e 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -76,10 +76,10 @@
 
    GLushort tex_swizzles[BRW_MAX_TEX_UNIT];
 
-   GLuint program_string_id:32;
    GLushort origin_x, origin_y;
    GLushort drawable_height;
-   GLuint vp_outputs_written;
+   GLbitfield64 vp_outputs_written;
+   GLuint program_string_id:32;
 };
 
 
@@ -162,6 +162,8 @@
 #define BRW_WM_MAX_CONST 256
 #define BRW_WM_MAX_SUBROUTINE 16
 
+/* used in masks next to WRITEMASK_*. */
+#define SATURATE (1<<5)
 
 
 /* New opcodes to track internal operations required for WM unit.
@@ -200,7 +202,7 @@
     * simplifying and adding instructions for interpolation and
     * framebuffer writes.
     */
-   struct prog_instruction prog_instructions[BRW_WM_MAX_INSN];
+   struct prog_instruction *prog_instructions;
    GLuint nr_fp_insns;
    GLuint fp_temp;
    GLuint fp_interp_emitted;
@@ -211,7 +213,7 @@
    struct prog_src_register pixel_w;
 
 
-   struct brw_wm_value vreg[BRW_WM_MAX_VREG];
+   struct brw_wm_value *vreg;
    GLuint nr_vreg;
 
    struct brw_wm_value creg[BRW_WM_MAX_PARAM];
@@ -228,10 +230,10 @@
    struct brw_wm_ref undef_ref;
    struct brw_wm_value undef_value;
 
-   struct brw_wm_ref refs[BRW_WM_MAX_REF];
+   struct brw_wm_ref *refs;
    GLuint nr_refs;
 
-   struct brw_wm_instruction instruction[BRW_WM_MAX_INSN];
+   struct brw_wm_instruction *instruction;
    GLuint nr_insns;
 
    struct brw_wm_constref constref[BRW_WM_MAX_CONST];
@@ -306,10 +308,141 @@
 GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp);
 void brw_wm_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c);
 
+/* brw_wm_emit.c */
+void emit_alu1(struct brw_compile *p,
+	       struct brw_instruction *(*func)(struct brw_compile *,
+					       struct brw_reg,
+					       struct brw_reg),
+	       const struct brw_reg *dst,
+	       GLuint mask,
+	       const struct brw_reg *arg0);
+void emit_alu2(struct brw_compile *p,
+	       struct brw_instruction *(*func)(struct brw_compile *,
+					       struct brw_reg,
+					       struct brw_reg,
+					       struct brw_reg),
+	       const struct brw_reg *dst,
+	       GLuint mask,
+	       const struct brw_reg *arg0,
+	       const struct brw_reg *arg1);
+void emit_cinterp(struct brw_compile *p,
+		  const struct brw_reg *dst,
+		  GLuint mask,
+		  const struct brw_reg *arg0);
 void emit_ddxy(struct brw_compile *p,
 	       const struct brw_reg *dst,
 	       GLuint mask,
 	       GLboolean is_ddx,
 	       const struct brw_reg *arg0);
+void emit_delta_xy(struct brw_compile *p,
+		   const struct brw_reg *dst,
+		   GLuint mask,
+		   const struct brw_reg *arg0);
+void emit_dp3(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1);
+void emit_dp4(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1);
+void emit_dph(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1);
+void emit_fb_write(struct brw_wm_compile *c,
+		   struct brw_reg *arg0,
+		   struct brw_reg *arg1,
+		   struct brw_reg *arg2,
+		   GLuint target,
+		   GLuint eot);
+void emit_frontfacing(struct brw_compile *p,
+		      const struct brw_reg *dst,
+		      GLuint mask);
+void emit_linterp(struct brw_compile *p,
+		  const struct brw_reg *dst,
+		  GLuint mask,
+		  const struct brw_reg *arg0,
+		  const struct brw_reg *deltas);
+void emit_lrp(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1,
+	      const struct brw_reg *arg2);
+void emit_mad(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1,
+	      const struct brw_reg *arg2);
+void emit_math1(struct brw_wm_compile *c,
+		GLuint function,
+		const struct brw_reg *dst,
+		GLuint mask,
+		const struct brw_reg *arg0);
+void emit_math2(struct brw_wm_compile *c,
+		GLuint function,
+		const struct brw_reg *dst,
+		GLuint mask,
+		const struct brw_reg *arg0,
+		const struct brw_reg *arg1);
+void emit_min(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1);
+void emit_max(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1);
+void emit_pinterp(struct brw_compile *p,
+		  const struct brw_reg *dst,
+		  GLuint mask,
+		  const struct brw_reg *arg0,
+		  const struct brw_reg *deltas,
+		  const struct brw_reg *w);
+void emit_pixel_xy(struct brw_wm_compile *c,
+		   const struct brw_reg *dst,
+		   GLuint mask);
+void emit_pixel_w(struct brw_wm_compile *c,
+		  const struct brw_reg *dst,
+		  GLuint mask,
+		  const struct brw_reg *arg0,
+		  const struct brw_reg *deltas);
+void emit_sop(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      GLuint cond,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1);
+void emit_tex(struct brw_wm_compile *c,
+	      struct brw_reg *dst,
+	      GLuint dst_flags,
+	      struct brw_reg *arg,
+	      struct brw_reg depth_payload,
+	      GLuint tex_idx,
+	      GLuint sampler,
+	      GLboolean shadow);
+void emit_txb(struct brw_wm_compile *c,
+	      struct brw_reg *dst,
+	      GLuint dst_flags,
+	      struct brw_reg *arg,
+	      struct brw_reg depth_payload,
+	      GLuint tex_idx,
+	      GLuint sampler);
+void emit_wpos_xy(struct brw_wm_compile *c,
+		  const struct brw_reg *dst,
+		  GLuint mask,
+		  const struct brw_reg *arg0);
+void emit_xpd(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1);
 
 #endif
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index bf80a29..f316e0c 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -44,6 +44,7 @@
    return reg;
 }
 
+
 /* Payload R0:
  *
  * R0.0 -- pixel mask, one bit for each of 4 pixels in 4 tiles,
@@ -60,42 +61,50 @@
  * R1.8 -- ?
  */
 
-
-static void emit_pixel_xy(struct brw_compile *p,
-			  const struct brw_reg *dst,
-			  GLuint mask)
+void emit_pixel_xy(struct brw_wm_compile *c,
+		   const struct brw_reg *dst,
+		   GLuint mask)
 {
+   struct brw_compile *p = &c->func;
    struct brw_reg r1 = brw_vec1_grf(1, 0);
    struct brw_reg r1_uw = retype(r1, BRW_REGISTER_TYPE_UW);
+   struct brw_reg dst0_uw, dst1_uw;
 
+   brw_push_insn_state(p);
    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
 
+   if (c->dispatch_width == 16) {
+      dst0_uw = vec16(retype(dst[0], BRW_REGISTER_TYPE_UW));
+      dst1_uw = vec16(retype(dst[1], BRW_REGISTER_TYPE_UW));
+   } else {
+      dst0_uw = vec8(retype(dst[0], BRW_REGISTER_TYPE_UW));
+      dst1_uw = vec8(retype(dst[1], BRW_REGISTER_TYPE_UW));
+   }
+
    /* Calculate pixel centers by adding 1 or 0 to each of the
     * micro-tile coordinates passed in r1.
     */
    if (mask & WRITEMASK_X) {
       brw_ADD(p,
-	      vec16(retype(dst[0], BRW_REGISTER_TYPE_UW)),
+	      dst0_uw,
 	      stride(suboffset(r1_uw, 4), 2, 4, 0),
 	      brw_imm_v(0x10101010));
    }
 
    if (mask & WRITEMASK_Y) {
       brw_ADD(p,
-	      vec16(retype(dst[1], BRW_REGISTER_TYPE_UW)),
+	      dst1_uw,
 	      stride(suboffset(r1_uw,5), 2, 4, 0),
 	      brw_imm_v(0x11001100));
    }
-
-   brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
+   brw_pop_insn_state(p);
 }
 
 
-
-static void emit_delta_xy(struct brw_compile *p,
-			  const struct brw_reg *dst,
-			  GLuint mask,
-			  const struct brw_reg *arg0)
+void emit_delta_xy(struct brw_compile *p,
+		   const struct brw_reg *dst,
+		   GLuint mask,
+		   const struct brw_reg *arg0)
 {
    struct brw_reg r1 = brw_vec1_grf(1, 0);
 
@@ -118,10 +127,10 @@
    }
 }
 
-static void emit_wpos_xy(struct brw_wm_compile *c,
-			 const struct brw_reg *dst,
-			 GLuint mask,
-			 const struct brw_reg *arg0)
+void emit_wpos_xy(struct brw_wm_compile *c,
+		  const struct brw_reg *dst,
+		  GLuint mask,
+		  const struct brw_reg *arg0)
 {
    struct brw_compile *p = &c->func;
 
@@ -146,12 +155,14 @@
 }
 
 
-static void emit_pixel_w( struct brw_compile *p,
-			  const struct brw_reg *dst,
-			  GLuint mask,
-			  const struct brw_reg *arg0,
-			  const struct brw_reg *deltas)
+void emit_pixel_w(struct brw_wm_compile *c,
+		  const struct brw_reg *dst,
+		  GLuint mask,
+		  const struct brw_reg *arg0,
+		  const struct brw_reg *deltas)
 {
+   struct brw_compile *p = &c->func;
+
    /* Don't need this if all you are doing is interpolating color, for
     * instance.
     */
@@ -165,21 +176,29 @@
       brw_MAC(p, brw_message_reg(2), suboffset(interp3, 1), deltas[1]);
 
       /* Calc w */
-      brw_math_16( p, dst[3],
-		   BRW_MATH_FUNCTION_INV,
-		   BRW_MATH_SATURATE_NONE,
-		   2, brw_null_reg(),
-		   BRW_MATH_PRECISION_FULL);
+      if (c->dispatch_width == 16) {
+	 brw_math_16(p, dst[3],
+		     BRW_MATH_FUNCTION_INV,
+		     BRW_MATH_SATURATE_NONE,
+		     2, brw_null_reg(),
+		     BRW_MATH_PRECISION_FULL);
+      } else {
+	 brw_math(p, dst[3],
+		  BRW_MATH_FUNCTION_INV,
+		  BRW_MATH_SATURATE_NONE,
+		  2, brw_null_reg(),
+		  BRW_MATH_DATA_VECTOR,
+		  BRW_MATH_PRECISION_FULL);
+      }
    }
 }
 
 
-
-static void emit_linterp( struct brw_compile *p, 
-			 const struct brw_reg *dst,
-			 GLuint mask,
-			 const struct brw_reg *arg0,
-			 const struct brw_reg *deltas )
+void emit_linterp(struct brw_compile *p,
+		  const struct brw_reg *dst,
+		  GLuint mask,
+		  const struct brw_reg *arg0,
+		  const struct brw_reg *deltas)
 {
    struct brw_reg interp[4];
    GLuint nr = arg0[0].nr;
@@ -199,12 +218,12 @@
 }
 
 
-static void emit_pinterp( struct brw_compile *p, 
-			  const struct brw_reg *dst,
-			  GLuint mask,
-			  const struct brw_reg *arg0,
-			  const struct brw_reg *deltas,
-			  const struct brw_reg *w)
+void emit_pinterp(struct brw_compile *p,
+		  const struct brw_reg *dst,
+		  GLuint mask,
+		  const struct brw_reg *arg0,
+		  const struct brw_reg *deltas,
+		  const struct brw_reg *w)
 {
    struct brw_reg interp[4];
    GLuint nr = arg0[0].nr;
@@ -229,10 +248,10 @@
 }
 
 
-static void emit_cinterp( struct brw_compile *p, 
-			 const struct brw_reg *dst,
-			 GLuint mask,
-			 const struct brw_reg *arg0 )
+void emit_cinterp(struct brw_compile *p,
+		  const struct brw_reg *dst,
+		  GLuint mask,
+		  const struct brw_reg *arg0)
 {
    struct brw_reg interp[4];
    GLuint nr = arg0[0].nr;
@@ -251,9 +270,9 @@
 }
 
 /* Sets the destination channels to 1.0 or 0.0 according to glFrontFacing. */
-static void emit_frontfacing( struct brw_compile *p,
-			      const struct brw_reg *dst,
-			      GLuint mask )
+void emit_frontfacing(struct brw_compile *p,
+		      const struct brw_reg *dst,
+		      GLuint mask)
 {
    struct brw_reg r1_6ud = retype(brw_vec1_grf(1, 6), BRW_REGISTER_TYPE_UD);
    GLuint i;
@@ -352,13 +371,13 @@
       brw_set_saturate(p, 0);
 }
 
-static void emit_alu1( struct brw_compile *p, 
-		       struct brw_instruction *(*func)(struct brw_compile *, 
-						       struct brw_reg, 
-						       struct brw_reg),
-		       const struct brw_reg *dst,
-		       GLuint mask,
-		       const struct brw_reg *arg0 )
+void emit_alu1(struct brw_compile *p,
+	       struct brw_instruction *(*func)(struct brw_compile *,
+					       struct brw_reg,
+					       struct brw_reg),
+	       const struct brw_reg *dst,
+	       GLuint mask,
+	       const struct brw_reg *arg0)
 {
    GLuint i;
 
@@ -376,15 +395,15 @@
 }
 
 
-static void emit_alu2( struct brw_compile *p, 
-		       struct brw_instruction *(*func)(struct brw_compile *, 
-						       struct brw_reg, 
-						       struct brw_reg, 
-						       struct brw_reg),
-		       const struct brw_reg *dst,
-		       GLuint mask,
-		       const struct brw_reg *arg0,
-		       const struct brw_reg *arg1 )
+void emit_alu2(struct brw_compile *p,
+	       struct brw_instruction *(*func)(struct brw_compile *,
+					       struct brw_reg,
+					       struct brw_reg,
+					       struct brw_reg),
+	       const struct brw_reg *dst,
+	       GLuint mask,
+	       const struct brw_reg *arg0,
+	       const struct brw_reg *arg1)
 {
    GLuint i;
 
@@ -402,12 +421,12 @@
 }
 
 
-static void emit_mad( struct brw_compile *p, 
-		      const struct brw_reg *dst,
-		      GLuint mask,
-		      const struct brw_reg *arg0,
-		      const struct brw_reg *arg1,
-		      const struct brw_reg *arg2 )
+void emit_mad(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1,
+	      const struct brw_reg *arg2)
 {
    GLuint i;
 
@@ -422,26 +441,12 @@
    }
 }
 
-static void emit_trunc( struct brw_compile *p,
-		      const struct brw_reg *dst,
-		      GLuint mask,
-		      const struct brw_reg *arg0)
-{
-   GLuint i;
-
-   for (i = 0; i < 4; i++) {
-      if (mask & (1<<i)) {
-	 brw_RNDZ(p, dst[i], arg0[i]);
-      }
-   }
-}
-
-static void emit_lrp( struct brw_compile *p, 
-		      const struct brw_reg *dst,
-		      GLuint mask,
-		      const struct brw_reg *arg0,
-		      const struct brw_reg *arg1,
-		      const struct brw_reg *arg2 )
+void emit_lrp(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1,
+	      const struct brw_reg *arg2)
 {
    GLuint i;
 
@@ -461,21 +466,24 @@
    }
 }
 
-static void emit_sop( struct brw_compile *p, 
-		      const struct brw_reg *dst,
-		      GLuint mask,
-		      GLuint cond,
-		      const struct brw_reg *arg0,
-		      const struct brw_reg *arg1 )
+void emit_sop(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      GLuint cond,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1)
 {
    GLuint i;
 
    for (i = 0; i < 4; i++) {
       if (mask & (1<<i)) {	
-	 brw_MOV(p, dst[i], brw_imm_f(0));
+	 brw_push_insn_state(p);
 	 brw_CMP(p, brw_null_reg(), cond, arg0[i], arg1[i]);
+	 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+	 brw_MOV(p, dst[i], brw_imm_f(0));
+	 brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
 	 brw_MOV(p, dst[i], brw_imm_f(1.0));
-	 brw_set_predicate_control_flag_value(p, 0xff);
+	 brw_pop_insn_state(p);
       }
    }
 }
@@ -559,11 +567,11 @@
    }
 }
 
-static void emit_max( struct brw_compile *p, 
-		      const struct brw_reg *dst,
-		      GLuint mask,
-		      const struct brw_reg *arg0,
-		      const struct brw_reg *arg1 )
+void emit_max(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1)
 {
    GLuint i;
 
@@ -583,11 +591,11 @@
    }
 }
 
-static void emit_min( struct brw_compile *p, 
-		      const struct brw_reg *dst,
-		      GLuint mask,
-		      const struct brw_reg *arg0,
-		      const struct brw_reg *arg1 )
+void emit_min(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1)
 {
    GLuint i;
 
@@ -608,11 +616,11 @@
 }
 
 
-static void emit_dp3( struct brw_compile *p, 
-		      const struct brw_reg *dst,
-		      GLuint mask,
-		      const struct brw_reg *arg0,
-		      const struct brw_reg *arg1 )
+void emit_dp3(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1)
 {
    int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
 
@@ -630,11 +638,11 @@
 }
 
 
-static void emit_dp4( struct brw_compile *p, 
-		      const struct brw_reg *dst,
-		      GLuint mask,
-		      const struct brw_reg *arg0,
-		      const struct brw_reg *arg1 )
+void emit_dp4(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1)
 {
    int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
 
@@ -653,11 +661,11 @@
 }
 
 
-static void emit_dph( struct brw_compile *p, 
-		      const struct brw_reg *dst,
-		      GLuint mask,
-		      const struct brw_reg *arg0,
-		      const struct brw_reg *arg1 )
+void emit_dph(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1)
 {
    const int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
 
@@ -676,15 +684,15 @@
 }
 
 
-static void emit_xpd( struct brw_compile *p, 
-		      const struct brw_reg *dst,
-		      GLuint mask,
-		      const struct brw_reg *arg0,
-		      const struct brw_reg *arg1 )
+void emit_xpd(struct brw_compile *p,
+	      const struct brw_reg *dst,
+	      GLuint mask,
+	      const struct brw_reg *arg0,
+	      const struct brw_reg *arg1)
 {
    GLuint i;
 
-   assert(!(mask & WRITEMASK_W) == WRITEMASK_X);
+   assert((mask & WRITEMASK_W) != WRITEMASK_W);
    
    for (i = 0 ; i < 3; i++) {
       if (mask & (1<<i)) {
@@ -701,41 +709,68 @@
 }
 
 
-static void emit_math1( struct brw_compile *p, 
-			GLuint function,
-			const struct brw_reg *dst,
-			GLuint mask,
-			const struct brw_reg *arg0 )
+void emit_math1(struct brw_wm_compile *c,
+		GLuint function,
+		const struct brw_reg *dst,
+		GLuint mask,
+		const struct brw_reg *arg0)
 {
+   struct brw_compile *p = &c->func;
    int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+   GLuint saturate = ((mask & SATURATE) ?
+		      BRW_MATH_SATURATE_SATURATE :
+		      BRW_MATH_SATURATE_NONE);
 
    if (!(mask & WRITEMASK_XYZW))
       return; /* Do not emit dead code */
 
    assert(is_power_of_two(mask & WRITEMASK_XYZW));
 
+   /* If compressed, this will write message reg 2,3 from arg0.x's 16
+    * channels.
+    */
    brw_MOV(p, brw_message_reg(2), arg0[0]);
 
    /* Send two messages to perform all 16 operations:
     */
-   brw_math_16(p, 
-	       dst[dst_chan],
+   brw_push_insn_state(p);
+   brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+   brw_math(p,
+	    dst[dst_chan],
+	    function,
+	    saturate,
+	    2,
+	    brw_null_reg(),
+	    BRW_MATH_DATA_VECTOR,
+	    BRW_MATH_PRECISION_FULL);
+
+   if (c->dispatch_width == 16) {
+      brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
+      brw_math(p,
+	       offset(dst[dst_chan],1),
 	       function,
-	       (mask & SATURATE) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
-	       2,
+	       saturate,
+	       3,
 	       brw_null_reg(),
+	       BRW_MATH_DATA_VECTOR,
 	       BRW_MATH_PRECISION_FULL);
+   }
+   brw_pop_insn_state(p);
 }
 
 
-static void emit_math2( struct brw_compile *p, 
-			GLuint function,
-			const struct brw_reg *dst,
-			GLuint mask,
-			const struct brw_reg *arg0,
-			const struct brw_reg *arg1)
+void emit_math2(struct brw_wm_compile *c,
+		GLuint function,
+		const struct brw_reg *dst,
+		GLuint mask,
+		const struct brw_reg *arg0,
+		const struct brw_reg *arg1)
 {
+   struct brw_compile *p = &c->func;
    int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+   GLuint saturate = ((mask & SATURATE) ?
+		      BRW_MATH_SATURATE_SATURATE :
+		      BRW_MATH_SATURATE_NONE);
 
    if (!(mask & WRITEMASK_XYZW))
       return; /* Do not emit dead code */
@@ -746,173 +781,233 @@
 
    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
    brw_MOV(p, brw_message_reg(2), arg0[0]);
-   brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
-   brw_MOV(p, brw_message_reg(4), sechalf(arg0[0]));
+   if (c->dispatch_width == 16) {
+      brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
+      brw_MOV(p, brw_message_reg(4), sechalf(arg0[0]));
+   }
 
    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
    brw_MOV(p, brw_message_reg(3), arg1[0]);
-   brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
-   brw_MOV(p, brw_message_reg(5), sechalf(arg1[0]));
+   if (c->dispatch_width == 16) {
+      brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
+      brw_MOV(p, brw_message_reg(5), sechalf(arg1[0]));
+   }
 
-   
-   /* Send two messages to perform all 16 operations:
-    */
    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
    brw_math(p, 
 	    dst[dst_chan],
 	    function,
-	    (mask & SATURATE) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
+	    saturate,
 	    2,
 	    brw_null_reg(),
 	    BRW_MATH_DATA_VECTOR,
 	    BRW_MATH_PRECISION_FULL);
 
-   brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
-   brw_math(p, 
-	    offset(dst[dst_chan],1),
-	    function,
-	    (mask & SATURATE) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
-	    4,
-	    brw_null_reg(),
-	    BRW_MATH_DATA_VECTOR,
-	    BRW_MATH_PRECISION_FULL);
-   
+   /* Send two messages to perform all 16 operations:
+    */
+   if (c->dispatch_width == 16) {
+      brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
+      brw_math(p,
+	       offset(dst[dst_chan],1),
+	       function,
+	       saturate,
+	       4,
+	       brw_null_reg(),
+	       BRW_MATH_DATA_VECTOR,
+	       BRW_MATH_PRECISION_FULL);
+   }
    brw_pop_insn_state(p);
 }
-		     
 
 
-static void emit_tex( struct brw_wm_compile *c,
-		      const struct brw_wm_instruction *inst,
-		      struct brw_reg *dst,
-		      GLuint dst_flags,
-		      struct brw_reg *arg )
+void emit_tex(struct brw_wm_compile *c,
+	      struct brw_reg *dst,
+	      GLuint dst_flags,
+	      struct brw_reg *arg,
+	      struct brw_reg depth_payload,
+	      GLuint tex_idx,
+	      GLuint sampler,
+	      GLboolean shadow)
 {
    struct brw_compile *p = &c->func;
-   GLuint msgLength, responseLength;
-   GLuint i, nr;
+   struct intel_context *intel = &p->brw->intel;
+   struct brw_reg dst_retyped;
+   GLuint cur_mrf = 2, response_length;
+   GLuint i, nr_texcoords;
    GLuint emit;
    GLuint msg_type;
+   GLuint mrf_per_channel;
+   GLuint simd_mode;
+
+   if (c->dispatch_width == 16) {
+      mrf_per_channel = 2;
+      response_length = 8;
+      dst_retyped = retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW);
+      simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD16;
+   } else {
+      mrf_per_channel = 1;
+      response_length = 4;
+      dst_retyped = retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW);
+      simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD8;
+   }
 
    /* How many input regs are there?
     */
-   switch (inst->tex_idx) {
+   switch (tex_idx) {
    case TEXTURE_1D_INDEX:
       emit = WRITEMASK_X;
-      nr = 1;
+      nr_texcoords = 1;
       break;
    case TEXTURE_2D_INDEX:
    case TEXTURE_RECT_INDEX:
       emit = WRITEMASK_XY;
-      nr = 2;
+      nr_texcoords = 2;
       break;
    case TEXTURE_3D_INDEX:
    case TEXTURE_CUBE_INDEX:
       emit = WRITEMASK_XYZ;
-      nr = 3;
+      nr_texcoords = 3;
       break;
    default:
       /* unexpected target */
       abort();
    }
 
-   if (inst->tex_shadow) {
-      nr = 4;
-      emit |= WRITEMASK_W;
-   }
+   /* Pre-Ironlake, the 8-wide sampler always took u,v,r. */
+   if (!intel->is_ironlake && c->dispatch_width == 8)
+      nr_texcoords = 3;
 
-   msgLength = 1;
+   /* For shadow comparisons, we have to supply u,v,r. */
+   if (shadow)
+      nr_texcoords = 3;
 
-   for (i = 0; i < nr; i++) {
-      static const GLuint swz[4] = {0,1,2,2};
-      if (emit & (1<<i)) 
-	 brw_MOV(p, brw_message_reg(msgLength+1), arg[swz[i]]);
+   /* Emit the texcoords. */
+   for (i = 0; i < nr_texcoords; i++) {
+      if (emit & (1<<i))
+	 brw_MOV(p, brw_message_reg(cur_mrf), arg[i]);
       else
-	 brw_MOV(p, brw_message_reg(msgLength+1), brw_imm_f(0));
-      msgLength += 2;
+	 brw_MOV(p, brw_message_reg(cur_mrf), brw_imm_f(0));
+      cur_mrf += mrf_per_channel;
    }
 
-   responseLength = 8;		/* always */
+   /* Fill in the shadow comparison reference value. */
+   if (shadow) {
+      if (intel->is_ironlake) {
+	 /* Fill in the cube map array index value. */
+	 brw_MOV(p, brw_message_reg(cur_mrf), brw_imm_f(0));
+	 cur_mrf += mrf_per_channel;
+      } else if (c->dispatch_width == 8) {
+	 /* Fill in the LOD bias value. */
+	 brw_MOV(p, brw_message_reg(cur_mrf), brw_imm_f(0));
+	 cur_mrf += mrf_per_channel;
+      }
+      brw_MOV(p, brw_message_reg(cur_mrf), arg[2]);
+      cur_mrf += mrf_per_channel;
+   }
 
-   if (BRW_IS_IGDNG(p->brw)) {
-       if (inst->tex_shadow)
-           msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE_IGDNG;
-       else
-           msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_IGDNG;
+   if (intel->is_ironlake) {
+      if (shadow)
+	 msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_COMPARE_IGDNG;
+      else
+	 msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_IGDNG;
    } else {
-       if (inst->tex_shadow)
-           msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE;
-       else
-           msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE;
+      /* Note that G45 and older determines shadow compare and dispatch width
+       * from message length for most messages.
+       */
+      if (c->dispatch_width == 16 && shadow)
+	 msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE;
+      else
+	 msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE;
    }
 
-   brw_SAMPLE(p, 
-	      retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW),
+   brw_SAMPLE(p,
+	      dst_retyped,
 	      1,
-	      retype(c->payload.depth[0].hw_reg, BRW_REGISTER_TYPE_UW),
-              SURF_INDEX_TEXTURE(inst->tex_unit),
-	      inst->tex_unit,	  /* sampler */
-	      inst->writemask,
-	      msg_type, 
-	      responseLength,
-	      msgLength,
-	      0,	
+	      retype(depth_payload, BRW_REGISTER_TYPE_UW),
+              SURF_INDEX_TEXTURE(sampler),
+	      sampler,
+	      dst_flags & WRITEMASK_XYZW,
+	      msg_type,
+	      response_length,
+	      cur_mrf - 1,
+	      0,
 	      1,
-	      BRW_SAMPLER_SIMD_MODE_SIMD16);	
+	      simd_mode);
 }
 
 
-static void emit_txb( struct brw_wm_compile *c,
-		      const struct brw_wm_instruction *inst,
-		      struct brw_reg *dst,
-		      GLuint dst_flags,
-		      struct brw_reg *arg )
+void emit_txb(struct brw_wm_compile *c,
+	      struct brw_reg *dst,
+	      GLuint dst_flags,
+	      struct brw_reg *arg,
+	      struct brw_reg depth_payload,
+	      GLuint tex_idx,
+	      GLuint sampler)
 {
    struct brw_compile *p = &c->func;
+   struct intel_context *intel = &p->brw->intel;
    GLuint msgLength;
    GLuint msg_type;
-   /* Shadow ignored for txb.
+   GLuint mrf_per_channel;
+   GLuint response_length;
+   struct brw_reg dst_retyped;
+
+   /* The G45 and older chipsets don't support 8-wide dispatch for LOD biased
+    * samples, so we'll use the 16-wide instruction, leave the second halves
+    * undefined, and trust the execution mask to keep the undefined pixels
+    * from mattering.
     */
-   switch (inst->tex_idx) {
+   if (c->dispatch_width == 16 || !intel->is_ironlake) {
+      if (intel->is_ironlake)
+	 msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_BIAS_IGDNG;
+      else
+	 msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
+      mrf_per_channel = 2;
+      dst_retyped = retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW);
+      response_length = 8;
+   } else {
+      msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_BIAS_IGDNG;
+      mrf_per_channel = 1;
+      dst_retyped = retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW);
+      response_length = 4;
+   }
+
+   /* Shadow ignored for txb. */
+   switch (tex_idx) {
    case TEXTURE_1D_INDEX:
-      brw_MOV(p, brw_message_reg(2), arg[0]);
-      brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
-      brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
+      brw_MOV(p, brw_message_reg(2 + 0 * mrf_per_channel), arg[0]);
+      brw_MOV(p, brw_message_reg(2 + 1 * mrf_per_channel), brw_imm_f(0));
+      brw_MOV(p, brw_message_reg(2 + 2 * mrf_per_channel), brw_imm_f(0));
       break;
    case TEXTURE_2D_INDEX:
    case TEXTURE_RECT_INDEX:
-      brw_MOV(p, brw_message_reg(2), arg[0]);
-      brw_MOV(p, brw_message_reg(4), arg[1]);
-      brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
+      brw_MOV(p, brw_message_reg(2 + 0 * mrf_per_channel), arg[0]);
+      brw_MOV(p, brw_message_reg(2 + 1 * mrf_per_channel), arg[1]);
+      brw_MOV(p, brw_message_reg(2 + 2 * mrf_per_channel), brw_imm_f(0));
       break;
    case TEXTURE_3D_INDEX:
    case TEXTURE_CUBE_INDEX:
-      brw_MOV(p, brw_message_reg(2), arg[0]);
-      brw_MOV(p, brw_message_reg(4), arg[1]);
-      brw_MOV(p, brw_message_reg(6), arg[2]);
+      brw_MOV(p, brw_message_reg(2 + 0 * mrf_per_channel), arg[0]);
+      brw_MOV(p, brw_message_reg(2 + 1 * mrf_per_channel), arg[1]);
+      brw_MOV(p, brw_message_reg(2 + 2 * mrf_per_channel), arg[2]);
       break;
    default:
       /* unexpected target */
       abort();
    }
 
-   brw_MOV(p, brw_message_reg(8), arg[3]);
-   msgLength = 9;
-
-   if (BRW_IS_IGDNG(p->brw))
-       msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS_IGDNG;
-   else
-       msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
+   brw_MOV(p, brw_message_reg(2 + 3 * mrf_per_channel), arg[3]);
+   msgLength = 2 + 4 * mrf_per_channel - 1;
 
    brw_SAMPLE(p, 
-	      retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW),
+	      dst_retyped,
 	      1,
-	      retype(c->payload.depth[0].hw_reg, BRW_REGISTER_TYPE_UW),
-              SURF_INDEX_TEXTURE(inst->tex_unit),
-	      inst->tex_unit,	  /* sampler */
-	      inst->writemask,
+	      retype(depth_payload, BRW_REGISTER_TYPE_UW),
+              SURF_INDEX_TEXTURE(sampler),
+	      sampler,
+	      dst_flags & WRITEMASK_XYZW,
 	      msg_type,
-	      8,		/* responseLength */
+	      response_length,
 	      msgLength,
 	      0,	
 	      1,
@@ -920,11 +1015,13 @@
 }
 
 
-static void emit_lit( struct brw_compile *p, 
-		      const struct brw_reg *dst,
-		      GLuint mask,
-		      const struct brw_reg *arg0 )
+static void emit_lit(struct brw_wm_compile *c,
+		     const struct brw_reg *dst,
+		     GLuint mask,
+		     const struct brw_reg *arg0)
 {
+   struct brw_compile *p = &c->func;
+
    assert((mask & WRITEMASK_XW) == 0);
 
    if (mask & WRITEMASK_Y) {
@@ -934,7 +1031,7 @@
    }
 
    if (mask & WRITEMASK_Z) {
-      emit_math2(p, BRW_MATH_FUNCTION_POW,
+      emit_math2(c, BRW_MATH_FUNCTION_POW,
 		 &dst[2],
 		 WRITEMASK_X | (mask & SATURATE),
 		 &arg0[1],
@@ -989,7 +1086,7 @@
 
    brw_push_insn_state(p);
    brw_set_mask_control(p, BRW_MASK_DISABLE);
-   brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); //IMASK
+   brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); /* IMASK */
    brw_AND(p, r0uw, c->emit_mask_reg, r0uw);
    brw_pop_insn_state(p);
 }
@@ -1001,7 +1098,13 @@
 			   GLuint eot )
 {
    struct brw_compile *p = &c->func;
-   
+   struct brw_reg dst;
+
+   if (c->dispatch_width == 16)
+      dst = retype(vec16(brw_null_reg()), BRW_REGISTER_TYPE_UW);
+   else
+      dst = retype(vec8(brw_null_reg()), BRW_REGISTER_TYPE_UW);
+
    /* Pass through control information:
     */
 /*  mov (8) m1.0<1>:ud   r1.0<8;8,1>:ud   { Align1 NoMask } */
@@ -1018,7 +1121,7 @@
    /* Send framebuffer write message: */
 /*  send (16) null.0<1>:uw m0               r0.0<8;8,1>:uw   0x85a04000:ud    { Align1 EOT } */
    brw_fb_WRITE(p,
-		retype(vec16(brw_null_reg()), BRW_REGISTER_TYPE_UW),
+		dst,
 		base_reg,
 		retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW),
 		target,		
@@ -1050,14 +1153,15 @@
  * \param arg1  the pass-through depth value
  * \param arg2  the shader-computed depth value
  */
-static void emit_fb_write( struct brw_wm_compile *c,
-			   struct brw_reg *arg0,
-			   struct brw_reg *arg1,
-			   struct brw_reg *arg2,
-			   GLuint target,
-			   GLuint eot)
+void emit_fb_write(struct brw_wm_compile *c,
+		   struct brw_reg *arg0,
+		   struct brw_reg *arg1,
+		   struct brw_reg *arg2,
+		   GLuint target,
+		   GLuint eot)
 {
    struct brw_compile *p = &c->func;
+   struct brw_context *brw = p->brw;
    GLuint nr = 2;
    GLuint channel;
 
@@ -1069,30 +1173,37 @@
    /* I don't really understand how this achieves the color interleave
     * (ie RGBARGBA) in the result:  [Do the saturation here]
     */
-   {
-      brw_push_insn_state(p);
-      
-      for (channel = 0; channel < 4; channel++) {
+   brw_push_insn_state(p);
+
+   for (channel = 0; channel < 4; channel++) {
+      if (c->dispatch_width == 16 && brw->has_compr4) {
+	 /* By setting the high bit of the MRF register number, we indicate
+	  * that we want COMPR4 mode - instead of doing the usual destination
+	  * + 1 for the second half we get destination + 4.
+	  */
+	 brw_MOV(p,
+		 brw_message_reg(nr + channel + (1 << 7)),
+		 arg0[channel]);
+      } else {
 	 /*  mov (8) m2.0<1>:ud   r28.0<8;8,1>:ud  { Align1 } */
 	 /*  mov (8) m6.0<1>:ud   r29.0<8;8,1>:ud  { Align1 SecHalf } */
-
 	 brw_set_compression_control(p, BRW_COMPRESSION_NONE);
 	 brw_MOV(p,
 		 brw_message_reg(nr + channel),
 		 arg0[channel]);
-       
-	 brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
-	 brw_MOV(p,
-		 brw_message_reg(nr + channel + 4),
-		 sechalf(arg0[channel]));
-      }
 
-      /* skip over the regs populated above:
-       */
-      nr += 8;
-   
-      brw_pop_insn_state(p);
+	 if (c->dispatch_width == 16) {
+	    brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
+	    brw_MOV(p,
+		    brw_message_reg(nr + channel + 4),
+		    sechalf(arg0[channel]));
+	 }
+      }
    }
+   /* skip over the regs populated above:
+    */
+   nr += 8;
+   brw_pop_insn_state(p);
 
    if (c->key.source_depth_to_render_target)
    {
@@ -1142,7 +1253,7 @@
 	      get_element_ud(brw_vec8_grf(1,0), 6), 
 	      brw_imm_ud(1<<26)); 
 
-      jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
+      jmp = brw_JMPI(p, ip, ip, brw_imm_w(0));
       {
 	 emit_aa(c, arg1, 2);
 	 fire_fb_write(c, 0, nr, target, eot);
@@ -1156,7 +1267,6 @@
    }
 }
 
-
 /**
  * Move a GPR to scratch memory. 
  */
@@ -1294,7 +1404,7 @@
 	 /* Generated instructions for calculating triangle interpolants:
 	  */
       case WM_PIXELXY:
-	 emit_pixel_xy(p, dst, dst_flags);
+	 emit_pixel_xy(c, dst, dst_flags);
 	 break;
 
       case WM_DELTAXY:
@@ -1306,7 +1416,7 @@
 	 break;
 
       case WM_PIXELW:
-	 emit_pixel_w(p, dst, dst_flags, args[0], args[1]);
+	 emit_pixel_w(c, dst, dst_flags, args[0], args[1]);
 	 break;
 
       case WM_LINTERP:
@@ -1364,7 +1474,7 @@
 	 break;
 
       case OPCODE_TRUNC:
-	 emit_trunc(p, dst, dst_flags, args[0]);
+	 emit_alu1(p, brw_RNDZ, dst, dst_flags, args[0]);
 	 break;
 
       case OPCODE_LRP:
@@ -1391,27 +1501,27 @@
 	 /* Higher math functions:
 	  */
       case OPCODE_RCP:
-	 emit_math1(p, BRW_MATH_FUNCTION_INV, dst, dst_flags, args[0]);
+	 emit_math1(c, BRW_MATH_FUNCTION_INV, dst, dst_flags, args[0]);
 	 break;
 
       case OPCODE_RSQ:
-	 emit_math1(p, BRW_MATH_FUNCTION_RSQ, dst, dst_flags, args[0]);
+	 emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, dst_flags, args[0]);
 	 break;
 
       case OPCODE_SIN:
-	 emit_math1(p, BRW_MATH_FUNCTION_SIN, dst, dst_flags, args[0]);
+	 emit_math1(c, BRW_MATH_FUNCTION_SIN, dst, dst_flags, args[0]);
 	 break;
 
       case OPCODE_COS:
-	 emit_math1(p, BRW_MATH_FUNCTION_COS, dst, dst_flags, args[0]);
+	 emit_math1(c, BRW_MATH_FUNCTION_COS, dst, dst_flags, args[0]);
 	 break;
 
       case OPCODE_EX2:
-	 emit_math1(p, BRW_MATH_FUNCTION_EXP, dst, dst_flags, args[0]);
+	 emit_math1(c, BRW_MATH_FUNCTION_EXP, dst, dst_flags, args[0]);
 	 break;
 
       case OPCODE_LG2:
-	 emit_math1(p, BRW_MATH_FUNCTION_LOG, dst, dst_flags, args[0]);
+	 emit_math1(c, BRW_MATH_FUNCTION_LOG, dst, dst_flags, args[0]);
 	 break;
 
       case OPCODE_SCS:
@@ -1419,13 +1529,13 @@
 	  * fixup for 16-element execution.
 	  */
 	 if (dst_flags & WRITEMASK_X)
-	    emit_math1(p, BRW_MATH_FUNCTION_COS, dst, (dst_flags&SATURATE)|WRITEMASK_X, args[0]);
+	    emit_math1(c, BRW_MATH_FUNCTION_COS, dst, (dst_flags&SATURATE)|WRITEMASK_X, args[0]);
 	 if (dst_flags & WRITEMASK_Y)
-	    emit_math1(p, BRW_MATH_FUNCTION_SIN, dst+1, (dst_flags&SATURATE)|WRITEMASK_X, args[0]);
+	    emit_math1(c, BRW_MATH_FUNCTION_SIN, dst+1, (dst_flags&SATURATE)|WRITEMASK_X, args[0]);
 	 break;
 
       case OPCODE_POW:
-	 emit_math2(p, BRW_MATH_FUNCTION_POW, dst, dst_flags, args[0], args[1]);
+	 emit_math2(c, BRW_MATH_FUNCTION_POW, dst, dst_flags, args[0], args[1]);
 	 break;
 
 	 /* Comparisons:
@@ -1463,17 +1573,20 @@
 	break;
 
       case OPCODE_LIT:
-	 emit_lit(p, dst, dst_flags, args[0]);
+	 emit_lit(c, dst, dst_flags, args[0]);
 	 break;
 
 	 /* Texturing operations:
 	  */
       case OPCODE_TEX:
-	 emit_tex(c, inst, dst, dst_flags, args[0]);
+	 emit_tex(c, dst, dst_flags, args[0], c->payload.depth[0].hw_reg,
+		  inst->tex_idx, inst->tex_unit,
+		  inst->tex_shadow);
 	 break;
 
       case OPCODE_TXB:
-	 emit_txb(c, inst, dst, dst_flags, args[0]);
+	 emit_txb(c, dst, dst_flags, args[0], c->payload.depth[0].hw_reg,
+		  inst->tex_idx, inst->tex_unit);
 	 break;
 
       case OPCODE_KIL:
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index 0e86d75..3737faf 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -138,7 +138,6 @@
    reg.CondMask = COND_TR;
    reg.CondSwizzle = 0;
    reg.CondSrc = 0;
-   reg.pad = 0;
    return reg;
 }
 
@@ -182,6 +181,8 @@
 static struct prog_instruction *get_fp_inst(struct brw_wm_compile *c)
 {
    assert(c->nr_fp_insns < BRW_WM_MAX_INSN);
+   memset(&c->prog_instructions[c->nr_fp_insns], 0,
+	  sizeof(*c->prog_instructions));
    return &c->prog_instructions[c->nr_fp_insns++];
 }
 
@@ -448,7 +449,6 @@
       break;
 
    case FRAG_ATTRIB_FACE:
-      /* XXX review/test this case */
       emit_op(c,
               WM_FRONTFACING,
               dst_mask(dst, WRITEMASK_X),
@@ -957,7 +957,7 @@
 
 
 
-static void emit_fb_write( struct brw_wm_compile *c )
+static void emit_render_target_writes( struct brw_wm_compile *c )
 {
    struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
    struct prog_src_register outdepth = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DEPTH);
@@ -985,7 +985,7 @@
    }
    else {
       /* if gl_FragData[0] is written, use it, else use gl_FragColor */
-      if (c->fp->program.Base.OutputsWritten & (1 << FRAG_RESULT_DATA0))
+      if (c->fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DATA0))
          outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0);
       else 
          outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR);
@@ -1154,7 +1154,7 @@
 	 out->DstReg.WriteMask = 0;
 	 break;
       case OPCODE_END:
-	 emit_fb_write(c);
+	 emit_render_target_writes(c);
 	 break;
       case OPCODE_PRINT:
 	 break;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 28d6d4e..fde83ee 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -371,7 +371,7 @@
 	  for (j = 0; j < 4; j++)
 	     set_reg(c, PROGRAM_PAYLOAD, fp_input, j, reg);
        }
-       if (c->key.vp_outputs_written & (1 << i)) {
+       if (c->key.vp_outputs_written & BITFIELD64_BIT(i)) {
 	  reg_index += 2;
        }
     }
@@ -550,42 +550,6 @@
     }
 }
 
-
-/**
- * Same as \sa get_src_reg() but if the register is a literal, emit
- * a brw_reg encoding the literal.
- * Note that a brw instruction only allows one src operand to be a literal.
- * For instructions with more than one operand, only the second can be a
- * literal.  This means that we treat some literals as constants/uniforms
- * (which why PROGRAM_CONSTANT is checked in fetch_constants()).
- * 
- */
-static struct brw_reg get_src_reg_imm(struct brw_wm_compile *c, 
-                                      const struct prog_instruction *inst,
-                                      GLuint srcRegIndex, GLuint channel)
-{
-    const struct prog_src_register *src = &inst->SrcReg[srcRegIndex];
-    if (src->File == PROGRAM_CONSTANT) {
-       /* a literal */
-       const int component = GET_SWZ(src->Swizzle, channel);
-       const GLfloat *param =
-          c->fp->program.Base.Parameters->ParameterValues[src->Index];
-       GLfloat value = param[component];
-       if (src->Negate & (1 << channel))
-          value = -value;
-       if (src->Abs)
-          value = FABSF(value);
-#if 0
-       printf("  form immed value %f for chan %d\n", value, channel);
-#endif
-       return brw_imm_f(value);
-    }
-    else {
-       return get_src_reg(c, inst, srcRegIndex, channel);
-    }
-}
-
-
 /**
  * Subroutines are minimal support for resusable instruction sequences.
  * They are implemented as simply as possible to minimise overhead: there
@@ -650,542 +614,110 @@
     }
 }
 
-static void emit_trunc( struct brw_wm_compile *c,
-                        const struct prog_instruction *inst)
-{
-    int i;
-    struct brw_compile *p = &c->func;
-    GLuint mask = inst->DstReg.WriteMask;
-    brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
-    for (i = 0; i < 4; i++) {
-	if (mask & (1<<i)) {
-	    struct brw_reg src, dst;
-	    dst = get_dst_reg(c, inst, i);
-	    src = get_src_reg(c, inst, 0, i);
-	    brw_RNDZ(p, dst, src);
-	}
-    }
-    brw_set_saturate(p, 0);
-}
-
-static void emit_mov( struct brw_wm_compile *c,
-                      const struct prog_instruction *inst)
-{
-    int i;
-    struct brw_compile *p = &c->func;
-    GLuint mask = inst->DstReg.WriteMask;
-    brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
-    for (i = 0; i < 4; i++) {
-	if (mask & (1<<i)) {
-	    struct brw_reg src, dst;
-	    dst = get_dst_reg(c, inst, i);
-            /* XXX some moves from immediate value don't work reliably!!! */
-            /*src = get_src_reg_imm(c, inst, 0, i);*/
-            src = get_src_reg(c, inst, 0, i);
-	    brw_MOV(p, dst, src);
-	}
-    }
-    brw_set_saturate(p, 0);
-}
-
-static void emit_pixel_xy(struct brw_wm_compile *c,
-                          const struct prog_instruction *inst)
-{
-    struct brw_reg r1 = brw_vec1_grf(1, 0);
-    struct brw_reg r1_uw = retype(r1, BRW_REGISTER_TYPE_UW);
-
-    struct brw_reg dst0, dst1;
-    struct brw_compile *p = &c->func;
-    GLuint mask = inst->DstReg.WriteMask;
-
-    dst0 = get_dst_reg(c, inst, 0);
-    dst1 = get_dst_reg(c, inst, 1);
-    /* Calculate pixel centers by adding 1 or 0 to each of the
-     * micro-tile coordinates passed in r1.
-     */
-    if (mask & WRITEMASK_X) {
-	brw_ADD(p,
-		vec8(retype(dst0, BRW_REGISTER_TYPE_UW)),
-		stride(suboffset(r1_uw, 4), 2, 4, 0),
-		brw_imm_v(0x10101010));
-    }
-
-    if (mask & WRITEMASK_Y) {
-	brw_ADD(p,
-		vec8(retype(dst1, BRW_REGISTER_TYPE_UW)),
-		stride(suboffset(r1_uw, 5), 2, 4, 0),
-		brw_imm_v(0x11001100));
-    }
-}
-
-static void emit_delta_xy(struct brw_wm_compile *c,
-                          const struct prog_instruction *inst)
-{
-    struct brw_reg r1 = brw_vec1_grf(1, 0);
-    struct brw_reg dst0, dst1, src0, src1;
-    struct brw_compile *p = &c->func;
-    GLuint mask = inst->DstReg.WriteMask;
-
-    dst0 = get_dst_reg(c, inst, 0);
-    dst1 = get_dst_reg(c, inst, 1);
-    src0 = get_src_reg(c, inst, 0, 0);
-    src1 = get_src_reg(c, inst, 0, 1);
-    /* Calc delta X,Y by subtracting origin in r1 from the pixel
-     * centers.
-     */
-    if (mask & WRITEMASK_X) {
-	brw_ADD(p,
-		dst0,
-		retype(src0, BRW_REGISTER_TYPE_UW),
-		negate(r1));
-    }
-
-    if (mask & WRITEMASK_Y) {
-	brw_ADD(p,
-		dst1,
-		retype(src1, BRW_REGISTER_TYPE_UW),
-		negate(suboffset(r1,1)));
-
-    }
-}
-
-static void fire_fb_write( struct brw_wm_compile *c,
-                           GLuint base_reg,
-                           GLuint nr,
-                           GLuint target,
-                           GLuint eot)
-{
-    struct brw_compile *p = &c->func;
-    /* Pass through control information:
-     */
-    /*  mov (8) m1.0<1>:ud   r1.0<8;8,1>:ud   { Align1 NoMask } */
-    {
-	brw_push_insn_state(p);
-	brw_set_mask_control(p, BRW_MASK_DISABLE); /* ? */
-	brw_MOV(p,
-		brw_message_reg(base_reg + 1),
-		brw_vec8_grf(1, 0));
-	brw_pop_insn_state(p);
-    }
-    /* Send framebuffer write message: */
-    brw_fb_WRITE(p,
-	    retype(vec8(brw_null_reg()), BRW_REGISTER_TYPE_UW),
-	    base_reg,
-	    retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW),
-	    target,              
-	    nr,
-	    0,
-	    eot);
-}
-
-static void emit_fb_write(struct brw_wm_compile *c,
-                          const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    int nr = 2;
-    int channel;
-    GLuint target, eot;
-    struct brw_reg src0;
-
-    /* Reserve a space for AA - may not be needed:
-     */
-    if (c->key.aa_dest_stencil_reg)
-	nr += 1;
-
-    brw_push_insn_state(p);
-    for (channel = 0; channel < 4; channel++) {
-        src0 = get_src_reg(c,  inst, 0, channel);
-        /*  mov (8) m2.0<1>:ud   r28.0<8;8,1>:ud  { Align1 } */
-        /*  mov (8) m6.0<1>:ud   r29.0<8;8,1>:ud  { Align1 SecHalf } */
-        brw_MOV(p, brw_message_reg(nr + channel), src0);
-    }
-    /* skip over the regs populated above: */
-    nr += 8;
-    brw_pop_insn_state(p);
-
-    if (c->key.source_depth_to_render_target) {
-       if (c->key.computes_depth) {
-          src0 = get_src_reg(c, inst, 2, 2);
-          brw_MOV(p, brw_message_reg(nr), src0);
-       }
-       else {
-          src0 = get_src_reg(c, inst, 1, 1);
-          brw_MOV(p, brw_message_reg(nr), src0);
-       }
-
-       nr += 2;
-    }
-
-    if (c->key.dest_depth_reg) {
-        const GLuint comp = c->key.dest_depth_reg / 2;
-        const GLuint off = c->key.dest_depth_reg % 2;
-
-        if (off != 0) {
-            /* XXX this code needs review/testing */
-            struct brw_reg arg1_0 = get_src_reg(c, inst, 1, comp);
-            struct brw_reg arg1_1 = get_src_reg(c, inst, 1, comp+1);
-
-            brw_push_insn_state(p);
-            brw_set_compression_control(p, BRW_COMPRESSION_NONE);
-
-            brw_MOV(p, brw_message_reg(nr), offset(arg1_0, 1));
-            /* 2nd half? */
-            brw_MOV(p, brw_message_reg(nr+1), arg1_1);
-            brw_pop_insn_state(p);
-        }
-        else
-        {
-            struct brw_reg src =  get_src_reg(c, inst, 1, 1);
-            brw_MOV(p, brw_message_reg(nr), src);
-        }
-        nr += 2;
-   }
-
-    target = INST_AUX_GET_TARGET(inst->Aux);
-    eot = inst->Aux & INST_AUX_EOT;
-    fire_fb_write(c, 0, nr, target, eot);
-}
-
-static void emit_pixel_w( struct brw_wm_compile *c,
-                          const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    GLuint mask = inst->DstReg.WriteMask;
-    if (mask & WRITEMASK_W) {
-	struct brw_reg dst, src0, delta0, delta1;
-	struct brw_reg interp3;
-
-	dst = get_dst_reg(c, inst, 3);
-	src0 = get_src_reg(c, inst, 0, 0);
-	delta0 = get_src_reg(c, inst, 1, 0);
-	delta1 = get_src_reg(c, inst, 1, 1);
-
-	interp3 = brw_vec1_grf(src0.nr+1, 4);
-	/* Calc 1/w - just linterp wpos[3] optimized by putting the
-	 * result straight into a message reg.
-	 */
-	brw_LINE(p, brw_null_reg(), interp3, delta0);
-	brw_MAC(p, brw_message_reg(2), suboffset(interp3, 1), delta1);
-
-	/* Calc w */
-	brw_math_16( p, dst,
-		BRW_MATH_FUNCTION_INV,
-		BRW_MATH_SATURATE_NONE,
-		2, brw_null_reg(),
-		BRW_MATH_PRECISION_FULL);
-    }
-}
-
-static void emit_linterp(struct brw_wm_compile *c,
-                         const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    GLuint mask = inst->DstReg.WriteMask;
-    struct brw_reg interp[4];
-    struct brw_reg dst, delta0, delta1;
-    struct brw_reg src0;
-    GLuint nr, i;
-
-    src0 = get_src_reg(c, inst, 0, 0);
-    delta0 = get_src_reg(c, inst, 1, 0);
-    delta1 = get_src_reg(c, inst, 1, 1);
-    nr = src0.nr;
-
-    interp[0] = brw_vec1_grf(nr, 0);
-    interp[1] = brw_vec1_grf(nr, 4);
-    interp[2] = brw_vec1_grf(nr+1, 0);
-    interp[3] = brw_vec1_grf(nr+1, 4);
-
-    for(i = 0; i < 4; i++ ) {
-	if (mask & (1<<i)) {
-	    dst = get_dst_reg(c, inst, i);
-	    brw_LINE(p, brw_null_reg(), interp[i], delta0);
-	    brw_MAC(p, dst, suboffset(interp[i],1), delta1);
-	}
-    }
-}
-
-static void emit_cinterp(struct brw_wm_compile *c,
-                         const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    GLuint mask = inst->DstReg.WriteMask;
-
-    struct brw_reg interp[4];
-    struct brw_reg dst, src0;
-    GLuint nr, i;
-
-    src0 = get_src_reg(c, inst, 0, 0);
-    nr = src0.nr;
-
-    interp[0] = brw_vec1_grf(nr, 0);
-    interp[1] = brw_vec1_grf(nr, 4);
-    interp[2] = brw_vec1_grf(nr+1, 0);
-    interp[3] = brw_vec1_grf(nr+1, 4);
-
-    for(i = 0; i < 4; i++ ) {
-	if (mask & (1<<i)) {
-	    dst = get_dst_reg(c, inst, i);
-	    brw_MOV(p, dst, suboffset(interp[i],3));
-	}
-    }
-}
-
-static void emit_pinterp(struct brw_wm_compile *c,
-                         const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    GLuint mask = inst->DstReg.WriteMask;
-
-    struct brw_reg interp[4];
-    struct brw_reg dst, delta0, delta1;
-    struct brw_reg src0, w;
-    GLuint nr, i;
-
-    src0 = get_src_reg(c, inst, 0, 0);
-    delta0 = get_src_reg(c, inst, 1, 0);
-    delta1 = get_src_reg(c, inst, 1, 1);
-    w = get_src_reg(c, inst, 2, 3);
-    nr = src0.nr;
-
-    interp[0] = brw_vec1_grf(nr, 0);
-    interp[1] = brw_vec1_grf(nr, 4);
-    interp[2] = brw_vec1_grf(nr+1, 0);
-    interp[3] = brw_vec1_grf(nr+1, 4);
-
-    for(i = 0; i < 4; i++ ) {
-	if (mask & (1<<i)) {
-	    dst = get_dst_reg(c, inst, i);
-	    brw_LINE(p, brw_null_reg(), interp[i], delta0);
-	    brw_MAC(p, dst, suboffset(interp[i],1), 
-		    delta1);
-	    brw_MUL(p, dst, dst, w);
-	}
-    }
-}
-
-/* Sets the destination channels to 1.0 or 0.0 according to glFrontFacing. */
-static void emit_frontfacing(struct brw_wm_compile *c,
-			     const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    struct brw_reg r1_6ud = retype(brw_vec1_grf(1, 6), BRW_REGISTER_TYPE_UD);
-    struct brw_reg dst;
-    GLuint mask = inst->DstReg.WriteMask;
-    int i;
-
-    for (i = 0; i < 4; i++) {
-	if (mask & (1<<i)) {
-	    dst = get_dst_reg(c, inst, i);
-	    brw_MOV(p, dst, brw_imm_f(0.0));
-	}
-    }
-
-    /* bit 31 is "primitive is back face", so checking < (1 << 31) gives
-     * us front face
-     */
-    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, r1_6ud, brw_imm_ud(1 << 31));
-    for (i = 0; i < 4; i++) {
-	if (mask & (1<<i)) {
-	    dst = get_dst_reg(c, inst, i);
-	    brw_MOV(p, dst, brw_imm_f(1.0));
-	}
-    }
-    brw_set_predicate_control_flag_value(p, 0xff);
-}
-
-static void emit_xpd(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    int i;
-    struct brw_compile *p = &c->func;
-    GLuint mask = inst->DstReg.WriteMask;
-    for (i = 0; i < 4; i++) {
-	GLuint i2 = (i+2)%3;
-	GLuint i1 = (i+1)%3;
-	if (mask & (1<<i)) {
-	    struct brw_reg src0, src1, dst;
-	    dst = get_dst_reg(c, inst, i);
-	    src0 = negate(get_src_reg(c, inst, 0, i2));
-	    src1 = get_src_reg_imm(c, inst, 1, i1);
-	    brw_MUL(p, brw_null_reg(), src0, src1);
-	    src0 = get_src_reg(c, inst, 0, i1);
-	    src1 = get_src_reg_imm(c, inst, 1, i2);
-	    brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
-	    brw_MAC(p, dst, src0, src1);
-	    brw_set_saturate(p, 0);
-	}
-    }
-    brw_set_saturate(p, 0);
-}
-
-static void emit_dp3(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    struct brw_reg src0[3], src1[3], dst;
-    int i;
-    struct brw_compile *p = &c->func;
-    GLuint mask = inst->DstReg.WriteMask;
-    int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
-
-    if (!(mask & WRITEMASK_XYZW))
-	return;
-
-    assert(is_power_of_two(mask & WRITEMASK_XYZW));
-
-    for (i = 0; i < 3; i++) {
-	src0[i] = get_src_reg(c, inst, 0, i);
-	src1[i] = get_src_reg_imm(c, inst, 1, i);
-    }
-
-    dst = get_dst_reg(c, inst, dst_chan);
-    brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
-    brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
-    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
-    brw_MAC(p, dst, src0[2], src1[2]);
-    brw_set_saturate(p, 0);
-}
-
-static void emit_dp4(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    struct brw_reg src0[4], src1[4], dst;
-    int i;
-    struct brw_compile *p = &c->func;
-    GLuint mask = inst->DstReg.WriteMask;
-    int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
-
-    if (!(mask & WRITEMASK_XYZW))
-	return;
-
-    assert(is_power_of_two(mask & WRITEMASK_XYZW));
-
-    for (i = 0; i < 4; i++) {
-	src0[i] = get_src_reg(c, inst, 0, i);
-	src1[i] = get_src_reg_imm(c, inst, 1, i);
-    }
-    dst = get_dst_reg(c, inst, dst_chan);
-    brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
-    brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
-    brw_MAC(p, brw_null_reg(), src0[2], src1[2]);
-    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
-    brw_MAC(p, dst, src0[3], src1[3]);
-    brw_set_saturate(p, 0);
-}
-
-static void emit_dph(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    struct brw_reg src0[4], src1[4], dst;
-    int i;
-    struct brw_compile *p = &c->func;
-    GLuint mask = inst->DstReg.WriteMask;
-    int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
-
-    if (!(mask & WRITEMASK_XYZW))
-	return;
-
-    assert(is_power_of_two(mask & WRITEMASK_XYZW));
-
-    for (i = 0; i < 4; i++) {
-	src0[i] = get_src_reg(c, inst, 0, i);
-	src1[i] = get_src_reg_imm(c, inst, 1, i);
-    }
-    dst = get_dst_reg(c, inst, dst_chan);
-    brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
-    brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
-    brw_MAC(p, dst, src0[2], src1[2]);
-    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
-    brw_ADD(p, dst, dst, src1[3]);
-    brw_set_saturate(p, 0);
-}
-
-/**
- * Emit a scalar instruction, like RCP, RSQ, LOG, EXP.
- * Note that the result of the function is smeared across the dest
- * register's X, Y, Z and W channels (subject to writemasking of course).
+/* Workaround for using brw_wm_emit.c's emit functions, which expect
+ * destination regs to be uniquely written.  Moves arguments out to
+ * temporaries as necessary for instructions which use their destination as
+ * a temporary.
  */
-static void emit_math1(struct brw_wm_compile *c,
-                       const struct prog_instruction *inst, GLuint func)
+static void
+unalias3(struct brw_wm_compile *c,
+	 void (*func)(struct brw_compile *c,
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1,
+		      const struct brw_reg *arg2),
+	 const struct brw_reg *dst,
+	 GLuint mask,
+	 const struct brw_reg *arg0,
+	 const struct brw_reg *arg1,
+	 const struct brw_reg *arg2)
 {
     struct brw_compile *p = &c->func;
-    struct brw_reg src0, dst;
-    GLuint mask = inst->DstReg.WriteMask;
-    int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+    struct brw_reg tmp_arg0[4], tmp_arg1[4], tmp_arg2[4];
+    int i, j;
+    int mark = mark_tmps(c);
 
-    if (!(mask & WRITEMASK_XYZW))
-	return;
+    for (j = 0; j < 4; j++) {
+	tmp_arg0[j] = arg0[j];
+	tmp_arg1[j] = arg1[j];
+	tmp_arg2[j] = arg2[j];
+    }
 
-    assert(is_power_of_two(mask & WRITEMASK_XYZW));
-
-    /* Get first component of source register */
-    dst = get_dst_reg(c, inst, dst_chan);
-    src0 = get_src_reg(c, inst, 0, 0);
-
-    brw_MOV(p, brw_message_reg(2), src0);
-    brw_math(p,
-             dst,
-             func,
-             (inst->SaturateMode != SATURATE_OFF) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
-             2,
-             brw_null_reg(),
-             BRW_MATH_DATA_VECTOR,
-             BRW_MATH_PRECISION_FULL);
-}
-
-static void emit_rcp(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    emit_math1(c, inst, BRW_MATH_FUNCTION_INV);
-}
-
-static void emit_rsq(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    emit_math1(c, inst, BRW_MATH_FUNCTION_RSQ);
-}
-
-static void emit_sin(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    emit_math1(c, inst, BRW_MATH_FUNCTION_SIN);
-}
-
-static void emit_cos(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    emit_math1(c, inst, BRW_MATH_FUNCTION_COS);
-}
-
-static void emit_ex2(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    emit_math1(c, inst, BRW_MATH_FUNCTION_EXP);
-}
-
-static void emit_lg2(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    emit_math1(c, inst, BRW_MATH_FUNCTION_LOG);
-}
-
-static void emit_add(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    struct brw_reg src0, src1, dst;
-    GLuint mask = inst->DstReg.WriteMask;
-    int i;
-    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
-    for (i = 0 ; i < 4; i++) {
+    for (i = 0; i < 4; i++) {
 	if (mask & (1<<i)) {
-	    dst = get_dst_reg(c, inst, i);
-	    src0 = get_src_reg(c, inst, 0, i);
-	    src1 = get_src_reg_imm(c, inst, 1, i);
-	    brw_ADD(p, dst, src0, src1);
+	    for (j = 0; j < 4; j++) {
+		if (arg0[j].file == dst[i].file &&
+		    dst[i].nr == arg0[j].nr) {
+		    tmp_arg0[j] = alloc_tmp(c);
+		    brw_MOV(p, tmp_arg0[j], arg0[j]);
+		}
+		if (arg1[j].file == dst[i].file &&
+		    dst[i].nr == arg1[j].nr) {
+		    tmp_arg1[j] = alloc_tmp(c);
+		    brw_MOV(p, tmp_arg1[j], arg1[j]);
+		}
+		if (arg2[j].file == dst[i].file &&
+		    dst[i].nr == arg2[j].nr) {
+		    tmp_arg2[j] = alloc_tmp(c);
+		    brw_MOV(p, tmp_arg2[j], arg2[j]);
+		}
+	    }
 	}
     }
-    brw_set_saturate(p, 0);
+
+    func(p, dst, mask, tmp_arg0, tmp_arg1, tmp_arg2);
+
+    release_tmps(c, mark);
+}
+
+/* Workaround for using brw_wm_emit.c's emit functions, which expect
+ * destination regs to be uniquely written.  Moves arguments out to
+ * temporaries as necessary for instructions which use their destination as
+ * a temporary.
+ */
+static void
+unalias2(struct brw_wm_compile *c,
+	 void (*func)(struct brw_compile *c,
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1),
+	 const struct brw_reg *dst,
+	 GLuint mask,
+	 const struct brw_reg *arg0,
+	 const struct brw_reg *arg1)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg tmp_arg0[4], tmp_arg1[4];
+    int i, j;
+    int mark = mark_tmps(c);
+
+    for (j = 0; j < 4; j++) {
+	tmp_arg0[j] = arg0[j];
+	tmp_arg1[j] = arg1[j];
+    }
+
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    for (j = 0; j < 4; j++) {
+		if (arg0[j].file == dst[i].file &&
+		    dst[i].nr == arg0[j].nr) {
+		    tmp_arg0[j] = alloc_tmp(c);
+		    brw_MOV(p, tmp_arg0[j], arg0[j]);
+		}
+		if (arg1[j].file == dst[i].file &&
+		    dst[i].nr == arg1[j].nr) {
+		    tmp_arg1[j] = alloc_tmp(c);
+		    brw_MOV(p, tmp_arg1[j], arg1[j]);
+		}
+	    }
+	}
+    }
+
+    func(p, dst, mask, tmp_arg0, tmp_arg1);
+
+    release_tmps(c, mark);
 }
 
 static void emit_arl(struct brw_wm_compile *c,
@@ -1201,180 +733,6 @@
     brw_set_saturate(p, 0);
 }
 
-
-static void emit_mul(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    struct brw_reg src0, src1, dst;
-    GLuint mask = inst->DstReg.WriteMask;
-    int i;
-    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
-    for (i = 0 ; i < 4; i++) {
-	if (mask & (1<<i)) {
-	    dst = get_dst_reg(c, inst, i);
-	    src0 = get_src_reg(c, inst, 0, i);
-	    src1 = get_src_reg_imm(c, inst, 1, i);
-	    brw_MUL(p, dst, src0, src1);
-	}
-    }
-    brw_set_saturate(p, 0);
-}
-
-static void emit_frc(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    struct brw_reg src0, dst;
-    GLuint mask = inst->DstReg.WriteMask;
-    int i;
-    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
-    for (i = 0 ; i < 4; i++) {
-	if (mask & (1<<i)) {
-	    dst = get_dst_reg(c, inst, i);
-	    src0 = get_src_reg_imm(c, inst, 0, i);
-	    brw_FRC(p, dst, src0);
-	}
-    }
-    if (inst->SaturateMode != SATURATE_OFF)
-	brw_set_saturate(p, 0);
-}
-
-static void emit_flr(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    struct brw_reg src0, dst;
-    GLuint mask = inst->DstReg.WriteMask;
-    int i;
-    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
-    for (i = 0 ; i < 4; i++) {
-	if (mask & (1<<i)) {
-	    dst = get_dst_reg(c, inst, i);
-	    src0 = get_src_reg_imm(c, inst, 0, i);
-	    brw_RNDD(p, dst, src0);
-	}
-    }
-    brw_set_saturate(p, 0);
-}
-
-
-static void emit_min_max(struct brw_wm_compile *c,
-                         const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    const GLuint mask = inst->DstReg.WriteMask;
-    const int mark = mark_tmps(c);
-    int i;
-    brw_push_insn_state(p);
-    for (i = 0; i < 4; i++) {
-	if (mask & (1<<i)) {
-            struct brw_reg real_dst = get_dst_reg(c, inst, i);
-	    struct brw_reg src0 = get_src_reg(c, inst, 0, i);
-	    struct brw_reg src1 = get_src_reg(c, inst, 1, i);
-            struct brw_reg dst;
-            /* if dst==src0 or dst==src1 we need to use a temp reg */
-            GLboolean use_temp = brw_same_reg(dst, src0) ||
-                                 brw_same_reg(dst, src1);
-            if (use_temp)
-               dst = alloc_tmp(c);
-            else
-               dst = real_dst;
-
-            /*
-            printf("  Min/max: dst %d  src0 %d  src1 %d\n",
-                   dst.nr, src0.nr, src1.nr);
-            */
-	    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
-	    brw_MOV(p, dst, src0);
-	    brw_set_saturate(p, 0);
-
-            if (inst->Opcode == OPCODE_MIN)
-               brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src1, src0);
-            else
-               brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, src1, src0);
-
-	    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
-	    brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
-	    brw_MOV(p, dst, src1);
-	    brw_set_saturate(p, 0);
-	    brw_set_predicate_control_flag_value(p, 0xff);
-            if (use_temp)
-               brw_MOV(p, real_dst, dst);
-	}
-    }
-    brw_pop_insn_state(p);
-    release_tmps(c, mark);
-}
-
-static void emit_pow(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    struct brw_reg dst, src0, src1;
-    GLuint mask = inst->DstReg.WriteMask;
-    int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
-
-    if (!(mask & WRITEMASK_XYZW))
-	return;
-
-    assert(is_power_of_two(mask & WRITEMASK_XYZW));
-
-    dst = get_dst_reg(c, inst, dst_chan);
-    src0 = get_src_reg_imm(c, inst, 0, 0);
-    src1 = get_src_reg_imm(c, inst, 1, 0);
-
-    brw_MOV(p, brw_message_reg(2), src0);
-    brw_MOV(p, brw_message_reg(3), src1);
-
-    brw_math(p,
-	    dst,
-	    BRW_MATH_FUNCTION_POW,
-	    (inst->SaturateMode != SATURATE_OFF) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
-	    2,
-	    brw_null_reg(),
-	    BRW_MATH_DATA_VECTOR,
-	    BRW_MATH_PRECISION_FULL);
-}
-
-static void emit_lrp(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    GLuint mask = inst->DstReg.WriteMask;
-    struct brw_reg dst, tmp1, tmp2, src0, src1, src2;
-    int i;
-    int mark = mark_tmps(c);
-    for (i = 0; i < 4; i++) {
-	if (mask & (1<<i)) {
-	    dst = get_dst_reg(c, inst, i);
-	    src0 = get_src_reg(c, inst, 0, i);
-
-	    src1 = get_src_reg_imm(c, inst, 1, i);
-
-	    if (src1.nr == dst.nr) {
-		tmp1 = alloc_tmp(c);
-		brw_MOV(p, tmp1, src1);
-	    } else
-		tmp1 = src1;
-
-	    src2 = get_src_reg(c, inst, 2, i);
-	    if (src2.nr == dst.nr) {
-		tmp2 = alloc_tmp(c);
-		brw_MOV(p, tmp2, src2);
-	    } else
-		tmp2 = src2;
-
-	    brw_ADD(p, dst, negate(src0), brw_imm_f(1.0));
-	    brw_MUL(p, brw_null_reg(), dst, tmp2);
-	    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
-	    brw_MAC(p, dst, src0, tmp1);
-	    brw_set_saturate(p, 0);
-	}
-	release_tmps(c, mark);
-    }
-}
-
 /**
  * For GLSL shaders, this KIL will be unconditional.
  * It may be contained inside an IF/ENDIF structure of course.
@@ -1385,94 +743,11 @@
     struct brw_reg depth = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
     brw_push_insn_state(p);
     brw_set_mask_control(p, BRW_MASK_DISABLE);
-    brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); //IMASK
+    brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); /* IMASK */
     brw_AND(p, depth, c->emit_mask_reg, depth);
     brw_pop_insn_state(p);
 }
 
-static void emit_mad(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    GLuint mask = inst->DstReg.WriteMask;
-    struct brw_reg dst, src0, src1, src2;
-    int i;
-
-    for (i = 0; i < 4; i++) {
-	if (mask & (1<<i)) {
-	    dst = get_dst_reg(c, inst, i);
-	    src0 = get_src_reg(c, inst, 0, i);
-	    src1 = get_src_reg_imm(c, inst, 1, i);
-	    src2 = get_src_reg_imm(c, inst, 2, i);
-	    brw_MUL(p, dst, src0, src1);
-
-	    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
-	    brw_ADD(p, dst, dst, src2);
-	    brw_set_saturate(p, 0);
-	}
-    }
-}
-
-static void emit_sop(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst, GLuint cond)
-{
-    struct brw_compile *p = &c->func;
-    GLuint mask = inst->DstReg.WriteMask;
-    struct brw_reg dst, src0, src1;
-    int i;
-
-    for (i = 0; i < 4; i++) {
-	if (mask & (1<<i)) {
-	    dst = get_dst_reg(c, inst, i);
-	    src0 = get_src_reg(c, inst, 0, i);
-	    src1 = get_src_reg_imm(c, inst, 1, i);
-	    brw_push_insn_state(p);
-	    brw_CMP(p, brw_null_reg(), cond, src0, src1);
-	    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
-	    brw_MOV(p, dst, brw_imm_f(0.0));
-	    brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
-	    brw_MOV(p, dst, brw_imm_f(1.0));
-	    brw_pop_insn_state(p);
-	}
-    }
-}
-
-static void emit_slt(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    emit_sop(c, inst, BRW_CONDITIONAL_L);
-}
-
-static void emit_sle(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    emit_sop(c, inst, BRW_CONDITIONAL_LE);
-}
-
-static void emit_sgt(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    emit_sop(c, inst, BRW_CONDITIONAL_G);
-}
-
-static void emit_sge(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    emit_sop(c, inst, BRW_CONDITIONAL_GE);
-}
-
-static void emit_seq(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    emit_sop(c, inst, BRW_CONDITIONAL_EQ);
-}
-
-static void emit_sne(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    emit_sop(c, inst, BRW_CONDITIONAL_NEQ);
-}
-
 static INLINE struct brw_reg high_words( struct brw_reg reg )
 {
     return stride( suboffset( retype( reg, BRW_REGISTER_TYPE_W ), 1 ),
@@ -2525,196 +1800,6 @@
     
     release_tmps( c, mark );
 }
-    
-static void emit_wpos_xy(struct brw_wm_compile *c,
-                         const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    GLuint mask = inst->DstReg.WriteMask;
-    struct brw_reg src0[2], dst[2];
-
-    dst[0] = get_dst_reg(c, inst, 0);
-    dst[1] = get_dst_reg(c, inst, 1);
-
-    src0[0] = get_src_reg(c, inst, 0, 0);
-    src0[1] = get_src_reg(c, inst, 0, 1);
-
-    /* Calculate the pixel offset from window bottom left into destination
-     * X and Y channels.
-     */
-    if (mask & WRITEMASK_X) {
-	/* X' = X - origin_x */
-	brw_ADD(p,
-		dst[0],
-		retype(src0[0], BRW_REGISTER_TYPE_W),
-		brw_imm_d(0 - c->key.origin_x));
-    }
-
-    if (mask & WRITEMASK_Y) {
-	/* Y' = height - (Y - origin_y) = height + origin_y - Y */
-	brw_ADD(p,
-		dst[1],
-		negate(retype(src0[1], BRW_REGISTER_TYPE_W)),
-		brw_imm_d(c->key.origin_y + c->key.drawable_height - 1));
-    }
-}
-
-/* TODO
-   BIAS on SIMD8 not working yet...
- */	
-static void emit_txb(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    struct brw_reg dst[4], src[4], payload_reg;
-    /* Note: TexSrcUnit was already looked up through SamplerTextures[] */
-    const GLuint unit = inst->TexSrcUnit;
-    GLuint i;
-    GLuint msg_type;
-
-    assert(unit < BRW_MAX_TEX_UNIT);
-
-    payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
-
-    for (i = 0; i < 4; i++) 
-	dst[i] = get_dst_reg(c, inst, i);
-    for (i = 0; i < 4; i++)
-	src[i] = get_src_reg(c, inst, 0, i);
-
-    switch (inst->TexSrcTarget) {
-	case TEXTURE_1D_INDEX:
-	    brw_MOV(p, brw_message_reg(2), src[0]);         /* s coord */
-	    brw_MOV(p, brw_message_reg(3), brw_imm_f(0));   /* t coord */
-	    brw_MOV(p, brw_message_reg(4), brw_imm_f(0));   /* r coord */
-	    break;
-	case TEXTURE_2D_INDEX:
-	case TEXTURE_RECT_INDEX:
-	    brw_MOV(p, brw_message_reg(2), src[0]);
-	    brw_MOV(p, brw_message_reg(3), src[1]);
-	    brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
-	    break;
-	case TEXTURE_3D_INDEX:
-	case TEXTURE_CUBE_INDEX:
-	    brw_MOV(p, brw_message_reg(2), src[0]);
-	    brw_MOV(p, brw_message_reg(3), src[1]);
-	    brw_MOV(p, brw_message_reg(4), src[2]);
-	    break;
-	default:
-            /* invalid target */
-            abort();
-    }
-    brw_MOV(p, brw_message_reg(5), src[3]);          /* bias */
-    brw_MOV(p, brw_message_reg(6), brw_imm_f(0));    /* ref (unused?) */
-
-    if (BRW_IS_IGDNG(p->brw)) {
-        msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_BIAS_IGDNG;
-    } else {
-        /* Does it work well on SIMD8? */
-        msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
-    }
-
-    brw_SAMPLE(p,
-               retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),  /* dest */
-               1,                                           /* msg_reg_nr */
-               retype(payload_reg, BRW_REGISTER_TYPE_UW),   /* src0 */
-               SURF_INDEX_TEXTURE(unit),
-               unit,                                        /* sampler */
-               inst->DstReg.WriteMask,                      /* writemask */
-               msg_type,                                    /* msg_type */
-               4,                                           /* response_length */
-               4,                                           /* msg_length */
-               0,                                           /* eot */
-               1,
-               BRW_SAMPLER_SIMD_MODE_SIMD8);	
-}
-
-
-static void emit_tex(struct brw_wm_compile *c,
-                     const struct prog_instruction *inst)
-{
-    struct brw_compile *p = &c->func;
-    struct brw_reg dst[4], src[4], payload_reg;
-    /* Note: TexSrcUnit was already looked up through SamplerTextures[] */
-    const GLuint unit = inst->TexSrcUnit;
-    GLuint msg_len;
-    GLuint i, nr;
-    GLuint emit;
-    GLboolean shadow = (c->key.shadowtex_mask & (1<<unit)) ? 1 : 0;
-    GLuint msg_type;
-
-    assert(unit < BRW_MAX_TEX_UNIT);
-
-    payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
-
-    for (i = 0; i < 4; i++) 
-	dst[i] = get_dst_reg(c, inst, i);
-    for (i = 0; i < 4; i++)
-	src[i] = get_src_reg(c, inst, 0, i);
-
-    switch (inst->TexSrcTarget) {
-	case TEXTURE_1D_INDEX:
-	    emit = WRITEMASK_X;
-	    nr = 1;
-	    break;
-	case TEXTURE_2D_INDEX:
-	case TEXTURE_RECT_INDEX:
-	    emit = WRITEMASK_XY;
-	    nr = 2;
-	    break;
-	case TEXTURE_3D_INDEX:
-	case TEXTURE_CUBE_INDEX:
-	    emit = WRITEMASK_XYZ;
-	    nr = 3;
-	    break;
-	default:
-           /* invalid target */
-           abort();
-    }
-    msg_len = 1;
-
-    /* move/load S, T, R coords */
-    for (i = 0; i < nr; i++) {
-	static const GLuint swz[4] = {0,1,2,2};
-	if (emit & (1<<i))
-	    brw_MOV(p, brw_message_reg(msg_len+1), src[swz[i]]);
-	else
-	    brw_MOV(p, brw_message_reg(msg_len+1), brw_imm_f(0));
-	msg_len += 1;
-    }
-
-    if (shadow) {
-       brw_MOV(p, brw_message_reg(5), brw_imm_f(0));  /* lod / bias */
-       brw_MOV(p, brw_message_reg(6), src[2]);        /* ref value / R coord */
-    }
-
-    if (BRW_IS_IGDNG(p->brw)) {
-        if (shadow)
-            msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_COMPARE_IGDNG;
-        else
-            msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_IGDNG;
-    } else {
-        /* Does it work for shadow on SIMD8 ? */
-        msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE;
-    }
-    
-    brw_SAMPLE(p,
-               retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW), /* dest */
-               1,                                          /* msg_reg_nr */
-               retype(payload_reg, BRW_REGISTER_TYPE_UW),  /* src0 */
-               SURF_INDEX_TEXTURE(unit),
-               unit,                                       /* sampler */
-               inst->DstReg.WriteMask,                     /* writemask */
-               msg_type,                                   /* msg_type */
-               4,                                          /* response_length */
-               shadow ? 6 : 4,                             /* msg_length */
-               0,                                          /* eot */
-               1,
-               BRW_SAMPLER_SIMD_MODE_SIMD8);	
-
-    if (shadow)
-	brw_MOV(p, dst[3], brw_imm_f(1.0));
-}
-
 
 /**
  * Resolve subroutine calls after code emit is done.
@@ -2741,6 +1826,7 @@
 
 static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
 {
+   struct intel_context *intel = &brw->intel;
 #define MAX_IF_DEPTH 32
 #define MAX_LOOP_DEPTH 32
     struct brw_instruction *if_inst[MAX_IF_DEPTH], *loop_inst[MAX_LOOP_DEPTH];
@@ -2771,137 +1857,153 @@
         if (c->fp->use_const_buffer)
            fetch_constants(c, inst);
 
-	if (inst->CondUpdate)
-	    brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
-	else
-	    brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE);
+	if (inst->Opcode != OPCODE_ARL) {
+	   for (j = 0; j < 4; j++) {
+	      if (inst->DstReg.WriteMask & (1 << j))
+		 dst[j] = get_dst_reg(c, inst, j);
+	      else
+		 dst[j] = brw_null_reg();
+	   }
+	}
+	for (j = 0; j < brw_wm_nr_args(inst->Opcode); j++)
+	    get_argument_regs(c, inst, j, args[j], WRITEMASK_XYZW);
 
 	dst_flags = inst->DstReg.WriteMask;
 	if (inst->SaturateMode == SATURATE_ZERO_ONE)
 	    dst_flags |= SATURATE;
 
+	if (inst->CondUpdate)
+	    brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+	else
+	    brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE);
+
 	switch (inst->Opcode) {
 	    case WM_PIXELXY:
-		emit_pixel_xy(c, inst);
+		emit_pixel_xy(c, dst, dst_flags);
 		break;
 	    case WM_DELTAXY: 
-		emit_delta_xy(c, inst);
+		emit_delta_xy(p, dst, dst_flags, args[0]);
 		break;
 	    case WM_PIXELW:
-		emit_pixel_w(c, inst);
+		emit_pixel_w(c, dst, dst_flags, args[0], args[1]);
 		break;	
 	    case WM_LINTERP:
-		emit_linterp(c, inst);
+		emit_linterp(p, dst, dst_flags, args[0], args[1]);
 		break;
 	    case WM_PINTERP:
-		emit_pinterp(c, inst);
+		emit_pinterp(p, dst, dst_flags, args[0], args[1], args[2]);
 		break;
 	    case WM_CINTERP:
-		emit_cinterp(c, inst);
+		emit_cinterp(p, dst, dst_flags, args[0]);
 		break;
 	    case WM_WPOSXY:
-		emit_wpos_xy(c, inst);
+		emit_wpos_xy(c, dst, dst_flags, args[0]);
 		break;
 	    case WM_FB_WRITE:
-		emit_fb_write(c, inst);
+		emit_fb_write(c, args[0], args[1], args[2],
+			      INST_AUX_GET_TARGET(inst->Aux),
+			      inst->Aux & INST_AUX_EOT);
 		break;
 	    case WM_FRONTFACING:
-		emit_frontfacing(c, inst);
+		emit_frontfacing(p, dst, dst_flags);
 		break;
 	    case OPCODE_ADD:
-		emit_add(c, inst);
+		emit_alu2(p, brw_ADD, dst, dst_flags, args[0], args[1]);
 		break;
 	    case OPCODE_ARL:
 		emit_arl(c, inst);
 		break;
 	    case OPCODE_FRC:
-		emit_frc(c, inst);
+		emit_alu1(p, brw_FRC, dst, dst_flags, args[0]);
 		break;
 	    case OPCODE_FLR:
-		emit_flr(c, inst);
+		emit_alu1(p, brw_RNDD, dst, dst_flags, args[0]);
 		break;
 	    case OPCODE_LRP:
-		emit_lrp(c, inst);
+		unalias3(c, emit_lrp,
+			 dst, dst_flags, args[0], args[1], args[2]);
 		break;
 	    case OPCODE_TRUNC:
-		emit_trunc(c, inst);
+		emit_alu1(p, brw_RNDZ, dst, dst_flags, args[0]);
 		break;
 	    case OPCODE_MOV:
 	    case OPCODE_SWZ:
-		emit_mov(c, inst);
+		emit_alu1(p, brw_MOV, dst, dst_flags, args[0]);
 		break;
 	    case OPCODE_DP3:
-		emit_dp3(c, inst);
+		emit_dp3(p, dst, dst_flags, args[0], args[1]);
 		break;
 	    case OPCODE_DP4:
-		emit_dp4(c, inst);
+		emit_dp4(p, dst, dst_flags, args[0], args[1]);
 		break;
 	    case OPCODE_XPD:
-		emit_xpd(c, inst);
+		emit_xpd(p, dst, dst_flags, args[0], args[1]);
 		break;
 	    case OPCODE_DPH:
-		emit_dph(c, inst);
+		emit_dph(p, dst, dst_flags, args[0], args[1]);
 		break;
 	    case OPCODE_RCP:
-		emit_rcp(c, inst);
+		emit_math1(c, BRW_MATH_FUNCTION_INV, dst, dst_flags, args[0]);
 		break;
 	    case OPCODE_RSQ:
-		emit_rsq(c, inst);
+		emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, dst_flags, args[0]);
 		break;
 	    case OPCODE_SIN:
-		emit_sin(c, inst);
+		emit_math1(c, BRW_MATH_FUNCTION_SIN, dst, dst_flags, args[0]);
 		break;
 	    case OPCODE_COS:
-		emit_cos(c, inst);
+		emit_math1(c, BRW_MATH_FUNCTION_COS, dst, dst_flags, args[0]);
 		break;
 	    case OPCODE_EX2:
-		emit_ex2(c, inst);
+		emit_math1(c, BRW_MATH_FUNCTION_EXP, dst, dst_flags, args[0]);
 		break;
 	    case OPCODE_LG2:
-		emit_lg2(c, inst);
+		emit_math1(c, BRW_MATH_FUNCTION_LOG, dst, dst_flags, args[0]);
 		break;
 	    case OPCODE_MIN:	
+		unalias2(c, emit_min, dst, dst_flags, args[0], args[1]);
+		break;
 	    case OPCODE_MAX:	
-		emit_min_max(c, inst);
+		unalias2(c, emit_max, dst, dst_flags, args[0], args[1]);
 		break;
 	    case OPCODE_DDX:
 	    case OPCODE_DDY:
-		for (j = 0; j < 4; j++) {
-		    if (inst->DstReg.WriteMask & (1 << j))
-			dst[j] = get_dst_reg(c, inst, j);
-		    else
-			dst[j] = brw_null_reg();
-		}
-		get_argument_regs(c, inst, 0, args[0], WRITEMASK_XYZW);
 		emit_ddxy(p, dst, dst_flags, (inst->Opcode == OPCODE_DDX),
 			  args[0]);
                 break;
 	    case OPCODE_SLT:
-		emit_slt(c, inst);
+		emit_sop(p, dst, dst_flags,
+			 BRW_CONDITIONAL_L, args[0], args[1]);
 		break;
 	    case OPCODE_SLE:
-		emit_sle(c, inst);
+		emit_sop(p, dst, dst_flags,
+			 BRW_CONDITIONAL_LE, args[0], args[1]);
 		break;
 	    case OPCODE_SGT:
-		emit_sgt(c, inst);
+		emit_sop(p, dst, dst_flags,
+			 BRW_CONDITIONAL_G, args[0], args[1]);
 		break;
 	    case OPCODE_SGE:
-		emit_sge(c, inst);
+		emit_sop(p, dst, dst_flags,
+			 BRW_CONDITIONAL_GE, args[0], args[1]);
 		break;
 	    case OPCODE_SEQ:
-		emit_seq(c, inst);
+		emit_sop(p, dst, dst_flags,
+			 BRW_CONDITIONAL_EQ, args[0], args[1]);
 		break;
 	    case OPCODE_SNE:
-		emit_sne(c, inst);
+		emit_sop(p, dst, dst_flags,
+			 BRW_CONDITIONAL_NEQ, args[0], args[1]);
 		break;
 	    case OPCODE_MUL:
-		emit_mul(c, inst);
+		emit_alu2(p, brw_MUL, dst, dst_flags, args[0], args[1]);
 		break;
 	    case OPCODE_POW:
-		emit_pow(c, inst);
+		emit_math2(c, BRW_MATH_FUNCTION_POW,
+			   dst, dst_flags, args[0], args[1]);
 		break;
 	    case OPCODE_MAD:
-		emit_mad(c, inst);
+		emit_mad(p, dst, dst_flags, args[0], args[1], args[2]);
 		break;
 	    case OPCODE_NOISE1:
 		emit_noise1(c, inst);
@@ -2916,10 +2018,19 @@
 		emit_noise4(c, inst);
 		break;
 	    case OPCODE_TEX:
-		emit_tex(c, inst);
+		emit_tex(c, dst, dst_flags, args[0],
+			 get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH,
+				 0, 1, 0, 0),
+			 inst->TexSrcTarget,
+			 inst->TexSrcUnit,
+			 (c->key.shadowtex_mask & (1 << inst->TexSrcUnit)) != 0);
 		break;
 	    case OPCODE_TXB:
-		emit_txb(c, inst);
+		emit_txb(c, dst, dst_flags, args[0],
+			 get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH,
+				 0, 1, 0, 0),
+			 inst->TexSrcTarget,
+			 c->fp->program.Base.SamplerUnits[inst->TexSrcUnit]);
 		break;
 	    case OPCODE_KIL_NV:
 		emit_kil(c);
@@ -2929,6 +2040,7 @@
 		if_inst[if_depth++] = brw_IF(p, BRW_EXECUTE_8);
 		break;
 	    case OPCODE_ELSE:
+		assert(if_depth > 0);
 		if_inst[if_depth-1]  = brw_ELSE(p, if_inst[if_depth-1]);
 		break;
 	    case OPCODE_ENDIF:
@@ -2982,9 +2094,10 @@
                   struct brw_instruction *inst0, *inst1;
                   GLuint br = 1;
 
-                  if (BRW_IS_IGDNG(brw))
+                  if (intel->is_ironlake)
                      br = 2;
- 
+
+		  assert(loop_depth > 0);
                   loop_depth--;
                   inst0 = inst1 = brw_WHILE(p, loop_inst[loop_depth]);
                   /* patch all the BREAK/CONT instructions from last BGNLOOP */
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass0.c b/src/mesa/drivers/dri/i965/brw_wm_pass0.c
index 602b135..ff4c082 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass0.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass0.c
@@ -42,12 +42,14 @@
 static struct brw_wm_ref *get_ref( struct brw_wm_compile *c )
 {
    assert(c->nr_refs < BRW_WM_MAX_REF);
+   memset(&c->refs[c->nr_refs], 0, sizeof(*c->refs));
    return &c->refs[c->nr_refs++];
 }
 
 static struct brw_wm_value *get_value( struct brw_wm_compile *c)
 {
    assert(c->nr_refs < BRW_WM_MAX_VREG);
+   memset(&c->vreg[c->nr_vreg], 0, sizeof(*c->vreg));
    return &c->vreg[c->nr_vreg++];
 }
 
@@ -55,6 +57,7 @@
 static struct brw_wm_instruction *get_instruction( struct brw_wm_compile *c )
 {
    assert(c->nr_insns < BRW_WM_MAX_INSN);
+   memset(&c->instruction[c->nr_insns], 0, sizeof(*c->instruction));
    return &c->instruction[c->nr_insns++];
 }
 
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass2.c b/src/mesa/drivers/dri/i965/brw_wm_pass2.c
index 6faea01..31303fe 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass2.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass2.c
@@ -82,8 +82,8 @@
    for (j = 0; j < c->nr_creg; j++) 
       prealloc_reg(c, &c->creg[j], i++);
 
-   for (j = 0; j < FRAG_ATTRIB_MAX; j++) {
-      if (c->key.vp_outputs_written & (1<<j)) {
+   for (j = 0; j < VERT_RESULT_MAX; j++) {
+      if (c->key.vp_outputs_written & BITFIELD64_BIT(j)) {
 	 int fp_index;
 
 	 if (j >= VERT_RESULT_VAR0)
diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
index 0acb027..ad267a4 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
@@ -73,8 +73,8 @@
 
    COPY_4V(sdc.color, color); 
    
-   return brw_cache_data( &brw->cache, BRW_SAMPLER_DEFAULT_COLOR, &sdc,
-			  NULL, 0 );
+   return brw_cache_data(&brw->cache, BRW_SAMPLER_DEFAULT_COLOR,
+			 &sdc, sizeof(sdc), NULL, 0);
 }
 
 
@@ -262,10 +262,10 @@
 	 dri_bo_unreference(brw->wm.sdc_bo[unit]);
 	 if (firstImage->_BaseFormat == GL_DEPTH_COMPONENT) {
 	    float bordercolor[4] = {
-	       texObj->BorderColor[0],
-	       texObj->BorderColor[0],
-	       texObj->BorderColor[0],
-	       texObj->BorderColor[0]
+	       texObj->BorderColor.f[0],
+	       texObj->BorderColor.f[0],
+	       texObj->BorderColor.f[0],
+	       texObj->BorderColor.f[0]
 	    };
 	    /* GL specs that border color for depth textures is taken from the
 	     * R channel, while the hardware uses A.  Spam R into all the
@@ -274,7 +274,7 @@
 	    brw->wm.sdc_bo[unit] = upload_default_color(brw, bordercolor);
 	 } else {
 	    brw->wm.sdc_bo[unit] = upload_default_color(brw,
-							texObj->BorderColor);
+							texObj->BorderColor.f);
 	 }
 	 key->sampler_count = unit + 1;
       }
diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c
index 361f912..d3373ea 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_state.c
@@ -49,8 +49,6 @@
    unsigned int curbe_offset;
    unsigned int urb_size;
 
-   unsigned int max_threads;
-
    unsigned int nr_surfaces, sampler_count;
    GLboolean uses_depth, computes_depth, uses_kill, is_glsl;
    GLboolean polygon_stipple, stats_wm, line_stipple, offset_enable;
@@ -67,18 +65,6 @@
 
    memset(key, 0, sizeof(*key));
 
-   if (INTEL_DEBUG & DEBUG_SINGLE_THREAD)
-      key->max_threads = 1;
-   else {
-      /* WM maximum threads is number of EUs times number of threads per EU. */
-      if (BRW_IS_IGDNG(brw))
-         key->max_threads = 12 * 6;
-      else if (BRW_IS_G4X(brw))
-	 key->max_threads = 10 * 5;
-      else
-	 key->max_threads = 8 * 4;
-   }
-
    /* CACHE_NEW_WM_PROG */
    key->total_grf = brw->wm.prog_data->total_grf;
    key->urb_entry_read_length = brw->wm.prog_data->urb_read_length;
@@ -106,7 +92,7 @@
 
    /* as far as we can tell */
    key->computes_depth =
-      (fp->Base.OutputsWritten & (1 << FRAG_RESULT_DEPTH)) != 0;
+      (fp->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) != 0;
    /* BRW_NEW_DEPTH_BUFFER
     * Override for NULL depthbuffer case, required by the Pixel Shader Computed
     * Depth field.
@@ -140,6 +126,7 @@
 wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key,
 			dri_bo **reloc_bufs)
 {
+   struct intel_context *intel = &brw->intel;
    struct brw_wm_unit_state wm;
    dri_bo *bo;
 
@@ -150,7 +137,7 @@
    wm.thread1.depth_coef_urb_read_offset = 1;
    wm.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
 
-   if (BRW_IS_IGDNG(brw))
+   if (intel->is_ironlake)
       wm.thread1.binding_table_entry_count = 0; /* hardware requirement */
    else
       wm.thread1.binding_table_entry_count = key->nr_surfaces;
@@ -170,7 +157,7 @@
    wm.thread3.const_urb_entry_read_length = key->curb_entry_read_length;
    wm.thread3.const_urb_entry_read_offset = key->curbe_offset * 2;
 
-   if (BRW_IS_IGDNG(brw)) 
+   if (intel->is_ironlake)
       wm.wm4.sampler_count = 0; /* hardware requirement */
    else
       wm.wm4.sampler_count = (key->sampler_count + 1) / 4;
@@ -191,7 +178,7 @@
    else
       wm.wm5.enable_16_pix = 1;
 
-   wm.wm5.max_threads = key->max_threads - 1;
+   wm.wm5.max_threads = brw->wm_max_threads - 1;
    wm.wm5.thread_dispatch_enable = 1;	/* AKA: color_write */
    wm.wm5.legacy_line_rast = 0;
    wm.wm5.legacy_global_depth_bias = 0;
@@ -268,7 +255,7 @@
     */
    assert(key.total_scratch <= 12 * 1024);
    if (key.total_scratch) {
-      GLuint total = key.total_scratch * key.max_threads;
+      GLuint total = key.total_scratch * brw->wm_max_threads;
 
       if (brw->wm.scratch_bo && total > brw->wm.scratch_bo->size) {
 	 dri_bo_unreference(brw->wm.scratch_bo);
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index 0bf735c..f26cfab 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -86,25 +86,22 @@
    case MESA_FORMAT_AL88:
       return BRW_SURFACEFORMAT_L8A8_UNORM;
 
+   case MESA_FORMAT_AL1616:
+      return BRW_SURFACEFORMAT_L16A16_UNORM;
+
    case MESA_FORMAT_RGB888:
       assert(0);		/* not supported for sampling */
       return BRW_SURFACEFORMAT_R8G8B8_UNORM;      
 
    case MESA_FORMAT_ARGB8888:
-      if (internal_format == GL_RGB)
-	 return BRW_SURFACEFORMAT_B8G8R8X8_UNORM;
-      else
-	 return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+      return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
 
    case MESA_FORMAT_XRGB8888:
       return BRW_SURFACEFORMAT_B8G8R8X8_UNORM;
 
    case MESA_FORMAT_RGBA8888_REV:
       _mesa_problem(NULL, "unexpected format in i965:translate_tex_format()");
-      if (internal_format == GL_RGB)
-	 return BRW_SURFACEFORMAT_R8G8B8X8_UNORM;
-      else
-	 return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
+      return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
 
    case MESA_FORMAT_RGB565:
       return BRW_SURFACEFORMAT_B5G6R5_UNORM;
@@ -358,7 +355,10 @@
 			 NULL, NULL);
 
    if (key->bo) {
-      /* Emit relocation to surface contents */
+      /* Emit relocation to surface contents.  Section 5.1.1 of the gen4
+       * bspec ("Data Cache") says that the data cache does not exist as
+       * a separate cache and is just the sampler cache.
+       */
       dri_bo_emit_reloc(bo,
 			I915_GEM_DOMAIN_SAMPLER, 0,
 			0,
@@ -511,7 +511,8 @@
 				struct gl_renderbuffer *rb,
 				unsigned int unit)
 {
-   GLcontext *ctx = &brw->intel.ctx;
+   struct intel_context *intel = &brw->intel;;
+   GLcontext *ctx = &intel->ctx;
    dri_bo *region_bo = NULL;
    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
    struct intel_region *region = irb ? irb->region : NULL;
@@ -522,7 +523,8 @@
       GLubyte color_mask[4];
       GLboolean color_blend;
       uint32_t tiling;
-      uint32_t draw_offset;
+      uint32_t draw_x;
+      uint32_t draw_y;
    } key;
 
    memset(&key, 0, sizeof(key));
@@ -531,12 +533,16 @@
       region_bo = region->buffer;
 
       key.surface_type = BRW_SURFACE_2D;
-      switch (irb->texformat) {
+      switch (irb->Base.Format) {
+      /* XRGB and ARGB are treated the same here because the chips in this
+       * family cannot render to XRGB targets.  This means that we have to
+       * mask writes to alpha (ala glColorMask) and reconfigure the alpha
+       * blending hardware to use GL_ONE (or GL_ZERO) for cases where
+       * GL_DST_ALPHA (or GL_ONE_MINUS_DST_ALPHA) is used.
+       */
       case MESA_FORMAT_ARGB8888:
-	 key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
-	 break;
       case MESA_FORMAT_XRGB8888:
-	 key.surface_format = BRW_SURFACEFORMAT_B8G8R8X8_UNORM;
+	 key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
 	 break;
       case MESA_FORMAT_RGB565:
 	 key.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
@@ -548,7 +554,7 @@
 	 key.surface_format = BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
 	 break;
       default:
-	 _mesa_problem(ctx, "Bad renderbuffer format: %d\n", irb->texformat);
+	 _mesa_problem(ctx, "Bad renderbuffer format: %d\n", irb->Base.Format);
       }
       key.tiling = region->tiling;
       if (brw->intel.intelScreen->driScrnPriv->dri2.enabled) {
@@ -560,7 +566,8 @@
       }
       key.pitch = region->pitch;
       key.cpp = region->cpp;
-      key.draw_offset = region->draw_offset; /* cur 3d or cube face offset */
+      key.draw_x = region->draw_x;
+      key.draw_y = region->draw_y;
    } else {
       key.surface_type = BRW_SURFACE_NULL;
       key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
@@ -568,11 +575,19 @@
       key.width = 1;
       key.height = 1;
       key.cpp = 4;
-      key.draw_offset = 0;
+      key.draw_x = 0;
+      key.draw_y = 0;
    }
    /* _NEW_COLOR */
-   memcpy(key.color_mask, ctx->Color.ColorMask,
+   memcpy(key.color_mask, ctx->Color.ColorMask[0],
 	  sizeof(key.color_mask));
+
+   /* As mentioned above, disable writes to the alpha component when the
+    * renderbuffer is XRGB.
+    */
+   if (ctx->DrawBuffer->Visual.alphaBits == 0)
+     key.color_mask[3] = GL_FALSE;
+
    key.color_blend = (!ctx->Color._LogicOpEnabled &&
 		      ctx->Color.BlendEnabled);
 
@@ -591,25 +606,32 @@
       surf.ss0.surface_format = key.surface_format;
       surf.ss0.surface_type = key.surface_type;
       if (key.tiling == I915_TILING_NONE) {
-	 surf.ss1.base_addr = key.draw_offset;
+	 surf.ss1.base_addr = (key.draw_x + key.draw_y * key.pitch) * key.cpp;
       } else {
-	 uint32_t tile_offset = key.draw_offset % 4096;
+	 uint32_t tile_base, tile_x, tile_y;
+	 uint32_t pitch = key.pitch * key.cpp;
 
-	 surf.ss1.base_addr = key.draw_offset - tile_offset;
-
-	 assert(BRW_IS_G4X(brw) || tile_offset == 0);
-	 if (BRW_IS_G4X(brw)) {
-	    if (key.tiling == I915_TILING_X) {
-	       /* Note that the low bits of these fields are missing, so
-		* there's the possibility of getting in trouble.
-		*/
-	       surf.ss5.x_offset = (tile_offset % 512) / key.cpp / 4;
-	       surf.ss5.y_offset = tile_offset / 512 / 2;
-	    } else {
-	       surf.ss5.x_offset = (tile_offset % 128) / key.cpp / 4;
-	       surf.ss5.y_offset = tile_offset / 128 / 2;
-	    }
+	 if (key.tiling == I915_TILING_X) {
+	    tile_x = key.draw_x % (512 / key.cpp);
+	    tile_y = key.draw_y % 8;
+	    tile_base = ((key.draw_y / 8) * (8 * pitch));
+	    tile_base += (key.draw_x - tile_x) / (512 / key.cpp) * 4096;
+	 } else {
+	    /* Y */
+	    tile_x = key.draw_x % (128 / key.cpp);
+	    tile_y = key.draw_y % 32;
+	    tile_base = ((key.draw_y / 32) * (32 * pitch));
+	    tile_base += (key.draw_x - tile_x) / (128 / key.cpp) * 4096;
 	 }
+	 assert(intel->is_g4x || (tile_x == 0 && tile_y == 0));
+	 assert(tile_x % 4 == 0);
+	 assert(tile_y % 2 == 0);
+	 /* Note that the low bits of these fields are missing, so
+	  * there's the possibility of getting in trouble.
+	  */
+	 surf.ss1.base_addr = tile_base;
+	 surf.ss5.x_offset = tile_x / 4;
+	 surf.ss5.y_offset = tile_y / 2;
       }
       if (region_bo != NULL)
 	 surf.ss1.base_addr += region_bo->offset; /* reloc */
diff --git a/src/mesa/drivers/dri/i965/intel_swapbuffers.c b/src/mesa/drivers/dri/i965/intel_swapbuffers.c
deleted file mode 120000
index 148d521..0000000
--- a/src/mesa/drivers/dri/i965/intel_swapbuffers.c
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_swapbuffers.c
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index e94b836..3a4b21a 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -80,7 +80,7 @@
       batch->buf = NULL;
    }
 
-   if (!batch->buffer && intel->ttm == GL_TRUE)
+   if (!batch->buffer)
       batch->buffer = malloc (intel->maxBatchSize);
 
    batch->buf = dri_bo_alloc(intel->bufmgr, "batchbuffer",
@@ -94,7 +94,6 @@
    batch->size = intel->maxBatchSize;
    batch->ptr = batch->map;
    batch->dirty_state = ~0;
-   batch->cliprect_mode = IGNORE_CLIPRECTS;
 }
 
 struct intel_batchbuffer *
@@ -129,13 +128,10 @@
 /* TODO: Push this whole function into bufmgr.
  */
 static void
-do_flush_locked(struct intel_batchbuffer *batch,
-		GLuint used, GLboolean allow_unlock)
+do_flush_locked(struct intel_batchbuffer *batch, GLuint used)
 {
    struct intel_context *intel = batch->intel;
    int ret = 0;
-   unsigned int num_cliprects = 0;
-   struct drm_clip_rect *cliprects = NULL;
    int x_off = 0, y_off = 0;
 
    if (batch->buffer)
@@ -146,31 +142,7 @@
    batch->map = NULL;
    batch->ptr = NULL;
 
-
-   if (batch->cliprect_mode == LOOP_CLIPRECTS) {
-      intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);
-   }
-   /* Dispatch the batchbuffer, if it has some effect (nonzero cliprects).
-    * Can't short-circuit like this once we have hardware contexts, but we
-    * should always be in DRI2 mode by then anyway.
-    */
-   if ((batch->cliprect_mode != LOOP_CLIPRECTS ||
-	num_cliprects != 0) && !intel->no_hw) {
-      dri_bo_exec(batch->buf, used, cliprects, num_cliprects,
-		  (x_off & 0xffff) | (y_off << 16));
-   }
-
-   if (batch->cliprect_mode == LOOP_CLIPRECTS && num_cliprects == 0) {
-      if (allow_unlock) {
-	 /* If we are not doing any actual user-visible rendering,
-	  * do a sched_yield to keep the app from pegging the cpu while
-	  * achieving nothing.
-	  */
-         UNLOCK_HARDWARE(intel);
-         sched_yield();
-         LOCK_HARDWARE(intel);
-      }
-   }
+   dri_bo_exec(batch->buf, used, NULL, 0, (x_off & 0xffff) | (y_off << 16));
 
    if (INTEL_DEBUG & DEBUG_BATCH) {
       dri_bo_map(batch->buf, GL_FALSE);
@@ -183,7 +155,6 @@
    }
 
    if (ret != 0) {
-      UNLOCK_HARDWARE(intel);
       exit(1);
    }
    intel->vtbl.new_batch(intel);
@@ -201,19 +172,17 @@
       drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
    }
 
-   if (used == 0) {
-      batch->cliprect_mode = IGNORE_CLIPRECTS;
+   if (used == 0)
       return;
-   }
 
    if (INTEL_DEBUG & DEBUG_BATCH)
       fprintf(stderr, "%s:%d: Batchbuffer flush with %db used\n", file, line,
 	      used);
 
+   batch->reserved_space = 0;
    /* Emit a flush if the bufmgr doesn't do it for us. */
-   if (intel->always_flush_cache || !intel->ttm) {
-      *(GLuint *) (batch->ptr) = intel->vtbl.flush_cmd();
-      batch->ptr += 4;
+   if (intel->always_flush_cache) {
+      intel_batchbuffer_emit_mi_flush(batch);
       used = batch->ptr - batch->map;
    }
 
@@ -244,12 +213,15 @@
    if (intel->vtbl.finish_batch)
       intel->vtbl.finish_batch(intel);
 
+   /* Check that we didn't just wrap our batchbuffer at a bad time. */
+   assert(!intel->no_batch_wrap);
+
+   batch->reserved_space = BATCH_RESERVED;
+
    /* TODO: Just pass the relocation list and dma buffer up to the
     * kernel.
     */
-   LOCK_HARDWARE(intel);
-   do_flush_locked(batch, used, GL_FALSE);
-   UNLOCK_HARDWARE(intel);
+   do_flush_locked(batch, used);
 
    if (INTEL_DEBUG & DEBUG_SYNC) {
       fprintf(stderr, "waiting for idle\n");
@@ -291,11 +263,38 @@
 
 void
 intel_batchbuffer_data(struct intel_batchbuffer *batch,
-                       const void *data, GLuint bytes,
-		       enum cliprect_mode cliprect_mode)
+                       const void *data, GLuint bytes)
 {
    assert((bytes & 3) == 0);
-   intel_batchbuffer_require_space(batch, bytes, cliprect_mode);
+   intel_batchbuffer_require_space(batch, bytes);
    __memcpy(batch->ptr, data, bytes);
    batch->ptr += bytes;
 }
+
+/* Emit a pipelined flush to either flush render and texture cache for
+ * reading from a FBO-drawn texture, or flush so that frontbuffer
+ * render appears on the screen in DRI1.
+ *
+ * This is also used for the always_flush_cache driconf debug option.
+ */
+void
+intel_batchbuffer_emit_mi_flush(struct intel_batchbuffer *batch)
+{
+   struct intel_context *intel = batch->intel;
+
+   if (intel->gen >= 4) {
+      BEGIN_BATCH(4);
+      OUT_BATCH(_3DSTATE_PIPE_CONTROL |
+		PIPE_CONTROL_INSTRUCTION_FLUSH |
+		PIPE_CONTROL_WRITE_FLUSH |
+		PIPE_CONTROL_NO_WRITE);
+      OUT_BATCH(0); /* write address */
+      OUT_BATCH(0); /* write data */
+      OUT_BATCH(0); /* write data */
+      ADVANCE_BATCH();
+   } else {
+      BEGIN_BATCH(1);
+      OUT_BATCH(MI_FLUSH);
+      ADVANCE_BATCH();
+   }
+}
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.h b/src/mesa/drivers/dri/intel/intel_batchbuffer.h
index d4899aa..b052b72 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.h
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.h
@@ -10,35 +10,6 @@
 #define BATCH_SZ 16384
 #define BATCH_RESERVED 16
 
-enum cliprect_mode {
-   /**
-    * Batchbuffer contents may be looped over per cliprect, but do not
-    * require it.
-    */
-   IGNORE_CLIPRECTS,
-   /**
-    * Batchbuffer contents require looping over per cliprect at batch submit
-    * time.
-    *
-    * This will be upgraded to NO_LOOP_CLIPRECTS when there's a single
-    * constant cliprect, as in DRI2 or FBO rendering.
-    */
-   LOOP_CLIPRECTS,
-   /**
-    * Batchbuffer contents contain drawing that should not be executed multiple
-    * times.
-    */
-   NO_LOOP_CLIPRECTS,
-   /**
-    * Batchbuffer contents contain drawing that already handles cliprects, such
-    * as 2D drawing to front/back/depth that doesn't respect DRAWING_RECTANGLE.
-    *
-    * Equivalent behavior to NO_LOOP_CLIPRECTS, but may not persist in batch
-    * outside of LOCK/UNLOCK.  This is upgraded to just NO_LOOP_CLIPRECTS when
-    * there's a constant cliprect, as in DRI2 or FBO rendering.
-    */
-   REFERENCES_CLIPRECTS
-};
 
 struct intel_batchbuffer
 {
@@ -51,8 +22,6 @@
    GLubyte *map;
    GLubyte *ptr;
 
-   enum cliprect_mode cliprect_mode;
-
    GLuint size;
 
    /** Tracking of BEGIN_BATCH()/OUT_BATCH()/ADVANCE_BATCH() debugging */
@@ -62,6 +31,7 @@
    } emit;
 
    GLuint dirty_state;
+   GLuint reserved_space;
 };
 
 struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context
@@ -84,8 +54,7 @@
  * intel_buffer_dword() calls.
  */
 void intel_batchbuffer_data(struct intel_batchbuffer *batch,
-                            const void *data, GLuint bytes,
-			    enum cliprect_mode cliprect_mode);
+                            const void *data, GLuint bytes);
 
 void intel_batchbuffer_release_space(struct intel_batchbuffer *batch,
                                      GLuint bytes);
@@ -95,6 +64,7 @@
 				       uint32_t read_domains,
 				       uint32_t write_domain,
 				       uint32_t offset);
+void intel_batchbuffer_emit_mi_flush(struct intel_batchbuffer *batch);
 
 /* Inline functions - might actually be better off with these
  * non-inlined.  Certainly better off switching all command packets to
@@ -104,7 +74,7 @@
 static INLINE GLint
 intel_batchbuffer_space(struct intel_batchbuffer *batch)
 {
-   return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
+   return (batch->size - batch->reserved_space) - (batch->ptr - batch->map);
 }
 
 
@@ -119,36 +89,19 @@
 
 static INLINE void
 intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
-                                GLuint sz,
-				enum cliprect_mode cliprect_mode)
+                                GLuint sz)
 {
    assert(sz < batch->size - 8);
    if (intel_batchbuffer_space(batch) < sz)
       intel_batchbuffer_flush(batch);
-
-   if ((cliprect_mode == LOOP_CLIPRECTS ||
-	cliprect_mode == REFERENCES_CLIPRECTS) &&
-       batch->intel->constant_cliprect)
-      cliprect_mode = NO_LOOP_CLIPRECTS;
-
-   if (cliprect_mode != IGNORE_CLIPRECTS) {
-      if (batch->cliprect_mode == IGNORE_CLIPRECTS) {
-	 batch->cliprect_mode = cliprect_mode;
-      } else {
-	 if (batch->cliprect_mode != cliprect_mode) {
-	    intel_batchbuffer_flush(batch);
-	    batch->cliprect_mode = cliprect_mode;
-	 }
-      }
-   }
 }
 
 /* Here are the crusty old macros, to be removed:
  */
 #define BATCH_LOCALS
 
-#define BEGIN_BATCH(n, cliprect_mode) do {				\
-   intel_batchbuffer_require_space(intel->batch, (n)*4, cliprect_mode); \
+#define BEGIN_BATCH(n) do {				\
+   intel_batchbuffer_require_space(intel->batch, (n)*4); \
    assert(intel->batch->emit.start_ptr == NULL);			\
    intel->batch->emit.total = (n) * 4;					\
    intel->batch->emit.start_ptr = intel->batch->ptr;			\
@@ -173,12 +126,4 @@
    intel->batch->emit.start_ptr = NULL;					\
 } while(0)
 
-
-static INLINE void
-intel_batchbuffer_emit_mi_flush(struct intel_batchbuffer *batch)
-{
-   intel_batchbuffer_require_space(batch, 4, IGNORE_CLIPRECTS);
-   intel_batchbuffer_emit_dword(batch, MI_FLUSH);
-}
-
 #endif
diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c
index 817223d..55bee00 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.c
+++ b/src/mesa/drivers/dri/intel/intel_blit.c
@@ -42,137 +42,6 @@
 
 #define FILE_DEBUG_FLAG DEBUG_BLIT
 
-/**
- * Copy the back color buffer to the front color buffer. 
- * Used for SwapBuffers().
- */
-void
-intelCopyBuffer(const __DRIdrawablePrivate * dPriv,
-                const drm_clip_rect_t * rect)
-{
-
-   struct intel_context *intel;
-   const intelScreenPrivate *intelScreen;
-
-   DBG("%s\n", __FUNCTION__);
-
-   assert(dPriv);
-
-   intel = intelScreenContext(dPriv->driScreenPriv->private);
-   if (!intel)
-      return;
-
-   intelScreen = intel->intelScreen;
-
-   /* The LOCK_HARDWARE is required for the cliprects.  Buffer offsets
-    * should work regardless.
-    */
-   LOCK_HARDWARE(intel);
-
-   if (dPriv && dPriv->numClipRects) {
-      struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
-      struct intel_region *src, *dst;
-      int nbox = dPriv->numClipRects;
-      drm_clip_rect_t *pbox = dPriv->pClipRects;
-      int cpp;
-      int src_pitch, dst_pitch;
-      unsigned short src_x, src_y;
-      int BR13, CMD;
-      int i;
-      dri_bo *aper_array[3];
-
-      src = intel_get_rb_region(&intel_fb->Base, BUFFER_BACK_LEFT);
-      dst = intel_get_rb_region(&intel_fb->Base, BUFFER_FRONT_LEFT);
-
-      src_pitch = src->pitch * src->cpp;
-      dst_pitch = dst->pitch * dst->cpp;
-
-      cpp = src->cpp;
-
-      ASSERT(intel_fb);
-      ASSERT(intel_fb->Base.Name == 0);    /* Not a user-created FBO */
-      ASSERT(src);
-      ASSERT(dst);
-      ASSERT(src->cpp == dst->cpp);
-
-      if (cpp == 2) {
-	 BR13 = (0xCC << 16) | BR13_565;
-	 CMD = XY_SRC_COPY_BLT_CMD;
-      }
-      else {
-	 BR13 = (0xCC << 16) | BR13_8888;
-	 CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
-      }
-
-      assert(src->tiling != I915_TILING_Y);
-      assert(dst->tiling != I915_TILING_Y);
-#ifndef I915
-      if (src->tiling != I915_TILING_NONE) {
-	 CMD |= XY_SRC_TILED;
-	 src_pitch /= 4;
-      }
-      if (dst->tiling != I915_TILING_NONE) {
-	 CMD |= XY_DST_TILED;
-	 dst_pitch /= 4;
-      }
-#endif
-      /* do space/cliprects check before going any further */
-      intel_batchbuffer_require_space(intel->batch, 8 * 4,
-				      REFERENCES_CLIPRECTS);
-   again:
-      aper_array[0] = intel->batch->buf;
-      aper_array[1] = dst->buffer;
-      aper_array[2] = src->buffer;
-
-      if (dri_bufmgr_check_aperture_space(aper_array, 3) != 0) {
-	intel_batchbuffer_flush(intel->batch);
-	goto again;
-      }
-
-      for (i = 0; i < nbox; i++, pbox++) {
-	 drm_clip_rect_t box = *pbox;
-
-	 if (rect) {
-	    if (!intel_intersect_cliprects(&box, &box, rect))
-	       continue;
-	 }
-
-	 if (box.x1 >= box.x2 ||
-	     box.y1 >= box.y2)
-	    continue;
-
-	 assert(box.x1 < box.x2);
-	 assert(box.y1 < box.y2);
-	 src_x = box.x1 - dPriv->x + dPriv->backX;
-	 src_y = box.y1 - dPriv->y + dPriv->backY;
-
-	 BEGIN_BATCH(8, REFERENCES_CLIPRECTS);
-	 OUT_BATCH(CMD);
-	 OUT_BATCH(BR13 | dst_pitch);
-	 OUT_BATCH((box.y1 << 16) | box.x1);
-	 OUT_BATCH((box.y2 << 16) | box.x2);
-
-	 OUT_RELOC(dst->buffer,
-		   I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
-		   0);
-	 OUT_BATCH((src_y << 16) | src_x);
-	 OUT_BATCH(src_pitch);
-	 OUT_RELOC(src->buffer,
-		   I915_GEM_DOMAIN_RENDER, 0,
-		   0);
-	 ADVANCE_BATCH();
-      }
-
-      /* Flush the rendering and the batch so that the results all land on the
-       * screen in a timely fashion.
-       */
-      intel_batchbuffer_emit_mi_flush(intel->batch);
-      intel_batchbuffer_flush(intel->batch);
-   }
-
-   UNLOCK_HARDWARE(intel);
-}
-
 static GLuint translate_raster_op(GLenum logicop)
 {
    switch(logicop) {
@@ -248,7 +117,6 @@
    } while (pass < 2);
 
    if (pass >= 2) {
-       LOCK_HARDWARE(intel);
        dri_bo_map(dst_buffer, GL_TRUE);
        dri_bo_map(src_buffer, GL_FALSE);
        _mesa_copy_rect((GLubyte *)dst_buffer->virtual + dst_offset,
@@ -262,12 +130,11 @@
        
        dri_bo_unmap(src_buffer);
        dri_bo_unmap(dst_buffer);
-       UNLOCK_HARDWARE(intel);
 
        return GL_TRUE;
    }
 
-   intel_batchbuffer_require_space(intel->batch, 8 * 4, NO_LOOP_CLIPRECTS);
+   intel_batchbuffer_require_space(intel->batch, 8 * 4);
    DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
        __FUNCTION__,
        src_buffer, src_pitch, src_offset, src_x, src_y,
@@ -312,7 +179,7 @@
    assert(dst_x < dst_x2);
    assert(dst_y < dst_y2);
 
-   BEGIN_BATCH(8, NO_LOOP_CLIPRECTS);
+   BEGIN_BATCH(8);
    OUT_BATCH(CMD);
    OUT_BATCH(BR13 | (uint16_t)dst_pitch);
    OUT_BATCH((dst_y << 16) | dst_x);
@@ -370,8 +237,6 @@
       skipBuffers = BUFFER_BIT_STENCIL;
    }
 
-   LOCK_HARDWARE(intel);
-
    intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);
    if (num_cliprects) {
       GLint cx, cy, cw, ch;
@@ -496,13 +361,14 @@
 		  CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]);
 		  CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]);
 
-		  switch (irb->texformat) {
+		  switch (irb->Base.Format) {
 		  case MESA_FORMAT_ARGB8888:
 		  case MESA_FORMAT_XRGB8888:
-		     clearVal = intel->ClearColor8888;
+		     clearVal = PACK_COLOR_8888(clear[3], clear[0],
+						clear[1], clear[2]);
 		     break;
 		  case MESA_FORMAT_RGB565:
-		     clearVal = intel->ClearColor565;
+		     clearVal = PACK_COLOR_565(clear[0], clear[1], clear[2]);
 		     break;
 		  case MESA_FORMAT_ARGB4444:
 		     clearVal = PACK_COLOR_4444(clear[3], clear[0],
@@ -514,7 +380,7 @@
 		     break;
 		  default:
 		     _mesa_problem(ctx, "Unexpected renderbuffer format: %d\n",
-				   irb->texformat);
+				   irb->Base.Format);
 		     clearVal = 0;
 		  }
 	       }
@@ -527,7 +393,7 @@
                assert(x1 < x2);
                assert(y1 < y2);
 
-               BEGIN_BATCH(6, REFERENCES_CLIPRECTS);
+               BEGIN_BATCH(6);
                OUT_BATCH(CMD);
                OUT_BATCH(BR13);
                OUT_BATCH((y1 << 16) | x1);
@@ -542,8 +408,6 @@
          }
       }
    }
-
-   UNLOCK_HARDWARE(intel);
 }
 
 GLboolean
@@ -585,8 +449,7 @@
    intel_batchbuffer_require_space( intel->batch,
 				    (8 * 4) +
 				    (3 * 4) +
-				    dwords * 4,
-				    REFERENCES_CLIPRECTS );
+				    dwords * 4 );
 
    opcode = XY_SETUP_BLT_CMD;
    if (cpp == 4)
@@ -608,7 +471,7 @@
    if (dst_tiling != I915_TILING_NONE)
       blit_cmd |= XY_DST_TILED;
 
-   BEGIN_BATCH(8 + 3, REFERENCES_CLIPRECTS);
+   BEGIN_BATCH(8 + 3);
    OUT_BATCH(opcode);
    OUT_BATCH(br13);
    OUT_BATCH((0 << 16) | 0); /* clip x1, y1 */
@@ -627,8 +490,7 @@
 
    intel_batchbuffer_data( intel->batch,
 			   src_bits,
-			   dwords * 4,
-			   REFERENCES_CLIPRECTS );
+			   dwords * 4 );
 
    intel_batchbuffer_emit_mi_flush(intel->batch);
 
diff --git a/src/mesa/drivers/dri/intel/intel_blit.h b/src/mesa/drivers/dri/intel/intel_blit.h
index 240cb7c..eb66fe0 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.h
+++ b/src/mesa/drivers/dri/intel/intel_blit.h
@@ -30,7 +30,7 @@
 
 #include "intel_context.h"
 
-extern void intelCopyBuffer(const __DRIdrawablePrivate * dpriv,
+extern void intelCopyBuffer(const __DRIdrawable * dpriv,
                             const drm_clip_rect_t * rect);
 
 extern void intelClearWithBlit(GLcontext * ctx, GLbitfield mask);
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
index ea9d5a6..3b7015b 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
@@ -209,10 +209,23 @@
       memcpy((char *)intel_obj->sys_buffer + offset, data, size);
    else {
       /* Flush any existing batchbuffer that might reference this data. */
-      if (drm_intel_bo_references(intel->batch->buf, intel_obj->buffer))
-	 intelFlush(ctx);
+      if (drm_intel_bo_busy(intel_obj->buffer) ||
+	  drm_intel_bo_references(intel->batch->buf, intel_obj->buffer)) {
+	 drm_intel_bo *temp_bo;
 
-      dri_bo_subdata(intel_obj->buffer, offset, size, data);
+	 temp_bo = drm_intel_bo_alloc(intel->bufmgr, "subdata temp", size, 64);
+
+	 drm_intel_bo_subdata(temp_bo, 0, size, data);
+
+	 intel_emit_linear_blit(intel,
+				intel_obj->buffer, offset,
+				temp_bo, 0,
+				size);
+
+	 drm_intel_bo_unreference(temp_bo);
+      } else {
+	 dri_bo_subdata(intel_obj->buffer, offset, size, data);
+      }
    }
 }
 
@@ -255,6 +268,8 @@
 
    if (intel_obj->sys_buffer) {
       obj->Pointer = intel_obj->sys_buffer;
+      obj->Length = obj->Size;
+      obj->Offset = 0;
       return obj->Pointer;
    }
 
diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c
index 6b12d48..7c4b79f 100644
--- a/src/mesa/drivers/dri/intel/intel_buffers.c
+++ b/src/mesa/drivers/dri/intel/intel_buffers.c
@@ -102,33 +102,15 @@
 		    unsigned int *num_cliprects,
 		    int *x_off, int *y_off)
 {
-   __DRIdrawablePrivate *dPriv = intel->driDrawable;
+   intel->fboRect.x1 = 0;
+   intel->fboRect.y1 = 0;
+   intel->fboRect.x2 = intel->ctx.DrawBuffer->Width;
+   intel->fboRect.y2 = intel->ctx.DrawBuffer->Height;
 
-   if (intel->constant_cliprect) {
-      /* FBO or DRI2 rendering, which can just use the fb's size. */
-      intel->fboRect.x1 = 0;
-      intel->fboRect.y1 = 0;
-      intel->fboRect.x2 = intel->ctx.DrawBuffer->Width;
-      intel->fboRect.y2 = intel->ctx.DrawBuffer->Height;
-
-      *cliprects = &intel->fboRect;
-      *num_cliprects = 1;
-      *x_off = 0;
-      *y_off = 0;
-   } else if (intel->front_cliprects || dPriv->numBackClipRects == 0) {
-      /* use the front clip rects */
-      *cliprects = dPriv->pClipRects;
-      *num_cliprects = dPriv->numClipRects;
-      *x_off = dPriv->x;
-      *y_off = dPriv->y;
-   }
-   else {
-      /* use the back clip rects */
-      *num_cliprects = dPriv->numBackClipRects;
-      *cliprects = dPriv->pBackClipRects;
-      *x_off = dPriv->backX;
-      *y_off = dPriv->backY;
-   }
+   *cliprects = &intel->fboRect;
+   *num_cliprects = 1;
+   *x_off = 0;
+   *y_off = 0;
 }
 
 
@@ -191,13 +173,17 @@
       return;
    }
 
-   /*
-    * How many color buffers are we drawing into?
+   /* How many color buffers are we drawing into?
+    *
+    * If there are zero buffers or the buffer is too big, don't configure any
+    * regions for hardware drawing.  We'll fallback to software below.  Not
+    * having regions set makes some of the software fallback paths faster.
     */
-   if (fb->_NumColorDrawBuffers == 0) {
+   if ((fb->Width > ctx->Const.MaxRenderbufferSize)
+       || (fb->Height > ctx->Const.MaxRenderbufferSize)
+       || (fb->_NumColorDrawBuffers == 0)) {
       /* writing to 0  */
       colorRegions[0] = NULL;
-      intel->constant_cliprect = GL_TRUE;
    }
    else if (fb->_NumColorDrawBuffers > 1) {
        int i;
@@ -207,34 +193,23 @@
            irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]);
            colorRegions[i] = irb ? irb->region : NULL;
        }
-       intel->constant_cliprect = GL_TRUE;
    }
    else {
       /* Get the intel_renderbuffer for the single colorbuffer we're drawing
-       * into, and set up cliprects if it's a DRI1 window front buffer.
+       * into.
        */
       if (fb->Name == 0) {
-	 intel->constant_cliprect = intel->driScreen->dri2.enabled;
 	 /* drawing to window system buffer */
-	 if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
-	    if (!intel->constant_cliprect && !intel->front_cliprects)
-	       intel_batchbuffer_flush(intel->batch);
-	    intel->front_cliprects = GL_TRUE;
+	 if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT)
 	    colorRegions[0] = intel_get_rb_region(fb, BUFFER_FRONT_LEFT);
-	 }
-	 else {
-	    if (!intel->constant_cliprect && intel->front_cliprects)
-	       intel_batchbuffer_flush(intel->batch);
-	    intel->front_cliprects = GL_FALSE;
+	 else
 	    colorRegions[0] = intel_get_rb_region(fb, BUFFER_BACK_LEFT);
-	 }
       }
       else {
 	 /* drawing to user-created FBO */
 	 struct intel_renderbuffer *irb;
 	 irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
 	 colorRegions[0] = (irb && irb->region) ? irb->region : NULL;
-	 intel->constant_cliprect = GL_TRUE;
       }
    }
 
@@ -286,6 +261,12 @@
       FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);
    }
 
+   /* If we have a (packed) stencil buffer attached but no depth buffer,
+    * we still need to set up the shared depth/stencil state so we can use it.
+    */
+   if (depthRegion == NULL && irbStencil && irbStencil->region)
+      depthRegion = irbStencil->region;
+
    /*
     * Update depth and stencil test state
     */
diff --git a/src/mesa/drivers/dri/intel/intel_clear.c b/src/mesa/drivers/dri/intel/intel_clear.c
index fb62f0f..956f233 100644
--- a/src/mesa/drivers/dri/intel/intel_clear.c
+++ b/src/mesa/drivers/dri/intel/intel_clear.c
@@ -68,13 +68,17 @@
 intelClear(GLcontext *ctx, GLbitfield mask)
 {
    struct intel_context *intel = intel_context(ctx);
-   const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
+   const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask[0]);
    GLbitfield tri_mask = 0;
    GLbitfield blit_mask = 0;
    GLbitfield swrast_mask = 0;
    struct gl_framebuffer *fb = ctx->DrawBuffer;
    GLuint i;
 
+   if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT)) {
+      intel->front_buffer_dirty = GL_TRUE;
+   }
+
    if (0)
       fprintf(stderr, "%s\n", __FUNCTION__);
 
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index a7d94ce..3f6634c 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -55,10 +55,8 @@
 #include "intel_decode.h"
 #include "intel_bufmgr.h"
 #include "intel_screen.h"
-#include "intel_swapbuffers.h"
 
 #include "drirenderbuffer.h"
-#include "vblank.h"
 #include "utils.h"
 #include "xmlpool.h"            /* for symbolic values of enum-type options */
 
@@ -68,12 +66,10 @@
 #endif
 
 
-#define DRIVER_DATE                     "20090712 2009Q2 RC3"
+#define DRIVER_DATE                     "20091221 DEVELOPMENT"
 #define DRIVER_DATE_GEM                 "GEM " DRIVER_DATE
 
 
-static void intel_flush(GLcontext *ctx, GLboolean needs_mi_flush);
-
 static const GLubyte *
 intelGetString(GLcontext * ctx, GLenum name)
 {
@@ -176,9 +172,7 @@
          break;
       }
 
-      (void) driGetRendererString(buffer, chipset, 
-				  (intel->ttm) ? DRIVER_DATE_GEM : DRIVER_DATE,
-				  0);
+      (void) driGetRendererString(buffer, chipset, DRIVER_DATE_GEM, 0);
       return (GLubyte *) buffer;
 
    default:
@@ -195,10 +189,11 @@
 void
 intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
 {
-   struct intel_framebuffer *intel_fb = drawable->driverPrivate;
+   struct gl_framebuffer *fb = drawable->driverPrivate;
    struct intel_renderbuffer *rb;
    struct intel_region *region, *depth_region;
    struct intel_context *intel = context->driverPrivate;
+   struct intel_renderbuffer *front_rb, *back_rb, *depth_rb, *stencil_rb;
    __DRIbuffer *buffers = NULL;
    __DRIscreen *screen;
    int i, count;
@@ -214,26 +209,25 @@
    if (screen->dri2.loader
        && (screen->dri2.loader->base.version > 2)
        && (screen->dri2.loader->getBuffersWithFormat != NULL)) {
-      struct intel_renderbuffer *depth_rb;
-      struct intel_renderbuffer *stencil_rb;
+
+      front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
+      back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
+      depth_rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
+      stencil_rb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
 
       i = 0;
       if ((intel->is_front_buffer_rendering ||
 	   intel->is_front_buffer_reading ||
-	   !intel_fb->color_rb[1])
-	   && intel_fb->color_rb[0]) {
+	   !back_rb) && front_rb) {
 	 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
-	 attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[0]);
+	 attachments[i++] = intel_bits_per_pixel(front_rb);
       }
 
-      if (intel_fb->color_rb[1]) {
+      if (back_rb) {
 	 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
-	 attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[1]);
+	 attachments[i++] = intel_bits_per_pixel(back_rb);
       }
 
-      depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
-      stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
-
       if ((depth_rb != NULL) && (stencil_rb != NULL)) {
 	 attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
 	 attachments[i++] = intel_bits_per_pixel(depth_rb);
@@ -254,13 +248,13 @@
 						      drawable->loaderPrivate);
    } else if (screen->dri2.loader) {
       i = 0;
-      if (intel_fb->color_rb[0])
+      if (intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT))
 	 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
-      if (intel_fb->color_rb[1])
+      if (intel_get_renderbuffer(fb, BUFFER_BACK_LEFT))
 	 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
-      if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH))
+      if (intel_get_renderbuffer(fb, BUFFER_DEPTH))
 	 attachments[i++] = __DRI_BUFFER_DEPTH;
-      if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL))
+      if (intel_get_renderbuffer(fb, BUFFER_STENCIL))
 	 attachments[i++] = __DRI_BUFFER_STENCIL;
 
       buffers = (*screen->dri2.loader->getBuffers)(drawable,
@@ -293,32 +287,32 @@
    for (i = 0; i < count; i++) {
        switch (buffers[i].attachment) {
        case __DRI_BUFFER_FRONT_LEFT:
-	   rb = intel_fb->color_rb[0];
+	   rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
 	   region_name = "dri2 front buffer";
 	   break;
 
        case __DRI_BUFFER_FAKE_FRONT_LEFT:
-	   rb = intel_fb->color_rb[0];
+	   rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
 	   region_name = "dri2 fake front buffer";
 	   break;
 
        case __DRI_BUFFER_BACK_LEFT:
-	   rb = intel_fb->color_rb[1];
+	   rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
 	   region_name = "dri2 back buffer";
 	   break;
 
        case __DRI_BUFFER_DEPTH:
-	   rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
+	   rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
 	   region_name = "dri2 depth buffer";
 	   break;
 
        case __DRI_BUFFER_DEPTH_STENCIL:
-	   rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
+	   rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
 	   region_name = "dri2 depth / stencil buffer";
 	   break;
 
        case __DRI_BUFFER_STENCIL:
-	   rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
+	   rb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
 	   region_name = "dri2 stencil buffer";
 	   break;
 
@@ -365,7 +359,7 @@
        intel_region_release(&region);
 
        if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
-	  rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
+	  rb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
 	  if (rb != NULL) {
 	     struct intel_region *stencil_region = NULL;
 
@@ -382,6 +376,7 @@
        }
    }
 
+   drawable->validBuffers = GL_TRUE;
    driUpdateFramebufferSize(&intel->ctx, drawable);
 }
 
@@ -393,9 +388,6 @@
     void (*old_viewport)(GLcontext *ctx, GLint x, GLint y,
 			 GLsizei w, GLsizei h);
 
-    if (!driContext->driScreenPriv->dri2.enabled)
-	return;
-
     if (!intel->meta.internal_viewport_call && ctx->DrawBuffer->Name == 0) {
        /* If we're rendering to the fake front buffer, make sure all the pending
 	* drawing has landed on the real front buffer.  Otherwise when we
@@ -414,7 +406,6 @@
     old_viewport = ctx->Driver.Viewport;
     ctx->Driver.Viewport = NULL;
     intel->driDrawable = driContext->driDrawablePriv;
-    intelWindowMoved(intel);
     intel_draw_buffer(ctx, intel->ctx.DrawBuffer);
     ctx->Driver.Viewport = old_viewport;
 }
@@ -469,7 +460,7 @@
       intel->vtbl.invalidate_state( intel, new_state );
 }
 
-static void
+void
 intel_flush(GLcontext *ctx, GLboolean needs_mi_flush)
 {
    struct intel_context *intel = intel_context(ctx);
@@ -477,16 +468,9 @@
    if (intel->Fallback)
       _swrast_flush(ctx);
 
-   if (!IS_965(intel->intelScreen->deviceID))
+   if (intel->gen < 4)
       INTEL_FIREVERTICES(intel);
 
-   /* Emit a flush so that any frontbuffer rendering that might have occurred
-    * lands onscreen in a timely manner, even if the X Server doesn't trigger
-    * a flush for us.
-    */
-   if (!intel->driScreen->dri2.enabled && needs_mi_flush)
-      intel_batchbuffer_emit_mi_flush(intel->batch);
-
    if (intel->batch->map != intel->batch->ptr)
       intel_batchbuffer_flush(intel->batch);
 
@@ -592,15 +576,15 @@
 GLboolean
 intelInitContext(struct intel_context *intel,
                  const __GLcontextModes * mesaVis,
-                 __DRIcontextPrivate * driContextPriv,
+                 __DRIcontext * driContextPriv,
                  void *sharedContextPrivate,
                  struct dd_function_table *functions)
 {
    GLcontext *ctx = &intel->ctx;
    GLcontext *shareCtx = (GLcontext *) sharedContextPrivate;
-   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
    intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private;
-   int fthrottle_mode;
+   int bo_reuse_mode;
 
    if (!_mesa_initialize_context(&intel->ctx, mesaVis, shareCtx,
                                  functions, (void *) intel)) {
@@ -611,35 +595,46 @@
    driContextPriv->driverPrivate = intel;
    intel->intelScreen = intelScreen;
    intel->driScreen = sPriv;
-   intel->sarea = intelScreen->sarea;
    intel->driContext = driContextPriv;
-
-   /* Dri stuff */
-   intel->hHWContext = driContextPriv->hHWContext;
    intel->driFd = sPriv->fd;
-   intel->driHwLock = sPriv->lock;
+
+   if (IS_965(intel->intelScreen->deviceID)) {
+      intel->gen = 4;
+   } else if (IS_9XX(intel->intelScreen->deviceID)) {
+      intel->gen = 3;
+      if (IS_945(intel->intelScreen->deviceID)) {
+	 intel->is_945 = GL_TRUE;
+      }
+   } else {
+      intel->gen = 2;
+   }
+
+   if (IS_IGDNG(intel->intelScreen->deviceID)) {
+      intel->is_ironlake = GL_TRUE;
+      intel->needs_ff_sync = GL_TRUE;
+      intel->has_luminance_srgb = GL_TRUE;
+   } else if (IS_G4X(intel->intelScreen->deviceID)) {
+      intel->has_luminance_srgb = GL_TRUE;
+      intel->is_g4x = GL_TRUE;
+   }
 
    driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache,
                        intel->driScreen->myNum,
-		       IS_965(intelScreen->deviceID) ? "i965" : "i915");
+		       (intel->gen >= 4) ? "i965" : "i915");
    if (intelScreen->deviceID == PCI_CHIP_I865_G)
       intel->maxBatchSize = 4096;
    else
       intel->maxBatchSize = BATCH_SZ;
 
    intel->bufmgr = intelScreen->bufmgr;
-   intel->ttm = intelScreen->ttm;
-   if (intel->ttm) {
-      int bo_reuse_mode;
 
-      bo_reuse_mode = driQueryOptioni(&intel->optionCache, "bo_reuse");
-      switch (bo_reuse_mode) {
-      case DRI_CONF_BO_REUSE_DISABLED:
-	 break;
-      case DRI_CONF_BO_REUSE_ALL:
-	 intel_bufmgr_gem_enable_reuse(intel->bufmgr);
-	 break;
-      }
+   bo_reuse_mode = driQueryOptioni(&intel->optionCache, "bo_reuse");
+   switch (bo_reuse_mode) {
+   case DRI_CONF_BO_REUSE_DISABLED:
+      break;
+   case DRI_CONF_BO_REUSE_ALL:
+      intel_bufmgr_gem_enable_reuse(intel->bufmgr);
+      break;
    }
 
    /* This doesn't yet catch all non-conformant rendering, but it's a
@@ -683,7 +678,7 @@
 
    meta_init_metaops(ctx, &intel->meta);
    ctx->Const.MaxColorAttachments = 4;  /* XXX FBO: review this */
-   if (IS_965(intelScreen->deviceID)) {
+   if (intel->gen >= 4) {
       if (MAX_WIDTH > 8192)
 	 ctx->Const.MaxRenderbufferSize = 8192;
    } else {
@@ -720,33 +715,22 @@
       break;
    }
 
-   if (IS_965(intelScreen->deviceID))
+   if (intel->gen >= 4)
       intel->polygon_offset_scale /= 0xffff;
 
    intel->RenderIndex = ~0;
 
-   fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode");
-   intel->irqsEmitted = 0;
-
-   intel->do_irqs = (intel->intelScreen->irq_active &&
-                     fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS);
-
-   intel->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
-
-   if (IS_965(intelScreen->deviceID) && !intel->intelScreen->irq_active) {
+   if (intel->gen >= 4 && !intel->intelScreen->irq_active) {
       _mesa_printf("IRQs not active.  Exiting\n");
       exit(1);
    }
 
-   intelInitExtensions(ctx, GL_FALSE);
+   intelInitExtensions(ctx);
 
    INTEL_DEBUG = driParseDebugString(getenv("INTEL_DEBUG"), debug_control);
    if (INTEL_DEBUG & DEBUG_BUFMGR)
       dri_bufmgr_set_debug(intel->bufmgr, GL_TRUE);
 
-   if (!sPriv->dri2.enabled)
-      intel_recreate_static_regions(intel);
-
    intel->batch = intel_batchbuffer_alloc(intel);
 
    intel_fbo_init(intel);
@@ -795,7 +779,7 @@
 }
 
 void
-intelDestroyContext(__DRIcontextPrivate * driContextPriv)
+intelDestroyContext(__DRIcontext * driContextPriv)
 {
    struct intel_context *intel =
       (struct intel_context *) driContextPriv->driverPrivate;
@@ -842,57 +826,6 @@
           */
       }
 
-      /* XXX In intelMakeCurrent() below, the context's static regions are 
-       * referenced inside the frame buffer; it's listed as a hack,
-       * with a comment of "XXX FBO temporary fix-ups!", but
-       * as long as it's there, we should release the regions here.
-       * The do/while loop around the block is used to allow the
-       * "continue" statements inside the block to exit the block,
-       * to avoid many layers of "if" constructs.
-       */
-      do {
-         __DRIdrawablePrivate * driDrawPriv = intel->driDrawable;
-         struct intel_framebuffer *intel_fb;
-         struct intel_renderbuffer *irbDepth, *irbStencil;
-         if (!driDrawPriv) {
-            /* We're already detached from the drawable; exit this block. */
-            continue;
-         }
-         intel_fb = (struct intel_framebuffer *) driDrawPriv->driverPrivate;
-         if (!intel_fb) {
-            /* The frame buffer is already gone; exit this block. */
-            continue;
-         }
-         irbDepth = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
-         irbStencil = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
-
-         /* If the regions of the frame buffer still match the regions
-          * of the context, release them.  If they've changed somehow,
-          * leave them alone.
-          */
-         if (intel_fb->color_rb[0] && intel_fb->color_rb[0]->region == intel->front_region) {
-	    intel_renderbuffer_set_region(intel_fb->color_rb[0], NULL);
-         }
-         if (intel_fb->color_rb[1] && intel_fb->color_rb[1]->region == intel->back_region) {
-	    intel_renderbuffer_set_region(intel_fb->color_rb[1], NULL);
-         }
-
-         if (irbDepth && irbDepth->region == intel->depth_region) {
-	    intel_renderbuffer_set_region(irbDepth, NULL);
-         }
-         /* Usually, the stencil buffer is the same as the depth buffer;
-          * but they're handled separately in MakeCurrent, so we'll
-          * handle them separately here.
-          */
-         if (irbStencil && irbStencil->region == intel->depth_region) {
-	    intel_renderbuffer_set_region(irbStencil, NULL);
-         }
-      } while (0);
-
-      intel_region_release(&intel->front_region);
-      intel_region_release(&intel->back_region);
-      intel_region_release(&intel->depth_region);
-
       driDestroyOptionCache(&intel->optionCache);
 
       /* free the Mesa context */
@@ -904,7 +837,7 @@
 }
 
 GLboolean
-intelUnbindContext(__DRIcontextPrivate * driContextPriv)
+intelUnbindContext(__DRIcontext * driContextPriv)
 {
    struct intel_context *intel =
       (struct intel_context *) driContextPriv->driverPrivate;
@@ -918,11 +851,10 @@
 }
 
 GLboolean
-intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
-                 __DRIdrawablePrivate * driDrawPriv,
-                 __DRIdrawablePrivate * driReadPriv)
+intelMakeCurrent(__DRIcontext * driContextPriv,
+                 __DRIdrawable * driDrawPriv,
+                 __DRIdrawable * driReadPriv)
 {
-   __DRIscreenPrivate *psp = driDrawPriv->driScreenPriv;
    struct intel_context *intel;
    GET_CURRENT_CONTEXT(curCtx);
 
@@ -940,41 +872,12 @@
    }
 
    if (driContextPriv) {
-      struct intel_framebuffer *intel_fb =
-	 (struct intel_framebuffer *) driDrawPriv->driverPrivate;
-      GLframebuffer *readFb = (GLframebuffer *) driReadPriv->driverPrivate;
+      struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
+      struct gl_framebuffer *readFb = driReadPriv->driverPrivate;
  
-      if (driContextPriv->driScreenPriv->dri2.enabled) {     
-          intel_update_renderbuffers(driContextPriv, driDrawPriv);
-          if (driDrawPriv != driReadPriv)
-              intel_update_renderbuffers(driContextPriv, driReadPriv);
-      } else {
-          /* XXX FBO temporary fix-ups!  These are released in 
-           * intelDextroyContext(), above.  Changes here should be
-           * reflected there.
-           */
-          /* if the renderbuffers don't have regions, init them from the context */
-         struct intel_renderbuffer *irbDepth
-            = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
-         struct intel_renderbuffer *irbStencil
-            = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
-
-         if (intel_fb->color_rb[0]) {
-	    intel_renderbuffer_set_region(intel_fb->color_rb[0],
-					  intel->front_region);
-         }
-         if (intel_fb->color_rb[1]) {
-	    intel_renderbuffer_set_region(intel_fb->color_rb[1],
-					  intel->back_region);
-         }
-
-         if (irbDepth) {
-	    intel_renderbuffer_set_region(irbDepth, intel->depth_region);
-         }
-         if (irbStencil) {
-	    intel_renderbuffer_set_region(irbStencil, intel->depth_region);
-         }
-      }
+      intel_update_renderbuffers(driContextPriv, driDrawPriv);
+      if (driDrawPriv != driReadPriv)
+	 intel_update_renderbuffers(driContextPriv, driReadPriv);
 
       /* set GLframebuffer size to match window, if needed */
       driUpdateFramebufferSize(&intel->ctx, driDrawPriv);
@@ -983,37 +886,10 @@
 	 driUpdateFramebufferSize(&intel->ctx, driReadPriv);
       }
 
-      _mesa_make_current(&intel->ctx, &intel_fb->Base, readFb);
-
+      _mesa_make_current(&intel->ctx, fb, readFb);
       intel->driReadDrawable = driReadPriv;
-
-      if (intel->driDrawable != driDrawPriv) {
-         if (driDrawPriv->swap_interval == (unsigned)-1) {
-            int i;
-
-            driDrawPriv->vblFlags = (intel->intelScreen->irq_active != 0)
-               ? driGetDefaultVBlankFlags(&intel->optionCache)
-               : VBLANK_FLAG_NO_IRQ;
-
-            /* Prevent error printf if one crtc is disabled, this will
-             * be properly calculated in intelWindowMoved() next.
-             */
-            driDrawPriv->vblFlags = intelFixupVblank(intel, driDrawPriv);
-
-            (*psp->systemTime->getUST) (&intel_fb->swap_ust);
-            driDrawableInitVBlank(driDrawPriv);
-            intel_fb->vbl_waited = driDrawPriv->vblSeq;
-
-            for (i = 0; i < 2; i++) {
-               if (intel_fb->color_rb[i])
-                  intel_fb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq;
-            }
-         }
-         intel->driDrawable = driDrawPriv;
-         intelWindowMoved(intel);
-      }
-
-      intel_draw_buffer(&intel->ctx, &intel_fb->Base);
+      intel->driDrawable = driDrawPriv;
+      intel_draw_buffer(&intel->ctx, fb);
    }
    else {
       _mesa_make_current(NULL, NULL, NULL);
@@ -1021,143 +897,3 @@
 
    return GL_TRUE;
 }
-
-static void
-intelContendedLock(struct intel_context *intel, GLuint flags)
-{
-   __DRIdrawablePrivate *dPriv = intel->driDrawable;
-   __DRIscreenPrivate *sPriv = intel->driScreen;
-   volatile drm_i915_sarea_t *sarea = intel->sarea;
-   int me = intel->hHWContext;
-
-   drmGetLock(intel->driFd, intel->hHWContext, flags);
-
-   if (INTEL_DEBUG & DEBUG_LOCK)
-      _mesa_printf("%s - got contended lock\n", __progname);
-
-   /* If the window moved, may need to set a new cliprect now.
-    *
-    * NOTE: This releases and regains the hw lock, so all state
-    * checking must be done *after* this call:
-    */
-   if (dPriv)
-       DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
-
-   if (sarea && sarea->ctxOwner != me) {
-      if (INTEL_DEBUG & DEBUG_BUFMGR) {
-	 fprintf(stderr, "Lost Context: sarea->ctxOwner %x me %x\n",
-		 sarea->ctxOwner, me);
-      }
-      sarea->ctxOwner = me;
-   }
-
-   /* If the last consumer of the texture memory wasn't us, notify the fake
-    * bufmgr and record the new owner.  We should have the memory shared
-    * between contexts of a single fake bufmgr, but this will at least make
-    * things correct for now.
-    */
-   if (!intel->ttm && sarea->texAge != intel->hHWContext) {
-      sarea->texAge = intel->hHWContext;
-      intel_bufmgr_fake_contended_lock_take(intel->bufmgr);
-      if (INTEL_DEBUG & DEBUG_BATCH)
-	 intel_decode_context_reset();
-      if (INTEL_DEBUG & DEBUG_BUFMGR)
-	 fprintf(stderr, "Lost Textures: sarea->texAge %x hw context %x\n",
-		 sarea->ctxOwner, intel->hHWContext);
-   }
-
-   /* Drawable changed?
-    */
-   if (dPriv && intel->lastStamp != dPriv->lastStamp) {
-       intelWindowMoved(intel);
-       intel->lastStamp = dPriv->lastStamp;
-   }
-}
-
-
-_glthread_DECLARE_STATIC_MUTEX(lockMutex);
-
-/* Lock the hardware and validate our state.  
- */
-void LOCK_HARDWARE( struct intel_context *intel )
-{
-    __DRIdrawable *dPriv = intel->driDrawable;
-    __DRIscreen *sPriv = intel->driScreen;
-    char __ret = 0;
-    struct intel_framebuffer *intel_fb = NULL;
-    struct intel_renderbuffer *intel_rb = NULL;
-
-    intel->locked++;
-    if (intel->locked >= 2)
-       return;
-
-    if (!sPriv->dri2.enabled)
-       _glthread_LOCK_MUTEX(lockMutex);
-
-    if (intel->driDrawable) {
-       intel_fb = intel->driDrawable->driverPrivate;
-
-       if (intel_fb)
-	  intel_rb =
-	     intel_get_renderbuffer(&intel_fb->Base,
-				    intel_fb->Base._ColorDrawBufferIndexes[0]);
-    }
-
-    if (intel_rb && dPriv->vblFlags &&
-	!(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) &&
-	(intel_fb->vbl_waited - intel_rb->vbl_pending) > (1<<23)) {
-	drmVBlank vbl;
-
-	vbl.request.type = DRM_VBLANK_ABSOLUTE;
-
-	if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
-	    vbl.request.type |= DRM_VBLANK_SECONDARY;
-	}
-
-	vbl.request.sequence = intel_rb->vbl_pending;
-	drmWaitVBlank(intel->driFd, &vbl);
-	intel_fb->vbl_waited = vbl.reply.sequence;
-    }
-
-    if (!sPriv->dri2.enabled) {
-	DRM_CAS(intel->driHwLock, intel->hHWContext,
-		(DRM_LOCK_HELD|intel->hHWContext), __ret);
-
-	if (__ret)
-	    intelContendedLock( intel, 0 );
-    }
-
-
-    if (INTEL_DEBUG & DEBUG_LOCK)
-      _mesa_printf("%s - locked\n", __progname);
-}
-
-
-/* Unlock the hardware using the global current context 
- */
-void UNLOCK_HARDWARE( struct intel_context *intel )
-{
-    __DRIscreen *sPriv = intel->driScreen;
-
-   intel->locked--;
-   if (intel->locked > 0)
-      return;
-
-   assert(intel->locked == 0);
-
-   if (!sPriv->dri2.enabled) {
-      DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext);
-      _glthread_UNLOCK_MUTEX(lockMutex);
-   }
-
-   if (INTEL_DEBUG & DEBUG_LOCK)
-      _mesa_printf("%s - unlocked\n", __progname);
-
-   /**
-    * Nothing should be left in batch outside of LOCK/UNLOCK which references
-    * cliprects.
-    */
-   if (intel->batch->cliprect_mode == REFERENCES_CLIPRECTS)
-      intel_batchbuffer_flush(intel->batch);
-}
-
diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h
index 356fa4d..07207bf 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -117,8 +117,6 @@
                                struct intel_region * depth_region,
 			       GLuint num_regions);
 
-      GLuint (*flush_cmd) (void);
-
       void (*reduced_primitive_state) (struct intel_context * intel,
                                        GLenum rprim);
 
@@ -137,14 +135,6 @@
                                 struct intel_region * draw_region,
                                 struct intel_region * depth_region);
 
-      void (*meta_draw_quad)(struct intel_context *intel,
-			     GLfloat x0, GLfloat x1,
-			     GLfloat y0, GLfloat y1,
-			     GLfloat z,
-			     GLuint color, /* ARGB32 */
-			     GLfloat s0, GLfloat s1,
-			     GLfloat t0, GLfloat t1);
-
       void (*meta_color_mask) (struct intel_context * intel, GLboolean);
 
       void (*meta_stencil_replace) (struct intel_context * intel,
@@ -176,27 +166,27 @@
 
    struct dri_metaops meta;
 
-   GLint refcount;
    GLbitfield Fallback;  /**< mask of INTEL_FALLBACK_x bits */
    GLuint NewGLState;
 
    dri_bufmgr *bufmgr;
    unsigned int maxBatchSize;
 
-   struct intel_region *front_region;
-   struct intel_region *back_region;
-   struct intel_region *depth_region;
-
    /**
-    * This value indicates that the kernel memory manager is being used
-    * instead of the fake client-side memory manager.
+    * Generation number of the hardware: 2 is 8xx, 3 is 9xx pre-965, 4 is 965.
     */
-   GLboolean ttm;
+   int gen;
+   GLboolean needs_ff_sync;
+   GLboolean is_ironlake;
+   GLboolean is_g4x;
+   GLboolean is_945;
+   GLboolean has_luminance_srgb;
+
+   int urb_size;
 
    struct intel_batchbuffer *batch;
    drm_intel_bo *first_post_swapbuffers_batch;
    GLboolean no_batch_wrap;
-   unsigned batch_id;
 
    struct
    {
@@ -216,10 +206,6 @@
    char *prevLockFile;
    int prevLockLine;
 
-   GLuint ClearColor565;
-   GLuint ClearColor8888;
-
-
    /* Offsets of fields within the current vertex:
     */
    GLuint coloroffset;
@@ -236,6 +222,7 @@
    GLboolean hw_stipple;
    GLboolean depth_buffer_is_float;
    GLboolean no_rast;
+   GLboolean no_hw;
    GLboolean always_flush_batch;
    GLboolean always_flush_cache;
 
@@ -261,19 +248,6 @@
    intel_tri_func draw_tri;
 
    /**
-    * Set to true if a single constant cliprect should be used in the
-    * batchbuffer.  Otherwise, cliprects must be calculated at batchbuffer
-    * flush time while the lock is held.
-    */
-   GLboolean constant_cliprect;
-
-   /**
-    * In !constant_cliprect mode, set to true if the front cliprects should be
-    * used instead of back.
-    */
-   GLboolean front_cliprects;
-
-   /**
     * Set if rendering has occured to the drawable's front buffer.
     *
     * This is used in the DRI2 case to detect that glFlush should also copy
@@ -301,48 +275,23 @@
    GLboolean use_early_z;
    drm_clip_rect_t fboRect;     /**< cliprect for FBO rendering */
 
-   int perf_boxes;
-
-   GLuint do_usleeps;
-   int do_irqs;
-   GLuint irqsEmitted;
-
-   GLboolean scissor;
    drm_clip_rect_t draw_rect;
    drm_clip_rect_t scissor_rect;
 
-   drm_context_t hHWContext;
-   drmLock *driHwLock;
    int driFd;
 
-   __DRIcontextPrivate *driContext;
-   __DRIdrawablePrivate *driDrawable;
-   __DRIdrawablePrivate *driReadDrawable;
-   __DRIscreenPrivate *driScreen;
+   __DRIcontext *driContext;
+   __DRIdrawable *driDrawable;
+   __DRIdrawable *driReadDrawable;
+   __DRIscreen *driScreen;
    intelScreenPrivate *intelScreen;
-   volatile drm_i915_sarea_t *sarea;
-
-   GLuint lastStamp;
-
-   GLboolean no_hw;
 
    /**
     * Configuration cache
     */
    driOptionCache optionCache;
-
-   int64_t swap_ust;
-   int64_t swap_missed_ust;
-
-   GLuint swap_count;
-   GLuint swap_missed_count;
 };
 
-/* These are functions now:
- */
-void LOCK_HARDWARE( struct intel_context *intel );
-void UNLOCK_HARDWARE( struct intel_context *intel );
-
 extern char *__progname;
 
 
@@ -353,14 +302,14 @@
 #define ALIGN(value, alignment)  ((value + alignment - 1) & ~(alignment - 1))
 #define IS_POWER_OF_TWO(val) (((val) & (val - 1)) == 0)
 
-static inline uint32_t
+static INLINE uint32_t
 U_FIXED(float value, uint32_t frac_bits)
 {
    value *= (1 << frac_bits);
    return value < 0 ? 0 : value;
 }
 
-static inline uint32_t
+static INLINE uint32_t
 S_FIXED(float value, uint32_t frac_bits)
 {
    return value * (1 << frac_bits);
@@ -373,29 +322,6 @@
 } while (0)
 
 /* ================================================================
- * Color packing:
- */
-
-#define INTEL_PACKCOLOR4444(r,g,b,a) \
-  ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4))
-
-#define INTEL_PACKCOLOR1555(r,g,b,a) \
-  ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
-    ((a) ? 0x8000 : 0))
-
-#define INTEL_PACKCOLOR565(r,g,b) \
-  ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
-
-#define INTEL_PACKCOLOR8888(r,g,b,a) \
-  ((a<<24) | (r<<16) | (g<<8) | b)
-
-#define INTEL_PACKCOLOR(format, r,  g,  b, a)		\
-(format == DV_PF_555 ? INTEL_PACKCOLOR1555(r,g,b,a) :	\
- (format == DV_PF_565 ? INTEL_PACKCOLOR565(r,g,b) :	\
-  (format == DV_PF_8888 ? INTEL_PACKCOLOR8888(r,g,b,a) :	\
-   0)))
-
-/* ================================================================
  * From linux kernel i386 header files, copes with odd sizes better
  * than COPY_DWORDS would:
  * XXX Put this in src/mesa/main/imports.h ???
@@ -480,14 +406,13 @@
 
 extern GLboolean intelInitContext(struct intel_context *intel,
                                   const __GLcontextModes * mesaVis,
-                                  __DRIcontextPrivate * driContextPriv,
+                                  __DRIcontext * driContextPriv,
                                   void *sharedContextPrivate,
                                   struct dd_function_table *functions);
 
-extern void intelGetLock(struct intel_context *intel, GLuint flags);
-
 extern void intelFinish(GLcontext * ctx);
 extern void intelFlush(GLcontext * ctx);
+extern void intel_flush(GLcontext * ctx, GLboolean needs_mi_flush);
 
 extern void intelInitDriverFunctions(struct dd_function_table *functions);
 
@@ -587,4 +512,25 @@
    return (value & (value - 1)) == 0;
 }
 
+static INLINE void
+intel_bo_map_gtt_preferred(struct intel_context *intel,
+			   drm_intel_bo *bo,
+			   GLboolean write)
+{
+   if (intel->intelScreen->kernel_exec_fencing)
+      drm_intel_gem_bo_map_gtt(bo);
+   else
+      drm_intel_bo_map(bo, write);
+}
+
+static INLINE void
+intel_bo_unmap_gtt_preferred(struct intel_context *intel,
+			     drm_intel_bo *bo)
+{
+   if (intel->intelScreen->kernel_exec_fencing)
+      drm_intel_gem_bo_unmap_gtt(bo);
+   else
+      drm_intel_bo_unmap(bo);
+}
+
 #endif
diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c
index b6754c9..5ac5ce1 100644
--- a/src/mesa/drivers/dri/intel/intel_extensions.c
+++ b/src/mesa/drivers/dri/intel/intel_extensions.c
@@ -79,6 +79,7 @@
    { "GL_ARB_half_float_pixel",           NULL },
    { "GL_ARB_map_buffer_range",           GL_ARB_map_buffer_range_functions },
    { "GL_ARB_multitexture",               NULL },
+   { "GL_ARB_pixel_buffer_object",      NULL },
    { "GL_ARB_point_parameters",           GL_ARB_point_parameters_functions },
    { "GL_ARB_point_sprite",               NULL },
    { "GL_ARB_shader_objects",             GL_ARB_shader_objects_functions },
@@ -104,6 +105,8 @@
    { "GL_EXT_blend_logic_op",             NULL },
    { "GL_EXT_blend_subtract",             NULL },
    { "GL_EXT_cull_vertex",                GL_EXT_cull_vertex_functions },
+   { "GL_EXT_framebuffer_blit",         GL_EXT_framebuffer_blit_functions },
+   { "GL_EXT_framebuffer_object",       GL_EXT_framebuffer_object_functions },
    { "GL_EXT_fog_coord",                  GL_EXT_fog_coord_functions },
    { "GL_EXT_gpu_program_parameters",     GL_EXT_gpu_program_parameters_functions },
    { "GL_EXT_packed_depth_stencil",       NULL },
@@ -121,7 +124,6 @@
    { "GL_MESA_pack_invert",               NULL },
    { "GL_MESA_ycbcr_texture",             NULL },
    { "GL_NV_blend_square",                NULL },
-   { "GL_NV_point_sprite",                GL_NV_point_sprite_functions },
    { "GL_NV_vertex_program",              GL_NV_vertex_program_functions },
    { "GL_NV_vertex_program1_1",           NULL },
    { "GL_SGIS_generate_mipmap",           NULL },
@@ -176,14 +178,6 @@
    { NULL, NULL }
 };
 
-
-static const struct dri_extension ttm_extensions[] = {
-   { "GL_ARB_pixel_buffer_object",      NULL },
-   { "GL_EXT_framebuffer_blit",         GL_EXT_framebuffer_blit_functions },
-   { "GL_EXT_framebuffer_object",       GL_EXT_framebuffer_object_functions },
-   { NULL, NULL }
-};
-
 static const struct dri_extension fragment_shader_extensions[] = {
    { "GL_ARB_fragment_shader",            NULL },
    { NULL, NULL }
@@ -194,31 +188,24 @@
  * extensions for a context.
  */
 void
-intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging)
+intelInitExtensions(GLcontext *ctx)
 {
-   struct intel_context *intel = ctx?intel_context(ctx):NULL;
+   struct intel_context *intel = intel_context(ctx);
 
    /* Disable imaging extension until convolution is working in teximage paths.
     */
-   enable_imaging = GL_FALSE;
+   driInitExtensions(ctx, card_extensions, GL_FALSE);
 
-   driInitExtensions(ctx, card_extensions, enable_imaging);
-
-   if (intel == NULL || intel->ttm)
-      driInitExtensions(ctx, ttm_extensions, GL_FALSE);
-
-   if (intel == NULL || IS_965(intel->intelScreen->deviceID))
+   if (intel->gen >= 4)
       driInitExtensions(ctx, brw_extensions, GL_FALSE);
 
-   if (intel == NULL || IS_915(intel->intelScreen->deviceID)
-       || IS_945(intel->intelScreen->deviceID)) {
+   if (intel->gen == 3) {
       driInitExtensions(ctx, i915_extensions, GL_FALSE);
 
-      if (intel == NULL || driQueryOptionb(&intel->optionCache, "fragment_shader"))
+      if (driQueryOptionb(&intel->optionCache, "fragment_shader"))
 	 driInitExtensions(ctx, fragment_shader_extensions, GL_FALSE);
 
-      if (intel == NULL || driQueryOptionb(&intel->optionCache,
-					   "stub_occlusion_query"))
+      if (driQueryOptionb(&intel->optionCache, "stub_occlusion_query"))
 	 driInitExtensions(ctx, arb_oq_extensions, GL_FALSE);
    }
 }
diff --git a/src/mesa/drivers/dri/intel/intel_extensions.h b/src/mesa/drivers/dri/intel/intel_extensions.h
index 97147ec..e78e073 100644
--- a/src/mesa/drivers/dri/intel/intel_extensions.h
+++ b/src/mesa/drivers/dri/intel/intel_extensions.h
@@ -30,7 +30,10 @@
 
 
 extern void
-intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging);
+intelInitExtensions(GLcontext *ctx);
+
+extern void
+intelFlushDrawable(__DRIdrawable *drawable);
 
 
 #endif
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index d8ac4d3..d58ffd9 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -37,6 +37,7 @@
 #include "drivers/common/meta.h"
 
 #include "intel_context.h"
+#include "intel_batchbuffer.h"
 #include "intel_buffers.h"
 #include "intel_fbo.h"
 #include "intel_mipmap_tree.h"
@@ -105,8 +106,8 @@
 {
    struct intel_context *intel = intel_context(ctx);
    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
-   GLboolean softwareBuffer = GL_FALSE;
    int cpp;
+   GLuint pitch;
 
    ASSERT(rb->Name != 0);
 
@@ -116,18 +117,14 @@
    case GL_RGB5:
       rb->Format = MESA_FORMAT_RGB565;
       rb->DataType = GL_UNSIGNED_BYTE;
-      irb->texformat = MESA_FORMAT_RGB565;
-      cpp = 2;
       break;
    case GL_RGB:
    case GL_RGB8:
    case GL_RGB10:
    case GL_RGB12:
    case GL_RGB16:
-      rb->Format = MESA_FORMAT_ARGB8888;
+      rb->Format = MESA_FORMAT_XRGB8888;
       rb->DataType = GL_UNSIGNED_BYTE;
-      irb->texformat = MESA_FORMAT_ARGB8888; /* XXX: Need xrgb8888 */
-      cpp = 4;
       break;
    case GL_RGBA:
    case GL_RGBA2:
@@ -139,8 +136,6 @@
    case GL_RGBA16:
       rb->Format = MESA_FORMAT_ARGB8888;
       rb->DataType = GL_UNSIGNED_BYTE;
-      irb->texformat = MESA_FORMAT_ARGB8888;
-      cpp = 4;
       break;
    case GL_STENCIL_INDEX:
    case GL_STENCIL_INDEX1_EXT:
@@ -150,29 +145,21 @@
       /* alloc a depth+stencil buffer */
       rb->Format = MESA_FORMAT_S8_Z24;
       rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
-      cpp = 4;
-      irb->texformat = MESA_FORMAT_S8_Z24;
       break;
    case GL_DEPTH_COMPONENT16:
       rb->Format = MESA_FORMAT_Z16;
       rb->DataType = GL_UNSIGNED_SHORT;
-      cpp = 2;
-      irb->texformat = MESA_FORMAT_Z16;
       break;
    case GL_DEPTH_COMPONENT:
    case GL_DEPTH_COMPONENT24:
    case GL_DEPTH_COMPONENT32:
       rb->Format = MESA_FORMAT_S8_Z24;
       rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
-      cpp = 4;
-      irb->texformat = MESA_FORMAT_S8_Z24;
       break;
    case GL_DEPTH_STENCIL_EXT:
    case GL_DEPTH24_STENCIL8_EXT:
       rb->Format = MESA_FORMAT_S8_Z24;
       rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
-      cpp = 4;
-      irb->texformat = MESA_FORMAT_S8_Z24;
       break;
    default:
       _mesa_problem(ctx,
@@ -181,6 +168,7 @@
    }
 
    rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
+   cpp = _mesa_get_format_bytes(rb->Format);
 
    intelFlush(ctx);
 
@@ -190,32 +178,25 @@
    }
 
    /* allocate new memory region/renderbuffer */
-   if (softwareBuffer) {
-      return _mesa_soft_renderbuffer_storage(ctx, rb, internalFormat,
-                                             width, height);
-   }
-   else {
-      /* Choose a pitch to match hardware requirements:
-       */
-      GLuint pitch = ((cpp * width + 63) & ~63) / cpp;
 
-      /* alloc hardware renderbuffer */
-      DBG("Allocating %d x %d Intel RBO (pitch %d)\n", width,
-	  height, pitch);
+   /* Choose a pitch to match hardware requirements:
+    */
+   pitch = ((cpp * width + 63) & ~63) / cpp;
 
-      irb->region = intel_region_alloc(intel, I915_TILING_NONE,
-				       cpp, width, height, pitch,
-				       GL_TRUE);
-      if (!irb->region)
-         return GL_FALSE;       /* out of memory? */
+   /* alloc hardware renderbuffer */
+   DBG("Allocating %d x %d Intel RBO (pitch %d)\n", width, height, pitch);
 
-      ASSERT(irb->region->buffer);
+   irb->region = intel_region_alloc(intel, I915_TILING_NONE, cpp,
+				    width, height, pitch, GL_TRUE);
+   if (!irb->region)
+      return GL_FALSE;       /* out of memory? */
 
-      rb->Width = width;
-      rb->Height = height;
+   ASSERT(irb->region->buffer);
 
-      return GL_TRUE;
-   }
+   rb->Width = width;
+   rb->Height = height;
+
+   return GL_TRUE;
 }
 
 
@@ -241,7 +222,6 @@
 intel_resize_buffers(GLcontext *ctx, struct gl_framebuffer *fb,
 		     GLuint width, GLuint height)
 {
-   struct intel_framebuffer *intel_fb = (struct intel_framebuffer*)fb;
    int i;
 
    _mesa_resize_framebuffer(ctx, fb, width, height);
@@ -252,9 +232,10 @@
       return;
    }
 
+
    /* Make sure all window system renderbuffers are up to date */
-   for (i = 0; i < 2; i++) {
-      struct gl_renderbuffer *rb = &intel_fb->color_rb[i]->Base;
+   for (i = BUFFER_FRONT_LEFT; i <= BUFFER_BACK_RIGHT; i++) {
+      struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
 
       /* only resize if size is changing */
       if (rb && (rb->Width != width || rb->Height != height)) {
@@ -297,7 +278,6 @@
    GET_CURRENT_CONTEXT(ctx);
 
    struct intel_renderbuffer *irb;
-   const GLuint name = 0;
 
    irb = CALLOC_STRUCT(intel_renderbuffer);
    if (!irb) {
@@ -305,7 +285,7 @@
       return NULL;
    }
 
-   _mesa_init_renderbuffer(&irb->Base, name);
+   _mesa_init_renderbuffer(&irb->Base, 0);
    irb->Base.ClassID = INTEL_RB_CLASS;
 
    switch (format) {
@@ -314,10 +294,6 @@
       irb->Base.DataType = GL_UNSIGNED_BYTE;
       break;
    case MESA_FORMAT_XRGB8888:
-      /* XXX this is a hack since XRGB surfaces don't seem to work
-       * properly yet.  Reading the alpha channel returns 0 instead of 1.
-       */
-      format = MESA_FORMAT_ARGB8888;
       irb->Base._BaseFormat = GL_RGB;
       irb->Base.DataType = GL_UNSIGNED_BYTE;
       break;
@@ -346,7 +322,6 @@
 
    irb->Base.Format = format;
    irb->Base.InternalFormat = irb->Base._BaseFormat;
-   irb->texformat = format;
 
    /* intel-specific methods */
    irb->Base.Delete = intel_delete_renderbuffer;
@@ -423,9 +398,6 @@
 intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb, 
 		     struct gl_texture_image *texImage)
 {
-   irb->texformat = texImage->TexFormat;
-   gl_format texFormat;
-
    if (texImage->TexFormat == MESA_FORMAT_ARGB8888) {
       irb->Base.DataType = GL_UNSIGNED_BYTE;
       DBG("Render to RGBA8 texture OK\n");
@@ -455,14 +427,13 @@
       DBG("Render to DEPTH_STENCIL texture OK\n");
    }
    else {
-      DBG("Render to texture BAD FORMAT %d\n", texImage->TexFormat);
+      DBG("Render to texture BAD FORMAT %s\n",
+	  _mesa_get_format_name(texImage->TexFormat));
       return GL_FALSE;
    }
 
    irb->Base.Format = texImage->TexFormat;
 
-   texFormat = texImage->TexFormat;
-
    irb->Base.InternalFormat = texImage->InternalFormat;
    irb->Base._BaseFormat = _mesa_base_fbo_format(ctx, irb->Base.InternalFormat);
    irb->Base.Width = texImage->Width;
@@ -577,6 +548,7 @@
 					   dst_x) * intel_image->mt->cpp;
    intel_image->mt->region->draw_x = dst_x;
    intel_image->mt->region->draw_y = dst_y;
+   intel_image->used_as_render_target = GL_TRUE;
 
    /* update drawing region, etc */
    intel_draw_buffer(ctx, fb);
@@ -590,18 +562,22 @@
 intel_finish_render_texture(GLcontext * ctx,
                             struct gl_renderbuffer_attachment *att)
 {
-   /* no-op
-    * Previously we released the renderbuffer's intel_region but
-    * that's not necessary and actually caused problems when trying
-    * to do a glRead/CopyPixels from the renderbuffer later.
-    * The region will be released later if the texture is replaced
-    * or the renderbuffer deleted.
-    *
-    * The intention of this driver hook is more of a "done rendering
-    * to texture, please re-twiddle/etc if necessary".
-    */
-}
+   struct intel_context *intel = intel_context(ctx);
+   struct gl_texture_object *tex_obj = att->Texture;
+   struct gl_texture_image *image =
+      tex_obj->Image[att->CubeMapFace][att->TextureLevel];
+   struct intel_texture_image *intel_image = intel_texture_image(image);
 
+   /* Flag that this image may now be validated into the object's miptree. */
+   intel_image->used_as_render_target = GL_FALSE;
+
+   /* Since we've (probably) rendered to the texture and will (likely) use
+    * it in the texture domain later on in this batchbuffer, flush the
+    * batch.  Once again, we wish for a domain tracker in libdrm to cover
+    * usage inside of a batchbuffer like GEM does in the kernel.
+    */
+   intel_batchbuffer_emit_mi_flush(intel->batch);
+}
 
 /**
  * Do additional "completeness" testing of a framebuffer object.
@@ -615,11 +591,21 @@
       intel_get_renderbuffer(fb, BUFFER_STENCIL);
    int i;
 
-   if (stencilRb && stencilRb != depthRb) {
-      /* we only support combined depth/stencil buffers, not separate
-       * stencil buffers.
-       */
-      fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+   if (depthRb && stencilRb && stencilRb != depthRb) {
+      if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Type == GL_TEXTURE &&
+	  ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Type == GL_TEXTURE &&
+	  (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Texture->Name ==
+	   ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Texture->Name)) {
+	 /* OK */
+      } else {
+	 /* we only support combined depth/stencil buffers, not separate
+	  * stencil buffers.
+	  */
+	 DBG("Only supports combined depth/stencil (found %s, %s)\n",
+	     depthRb ? _mesa_get_format_name(depthRb->Base.Format): "NULL",
+	     stencilRb ? _mesa_get_format_name(stencilRb->Base.Format): "NULL");
+	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+      }
    }
 
    for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
@@ -630,11 +616,12 @@
 	 continue;
 
       if (irb == NULL) {
+	 DBG("software rendering renderbuffer\n");
 	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
 	 continue;
       }
 
-      switch (irb->texformat) {
+      switch (irb->Base.Format) {
       case MESA_FORMAT_ARGB8888:
       case MESA_FORMAT_XRGB8888:
       case MESA_FORMAT_RGB565:
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h
index 50a8a95..586dbbb 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.h
+++ b/src/mesa/drivers/dri/intel/intel_fbo.h
@@ -34,27 +34,6 @@
 struct intel_context;
 
 /**
- * Intel framebuffer, derived from gl_framebuffer.
- */
-struct intel_framebuffer
-{
-   struct gl_framebuffer Base;
-
-   struct intel_renderbuffer *color_rb[2];
-
-   /* VBI
-    */
-   GLuint vbl_waited;
-
-   int64_t swap_ust;
-   int64_t swap_missed_ust;
-
-   GLuint swap_count;
-   GLuint swap_missed_count;
-};
-
-
-/**
  * Intel renderbuffer, derived from gl_renderbuffer.
  */
 struct intel_renderbuffer
@@ -62,10 +41,6 @@
    struct gl_renderbuffer Base;
    struct intel_region *region;
 
-   gl_format texformat;
-
-   GLuint vbl_pending;   /**< vblank sequence number of pending flip */
-
    uint8_t *span_cache;
    unsigned long span_cache_offset;
 };
@@ -123,7 +98,7 @@
 
 
 extern void
-intel_flip_renderbuffers(struct intel_framebuffer *intel_fb);
+intel_flip_renderbuffers(struct gl_framebuffer *fb);
 
 
 static INLINE struct intel_region *
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index 3996c10..82e4150 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -87,7 +87,7 @@
    mt->pitch = 0;
 
 #ifdef I915
-   if (IS_945(intel->intelScreen->deviceID))
+   if (intel->is_945)
       ok = i945_miptree_layout(intel, mt, tiling);
    else
       ok = i915_miptree_layout(intel, mt, tiling);
@@ -122,7 +122,7 @@
 
    if (intel->use_texture_tiling && compress_byte == 0 &&
        intel->intelScreen->kernel_exec_fencing) {
-      if (IS_965(intel->intelScreen->deviceID) &&
+      if (intel->gen >= 4 &&
 	  (base_format == GL_DEPTH_COMPONENT ||
 	   base_format == GL_DEPTH_STENCIL_EXT))
 	 tiling = I915_TILING_Y;
@@ -224,16 +224,12 @@
    if (!mt->compressed) {
       int pitch_align;
 
-      if (intel->ttm) {
-	 /* XXX: Align pitch to multiple of 64 bytes for now to allow
-	  * render-to-texture to work in all cases. This should probably be
-	  * replaced at some point by some scheme to only do this when really
-	  * necessary.
-	  */
-	 pitch_align = 64;
-      } else {
-	 pitch_align = 4;
-      }
+      /* XXX: Align pitch to multiple of 64 bytes for now to allow
+       * render-to-texture to work in all cases. This should probably be
+       * replaced at some point by some scheme to only do this when really
+       * necessary.
+       */
+      pitch_align = 64;
 
       if (tiling == I915_TILING_X)
 	 pitch_align = 512;
@@ -315,17 +311,14 @@
  */
 GLboolean
 intel_miptree_match_image(struct intel_mipmap_tree *mt,
-                          struct gl_texture_image *image,
-                          GLuint face, GLuint level)
+                          struct gl_texture_image *image)
 {
    GLboolean isCompressed = _mesa_is_format_compressed(image->TexFormat);
+   struct intel_texture_image *intelImage = intel_texture_image(image);
+   GLuint level = intelImage->level;
 
-   /* Images with borders are never pulled into mipmap trees. 
-    */
-   if (image->Border ||
-       ((image->_BaseFormat == GL_DEPTH_COMPONENT) &&
-        ((image->TexObject->WrapS == GL_CLAMP_TO_BORDER) ||
-         (image->TexObject->WrapT == GL_CLAMP_TO_BORDER)))) 
+   /* Images with borders are never pulled into mipmap trees. */
+   if (image->Border)
       return GL_FALSE;
 
    if (image->InternalFormat != mt->internal_format ||
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
index 3bce54d..b19c548 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
@@ -165,8 +165,7 @@
 /* Check if an image fits an existing mipmap tree layout
  */
 GLboolean intel_miptree_match_image(struct intel_mipmap_tree *mt,
-                                    struct gl_texture_image *image,
-                                    GLuint face, GLuint level);
+                                    struct gl_texture_image *image);
 
 /* Return a pointer to an image within a tree.  Return image stride as
  * well.
diff --git a/src/mesa/drivers/dri/intel/intel_pixel.c b/src/mesa/drivers/dri/intel/intel_pixel.c
index 993e427..5142f3d 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel.c
@@ -88,10 +88,10 @@
       return GL_FALSE;
    }
 
-   if (!(ctx->Color.ColorMask[0] &&
-	 ctx->Color.ColorMask[1] &&
-	 ctx->Color.ColorMask[2] &&
-	 ctx->Color.ColorMask[3])) {
+   if (!(ctx->Color.ColorMask[0][0] &&
+	 ctx->Color.ColorMask[0][1] &&
+	 ctx->Color.ColorMask[0][2] &&
+	 ctx->Color.ColorMask[0][3])) {
       DBG("fallback due to color masking\n");
       return GL_FALSE;
    }
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
index 99330b6..85e5ad2 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
@@ -32,6 +32,7 @@
 #include "main/mtypes.h"
 #include "main/macros.h"
 #include "main/bufferobj.h"
+#include "main/polygon.h"
 #include "main/pixelstore.h"
 #include "main/polygon.h"
 #include "main/state.h"
@@ -165,7 +166,7 @@
  * Returns the low Y value of the vertical range given, flipped according to
  * whether the framebuffer is or not.
  */
-static inline int
+static INLINE int
 y_flip(struct gl_framebuffer *fb, int y, int height)
 {
    if (fb->Name != 0)
@@ -228,16 +229,13 @@
    UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[3], tmpColor[3]);
 
    if (dst->cpp == 2)
-      color = INTEL_PACKCOLOR565(ubcolor[0], ubcolor[1], ubcolor[2]);
+      color = PACK_COLOR_565(ubcolor[0], ubcolor[1], ubcolor[2]);
    else
-      color = INTEL_PACKCOLOR8888(ubcolor[0], ubcolor[1],
-				  ubcolor[2], ubcolor[3]);
+      color = PACK_COLOR_8888(ubcolor[3], ubcolor[0], ubcolor[1], ubcolor[2]);
 
    if (!intel_check_blit_fragment_ops(ctx, tmpColor[3] == 1.0F))
       return GL_FALSE;
 
-   LOCK_HARDWARE(intel);
-
    intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);
    if (num_cliprects != 0) {
       GLuint i;
@@ -325,7 +323,6 @@
       }
    }
 out:
-   UNLOCK_HARDWARE(intel);
 
    if (INTEL_DEBUG & DEBUG_SYNC)
       intel_batchbuffer_flush(intel->batch);
@@ -336,6 +333,8 @@
                               unpack->BufferObj);
    }
 
+   intel_check_front_buffer_rendering(intel);
+
    return GL_TRUE;
 }
 
@@ -502,6 +501,7 @@
    meta_restore_fragment_program(&intel->meta);
    meta_restore_vertex_program(&intel->meta);
 
+   _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture);
    _mesa_PopClientAttrib();
    _mesa_PopAttrib();
 
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_copy.c b/src/mesa/drivers/dri/intel/intel_pixel_copy.c
index f058b3c..e002516 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_copy.c
@@ -35,28 +35,33 @@
 #include "intel_buffers.h"
 #include "intel_regions.h"
 #include "intel_pixel.h"
+#include "intel_fbo.h"
 
 #define FILE_DEBUG_FLAG DEBUG_PIXEL
 
 static struct intel_region *
 copypix_src_region(struct intel_context *intel, GLenum type)
 {
+   struct intel_renderbuffer *depth;
+
+   depth = (struct intel_renderbuffer *)
+      &intel->ctx.DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
+
    switch (type) {
    case GL_COLOR:
       return intel_readbuf_region(intel);
    case GL_DEPTH:
-      /* Don't think this is really possible execpt at 16bpp, when we have no stencil.
-       */
-      if (intel->depth_region && intel->depth_region->cpp == 2)
-         return intel->depth_region;
+      /* Don't think this is really possible execpt at 16bpp, when we
+       * have no stencil. */
+      if (depth && depth->region->cpp == 2)
+         return depth->region;
    case GL_STENCIL:
-      /* Don't think this is really possible. 
-       */
+      /* Don't think this is really possible. */
       break;
    case GL_DEPTH_STENCIL_EXT:
       /* Does it matter whether it is stencil/depth or depth/stencil?
        */
-      return intel->depth_region;
+      return depth->region;
    default:
       break;
    }
@@ -83,10 +88,10 @@
             ctx->Depth.Test ||
             ctx->Fog.Enabled ||
             ctx->Stencil._Enabled ||
-            !ctx->Color.ColorMask[0] ||
-            !ctx->Color.ColorMask[1] ||
-            !ctx->Color.ColorMask[2] ||
-            !ctx->Color.ColorMask[3] ||
+            !ctx->Color.ColorMask[0][0] ||
+            !ctx->Color.ColorMask[0][1] ||
+            !ctx->Color.ColorMask[0][2] ||
+            !ctx->Color.ColorMask[0][3] ||
             ctx->Texture._EnabledUnits ||
 	    ctx->FragmentProgram._Enabled ||
 	    ctx->Color.BlendEnabled);
@@ -134,8 +139,6 @@
 
    intelFlush(&intel->ctx);
 
-   LOCK_HARDWARE(intel);
-
    intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);
    if (num_cliprects != 0) {
       GLint delta_x;
@@ -214,13 +217,13 @@
 				ctx->Color.ColorLogicOpEnabled ?
 				ctx->Color.LogicOp : GL_COPY)) {
 	    DBG("%s: blit failure\n", __FUNCTION__);
-	    UNLOCK_HARDWARE(intel);
 	    return GL_FALSE;
 	 }
       }
    }
 out:
-   UNLOCK_HARDWARE(intel);
+
+   intel_check_front_buffer_rendering(intel);
 
    DBG("%s: success\n", __FUNCTION__);
    return GL_TRUE;
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c
index 9b382e3..b870e93 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c
@@ -69,7 +69,6 @@
    GLfloat vertices[4][2];
    struct intel_renderbuffer *irb;
    struct intel_renderbuffer *depth_irb;
-   struct gl_renderbuffer *rb;
    struct gl_pixelstore_attrib old_unpack;
    GLstencil *stencil_pixels;
    int row, y1, y2;
@@ -170,7 +169,6 @@
     */
    depth_irb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_DEPTH);
    irb = intel_create_renderbuffer(MESA_FORMAT_ARGB8888);
-   rb = &irb->Base;
    irb->Base.Width = depth_irb->Base.Width;
    irb->Base.Height = depth_irb->Base.Height;
    intel_renderbuffer_set_region(irb, depth_irb->region);
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_read.c b/src/mesa/drivers/dri/intel/intel_pixel_read.c
index 4707500..9c0fdc6 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_read.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_read.c
@@ -77,7 +77,7 @@
    struct intel_context *intel = intel_context(ctx);
    intelScreenPrivate *screen = intel->intelScreen;
    GLint pitch = pack->RowLength ? pack->RowLength : width;
-   __DRIdrawablePrivate *dPriv = intel->driDrawable;
+   __DRIdrawable *dPriv = intel->driDrawable;
    int textureFormat;
    GLenum glTextureFormat;
    int destFormat, depthFormat, destPitch;
@@ -105,15 +105,12 @@
       return GL_FALSE;
    }
 
-   LOCK_HARDWARE(intel);
-
    if (intel->driDrawable->numClipRects) {
       intel->vtbl.install_meta_state(intel);
       intel->vtbl.meta_no_depth_write(intel);
       intel->vtbl.meta_no_stencil_write(intel);
 
       if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) {
-         UNLOCK_HARDWARE(intel);
          SET_STATE(i830, state);
          if (INTEL_DEBUG & DEBUG_PIXEL)
             fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__);
@@ -150,7 +147,6 @@
 
       intel->vtbl.leave_meta_state(intel);
    }
-   UNLOCK_HARDWARE(intel);
 
    intel_region_wait_fence(ctx, dest_region);   /* required by GL */
    return GL_TRUE;
@@ -224,7 +220,6 @@
     * fire with lock held to guarentee cliprects are correct.
     */
    intelFlush(&intel->ctx);
-   LOCK_HARDWARE(intel);
 
    if (intel->driReadDrawable->numClipRects) {
       GLboolean all = (width * height * src->cpp == dst->Base.Size &&
@@ -233,7 +228,7 @@
       dri_bo *dst_buffer = intel_bufferobj_buffer(intel, dst,
 						  all ? INTEL_WRITE_FULL :
 						  INTEL_WRITE_PART);
-      __DRIdrawablePrivate *dPriv = intel->driReadDrawable;
+      __DRIdrawable *dPriv = intel->driReadDrawable;
       int nbox = dPriv->numClipRects;
       drm_clip_rect_t *box = dPriv->pClipRects;
       drm_clip_rect_t rect;
@@ -261,12 +256,10 @@
 				rect.y2 - src_rect.y2,
 				rect.x2 - rect.x1, rect.y2 - rect.y1,
 				GL_COPY)) {
-	    UNLOCK_HARDWARE(intel);
 	    return GL_FALSE;
 	 }
       }
    }
-   UNLOCK_HARDWARE(intel);
 
    if (INTEL_DEBUG & DEBUG_PIXEL)
       _mesa_printf("%s - DONE\n", __FUNCTION__);
@@ -285,11 +278,11 @@
 
    intelFlush(ctx);
 
-#ifdef I915
    if (do_blit_readpixels
        (ctx, x, y, width, height, format, type, pack, pixels))
       return;
 
+#ifdef I915
    if (do_texture_readpixels
        (ctx, x, y, width, height, format, type, pack, pixels))
       return;
diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index a86c66a..61aefa0 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -362,14 +362,12 @@
          intel_region_cow(intel, dst);
    }
 
-   LOCK_HARDWARE(intel);
    _mesa_copy_rect(intel_region_map(intel, dst) + dst_offset,
                    dst->cpp,
                    dst->pitch,
                    dstx, dsty, width, height, src, src_pitch, srcx, srcy);
 
    intel_region_unmap(intel, dst);
-   UNLOCK_HARDWARE(intel);
 }
 
 /* Copy rectangular sub-regions. Need better logic about when to
@@ -485,7 +483,6 @@
    /* Now blit from the texture buffer to the new buffer: 
     */
 
-   LOCK_HARDWARE(intel);
    ok = intelEmitCopyBlit(intel,
                           region->cpp,
                           region->pitch, pbo->buffer, 0, region->tiling,
@@ -494,7 +491,6 @@
                           region->pitch, region->height,
                           GL_COPY);
    assert(ok);
-   UNLOCK_HARDWARE(intel);
 }
 
 dri_bo *
@@ -510,126 +506,3 @@
 
    return region->buffer;
 }
-
-static struct intel_region *
-intel_recreate_static(struct intel_context *intel,
-		      const char *name,
-		      struct intel_region *region,
-		      intelRegion *region_desc)
-{
-   intelScreenPrivate *intelScreen = intel->intelScreen;
-   int ret;
-
-   if (region == NULL) {
-      region = calloc(sizeof(*region), 1);
-      region->refcount = 1;
-      _DBG("%s creating new region %p\n", __FUNCTION__, region);
-   }
-   else {
-      _DBG("%s %p\n", __FUNCTION__, region);
-   }
-
-   if (intel->ctx.Visual.rgbBits == 24)
-      region->cpp = 4;
-   else
-      region->cpp = intel->ctx.Visual.rgbBits / 8;
-   region->pitch = intelScreen->pitch;
-   region->width = intelScreen->width;
-   region->height = intelScreen->height;
-
-   if (region->buffer != NULL) {
-      dri_bo_unreference(region->buffer);
-      region->buffer = NULL;
-   }
-
-   if (intel->ttm) {
-      assert(region_desc->bo_handle != -1);
-      region->buffer = intel_bo_gem_create_from_name(intel->bufmgr,
-						     name,
-						     region_desc->bo_handle);
-
-      ret = dri_bo_get_tiling(region->buffer, &region->tiling,
-			      &region->bit_6_swizzle);
-      if (ret != 0) {
-	 fprintf(stderr, "Couldn't get tiling of buffer %d (%s): %s\n",
-		 region_desc->bo_handle, name, strerror(-ret));
-	 intel_region_release(&region);
-	 return NULL;
-      }
-   } else {
-      if (region->classic_map != NULL) {
-	 drmUnmap(region->classic_map,
-		  region->pitch * region->cpp * region->height);
-	 region->classic_map = NULL;
-      }
-      ret = drmMap(intel->driFd, region_desc->handle,
-		   region->pitch * region->cpp * region->height,
-		   &region->classic_map);
-      if (ret != 0) {
-	 fprintf(stderr, "Failed to drmMap %s buffer\n", name);
-	 free(region);
-	 return NULL;
-      }
-
-      region->buffer = intel_bo_fake_alloc_static(intel->bufmgr,
-						  name,
-						  region_desc->offset,
-						  region->pitch * region->cpp *
-						  region->height,
-						  region->classic_map);
-
-      /* The sarea just gives us a boolean for whether it's tiled or not,
-       * instead of which tiling mode it is.  Guess.
-       */
-      if (region_desc->tiled) {
-	 if (IS_965(intel->intelScreen->deviceID) &&
-	     region_desc == &intelScreen->depth)
-	    region->tiling = I915_TILING_Y;
-	 else
-	    region->tiling = I915_TILING_X;
-      } else {
-	 region->tiling = I915_TILING_NONE;
-      }
-
-      region->bit_6_swizzle = I915_BIT_6_SWIZZLE_NONE;
-   }
-
-   assert(region->buffer != NULL);
-
-   return region;
-}
-
-/**
- * Create intel_region structs to describe the static front, back, and depth
- * buffers created by the xserver.
- *
- * Although FBO's mean we now no longer use these as render targets in
- * all circumstances, they won't go away until the back and depth
- * buffers become private, and the front buffer will remain even then.
- *
- * Note that these don't allocate video memory, just describe
- * allocations alread made by the X server.
- */
-void
-intel_recreate_static_regions(struct intel_context *intel)
-{
-   intelScreenPrivate *intelScreen = intel->intelScreen;
-
-   intel->front_region =
-      intel_recreate_static(intel, "front",
-			    intel->front_region,
-			    &intelScreen->front);
-
-   intel->back_region =
-      intel_recreate_static(intel, "back",
-			    intel->back_region,
-			    &intelScreen->back);
-
-   /* Still assumes front.cpp == depth.cpp.  We can kill this when we move to
-    * private buffers.
-    */
-   intel->depth_region =
-      intel_recreate_static(intel, "depth",
-			    intel->depth_region,
-			    &intelScreen->depth);
-}
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 789135b..e240957 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -31,7 +31,6 @@
 #include "main/renderbuffer.h"
 
 #include "utils.h"
-#include "vblank.h"
 #include "xmlpool.h"
 
 #include "intel_batchbuffer.h"
@@ -41,7 +40,6 @@
 #include "intel_extensions.h"
 #include "intel_fbo.h"
 #include "intel_regions.h"
-#include "intel_swapbuffers.h"
 #include "intel_screen.h"
 #include "intel_span.h"
 #include "intel_tex.h"
@@ -57,7 +55,6 @@
 PUBLIC const char __driConfigOptions[] =
    DRI_CONF_BEGIN
    DRI_CONF_SECTION_PERFORMANCE
-      DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
       DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC)
       /* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
        * DRI_CONF_BO_REUSE_ALL
@@ -99,133 +96,12 @@
    DRI_CONF_SECTION_END
 DRI_CONF_END;
 
-const GLuint __driNConfigOptions = 12;
+const GLuint __driNConfigOptions = 11;
 
 #ifdef USE_NEW_INTERFACE
 static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
 #endif /*USE_NEW_INTERFACE */
 
-/**
- * Map all the memory regions described by the screen.
- * \return GL_TRUE if success, GL_FALSE if error.
- */
-GLboolean
-intelMapScreenRegions(__DRIscreenPrivate * sPriv)
-{
-   intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private;
-
-   if (0)
-      _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle);
-   if (intelScreen->tex.size != 0) {
-      if (drmMap(sPriv->fd,
-		 intelScreen->tex.handle,
-		 intelScreen->tex.size,
-		 (drmAddress *) & intelScreen->tex.map) != 0) {
-	 intelUnmapScreenRegions(intelScreen);
-	 return GL_FALSE;
-      }
-   }
-
-   return GL_TRUE;
-}
-
-void
-intelUnmapScreenRegions(intelScreenPrivate * intelScreen)
-{
-   if (intelScreen->tex.map) {
-      drmUnmap(intelScreen->tex.map, intelScreen->tex.size);
-      intelScreen->tex.map = NULL;
-   }
-}
-
-
-static void
-intelPrintDRIInfo(intelScreenPrivate * intelScreen,
-                  __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv)
-{
-   fprintf(stderr, "*** Front size:   0x%x  offset: 0x%x  pitch: %d\n",
-           intelScreen->front.size, intelScreen->front.offset,
-           intelScreen->pitch);
-   fprintf(stderr, "*** Back size:    0x%x  offset: 0x%x  pitch: %d\n",
-           intelScreen->back.size, intelScreen->back.offset,
-           intelScreen->pitch);
-   fprintf(stderr, "*** Depth size:   0x%x  offset: 0x%x  pitch: %d\n",
-           intelScreen->depth.size, intelScreen->depth.offset,
-           intelScreen->pitch);
-   fprintf(stderr, "*** Texture size: 0x%x  offset: 0x%x\n",
-           intelScreen->tex.size, intelScreen->tex.offset);
-   fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem);
-}
-
-
-static void
-intelPrintSAREA(const drm_i915_sarea_t * sarea)
-{
-   fprintf(stderr, "SAREA: sarea width %d  height %d\n", sarea->width,
-           sarea->height);
-   fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch);
-   fprintf(stderr,
-           "SAREA: front offset: 0x%08x  size: 0x%x  handle: 0x%x tiled: %d\n",
-           sarea->front_offset, sarea->front_size,
-           (unsigned) sarea->front_handle, sarea->front_tiled);
-   fprintf(stderr,
-           "SAREA: back  offset: 0x%08x  size: 0x%x  handle: 0x%x tiled: %d\n",
-           sarea->back_offset, sarea->back_size,
-           (unsigned) sarea->back_handle, sarea->back_tiled);
-   fprintf(stderr, "SAREA: depth offset: 0x%08x  size: 0x%x  handle: 0x%x tiled: %d\n",
-           sarea->depth_offset, sarea->depth_size,
-           (unsigned) sarea->depth_handle, sarea->depth_tiled);
-   fprintf(stderr, "SAREA: tex   offset: 0x%08x  size: 0x%x  handle: 0x%x\n",
-           sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle);
-}
-
-
-/**
- * A number of the screen parameters are obtained/computed from
- * information in the SAREA.  This function updates those parameters.
- */
-static void
-intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen,
-                           drm_i915_sarea_t * sarea)
-{
-   intelScreen->width = sarea->width;
-   intelScreen->height = sarea->height;
-   intelScreen->pitch = sarea->pitch;
-
-   intelScreen->front.offset = sarea->front_offset;
-   intelScreen->front.handle = sarea->front_handle;
-   intelScreen->front.size = sarea->front_size;
-   intelScreen->front.tiled = sarea->front_tiled;
-
-   intelScreen->back.offset = sarea->back_offset;
-   intelScreen->back.handle = sarea->back_handle;
-   intelScreen->back.size = sarea->back_size;
-   intelScreen->back.tiled = sarea->back_tiled;
-
-   intelScreen->depth.offset = sarea->depth_offset;
-   intelScreen->depth.handle = sarea->depth_handle;
-   intelScreen->depth.size = sarea->depth_size;
-   intelScreen->depth.tiled = sarea->depth_tiled;
-
-   if (intelScreen->driScrnPriv->ddx_version.minor >= 9) {
-      intelScreen->front.bo_handle = sarea->front_bo_handle;
-      intelScreen->back.bo_handle = sarea->back_bo_handle;
-      intelScreen->depth.bo_handle = sarea->depth_bo_handle;
-   } else {
-      intelScreen->front.bo_handle = -1;
-      intelScreen->back.bo_handle = -1;
-      intelScreen->depth.bo_handle = -1;
-   }
-
-   intelScreen->tex.offset = sarea->tex_offset;
-   intelScreen->logTextureGranularity = sarea->log_tex_granularity;
-   intelScreen->tex.handle = sarea->tex_handle;
-   intelScreen->tex.size = sarea->tex_size;
-
-   if (0)
-      intelPrintSAREA(sarea);
-}
-
 static const __DRItexOffsetExtension intelTexOffsetExtension = {
    { __DRI_TEX_OFFSET },
    intelSetTexOffset,
@@ -237,19 +113,41 @@
    intelSetTexBuffer2,
 };
 
+static void
+intelDRI2Flush(__DRIdrawable *drawable)
+{
+   struct intel_context *intel = drawable->driContextPriv->driverPrivate;
+
+   if (intel->gen < 4)
+      INTEL_FIREVERTICES(intel);
+
+   if (intel->batch->map != intel->batch->ptr)
+      intel_batchbuffer_flush(intel->batch);
+}
+
+static void
+intelDRI2FlushInvalidate(__DRIdrawable *drawable)
+{
+   intelDRI2Flush(drawable);
+   drawable->validBuffers = GL_FALSE;
+}
+
+static const struct __DRI2flushExtensionRec intelFlushExtension = {
+    { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
+    intelDRI2Flush,
+    intelDRI2FlushInvalidate,
+};
+
 static const __DRIextension *intelScreenExtensions[] = {
     &driReadDrawableExtension,
-    &driCopySubBufferExtension.base,
-    &driSwapControlExtension.base,
-    &driFrameTrackingExtension.base,
-    &driMediaStreamCounterExtension.base,
     &intelTexOffsetExtension.base,
     &intelTexBufferExtension.base,
+    &intelFlushExtension.base,
     NULL
 };
 
 static GLboolean
-intel_get_param(__DRIscreenPrivate *psp, int param, int *value)
+intel_get_param(__DRIscreen *psp, int param, int *value)
 {
    int ret;
    struct drm_i915_getparam gp;
@@ -266,68 +164,12 @@
    return GL_TRUE;
 }
 
-static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
-{
-   intelScreenPrivate *intelScreen;
-   I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv;
-   drm_i915_sarea_t *sarea;
-
-   if (sPriv->devPrivSize != sizeof(I830DRIRec)) {
-      fprintf(stderr,
-              "\nERROR!  sizeof(I830DRIRec) does not match passed size from device driver\n");
-      return GL_FALSE;
-   }
-
-   /* Allocate the private area */
-   intelScreen = (intelScreenPrivate *) CALLOC(sizeof(intelScreenPrivate));
-   if (!intelScreen) {
-      fprintf(stderr, "\nERROR!  Allocating private area failed\n");
-      return GL_FALSE;
-   }
-   /* parse information in __driConfigOptions */
-   driParseOptionInfo(&intelScreen->optionCache,
-                      __driConfigOptions, __driNConfigOptions);
-
-   intelScreen->driScrnPriv = sPriv;
-   sPriv->private = (void *) intelScreen;
-   sarea = (drm_i915_sarea_t *)
-      (((GLubyte *) sPriv->pSAREA) + gDRIPriv->sarea_priv_offset);
-   intelScreen->sarea = sarea;
-
-   intelScreen->deviceID = gDRIPriv->deviceID;
-
-   intelUpdateScreenFromSAREA(intelScreen, sarea);
-
-   if (!intelMapScreenRegions(sPriv)) {
-      fprintf(stderr, "\nERROR!  mapping regions\n");
-      _mesa_free(intelScreen);
-      sPriv->private = NULL;
-      return GL_FALSE;
-   }
-
-   if (0)
-      intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv);
-
-   intelScreen->drmMinor = sPriv->drm_version.minor;
-
-   /* Determine if IRQs are active? */
-   if (!intel_get_param(sPriv, I915_PARAM_IRQ_ACTIVE,
-			&intelScreen->irq_active))
-      return GL_FALSE;
-
-   sPriv->extensions = intelScreenExtensions;
-
-   return GL_TRUE;
-}
-
-
 static void
-intelDestroyScreen(__DRIscreenPrivate * sPriv)
+intelDestroyScreen(__DRIscreen * sPriv)
 {
    intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private;
 
    dri_bufmgr_destroy(intelScreen->bufmgr);
-   intelUnmapScreenRegions(intelScreen);
    driDestroyOptionInfo(&intelScreen->optionCache);
 
    FREE(intelScreen);
@@ -339,10 +181,12 @@
  * This is called when we need to set up GL rendering to a new X window.
  */
 static GLboolean
-intelCreateBuffer(__DRIscreenPrivate * driScrnPriv,
-                  __DRIdrawablePrivate * driDrawPriv,
+intelCreateBuffer(__DRIscreen * driScrnPriv,
+                  __DRIdrawable * driDrawPriv,
                   const __GLcontextModes * mesaVis, GLboolean isPixmap)
 {
+   struct intel_renderbuffer *rb;
+
    if (isPixmap) {
       return GL_FALSE;          /* not implemented */
    }
@@ -351,12 +195,12 @@
                              mesaVis->depthBits != 24);
       gl_format rgbFormat;
 
-      struct intel_framebuffer *intel_fb = CALLOC_STRUCT(intel_framebuffer);
+      struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer);
 
-      if (!intel_fb)
+      if (!fb)
 	 return GL_FALSE;
 
-      _mesa_initialize_framebuffer(&intel_fb->Base, mesaVis);
+      _mesa_initialize_framebuffer(fb, mesaVis);
 
       if (mesaVis->redBits == 5)
 	 rgbFormat = MESA_FORMAT_RGB565;
@@ -366,16 +210,12 @@
 	 rgbFormat = MESA_FORMAT_ARGB8888;
 
       /* setup the hardware-based renderbuffers */
-      intel_fb->color_rb[0] = intel_create_renderbuffer(rgbFormat);
-      _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT,
-			     &intel_fb->color_rb[0]->Base);
+      rb = intel_create_renderbuffer(rgbFormat);
+      _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base);
 
       if (mesaVis->doubleBufferMode) {
-	 intel_fb->color_rb[1] = intel_create_renderbuffer(rgbFormat);
-
-         _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT,
-				&intel_fb->color_rb[1]->Base);
-
+	 rb = intel_create_renderbuffer(rgbFormat);
+         _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base);
       }
 
       if (mesaVis->depthBits == 24) {
@@ -384,115 +224,63 @@
 	    struct intel_renderbuffer *depthStencilRb
 	       = intel_create_renderbuffer(MESA_FORMAT_S8_Z24);
 	    /* note: bind RB to two attachment points */
-	    _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH,
-				   &depthStencilRb->Base);
-	    _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_STENCIL,
-				   &depthStencilRb->Base);
+	    _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthStencilRb->Base);
+	    _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &depthStencilRb->Base);
 	 } else {
 	    struct intel_renderbuffer *depthRb
 	       = intel_create_renderbuffer(MESA_FORMAT_X8_Z24);
-	    _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH,
-				   &depthRb->Base);
+	    _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
 	 }
       }
       else if (mesaVis->depthBits == 16) {
          /* just 16-bit depth buffer, no hw stencil */
          struct intel_renderbuffer *depthRb
 	    = intel_create_renderbuffer(MESA_FORMAT_Z16);
-         _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, &depthRb->Base);
+         _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
       }
 
       /* now add any/all software-based renderbuffers we may need */
-      _mesa_add_soft_renderbuffers(&intel_fb->Base,
+      _mesa_add_soft_renderbuffers(fb,
                                    GL_FALSE, /* never sw color */
                                    GL_FALSE, /* never sw depth */
                                    swStencil, mesaVis->accumRedBits > 0,
                                    GL_FALSE, /* never sw alpha */
                                    GL_FALSE  /* never sw aux */ );
-      driDrawPriv->driverPrivate = (void *) intel_fb;
+      driDrawPriv->driverPrivate = fb;
 
       return GL_TRUE;
    }
 }
 
 static void
-intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv)
+intelDestroyBuffer(__DRIdrawable * driDrawPriv)
 {
-   struct intel_framebuffer *intel_fb = driDrawPriv->driverPrivate;
-   struct intel_renderbuffer *depth_rb;
-   struct intel_renderbuffer *stencil_rb;
-
-   if (intel_fb) {
-      if (intel_fb->color_rb[0]) {
-         intel_renderbuffer_set_region(intel_fb->color_rb[0], NULL);
-      }
-
-      if (intel_fb->color_rb[1]) {
-         intel_renderbuffer_set_region(intel_fb->color_rb[1], NULL);
-      }
-
-      depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
-      if (depth_rb) {
-         intel_renderbuffer_set_region(depth_rb, NULL);
-      }
-
-      stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
-      if (stencil_rb) {
-         intel_renderbuffer_set_region(stencil_rb, NULL);
-      }
-   }
-
-   _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
+    struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
+  
+    _mesa_reference_framebuffer(&fb, NULL);
 }
 
-
-/**
- * Get information about previous buffer swaps.
- */
-static int
-intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo)
-{
-   struct intel_framebuffer *intel_fb;
-
-   if ((dPriv == NULL) || (dPriv->driverPrivate == NULL)
-       || (sInfo == NULL)) {
-      return -1;
-   }
-
-   intel_fb = dPriv->driverPrivate;
-   sInfo->swap_count = intel_fb->swap_count;
-   sInfo->swap_ust = intel_fb->swap_ust;
-   sInfo->swap_missed_count = intel_fb->swap_missed_count;
-
-   sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
-      ? driCalculateSwapUsage(dPriv, 0, intel_fb->swap_missed_ust)
-      : 0.0;
-
-   return 0;
-}
-
-
 /* There are probably better ways to do this, such as an
  * init-designated function to register chipids and createcontext
  * functions.
  */
 extern GLboolean i830CreateContext(const __GLcontextModes * mesaVis,
-                                   __DRIcontextPrivate * driContextPriv,
+                                   __DRIcontext * driContextPriv,
                                    void *sharedContextPrivate);
 
 extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis,
-                                   __DRIcontextPrivate * driContextPriv,
+                                   __DRIcontext * driContextPriv,
                                    void *sharedContextPrivate);
 extern GLboolean brwCreateContext(const __GLcontextModes * mesaVis,
-				  __DRIcontextPrivate * driContextPriv,
+				  __DRIcontext * driContextPriv,
 				  void *sharedContextPrivate);
 
 static GLboolean
 intelCreateContext(const __GLcontextModes * mesaVis,
-                   __DRIcontextPrivate * driContextPriv,
+                   __DRIcontext * driContextPriv,
                    void *sharedContextPrivate)
 {
-   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
    intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private;
 
 #ifdef I915
@@ -513,152 +301,20 @@
    return GL_FALSE;
 }
 
-
-static __DRIconfig **
-intelFillInModes(__DRIscreenPrivate *psp,
-		 unsigned pixel_bits, unsigned depth_bits,
-                 unsigned stencil_bits, GLboolean have_back_buffer)
-{
-   __DRIconfig **configs;
-   __GLcontextModes *m;
-   unsigned depth_buffer_factor;
-   unsigned back_buffer_factor;
-   int i;
-
-   /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
-    * support pageflipping at all.
-    */
-   static const GLenum back_buffer_modes[] = {
-      GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
-   };
-
-   uint8_t depth_bits_array[3];
-   uint8_t stencil_bits_array[3];
-   uint8_t msaa_samples_array[1];
-
-   depth_bits_array[0] = 0;
-   depth_bits_array[1] = depth_bits;
-   depth_bits_array[2] = depth_bits;
-
-   /* Just like with the accumulation buffer, always provide some modes
-    * with a stencil buffer.  It will be a sw fallback, but some apps won't
-    * care about that.
-    */
-   stencil_bits_array[0] = 0;
-   stencil_bits_array[1] = 0;
-   if (depth_bits == 24)
-      stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
-
-   stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits;
-
-   msaa_samples_array[0] = 0;
-
-   depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1;
-   back_buffer_factor = (have_back_buffer) ? 3 : 1;
-
-   if (pixel_bits == 16) {
-      configs = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
-				 depth_bits_array, stencil_bits_array,
-				 depth_buffer_factor, back_buffer_modes,
-				 back_buffer_factor,
-				 msaa_samples_array, 1);
-   }
-   else {
-      __DRIconfig **configs_a8r8g8b8;
-      __DRIconfig **configs_x8r8g8b8;
-
-      configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
-					  depth_bits_array,
-					  stencil_bits_array,
-					  depth_buffer_factor,
-					  back_buffer_modes,
-					  back_buffer_factor,
-					  msaa_samples_array, 1);
-      configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV,
-					  depth_bits_array,
-					  stencil_bits_array,
-					  depth_buffer_factor,
-					  back_buffer_modes,
-					  back_buffer_factor,
-					  msaa_samples_array, 1);
-      configs = driConcatConfigs(configs_a8r8g8b8, configs_x8r8g8b8);
-   }
-
-   if (configs == NULL) {
-    fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
-              __LINE__);
-      return NULL;
-   }
-
-   /* Mark the visual as slow if there are "fake" stencil bits.
-    */
-   for (i = 0; configs[i]; i++) {
-      m = &configs[i]->modes;
-      if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
-         m->visualRating = GLX_SLOW_CONFIG;
-      }
-   }
-
-   return configs;
-}
-
 static GLboolean
 intel_init_bufmgr(intelScreenPrivate *intelScreen)
 {
-   GLboolean gem_disable = getenv("INTEL_NO_GEM") != NULL;
-   int gem_kernel = 0;
-   GLboolean gem_supported;
-   struct drm_i915_getparam gp;
-   __DRIscreenPrivate *spriv = intelScreen->driScrnPriv;
+   __DRIscreen *spriv = intelScreen->driScrnPriv;
    int num_fences = 0;
 
    intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
 
-   gp.param = I915_PARAM_HAS_GEM;
-   gp.value = &gem_kernel;
-
-   (void) drmCommandWriteRead(spriv->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
-
-   /* If we've got a new enough DDX that's initializing GEM and giving us
-    * object handles for the shared buffers, use that.
-    */
-   intelScreen->ttm = GL_FALSE;
-   if (intelScreen->driScrnPriv->dri2.enabled)
-       gem_supported = GL_TRUE;
-   else if (intelScreen->driScrnPriv->ddx_version.minor >= 9 &&
-	    gem_kernel &&
-	    intelScreen->front.bo_handle != -1)
-       gem_supported = GL_TRUE;
-   else
-       gem_supported = GL_FALSE;
-
-   if (!gem_disable && gem_supported) {
-      intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
-      if (intelScreen->bufmgr != NULL)
-	 intelScreen->ttm = GL_TRUE;
-   }
+   intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
    /* Otherwise, use the classic buffer manager. */
    if (intelScreen->bufmgr == NULL) {
-      if (gem_disable) {
-	 _mesa_warning(NULL, "GEM disabled.  Using classic.");
-      } else {
-	 _mesa_warning(NULL,
-                       "Failed to initialize GEM.  Falling back to classic.");
-      }
-
-      if (intelScreen->tex.size == 0) {
-	 fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
-		 __func__, __LINE__);
-	 return GL_FALSE;
-      }
-
-      intelScreen->bufmgr =
-	 intel_bufmgr_fake_init(spriv->fd,
-				intelScreen->tex.offset,
-				intelScreen->tex.map,
-				intelScreen->tex.size,
-				(unsigned int * volatile)
-				&intelScreen->sarea->last_dispatch);
+      fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
+	      __func__, __LINE__);
+      return GL_FALSE;
    }
 
    if (intel_get_param(spriv, I915_PARAM_NUM_FENCES_AVAIL, &num_fences))
@@ -671,78 +327,20 @@
 
 /**
  * This is the driver specific part of the createNewScreen entry point.
- * Called when using legacy DRI.
- * 
- * \todo maybe fold this into intelInitDriver
- *
- * \return the __GLcontextModes supported by this driver
- */
-static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp)
-{
-   intelScreenPrivate *intelScreen;
-#ifdef I915
-   static const __DRIversion ddx_expected = { 1, 5, 0 };
-#else
-   static const __DRIversion ddx_expected = { 1, 6, 0 };
-#endif
-   static const __DRIversion dri_expected = { 4, 0, 0 };
-   static const __DRIversion drm_expected = { 1, 5, 0 };
-   I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv;
-
-   if (!driCheckDriDdxDrmVersions2("i915",
-                                   &psp->dri_version, &dri_expected,
-                                   &psp->ddx_version, &ddx_expected,
-                                   &psp->drm_version, &drm_expected)) {
-      return NULL;
-   }
-
-   if (!intelInitDriver(psp))
-       return NULL;
-
-   psp->extensions = intelScreenExtensions;
-
-   intelScreen = psp->private;
-   if (!intel_init_bufmgr(intelScreen))
-       return GL_FALSE;
-
-   return (const __DRIconfig **)
-       intelFillInModes(psp, dri_priv->cpp * 8,
-			(dri_priv->cpp == 2) ? 16 : 24,
-			(dri_priv->cpp == 2) ? 0  : 8, 1);
-}
-
-struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen)
-{
-  /*
-   * This should probably change to have the screen allocate a dummy
-   * context at screen creation. For now just use the current context.
-   */
-
-  GET_CURRENT_CONTEXT(ctx);
-  if (ctx == NULL) {
-     _mesa_problem(NULL, "No current context in intelScreenContext\n");
-     return NULL;
-  }
-  return intel_context(ctx);
-}
-
-/**
- * This is the driver specific part of the createNewScreen entry point.
  * Called when using DRI2.
  *
  * \return the __GLcontextModes supported by this driver
  */
 static const
-__DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp)
+__DRIconfig **intelInitScreen2(__DRIscreen *psp)
 {
    intelScreenPrivate *intelScreen;
    GLenum fb_format[3];
    GLenum fb_type[3];
-   /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
-    * support pageflipping at all.
-    */
+
    static const GLenum back_buffer_modes[] = {
-      GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
+       GLX_NONE, GLX_SWAP_UNDEFINED_OML,
+       GLX_SWAP_EXCHANGE_OML, GLX_SWAP_COPY_OML
    };
    uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1];
    int color;
@@ -842,19 +440,19 @@
 }
 
 const struct __DriverAPIRec driDriverAPI = {
-   .InitScreen		 = intelInitScreen,
    .DestroyScreen	 = intelDestroyScreen,
    .CreateContext	 = intelCreateContext,
    .DestroyContext	 = intelDestroyContext,
    .CreateBuffer	 = intelCreateBuffer,
    .DestroyBuffer	 = intelDestroyBuffer,
-   .SwapBuffers		 = intelSwapBuffers,
    .MakeCurrent		 = intelMakeCurrent,
    .UnbindContext	 = intelUnbindContext,
-   .GetSwapInfo		 = intelGetSwapInfo,
-   .GetDrawableMSC	 = driDrawableGetMSC32,
-   .WaitForMSC		 = driWaitForMSC32,
-   .CopySubBuffer	 = intelCopySubBuffer,
-
    .InitScreen2		 = intelInitScreen2,
 };
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driDRI2Extension.base,
+    NULL
+};
diff --git a/src/mesa/drivers/dri/intel/intel_screen.h b/src/mesa/drivers/dri/intel/intel_screen.h
index a9b9e10..e87e306 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.h
+++ b/src/mesa/drivers/dri/intel/intel_screen.h
@@ -66,7 +66,7 @@
 
    int logTextureGranularity;
 
-   __DRIscreenPrivate *driScrnPriv;
+   __DRIscreen *driScrnPriv;
 
    volatile drm_i915_sarea_t *sarea;
 
@@ -77,7 +77,6 @@
    GLboolean no_hw;
 
    GLboolean no_vbo;
-   int ttm;
    dri_bufmgr *bufmgr;
    GLboolean kernel_exec_fencing;
 
@@ -89,18 +88,18 @@
 
 
 
-extern GLboolean intelMapScreenRegions(__DRIscreenPrivate * sPriv);
+extern GLboolean intelMapScreenRegions(__DRIscreen * sPriv);
 
 extern void intelUnmapScreenRegions(intelScreenPrivate * intelScreen);
 
-extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv);
+extern void intelDestroyContext(__DRIcontext * driContextPriv);
 
-extern GLboolean intelUnbindContext(__DRIcontextPrivate * driContextPriv);
+extern GLboolean intelUnbindContext(__DRIcontext * driContextPriv);
 
 extern GLboolean
-intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
-                 __DRIdrawablePrivate * driDrawPriv,
-                 __DRIdrawablePrivate * driReadPriv);
+intelMakeCurrent(__DRIcontext * driContextPriv,
+                 __DRIdrawable * driDrawPriv,
+                 __DRIdrawable * driReadPriv);
 
 extern struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen);
 
diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c
index bab13e3..605734d 100644
--- a/src/mesa/drivers/dri/intel/intel_span.c
+++ b/src/mesa/drivers/dri/intel/intel_span.c
@@ -292,7 +292,6 @@
 
 #define Y_FLIP(_y) ((_y) * yScale + yBias)
 
-/* XXX with GEM, these need to tell the kernel */
 #define HW_LOCK()
 
 #define HW_UNLOCK()
@@ -335,7 +334,7 @@
 #include "intel_spantmp.h"
 
 /* x8r8g8b8 color span and pixel functions */
-#define INTEL_PIXEL_FMT GL_BGRA
+#define INTEL_PIXEL_FMT GL_BGR
 #define INTEL_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
 #define INTEL_READ_VALUE(offset) pread_xrgb8888(irb, offset)
 #define INTEL_WRITE_VALUE(offset, v) pwrite_xrgb8888(irb, offset, v)
@@ -518,7 +517,6 @@
    GLuint i;
 
    intelFlush(&intel->ctx);
-   LOCK_HARDWARE(intel);
 
    for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
       if (ctx->Texture.Unit[i]._ReallyEnabled) {
@@ -554,8 +552,6 @@
    intel_map_unmap_framebuffer(intel, ctx->DrawBuffer, GL_FALSE);
    if (ctx->ReadBuffer != ctx->DrawBuffer)
       intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_FALSE);
-
-   UNLOCK_HARDWARE(intel);
 }
 
 
@@ -614,18 +610,10 @@
 			 struct gl_renderbuffer *rb)
 {
    struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb;
-   uint32_t tiling;
-
-   /* If in GEM mode, we need to do the tile address swizzling ourselves,
-    * instead of the fence registers handling it.
-    */
-   if (intel->ttm)
-      tiling = irb->region->tiling;
-   else
-      tiling = I915_TILING_NONE;
+   uint32_t tiling = irb->region->tiling;
 
    if (intel->intelScreen->kernel_exec_fencing) {
-      switch (irb->texformat) {
+      switch (irb->Base.Format) {
       case MESA_FORMAT_RGB565:
 	 intel_gttmap_InitPointers_RGB565(rb);
 	 break;
@@ -639,13 +627,7 @@
          intel_gttmap_InitPointers_xRGB8888(rb);
 	 break;
       case MESA_FORMAT_ARGB8888:
-	 if (rb->_BaseFormat == GL_RGB) {
-	    /* XXX remove this code someday when we enable XRGB surfaces */
-	    /* 8888 RGBx */
-	    intel_gttmap_InitPointers_xRGB8888(rb);
-	 } else {
-	    intel_gttmap_InitPointers_ARGB8888(rb);
-	 }
+	 intel_gttmap_InitPointers_ARGB8888(rb);
 	 break;
       case MESA_FORMAT_Z16:
 	 intel_gttmap_InitDepthPointers_z16(rb);
@@ -668,13 +650,16 @@
       default:
 	 _mesa_problem(NULL,
 		       "Unexpected MesaFormat %d in intelSetSpanFunctions",
-		       irb->texformat);
+		       irb->Base.Format);
 	 break;
       }
       return;
    }
 
-   switch (irb->texformat) {
+   /* If in GEM mode, we need to do the tile address swizzling ourselves,
+    * instead of the fence registers handling it.
+    */
+   switch (irb->Base.Format) {
    case MESA_FORMAT_RGB565:
       switch (tiling) {
       case I915_TILING_NONE:
@@ -732,35 +717,18 @@
       }
       break;
    case MESA_FORMAT_ARGB8888:
-      if (rb->_BaseFormat == GL_RGB) {
-         /* XXX remove this code someday when we enable XRGB surfaces */
-	 /* 8888 RGBx */
-	 switch (tiling) {
-	 case I915_TILING_NONE:
-	 default:
-	    intelInitPointers_xRGB8888(rb);
-	    break;
-	 case I915_TILING_X:
-	    intel_XTile_InitPointers_xRGB8888(rb);
-	    break;
-	 case I915_TILING_Y:
-	    intel_YTile_InitPointers_xRGB8888(rb);
-	    break;
-	 }
-      } else {
-	 /* 8888 RGBA */
-	 switch (tiling) {
-	 case I915_TILING_NONE:
-	 default:
-	    intelInitPointers_ARGB8888(rb);
-	    break;
-	 case I915_TILING_X:
-	    intel_XTile_InitPointers_ARGB8888(rb);
-	    break;
-	 case I915_TILING_Y:
-	    intel_YTile_InitPointers_ARGB8888(rb);
-	    break;
-	 }
+      /* 8888 RGBA */
+      switch (tiling) {
+      case I915_TILING_NONE:
+      default:
+	 intelInitPointers_ARGB8888(rb);
+	 break;
+      case I915_TILING_X:
+	 intel_XTile_InitPointers_ARGB8888(rb);
+	 break;
+      case I915_TILING_Y:
+	 intel_YTile_InitPointers_ARGB8888(rb);
+	 break;
       }
       break;
    case MESA_FORMAT_Z16:
diff --git a/src/mesa/drivers/dri/intel/intel_state.c b/src/mesa/drivers/dri/intel/intel_state.c
index 4ee7423..aefae53 100644
--- a/src/mesa/drivers/dri/intel/intel_state.c
+++ b/src/mesa/drivers/dri/intel/intel_state.c
@@ -196,25 +196,6 @@
    }
 }
 
-
-static void
-intelClearColor(GLcontext *ctx, const GLfloat color[4])
-{
-   struct intel_context *intel = intel_context(ctx);
-   GLubyte clear[4];
-
-   CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]);
-   CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]);
-   CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]);
-   CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]);
-
-   /* compute both 32 and 16-bit clear values */
-   intel->ClearColor8888 = INTEL_PACKCOLOR8888(clear[0], clear[1],
-                                               clear[2], clear[3]);
-   intel->ClearColor565 = INTEL_PACKCOLOR565(clear[0], clear[1], clear[2]);
-}
-
-
 /* Fallback to swrast for select and feedback.
  */
 static void
@@ -229,5 +210,4 @@
 intelInitStateFuncs(struct dd_function_table *functions)
 {
    functions->RenderMode = intelRenderMode;
-   functions->ClearColor = intelClearColor;
 }
diff --git a/src/mesa/drivers/dri/intel/intel_swapbuffers.c b/src/mesa/drivers/dri/intel/intel_swapbuffers.c
deleted file mode 100644
index 7d035b9..0000000
--- a/src/mesa/drivers/dri/intel/intel_swapbuffers.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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.
- * 
- **************************************************************************/
-
-#include "intel_blit.h"
-#include "intel_buffers.h"
-#include "intel_swapbuffers.h"
-#include "intel_fbo.h"
-#include "intel_batchbuffer.h"
-#include "drirenderbuffer.h"
-#include "vblank.h"
-#include "i915_drm.h"
-
-
-
-/*
- * Correct a drawablePrivate's set of vblank flags WRT the current context.
- * When considering multiple crtcs.
- */
-GLuint
-intelFixupVblank(struct intel_context *intel, __DRIdrawablePrivate *dPriv)
-{
-   if (!intel->intelScreen->driScrnPriv->dri2.enabled &&
-       intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
-      volatile drm_i915_sarea_t *sarea = intel->sarea;
-      drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
-				   .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h };
-      drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y,
-				     .x2 = sarea->planeA_x + sarea->planeA_w,
-				     .y2 = sarea->planeA_y + sarea->planeA_h };
-      drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y,
-				     .x2 = sarea->planeB_x + sarea->planeB_w,
-				     .y2 = sarea->planeB_y + sarea->planeB_h };
-      GLint areaA = driIntersectArea( drw_rect, planeA_rect );
-      GLint areaB = driIntersectArea( drw_rect, planeB_rect );
-      GLuint flags = dPriv->vblFlags;
-
-      /* Update vblank info
-       */
-      if (areaB > areaA || (areaA == areaB && areaB > 0)) {
-	 flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY;
-      } else {
-	 flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
-      }
-
-      /* Do the stupid test: Is one of them actually disabled?
-       */
-      if (sarea->planeA_w == 0 || sarea->planeA_h == 0) {
-	 flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY;
-      } else if (sarea->planeB_w == 0 || sarea->planeB_h == 0) {
-	 flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
-      }
-
-      return flags;
-   } else {
-      return dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
-   }
-}
-
-
-/**
- * Called from driSwapBuffers()
- */
-void
-intelSwapBuffers(__DRIdrawablePrivate * dPriv)
-{
-   __DRIscreenPrivate *psp = dPriv->driScreenPriv;
-
-   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
-      GET_CURRENT_CONTEXT(ctx);
-      struct intel_context *intel;
-
-      if (ctx == NULL)
-	 return;
-
-      intel = intel_context(ctx);
-
-      if (ctx->Visual.doubleBufferMode) {
-	 GLboolean missed_target;
-	 struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
-	 int64_t ust;
-         
-	 _mesa_notifySwapBuffers(ctx);  /* flush pending rendering comands */
-
-	/*
-	 * The old swapping ioctl was incredibly racy, just wait for vblank
-	 * and do the swap ourselves.
-	 */
-	 driWaitForVBlank(dPriv, &missed_target);
-
-	 /*
-	  * Update each buffer's vbl_pending so we don't get too out of
-	  * sync
-	  */
-	 intel_get_renderbuffer(&intel_fb->Base,
-		   		BUFFER_BACK_LEFT)->vbl_pending = dPriv->vblSeq;
-         intel_get_renderbuffer(&intel_fb->Base,
-		   		BUFFER_FRONT_LEFT)->vbl_pending = dPriv->vblSeq;
-
-	 intelCopyBuffer(dPriv, NULL);
-
-	 intel_fb->swap_count++;
-	 (*psp->systemTime->getUST) (&ust);
-	 if (missed_target) {
-	    intel_fb->swap_missed_count++;
-	    intel_fb->swap_missed_ust = ust - intel_fb->swap_ust;
-	 }
-
-	 intel_fb->swap_ust = ust;
-      }
-      drmCommandNone(intel->driFd, DRM_I915_GEM_THROTTLE);
-   }
-   else {
-      /* XXX this shouldn't be an error but we can't handle it for now */
-      fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
-   }
-}
-
-
-/**
- * Called from driCopySubBuffer()
- */
-void
-intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
-{
-   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
-      struct intel_context *intel =
-         (struct intel_context *) dPriv->driContextPriv->driverPrivate;
-      GLcontext *ctx = &intel->ctx;
-
-      if (ctx->Visual.doubleBufferMode) {
-         drm_clip_rect_t rect;
-         rect.x1 = x + dPriv->x;
-         rect.y1 = (dPriv->h - y - h) + dPriv->y;
-         rect.x2 = rect.x1 + w;
-         rect.y2 = rect.y1 + h;
-         _mesa_notifySwapBuffers(ctx);  /* flush pending rendering comands */
-         intelCopyBuffer(dPriv, &rect);
-      }
-   }
-   else {
-      /* XXX this shouldn't be an error but we can't handle it for now */
-      fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
-   }
-}
-
-
-/**
- * This will be called whenever the currently bound window is moved/resized.
- * XXX: actually, it seems to NOT be called when the window is only moved (BP).
- */
-void
-intelWindowMoved(struct intel_context *intel)
-{
-   GLcontext *ctx = &intel->ctx;
-   __DRIdrawablePrivate *dPriv = intel->driDrawable;
-   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
-
-   if (!intel->intelScreen->driScrnPriv->dri2.enabled &&
-       intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
-      GLuint flags = intelFixupVblank(intel, dPriv);
-
-      /* Check to see if we changed pipes */
-      if (flags != dPriv->vblFlags && dPriv->vblFlags &&
-	  !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) {
-	 int64_t count;
-	 drmVBlank vbl;
-	 int i;
-
-	 /*
-	  * Deal with page flipping
-	  */
-	 vbl.request.type = DRM_VBLANK_ABSOLUTE;
-
-	 if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
-	    vbl.request.type |= DRM_VBLANK_SECONDARY;
-	 }
-
-	 for (i = 0; i < 2; i++) {
-	    if (!intel_fb->color_rb[i] ||
-		(intel_fb->vbl_waited - intel_fb->color_rb[i]->vbl_pending) <=
-		(1<<23))
-	       continue;
-
-	    vbl.request.sequence = intel_fb->color_rb[i]->vbl_pending;
-	    drmWaitVBlank(intel->driFd, &vbl);
-	 }
-
-	 /*
-	  * Update msc_base from old pipe
-	  */
-	 driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count);
-	 dPriv->msc_base = count;
-	 /*
-	  * Then get new vblank_base and vblSeq values
-	  */
-	 dPriv->vblFlags = flags;
-	 driGetCurrentVBlank(dPriv);
-	 dPriv->vblank_base = dPriv->vblSeq;
-
-	 intel_fb->vbl_waited = dPriv->vblSeq;
-
-	 for (i = 0; i < 2; i++) {
-	    if (intel_fb->color_rb[i])
-	       intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_waited;
-	 }
-      }
-   } else {
-      dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY;
-   }
-
-   /* Update Mesa's notion of window size */
-   driUpdateFramebufferSize(ctx, dPriv);
-   intel_fb->Base.Initialized = GL_TRUE; /* XXX remove someday */
-
-   /* Update hardware scissor */
-   if (ctx->Driver.Scissor != NULL) {
-      ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
-			  ctx->Scissor.Width, ctx->Scissor.Height);
-   }
-
-   /* Re-calculate viewport related state */
-   if (ctx->Driver.DepthRange != NULL)
-      ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far );
-}
diff --git a/src/mesa/drivers/dri/intel/intel_swapbuffers.h b/src/mesa/drivers/dri/intel/intel_swapbuffers.h
deleted file mode 100644
index 75bb624..0000000
--- a/src/mesa/drivers/dri/intel/intel_swapbuffers.h
+++ /dev/null
@@ -1,52 +0,0 @@
-
-/**************************************************************************
- * 
- * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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.
- * 
- **************************************************************************/
-
-#ifndef INTEL_SWAPBUFFERS_H
-#define INTEL_SWAPBUFFERS_H
-
-#include "dri_util.h"
-#include "drm.h"
-
-struct intel_context;
-struct intel_framebuffer;
-
-
-extern void
-intelSwapBuffers(__DRIdrawablePrivate * dPriv);
-
-extern void
-intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h);
-
-extern GLuint
-intelFixupVblank(struct intel_context *intel, __DRIdrawablePrivate *dPriv);
-
-extern void
-intelWindowMoved(struct intel_context *intel);
-
-
-#endif /* INTEL_SWAPBUFFERS_H */
diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
index bb21dd5..d8e7109 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c
@@ -109,8 +109,7 @@
       return GL_FALSE;
    }
 
-   intelFlush(ctx);
-   LOCK_HARDWARE(intel);
+   /* intelFlush(ctx); */
    {
       drm_intel_bo *dst_bo = intel_region_buffer(intel,
 						 intelImage->mt->region,
@@ -132,13 +131,12 @@
 
       /* Can't blit to tiled buffers with non-tile-aligned offset. */
       if (intelImage->mt->region->tiling == I915_TILING_Y) {
-	 UNLOCK_HARDWARE(intel);
 	 return GL_FALSE;
       }
 
       if (ctx->ReadBuffer->Name == 0) {
 	 /* reading from a window, adjust x, y */
-	 const __DRIdrawablePrivate *dPriv = intel->driReadDrawable;
+	 const __DRIdrawable *dPriv = intel->driReadDrawable;
 	 y = dPriv->y + (dPriv->h - (y + height));
 	 x += dPriv->x;
 
@@ -160,22 +158,20 @@
 			     intelImage->mt->cpp,
 			     src_pitch,
 			     src->buffer,
-			     src->draw_offset,
+			     0,
 			     src->tiling,
 			     intelImage->mt->pitch,
 			     dst_bo,
 			     0,
 			     intelImage->mt->region->tiling,
-			     x, y, image_x + dstx, image_y + dsty,
+			     src->draw_x + x, src->draw_y + y,
+			     image_x + dstx, image_y + dsty,
 			     width, height,
 			     GL_COPY)) {
-	 UNLOCK_HARDWARE(intel);
 	 return GL_FALSE;
       }
    }
 
-   UNLOCK_HARDWARE(intel);
-
    return GL_TRUE;
 }
 
@@ -221,6 +217,8 @@
    return;
 
  fail:
+   if (INTEL_DEBUG & DEBUG_FALLBACKS)
+      fprintf(stderr, "%s - fallback to swrast\n", __FUNCTION__);
    _mesa_meta_CopyTexImage1D(ctx, target, level, internalFormat, x, y,
                              width, border);
 }
@@ -268,6 +266,8 @@
    return;
 
  fail:
+   if (INTEL_DEBUG & DEBUG_FALLBACKS)
+      fprintf(stderr, "%s - fallback to swrast\n", __FUNCTION__);
    _mesa_meta_CopyTexImage2D(ctx, target, level, internalFormat, x, y,
                              width, height, border);
 }
@@ -292,6 +292,8 @@
    if (!do_copy_texsubimage(intel_context(ctx), target,
                             intel_texture_image(texImage),
                             internalFormat, xoffset, 0, x, y, width, 1)) {
+      if (INTEL_DEBUG & DEBUG_FALLBACKS)
+         fprintf(stderr, "%s - fallback to swrast\n", __FUNCTION__);
       _mesa_meta_CopyTexSubImage1D(ctx, target, level, xoffset, x, y, width);
    }
 }
@@ -317,8 +319,8 @@
                             internalFormat,
                             xoffset, yoffset, x, y, width, height)) {
 
-      DBG("%s - fallback to _mesa_meta_CopyTexSubImage2D\n", __FUNCTION__);
-
+      if (INTEL_DEBUG & DEBUG_FALLBACKS)
+         fprintf(stderr, "%s - fallback to swrast\n", __FUNCTION__);
       _mesa_meta_CopyTexSubImage2D(ctx, target, level,
                                    xoffset, yoffset, x, y, width, height);
    }
diff --git a/src/mesa/drivers/dri/intel/intel_tex_format.c b/src/mesa/drivers/dri/intel/intel_tex_format.c
index f37a545..a7c6c45 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_format.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_format.c
@@ -50,8 +50,7 @@
       if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) {
          return MESA_FORMAT_RGB565;
       }
-      /* XXX use MESA_FORMAT_XRGB8888 someday */
-      return do32bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_RGB565;
+      return do32bpt ? MESA_FORMAT_XRGB8888 : MESA_FORMAT_RGB565;
 
    case GL_RGBA8:
    case GL_RGB10_A2:
@@ -70,8 +69,7 @@
    case GL_RGB10:
    case GL_RGB12:
    case GL_RGB16:
-      /* XXX use MESA_FORMAT_XRGB8888 someday */
-      return MESA_FORMAT_ARGB8888;
+      return MESA_FORMAT_XRGB8888;
 
    case GL_RGB5:
    case GL_RGB4:
@@ -95,14 +93,20 @@
    case GL_COMPRESSED_LUMINANCE:
       return MESA_FORMAT_L8;
 
+   case GL_LUMINANCE12_ALPHA4:
+   case GL_LUMINANCE12_ALPHA12:
+   case GL_LUMINANCE16_ALPHA16:
+#ifndef I915
+      return MESA_FORMAT_AL1616;
+#else
+      /* FALLTHROUGH */
+#endif
+
    case 2:
    case GL_LUMINANCE_ALPHA:
    case GL_LUMINANCE4_ALPHA4:
    case GL_LUMINANCE6_ALPHA2:
    case GL_LUMINANCE8_ALPHA8:
-   case GL_LUMINANCE12_ALPHA4:
-   case GL_LUMINANCE12_ALPHA12:
-   case GL_LUMINANCE16_ALPHA16:
    case GL_COMPRESSED_LUMINANCE_ALPHA:
       return MESA_FORMAT_AL88;
 
@@ -169,13 +173,13 @@
       return MESA_FORMAT_SARGB8;
    case GL_SLUMINANCE_EXT:
    case GL_SLUMINANCE8_EXT:
-      if (IS_G4X(intel->intelScreen->deviceID))
+      if (intel->has_luminance_srgb)
          return MESA_FORMAT_SL8;
       else
          return MESA_FORMAT_SARGB8;
    case GL_SLUMINANCE_ALPHA_EXT:
    case GL_SLUMINANCE8_ALPHA8_EXT:
-      if (IS_G4X(intel->intelScreen->deviceID))
+      if (intel->has_luminance_srgb)
          return MESA_FORMAT_SLA8;
       else
          return MESA_FORMAT_SARGB8;
diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c
index 3412e76..6f41eaf 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_image.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
@@ -115,7 +115,8 @@
     */
    if ((intelObj->base.MinFilter == GL_NEAREST ||
         intelObj->base.MinFilter == GL_LINEAR) &&
-       intelImage->level == firstLevel) {
+       intelImage->level == firstLevel &&
+       (intel->gen < 4 || firstLevel == 0)) {
       lastLevel = firstLevel;
    }
    else {
@@ -234,7 +235,6 @@
 
    if (drm_intel_bo_references(intel->batch->buf, dst_buffer))
       intelFlush(&intel->ctx);
-   LOCK_HARDWARE(intel);
    {
       dri_bo *src_buffer = intel_bufferobj_buffer(intel, pbo, INTEL_READ);
 
@@ -244,11 +244,9 @@
 			     dst_stride, dst_buffer, 0, GL_FALSE,
 			     0, 0, dst_x, dst_y, width, height,
 			     GL_COPY)) {
-	 UNLOCK_HARDWARE(intel);
 	 return GL_FALSE;
       }
    }
-   UNLOCK_HARDWARE(intel);
 
    return GL_TRUE;
 }
@@ -368,8 +366,7 @@
        intelObj->mt->first_level == level &&
        intelObj->mt->last_level == level &&
        intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB &&
-       !intel_miptree_match_image(intelObj->mt, &intelImage->base,
-                                  intelImage->face, intelImage->level)) {
+       !intel_miptree_match_image(intelObj->mt, &intelImage->base)) {
 
       DBG("release it\n");
       intel_miptree_release(intel, &intelObj->mt);
@@ -386,8 +383,7 @@
    assert(!intelImage->mt);
 
    if (intelObj->mt &&
-       intel_miptree_match_image(intelObj->mt, &intelImage->base,
-                                 intelImage->face, intelImage->level)) {
+       intel_miptree_match_image(intelObj->mt, &intelImage->base)) {
 
       intel_miptree_reference(&intelImage->mt, intelObj->mt);
       assert(intelImage->mt);
@@ -470,8 +466,6 @@
 					   pixels, unpack, "glTexImage");
    }
 
-   LOCK_HARDWARE(intel);
-
    if (intelImage->mt) {
       if (pixels != NULL) {
 	 /* Flush any queued rendering with the texture before mapping. */
@@ -552,8 +546,6 @@
          intel_miptree_image_unmap(intel, intelImage->mt);
       texImage->Data = NULL;
    }
-
-   UNLOCK_HARDWARE(intel);
 }
 
 
@@ -733,27 +725,27 @@
 		   GLint glx_texture_format,
 		   __DRIdrawable *dPriv)
 {
-   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
+   struct gl_framebuffer *fb = dPriv->driverPrivate;
    struct intel_context *intel = pDRICtx->driverPrivate;
+   GLcontext *ctx = &intel->ctx;
    struct intel_texture_object *intelObj;
    struct intel_texture_image *intelImage;
    struct intel_mipmap_tree *mt;
    struct intel_renderbuffer *rb;
-   struct gl_texture_unit *texUnit;
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
    int level = 0, internalFormat;
 
-   texUnit = &intel->ctx.Texture.Unit[intel->ctx.Texture.CurrentUnit];
-   texObj = _mesa_select_tex_object(&intel->ctx, texUnit, target);
+   texObj = _mesa_get_current_tex_object(ctx, target);
    intelObj = intel_texture_object(texObj);
 
    if (!intelObj)
       return;
 
-   intel_update_renderbuffers(pDRICtx, dPriv);
+   if (!dPriv->validBuffers)
+      intel_update_renderbuffers(pDRICtx, dPriv);
 
-   rb = intel_fb->color_rb[0];
+   rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
    /* If the region isn't set, then intel_update_renderbuffers was unable
     * to get the buffers for the drawable.
     */
@@ -797,8 +789,7 @@
    texImage->RowStride = rb->region->pitch;
    intel_miptree_reference(&intelImage->mt, intelObj->mt);
 
-   if (!intel_miptree_match_image(intelObj->mt, &intelImage->base,
-				  intelImage->face, intelImage->level)) {
+   if (!intel_miptree_match_image(intelObj->mt, &intelImage->base)) {
 	   fprintf(stderr, "miptree doesn't match image\n");
    }
 
diff --git a/src/mesa/drivers/dri/intel/intel_tex_obj.h b/src/mesa/drivers/dri/intel/intel_tex_obj.h
index 5a93461..3ad10d3 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_obj.h
+++ b/src/mesa/drivers/dri/intel/intel_tex_obj.h
@@ -66,6 +66,7 @@
     * Else there is no image data.
     */
    struct intel_mipmap_tree *mt;
+   GLboolean used_as_render_target;
 };
 
 static INLINE struct intel_texture_object *
diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
index 1f68208..7f1dc89 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
@@ -72,8 +72,6 @@
    if (!pixels)
       return;
 
-   LOCK_HARDWARE(intel);
-
    /* Map buffer if necessary.  Need to lock to prevent other contexts
     * from uploading the buffer under us.
     */
@@ -129,8 +127,6 @@
       intel_miptree_image_unmap(intel, intelImage->mt);
       texImage->Data = NULL;
    }
-
-   UNLOCK_HARDWARE(intel);
 }
 
 
diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c
index 5049939..c9a24ac 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_validate.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c
@@ -42,7 +42,7 @@
          firstLevel = lastLevel = tObj->BaseLevel;
       }
       else {
-	 if (!IS_9XX(intel->intelScreen->deviceID)) {
+	 if (intel->gen == 2) {
 	    firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
 	    firstLevel = MAX2(firstLevel, tObj->BaseLevel);
 	    firstLevel = MIN2(firstLevel, tObj->BaseLevel + baseImage->MaxLog2);
@@ -138,8 +138,7 @@
    /* What levels must the tree include at a minimum?
     */
    intel_calculate_first_last_level(intel, intelObj);
-   firstImage =
-      intel_texture_image(intelObj->base.Image[0][intelObj->firstLevel]);
+   firstImage = intel_texture_image(tObj->Image[0][intelObj->firstLevel]);
 
    /* Fallback case:
     */
@@ -223,8 +222,13 @@
             intel_texture_image(intelObj->base.Image[face][i]);
 
          /* Need to import images in main memory or held in other trees.
+	  * If it's a render target, then its data isn't needed to be in
+	  * the object tree (otherwise we'd be FBO incomplete), and we need
+	  * to keep track of the image's MT as needing to be pulled in still,
+	  * or we'll lose the rendering that's done to it.
           */
-         if (intelObj->mt != intelImage->mt) {
+         if (intelObj->mt != intelImage->mt &&
+	     !intelImage->used_as_render_target) {
             copy_image_data_to_tree(intel, intelObj, intelImage);
          }
       }
diff --git a/src/mesa/drivers/dri/mach64/mach64_context.c b/src/mesa/drivers/dri/mach64/mach64_context.c
index 2bca293..3b4ef7f 100644
--- a/src/mesa/drivers/dri/mach64/mach64_context.c
+++ b/src/mesa/drivers/dri/mach64/mach64_context.c
@@ -89,11 +89,11 @@
 /* Create the device specific context.
   */
 GLboolean mach64CreateContext( const __GLcontextModes *glVisual,
-			       __DRIcontextPrivate *driContextPriv,
+			       __DRIcontext *driContextPriv,
                                void *sharedContextPrivate )
 {
    GLcontext *ctx, *shareCtx;
-   __DRIscreenPrivate *driScreen = driContextPriv->driScreenPriv;
+   __DRIscreen *driScreen = driContextPriv->driScreenPriv;
    struct dd_function_table functions;
    mach64ContextPtr mmesa;
    mach64ScreenPtr mach64Screen;
@@ -260,7 +260,7 @@
 
 /* Destroy the device specific context.
  */
-void mach64DestroyContext( __DRIcontextPrivate *driContextPriv  )
+void mach64DestroyContext( __DRIcontext *driContextPriv  )
 {
    mach64ContextPtr mmesa = (mach64ContextPtr) driContextPriv->driverPrivate;
 
@@ -307,9 +307,9 @@
  * buffer `b'.
  */
 GLboolean
-mach64MakeCurrent( __DRIcontextPrivate *driContextPriv,
-                 __DRIdrawablePrivate *driDrawPriv,
-                 __DRIdrawablePrivate *driReadPriv )
+mach64MakeCurrent( __DRIcontext *driContextPriv,
+                 __DRIdrawable *driDrawPriv,
+                 __DRIdrawable *driReadPriv )
 {
    if ( driContextPriv ) {
       GET_CURRENT_CONTEXT(ctx);
@@ -352,7 +352,7 @@
 /* Force the context `c' to be unbound from its buffer.
  */
 GLboolean
-mach64UnbindContext( __DRIcontextPrivate *driContextPriv )
+mach64UnbindContext( __DRIcontext *driContextPriv )
 {
    return GL_TRUE;
 }
diff --git a/src/mesa/drivers/dri/mach64/mach64_context.h b/src/mesa/drivers/dri/mach64/mach64_context.h
index 8547516..18fc859 100644
--- a/src/mesa/drivers/dri/mach64/mach64_context.h
+++ b/src/mesa/drivers/dri/mach64/mach64_context.h
@@ -232,9 +232,9 @@
 
    /* Mirrors of some DRI state
     */
-   __DRIcontextPrivate	*driContext;	/* DRI context */
-   __DRIscreenPrivate	*driScreen;	/* DRI screen */
-   __DRIdrawablePrivate	*driDrawable;	/* DRI drawable bound to this ctx */
+   __DRIcontext	*driContext;	/* DRI context */
+   __DRIscreen	*driScreen;	/* DRI screen */
+   __DRIdrawable	*driDrawable;	/* DRI drawable bound to this ctx */
 
    unsigned int lastStamp;		/* mirror driDrawable->lastStamp */
 
@@ -274,16 +274,16 @@
 
 
 extern GLboolean mach64CreateContext( const __GLcontextModes *glVisual,
-				      __DRIcontextPrivate *driContextPriv,
+				      __DRIcontext *driContextPriv,
                                       void *sharedContextPrivate );
 
-extern void mach64DestroyContext( __DRIcontextPrivate * );
+extern void mach64DestroyContext( __DRIcontext * );
 
-extern GLboolean mach64MakeCurrent( __DRIcontextPrivate *driContextPriv,
-                                    __DRIdrawablePrivate *driDrawPriv,
-                                    __DRIdrawablePrivate *driReadPriv );
+extern GLboolean mach64MakeCurrent( __DRIcontext *driContextPriv,
+                                    __DRIdrawable *driDrawPriv,
+                                    __DRIdrawable *driReadPriv );
 
-extern GLboolean mach64UnbindContext( __DRIcontextPrivate *driContextPriv );
+extern GLboolean mach64UnbindContext( __DRIcontext *driContextPriv );
 
 /* ================================================================
  * Byte ordering
diff --git a/src/mesa/drivers/dri/mach64/mach64_ioctl.c b/src/mesa/drivers/dri/mach64/mach64_ioctl.c
index ef5c062..03587c4 100644
--- a/src/mesa/drivers/dri/mach64/mach64_ioctl.c
+++ b/src/mesa/drivers/dri/mach64/mach64_ioctl.c
@@ -279,7 +279,7 @@
 
 /* Copy the back color buffer to the front color buffer.
  */
-void mach64CopyBuffer( __DRIdrawablePrivate *dPriv )
+void mach64CopyBuffer( __DRIdrawable *dPriv )
 {
    mach64ContextPtr mmesa;
    GLint nbox, i, ret;
@@ -668,7 +668,7 @@
 static void mach64DDClear( GLcontext *ctx, GLbitfield mask )
 {
    mach64ContextPtr mmesa = MACH64_CONTEXT( ctx );
-   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+   __DRIdrawable *dPriv = mmesa->driDrawable;
    drm_mach64_clear_t clear;
    GLuint flags = 0;
    GLint i;
diff --git a/src/mesa/drivers/dri/mach64/mach64_ioctl.h b/src/mesa/drivers/dri/mach64/mach64_ioctl.h
index 6ef9bc0..1ffda19 100644
--- a/src/mesa/drivers/dri/mach64/mach64_ioctl.h
+++ b/src/mesa/drivers/dri/mach64/mach64_ioctl.h
@@ -78,7 +78,7 @@
 				  GLint offset, GLint pitch, GLint format,
 				  GLint x, GLint y, GLint width, GLint height );
 
-extern void mach64CopyBuffer( __DRIdrawablePrivate *dPriv );
+extern void mach64CopyBuffer( __DRIdrawable *dPriv );
 #if ENABLE_PERF_BOXES
 extern void mach64PerformanceCounters( mach64ContextPtr mmesa );
 extern void mach64PerformanceBoxesLocked( mach64ContextPtr mmesa );
diff --git a/src/mesa/drivers/dri/mach64/mach64_lock.c b/src/mesa/drivers/dri/mach64/mach64_lock.c
index d018ba4..8653c77 100644
--- a/src/mesa/drivers/dri/mach64/mach64_lock.c
+++ b/src/mesa/drivers/dri/mach64/mach64_lock.c
@@ -51,8 +51,8 @@
  */
 void mach64GetLock( mach64ContextPtr mmesa, GLuint flags )
 {
-   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
-   __DRIscreenPrivate *sPriv = mmesa->driScreen;
+   __DRIdrawable *dPriv = mmesa->driDrawable;
+   __DRIscreen *sPriv = mmesa->driScreen;
    drm_mach64_sarea_t *sarea = mmesa->sarea;
    int i;
 
diff --git a/src/mesa/drivers/dri/mach64/mach64_native_vb.c b/src/mesa/drivers/dri/mach64/mach64_native_vb.c
index 99f1a14..816682e 100644
--- a/src/mesa/drivers/dri/mach64/mach64_native_vb.c
+++ b/src/mesa/drivers/dri/mach64/mach64_native_vb.c
@@ -207,19 +207,19 @@
    LOCALVARS
    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
 
-   if (VB->ColorPtr[1]) {
-      assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat));
+   if (VB->BackfaceColorPtr) {
+      assert(VB->BackfaceColorPtr->stride == 4 * sizeof(GLfloat));
       
       INTERP_4F( t,
-		    GET_COLOR(VB->ColorPtr[1], dst),
-		    GET_COLOR(VB->ColorPtr[1], out),
-		    GET_COLOR(VB->ColorPtr[1], in) );
+		 GET_COLOR(VB->BackfaceColorPtr, dst),
+		 GET_COLOR(VB->BackfaceColorPtr, out),
+		 GET_COLOR(VB->BackfaceColorPtr, in) );
 
-      if (VB->SecondaryColorPtr[1]) {
+      if (VB->BackfaceSecondaryColorPtr) {
 	 INTERP_3F( t,
-		       GET_COLOR(VB->SecondaryColorPtr[1], dst),
-		       GET_COLOR(VB->SecondaryColorPtr[1], out),
-		       GET_COLOR(VB->SecondaryColorPtr[1], in) );
+		    GET_COLOR(VB->BackfaceSecondaryColorPtr, dst),
+		    GET_COLOR(VB->BackfaceSecondaryColorPtr, out),
+		    GET_COLOR(VB->BackfaceSecondaryColorPtr, in) );
       }
    }
 
@@ -236,13 +236,13 @@
    LOCALVARS
       struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
 
-   if (VB->ColorPtr[1]) {
-      COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst), 
-		GET_COLOR(VB->ColorPtr[1], src) );
+   if (VB->BackfaceColorPtr) {
+      COPY_4FV( GET_COLOR(VB->BackfaceColorPtr, dst),
+		GET_COLOR(VB->BackfaceColorPtr, src) );
 
-      if (VB->SecondaryColorPtr[1]) {
-	 COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst), 
-		   GET_COLOR(VB->SecondaryColorPtr[1], src) );
+      if (VB->BackfaceSecondaryColorPtr) {
+	 COPY_4FV( GET_COLOR(VB->BackfaceSecondaryColorPtr, dst),
+		   GET_COLOR(VB->BackfaceSecondaryColorPtr, src) );
       }
    }
 
diff --git a/src/mesa/drivers/dri/mach64/mach64_native_vbtmp.h b/src/mesa/drivers/dri/mach64/mach64_native_vbtmp.h
index 684f2ac..6e5fa35 100644
--- a/src/mesa/drivers/dri/mach64/mach64_native_vbtmp.h
+++ b/src/mesa/drivers/dri/mach64/mach64_native_vbtmp.h
@@ -103,10 +103,10 @@
 #if DO_TEX1
    {
       const GLuint t1 = GET_TEXSOURCE(1);
-      tc1 = VB->TexCoordPtr[t1]->data;
-      tc1_stride = VB->TexCoordPtr[t1]->stride;
+      tc1 = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->data;
+      tc1_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->stride;
 #if DO_PTEX
-      tc1_size = VB->TexCoordPtr[t1]->size;
+      tc1_size = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->size;
 #endif
    }
 #endif
@@ -114,18 +114,18 @@
 #if DO_TEX0
    {
       const GLuint t0 = GET_TEXSOURCE(0);
-      tc0 = VB->TexCoordPtr[t0]->data;
-      tc0_stride = VB->TexCoordPtr[t0]->stride;
+      tc0 = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->data;
+      tc0_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->stride;
 #if DO_PTEX
-      tc0_size = VB->TexCoordPtr[t0]->size;
+      tc0_size = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->size;
 #endif
    }
 #endif
 
 #if DO_SPEC
-   if (VB->SecondaryColorPtr[0]) {
-      spec = VB->SecondaryColorPtr[0]->data;
-      spec_stride = VB->SecondaryColorPtr[0]->stride;
+   if (VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
+      spec = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->data;
+      spec_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->stride;
    } else {
       spec = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
       spec_stride = 0;
@@ -133,9 +133,9 @@
 #endif
 
 #if DO_FOG
-   if (VB->FogCoordPtr) {
-      fog = VB->FogCoordPtr->data;
-      fog_stride = VB->FogCoordPtr->stride;
+   if (VB->AttribPtr[_TNL_ATTRIB_FOG]) {
+      fog = VB->AttribPtr[_TNL_ATTRIB_FOG]->data;
+      fog_stride = VB->AttribPtr[_TNL_ATTRIB_FOG]->stride;
    } else {
       static GLfloat tmp[4] = {0, 0, 0, 0};
       fog = &tmp;
@@ -144,8 +144,8 @@
 #endif
 
 #if DO_RGBA
-   col = VB->ColorPtr[0]->data;
-   col_stride = VB->ColorPtr[0]->stride;
+   col = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;
+   col_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride;
 #endif
 
    coord = VB->NdcPtr->data;
@@ -319,8 +319,8 @@
 
    /* Force 'missing' texcoords to something valid.
     */
-   if (DO_TEX1 && VB->TexCoordPtr[0] == 0)
-      VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
+   if (DO_TEX1 && VB->AttribPtr[_TNL_ATTRIB_TEX0] == 0)
+      VB->AttribPtr[_TNL_ATTRIB_TEX0] = VB->AttribPtr[_TNL_ATTRIB_TEX1];
 
    if (DO_PTEX)
       return GL_TRUE;
@@ -328,12 +328,12 @@
    /* No hardware support for projective texture.  Can fake it for
     * TEX0 only.
     */
-   if ((DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4)) {
+   if ((DO_TEX1 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(1)]->size == 4)) {
       PTEX_FALLBACK();
       return GL_FALSE;
    }
 
-   if (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4) {
+   if (DO_TEX0 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(0)]->size == 4) {
       if (DO_TEX1) {
 	 PTEX_FALLBACK();
       }
diff --git a/src/mesa/drivers/dri/mach64/mach64_screen.c b/src/mesa/drivers/dri/mach64/mach64_screen.c
index 3b19cf5..1ed3b0b 100644
--- a/src/mesa/drivers/dri/mach64/mach64_screen.c
+++ b/src/mesa/drivers/dri/mach64/mach64_screen.c
@@ -68,7 +68,7 @@
 #endif
 
 static const __DRIconfig **
-mach64FillInModes( __DRIscreenPrivate *psp,
+mach64FillInModes( __DRIscreen *psp,
 		   unsigned pixel_bits, unsigned depth_bits,
 		   unsigned stencil_bits, GLboolean have_back_buffer )
 {
@@ -144,7 +144,7 @@
 /* Create the device specific screen private data struct.
  */
 static mach64ScreenRec *
-mach64CreateScreen( __DRIscreenPrivate *sPriv )
+mach64CreateScreen( __DRIscreen *sPriv )
 {
    mach64ScreenPtr mach64Screen;
    ATIDRIPtr serverInfo = (ATIDRIPtr)sPriv->pDevPriv;
@@ -272,7 +272,7 @@
 /* Destroy the device specific screen private data struct.
  */
 static void
-mach64DestroyScreen( __DRIscreenPrivate *driScreen )
+mach64DestroyScreen( __DRIscreen *driScreen )
 {
    mach64ScreenRec *mach64Screen = (mach64ScreenRec *) driScreen->private;
 
@@ -299,8 +299,8 @@
  * data.
  */
 static GLboolean
-mach64CreateBuffer( __DRIscreenPrivate *driScrnPriv,
-		    __DRIdrawablePrivate *driDrawPriv,
+mach64CreateBuffer( __DRIscreen *driScrnPriv,
+		    __DRIdrawable *driDrawPriv,
 		    const __GLcontextModes *mesaVis,
 		    GLboolean isPixmap )
 {
@@ -370,7 +370,7 @@
 
 
 static void
-mach64DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+mach64DestroyBuffer(__DRIdrawable *driDrawPriv)
 {
    _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
 }
@@ -378,7 +378,7 @@
 
 /* Copy the back color buffer to the front color buffer */
 static void
-mach64SwapBuffers(__DRIdrawablePrivate *dPriv)
+mach64SwapBuffers(__DRIdrawable *dPriv)
 {
    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
       mach64ContextPtr mmesa;
@@ -400,7 +400,7 @@
 /* Initialize the driver specific screen private data.
  */
 static GLboolean
-mach64InitDriver( __DRIscreenPrivate *driScreen )
+mach64InitDriver( __DRIscreen *driScreen )
 {
    driScreen->private = (void *) mach64CreateScreen( driScreen );
 
@@ -420,7 +420,7 @@
  * \return the __GLcontextModes supported by this driver
  */
 static const __DRIconfig **
-mach64InitScreen(__DRIscreenPrivate *psp)
+mach64InitScreen(__DRIscreen *psp)
 {
    static const __DRIversion ddx_expected = { 6, 4, 0 };
    static const __DRIversion dri_expected = { 4, 0, 0 };
@@ -457,3 +457,9 @@
    .SwapBuffersMSC  = NULL
 };
 
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driLegacyExtension.base,
+    NULL
+};
diff --git a/src/mesa/drivers/dri/mach64/mach64_screen.h b/src/mesa/drivers/dri/mach64/mach64_screen.h
index be5e29a..1966809 100644
--- a/src/mesa/drivers/dri/mach64/mach64_screen.h
+++ b/src/mesa/drivers/dri/mach64/mach64_screen.h
@@ -70,7 +70,7 @@
 
    drmBufMapPtr buffers;
 
-   __DRIscreenPrivate *driScreen;
+   __DRIscreen *driScreen;
 
    driOptionCache optionCache;
 
diff --git a/src/mesa/drivers/dri/mach64/mach64_span.c b/src/mesa/drivers/dri/mach64/mach64_span.c
index 500319e..b4ba2a4 100644
--- a/src/mesa/drivers/dri/mach64/mach64_span.c
+++ b/src/mesa/drivers/dri/mach64/mach64_span.c
@@ -40,8 +40,8 @@
 
 #define LOCAL_VARS							\
    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);			\
-   __DRIscreenPrivate *sPriv = mmesa->driScreen;			\
-   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;			\
+   __DRIscreen *sPriv = mmesa->driScreen;			\
+   __DRIdrawable *dPriv = mmesa->driDrawable;			\
    driRenderbuffer *drb = (driRenderbuffer *) rb;			\
    GLuint height = dPriv->h;						\
    GLushort p;								\
@@ -49,8 +49,8 @@
 
 #define LOCAL_DEPTH_VARS						\
    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);			\
-   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;			\
-   __DRIscreenPrivate *driScreen = mmesa->driScreen;			\
+   __DRIdrawable *dPriv = mmesa->driDrawable;			\
+   __DRIscreen *driScreen = mmesa->driScreen;			\
    driRenderbuffer *drb = (driRenderbuffer *) rb;			\
    GLuint height = dPriv->h;						\
    char *buf = (char *)(driScreen->pFB + drb->offset +			\
diff --git a/src/mesa/drivers/dri/mach64/mach64_state.c b/src/mesa/drivers/dri/mach64/mach64_state.c
index 3a02318..df7cbc8 100644
--- a/src/mesa/drivers/dri/mach64/mach64_state.c
+++ b/src/mesa/drivers/dri/mach64/mach64_state.c
@@ -388,7 +388,7 @@
    mach64ScreenPtr mach64Screen = mmesa->mach64Screen;
 
    if ( mmesa->driDrawable ) {
-      __DRIdrawablePrivate *drawable = mmesa->driDrawable;
+      __DRIdrawable *drawable = mmesa->driDrawable;
       int x1 = 0;
       int y1 = 0;
       int x2 = drawable->w - 1;
@@ -527,10 +527,10 @@
    /* mach64 can't color mask with alpha blending enabled */
    if ( !ctx->Color.BlendEnabled ) {
       mask = mach64PackColor( mmesa->mach64Screen->cpp,
-			      ctx->Color.ColorMask[RCOMP],
-			      ctx->Color.ColorMask[GCOMP],
-			      ctx->Color.ColorMask[BCOMP],
-			      ctx->Color.ColorMask[ACOMP] );
+			      ctx->Color.ColorMask[0][RCOMP],
+			      ctx->Color.ColorMask[0][GCOMP],
+			      ctx->Color.ColorMask[0][BCOMP],
+			      ctx->Color.ColorMask[0][ACOMP] );
    }
 
    if ( mmesa->setup.dp_write_mask != mask ) {
@@ -689,7 +689,7 @@
 void mach64SetCliprects( GLcontext *ctx, GLenum mode )
 {
    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+   __DRIdrawable *dPriv = mmesa->driDrawable;
 
    switch ( mode ) {
    case GL_FRONT_LEFT:
diff --git a/src/mesa/drivers/dri/mach64/mach64_tex.c b/src/mesa/drivers/dri/mach64/mach64_tex.c
index a757362..6627d3c 100644
--- a/src/mesa/drivers/dri/mach64/mach64_tex.c
+++ b/src/mesa/drivers/dri/mach64/mach64_tex.c
@@ -130,7 +130,7 @@
 
    mach64SetTexWrap( t, texObj->WrapS, texObj->WrapT );
    mach64SetTexFilter( t, texObj->MinFilter, texObj->MagFilter );
-   mach64SetTexBorderColor( t, texObj->BorderColor );
+   mach64SetTexBorderColor( t, texObj->BorderColor.f );
 
    return t;
 }
@@ -470,7 +470,7 @@
 
    case GL_TEXTURE_BORDER_COLOR:
       if ( t->base.bound ) FLUSH_BATCH( mmesa );
-      mach64SetTexBorderColor( t, tObj->BorderColor );
+      mach64SetTexBorderColor( t, tObj->BorderColor.f );
       break;
 
    case GL_TEXTURE_BASE_LEVEL:
@@ -565,7 +565,6 @@
    functions->IsTextureResident		= driIsTextureResident;
 
    functions->UpdateTexturePalette	= NULL;
-   functions->ActiveTexture		= NULL;
 
    driInitTextureFormats();
 }
diff --git a/src/mesa/drivers/dri/mach64/mach64_tris.c b/src/mesa/drivers/dri/mach64/mach64_tris.c
index f2e8e2e..c2a0adf 100644
--- a/src/mesa/drivers/dri/mach64/mach64_tris.c
+++ b/src/mesa/drivers/dri/mach64/mach64_tris.c
@@ -1297,7 +1297,8 @@
 
 #define LOCAL_VARS(n)						\
    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);		\
-   GLuint color[n], spec[n];					\
+   GLuint color[n] = { 0 };					\
+   GLuint spec[n] = { 0 };					\
    GLuint vertex_size = mmesa->vertex_size;			\
    const GLuint xyoffset = 9;					\
    const GLuint coloroffset = 8;				\
diff --git a/src/mesa/drivers/dri/mach64/mach64_vbtmp.h b/src/mesa/drivers/dri/mach64/mach64_vbtmp.h
index 938804a..60bfab8 100644
--- a/src/mesa/drivers/dri/mach64/mach64_vbtmp.h
+++ b/src/mesa/drivers/dri/mach64/mach64_vbtmp.h
@@ -156,53 +156,53 @@
 
    if (DO_TEX3) {
       const GLuint t3 = GET_TEXSOURCE(3);
-      tc3 = VB->TexCoordPtr[t3]->data;
-      tc3_stride = VB->TexCoordPtr[t3]->stride;
+      tc3 = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t3]->data;
+      tc3_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t3]->stride;
       if (DO_PTEX)
-	 tc3_size = VB->TexCoordPtr[t3]->size;
+	 tc3_size = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t3]->size;
    }
 
    if (DO_TEX2) {
       const GLuint t2 = GET_TEXSOURCE(2);
-      tc2 = VB->TexCoordPtr[t2]->data;
-      tc2_stride = VB->TexCoordPtr[t2]->stride;
+      tc2 = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->data;
+      tc2_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->stride;
       if (DO_PTEX)
-	 tc2_size = VB->TexCoordPtr[t2]->size;
+	 tc2_size = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->size;
    }
 
    if (DO_TEX1) {
       const GLuint t1 = GET_TEXSOURCE(1);
-      tc1 = VB->TexCoordPtr[t1]->data;
-      tc1_stride = VB->TexCoordPtr[t1]->stride;
+      tc1 = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->data;
+      tc1_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->stride;
       if (DO_PTEX)
-	 tc1_size = VB->TexCoordPtr[t1]->size;
+	 tc1_size = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->size;
    }
 
    if (DO_TEX0) {
       const GLuint t0 = GET_TEXSOURCE(0);
-      tc0_stride = VB->TexCoordPtr[t0]->stride;
-      tc0 = VB->TexCoordPtr[t0]->data;
+      tc0_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->stride;
+      tc0 = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->data;
       if (DO_PTEX) 
-	 tc0_size = VB->TexCoordPtr[t0]->size;
+	 tc0_size = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->size;
    }
 
    if (DO_RGBA) {
-      col = VB->ColorPtr[0]->data;
-      col_stride = VB->ColorPtr[0]->stride;
+      col = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;
+      col_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride;
    }
 
    if (DO_SPEC) {
-      spec = VB->SecondaryColorPtr[0]->data;
-      spec_stride = VB->SecondaryColorPtr[0]->stride;
+      spec = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->data;
+      spec_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->stride;
    } else {
       spec = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
       spec_stride = 0;
    }
 
    if (DO_FOG) {
-      if (VB->FogCoordPtr) {
-	 fog = VB->FogCoordPtr->data;
-	 fog_stride = VB->FogCoordPtr->stride;
+      if (VB->AttribPtr[_TNL_ATTRIB_FOG]) {
+	 fog = VB->AttribPtr[_TNL_ATTRIB_FOG]->data;
+	 fog_stride = VB->AttribPtr[_TNL_ATTRIB_FOG]->stride;
       } else {
 	 static GLfloat tmp[4] = {0, 0, 0, 0};
 	 fog = &tmp;
@@ -384,8 +384,8 @@
 
    ASSERT(stride == 4);
 
-   col = VB->ColorPtr[0]->data;
-   col_stride = VB->ColorPtr[0]->stride;
+   col = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;
+   col_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride;
 
    /* Pack what's left into a 4-dword vertex.  Color is in a different
     * place, and there is no 'w' coordinate.
@@ -432,8 +432,8 @@
    GLfloat *v = (GLfloat *)dest;
    int i;
 
-   col = VB->ColorPtr[0]->data;
-   col_stride = VB->ColorPtr[0]->stride;
+   col = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;
+   col_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride;
 
    if (start)
       STRIDE_4F(col, col_stride * start);
@@ -473,22 +473,22 @@
 
    /* Force 'missing' texcoords to something valid.
     */
-   if (DO_TEX3 && VB->TexCoordPtr[2] == 0)
-      VB->TexCoordPtr[2] = VB->TexCoordPtr[3];
+   if (DO_TEX3 && VB->AttribPtr[_TNL_ATTRIB_TEX2] == 0)
+      VB->AttribPtr[_TNL_ATTRIB_TEX2] = VB->AttribPtr[_TNL_ATTRIB_TEX3];
 
-   if (DO_TEX2 && VB->TexCoordPtr[1] == 0)
-      VB->TexCoordPtr[1] = VB->TexCoordPtr[2];
+   if (DO_TEX2 && VB->AttribPtr[_TNL_ATTRIB_TEX1] == 0)
+      VB->AttribPtr[_TNL_ATTRIB_TEX1] = VB->AttribPtr[_TNL_ATTRIB_TEX2];
 
-   if (DO_TEX1 && VB->TexCoordPtr[0] == 0)
-      VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
+   if (DO_TEX1 && VB->AttribPtr[_TNL_ATTRIB_TEX0] == 0)
+      VB->AttribPtr[_TNL_ATTRIB_TEX0] = VB->AttribPtr[_TNL_ATTRIB_TEX1];
 
    if (DO_PTEX)
       return GL_TRUE;
    
-   if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) ||
-       (DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) ||
-       (DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4) ||
-       (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4))
+   if ((DO_TEX3 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(3)]->size == 4) ||
+       (DO_TEX2 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(2)]->size == 4) ||
+       (DO_TEX1 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(1)]->size == 4) ||
+       (DO_TEX0 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(0)]->size == 4))
       return GL_FALSE;
 
    return GL_TRUE;
@@ -501,14 +501,14 @@
 
    /* Force 'missing' texcoords to something valid.
     */
-   if (DO_TEX3 && VB->TexCoordPtr[2] == 0)
-      VB->TexCoordPtr[2] = VB->TexCoordPtr[3];
+   if (DO_TEX3 && VB->AttribPtr[_TNL_ATTRIB_TEX2] == 0)
+      VB->AttribPtr[_TNL_ATTRIB_TEX2] = VB->AttribPtr[_TNL_ATTRIB_TEX3];
 
-   if (DO_TEX2 && VB->TexCoordPtr[1] == 0)
-      VB->TexCoordPtr[1] = VB->TexCoordPtr[2];
+   if (DO_TEX2 && VB->AttribPtr[_TNL_ATTRIB_TEX1] == 0)
+      VB->AttribPtr[_TNL_ATTRIB_TEX1] = VB->AttribPtr[_TNL_ATTRIB_TEX2];
 
-   if (DO_TEX1 && VB->TexCoordPtr[0] == 0)
-      VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
+   if (DO_TEX1 && VB->AttribPtr[_TNL_ATTRIB_TEX0] == 0)
+      VB->AttribPtr[_TNL_ATTRIB_TEX0] = VB->AttribPtr[_TNL_ATTRIB_TEX1];
 
    if (DO_PTEX)
       return GL_TRUE;
@@ -516,14 +516,14 @@
    /* No hardware support for projective texture.  Can fake it for
     * TEX0 only.
     */
-   if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) ||
-       (DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) ||
-       (DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4)) {
+   if ((DO_TEX3 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(3)]->size == 4) ||
+       (DO_TEX2 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(2)]->size == 4) ||
+       (DO_TEX1 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(1)]->size == 4)) {
       PTEX_FALLBACK();
       return GL_FALSE;
    }
 
-   if (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4) {
+   if (DO_TEX0 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(0)]->size == 4) {
       if (DO_TEX1 || DO_TEX2 || DO_TEX3) {
 	 PTEX_FALLBACK();
       }
diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c
index 2c7f50c..f835cb8 100644
--- a/src/mesa/drivers/dri/mga/mga_xmesa.c
+++ b/src/mesa/drivers/dri/mga/mga_xmesa.c
@@ -108,7 +108,7 @@
 #endif
 
 static const __DRIconfig **
-mgaFillInModes( __DRIscreenPrivate *psp,
+mgaFillInModes( __DRIscreen *psp,
 		unsigned pixel_bits, unsigned depth_bits,
 		unsigned stencil_bits, GLboolean have_back_buffer )
 {
@@ -190,7 +190,7 @@
 };
 
 static GLboolean
-mgaInitDriver(__DRIscreenPrivate *sPriv)
+mgaInitDriver(__DRIscreen *sPriv)
 {
    mgaScreenPrivate *mgaScreen;
    MGADRIPtr         serverInfo = (MGADRIPtr)sPriv->pDevPriv;
@@ -332,7 +332,7 @@
 
 
 static void
-mgaDestroyScreen(__DRIscreenPrivate *sPriv)
+mgaDestroyScreen(__DRIscreen *sPriv)
 {
    mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *) sPriv->private;
 
@@ -426,14 +426,14 @@
 
 static GLboolean
 mgaCreateContext( const __GLcontextModes *mesaVis,
-                  __DRIcontextPrivate *driContextPriv,
+                  __DRIcontext *driContextPriv,
                   void *sharedContextPrivate )
 {
    int i;
    unsigned   maxlevels;
    GLcontext *ctx, *shareCtx;
    mgaContextPtr mmesa;
-   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
    mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *)sPriv->private;
    drm_mga_sarea_t *saPriv = (drm_mga_sarea_t *)(((char*)sPriv->pSAREA)+
 					      mgaScreen->sarea_priv_offset);
@@ -645,7 +645,7 @@
 }
 
 static void
-mgaDestroyContext(__DRIcontextPrivate *driContextPriv)
+mgaDestroyContext(__DRIcontext *driContextPriv)
 {
    mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
 
@@ -697,8 +697,8 @@
 
 
 static GLboolean
-mgaCreateBuffer( __DRIscreenPrivate *driScrnPriv,
-                 __DRIdrawablePrivate *driDrawPriv,
+mgaCreateBuffer( __DRIscreen *driScrnPriv,
+                 __DRIdrawable *driDrawPriv,
                  const __GLcontextModes *mesaVis,
                  GLboolean isPixmap )
 {
@@ -814,13 +814,13 @@
 
 
 static void
-mgaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+mgaDestroyBuffer(__DRIdrawable *driDrawPriv)
 {
    _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
 }
 
 static void
-mgaSwapBuffers(__DRIdrawablePrivate *dPriv)
+mgaSwapBuffers(__DRIdrawable *dPriv)
 {
    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
       mgaContextPtr mmesa;
@@ -839,7 +839,7 @@
 }
 
 static GLboolean
-mgaUnbindContext(__DRIcontextPrivate *driContextPriv)
+mgaUnbindContext(__DRIcontext *driContextPriv)
 {
    mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
    if (mmesa)
@@ -855,9 +855,9 @@
  * But why are we doing context initialization here???
  */
 static GLboolean
-mgaMakeCurrent(__DRIcontextPrivate *driContextPriv,
-               __DRIdrawablePrivate *driDrawPriv,
-               __DRIdrawablePrivate *driReadPriv)
+mgaMakeCurrent(__DRIcontext *driContextPriv,
+               __DRIdrawable *driDrawPriv,
+               __DRIdrawable *driReadPriv)
 {
    if (driContextPriv) {
       mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
@@ -892,7 +892,7 @@
 
 void mgaGetLock( mgaContextPtr mmesa, GLuint flags )
 {
-   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+   __DRIdrawable *dPriv = mmesa->driDrawable;
    drm_mga_sarea_t *sarea = mmesa->sarea;
    int me = mmesa->hHWContext;
    int i;
@@ -960,7 +960,7 @@
  * Get information about previous buffer swaps.
  */
 static int
-getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
+getSwapInfo( __DRIdrawable *dPriv, __DRIswapInfo * sInfo )
 {
    mgaContextPtr  mmesa;
 
@@ -998,3 +998,10 @@
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
 };
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driLegacyExtension.base,
+    NULL
+};
diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.h b/src/mesa/drivers/dri/mga/mga_xmesa.h
index 07c22bd..aee1460 100644
--- a/src/mesa/drivers/dri/mga/mga_xmesa.h
+++ b/src/mesa/drivers/dri/mga/mga_xmesa.h
@@ -67,7 +67,7 @@
    char *texVirtual[MGA_NR_TEX_HEAPS];
 
 
-   __DRIscreenPrivate *sPriv;
+   __DRIscreen *sPriv;
    drmBufMapPtr  bufs;
 
    drmRegion mmio;
diff --git a/src/mesa/drivers/dri/mga/mgacontext.h b/src/mesa/drivers/dri/mga/mgacontext.h
index 30640a2..4141565 100644
--- a/src/mesa/drivers/dri/mga/mgacontext.h
+++ b/src/mesa/drivers/dri/mga/mgacontext.h
@@ -294,10 +294,10 @@
    drm_context_t hHWContext;
    drm_hw_lock_t *driHwLock;
    int driFd;
-   __DRIdrawablePrivate *driDrawable;
-   __DRIdrawablePrivate *driReadable;
+   __DRIdrawable *driDrawable;
+   __DRIdrawable *driReadable;
 
-   __DRIscreenPrivate *driScreen;
+   __DRIscreen *driScreen;
    struct mga_screen_private_s *mgaScreen;
    drm_mga_sarea_t *sarea;
 
diff --git a/src/mesa/drivers/dri/mga/mgaioctl.c b/src/mesa/drivers/dri/mga/mgaioctl.c
index 4438bad..8ce5d80 100644
--- a/src/mesa/drivers/dri/mga/mgaioctl.c
+++ b/src/mesa/drivers/dri/mga/mgaioctl.c
@@ -207,7 +207,7 @@
 mgaClear( GLcontext *ctx, GLbitfield mask )
 {
    mgaContextPtr mmesa = MGA_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+   __DRIdrawable *dPriv = mmesa->driDrawable;
    GLuint flags = 0;
    GLuint clear_color = mmesa->ClearColor;
    GLuint clear_depth = 0;
@@ -409,7 +409,7 @@
 /*
  * Copy the back buffer to the front buffer.
  */
-void mgaCopyBuffer( __DRIdrawablePrivate *dPriv )
+void mgaCopyBuffer( __DRIdrawable *dPriv )
 {
    mgaContextPtr mmesa;
    drm_clip_rect_t *pbox;
@@ -417,7 +417,7 @@
    GLint ret;
    GLint i;
    GLboolean   missed_target;
-   __DRIscreenPrivate *psp = dPriv->driScreenPriv;
+   __DRIscreen *psp = dPriv->driScreenPriv;
 
    assert(dPriv);
    assert(dPriv->driContextPriv);
diff --git a/src/mesa/drivers/dri/mga/mgaioctl.h b/src/mesa/drivers/dri/mga/mgaioctl.h
index dbc823d..7a8660d 100644
--- a/src/mesa/drivers/dri/mga/mgaioctl.h
+++ b/src/mesa/drivers/dri/mga/mgaioctl.h
@@ -32,7 +32,7 @@
 #include "mgacontext.h"
 #include "mga_xmesa.h"
 
-void mgaCopyBuffer( __DRIdrawablePrivate *dPriv );
+void mgaCopyBuffer( __DRIdrawable *dPriv );
 void mgaWaitForVBlank( mgaContextPtr mmesa );
 
 void mgaGetILoadBufferLocked( mgaContextPtr mmesa );
diff --git a/src/mesa/drivers/dri/mga/mgapixel.c b/src/mesa/drivers/dri/mga/mgapixel.c
index 977dfa0..69415f8 100644
--- a/src/mesa/drivers/dri/mga/mgapixel.c
+++ b/src/mesa/drivers/dri/mga/mgapixel.c
@@ -134,10 +134,10 @@
 		    ctx->Fog.Enabled ||
 		    ctx->Scissor.Enabled ||
 		    ctx->Stencil._Enabled ||
-		    !ctx->Color.ColorMask[0] ||
-		    !ctx->Color.ColorMask[1] ||
-		    !ctx->Color.ColorMask[2] ||
-		    !ctx->Color.ColorMask[3] ||
+		    !ctx->Color.ColorMask[0][0] ||
+		    !ctx->Color.ColorMask[0][1] ||
+		    !ctx->Color.ColorMask[0][2] ||
+		    !ctx->Color.ColorMask[0][3] ||
 		    ctx->Color.ColorLogicOpEnabled ||
 		    ctx->Texture._EnabledUnits
            ) &&
@@ -150,10 +150,10 @@
 check_depth_per_fragment_ops( const GLcontext *ctx )
 {
    return ( ctx->Current.RasterPosValid &&
-	    ctx->Color.ColorMask[RCOMP] == 0 &&
-	    ctx->Color.ColorMask[BCOMP] == 0 &&
-	    ctx->Color.ColorMask[GCOMP] == 0 &&
-	    ctx->Color.ColorMask[ACOMP] == 0 &&
+	    ctx->Color.ColorMask[0][RCOMP] == 0 &&
+	    ctx->Color.ColorMask[0][BCOMP] == 0 &&
+	    ctx->Color.ColorMask[0][GCOMP] == 0 &&
+	    ctx->Color.ColorMask[0][ACOMP] == 0 &&
 	    ctx->Pixel.ZoomX == 1.0F &&
 	    ( ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F ) );
 }
@@ -299,7 +299,7 @@
 
 #if 0
    {
-      __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+      __DRIdrawable *dPriv = mmesa->driDrawable;
       int nbox, retcode, i;
 
       UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT );
@@ -399,7 +399,7 @@
 #if 0
    mgaContextPtr mmesa = MGA_CONTEXT(ctx);
    drmMGABlit blit;
-   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
+   __DRIdrawable *dPriv = mmesa->driDrawable;
    drm_clip_rect_t pbox = dPriv->pClipRects;
    int nbox = dPriv->numClipRects;
    int retcode, i;
@@ -525,10 +525,10 @@
 	      mmesa->mgaScreen->backOffset);
 
       planemask = mgaPackColor(cpp,
-			       ctx->Color.ColorMask[RCOMP],
-			       ctx->Color.ColorMask[GCOMP],
-			       ctx->Color.ColorMask[BCOMP],
-			       ctx->Color.ColorMask[ACOMP]);
+			       ctx->Color.ColorMask[0][RCOMP],
+			       ctx->Color.ColorMask[0][GCOMP],
+			       ctx->Color.ColorMask[0][BCOMP],
+			       ctx->Color.ColorMask[0][ACOMP]);
 
       if (cpp == 2)
 	 planemask |= planemask << 16;
diff --git a/src/mesa/drivers/dri/mga/mgaspan.c b/src/mesa/drivers/dri/mga/mgaspan.c
index 2ff1cac..10606c1 100644
--- a/src/mesa/drivers/dri/mga/mgaspan.c
+++ b/src/mesa/drivers/dri/mga/mgaspan.c
@@ -36,9 +36,9 @@
 
 #define LOCAL_VARS					\
    mgaContextPtr mmesa = MGA_CONTEXT(ctx);		\
-   __DRIscreenPrivate *sPriv = mmesa->driScreen;	\
+   __DRIscreen *sPriv = mmesa->driScreen;	\
    driRenderbuffer *drb = (driRenderbuffer *) rb;	\
-   const __DRIdrawablePrivate *dPriv = drb->dPriv;	\
+   const __DRIdrawable *dPriv = drb->dPriv;	\
    GLuint pitch = drb->pitch;				\
    GLuint height = dPriv->h;				\
    char *buf = (char *)(sPriv->pFB +			\
@@ -52,9 +52,9 @@
 
 #define LOCAL_DEPTH_VARS						\
    mgaContextPtr mmesa = MGA_CONTEXT(ctx);				\
-   __DRIscreenPrivate *sPriv = mmesa->driScreen;			\
+   __DRIscreen *sPriv = mmesa->driScreen;			\
    driRenderbuffer *drb = (driRenderbuffer *) rb;			\
-   const __DRIdrawablePrivate *dPriv = drb->dPriv;			\
+   const __DRIdrawable *dPriv = drb->dPriv;			\
    GLuint pitch = drb->pitch;						\
    GLuint height = dPriv->h;						\
    char *buf = (char *)(sPriv->pFB +					\
diff --git a/src/mesa/drivers/dri/mga/mgastate.c b/src/mesa/drivers/dri/mga/mgastate.c
index 7c830ec..0253044 100644
--- a/src/mesa/drivers/dri/mga/mgastate.c
+++ b/src/mesa/drivers/dri/mga/mgastate.c
@@ -374,13 +374,11 @@
 {
    mgaContextPtr mmesa = MGA_CONTEXT( ctx );
    mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
-
-
    GLuint mask = mgaPackColor(mgaScreen->cpp,
-			      ctx->Color.ColorMask[RCOMP],
-			      ctx->Color.ColorMask[GCOMP],
-			      ctx->Color.ColorMask[BCOMP],
-			      ctx->Color.ColorMask[ACOMP]);
+			      ctx->Color.ColorMask[0][RCOMP],
+			      ctx->Color.ColorMask[0][GCOMP],
+			      ctx->Color.ColorMask[0][BCOMP],
+			      ctx->Color.ColorMask[0][ACOMP]);
 
    if (mgaScreen->cpp == 2)
       mask = mask | (mask << 16);
@@ -748,7 +746,7 @@
 
 static void mga_set_cliprects(mgaContextPtr mmesa)
 {
-   __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
+   __DRIdrawable *driDrawable = mmesa->driDrawable;
 
    if ((mmesa->draw_buffer != MGA_FRONT)
        || (driDrawable->numBackClipRects == 0)) {
@@ -776,8 +774,8 @@
 
 void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers )
 {
-   __DRIdrawablePrivate *const driDrawable = mmesa->driDrawable;
-   __DRIdrawablePrivate *const driReadable = mmesa->driReadable;
+   __DRIdrawable *const driDrawable = mmesa->driDrawable;
+   __DRIdrawable *const driReadable = mmesa->driReadable;
 
    mmesa->dirty_cliprects = 0;	
 
diff --git a/src/mesa/drivers/dri/mga/mgatex.c b/src/mesa/drivers/dri/mga/mgatex.c
index 9163371..62a9317 100644
--- a/src/mesa/drivers/dri/mga/mgatex.c
+++ b/src/mesa/drivers/dri/mga/mgatex.c
@@ -332,7 +332,7 @@
 
       mgaSetTexWrapping( t, tObj->WrapS, tObj->WrapT );
       mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
-      mgaSetTexBorderColor( t, tObj->BorderColor );
+      mgaSetTexBorderColor( t, tObj->BorderColor.f );
    }
 
    return( t );
@@ -461,7 +461,7 @@
 
    case GL_TEXTURE_BORDER_COLOR:
       FLUSH_BATCH(mmesa);
-      mgaSetTexBorderColor(t, tObj->BorderColor);
+      mgaSetTexBorderColor(t, tObj->BorderColor.f);
       break;
 
    case GL_TEXTURE_BASE_LEVEL:
diff --git a/src/mesa/drivers/dri/mga/mgatris.c b/src/mesa/drivers/dri/mga/mgatris.c
index b93a21c..c1bcd4b 100644
--- a/src/mesa/drivers/dri/mga/mgatris.c
+++ b/src/mesa/drivers/dri/mga/mgatris.c
@@ -397,7 +397,8 @@
 
 #define LOCAL_VARS(n)					\
    mgaContextPtr mmesa = MGA_CONTEXT(ctx);		\
-   GLuint color[n], spec[n];				\
+   GLuint color[n] = { 0 };				\
+   GLuint spec[n] = { 0 };				\
    (void) color; (void) spec;
 
 
diff --git a/src/mesa/drivers/dri/r128/r128_context.c b/src/mesa/drivers/dri/r128/r128_context.c
index 0b25087..e389e1c 100644
--- a/src/mesa/drivers/dri/r128/r128_context.c
+++ b/src/mesa/drivers/dri/r128/r128_context.c
@@ -101,11 +101,11 @@
 /* Create the device specific context.
  */
 GLboolean r128CreateContext( const __GLcontextModes *glVisual,
-			     __DRIcontextPrivate *driContextPriv,
+			     __DRIcontext *driContextPriv,
                              void *sharedContextPrivate )
 {
    GLcontext *ctx, *shareCtx;
-   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
    struct dd_function_table functions;
    r128ContextPtr rmesa;
    r128ScreenPtr r128scrn;
@@ -274,7 +274,7 @@
 
 /* Destroy the device specific context.
  */
-void r128DestroyContext( __DRIcontextPrivate *driContextPriv  )
+void r128DestroyContext( __DRIcontext *driContextPriv  )
 {
    r128ContextPtr rmesa = (r128ContextPtr) driContextPriv->driverPrivate;
 
@@ -325,9 +325,9 @@
  * buffer `b'.
  */
 GLboolean
-r128MakeCurrent( __DRIcontextPrivate *driContextPriv,
-                 __DRIdrawablePrivate *driDrawPriv,
-                 __DRIdrawablePrivate *driReadPriv )
+r128MakeCurrent( __DRIcontext *driContextPriv,
+                 __DRIdrawable *driDrawPriv,
+                 __DRIdrawable *driReadPriv )
 {
    if ( driContextPriv ) {
       GET_CURRENT_CONTEXT(ctx);
@@ -364,7 +364,7 @@
 /* Force the context `c' to be unbound from its buffer.
  */
 GLboolean
-r128UnbindContext( __DRIcontextPrivate *driContextPriv )
+r128UnbindContext( __DRIcontext *driContextPriv )
 {
    return GL_TRUE;
 }
diff --git a/src/mesa/drivers/dri/r128/r128_context.h b/src/mesa/drivers/dri/r128/r128_context.h
index 0e10209..65f845c 100644
--- a/src/mesa/drivers/dri/r128/r128_context.h
+++ b/src/mesa/drivers/dri/r128/r128_context.h
@@ -186,9 +186,9 @@
 
    /* Mirrors of some DRI state
     */
-   __DRIcontextPrivate	*driContext;	/* DRI context */
-   __DRIscreenPrivate	*driScreen;	/* DRI screen */
-   __DRIdrawablePrivate	*driDrawable;	/* DRI drawable bound to this ctx */
+   __DRIcontext	*driContext;	/* DRI context */
+   __DRIscreen	*driScreen;	/* DRI screen */
+   __DRIdrawable	*driDrawable;	/* DRI drawable bound to this ctx */
 
    unsigned int lastStamp;	        /* mirror driDrawable->lastStamp */
 
@@ -225,16 +225,16 @@
 
 
 extern GLboolean r128CreateContext( const __GLcontextModes *glVisual,
-				    __DRIcontextPrivate *driContextPriv,
+				    __DRIcontext *driContextPriv,
                                     void *sharedContextPrivate );
 
-extern void r128DestroyContext( __DRIcontextPrivate * );
+extern void r128DestroyContext( __DRIcontext * );
 
-extern GLboolean r128MakeCurrent( __DRIcontextPrivate *driContextPriv,
-                                  __DRIdrawablePrivate *driDrawPriv,
-                                  __DRIdrawablePrivate *driReadPriv );
+extern GLboolean r128MakeCurrent( __DRIcontext *driContextPriv,
+                                  __DRIdrawable *driDrawPriv,
+                                  __DRIdrawable *driReadPriv );
 
-extern GLboolean r128UnbindContext( __DRIcontextPrivate *driContextPriv );
+extern GLboolean r128UnbindContext( __DRIcontext *driContextPriv );
 
 /* ================================================================
  * Debugging:
diff --git a/src/mesa/drivers/dri/r128/r128_ioctl.c b/src/mesa/drivers/dri/r128/r128_ioctl.c
index 84ac3d9..56758d9 100644
--- a/src/mesa/drivers/dri/r128/r128_ioctl.c
+++ b/src/mesa/drivers/dri/r128/r128_ioctl.c
@@ -248,7 +248,7 @@
 
 /* Copy the back color buffer to the front color buffer.
  */
-void r128CopyBuffer( __DRIdrawablePrivate *dPriv )
+void r128CopyBuffer( __DRIdrawable *dPriv )
 {
    r128ContextPtr rmesa;
    GLint nbox, i, ret;
@@ -327,7 +327,7 @@
 #endif
 }
 
-void r128PageFlip( __DRIdrawablePrivate *dPriv )
+void r128PageFlip( __DRIdrawable *dPriv )
 {
    r128ContextPtr rmesa;
    GLint ret;
@@ -401,7 +401,7 @@
 static void r128Clear( GLcontext *ctx, GLbitfield mask )
 {
    r128ContextPtr rmesa = R128_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = rmesa->driDrawable;
+   __DRIdrawable *dPriv = rmesa->driDrawable;
    drm_r128_clear_t clear;
    GLuint flags = 0;
    GLint i;
diff --git a/src/mesa/drivers/dri/r128/r128_ioctl.h b/src/mesa/drivers/dri/r128/r128_ioctl.h
index 4b0c9cd..84ace90 100644
--- a/src/mesa/drivers/dri/r128/r128_ioctl.h
+++ b/src/mesa/drivers/dri/r128/r128_ioctl.h
@@ -85,8 +85,8 @@
 extern void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n,
 				       const GLint x[], const GLint y[] );
 
-extern void r128CopyBuffer( __DRIdrawablePrivate *dPriv );
-extern void r128PageFlip( __DRIdrawablePrivate *dPriv );
+extern void r128CopyBuffer( __DRIdrawable *dPriv );
+extern void r128PageFlip( __DRIdrawable *dPriv );
 void r128WaitForVBlank( r128ContextPtr rmesa );
 
 extern void r128WaitForIdleLocked( r128ContextPtr rmesa );
diff --git a/src/mesa/drivers/dri/r128/r128_lock.c b/src/mesa/drivers/dri/r128/r128_lock.c
index 81488a2..9bc3515 100644
--- a/src/mesa/drivers/dri/r128/r128_lock.c
+++ b/src/mesa/drivers/dri/r128/r128_lock.c
@@ -68,8 +68,8 @@
  */
 void r128GetLock( r128ContextPtr rmesa, GLuint flags )
 {
-   __DRIdrawablePrivate *dPriv = rmesa->driDrawable;
-   __DRIscreenPrivate *sPriv = rmesa->driScreen;
+   __DRIdrawable *dPriv = rmesa->driDrawable;
+   __DRIscreen *sPriv = rmesa->driScreen;
    drm_r128_sarea_t *sarea = rmesa->sarea;
    int i;
 
diff --git a/src/mesa/drivers/dri/r128/r128_screen.c b/src/mesa/drivers/dri/r128/r128_screen.c
index 9da3b5f..80b2658 100644
--- a/src/mesa/drivers/dri/r128/r128_screen.c
+++ b/src/mesa/drivers/dri/r128/r128_screen.c
@@ -91,7 +91,7 @@
 /* Create the device specific screen private data struct.
  */
 static r128ScreenPtr
-r128CreateScreen( __DRIscreenPrivate *sPriv )
+r128CreateScreen( __DRIscreen *sPriv )
 {
    r128ScreenPtr r128Screen;
    R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv;
@@ -236,7 +236,7 @@
 /* Destroy the device specific screen private data struct.
  */
 static void
-r128DestroyScreen( __DRIscreenPrivate *sPriv )
+r128DestroyScreen( __DRIscreen *sPriv )
 {
    r128ScreenPtr r128Screen = (r128ScreenPtr)sPriv->private;
 
@@ -262,8 +262,8 @@
  * data.
  */
 static GLboolean
-r128CreateBuffer( __DRIscreenPrivate *driScrnPriv,
-                  __DRIdrawablePrivate *driDrawPriv,
+r128CreateBuffer( __DRIscreen *driScrnPriv,
+                  __DRIdrawable *driDrawPriv,
                   const __GLcontextModes *mesaVis,
                   GLboolean isPixmap )
 {
@@ -349,7 +349,7 @@
 
 
 static void
-r128DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+r128DestroyBuffer(__DRIdrawable *driDrawPriv)
 {
    _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
 }
@@ -357,7 +357,7 @@
 
 /* Copy the back color buffer to the front color buffer */
 static void
-r128SwapBuffers(__DRIdrawablePrivate *dPriv)
+r128SwapBuffers(__DRIdrawable *dPriv)
 {
    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
       r128ContextPtr rmesa;
@@ -384,7 +384,7 @@
 /* Initialize the driver specific screen private data.
  */
 static GLboolean
-r128InitDriver( __DRIscreenPrivate *sPriv )
+r128InitDriver( __DRIscreen *sPriv )
 {
    sPriv->private = (void *) r128CreateScreen( sPriv );
 
@@ -397,7 +397,7 @@
 }
 
 static const __DRIconfig **
-r128FillInModes( __DRIscreenPrivate *psp,
+r128FillInModes( __DRIscreen *psp,
 		 unsigned pixel_bits, unsigned depth_bits,
 		 unsigned stencil_bits, GLboolean have_back_buffer )
 {
@@ -478,7 +478,7 @@
  * \return the __GLcontextModes supported by this driver
  */
 static const __DRIconfig **
-r128InitScreen(__DRIscreenPrivate *psp)
+r128InitScreen(__DRIscreen *psp)
 {
    static const __DRIversion ddx_expected = { 4, 0, 0 };
    static const __DRIversion dri_expected = { 4, 0, 0 };
@@ -517,3 +517,10 @@
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
 };
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driLegacyExtension.base,
+    NULL
+};
diff --git a/src/mesa/drivers/dri/r128/r128_screen.h b/src/mesa/drivers/dri/r128/r128_screen.h
index e2fa167..8d450ad 100644
--- a/src/mesa/drivers/dri/r128/r128_screen.h
+++ b/src/mesa/drivers/dri/r128/r128_screen.h
@@ -71,7 +71,7 @@
 
    drmBufMapPtr buffers;
 
-   __DRIscreenPrivate *driScreen;
+   __DRIscreen *driScreen;
    unsigned int sarea_priv_offset;
 
    /* Configuration cache with default values for all contexts */
diff --git a/src/mesa/drivers/dri/r128/r128_span.c b/src/mesa/drivers/dri/r128/r128_span.c
index d238cc3..0413e5b 100644
--- a/src/mesa/drivers/dri/r128/r128_span.c
+++ b/src/mesa/drivers/dri/r128/r128_span.c
@@ -50,8 +50,8 @@
 
 #define LOCAL_VARS							\
    r128ContextPtr rmesa = R128_CONTEXT(ctx);				\
-   __DRIscreenPrivate *sPriv = rmesa->driScreen;			\
-   __DRIdrawablePrivate *dPriv = rmesa->driDrawable;			\
+   __DRIscreen *sPriv = rmesa->driScreen;			\
+   __DRIdrawable *dPriv = rmesa->driDrawable;			\
    driRenderbuffer *drb = (driRenderbuffer *) rb;			\
    GLuint height = dPriv->h;						\
    GLuint p;								\
@@ -60,8 +60,8 @@
 #define LOCAL_DEPTH_VARS						\
    r128ContextPtr rmesa = R128_CONTEXT(ctx);				\
    r128ScreenPtr r128scrn = rmesa->r128Screen;				\
-   __DRIscreenPrivate *sPriv = rmesa->driScreen;			\
-   __DRIdrawablePrivate *dPriv = rmesa->driDrawable;			\
+   __DRIscreen *sPriv = rmesa->driScreen;			\
+   __DRIdrawable *dPriv = rmesa->driDrawable;			\
    GLuint height = dPriv->h;						\
    (void) r128scrn; (void) sPriv; (void) height
 
diff --git a/src/mesa/drivers/dri/r128/r128_state.c b/src/mesa/drivers/dri/r128/r128_state.c
index 4ae7bf5..2254a7a 100644
--- a/src/mesa/drivers/dri/r128/r128_state.c
+++ b/src/mesa/drivers/dri/r128/r128_state.c
@@ -572,7 +572,7 @@
    r128ContextPtr rmesa = R128_CONTEXT(ctx);
 
    if ( rmesa->driDrawable ) {
-      __DRIdrawablePrivate *drawable = rmesa->driDrawable;
+      __DRIdrawable *drawable = rmesa->driDrawable;
       int x1 = 0;
       int y1 = 0;
       int x2 = drawable->w - 1;
@@ -702,10 +702,10 @@
    r128ContextPtr rmesa = R128_CONTEXT(ctx);
 
    GLuint mask = r128PackColor( rmesa->r128Screen->cpp,
-				ctx->Color.ColorMask[RCOMP],
-				ctx->Color.ColorMask[GCOMP],
-				ctx->Color.ColorMask[BCOMP],
-				ctx->Color.ColorMask[ACOMP] );
+				ctx->Color.ColorMask[0][RCOMP],
+				ctx->Color.ColorMask[0][GCOMP],
+				ctx->Color.ColorMask[0][BCOMP],
+				ctx->Color.ColorMask[0][ACOMP] );
 
    if ( rmesa->setup.plane_3d_mask_c != mask ) {
       rmesa->setup.plane_3d_mask_c = mask;
diff --git a/src/mesa/drivers/dri/r128/r128_tex.c b/src/mesa/drivers/dri/r128/r128_tex.c
index 0a1207f..f1be7cc 100644
--- a/src/mesa/drivers/dri/r128/r128_tex.c
+++ b/src/mesa/drivers/dri/r128/r128_tex.c
@@ -169,7 +169,7 @@
 
       r128SetTexWrap( t, texObj->WrapS, texObj->WrapT );
       r128SetTexFilter( t, texObj->MinFilter, texObj->MagFilter );
-      r128SetTexBorderColor( t, texObj->BorderColor );
+      r128SetTexBorderColor( t, texObj->BorderColor.f );
    }
 
    return t;
@@ -535,7 +535,7 @@
 
    case GL_TEXTURE_BORDER_COLOR:
       if ( t->base.bound ) FLUSH_BATCH( rmesa );
-      r128SetTexBorderColor( t, tObj->BorderColor );
+      r128SetTexBorderColor( t, tObj->BorderColor.f );
       break;
 
    case GL_TEXTURE_BASE_LEVEL:
diff --git a/src/mesa/drivers/dri/r128/r128_tris.c b/src/mesa/drivers/dri/r128/r128_tris.c
index 5b91271..86d4717 100644
--- a/src/mesa/drivers/dri/r128/r128_tris.c
+++ b/src/mesa/drivers/dri/r128/r128_tris.c
@@ -216,7 +216,8 @@
 
 #define LOCAL_VARS(n)						\
    r128ContextPtr rmesa = R128_CONTEXT(ctx);			\
-   GLuint color[n], spec[n];					\
+   GLuint color[n] = { 0 };					\
+   GLuint spec[n] = { 0 };					\
    GLuint coloroffset = rmesa->coloroffset;			\
    GLuint specoffset = rmesa->specoffset;			\
    GLboolean havespec = (rmesa->specoffset != 0);		\
@@ -650,12 +651,12 @@
    }
 
    if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(rmesa->tmu_source[0]) )) {
-      if ( VB->TexCoordPtr[rmesa->tmu_source[0]]->size > 2 )
+      if ( VB->AttribPtr[_TNL_ATTRIB_TEX0 + rmesa->tmu_source[0]]->size > 2 )
 	 fallback_projtex = GL_TRUE;
       EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, R128_CCE_VC_FRMT_S_T, 8 );
    }
    if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(rmesa->tmu_source[1]) )) {
-      if ( VB->TexCoordPtr[rmesa->tmu_source[1]]->size > 2 )
+      if ( VB->AttribPtr[_TNL_ATTRIB_TEX0 + rmesa->tmu_source[1]]->size > 2 )
 	 fallback_projtex = GL_TRUE;
       EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, R128_CCE_VC_FRMT_S2_T2, 8 );
    }
diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile
index 776f1e3..8212dc1 100644
--- a/src/mesa/drivers/dri/r200/Makefile
+++ b/src/mesa/drivers/dri/r200/Makefile
@@ -14,7 +14,7 @@
 endif
 
 ifeq ($(RADEON_LDFLAGS),)
-CS_SOURCES = radeon_cs_space_drm.c
+CS_SOURCES = radeon_cs_space_drm.c radeon_bo.c radeon_cs.c
 endif
 
 RADEON_COMMON_SOURCES = \
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
index e3ae839..f34e319 100644
--- a/src/mesa/drivers/dri/r200/r200_context.c
+++ b/src/mesa/drivers/dri/r200/r200_context.c
@@ -274,10 +274,10 @@
 /* Create the device specific rendering context.
  */
 GLboolean r200CreateContext( const __GLcontextModes *glVisual,
-			     __DRIcontextPrivate *driContextPriv,
+			     __DRIcontext *driContextPriv,
 			     void *sharedContextPrivate)
 {
-   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
    radeonScreenPtr screen = (radeonScreenPtr)(sPriv->private);
    struct dd_function_table functions;
    r200ContextPtr rmesa;
@@ -325,9 +325,9 @@
    _mesa_init_driver_functions(&functions);
    r200InitDriverFuncs(&functions);
    r200InitIoctlFuncs(&functions);
-   r200InitStateFuncs(&functions, screen->kernel_mm);
+   r200InitStateFuncs(&functions);
    r200InitTextureFuncs(&functions);
-   r200InitShaderFuncs(&functions); 
+   r200InitShaderFuncs(&functions);
    radeonInitQueryObjFunctions(&functions);
 
    if (!radeonInitContext(&rmesa->radeon, &functions,
@@ -496,7 +496,7 @@
 }
 
 
-void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
+void r200DestroyContext( __DRIcontext *driContextPriv )
 {
 	int i;
 	r200ContextPtr rmesa = (r200ContextPtr)driContextPriv->driverPrivate;
diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h
index 246f98c..17e4d89 100644
--- a/src/mesa/drivers/dri/r200/r200_context.h
+++ b/src/mesa/drivers/dri/r200/r200_context.h
@@ -636,14 +636,14 @@
 #define R200_CONTEXT(ctx)		((r200ContextPtr)(ctx->DriverCtx))
 
 
-extern void r200DestroyContext( __DRIcontextPrivate *driContextPriv );
+extern void r200DestroyContext( __DRIcontext *driContextPriv );
 extern GLboolean r200CreateContext( const __GLcontextModes *glVisual,
-				    __DRIcontextPrivate *driContextPriv,
+				    __DRIcontext *driContextPriv,
 				    void *sharedContextPrivate);
-extern GLboolean r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
-				  __DRIdrawablePrivate *driDrawPriv,
-				  __DRIdrawablePrivate *driReadPriv );
-extern GLboolean r200UnbindContext( __DRIcontextPrivate *driContextPriv );
+extern GLboolean r200MakeCurrent( __DRIcontext *driContextPriv,
+				  __DRIdrawable *driDrawPriv,
+				  __DRIdrawable *driReadPriv );
+extern GLboolean r200UnbindContext( __DRIcontext *driContextPriv );
 
 /* ================================================================
  * Debugging:
diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c
index b238adb..66c5d36 100644
--- a/src/mesa/drivers/dri/r200/r200_ioctl.c
+++ b/src/mesa/drivers/dri/r200/r200_ioctl.c
@@ -61,7 +61,7 @@
 static void r200KernelClear(GLcontext *ctx, GLuint flags)
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
+   __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
    GLint cx, cy, cw, ch, ret;
    GLuint i;
 
@@ -185,7 +185,7 @@
 static void r200Clear( GLcontext *ctx, GLbitfield mask )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
+   __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
    GLuint flags = 0;
    GLuint color_mask = 0;
    GLuint orig_mask = mask;
diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c
index 383a0c4..249c0bb 100644
--- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c
+++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c
@@ -90,12 +90,14 @@
 	aos->components = size;
 	aos->count = count;
 
+	radeon_bo_map(aos->bo, 1);
 	out = (uint32_t*)((char*)aos->bo->ptr + aos->offset);
 	for (i = 0; i < count; i++) {
 	  out[0] = r200ComputeFogBlendFactor( ctx, *(GLfloat *)data );
 	  out++;
 	  data += stride;
 	}
+	radeon_bo_unmap(aos->bo);
 }
 
 /* Emit any changed arrays to new GART memory, re-emit a packet to
diff --git a/src/mesa/drivers/dri/r200/r200_pixel.c b/src/mesa/drivers/dri/r200/r200_pixel.c
index 9577387..bfb7e2a 100644
--- a/src/mesa/drivers/dri/r200/r200_pixel.c
+++ b/src/mesa/drivers/dri/r200/r200_pixel.c
@@ -88,10 +88,10 @@
 		    ctx->Fog.Enabled ||
 		    ctx->Scissor.Enabled ||
 		    ctx->Stencil._Enabled ||
-		    !ctx->Color.ColorMask[0] ||
-		    !ctx->Color.ColorMask[1] ||
-		    !ctx->Color.ColorMask[2] ||
-		    !ctx->Color.ColorMask[3] ||
+		    !ctx->Color.ColorMask[0][0] ||
+		    !ctx->Color.ColorMask[0][1] ||
+		    !ctx->Color.ColorMask[0][2] ||
+		    !ctx->Color.ColorMask[0][3] ||
 		    ctx->Color.ColorLogicOpEnabled ||
 		    ctx->Texture._EnabledUnits
            ) &&
@@ -214,7 +214,7 @@
    }
 
    {
-      __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
+      __DRIdrawable *dPriv = rmesa->radeon.dri.drawable;
       driRenderbuffer *drb = (driRenderbuffer *) ctx->ReadBuffer->_ColorReadBuffer;
       int nbox = dPriv->numClipRects;
       int src_offset = drb->offset
@@ -298,7 +298,7 @@
 
 #if 0
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
+   __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
    drm_clip_rect_t *box = dPriv->pClipRects;
    struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorDrawBuffers[0];
    driRenderbuffer *drb = (driRenderbuffer *) rb;
@@ -400,10 +400,10 @@
    case GL_RGBA:
    case GL_BGRA:
       planemask = radeonPackColor(cpp,
-				ctx->Color.ColorMask[RCOMP],
-				ctx->Color.ColorMask[GCOMP],
-				ctx->Color.ColorMask[BCOMP],
-				ctx->Color.ColorMask[ACOMP]);
+				ctx->Color.ColorMask[0][RCOMP],
+				ctx->Color.ColorMask[0][GCOMP],
+				ctx->Color.ColorMask[0][BCOMP],
+				ctx->Color.ColorMask[0][ACOMP]);
 
       if (cpp == 2)
 	 planemask |= planemask << 16;
diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
index d28e96d..7fe482f 100644
--- a/src/mesa/drivers/dri/r200/r200_state.c
+++ b/src/mesa/drivers/dri/r200/r200_state.c
@@ -721,10 +721,10 @@
    if (!rrb)
      return;
    mask = radeonPackColor( rrb->cpp,
-			   ctx->Color.ColorMask[RCOMP],
-			   ctx->Color.ColorMask[GCOMP],
-			   ctx->Color.ColorMask[BCOMP],
-			   ctx->Color.ColorMask[ACOMP] );
+			   ctx->Color.ColorMask[0][RCOMP],
+			   ctx->Color.ColorMask[0][GCOMP],
+			   ctx->Color.ColorMask[0][BCOMP],
+			   ctx->Color.ColorMask[0][ACOMP] );
 
 
    if (!(r && g && b && a))
@@ -1585,7 +1585,7 @@
 void r200UpdateWindow( GLcontext *ctx )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
+   __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
    GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
    GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
    const GLfloat *v = ctx->Viewport._WindowMap.m;
@@ -1665,7 +1665,7 @@
 void r200UpdateViewportOffset( GLcontext *ctx )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
+   __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
    GLfloat xoffset = (GLfloat)dPriv->x;
    GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
    const GLfloat *v = ctx->Viewport._WindowMap.m;
@@ -2476,7 +2476,7 @@
 }
 /* Initialize the driver's state functions.
  */
-void r200InitStateFuncs( struct dd_function_table *functions, GLboolean dri2 )
+void r200InitStateFuncs( struct dd_function_table *functions )
 {
    functions->UpdateState		= r200InvalidateState;
    functions->LightingSpaceChange	= r200LightingSpaceChange;
@@ -2510,10 +2510,7 @@
    functions->LogicOpcode		= r200LogicOpCode;
    functions->PolygonMode		= r200PolygonMode;
    functions->PolygonOffset		= r200PolygonOffset;
-   if (dri2)
-      functions->PolygonStipple		= r200PolygonStipple;
-   else
-      functions->PolygonStipple		= radeonPolygonStipplePreKMS;
+   functions->PolygonStipple		= r200PolygonStipple;
    functions->PointParameterfv		= r200PointParameter;
    functions->PointSize			= r200PointSize;
    functions->RenderMode		= r200RenderMode;
diff --git a/src/mesa/drivers/dri/r200/r200_state.h b/src/mesa/drivers/dri/r200/r200_state.h
index 9c62f0a..7b9b0c1 100644
--- a/src/mesa/drivers/dri/r200/r200_state.h
+++ b/src/mesa/drivers/dri/r200/r200_state.h
@@ -38,7 +38,7 @@
 #include "r200_context.h"
 
 extern void r200InitState( r200ContextPtr rmesa );
-extern void r200InitStateFuncs( struct dd_function_table *functions, GLboolean dri2 );
+extern void r200InitStateFuncs( struct dd_function_table *functions );
 extern void r200InitTnlFuncs( GLcontext *ctx );
 
 extern void r200UpdateMaterial( GLcontext *ctx );
diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c
index 68bfeea..6c5a0b7 100644
--- a/src/mesa/drivers/dri/r200/r200_state_init.c
+++ b/src/mesa/drivers/dri/r200/r200_state_init.c
@@ -640,7 +640,7 @@
    OUT_BATCH_TABLE(atom->cmd, 10);
 
    if (t && t->mt && !t->image_override) {
-     OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0,
+     OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, get_base_teximage_offset(t),
 		  RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
    } else if (!t) {
      /* workaround for old CS mechanism */
@@ -887,10 +887,8 @@
          }
       }
    }
-   /* polygon stipple is done with irq for non-kms */
-   if (rmesa->radeon.radeonScreen->kernel_mm) {
-       ALLOC_STATE( stp, always, STP_STATE_SIZE, "STP/stp", 0 );
-   }
+
+   ALLOC_STATE( stp, always, STP_STATE_SIZE, "STP/stp", 0 );
 
    for (i = 0; i < 6; i++)
       if (rmesa->radeon.radeonScreen->kernel_mm)
@@ -1122,12 +1120,11 @@
    rmesa->hw.sci.cmd[SCI_CMD_1] = CP_PACKET0(R200_RE_TOP_LEFT, 0);
    rmesa->hw.sci.cmd[SCI_CMD_2] = CP_PACKET0(R200_RE_WIDTH_HEIGHT, 0);
 
+   rmesa->hw.stp.cmd[STP_CMD_0] = CP_PACKET0(RADEON_RE_STIPPLE_ADDR, 0);
+   rmesa->hw.stp.cmd[STP_DATA_0] = 0;
+   rmesa->hw.stp.cmd[STP_CMD_1] = CP_PACKET0_ONE(RADEON_RE_STIPPLE_DATA, 31);
+
    if (rmesa->radeon.radeonScreen->kernel_mm) {
-
-	rmesa->hw.stp.cmd[STP_CMD_0] = CP_PACKET0(RADEON_RE_STIPPLE_ADDR, 0);
-	rmesa->hw.stp.cmd[STP_DATA_0] = 0;
-	rmesa->hw.stp.cmd[STP_CMD_1] = CP_PACKET0_ONE(RADEON_RE_STIPPLE_DATA, 31);
-
         rmesa->hw.mtl[0].emit = mtl_emit;
         rmesa->hw.mtl[1].emit = mtl_emit;
 
diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.c b/src/mesa/drivers/dri/r200/r200_swtcl.c
index 240fb45..4596912 100644
--- a/src/mesa/drivers/dri/r200/r200_swtcl.c
+++ b/src/mesa/drivers/dri/r200/r200_swtcl.c
@@ -168,7 +168,7 @@
 
       for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
 	 if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) {
-	    GLuint sz = VB->TexCoordPtr[i]->size;
+	    GLuint sz = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size;
 
 	    fmt_1 |= sz << (3 * i);
 	    EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_1F + sz - 1, 0 );
@@ -297,7 +297,7 @@
    radeonEmitState(&rmesa->radeon);
    r200EmitVertexAOS( rmesa,
 		      rmesa->radeon.swtcl.vertex_size,
-		      first_elem(&rmesa->radeon.dma.reserved)->bo,
+		      rmesa->radeon.swtcl.bo,
 		      current_offset);
 
 
diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c
index c702910..e7d48a7 100644
--- a/src/mesa/drivers/dri/r200/r200_tcl.c
+++ b/src/mesa/drivers/dri/r200/r200_tcl.c
@@ -509,25 +509,26 @@
 	 prog to a not enabled output however, so just don't mess with it.
 	 We only need to change compsel. */
       GLuint out_compsel = 0;
-      GLuint vp_out = rmesa->curr_vp_hw->mesa_program.Base.OutputsWritten;
+      const GLbitfield64 vp_out =
+	 rmesa->curr_vp_hw->mesa_program.Base.OutputsWritten;
 
       vimap_rev = &rmesa->curr_vp_hw->inputmap_rev[0];
-      assert(vp_out & (1 << VERT_RESULT_HPOS));
+      assert(vp_out & BITFIELD64_BIT(VERT_RESULT_HPOS));
       out_compsel = R200_OUTPUT_XYZW;
-      if (vp_out & (1 << VERT_RESULT_COL0)) {
+      if (vp_out & BITFIELD64_BIT(VERT_RESULT_COL0)) {
 	 out_compsel |= R200_OUTPUT_COLOR_0;
       }
-      if (vp_out & (1 << VERT_RESULT_COL1)) {
+      if (vp_out & BITFIELD64_BIT(VERT_RESULT_COL1)) {
 	 out_compsel |= R200_OUTPUT_COLOR_1;
       }
-      if (vp_out & (1 << VERT_RESULT_FOGC)) {
+      if (vp_out & BITFIELD64_BIT(VERT_RESULT_FOGC)) {
          out_compsel |= R200_OUTPUT_DISCRETE_FOG;
       }
-      if (vp_out & (1 << VERT_RESULT_PSIZ)) {
+      if (vp_out & BITFIELD64_BIT(VERT_RESULT_PSIZ)) {
 	 out_compsel |= R200_OUTPUT_PT_SIZE;
       }
       for (i = VERT_RESULT_TEX0; i < VERT_RESULT_TEX6; i++) {
-	 if (vp_out & (1 << i)) {
+	 if (vp_out & BITFIELD64_BIT(i)) {
 	    out_compsel |= R200_OUTPUT_TEX_0 << (i - VERT_RESULT_TEX0);
 	 }
       }
diff --git a/src/mesa/drivers/dri/r200/r200_tex.c b/src/mesa/drivers/dri/r200/r200_tex.c
index 5a21a8b..5b87ba6 100644
--- a/src/mesa/drivers/dri/r200/r200_tex.c
+++ b/src/mesa/drivers/dri/r200/r200_tex.c
@@ -378,23 +378,14 @@
       break;
 
    case GL_TEXTURE_BORDER_COLOR:
-      r200SetTexBorderColor( t, texObj->BorderColor );
+      r200SetTexBorderColor( t, texObj->BorderColor.f );
       break;
 
    case GL_TEXTURE_BASE_LEVEL:
    case GL_TEXTURE_MAX_LEVEL:
    case GL_TEXTURE_MIN_LOD:
    case GL_TEXTURE_MAX_LOD:
-      /* This isn't the most efficient solution but there doesn't appear to
-       * be a nice alternative.  Since there's no LOD clamping,
-       * we just have to rely on loading the right subset of mipmap levels
-       * to simulate a clamped LOD.
-       */
-      if (t->mt) {
-         radeon_miptree_unreference(t->mt);
-	 t->mt = 0;
-	 t->validated = GL_FALSE;
-      }
+      t->validated = GL_FALSE;
       break;
 
    default:
@@ -413,7 +404,7 @@
 	      (void *)texObj,
 	      _mesa_lookup_enum_by_nr(texObj->Target));
    }
-   
+
    if (rmesa) {
       int i;
       radeon_firevertices(&rmesa->radeon);
@@ -425,11 +416,9 @@
 	 }
       }      
    }
-   
-   if (t->mt) {
-      radeon_miptree_unreference(t->mt);
-      t->mt = 0;
-   }
+
+   radeon_miptree_unreference(&t->mt);
+
    _mesa_delete_texture_object(ctx, texObj);
 }
 
@@ -481,7 +470,7 @@
    r200SetTexWrap( t, t->base.WrapS, t->base.WrapT, t->base.WrapR );
    r200SetTexMaxAnisotropy( t, t->base.MaxAnisotropy );
    r200SetTexFilter(t, t->base.MinFilter, t->base.MagFilter);
-   r200SetTexBorderColor(t, t->base.BorderColor);
+   r200SetTexBorderColor(t, t->base.BorderColor.f);
 
    return &t->base;
 }
diff --git a/src/mesa/drivers/dri/r200/r200_texstate.c b/src/mesa/drivers/dri/r200/r200_texstate.c
index 7d0afa1..e2f9cf0 100644
--- a/src/mesa/drivers/dri/r200/r200_texstate.c
+++ b/src/mesa/drivers/dri/r200/r200_texstate.c
@@ -797,24 +797,13 @@
     	    return;
     	}
 
-	radeon_update_renderbuffers(pDRICtx, dPriv);
-	/* back & depth buffer are useless free them right away */
-	rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
-	if (rb && rb->bo) {
-		radeon_bo_unref(rb->bo);
-        rb->bo = NULL;
-	}
-	rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
-	if (rb && rb->bo) {
-		radeon_bo_unref(rb->bo);
-		rb->bo = NULL;
-	}
+	radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE);
 	rb = rfb->color_rb[0];
 	if (rb->bo == NULL) {
 		/* Failed to BO for the buffer */
 		return;
 	}
-	
+
 	_mesa_lock_texture(radeon->glCtx, texObj);
 	if (t->bo) {
 		radeon_bo_unref(t->bo);
@@ -824,14 +813,10 @@
 		radeon_bo_unref(rImage->bo);
 		rImage->bo = NULL;
 	}
-	if (t->mt) {
-		radeon_miptree_unreference(t->mt);
-		t->mt = NULL;
-	}
-	if (rImage->mt) {
-		radeon_miptree_unreference(rImage->mt);
-		rImage->mt = NULL;
-	}
+
+	radeon_miptree_unreference(&t->mt);
+	radeon_miptree_unreference(&rImage->mt);
+
 	_mesa_init_teximage_fields(radeon->glCtx, target, texImage,
 				   rb->base.Width, rb->base.Height, 1, 0, rb->cpp);
 	texImage->RowStride = rb->pitch / rb->cpp;
@@ -1423,10 +1408,9 @@
  */
 static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
 {
-   int firstlevel = t->mt ? t->mt->firstLevel : 0;
-   const struct gl_texture_image *firstImage = t->base.Image[0][firstlevel];
+   const struct gl_texture_image *firstImage = t->base.Image[0][t->minLod];
    GLint log2Width, log2Height, log2Depth, texelBytes;
-   
+
    if ( t->bo ) {
        return;
    }
@@ -1454,9 +1438,9 @@
 	 return;
       }
    }
-   
+
    t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK;
-   t->pp_txfilter |= (t->mt->lastLevel - t->mt->firstLevel) << R200_MAX_MIP_LEVEL_SHIFT;
+   t->pp_txfilter |= (t->maxLod - t->minLod) << R200_MAX_MIP_LEVEL_SHIFT;
 	
    t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
 		       R200_TXFORMAT_HEIGHT_MASK |
diff --git a/src/mesa/drivers/dri/r200/radeon_bo.c b/src/mesa/drivers/dri/r200/radeon_bo.c
new file mode 120000
index 0000000..9448ffe
--- /dev/null
+++ b/src/mesa/drivers/dri/r200/radeon_bo.c
@@ -0,0 +1 @@
+../radeon/radeon_bo.c
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r200/radeon_bo_int_drm.h b/src/mesa/drivers/dri/r200/radeon_bo_int_drm.h
new file mode 120000
index 0000000..0294509
--- /dev/null
+++ b/src/mesa/drivers/dri/r200/radeon_bo_int_drm.h
@@ -0,0 +1 @@
+../radeon/radeon_bo_int_drm.h
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r200/radeon_cs.c b/src/mesa/drivers/dri/r200/radeon_cs.c
new file mode 120000
index 0000000..66b7ad1
--- /dev/null
+++ b/src/mesa/drivers/dri/r200/radeon_cs.c
@@ -0,0 +1 @@
+../radeon/radeon_cs.c
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r200/radeon_cs_int_drm.h b/src/mesa/drivers/dri/r200/radeon_cs_int_drm.h
new file mode 120000
index 0000000..462f524
--- /dev/null
+++ b/src/mesa/drivers/dri/r200/radeon_cs_int_drm.h
@@ -0,0 +1 @@
+../radeon/radeon_cs_int_drm.h
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile
index cb0f715..be005bd 100644
--- a/src/mesa/drivers/dri/r300/Makefile
+++ b/src/mesa/drivers/dri/r300/Makefile
@@ -14,7 +14,7 @@
 endif
 
 ifeq ($(RADEON_LDFLAGS),)
-CS_SOURCES = radeon_cs_space_drm.c
+CS_SOURCES = radeon_cs_space_drm.c radeon_bo.c radeon_cs.c
 endif
 
 COMMON_SOURCES = \
@@ -43,13 +43,14 @@
 
 DRIVER_SOURCES = \
 		 radeon_screen.c \
+		 r300_blit.c \
 		 r300_context.c \
 		 r300_draw.c \
-		 r300_ioctl.c \
 		 r300_cmdbuf.c \
 		 r300_state.c \
 		 r300_render.c \
 		 r300_tex.c \
+		 r300_texcopy.c \
 		 r300_texstate.c \
 		 r300_vertprog.c \
 		 r300_fragprog_common.c \
diff --git a/src/mesa/drivers/dri/r300/compiler/memory_pool.c b/src/mesa/drivers/dri/r300/compiler/memory_pool.c
index 37aa2b6..76c7c60 100644
--- a/src/mesa/drivers/dri/r300/compiler/memory_pool.c
+++ b/src/mesa/drivers/dri/r300/compiler/memory_pool.c
@@ -71,12 +71,14 @@
 void * memory_pool_malloc(struct memory_pool * pool, unsigned int bytes)
 {
 	if (bytes < POOL_LARGE_ALLOC) {
+		void * ptr;
+
 		if (pool->head + bytes > pool->end)
 			refill_pool(pool);
 
 		assert(pool->head + bytes <= pool->end);
 
-		void * ptr = pool->head;
+		ptr = pool->head;
 
 		pool->head += bytes;
 		pool->head = (unsigned char*)(((unsigned long)pool->head + POOL_ALIGN - 1) & ~(POOL_ALIGN - 1));
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_code.c b/src/mesa/drivers/dri/r300/compiler/radeon_code.c
index 1a3d8bb..853b2be 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_code.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_code.c
@@ -143,7 +143,8 @@
 
 	for(index = 0; index < c->Count; ++index) {
 		if (c->Constants[index].Type == RC_CONSTANT_IMMEDIATE) {
-			for(unsigned comp = 0; comp < c->Constants[index].Size; ++comp) {
+			unsigned comp;
+			for(comp = 0; comp < c->Constants[index].Size; ++comp) {
 				if (c->Constants[index].u.Immediate[comp] == data) {
 					*swizzle = RC_MAKE_SWIZZLE(comp, comp, comp, comp);
 					return index;
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_code.h b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
index 902b7cf..6d979bb 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_code.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
@@ -59,7 +59,9 @@
 	RC_STATE_SHADOW_AMBIENT = 0,
 
 	RC_STATE_R300_WINDOW_DIMENSION,
-	RC_STATE_R300_TEXRECT_FACTOR
+	RC_STATE_R300_TEXRECT_FACTOR,
+	RC_STATE_R300_VIEWPORT_SCALE,
+	RC_STATE_R300_VIEWPORT_OFFSET
 };
 
 struct rc_constant {
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
index c0e7a7f..272f907 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
@@ -229,15 +229,20 @@
 /**
  * Introduce standard code fragment to deal with fragment.position.
  */
-void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsigned new_input)
+void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsigned new_input,
+                                int full_vtransform)
 {
 	unsigned tempregi = rc_find_free_temporary(c);
+	struct rc_instruction * inst_rcp;
+	struct rc_instruction * inst_mul;
+	struct rc_instruction * inst_mad;
+	struct rc_instruction * inst;
 
 	c->Program.InputsRead &= ~(1 << wpos);
 	c->Program.InputsRead |= 1 << new_input;
 
 	/* perspective divide */
-	struct rc_instruction * inst_rcp = rc_insert_new_instruction(c, &c->Program.Instructions);
+	inst_rcp = rc_insert_new_instruction(c, &c->Program.Instructions);
 	inst_rcp->U.I.Opcode = RC_OPCODE_RCP;
 
 	inst_rcp->U.I.DstReg.File = RC_FILE_TEMPORARY;
@@ -248,7 +253,7 @@
 	inst_rcp->U.I.SrcReg[0].Index = new_input;
 	inst_rcp->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_WWWW;
 
-	struct rc_instruction * inst_mul = rc_insert_new_instruction(c, inst_rcp);
+	inst_mul = rc_insert_new_instruction(c, inst_rcp);
 	inst_mul->U.I.Opcode = RC_OPCODE_MUL;
 
 	inst_mul->U.I.DstReg.File = RC_FILE_TEMPORARY;
@@ -263,7 +268,7 @@
 	inst_mul->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_WWWW;
 
 	/* viewport transformation */
-	struct rc_instruction * inst_mad = rc_insert_new_instruction(c, inst_mul);
+	inst_mad = rc_insert_new_instruction(c, inst_mul);
 	inst_mad->U.I.Opcode = RC_OPCODE_MAD;
 
 	inst_mad->U.I.DstReg.File = RC_FILE_TEMPORARY;
@@ -275,14 +280,19 @@
 	inst_mad->U.I.SrcReg[0].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO);
 
 	inst_mad->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
-	inst_mad->U.I.SrcReg[1].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_WINDOW_DIMENSION, 0);
 	inst_mad->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO);
 
 	inst_mad->U.I.SrcReg[2].File = RC_FILE_CONSTANT;
-	inst_mad->U.I.SrcReg[2].Index = inst_mad->U.I.SrcReg[1].Index;
 	inst_mad->U.I.SrcReg[2].Swizzle = RC_MAKE_SWIZZLE(RC_SWIZZLE_X, RC_SWIZZLE_Y, RC_SWIZZLE_Z, RC_SWIZZLE_ZERO);
 
-	struct rc_instruction * inst;
+	if (full_vtransform) {
+		inst_mad->U.I.SrcReg[1].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_VIEWPORT_SCALE, 0);
+		inst_mad->U.I.SrcReg[2].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_VIEWPORT_OFFSET, 0);
+	} else {
+		inst_mad->U.I.SrcReg[1].Index =
+		inst_mad->U.I.SrcReg[2].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_WINDOW_DIMENSION, 0);
+	}
+
 	for (inst = inst_mad->Next; inst != &c->Program.Instructions; inst = inst->Next) {
 		const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
 		unsigned i;
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
index 87a732c..731adc1 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
@@ -73,7 +73,8 @@
 void rc_move_input(struct radeon_compiler * c, unsigned input, struct rc_src_register new_input);
 void rc_move_output(struct radeon_compiler * c, unsigned output, unsigned new_output, unsigned writemask);
 void rc_copy_output(struct radeon_compiler * c, unsigned output, unsigned dup_output);
-void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsigned new_input);
+void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsigned new_input,
+                                int full_vtransform);
 
 struct r300_fragment_program_compiler {
 	struct radeon_compiler Base;
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
index 828d0c8..b2fe7f7 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
@@ -49,7 +49,7 @@
 
 	unsigned int Used:1;
 	unsigned int Allocated:1;
-	rc_register_file File:3;
+	unsigned int File:3;
 	unsigned int Index:RC_REGISTER_INDEX_BITS;
 };
 
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program.c b/src/mesa/drivers/dri/r300/compiler/radeon_program.c
index 0dbc538..a3c41d7 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program.c
@@ -94,10 +94,11 @@
 {
 	char used[RC_REGISTER_MAX_INDEX];
 	unsigned int i;
+	struct rc_instruction * rcinst;
 
 	memset(used, 0, sizeof(used));
 
-	for (struct rc_instruction * rcinst = c->Program.Instructions.Next; rcinst != &c->Program.Instructions; rcinst = rcinst->Next) {
+	for (rcinst = c->Program.Instructions.Next; rcinst != &c->Program.Instructions; rcinst = rcinst->Next) {
 		const struct rc_sub_instruction *inst = &rcinst->U.I;
 		const struct rc_opcode_info *opcode = rc_get_opcode_info(inst->Opcode);
 		unsigned int k;
@@ -168,8 +169,9 @@
 unsigned int rc_recompute_ips(struct radeon_compiler * c)
 {
 	unsigned int ip = 0;
+	struct rc_instruction * inst;
 
-	for(struct rc_instruction * inst = c->Program.Instructions.Next;
+	for(inst = c->Program.Instructions.Next;
 	    inst != &c->Program.Instructions;
 	    inst = inst->Next) {
 		inst->IP = ip++;
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program.h b/src/mesa/drivers/dri/r300/compiler/radeon_program.h
index 33db3ea..e318867 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program.h
@@ -39,7 +39,7 @@
 struct radeon_compiler;
 
 struct rc_src_register {
-	rc_register_file File:3;
+	unsigned int File:3;
 
 	/** Negative values may be used for relative addressing. */
 	signed int Index:(RC_REGISTER_INDEX_BITS+1);
@@ -55,7 +55,7 @@
 };
 
 struct rc_dst_register {
-	rc_register_file File:3;
+	unsigned int File:3;
 
 	/** Negative values may be used for relative addressing. */
 	signed int Index:(RC_REGISTER_INDEX_BITS+1);
@@ -79,20 +79,20 @@
 	/**
 	 * Opcode of this instruction, according to \ref rc_opcode enums.
 	 */
-	rc_opcode Opcode:8;
+	unsigned int Opcode:8;
 
 	/**
 	 * Saturate each value of the result to the range [0,1] or [-1,1],
 	 * according to \ref rc_saturate_mode enums.
 	 */
-	rc_saturate_mode SaturateMode:2;
+	unsigned int SaturateMode:2;
 
 	/**
 	 * Writing to the special register RC_SPECIAL_ALU_RESULT
 	 */
 	/*@{*/
-	rc_write_aluresult WriteALUResult:2;
-	rc_compare_func ALUResultCompare:3;
+	unsigned int WriteALUResult:2;
+	unsigned int ALUResultCompare:3;
 	/*@}*/
 
 	/**
@@ -103,7 +103,7 @@
 	unsigned int TexSrcUnit:5;
 
 	/** Source texture target, one of the \ref rc_texture_target enums */
-	rc_texture_target TexSrcTarget:3;
+	unsigned int TexSrcTarget:3;
 
 	/** True if tex instruction should do shadow comparison */
 	unsigned int TexShadow:1;
@@ -191,7 +191,7 @@
 
 static inline void reset_srcreg(struct rc_src_register* reg)
 {
-	memset(reg, 0, sizeof(reg));
+	memset(reg, 0, sizeof(struct rc_src_register));
 	reg->Swizzle = RC_SWIZZLE_XYZW;
 }
 
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
index 0326d25..b5c08ae 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
@@ -267,9 +267,9 @@
 	temp = inst->U.I.DstReg.Index;
 	srctemp = srcreg(RC_FILE_TEMPORARY, temp);
 
-	// tmp.x = max(0.0, Src.x);
-	// tmp.y = max(0.0, Src.y);
-	// tmp.w = clamp(Src.z, -128+eps, 128-eps);
+	/* tmp.x = max(0.0, Src.x); */
+	/* tmp.y = max(0.0, Src.y); */
+	/* tmp.w = clamp(Src.z, -128+eps, 128-eps); */
 	emit2(c, inst->Prev, RC_OPCODE_MAX, 0,
 		dstregtmpmask(temp, RC_MASK_XYW),
 		inst->U.I.SrcReg[0],
@@ -280,7 +280,7 @@
 		swizzle(srctemp, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W),
 		negate(srcregswz(RC_FILE_CONSTANT, constant, constant_swizzle)));
 
-	// tmp.w = Pow(tmp.y, tmp.w)
+	/* tmp.w = Pow(tmp.y, tmp.w) */
 	emit1(c, inst->Prev, RC_OPCODE_LG2, 0,
 		dstregtmpmask(temp, RC_MASK_W),
 		swizzle(srctemp, RC_SWIZZLE_Y, RC_SWIZZLE_Y, RC_SWIZZLE_Y, RC_SWIZZLE_Y));
@@ -292,14 +292,14 @@
 		dstregtmpmask(temp, RC_MASK_W),
 		swizzle(srctemp, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W));
 
-	// tmp.z = (tmp.x > 0) ? tmp.w : 0.0
+	/* tmp.z = (tmp.x > 0) ? tmp.w : 0.0 */
 	emit3(c, inst->Prev, RC_OPCODE_CMP, inst->U.I.SaturateMode,
 		dstregtmpmask(temp, RC_MASK_Z),
 		negate(swizzle(srctemp, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X)),
 		swizzle(srctemp, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W),
 		builtin_zero);
 
-	// tmp.x, tmp.y, tmp.w = 1.0, tmp.x, 1.0
+	/* tmp.x, tmp.y, tmp.w = 1.0, tmp.x, 1.0 */
 	emit1(c, inst->Prev, RC_OPCODE_MOV, inst->U.I.SaturateMode,
 		dstregtmpmask(temp, RC_MASK_XYW),
 		swizzle(srctemp, RC_SWIZZLE_ONE, RC_SWIZZLE_X, RC_SWIZZLE_ONE, RC_SWIZZLE_ONE));
@@ -533,16 +533,16 @@
 {
 	static const float SinCosConsts[2][4] = {
 		{
-			1.273239545,		// 4/PI
-			-0.405284735,		// -4/(PI*PI)
-			3.141592654,		// PI
-			0.2225			// weight
+			1.273239545,		/* 4/PI */
+			-0.405284735,		/* -4/(PI*PI) */
+			3.141592654,		/* PI */
+			0.2225			/* weight */
 		},
 		{
 			0.75,
 			0.5,
-			0.159154943,		// 1/(2*PI)
-			6.283185307		// 2*PI
+			0.159154943,		/* 1/(2*PI) */
+			6.283185307		/* 2*PI */
 		}
 	};
 	int i;
@@ -560,23 +560,23 @@
  * MAD dest, tmp.y, weight, tmp.x
  */
 static void sin_approx(
-	struct radeon_compiler* c, struct rc_instruction * before,
+	struct radeon_compiler* c, struct rc_instruction * inst,
 	struct rc_dst_register dst, struct rc_src_register src, const unsigned int* constants)
 {
 	unsigned int tempreg = rc_find_free_temporary(c);
 
-	emit2(c, before, RC_OPCODE_MUL, 0, dstregtmpmask(tempreg, RC_MASK_XY),
+	emit2(c, inst->Prev, RC_OPCODE_MUL, 0, dstregtmpmask(tempreg, RC_MASK_XY),
 		swizzle(src, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X),
 		srcreg(RC_FILE_CONSTANT, constants[0]));
-	emit3(c, before, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_X),
+	emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_X),
 		swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_Y, RC_SWIZZLE_Y, RC_SWIZZLE_Y, RC_SWIZZLE_Y),
 		absolute(swizzle(src, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X)),
 		swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X));
-	emit3(c, before, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_Y),
+	emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_Y),
 		swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X),
 		absolute(swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X)),
 		negate(swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X)));
-	emit3(c, before, RC_OPCODE_MAD, 0, dst,
+	emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dst,
 		swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_Y, RC_SWIZZLE_Y, RC_SWIZZLE_Y, RC_SWIZZLE_Y),
 		swizzle(srcreg(RC_FILE_CONSTANT, constants[0]), RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W, RC_SWIZZLE_W),
 		swizzle(srcreg(RC_FILE_TEMPORARY, tempreg), RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X));
@@ -602,9 +602,9 @@
 	sincos_constants(c, constants);
 
 	if (inst->U.I.Opcode == RC_OPCODE_COS) {
-		// MAD tmp.x, src, 1/(2*PI), 0.75
-		// FRC tmp.x, tmp.x
-		// MAD tmp.z, tmp.x, 2*PI, -PI
+		/* MAD tmp.x, src, 1/(2*PI), 0.75 */
+		/* FRC tmp.x, tmp.x */
+		/* MAD tmp.z, tmp.x, 2*PI, -PI */
 		emit3(c, inst->Prev, RC_OPCODE_MAD, 0, dstregtmpmask(tempreg, RC_MASK_W),
 			swizzle(inst->U.I.SrcReg[0], RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X, RC_SWIZZLE_X),
 			swizzle(srcreg(RC_FILE_CONSTANT, constants[1]), RC_SWIZZLE_Z, RC_SWIZZLE_Z, RC_SWIZZLE_Z, RC_SWIZZLE_Z),
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
index 1600598..6685ade 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
@@ -52,12 +52,12 @@
 
 struct radeon_pair_instruction_source {
 	unsigned int Used:1;
-	rc_register_file File:3;
+	unsigned int File:3;
 	unsigned int Index:RC_REGISTER_INDEX_BITS;
 };
 
 struct radeon_pair_instruction_rgb {
-	rc_opcode Opcode:8;
+	unsigned int Opcode:8;
 	unsigned int DestIndex:RC_REGISTER_INDEX_BITS;
 	unsigned int WriteMask:3;
 	unsigned int OutputWriteMask:3;
@@ -74,7 +74,7 @@
 };
 
 struct radeon_pair_instruction_alpha {
-	rc_opcode Opcode:8;
+	unsigned int Opcode:8;
 	unsigned int DestIndex:RC_REGISTER_INDEX_BITS;
 	unsigned int WriteMask:1;
 	unsigned int OutputWriteMask:1;
@@ -95,8 +95,8 @@
 	struct radeon_pair_instruction_rgb RGB;
 	struct radeon_pair_instruction_alpha Alpha;
 
-	rc_write_aluresult WriteALUResult:2;
-	rc_compare_func ALUResultCompare:3;
+	unsigned int WriteALUResult:2;
+	unsigned int ALUResultCompare:3;
 };
 
 
diff --git a/src/mesa/drivers/dri/r300/r300_blit.c b/src/mesa/drivers/dri/r300/r300_blit.c
new file mode 100644
index 0000000..2eec27e
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/r300_blit.c
@@ -0,0 +1,622 @@
+/*
+ * Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com>
+ *
+ * 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, sublicense, 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 NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "radeon_common.h"
+#include "r300_context.h"
+
+#include "r300_blit.h"
+#include "r300_cmdbuf.h"
+#include "r300_emit.h"
+#include "r300_tex.h"
+#include "compiler/radeon_compiler.h"
+#include "compiler/radeon_opcodes.h"
+
+static void vp_ins_outs(struct r300_vertex_program_compiler *c)
+{
+    c->code->inputs[VERT_ATTRIB_POS] = 0;
+    c->code->inputs[VERT_ATTRIB_TEX0] = 1;
+    c->code->outputs[VERT_RESULT_HPOS] = 0;
+    c->code->outputs[VERT_RESULT_TEX0] = 1;
+}
+
+static void fp_allocate_hw_inputs(
+    struct r300_fragment_program_compiler * c,
+    void (*allocate)(void * data, unsigned input, unsigned hwreg),
+    void * mydata)
+{
+    allocate(mydata, FRAG_ATTRIB_TEX0, 0);
+}
+
+static void create_vertex_program(struct r300_context *r300)
+{
+    struct r300_vertex_program_compiler compiler;
+    struct rc_instruction *inst;
+
+    rc_init(&compiler.Base);
+
+    inst = rc_insert_new_instruction(&compiler.Base, compiler.Base.Program.Instructions.Prev);
+    inst->U.I.Opcode = RC_OPCODE_MOV;
+    inst->U.I.DstReg.File = RC_FILE_OUTPUT;
+    inst->U.I.DstReg.Index = VERT_RESULT_HPOS;
+    inst->U.I.DstReg.RelAddr = 0;
+    inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
+    inst->U.I.SrcReg[0].Abs = 0;
+    inst->U.I.SrcReg[0].File = RC_FILE_INPUT;
+    inst->U.I.SrcReg[0].Index = VERT_ATTRIB_POS;
+    inst->U.I.SrcReg[0].Negate = 0;
+    inst->U.I.SrcReg[0].RelAddr = 0;
+    inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
+
+    inst = rc_insert_new_instruction(&compiler.Base, compiler.Base.Program.Instructions.Prev);
+    inst->U.I.Opcode = RC_OPCODE_MOV;
+    inst->U.I.DstReg.File = RC_FILE_OUTPUT;
+    inst->U.I.DstReg.Index = VERT_RESULT_TEX0;
+    inst->U.I.DstReg.RelAddr = 0;
+    inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
+    inst->U.I.SrcReg[0].Abs = 0;
+    inst->U.I.SrcReg[0].File = RC_FILE_INPUT;
+    inst->U.I.SrcReg[0].Index = VERT_ATTRIB_TEX0;
+    inst->U.I.SrcReg[0].Negate = 0;
+    inst->U.I.SrcReg[0].RelAddr = 0;
+    inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
+
+    compiler.Base.Program.InputsRead = (1 << VERT_ATTRIB_POS) | (1 << VERT_ATTRIB_TEX0);
+    compiler.RequiredOutputs = compiler.Base.Program.OutputsWritten = (1 << VERT_RESULT_HPOS) | (1 << VERT_RESULT_TEX0);
+    compiler.SetHwInputOutput = vp_ins_outs;
+    compiler.code = &r300->blit.vp_code;
+
+    r3xx_compile_vertex_program(&compiler);
+}
+
+static void create_fragment_program(struct r300_context *r300)
+{
+    struct r300_fragment_program_compiler compiler;
+    struct rc_instruction *inst;
+
+    rc_init(&compiler.Base);
+
+    inst = rc_insert_new_instruction(&compiler.Base, compiler.Base.Program.Instructions.Prev);
+    inst->U.I.Opcode = RC_OPCODE_TEX;
+    inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
+    inst->U.I.TexSrcUnit = 0;
+    inst->U.I.DstReg.File = RC_FILE_OUTPUT;
+    inst->U.I.DstReg.Index = FRAG_RESULT_COLOR;
+    inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
+    inst->U.I.SrcReg[0].Abs = 0;
+    inst->U.I.SrcReg[0].File = RC_FILE_INPUT;
+    inst->U.I.SrcReg[0].Index = FRAG_ATTRIB_TEX0;
+    inst->U.I.SrcReg[0].Negate = 0;
+    inst->U.I.SrcReg[0].RelAddr = 0;
+    inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
+
+    compiler.Base.Program.InputsRead = (1 << FRAG_ATTRIB_TEX0);
+    compiler.OutputColor = FRAG_RESULT_COLOR;
+    compiler.OutputDepth = FRAG_RESULT_DEPTH;
+    compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515);
+    compiler.code = &r300->blit.fp_code;
+    compiler.AllocateHwInputs = fp_allocate_hw_inputs;
+
+    r3xx_compile_fragment_program(&compiler);
+}
+
+void r300_blit_init(struct r300_context *r300)
+{
+    create_vertex_program(r300);
+    create_fragment_program(r300);
+}
+
+static void r300_emit_tx_setup(struct r300_context *r300,
+                               gl_format mesa_format,
+                               struct radeon_bo *bo,
+                               intptr_t offset,
+                               unsigned width,
+                               unsigned height,
+                               unsigned pitch)
+{
+    BATCH_LOCALS(&r300->radeon);
+
+    assert(width <= 2048);
+    assert(height <= 2048);
+    assert(r300TranslateTexFormat(mesa_format) >= 0);
+    assert(offset % 32 == 0);
+
+    BEGIN_BATCH(17);
+    OUT_BATCH_REGVAL(R300_TX_FILTER0_0,
+                     (R300_TX_CLAMP_TO_EDGE  << R300_TX_WRAP_S_SHIFT) |
+                     (R300_TX_CLAMP_TO_EDGE  << R300_TX_WRAP_T_SHIFT) |
+                     (R300_TX_CLAMP_TO_EDGE  << R300_TX_WRAP_R_SHIFT) |
+                     R300_TX_MIN_FILTER_MIP_NONE |
+                     R300_TX_MIN_FILTER_LINEAR |
+                     R300_TX_MAG_FILTER_LINEAR |
+                     (0 << 28));
+    OUT_BATCH_REGVAL(R300_TX_FILTER1_0, 0);
+    OUT_BATCH_REGVAL(R300_TX_SIZE_0,
+                     ((width-1) << R300_TX_WIDTHMASK_SHIFT) |
+                     ((height-1) << R300_TX_HEIGHTMASK_SHIFT) |
+                     (0 << R300_TX_DEPTHMASK_SHIFT) |
+                     (0 << R300_TX_MAX_MIP_LEVEL_SHIFT) |
+                     R300_TX_SIZE_TXPITCH_EN);
+
+    OUT_BATCH_REGVAL(R300_TX_FORMAT_0, r300TranslateTexFormat(mesa_format));
+    OUT_BATCH_REGVAL(R300_TX_FORMAT2_0, pitch - 1);
+    OUT_BATCH_REGSEQ(R300_TX_OFFSET_0, 1);
+    OUT_BATCH_RELOC(0, bo, offset, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
+
+    OUT_BATCH_REGSEQ(R300_TX_INVALTAGS, 2);
+    OUT_BATCH(0);
+    OUT_BATCH(1);
+
+    END_BATCH();
+}
+
+#define EASY_US_FORMAT(FMT, C0, C1, C2, C3, SIGN) \
+    (FMT  | R500_C0_SEL_##C0 | R500_C1_SEL_##C1 | \
+    R500_C2_SEL_##C2 | R500_C3_SEL_##C3 | R500_OUT_SIGN(SIGN))
+
+static uint32_t mesa_format_to_us_format(gl_format mesa_format)
+{
+    switch(mesa_format)
+    {
+        case MESA_FORMAT_RGBA8888: // x
+            return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, B, G, R, 0);
+        case MESA_FORMAT_RGB565: // x
+        case MESA_FORMAT_ARGB1555: // x
+        case MESA_FORMAT_RGBA8888_REV: // x
+            return EASY_US_FORMAT(R500_OUT_FMT_C4_8, R, G, B, A, 0);
+        case MESA_FORMAT_ARGB8888: // x
+            return EASY_US_FORMAT(R500_OUT_FMT_C4_8, B, G, R, A, 0);
+        case MESA_FORMAT_ARGB8888_REV:
+            return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, R, G, B, 0);
+        case MESA_FORMAT_XRGB8888:
+            return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, R, G, B, 0);
+
+        case MESA_FORMAT_RGB332:
+            return EASY_US_FORMAT(R500_OUT_FMT_C_3_3_2, A, R, G, B, 0);
+
+        case MESA_FORMAT_RGBA_FLOAT32:
+            return EASY_US_FORMAT(R500_OUT_FMT_C4_32_FP, R, G, B, A, 0);
+        case MESA_FORMAT_RGBA_FLOAT16:
+            return EASY_US_FORMAT(R500_OUT_FMT_C4_16_FP, R, G, B, A, 0);
+        case MESA_FORMAT_ALPHA_FLOAT32:
+            return EASY_US_FORMAT(R500_OUT_FMT_C_32_FP, A, A, A, A, 0);
+        case MESA_FORMAT_ALPHA_FLOAT16:
+            return EASY_US_FORMAT(R500_OUT_FMT_C_16_FP, A, A, A, A, 0);
+
+        case MESA_FORMAT_SIGNED_RGBA8888:
+            return EASY_US_FORMAT(R500_OUT_FMT_C4_8, R, G, B, A, 0xf);
+        case MESA_FORMAT_SIGNED_RGBA8888_REV:
+            return EASY_US_FORMAT(R500_OUT_FMT_C4_8, A, B, G, R, 0xf);
+        case MESA_FORMAT_SIGNED_RGBA_16:
+            return EASY_US_FORMAT(R500_OUT_FMT_C4_16, R, G, B, A, 0xf);
+
+        default:
+            fprintf(stderr, "Unsupported format %s for US output\n", _mesa_get_format_name(mesa_format));
+            assert(0);
+            return 0;
+    }
+}
+#undef EASY_US_FORMAT
+
+static void r500_emit_fp_setup(struct r300_context *r300,
+                               struct r500_fragment_program_code *fp,
+                               gl_format dst_format)
+{
+    r500_emit_fp(r300, (uint32_t *)fp->inst, (fp->inst_end + 1) * 6, 0, 0, 0);
+    BATCH_LOCALS(&r300->radeon);
+
+    BEGIN_BATCH(10);
+    OUT_BATCH_REGSEQ(R500_US_CODE_ADDR, 3);
+    OUT_BATCH(R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(fp->inst_end));
+    OUT_BATCH(R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(fp->inst_end));
+    OUT_BATCH(0);
+    OUT_BATCH_REGVAL(R500_US_CONFIG, 0);
+    OUT_BATCH_REGVAL(R500_US_OUT_FMT_0, mesa_format_to_us_format(dst_format));
+    OUT_BATCH_REGVAL(R500_US_PIXSIZE, fp->max_temp_idx);
+    END_BATCH();
+}
+
+static void r500_emit_rs_setup(struct r300_context *r300)
+{
+    BATCH_LOCALS(&r300->radeon);
+
+    BEGIN_BATCH(7);
+    OUT_BATCH_REGSEQ(R300_RS_COUNT, 2);
+    OUT_BATCH((4 << R300_IT_COUNT_SHIFT) | R300_HIRES_EN);
+    OUT_BATCH(0);
+    OUT_BATCH_REGVAL(R500_RS_INST_0,
+                     (0 << R500_RS_INST_TEX_ID_SHIFT) |
+                     (0 << R500_RS_INST_TEX_ADDR_SHIFT) |
+                     R500_RS_INST_TEX_CN_WRITE |
+                     R500_RS_INST_COL_CN_NO_WRITE);
+    OUT_BATCH_REGVAL(R500_RS_IP_0,
+                     (0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
+                     (1 << R500_RS_IP_TEX_PTR_T_SHIFT) |
+                     (2 << R500_RS_IP_TEX_PTR_R_SHIFT) |
+                     (3 << R500_RS_IP_TEX_PTR_Q_SHIFT));
+    END_BATCH();
+}
+
+static void r300_emit_fp_setup(struct r300_context *r300,
+                               struct r300_fragment_program_code *code,
+                               gl_format dst_format)
+{
+    unsigned i;
+    BATCH_LOCALS(&r300->radeon);
+
+    BEGIN_BATCH((code->alu.length + 1) * 4 + code->tex.length + 1 + 11);
+
+    OUT_BATCH_REGSEQ(R300_US_ALU_RGB_INST_0, code->alu.length);
+    for (i = 0; i < code->alu.length; i++) {
+        OUT_BATCH(code->alu.inst[i].rgb_inst);
+    }
+    OUT_BATCH_REGSEQ(R300_US_ALU_RGB_ADDR_0, code->alu.length);
+    for (i = 0; i < code->alu.length; i++) {
+        OUT_BATCH(code->alu.inst[i].rgb_addr);
+    }
+    OUT_BATCH_REGSEQ(R300_US_ALU_ALPHA_INST_0, code->alu.length);
+    for (i = 0; i < code->alu.length; i++) {
+        OUT_BATCH(code->alu.inst[i].alpha_inst);
+    }
+    OUT_BATCH_REGSEQ(R300_US_ALU_ALPHA_ADDR_0, code->alu.length);
+    for (i = 0; i < code->alu.length; i++) {
+        OUT_BATCH(code->alu.inst[i].alpha_addr);
+    }
+
+    OUT_BATCH_REGSEQ(R300_US_TEX_INST_0, code->tex.length);
+    OUT_BATCH_TABLE(code->tex.inst, code->tex.length);
+
+    OUT_BATCH_REGSEQ(R300_US_CONFIG, 3);
+    OUT_BATCH(R300_PFS_CNTL_FIRST_NODE_HAS_TEX);
+    OUT_BATCH(code->pixsize);
+    OUT_BATCH(code->code_offset);
+    OUT_BATCH_REGSEQ(R300_US_CODE_ADDR_0, 4);
+    OUT_BATCH_TABLE(code->code_addr, 4);
+    OUT_BATCH_REGVAL(R500_US_OUT_FMT_0, mesa_format_to_us_format(dst_format));
+    END_BATCH();
+}
+
+static void r300_emit_rs_setup(struct r300_context *r300)
+{
+    BATCH_LOCALS(&r300->radeon);
+
+    BEGIN_BATCH(7);
+    OUT_BATCH_REGSEQ(R300_RS_COUNT, 2);
+    OUT_BATCH((4 << R300_IT_COUNT_SHIFT) | R300_HIRES_EN);
+    OUT_BATCH(0);
+    OUT_BATCH_REGVAL(R300_RS_INST_0,
+                     R300_RS_INST_TEX_ID(0) |
+                     R300_RS_INST_TEX_ADDR(0) |
+                     R300_RS_INST_TEX_CN_WRITE);
+    OUT_BATCH_REGVAL(R300_RS_IP_0,
+                     R300_RS_TEX_PTR(0) |
+                     R300_RS_SEL_S(R300_RS_SEL_C0) |
+                     R300_RS_SEL_T(R300_RS_SEL_C1) |
+                     R300_RS_SEL_R(R300_RS_SEL_K0) |
+                     R300_RS_SEL_Q(R300_RS_SEL_K1));
+    END_BATCH();
+}
+
+static void emit_pvs_setup(struct r300_context *r300,
+                           uint32_t *vp_code,
+                           unsigned vp_len)
+{
+    BATCH_LOCALS(&r300->radeon);
+
+    r300_emit_vpu(r300, vp_code, vp_len * 4, R300_PVS_CODE_START);
+
+    BEGIN_BATCH(4);
+    OUT_BATCH_REGSEQ(R300_VAP_PVS_CODE_CNTL_0, 3);
+    OUT_BATCH((0 << R300_PVS_FIRST_INST_SHIFT) |
+              ((vp_len - 1)  << R300_PVS_XYZW_VALID_INST_SHIFT) |
+              ((vp_len - 1)<< R300_PVS_LAST_INST_SHIFT));
+    OUT_BATCH(0);
+    OUT_BATCH((vp_len - 1) << R300_PVS_LAST_VTX_SRC_INST_SHIFT);
+    END_BATCH();
+}
+
+static void emit_vap_setup(struct r300_context *r300)
+{
+    BATCH_LOCALS(&r300->radeon);
+
+    BEGIN_BATCH(12);
+    OUT_BATCH_REGSEQ(R300_SE_VTE_CNTL, 2);
+    OUT_BATCH(R300_VTX_XY_FMT | R300_VTX_Z_FMT);
+    OUT_BATCH(4);
+
+    OUT_BATCH_REGVAL(R300_VAP_PSC_SGN_NORM_CNTL, 0xaaaaaaaa);
+    OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_0,
+                     ((R300_DATA_TYPE_FLOAT_2 | (0 << R300_DST_VEC_LOC_SHIFT)) << 0) |
+                     (((1 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_2 | R300_LAST_VEC) << 16));
+    OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_EXT_0,
+                    ((((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) |
+                       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) |
+                       (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_SHIFT) |
+                       (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_SHIFT) | 
+                       (0xf << R300_WRITE_ENA_SHIFT) ) << 0) |
+                     (((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) |
+                       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) |
+                       (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_SHIFT) |
+                       (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_SHIFT) |
+                       (0xf << R300_WRITE_ENA_SHIFT) ) << 16) ) );
+    OUT_BATCH_REGSEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
+    OUT_BATCH(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT);
+    OUT_BATCH(R300_VAP_OUTPUT_VTX_FMT_1__4_COMPONENTS);
+    END_BATCH();
+}
+
+static GLboolean validate_buffers(struct r300_context *r300,
+                                  struct radeon_bo *src_bo,
+                                  struct radeon_bo *dst_bo)
+{
+    int ret;
+    radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
+                                      src_bo, RADEON_GEM_DOMAIN_VRAM, 0);
+
+    radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
+                                      dst_bo, 0, RADEON_GEM_DOMAIN_VRAM);
+
+    ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs,
+                                        first_elem(&r300->radeon.dma.reserved)->bo,
+                                        RADEON_GEM_DOMAIN_GTT, 0);
+    if (ret)
+        return GL_FALSE;
+
+    return GL_TRUE;
+}
+
+/**
+ * Calculate texcoords for given image region.
+ * Output values are [minx, maxx, miny, maxy]
+ */
+static void calc_tex_coords(float img_width, float img_height,
+                            float x, float y,
+                            float reg_width, float reg_height,
+                            unsigned flip_y, float *buf)
+{
+    buf[0] = x / img_width;
+    buf[1] = buf[0] + reg_width / img_width;
+    buf[2] = y / img_height;
+    buf[3] = buf[2] + reg_height / img_height;
+    if (flip_y)
+    {
+        float tmp = buf[2];
+        buf[2] = 1.0 - buf[3];
+        buf[3] = 1.0 - tmp;
+    }
+}
+
+static void emit_draw_packet(struct r300_context *r300,
+                             unsigned src_width, unsigned src_height,
+                             unsigned src_x_offset, unsigned src_y_offset,
+                             unsigned dst_x_offset, unsigned dst_y_offset,
+                             unsigned reg_width, unsigned reg_height,
+                             unsigned flip_y)
+{
+    float texcoords[4];
+
+    calc_tex_coords(src_width, src_height,
+                    src_x_offset, src_y_offset,
+                    reg_width, reg_height,
+                    flip_y, texcoords);
+
+    float verts[] = { dst_x_offset, dst_y_offset,
+                      texcoords[0], texcoords[3],
+                      dst_x_offset, dst_y_offset + reg_height,
+                      texcoords[0], texcoords[2],
+                      dst_x_offset + reg_width, dst_y_offset + reg_height,
+                      texcoords[1], texcoords[2],
+                      dst_x_offset + reg_width, dst_y_offset,
+                      texcoords[1], texcoords[3] };
+
+    BATCH_LOCALS(&r300->radeon);
+
+    BEGIN_BATCH(19);
+    OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_IMMD_2, 16);
+    OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED |
+              (4 << 16) | R300_VAP_VF_CNTL__PRIM_QUADS);
+    OUT_BATCH_TABLE(verts, 16);
+    END_BATCH();
+}
+
+static void other_stuff(struct r300_context *r300)
+{
+    BATCH_LOCALS(&r300->radeon);
+
+    BEGIN_BATCH(15);
+    OUT_BATCH_REGVAL(R300_GA_POLY_MODE,
+                     R300_GA_POLY_MODE_FRONT_PTYPE_TRI | R300_GA_POLY_MODE_BACK_PTYPE_TRI);
+    OUT_BATCH_REGVAL(R300_SU_CULL_MODE, R300_FRONT_FACE_CCW);
+    OUT_BATCH_REGVAL(R300_FG_FOG_BLEND, 0);
+    OUT_BATCH_REGVAL(R300_FG_ALPHA_FUNC, 0);
+    OUT_BATCH_REGSEQ(R300_RB3D_CBLEND, 2);
+    OUT_BATCH(0x0);
+    OUT_BATCH(0x0);
+    OUT_BATCH_REGVAL(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
+    OUT_BATCH_REGVAL(R300_ZB_CNTL, 0);
+    END_BATCH();
+}
+
+static void emit_cb_setup(struct r300_context *r300,
+                          struct radeon_bo *bo,
+                          intptr_t offset,
+                          gl_format mesa_format,
+                          unsigned pitch,
+                          unsigned width,
+                          unsigned height)
+{
+    BATCH_LOCALS(&r300->radeon);
+
+    unsigned x1, y1, x2, y2;
+    x1 = 0;
+    y1 = 0;
+    x2 = width - 1;
+    y2 = height - 1;
+
+    if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
+        x1 += R300_SCISSORS_OFFSET;
+        y1 += R300_SCISSORS_OFFSET;
+        x2 += R300_SCISSORS_OFFSET;
+        y2 += R300_SCISSORS_OFFSET;
+    }
+
+    r300_emit_cb_setup(r300, bo, offset, mesa_format,
+                       _mesa_get_format_bytes(mesa_format),
+                       _mesa_format_row_stride(mesa_format, pitch));
+
+    BEGIN_BATCH_NO_AUTOSTATE(5);
+    OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2);
+    OUT_BATCH((x1 << R300_SCISSORS_X_SHIFT)|(y1 << R300_SCISSORS_Y_SHIFT));
+    OUT_BATCH((x2 << R300_SCISSORS_X_SHIFT)|(y2 << R300_SCISSORS_Y_SHIFT));
+    OUT_BATCH_REGVAL(R300_RB3D_CCTL, 0);
+    END_BATCH();
+}
+
+/**
+ * Copy a region of [@a width x @a height] pixels from source buffer
+ * to destination buffer.
+ * @param[in] r300 r300 context
+ * @param[in] src_bo source radeon buffer object
+ * @param[in] src_offset offset of the source image in the @a src_bo
+ * @param[in] src_mesaformat source image format
+ * @param[in] src_pitch aligned source image width
+ * @param[in] src_width source image width
+ * @param[in] src_height source image height
+ * @param[in] src_x_offset x offset in the source image
+ * @param[in] src_y_offset y offset in the source image
+ * @param[in] dst_bo destination radeon buffer object
+ * @param[in] dst_offset offset of the destination image in the @a dst_bo
+ * @param[in] dst_mesaformat destination image format
+ * @param[in] dst_pitch aligned destination image width
+ * @param[in] dst_width destination image width
+ * @param[in] dst_height destination image height
+ * @param[in] dst_x_offset x offset in the destination image
+ * @param[in] dst_y_offset y offset in the destination image
+ * @param[in] width region width
+ * @param[in] height region height
+ * @param[in] flip_y set if y coords of the source image need to be flipped
+ */
+GLboolean r300_blit(struct r300_context *r300,
+                    struct radeon_bo *src_bo,
+                    intptr_t src_offset,
+                    gl_format src_mesaformat,
+                    unsigned src_pitch,
+                    unsigned src_width,
+                    unsigned src_height,
+                    unsigned src_x_offset,
+                    unsigned src_y_offset,
+                    struct radeon_bo *dst_bo,
+                    intptr_t dst_offset,
+                    gl_format dst_mesaformat,
+                    unsigned dst_pitch,
+                    unsigned dst_width,
+                    unsigned dst_height,
+                    unsigned dst_x_offset,
+                    unsigned dst_y_offset,
+                    unsigned reg_width,
+                    unsigned reg_height,
+                    unsigned flip_y)
+{
+    if (_mesa_get_format_bits(src_mesaformat, GL_DEPTH_BITS) > 0)
+        return GL_FALSE;
+
+    /* Make sure that colorbuffer has even width - hw limitation */
+    if (dst_pitch % 2 > 0)
+        ++dst_pitch;
+
+    /* Rendering to small buffer doesn't work.
+     * Looks like a hw limitation.
+     */
+    if (dst_pitch < 32)
+        return GL_FALSE;
+
+    /* Need to clamp the region size to make sure
+     * we don't read outside of the source buffer
+     * or write outside of the destination buffer.
+     */
+    if (reg_width + src_x_offset > src_width)
+        reg_width = src_width - src_x_offset;
+    if (reg_height + src_y_offset > src_height)
+        reg_height = src_height - src_y_offset;
+    if (reg_width + dst_x_offset > dst_width)
+        reg_width = dst_width - dst_x_offset;
+    if (reg_height + dst_y_offset > dst_height)
+        reg_height = dst_height - dst_y_offset;
+
+    if (src_bo == dst_bo) {
+        return GL_FALSE;
+    }
+
+    if (0) {
+        fprintf(stderr, "src: size [%d x %d], pitch %d, "
+                "offset [%d x %d], format %s, bo %p\n",
+                src_width, src_height, src_pitch,
+                src_x_offset, src_y_offset,
+                _mesa_get_format_name(src_mesaformat),
+                src_bo);
+        fprintf(stderr, "dst: pitch %d, offset[%d x %d], format %s, bo %p\n",
+                dst_pitch, dst_x_offset, dst_y_offset,
+                _mesa_get_format_name(dst_mesaformat), dst_bo);
+        fprintf(stderr, "region: %d x %d\n", reg_width, reg_height);
+    }
+
+    /* Flush is needed to make sure that source buffer has correct data */
+    radeonFlush(r300->radeon.glCtx);
+
+    if (!validate_buffers(r300, src_bo, dst_bo))
+        return GL_FALSE;
+
+    rcommonEnsureCmdBufSpace(&r300->radeon, 200, __FUNCTION__);
+
+    other_stuff(r300);
+
+    r300_emit_tx_setup(r300, src_mesaformat, src_bo, src_offset, src_width, src_height, src_pitch);
+
+    if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
+        r500_emit_fp_setup(r300, &r300->blit.fp_code.code.r500, dst_mesaformat);
+        r500_emit_rs_setup(r300);
+    } else {
+        r300_emit_fp_setup(r300, &r300->blit.fp_code.code.r300, dst_mesaformat);
+        r300_emit_rs_setup(r300);
+    }
+
+    emit_pvs_setup(r300, r300->blit.vp_code.body.d, 2);
+    emit_vap_setup(r300);
+
+    emit_cb_setup(r300, dst_bo, dst_offset, dst_mesaformat, dst_pitch, dst_width, dst_height);
+
+    emit_draw_packet(r300, src_width, src_height,
+                     src_x_offset, src_y_offset,
+                     dst_x_offset, dst_y_offset,
+                     reg_width, reg_height,
+                     flip_y);
+
+    r300EmitCacheFlush(r300);
+
+    radeonFlush(r300->radeon.glCtx);
+
+    return GL_TRUE;
+}
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r300/r300_blit.h b/src/mesa/drivers/dri/r300/r300_blit.h
new file mode 100644
index 0000000..dc21e88
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/r300_blit.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com>
+ *
+ * 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, sublicense, 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 NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+ *
+ */
+
+#ifndef R300_BLIT_H
+#define R300_BLIT_H
+
+void r300_blit_init(struct r300_context *r300);
+
+GLboolean r300_blit(struct r300_context *r300,
+                    struct radeon_bo *src_bo,
+                    intptr_t src_offset,
+                    gl_format src_mesaformat,
+                    unsigned src_pitch,
+                    unsigned src_width,
+                    unsigned src_height,
+                    unsigned src_x_offset,
+                    unsigned src_y_offset,
+                    struct radeon_bo *dst_bo,
+                    intptr_t dst_offset,
+                    gl_format dst_mesaformat,
+                    unsigned dst_pitch,
+                    unsigned dst_width,
+                    unsigned dst_height,
+                    unsigned dst_x_offset,
+                    unsigned dst_y_offset,
+                    unsigned width,
+                    unsigned height,
+                    unsigned flip_y);
+
+#endif // R300_BLIT_H
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
index 1e2a54f..e1c33bb 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
@@ -45,15 +45,12 @@
 #include "radeon_drm.h"
 
 #include "r300_context.h"
-#include "r300_ioctl.h"
-#include "radeon_reg.h"
 #include "r300_reg.h"
 #include "r300_cmdbuf.h"
 #include "r300_emit.h"
 #include "radeon_bocs_wrapper.h"
 #include "radeon_mipmap_tree.h"
 #include "r300_state.h"
-#include "radeon_reg.h"
 #include "radeon_queryobj.h"
 
 /** # of dwords reserved for additional instructions that may need to be written
@@ -74,7 +71,7 @@
 #define vpu_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
 #define r500fp_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->r500fp.count)
 
-int check_vpu(GLcontext *ctx, struct radeon_state_atom *atom)
+static int check_vpu(GLcontext *ctx, struct radeon_state_atom *atom)
 {
 	r300ContextPtr r300 = R300_CONTEXT(ctx);
 	int cnt;
@@ -88,54 +85,73 @@
 	return cnt ? (cnt * 4) + extra : 0;
 }
 
-
-void emit_vpu(GLcontext *ctx, struct radeon_state_atom * atom)
+void r300_emit_vpu(struct r300_context *r300,
+                   uint32_t *data,
+                   unsigned len,
+                   uint32_t addr)
 {
-	r300ContextPtr r300 = R300_CONTEXT(ctx);
-	BATCH_LOCALS(&r300->radeon);
-	drm_r300_cmd_header_t cmd;
-	uint32_t addr, ndw;
+    BATCH_LOCALS(&r300->radeon);
 
-	cmd.u = atom->cmd[0];
-	addr = (cmd.vpu.adrhi << 8) | cmd.vpu.adrlo;
-	ndw = atom->check(ctx, atom);
-
-	BEGIN_BATCH_NO_AUTOSTATE(ndw);
-
-	ndw -= 5;
-	OUT_BATCH_REGVAL(R300_VAP_PVS_VECTOR_INDX_REG, addr);
-	OUT_BATCH(CP_PACKET0(R300_VAP_PVS_UPLOAD_DATA, ndw-1) | RADEON_ONE_REG_WR);
-	OUT_BATCH_TABLE(&atom->cmd[1], ndw);
-	OUT_BATCH_REGVAL(R300_VAP_PVS_STATE_FLUSH_REG, 0);
-	END_BATCH();
+    BEGIN_BATCH_NO_AUTOSTATE(5 + len);
+    OUT_BATCH_REGVAL(R300_VAP_PVS_STATE_FLUSH_REG, 0);
+    OUT_BATCH_REGVAL(R300_VAP_PVS_VECTOR_INDX_REG, addr);
+    OUT_BATCH(CP_PACKET0(R300_VAP_PVS_UPLOAD_DATA, len-1) | RADEON_ONE_REG_WR);
+    OUT_BATCH_TABLE(data, len);
+    END_BATCH();
 }
 
-void emit_r500fp(GLcontext *ctx, struct radeon_state_atom * atom)
+static void emit_vpu_state(GLcontext *ctx, struct radeon_state_atom * atom)
 {
-	r300ContextPtr r300 = R300_CONTEXT(ctx);
-	BATCH_LOCALS(&r300->radeon);
-	drm_r300_cmd_header_t cmd;
-	uint32_t addr, ndw, sz;
-	int type, clamp;
+    r300ContextPtr r300 = R300_CONTEXT(ctx);
+    drm_r300_cmd_header_t cmd;
+    uint32_t addr, ndw;
 
-	ndw = atom->check(ctx, atom);
+    cmd.u = atom->cmd[0];
+    addr = (cmd.vpu.adrhi << 8) | cmd.vpu.adrlo;
+    ndw = atom->check(ctx, atom);
 
-	cmd.u = atom->cmd[0];
-	sz = cmd.r500fp.count;
-	addr = ((cmd.r500fp.adrhi_flags & 1) << 8) | cmd.r500fp.adrlo;
-	type = !!(cmd.r500fp.adrhi_flags & R500FP_CONSTANT_TYPE);
-	clamp = !!(cmd.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP);
+    r300_emit_vpu(r300, &atom->cmd[1], vpu_count(atom->cmd) * 4, addr);
+}
 
-	addr |= (type << 16);
-	addr |= (clamp << 17);
+void r500_emit_fp(struct r300_context *r300,
+                  uint32_t *data,
+                  unsigned len,
+                  uint32_t addr,
+                  unsigned type,
+                  unsigned clamp)
+{
+    BATCH_LOCALS(&r300->radeon);
 
-	BEGIN_BATCH_NO_AUTOSTATE(ndw);
-	OUT_BATCH(CP_PACKET0(R500_GA_US_VECTOR_INDEX, 0));
-	OUT_BATCH(addr);
-	ndw-=3;
-	OUT_BATCH(CP_PACKET0(R500_GA_US_VECTOR_DATA, ndw-1) | RADEON_ONE_REG_WR);
-	OUT_BATCH_TABLE(&atom->cmd[1], ndw);
-	END_BATCH();
+    addr |= (type << 16);
+    addr |= (clamp << 17);
+
+    BEGIN_BATCH_NO_AUTOSTATE(len + 3);
+    OUT_BATCH(CP_PACKET0(R500_GA_US_VECTOR_INDEX, 0));
+    OUT_BATCH(addr);
+    OUT_BATCH(CP_PACKET0(R500_GA_US_VECTOR_DATA, len-1) | RADEON_ONE_REG_WR);
+    OUT_BATCH_TABLE(data, len);
+    END_BATCH();
+}
+
+static void emit_r500fp_atom(GLcontext *ctx, struct radeon_state_atom * atom)
+{
+    r300ContextPtr r300 = R300_CONTEXT(ctx);
+    drm_r300_cmd_header_t cmd;
+    uint32_t addr, count;
+    int type, clamp;
+
+    cmd.u = atom->cmd[0];
+    addr = ((cmd.r500fp.adrhi_flags & 1) << 8) | cmd.r500fp.adrlo;
+    type = !!(cmd.r500fp.adrhi_flags & R500FP_CONSTANT_TYPE);
+    clamp = !!(cmd.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP);
+
+    if (type) {
+        count = r500fp_count(atom->cmd) * 4;
+    } else {
+        count = r500fp_count(atom->cmd) * 6;
+    }
+
+    r500_emit_fp(r300, &atom->cmd[1], count, addr, type, clamp);
 }
 
 static int check_tex_offsets(GLcontext *ctx, struct radeon_state_atom * atom)
@@ -171,7 +187,7 @@
 		if (t && !t->image_override) {
 			BEGIN_BATCH_NO_AUTOSTATE(4);
 			OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
-			OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0,
+			OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, get_base_teximage_offset(t),
 					RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
 			END_BATCH();
 		} else if (!t) {
@@ -258,95 +274,136 @@
 	return dw;
 }
 
-static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom)
+static void emit_scissor(struct r300_context *r300,
+                         unsigned width,
+                         unsigned height)
 {
-	r300ContextPtr r300 = R300_CONTEXT(ctx);
-	BATCH_LOCALS(&r300->radeon);
-	struct radeon_renderbuffer *rrb;
-	uint32_t cbpitch;
-	uint32_t offset = r300->radeon.state.color.draw_offset;
-	uint32_t dw = 6;
-	int i;
-
-	rrb = radeon_get_colorbuffer(&r300->radeon);
-	if (!rrb || !rrb->bo) {
-		fprintf(stderr, "no rrb\n");
-		return;
-	}
-
-        if (RADEON_DEBUG & RADEON_STATE)
-           fprintf(stderr,"rrb is %p %d %dx%d\n", rrb, offset, rrb->base.Width, rrb->base.Height);
-	cbpitch = (rrb->pitch / rrb->cpp);
-	if (rrb->cpp == 4)
-		cbpitch |= R300_COLOR_FORMAT_ARGB8888;
-	else switch (rrb->base.Format) {
-        case MESA_FORMAT_RGB565:
-		cbpitch |= R300_COLOR_FORMAT_RGB565;
-		break;
-        case MESA_FORMAT_ARGB4444:
-		cbpitch |= R300_COLOR_FORMAT_ARGB4444;
-		break;
-	case MESA_FORMAT_ARGB1555:
-		cbpitch |= R300_COLOR_FORMAT_ARGB1555;
-		break;
-	default:
-		_mesa_problem(ctx, "unexpected format in emit_cb_offset()");
-	}
-
-	if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
-		cbpitch |= R300_COLOR_TILE_ENABLE;
-
-    	if (r300->radeon.radeonScreen->kernel_mm)
-		dw += 2;
-	BEGIN_BATCH_NO_AUTOSTATE(dw);
-	OUT_BATCH_REGSEQ(R300_RB3D_COLOROFFSET0, 1);
-	OUT_BATCH_RELOC(offset, rrb->bo, offset, 0, RADEON_GEM_DOMAIN_VRAM, 0);
-	OUT_BATCH_REGSEQ(R300_RB3D_COLORPITCH0, 1);
-    	if (!r300->radeon.radeonScreen->kernel_mm)
-		OUT_BATCH(cbpitch);
-	else
-		OUT_BATCH_RELOC(cbpitch, rrb->bo, cbpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0);
-	END_BATCH();
-    if (r300->radeon.radeonScreen->driScreen->dri2.enabled) {
-        if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
-            BEGIN_BATCH_NO_AUTOSTATE(3);
-            OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2);
-            OUT_BATCH(0);
-            OUT_BATCH(((rrb->base.Width - 1) << R300_SCISSORS_X_SHIFT) |
-                    ((rrb->base.Height - 1) << R300_SCISSORS_Y_SHIFT));
-            END_BATCH();
-            BEGIN_BATCH_NO_AUTOSTATE(16);
-            for (i = 0; i < 4; i++) {
-                OUT_BATCH_REGSEQ(R300_SC_CLIPRECT_TL_0 + (i * 8), 2);
-                OUT_BATCH((0 << R300_CLIPRECT_X_SHIFT) | (0 << R300_CLIPRECT_Y_SHIFT));
-                OUT_BATCH(((rrb->base.Width - 1) << R300_CLIPRECT_X_SHIFT) | ((rrb->base.Height - 1) << R300_CLIPRECT_Y_SHIFT));
-            }
-            OUT_BATCH_REGSEQ(R300_SC_CLIP_RULE, 1);
-            OUT_BATCH(0xAAAA);
-            OUT_BATCH_REGSEQ(R300_SC_SCREENDOOR, 1);
-            OUT_BATCH(0xffffff);
-            END_BATCH();
-        } else {
-            BEGIN_BATCH_NO_AUTOSTATE(3);
-            OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2);
-            OUT_BATCH((R300_SCISSORS_OFFSET << R300_SCISSORS_X_SHIFT) |
-                    (R300_SCISSORS_OFFSET << R300_SCISSORS_Y_SHIFT));
-            OUT_BATCH(((rrb->base.Width + R300_SCISSORS_OFFSET - 1) << R300_SCISSORS_X_SHIFT) |
-                    ((rrb->base.Height + R300_SCISSORS_OFFSET - 1) << R300_SCISSORS_Y_SHIFT));
-            END_BATCH();
-            BEGIN_BATCH_NO_AUTOSTATE(16);
-            for (i = 0; i < 4; i++) {
-                OUT_BATCH_REGSEQ(R300_SC_CLIPRECT_TL_0 + (i * 8), 2);
-                OUT_BATCH((R300_SCISSORS_OFFSET << R300_CLIPRECT_X_SHIFT) | (R300_SCISSORS_OFFSET << R300_CLIPRECT_Y_SHIFT));
-                OUT_BATCH(((R300_SCISSORS_OFFSET + rrb->base.Width - 1) << R300_CLIPRECT_X_SHIFT) |
-                          ((R300_SCISSORS_OFFSET + rrb->base.Height - 1) << R300_CLIPRECT_Y_SHIFT));
-            }
-            OUT_BATCH_REGSEQ(R300_SC_CLIP_RULE, 1);
-            OUT_BATCH(0xAAAA);
-            OUT_BATCH_REGSEQ(R300_SC_SCREENDOOR, 1);
-            OUT_BATCH(0xffffff);
-            END_BATCH();
+    int i;
+    BATCH_LOCALS(&r300->radeon);
+    if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
+        BEGIN_BATCH_NO_AUTOSTATE(3);
+        OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2);
+        OUT_BATCH(0);
+        OUT_BATCH(((width - 1) << R300_SCISSORS_X_SHIFT) |
+                ((height - 1) << R300_SCISSORS_Y_SHIFT));
+        END_BATCH();
+        BEGIN_BATCH_NO_AUTOSTATE(16);
+        for (i = 0; i < 4; i++) {
+            OUT_BATCH_REGSEQ(R300_SC_CLIPRECT_TL_0 + (i * 8), 2);
+            OUT_BATCH((0 << R300_CLIPRECT_X_SHIFT) | (0 << R300_CLIPRECT_Y_SHIFT));
+            OUT_BATCH(((width - 1) << R300_CLIPRECT_X_SHIFT) | ((height - 1) << R300_CLIPRECT_Y_SHIFT));
         }
+        OUT_BATCH_REGSEQ(R300_SC_CLIP_RULE, 1);
+        OUT_BATCH(0xAAAA);
+        OUT_BATCH_REGSEQ(R300_SC_SCREENDOOR, 1);
+        OUT_BATCH(0xffffff);
+        END_BATCH();
+    } else {
+        BEGIN_BATCH_NO_AUTOSTATE(3);
+        OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL, 2);
+        OUT_BATCH((R300_SCISSORS_OFFSET << R300_SCISSORS_X_SHIFT) |
+                (R300_SCISSORS_OFFSET << R300_SCISSORS_Y_SHIFT));
+        OUT_BATCH(((width + R300_SCISSORS_OFFSET - 1) << R300_SCISSORS_X_SHIFT) |
+                ((height + R300_SCISSORS_OFFSET - 1) << R300_SCISSORS_Y_SHIFT));
+        END_BATCH();
+        BEGIN_BATCH_NO_AUTOSTATE(16);
+        for (i = 0; i < 4; i++) {
+            OUT_BATCH_REGSEQ(R300_SC_CLIPRECT_TL_0 + (i * 8), 2);
+            OUT_BATCH((R300_SCISSORS_OFFSET << R300_CLIPRECT_X_SHIFT) | (R300_SCISSORS_OFFSET << R300_CLIPRECT_Y_SHIFT));
+            OUT_BATCH(((R300_SCISSORS_OFFSET + width - 1) << R300_CLIPRECT_X_SHIFT) |
+                        ((R300_SCISSORS_OFFSET + height - 1) << R300_CLIPRECT_Y_SHIFT));
+        }
+        OUT_BATCH_REGSEQ(R300_SC_CLIP_RULE, 1);
+        OUT_BATCH(0xAAAA);
+        OUT_BATCH_REGSEQ(R300_SC_SCREENDOOR, 1);
+        OUT_BATCH(0xffffff);
+        END_BATCH();
+    }
+}
+
+void r300_emit_cb_setup(struct r300_context *r300,
+                        struct radeon_bo *bo,
+                        uint32_t offset,
+                        GLuint format,
+                        unsigned cpp,
+                        unsigned pitch)
+{
+    BATCH_LOCALS(&r300->radeon);
+    uint32_t cbpitch = pitch / cpp;
+    uint32_t dw = 6;
+
+    assert(offset % 32 == 0);
+
+    switch (format) {
+        case MESA_FORMAT_RGB565:
+            assert(_mesa_little_endian());
+            cbpitch |= R300_COLOR_FORMAT_RGB565;
+            break;
+        case MESA_FORMAT_RGB565_REV:
+            assert(!_mesa_little_endian());
+            cbpitch |= R300_COLOR_FORMAT_RGB565;
+            break;
+        case MESA_FORMAT_ARGB4444:
+            assert(_mesa_little_endian());
+            cbpitch |= R300_COLOR_FORMAT_ARGB4444;
+            break;
+        case MESA_FORMAT_ARGB4444_REV:
+            assert(!_mesa_little_endian());
+            cbpitch |= R300_COLOR_FORMAT_ARGB4444;
+            break;
+        case MESA_FORMAT_ARGB1555:
+            assert(_mesa_little_endian());
+            cbpitch |= R300_COLOR_FORMAT_ARGB1555;
+            break;
+        case MESA_FORMAT_ARGB1555_REV:
+            assert(!_mesa_little_endian());
+            cbpitch |= R300_COLOR_FORMAT_ARGB1555;
+            break;
+        default:
+            if (cpp == 4) {
+                cbpitch |= R300_COLOR_FORMAT_ARGB8888;
+            } else {
+                _mesa_problem(r300->radeon.glCtx, "unexpected format in emit_cb_offset()");;
+            }
+            break;
+    }
+
+    if (bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
+        cbpitch |= R300_COLOR_TILE_ENABLE;
+
+    if (r300->radeon.radeonScreen->kernel_mm)
+        dw += 2;
+
+    BEGIN_BATCH_NO_AUTOSTATE(dw);
+    OUT_BATCH_REGSEQ(R300_RB3D_COLOROFFSET0, 1);
+    OUT_BATCH_RELOC(offset, bo, offset, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+    OUT_BATCH_REGSEQ(R300_RB3D_COLORPITCH0, 1);
+    if (!r300->radeon.radeonScreen->kernel_mm)
+        OUT_BATCH(cbpitch);
+    else
+        OUT_BATCH_RELOC(cbpitch, bo, cbpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+    END_BATCH();
+}
+
+static void emit_cb_offset_atom(GLcontext *ctx, struct radeon_state_atom * atom)
+{
+    r300ContextPtr r300 = R300_CONTEXT(ctx);
+    struct radeon_renderbuffer *rrb;
+    uint32_t offset = r300->radeon.state.color.draw_offset;
+
+    rrb = radeon_get_colorbuffer(&r300->radeon);
+    if (!rrb || !rrb->bo) {
+        fprintf(stderr, "no rrb\n");
+        return;
+    }
+
+    if (RADEON_DEBUG & RADEON_STATE)
+        fprintf(stderr,"rrb is %p %d %dx%d\n", rrb, offset, rrb->base.Width, rrb->base.Height);
+
+    r300_emit_cb_setup(r300, rrb->bo, offset, rrb->base.Format, rrb->cpp, rrb->pitch);
+
+    if (r300->radeon.radeonScreen->driScreen->dri2.enabled) {
+        emit_scissor(r300, rrb->base.Width, rrb->base.Height);
     }
 }
 
@@ -442,7 +499,7 @@
 	return cnt ? cnt + 1 : 0;
 }
 
-int check_r500fp(GLcontext *ctx, struct radeon_state_atom *atom)
+static int check_r500fp(GLcontext *ctx, struct radeon_state_atom *atom)
 {
 	int cnt;
 	r300ContextPtr r300 = R300_CONTEXT(ctx);
@@ -454,7 +511,7 @@
 	return cnt ? (cnt * 6) + extra : 0;
 }
 
-int check_r500fp_const(GLcontext *ctx, struct radeon_state_atom *atom)
+static int check_r500fp_const(GLcontext *ctx, struct radeon_state_atom *atom)
 {
 	int cnt;
 	r300ContextPtr r300 = R300_CONTEXT(ctx);
@@ -631,13 +688,13 @@
 		r300->hw.r500fp.cmd[R300_FPI_CMD_0] =
 			cmdr500fp(r300->radeon.radeonScreen, 0, 0, 0, 0);
 		if (r300->radeon.radeonScreen->kernel_mm)
-			r300->hw.r500fp.emit = emit_r500fp;
+			r300->hw.r500fp.emit = emit_r500fp_atom;
 
 		ALLOC_STATE(r500fp_const, r500fp_const, R500_FPP_CMDSIZE, 0);
 		r300->hw.r500fp_const.cmd[R300_FPI_CMD_0] =
 			cmdr500fp(r300->radeon.radeonScreen, 0, 0, 1, 0);
 		if (r300->radeon.radeonScreen->kernel_mm)
-			r300->hw.r500fp_const.emit = emit_r500fp;
+			r300->hw.r500fp_const.emit = emit_r500fp_atom;
 	} else {
 		ALLOC_STATE(fp, always, R300_FP_CMDSIZE, 0);
 		r300->hw.fp.cmd[R300_FP_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_CONFIG, 3);
@@ -681,7 +738,7 @@
 	ALLOC_STATE(rop, always, 2, 0);
 	r300->hw.rop.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_ROPCNTL, 1);
 	ALLOC_STATE(cb, cb_offset, R300_CB_CMDSIZE, 0);
-	r300->hw.cb.emit = &emit_cb_offset;
+	r300->hw.cb.emit = &emit_cb_offset_atom;
 	ALLOC_STATE(rb3d_dither_ctl, always, 10, 0);
 	r300->hw.rb3d_dither_ctl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_DITHER_CTL, 9);
 	ALLOC_STATE(rb3d_aaresolve_ctl, always, 2, 0);
@@ -745,20 +802,20 @@
 		r300->hw.vpi.cmd[0] =
 			cmdvpu(r300->radeon.radeonScreen, R300_PVS_CODE_START, 0);
 		if (r300->radeon.radeonScreen->kernel_mm)
-			r300->hw.vpi.emit = emit_vpu;
+			r300->hw.vpi.emit = emit_vpu_state;
 
 		if (is_r500) {
 			ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0);
 			r300->hw.vpp.cmd[0] =
 				cmdvpu(r300->radeon.radeonScreen, R500_PVS_CONST_START, 0);
 			if (r300->radeon.radeonScreen->kernel_mm)
-				r300->hw.vpp.emit = emit_vpu;
+				r300->hw.vpp.emit = emit_vpu_state;
 
 			ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0);
 			r300->hw.vps.cmd[0] =
 				cmdvpu(r300->radeon.radeonScreen, R500_POINT_VPORT_SCALE_OFFSET, 1);
 			if (r300->radeon.radeonScreen->kernel_mm)
-				r300->hw.vps.emit = emit_vpu;
+				r300->hw.vps.emit = emit_vpu_state;
 
 			for (i = 0; i < 6; i++) {
 				ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0);
@@ -766,20 +823,20 @@
 					cmdvpu(r300->radeon.radeonScreen,
 							R500_PVS_UCP_START + i, 1);
 				if (r300->radeon.radeonScreen->kernel_mm)
-					r300->hw.vpucp[i].emit = emit_vpu;
+					r300->hw.vpucp[i].emit = emit_vpu_state;
 			}
 		} else {
 			ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0);
 			r300->hw.vpp.cmd[0] =
 				cmdvpu(r300->radeon.radeonScreen, R300_PVS_CONST_START, 0);
 			if (r300->radeon.radeonScreen->kernel_mm)
-				r300->hw.vpp.emit = emit_vpu;
+				r300->hw.vpp.emit = emit_vpu_state;
 
 			ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0);
 			r300->hw.vps.cmd[0] =
 				cmdvpu(r300->radeon.radeonScreen, R300_POINT_VPORT_SCALE_OFFSET, 1);
 			if (r300->radeon.radeonScreen->kernel_mm)
-				r300->hw.vps.emit = emit_vpu;
+				r300->hw.vps.emit = emit_vpu_state;
 
 			for (i = 0; i < 6; i++) {
 				ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0);
@@ -787,7 +844,7 @@
 					cmdvpu(r300->radeon.radeonScreen,
 							R300_PVS_UCP_START + i, 1);
 				if (r300->radeon.radeonScreen->kernel_mm)
-					r300->hw.vpucp[i].emit = emit_vpu;
+					r300->hw.vpucp[i].emit = emit_vpu_state;
 			}
 		}
 	}
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.h b/src/mesa/drivers/dri/r300/r300_cmdbuf.h
index 1b703e5..0e68da9 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.h
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.h
@@ -44,14 +44,26 @@
 #define FIREAOS_BUFSZ          (3)
 #define SCISSORS_BUFSZ         (3)
 
-extern void r300InitCmdBuf(r300ContextPtr r300);
+void r300InitCmdBuf(r300ContextPtr r300);
 void r300_emit_scissor(GLcontext *ctx);
 
-void emit_vpu(GLcontext *ctx, struct radeon_state_atom * atom);
-int check_vpu(GLcontext *ctx, struct radeon_state_atom *atom);
+void r300_emit_vpu(struct r300_context *ctx,
+                   uint32_t *data,
+                   unsigned len,
+                   uint32_t addr);
 
-void emit_r500fp(GLcontext *ctx, struct radeon_state_atom * atom);
-int check_r500fp(GLcontext *ctx, struct radeon_state_atom *atom);
-int check_r500fp_const(GLcontext *ctx, struct radeon_state_atom *atom);
+void r500_emit_fp(struct r300_context *r300,
+                  uint32_t *data,
+                  unsigned len,
+                  uint32_t addr,
+                  unsigned type,
+                  unsigned clamp);
 
-#endif				/* __R300_CMDBUF_H__ */
+void r300_emit_cb_setup(struct r300_context *r300,
+                        struct radeon_bo *bo,
+                        uint32_t offset,
+                        GLuint format,
+                        unsigned cpp,
+                        unsigned pitch);
+
+#endif /* __R300_CMDBUF_H__ */
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index 6f66e97..1f6ccf6 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -55,13 +55,14 @@
 #include "tnl/t_vp_build.h"
 
 #include "drivers/common/driverfuncs.h"
+#include "drivers/common/meta.h"
 
 #include "r300_context.h"
 #include "radeon_context.h"
 #include "radeon_span.h"
+#include "r300_blit.h"
 #include "r300_cmdbuf.h"
 #include "r300_state.h"
-#include "r300_ioctl.h"
 #include "r300_tex.h"
 #include "r300_emit.h"
 #include "r300_swtcl.h"
@@ -92,6 +93,7 @@
 
 #include "main/remap_helper.h"
 
+void r300_init_texcopy_functions(struct dd_function_table *table);
 
 static const struct dri_extension card_extensions[] = {
   /* *INDENT-OFF* */
@@ -439,11 +441,11 @@
 	if (r300->options.stencil_two_side_disabled)
 		_mesa_disable_extension(ctx, "GL_EXT_stencil_two_side");
 
-	if (r300->options.s3tc_force_enabled) {
+	if (r300->options.s3tc_force_disabled) {
+		_mesa_disable_extension(ctx, "GL_EXT_texture_compression_s3tc");
+	} else if (ctx->Mesa_DXTn || r300->options.s3tc_force_enabled) {
 		_mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
 		_mesa_enable_extension(ctx, "GL_S3_s3tc");
-	} else if (r300->options.s3tc_force_disabled) {
-		_mesa_disable_extension(ctx, "GL_EXT_texture_compression_s3tc");
 	}
 
 	if (!r300->radeon.radeonScreen->drmSupportsOcclusionQueries) {
@@ -451,13 +453,20 @@
 	}
 }
 
+static void r300InitIoctlFuncs(struct dd_function_table *functions)
+{
+	functions->Clear = _mesa_meta_Clear;
+	functions->Finish = radeonFinish;
+	functions->Flush = radeonFlush;
+}
+
 /* Create the device specific rendering context.
  */
 GLboolean r300CreateContext(const __GLcontextModes * glVisual,
-			    __DRIcontextPrivate * driContextPriv,
+			    __DRIcontext * driContextPriv,
 			    void *sharedContextPrivate)
 {
-	__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+	__DRIscreen *sPriv = driContextPriv->driScreenPriv;
 	radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
 	struct dd_function_table functions;
 	r300ContextPtr r300;
@@ -484,6 +493,10 @@
 	radeonInitQueryObjFunctions(&functions);
 	radeonInitBufferObjectFuncs(&functions);
 
+	if (r300->radeon.radeonScreen->kernel_mm) {
+		r300_init_texcopy_functions(&functions);
+	}
+
 	if (!radeonInitContext(&r300->radeon, &functions,
 			       glVisual, driContextPriv,
 			       sharedContextPrivate)) {
@@ -530,6 +543,7 @@
 		r300InitSwtcl(ctx);
 	}
 
+	r300_blit_init(r300);
 	radeon_fbo_init(&r300->radeon);
 	radeonInitSpanFuncs( ctx );
 	r300InitCmdBuf(r300);
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
index 518d5cd..546cd8d 100644
--- a/src/mesa/drivers/dri/r300/r300_context.h
+++ b/src/mesa/drivers/dri/r300/r300_context.h
@@ -533,14 +533,19 @@
 
 	uint32_t fallback;
 
+	struct {
+		struct r300_vertex_program_code vp_code;
+		struct rX00_fragment_program_code fp_code;
+	} blit;
+
 	DECLARE_RENDERINPUTS(render_inputs_bitset);
 };
 
 #define R300_CONTEXT(ctx)		((r300ContextPtr)(ctx->DriverCtx))
 
-extern void r300DestroyContext(__DRIcontextPrivate * driContextPriv);
+extern void r300DestroyContext(__DRIcontext * driContextPriv);
 extern GLboolean r300CreateContext(const __GLcontextModes * glVisual,
-				   __DRIcontextPrivate * driContextPriv,
+				   __DRIcontext * driContextPriv,
 				   void *sharedContextPrivate);
 
 extern void r300InitShaderFuncs(struct dd_function_table *functions);
@@ -549,6 +554,8 @@
 
 extern void r300InitDraw(GLcontext *ctx);
 
+extern void r300_init_texcopy_functions(struct dd_function_table *table);
+
 #define r300PackFloat32 radeonPackFloat32
 #define r300PackFloat24 radeonPackFloat24
 
diff --git a/src/mesa/drivers/dri/r300/r300_draw.c b/src/mesa/drivers/dri/r300/r300_draw.c
index e9968f9..3dcd986 100644
--- a/src/mesa/drivers/dri/r300/r300_draw.c
+++ b/src/mesa/drivers/dri/r300/r300_draw.c
@@ -100,7 +100,7 @@
 		GLubyte *in = (GLubyte *)src_ptr;
 
 		radeonAllocDmaRegion(&r300->radeon, &r300->ind_buf.bo, &r300->ind_buf.bo_offset, size, 4);
-
+		radeon_bo_map(r300->ind_buf.bo, 1);
 		assert(r300->ind_buf.bo->ptr != NULL);
 		out = (GLuint *)ADD_POINTERS(r300->ind_buf.bo->ptr, r300->ind_buf.bo_offset);
 
@@ -111,7 +111,7 @@
 		if (i < mesa_ind_buf->count) {
 			*out++ = in[i];
 		}
-
+		radeon_bo_unmap(r300->ind_buf.bo);
 #if MESA_BIG_ENDIAN
 	} else { /* if (mesa_ind_buf->type == GL_UNSIGNED_SHORT) */
 		GLushort *in = (GLushort *)src_ptr;
@@ -120,6 +120,7 @@
 		radeonAllocDmaRegion(&r300->radeon, &r300->ind_buf.bo,
 				     &r300->ind_buf.bo_offset, size, 4);
 
+		radeon_bo_map(r300->ind_buf.bo, 1);
 		assert(r300->ind_buf.bo->ptr != NULL);
 		out = (GLuint *)ADD_POINTERS(r300->ind_buf.bo->ptr, r300->ind_buf.bo_offset);
 
@@ -130,6 +131,7 @@
 		if (i < mesa_ind_buf->count) {
 			*out++ = in[i];
 		}
+		radeon_bo_unmap(r300->ind_buf.bo);
 #endif
 	}
 
@@ -173,10 +175,12 @@
 
 		radeonAllocDmaRegion(&r300->radeon, &r300->ind_buf.bo, &r300->ind_buf.bo_offset, size, 4);
 
+		radeon_bo_map(r300->ind_buf.bo, 1);
 		assert(r300->ind_buf.bo->ptr != NULL);
 		dst_ptr = ADD_POINTERS(r300->ind_buf.bo->ptr, r300->ind_buf.bo_offset);
 		_mesa_memcpy(dst_ptr, src_ptr, size);
 
+		radeon_bo_unmap(r300->ind_buf.bo);
 		r300->ind_buf.is_32bit = (mesa_ind_buf->type == GL_UNSIGNED_INT);
 		r300->ind_buf.count = mesa_ind_buf->count;
 
@@ -242,6 +246,7 @@
 	}
 
 	radeonAllocDmaRegion(&r300->radeon, &attr->bo, &attr->bo_offset, sizeof(GLfloat) * input->Size * count, 32);
+	radeon_bo_map(attr->bo, 1);
 	dst_ptr = (GLfloat *)ADD_POINTERS(attr->bo->ptr, attr->bo_offset);
 
 	radeon_print(RADEON_FALLBACKS, RADEON_IMPORTANT,
@@ -280,6 +285,7 @@
 			break;
 	}
 
+	radeon_bo_unmap(attr->bo);
 	if (mapped_named_bo) {
 		ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj);
 	}
@@ -294,6 +300,8 @@
 
 	radeonAllocDmaRegion(&r300->radeon, &attr->bo, &attr->bo_offset, size, 32);
 
+	radeon_bo_map(attr->bo, 1);
+
 	if (!input->BufferObj->Pointer) {
 		ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj);
 		mapped_named_bo = GL_TRUE;
@@ -317,6 +325,7 @@
 		ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj);
 	}
 
+	radeon_bo_unmap(attr->bo);
 	attr->stride = dst_stride;
 }
 
@@ -527,6 +536,7 @@
 				}
 
 				radeonAllocDmaRegion(&r300->radeon, &vbuf->attribs[index].bo, &vbuf->attribs[index].bo_offset, size, 32);
+				radeon_bo_map(vbuf->attribs[index].bo, 1);
 				assert(vbuf->attribs[index].bo->ptr != NULL);
 				dst = (uint32_t *)ADD_POINTERS(vbuf->attribs[index].bo->ptr, vbuf->attribs[index].bo_offset);
 				switch (vbuf->attribs[index].dwords) {
@@ -536,6 +546,7 @@
 					case 4: radeonEmitVec16(dst, input[i]->Ptr, input[i]->StrideB, local_count); break;
 					default: assert(0); break;
 				}
+				radeon_bo_unmap(vbuf->attribs[index].bo);
 
 			}
 		}
diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c
index 07e6223..15aeaf0 100644
--- a/src/mesa/drivers/dri/r300/r300_emit.c
+++ b/src/mesa/drivers/dri/r300/r300_emit.c
@@ -49,7 +49,6 @@
 #include "r300_context.h"
 #include "r300_state.h"
 #include "r300_emit.h"
-#include "r300_ioctl.h"
 #include "r300_render.h"
 #include "r300_swtcl.h"
 
@@ -118,7 +117,7 @@
 
 	if (first_free_texcoord > 8) {
 		fprintf(stderr, "\tout of free texcoords\n");
-		_mesa_exit(-1);
+		exit(-1);
 	}
 
 	return ret;
diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h
index 8e57e35..a456d88 100644
--- a/src/mesa/drivers/dri/r300/r300_emit.h
+++ b/src/mesa/drivers/dri/r300/r300_emit.h
@@ -42,7 +42,6 @@
 #include "main/glheader.h"
 #include "r300_context.h"
 #include "r300_cmdbuf.h"
-#include "radeon_reg.h"
 
 static INLINE uint32_t cmdpacket0(struct radeon_screen *rscrn,
                                   int reg, int count)
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.c b/src/mesa/drivers/dri/r300/r300_fragprog_common.c
index 267ee81..2933d31 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog_common.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.c
@@ -120,7 +120,7 @@
 		return;
 	}
 
-	rc_transform_fragment_wpos(&compiler->Base, FRAG_ATTRIB_WPOS, fp->wpos_attr);
+	rc_transform_fragment_wpos(&compiler->Base, FRAG_ATTRIB_WPOS, fp->wpos_attr, GL_FALSE);
 }
 
 /**
diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c
deleted file mode 100644
index 5cb04e2..0000000
--- a/src/mesa/drivers/dri/r300/r300_ioctl.c
+++ /dev/null
@@ -1,782 +0,0 @@
-/*
-Copyright (C) The Weather Channel, Inc.  2002.
-Copyright (C) 2004 Nicolai Haehnle.
-All Rights Reserved.
-
-The Weather Channel (TM) funded Tungsten Graphics to develop the
-initial release of the Radeon 8500 driver under the XFree86 license.
-This notice must be preserved.
-
-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, sublicense, 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 NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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
- *
- * \author Keith Whitwell <keith@tungstengraphics.com>
- *
- * \author Nicolai Haehnle <prefect_@gmx.net>
- */
-
-#include <sched.h>
-#include <errno.h>
-
-#include "main/glheader.h"
-#include "main/imports.h"
-#include "main/macros.h"
-#include "main/context.h"
-#include "main/simple_list.h"
-#include "swrast/swrast.h"
-
-#include "radeon_common.h"
-#include "radeon_lock.h"
-#include "r300_context.h"
-#include "r300_ioctl.h"
-#include "r300_cmdbuf.h"
-#include "r300_state.h"
-#include "r300_vertprog.h"
-#include "radeon_reg.h"
-#include "r300_emit.h"
-#include "r300_context.h"
-
-#include "vblank.h"
-
-#define R200_3D_DRAW_IMMD_2      0xC0003500
-
-#define CLEARBUFFER_COLOR	0x1
-#define CLEARBUFFER_DEPTH	0x2
-#define CLEARBUFFER_STENCIL	0x4
-
-#if 1
-
-/**
- * Fragment program helper macros
- */
-
-/* Produce unshifted source selectors */
-#define FP_TMP(idx) (idx)
-#define FP_CONST(idx) ((idx) | (1 << 5))
-
-/* Produce source/dest selector dword */
-#define FP_SELC_MASK_NO		0
-#define FP_SELC_MASK_X		1
-#define FP_SELC_MASK_Y		2
-#define FP_SELC_MASK_XY		3
-#define FP_SELC_MASK_Z		4
-#define FP_SELC_MASK_XZ		5
-#define FP_SELC_MASK_YZ		6
-#define FP_SELC_MASK_XYZ	7
-
-#define FP_SELC(destidx,regmask,outmask,src0,src1,src2) \
-	(((destidx) << R300_ALU_DSTC_SHIFT) |		\
-	 (FP_SELC_MASK_##regmask << 23) |		\
-	 (FP_SELC_MASK_##outmask << 26) |		\
-	 ((src0) << R300_ALU_SRC0C_SHIFT) |		\
-	 ((src1) << R300_ALU_SRC1C_SHIFT) |		\
-	 ((src2) << R300_ALU_SRC2C_SHIFT))
-
-#define FP_SELA_MASK_NO		0
-#define FP_SELA_MASK_W		1
-
-#define FP_SELA(destidx,regmask,outmask,src0,src1,src2) \
-	(((destidx) << R300_ALU_DSTA_SHIFT) |		\
-	 (FP_SELA_MASK_##regmask << 23) |		\
-	 (FP_SELA_MASK_##outmask << 24) |		\
-	 ((src0) << R300_ALU_SRC0A_SHIFT) |		\
-	 ((src1) << R300_ALU_SRC1A_SHIFT) |		\
-	 ((src2) << R300_ALU_SRC2A_SHIFT))
-
-/* Produce unshifted argument selectors */
-#define FP_ARGC(source)	R300_ALU_ARGC_##source
-#define FP_ARGA(source) R300_ALU_ARGA_##source
-#define FP_ABS(arg) ((arg) | (1 << 6))
-#define FP_NEG(arg) ((arg) ^ (1 << 5))
-
-/* Produce instruction dword */
-#define FP_INSTRC(opcode,arg0,arg1,arg2) \
-	(R300_ALU_OUTC_##opcode | 		\
-	((arg0) << R300_ALU_ARG0C_SHIFT) |	\
-	((arg1) << R300_ALU_ARG1C_SHIFT) |	\
-	((arg2) << R300_ALU_ARG2C_SHIFT))
-
-#define FP_INSTRA(opcode,arg0,arg1,arg2) \
-	(R300_ALU_OUTA_##opcode | 		\
-	((arg0) << R300_ALU_ARG0A_SHIFT) |	\
-	((arg1) << R300_ALU_ARG1A_SHIFT) |	\
-	((arg2) << R300_ALU_ARG2A_SHIFT))
-
-#endif
-
-static void r300EmitClearState(GLcontext * ctx);
-
-static void r300ClearBuffer(r300ContextPtr r300, int flags,
-			    struct radeon_renderbuffer *rrb,
-			    struct radeon_renderbuffer *rrbd)
-{
-	BATCH_LOCALS(&r300->radeon);
-	GLcontext *ctx = r300->radeon.glCtx;
-	__DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
-	GLuint cbpitch = 0;
-	r300ContextPtr rmesa = r300;
-
-	if (RADEON_DEBUG & RADEON_IOCTL)
-		fprintf(stderr, "%s: buffer %p (%i,%i %ix%i)\n",
-			__FUNCTION__, rrb, dPriv->x, dPriv->y,
-			dPriv->w, dPriv->h);
-
-	if (rrb) {
-		cbpitch = (rrb->pitch / rrb->cpp);
-		if (rrb->cpp == 4)
-			cbpitch |= R300_COLOR_FORMAT_ARGB8888;
-		else
-			cbpitch |= R300_COLOR_FORMAT_RGB565;
-
-		if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE){
-			cbpitch |= R300_COLOR_TILE_ENABLE;
-        }
-	}
-
-	/* TODO in bufmgr */
-	cp_wait(&r300->radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
-	end_3d(&rmesa->radeon);
-
-	if (flags & CLEARBUFFER_COLOR) {
-		assert(rrb != 0);
-		BEGIN_BATCH_NO_AUTOSTATE(6);
-		OUT_BATCH_REGSEQ(R300_RB3D_COLOROFFSET0, 1);
-		OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
-		OUT_BATCH_REGVAL(R300_RB3D_COLORPITCH0, cbpitch);
-		END_BATCH();
-	}
-#if 1
-	if (flags & (CLEARBUFFER_DEPTH | CLEARBUFFER_STENCIL)) {
-		uint32_t zbpitch = (rrbd->pitch / rrbd->cpp);
-		if (rrbd->bo->flags & RADEON_BO_FLAGS_MACRO_TILE){
-			zbpitch |= R300_DEPTHMACROTILE_ENABLE;
-        }
-		if (rrbd->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){
-            zbpitch |= R300_DEPTHMICROTILE_TILED;
-        }
-		BEGIN_BATCH_NO_AUTOSTATE(6);
-		OUT_BATCH_REGSEQ(R300_ZB_DEPTHOFFSET, 1);
-		OUT_BATCH_RELOC(0, rrbd->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
-		OUT_BATCH_REGSEQ(R300_ZB_DEPTHPITCH, 1);
-		if (!r300->radeon.radeonScreen->kernel_mm)
-			OUT_BATCH(zbpitch);
-		else
-			OUT_BATCH_RELOC(zbpitch, rrbd->bo, zbpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0);
-		END_BATCH();
-	}
-#endif
-	BEGIN_BATCH_NO_AUTOSTATE(6);
-	OUT_BATCH_REGSEQ(RB3D_COLOR_CHANNEL_MASK, 1);
-	if (flags & CLEARBUFFER_COLOR) {
-		OUT_BATCH((ctx->Color.ColorMask[BCOMP] ? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0 : 0) |
-			  (ctx->Color.ColorMask[GCOMP] ? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0 : 0) |
-			  (ctx->Color.ColorMask[RCOMP] ? RB3D_COLOR_CHANNEL_MASK_RED_MASK0 : 0) |
-			  (ctx->Color.ColorMask[ACOMP] ? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0 : 0));
-	} else {
-		OUT_BATCH(0);
-	}
-
-
-	{
-		uint32_t t1, t2;
-
-		t1 = 0x0;
-		t2 = 0x0;
-
-		if (flags & CLEARBUFFER_DEPTH) {
-			t1 |= R300_Z_ENABLE | R300_Z_WRITE_ENABLE;
-			t2 |=
-			    (R300_ZS_ALWAYS << R300_Z_FUNC_SHIFT);
-		}
-
-		if (flags & CLEARBUFFER_STENCIL) {
-			t1 |= R300_STENCIL_ENABLE;
-			t2 |=
-			    (R300_ZS_ALWAYS <<
-			     R300_S_FRONT_FUNC_SHIFT) |
-			    (R300_ZS_REPLACE <<
-			     R300_S_FRONT_SFAIL_OP_SHIFT) |
-			    (R300_ZS_REPLACE <<
-			     R300_S_FRONT_ZPASS_OP_SHIFT) |
-			    (R300_ZS_REPLACE <<
-			     R300_S_FRONT_ZFAIL_OP_SHIFT);
-		}
-
-		OUT_BATCH_REGSEQ(R300_ZB_CNTL, 3);
-		OUT_BATCH(t1);
-		OUT_BATCH(t2);
-		OUT_BATCH(((ctx->Stencil.WriteMask[0] & R300_STENCILREF_MASK) <<
-                   R300_STENCILWRITEMASK_SHIFT) |
-			  (ctx->Stencil.Clear & R300_STENCILREF_MASK));
-		END_BATCH();
-	}
-
-	if (!rmesa->radeon.radeonScreen->kernel_mm) {
-		BEGIN_BATCH_NO_AUTOSTATE(9);
-		OUT_BATCH(cmdpacket3(r300->radeon.radeonScreen, R300_CMD_PACKET3_CLEAR));
-		OUT_BATCH_FLOAT32(dPriv->w / 2.0);
-		OUT_BATCH_FLOAT32(dPriv->h / 2.0);
-		OUT_BATCH_FLOAT32(ctx->Depth.Clear);
-		OUT_BATCH_FLOAT32(1.0);
-		OUT_BATCH_FLOAT32(ctx->Color.ClearColor[0]);
-		OUT_BATCH_FLOAT32(ctx->Color.ClearColor[1]);
-		OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]);
-		OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]);
-		END_BATCH();
-	} else {
-		OUT_BATCH(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8));
-		OUT_BATCH(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING |
-			  (1 << R300_PRIM_NUM_VERTICES_SHIFT));
-		OUT_BATCH_FLOAT32(dPriv->w / 2.0);
-		OUT_BATCH_FLOAT32(dPriv->h / 2.0);
-		OUT_BATCH_FLOAT32(ctx->Depth.Clear);
-		OUT_BATCH_FLOAT32(1.0);
-		OUT_BATCH_FLOAT32(ctx->Color.ClearColor[0]);
-		OUT_BATCH_FLOAT32(ctx->Color.ClearColor[1]);
-		OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]);
-		OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]);
-	}
-
-	r300EmitCacheFlush(rmesa);
-	cp_wait(&r300->radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
-
-	R300_STATECHANGE(r300, cb);
-	R300_STATECHANGE(r300, cmk);
-	R300_STATECHANGE(r300, zs);
-}
-
-static void r300EmitClearState(GLcontext * ctx)
-{
-	r300ContextPtr r300 = R300_CONTEXT(ctx);
-	BATCH_LOCALS(&r300->radeon);
-	__DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
-	int i;
-	int has_tcl;
-	int is_r500 = 0;
-	GLuint vap_cntl;
-
-	has_tcl = r300->options.hw_tcl_enabled;
-
-	if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
-		is_r500 = 1;
-
-	/* State atom dirty tracking is a little subtle here.
-	 *
-	 * On the one hand, we need to make sure base state is emitted
-	 * here if we start with an empty batch buffer, otherwise clear
-	 * works incorrectly with multiple processes. Therefore, the first
-	 * BEGIN_BATCH cannot be a BEGIN_BATCH_NO_AUTOSTATE.
-	 *
-	 * On the other hand, implicit state emission clears the state atom
-	 * dirty bits, so we have to call R300_STATECHANGE later than the
-	 * first BEGIN_BATCH.
-	 *
-	 * The final trickiness is that, because we change state, we need
-	 * to ensure that any stored swtcl primitives are flushed properly
-	 * before we start changing state. See the R300_NEWPRIM in r300Clear
-	 * for this.
-	 */
-	BEGIN_BATCH(31);
-	OUT_BATCH_REGSEQ(R300_VAP_PROG_STREAM_CNTL_0, 1);
-	if (!has_tcl)
-		OUT_BATCH(((((0 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_0_SHIFT) |
-		 ((R300_LAST_VEC | (2 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT)));
-	else
-		OUT_BATCH(((((0 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_0_SHIFT) |
-		 ((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT)));
-
-	OUT_BATCH_REGVAL(R300_FG_FOG_BLEND, 0);
-	OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_EXT_0,
-	   ((((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) |
-	       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) |
-	       (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_SHIFT) |
-	       (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_SHIFT) |
-	       ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W) << R300_WRITE_ENA_SHIFT))
-	      << R300_SWIZZLE0_SHIFT) |
-	     (((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) |
-	       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) |
-	       (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_SHIFT) |
-	       (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_SHIFT) |
-	       ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W) << R300_WRITE_ENA_SHIFT))
-	      << R300_SWIZZLE1_SHIFT)));
-
-	/* R300_VAP_INPUT_CNTL_0, R300_VAP_INPUT_CNTL_1 */
-	OUT_BATCH_REGSEQ(R300_VAP_VTX_STATE_CNTL, 2);
-	OUT_BATCH((R300_SEL_USER_COLOR_0 << R300_COLOR_0_ASSEMBLY_SHIFT));
-	OUT_BATCH(R300_INPUT_CNTL_POS | R300_INPUT_CNTL_COLOR | R300_INPUT_CNTL_TC0);
-
-	/* comes from fglrx startup of clear */
-	OUT_BATCH_REGSEQ(R300_SE_VTE_CNTL, 2);
-	OUT_BATCH(R300_VTX_W0_FMT | R300_VPORT_X_SCALE_ENA |
-		  R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA |
-		  R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA |
-		  R300_VPORT_Z_OFFSET_ENA);
-	OUT_BATCH(0x8);
-
-	OUT_BATCH_REGVAL(R300_VAP_PSC_SGN_NORM_CNTL, 0xaaaaaaaa);
-
-	OUT_BATCH_REGSEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
-	OUT_BATCH(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT |
-		  R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT);
-	OUT_BATCH(0); /* no textures */
-
-	OUT_BATCH_REGVAL(R300_TX_ENABLE, 0);
-
-	OUT_BATCH_REGSEQ(R300_SE_VPORT_XSCALE, 6);
-	OUT_BATCH_FLOAT32(1.0);
-	OUT_BATCH_FLOAT32(dPriv->x);
-	OUT_BATCH_FLOAT32(1.0);
-	OUT_BATCH_FLOAT32(dPriv->y);
-	OUT_BATCH_FLOAT32(1.0);
-	OUT_BATCH_FLOAT32(0.0);
-
-	OUT_BATCH_REGVAL(R300_FG_ALPHA_FUNC, 0);
-
-	OUT_BATCH_REGSEQ(R300_RB3D_CBLEND, 2);
-	OUT_BATCH(0x0);
-	OUT_BATCH(0x0);
-	END_BATCH();
-
-	R300_STATECHANGE(r300, vir[0]);
-	R300_STATECHANGE(r300, fogs);
-	R300_STATECHANGE(r300, vir[1]);
-	R300_STATECHANGE(r300, vic);
-	R300_STATECHANGE(r300, vte);
-	R300_STATECHANGE(r300, vof);
-	R300_STATECHANGE(r300, txe);
-	R300_STATECHANGE(r300, vpt);
-	R300_STATECHANGE(r300, at);
-	R300_STATECHANGE(r300, bld);
-	R300_STATECHANGE(r300, ps);
-
-	if (has_tcl) {
-		R300_STATECHANGE(r300, vap_clip_cntl);
-
-		BEGIN_BATCH_NO_AUTOSTATE(2);
-		OUT_BATCH_REGVAL(R300_VAP_CLIP_CNTL, R300_PS_UCP_MODE_CLIP_AS_TRIFAN | R300_CLIP_DISABLE);
-		END_BATCH();
-        }
-
-	BEGIN_BATCH_NO_AUTOSTATE(2);
-	OUT_BATCH_REGVAL(R300_GA_POINT_SIZE,
-		((dPriv->w * 6) << R300_POINTSIZE_X_SHIFT) |
-		((dPriv->h * 6) << R300_POINTSIZE_Y_SHIFT));
-	END_BATCH();
-
-	if (!is_r500) {
-		R300_STATECHANGE(r300, ri);
-		R300_STATECHANGE(r300, rc);
-		R300_STATECHANGE(r300, rr);
-
-		BEGIN_BATCH(14);
-		OUT_BATCH_REGSEQ(R300_RS_IP_0, 8);
-		for (i = 0; i < 8; ++i)
-			OUT_BATCH(R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3));
-
-		OUT_BATCH_REGSEQ(R300_RS_COUNT, 2);
-		OUT_BATCH((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN);
-		OUT_BATCH(0x0);
-
-		OUT_BATCH_REGVAL(R300_RS_INST_0, R300_RS_INST_COL_CN_WRITE);
-		END_BATCH();
-	} else {
-		R300_STATECHANGE(r300, ri);
-		R300_STATECHANGE(r300, rc);
-		R300_STATECHANGE(r300, rr);
-
-		BEGIN_BATCH(14);
-		OUT_BATCH_REGSEQ(R500_RS_IP_0, 8);
-		for (i = 0; i < 8; ++i) {
-			OUT_BATCH((R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
-				  (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) |
-				  (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
-				  (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT));
-		}
-
-		OUT_BATCH_REGSEQ(R300_RS_COUNT, 2);
-		OUT_BATCH((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN);
-		OUT_BATCH(0x0);
-
-		OUT_BATCH_REGVAL(R500_RS_INST_0, R500_RS_INST_COL_CN_WRITE);
-		END_BATCH();
-	}
-
-	if (!is_r500) {
-		R300_STATECHANGE(r300, fp);
-		R300_STATECHANGE(r300, fpi[0]);
-		R300_STATECHANGE(r300, fpi[1]);
-		R300_STATECHANGE(r300, fpi[2]);
-		R300_STATECHANGE(r300, fpi[3]);
-
-		BEGIN_BATCH(17);
-		OUT_BATCH_REGSEQ(R300_US_CONFIG, 3);
-		OUT_BATCH(0x0);
-		OUT_BATCH(0x0);
-		OUT_BATCH(0x0);
-		OUT_BATCH_REGSEQ(R300_US_CODE_ADDR_0, 4);
-		OUT_BATCH(0x0);
-		OUT_BATCH(0x0);
-		OUT_BATCH(0x0);
-		OUT_BATCH(R300_RGBA_OUT);
-
-		OUT_BATCH_REGVAL(R300_US_ALU_RGB_INST_0,
-			FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO)));
-		OUT_BATCH_REGVAL(R300_US_ALU_RGB_ADDR_0,
-			FP_SELC(0, NO, XYZ, FP_TMP(0), 0, 0));
-		OUT_BATCH_REGVAL(R300_US_ALU_ALPHA_INST_0,
-			FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO)));
-		OUT_BATCH_REGVAL(R300_US_ALU_ALPHA_ADDR_0,
-			FP_SELA(0, NO, W, FP_TMP(0), 0, 0));
-		END_BATCH();
-	} else {
-		struct radeon_state_atom r500fp;
-		uint32_t _cmd[10];
-
-		R300_STATECHANGE(r300, fp);
-		R300_STATECHANGE(r300, r500fp);
-
-		BEGIN_BATCH(7);
-		OUT_BATCH_REGSEQ(R500_US_CONFIG, 2);
-		OUT_BATCH(R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
-		OUT_BATCH(0x0);
-		OUT_BATCH_REGSEQ(R500_US_CODE_ADDR, 3);
-		OUT_BATCH(R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(1));
-		OUT_BATCH(R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(1));
-		OUT_BATCH(R500_US_CODE_OFFSET_ADDR(0));
-		END_BATCH();
-
-		r500fp.check = check_r500fp;
-		r500fp.cmd = _cmd;
-		r500fp.cmd[0] = cmdr500fp(r300->radeon.radeonScreen, 0, 1, 0, 0);
-		r500fp.cmd[1] = R500_INST_TYPE_OUT |
-			R500_INST_TEX_SEM_WAIT |
-			R500_INST_LAST |
-			R500_INST_RGB_OMASK_R |
-			R500_INST_RGB_OMASK_G |
-			R500_INST_RGB_OMASK_B |
-			R500_INST_ALPHA_OMASK |
-			R500_INST_RGB_CLAMP |
-			R500_INST_ALPHA_CLAMP;
-		r500fp.cmd[2] = R500_RGB_ADDR0(0) |
-			R500_RGB_ADDR1(0) |
-			R500_RGB_ADDR1_CONST |
-			R500_RGB_ADDR2(0) |
-			R500_RGB_ADDR2_CONST;
-		r500fp.cmd[3] = R500_ALPHA_ADDR0(0) |
-			R500_ALPHA_ADDR1(0) |
-			R500_ALPHA_ADDR1_CONST |
-			R500_ALPHA_ADDR2(0) |
-			R500_ALPHA_ADDR2_CONST;
-		r500fp.cmd[4] = R500_ALU_RGB_SEL_A_SRC0 |
-			R500_ALU_RGB_R_SWIZ_A_R |
-			R500_ALU_RGB_G_SWIZ_A_G |
-			R500_ALU_RGB_B_SWIZ_A_B |
-			R500_ALU_RGB_SEL_B_SRC0 |
-			R500_ALU_RGB_R_SWIZ_B_R |
-			R500_ALU_RGB_B_SWIZ_B_G |
-			R500_ALU_RGB_G_SWIZ_B_B;
-		r500fp.cmd[5] = R500_ALPHA_OP_CMP |
-			R500_ALPHA_SWIZ_A_A |
-			R500_ALPHA_SWIZ_B_A;
-		r500fp.cmd[6] = R500_ALU_RGBA_OP_CMP |
-			R500_ALU_RGBA_R_SWIZ_0 |
-			R500_ALU_RGBA_G_SWIZ_0 |
-			R500_ALU_RGBA_B_SWIZ_0 |
-			R500_ALU_RGBA_A_SWIZ_0;
-
-		r500fp.cmd[7] = 0;
-		if (r300->radeon.radeonScreen->kernel_mm) {
-			emit_r500fp(ctx, &r500fp);
-		} else {
-			int dwords = r500fp.check(ctx,&r500fp);
-			BEGIN_BATCH_NO_AUTOSTATE(dwords);
-			OUT_BATCH_TABLE(r500fp.cmd, dwords);
-			END_BATCH();
-		}
-
-	}
-
-	BEGIN_BATCH(2);
-	OUT_BATCH_REGVAL(R300_VAP_PVS_STATE_FLUSH_REG, 0);
-	END_BATCH();
-
-	if (has_tcl) {
-		vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
-			(5 << R300_PVS_NUM_CNTLRS_SHIFT) |
-			(12 << R300_VF_MAX_VTX_NUM_SHIFT));
-		if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
-			vap_cntl |= R500_TCL_STATE_OPTIMIZATION;
-	} else {
-		vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
-			(5 << R300_PVS_NUM_CNTLRS_SHIFT) |
-			(5 << R300_VF_MAX_VTX_NUM_SHIFT));
-	}
-
-	if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV515)
-		vap_cntl |= (2 << R300_PVS_NUM_FPUS_SHIFT);
-	else if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) ||
-		 (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV560) ||
-		 (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV570))
-		vap_cntl |= (5 << R300_PVS_NUM_FPUS_SHIFT);
-	else if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV410) ||
-		 (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R420))
-		vap_cntl |= (6 << R300_PVS_NUM_FPUS_SHIFT);
-	else if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R520) ||
-		 (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R580))
-		vap_cntl |= (8 << R300_PVS_NUM_FPUS_SHIFT);
-	else
-		vap_cntl |= (4 << R300_PVS_NUM_FPUS_SHIFT);
-
-	R300_STATECHANGE(r300, vap_cntl);
-
-	BEGIN_BATCH(2);
-	OUT_BATCH_REGVAL(R300_VAP_CNTL, vap_cntl);
-	END_BATCH();
-
-	if (has_tcl) {
-        struct radeon_state_atom vpu;
-        uint32_t _cmd[10];
-		R300_STATECHANGE(r300, pvs);
-		R300_STATECHANGE(r300, vap_flush);
-		R300_STATECHANGE(r300, vpi);
-
-		BEGIN_BATCH(4);
-		OUT_BATCH_REGSEQ(R300_VAP_PVS_CODE_CNTL_0, 3);
-		OUT_BATCH((0 << R300_PVS_FIRST_INST_SHIFT) |
-			  (0 << R300_PVS_XYZW_VALID_INST_SHIFT) |
-			  (1 << R300_PVS_LAST_INST_SHIFT));
-		OUT_BATCH((0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) |
-			  (0 << R300_PVS_MAX_CONST_ADDR_SHIFT));
-		OUT_BATCH(1 << R300_PVS_LAST_VTX_SRC_INST_SHIFT);
-		END_BATCH();
-
-		vpu.check = check_vpu;
-		vpu.cmd = _cmd;
-		vpu.cmd[0] = cmdvpu(r300->radeon.radeonScreen, 0, 2);
-
-		vpu.cmd[1] = PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE,
-                                         0, 0xf, PVS_DST_REG_OUT);
-		vpu.cmd[2] = PVS_SRC_OPERAND(0, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y,
-                                      PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W,
-                                      PVS_SRC_REG_INPUT, NEGATE_NONE);
-		vpu.cmd[3] = PVS_SRC_OPERAND(0, PVS_SRC_SELECT_FORCE_0,
-                                      PVS_SRC_SELECT_FORCE_0,
-                                      PVS_SRC_SELECT_FORCE_0,
-                                      PVS_SRC_SELECT_FORCE_0,
-                                      PVS_SRC_REG_INPUT, NEGATE_NONE);
-		vpu.cmd[4] = 0x0;
-
-		vpu.cmd[5] = PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 1, 0xf,
-                                         PVS_DST_REG_OUT);
-		vpu.cmd[6] = PVS_SRC_OPERAND(1, PVS_SRC_SELECT_X,
-                                      PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z,
-                                      PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT,
-                                      NEGATE_NONE);
-		vpu.cmd[7] = PVS_SRC_OPERAND(1, PVS_SRC_SELECT_FORCE_0,
-                                      PVS_SRC_SELECT_FORCE_0,
-                                      PVS_SRC_SELECT_FORCE_0,
-                                      PVS_SRC_SELECT_FORCE_0,
-                                      PVS_SRC_REG_INPUT, NEGATE_NONE);
-		vpu.cmd[8] = 0x0;
-
-		if (r300->radeon.radeonScreen->kernel_mm) {
-			int dwords = r300->hw.vap_flush.check(ctx,&r300->hw.vap_flush);
-			BEGIN_BATCH_NO_AUTOSTATE(dwords);
-			OUT_BATCH_TABLE(r300->hw.vap_flush.cmd, dwords);
-			END_BATCH();
-			emit_vpu(ctx, &vpu);
-		} else {
-			int dwords = vpu.check(ctx,&vpu);
-			BEGIN_BATCH_NO_AUTOSTATE(dwords);
-			OUT_BATCH_TABLE(vpu.cmd, dwords);
-			END_BATCH();
-		}
-
-	}
-}
-
-static int r300KernelClear(GLcontext *ctx, GLuint flags)
-{
-	r300ContextPtr r300 = R300_CONTEXT(ctx);
-	__DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
-	struct radeon_framebuffer *rfb = dPriv->driverPrivate;
-	struct radeon_renderbuffer *rrb;
-	struct radeon_renderbuffer *rrbd;
-	int bits = 0, ret;
-
-	/* Make sure it fits there. */
-	radeon_cs_space_reset_bos(r300->radeon.cmdbuf.cs);
-
-	if (flags & BUFFER_BIT_COLOR0) {
-		rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_COLOR0);
-		radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
-						  rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM);
-	}
-
-	if (flags & BUFFER_BIT_FRONT_LEFT) {
-		rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT);
-		radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
-						  rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM);
-	}
-
-	if (flags & BUFFER_BIT_BACK_LEFT) {
-		rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_BACK_LEFT);
-		radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
-						  rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM);
-	}
-
-	rrbd = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
-	if (rrbd) {
-		radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
-						  rrbd->bo, 0, RADEON_GEM_DOMAIN_VRAM);
-	}
-
-	ret = radeon_cs_space_check(r300->radeon.cmdbuf.cs);
-	if (ret)
-	  return -1;
-
-	rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__);
-	if (flags || bits)
-		r300EmitClearState(ctx);
-
-	rrbd = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
-	if (rrbd && (flags & BUFFER_BIT_DEPTH))
-		bits |= CLEARBUFFER_DEPTH;
-
-	if (rrbd && (flags & BUFFER_BIT_STENCIL))
-		bits |= CLEARBUFFER_STENCIL;
-
-	if (flags & BUFFER_BIT_COLOR0) {
-		rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_COLOR0);
-		r300ClearBuffer(r300, CLEARBUFFER_COLOR, rrb, NULL);
-		bits = 0;
-	}
-
-	if (flags & BUFFER_BIT_FRONT_LEFT) {
-		rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT);
-		r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd);
-		bits = 0;
-	}
-
-	if (flags & BUFFER_BIT_BACK_LEFT) {
-		rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_BACK_LEFT);
-		r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd);
-		bits = 0;
-	}
-
-	if (bits)
-		r300ClearBuffer(r300, bits, NULL, rrbd);
-
-	COMMIT_BATCH();
-	return 0;
-}
-
-/**
- * Buffer clear
- */
-static void r300Clear(GLcontext * ctx, GLbitfield mask)
-{
-	r300ContextPtr r300 = R300_CONTEXT(ctx);
-	__DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
-	const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
-	GLbitfield swrast_mask = 0, tri_mask = 0;
-	int i, ret;
-	struct gl_framebuffer *fb = ctx->DrawBuffer;
-
-	if (RADEON_DEBUG & RADEON_IOCTL)
-		fprintf(stderr, "r300Clear\n");
-
-	if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) {
-		LOCK_HARDWARE(&r300->radeon);
-		UNLOCK_HARDWARE(&r300->radeon);
-		if (dPriv->numClipRects == 0)
-			return;
-	}
-
-	/* Flush swtcl vertices if necessary, because we will change hardware
-	 * state during clear. See also the state-related comment in
-	 * r300EmitClearState.
-	 */
-	R300_NEWPRIM(r300);
-
-	if (colorMask == ~0)
-	  tri_mask |= (mask & BUFFER_BITS_COLOR);
-	else
-	  tri_mask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT));
-
-
-	/* HW stencil */
-	if (mask & BUFFER_BIT_STENCIL) {
-		tri_mask |= BUFFER_BIT_STENCIL;
-	}
-
-	/* HW depth */
-	if (mask & BUFFER_BIT_DEPTH) {
-    	        tri_mask |= BUFFER_BIT_DEPTH;
-	}
-
-	/* If we're doing a tri pass for depth/stencil, include a likely color
-	 * buffer with it.
-	 */
-
-	for (i = 0; i < BUFFER_COUNT; i++) {
-	  GLuint bufBit = 1 << i;
-	  if ((tri_mask) & bufBit) {
-	    if (!fb->Attachment[i].Renderbuffer->ClassID) {
-	      tri_mask &= ~bufBit;
-	      swrast_mask |= bufBit;
-	    }
-	  }
-	}
-
-	/* SW fallback clearing */
-	swrast_mask = mask & ~tri_mask;
-
-	ret = 0;
-	if (tri_mask) {
-		if (r300->radeon.radeonScreen->kernel_mm)
-			radeonUserClear(ctx, tri_mask);
-		else {
-			/* if kernel clear fails due to size restraints fallback */
-			ret = r300KernelClear(ctx, tri_mask);
-			if (ret < 0)
-				swrast_mask |= tri_mask;
-		}
-	}
-
-	if (swrast_mask) {
-		if (RADEON_DEBUG & RADEON_FALLBACKS)
-			fprintf(stderr, "%s: swrast clear, mask: %x\n",
-				__FUNCTION__, swrast_mask);
-		_swrast_Clear(ctx, swrast_mask);
-	}
-}
-
-void r300InitIoctlFuncs(struct dd_function_table *functions)
-{
-	functions->Clear = r300Clear;
-	functions->Finish = radeonFinish;
-	functions->Flush = radeonFlush;
-}
diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.h b/src/mesa/drivers/dri/r300/r300_ioctl.h
deleted file mode 100644
index 3abfa71..0000000
--- a/src/mesa/drivers/dri/r300/r300_ioctl.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
-
-The Weather Channel (TM) funded Tungsten Graphics to develop the
-initial release of the Radeon 8500 driver under the XFree86 license.
-This notice must be preserved.
-
-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, sublicense, 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 NONINFRINGEMENT.
-IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
-
-**************************************************************************/
-
-/*
- * Authors:
- *   Keith Whitwell <keith@tungstengraphics.com>
- *   Nicolai Haehnle <prefect_@gmx.net>
- */
-
-#ifndef __R300_IOCTL_H__
-#define __R300_IOCTL_H__
-
-#include "r300_context.h"
-#include "radeon_drm.h"
-
-extern void r300InitIoctlFuncs(struct dd_function_table *functions);
-
-#endif				/* __R300_IOCTL_H__ */
diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h
index 623da60..ea684e7 100644
--- a/src/mesa/drivers/dri/r300/r300_reg.h
+++ b/src/mesa/drivers/dri/r300/r300_reg.h
@@ -1789,6 +1789,7 @@
 #       define R300_ALU_DSTC_OUTPUT_X           (1 << 26)
 #       define R300_ALU_DSTC_OUTPUT_Y           (1 << 27)
 #       define R300_ALU_DSTC_OUTPUT_Z           (1 << 28)
+#       define R300_RGB_TARGET(x)               ((x) << 29)
 
 #define R300_US_ALU_ALPHA_ADDR_0                 0x47C0
 #       define R300_ALU_SRC0A_SHIFT             0
@@ -1806,6 +1807,7 @@
 #       define R300_ALU_DSTA_REG                (1 << 23)
 #       define R300_ALU_DSTA_OUTPUT             (1 << 24)
 #		define R300_ALU_DSTA_DEPTH              (1 << 27)
+#		define R300_ALPHA_TARGET(x)             ((x) << 25)
 
 #define R300_US_ALU_RGB_INST_0                   0x48C0
 #       define R300_ALU_ARGC_SRC0C_XYZ          0
diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c
index 3cd3875..02c9425 100644
--- a/src/mesa/drivers/dri/r300/r300_render.c
+++ b/src/mesa/drivers/dri/r300/r300_render.c
@@ -67,10 +67,7 @@
 #include "vbo/vbo_split.h"
 #include "tnl/tnl.h"
 #include "tnl/t_vp_build.h"
-#include "radeon_reg.h"
-#include "radeon_macros.h"
 #include "r300_context.h"
-#include "r300_ioctl.h"
 #include "r300_state.h"
 #include "r300_reg.h"
 #include "r300_tex.h"
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index ac20c08..c51285a 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -55,7 +55,6 @@
 #include "tnl/t_vp_build.h"
 
 #include "r300_context.h"
-#include "r300_ioctl.h"
 #include "r300_state.h"
 #include "r300_reg.h"
 #include "r300_emit.h"
@@ -998,7 +997,7 @@
 static void r300UpdateWindow(GLcontext * ctx)
 {
 	r300ContextPtr rmesa = R300_CONTEXT(ctx);
-	__DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
+	__DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
 	GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
 	GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
 	const GLfloat *v = ctx->Viewport._WindowMap.m;
@@ -1051,7 +1050,7 @@
 void r300UpdateViewportOffset(GLcontext * ctx)
 {
 	r300ContextPtr rmesa = R300_CONTEXT(ctx);
-	__DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
+	__DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
 	GLfloat xoffset = (GLfloat) dPriv->x;
 	GLfloat yoffset = (GLfloat) dPriv->y + dPriv->h;
 	const GLfloat *v = ctx->Viewport._WindowMap.m;
@@ -1312,7 +1311,7 @@
 		fprintf(stderr,
 			"Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n",
 			mtu, R300_MAX_TEXTURE_UNITS);
-		_mesa_exit(-1);
+		exit(-1);
 	}
 
 	/* We cannot let disabled tmu offsets pass DRM */
@@ -1769,9 +1768,10 @@
 	radeon_firevertices(&r300->radeon);
 
 	r300ColorMask(ctx,
-		      ctx->Color.ColorMask[RCOMP],
-		      ctx->Color.ColorMask[GCOMP],
-		      ctx->Color.ColorMask[BCOMP], ctx->Color.ColorMask[ACOMP]);
+		      ctx->Color.ColorMask[0][RCOMP],
+		      ctx->Color.ColorMask[0][GCOMP],
+		      ctx->Color.ColorMask[0][BCOMP],
+                      ctx->Color.ColorMask[0][ACOMP]);
 
 	r300Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);
 	r300DepthMask(ctx, ctx->Depth.Mask);
@@ -2040,7 +2040,7 @@
 		}
 
 		case RC_STATE_R300_WINDOW_DIMENSION: {
-			__DRIdrawablePrivate * drawable = radeon_get_drawable(&rmesa->radeon);
+			__DRIdrawable * drawable = radeon_get_drawable(&rmesa->radeon);
 			buffer[0] = drawable->w * 0.5f;	/* width*0.5 */
 			buffer[1] = drawable->h * 0.5f;	/* height*0.5 */
 			buffer[2] = 0.5F;	/* for moving range [-1 1] -> [0 1] */
diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c
index ee2c71e..93983ce 100644
--- a/src/mesa/drivers/dri/r300/r300_swtcl.c
+++ b/src/mesa/drivers/dri/r300/r300_swtcl.c
@@ -124,7 +124,7 @@
 	}
 
 	if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
-		VB->AttribPtr[VERT_ATTRIB_GENERIC0] = VB->ColorPtr[1];
+		VB->AttribPtr[VERT_ATTRIB_GENERIC0] = VB->BackfaceColorPtr;
 		OutputsWritten |= 1 << VERT_RESULT_BFC0;
 #if MESA_LITTLE_ENDIAN
 		EMIT_ATTR( _TNL_ATTRIB_GENERIC0, EMIT_4UB_4F_RGBA );
@@ -134,7 +134,7 @@
 		ADD_ATTR(VERT_ATTRIB_GENERIC0, R300_DATA_TYPE_BYTE, SWTCL_OVM_COLOR2, SWIZZLE_XYZW, MASK_XYZW, 1);
 #endif
 		if (fp_reads & FRAG_BIT_COL1) {
-			VB->AttribPtr[VERT_ATTRIB_GENERIC1] = VB->SecondaryColorPtr[1];
+			VB->AttribPtr[VERT_ATTRIB_GENERIC1] = VB->BackfaceSecondaryColorPtr;
 			GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
 			OutputsWritten |= 1 << VERT_RESULT_BFC1;
 #if MESA_LITTLE_ENDIAN
@@ -159,7 +159,7 @@
 		int tex_id = rmesa->selected_fp->wpos_attr - FRAG_ATTRIB_TEX0;
 
 		VB->AttribPtr[VERT_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_POS];
-		VB->TexCoordPtr[tex_id] = VB->AttribPtr[VERT_ATTRIB_POS];
+		VB->AttribPtr[_TNL_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_POS];
 		RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 + tex_id);
 	}
 
@@ -167,7 +167,7 @@
 		int tex_id = rmesa->selected_fp->fog_attr - FRAG_ATTRIB_TEX0;
 
 		VB->AttribPtr[VERT_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_FOG];
-		VB->TexCoordPtr[tex_id] = VB->AttribPtr[VERT_ATTRIB_FOG];
+		VB->AttribPtr[_TNL_ATTRIB_TEX0 + tex_id] = VB->AttribPtr[VERT_ATTRIB_FOG];
 		RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 + tex_id);
 	}
 
@@ -180,7 +180,7 @@
 		GLuint swiz, format, hw_format;
 		for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
 			if (fp_reads & FRAG_BIT_TEX(i)) {
-				switch (VB->TexCoordPtr[i]->size) {
+				switch (VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size) {
 					case 1:
 						format = EMIT_1F;
 						hw_format = R300_DATA_TYPE_FLOAT_1;
@@ -215,7 +215,7 @@
 
 	if (first_free_tex >= ctx->Const.MaxTextureUnits) {
 		fprintf(stderr, "\tout of free texcoords to write fog coordinate\n");
-		_mesa_exit(-1);
+		exit(-1);
 	}
 
 	R300_NEWPRIM(rmesa);
@@ -665,11 +665,11 @@
 	r300EmitCacheFlush(rmesa);
 
 	radeonEmitState(&rmesa->radeon);
-    r300_emit_scissor(ctx);
+	r300_emit_scissor(ctx);
 	r300EmitVertexAOS(rmesa,
-			rmesa->radeon.swtcl.vertex_size,
-			first_elem(&rmesa->radeon.dma.reserved)->bo,
-			current_offset);
+			  rmesa->radeon.swtcl.vertex_size,
+			  rmesa->radeon.swtcl.bo,
+			  current_offset);
 
 	r300EmitVbufPrim(rmesa,
 		   rmesa->radeon.swtcl.hw_primitive,
diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c
index 27b78a9..963f648 100644
--- a/src/mesa/drivers/dri/r300/r300_tex.c
+++ b/src/mesa/drivers/dri/r300/r300_tex.c
@@ -48,7 +48,6 @@
 
 #include "r300_context.h"
 #include "r300_state.h"
-#include "r300_ioctl.h"
 #include "radeon_mipmap_tree.h"
 #include "r300_tex.h"
 
@@ -216,23 +215,14 @@
 		break;
 
 	case GL_TEXTURE_BORDER_COLOR:
-		r300SetTexBorderColor(t, texObj->BorderColor);
+		r300SetTexBorderColor(t, texObj->BorderColor.f);
 		break;
 
 	case GL_TEXTURE_BASE_LEVEL:
 	case GL_TEXTURE_MAX_LEVEL:
 	case GL_TEXTURE_MIN_LOD:
 	case GL_TEXTURE_MAX_LOD:
-		/* This isn't the most efficient solution but there doesn't appear to
-		 * be a nice alternative.  Since there's no LOD clamping,
-		 * we just have to rely on loading the right subset of mipmap levels
-		 * to simulate a clamped LOD.
-		 */
-		if (t->mt) {
-			radeon_miptree_unreference(t->mt);
-			t->mt = 0;
-			t->validated = GL_FALSE;
-		}
+		t->validated = GL_FALSE;
 		break;
 
 	case GL_DEPTH_TEXTURE_MODE:
@@ -270,7 +260,11 @@
 
 	if (rmesa) {
 		int i;
-		radeon_firevertices(&rmesa->radeon);
+		struct radeon_bo *bo;
+		bo = !t->mt ? t->bo : t->mt->bo;
+		if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->radeon.cmdbuf.cs)) {
+			radeon_firevertices(&rmesa->radeon);
+		}
 
 		for(i = 0; i < R300_MAX_TEXTURE_UNITS; ++i)
 			if (rmesa->hw.textures[i] == t)
@@ -282,10 +276,8 @@
 		t->bo = NULL;
 	}
 
-	if (t->mt) {
-		radeon_miptree_unreference(t->mt);
-		t->mt = 0;
-	}
+	radeon_miptree_unreference(&t->mt);
+
 	_mesa_delete_texture_object(ctx, texObj);
 }
 
@@ -315,7 +307,7 @@
 	/* Initialize hardware state */
 	r300UpdateTexWrap(t);
 	r300SetTexFilter(t, t->base.MinFilter, t->base.MagFilter, t->base.MaxAnisotropy);
-	r300SetTexBorderColor(t, t->base.BorderColor);
+	r300SetTexBorderColor(t, t->base.BorderColor.f);
 
 	return &t->base;
 }
diff --git a/src/mesa/drivers/dri/r300/r300_tex.h b/src/mesa/drivers/dri/r300/r300_tex.h
index 8a653ea..6ede0fe 100644
--- a/src/mesa/drivers/dri/r300/r300_tex.h
+++ b/src/mesa/drivers/dri/r300/r300_tex.h
@@ -51,4 +51,6 @@
 
 extern void r300InitTextureFuncs(struct dd_function_table *functions);
 
+int32_t r300TranslateTexFormat(gl_format mesaFormat);
+
 #endif				/* __r300_TEX_H__ */
diff --git a/src/mesa/drivers/dri/r300/r300_texcopy.c b/src/mesa/drivers/dri/r300/r300_texcopy.c
new file mode 100644
index 0000000..ebc9c05
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/r300_texcopy.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com>
+ *
+ * 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, sublicense, 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 NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "radeon_common.h"
+#include "r300_context.h"
+
+#include "main/image.h"
+#include "main/teximage.h"
+#include "main/texstate.h"
+#include "drivers/common/meta.h"
+
+#include "radeon_mipmap_tree.h"
+#include "r300_blit.h"
+#include <main/debug.h>
+
+// TODO:
+// need to pass correct pitch for small dst textures!
+static GLboolean
+do_copy_texsubimage(GLcontext *ctx,
+                    GLenum target, GLint level,
+                    struct radeon_tex_obj *tobj,
+                    radeon_texture_image *timg,
+                    GLint dstx, GLint dsty,
+                    GLint x, GLint y,
+                    GLsizei width, GLsizei height)
+{
+    struct r300_context *r300 = R300_CONTEXT(ctx);
+    struct radeon_renderbuffer *rrb;
+
+    if (_mesa_get_format_bits(timg->base.TexFormat, GL_DEPTH_BITS) > 0) {
+        rrb = radeon_get_depthbuffer(&r300->radeon);
+    } else {
+        rrb = radeon_get_colorbuffer(&r300->radeon);
+    }
+
+    if (!timg->mt) {
+        radeon_validate_texture_miptree(ctx, &tobj->base);
+    }
+
+    assert(rrb && rrb->bo);
+    assert(timg->mt->bo);
+    assert(timg->base.Width >= dstx + width);
+    assert(timg->base.Height >= dsty + height);
+
+    intptr_t src_offset = rrb->draw_offset;
+    intptr_t dst_offset = radeon_miptree_image_offset(timg->mt, _mesa_tex_target_to_face(target), level);
+
+    if (src_offset % 32 || dst_offset % 32) {
+        return GL_FALSE;
+    }
+
+    if (0) {
+        fprintf(stderr, "%s: copying to face %d, level %d\n",
+                __FUNCTION__, _mesa_tex_target_to_face(target), level);
+        fprintf(stderr, "to: x %d, y %d, offset %d\n", dstx, dsty, (uint32_t) dst_offset);
+        fprintf(stderr, "from (%dx%d) width %d, height %d, offset %d, pitch %d\n",
+                x, y, rrb->base.Width, rrb->base.Height, (uint32_t) src_offset, rrb->pitch/rrb->cpp);
+        fprintf(stderr, "src size %d, dst size %d\n", rrb->bo->size, timg->mt->bo->size);
+
+    }
+
+    /* blit from src buffer to texture */
+    return r300_blit(r300, rrb->bo, src_offset, rrb->base.Format, rrb->pitch/rrb->cpp,
+                     rrb->base.Width, rrb->base.Height, x, y,
+                     timg->mt->bo, dst_offset, timg->base.TexFormat,
+                     timg->base.Width, timg->base.Width, timg->base.Height,
+                     dstx, dsty, width, height, 1);
+}
+
+static void
+r300CopyTexImage2D(GLcontext *ctx, GLenum target, GLint level,
+                   GLenum internalFormat,
+                   GLint x, GLint y, GLsizei width, GLsizei height,
+                   GLint border)
+{
+    struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
+    struct gl_texture_object *texObj =
+        _mesa_select_tex_object(ctx, texUnit, target);
+    struct gl_texture_image *texImage =
+        _mesa_select_tex_image(ctx, texObj, target, level);
+    int srcx, srcy, dstx, dsty;
+
+    if (border)
+        goto fail;
+
+    /* Setup or redefine the texture object, mipmap tree and texture
+     * image.  Don't populate yet.
+     */
+    ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
+                           width, height, border,
+                           GL_RGBA, GL_UNSIGNED_BYTE, NULL,
+                           &ctx->DefaultPacking, texObj, texImage);
+
+    srcx = x;
+    srcy = y;
+    dstx = 0;
+    dsty = 0;
+    if (!_mesa_clip_copytexsubimage(ctx,
+                                    &dstx, &dsty,
+                                    &srcx, &srcy,
+                                    &width, &height)) {
+        return;
+    }
+
+    if (!do_copy_texsubimage(ctx, target, level,
+                             radeon_tex_obj(texObj), (radeon_texture_image *)texImage,
+                             0, 0, x, y, width, height)) {
+        goto fail;
+    }
+
+    return;
+
+fail:
+    _mesa_meta_CopyTexImage2D(ctx, target, level, internalFormat, x, y,
+                              width, height, border);
+}
+
+static void
+r300CopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
+                      GLint xoffset, GLint yoffset,
+                      GLint x, GLint y,
+                      GLsizei width, GLsizei height)
+{
+    struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
+    struct gl_texture_object *texObj = _mesa_select_tex_object(ctx, texUnit, target);
+    struct gl_texture_image *texImage = _mesa_select_tex_image(ctx, texObj, target, level);
+
+    if (!do_copy_texsubimage(ctx, target, level,
+                             radeon_tex_obj(texObj), (radeon_texture_image *)texImage,
+                             xoffset, yoffset, x, y, width, height)) {
+
+       //DEBUG_FALLBACKS
+
+        _mesa_meta_CopyTexSubImage2D(ctx, target, level,
+                                     xoffset, yoffset, x, y, width, height);
+    }
+}
+
+
+void r300_init_texcopy_functions(struct dd_function_table *table)
+{
+    table->CopyTexImage2D = r300CopyTexImage2D;
+    table->CopyTexSubImage2D = r300CopyTexSubImage2D;
+}
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
index 44ca24d..78ff545 100644
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
@@ -46,19 +46,10 @@
 
 #include "r300_context.h"
 #include "r300_state.h"
-#include "r300_ioctl.h"
 #include "radeon_mipmap_tree.h"
 #include "r300_tex.h"
 #include "r300_reg.h"
 
-#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5			\
-			   || ((f) >= MESA_FORMAT_RGBA_FLOAT32 &&	\
-			       (f) <= MESA_FORMAT_INTENSITY_FLOAT16))	\
-			  && tx_table[f].flag )
-
-#define _ASSIGN(entry, format)				\
-	[ MESA_FORMAT_ ## entry ] = { format, 0, 1}
-
 /*
  * Note that the _REV formats are the same as the non-REV formats.  This is
  * because the REV and non-REV formats are identical as a byte string, but
@@ -68,66 +59,119 @@
  * identically.  -- paulus
  */
 
-static const struct tx_table {
-	GLuint format, filter, flag;
-} tx_table[] = {
-	/* *INDENT-OFF* */
+int32_t r300TranslateTexFormat(gl_format mesaFormat)
+{
+	switch (mesaFormat)
+	{
 #ifdef MESA_LITTLE_ENDIAN
-	_ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
-	_ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
-	_ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
-	_ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
+		case MESA_FORMAT_RGBA8888:
+			return R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8);
+		case MESA_FORMAT_RGBA8888_REV:
+			return R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8);
+		case MESA_FORMAT_ARGB8888:
+			return R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
+		case MESA_FORMAT_ARGB8888_REV:
+			return R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8);
 #else
-	_ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
-	_ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
-	_ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
-	_ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
+		case MESA_FORMAT_RGBA8888:
+			return R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8);
+		case MESA_FORMAT_RGBA8888_REV:
+			return R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8);
+		case MESA_FORMAT_ARGB8888:
+			return R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8);
+		case MESA_FORMAT_ARGB8888_REV:
+			return R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
 #endif
-	_ASSIGN(RGB888, R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)),
-	_ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
-	_ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
-	_ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
-	_ASSIGN(ARGB4444_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
-	_ASSIGN(ARGB1555, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
-	_ASSIGN(ARGB1555_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
-	_ASSIGN(AL88, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
-	_ASSIGN(AL88_REV, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
-	_ASSIGN(RGB332, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z3Y3X2)),
-	_ASSIGN(A8, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8)),
-	_ASSIGN(L8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8)),
-	_ASSIGN(I8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
-	_ASSIGN(CI8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
-	_ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE),
-	_ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE),
-	_ASSIGN(RGB_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1)),
-	_ASSIGN(RGBA_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1)),
-	_ASSIGN(RGBA_DXT3, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3)),
-	_ASSIGN(RGBA_DXT5, R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5)),
-	_ASSIGN(RGBA_FLOAT32, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R32G32B32A32)),
-	_ASSIGN(RGBA_FLOAT16, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R16G16B16A16)),
-	_ASSIGN(RGB_FLOAT32, 0xffffffff),
-	_ASSIGN(RGB_FLOAT16, 0xffffffff),
-	_ASSIGN(ALPHA_FLOAT32, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I32)),
-	_ASSIGN(ALPHA_FLOAT16, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I16)),
-	_ASSIGN(LUMINANCE_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I32)),
-	_ASSIGN(LUMINANCE_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I16)),
-	_ASSIGN(LUMINANCE_ALPHA_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I32A32)),
-	_ASSIGN(LUMINANCE_ALPHA_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16)),
-	_ASSIGN(INTENSITY_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, X, FL_I32)),
-	_ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)),
-	_ASSIGN(Z16, R300_EASY_TX_FORMAT(X, X, X, X, X16)),
-	_ASSIGN(Z24_S8, R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8)),
-	_ASSIGN(S8_Z24, R300_EASY_TX_FORMAT(Y, Y, Y, Y, X24_Y8)),
-	_ASSIGN(Z32, R300_EASY_TX_FORMAT(X, X, X, X, X32)),
-	/* EXT_texture_sRGB */
-	_ASSIGN(SRGBA8, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8) | R300_TX_FORMAT_GAMMA),
-	_ASSIGN(SLA8, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8) | R300_TX_FORMAT_GAMMA),
-	_ASSIGN(SL8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8) | R300_TX_FORMAT_GAMMA),
-	/* *INDENT-ON* */
+		case MESA_FORMAT_XRGB8888:
+			return R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
+		case MESA_FORMAT_RGB888:
+			return R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
+		case MESA_FORMAT_RGB565:
+			return R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
+		case MESA_FORMAT_RGB565_REV:
+			return R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
+		case MESA_FORMAT_ARGB4444:
+			return R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4);
+		case MESA_FORMAT_ARGB4444_REV:
+			return R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4);
+		case MESA_FORMAT_ARGB1555:
+			return R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5);
+		case MESA_FORMAT_ARGB1555_REV:
+			return R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5);
+		case MESA_FORMAT_AL88:
+			return R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8);
+		case MESA_FORMAT_AL88_REV:
+			return R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8);
+		case MESA_FORMAT_RGB332:
+			return R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z3Y3X2);
+		case MESA_FORMAT_A8:
+			return R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8);
+		case MESA_FORMAT_L8:
+			return R300_EASY_TX_FORMAT(X, X, X, ONE, X8);
+		case MESA_FORMAT_I8:
+			return R300_EASY_TX_FORMAT(X, X, X, X, X8);
+		case MESA_FORMAT_CI8:
+			return R300_EASY_TX_FORMAT(X, X, X, X, X8);
+		case MESA_FORMAT_YCBCR:
+			return R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE;
+		case MESA_FORMAT_YCBCR_REV:
+			return R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE;
+		case MESA_FORMAT_RGB_DXT1:
+			return R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1);
+		case MESA_FORMAT_RGBA_DXT1:
+			return R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1);
+		case MESA_FORMAT_RGBA_DXT3:
+			return R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3);
+		case MESA_FORMAT_RGBA_DXT5:
+			return R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5);
+		case MESA_FORMAT_RGBA_FLOAT32:
+			return R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R32G32B32A32);
+		case MESA_FORMAT_RGBA_FLOAT16:
+			return R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R16G16B16A16);
+		case MESA_FORMAT_ALPHA_FLOAT32:
+			return R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I32);
+		case MESA_FORMAT_ALPHA_FLOAT16:
+			return R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I16);
+		case MESA_FORMAT_LUMINANCE_FLOAT32:
+			return R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I32);
+		case MESA_FORMAT_LUMINANCE_FLOAT16:
+			return R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I16);
+		case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
+			return R300_EASY_TX_FORMAT(X, X, X, Y, FL_I32A32);
+		case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
+			return R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16);
+		case MESA_FORMAT_INTENSITY_FLOAT32:
+			return R300_EASY_TX_FORMAT(X, X, X, X, FL_I32);
+		case MESA_FORMAT_INTENSITY_FLOAT16:
+			return R300_EASY_TX_FORMAT(X, X, X, X, FL_I16);
+		case MESA_FORMAT_Z16:
+			return R300_EASY_TX_FORMAT(X, X, X, X, X16);
+		case MESA_FORMAT_Z24_S8:
+			return R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8);
+		case MESA_FORMAT_S8_Z24:
+			return R300_EASY_TX_FORMAT(Y, Y, Y, Y, X24_Y8);
+		case MESA_FORMAT_Z32:
+			return R300_EASY_TX_FORMAT(X, X, X, X, X32);
+		/* EXT_texture_sRGB */
+		case MESA_FORMAT_SRGBA8:
+			return R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8) | R300_TX_FORMAT_GAMMA;
+		case MESA_FORMAT_SLA8:
+			return R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8) | R300_TX_FORMAT_GAMMA;
+		case MESA_FORMAT_SL8:
+			return R300_EASY_TX_FORMAT(X, X, X, ONE, X8) | R300_TX_FORMAT_GAMMA;
+		case MESA_FORMAT_SRGB_DXT1:
+			return R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1) | R300_TX_FORMAT_GAMMA;
+		case MESA_FORMAT_SRGBA_DXT1:
+			return R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1) | R300_TX_FORMAT_GAMMA;
+		case MESA_FORMAT_SRGBA_DXT3:
+			return R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3) | R300_TX_FORMAT_GAMMA;
+		case MESA_FORMAT_SRGBA_DXT5:
+			return R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5) | R300_TX_FORMAT_GAMMA;
+		default:
+			return -1;
+	}
 };
 
-#undef _ASSIGN
-
 void r300SetDepthTexMode(struct gl_texture_object *tObj)
 {
 	static const GLuint formats[3][3] = {
@@ -137,9 +181,9 @@
 			R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X16),
 		},
 		{
-			R300_EASY_TX_FORMAT(X, X, X, ONE, X24_Y8),
-			R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8),
-			R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X24_Y8),
+			R300_EASY_TX_FORMAT(Y, Y, Y, ONE, X24_Y8),
+			R300_EASY_TX_FORMAT(Y, Y, Y, Y, X24_Y8),
+			R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, Y, X24_Y8),
 		},
 		{
 			R300_EASY_TX_FORMAT(X, X, X, ONE, X32),
@@ -202,23 +246,20 @@
 static void setup_hardware_state(r300ContextPtr rmesa, radeonTexObj *t)
 {
 	const struct gl_texture_image *firstImage;
-	int firstlevel = t->mt ? t->mt->firstLevel : 0;
-	    
-	firstImage = t->base.Image[0][firstlevel];
+	firstImage = t->base.Image[0][t->minLod];
 
-	if (!t->image_override
-	    && VALID_FORMAT(firstImage->TexFormat)) {
+	if (!t->image_override) {
 		if (firstImage->_BaseFormat == GL_DEPTH_COMPONENT) {
 			r300SetDepthTexMode(&t->base);
 		} else {
-			t->pp_txformat = tx_table[firstImage->TexFormat].format;
+			int32_t txformat = r300TranslateTexFormat(firstImage->TexFormat);
+			if (txformat < 0) {
+				_mesa_problem(rmesa->radeon.glCtx, "%s: Invalid format %s",
+							  __FUNCTION__, _mesa_get_format_name(firstImage->TexFormat));
+				exit(1);
+			}
+			t->pp_txformat = (uint32_t) txformat;
 		}
-
-		t->pp_txfilter |= tx_table[firstImage->TexFormat].filter;
-	} else if (!t->image_override) {
-		_mesa_problem(NULL, "unexpected texture format in %s",
-			      __FUNCTION__);
-		return;
 	}
 
 	if (t->image_override && t->bo)
@@ -227,7 +268,7 @@
 	t->pp_txsize = (((R300_TX_WIDTHMASK_MASK & ((firstImage->Width - 1) << R300_TX_WIDTHMASK_SHIFT)))
 			| ((R300_TX_HEIGHTMASK_MASK & ((firstImage->Height - 1) << R300_TX_HEIGHTMASK_SHIFT)))
 			| ((R300_TX_DEPTHMASK_MASK & ((firstImage->DepthLog2) << R300_TX_DEPTHMASK_SHIFT)))
-			| ((R300_TX_MAX_MIP_LEVEL_MASK & ((t->mt->lastLevel - t->mt->firstLevel) << R300_TX_MAX_MIP_LEVEL_SHIFT))));
+			| ((R300_TX_MAX_MIP_LEVEL_MASK & ((t->maxLod - t->minLod) << R300_TX_MAX_MIP_LEVEL_SHIFT))));
 
 	t->tile_bits = 0;
 
@@ -238,7 +279,7 @@
 
 
 	if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
-		unsigned int align = (64 / t->mt->bpp) - 1;
+		unsigned int align = (64 / _mesa_get_format_bytes(firstImage->TexFormat)) - 1;
 		t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN;
 		if (!t->image_override)
 			t->pp_txpitch = ((firstImage->Width + align) & ~align) - 1;
@@ -358,18 +399,15 @@
 	switch (depth) {
 	case 32:
 		t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
-		t->pp_txfilter |= tx_table[2].filter;
 		pitch_val /= 4;
 		break;
 	case 24:
 	default:
 		t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
-		t->pp_txfilter |= tx_table[4].filter;
 		pitch_val /= 4;
 		break;
 	case 16:
 		t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
-		t->pp_txfilter |= tx_table[5].filter;
 		pitch_val /= 2;
 		break;
 	}
@@ -410,18 +448,7 @@
     	    return;
     	}
 
-	radeon_update_renderbuffers(pDRICtx, dPriv);
-	/* back & depth buffer are useless free them right away */
-	rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
-	if (rb && rb->bo) {
-		radeon_bo_unref(rb->bo);
-        rb->bo = NULL;
-	}
-	rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
-	if (rb && rb->bo) {
-		radeon_bo_unref(rb->bo);
-		rb->bo = NULL;
-	}
+	radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE);
 	rb = rfb->color_rb[0];
 	if (rb->bo == NULL) {
 		/* Failed to BO for the buffer */
@@ -437,14 +464,10 @@
 		radeon_bo_unref(rImage->bo);
 		rImage->bo = NULL;
 	}
-	if (t->mt) {
-		radeon_miptree_unreference(t->mt);
-		t->mt = NULL;
-	}
-	if (rImage->mt) {
-		radeon_miptree_unreference(rImage->mt);
-		rImage->mt = NULL;
-	}
+
+	radeon_miptree_unreference(&t->mt);
+	radeon_miptree_unreference(&rImage->mt);
+
 	_mesa_init_teximage_fields(radeon->glCtx, target, texImage,
 				   rb->base.Width, rb->base.Height, 1, 0, rb->cpp);
 	texImage->RowStride = rb->pitch / rb->cpp;
@@ -463,18 +486,15 @@
 			t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
 		else
 			t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
-		t->pp_txfilter |= tx_table[2].filter;
 		pitch_val /= 4;
 		break;
 	case 3:
 	default:
 		t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
-		t->pp_txfilter |= tx_table[4].filter;
 		pitch_val /= 4;
 		break;
 	case 2:
 		t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
-		t->pp_txfilter |= tx_table[5].filter;
 		pitch_val /= 2;
 		break;
 	}
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
index c2f96af..aa98a04 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
@@ -365,7 +365,7 @@
 			break;
 		default:
 			fprintf(stderr, "%s:%s don't know how to handle dest %04x\n", __FILE__, __FUNCTION__, dest);
-			_mesa_exit(-1);
+			exit(-1);
 	}
 }
 
diff --git a/src/mesa/drivers/dri/r300/radeon_bo.c b/src/mesa/drivers/dri/r300/radeon_bo.c
new file mode 120000
index 0000000..9448ffe
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/radeon_bo.c
@@ -0,0 +1 @@
+../radeon/radeon_bo.c
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r300/radeon_bo_int_drm.h b/src/mesa/drivers/dri/r300/radeon_bo_int_drm.h
new file mode 120000
index 0000000..0294509
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/radeon_bo_int_drm.h
@@ -0,0 +1 @@
+../radeon/radeon_bo_int_drm.h
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r300/radeon_cs.c b/src/mesa/drivers/dri/r300/radeon_cs.c
new file mode 120000
index 0000000..66b7ad1
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/radeon_cs.c
@@ -0,0 +1 @@
+../radeon/radeon_cs.c
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r300/radeon_cs_int_drm.h b/src/mesa/drivers/dri/r300/radeon_cs_int_drm.h
new file mode 120000
index 0000000..462f524
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/radeon_cs_int_drm.h
@@ -0,0 +1 @@
+../radeon/radeon_cs_int_drm.h
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r600/Makefile b/src/mesa/drivers/dri/r600/Makefile
index 9b7c420..26f47b7 100644
--- a/src/mesa/drivers/dri/r600/Makefile
+++ b/src/mesa/drivers/dri/r600/Makefile
@@ -14,7 +14,7 @@
 endif
 
 ifeq ($(RADEON_LDFLAGS),)
-CS_SOURCES = radeon_cs_space_drm.c
+CS_SOURCES = radeon_cs_space_drm.c radeon_bo.c radeon_cs.c
 endif
 
 COMMON_SOURCES = \
diff --git a/src/mesa/drivers/dri/r600/r600_cmdbuf.c b/src/mesa/drivers/dri/r600/r600_cmdbuf.c
index d27a324..370bb04 100644
--- a/src/mesa/drivers/dri/r600/r600_cmdbuf.c
+++ b/src/mesa/drivers/dri/r600/r600_cmdbuf.c
@@ -52,29 +52,49 @@
 #include "radeon_mipmap_tree.h"
 #include "radeon_reg.h"
 
+#ifdef HAVE_LIBDRM_RADEON
+#include "radeon_cs_int.h"
+#else
+#include "radeon_cs_int_drm.h"
+#endif
 
-
-static struct radeon_cs * r600_cs_create(struct radeon_cs_manager *csm,
-                                   uint32_t ndw)
+struct r600_cs_manager_legacy
 {
-    struct radeon_cs *cs;
+    struct radeon_cs_manager    base;
+    struct radeon_context       *ctx;
+    /* hack for scratch stuff */
+    uint32_t                    pending_age;
+    uint32_t                    pending_count;
+};
 
-    cs = (struct radeon_cs*)calloc(1, sizeof(struct radeon_cs));
-    if (cs == NULL) {
+struct r600_cs_reloc_legacy {
+    struct radeon_cs_reloc  base;
+    uint32_t                cindices;
+    uint32_t                *indices;
+    uint32_t                *reloc_indices;
+};
+
+static struct radeon_cs_int *r600_cs_create(struct radeon_cs_manager *csm,
+					    uint32_t ndw)
+{
+    struct radeon_cs_int *csi;
+
+    csi = (struct radeon_cs_int*)calloc(1, sizeof(struct radeon_cs_int));
+    if (csi == NULL) {
         return NULL;
     }
-    cs->csm = csm;
-    cs->ndw = (ndw + 0x3FF) & (~0x3FF);
-    cs->packets = (uint32_t*)malloc(4*cs->ndw);
-    if (cs->packets == NULL) {
-        free(cs);
+    csi->csm = csm;
+    csi->ndw = (ndw + 0x3FF) & (~0x3FF);
+    csi->packets = (uint32_t*)malloc(4*csi->ndw);
+    if (csi->packets == NULL) {
+        free(csi);
         return NULL;
     }
-    cs->relocs_total_size = 0;
-    return cs;
+    csi->relocs_total_size = 0;
+    return csi;
 }
 
-static int r600_cs_write_reloc(struct radeon_cs *cs,
+static int r600_cs_write_reloc(struct radeon_cs_int *csi,
 			       struct radeon_bo *bo,
 			       uint32_t read_domain,
 			       uint32_t write_domain,
@@ -83,7 +103,7 @@
     struct r600_cs_reloc_legacy *relocs;
     int i;
 
-    relocs = (struct r600_cs_reloc_legacy *)cs->relocs;
+    relocs = (struct r600_cs_reloc_legacy *)csi->relocs;
     /* check domains */
     if ((read_domain && write_domain) || (!read_domain && !write_domain)) {
         /* in one CS a bo can only be in read or write domain but not
@@ -98,7 +118,7 @@
         return -EINVAL;
     }
     /* check if bo is already referenced */
-    for(i = 0; i < cs->crelocs; i++) {
+    for(i = 0; i < csi->crelocs; i++) {
         uint32_t *indices;
         uint32_t *reloc_indices;
 
@@ -129,109 +149,108 @@
             }
             relocs[i].indices = indices;
             relocs[i].reloc_indices = reloc_indices;
-            relocs[i].indices[relocs[i].cindices - 1] = cs->cdw;
-            relocs[i].reloc_indices[relocs[i].cindices - 1] = cs->cdw;
-            cs->section_cdw += 2;
-	    cs->cdw += 2;
+            relocs[i].indices[relocs[i].cindices - 1] = csi->cdw;
+            relocs[i].reloc_indices[relocs[i].cindices - 1] = csi->cdw;
+            csi->section_cdw += 2;
+	    csi->cdw += 2;
 
             return 0;
         }
     }
     /* add bo to reloc */
     relocs = (struct r600_cs_reloc_legacy*)
-             realloc(cs->relocs,
-                     sizeof(struct r600_cs_reloc_legacy) * (cs->crelocs + 1));
+             realloc(csi->relocs,
+                     sizeof(struct r600_cs_reloc_legacy) * (csi->crelocs + 1));
     if (relocs == NULL) {
         return -ENOMEM;
     }
-    cs->relocs = relocs;
-    relocs[cs->crelocs].base.bo = bo;
-    relocs[cs->crelocs].base.read_domain = read_domain;
-    relocs[cs->crelocs].base.write_domain = write_domain;
-    relocs[cs->crelocs].base.flags = flags;
-    relocs[cs->crelocs].indices = (uint32_t*)malloc(4);
-    relocs[cs->crelocs].reloc_indices = (uint32_t*)malloc(4);
-    if ( (relocs[cs->crelocs].indices == NULL) || (relocs[cs->crelocs].reloc_indices == NULL) )
+    csi->relocs = relocs;
+    relocs[csi->crelocs].base.bo = bo;
+    relocs[csi->crelocs].base.read_domain = read_domain;
+    relocs[csi->crelocs].base.write_domain = write_domain;
+    relocs[csi->crelocs].base.flags = flags;
+    relocs[csi->crelocs].indices = (uint32_t*)malloc(4);
+    relocs[csi->crelocs].reloc_indices = (uint32_t*)malloc(4);
+    if ( (relocs[csi->crelocs].indices == NULL) || (relocs[csi->crelocs].reloc_indices == NULL) )
     {
         return -ENOMEM;
     }
 
-    relocs[cs->crelocs].indices[0] = cs->cdw;
-    relocs[cs->crelocs].reloc_indices[0] = cs->cdw;
-    cs->section_cdw += 2;
-    cs->cdw += 2;
-    relocs[cs->crelocs].cindices = 1;
-    cs->relocs_total_size += radeon_bo_legacy_relocs_size(bo);
-    cs->crelocs++;
+    relocs[csi->crelocs].indices[0] = csi->cdw;
+    relocs[csi->crelocs].reloc_indices[0] = csi->cdw;
+    csi->section_cdw += 2;
+    csi->cdw += 2;
+    relocs[csi->crelocs].cindices = 1;
+    csi->relocs_total_size += radeon_bo_legacy_relocs_size(bo);
+    csi->crelocs++;
 
     radeon_bo_ref(bo);
 
     return 0;
 }
 
-static int r600_cs_begin(struct radeon_cs *cs,
+static int r600_cs_begin(struct radeon_cs_int *csi,
                     uint32_t ndw,
                     const char *file,
                     const char *func,
                     int line)
 {
-    if (cs->section) {
+    if (csi->section_ndw) {
         fprintf(stderr, "CS already in a section(%s,%s,%d)\n",
-                cs->section_file, cs->section_func, cs->section_line);
+                csi->section_file, csi->section_func, csi->section_line);
         fprintf(stderr, "CS can't start section(%s,%s,%d)\n",
                 file, func, line);
         return -EPIPE;
     }
 
-    cs->section = 1;
-    cs->section_ndw = ndw;
-    cs->section_cdw = 0;
-    cs->section_file = file;
-    cs->section_func = func;
-    cs->section_line = line;
+    csi->section_ndw = ndw;
+    csi->section_cdw = 0;
+    csi->section_file = file;
+    csi->section_func = func;
+    csi->section_line = line;
 
-    if (cs->cdw + ndw > cs->ndw) {
+    if (csi->cdw + ndw > csi->ndw) {
         uint32_t tmp, *ptr;
 	int num = (ndw > 0x400) ? ndw : 0x400;
 
-        tmp = (cs->cdw + num + 0x3FF) & (~0x3FF);
-        ptr = (uint32_t*)realloc(cs->packets, 4 * tmp);
+        tmp = (csi->cdw + num + 0x3FF) & (~0x3FF);
+        ptr = (uint32_t*)realloc(csi->packets, 4 * tmp);
         if (ptr == NULL) {
             return -ENOMEM;
         }
-        cs->packets = ptr;
-        cs->ndw = tmp;
+        csi->packets = ptr;
+        csi->ndw = tmp;
     }
 
     return 0;
 }
 
-static int r600_cs_end(struct radeon_cs *cs,
+static int r600_cs_end(struct radeon_cs_int *csi,
                   const char *file,
                   const char *func,
                   int line)
 
 {
-    if (!cs->section) {
+    if (!csi->section_ndw) {
         fprintf(stderr, "CS no section to end at (%s,%s,%d)\n",
                 file, func, line);
         return -EPIPE;
     }
-    cs->section = 0;
 
-    if ( cs->section_ndw != cs->section_cdw ) {
+    if ( csi->section_ndw != csi->section_cdw ) {
         fprintf(stderr, "CS section size missmatch start at (%s,%s,%d) %d vs %d\n",
-                cs->section_file, cs->section_func, cs->section_line, cs->section_ndw, cs->section_cdw);
-        fprintf(stderr, "cs->section_ndw = %d, cs->cdw = %d, cs->section_cdw = %d \n",
-                cs->section_ndw, cs->cdw, cs->section_cdw);
+                csi->section_file, csi->section_func, csi->section_line, csi->section_ndw, csi->section_cdw);
+        fprintf(stderr, "csi->section_ndw = %d, csi->cdw = %d, csi->section_cdw = %d \n",
+                csi->section_ndw, csi->cdw, csi->section_cdw);
         fprintf(stderr, "CS section end at (%s,%s,%d)\n",
                 file, func, line);
         return -EPIPE;
     }
+    csi->section_ndw = 0;
 
-    if (cs->cdw > cs->ndw) {
+    if (csi->cdw > csi->ndw) {
 	    fprintf(stderr, "CS section overflow at (%s,%s,%d) cdw %d ndw %d\n",
-		    cs->section_file, cs->section_func, cs->section_line,cs->cdw,cs->ndw);
+		    csi->section_file, csi->section_func, csi->section_line,csi->cdw,csi->ndw);
 	    fprintf(stderr, "CS section end at (%s,%s,%d)\n",
 		    file, func, line);
 	    assert(0);
@@ -240,20 +259,20 @@
     return 0;
 }
 
-static int r600_cs_process_relocs(struct radeon_cs *cs, 
+static int r600_cs_process_relocs(struct radeon_cs_int *csi, 
                                   uint32_t * reloc_chunk,
                                   uint32_t * length_dw_reloc_chunk) 
 {
-    struct r600_cs_manager_legacy *csm = (struct r600_cs_manager_legacy*)cs->csm;
+    struct r600_cs_manager_legacy *csm = (struct r600_cs_manager_legacy*)csi->csm;
     struct r600_cs_reloc_legacy *relocs;
     int i, j, r;
 
     uint32_t offset_dw = 0;
 
-    csm = (struct r600_cs_manager_legacy*)cs->csm;
-    relocs = (struct r600_cs_reloc_legacy *)cs->relocs;
+    csm = (struct r600_cs_manager_legacy*)csi->csm;
+    relocs = (struct r600_cs_reloc_legacy *)csi->relocs;
 restart:
-    for (i = 0; i < cs->crelocs; i++) {
+    for (i = 0; i < csi->crelocs; i++) {
             uint32_t soffset, eoffset;
 
             r = radeon_bo_legacy_validate(relocs[i].base.bo,
@@ -269,9 +288,9 @@
 
 	    for (j = 0; j < relocs[i].cindices; j++) {
 		    /* pkt3 nop header in ib chunk */
-		    cs->packets[relocs[i].reloc_indices[j]] = 0xC0001000;
+		    csi->packets[relocs[i].reloc_indices[j]] = 0xC0001000;
 		    /* reloc index in ib chunk */
-		    cs->packets[relocs[i].reloc_indices[j] + 1] = offset_dw;
+		    csi->packets[relocs[i].reloc_indices[j] + 1] = offset_dw;
 	    }
 
 	    /* asic offset in reloc chunk */ /* see alex drm r600_nomm_relocate */
@@ -286,14 +305,14 @@
     return 0;
 }
 
-static int r600_cs_set_age(struct radeon_cs *cs) /* -------------- */
+static int r600_cs_set_age(struct radeon_cs_int *csi) /* -------------- */
 {
-    struct r600_cs_manager_legacy *csm = (struct r600_cs_manager_legacy*)cs->csm;
+    struct r600_cs_manager_legacy *csm = (struct r600_cs_manager_legacy*)csi->csm;
     struct r600_cs_reloc_legacy *relocs;
     int i;
 
-    relocs = (struct r600_cs_reloc_legacy *)cs->relocs;
-    for (i = 0; i < cs->crelocs; i++) {
+    relocs = (struct r600_cs_reloc_legacy *)csi->relocs;
+    for (i = 0; i < csi->crelocs; i++) {
         radeon_bo_legacy_pending(relocs[i].base.bo, csm->pending_age);
         radeon_bo_unref(relocs[i].base.bo);
     }
@@ -301,21 +320,21 @@
 }
 
 #if 0
-static void dump_cmdbuf(struct radeon_cs *cs)
+static void dump_cmdbuf(struct radeon_cs_int *csi)
 {
 	int i;
 	fprintf(stderr,"--start--\n");
-	for (i = 0; i < cs->cdw; i++){
-		fprintf(stderr,"0x%08x\n", cs->packets[i]);
+	for (i = 0; i < csi->cdw; i++){
+		fprintf(stderr,"0x%08x\n", csi->packets[i]);
 	}
 	fprintf(stderr,"--end--\n");
 
 }
 #endif
 
-static int r600_cs_emit(struct radeon_cs *cs)
+static int r600_cs_emit(struct radeon_cs_int *csi)
 {
-    struct r600_cs_manager_legacy *csm = (struct r600_cs_manager_legacy*)cs->csm;
+    struct r600_cs_manager_legacy *csm = (struct r600_cs_manager_legacy*)csi->csm;
     struct drm_radeon_cs       cs_cmd;
     struct drm_radeon_cs_chunk cs_chunk[2];
     uint32_t length_dw_reloc_chunk;
@@ -329,9 +348,9 @@
 
     csm->pending_count = 1;
 
-    reloc_chunk = (uint32_t*)calloc(1, cs->crelocs * 4 * 4);
+    reloc_chunk = (uint32_t*)calloc(1, csi->crelocs * 4 * 4);
 
-    r = r600_cs_process_relocs(cs, reloc_chunk, &length_dw_reloc_chunk);
+    r = r600_cs_process_relocs(csi, reloc_chunk, &length_dw_reloc_chunk);
     if (r) {
 	free(reloc_chunk);
         return 0;
@@ -339,8 +358,8 @@
 
     /* raw ib chunk */
     cs_chunk[0].chunk_id   = RADEON_CHUNK_ID_IB;
-    cs_chunk[0].length_dw  = cs->cdw;
-    cs_chunk[0].chunk_data = (unsigned long)(cs->packets);
+    cs_chunk[0].length_dw  = csi->cdw;
+    cs_chunk[0].chunk_data = (unsigned long)(csi->packets);
 
     /* reloc chaunk */
     cs_chunk[1].chunk_id   = RADEON_CHUNK_ID_RELOCS;
@@ -358,7 +377,7 @@
 
     do 
     {
-        r = drmCommandWriteRead(cs->csm->fd, DRM_RADEON_CS, &cs_cmd, sizeof(cs_cmd));
+        r = drmCommandWriteRead(csi->csm->fd, DRM_RADEON_CS, &cs_cmd, sizeof(cs_cmd));
         retry++;
     } while (r == -EAGAIN && retry < 1000);
 
@@ -369,11 +388,11 @@
 
     csm->pending_age = cs_cmd.cs_id;
 
-    r600_cs_set_age(cs);
+    r600_cs_set_age(csi);
 
-    cs->csm->read_used = 0;
-    cs->csm->vram_write_used = 0;
-    cs->csm->gart_write_used = 0;
+    csi->csm->read_used = 0;
+    csi->csm->vram_write_used = 0;
+    csi->csm->gart_write_used = 0;
 
     free(reloc_chunk);
 
@@ -393,35 +412,34 @@
     }
 }
 
-static int r600_cs_destroy(struct radeon_cs *cs)
+static int r600_cs_destroy(struct radeon_cs_int *csi)
 {
-    r600_cs_free_reloc(cs->relocs, cs->crelocs);
-    free(cs->relocs);
-    free(cs->packets);
-    free(cs);
+    r600_cs_free_reloc(csi->relocs, csi->crelocs);
+    free(csi->relocs);
+    free(csi->packets);
+    free(csi);
     return 0;
 }
 
-static int r600_cs_erase(struct radeon_cs *cs)
+static int r600_cs_erase(struct radeon_cs_int *csi)
 {
-    r600_cs_free_reloc(cs->relocs, cs->crelocs);
-    free(cs->relocs);
-    cs->relocs_total_size = 0;
-    cs->relocs = NULL;
-    cs->crelocs = 0;
-    cs->cdw = 0;
-    cs->section = 0;
+    r600_cs_free_reloc(csi->relocs, csi->crelocs);
+    free(csi->relocs);
+    csi->relocs_total_size = 0;
+    csi->relocs = NULL;
+    csi->crelocs = 0;
+    csi->cdw = 0;
     return 0;
 }
 
-static int r600_cs_need_flush(struct radeon_cs *cs)
+static int r600_cs_need_flush(struct radeon_cs_int *csi)
 {
     /* this function used to flush when the BO usage got to
      * a certain size, now the higher levels handle this better */
     return 0;
 }
 
-static void r600_cs_print(struct radeon_cs *cs, FILE *file)
+static void r600_cs_print(struct radeon_cs_int *csi, FILE *file)
 {
 }
 
diff --git a/src/mesa/drivers/dri/r600/r600_cmdbuf.h b/src/mesa/drivers/dri/r600/r600_cmdbuf.h
index eba43d3..dff0009 100644
--- a/src/mesa/drivers/dri/r600/r600_cmdbuf.h
+++ b/src/mesa/drivers/dri/r600/r600_cmdbuf.h
@@ -118,22 +118,6 @@
 #define R600_IT_SET_CTL_CONST                     0x00006F00
 #define R600_IT_SURFACE_BASE_UPDATE               0x00007300
 
-struct r600_cs_manager_legacy
-{
-    struct radeon_cs_manager    base;
-    struct radeon_context       *ctx;
-    /* hack for scratch stuff */
-    uint32_t                    pending_age;
-    uint32_t                    pending_count;
-};
-
-struct r600_cs_reloc_legacy {
-    struct radeon_cs_reloc  base;
-    uint32_t                cindices;
-    uint32_t                *indices;
-    uint32_t                *reloc_indices;
-};
-
 struct radeon_cs_manager * r600_radeon_cs_manager_legacy_ctor(struct radeon_context *ctx);
 
 /**
diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c
index dbd2337..cb54949 100644
--- a/src/mesa/drivers/dri/r600/r600_context.c
+++ b/src/mesa/drivers/dri/r600/r600_context.c
@@ -74,6 +74,8 @@
 #include "utils.h"
 #include "xmlpool.h"		/* for symbolic values of enum-type options */
 
+#define R600_ENABLE_GLSL_TEST 1
+
 #define need_GL_VERSION_2_0
 #define need_GL_ARB_occlusion_query
 #define need_GL_ARB_point_parameters
@@ -97,6 +99,7 @@
   {"GL_ARB_depth_clamp",                NULL},
   {"GL_ARB_depth_texture",		NULL},
   {"GL_ARB_fragment_program",		NULL},
+  {"GL_ARB_fragment_program_shadow",	NULL},
   {"GL_ARB_occlusion_query",            GL_ARB_occlusion_query_functions},
   {"GL_ARB_multitexture",		NULL},
   {"GL_ARB_point_parameters",		GL_ARB_point_parameters_functions},
@@ -109,6 +112,7 @@
   {"GL_ARB_texture_env_crossbar",	NULL},
   {"GL_ARB_texture_env_dot3",		NULL},
   {"GL_ARB_texture_mirrored_repeat",	NULL},
+  {"GL_ARB_texture_non_power_of_two",   NULL},
   {"GL_ARB_vertex_program",		GL_ARB_vertex_program_functions},
   {"GL_EXT_blend_equation_separate",	GL_EXT_blend_equation_separate_functions},
   {"GL_EXT_blend_func_separate",	GL_EXT_blend_func_separate_functions},
@@ -155,7 +159,12 @@
  * functions added by GL_ATI_separate_stencil.
  */
 static const struct dri_extension gl_20_extension[] = {
+#ifdef R600_ENABLE_GLSL_TEST
+    {"GL_ARB_shading_language_100",			GL_VERSION_2_0_functions },
+#else
   {"GL_VERSION_2_0",			GL_VERSION_2_0_functions },
+#endif /* R600_ENABLE_GLSL_TEST */
+  {NULL, NULL}
 };
 
 static const struct tnl_pipeline_stage *r600_pipeline[] = {
@@ -308,6 +317,14 @@
 	if (r600->radeon.radeonScreen->kernel_mm)
 	  driInitExtensions(ctx, mm_extensions, GL_FALSE);
 
+#ifdef R600_ENABLE_GLSL_TEST
+    driInitExtensions(ctx, gl_20_extension, GL_TRUE);
+    _mesa_enable_2_0_extensions(ctx);
+    
+    /* glsl compiler has problem if this is not GL_TRUE */
+    ctx->Shader.EmitCondCodes = GL_TRUE;
+#endif /* R600_ENABLE_GLSL_TEST */
+
 	if (driQueryOptionb
 	    (&r600->radeon.optionCache, "disable_stencil_two_side"))
 		_mesa_disable_extension(ctx, "GL_EXT_stencil_two_side");
@@ -330,10 +347,10 @@
 /* Create the device specific rendering context.
  */
 GLboolean r600CreateContext(const __GLcontextModes * glVisual,
-			    __DRIcontextPrivate * driContextPriv,
+			    __DRIcontext * driContextPriv,
 			    void *sharedContextPrivate)
 {
-	__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+	__DRIscreen *sPriv = driContextPriv->driScreenPriv;
 	radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
 	struct dd_function_table functions;
 	context_t *r600;
diff --git a/src/mesa/drivers/dri/r600/r600_context.h b/src/mesa/drivers/dri/r600/r600_context.h
index 394fd75..a1b4af7 100644
--- a/src/mesa/drivers/dri/r600/r600_context.h
+++ b/src/mesa/drivers/dri/r600/r600_context.h
@@ -108,6 +108,7 @@
 	GLint   size;   //number of data element
 	GLenum  type;  //data element type
 	GLsizei stride;
+	GLenum  format; // GL_RGBA,GLBGRA 
 
 	struct radeon_bo *bo;
 	GLint  bo_offset;
@@ -153,7 +154,7 @@
 #define GL_CONTEXT(context)     ((GLcontext *)(context->radeon.glCtx))
 
 extern GLboolean r600CreateContext(const __GLcontextModes * glVisual,
-				   __DRIcontextPrivate * driContextPriv,
+				   __DRIcontext * driContextPriv,
 				   void *sharedContextPrivate);
 
 #define R700_CONTEXT_STATES(context) ((R700_CHIP_CONTEXT *)(&context->hw))
diff --git a/src/mesa/drivers/dri/r600/r600_reg_r6xx.h b/src/mesa/drivers/dri/r600/r600_reg_r6xx.h
index f7702c4..74af7b4 100644
--- a/src/mesa/drivers/dri/r600/r600_reg_r6xx.h
+++ b/src/mesa/drivers/dri/r600/r600_reg_r6xx.h
@@ -415,11 +415,11 @@
 	ALPHA_TO_MASK_ENABLE                              = 1 << 0,
 	ALPHA_TO_MASK_OFFSET0_mask                        = 0x03 << 8,
 	ALPHA_TO_MASK_OFFSET0_shift                       = 8,
-	ALPHA_TO_MASK_OFFSET1_mask                        = 0x03 << 8,
+	ALPHA_TO_MASK_OFFSET1_mask                        = 0x03 << 10,
 	ALPHA_TO_MASK_OFFSET1_shift                       = 10,
-	ALPHA_TO_MASK_OFFSET2_mask                        = 0x03 << 8,
+	ALPHA_TO_MASK_OFFSET2_mask                        = 0x03 << 12,
 	ALPHA_TO_MASK_OFFSET2_shift                       = 12,
-	ALPHA_TO_MASK_OFFSET3_mask                        = 0x03 << 8,
+	ALPHA_TO_MASK_OFFSET3_mask                        = 0x03 << 14,
 	ALPHA_TO_MASK_OFFSET3_shift                       = 14,
 
 //  SQ_VTX_CONSTANT_WORD2_0                               = 0x00038008,
diff --git a/src/mesa/drivers/dri/r600/r600_reg_r7xx.h b/src/mesa/drivers/dri/r600/r600_reg_r7xx.h
index e5c01c8..eb169bd 100644
--- a/src/mesa/drivers/dri/r600/r600_reg_r7xx.h
+++ b/src/mesa/drivers/dri/r600/r600_reg_r7xx.h
@@ -143,6 +143,8 @@
 //  SQ_TEX_SAMPLER_MISC_0                                 = 0x0003d03c,
 	R7xx_TRUNCATE_COORD_bit                           = 1 << 9,
 	R7xx_DISABLE_CUBE_WRAP_bit                        = 1 << 10,
+//  DB_RENDER_CONTROL                                     = 0x00028d0c,
+	PERFECT_ZPASS_COUNTS_bit                          = 1 << 15,
 
 } ;
 
diff --git a/src/mesa/drivers/dri/r600/r600_tex.c b/src/mesa/drivers/dri/r600/r600_tex.c
index 20965bb..f745fe3 100644
--- a/src/mesa/drivers/dri/r600/r600_tex.c
+++ b/src/mesa/drivers/dri/r600/r600_tex.c
@@ -305,23 +305,14 @@
 		break;
 
 	case GL_TEXTURE_BORDER_COLOR:
-		r600SetTexBorderColor(t, texObj->BorderColor);
+		r600SetTexBorderColor(t, texObj->BorderColor.f);
 		break;
 
 	case GL_TEXTURE_BASE_LEVEL:
 	case GL_TEXTURE_MAX_LEVEL:
 	case GL_TEXTURE_MIN_LOD:
 	case GL_TEXTURE_MAX_LOD:
-		/* This isn't the most efficient solution but there doesn't appear to
-		 * be a nice alternative.  Since there's no LOD clamping,
-		 * we just have to rely on loading the right subset of mipmap levels
-		 * to simulate a clamped LOD.
-		 */
-		if (t->mt) {
-			radeon_miptree_unreference(t->mt);
-			t->mt = 0;
-			t->validated = GL_FALSE;
-		}
+		t->validated = GL_FALSE;
 		break;
 
 	case GL_DEPTH_TEXTURE_MODE:
@@ -369,10 +360,8 @@
 		t->bo = NULL;
 	}
 
-	if (t->mt) {
-		radeon_miptree_unreference(t->mt);
-		t->mt = 0;
-	}
+	radeon_miptree_unreference(&t->mt);
+
 	_mesa_delete_texture_object(ctx, texObj);
 }
 
@@ -402,7 +391,7 @@
 	r600SetTexDefaultState(t);
 	r600UpdateTexWrap(t);
 	r600SetTexFilter(t, t->base.MinFilter, t->base.MagFilter, t->base.MaxAnisotropy);
-	r600SetTexBorderColor(t, t->base.BorderColor);
+	r600SetTexBorderColor(t, t->base.BorderColor.f);
 
 	return &t->base;
 }
diff --git a/src/mesa/drivers/dri/r600/r600_texstate.c b/src/mesa/drivers/dri/r600/r600_texstate.c
index 27c8354..b8466bd 100644
--- a/src/mesa/drivers/dri/r600/r600_texstate.c
+++ b/src/mesa/drivers/dri/r600/r600_texstate.c
@@ -91,7 +91,7 @@
 	SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
 		 FORMAT_COMP_Y_shift, FORMAT_COMP_Y_mask);
 	SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
-		 FORMAT_COMP_X_shift, FORMAT_COMP_Z_mask);
+		 FORMAT_COMP_Z_shift, FORMAT_COMP_Z_mask);
 	SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
 		 FORMAT_COMP_W_shift, FORMAT_COMP_W_mask);
 
@@ -357,37 +357,37 @@
 		SETfield(t->SQ_TEX_RESOURCE1, FMT_32_32_32_32_FLOAT,
 			 SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
 
-		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
-			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
-		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
-			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
-		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
-			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
 		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
 			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
 		break;
 	case MESA_FORMAT_RGBA_FLOAT16:
 		SETfield(t->SQ_TEX_RESOURCE1, FMT_16_16_16_16_FLOAT,
 			 SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
 
-		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
-			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
-		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
-			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
-		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
-			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
 		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
 			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
 		break;
 	case MESA_FORMAT_RGB_FLOAT32: /* X, Y, Z, ONE */
 		SETfield(t->SQ_TEX_RESOURCE1, FMT_32_32_32_FLOAT,
 			 SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
 
-		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
 			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
 		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
 			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
-		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
 			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
 		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
 			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
@@ -396,11 +396,11 @@
 		SETfield(t->SQ_TEX_RESOURCE1, FMT_16_16_16_FLOAT,
 			 SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
 
-		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
 			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
 		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
 			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
-		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
 			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
 		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
 			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
@@ -461,26 +461,26 @@
 		SETfield(t->SQ_TEX_RESOURCE1, FMT_32_32_FLOAT,
 			 SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
 
-		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
-			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
-		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
-			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
-		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
-			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
 		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
 			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
 		break;
 	case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
 		SETfield(t->SQ_TEX_RESOURCE1, FMT_16_16_FLOAT,
 			 SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
 
-		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
-			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
-		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
-			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
-		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
-			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
 		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+		SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
 			 SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
 		break;
 	case MESA_FORMAT_INTENSITY_FLOAT32: /* X, X, X, X */
@@ -626,6 +626,31 @@
 	return GL_TRUE;
 }
 
+static GLuint r600_translate_shadow_func(GLenum func)
+{
+   switch (func) {
+   case GL_NEVER:
+      return SQ_TEX_DEPTH_COMPARE_NEVER;
+   case GL_LESS:
+      return SQ_TEX_DEPTH_COMPARE_LESS;
+   case GL_LEQUAL:
+      return SQ_TEX_DEPTH_COMPARE_LESSEQUAL;
+   case GL_GREATER:
+      return SQ_TEX_DEPTH_COMPARE_GREATER;
+   case GL_GEQUAL:
+      return SQ_TEX_DEPTH_COMPARE_GREATEREQUAL;
+   case GL_NOTEQUAL:
+      return SQ_TEX_DEPTH_COMPARE_NOTEQUAL;
+   case GL_EQUAL:
+      return SQ_TEX_DEPTH_COMPARE_EQUAL;
+   case GL_ALWAYS:
+      return SQ_TEX_DEPTH_COMPARE_ALWAYS;
+   default:
+      WARN_ONCE("Unknown shadow compare function! %d", func);
+      return 0;
+   }
+}
+
 void r600SetDepthTexMode(struct gl_texture_object *tObj)
 {
 	radeonTexObjPtr t;
@@ -649,7 +674,6 @@
 {
 	radeonTexObj *t = radeon_tex_obj(texObj);
 	const struct gl_texture_image *firstImage;
-	int firstlevel = t->mt ? t->mt->firstLevel : 0;
 	GLuint uTexelPitch, row_align;
 
 	if (rmesa->radeon.radeonScreen->driScreen->dri2.enabled &&
@@ -657,7 +681,7 @@
 	    t->bo)
 		return;
 
-	firstImage = t->base.Image[0][firstlevel];
+	firstImage = t->base.Image[0][t->minLod];
 
 	if (!t->image_override) {
 		if (!r600GetTexFormat(texObj, firstImage->TexFormat)) {
@@ -692,7 +716,8 @@
 	}
 
 	row_align = rmesa->radeon.texture_row_align - 1;
-	uTexelPitch = ((firstImage->Width * t->mt->bpp + row_align) & ~row_align) / t->mt->bpp;
+	uTexelPitch = (_mesa_format_row_stride(firstImage->TexFormat, firstImage->Width) + row_align) & ~row_align;
+	uTexelPitch = uTexelPitch / _mesa_get_format_bytes(firstImage->TexFormat);
 	uTexelPitch = (uTexelPitch + R700_TEXEL_PITCH_ALIGNMENT_MASK)
 		& ~R700_TEXEL_PITCH_ALIGNMENT_MASK;
 
@@ -706,11 +731,22 @@
 	SETfield(t->SQ_TEX_RESOURCE1, firstImage->Height - 1,
 		 TEX_HEIGHT_shift, TEX_HEIGHT_mask);
 
-	if ((t->mt->lastLevel - t->mt->firstLevel) > 0) {
-		t->SQ_TEX_RESOURCE3 = t->mt->levels[0].size / 256;
-		SETfield(t->SQ_TEX_RESOURCE4, t->mt->firstLevel, BASE_LEVEL_shift, BASE_LEVEL_mask);
-		SETfield(t->SQ_TEX_RESOURCE5, t->mt->lastLevel, LAST_LEVEL_shift, LAST_LEVEL_mask);
+	t->SQ_TEX_RESOURCE2 = get_base_teximage_offset(t) / 256;
+
+	if ((t->maxLod - t->minLod) > 0) {
+		t->SQ_TEX_RESOURCE3 = radeon_miptree_image_offset(t->mt, 0, t->minLod + 1) / 256;
+		SETfield(t->SQ_TEX_RESOURCE4, 0, BASE_LEVEL_shift, BASE_LEVEL_mask);
+		SETfield(t->SQ_TEX_RESOURCE5, t->maxLod - t->minLod, LAST_LEVEL_shift, LAST_LEVEL_mask);
 	}
+	if(texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB)
+	{
+		SETfield(t->SQ_TEX_SAMPLER0, r600_translate_shadow_func(texObj->CompareFunc), DEPTH_COMPARE_FUNCTION_shift, DEPTH_COMPARE_FUNCTION_mask);
+	}
+	else
+	{
+		CLEARfield(t->SQ_TEX_SAMPLER0, DEPTH_COMPARE_FUNCTION_mask);
+	}
+
 }
 
 /**
@@ -808,9 +844,8 @@
 	struct gl_texture_object *tObj =
 	    _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
 	radeonTexObjPtr t = radeon_tex_obj(tObj);
-	int firstlevel = t->mt ? t->mt->firstLevel : 0;
 	const struct gl_texture_image *firstImage;
-	uint32_t pitch_val, size, row_align, bpp;
+	uint32_t pitch_val, size, row_align;
 
 	if (!tObj)
 		return;
@@ -820,13 +855,9 @@
 	if (!offset)
 		return;
 
-	bpp = depth / 8;
-	if (bpp == 3) 
-		bpp = 4;
-
-	firstImage = t->base.Image[0][firstlevel];
+	firstImage = t->base.Image[0][t->minLod];
 	row_align = rmesa->radeon.texture_row_align - 1;
-	size = ((firstImage->Width * bpp + row_align) & ~row_align) * firstImage->Height;
+	size = ((_mesa_format_row_stride(firstImage->TexFormat, firstImage->Width) + row_align) & ~row_align) * firstImage->Height;
 	if (t->bo) {
 		radeon_bo_unref(t->bo);
 		t->bo = NULL;
@@ -922,18 +953,7 @@
     	    return;
     	}
 
-	radeon_update_renderbuffers(pDRICtx, dPriv);
-	/* back & depth buffer are useless free them right away */
-	rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
-	if (rb && rb->bo) {
-		radeon_bo_unref(rb->bo);
-        rb->bo = NULL;
-	}
-	rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
-	if (rb && rb->bo) {
-		radeon_bo_unref(rb->bo);
-		rb->bo = NULL;
-	}
+	radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE);
 	rb = rfb->color_rb[0];
 	if (rb->bo == NULL) {
 		/* Failed to BO for the buffer */
@@ -949,14 +969,10 @@
 		radeon_bo_unref(rImage->bo);
 		rImage->bo = NULL;
 	}
-	if (t->mt) {
-		radeon_miptree_unreference(t->mt);
-		t->mt = NULL;
-	}
-	if (rImage->mt) {
-		radeon_miptree_unreference(rImage->mt);
-		rImage->mt = NULL;
-	}
+
+	radeon_miptree_unreference(&t->mt);
+	radeon_miptree_unreference(&rImage->mt);
+
 	_mesa_init_teximage_fields(radeon->glCtx, target, texImage,
 				   rb->base.Width, rb->base.Height, 1, 0, rb->cpp);
 	texImage->RowStride = rb->pitch / rb->cpp;
diff --git a/src/mesa/drivers/dri/r600/r700_assembler.c b/src/mesa/drivers/dri/r600/r700_assembler.c
index e0d7d4f..0ff16b4 100644
--- a/src/mesa/drivers/dri/r600/r700_assembler.c
+++ b/src/mesa/drivers/dri/r600/r700_assembler.c
@@ -32,12 +32,49 @@
 
 #include "main/mtypes.h"
 #include "main/imports.h"
+#include "shader/prog_parameter.h"
 
 #include "radeon_debug.h"
 #include "r600_context.h"
 
 #include "r700_assembler.h"
 
+#define USE_CF_FOR_CONTINUE_BREAK 1
+#define USE_CF_FOR_POP_AFTER      1
+
+struct prog_instruction noise1_insts[12] = { 
+    {OPCODE_BGNSUB , {{13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}}, {13, 0, 15, 0, 8, 1672, 0}, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0}, 
+    {OPCODE_MOV , {{0, 0, 0, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}}, {0, 0, 2, 0, 8, 1672, 0}, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0}, 
+    {OPCODE_MOV , {{8, 0, 0, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}}, {0, 0, 4, 0, 8, 1672, 0}, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0}, 
+    {OPCODE_MOV , {{8, 0, 585, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}}, {0, 0, 8, 0, 8, 1672, 0}, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0}, 
+    {OPCODE_SGT , {{0, 0, 585, 0, 0, 0}, {8, 0, 1170, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}}, {0, 1, 1, 0, 8, 1672, 0}, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0}, 
+    {OPCODE_IF , {{13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}}, {13, 0, 15, 0, 7, 0, 0}, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0}, 
+    {OPCODE_MOV , {{0, 0, 1755, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}}, {0, 0, 1, 0, 8, 1672, 0}, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0}, 
+    {OPCODE_RET , {{13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}}, {13, 0, 15, 0, 8, 1672, 0}, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0}, 
+    {OPCODE_ENDIF , {{13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}}, {13, 0, 15, 0, 8, 1672, 0}, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0}, 
+    {OPCODE_MOV , {{0, 0, 1170, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}}, {0, 0, 1, 0, 8, 1672, 0}, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0}, 
+    {OPCODE_RET , {{13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}}, {13, 0, 15, 0, 8, 1672, 0}, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0}, 
+    {OPCODE_ENDSUB , {{13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}, {13, 0, 1672, 0, 0, 0}}, {13, 0, 15, 0, 8, 1672, 0}, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0}
+};
+float noise1_const[2][4] = {
+    {0.300000f, 0.900000f, 0.500000f, 0.300000f}
+};
+
+COMPILED_SUB noise1_presub = {
+    &(noise1_insts[0]),
+    12, 
+    2, 
+    1, 
+    0, 
+    &(noise1_const[0]), 
+    SWIZZLE_X, 
+    SWIZZLE_X, 
+    SWIZZLE_X, 
+    SWIZZLE_X,
+    {0,0,0},
+    0 
+};
+
 BITS addrmode_PVSDST(PVSDST * pPVSDST)
 {
 	return pPVSDST->addrmode0 | ((BITS)pPVSDST->addrmode1 << 1);
@@ -327,22 +364,27 @@
     return(format);
 }
 
-unsigned int r700GetNumOperands(r700_AssemblerBase* pAsm)
+unsigned int r700GetNumOperands(GLuint opcode, GLuint nIsOp3) 
 {
-    if(pAsm->D.dst.op3)
+    if(nIsOp3 > 0)
     {
         return 3;
     }
 
-    switch (pAsm->D.dst.opcode)
+    switch (opcode)
     {
     case SQ_OP2_INST_ADD:
+    case SQ_OP2_INST_KILLE:
     case SQ_OP2_INST_KILLGT:
+    case SQ_OP2_INST_KILLGE:
+    case SQ_OP2_INST_KILLNE:
     case SQ_OP2_INST_MUL: 
     case SQ_OP2_INST_MAX:
     case SQ_OP2_INST_MIN:
     //case SQ_OP2_INST_MAX_DX10:
     //case SQ_OP2_INST_MIN_DX10:
+    case SQ_OP2_INST_SETE: 
+    case SQ_OP2_INST_SETNE:
     case SQ_OP2_INST_SETGT:
     case SQ_OP2_INST_SETGE:
     case SQ_OP2_INST_PRED_SETE:
@@ -358,6 +400,7 @@
     case SQ_OP2_INST_MOVA_FLOOR:
     case SQ_OP2_INST_FRACT:
     case SQ_OP2_INST_FLOOR:
+    case SQ_OP2_INST_TRUNC:
     case SQ_OP2_INST_EXP_IEEE:
     case SQ_OP2_INST_LOG_CLAMPED:
     case SQ_OP2_INST_LOG_IEEE:
@@ -369,7 +412,7 @@
         return 1;
         
     default: radeon_error(
-		    "Need instruction operand number for %x.\n", pAsm->D.dst.opcode);
+		    "Need instruction operand number for %x.\n", opcode); 
     };
 
     return 3;
@@ -383,103 +426,128 @@
     pAsm->pR700Shader = pShader;
     pAsm->currentShaderType = spt;
 
-	pAsm->cf_last_export_ptr   = NULL;
+    pAsm->cf_last_export_ptr   = NULL;
 
-	pAsm->cf_current_export_clause_ptr = NULL;
-	pAsm->cf_current_alu_clause_ptr    = NULL;
-	pAsm->cf_current_tex_clause_ptr    = NULL;
-	pAsm->cf_current_vtx_clause_ptr    = NULL;
-	pAsm->cf_current_cf_clause_ptr     = NULL;
+    pAsm->cf_current_export_clause_ptr = NULL;
+    pAsm->cf_current_alu_clause_ptr    = NULL;
+    pAsm->cf_current_tex_clause_ptr    = NULL;
+    pAsm->cf_current_vtx_clause_ptr    = NULL;
+    pAsm->cf_current_cf_clause_ptr     = NULL;
 
-	// No clause has been created yet
-	pAsm->cf_current_clause_type = CF_EMPTY_CLAUSE;
+    // No clause has been created yet
+    pAsm->cf_current_clause_type = CF_EMPTY_CLAUSE;
 
-	pAsm->number_of_colorandz_exports = 0;
-	pAsm->number_of_exports           = 0;
-	pAsm->number_of_export_opcodes    = 0;
+    pAsm->number_of_colorandz_exports = 0;
+    pAsm->number_of_exports           = 0;
+    pAsm->number_of_export_opcodes    = 0;
 
+    pAsm->alu_x_opcode = 0;
 
-	pAsm->D.bits = 0;
-	pAsm->S[0].bits = 0;
-	pAsm->S[1].bits = 0;
-	pAsm->S[2].bits = 0;
+    pAsm->D2.bits = 0;
 
-	pAsm->uLastPosUpdate = 0; 
+    pAsm->D.bits = 0;
+    pAsm->S[0].bits = 0;
+    pAsm->S[1].bits = 0;
+    pAsm->S[2].bits = 0;
+
+    pAsm->uLastPosUpdate = 0; 
 	
-	*(BITS *) &pAsm->fp_stOutFmt0 = 0;
+    *(BITS *) &pAsm->fp_stOutFmt0 = 0;
 
-	pAsm->uIIns = 0;
-	pAsm->uOIns = 0;
-	pAsm->number_used_registers = 0;
-	pAsm->uUsedConsts = 256; 
+    pAsm->uIIns = 0;
+    pAsm->uOIns = 0;
+    pAsm->number_used_registers = 0;
+    pAsm->uUsedConsts = 256; 
 
 
-	// Fragment programs
-	pAsm->uBoolConsts = 0;
-	pAsm->uIntConsts = 0;
-	pAsm->uInsts = 0;
-	pAsm->uConsts = 0;
+    // Fragment programs
+    pAsm->uBoolConsts = 0;
+    pAsm->uIntConsts = 0;
+    pAsm->uInsts = 0;
+    pAsm->uConsts = 0;
 
-	pAsm->FCSP = 0;
-	pAsm->fc_stack[0].type = FC_NONE;
+    pAsm->FCSP = 0;
+    pAsm->fc_stack[0].type = FC_NONE;
 
-	pAsm->branch_depth     = 0;
-	pAsm->max_branch_depth = 0;
+    pAsm->aArgSubst[0] =
+    pAsm->aArgSubst[1] =
+    pAsm->aArgSubst[2] =
+    pAsm->aArgSubst[3] = (-1);
 
-	pAsm->aArgSubst[0] =
-	pAsm->aArgSubst[1] =
-	pAsm->aArgSubst[2] =
-	pAsm->aArgSubst[3] = (-1);
+    pAsm->uOutputs = 0;
 
-	pAsm->uOutputs = 0;
-
-	for (i=0; i<NUMBER_OF_OUTPUT_COLORS; i++) 
-	{
-		pAsm->color_export_register_number[i] = (-1);
-	}
+    for (i=0; i<NUMBER_OF_OUTPUT_COLORS; i++) 
+    {
+        pAsm->color_export_register_number[i] = (-1);
+    }
 
 
-	pAsm->depth_export_register_number = (-1);
-	pAsm->stencil_export_register_number = (-1);
-	pAsm->coverage_to_mask_export_register_number = (-1);
-	pAsm->mask_export_register_number = (-1);
+    pAsm->depth_export_register_number = (-1);
+    pAsm->stencil_export_register_number = (-1);
+    pAsm->coverage_to_mask_export_register_number = (-1);
+    pAsm->mask_export_register_number = (-1);
 
-	pAsm->starting_export_register_number = 0;
-	pAsm->starting_vfetch_register_number = 0;
-	pAsm->starting_temp_register_number   = 0;
-	pAsm->uFirstHelpReg = 0;
+    pAsm->starting_export_register_number = 0;
+    pAsm->starting_vfetch_register_number = 0;
+    pAsm->starting_temp_register_number   = 0;
+    pAsm->uFirstHelpReg = 0;
 
+    pAsm->input_position_is_used = GL_FALSE;
+    pAsm->input_normal_is_used   = GL_FALSE;
 
-	pAsm->input_position_is_used = GL_FALSE;
-	pAsm->input_normal_is_used   = GL_FALSE;
+    for (i=0; i<NUMBER_OF_INPUT_COLORS; i++) 
+    {
+        pAsm->input_color_is_used[ i ] = GL_FALSE;
+    }
 
+    for (i=0; i<NUMBER_OF_TEXTURE_UNITS; i++) 
+    {
+        pAsm->input_texture_unit_is_used[ i ] = GL_FALSE;
+    }
 
-	for (i=0; i<NUMBER_OF_INPUT_COLORS; i++) 
-	{
-		pAsm->input_color_is_used[ i ] = GL_FALSE;
-	}
+    for (i=0; i<VERT_ATTRIB_MAX; i++) 
+    {
+        pAsm->vfetch_instruction_ptr_array[ i ] = NULL;
+    }
 
-	for (i=0; i<NUMBER_OF_TEXTURE_UNITS; i++) 
-	{
-		pAsm->input_texture_unit_is_used[ i ] = GL_FALSE;
-	}
+    pAsm->number_of_inputs = 0;
 
-	for (i=0; i<VERT_ATTRIB_MAX; i++) 
-	{
-		pAsm->vfetch_instruction_ptr_array[ i ] = NULL;
-	}
+    pAsm->is_tex = GL_FALSE;
+    pAsm->need_tex_barrier = GL_FALSE;
 
-	pAsm->number_of_inputs = 0;
+    pAsm->subs              = NULL;
+    pAsm->unSubArraySize    = 0;
+    pAsm->unSubArrayPointer = 0;
+    pAsm->callers              = NULL;
+    pAsm->unCallerArraySize    = 0;
+    pAsm->unCallerArrayPointer = 0;
 
-	pAsm->is_tex = GL_FALSE;
-	pAsm->need_tex_barrier = GL_FALSE;
+    pAsm->CALLSP = 0;
+    pAsm->CALLSTACK[0].FCSP_BeforeEntry = 0;
+    pAsm->CALLSTACK[0].plstCFInstructions_local
+          = &(pAsm->pR700Shader->lstCFInstructions);
 
-	return 0;
+    pAsm->CALLSTACK[0].max = 0;
+    pAsm->CALLSTACK[0].current = 0;
+
+    SetActiveCFlist(pAsm->pR700Shader, pAsm->CALLSTACK[0].plstCFInstructions_local);
+
+    pAsm->unCFflags = 0;
+
+    pAsm->presubs           = NULL;
+    pAsm->unPresubArraySize = 0;
+    pAsm->unNumPresub       = 0;
+    pAsm->unCurNumILInsts   = 0;
+
+    pAsm->unVetTexBits      = 0;
+
+    return 0;
 }
 
 GLboolean IsTex(gl_inst_opcode Opcode)
 {
-    if( (OPCODE_TEX==Opcode) || (OPCODE_TXP==Opcode) || (OPCODE_TXB==Opcode) )
+    if( (OPCODE_TEX==Opcode) || (OPCODE_TXP==Opcode) || (OPCODE_TXB==Opcode) ||
+        (OPCODE_DDX==Opcode) || (OPCODE_DDY==Opcode) )
     {
         return GL_TRUE;
     }
@@ -592,6 +660,31 @@
     return GL_TRUE;
 }
 
+GLboolean add_cf_instruction(r700_AssemblerBase* pAsm)
+{
+    if(GL_FALSE == check_current_clause(pAsm, CF_OTHER_CLAUSE))
+    {
+        return GL_FALSE;
+    }
+
+    pAsm->cf_current_cf_clause_ptr = 
+      (R700ControlFlowGenericClause*) CALLOC_STRUCT(R700ControlFlowGenericClause);
+
+    if (pAsm->cf_current_cf_clause_ptr != NULL) 
+	{
+		Init_R700ControlFlowGenericClause(pAsm->cf_current_cf_clause_ptr);
+		AddCFInstruction( pAsm->pR700Shader, 
+                          (R700ControlFlowInstruction *)pAsm->cf_current_cf_clause_ptr );
+	}
+	else 
+	{
+        radeon_error("Could not allocate a new VFetch CF instruction.\n");
+		return GL_FALSE;
+	}
+
+    return GL_TRUE;
+}
+
 GLboolean add_vfetch_instruction(r700_AssemblerBase*     pAsm,
 								 R700VertexInstruction*  vertex_instruction_ptr)
 {
@@ -798,6 +891,7 @@
                                        GLubyte             element,
                                        GLuint              _signed,
                                        GLboolean           normalize,
+                                       GLenum              format,
                                        VTX_FETCH_METHOD  * pFetchMethod)
 {
     GLuint client_size_inbyte;
@@ -846,10 +940,21 @@
 	vfetch_instruction_ptr->m_Word0.f.src_sel_x        = SQ_SEL_X;
 	vfetch_instruction_ptr->m_Word0.f.mega_fetch_count = mega_fetch_count;
 
-	vfetch_instruction_ptr->m_Word1.f.dst_sel_x        = (size < 1) ? SQ_SEL_0 : SQ_SEL_X;
-	vfetch_instruction_ptr->m_Word1.f.dst_sel_y        = (size < 2) ? SQ_SEL_0 : SQ_SEL_Y;
-	vfetch_instruction_ptr->m_Word1.f.dst_sel_z        = (size < 3) ? SQ_SEL_0 : SQ_SEL_Z;
-	vfetch_instruction_ptr->m_Word1.f.dst_sel_w        = (size < 4) ? SQ_SEL_1 : SQ_SEL_W;
+	if(format == GL_BGRA)
+	{
+		vfetch_instruction_ptr->m_Word1.f.dst_sel_x        = (size < 1) ? SQ_SEL_0 : SQ_SEL_Z;
+		vfetch_instruction_ptr->m_Word1.f.dst_sel_y        = (size < 2) ? SQ_SEL_0 : SQ_SEL_Y;
+		vfetch_instruction_ptr->m_Word1.f.dst_sel_z        = (size < 3) ? SQ_SEL_0 : SQ_SEL_X;
+		vfetch_instruction_ptr->m_Word1.f.dst_sel_w        = (size < 4) ? SQ_SEL_1 : SQ_SEL_W;
+	}
+	else
+	{
+		vfetch_instruction_ptr->m_Word1.f.dst_sel_x        = (size < 1) ? SQ_SEL_0 : SQ_SEL_X;
+		vfetch_instruction_ptr->m_Word1.f.dst_sel_y        = (size < 2) ? SQ_SEL_0 : SQ_SEL_Y;
+		vfetch_instruction_ptr->m_Word1.f.dst_sel_z        = (size < 3) ? SQ_SEL_0 : SQ_SEL_Z;
+		vfetch_instruction_ptr->m_Word1.f.dst_sel_w        = (size < 4) ? SQ_SEL_1 : SQ_SEL_W;
+
+	}
 
 	vfetch_instruction_ptr->m_Word1.f.use_const_fields = 1;
     vfetch_instruction_ptr->m_Word1.f.data_format      = data_format;
@@ -987,7 +1092,8 @@
 
     checkop_init(pAsm);
 
-    if( (pILInst->SrcReg[0].File == PROGRAM_CONSTANT)    ||
+    if( (pILInst->SrcReg[0].File == PROGRAM_UNIFORM)     || 
+        (pILInst->SrcReg[0].File == PROGRAM_CONSTANT)    ||
         (pILInst->SrcReg[0].File == PROGRAM_LOCAL_PARAM) ||
         (pILInst->SrcReg[0].File == PROGRAM_ENV_PARAM)   ||
         (pILInst->SrcReg[0].File == PROGRAM_STATE_VAR) )
@@ -998,7 +1104,8 @@
     {
         bSrcConst[0] = GL_FALSE;
     }
-    if( (pILInst->SrcReg[1].File == PROGRAM_CONSTANT)    ||
+    if( (pILInst->SrcReg[1].File == PROGRAM_UNIFORM)     || 
+        (pILInst->SrcReg[1].File == PROGRAM_CONSTANT)    ||
         (pILInst->SrcReg[1].File == PROGRAM_LOCAL_PARAM) ||
         (pILInst->SrcReg[1].File == PROGRAM_ENV_PARAM)   ||
         (pILInst->SrcReg[1].File == PROGRAM_STATE_VAR) )
@@ -1031,7 +1138,8 @@
 
     checkop_init(pAsm);
 
-    if( (pILInst->SrcReg[0].File == PROGRAM_CONSTANT)    ||
+    if( (pILInst->SrcReg[0].File == PROGRAM_UNIFORM)     || 
+        (pILInst->SrcReg[0].File == PROGRAM_CONSTANT)    ||
         (pILInst->SrcReg[0].File == PROGRAM_LOCAL_PARAM) ||
         (pILInst->SrcReg[0].File == PROGRAM_ENV_PARAM)   ||
         (pILInst->SrcReg[0].File == PROGRAM_STATE_VAR) )
@@ -1042,7 +1150,8 @@
     {
         bSrcConst[0] = GL_FALSE;
     }
-    if( (pILInst->SrcReg[1].File == PROGRAM_CONSTANT)    ||
+    if( (pILInst->SrcReg[1].File == PROGRAM_UNIFORM)     || 
+        (pILInst->SrcReg[1].File == PROGRAM_CONSTANT)    ||
         (pILInst->SrcReg[1].File == PROGRAM_LOCAL_PARAM) ||
         (pILInst->SrcReg[1].File == PROGRAM_ENV_PARAM)   ||
         (pILInst->SrcReg[1].File == PROGRAM_STATE_VAR) )
@@ -1053,7 +1162,8 @@
     {
         bSrcConst[1] = GL_FALSE;
     }
-    if( (pILInst->SrcReg[2].File == PROGRAM_CONSTANT)    ||
+    if( (pILInst->SrcReg[2].File == PROGRAM_UNIFORM)     || 
+        (pILInst->SrcReg[2].File == PROGRAM_CONSTANT)    ||
         (pILInst->SrcReg[2].File == PROGRAM_LOCAL_PARAM) ||
         (pILInst->SrcReg[2].File == PROGRAM_ENV_PARAM)   ||
         (pILInst->SrcReg[2].File == PROGRAM_STATE_VAR) )
@@ -1153,6 +1263,7 @@
         case PROGRAM_LOCAL_PARAM:
         case PROGRAM_ENV_PARAM:
         case PROGRAM_STATE_VAR:
+        case PROGRAM_UNIFORM:
             if (1 == pILInst->SrcReg[src].RelAddr)
             {
                 setaddrmode_PVSSRC(&(pAsm->S[fld].src), ADDR_RELATIVE_A0);
@@ -1163,10 +1274,18 @@
             }
 
             pAsm->S[fld].src.rtype = SRC_REG_CONSTANT;
-            pAsm->S[fld].src.reg   = pILInst->SrcReg[src].Index;
+            if(pILInst->SrcReg[src].Index < 0)
+            {
+                WARN_ONCE("Negative register offsets not supported yet!\n");
+                pAsm->S[fld].src.reg  = 0;
+            } 
+            else
+            {
+                pAsm->S[fld].src.reg = pILInst->SrcReg[src].Index;
+            }
             break;      
         case PROGRAM_INPUT:
-            setaddrmode_PVSSRC(&(pAsm->S[fld].src), ADDR_ABSOLUTE);
+            setaddrmode_PVSSRC(&(pAsm->S[fld].src), ADDR_ABSOLUTE); 
             pAsm->S[fld].src.rtype = SRC_REG_INPUT;
             switch (pAsm->currentShaderType)
             {
@@ -1179,7 +1298,7 @@
             }
             break;      
         default:
-            radeon_error("Invalid source argument type\n");
+            radeon_error("Invalid source argument type : %d \n", pILInst->SrcReg[src].File);
             return GL_FALSE;
         }
     } 
@@ -1235,6 +1354,15 @@
     pAsm->D.dst.writez = (pILInst->DstReg.WriteMask >> 2) & 0x1;
     pAsm->D.dst.writew = (pILInst->DstReg.WriteMask >> 3) & 0x1;
   
+    if(pILInst->SaturateMode == SATURATE_ZERO_ONE)
+    {
+        pAsm->D2.dst2.SaturateMode = 1;
+    }
+    else
+    {
+        pAsm->D2.dst2.SaturateMode = 0;
+    }
+
     return GL_TRUE;
 }
 
@@ -1294,6 +1422,7 @@
     else
     {
     switch (pILInst->SrcReg[0].File) {
+        case PROGRAM_UNIFORM: 
         case PROGRAM_CONSTANT:
         case PROGRAM_LOCAL_PARAM:
         case PROGRAM_ENV_PARAM:
@@ -1306,36 +1435,65 @@
             pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
             break;
         case PROGRAM_INPUT:
-            switch (pILInst->SrcReg[0].Index)
+            if(SPT_VP == pAsm->currentShaderType)
             {
-                case FRAG_ATTRIB_WPOS:
-                case FRAG_ATTRIB_COL0:
-                case FRAG_ATTRIB_COL1:
-                case FRAG_ATTRIB_FOGC:
-                case FRAG_ATTRIB_TEX0:
-                case FRAG_ATTRIB_TEX1:
-                case FRAG_ATTRIB_TEX2:
-	        case FRAG_ATTRIB_TEX3:
-                case FRAG_ATTRIB_TEX4:
-                case FRAG_ATTRIB_TEX5:
-                case FRAG_ATTRIB_TEX6:
-                case FRAG_ATTRIB_TEX7:
-                    bValidTexCoord = GL_TRUE;
+                switch (pILInst->SrcReg[0].Index)
+                {
+                    case VERT_ATTRIB_TEX0:
+                    case VERT_ATTRIB_TEX1:
+                    case VERT_ATTRIB_TEX2:
+                    case VERT_ATTRIB_TEX3:
+                    case VERT_ATTRIB_TEX4:
+                    case VERT_ATTRIB_TEX5:
+                    case VERT_ATTRIB_TEX6:
+                    case VERT_ATTRIB_TEX7:
+                        bValidTexCoord = GL_TRUE;
+                        pAsm->S[0].src.reg   =
+                            pAsm->ucVP_AttributeMap[pILInst->SrcReg[0].Index];
+                        pAsm->S[0].src.rtype = SRC_REG_INPUT;
+                        break;
+                }
+            }
+            else
+            {
+                switch (pILInst->SrcReg[0].Index)
+                {
+                    case FRAG_ATTRIB_WPOS:
+                    case FRAG_ATTRIB_COL0:
+                    case FRAG_ATTRIB_COL1:
+                    case FRAG_ATTRIB_FOGC:
+                    case FRAG_ATTRIB_TEX0:
+                    case FRAG_ATTRIB_TEX1:
+                    case FRAG_ATTRIB_TEX2:
+                    case FRAG_ATTRIB_TEX3:
+                    case FRAG_ATTRIB_TEX4:
+                    case FRAG_ATTRIB_TEX5:
+                    case FRAG_ATTRIB_TEX6:
+                    case FRAG_ATTRIB_TEX7:
+                        bValidTexCoord = GL_TRUE;
+                        pAsm->S[0].src.reg   =
+                            pAsm->uiFP_AttributeMap[pILInst->SrcReg[0].Index];
+                        pAsm->S[0].src.rtype = SRC_REG_INPUT;
+                        break;
+                    case FRAG_ATTRIB_FACE:
+                        fprintf(stderr, "FRAG_ATTRIB_FACE unsupported\n");
+                        break;
+                    case FRAG_ATTRIB_PNTC:
+                        fprintf(stderr, "FRAG_ATTRIB_PNTC unsupported\n");
+                        break;
+                }
+
+                if( (pILInst->SrcReg[0].Index >= FRAG_ATTRIB_VAR0) ||
+                    (pILInst->SrcReg[0].Index < FRAG_ATTRIB_MAX) )
+                {
+				    bValidTexCoord = GL_TRUE;
                     pAsm->S[0].src.reg   =
                         pAsm->uiFP_AttributeMap[pILInst->SrcReg[0].Index];
                     pAsm->S[0].src.rtype = SRC_REG_INPUT;
-                    break;
-                case FRAG_ATTRIB_FACE:
-                    fprintf(stderr, "FRAG_ATTRIB_FACE unsupported\n");
-                    break;
-                case FRAG_ATTRIB_PNTC:
-                    fprintf(stderr, "FRAG_ATTRIB_PNTC unsupported\n");
-                    break;
-                case FRAG_ATTRIB_VAR0:
-                    fprintf(stderr, "FRAG_ATTRIB_VAR0 unsupported\n");
-                    break;
+                }
             }
-        break;
+
+            break;
         }
     }
 
@@ -1380,8 +1538,17 @@
     tex_instruction_ptr->m_Word0.f.tex_inst         = pAsm->D.dst.opcode;
     tex_instruction_ptr->m_Word0.f.bc_frac_mode     = 0x0;
     tex_instruction_ptr->m_Word0.f.fetch_whole_quad = 0x0;
+    tex_instruction_ptr->m_Word0.f.alt_const        = 0;
 
-    tex_instruction_ptr->m_Word0.f.resource_id      = texture_unit_source->reg;
+    if(SPT_VP == pAsm->currentShaderType)
+    {
+        tex_instruction_ptr->m_Word0.f.resource_id      = texture_unit_source->reg + VERT_ATTRIB_MAX;
+        pAsm->unVetTexBits |= 1 << texture_unit_source->reg;
+    }
+    else
+    {
+        tex_instruction_ptr->m_Word0.f.resource_id      = texture_unit_source->reg;
+    }
 
     tex_instruction_ptr->m_Word1.f.lod_bias     = 0x0;
     if (normalized) {
@@ -1400,7 +1567,6 @@
     tex_instruction_ptr->m_Word2.f.offset_x   = 0x0;
     tex_instruction_ptr->m_Word2.f.offset_y   = 0x0;
     tex_instruction_ptr->m_Word2.f.offset_z   = 0x0;
-
     tex_instruction_ptr->m_Word2.f.sampler_id = texture_unit_source->reg;
 
     // dst
@@ -1517,6 +1683,10 @@
         {
             src_sel = pSource->reg + CFILE_REGISTER_OFFSET;            
         }
+        else if (pSource->rtype == SRC_REC_LITERAL)
+        {
+            src_sel = SQ_ALU_SRC_LITERAL;            
+        }
         else
         {
             radeon_error("Source (%d) register type (%d) not one of TEMP, INPUT, or CONSTANT.\n",
@@ -1606,7 +1776,8 @@
         return GL_FALSE;
     }
 
-    if ( pAsm->cf_current_alu_clause_ptr == NULL ||
+    if ( pAsm->alu_x_opcode != 0 ||
+         pAsm->cf_current_alu_clause_ptr == NULL ||
          ( (pAsm->cf_current_alu_clause_ptr != NULL) && 
            (pAsm->cf_current_alu_clause_ptr->m_Word1.f.count >= (GetCFMaxInstructions(pAsm->cf_current_alu_clause_ptr->m_ShaderInstType)-contiguous_slots_needed-1) )
          ) ) 
@@ -1636,9 +1807,17 @@
         pAsm->cf_current_alu_clause_ptr->m_Word1.f.kcache_addr0 = 0x0;
         pAsm->cf_current_alu_clause_ptr->m_Word1.f.kcache_addr1 = 0x0;
 
-        //cf_current_alu_clause_ptr->m_Word1.f.count           = number_of_scalar_operations - 1;
         pAsm->cf_current_alu_clause_ptr->m_Word1.f.count           = 0x0;
-        pAsm->cf_current_alu_clause_ptr->m_Word1.f.cf_inst         = SQ_CF_INST_ALU;
+
+        if(pAsm->alu_x_opcode != 0)
+        {
+            pAsm->cf_current_alu_clause_ptr->m_Word1.f.cf_inst = pAsm->alu_x_opcode;
+            pAsm->alu_x_opcode = 0;
+        }
+        else
+        {
+            pAsm->cf_current_alu_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_ALU;
+        }
 
         pAsm->cf_current_alu_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
 
@@ -1646,7 +1825,7 @@
     }
     else 
     {
-        pAsm->cf_current_alu_clause_ptr->m_Word1.f.count++;
+        pAsm->cf_current_alu_clause_ptr->m_Word1.f.count += (GetInstructionSize(alu_instruction_ptr->m_ShaderInstType) / 2);
     }
 
     // If this clause constains any instruction that is forward dependent on a TEX instruction, 
@@ -1923,7 +2102,7 @@
 
     GLuint swizzle_key;
 
-    GLuint number_of_operands = r700GetNumOperands(pAsm);
+    GLuint number_of_operands = r700GetNumOperands(pAsm->D.dst.opcode, pAsm->D.dst.op3);
 
     for (src=0; src<number_of_operands; src++) 
     {
@@ -2012,7 +2191,7 @@
 
     GLuint swizzle_key;
 
-    GLuint number_of_operands = r700GetNumOperands(pAsm);
+    GLuint number_of_operands = r700GetNumOperands(pAsm->D.dst.opcode, pAsm->D.dst.op3);
 
     for (src=0; src<number_of_operands; src++) 
     {
@@ -2045,7 +2224,7 @@
         if( is_gpr(sel) ) 
         {
             if( GL_FALSE == cycle_for_vector_bank_swizzle(bank_swizzle, src, &cycle) )
-            {
+            {             
                 return GL_FALSE;
             }
 
@@ -2057,7 +2236,7 @@
             else 
             {
                 if( GL_FALSE == reserve_gpr(pAsm, sel, chan, cycle) )
-                {
+                {                    
                     return GL_FALSE;
                 }
             }
@@ -2069,7 +2248,7 @@
             if( is_cfile(sel) ) 
             {        
                 if( GL_FALSE == reserve_cfile(pAsm, sel, chan) )
-                {
+                {                    
                     return GL_FALSE;
                 }
             }
@@ -2081,6 +2260,10 @@
 
 GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm)
 {
+    R700ALUInstruction            * alu_instruction_ptr;
+    R700ALUInstructionHalfLiteral * alu_instruction_ptr_hl;
+    R700ALUInstructionFullLiteral * alu_instruction_ptr_fl;
+
     GLuint    number_of_scalar_operations;
     GLboolean is_single_scalar_operation;
     GLuint    scalar_channel_index;
@@ -2089,7 +2272,7 @@
     int    current_source_index;
     GLuint contiguous_slots_needed;
 
-    GLuint    uNumSrc = r700GetNumOperands(pAsm);
+    GLuint    uNumSrc = r700GetNumOperands(pAsm->D.dst.opcode, pAsm->D.dst.op3);
     //GLuint    channel_swizzle, j;
     //GLuint    chan_counter[4] = {0, 0, 0, 0};
     //PVSSRC *  pSource[3];
@@ -2146,23 +2329,44 @@
 
     contiguous_slots_needed = 0;
 
-    if(GL_TRUE == is_reduction_opcode(&(pAsm->D)) ) 
+    if(!is_single_scalar_operation) 
     {
         contiguous_slots_needed = 4;
     }
 
+    contiguous_slots_needed += pAsm->D2.dst2.literal_slots;
+
     initialize(pAsm);    
 
     for (scalar_channel_index=0;
             scalar_channel_index < number_of_scalar_operations; 
                 scalar_channel_index++) 
     {
-        R700ALUInstruction* alu_instruction_ptr = (R700ALUInstruction*) CALLOC_STRUCT(R700ALUInstruction);
-        if (alu_instruction_ptr == NULL) 
-		{
-			return GL_FALSE;
-		}
-        Init_R700ALUInstruction(alu_instruction_ptr);
+        if(scalar_channel_index == (number_of_scalar_operations-1))
+        {
+            switch(pAsm->D2.dst2.literal_slots)
+            {
+            case 0:
+                alu_instruction_ptr = (R700ALUInstruction*) CALLOC_STRUCT(R700ALUInstruction);
+                Init_R700ALUInstruction(alu_instruction_ptr);
+                break;
+            case 1:
+                alu_instruction_ptr_hl = (R700ALUInstructionHalfLiteral*) CALLOC_STRUCT(R700ALUInstructionHalfLiteral);
+                Init_R700ALUInstructionHalfLiteral(alu_instruction_ptr_hl, pAsm->C[0].f, pAsm->C[1].f);
+                alu_instruction_ptr = (R700ALUInstruction*)alu_instruction_ptr_hl;
+                break;
+            case 2:
+                alu_instruction_ptr_fl = (R700ALUInstructionFullLiteral*) CALLOC_STRUCT(R700ALUInstructionFullLiteral);
+                Init_R700ALUInstructionFullLiteral(alu_instruction_ptr_fl,pAsm->C[0].f, pAsm->C[1].f, pAsm->C[2].f, pAsm->C[3].f);
+                alu_instruction_ptr = (R700ALUInstruction*)alu_instruction_ptr_fl;
+            break;
+            };
+        }
+        else
+        {
+            alu_instruction_ptr = (R700ALUInstruction*) CALLOC_STRUCT(R700ALUInstruction);
+            Init_R700ALUInstruction(alu_instruction_ptr);
+        }
         
         //src 0
         current_source_index = 0;
@@ -2172,7 +2376,7 @@
                                          current_source_index,
                                          pcurrent_source, 
                                          scalar_channel_index) )     
-        {
+        {            
             return GL_FALSE;
         }
    
@@ -2186,13 +2390,13 @@
                                              current_source_index,
                                              pcurrent_source, 
                                              scalar_channel_index) ) 
-            {
+            {                
                 return GL_FALSE;
             }
         }
 
         //other bits
-        alu_instruction_ptr->m_Word0.f.index_mode = SQ_INDEX_AR_X;
+        alu_instruction_ptr->m_Word0.f.index_mode = pAsm->D2.dst2.index_mode;
 
         if(   (is_single_scalar_operation == GL_TRUE) 
            || (GL_TRUE == bSplitInst) )
@@ -2204,9 +2408,17 @@
             alu_instruction_ptr->m_Word0.f.last = (scalar_channel_index == 3) ?  1 : 0;
         }
 
-        alu_instruction_ptr->m_Word0.f.pred_sel                = 0x0;
-        alu_instruction_ptr->m_Word1_OP2.f.update_pred         = 0x0;  
-        alu_instruction_ptr->m_Word1_OP2.f.update_execute_mask = 0x0;
+        alu_instruction_ptr->m_Word0.f.pred_sel = (pAsm->D.dst.pred_inv > 0) ? 1 : 0;
+        if(1 == pAsm->D.dst.predicated)
+        {
+            alu_instruction_ptr->m_Word1_OP2.f.update_pred         = 0x1;
+            alu_instruction_ptr->m_Word1_OP2.f.update_execute_mask = 0x1;
+        }
+        else
+        {
+            alu_instruction_ptr->m_Word1_OP2.f.update_pred         = 0x0;
+            alu_instruction_ptr->m_Word1_OP2.f.update_execute_mask = 0x0;
+        }
 
         // dst
         if( (pAsm->D.dst.rtype == DST_REG_TEMPORARY) || 
@@ -2215,7 +2427,7 @@
             alu_instruction_ptr->m_Word1.f.dst_gpr  = pAsm->D.dst.reg;
         }
         else 
-        {
+        {            
             radeon_error("Only temp destination registers supported for ALU dest regs.\n");
             return GL_FALSE;
         }
@@ -2245,7 +2457,7 @@
 
         alu_instruction_ptr->m_Word1.f.dst_chan = scalar_channel_index;
 
-        alu_instruction_ptr->m_Word1.f.clamp    = pAsm->pILInst[pAsm->uiCurInst].SaturateMode;
+        alu_instruction_ptr->m_Word1.f.clamp    = pAsm->D2.dst2.SaturateMode;
 
         if (pAsm->D.dst.op3) 
         {            
@@ -2272,8 +2484,8 @@
             {
                 alu_instruction_ptr->m_Word1_OP2.f6.alu_inst           = pAsm->D.dst.opcode;
 
-                alu_instruction_ptr->m_Word1_OP2.f6.src0_abs           = 0x0;
-                alu_instruction_ptr->m_Word1_OP2.f6.src1_abs           = 0x0;
+                alu_instruction_ptr->m_Word1_OP2.f6.src0_abs           = pAsm->S[0].src.abs;
+                alu_instruction_ptr->m_Word1_OP2.f6.src1_abs           = pAsm->S[1].src.abs;
 
                 //alu_instruction_ptr->m_Word1_OP2.f6.update_execute_mask = 0x0;
                 //alu_instruction_ptr->m_Word1_OP2.f6.update_pred         = 0x0;
@@ -2301,8 +2513,8 @@
             {
                 alu_instruction_ptr->m_Word1_OP2.f.alu_inst           = pAsm->D.dst.opcode;
 
-                alu_instruction_ptr->m_Word1_OP2.f.src0_abs           = 0x0;
-                alu_instruction_ptr->m_Word1_OP2.f.src1_abs           = 0x0;
+                alu_instruction_ptr->m_Word1_OP2.f.src0_abs           = pAsm->S[0].src.abs;
+                alu_instruction_ptr->m_Word1_OP2.f.src1_abs           = pAsm->S[1].src.abs;
 
                 //alu_instruction_ptr->m_Word1_OP2.f.update_execute_mask = 0x0;
                 //alu_instruction_ptr->m_Word1_OP2.f.update_pred         = 0x0;
@@ -2329,7 +2541,7 @@
         }
 
         if(GL_FALSE == add_alu_instruction(pAsm, alu_instruction_ptr, contiguous_slots_needed) )
-        {
+        {            
             return GL_FALSE;
         }
 
@@ -2340,19 +2552,19 @@
         if (is_single_scalar_operation) 
         {
             if(GL_FALSE == check_scalar(pAsm, alu_instruction_ptr) )
-            {
+            {                
                 return GL_FALSE;
             }
         }
         else 
         {
             if(GL_FALSE == check_vector(pAsm, alu_instruction_ptr) )
-            {
-                return 1;
+            {                
+                return GL_FALSE; 
             }
         }
 
-        contiguous_slots_needed = 0;
+        contiguous_slots_needed -= 1;
     }
 
     return GL_TRUE;
@@ -2403,11 +2615,14 @@
     
     //reset for next inst.
     pAsm->D.bits    = 0;
+    pAsm->D2.bits   = 0;
     pAsm->S[0].bits = 0;
     pAsm->S[1].bits = 0;
     pAsm->S[2].bits = 0;
     pAsm->is_tex = GL_FALSE;
     pAsm->need_tex_barrier = GL_FALSE;
+    pAsm->D2.bits = 0;
+    pAsm->C[0].bits = pAsm->C[1].bits = pAsm->C[2].bits = pAsm->C[3].bits = 0;
     return GL_TRUE;
 }
 
@@ -2640,9 +2855,44 @@
     return GL_TRUE;
 }
 
-GLboolean assemble_COS(r700_AssemblerBase *pAsm)
+GLboolean assemble_TRIG(r700_AssemblerBase *pAsm, BITS opcode)
 {
-    return assemble_math_function(pAsm, SQ_OP2_INST_COS);
+    int tmp;
+    checkop1(pAsm);
+
+    tmp = gethelpr(pAsm);
+
+    pAsm->D.dst.opcode = SQ_OP2_INST_MUL;
+    setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
+    pAsm->D.dst.rtype  = DST_REG_TEMPORARY;
+    pAsm->D.dst.reg    = tmp;
+    pAsm->D.dst.writex = 1;
+
+    assemble_src(pAsm, 0, -1);
+
+    pAsm->S[1].src.rtype = SRC_REC_LITERAL;
+    setswizzle_PVSSRC(&(pAsm->S[1].src), SQ_SEL_X);
+    pAsm->D2.dst2.literal_slots = 1;
+    pAsm->C[0].f = 1/(3.1415926535 * 2);
+    pAsm->C[1].f = 0.0F;
+    next_ins(pAsm);
+
+    pAsm->D.dst.opcode = opcode;
+    pAsm->D.dst.math = 1;
+
+    assemble_dst(pAsm);
+
+    setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
+    pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
+    pAsm->S[0].src.reg   = tmp;
+    setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X);
+    noneg_PVSSRC(&(pAsm->S[0].src));
+
+    next_ins(pAsm);
+
+    //TODO - replicate if more channels set in WriteMask
+    return GL_TRUE;
+
 }
  
 GLboolean assemble_DOT(r700_AssemblerBase *pAsm)
@@ -2910,13 +3160,15 @@
     return GL_TRUE;
 }
  
-GLboolean assemble_KIL(r700_AssemblerBase *pAsm)
-{
-    /* TODO: doc says KILL has to be last(end) ALU clause */
-    
-    checkop1(pAsm);
+GLboolean assemble_KIL(r700_AssemblerBase *pAsm, GLuint opcode)
+{  
+    struct prog_instruction *pILInst = &(pAsm->pILInst[pAsm->uiCurInst]);
 
-    pAsm->D.dst.opcode = SQ_OP2_INST_KILLGT;  
+    if(pILInst->Opcode == OPCODE_KIL)
+        checkop1(pAsm);
+
+    pAsm->D.dst.opcode = opcode;  
+    //pAsm->D.dst.math = 1;
 
     setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
     pAsm->D.dst.rtype = DST_REG_TEMPORARY;
@@ -2929,21 +3181,34 @@
     setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
     pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
     pAsm->S[0].src.reg = 0;
-
     setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_0);
     noneg_PVSSRC(&(pAsm->S[0].src));
 
-    if ( GL_FALSE == assemble_src(pAsm, 0, 1) )
+    if(pILInst->Opcode == OPCODE_KIL_NV)
     {
-        return GL_FALSE;
+        setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
+        pAsm->S[1].src.rtype = SRC_REG_TEMPORARY;
+        pAsm->S[1].src.reg = 0;
+        setswizzle_PVSSRC(&(pAsm->S[1].src), SQ_SEL_1);
+        neg_PVSSRC(&(pAsm->S[1].src));
     }
-  
+    else
+    {
+        if( GL_FALSE == assemble_src(pAsm, 0, 1) )
+        {
+            return GL_FALSE;
+        }
+
+    }
+
     if ( GL_FALSE == next_ins(pAsm) )
     {
         return GL_FALSE;
     }
 
+    /* Doc says KILL has to be last(end) ALU clause */
     pAsm->pR700Shader->killIsUsed = GL_TRUE;
+    pAsm->alu_x_opcode = SQ_CF_INST_ALU;
     
     return GL_TRUE;
 }
@@ -3007,6 +3272,7 @@
     {
         return GL_FALSE;
     }
+
     if( GL_FALSE == assemble_src(pAsm, 2, -1) ) 
     {
         return GL_FALSE;
@@ -3742,77 +4008,137 @@
     return assemble_math_function(pAsm, SQ_OP2_INST_RECIPSQRT_IEEE);
 }
  
-GLboolean assemble_SIN(r700_AssemblerBase *pAsm) 
-{
-    return assemble_math_function(pAsm, SQ_OP2_INST_SIN);
-}
- 
 GLboolean assemble_SCS(r700_AssemblerBase *pAsm) 
 {
     BITS tmp;
 
-	checkop1(pAsm);
+    checkop1(pAsm);
 
-	tmp = gethelpr(pAsm);
+    tmp = gethelpr(pAsm);
+    /* tmp.x = src /2*PI */
+    pAsm->D.dst.opcode = SQ_OP2_INST_MUL;
+    setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
+    pAsm->D.dst.rtype  = DST_REG_TEMPORARY;
+    pAsm->D.dst.reg    = tmp;
+    pAsm->D.dst.writex = 1;
 
-	// COS tmp.x,    a.x
-	pAsm->D.dst.opcode = SQ_OP2_INST_COS;
-	pAsm->D.dst.math = 1;
+    assemble_src(pAsm, 0, -1);
 
-	setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
-	pAsm->D.dst.rtype = DST_REG_TEMPORARY;
-	pAsm->D.dst.reg = tmp;
-	pAsm->D.dst.writex = 1;
+    pAsm->S[1].src.rtype = SRC_REC_LITERAL;
+    setswizzle_PVSSRC(&(pAsm->S[1].src), SQ_SEL_X);
+    pAsm->D2.dst2.literal_slots = 1;
+    pAsm->C[0].f = 1/(3.1415926535 * 2);
+    pAsm->C[1].f = 0.0F;
 
-	if( GL_FALSE == assemble_src(pAsm, 0, -1) )
-	{
-		return GL_FALSE;
-	}
+    next_ins(pAsm);
 
-	if ( GL_FALSE == next_ins(pAsm) )
-	{
-		return GL_FALSE;
-	}
+    // COS dst.x,    a.x
+    pAsm->D.dst.opcode = SQ_OP2_INST_COS;
+    pAsm->D.dst.math = 1;
 
-	// SIN tmp.y,    a.x
-	pAsm->D.dst.opcode = SQ_OP2_INST_SIN;
-	pAsm->D.dst.math = 1;
+    assemble_dst(pAsm);
+    /* mask y */
+    pAsm->D.dst.writey = 0;
 
-	setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
-	pAsm->D.dst.rtype = DST_REG_TEMPORARY;
-	pAsm->D.dst.reg = tmp;
-	pAsm->D.dst.writey = 1;
+    setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
+    pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
+    pAsm->S[0].src.reg   = tmp;
+    setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X);
+    noneg_PVSSRC(&(pAsm->S[0].src));
 
-	if( GL_FALSE == assemble_src(pAsm, 0, -1) )
-	{
-		return GL_FALSE;
-	}
+    if ( GL_FALSE == next_ins(pAsm) )
+    {
+        return GL_FALSE;
+    }
 
-	if( GL_FALSE == next_ins(pAsm) )
-	{
-		return GL_FALSE;
-	}
+    // SIN dst.y,    a.x
+    pAsm->D.dst.opcode = SQ_OP2_INST_SIN;
+    pAsm->D.dst.math = 1;
 
-	// MOV dst.mask,     tmp
-	pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
+    assemble_dst(pAsm);
+    /* mask x */
+    pAsm->D.dst.writex = 0;
 
-	if( GL_FALSE == assemble_dst(pAsm) )
-	{
-		return GL_FALSE;
-	}
+    setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
+    pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
+    pAsm->S[0].src.reg   = tmp;
+    setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X);
+    noneg_PVSSRC(&(pAsm->S[0].src));
 
-	setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
-	pAsm->S[0].src.rtype = DST_REG_TEMPORARY;
-	pAsm->S[0].src.reg = tmp;
+    if( GL_FALSE == next_ins(pAsm) )
+    {
+        return GL_FALSE;
+    }
 
-	noswizzle_PVSSRC(&(pAsm->S[0].src));
-	pAsm->S[0].src.swizzlez = SQ_SEL_0;
-	pAsm->S[0].src.swizzlew = SQ_SEL_0;
+    return GL_TRUE;
+}
 
-	if ( GL_FALSE == next_ins(pAsm) )
-	{
-		return GL_FALSE;
-	}
+GLboolean assemble_LOGIC(r700_AssemblerBase *pAsm, BITS opcode) 
+{
+    if( GL_FALSE == checkop2(pAsm) )
+    {
+	    return GL_FALSE;
+    }
+
+    pAsm->D.dst.opcode = opcode;
+    //pAsm->D.dst.math   = 1;
+
+    if( GL_FALSE == assemble_dst(pAsm) )
+    {
+	    return GL_FALSE;
+    }
+
+    if( GL_FALSE == assemble_src(pAsm, 0, -1) )
+    {
+	    return GL_FALSE;
+    }
+
+    if( GL_FALSE == assemble_src(pAsm, 1, -1) )
+    {
+	    return GL_FALSE;
+    }
+
+    if( GL_FALSE == next_ins(pAsm) ) 
+    {
+	    return GL_FALSE;
+    }
+
+    return GL_TRUE;
+}
+
+GLboolean assemble_LOGIC_PRED(r700_AssemblerBase *pAsm, BITS opcode) 
+{
+    struct prog_instruction *pILInst = &(pAsm->pILInst[pAsm->uiCurInst]);
+
+    pAsm->D.dst.opcode = opcode;
+    pAsm->D.dst.math   = 1;
+    pAsm->D.dst.predicated = 1;
+
+    setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
+    pAsm->D.dst.rtype = DST_REG_TEMPORARY;
+    pAsm->D.dst.reg = pAsm->uHelpReg;
+    pAsm->D.dst.writex = 1;
+    pAsm->D.dst.writey = pAsm->D.dst.writez = pAsm->D.dst.writew = 0;
+
+    setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
+    pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
+    pAsm->S[0].src.reg = pAsm->last_cond_register + pAsm->starting_temp_register_number;
+    pAsm->S[0].src.swizzlex = pILInst->DstReg.CondSwizzle & 0x7;
+    noneg_PVSSRC(&(pAsm->S[0].src));
+
+    pAsm->S[1].src.rtype = SRC_REG_TEMPORARY;
+    pAsm->S[1].src.reg   = pAsm->uHelpReg;
+    setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
+    noneg_PVSSRC(&(pAsm->S[1].src));
+    pAsm->S[1].src.swizzlex = SQ_SEL_0;
+    pAsm->S[1].src.swizzley = SQ_SEL_0;
+    pAsm->S[1].src.swizzlez = SQ_SEL_0;
+    pAsm->S[1].src.swizzlew = SQ_SEL_0;
+
+    if( GL_FALSE == next_ins(pAsm) ) 
+    {
+	    return GL_FALSE;
+    }
 
     return GL_TRUE;
 }
@@ -3895,6 +4221,7 @@
     
     switch (pAsm->pILInst[pAsm->uiCurInst].SrcReg[0].File)
     {
+    case PROGRAM_UNIFORM: 
     case PROGRAM_CONSTANT:
     case PROGRAM_LOCAL_PARAM:
     case PROGRAM_ENV_PARAM:
@@ -3915,22 +4242,6 @@
 	    need_barrier = GL_TRUE;
     }
 
-    switch (pAsm->pILInst[pAsm->uiCurInst].Opcode)
-    {
-        case OPCODE_TEX:
-            break;
-        case OPCODE_TXB:
-            radeon_error("do not support TXB yet\n");
-            return GL_FALSE;
-            break;
-        case OPCODE_TXP:
-            break;
-        default:
-            radeon_error("Internal error: bad texture op (not TEX)\n");
-            return GL_FALSE;
-            break;
-    }
-
     if (pAsm->pILInst[pAsm->uiCurInst].Opcode == OPCODE_TXP)
     {
         GLuint tmp = gethelpr(pAsm);
@@ -4008,24 +4319,6 @@
             return GL_FALSE;
         }
  
-        /* tmp1.z = ABS(tmp1.z) dont have abs support in assembler currently
-         * have to do explicit instruction
-         */
-        pAsm->D.dst.opcode = SQ_OP2_INST_MAX;
-        setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
-        pAsm->D.dst.rtype = DST_REG_TEMPORARY;
-        pAsm->D.dst.reg   = tmp1;
-        pAsm->D.dst.writez = 1;
-
-        setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
-        pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
-        pAsm->S[0].src.reg = tmp1;
-	noswizzle_PVSSRC(&(pAsm->S[0].src));
-        pAsm->S[1].bits = pAsm->S[0].bits;
-        flipneg_PVSSRC(&(pAsm->S[1].src));
-        
-        next_ins(pAsm);
-
         /* tmp1.z = RCP_e(|tmp1.z|) */
         pAsm->D.dst.opcode = SQ_OP2_INST_RECIP_IEEE;
         pAsm->D.dst.math = 1;
@@ -4038,13 +4331,13 @@
         pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
         pAsm->S[0].src.reg = tmp1;
         pAsm->S[0].src.swizzlex = SQ_SEL_Z;
+        pAsm->S[0].src.abs = 1;
 
         next_ins(pAsm);
 
         /* MULADD R0.x,  R0.x,  PS1,  (0x3FC00000, 1.5f).x
          * MULADD R0.y,  R0.y,  PS1,  (0x3FC00000, 1.5f).x
          * muladd has no writemask, have to use another temp 
-         * also no support for imm constants, so add 1 here
          */
         pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
         pAsm->D.dst.op3    = 1;
@@ -4061,30 +4354,12 @@
         pAsm->S[1].src.reg   = tmp1;
         setswizzle_PVSSRC(&(pAsm->S[1].src), SQ_SEL_Z);
         setaddrmode_PVSSRC(&(pAsm->S[2].src), ADDR_ABSOLUTE);
-        pAsm->S[2].src.rtype = SRC_REG_TEMPORARY;
+        /* immediate c 1.5 */
+        pAsm->D2.dst2.literal_slots = 1;
+        pAsm->C[0].f = 1.5F;
+        pAsm->S[2].src.rtype = SRC_REC_LITERAL;
         pAsm->S[2].src.reg   = tmp1;
-        setswizzle_PVSSRC(&(pAsm->S[2].src), SQ_SEL_1);
-
-        next_ins(pAsm);
-
-        /* ADD the remaining .5 */
-        pAsm->D.dst.opcode = SQ_OP2_INST_ADD;
-        setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
-        pAsm->D.dst.rtype = DST_REG_TEMPORARY;
-        pAsm->D.dst.reg   = tmp2;
-        pAsm->D.dst.writex = 1;
-        pAsm->D.dst.writey = 1;
-        pAsm->D.dst.writez = 0;
-        pAsm->D.dst.writew = 0;
-
-        setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
-        pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
-        pAsm->S[0].src.reg   = tmp2;
-        noswizzle_PVSSRC(&(pAsm->S[0].src));
-        setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
-        pAsm->S[1].src.rtype = SRC_REG_TEMPORARY;
-        pAsm->S[1].src.reg   = 252; // SQ_ALU_SRC_0_5 
-        noswizzle_PVSSRC(&(pAsm->S[1].src));
+        setswizzle_PVSSRC(&(pAsm->S[2].src), SQ_SEL_X);
 
         next_ins(pAsm);
 
@@ -4109,14 +4384,35 @@
 
     }
 
-    pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE;
+    switch(pAsm->pILInst[pAsm->uiCurInst].Opcode)
+    {
+        case OPCODE_DDX:
+            /* will these need WQM(1) on CF inst ? */
+            pAsm->D.dst.opcode = SQ_TEX_INST_GET_GRADIENTS_H;
+            break;
+        case OPCODE_DDY:
+            pAsm->D.dst.opcode = SQ_TEX_INST_GET_GRADIENTS_V;
+            break;
+        case OPCODE_TXB:
+            pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE_L;
+            break;
+        default:
+            if(pAsm->pILInst[pAsm->uiCurInst].TexShadow == 1)
+                pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE_C;
+            else
+                pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE;
+    }
+
+    pAsm->is_tex = GL_TRUE;
+    if ( GL_TRUE == need_barrier )
+
     pAsm->is_tex = GL_TRUE;
     if ( GL_TRUE == need_barrier )
     {
         pAsm->need_tex_barrier = GL_TRUE;
     }
     // Set src1 to tex unit id
-    pAsm->S[1].src.reg   = pAsm->pILInst[pAsm->uiCurInst].TexSrcUnit;
+    pAsm->S[1].src.reg   = pAsm->SamplerUnits[pAsm->pILInst[pAsm->uiCurInst].TexSrcUnit];
     pAsm->S[1].src.rtype = SRC_REG_TEMPORARY;
 
     //No sw info from mesa compiler, so hard code here.
@@ -4150,11 +4446,46 @@
         pAsm->S[0].src.swizzlew = SQ_SEL_Y;
     }
  
+    if(pAsm->pILInst[pAsm->uiCurInst].TexShadow == 1)
+    {
+        /* compare value goes to w chan ? */
+        pAsm->S[0].src.swizzlew = SQ_SEL_Z;
+    }
+
     if ( GL_FALSE == next_ins(pAsm) )
         {
             return GL_FALSE;
         }
 
+    /* add ARB shadow ambient but clamp to 0..1 */
+    if(pAsm->pILInst[pAsm->uiCurInst].TexShadow == 1)
+    {
+	/* ADD_SAT dst,  dst,  ambient[texunit] */
+	pAsm->D.dst.opcode = SQ_OP2_INST_ADD;
+
+	if( GL_FALSE == assemble_dst(pAsm) )
+	{
+	    return GL_FALSE;
+	}
+	pAsm->D2.dst2.SaturateMode = 1;
+
+	pAsm->S[0].src.rtype = pAsm->D.dst.rtype;
+	pAsm->S[0].src.reg = pAsm->D.dst.reg;
+	noswizzle_PVSSRC(&(pAsm->S[0].src));
+	noneg_PVSSRC(&(pAsm->S[0].src));
+
+	pAsm->S[1].src.rtype = SRC_REG_CONSTANT;
+	pAsm->S[1].src.reg = pAsm->shadow_regs[pAsm->pILInst[pAsm->uiCurInst].TexSrcUnit];
+	noswizzle_PVSSRC(&(pAsm->S[1].src));
+	noneg_PVSSRC(&(pAsm->S[1].src));
+
+	if( GL_FALSE == next_ins(pAsm) )
+	{
+	    return GL_FALSE;
+	}
+
+    }
+
     return GL_TRUE;
 }
 
@@ -4273,27 +4604,909 @@
     return GL_TRUE;
 }
 
-GLboolean assemble_IF(r700_AssemblerBase *pAsm)
+static inline void decreaseCurrent(r700_AssemblerBase *pAsm, GLuint uReason)
 {
+    switch (uReason)
+    {
+    case FC_PUSH_VPM:
+        pAsm->CALLSTACK[pAsm->CALLSP].current--;
+        break;
+    case FC_PUSH_WQM:
+        pAsm->CALLSTACK[pAsm->CALLSP].current -= 4;
+        break;
+    case FC_LOOP:
+        pAsm->CALLSTACK[pAsm->CALLSP].current -= 4;
+        break;
+    case FC_REP:
+        /* TODO : for 16 vp asic, should -= 2; */
+        pAsm->CALLSTACK[pAsm->CALLSP].current -= 1;
+        break;
+    };
+}
+
+static inline void checkStackDepth(r700_AssemblerBase *pAsm, GLuint uReason, GLboolean bCheckMaxOnly)
+{
+    if(GL_TRUE == bCheckMaxOnly)
+    {
+        switch (uReason)
+        {
+        case FC_PUSH_VPM:
+            if((pAsm->CALLSTACK[pAsm->CALLSP].current + 1)
+                    > pAsm->CALLSTACK[pAsm->CALLSP].max)
+            {
+                pAsm->CALLSTACK[pAsm->CALLSP].max =
+                    pAsm->CALLSTACK[pAsm->CALLSP].current + 1;
+            }
+            break;
+        case FC_PUSH_WQM:
+            if((pAsm->CALLSTACK[pAsm->CALLSP].current + 4)
+                    > pAsm->CALLSTACK[pAsm->CALLSP].max)
+            {
+                pAsm->CALLSTACK[pAsm->CALLSP].max =
+                    pAsm->CALLSTACK[pAsm->CALLSP].current + 4;
+            }
+            break;
+        }
+        return;
+    }
+
+    switch (uReason)
+    {
+    case FC_PUSH_VPM:
+        pAsm->CALLSTACK[pAsm->CALLSP].current++;
+        break;
+    case FC_PUSH_WQM:
+        pAsm->CALLSTACK[pAsm->CALLSP].current += 4;
+        break;
+    case FC_LOOP:
+        pAsm->CALLSTACK[pAsm->CALLSP].current += 4;
+        break;
+    case FC_REP:
+        /* TODO : for 16 vp asic, should += 2; */
+        pAsm->CALLSTACK[pAsm->CALLSP].current += 1;
+        break;
+    };
+
+    if(pAsm->CALLSTACK[pAsm->CALLSP].current
+         > pAsm->CALLSTACK[pAsm->CALLSP].max)
+    {
+        pAsm->CALLSTACK[pAsm->CALLSP].max =
+            pAsm->CALLSTACK[pAsm->CALLSP].current;
+    }
+}
+
+GLboolean jumpToOffest(r700_AssemblerBase *pAsm, GLuint pops, GLint offset)
+{
+    if(GL_FALSE == add_cf_instruction(pAsm) )
+    {
+        return GL_FALSE;
+    }
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count        = pops;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const         = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond             = SQ_CF_COND_ACTIVE;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program   = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst          = SQ_CF_INST_JUMP;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode  = 0x0;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier          = 0x1;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word0.f.addr = pAsm->cf_current_cf_clause_ptr->m_uIndex + offset;
+
+    return GL_TRUE;
+}
+
+GLboolean pops(r700_AssemblerBase *pAsm, GLuint pops)
+{
+    if(GL_FALSE == add_cf_instruction(pAsm) )
+    {
+        return GL_FALSE;
+    }
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count        = pops;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const         = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond             = SQ_CF_COND_ACTIVE;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program   = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst          = SQ_CF_INST_POP;
+ 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode  = 0x0;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier          = 0x1;
+    pAsm->cf_current_cf_clause_ptr->m_Word0.f.addr             = pAsm->cf_current_cf_clause_ptr->m_uIndex + 1;
+
+    return GL_TRUE;
+}
+
+GLboolean assemble_IF(r700_AssemblerBase *pAsm, GLboolean bHasElse)
+{
+    pAsm->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
+
+    assemble_LOGIC_PRED(pAsm, SQ_OP2_INST_PRED_SETNE);
+
+
+    if(GL_FALSE == add_cf_instruction(pAsm) )
+    {
+        return GL_FALSE;
+    }
+
+    if(GL_TRUE != bHasElse)
+    {
+        pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1; 
+    }
+    else
+    {
+        pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0;
+    }
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const         = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond             = SQ_CF_COND_ACTIVE;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program   = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst          = SQ_CF_INST_JUMP;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode  = 0x0;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier          = 0x1;
+
+    pAsm->FCSP++;
+	pAsm->fc_stack[pAsm->FCSP].type  = FC_IF;
+    pAsm->fc_stack[pAsm->FCSP].mid   = NULL;
+    pAsm->fc_stack[pAsm->FCSP].midLen= 0;
+    pAsm->fc_stack[pAsm->FCSP].first = pAsm->cf_current_cf_clause_ptr;
+
+#ifndef USE_CF_FOR_POP_AFTER
+    if(GL_TRUE != bHasElse)
+    {
+        pAsm->alu_x_opcode = SQ_CF_INST_ALU_POP_AFTER;
+    }
+#endif /* USE_CF_FOR_POP_AFTER */
+
+    checkStackDepth(pAsm, FC_PUSH_VPM, GL_FALSE); 
+
+    return GL_TRUE;
+}
+
+GLboolean assemble_ELSE(r700_AssemblerBase *pAsm)
+{
+    if(GL_FALSE == add_cf_instruction(pAsm) )
+    {
+        return GL_FALSE;
+    }
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count        = 1; ///
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const         = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond             = SQ_CF_COND_ACTIVE;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program   = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst          = SQ_CF_INST_ELSE;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode  = 0x0;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier          = 0x1;
+
+    pAsm->fc_stack[pAsm->FCSP].mid = (R700ControlFlowGenericClause **)_mesa_realloc( (void *)pAsm->fc_stack[pAsm->FCSP].mid,
+                                                                                     0,
+                                                                                     sizeof(R700ControlFlowGenericClause *) );
+    pAsm->fc_stack[pAsm->FCSP].mid[0] = pAsm->cf_current_cf_clause_ptr;
+    //pAsm->fc_stack[pAsm->FCSP].unNumMid = 1;
+
+#ifndef USE_CF_FOR_POP_AFTER
+    pAsm->alu_x_opcode = SQ_CF_INST_ALU_POP_AFTER;
+#endif /* USE_CF_FOR_POP_AFTER */
+
+    pAsm->fc_stack[pAsm->FCSP].first->m_Word0.f.addr = pAsm->pR700Shader->plstCFInstructions_active->uNumOfNode - 1; 
+
     return GL_TRUE;
 }
 
 GLboolean assemble_ENDIF(r700_AssemblerBase *pAsm)
 {
+#ifdef USE_CF_FOR_POP_AFTER
+    pops(pAsm, 1); 
+#endif /* USE_CF_FOR_POP_AFTER */
+
+    pAsm->alu_x_opcode = SQ_CF_INST_ALU;
+
+    if(NULL == pAsm->fc_stack[pAsm->FCSP].mid)
+    {
+        /* no else in between */
+        pAsm->fc_stack[pAsm->FCSP].first->m_Word0.f.addr = pAsm->pR700Shader->plstCFInstructions_active->uNumOfNode;
+    }
+    else
+    {
+        pAsm->fc_stack[pAsm->FCSP].mid[0]->m_Word0.f.addr = pAsm->pR700Shader->plstCFInstructions_active->uNumOfNode;
+    }
+
+    if(NULL != pAsm->fc_stack[pAsm->FCSP].mid)
+    {
+        FREE(pAsm->fc_stack[pAsm->FCSP].mid);
+    }
+
+    if(pAsm->fc_stack[pAsm->FCSP].type != FC_IF)
+    {
+        radeon_error("if/endif in shader code are not paired. \n");
+        return GL_FALSE;
+    }
+    
+    pAsm->FCSP--;
+
+    decreaseCurrent(pAsm, FC_PUSH_VPM);
+
     return GL_TRUE;
 }
 
-GLboolean AssembleInstr(GLuint uiNumberInsts,
+GLboolean assemble_BGNLOOP(r700_AssemblerBase *pAsm)
+{
+    if(GL_FALSE == add_cf_instruction(pAsm) )
+    {
+        return GL_FALSE;
+    }
+
+    
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count        = 0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const         = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond             = SQ_CF_COND_ACTIVE;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program   = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst          = SQ_CF_INST_LOOP_START_NO_AL;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode  = 0x0;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier          = 0x1;
+
+    pAsm->FCSP++;
+	pAsm->fc_stack[pAsm->FCSP].type  = FC_LOOP;
+    pAsm->fc_stack[pAsm->FCSP].mid   = NULL;
+    pAsm->fc_stack[pAsm->FCSP].unNumMid = 0;
+    pAsm->fc_stack[pAsm->FCSP].midLen   = 0;
+    pAsm->fc_stack[pAsm->FCSP].first    = pAsm->cf_current_cf_clause_ptr;
+
+    checkStackDepth(pAsm, FC_LOOP, GL_FALSE);
+
+    return GL_TRUE;
+}
+
+GLboolean assemble_BRK(r700_AssemblerBase *pAsm)
+{
+#ifdef USE_CF_FOR_CONTINUE_BREAK
+
+    pAsm->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
+
+    assemble_LOGIC_PRED(pAsm, SQ_OP2_INST_PRED_SETNE);
+    
+    unsigned int unFCSP;
+    for(unFCSP=pAsm->FCSP; unFCSP>0; unFCSP--)
+    {
+        if(FC_LOOP == pAsm->fc_stack[unFCSP].type)
+        {
+            break;
+        }
+    }
+    if(0 == FC_LOOP)
+    {
+        radeon_error("Break is not inside loop/endloop pair.\n");
+        return GL_FALSE;
+    }
+
+    if(GL_FALSE == add_cf_instruction(pAsm) )
+    {
+        return GL_FALSE;
+    }
+
+    
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count        = 1;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const         = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond             = SQ_CF_COND_ACTIVE;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program   = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst          = SQ_CF_INST_LOOP_BREAK;
+ 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode  = 0x0;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier          = 0x1;
+
+    pAsm->fc_stack[unFCSP].mid = (R700ControlFlowGenericClause **)_mesa_realloc( 
+                                              (void *)pAsm->fc_stack[unFCSP].mid,
+                                              sizeof(R700ControlFlowGenericClause *) * pAsm->fc_stack[unFCSP].unNumMid,
+                                              sizeof(R700ControlFlowGenericClause *) * (pAsm->fc_stack[unFCSP].unNumMid + 1) );
+    pAsm->fc_stack[unFCSP].mid[pAsm->fc_stack[unFCSP].unNumMid] = pAsm->cf_current_cf_clause_ptr;
+    pAsm->fc_stack[unFCSP].unNumMid++;
+
+    if(GL_FALSE == add_cf_instruction(pAsm) )
+    {
+        return GL_FALSE;
+    }
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count        = 1;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const         = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond             = SQ_CF_COND_ACTIVE;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program   = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst          = SQ_CF_INST_POP;
+ 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode  = 0x0;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier          = 0x1;
+    pAsm->cf_current_cf_clause_ptr->m_Word0.f.addr             = pAsm->cf_current_cf_clause_ptr->m_uIndex + 1;
+
+    checkStackDepth(pAsm, FC_PUSH_VPM, GL_TRUE);
+
+#endif //USE_CF_FOR_CONTINUE_BREAK
+    return GL_TRUE;
+}
+
+GLboolean assemble_CONT(r700_AssemblerBase *pAsm)
+{
+#ifdef USE_CF_FOR_CONTINUE_BREAK
+    pAsm->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
+
+    assemble_LOGIC_PRED(pAsm, SQ_OP2_INST_PRED_SETNE);
+
+    unsigned int unFCSP;
+    for(unFCSP=pAsm->FCSP; unFCSP>0; unFCSP--)
+    {
+        if(FC_LOOP == pAsm->fc_stack[unFCSP].type)
+        {
+            break;
+        }
+    }
+    if(0 == FC_LOOP)
+    {
+        radeon_error("Continue is not inside loop/endloop pair.\n");
+        return GL_FALSE;
+    }
+
+    if(GL_FALSE == add_cf_instruction(pAsm) )
+    {
+        return GL_FALSE;
+    }
+
+    
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count        = 1;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const         = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond             = SQ_CF_COND_ACTIVE;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program   = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst          = SQ_CF_INST_LOOP_CONTINUE;
+ 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode  = 0x0;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier          = 0x1;
+
+    pAsm->fc_stack[unFCSP].mid = (R700ControlFlowGenericClause **)_mesa_realloc( 
+                                              (void *)pAsm->fc_stack[unFCSP].mid,
+                                              sizeof(R700ControlFlowGenericClause *) * pAsm->fc_stack[unFCSP].unNumMid,
+                                              sizeof(R700ControlFlowGenericClause *) * (pAsm->fc_stack[unFCSP].unNumMid + 1) );
+    pAsm->fc_stack[unFCSP].mid[pAsm->fc_stack[unFCSP].unNumMid] = pAsm->cf_current_cf_clause_ptr;
+    pAsm->fc_stack[unFCSP].unNumMid++;
+
+    if(GL_FALSE == add_cf_instruction(pAsm) )
+    {
+        return GL_FALSE;
+    }
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count        = 1;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const         = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond             = SQ_CF_COND_ACTIVE;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program   = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst          = SQ_CF_INST_POP;
+ 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode  = 0x0;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier          = 0x1;
+    pAsm->cf_current_cf_clause_ptr->m_Word0.f.addr             = pAsm->cf_current_cf_clause_ptr->m_uIndex + 1;
+
+    checkStackDepth(pAsm, FC_PUSH_VPM, GL_TRUE);
+
+#endif /* USE_CF_FOR_CONTINUE_BREAK */
+
+    return GL_TRUE;
+}
+
+GLboolean assemble_ENDLOOP(r700_AssemblerBase *pAsm)
+{
+    GLuint i;
+
+    if(GL_FALSE == add_cf_instruction(pAsm) )
+    {
+        return GL_FALSE;
+    }
+
+    
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count        = 0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const         = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond             = SQ_CF_COND_ACTIVE;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program   = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst          = SQ_CF_INST_LOOP_END;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode  = 0x0;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier          = 0x1;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word0.f.addr   = pAsm->fc_stack[pAsm->FCSP].first->m_uIndex + 1;
+    pAsm->fc_stack[pAsm->FCSP].first->m_Word0.f.addr = pAsm->cf_current_cf_clause_ptr->m_uIndex + 1;
+
+#ifdef USE_CF_FOR_CONTINUE_BREAK
+    for(i=0; i<pAsm->fc_stack[pAsm->FCSP].unNumMid; i++)
+    {
+        pAsm->fc_stack[pAsm->FCSP].mid[i]->m_Word0.f.addr = pAsm->cf_current_cf_clause_ptr->m_uIndex;
+    }
+    if(NULL != pAsm->fc_stack[pAsm->FCSP].mid)
+    {
+        FREE(pAsm->fc_stack[pAsm->FCSP].mid);
+    }
+#endif
+
+    if(pAsm->fc_stack[pAsm->FCSP].type != FC_LOOP)
+    {
+        radeon_error("loop/endloop in shader code are not paired. \n");
+        return GL_FALSE;
+    }
+
+    GLuint unFCSP;
+    GLuint unIF = 0;
+    if((pAsm->unCFflags & HAS_CURRENT_LOOPRET) > 0)
+    {        
+        for(unFCSP=(pAsm->FCSP-1); unFCSP>pAsm->CALLSTACK[pAsm->CALLSP].FCSP_BeforeEntry; unFCSP--)
+        {
+            if(FC_LOOP == pAsm->fc_stack[unFCSP].type)
+            {
+                breakLoopOnFlag(pAsm, unFCSP);
+                break;
+            }
+            else if(FC_IF == pAsm->fc_stack[unFCSP].type)
+            {
+                unIF++;
+            }
+        }
+        if(unFCSP <= pAsm->CALLSTACK[pAsm->CALLSP].FCSP_BeforeEntry)
+        {            
+#ifdef USE_CF_FOR_POP_AFTER
+            returnOnFlag(pAsm, unIF); 
+#else
+            returnOnFlag(pAsm, 0);
+#endif /* USE_CF_FOR_POP_AFTER */
+            pAsm->unCFflags &= ~HAS_CURRENT_LOOPRET;
+        }
+    }
+
+    pAsm->FCSP--;
+
+    decreaseCurrent(pAsm, FC_LOOP);
+    
+    return GL_TRUE;
+}
+
+void add_return_inst(r700_AssemblerBase *pAsm)
+{
+    if(GL_FALSE == add_cf_instruction(pAsm) )
+    {
+        return GL_FALSE;
+    }
+    //pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count        = 1;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count        = 0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const         = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond             = SQ_CF_COND_ACTIVE;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program   = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst          = SQ_CF_INST_RETURN;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode  = 0x0;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier          = 0x1;
+}
+
+GLboolean assemble_BGNSUB(r700_AssemblerBase *pAsm, GLint nILindex, GLuint uiIL_Shift)
+{
+    /* Put in sub */
+    if( (pAsm->unSubArrayPointer + 1) > pAsm->unSubArraySize )
+    {
+        pAsm->subs = (SUB_OFFSET*)_mesa_realloc( (void *)pAsm->subs,
+                                  sizeof(SUB_OFFSET) * pAsm->unSubArraySize,
+                                  sizeof(SUB_OFFSET) * (pAsm->unSubArraySize + 10) );
+        if(NULL == pAsm->subs)
+        {
+            return GL_FALSE;
+        }
+        pAsm->unSubArraySize += 10;
+    }
+
+    pAsm->subs[pAsm->unSubArrayPointer].subIL_Offset = nILindex + uiIL_Shift;
+    pAsm->subs[pAsm->unSubArrayPointer].lstCFInstructions_local.pHead=NULL;  
+    pAsm->subs[pAsm->unSubArrayPointer].lstCFInstructions_local.pTail=NULL;  
+    pAsm->subs[pAsm->unSubArrayPointer].lstCFInstructions_local.uNumOfNode=0;
+
+    pAsm->CALLSP++;
+    pAsm->CALLSTACK[pAsm->CALLSP].subDescIndex = pAsm->unSubArrayPointer;
+    pAsm->CALLSTACK[pAsm->CALLSP].FCSP_BeforeEntry = pAsm->FCSP;
+    pAsm->CALLSTACK[pAsm->CALLSP].plstCFInstructions_local
+                   = &(pAsm->subs[pAsm->unSubArrayPointer].lstCFInstructions_local);
+    pAsm->CALLSTACK[pAsm->CALLSP].max = 0;
+    pAsm->CALLSTACK[pAsm->CALLSP].current = 0;
+    SetActiveCFlist(pAsm->pR700Shader, 
+                    pAsm->CALLSTACK[pAsm->CALLSP].plstCFInstructions_local);
+
+    pAsm->unSubArrayPointer++;
+
+    /* start sub */
+    pAsm->alu_x_opcode = SQ_CF_INST_ALU;
+
+    pAsm->FCSP++;
+    pAsm->fc_stack[pAsm->FCSP].type  = FC_REP;
+
+    checkStackDepth(pAsm, FC_REP, GL_FALSE);
+
+    return GL_TRUE;
+}
+
+GLboolean assemble_ENDSUB(r700_AssemblerBase *pAsm)
+{
+    if(pAsm->fc_stack[pAsm->FCSP].type != FC_REP)
+    {
+        radeon_error("BGNSUB/ENDSUB in shader code are not paired. \n");
+        return GL_FALSE;
+    }
+
+    /* copy max to sub structure */
+    pAsm->subs[pAsm->CALLSTACK[pAsm->CALLSP].subDescIndex].unStackDepthMax
+        = pAsm->CALLSTACK[pAsm->CALLSP].max;
+
+    decreaseCurrent(pAsm, FC_REP);
+
+    pAsm->CALLSP--;
+    SetActiveCFlist(pAsm->pR700Shader, 
+                    pAsm->CALLSTACK[pAsm->CALLSP].plstCFInstructions_local);
+    
+    pAsm->alu_x_opcode = SQ_CF_INST_ALU;
+
+    pAsm->FCSP--;
+
+    return GL_TRUE;
+}
+
+GLboolean assemble_RET(r700_AssemblerBase *pAsm)
+{
+    GLuint unIF = 0;
+
+    if(pAsm->CALLSP > 0)
+    {   /* in sub */
+        GLuint unFCSP;        
+        for(unFCSP=pAsm->FCSP; unFCSP>pAsm->CALLSTACK[pAsm->CALLSP].FCSP_BeforeEntry; unFCSP--)
+        {
+            if(FC_LOOP == pAsm->fc_stack[unFCSP].type)
+            {
+                setRetInLoopFlag(pAsm, SQ_SEL_1);
+                breakLoopOnFlag(pAsm, unFCSP);
+                pAsm->unCFflags |= LOOPRET_FLAGS;
+
+                return GL_TRUE;
+            }
+            else if(FC_IF == pAsm->fc_stack[unFCSP].type)
+            {
+                unIF++;
+            }
+        }
+    }
+
+#ifdef USE_CF_FOR_POP_AFTER    
+    if(unIF > 0)
+    {
+        pops(pAsm, unIF);
+    }
+#endif /* USE_CF_FOR_POP_AFTER */
+
+    add_return_inst(pAsm);
+
+    return GL_TRUE;
+}
+
+GLboolean assemble_CAL(r700_AssemblerBase *pAsm, 
+                       GLint nILindex,
+                       GLuint uiIL_Shift,
+                       GLuint uiNumberInsts,
+                       struct prog_instruction *pILInst,
+                       PRESUB_DESC * pPresubDesc)
+{
+    GLint uiIL_Offset;
+
+    pAsm->alu_x_opcode = SQ_CF_INST_ALU;
+
+    if(GL_FALSE == add_cf_instruction(pAsm) )
+    {
+        return GL_FALSE;
+    }
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.call_count       = 1;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count        = 0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const         = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond             = SQ_CF_COND_ACTIVE;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program   = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst          = SQ_CF_INST_CALL;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode  = 0x0;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier          = 0x1;
+
+    /* Put in caller */
+    if( (pAsm->unCallerArrayPointer + 1) > pAsm->unCallerArraySize )
+    {
+        pAsm->callers = (CALLER_POINTER*)_mesa_realloc( (void *)pAsm->callers, 
+                       sizeof(CALLER_POINTER) * pAsm->unCallerArraySize, 
+                       sizeof(CALLER_POINTER) * (pAsm->unCallerArraySize + 10) );
+        if(NULL == pAsm->callers)
+        {
+            return GL_FALSE;
+        }
+        pAsm->unCallerArraySize += 10;
+    }
+    
+    uiIL_Offset = nILindex + uiIL_Shift;
+    pAsm->callers[pAsm->unCallerArrayPointer].subIL_Offset = uiIL_Offset; 
+    pAsm->callers[pAsm->unCallerArrayPointer].cf_ptr       = pAsm->cf_current_cf_clause_ptr;
+    
+    pAsm->callers[pAsm->unCallerArrayPointer].finale_cf_ptr  = NULL; 
+    pAsm->callers[pAsm->unCallerArrayPointer].prelude_cf_ptr = NULL; 
+
+    pAsm->unCallerArrayPointer++;
+
+    int j;
+    GLuint max;
+    GLuint unSubID;
+    GLboolean bRet;
+    for(j=0; j<pAsm->unSubArrayPointer; j++)
+    {
+        if(uiIL_Offset == pAsm->subs[j].subIL_Offset)
+        {   /* compiled before */
+
+            max = pAsm->subs[j].unStackDepthMax 
+                + pAsm->CALLSTACK[pAsm->CALLSP].current;
+            if(max > pAsm->CALLSTACK[pAsm->CALLSP].max)
+            {
+                pAsm->CALLSTACK[pAsm->CALLSP].max = max;
+            }
+            
+            pAsm->callers[pAsm->unCallerArrayPointer - 1].subDescIndex = j; 
+            return GL_TRUE;
+        }
+    }
+
+    pAsm->callers[pAsm->unCallerArrayPointer - 1].subDescIndex = pAsm->unSubArrayPointer;
+    unSubID = pAsm->unSubArrayPointer;
+
+    bRet = AssembleInstr(nILindex, uiIL_Shift, uiNumberInsts, pILInst, pAsm);
+
+    if(GL_TRUE == bRet)
+    {
+        max = pAsm->subs[unSubID].unStackDepthMax 
+            + pAsm->CALLSTACK[pAsm->CALLSP].current;
+        if(max > pAsm->CALLSTACK[pAsm->CALLSP].max)
+        {
+            pAsm->CALLSTACK[pAsm->CALLSP].max = max;
+        }
+
+        pAsm->subs[unSubID].pPresubDesc = pPresubDesc;
+    }
+
+    return bRet;
+}
+
+GLboolean setRetInLoopFlag(r700_AssemblerBase *pAsm, GLuint flagValue)
+{
+    GLfloat fLiteral[2] = {0.1, 0.0};
+
+    pAsm->D.dst.opcode   = SQ_OP2_INST_MOV;
+    pAsm->D.dst.op3      = 0;
+    pAsm->D.dst.rtype    = DST_REG_TEMPORARY;
+    pAsm->D.dst.reg      = pAsm->flag_reg_index;
+    pAsm->D.dst.writex   = 1;
+    pAsm->D.dst.writey   = 0;
+    pAsm->D.dst.writez   = 0;
+    pAsm->D.dst.writew   = 0;
+    pAsm->D2.dst2.literal_slots      = 1;
+    pAsm->D2.dst2.SaturateMode = SATURATE_OFF;
+    pAsm->D.dst.predicated     = 0;
+    /* in reloc where dislink flag init inst, only one slot alu inst is handled. */
+    pAsm->D.dst.math           = 1; /* TODO : not math really, but one channel op, more generic alu assembler needed */
+    pAsm->D2.dst2.index_mode = SQ_INDEX_LOOP; /* Check this ! */
+#if 0
+    pAsm->S[0].src.rtype = SRC_REC_LITERAL;
+    //pAsm->S[0].src.reg   = 0;
+    setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
+    noneg_PVSSRC(&(pAsm->S[0].src));
+    pAsm->S[0].src.swizzlex = SQ_SEL_X;
+    pAsm->S[0].src.swizzley = SQ_SEL_Y;
+    pAsm->S[0].src.swizzlez = SQ_SEL_Z;
+    pAsm->S[0].src.swizzlew = SQ_SEL_W;
+
+    if( GL_FALSE == next_ins_literal(pAsm, &(fLiteral[0])) )
+    {
+        return GL_FALSE;
+    }
+#else
+    pAsm->S[0].src.rtype = DST_REG_TEMPORARY;
+    pAsm->S[0].src.reg   = 0;
+    setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
+    noneg_PVSSRC(&(pAsm->S[0].src));
+    pAsm->S[0].src.swizzlex = flagValue;
+    pAsm->S[0].src.swizzley = flagValue;
+    pAsm->S[0].src.swizzlez = flagValue;
+    pAsm->S[0].src.swizzlew = flagValue;
+
+    if( GL_FALSE == next_ins(pAsm) )
+    {
+        return GL_FALSE;
+    }
+#endif
+
+    return GL_TRUE;
+}
+
+GLboolean testFlag(r700_AssemblerBase *pAsm)
+{
+    GLfloat fLiteral[2] = {0.1, 0.0};
+
+    //Test flag
+    GLuint tmp = gethelpr(pAsm);
+    pAsm->alu_x_opcode = SQ_CF_INST_ALU_PUSH_BEFORE;
+
+    pAsm->D.dst.opcode   = SQ_OP2_INST_PRED_SETE;
+    pAsm->D.dst.math     = 1;
+    pAsm->D.dst.rtype    = DST_REG_TEMPORARY;
+    pAsm->D.dst.reg      = tmp;
+    pAsm->D.dst.writex   = 1;
+    pAsm->D.dst.writey   = 0;
+    pAsm->D.dst.writez   = 0;
+    pAsm->D.dst.writew   = 0;
+    pAsm->D2.dst2.literal_slots      = 1;
+    pAsm->D2.dst2.SaturateMode = SATURATE_OFF;
+    pAsm->D.dst.predicated     = 1;
+    pAsm->D2.dst2.index_mode = SQ_INDEX_LOOP; /* Check this ! */
+
+    pAsm->S[0].src.rtype = DST_REG_TEMPORARY;
+    pAsm->S[0].src.reg   = pAsm->flag_reg_index;
+    setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
+    noneg_PVSSRC(&(pAsm->S[0].src));
+    pAsm->S[0].src.swizzlex = SQ_SEL_X;
+    pAsm->S[0].src.swizzley = SQ_SEL_Y;
+    pAsm->S[0].src.swizzlez = SQ_SEL_Z;
+    pAsm->S[0].src.swizzlew = SQ_SEL_W;
+#if 0
+    pAsm->S[1].src.rtype = SRC_REC_LITERAL;
+    //pAsm->S[1].src.reg   = 0;
+    setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
+    noneg_PVSSRC(&(pAsm->S[1].src));
+    pAsm->S[1].src.swizzlex = SQ_SEL_X;
+    pAsm->S[1].src.swizzley = SQ_SEL_Y;
+    pAsm->S[1].src.swizzlez = SQ_SEL_Z;
+    pAsm->S[1].src.swizzlew = SQ_SEL_W;
+
+    if( GL_FALSE == next_ins_literal(pAsm, &(fLiteral[0])) )
+    {
+        return GL_FALSE;
+    }
+#else
+    pAsm->S[1].src.rtype = DST_REG_TEMPORARY;
+    pAsm->S[1].src.reg   = 0;
+    setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
+    noneg_PVSSRC(&(pAsm->S[1].src));
+    pAsm->S[1].src.swizzlex = SQ_SEL_1;
+    pAsm->S[1].src.swizzley = SQ_SEL_1;
+    pAsm->S[1].src.swizzlez = SQ_SEL_1;
+    pAsm->S[1].src.swizzlew = SQ_SEL_1;
+
+    if( GL_FALSE == next_ins(pAsm) )
+    {
+        return GL_FALSE;
+    }
+#endif
+
+    checkStackDepth(pAsm, FC_PUSH_VPM, GL_TRUE);
+
+    return GL_TRUE;
+}
+
+GLboolean returnOnFlag(r700_AssemblerBase *pAsm, GLuint unIF)
+{
+    testFlag(pAsm);
+    jumpToOffest(pAsm, 1, 4);
+    setRetInLoopFlag(pAsm, SQ_SEL_0);
+    pops(pAsm, unIF + 1);
+    add_return_inst(pAsm);
+
+    return GL_TRUE;
+}
+
+GLboolean breakLoopOnFlag(r700_AssemblerBase *pAsm, GLuint unFCSP)
+{
+    testFlag(pAsm);
+ 
+    //break
+    if(GL_FALSE == add_cf_instruction(pAsm) )
+    {
+        return GL_FALSE;
+    }
+    
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count        = 1;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const         = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond             = SQ_CF_COND_ACTIVE;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program   = 0x0;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0; 
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst          = SQ_CF_INST_LOOP_BREAK;
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode  = 0x0;
+
+    pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier          = 0x1;
+
+    pAsm->fc_stack[unFCSP].mid = (R700ControlFlowGenericClause **)_mesa_realloc( 
+                                              (void *)pAsm->fc_stack[unFCSP].mid,
+                                              sizeof(R700ControlFlowGenericClause *) * pAsm->fc_stack[unFCSP].unNumMid,
+                                              sizeof(R700ControlFlowGenericClause *) * (pAsm->fc_stack[unFCSP].unNumMid + 1) );
+    pAsm->fc_stack[unFCSP].mid[pAsm->fc_stack[unFCSP].unNumMid] = pAsm->cf_current_cf_clause_ptr;
+    pAsm->fc_stack[unFCSP].unNumMid++;
+
+    pops(pAsm, 1);
+               
+    return GL_TRUE;
+}
+
+GLboolean AssembleInstr(GLuint uiFirstInst,
+                        GLuint uiIL_Shift,
+                        GLuint uiNumberInsts,
                         struct prog_instruction *pILInst, 
 						r700_AssemblerBase *pR700AsmCode)
 {
     GLuint i;
 
     pR700AsmCode->pILInst = pILInst;
-	for(i=0; i<uiNumberInsts; i++)
+	for(i=uiFirstInst; i<uiNumberInsts; i++)
     {
         pR700AsmCode->uiCurInst = i;
 
+#ifndef USE_CF_FOR_CONTINUE_BREAK
+        if(OPCODE_BRK == pILInst[i+1].Opcode)
+        {
+            switch(pILInst[i].Opcode)            
+            {
+            case OPCODE_SLE:
+                pILInst[i].Opcode = OPCODE_SGT;
+                break;
+            case OPCODE_SLT:
+                pILInst[i].Opcode = OPCODE_SGE;
+                break;
+            case OPCODE_SGE:
+                pILInst[i].Opcode = OPCODE_SLT;
+                break;
+            case OPCODE_SGT:
+                pILInst[i].Opcode = OPCODE_SLE;
+                break;
+            case OPCODE_SEQ:
+                pILInst[i].Opcode = OPCODE_SNE;
+                break;
+            case OPCODE_SNE:
+                pILInst[i].Opcode = OPCODE_SEQ;
+                break;
+            default:
+                break;
+            }
+        }
+#endif
+        if(pILInst[i].CondUpdate == 1)
+        {
+            /* remember dest register used for cond evaluation */
+            /* XXX also handle PROGRAM_OUTPUT registers here? */
+            pR700AsmCode->last_cond_register = pILInst[i].DstReg.Index; 
+        }
+
         switch (pILInst[i].Opcode)
         {
         case OPCODE_ABS: 
@@ -4321,7 +5534,7 @@
                 return GL_FALSE;
             break;  
         case OPCODE_COS: 
-            if ( GL_FALSE == assemble_COS(pR700AsmCode) ) 
+            if ( GL_FALSE == assemble_TRIG(pR700AsmCode, SQ_OP2_INST_COS) ) 
                 return GL_FALSE;
             break;  
 
@@ -4350,7 +5563,8 @@
             if ( GL_FALSE == assemble_FLR(pR700AsmCode) ) 
                 return GL_FALSE;
             break;  
-        //case OP_FLR_INT: 
+        //case OP_FLR_INT: ;
+
         //    if ( GL_FALSE == assemble_FLR_INT() ) 
         //        return GL_FALSE;
         //    break;  
@@ -4361,7 +5575,8 @@
             break;  
 
         case OPCODE_KIL: 
-            if ( GL_FALSE == assemble_KIL(pR700AsmCode) ) 
+        case OPCODE_KIL_NV: 
+            if ( GL_FALSE == assemble_KIL(pR700AsmCode, SQ_OP2_INST_KILLGT) ) 
                 return GL_FALSE;
             break;
         case OPCODE_LG2: 
@@ -4401,6 +5616,26 @@
         case OPCODE_MUL: 
             if ( GL_FALSE == assemble_MUL(pR700AsmCode) ) 
                 return GL_FALSE;
+            break;
+            
+        case OPCODE_NOISE1:
+            {                                               
+                callPreSub(pR700AsmCode, 
+                           GLSL_NOISE1,                         
+                           &noise1_presub,                                                  
+                           pILInst->DstReg.Index + pR700AsmCode->starting_temp_register_number, 
+                           1); 
+                radeon_error("noise1: not yet supported shader instruction\n");
+            };
+            break; 
+        case OPCODE_NOISE2: 
+            radeon_error("noise2: not yet supported shader instruction\n");
+            break; 
+        case OPCODE_NOISE3: 
+            radeon_error("noise3: not yet supported shader instruction\n");
+            break; 
+        case OPCODE_NOISE4: 
+            radeon_error("noise4: not yet supported shader instruction\n");
             break; 
 
         case OPCODE_POW: 
@@ -4416,22 +5651,78 @@
                 return GL_FALSE;
             break;  
         case OPCODE_SIN: 
-            if ( GL_FALSE == assemble_SIN(pR700AsmCode) ) 
+            if ( GL_FALSE == assemble_TRIG(pR700AsmCode, SQ_OP2_INST_SIN) ) 
                 return GL_FALSE;
             break;  
         case OPCODE_SCS: 
             if ( GL_FALSE == assemble_SCS(pR700AsmCode) ) 
                 return GL_FALSE;
-            break;  
+            break; 
+            
+        case OPCODE_SEQ:
+            if ( GL_FALSE == assemble_LOGIC(pR700AsmCode, SQ_OP2_INST_SETE) ) 
+            {
+                return GL_FALSE;
+            }
+            break;
+
+        case OPCODE_SGT: 
+            if ( GL_FALSE == assemble_LOGIC(pR700AsmCode, SQ_OP2_INST_SETGT) ) 
+            {
+                return GL_FALSE;
+            }
+            break;
 
         case OPCODE_SGE: 
             if ( GL_FALSE == assemble_SGE(pR700AsmCode) ) 
+            { 
                 return GL_FALSE;
-            break; 
+            }
+            break;
+        
+        /* NO LT, LE, TODO : use GE => LE, GT => LT : reverse 2 src order would be simpliest. Or use SQ_CF_COND_FALSE for SQ_CF_COND_ACTIVE.*/
         case OPCODE_SLT: 
-            if ( GL_FALSE == assemble_SLT(pR700AsmCode) ) 
+            {
+                struct prog_src_register SrcRegSave[2];
+                SrcRegSave[0] = pILInst[i].SrcReg[0];
+                SrcRegSave[1] = pILInst[i].SrcReg[1];
+                pILInst[i].SrcReg[0] = SrcRegSave[1];
+                pILInst[i].SrcReg[1] = SrcRegSave[0];
+                if ( GL_FALSE == assemble_LOGIC(pR700AsmCode, SQ_OP2_INST_SETGT) ) 
+                {
+                    pILInst[i].SrcReg[0] = SrcRegSave[0];
+                    pILInst[i].SrcReg[1] = SrcRegSave[1];
+                    return GL_FALSE;
+                }
+                pILInst[i].SrcReg[0] = SrcRegSave[0];
+                pILInst[i].SrcReg[1] = SrcRegSave[1];
+            }
+            break;
+
+        case OPCODE_SLE: 
+            {
+                struct prog_src_register SrcRegSave[2];
+                SrcRegSave[0] = pILInst[i].SrcReg[0];
+                SrcRegSave[1] = pILInst[i].SrcReg[1];
+                pILInst[i].SrcReg[0] = SrcRegSave[1];
+                pILInst[i].SrcReg[1] = SrcRegSave[0];
+                if ( GL_FALSE == assemble_LOGIC(pR700AsmCode, SQ_OP2_INST_SETGE) ) 
+                {
+                    pILInst[i].SrcReg[0] = SrcRegSave[0];
+                    pILInst[i].SrcReg[1] = SrcRegSave[1];
+                    return GL_FALSE;
+                }
+                pILInst[i].SrcReg[0] = SrcRegSave[0];
+                pILInst[i].SrcReg[1] = SrcRegSave[1];
+            }
+            break;
+
+        case OPCODE_SNE: 
+            if ( GL_FALSE == assemble_LOGIC(pR700AsmCode, SQ_OP2_INST_SETNE) ) 
+            {
                 return GL_FALSE;
-            break; 
+            }
+            break;
 
         //case OP_STP: 
         //    if ( GL_FALSE == assemble_STP(pR700AsmCode) ) 
@@ -4457,7 +5748,8 @@
                 }
             }
             break;
-
+        case OPCODE_DDX:
+        case OPCODE_DDY:
         case OPCODE_TEX: 
         case OPCODE_TXB:  
         case OPCODE_TXP: 
@@ -4465,30 +5757,104 @@
                 return GL_FALSE;
             break;
 
+        case OPCODE_TRUNC:
+            if ( GL_FALSE == assemble_math_function(pR700AsmCode, SQ_OP2_INST_TRUNC) )
+                return GL_FALSE;
+            break;
+
         case OPCODE_XPD: 
             if ( GL_FALSE == assemble_XPD(pR700AsmCode) ) 
                 return GL_FALSE;
             break;  
 
-        case OPCODE_IF   : 
-            if ( GL_FALSE == assemble_IF(pR700AsmCode) ) 
-                return GL_FALSE;
+        case OPCODE_IF:
+            {                
+                GLboolean bHasElse = GL_FALSE;
+
+                if(pILInst[pILInst[i].BranchTarget].Opcode == OPCODE_ELSE)
+                {
+                    bHasElse = GL_TRUE;
+                }
+
+                if ( GL_FALSE == assemble_IF(pR700AsmCode, bHasElse) ) 
+                {
+                    return GL_FALSE;
+                }
+            }
             break;
+
         case OPCODE_ELSE : 
-            radeon_error("Not yet implemented instruction OPCODE_ELSE \n");
-            //if ( GL_FALSE == assemble_BAD("ELSE") ) 
+            if ( GL_FALSE == assemble_ELSE(pR700AsmCode) ) 
                 return GL_FALSE;
             break;
+
         case OPCODE_ENDIF: 
             if ( GL_FALSE == assemble_ENDIF(pR700AsmCode) ) 
                 return GL_FALSE;
             break;
 
+        case OPCODE_BGNLOOP:
+            if( GL_FALSE == assemble_BGNLOOP(pR700AsmCode) )
+            {
+                return GL_FALSE;
+            }
+            break;
+
+        case OPCODE_BRK:
+            if( GL_FALSE == assemble_BRK(pR700AsmCode) )
+            {
+                return GL_FALSE;
+            }
+            break;
+
+        case OPCODE_CONT:
+            if( GL_FALSE == assemble_CONT(pR700AsmCode) )
+            {
+                return GL_FALSE;
+            }
+            break;
+
+        case OPCODE_ENDLOOP:
+            if( GL_FALSE == assemble_ENDLOOP(pR700AsmCode) )
+            {
+                return GL_FALSE;
+            }
+            break;
+
+        case OPCODE_BGNSUB:
+            if( GL_FALSE == assemble_BGNSUB(pR700AsmCode, i, uiIL_Shift) )
+            {
+                return GL_FALSE;
+            }
+            break;
+        
+        case OPCODE_RET:
+            if( GL_FALSE == assemble_RET(pR700AsmCode) )
+            {
+                return GL_FALSE;
+            }
+            break;
+        
+        case OPCODE_CAL:
+            if( GL_FALSE == assemble_CAL(pR700AsmCode, 
+                                         pILInst[i].BranchTarget,
+                                         uiIL_Shift,
+                                         uiNumberInsts,
+                                         pILInst,
+                                         NULL) )
+            {
+                return GL_FALSE;
+            }
+            break;
+
         //case OPCODE_EXPORT: 
         //    if ( GL_FALSE == assemble_EXPORT() ) 
         //        return GL_FALSE;
         //    break;
 
+        case OPCODE_ENDSUB:
+            return assemble_ENDSUB(pR700AsmCode);
+
         case OPCODE_END: 
 			//pR700AsmCode->uiCurInst = i;
 			//This is to remaind that if in later exoort there is depth/stencil
@@ -4505,6 +5871,417 @@
     return GL_TRUE;
 }
 
+GLboolean InitShaderProgram(r700_AssemblerBase * pAsm)
+{
+    setRetInLoopFlag(pAsm, SQ_SEL_0);
+    pAsm->alu_x_opcode = SQ_CF_INST_ALU;
+    return GL_TRUE;
+}
+
+GLboolean RelocProgram(r700_AssemblerBase * pAsm, struct gl_program * pILProg)
+{
+    GLuint i;
+    GLuint unCFoffset;
+    TypedShaderList * plstCFmain;
+    TypedShaderList * plstCFsub;
+
+    R700ShaderInstruction *        pInst;
+    R700ControlFlowGenericClause * pCFInst;
+
+    R700ControlFlowALUClause * pCF_ALU;
+    R700ALUInstruction       * pALU;
+    GLuint                     unConstOffset = 0;
+    GLuint                     unRegOffset;
+    GLuint                     unMinRegIndex;
+
+    plstCFmain = pAsm->CALLSTACK[0].plstCFInstructions_local;
+
+    /* remove flags init if they are not used */
+    if((pAsm->unCFflags & HAS_LOOPRET) == 0)
+    {
+        R700ControlFlowALUClause * pCF_ALU;
+        pInst = plstCFmain->pHead;
+        while(pInst)
+        {
+            if(SIT_CF_ALU == pInst->m_ShaderInstType)
+            {
+                pCF_ALU = (R700ControlFlowALUClause *)pInst;
+                if(0 == pCF_ALU->m_Word1.f.count)
+                {
+                    pCF_ALU->m_Word1.f.cf_inst = SQ_CF_INST_NOP;
+                }
+                else
+                {
+                    R700ALUInstruction * pALU = pCF_ALU->m_pLinkedALUInstruction;
+                    
+                    pALU->m_pLinkedALUClause = NULL;
+                    pALU = (R700ALUInstruction *)(pALU->pNextInst);
+                    pALU->m_pLinkedALUClause = pCF_ALU;
+                    pCF_ALU->m_pLinkedALUInstruction = pALU;
+
+                    pCF_ALU->m_Word1.f.count--;
+                }
+                break;
+            }
+            pInst = pInst->pNextInst;
+        };
+    }
+
+    if(pAsm->CALLSTACK[0].max > 0)
+    {
+        pAsm->pR700Shader->uStackSize = ((pAsm->CALLSTACK[0].max + 3)>>2) + 2;
+    }
+
+    if(0 == pAsm->unSubArrayPointer)
+    {
+        return GL_TRUE;
+    }
+
+    unCFoffset = plstCFmain->uNumOfNode;
+
+    if(NULL != pILProg->Parameters)
+    {        
+        unConstOffset = pILProg->Parameters->NumParameters;
+    }
+
+    /* Reloc subs */
+    for(i=0; i<pAsm->unSubArrayPointer; i++)
+    {
+        pAsm->subs[i].unCFoffset = unCFoffset;
+        plstCFsub = &(pAsm->subs[i].lstCFInstructions_local);
+
+        pInst = plstCFsub->pHead;
+
+        /* reloc instructions */
+        while(pInst)
+        {
+            if(SIT_CF_GENERIC == pInst->m_ShaderInstType)
+            {
+                pCFInst = (R700ControlFlowGenericClause *)pInst;
+
+                switch (pCFInst->m_Word1.f.cf_inst)
+                {
+                case SQ_CF_INST_POP:
+                case SQ_CF_INST_JUMP:
+                case SQ_CF_INST_ELSE:
+                case SQ_CF_INST_LOOP_END:
+                case SQ_CF_INST_LOOP_START:
+                case SQ_CF_INST_LOOP_START_NO_AL:
+                case SQ_CF_INST_LOOP_CONTINUE:
+                case SQ_CF_INST_LOOP_BREAK:
+                    pCFInst->m_Word0.f.addr += unCFoffset;
+                    break;
+                default:
+                    break;
+                }
+            }  
+            
+            pInst->m_uIndex += unCFoffset;
+
+            pInst = pInst->pNextInst;
+        };
+
+        if(NULL != pAsm->subs[i].pPresubDesc)
+        {
+            GLuint                     uNumSrc;            
+            
+            unMinRegIndex  = pAsm->subs[i].pPresubDesc->pCompiledSub->MinRegIndex;
+            unRegOffset    = pAsm->subs[i].pPresubDesc->maxStartReg;            
+            unConstOffset += pAsm->subs[i].pPresubDesc->unConstantsStart;
+
+            pInst = plstCFsub->pHead;
+            while(pInst)
+            {
+                if(SIT_CF_ALU == pInst->m_ShaderInstType)
+                {
+                    pCF_ALU = (R700ControlFlowALUClause *)pInst;
+
+                    pALU = pCF_ALU->m_pLinkedALUInstruction;
+                    for(int j=0; j<=pCF_ALU->m_Word1.f.count; j++)
+                    {
+                        pALU->m_Word1.f.dst_gpr = pALU->m_Word1.f.dst_gpr + unRegOffset - unMinRegIndex;
+
+                        if(pALU->m_Word0.f.src0_sel < SQ_ALU_SRC_GPR_SIZE)
+                        {   
+                            pALU->m_Word0.f.src0_sel = pALU->m_Word0.f.src0_sel + unRegOffset - unMinRegIndex;
+                        }
+                        else if(pALU->m_Word0.f.src0_sel >= SQ_ALU_SRC_CFILE_BASE)
+                        {   
+                            pALU->m_Word0.f.src0_sel += unConstOffset;
+                        }
+
+                        if( ((pALU->m_Word1.val >> SQ_ALU_WORD1_OP3_ALU_INST_SHIFT) & 0x0000001F) 
+                            >= SQ_OP3_INST_MUL_LIT )
+                        {   /* op3 : 3 srcs */
+                            if(pALU->m_Word1_OP3.f.src2_sel < SQ_ALU_SRC_GPR_SIZE)
+                            {   
+                                pALU->m_Word1_OP3.f.src2_sel = pALU->m_Word1_OP3.f.src2_sel + unRegOffset - unMinRegIndex;
+                            }
+                            else if(pALU->m_Word1_OP3.f.src2_sel >= SQ_ALU_SRC_CFILE_BASE)
+                            {   
+                                pALU->m_Word1_OP3.f.src2_sel += unConstOffset;
+                            }    
+                            if(pALU->m_Word0.f.src1_sel < SQ_ALU_SRC_GPR_SIZE)
+                            {   
+                                pALU->m_Word0.f.src1_sel = pALU->m_Word0.f.src1_sel + unRegOffset - unMinRegIndex;
+                            }
+                            else if(pALU->m_Word0.f.src1_sel >= SQ_ALU_SRC_CFILE_BASE)
+                            {   
+                                pALU->m_Word0.f.src1_sel += unConstOffset;
+                            }                                 
+                        }
+                        else
+                        {
+                            if(pAsm->bR6xx)
+                            {
+                                uNumSrc = r700GetNumOperands(pALU->m_Word1_OP2.f6.alu_inst, 0);
+                            }
+                            else
+                            {
+                                uNumSrc = r700GetNumOperands(pALU->m_Word1_OP2.f.alu_inst, 0);
+                            }
+                            if(2 == uNumSrc)
+                            {   /* 2 srcs */
+                                if(pALU->m_Word0.f.src1_sel < SQ_ALU_SRC_GPR_SIZE)
+                                {   
+                                    pALU->m_Word0.f.src1_sel = pALU->m_Word0.f.src1_sel + unRegOffset - unMinRegIndex;
+                                }
+                                else if(pALU->m_Word0.f.src1_sel >= SQ_ALU_SRC_CFILE_BASE)
+                                {   
+                                    pALU->m_Word0.f.src1_sel += unConstOffset;
+                                }                                  
+                            }                            
+                        }
+                        pALU = (R700ALUInstruction*)(pALU->pNextInst);
+                    }                    
+                }             
+                pInst = pInst->pNextInst;
+            };
+        }
+
+        /* Put sub into main */
+        plstCFmain->pTail->pNextInst = plstCFsub->pHead;
+        plstCFmain->pTail            = plstCFsub->pTail;
+        plstCFmain->uNumOfNode      += plstCFsub->uNumOfNode;
+
+        unCFoffset += plstCFsub->uNumOfNode;
+    }
+
+    /* reloc callers */
+    for(i=0; i<pAsm->unCallerArrayPointer; i++)
+    {
+        pAsm->callers[i].cf_ptr->m_Word0.f.addr
+            = pAsm->subs[pAsm->callers[i].subDescIndex].unCFoffset; 
+
+        if(NULL != pAsm->subs[pAsm->callers[i].subDescIndex].pPresubDesc)
+        {                 
+            unMinRegIndex = pAsm->subs[pAsm->callers[i].subDescIndex].pPresubDesc->pCompiledSub->MinRegIndex;
+            unRegOffset = pAsm->subs[pAsm->callers[i].subDescIndex].pPresubDesc->maxStartReg;
+
+            if(NULL != pAsm->callers[i].prelude_cf_ptr)
+            {                
+                pCF_ALU = (R700ControlFlowALUClause * )(pAsm->callers[i].prelude_cf_ptr);
+                pALU = pCF_ALU->m_pLinkedALUInstruction;
+                for(int j=0; j<=pCF_ALU->m_Word1.f.count; j++)
+                {
+                    pALU->m_Word1.f.dst_gpr = pALU->m_Word1.f.dst_gpr + unRegOffset - unMinRegIndex;
+                    pALU = (R700ALUInstruction*)(pALU->pNextInst);
+                }
+            }
+            if(NULL != pAsm->callers[i].finale_cf_ptr)
+            {
+                pCF_ALU = (R700ControlFlowALUClause * )(pAsm->callers[i].finale_cf_ptr);
+                pALU = pCF_ALU->m_pLinkedALUInstruction;
+                for(int j=0; j<=pCF_ALU->m_Word1.f.count; j++)
+                {
+                    pALU->m_Word0.f.src0_sel = pALU->m_Word0.f.src0_sel + unRegOffset - unMinRegIndex;
+                    pALU = (R700ALUInstruction*)(pALU->pNextInst);
+                }
+            }
+        }
+    }
+
+    return GL_TRUE;
+}
+
+GLboolean callPreSub(r700_AssemblerBase* pAsm, 
+                         LOADABLE_SCRIPT_SIGNITURE scriptSigniture,                          
+                         COMPILED_SUB * pCompiledSub,                                               
+                         GLshort uOutReg,
+                         GLshort uNumValidSrc)
+{
+    /* save assemble context */
+    GLuint starting_temp_register_number_save;
+    GLuint number_used_registers_save;
+    GLuint uFirstHelpReg_save;
+    GLuint uHelpReg_save;
+    GLuint uiCurInst_save;
+    struct prog_instruction *pILInst_save;
+    PRESUB_DESC * pPresubDesc;
+    GLboolean     bRet;
+    int i;
+
+    R700ControlFlowGenericClause* prelude_cf_ptr = NULL;
+
+    /* copy srcs to presub inputs */  
+    pAsm->alu_x_opcode = SQ_CF_INST_ALU;
+    for(i=0; i<uNumValidSrc; i++)
+    {
+        pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
+        setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
+        pAsm->D.dst.rtype = DST_REG_TEMPORARY;
+        pAsm->D.dst.reg   = pCompiledSub->srcRegIndex[i];
+        pAsm->D.dst.writex = 1;
+        pAsm->D.dst.writey = 1;
+        pAsm->D.dst.writez = 1;
+        pAsm->D.dst.writew = 1;
+
+        if( GL_FALSE == assemble_src(pAsm, i, 0) )
+        {
+            return GL_FALSE;
+        }
+
+        next_ins(pAsm);
+    }
+    if(uNumValidSrc > 0)
+    {
+        prelude_cf_ptr     = pAsm->cf_current_alu_clause_ptr;
+        pAsm->alu_x_opcode = SQ_CF_INST_ALU;
+    }
+
+    /* browse thro existing presubs. */
+    for(i=0; i<pAsm->unNumPresub; i++)
+    {
+        if(pAsm->presubs[i].sptSigniture == scriptSigniture)
+        {
+            break;
+        }
+    }
+
+    if(i == pAsm->unNumPresub)
+    {   /* not loaded yet */
+        /* save assemble context */
+        number_used_registers_save         = pAsm->number_used_registers;
+        uFirstHelpReg_save                 = pAsm->uFirstHelpReg;
+        uHelpReg_save                      = pAsm->uHelpReg;
+        starting_temp_register_number_save = pAsm->starting_temp_register_number;
+        pILInst_save                       = pAsm->pILInst;
+        uiCurInst_save                     = pAsm->uiCurInst;
+
+        /* alloc in presub */
+        if( (pAsm->unNumPresub + 1) > pAsm->unPresubArraySize )
+        {
+            pAsm->presubs = (PRESUB_DESC*)_mesa_realloc( (void *)pAsm->presubs,
+                                      sizeof(PRESUB_DESC) * pAsm->unPresubArraySize,
+                                      sizeof(PRESUB_DESC) * (pAsm->unPresubArraySize + 4) );
+            if(NULL == pAsm->presubs)
+            {
+                radeon_error("No memeory to allocate built in shader function description structures. \n");
+                return GL_FALSE;
+            }
+            pAsm->unPresubArraySize += 4;
+        }
+        
+        pPresubDesc = &(pAsm->presubs[i]);
+        pPresubDesc->sptSigniture = scriptSigniture;
+
+        /* constants offsets need to be final resolved at reloc. */
+        if(0 == pAsm->unNumPresub)
+        {
+            pPresubDesc->unConstantsStart = 0; 
+        }
+        else
+        {
+            pPresubDesc->unConstantsStart =  pAsm->presubs[i-1].unConstantsStart
+                                           + pAsm->presubs[i-1].pCompiledSub->NumParameters;
+        }
+
+        pPresubDesc->pCompiledSub = pCompiledSub;
+
+        pPresubDesc->subIL_Shift = pAsm->unCurNumILInsts;
+        pPresubDesc->maxStartReg  = uFirstHelpReg_save;
+        pAsm->unCurNumILInsts    += pCompiledSub->NumInstructions;
+
+        pAsm->unNumPresub++;
+
+        /* setup new assemble context */
+        pAsm->starting_temp_register_number = 0;
+        pAsm->number_used_registers = pCompiledSub->NumTemporaries;
+        pAsm->uFirstHelpReg         = pAsm->number_used_registers;
+        pAsm->uHelpReg              = pAsm->uFirstHelpReg;
+
+        bRet = assemble_CAL(pAsm, 
+                            0, 
+                            pPresubDesc->subIL_Shift, 
+                            pCompiledSub->NumInstructions,
+                            pCompiledSub->Instructions,
+                            pPresubDesc);
+
+        
+        pPresubDesc->number_used_registers = pAsm->number_used_registers;        
+
+        /* restore assemble context */
+        pAsm->number_used_registers         = number_used_registers_save; 
+        pAsm->uFirstHelpReg                 = uFirstHelpReg_save;
+        pAsm->uHelpReg                      = uHelpReg_save;
+        pAsm->starting_temp_register_number = starting_temp_register_number_save;
+        pAsm->pILInst                       = pILInst_save; 
+        pAsm->uiCurInst                     = uiCurInst_save;
+    }
+    else
+    {   /* was loaded */
+        pPresubDesc = &(pAsm->presubs[i]);  
+        
+        bRet = assemble_CAL(pAsm, 
+                            0, 
+                            pPresubDesc->subIL_Shift, 
+                            pCompiledSub->NumInstructions,
+                            pCompiledSub->Instructions,
+                            pPresubDesc);
+    }
+
+    if(GL_FALSE == bRet)
+    {
+        radeon_error("Shader presub assemble failed. \n");
+    }
+    else
+    {
+        /* copy presub output to real dst */ 
+        pAsm->alu_x_opcode = SQ_CF_INST_ALU;
+        pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
+
+        if( GL_FALSE == assemble_dst(pAsm) )
+        {
+            return GL_FALSE;
+        }
+
+        setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
+        pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
+        pAsm->S[0].src.reg   = pCompiledSub->dstRegIndex;
+        pAsm->S[0].src.swizzlex = pCompiledSub->outputSwizzleX;
+        pAsm->S[0].src.swizzley = pCompiledSub->outputSwizzleY;
+        pAsm->S[0].src.swizzlez = pCompiledSub->outputSwizzleZ;
+        pAsm->S[0].src.swizzlew = pCompiledSub->outputSwizzleW;
+
+        next_ins(pAsm);        
+
+        pAsm->callers[pAsm->unCallerArrayPointer - 1].finale_cf_ptr  = pAsm->cf_current_alu_clause_ptr;
+        pAsm->callers[pAsm->unCallerArrayPointer - 1].prelude_cf_ptr = prelude_cf_ptr;
+        pAsm->alu_x_opcode = SQ_CF_INST_ALU;
+    }
+
+    if( (pPresubDesc->number_used_registers + pAsm->uFirstHelpReg) > pAsm->number_used_registers )
+    {
+        pAsm->number_used_registers = pPresubDesc->number_used_registers + pAsm->uFirstHelpReg;
+    }
+    if(pAsm->uFirstHelpReg > pPresubDesc->maxStartReg)
+    {
+        pPresubDesc->maxStartReg = pAsm->uFirstHelpReg;
+    }
+
+    return bRet;
+}
+
 GLboolean Process_Export(r700_AssemblerBase* pAsm,
                          GLuint type,
                          GLuint export_starting_index,
@@ -4799,6 +6576,25 @@
             export_starting_index++;
 		}
 	}
+    
+    for(i=VERT_RESULT_VAR0; i<VERT_RESULT_MAX; i++)
+	{
+        unBit = 1 << i;
+        if(OutputsWritten & unBit)
+		{
+            if( GL_FALSE == Process_Export(pR700AsmCode,
+                                          SQ_EXPORT_PARAM, 
+                                          export_starting_index, 
+                                          1, 
+                                          pR700AsmCode->ucVP_OutputMap[i],
+                                          GL_FALSE) )
+            {                
+                return GL_FALSE;
+            }
+
+            export_starting_index++;
+		}
+    }
 
     // At least one param should be exported
     if (export_count) 
@@ -4833,6 +6629,21 @@
 {
     FREE(pR700AsmCode->pucOutMask);
     FREE(pR700AsmCode->pInstDeps);
+
+    if(NULL != pR700AsmCode->subs)
+    {
+        FREE(pR700AsmCode->subs);
+    }
+    if(NULL != pR700AsmCode->callers)
+    {
+        FREE(pR700AsmCode->callers);
+    }
+
+    if(NULL != pR700AsmCode->presubs)
+    {
+        FREE(pR700AsmCode->presubs);
+    }
+
     return GL_TRUE;
 }
 
diff --git a/src/mesa/drivers/dri/r600/r700_assembler.h b/src/mesa/drivers/dri/r600/r700_assembler.h
index c66db50..56baf5b 100644
--- a/src/mesa/drivers/dri/r600/r700_assembler.h
+++ b/src/mesa/drivers/dri/r600/r700_assembler.h
@@ -34,6 +34,45 @@
 #include "r700_shaderinst.h"
 #include "r700_shader.h"
 
+typedef enum LOADABLE_SCRIPT_SIGNITURE
+{
+    GLSL_NOISE1 = 0x10000001,
+    GLSL_NOISE2 = 0x10000002,
+    GLSL_NOISE3 = 0x10000003,
+    GLSL_NOISE4 = 0x10000004
+}LOADABLE_SCRIPT_SIGNITURE;
+
+typedef struct COMPILED_SUB
+{
+    struct  prog_instruction *Instructions;
+    GLuint  NumInstructions;
+    GLuint  NumTemporaries;
+    GLuint  NumParameters;
+    GLuint  MinRegIndex;
+    GLfloat (*ParameterValues)[4];
+    GLbyte  outputSwizzleX; 
+    GLbyte  outputSwizzleY;
+    GLbyte  outputSwizzleZ;
+    GLbyte  outputSwizzleW;
+    GLshort srcRegIndex[3];
+    GLushort dstRegIndex;
+}COMPILED_SUB;
+
+typedef struct PRESUB_DESCtag 
+{
+    LOADABLE_SCRIPT_SIGNITURE sptSigniture;
+    GLint  subIL_Shift;
+    struct prog_src_register InReg[3];
+    struct prog_dst_register OutReg;
+
+    GLushort maxStartReg;
+    GLushort number_used_registers;
+
+    GLuint   unConstantsStart;
+
+    COMPILED_SUB * pCompiledSub;
+} PRESUB_DESC;
+
 typedef enum SHADER_PIPE_TYPE 
 {
     SPT_VP = 0,
@@ -72,7 +111,8 @@
     SRC_REG_INPUT          = 1,
     SRC_REG_CONSTANT       = 2,
     SRC_REG_ALT_TEMPORARY  = 3,
-    NUMBER_OF_SRC_REG_TYPE = 4
+    SRC_REC_LITERAL        = 4, 
+    NUMBER_OF_SRC_REG_TYPE = 5
 } SrcRegisterType;
 
 typedef enum DstRegisterType 
@@ -111,16 +151,24 @@
 	BITS addrmode1:1; //32
 } PVSDST;
 
+typedef struct PVSINSTtag
+{
+    BITS literal_slots      :2; 
+    BITS SaturateMode :2; 
+    BITS index_mode   :3;
+} PVSINST;
+
 typedef struct PVSSRCtag 
 {
-	BITS rtype:4;            
+	BITS rtype:3;            
 	BITS addrmode0:1;        
-	BITS reg:10;      //15     (8)
+	BITS reg:10;      //14     (8)
 	BITS swizzlex:3;
 	BITS swizzley:3;
 	BITS swizzlez:3;
-	BITS swizzlew:3;  //27        
+	BITS swizzlew:3;  //26        
 
+	BITS abs:1;
 	BITS negx:1;
 	BITS negy:1;
 	BITS negz:1;
@@ -148,6 +196,7 @@
 {
 	BITS    bits;
 	PVSDST  dst;
+    PVSINST dst2;
 	PVSSRC  src;
 	PVSMATH math;
 	float   f;
@@ -251,6 +300,8 @@
     FC_IF = 1,
     FC_LOOP = 2,
     FC_REP = 3,
+    FC_PUSH_VPM = 4,
+    FC_PUSH_WQM = 5,
 
     COND_NONE = 0,
     COND_BOOL = 1,
@@ -263,22 +314,56 @@
 
 typedef struct FC_LEVEL 
 {
-	unsigned int           first; ///< first fc instruction on level (if, rep, loop)
-	unsigned int*          mid; ///< middle instructions - else or all breaks on this level
-	unsigned int           midLen;
-	unsigned int           type;
-	unsigned int           cond;
-	unsigned int           inv;
-	unsigned int           bpush; ///< 1 if first instruction does branch stack push
-			 int           id; ///< id of bool or int variable
+    R700ControlFlowGenericClause *  first;
+    R700ControlFlowGenericClause ** mid;
+    unsigned int unNumMid;
+    unsigned int midLen;
+    unsigned int type;
+    unsigned int cond;
+    unsigned int inv;
+    int id; ///< id of bool or int variable
 } FC_LEVEL;
 
 typedef struct VTX_FETCH_METHOD 
 {
-	GLboolean bEnableMini;
-	GLuint mega_fetch_remainder;
+    GLboolean bEnableMini;
+    GLuint mega_fetch_remainder;
 } VTX_FETCH_METHOD;
 
+typedef struct SUB_OFFSET
+{
+    GLint  subIL_Offset;
+    GLuint unCFoffset;
+    GLuint unStackDepthMax;
+    PRESUB_DESC *   pPresubDesc;
+    TypedShaderList lstCFInstructions_local;
+} SUB_OFFSET;
+
+typedef struct CALLER_POINTER
+{
+    GLint  subIL_Offset;
+    GLint  subDescIndex;
+    R700ControlFlowGenericClause* cf_ptr;
+
+    R700ControlFlowGenericClause* prelude_cf_ptr;
+    R700ControlFlowGenericClause* finale_cf_ptr;
+} CALLER_POINTER;
+
+#define SQ_MAX_CALL_DEPTH 0x00000020
+
+typedef struct CALL_LEVEL
+{
+    unsigned int      FCSP_BeforeEntry;
+    GLint             subDescIndex;
+    GLushort          current;
+    GLushort          max;
+    TypedShaderList * plstCFInstructions_local;
+} CALL_LEVEL;
+
+#define HAS_CURRENT_LOOPRET 0x1L
+#define HAS_LOOPRET         0x2L
+#define LOOPRET_FLAGS       HAS_LOOPRET | HAS_CURRENT_LOOPRET
+
 typedef struct r700_AssemblerBase 
 {
 	R700ControlFlowSXClause*      cf_last_export_ptr;
@@ -294,14 +379,19 @@
 	// No clause has been created yet
 	CF_CLAUSE_TYPE cf_current_clause_type;
 
+    BITS alu_x_opcode;
+
 	GLuint number_of_exports;
 	GLuint number_of_colorandz_exports;
 	GLuint number_of_export_opcodes;
 
 	PVSDWORD D;
+    PVSDWORD D2;
 	PVSDWORD S[3];
+        PVSDWORD C[4];
 
 	unsigned int uLastPosUpdate;
+	unsigned int last_cond_register;
 
 	OUT_FRAGMENT_FMT_0     fp_stOutFmt0;
 
@@ -310,6 +400,8 @@
 	unsigned int number_used_registers;
 	unsigned int uUsedConsts; 
 
+    unsigned int flag_reg_index;
+
 	// Fragment programs
 	unsigned int uiFP_AttributeMap[FRAG_ATTRIB_MAX];
 	unsigned int uiFP_OutputMap[FRAG_RESULT_MAX];
@@ -330,9 +422,6 @@
 	unsigned int FCSP;
 	FC_LEVEL fc_stack[32];
 
-	unsigned int branch_depth;
-	unsigned int max_branch_depth;
-
 	//-----------------------------------------------------------------------------------
 	// ArgSubst used in Assemble_Source() function
 	//-----------------------------------------------------------------------------------
@@ -373,11 +462,33 @@
     SHADER_PIPE_TYPE currentShaderType;
     struct prog_instruction * pILInst;
     GLuint             uiCurInst;
+    GLubyte SamplerUnits[MAX_SAMPLERS];
     GLboolean   bR6xx;
     /* helper to decide which type of instruction to assemble */
     GLboolean is_tex;
     /* we inserted helper intructions and need barrier on next TEX ins */ 
     GLboolean need_tex_barrier; 
+
+    SUB_OFFSET     * subs;
+    GLuint           unSubArraySize;
+    GLuint           unSubArrayPointer;
+    CALLER_POINTER * callers;
+    GLuint           unCallerArraySize;
+    GLuint           unCallerArrayPointer;
+    unsigned int     CALLSP;
+    CALL_LEVEL       CALLSTACK[SQ_MAX_CALL_DEPTH];
+
+    GLuint unCFflags;
+
+    PRESUB_DESC * presubs;
+    GLuint        unPresubArraySize;
+    GLuint        unNumPresub;
+    GLuint        unCurNumILInsts;
+
+    GLuint    unVetTexBits;
+
+    GLuint    shadow_regs[R700_MAX_TEXTURE_UNITS];
+
 } r700_AssemblerBase;
 
 //Internal use
@@ -399,7 +510,7 @@
 GLboolean is_reduction_opcode(PVSDWORD * dest);
 GLuint GetSurfaceFormat(GLenum eType, GLuint nChannels, GLuint * pClient_size);
 
-unsigned int r700GetNumOperands(r700_AssemblerBase* pAsm);
+unsigned int r700GetNumOperands(GLuint opcode, GLuint nIsOp3);
 
 GLboolean IsTex(gl_inst_opcode Opcode);
 GLboolean IsAlu(gl_inst_opcode Opcode);
@@ -422,6 +533,7 @@
                                        GLubyte             element,
                                        GLuint              _signed,
                                        GLboolean           normalize,
+                                       GLenum              format,
                                        VTX_FETCH_METHOD  * pFetchMethod);
 GLboolean cleanup_vfetch_instructions(r700_AssemblerBase* pAsm);
 GLuint gethelpr(r700_AssemblerBase* pAsm);
@@ -446,6 +558,10 @@
 GLboolean add_alu_instruction(r700_AssemblerBase* pAsm,
                               R700ALUInstruction* alu_instruction_ptr,
                               GLuint              contiguous_slots_needed);
+
+GLboolean add_cf_instruction(r700_AssemblerBase* pAsm);
+void add_return_inst(r700_AssemblerBase *pAsm);
+
 void get_src_properties(R700ALUInstruction*  alu_instruction_ptr,
                         int                  source_index,
                         BITS*                psrc_sel,
@@ -467,13 +583,20 @@
                        R700ALUInstruction* alu_instruction_ptr);
 GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm);
 GLboolean next_ins(r700_AssemblerBase *pAsm);
+
+GLboolean pops(r700_AssemblerBase *pAsm, GLuint pops);
+GLboolean jumpToOffest(r700_AssemblerBase *pAsm, GLuint pops, GLint offset);
+GLboolean setRetInLoopFlag(r700_AssemblerBase *pAsm, GLuint flagValue);
+GLboolean testFlag(r700_AssemblerBase *pAsm);
+GLboolean breakLoopOnFlag(r700_AssemblerBase *pAsm, GLuint unFCSP);
+GLboolean returnOnFlag(r700_AssemblerBase *pAsm, GLuint unIF);
+
 GLboolean assemble_math_function(r700_AssemblerBase* pAsm, BITS opcode);
 GLboolean assemble_ABS(r700_AssemblerBase *pAsm);
 GLboolean assemble_ADD(r700_AssemblerBase *pAsm);
 GLboolean assemble_ARL(r700_AssemblerBase *pAsm);
 GLboolean assemble_BAD(char *opcode_str);
 GLboolean assemble_CMP(r700_AssemblerBase *pAsm);
-GLboolean assemble_COS(r700_AssemblerBase *pAsm);
 GLboolean assemble_DOT(r700_AssemblerBase *pAsm);
 GLboolean assemble_DST(r700_AssemblerBase *pAsm);
 GLboolean assemble_EX2(r700_AssemblerBase *pAsm);
@@ -481,7 +604,7 @@
 GLboolean assemble_FLR(r700_AssemblerBase *pAsm);
 GLboolean assemble_FLR_INT(r700_AssemblerBase *pAsm);
 GLboolean assemble_FRC(r700_AssemblerBase *pAsm);
-GLboolean assemble_KIL(r700_AssemblerBase *pAsm);
+GLboolean assemble_KIL(r700_AssemblerBase *pAsm, GLuint opcode);
 GLboolean assemble_LG2(r700_AssemblerBase *pAsm);
 GLboolean assemble_LRP(r700_AssemblerBase *pAsm);
 GLboolean assemble_LOG(r700_AssemblerBase *pAsm);
@@ -494,17 +617,37 @@
 GLboolean assemble_POW(r700_AssemblerBase *pAsm);
 GLboolean assemble_RCP(r700_AssemblerBase *pAsm);
 GLboolean assemble_RSQ(r700_AssemblerBase *pAsm);
-GLboolean assemble_SIN(r700_AssemblerBase *pAsm);
 GLboolean assemble_SCS(r700_AssemblerBase *pAsm);
 GLboolean assemble_SGE(r700_AssemblerBase *pAsm);
+
+GLboolean assemble_LOGIC(r700_AssemblerBase *pAsm, BITS opcode);
+GLboolean assemble_LOGIC_PRED(r700_AssemblerBase *pAsm, BITS opcode); 
+GLboolean assemble_TRIG(r700_AssemblerBase *pAsm, BITS opcode);
+
 GLboolean assemble_SLT(r700_AssemblerBase *pAsm);
 GLboolean assemble_STP(r700_AssemblerBase *pAsm);
 GLboolean assemble_TEX(r700_AssemblerBase *pAsm);
 GLboolean assemble_XPD(r700_AssemblerBase *pAsm);
 GLboolean assemble_EXPORT(r700_AssemblerBase *pAsm);
-GLboolean assemble_IF(r700_AssemblerBase *pAsm);
+GLboolean assemble_IF(r700_AssemblerBase *pAsm, GLboolean bHasElse);
+GLboolean assemble_ELSE(r700_AssemblerBase *pAsm);
 GLboolean assemble_ENDIF(r700_AssemblerBase *pAsm);
 
+GLboolean assemble_BGNLOOP(r700_AssemblerBase *pAsm);
+GLboolean assemble_BRK(r700_AssemblerBase *pAsm);
+GLboolean assemble_COND(r700_AssemblerBase *pAsm);
+GLboolean assemble_ENDLOOP(r700_AssemblerBase *pAsm);
+
+GLboolean assemble_BGNSUB(r700_AssemblerBase *pAsm, GLint nILindex, GLuint uiIL_Shift);
+GLboolean assemble_ENDSUB(r700_AssemblerBase *pAsm);
+GLboolean assemble_RET(r700_AssemblerBase *pAsm);
+GLboolean assemble_CAL(r700_AssemblerBase *pAsm, 
+                       GLint nILindex,
+                       GLuint uiIL_Offest,
+                       GLuint uiNumberInsts,
+                       struct prog_instruction *pILInst,
+                       PRESUB_DESC * pPresubDesc);
+
 GLboolean Process_Export(r700_AssemblerBase* pAsm,
                          GLuint type, 
                          GLuint export_starting_index,
@@ -514,14 +657,25 @@
 GLboolean Move_Depth_Exports_To_Correct_Channels(r700_AssemblerBase *pAsm, 
                                                  BITS depth_channel_select);
 
+GLboolean callPreSub(r700_AssemblerBase* pAsm, 
+                     LOADABLE_SCRIPT_SIGNITURE scriptSigniture,
+                     /* struct prog_instruction ** pILInstParent, */
+                     COMPILED_SUB * pCompiledSub,                                            
+                     GLshort uOutReg,
+                     GLshort uNumValidSrc);
 
 //Interface
-GLboolean AssembleInstr(GLuint uiNumberInsts,
+GLboolean AssembleInstr(GLuint uiFirstInst,
+                        GLuint uiIL_Shift,
+                        GLuint uiNumberInsts,
                         struct prog_instruction *pILInst, 
 						r700_AssemblerBase *pR700AsmCode);
 GLboolean Process_Fragment_Exports(r700_AssemblerBase *pR700AsmCode, GLbitfield OutputsWritten);  
 GLboolean Process_Vertex_Exports(r700_AssemblerBase *pR700AsmCode, GLbitfield OutputsWritten);
 
+GLboolean RelocProgram(r700_AssemblerBase * pAsm, struct gl_program * pILProg);
+GLboolean InitShaderProgram(r700_AssemblerBase * pAsm);
+
 int       Init_r700_AssemblerBase(SHADER_PIPE_TYPE spt, r700_AssemblerBase* pAsm, R700_Shader* pShader);
 GLboolean Clean_Up_Assembler(r700_AssemblerBase *pR700AsmCode);
 
diff --git a/src/mesa/drivers/dri/r600/r700_chip.c b/src/mesa/drivers/dri/r600/r700_chip.c
index 47b38d2..3bc2d2b 100644
--- a/src/mesa/drivers/dri/r600/r700_chip.c
+++ b/src/mesa/drivers/dri/r600/r700_chip.c
@@ -45,6 +45,9 @@
 {
 	context_t         *context = R700_CONTEXT(ctx);
 	R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+
+    struct r700_vertex_program *vp = context->selected_vp;
+
 	struct radeon_bo *bo = NULL;
 	unsigned int i;
 	BATCH_LOCALS(&context->radeon);
@@ -52,13 +55,14 @@
 	radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
 
 	for (i = 0; i < R700_TEXTURE_NUMBERUNITS; i++) {
-		if (ctx->Texture.Unit[i]._ReallyEnabled) {
+		if (ctx->Texture.Unit[i]._ReallyEnabled) {            
 			radeonTexObj *t = r700->textures[i];
 			if (t) {
-				if (!t->image_override)
+				if (!t->image_override) {
 					bo = t->mt->bo;
-				else
+				} else {
 					bo = t->bo;
+				}
 				if (bo) {
 
 					r700SyncSurf(context, bo,
@@ -67,7 +71,16 @@
 
 					BEGIN_BATCH_NO_AUTOSTATE(9 + 4);
 					R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
-					R600_OUT_BATCH(i * 7);
+
+                    if( (1<<i) & vp->r700AsmCode.unVetTexBits )                    
+                    {   /* vs texture */                                     
+                        R600_OUT_BATCH((i + VERT_ATTRIB_MAX + SQ_FETCH_RESOURCE_VS_OFFSET) * FETCH_RESOURCE_STRIDE);
+                    }
+                    else
+                    {
+					    R600_OUT_BATCH(i * 7);
+                    }
+
 					R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE0);
 					R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE1);
 					R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE2);
@@ -77,7 +90,7 @@
 					R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE6);
 					R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE2,
 							     bo,
-							     0,
+							     r700->textures[i]->SQ_TEX_RESOURCE2,
 							     RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
 					R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE3,
 							     bo,
@@ -91,21 +104,35 @@
 	}
 }
 
+#define SAMPLER_STRIDE                 3
+
 static void r700SendTexSamplerState(GLcontext *ctx, struct radeon_state_atom *atom)
 {
 	context_t         *context = R700_CONTEXT(ctx);
 	R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
 	unsigned int i;
+
+    struct r700_vertex_program *vp = context->selected_vp;
+
 	BATCH_LOCALS(&context->radeon);
 	radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
 
 	for (i = 0; i < R700_TEXTURE_NUMBERUNITS; i++) {
-		if (ctx->Texture.Unit[i]._ReallyEnabled) {
+		if (ctx->Texture.Unit[i]._ReallyEnabled) {            
 			radeonTexObj *t = r700->textures[i];
 			if (t) {
 				BEGIN_BATCH_NO_AUTOSTATE(5);
 				R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_SAMPLER, 3));
-				R600_OUT_BATCH(i * 3);
+
+                if( (1<<i) & vp->r700AsmCode.unVetTexBits )                    
+                {   /* vs texture */
+                    R600_OUT_BATCH((i+SQ_TEX_SAMPLER_VS_OFFSET) * SAMPLER_STRIDE); //work 1
+                }
+                else
+                {
+				    R600_OUT_BATCH(i * 3);
+                }
+
 				R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER0);
 				R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER1);
 				R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER2);
@@ -442,68 +469,77 @@
 
 static void r700SendPSState(GLcontext *ctx, struct radeon_state_atom *atom)
 {
-	context_t *context = R700_CONTEXT(ctx);
-	R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
-	struct radeon_bo * pbo;
-	BATCH_LOCALS(&context->radeon);
-	radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+    context_t *context = R700_CONTEXT(ctx);
+    R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+    struct radeon_bo * pbo;
+    BATCH_LOCALS(&context->radeon);
+    radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
 
-	pbo = (struct radeon_bo *)r700GetActiveFpShaderBo(GL_CONTEXT(context));
+    pbo = (struct radeon_bo *)r700GetActiveFpShaderBo(GL_CONTEXT(context));
 
-	if (!pbo)
-		return;
+    if (!pbo)
+	    return;
 
-	r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
+    r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
 
-        BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
-	R600_OUT_BATCH_REGSEQ(SQ_PGM_START_PS, 1);
-	R600_OUT_BATCH(r700->ps.SQ_PGM_START_PS.u32All);
-	R600_OUT_BATCH_RELOC(r700->ps.SQ_PGM_START_PS.u32All,
-			     pbo,
-			     r700->ps.SQ_PGM_START_PS.u32All,
-			     RADEON_GEM_DOMAIN_GTT, 0, 0);
-	END_BATCH();
+    BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
+    R600_OUT_BATCH_REGSEQ(SQ_PGM_START_PS, 1);
+    R600_OUT_BATCH(r700->ps.SQ_PGM_START_PS.u32All);
+    R600_OUT_BATCH_RELOC(r700->ps.SQ_PGM_START_PS.u32All,
+		         pbo,
+		         r700->ps.SQ_PGM_START_PS.u32All,
+		         RADEON_GEM_DOMAIN_GTT, 0, 0);
+    END_BATCH();
 
-        BEGIN_BATCH_NO_AUTOSTATE(9);
-	R600_OUT_BATCH_REGVAL(SQ_PGM_RESOURCES_PS, r700->ps.SQ_PGM_RESOURCES_PS.u32All);
-	R600_OUT_BATCH_REGVAL(SQ_PGM_EXPORTS_PS, r700->ps.SQ_PGM_EXPORTS_PS.u32All);
-	R600_OUT_BATCH_REGVAL(SQ_PGM_CF_OFFSET_PS, r700->ps.SQ_PGM_CF_OFFSET_PS.u32All);
-        END_BATCH();
+    BEGIN_BATCH_NO_AUTOSTATE(9);
+    R600_OUT_BATCH_REGVAL(SQ_PGM_RESOURCES_PS, r700->ps.SQ_PGM_RESOURCES_PS.u32All);
+    R600_OUT_BATCH_REGVAL(SQ_PGM_EXPORTS_PS, r700->ps.SQ_PGM_EXPORTS_PS.u32All);
+    R600_OUT_BATCH_REGVAL(SQ_PGM_CF_OFFSET_PS, r700->ps.SQ_PGM_CF_OFFSET_PS.u32All);
+    END_BATCH();
 
-	COMMIT_BATCH();
+    BEGIN_BATCH_NO_AUTOSTATE(3);
+    R600_OUT_BATCH_REGVAL(SQ_LOOP_CONST_0, 0x01000FFF);
+    END_BATCH();
+
+    COMMIT_BATCH();
 
 }
 
 static void r700SendVSState(GLcontext *ctx, struct radeon_state_atom *atom)
 {
-	context_t *context = R700_CONTEXT(ctx);
-	R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
-	struct radeon_bo * pbo;
-	BATCH_LOCALS(&context->radeon);
-	radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+    context_t *context = R700_CONTEXT(ctx);
+    R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+    struct radeon_bo * pbo;
+    BATCH_LOCALS(&context->radeon);
+    radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
 
-	pbo = (struct radeon_bo *)r700GetActiveVpShaderBo(GL_CONTEXT(context));
+    pbo = (struct radeon_bo *)r700GetActiveVpShaderBo(GL_CONTEXT(context));
 
-	if (!pbo)
-		return;
+    if (!pbo)
+	    return;
 
-	r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
+    r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
 
-        BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
-	R600_OUT_BATCH_REGSEQ(SQ_PGM_START_VS, 1);
-	R600_OUT_BATCH(r700->vs.SQ_PGM_START_VS.u32All);
-	R600_OUT_BATCH_RELOC(r700->vs.SQ_PGM_START_VS.u32All,
-			     pbo,
-			     r700->vs.SQ_PGM_START_VS.u32All,
-			     RADEON_GEM_DOMAIN_GTT, 0, 0);
-	END_BATCH();
+    BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
+    R600_OUT_BATCH_REGSEQ(SQ_PGM_START_VS, 1);
+    R600_OUT_BATCH(r700->vs.SQ_PGM_START_VS.u32All);
+    R600_OUT_BATCH_RELOC(r700->vs.SQ_PGM_START_VS.u32All,
+		         pbo,
+		         r700->vs.SQ_PGM_START_VS.u32All,
+		         RADEON_GEM_DOMAIN_GTT, 0, 0);
+    END_BATCH();
 
-        BEGIN_BATCH_NO_AUTOSTATE(6);
-	R600_OUT_BATCH_REGVAL(SQ_PGM_RESOURCES_VS, r700->vs.SQ_PGM_RESOURCES_VS.u32All);
-	R600_OUT_BATCH_REGVAL(SQ_PGM_CF_OFFSET_VS, r700->vs.SQ_PGM_CF_OFFSET_VS.u32All);
-        END_BATCH();
+    BEGIN_BATCH_NO_AUTOSTATE(6);
+    R600_OUT_BATCH_REGVAL(SQ_PGM_RESOURCES_VS, r700->vs.SQ_PGM_RESOURCES_VS.u32All);
+    R600_OUT_BATCH_REGVAL(SQ_PGM_CF_OFFSET_VS, r700->vs.SQ_PGM_CF_OFFSET_VS.u32All);
+    END_BATCH();
 
-	COMMIT_BATCH();
+    BEGIN_BATCH_NO_AUTOSTATE(3);
+    R600_OUT_BATCH_REGVAL((SQ_LOOP_CONST_0 + 32*4), 0x0100000F);
+    //R600_OUT_BATCH_REGVAL((SQ_LOOP_CONST_0 + (SQ_LOOP_CONST_vs<2)), 0x0100000F);
+    END_BATCH();
+
+    COMMIT_BATCH();
 }
 
 static void r700SendFSState(GLcontext *ctx, struct radeon_state_atom *atom)
@@ -784,8 +820,7 @@
 	BATCH_LOCALS(&context->radeon);
 	radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
 
-        BEGIN_BATCH_NO_AUTOSTATE(23);
-	R600_OUT_BATCH_REGVAL(DB_HTILE_DATA_BASE, r700->DB_HTILE_DATA_BASE.u32All);
+	BEGIN_BATCH_NO_AUTOSTATE(17);
 
 	R600_OUT_BATCH_REGSEQ(DB_STENCIL_CLEAR, 2);
 	R600_OUT_BATCH(r700->DB_STENCIL_CLEAR.u32All);
@@ -798,7 +833,6 @@
 	R600_OUT_BATCH(r700->DB_RENDER_CONTROL.u32All);
 	R600_OUT_BATCH(r700->DB_RENDER_OVERRIDE.u32All);
 
-	R600_OUT_BATCH_REGVAL(DB_HTILE_SURFACE, r700->DB_HTILE_SURFACE.u32All);
 	R600_OUT_BATCH_REGVAL(DB_ALPHA_TO_MASK, r700->DB_ALPHA_TO_MASK.u32All);
 
 	END_BATCH();
@@ -1152,7 +1186,11 @@
 		count += 3;
 
 	if (context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) {
-		for (ui = 0; ui < R700_MAX_RENDER_TARGETS; ui++) {
+		/* targets are enabled in r700SetRenderTarget but state
+		   size is calculated before that. Until MRT's are done
+		   hardcode target0 as enabled. */
+		count += 3;
+		for (ui = 1; ui < R700_MAX_RENDER_TARGETS; ui++) {
                         if (r700->render_target[ui].enabled)
 				count += 3;
 		}
@@ -1282,7 +1320,7 @@
 	context->radeon.hw.atomlist.name = "atom-list";
 
 	ALLOC_STATE(sq, always, 34, r700SendSQConfig);
-	ALLOC_STATE(db, always, 23, r700SendDBState);
+	ALLOC_STATE(db, always, 17, r700SendDBState);
 	ALLOC_STATE(stencil, always, 4, r700SendStencilState);
 	ALLOC_STATE(db_target, always, 12, r700SendDepthTargetState);
 	ALLOC_STATE(sc, always, 15, r700SendSCState);
@@ -1295,16 +1333,16 @@
 	ALLOC_STATE(poly, always, 10, r700SendPolyState);
 	ALLOC_STATE(cb, cb, 18, r700SendCBState);
 	ALLOC_STATE(clrcmp, always, 6, r700SendCBCLRCMPState);
+	ALLOC_STATE(cb_target, always, 25, r700SendRenderTargetState);
 	ALLOC_STATE(blnd, blnd, (6 + (R700_MAX_RENDER_TARGETS * 3)), r700SendCBBlendState);
 	ALLOC_STATE(blnd_clr, always, 6, r700SendCBBlendColorState);
-	ALLOC_STATE(cb_target, always, 25, r700SendRenderTargetState);
 	ALLOC_STATE(sx, always, 9, r700SendSXState);
 	ALLOC_STATE(vgt, always, 41, r700SendVGTState);
 	ALLOC_STATE(spi, always, (59 + R700_MAX_SHADER_EXPORTS), r700SendSPIState);
 	ALLOC_STATE(vpt, always, 16, r700SendViewportState);
 	ALLOC_STATE(fs, always, 18, r700SendFSState);
-	ALLOC_STATE(vs, always, 18, r700SendVSState);
-	ALLOC_STATE(ps, always, 21, r700SendPSState);
+	ALLOC_STATE(vs, always, 21, r700SendVSState);
+	ALLOC_STATE(ps, always, 24, r700SendPSState);
 	ALLOC_STATE(vs_consts, vs_consts, (2 + (R700_MAX_DX9_CONSTS * 4)), r700SendVSConsts);
 	ALLOC_STATE(ps_consts, ps_consts, (2 + (R700_MAX_DX9_CONSTS * 4)), r700SendPSConsts);
 	ALLOC_STATE(vtx, vtx, (6 + (VERT_ATTRIB_MAX * 18)), r700SendVTXState);
diff --git a/src/mesa/drivers/dri/r600/r700_clear.c b/src/mesa/drivers/dri/r600/r700_clear.c
index c6546ab..98bfdd0 100644
--- a/src/mesa/drivers/dri/r600/r700_clear.c
+++ b/src/mesa/drivers/dri/r600/r700_clear.c
@@ -49,14 +49,18 @@
 void r700Clear(GLcontext * ctx, GLbitfield mask)
 {
     context_t *context = R700_CONTEXT(ctx);
-    __DRIdrawablePrivate *dPriv = radeon_get_drawable(&context->radeon);
-    const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
+    __DRIdrawable *dPriv = radeon_get_drawable(&context->radeon);
+    const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask[0]);
     GLbitfield swrast_mask = 0, tri_mask = 0;
     int i;
     struct gl_framebuffer *fb = ctx->DrawBuffer;
 
     radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s %x\n", __func__, mask);
 
+    if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT)) {
+        context->radeon.front_buffer_dirty = GL_TRUE;
+    }
+
     if( GL_TRUE == r700ClearFast(context, mask) )
     {
         return;
diff --git a/src/mesa/drivers/dri/r600/r700_fragprog.c b/src/mesa/drivers/dri/r600/r700_fragprog.c
index 0f549ea..84d51e6 100644
--- a/src/mesa/drivers/dri/r600/r700_fragprog.c
+++ b/src/mesa/drivers/dri/r600/r700_fragprog.c
@@ -34,6 +34,7 @@
 #include "main/imports.h"
 #include "shader/prog_parameter.h"
 #include "shader/prog_statevars.h"
+#include "shader/program.h"
 
 #include "r600_context.h"
 #include "r600_cmdbuf.h"
@@ -42,14 +43,68 @@
 
 #include "r700_debug.h"
 
+void insert_wpos_code(GLcontext *ctx, struct gl_fragment_program *fprog)
+{
+    static const gl_state_index winstate[STATE_LENGTH]
+         = { STATE_INTERNAL, STATE_FB_SIZE, 0, 0, 0};
+    struct prog_instruction *newInst, *inst;
+    GLint  win_size;  /* state reference */
+    GLuint wpos_temp; /* temp register */
+    int i, j;
+
+    /* PARAM win_size = STATE_FB_SIZE */
+    win_size = _mesa_add_state_reference(fprog->Base.Parameters, winstate);
+
+    wpos_temp = fprog->Base.NumTemporaries++;
+
+    /* scan program where WPOS is used and replace with wpos_temp */
+    inst = fprog->Base.Instructions;
+    for (i = 0; i < fprog->Base.NumInstructions; i++) {
+        for (j=0; j < 3; j++) {
+            if(inst->SrcReg[j].File == PROGRAM_INPUT && 
+               inst->SrcReg[j].Index == FRAG_ATTRIB_WPOS) {
+                inst->SrcReg[j].File = PROGRAM_TEMPORARY;
+                inst->SrcReg[j].Index = wpos_temp;
+            }
+        }
+        inst++;
+    }
+
+    _mesa_insert_instructions(&(fprog->Base), 0, 1);
+
+    newInst = fprog->Base.Instructions;
+    /* invert wpos.y
+     * wpos_temp.xyzw = wpos.x-yzw + winsize.0y00 */
+    newInst[0].Opcode = OPCODE_ADD;
+    newInst[0].DstReg.File = PROGRAM_TEMPORARY;
+    newInst[0].DstReg.Index = wpos_temp;
+    newInst[0].DstReg.WriteMask = WRITEMASK_XYZW;
+
+    newInst[0].SrcReg[0].File = PROGRAM_INPUT;
+    newInst[0].SrcReg[0].Index = FRAG_ATTRIB_WPOS;
+    newInst[0].SrcReg[0].Swizzle = SWIZZLE_XYZW;
+    newInst[0].SrcReg[0].Negate = NEGATE_Y;
+
+    newInst[0].SrcReg[1].File = PROGRAM_STATE_VAR;
+    newInst[0].SrcReg[1].Index = win_size;
+    newInst[0].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ZERO);
+
+}
+
 //TODO : Validate FP input with VP output.
 void Map_Fragment_Program(r700_AssemblerBase         *pAsm,
-						  struct gl_fragment_program *mesa_fp)
+						  struct gl_fragment_program *mesa_fp,
+                          GLcontext *ctx) 
 {
 	unsigned int unBit;
     unsigned int i;
     GLuint       ui;
 
+    /* match fp inputs with vp exports. */
+    struct r700_vertex_program_cont *vpc =
+		       (struct r700_vertex_program_cont *)ctx->VertexProgram._Current;
+    GLbitfield OutputsWritten = vpc->mesa_program.Base.OutputsWritten;
+    
 	pAsm->number_used_registers = 0;
 
 //Input mapping : mesa_fp->Base.InputsRead set the flag, set in 
@@ -61,32 +116,99 @@
 		pAsm->uiFP_AttributeMap[FRAG_ATTRIB_WPOS] = pAsm->number_used_registers++;
 	}
 
-	unBit = 1 << FRAG_ATTRIB_COL0;
-	if(mesa_fp->Base.InputsRead & unBit)
+    unBit = 1 << VERT_RESULT_COL0;
+	if(OutputsWritten & unBit)
 	{
 		pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL0] = pAsm->number_used_registers++;
 	}
 
-	unBit = 1 << FRAG_ATTRIB_COL1;
-	if(mesa_fp->Base.InputsRead & unBit)
+	unBit = 1 << VERT_RESULT_COL1;
+	if(OutputsWritten & unBit)
 	{
 		pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL1] = pAsm->number_used_registers++;
 	}
 
-        unBit = 1 << FRAG_ATTRIB_FOGC;
-        if(mesa_fp->Base.InputsRead & unBit)
-        {
-                pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FOGC] = pAsm->number_used_registers++;
-        }
+    unBit = 1 << VERT_RESULT_FOGC;
+    if(OutputsWritten & unBit)
+    {
+        pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FOGC] = pAsm->number_used_registers++;
+    }
 
 	for(i=0; i<8; i++)
 	{
-		unBit = 1 << (FRAG_ATTRIB_TEX0 + i);
-		if(mesa_fp->Base.InputsRead & unBit)
+		unBit = 1 << (VERT_RESULT_TEX0 + i);
+		if(OutputsWritten & unBit)
 		{
 			pAsm->uiFP_AttributeMap[FRAG_ATTRIB_TEX0 + i] = pAsm->number_used_registers++;
 		}
 	}
+ 
+/* order has been taken care of */ 
+#if 1
+    for(i=VERT_RESULT_VAR0; i<VERT_RESULT_MAX; i++)
+	{
+        unBit = 1 << i;
+        if(OutputsWritten & unBit)
+		{
+            pAsm->uiFP_AttributeMap[i-VERT_RESULT_VAR0+FRAG_ATTRIB_VAR0] = pAsm->number_used_registers++;
+        }
+    }
+#else
+    if( (mesa_fp->Base.InputsRead >> FRAG_ATTRIB_VAR0) > 0 )
+    {
+	    struct r700_vertex_program_cont *vpc =
+		       (struct r700_vertex_program_cont *)ctx->VertexProgram._Current;
+        struct gl_program_parameter_list * VsVarying = vpc->mesa_program.Base.Varying;
+        struct gl_program_parameter_list * PsVarying = mesa_fp->Base.Varying;
+        struct gl_program_parameter      * pVsParam;
+        struct gl_program_parameter      * pPsParam;
+        GLuint j, k;
+        GLuint unMaxVarying = 0;
+
+        for(i=0; i<VsVarying->NumParameters; i++)
+        {
+            pAsm->uiFP_AttributeMap[i + FRAG_ATTRIB_VAR0] = 0;
+        }
+
+        for(i=FRAG_ATTRIB_VAR0; i<FRAG_ATTRIB_MAX; i++)
+	    {
+            unBit = 1 << i;
+            if(mesa_fp->Base.InputsRead & unBit)
+		    {
+                j = i - FRAG_ATTRIB_VAR0;
+                pPsParam = PsVarying->Parameters + j;
+
+                for(k=0; k<VsVarying->NumParameters; k++)
+                {					
+                    pVsParam = VsVarying->Parameters + k;
+
+			        if( strcmp(pPsParam->Name, pVsParam->Name) == 0)
+                    {
+                        pAsm->uiFP_AttributeMap[i] = pAsm->number_used_registers + k;                  
+                        if(k > unMaxVarying)
+                        {
+                            unMaxVarying = k;
+                        }
+                        break;
+                    }
+                }
+		    }
+        }
+
+        pAsm->number_used_registers += unMaxVarying + 1;
+    }
+#endif
+    unBit = 1 << FRAG_ATTRIB_FACE;
+    if(mesa_fp->Base.InputsRead & unBit)
+    {
+        pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FACE] = pAsm->number_used_registers++;
+    }
+
+    unBit = 1 << FRAG_ATTRIB_PNTC;
+    if(mesa_fp->Base.InputsRead & unBit)
+    {
+        pAsm->uiFP_AttributeMap[FRAG_ATTRIB_PNTC] = pAsm->number_used_registers++;
+    }
 
 /* Map temporary registers (GPRs) */
     pAsm->starting_temp_register_number = pAsm->number_used_registers;
@@ -127,6 +249,8 @@
         pAsm->pucOutMask[ui] = 0x0;
     }
 
+    pAsm->flag_reg_index = pAsm->number_used_registers++;
+
     pAsm->uFirstHelpReg = pAsm->number_used_registers;
 }
 
@@ -233,22 +357,61 @@
 }
 
 GLboolean r700TranslateFragmentShader(struct r700_fragment_program *fp,
-							     struct gl_fragment_program   *mesa_fp)
+							     struct gl_fragment_program   *mesa_fp,
+                                 GLcontext *ctx) 
 {
 	GLuint    number_of_colors_exported;
 	GLboolean z_enabled = GL_FALSE;
-	GLuint    unBit;
+	GLuint    unBit, shadow_unit;
+	int i;
+	struct prog_instruction *inst;
+	gl_state_index shadow_ambient[STATE_LENGTH]
+	    = { STATE_INTERNAL, STATE_SHADOW_AMBIENT, 0, 0, 0};
 
     //Init_Program
 	Init_r700_AssemblerBase( SPT_FP, &(fp->r700AsmCode), &(fp->r700Shader) );
-	Map_Fragment_Program(&(fp->r700AsmCode), mesa_fp);
+
+    if(mesa_fp->Base.InputsRead & FRAG_BIT_WPOS)
+    {
+        insert_wpos_code(ctx, mesa_fp);
+    }
+
+    /* add/map  consts for ARB_shadow_ambient */
+    if(mesa_fp->Base.ShadowSamplers)
+    {
+        inst = mesa_fp->Base.Instructions;
+        for (i = 0; i < mesa_fp->Base.NumInstructions; i++)
+        {
+            if(inst->TexShadow == 1)
+            {
+                shadow_unit = inst->TexSrcUnit;
+                shadow_ambient[2] = shadow_unit;
+                fp->r700AsmCode.shadow_regs[shadow_unit] = 
+                    _mesa_add_state_reference(mesa_fp->Base.Parameters, shadow_ambient);
+            }
+            inst++;
+        }
+    }
+
+    Map_Fragment_Program(&(fp->r700AsmCode), mesa_fp, ctx); 
 
     if( GL_FALSE == Find_Instruction_Dependencies_fp(fp, mesa_fp) )
 	{
 		return GL_FALSE;
     }
+
+    InitShaderProgram(&(fp->r700AsmCode));
 	
-	if( GL_FALSE == AssembleInstr(mesa_fp->Base.NumInstructions,
+    for(i=0; i < MAX_SAMPLERS; i++)
+    {
+         fp->r700AsmCode.SamplerUnits[i] = fp->mesa_program.Base.SamplerUnits[i];
+    }
+
+    fp->r700AsmCode.unCurNumILInsts = mesa_fp->Base.NumInstructions;
+
+	if( GL_FALSE == AssembleInstr(0,
+                                  0,
+                                  mesa_fp->Base.NumInstructions,
                                   &(mesa_fp->Base.Instructions[0]), 
                                   &(fp->r700AsmCode)) )
 	{
@@ -260,6 +423,11 @@
         return GL_FALSE;
     }
 
+    if( GL_FALSE == RelocProgram(&(fp->r700AsmCode), &(mesa_fp->Base)) )
+    {
+        return GL_FALSE;
+    }
+
     fp->r700Shader.nRegs = (fp->r700AsmCode.number_used_registers == 0) ? 0 
                          : (fp->r700AsmCode.number_used_registers - 1);
 
@@ -300,7 +468,7 @@
     }
 
     if (GL_FALSE == fp->translated)
-	    r700TranslateFragmentShader(fp, &(fp->mesa_program));
+	    r700TranslateFragmentShader(fp, &(fp->mesa_program), ctx); 
 }
 
 void * r700GetActiveFpShaderBo(GLcontext * ctx)
@@ -325,6 +493,7 @@
     unsigned int unNumOfReg;
     unsigned int unBit;
     GLuint exportCount;
+    GLboolean point_sprite = GL_FALSE;
 
     if(GL_FALSE == fp->loaded)
     {
@@ -378,6 +547,50 @@
         CLEARbit(r700->SPI_INPUT_Z.u32All, PROVIDE_Z_TO_SPI_bit);
     }
 
+    if (mesa_fp->Base.InputsRead & (1 << FRAG_ATTRIB_FACE))
+    {
+        ui += 1;
+        SETfield(r700->SPI_PS_IN_CONTROL_0.u32All, ui, NUM_INTERP_shift, NUM_INTERP_mask);
+        SETbit(r700->SPI_PS_IN_CONTROL_1.u32All, FRONT_FACE_ENA_bit);
+        SETbit(r700->SPI_PS_IN_CONTROL_1.u32All, FRONT_FACE_ALL_BITS_bit);
+        SETfield(r700->SPI_PS_IN_CONTROL_1.u32All, pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FACE], FRONT_FACE_ADDR_shift, FRONT_FACE_ADDR_mask);
+    }
+    else
+    {
+        CLEARbit(r700->SPI_PS_IN_CONTROL_1.u32All, FRONT_FACE_ENA_bit);
+    }
+
+    /* see if we need any point_sprite replacements */
+    for (i = VERT_RESULT_TEX0; i<= VERT_RESULT_TEX7; i++)
+    {
+        if(ctx->Point.CoordReplace[i - VERT_RESULT_TEX0] == GL_TRUE)
+            point_sprite = GL_TRUE;
+    }
+
+    if ((mesa_fp->Base.InputsRead & (1 << FRAG_ATTRIB_PNTC)) || point_sprite)
+    {
+        /* for FRAG_ATTRIB_PNTC we need to increase num_interp */
+        if(mesa_fp->Base.InputsRead & (1 << FRAG_ATTRIB_PNTC))
+        {
+            ui++;
+            SETfield(r700->SPI_PS_IN_CONTROL_0.u32All, ui, NUM_INTERP_shift, NUM_INTERP_mask);
+        }
+        SETbit(r700->SPI_INTERP_CONTROL_0.u32All, PNT_SPRITE_ENA_bit);
+        SETfield(r700->SPI_INTERP_CONTROL_0.u32All, SPI_PNT_SPRITE_SEL_S, PNT_SPRITE_OVRD_X_shift, PNT_SPRITE_OVRD_X_mask);
+        SETfield(r700->SPI_INTERP_CONTROL_0.u32All, SPI_PNT_SPRITE_SEL_T, PNT_SPRITE_OVRD_Y_shift, PNT_SPRITE_OVRD_Y_mask);
+        SETfield(r700->SPI_INTERP_CONTROL_0.u32All, SPI_PNT_SPRITE_SEL_0, PNT_SPRITE_OVRD_Z_shift, PNT_SPRITE_OVRD_Z_mask);
+        SETfield(r700->SPI_INTERP_CONTROL_0.u32All, SPI_PNT_SPRITE_SEL_1, PNT_SPRITE_OVRD_W_shift, PNT_SPRITE_OVRD_W_mask);
+        if(ctx->Point.SpriteOrigin == GL_LOWER_LEFT)
+            SETbit(r700->SPI_INTERP_CONTROL_0.u32All, PNT_SPRITE_TOP_1_bit);
+        else
+            CLEARbit(r700->SPI_INTERP_CONTROL_0.u32All, PNT_SPRITE_TOP_1_bit);
+    }
+    else
+    {
+        CLEARbit(r700->SPI_INTERP_CONTROL_0.u32All, PNT_SPRITE_ENA_bit);
+    }
+
+
     ui = (unNumOfReg < ui) ? ui : unNumOfReg;
 
     SETfield(r700->ps.SQ_PGM_RESOURCES_PS.u32All, ui, NUM_GPRS_shift, NUM_GPRS_mask);
@@ -393,27 +606,14 @@
     SETfield(r700->ps.SQ_PGM_EXPORTS_PS.u32All, fp->r700Shader.exportMode,
              EXPORT_MODE_shift, EXPORT_MODE_mask);
 
-    R600_STATECHANGE(context, db);
-
-    if(fp->r700Shader.killIsUsed)
-    {
-	    SETbit(r700->DB_SHADER_CONTROL.u32All, KILL_ENABLE_bit);
-    }
-    else
-    {
-        CLEARbit(r700->DB_SHADER_CONTROL.u32All, KILL_ENABLE_bit);
-    }
-
-    if(fp->r700Shader.depthIsExported)
-    {
-	    SETbit(r700->DB_SHADER_CONTROL.u32All, Z_EXPORT_ENABLE_bit);
-    }
-    else
-    {
-        CLEARbit(r700->DB_SHADER_CONTROL.u32All, Z_EXPORT_ENABLE_bit);
-    }
-
     // emit ps input map
+    struct r700_vertex_program_cont *vpc =
+		       (struct r700_vertex_program_cont *)ctx->VertexProgram._Current;
+    GLbitfield OutputsWritten = vpc->mesa_program.Base.OutputsWritten;
+    
+    for(ui = 0; ui < R700_MAX_SHADER_EXPORTS; ui++)
+        r700->SPI_PS_INPUT_CNTL[ui].u32All = 0;
+
     unBit = 1 << FRAG_ATTRIB_WPOS;
     if(mesa_fp->Base.InputsRead & unBit)
     {
@@ -427,8 +627,8 @@
                     CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
     }
 
-    unBit = 1 << FRAG_ATTRIB_COL0;
-    if(mesa_fp->Base.InputsRead & unBit)
+    unBit = 1 << VERT_RESULT_COL0;
+    if(OutputsWritten & unBit)
     {
 	    ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL0];
 	    SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
@@ -440,8 +640,8 @@
 		    CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
     }
 
-    unBit = 1 << FRAG_ATTRIB_COL1;
-    if(mesa_fp->Base.InputsRead & unBit)
+    unBit = 1 << VERT_RESULT_COL1;
+    if(OutputsWritten & unBit)
     {
 	    ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL1];
 	    SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
@@ -453,8 +653,8 @@
 		    CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
     }
 
-    unBit = 1 << FRAG_ATTRIB_FOGC;
-    if(mesa_fp->Base.InputsRead & unBit)
+    unBit = 1 << VERT_RESULT_FOGC;
+    if(OutputsWritten & unBit)
     {
             ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FOGC];
             SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
@@ -468,25 +668,79 @@
 
     for(i=0; i<8; i++)
     {
-	    unBit = 1 << (FRAG_ATTRIB_TEX0 + i);
-	    if(mesa_fp->Base.InputsRead & unBit)
+	    unBit = 1 << (VERT_RESULT_TEX0 + i);
+	    if(OutputsWritten & unBit)
 	    {
 		    ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_TEX0 + i];
 		    SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
 		    SETfield(r700->SPI_PS_INPUT_CNTL[ui].u32All, ui,
 			     SEMANTIC_shift, SEMANTIC_mask);
 		    CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+		    /* ARB_point_sprite */
+		    if(ctx->Point.CoordReplace[i] == GL_TRUE)
+		    {
+			     SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, PT_SPRITE_TEX_bit);
+		    }
 	    }
     }
 
-    R600_STATECHANGE(context, cb);
+    unBit = 1 << FRAG_ATTRIB_FACE;
+    if(mesa_fp->Base.InputsRead & unBit)
+    {
+            ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FACE];
+            SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+            SETfield(r700->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+                     SEMANTIC_shift, SEMANTIC_mask);
+            if (r700->SPI_INTERP_CONTROL_0.u32All & FLAT_SHADE_ENA_bit)
+                    SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+            else
+                    CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+    }
+    unBit = 1 << FRAG_ATTRIB_PNTC;
+    if(mesa_fp->Base.InputsRead & unBit)
+    {
+            ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_PNTC];
+            SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+            SETfield(r700->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+                     SEMANTIC_shift, SEMANTIC_mask);
+            if (r700->SPI_INTERP_CONTROL_0.u32All & FLAT_SHADE_ENA_bit)
+                    SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+            else
+                    CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+            SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, PT_SPRITE_TEX_bit);
+    }
+
+
+
+
+    for(i=VERT_RESULT_VAR0; i<VERT_RESULT_MAX; i++)
+	{
+        unBit = 1 << i;
+        if(OutputsWritten & unBit)
+		{
+            ui = pAsm->uiFP_AttributeMap[i-VERT_RESULT_VAR0+FRAG_ATTRIB_VAR0];
+            SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+            SETfield(r700->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+		             SEMANTIC_shift, SEMANTIC_mask);
+            if (r700->SPI_INTERP_CONTROL_0.u32All & FLAT_SHADE_ENA_bit)
+		        SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+            else
+		        CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+        }
+    }
+
     exportCount = (r700->ps.SQ_PGM_EXPORTS_PS.u32All & EXPORT_MODE_mask) / (1 << EXPORT_MODE_shift);
-    r700->CB_SHADER_CONTROL.u32All = (1 << exportCount) - 1;
+    if (r700->CB_SHADER_CONTROL.u32All != ((1 << exportCount) - 1))
+    {
+	    R600_STATECHANGE(context, cb);
+	    r700->CB_SHADER_CONTROL.u32All = (1 << exportCount) - 1;
+    }
 
     /* sent out shader constants. */
     paramList = fp->mesa_program.Base.Parameters;
 
-    if(NULL != paramList) {
+    if(NULL != paramList) 
+    {
 	    _mesa_load_state_parameters(ctx, paramList);
 
 	    if (paramList->NumParameters > R700_MAX_DX9_CONSTS)
@@ -499,14 +753,33 @@
 	    unNumParamData = paramList->NumParameters;
 
 	    for(ui=0; ui<unNumParamData; ui++) {
-		    r700->ps.consts[ui][0].f32All = paramList->ParameterValues[ui][0];
-		    r700->ps.consts[ui][1].f32All = paramList->ParameterValues[ui][1];
-		    r700->ps.consts[ui][2].f32All = paramList->ParameterValues[ui][2];
-		    r700->ps.consts[ui][3].f32All = paramList->ParameterValues[ui][3];
+		        r700->ps.consts[ui][0].f32All = paramList->ParameterValues[ui][0];
+		        r700->ps.consts[ui][1].f32All = paramList->ParameterValues[ui][1];
+		        r700->ps.consts[ui][2].f32All = paramList->ParameterValues[ui][2];
+		        r700->ps.consts[ui][3].f32All = paramList->ParameterValues[ui][3];
 	    }
     } else
 	    r700->ps.num_consts = 0;
 
+    COMPILED_SUB * pCompiledSub;
+    GLuint uj;
+    GLuint unConstOffset = r700->ps.num_consts;
+    for(ui=0; ui<pAsm->unNumPresub; ui++)
+    {
+        pCompiledSub = pAsm->presubs[ui].pCompiledSub;
+
+        r700->ps.num_consts += pCompiledSub->NumParameters;
+
+        for(uj=0; uj<pCompiledSub->NumParameters; uj++)
+        {
+            r700->ps.consts[uj + unConstOffset][0].f32All = pCompiledSub->ParameterValues[uj][0];
+		    r700->ps.consts[uj + unConstOffset][1].f32All = pCompiledSub->ParameterValues[uj][1];
+		    r700->ps.consts[uj + unConstOffset][2].f32All = pCompiledSub->ParameterValues[uj][2];
+		    r700->ps.consts[uj + unConstOffset][3].f32All = pCompiledSub->ParameterValues[uj][3];
+        }
+        unConstOffset += pCompiledSub->NumParameters;
+    }
+
     return GL_TRUE;
 }
 
diff --git a/src/mesa/drivers/dri/r600/r700_fragprog.h b/src/mesa/drivers/dri/r600/r700_fragprog.h
index cbb108d..39c59c9 100644
--- a/src/mesa/drivers/dri/r600/r700_fragprog.h
+++ b/src/mesa/drivers/dri/r600/r700_fragprog.h
@@ -48,13 +48,17 @@
 };
 
 /* Internal */
+void insert_wpos_code(GLcontext *ctx, struct gl_fragment_program *fprog);
+
 void Map_Fragment_Program(r700_AssemblerBase         *pAsm,
-			  struct gl_fragment_program *mesa_fp);
+			  struct gl_fragment_program *mesa_fp,
+                          GLcontext *ctx); 
 GLboolean Find_Instruction_Dependencies_fp(struct r700_fragment_program *fp,
 					   struct gl_fragment_program   *mesa_fp);
 
 GLboolean r700TranslateFragmentShader(struct r700_fragment_program *fp,
-				      struct gl_fragment_program   *mesa_vp);
+				      struct gl_fragment_program   *mesa_vp,
+                                      GLcontext *ctx); 
 
 /* Interface */
 extern void r700SelectFragmentShader(GLcontext *ctx);
diff --git a/src/mesa/drivers/dri/r600/r700_render.c b/src/mesa/drivers/dri/r600/r700_render.c
index c345b9d..eab27cb 100644
--- a/src/mesa/drivers/dri/r600/r700_render.c
+++ b/src/mesa/drivers/dri/r600/r700_render.c
@@ -59,9 +59,7 @@
 
 void r700WaitForIdle(context_t *context);
 void r700WaitForIdleClean(context_t *context);
-GLboolean r700SendTextureState(context_t *context);
 static unsigned int r700PrimitiveType(int prim);
-void r600UpdateTextureState(GLcontext * ctx);
 GLboolean r700SyncSurf(context_t *context,
 		       struct radeon_bo *pbo,
 		       uint32_t read_domain,
@@ -528,6 +526,9 @@
 
     radeonAllocDmaRegion(&context->radeon, &attr->bo, &attr->bo_offset, 
                          sizeof(GLfloat) * input->Size * count, 32);
+
+    radeon_bo_map(attr->bo, 1);
+
     dst_ptr = (GLfloat *)ADD_POINTERS(attr->bo->ptr, attr->bo_offset);
 
     assert(src_ptr != NULL);
@@ -561,6 +562,8 @@
             break;
     }
 
+    radeon_bo_unmap(attr->bo);
+
     if (mapped_named_bo) 
     {
         ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj);
@@ -579,6 +582,8 @@
 
     radeonAllocDmaRegion(&context->radeon, &attr->bo, &attr->bo_offset, size, 32);
 
+    radeon_bo_map(attr->bo, 1);
+
     if (!input->BufferObj->Pointer) 
     {
         ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj);
@@ -598,6 +603,7 @@
         }
     }
 
+    radeon_bo_unmap(attr->bo);
     if (mapped_named_bo) 
     {
         ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj);
@@ -666,14 +672,18 @@
 
                 radeonAllocDmaRegion(&context->radeon, &context->stream_desc[index].bo, 
                                      &context->stream_desc[index].bo_offset, size, 32);
+
+                radeon_bo_map(context->stream_desc[index].bo, 1);
                 assert(context->stream_desc[index].bo->ptr != NULL);
+
+
                 dst = (uint32_t *)ADD_POINTERS(context->stream_desc[index].bo->ptr, 
                                                context->stream_desc[index].bo_offset);
 
                 switch (context->stream_desc[index].dwords) 
                 {
                 case 1:                     
-                    radeonEmitVec4(dst, input[i]->Ptr, input[i]->StrideB, local_count);                         
+                    radeonEmitVec4(dst, input[i]->Ptr, input[i]->StrideB, local_count);
                     break;
                 case 2: 
                     radeonEmitVec8(dst, input[i]->Ptr, input[i]->StrideB, local_count); 
@@ -688,6 +698,7 @@
                     assert(0); 
                     break;
                 }
+		radeon_bo_unmap(context->stream_desc[index].bo);
             }
         }
 
@@ -759,6 +770,7 @@
 	radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo,
 			     &context->ind_buf.bo_offset, size, 4);
 
+	radeon_bo_map(context->ind_buf.bo, 1);
 	assert(context->ind_buf.bo->ptr != NULL);
 	out = (GLuint *)ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
 
@@ -772,6 +784,7 @@
             *out++ = in[i];
         }
 
+	radeon_bo_unmap(context->ind_buf.bo);
 #if MESA_BIG_ENDIAN
     }
     else
@@ -782,6 +795,7 @@
 	radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo,
 			     &context->ind_buf.bo_offset, size, 4);
 
+	radeon_bo_map(context->ind_buf.bo, 1);
 	assert(context->ind_buf.bo->ptr != NULL);
 	out = (GLuint *)ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
 
@@ -794,6 +808,7 @@
         {
             *out++ = in[i];
         }
+	radeon_bo_unmap(context->ind_buf.bo);
 #endif
     }
 
@@ -839,11 +854,13 @@
 
 	radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo,
 			     &context->ind_buf.bo_offset, size, 4);
+	radeon_bo_map(context->ind_buf.bo, 1);
 	assert(context->ind_buf.bo->ptr != NULL);
 	dst_ptr = ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
 
         _mesa_memcpy(dst_ptr, src_ptr, size);
 
+	radeon_bo_unmap(context->ind_buf.bo);
         context->ind_buf.is_32bit = (mesa_ind_buf->type == GL_UNSIGNED_INT);
         context->ind_buf.count = mesa_ind_buf->count;
 
@@ -891,7 +908,7 @@
     r700SetScissor(context);
     r700SetupVertexProgram(ctx);
     r700SetupFragmentProgram(ctx);
-    r600UpdateTextureState(ctx);
+    r700UpdateShaderStates(ctx);
 
     GLuint emit_end = r700PredictRenderSize(ctx, prim, ib, nr_prims)
                     + context->radeon.cmdbuf.cs->cdw;
diff --git a/src/mesa/drivers/dri/r600/r700_shader.c b/src/mesa/drivers/dri/r600/r700_shader.c
index 955ea4e..2eed1ac 100644
--- a/src/mesa/drivers/dri/r600/r700_shader.c
+++ b/src/mesa/drivers/dri/r600/r700_shader.c
@@ -159,13 +159,18 @@
 	pShader->lstVTXInstructions.uNumOfNode=0;
 }
 
+void SetActiveCFlist(R700_Shader *pShader, TypedShaderList * plstCF)
+{
+    pShader->plstCFInstructions_active = plstCF;
+}
+
 void AddCFInstruction(R700_Shader *pShader, R700ControlFlowInstruction *pCFInst)
 {
     R700ControlFlowSXClause*  pSXClause; 
     R700ControlFlowSMXClause* pSMXClause;
 
-    pCFInst->m_uIndex = pShader->lstCFInstructions.uNumOfNode;
-    AddInstToList(&(pShader->lstCFInstructions), 
+    pCFInst->m_uIndex = pShader->plstCFInstructions_active->uNumOfNode;
+    AddInstToList(pShader->plstCFInstructions_active, 
                   (R700ShaderInstruction*)pCFInst);
     pShader->uShaderBinaryDWORDSize += GetInstructionSize(pCFInst->m_ShaderInstType);
 
diff --git a/src/mesa/drivers/dri/r600/r700_shader.h b/src/mesa/drivers/dri/r600/r700_shader.h
index c6a0586..0599ffd 100644
--- a/src/mesa/drivers/dri/r600/r700_shader.h
+++ b/src/mesa/drivers/dri/r600/r700_shader.h
@@ -109,6 +109,7 @@
     GLuint  uStackSize;
     GLuint  uMaxCallDepth;
 
+    TypedShaderList * plstCFInstructions_active;
 	TypedShaderList lstCFInstructions;
 	TypedShaderList lstALUInstructions;
 	TypedShaderList lstTEXInstructions;
@@ -132,13 +133,13 @@
 void ResolveLinks(R700_Shader *pShader);
 void Assemble(R700_Shader *pShader);
 
-
 //Interface
 void Init_R700_Shader(R700_Shader * pShader);
 void AddCFInstruction(R700_Shader *pShader, R700ControlFlowInstruction *pCFInst);
 void AddVTXInstruction(R700_Shader *pShader, R700VertexInstruction *pVTXInst);
 void AddTEXInstruction(R700_Shader *pShader, R700TextureInstruction *pTEXInst);
 void AddALUInstruction(R700_Shader *pShader, R700ALUInstruction *pALUInst);
+void SetActiveCFlist(R700_Shader *pShader, TypedShaderList * plstCF);
 
 void LoadProgram(R700_Shader *pShader);
 void UpdateShaderRegisters(R700_Shader *pShader);
diff --git a/src/mesa/drivers/dri/r600/r700_shaderinst.h b/src/mesa/drivers/dri/r600/r700_shaderinst.h
index 2829cca..cdb9a57 100644
--- a/src/mesa/drivers/dri/r600/r700_shaderinst.h
+++ b/src/mesa/drivers/dri/r600/r700_shaderinst.h
@@ -42,6 +42,13 @@
 #define SQ_FETCH_RESOURCE_VS_OFFSET    0x000000a0
 #define SQ_FETCH_RESOURCE_VS_COUNT     0x000000b0
 
+//richard dec.10 glsl
+#define SQ_TEX_SAMPLER_PS_OFFSET       0x00000000
+#define SQ_TEX_SAMPLER_PS_COUNT        0x00000012
+#define SQ_TEX_SAMPLER_VS_OFFSET       0x00000012
+#define SQ_TEX_SAMPLER_VS_COUNT        0x00000012
+//-------------------
+
 #define SHADERINST_TYPEMASK_CF  0x10
 #define SHADERINST_TYPEMASK_ALU 0x20
 #define SHADERINST_TYPEMASK_TEX 0x40
diff --git a/src/mesa/drivers/dri/r600/r700_state.c b/src/mesa/drivers/dri/r600/r700_state.c
index b278887..3c8cb57 100644
--- a/src/mesa/drivers/dri/r600/r700_state.c
+++ b/src/mesa/drivers/dri/r600/r700_state.c
@@ -54,7 +54,7 @@
 #include "r700_fragprog.h"
 #include "r700_vertprog.h"
 
-
+void r600UpdateTextureState(GLcontext * ctx);
 static void r700SetClipPlaneState(GLcontext * ctx, GLenum cap, GLboolean state);
 static void r700UpdatePolygonMode(GLcontext * ctx);
 static void r700SetPolygonOffsetState(GLcontext * ctx, GLboolean state);
@@ -85,7 +85,7 @@
 {
 	context_t *context = R700_CONTEXT(ctx);
 	R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
-	__DRIdrawablePrivate *dPriv = radeon_get_drawable(&context->radeon);
+	__DRIdrawable *dPriv = radeon_get_drawable(&context->radeon);
 	GLfloat xoffset = (GLfloat) dPriv->x;
 	GLfloat yoffset = (GLfloat) dPriv->y + dPriv->h;
 	const GLfloat *v = ctx->Viewport._WindowMap.m;
@@ -191,6 +191,67 @@
     context->radeon.NewGLState |= new_state;
 }
 
+static void r700SetDBRenderState(GLcontext * ctx)
+{
+	context_t *context = R700_CONTEXT(ctx);
+	R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+	struct r700_fragment_program *fp = (struct r700_fragment_program *)
+		(ctx->FragmentProgram._Current);
+
+	R600_STATECHANGE(context, db);
+
+	SETbit(r700->DB_SHADER_CONTROL.u32All, DUAL_EXPORT_ENABLE_bit);
+	SETfield(r700->DB_SHADER_CONTROL.u32All, EARLY_Z_THEN_LATE_Z, Z_ORDER_shift, Z_ORDER_mask);
+	/* XXX need to enable htile for hiz/s */
+	SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIZ_ENABLE_shift, FORCE_HIZ_ENABLE_mask);
+	SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE0_shift, FORCE_HIS_ENABLE0_mask);
+	SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE1_shift, FORCE_HIS_ENABLE1_mask);
+
+	if (context->radeon.query.current)
+	{
+		SETbit(r700->DB_RENDER_OVERRIDE.u32All, NOOP_CULL_DISABLE_bit);
+		if (context->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV770)
+		{
+			SETbit(r700->DB_RENDER_CONTROL.u32All, PERFECT_ZPASS_COUNTS_bit);
+		}
+	}
+	else
+	{
+		CLEARbit(r700->DB_RENDER_OVERRIDE.u32All, NOOP_CULL_DISABLE_bit);
+		if (context->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV770)
+		{
+			CLEARbit(r700->DB_RENDER_CONTROL.u32All, PERFECT_ZPASS_COUNTS_bit);
+		}
+	}
+
+	if (fp)
+	{
+		if (fp->r700Shader.killIsUsed)
+		{
+			SETbit(r700->DB_SHADER_CONTROL.u32All, KILL_ENABLE_bit);
+		}
+		else
+		{
+			CLEARbit(r700->DB_SHADER_CONTROL.u32All, KILL_ENABLE_bit);
+		}
+
+		if (fp->r700Shader.depthIsExported)
+		{
+			SETbit(r700->DB_SHADER_CONTROL.u32All, Z_EXPORT_ENABLE_bit);
+		}
+		else
+		{
+			CLEARbit(r700->DB_SHADER_CONTROL.u32All, Z_EXPORT_ENABLE_bit);
+		}
+	}
+}
+
+void r700UpdateShaderStates(GLcontext * ctx)
+{
+	r700SetDBRenderState(ctx);
+	r600UpdateTextureState(ctx);
+}
+
 static void r700SetDepthState(GLcontext * ctx)
 {
 	context_t *context = R700_CONTEXT(ctx);
@@ -644,6 +705,10 @@
             CLEARbit(r700->PA_SU_SC_MODE_CNTL.u32All, FACE_bit); /* default: ccw */
             break;
     }
+
+    /* Winding is inverted when rendering to FBO */
+    if (ctx->DrawBuffer && ctx->DrawBuffer->Name)
+	    r700->PA_SU_SC_MODE_CNTL.u32All ^= FACE_bit;
 }
 
 static void r700UpdateLineStipple(GLcontext * ctx)
@@ -1006,7 +1071,7 @@
 {
 	context_t *context = R700_CONTEXT(ctx);
 	R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
-	__DRIdrawablePrivate *dPriv = radeon_get_drawable(&context->radeon);
+	__DRIdrawable *dPriv = radeon_get_drawable(&context->radeon);
 	GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
 	GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
 	const GLfloat *v = ctx->Viewport._WindowMap.m;
@@ -1166,13 +1231,8 @@
 		/* Handle GL_CW (clock wise and GL_CCW (counter clock wise)
 		 * correctly by selecting the correct front and back face
 		 */
-		if (ctx->Polygon.FrontFace == GL_CCW) {
-			f = ctx->Polygon.FrontMode;
-			b = ctx->Polygon.BackMode;
-		} else {
-			f = ctx->Polygon.BackMode;
-			b = ctx->Polygon.FrontMode;
-		}
+		f = ctx->Polygon.FrontMode;
+		b = ctx->Polygon.BackMode;
 
 		/* Enable polygon mode */
 		SETfield(r700->PA_SU_SC_MODE_CNTL.u32All, X_DUAL_MODE, POLY_MODE_shift, POLY_MODE_mask);
@@ -1664,28 +1724,18 @@
     r700InitSQConfig(ctx);
 
     r700ColorMask(ctx,
-		  ctx->Color.ColorMask[RCOMP],
-		  ctx->Color.ColorMask[GCOMP],
-		  ctx->Color.ColorMask[BCOMP],
-		  ctx->Color.ColorMask[ACOMP]);
+		  ctx->Color.ColorMask[0][RCOMP],
+		  ctx->Color.ColorMask[0][GCOMP],
+		  ctx->Color.ColorMask[0][BCOMP],
+		  ctx->Color.ColorMask[0][ACOMP]);
 
     r700Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);
     r700DepthMask(ctx, ctx->Depth.Mask);
     r700DepthFunc(ctx, ctx->Depth.Func);
-    SETbit(r700->DB_SHADER_CONTROL.u32All, DUAL_EXPORT_ENABLE_bit);
-
     r700->DB_DEPTH_CLEAR.u32All     = 0x3F800000;
-
-    r700->DB_RENDER_CONTROL.u32All  = 0;
     SETbit(r700->DB_RENDER_CONTROL.u32All, STENCIL_COMPRESS_DISABLE_bit);
     SETbit(r700->DB_RENDER_CONTROL.u32All, DEPTH_COMPRESS_DISABLE_bit);
-    r700->DB_RENDER_OVERRIDE.u32All = 0;
-    if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
-	    SETbit(r700->DB_RENDER_OVERRIDE.u32All, FORCE_SHADER_Z_ORDER_bit);
-    SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIZ_ENABLE_shift, FORCE_HIZ_ENABLE_mask);
-    SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE0_shift, FORCE_HIS_ENABLE0_mask);
-    SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE1_shift, FORCE_HIS_ENABLE1_mask);
-    SETbit(r700->DB_RENDER_OVERRIDE.u32All, NOOP_CULL_DISABLE_bit);
+    r700SetDBRenderState(ctx);
 
     r700->DB_ALPHA_TO_MASK.u32All = 0;
     SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET0_shift, ALPHA_TO_MASK_OFFSET0_mask);
diff --git a/src/mesa/drivers/dri/r600/r700_state.h b/src/mesa/drivers/dri/r600/r700_state.h
index 209189d..60c6a7f 100644
--- a/src/mesa/drivers/dri/r600/r700_state.h
+++ b/src/mesa/drivers/dri/r600/r700_state.h
@@ -35,7 +35,7 @@
 
 extern void r700UpdateStateParameters(GLcontext * ctx, GLuint new_state);
 extern void r700UpdateShaders (GLcontext * ctx);
-extern void r700UpdateShaders2(GLcontext * ctx);
+extern void r700UpdateShaderStates(GLcontext * ctx);
 
 extern void r700UpdateViewportOffset(GLcontext * ctx);
 
diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.c b/src/mesa/drivers/dri/r600/r700_vertprog.c
index ffc6068..782f151 100644
--- a/src/mesa/drivers/dri/r600/r700_vertprog.c
+++ b/src/mesa/drivers/dri/r600/r700_vertprog.c
@@ -111,6 +111,15 @@
 		}
 	}
 
+    for(i=VERT_RESULT_VAR0; i<VERT_RESULT_MAX; i++)
+	{
+		unBit = 1 << i;
+		if(mesa_vp->Base.OutputsWritten & unBit)
+		{
+			pAsm->ucVP_OutputMap[i] = unTotal++;
+		}
+	}
+
 	return (unTotal - unStart);
 }
 
@@ -179,7 +188,8 @@
                                       context->stream_desc[i].size,
                                       context->stream_desc[i].element,
                                       context->stream_desc[i]._signed,
-                                      context->stream_desc[i].normalize,						            
+                                      context->stream_desc[i].normalize,
+                                      context->stream_desc[i].format,
                                      &vtxFetchMethod);
     }
 
@@ -235,6 +245,8 @@
         pAsm->number_used_registers += mesa_vp->Base.NumTemporaries;
     }
 
+    pAsm->flag_reg_index = pAsm->number_used_registers++;
+
     pAsm->uFirstHelpReg = pAsm->number_used_registers;
 }
 
@@ -308,6 +320,7 @@
 		vp->aos_desc[i].size   = context->stream_desc[i].size;
 		vp->aos_desc[i].stride = context->stream_desc[i].stride;
 		vp->aos_desc[i].type   = context->stream_desc[i].type;
+		vp->aos_desc[i].format = context->stream_desc[i].format;
 	}
 
 	if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
@@ -324,7 +337,18 @@
 		return NULL;
 	}
 
-	if(GL_FALSE == AssembleInstr(vp->mesa_program->Base.NumInstructions,
+    InitShaderProgram(&(vp->r700AsmCode));
+
+    for(i=0; i < MAX_SAMPLERS; i++)
+    {
+        vp->r700AsmCode.SamplerUnits[i] = vp->mesa_program->Base.SamplerUnits[i];
+    }
+
+    vp->r700AsmCode.unCurNumILInsts = vp->mesa_program->Base.NumInstructions;
+
+	if(GL_FALSE == AssembleInstr(0,
+                                 0,
+                                 vp->mesa_program->Base.NumInstructions,
                                  &(vp->mesa_program->Base.Instructions[0]),
                                  &(vp->r700AsmCode)) )
 	{
@@ -336,6 +360,11 @@
         return NULL;
     }
 
+    if( GL_FALSE == RelocProgram(&(vp->r700AsmCode), &(vp->mesa_program->Base)) )
+    {
+        return GL_FALSE;
+    }
+
     vp->r700Shader.nRegs = (vp->r700AsmCode.number_used_registers == 0) ? 0 
                          : (vp->r700AsmCode.number_used_registers - 1);
 
@@ -368,7 +397,8 @@
 	match = GL_TRUE;
 	for(i=0; i<context->nNumActiveAos; i++)
 	{
-		if (vp->aos_desc[i].size != context->stream_desc[i].size)
+		if (vp->aos_desc[i].size != context->stream_desc[i].size ||
+		    vp->aos_desc[i].format != context->stream_desc[i].format)
 		{
 			match = GL_FALSE;
 			break;
@@ -471,6 +501,7 @@
 	pStreamDesc->size = input->Size;
 	pStreamDesc->dst_loc = context->nNumActiveAos;
 	pStreamDesc->element = unLoc;
+	pStreamDesc->format = input->Format;
 
 	switch (pStreamDesc->type) 
 	{ //GetSurfaceFormat
@@ -612,6 +643,12 @@
     paramList = vp->mesa_program->Base.Parameters;
 
     if(NULL != paramList) {
+        /* vp->mesa_program was cloned, not updated by glsl shader api. */
+        /* _mesa_reference_program has already checked glsl shProg is ok and set ctx->VertexProgem._Current */
+        /* so, use ctx->VertexProgem._Current */       
+        struct gl_program_parameter_list *paramListOrginal = 
+                         paramListOrginal = ctx->VertexProgram._Current->Base.Parameters;
+         
 	    _mesa_load_state_parameters(ctx, paramList);
 
 	    if (paramList->NumParameters > R700_MAX_DX9_CONSTS)
@@ -624,13 +661,42 @@
 	    unNumParamData = paramList->NumParameters;
 
 	    for(ui=0; ui<unNumParamData; ui++) {
-		    r700->vs.consts[ui][0].f32All = paramList->ParameterValues[ui][0];
-		    r700->vs.consts[ui][1].f32All = paramList->ParameterValues[ui][1];
-		    r700->vs.consts[ui][2].f32All = paramList->ParameterValues[ui][2];
-		    r700->vs.consts[ui][3].f32All = paramList->ParameterValues[ui][3];
+            if(paramList->Parameters[ui].Type == PROGRAM_UNIFORM) 
+            {
+                r700->vs.consts[ui][0].f32All = paramListOrginal->ParameterValues[ui][0];
+		        r700->vs.consts[ui][1].f32All = paramListOrginal->ParameterValues[ui][1];
+		        r700->vs.consts[ui][2].f32All = paramListOrginal->ParameterValues[ui][2];
+		        r700->vs.consts[ui][3].f32All = paramListOrginal->ParameterValues[ui][3];
+            }
+            else
+            {
+		        r700->vs.consts[ui][0].f32All = paramList->ParameterValues[ui][0];
+		        r700->vs.consts[ui][1].f32All = paramList->ParameterValues[ui][1];
+		        r700->vs.consts[ui][2].f32All = paramList->ParameterValues[ui][2];
+		        r700->vs.consts[ui][3].f32All = paramList->ParameterValues[ui][3];
+            }
 	    }
     } else
 	    r700->vs.num_consts = 0;
 
+    COMPILED_SUB * pCompiledSub;
+    GLuint uj;
+    GLuint unConstOffset = r700->vs.num_consts;
+    for(ui=0; ui<vp->r700AsmCode.unNumPresub; ui++)
+    {
+        pCompiledSub = vp->r700AsmCode.presubs[ui].pCompiledSub;
+
+        r700->vs.num_consts += pCompiledSub->NumParameters;
+
+        for(uj=0; uj<pCompiledSub->NumParameters; uj++)
+        {
+            r700->vs.consts[uj + unConstOffset][0].f32All = pCompiledSub->ParameterValues[uj][0];
+		    r700->vs.consts[uj + unConstOffset][1].f32All = pCompiledSub->ParameterValues[uj][1];
+		    r700->vs.consts[uj + unConstOffset][2].f32All = pCompiledSub->ParameterValues[uj][2];
+		    r700->vs.consts[uj + unConstOffset][3].f32All = pCompiledSub->ParameterValues[uj][3];
+        }
+        unConstOffset += pCompiledSub->NumParameters;
+    }
+
     return GL_TRUE;
 }
diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.h b/src/mesa/drivers/dri/r600/r700_vertprog.h
index 00824c2..645c9ac 100644
--- a/src/mesa/drivers/dri/r600/r700_vertprog.h
+++ b/src/mesa/drivers/dri/r600/r700_vertprog.h
@@ -39,6 +39,7 @@
 	GLint size;   //number of data element
 	GLenum type;  //data element type
 	GLsizei stride;
+	GLenum format; //GL_RGBA or GL_BGRA
 } ArrayDesc;
 
 struct r700_vertex_program 
diff --git a/src/mesa/drivers/dri/r600/radeon_bo.c b/src/mesa/drivers/dri/r600/radeon_bo.c
new file mode 120000
index 0000000..9448ffe
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/radeon_bo.c
@@ -0,0 +1 @@
+../radeon/radeon_bo.c
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r600/radeon_bo_int_drm.h b/src/mesa/drivers/dri/r600/radeon_bo_int_drm.h
new file mode 120000
index 0000000..0294509
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/radeon_bo_int_drm.h
@@ -0,0 +1 @@
+../radeon/radeon_bo_int_drm.h
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r600/radeon_cs.c b/src/mesa/drivers/dri/r600/radeon_cs.c
new file mode 120000
index 0000000..66b7ad1
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/radeon_cs.c
@@ -0,0 +1 @@
+../radeon/radeon_cs.c
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r600/radeon_cs_int_drm.h b/src/mesa/drivers/dri/r600/radeon_cs_int_drm.h
new file mode 120000
index 0000000..462f524
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/radeon_cs_int_drm.h
@@ -0,0 +1 @@
+../radeon/radeon_cs_int_drm.h
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile
index ae2e695..2b2f2c4 100644
--- a/src/mesa/drivers/dri/radeon/Makefile
+++ b/src/mesa/drivers/dri/radeon/Makefile
@@ -11,7 +11,7 @@
 MINIGLX_SOURCES = server/radeon_dri.c 
 
 ifeq ($(RADEON_LDFLAGS),)
-CS_SOURCES = radeon_cs_space_drm.c
+CS_SOURCES = radeon_cs_space_drm.c radeon_bo.c radeon_cs.c
 endif
 
 RADEON_COMMON_SOURCES = \
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo.c b/src/mesa/drivers/dri/radeon/radeon_bo.c
new file mode 100644
index 0000000..393d156
--- /dev/null
+++ b/src/mesa/drivers/dri/radeon/radeon_bo.c
@@ -0,0 +1,110 @@
+#include <radeon_bocs_wrapper.h>
+#include <radeon_bo_int_drm.h>
+
+void radeon_bo_debug(struct radeon_bo *bo,
+		     const char *op)
+{
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
+
+    fprintf(stderr, "%s %p 0x%08X 0x%08X 0x%08X\n",
+            op, bo, bo->handle, boi->size, boi->cref);
+}
+
+struct radeon_bo *radeon_bo_open(struct radeon_bo_manager *bom,
+				 uint32_t handle,
+				 uint32_t size,
+				 uint32_t alignment,
+				 uint32_t domains,
+				 uint32_t flags)
+{
+    struct radeon_bo *bo;
+    bo = bom->funcs->bo_open(bom, handle, size, alignment, domains, flags);
+    return bo;
+}
+
+void radeon_bo_ref(struct radeon_bo *bo)
+{
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
+    boi->cref++;
+    boi->bom->funcs->bo_ref(boi);
+}
+
+struct radeon_bo *radeon_bo_unref(struct radeon_bo *bo)
+{
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
+    boi->cref--;
+    return boi->bom->funcs->bo_unref(boi);
+}
+
+int radeon_bo_map(struct radeon_bo *bo, int write)
+{
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
+    return boi->bom->funcs->bo_map(boi, write);
+}
+
+int radeon_bo_unmap(struct radeon_bo *bo)
+{
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
+    return boi->bom->funcs->bo_unmap(boi);
+}
+
+int radeon_bo_wait(struct radeon_bo *bo)
+{
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
+    if (!boi->bom->funcs->bo_wait)
+	return 0;
+    return boi->bom->funcs->bo_wait(boi);
+}
+
+int radeon_bo_is_busy(struct radeon_bo *bo,
+		      uint32_t *domain)
+{
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
+    return boi->bom->funcs->bo_is_busy(boi, domain);
+}
+
+int radeon_bo_set_tiling(struct radeon_bo *bo,
+			 uint32_t tiling_flags, uint32_t pitch)
+{
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
+    return boi->bom->funcs->bo_set_tiling(boi, tiling_flags, pitch);
+}
+
+int radeon_bo_get_tiling(struct radeon_bo *bo,
+			  uint32_t *tiling_flags, uint32_t *pitch)
+{
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
+    return boi->bom->funcs->bo_get_tiling(boi, tiling_flags, pitch);
+}
+
+int radeon_bo_is_static(struct radeon_bo *bo)
+{
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
+    if (boi->bom->funcs->bo_is_static)
+	return boi->bom->funcs->bo_is_static(boi);
+    return 0;
+}
+
+int radeon_bo_is_referenced_by_cs(struct radeon_bo *bo,
+				  struct radeon_cs *cs)
+{
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
+    return boi->cref > 1;
+}
+
+uint32_t radeon_bo_get_handle(struct radeon_bo *bo)
+{
+    return bo->handle;
+}
+
+uint32_t radeon_bo_get_src_domain(struct radeon_bo *bo)
+{
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
+    uint32_t src_domain;
+
+    src_domain = boi->space_accounted & 0xffff;
+    if (!src_domain)
+	src_domain = boi->space_accounted >> 16;
+
+    return src_domain;
+}
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_drm.h b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h
index 7141371..beb2369 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bo_drm.h
+++ b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h
@@ -32,188 +32,44 @@
 
 #include <stdio.h>
 #include <stdint.h>
-//#include "radeon_track.h"
 
 /* bo object */
 #define RADEON_BO_FLAGS_MACRO_TILE  1
 #define RADEON_BO_FLAGS_MICRO_TILE  2
 
 struct radeon_bo_manager;
+struct radeon_cs;
 
 struct radeon_bo {
-    uint32_t                    alignment;
+    void                        *ptr;
+    uint32_t                    flags;
     uint32_t                    handle;
     uint32_t                    size;
-    uint32_t                    domains;
-    uint32_t                    flags;
-    unsigned                    cref;
-#ifdef RADEON_BO_TRACK
-    struct radeon_track         *track;
-#endif
-    void                        *ptr;
-    struct radeon_bo_manager    *bom;
-    uint32_t                    space_accounted;
 };
 
-/* bo functions */
-struct radeon_bo_funcs {
-    struct radeon_bo *(*bo_open)(struct radeon_bo_manager *bom,
-                                 uint32_t handle,
-                                 uint32_t size,
-                                 uint32_t alignment,
-                                 uint32_t domains,
-                                 uint32_t flags);
-    void (*bo_ref)(struct radeon_bo *bo);
-    struct radeon_bo *(*bo_unref)(struct radeon_bo *bo);
-    int (*bo_map)(struct radeon_bo *bo, int write);
-    int (*bo_unmap)(struct radeon_bo *bo);
-    int (*bo_wait)(struct radeon_bo *bo);
-    int (*bo_is_static)(struct radeon_bo *bo);
-    int (*bo_set_tiling)(struct radeon_bo *bo, uint32_t tiling_flags,
-			  uint32_t pitch);
-    int (*bo_get_tiling)(struct radeon_bo *bo, uint32_t *tiling_flags,
-			  uint32_t *pitch);
-    int (*bo_is_busy)(struct radeon_bo *bo, uint32_t *domain);
-};
+struct radeon_bo_manager;
 
-struct radeon_bo_manager {
-    struct radeon_bo_funcs  *funcs;
-    int                     fd;
+void radeon_bo_debug(struct radeon_bo *bo,
+		     const char *op);
 
-#ifdef RADEON_BO_TRACK
-    struct radeon_tracker   tracker;
-#endif
-};
-    
-static inline void _radeon_bo_debug(struct radeon_bo *bo,
-                                    const char *op,
-                                    const char *file,
-                                    const char *func,
-                                    int line)
-{
-    fprintf(stderr, "%s %p 0x%08X 0x%08X 0x%08X [%s %s %d]\n",
-            op, bo, bo->handle, bo->size, bo->cref, file, func, line);
-}
+struct radeon_bo *radeon_bo_open(struct radeon_bo_manager *bom,
+				  uint32_t handle,
+				  uint32_t size,
+				  uint32_t alignment,
+				  uint32_t domains,
+				  uint32_t flags);
 
-static inline struct radeon_bo *_radeon_bo_open(struct radeon_bo_manager *bom,
-                                                uint32_t handle,
-                                                uint32_t size,
-                                                uint32_t alignment,
-                                                uint32_t domains,
-                                                uint32_t flags,
-                                                const char *file,
-                                                const char *func,
-                                                int line)
-{
-    struct radeon_bo *bo;
-
-    bo = bom->funcs->bo_open(bom, handle, size, alignment, domains, flags);
-
-#ifdef RADEON_BO_TRACK
-    if (bo) {
-        bo->track = radeon_tracker_add_track(&bom->tracker, bo->handle);
-        radeon_track_add_event(bo->track, file, func, "open", line);
-    }
-#endif
-    return bo;
-}
-
-static inline void _radeon_bo_ref(struct radeon_bo *bo,
-                                  const char *file,
-                                  const char *func,
-                                  int line)
-{
-    bo->cref++;
-#ifdef RADEON_BO_TRACK
-    radeon_track_add_event(bo->track, file, func, "ref", line); 
-#endif
-    bo->bom->funcs->bo_ref(bo);
-}
-
-static inline struct radeon_bo *_radeon_bo_unref(struct radeon_bo *bo,
-                                                 const char *file,
-                                                 const char *func,
-                                                 int line)
-{
-    bo->cref--;
-#ifdef RADEON_BO_TRACK
-    radeon_track_add_event(bo->track, file, func, "unref", line);
-    if (bo->cref <= 0) {
-        radeon_tracker_remove_track(&bo->bom->tracker, bo->track);
-        bo->track = NULL;
-    }
-#endif
-    return bo->bom->funcs->bo_unref(bo);
-}
-
-static inline int _radeon_bo_map(struct radeon_bo *bo,
-                                 int write,
-                                 const char *file,
-                                 const char *func,
-                                 int line)
-{
-    return bo->bom->funcs->bo_map(bo, write);
-}
-
-static inline int _radeon_bo_unmap(struct radeon_bo *bo,
-                                   const char *file,
-                                   const char *func,
-                                   int line)
-{
-    return bo->bom->funcs->bo_unmap(bo);
-}
-
-static inline int _radeon_bo_wait(struct radeon_bo *bo,
-                                  const char *file,
-                                  const char *func,
-                                  int line)
-{
-    return bo->bom->funcs->bo_wait(bo);
-}
-
-static inline int _radeon_bo_is_busy(struct radeon_bo *bo,
-				     uint32_t *domain,
-                                     const char *file,
-                                     const char *func,
-                                     int line)
-{
-    return bo->bom->funcs->bo_is_busy(bo, domain);
-}
-
-static inline int radeon_bo_set_tiling(struct radeon_bo *bo,
-				       uint32_t tiling_flags, uint32_t pitch)
-{
-    return bo->bom->funcs->bo_set_tiling(bo, tiling_flags, pitch);
-}
-
-static inline int radeon_bo_get_tiling(struct radeon_bo *bo,
-				       uint32_t *tiling_flags, uint32_t *pitch)
-{
-    return bo->bom->funcs->bo_get_tiling(bo, tiling_flags, pitch);
-}
-
-static inline int radeon_bo_is_static(struct radeon_bo *bo)
-{
-	if (bo->bom->funcs->bo_is_static)
-		return bo->bom->funcs->bo_is_static(bo);
-	return 0;
-}
-
-#define radeon_bo_open(bom, h, s, a, d, f)\
-    _radeon_bo_open(bom, h, s, a, d, f, __FILE__, __FUNCTION__, __LINE__)
-#define radeon_bo_ref(bo)\
-    _radeon_bo_ref(bo, __FILE__, __FUNCTION__, __LINE__)
-#define radeon_bo_unref(bo)\
-    _radeon_bo_unref(bo, __FILE__, __FUNCTION__, __LINE__)
-#define radeon_bo_map(bo, w)\
-    _radeon_bo_map(bo, w, __FILE__, __FUNCTION__, __LINE__)
-#define radeon_bo_unmap(bo)\
-    _radeon_bo_unmap(bo, __FILE__, __FUNCTION__, __LINE__)
-#define radeon_bo_debug(bo, opcode)\
-    _radeon_bo_debug(bo, opcode, __FILE__, __FUNCTION__, __LINE__)
-#define radeon_bo_wait(bo) \
-    _radeon_bo_wait(bo, __FILE__, __func__, __LINE__)
-#define radeon_bo_is_busy(bo, domain) \
-    _radeon_bo_is_busy(bo, domain, __FILE__, __func__, __LINE__)
-
+void radeon_bo_ref(struct radeon_bo *bo);
+struct radeon_bo *radeon_bo_unref(struct radeon_bo *bo);
+int radeon_bo_map(struct radeon_bo *bo, int write);
+int radeon_bo_unmap(struct radeon_bo *bo);
+int radeon_bo_wait(struct radeon_bo *bo);
+int radeon_bo_is_busy(struct radeon_bo *bo, uint32_t *domain);
+int radeon_bo_set_tiling(struct radeon_bo *bo, uint32_t tiling_flags, uint32_t pitch);
+int radeon_bo_get_tiling(struct radeon_bo *bo, uint32_t *tiling_flags, uint32_t *pitch);
+int radeon_bo_is_static(struct radeon_bo *bo);
+int radeon_bo_is_referenced_by_cs(struct radeon_bo *bo,
+				  struct radeon_cs *cs);
+uint32_t radeon_bo_get_handle(struct radeon_bo *bo);
+uint32_t radeon_bo_get_src_domain(struct radeon_bo *bo);
 #endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_int_drm.h b/src/mesa/drivers/dri/radeon/radeon_bo_int_drm.h
new file mode 100644
index 0000000..190c332
--- /dev/null
+++ b/src/mesa/drivers/dri/radeon/radeon_bo_int_drm.h
@@ -0,0 +1,45 @@
+#ifndef RADEON_BO_INT
+#define RADEON_BO_INT
+
+struct radeon_bo_manager {
+    struct radeon_bo_funcs  *funcs;
+    int                     fd;
+};
+
+struct radeon_bo_int {
+    void                        *ptr;
+    uint32_t                    flags;
+    uint32_t                    handle;
+    uint32_t                    size;
+    /* private members */
+    uint32_t                    alignment;
+    uint32_t                    domains;
+    unsigned                    cref;
+    struct radeon_bo_manager    *bom;
+    uint32_t                    space_accounted;
+    uint32_t                    referenced_in_cs;
+};
+
+/* bo functions */
+struct radeon_bo_funcs {
+    struct radeon_bo *(*bo_open)(struct radeon_bo_manager *bom,
+                                 uint32_t handle,
+                                 uint32_t size,
+                                 uint32_t alignment,
+                                 uint32_t domains,
+                                 uint32_t flags);
+    void (*bo_ref)(struct radeon_bo_int *bo);
+    struct radeon_bo *(*bo_unref)(struct radeon_bo_int *bo);
+    int (*bo_map)(struct radeon_bo_int *bo, int write);
+    int (*bo_unmap)(struct radeon_bo_int *bo);
+    int (*bo_wait)(struct radeon_bo_int *bo);
+    int (*bo_is_static)(struct radeon_bo_int *bo);
+    int (*bo_set_tiling)(struct radeon_bo_int *bo, uint32_t tiling_flags,
+			  uint32_t pitch);
+    int (*bo_get_tiling)(struct radeon_bo_int *bo, uint32_t *tiling_flags,
+			  uint32_t *pitch);
+    int (*bo_is_busy)(struct radeon_bo_int *bo, uint32_t *domain);
+    int (*bo_is_referenced_by_cs)(struct radeon_bo_int *bo, struct radeon_cs *cs);
+};
+
+#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
index ce60a2f..cf12664 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
+++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
@@ -50,6 +50,12 @@
 #include "radeon_bocs_wrapper.h"
 #include "radeon_macros.h"
 
+#ifdef HAVE_LIBDRM_RADEON
+#include "radeon_bo_int.h"
+#else
+#include "radeon_bo_int_drm.h"
+#endif
+
 /* no seriously texmem.c is this screwed up */
 struct bo_legacy_texture_object {
     driTextureObject    base;
@@ -57,7 +63,7 @@
 };
 
 struct bo_legacy {
-    struct radeon_bo    base;
+    struct radeon_bo_int    base;
     int                 map_count;
     uint32_t            pending;
     int                 is_pending;
@@ -187,10 +193,10 @@
     }
 }
 
-static int legacy_is_pending(struct radeon_bo *bo)
+static int legacy_is_pending(struct radeon_bo_int *boi)
 {
-    struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
-    struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
+    struct bo_manager_legacy *boml = (struct bo_manager_legacy *)boi->bom;
+    struct bo_legacy *bo_legacy = (struct bo_legacy*)boi;
 
     if (bo_legacy->is_pending <= 0) {
         bo_legacy->is_pending = 0;
@@ -204,13 +210,13 @@
         if (bo_legacy->pnext) {
             bo_legacy->pnext->pprev = bo_legacy->pprev;
         }
-	assert(bo_legacy->is_pending <= bo->cref);
+	assert(bo_legacy->is_pending <= boi->cref);
         while (bo_legacy->is_pending--) {
-	    bo = radeon_bo_unref(bo);
-	    if (!bo)
+	    boi = (struct radeon_bo_int *)radeon_bo_unref((struct radeon_bo *)boi);
+	    if (!boi)
 	      break;
         }
-	if (bo)
+	if (boi)
 	  bo_legacy->is_pending = 0;
         boml->cpendings--;
         return 0;
@@ -218,7 +224,7 @@
     return 1;
 }
 
-static int legacy_wait_pending(struct radeon_bo *bo)
+static int legacy_wait_pending(struct radeon_bo_int *bo)
 {
     struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
@@ -323,7 +329,7 @@
     return bo_legacy;
 }
 
-static int bo_dma_alloc(struct radeon_bo *bo)
+static int bo_dma_alloc(struct radeon_bo_int *bo)
 {
     struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
@@ -333,7 +339,7 @@
     int r;
 
     /* align size on 4Kb */
-    size = (((4 * 1024) - 1) + bo->size) & ~((4 * 1024) - 1);
+    size = (((4 * 1024) - 1) + bo_legacy->base.size) & ~((4 * 1024) - 1);
     alloc.region = RADEON_MEM_REGION_GART;
     alloc.alignment = bo_legacy->base.alignment;
     alloc.size = size;
@@ -355,7 +361,7 @@
     return 0;
 }
 
-static int bo_dma_free(struct radeon_bo *bo)
+static int bo_dma_free(struct radeon_bo_int *bo)
 {
     struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
@@ -428,7 +434,7 @@
         bo_legacy = boml->bos.next;
         while (bo_legacy) {
             if (bo_legacy->base.handle == handle) {
-                radeon_bo_ref(&(bo_legacy->base));
+                radeon_bo_ref((struct radeon_bo *)&(bo_legacy->base));
                 return (struct radeon_bo*)bo_legacy;
             }
             bo_legacy = bo_legacy->next;
@@ -468,20 +474,20 @@
             return NULL;
         }
     }
-    radeon_bo_ref(&(bo_legacy->base));
+    radeon_bo_ref((struct radeon_bo *)&(bo_legacy->base));
 
     return (struct radeon_bo*)bo_legacy;
 }
 
-static void bo_ref(struct radeon_bo *bo)
+static void bo_ref(struct radeon_bo_int *bo)
 {
 }
 
-static struct radeon_bo *bo_unref(struct radeon_bo *bo)
+static struct radeon_bo *bo_unref(struct radeon_bo_int *boi)
 {
-    struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
+    struct bo_legacy *bo_legacy = (struct bo_legacy*)boi;
 
-    if (bo->cref <= 0) {
+    if (boi->cref <= 0) {
         bo_legacy->prev->next = bo_legacy->next;
         if (bo_legacy->next) {
             bo_legacy->next->prev = bo_legacy->prev;
@@ -491,10 +497,10 @@
         }
         return NULL;
     }
-    return bo;
+    return (struct radeon_bo *)boi;
 }
 
-static int bo_map(struct radeon_bo *bo, int write)
+static int bo_map(struct radeon_bo_int *bo, int write)
 {
     struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
@@ -528,7 +534,7 @@
     return 0;
 }
 
-static int bo_unmap(struct radeon_bo *bo)
+static int bo_unmap(struct radeon_bo_int *bo)
 {
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
 
@@ -542,7 +548,7 @@
     return 0;
 }
 
-static int bo_is_busy(struct radeon_bo *bo, uint32_t *domain)
+static int bo_is_busy(struct radeon_bo_int *bo, uint32_t *domain)
 {
     *domain = 0;
     if (bo->domains & RADEON_GEM_DOMAIN_GTT)
@@ -555,7 +561,7 @@
         return 0;
 }
 
-static int bo_is_static(struct radeon_bo *bo)
+static int bo_is_static(struct radeon_bo_int *bo)
 {
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
     return bo_legacy->static_bo;
@@ -574,7 +580,7 @@
     bo_is_busy
 };
 
-static int bo_vram_validate(struct radeon_bo *bo,
+static int bo_vram_validate(struct radeon_bo_int *bo,
                             uint32_t *soffset,
                             uint32_t *eoffset)
 {
@@ -700,29 +706,30 @@
                               uint32_t *soffset,
                               uint32_t *eoffset)
 {
-    struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
+    struct bo_manager_legacy *boml = (struct bo_manager_legacy *)boi->bom;
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
     int r;
     int retries = 0;
 
     if (bo_legacy->map_count) {
         fprintf(stderr, "bo(%p, %d) is mapped (%d) can't valide it.\n",
-                bo, bo->size, bo_legacy->map_count);
+                bo, boi->size, bo_legacy->map_count);
         return -EINVAL;
     }
-    if(bo->size == 0) {
+    if(boi->size == 0) {
         fprintf(stderr, "bo(%p) has size 0.\n", bo);
         return -EINVAL;
     }
     if (bo_legacy->static_bo || bo_legacy->validated) {
         *soffset = bo_legacy->offset;
-        *eoffset = bo_legacy->offset + bo->size;
+        *eoffset = bo_legacy->offset + boi->size;
 
         return 0;
     }
-    if (!(bo->domains & RADEON_GEM_DOMAIN_GTT)) {
+    if (!(boi->domains & RADEON_GEM_DOMAIN_GTT)) {
 
-        r = bo_vram_validate(bo, soffset, eoffset);
+        r = bo_vram_validate(boi, soffset, eoffset);
         if (r) {
 	    legacy_track_pending(&boml->base, 0);
 	    legacy_kick_all_buffers(boml);
@@ -736,7 +743,7 @@
         }
     }
     *soffset = bo_legacy->offset;
-    *eoffset = bo_legacy->offset + bo->size;
+    *eoffset = bo_legacy->offset + boi->size;
     bo_legacy->validated = 1;
 
     return 0;
@@ -744,7 +751,8 @@
 
 void radeon_bo_legacy_pending(struct radeon_bo *bo, uint32_t pending)
 {
-    struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
+    struct bo_manager_legacy *boml = (struct bo_manager_legacy *)boi->bom;
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
 
     bo_legacy->pending = pending;
@@ -799,7 +807,7 @@
     if (bo->base.handle > bom->nhandle) {
         bom->nhandle = bo->base.handle + 1;
     }
-    radeon_bo_ref(&(bo->base));
+    radeon_bo_ref((struct radeon_bo *)&(bo->base));
     return bo;
 }
 
@@ -894,12 +902,13 @@
 
 unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo)
 {
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
     struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
 
-    if (bo_legacy->static_bo || (bo->domains & RADEON_GEM_DOMAIN_GTT)) {
+    if (bo_legacy->static_bo || (boi->domains & RADEON_GEM_DOMAIN_GTT)) {
         return 0;
     }
-    return bo->size;
+    return boi->size;
 }
 
 /*
@@ -924,7 +933,7 @@
     if (bo->base.handle > boml->nhandle) {
         boml->nhandle = bo->base.handle + 1;
     }
-    radeon_bo_ref(&(bo->base));
-    return &(bo->base);
+    radeon_bo_ref((struct radeon_bo *)&(bo->base));
+    return (struct radeon_bo *)&(bo->base);
 }
 
diff --git a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h
index 4520a7d..6c2648b 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h
+++ b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h
@@ -18,8 +18,11 @@
 #define RADEON_TILING_MACRO 0x1
 #define RADEON_TILING_MICRO 0x2
 #define RADEON_TILING_SWAP 0x4
+
+#ifndef RADEON_TILING_SURFACE
 #define RADEON_TILING_SURFACE 0x8 /* this object requires a surface
 				   * when mapped - i.e. front buffer */
+#endif
 
 /* to be used to build locally in mesa with no libdrm bits */
 #include "../radeon/radeon_bo_drm.h"
diff --git a/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c b/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c
index 8fac5c6..99d3ec7 100644
--- a/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c
+++ b/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c
@@ -136,8 +136,13 @@
                     const GLvoid * data,
                     struct gl_buffer_object *obj)
 {
+    radeonContextPtr radeon = RADEON_CONTEXT(ctx);
     struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);
 
+    if (radeon_bo_is_referenced_by_cs(radeon_obj->bo, radeon->cmdbuf.cs)) {
+        radeon_firevertices(radeon);
+    }
+
     radeon_bo_map(radeon_obj->bo, GL_TRUE);
 
     _mesa_memcpy(radeon_obj->bo->ptr + offset, data, size);
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c
index 097ab7c..e0b853b 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common.c
@@ -137,7 +137,7 @@
 			  unsigned int *num_cliprects,
 			  int *x_off, int *y_off)
 {
-	__DRIdrawablePrivate *dPriv = radeon_get_drawable(radeon);
+	__DRIdrawable *dPriv = radeon_get_drawable(radeon);
 	struct radeon_framebuffer *rfb = dPriv->driverPrivate;
 
 	if (radeon->constant_cliprect) {
@@ -169,8 +169,8 @@
  */
 void radeonSetCliprects(radeonContextPtr radeon)
 {
-	__DRIdrawablePrivate *const drawable = radeon_get_drawable(radeon);
-	__DRIdrawablePrivate *const readable = radeon_get_readable(radeon);
+	__DRIdrawable *const drawable = radeon_get_drawable(radeon);
+	__DRIdrawable *const readable = radeon_get_readable(radeon);
 	struct radeon_framebuffer *const draw_rfb = drawable->driverPrivate;
 	struct radeon_framebuffer *const read_rfb = readable->driverPrivate;
 	int x_off, y_off;
@@ -229,7 +229,7 @@
 	}
 	if (!rmesa->radeonScreen->kernel_mm) {
 	   /* Fix scissors for dri 1 */
-	   __DRIdrawablePrivate *dPriv = radeon_get_drawable(rmesa);
+	   __DRIdrawable *dPriv = radeon_get_drawable(rmesa);
 	   x1 += dPriv->x;
 	   x2 += dPriv->x + 1;
 	   min_x += dPriv->x;
@@ -262,29 +262,6 @@
 	}
 }
 
-void radeonPolygonStipplePreKMS( GLcontext *ctx, const GLubyte *mask )
-{
-   radeonContextPtr radeon = RADEON_CONTEXT(ctx);
-   GLuint i;
-   drm_radeon_stipple_t stipple;
-
-   /* Must flip pattern upside down.
-   */
-   for ( i = 0 ; i < 32 ; i++ ) {
-      stipple.mask[31 - i] = ((GLuint *) mask)[i];
-   }
-
-   /* TODO: push this into cmd mechanism
-   */
-   radeon_firevertices(radeon);
-   LOCK_HARDWARE( radeon );
-
-   drmCommandWrite( radeon->dri.fd, DRM_RADEON_STIPPLE,
-	 &stipple, sizeof(stipple) );
-   UNLOCK_HARDWARE( radeon );
-}
-
-
 /* ================================================================
  * SwapBuffers with client-side throttling
  */
@@ -451,7 +428,7 @@
 
 /* Copy the back color buffer to the front color buffer.
  */
-void radeonCopyBuffer( __DRIdrawablePrivate *dPriv,
+void radeonCopyBuffer( __DRIdrawable *dPriv,
 		       const drm_clip_rect_t	  *rect)
 {
 	radeonContextPtr rmesa;
@@ -519,7 +496,7 @@
 	UNLOCK_HARDWARE( rmesa );
 }
 
-static int radeonScheduleSwap(__DRIdrawablePrivate *dPriv, GLboolean *missed_target)
+static int radeonScheduleSwap(__DRIdrawable *dPriv, GLboolean *missed_target)
 {
 	radeonContextPtr rmesa;
 
@@ -542,11 +519,11 @@
 	return 0;
 }
 
-static GLboolean radeonPageFlip( __DRIdrawablePrivate *dPriv )
+static GLboolean radeonPageFlip( __DRIdrawable *dPriv )
 {
 	radeonContextPtr radeon;
 	GLint ret;
-	__DRIscreenPrivate *psp;
+	__DRIscreen *psp;
 	struct radeon_renderbuffer *rrb;
 	struct radeon_framebuffer *rfb;
 
@@ -594,10 +571,10 @@
 /**
  * Swap front and back buffer.
  */
-void radeonSwapBuffers(__DRIdrawablePrivate * dPriv)
+void radeonSwapBuffers(__DRIdrawable * dPriv)
 {
 	int64_t ust;
-	__DRIscreenPrivate *psp;
+	__DRIscreen *psp;
 
 	if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
 		radeonContextPtr radeon;
@@ -638,7 +615,7 @@
 	}
 }
 
-void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv,
+void radeonCopySubBuffer(__DRIdrawable * dPriv,
 			 int x, int y, int w, int h )
 {
 	if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
@@ -664,6 +641,27 @@
 	}
 }
 
+/**
+ * Check if we're about to draw into the front color buffer.
+ * If so, set the intel->front_buffer_dirty field to true.
+ */
+void
+radeon_check_front_buffer_rendering(GLcontext *ctx)
+{
+	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+	const struct gl_framebuffer *fb = ctx->DrawBuffer;
+
+	if (fb->Name == 0) {
+		/* drawing to window system buffer */
+		if (fb->_NumColorDrawBuffers > 0) {
+			if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
+				radeon->front_buffer_dirty = GL_TRUE;
+			}
+		}
+	}
+}
+
+
 void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
 {
 	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
@@ -840,7 +838,7 @@
        */
 		if (!was_front_buffer_rendering && radeon->is_front_buffer_rendering) {
 			radeon_update_renderbuffers(radeon->dri.context,
-				radeon->dri.context->driDrawablePriv);
+				radeon->dri.context->driDrawablePriv, GL_FALSE);
       }
 	}
 
@@ -857,7 +855,7 @@
 
 		if (!was_front_buffer_reading && rmesa->is_front_buffer_reading) {
 			radeon_update_renderbuffers(rmesa->dri.context,
-						    rmesa->dri.context->driReadablePriv);
+						    rmesa->dri.context->driReadablePriv, GL_FALSE);
 	 	}
 	}
 	/* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
@@ -908,9 +906,9 @@
 		if (radeon->is_front_buffer_rendering) {
 			ctx->Driver.Flush(ctx);
 		}
-		radeon_update_renderbuffers(driContext, driContext->driDrawablePriv);
+		radeon_update_renderbuffers(driContext, driContext->driDrawablePriv, GL_FALSE);
 		if (driContext->driDrawablePriv != driContext->driReadablePriv)
-			radeon_update_renderbuffers(driContext, driContext->driReadablePriv);
+			radeon_update_renderbuffers(driContext, driContext->driReadablePriv, GL_FALSE);
 	}
 
 	old_viewport = ctx->Driver.Viewport;
@@ -1118,22 +1116,21 @@
 	   then no point flushing anything at all.
 	*/
 	if (!radeon->dma.flush && !radeon->cmdbuf.cs->cdw && is_empty_list(&radeon->dma.reserved))
-		return;
+		goto flush_front;
 
 	if (radeon->dma.flush)
 		radeon->dma.flush( ctx );
 
-	radeonEmitState(radeon);
-
 	if (radeon->cmdbuf.cs->cdw)
 		rcommonFlushCmdBuf(radeon, __FUNCTION__);
 
+flush_front:
 	if ((ctx->DrawBuffer->Name == 0) && radeon->front_buffer_dirty) {
 		__DRIscreen *const screen = radeon->radeonScreen->driScreen;
 
 		if (screen->dri2.loader && (screen->dri2.loader->base.version >= 2)
 			&& (screen->dri2.loader->flushFrontBuffer != NULL)) {
-			__DRIdrawablePrivate * drawable = radeon_get_drawable(radeon);
+			__DRIdrawable * drawable = radeon_get_drawable(radeon);
 			(*screen->dri2.loader->flushFrontBuffer)(drawable, drawable->loaderPrivate);
 
 			/* Only clear the dirty bit if front-buffer rendering is no longer
@@ -1147,9 +1144,6 @@
 			}
 		}
 	}
-
-	make_empty_list(&radeon->query.not_flushed_head);
-
 }
 
 /* Make sure all commands have been sent to the hardware and have
@@ -1236,7 +1230,7 @@
 		fprintf(stderr, "drmRadeonCmdBuffer: %d. Kernel failed to "
 				"parse or rejected command stream. See dmesg "
 				"for more info.\n", ret);
-		_mesa_exit(ret);
+		exit(ret);
 	}
 
 	return ret;
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h
index def0cc1..f31f08e 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common.h
@@ -10,14 +10,13 @@
 void radeonSetCliprects(radeonContextPtr radeon);
 void radeonUpdateScissor( GLcontext *ctx );
 void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h);
-void radeonPolygonStipplePreKMS( GLcontext *ctx, const GLubyte *mask );
 
 void radeonWaitForIdleLocked(radeonContextPtr radeon);
 extern uint32_t radeonGetAge(radeonContextPtr radeon);
-void radeonCopyBuffer( __DRIdrawablePrivate *dPriv,
+void radeonCopyBuffer( __DRIdrawable *dPriv,
 		       const drm_clip_rect_t	  *rect);
-void radeonSwapBuffers(__DRIdrawablePrivate * dPriv);
-void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv,
+void radeonSwapBuffers(__DRIdrawable * dPriv);
+void radeonCopySubBuffer(__DRIdrawable * dPriv,
 			 int x, int y, int w, int h );
 
 void radeonUpdatePageFlipping(radeonContextPtr rmesa);
@@ -43,7 +42,9 @@
 radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb,
 			   struct radeon_bo *bo);
 struct radeon_renderbuffer *
-radeon_create_renderbuffer(gl_format format, __DRIdrawablePrivate *driDrawPriv);
+radeon_create_renderbuffer(gl_format format, __DRIdrawable *driDrawPriv);
+
+void radeon_check_front_buffer_rendering(GLcontext *ctx);
 static inline struct radeon_renderbuffer *radeon_renderbuffer(struct gl_renderbuffer *rb)
 {
 	struct radeon_renderbuffer *rrb = (struct radeon_renderbuffer *)rb;
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c
index fe99644..b9c29b9 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c
@@ -181,10 +181,10 @@
 GLboolean radeonInitContext(radeonContextPtr radeon,
 			    struct dd_function_table* functions,
 			    const __GLcontextModes * glVisual,
-			    __DRIcontextPrivate * driContextPriv,
+			    __DRIcontext * driContextPriv,
 			    void *sharedContextPrivate)
 {
-	__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+	__DRIscreen *sPriv = driContextPriv->driScreenPriv;
 	radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
 	GLcontext* ctx;
 	GLcontext* shareCtx;
@@ -262,10 +262,9 @@
 		else
 			radeon->texture_row_align = 32;
 		radeon->texture_rect_row_align = 64;
-		radeon->texture_compressed_row_align = 64;
+		radeon->texture_compressed_row_align = 32;
 	}
 
-	make_empty_list(&radeon->query.not_flushed_head);
 	radeon_init_dma(radeon);
 
 	return GL_TRUE;
@@ -292,7 +291,7 @@
  * Cleanup common context fields.
  * Called by r200DestroyContext/r300DestroyContext
  */
-void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
+void radeonDestroyContext(__DRIcontext *driContextPriv )
 {
 #ifdef RADEON_BO_TRACK
 	FILE *track;
@@ -356,7 +355,7 @@
 
 /* Force the context `c' to be unbound from its buffer.
  */
-GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv)
+GLboolean radeonUnbindContext(__DRIcontext * driContextPriv)
 {
 	radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
 
@@ -500,7 +499,8 @@
 }
 
 void
-radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
+radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable,
+			    GLboolean front_only)
 {
 	unsigned int attachments[10];
 	__DRIbuffer *buffers = NULL;
@@ -526,7 +526,7 @@
 		struct radeon_renderbuffer *stencil_rb;
 
 		i = 0;
-		if ((radeon->is_front_buffer_rendering ||
+		if ((front_only || radeon->is_front_buffer_rendering ||
 		     radeon->is_front_buffer_reading ||
 		     !draw->color_rb[1])
 		    && draw->color_rb[0]) {
@@ -534,23 +534,25 @@
 			attachments[i++] = radeon_bits_per_pixel(draw->color_rb[0]);
 		}
 
-		if (draw->color_rb[1]) {
-			attachments[i++] = __DRI_BUFFER_BACK_LEFT;
-			attachments[i++] = radeon_bits_per_pixel(draw->color_rb[1]);
-		}
+		if (!front_only) {
+			if (draw->color_rb[1]) {
+				attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+				attachments[i++] = radeon_bits_per_pixel(draw->color_rb[1]);
+			}
 
-		depth_rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
-		stencil_rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
+			depth_rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
+			stencil_rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
 
-		if ((depth_rb != NULL) && (stencil_rb != NULL)) {
-			attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
-			attachments[i++] = radeon_bits_per_pixel(depth_rb);
-		} else if (depth_rb != NULL) {
-			attachments[i++] = __DRI_BUFFER_DEPTH;
-			attachments[i++] = radeon_bits_per_pixel(depth_rb);
-		} else if (stencil_rb != NULL) {
-			attachments[i++] = __DRI_BUFFER_STENCIL;
-			attachments[i++] = radeon_bits_per_pixel(stencil_rb);
+			if ((depth_rb != NULL) && (stencil_rb != NULL)) {
+				attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
+				attachments[i++] = radeon_bits_per_pixel(depth_rb);
+			} else if (depth_rb != NULL) {
+				attachments[i++] = __DRI_BUFFER_DEPTH;
+				attachments[i++] = radeon_bits_per_pixel(depth_rb);
+			} else if (stencil_rb != NULL) {
+				attachments[i++] = __DRI_BUFFER_STENCIL;
+				attachments[i++] = radeon_bits_per_pixel(stencil_rb);
+			}
 		}
 
 		buffers = (*screen->dri2.loader->getBuffersWithFormat)(drawable,
@@ -563,12 +565,14 @@
 		i = 0;
 		if (draw->color_rb[0])
 			attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
-		if (draw->color_rb[1])
-			attachments[i++] = __DRI_BUFFER_BACK_LEFT;
-		if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH))
-			attachments[i++] = __DRI_BUFFER_DEPTH;
-		if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL))
-			attachments[i++] = __DRI_BUFFER_STENCIL;
+		if (!front_only) {
+			if (draw->color_rb[1])
+				attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+			if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH))
+				attachments[i++] = __DRI_BUFFER_DEPTH;
+			if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL))
+				attachments[i++] = __DRI_BUFFER_STENCIL;
+		}
 
 		buffers = (*screen->dri2.loader->getBuffers)(drawable,
 								 &drawable->w,
@@ -716,9 +720,9 @@
 /* Force the context `c' to be the current context and associate with it
  * buffer `b'.
  */
-GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
-			    __DRIdrawablePrivate * driDrawPriv,
-			    __DRIdrawablePrivate * driReadPriv)
+GLboolean radeonMakeCurrent(__DRIcontext * driContextPriv,
+			    __DRIdrawable * driDrawPriv,
+			    __DRIdrawable * driReadPriv)
 {
 	radeonContextPtr radeon;
 	struct radeon_framebuffer *drfb;
@@ -736,9 +740,9 @@
 	readfb = driReadPriv->driverPrivate;
 
 	if (driContextPriv->driScreenPriv->dri2.enabled) {
-		radeon_update_renderbuffers(driContextPriv, driDrawPriv);
+		radeon_update_renderbuffers(driContextPriv, driDrawPriv, GL_FALSE);
 		if (driDrawPriv != driReadPriv)
-			radeon_update_renderbuffers(driContextPriv, driReadPriv);
+			radeon_update_renderbuffers(driContextPriv, driReadPriv, GL_FALSE);
 		_mesa_reference_renderbuffer(&radeon->state.color.rb,
 			&(radeon_get_renderbuffer(&drfb->base, BUFFER_BACK_LEFT)->base));
 		_mesa_reference_renderbuffer(&radeon->state.depth.rb,
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h
index 0309345..ab79d2d 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h
@@ -92,7 +92,7 @@
 
 	GLuint pf_pending;  /**< sequence number of pending flip */
 	GLuint vbl_pending;   /**< vblank sequence number of pending flip */
-	__DRIdrawablePrivate *dPriv;
+	__DRIdrawable *dPriv;
 };
 
 struct radeon_framebuffer
@@ -208,6 +208,10 @@
 	 * and so on.
 	 */
 	GLboolean validated;
+	/* Minimum LOD to be used during rendering */
+	unsigned minLod;
+	/* Miximum LOD to be used during rendering */
+	unsigned maxLod;
 
 	GLuint override_offset;
 	GLboolean image_override; /* Image overridden by GLX_EXT_tfp */
@@ -324,6 +328,7 @@
 	GLuint vertex_attr_count;
 
 	GLuint emit_prediction;
+        struct radeon_bo *bo;
 };
 
 #define RADEON_MAX_AOS_ARRAYS		16
@@ -376,8 +381,8 @@
 };
 
 struct radeon_dri_mirror {
-	__DRIcontextPrivate *context;	/* DRI context */
-	__DRIscreenPrivate *screen;	/* DRI screen */
+	__DRIcontext *context;	/* DRI context */
+	__DRIscreen *screen;	/* DRI screen */
 
 	drm_context_t hwContext;
 	drm_hw_lock_t *hwLock;
@@ -401,9 +406,6 @@
 	struct radeon_depthbuffer_state depth;
 	struct radeon_scissor_state scissor;
 	struct radeon_stencilbuffer_state stencil;
-
-	struct radeon_cs_space_check bos[RADEON_MAX_BOS];
-	int validated_bo_count;
 };
 
 /**
@@ -502,7 +504,6 @@
 
    struct {
 	struct radeon_query_object *current;
-	struct radeon_query_object not_flushed_head;
 	struct radeon_state_atom queryobj;
    } query;
 
@@ -522,12 +523,12 @@
 
 #define RADEON_CONTEXT(glctx) ((radeonContextPtr)(ctx->DriverCtx))
 
-static inline __DRIdrawablePrivate* radeon_get_drawable(radeonContextPtr radeon)
+static inline __DRIdrawable* radeon_get_drawable(radeonContextPtr radeon)
 {
 	return radeon->dri.context->driDrawablePriv;
 }
 
-static inline __DRIdrawablePrivate* radeon_get_readable(radeonContextPtr radeon)
+static inline __DRIdrawable* radeon_get_readable(radeonContextPtr radeon)
 {
 	return radeon->dri.context->driReadablePriv;
 }
@@ -580,15 +581,16 @@
 GLboolean radeonInitContext(radeonContextPtr radeon,
 			    struct dd_function_table* functions,
 			    const __GLcontextModes * glVisual,
-			    __DRIcontextPrivate * driContextPriv,
+			    __DRIcontext * driContextPriv,
 			    void *sharedContextPrivate);
 
 void radeonCleanupContext(radeonContextPtr radeon);
-GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv);
-void radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable);
-GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
-			    __DRIdrawablePrivate * driDrawPriv,
-			    __DRIdrawablePrivate * driReadPriv);
-extern void radeonDestroyContext(__DRIcontextPrivate * driContextPriv);
+GLboolean radeonUnbindContext(__DRIcontext * driContextPriv);
+void radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable,
+				 GLboolean front_only);
+GLboolean radeonMakeCurrent(__DRIcontext * driContextPriv,
+			    __DRIdrawable * driDrawPriv,
+			    __DRIdrawable * driReadPriv);
+extern void radeonDestroyContext(__DRIcontext * driContextPriv);
 
 #endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c
index 5e700be..3cd305b 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_context.c
@@ -208,10 +208,10 @@
  */
 GLboolean
 r100CreateContext( const __GLcontextModes *glVisual,
-                     __DRIcontextPrivate *driContextPriv,
+                     __DRIcontext *driContextPriv,
                      void *sharedContextPrivate)
 {
-   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
    radeonScreenPtr screen = (radeonScreenPtr)(sPriv->private);
    struct dd_function_table functions;
    r100ContextPtr rmesa;
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h
index 4e2c52c..dfedc38 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_context.h
@@ -331,8 +331,12 @@
 	struct radeon_state_atom stp;
 };
 
+struct radeon_stipple_state {
+	GLuint mask[32];
+};
 
 struct r100_state {
+	struct radeon_stipple_state stipple;
 	struct radeon_texture_state texture;
 };
 
@@ -447,7 +451,7 @@
 #define RADEON_OLD_PACKETS 1
 
 extern GLboolean r100CreateContext( const __GLcontextModes *glVisual,
-				    __DRIcontextPrivate *driContextPriv,
+				    __DRIcontext *driContextPriv,
 				    void *sharedContextPrivate);
   
 
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs.c b/src/mesa/drivers/dri/radeon/radeon_cs.c
new file mode 100644
index 0000000..17e7433
--- /dev/null
+++ b/src/mesa/drivers/dri/radeon/radeon_cs.c
@@ -0,0 +1,95 @@
+
+#include <stdio.h>
+#include <stdint.h>
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon_bocs_wrapper.h"
+#include "radeon_cs_int_drm.h"
+
+struct radeon_cs *radeon_cs_create(struct radeon_cs_manager *csm,
+			    uint32_t ndw)
+{
+    struct radeon_cs_int *csi = csm->funcs->cs_create(csm, ndw);
+    return (struct radeon_cs *)csi;
+}
+
+int radeon_cs_write_reloc(struct radeon_cs *cs,
+			  struct radeon_bo *bo,
+			  uint32_t read_domain,
+			  uint32_t write_domain,
+			  uint32_t flags)
+{
+    struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
+
+    return csi->csm->funcs->cs_write_reloc(csi,
+					   bo,
+					   read_domain,
+					   write_domain,
+					   flags);
+}
+
+int radeon_cs_begin(struct radeon_cs *cs,
+		    uint32_t ndw,
+		    const char *file,
+		    const char *func,
+		    int line)
+{
+    struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
+    return csi->csm->funcs->cs_begin(csi, ndw, file, func, line);
+}
+
+int radeon_cs_end(struct radeon_cs *cs,
+		  const char *file,
+		  const char *func,
+		  int line)
+{
+    struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
+    return csi->csm->funcs->cs_end(csi, file, func, line);
+}
+
+int radeon_cs_emit(struct radeon_cs *cs)
+{
+    struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
+    return csi->csm->funcs->cs_emit(csi);
+}
+
+int radeon_cs_destroy(struct radeon_cs *cs)
+{
+    struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
+    return csi->csm->funcs->cs_destroy(csi);
+}
+
+int radeon_cs_erase(struct radeon_cs *cs)
+{
+    struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
+    return csi->csm->funcs->cs_erase(csi);
+}
+
+int radeon_cs_need_flush(struct radeon_cs *cs)
+{
+    struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
+    return csi->csm->funcs->cs_need_flush(csi);
+}
+
+void radeon_cs_print(struct radeon_cs *cs, FILE *file)
+{
+    struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
+    csi->csm->funcs->cs_print(csi, file);
+}
+
+void radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit)
+{
+    struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
+    if (domain == RADEON_GEM_DOMAIN_VRAM)
+	csi->csm->vram_limit = limit;
+    else
+	csi->csm->gart_limit = limit;
+}
+
+void radeon_cs_space_set_flush(struct radeon_cs *cs, void (*fn)(void *), void *data)
+{
+    struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
+    csi->space_flush_fn = fn;
+    csi->space_flush_data = data;
+}
+
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_drm.h b/src/mesa/drivers/dri/radeon/radeon_cs_drm.h
index ab4eca3..a3f1750 100644
--- a/src/mesa/drivers/dri/radeon/radeon_cs_drm.h
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_drm.h
@@ -36,6 +36,7 @@
 #include <string.h>
 #include "drm.h"
 #include "radeon_drm.h"
+#include "radeon_bo_drm.h"
 
 struct radeon_cs_reloc {
     struct radeon_bo    *bo;
@@ -49,173 +50,41 @@
 #define RADEON_CS_SPACE_OP_TO_BIG 1
 #define RADEON_CS_SPACE_FLUSH 2
 
-struct radeon_cs_space_check {
-    struct radeon_bo *bo;
-    uint32_t read_domains;
-    uint32_t write_domain;
-    uint32_t new_accounted;
+struct radeon_cs {
+    uint32_t *packets;
+    unsigned cdw;
+    unsigned ndw;
+    unsigned                    section_ndw;
+    unsigned                    section_cdw;
 };
 
 #define MAX_SPACE_BOS (32)
 
 struct radeon_cs_manager;
 
-struct radeon_cs {
-    struct radeon_cs_manager    *csm;
-    void                        *relocs;
-    uint32_t                    *packets;
-    unsigned                    crelocs;
-    unsigned                    relocs_total_size;
-    unsigned                    cdw;
-    unsigned                    ndw;
-    int                         section;
-    unsigned                    section_ndw;
-    unsigned                    section_cdw;
-    const char                  *section_file;
-    const char                  *section_func;
-    int                         section_line;
-    struct radeon_cs_space_check bos[MAX_SPACE_BOS];
-    int                         bo_count;
-    void                        (*space_flush_fn)(void *);
-    void                        *space_flush_data;
-};
+extern struct radeon_cs *radeon_cs_create(struct radeon_cs_manager *csm,
+					  uint32_t ndw);
 
-/* cs functions */
-struct radeon_cs_funcs {
-    struct radeon_cs *(*cs_create)(struct radeon_cs_manager *csm,
-                                   uint32_t ndw);
-    int (*cs_write_reloc)(struct radeon_cs *cs,
-                          struct radeon_bo *bo,
-                          uint32_t read_domain,
-                          uint32_t write_domain,
-                          uint32_t flags);
-    int (*cs_begin)(struct radeon_cs *cs,
-                    uint32_t ndw,
-                    const char *file,
-                    const char *func,
-                    int line);
-    int (*cs_end)(struct radeon_cs *cs,
-                  const char *file,
-                  const char *func,
-                  int line);
-    int (*cs_emit)(struct radeon_cs *cs);
-    int (*cs_destroy)(struct radeon_cs *cs);
-    int (*cs_erase)(struct radeon_cs *cs);
-    int (*cs_need_flush)(struct radeon_cs *cs);
-    void (*cs_print)(struct radeon_cs *cs, FILE *file);
-};
-
-struct radeon_cs_manager {
-    struct radeon_cs_funcs  *funcs;
-    int                     fd;
-    int32_t vram_limit, gart_limit;
-    int32_t vram_write_used, gart_write_used;
-    int32_t read_used;
-};
-
-static inline struct radeon_cs *radeon_cs_create(struct radeon_cs_manager *csm,
-                                                 uint32_t ndw)
-{
-    return csm->funcs->cs_create(csm, ndw);
-}
-
-static inline int radeon_cs_write_reloc(struct radeon_cs *cs,
-                                        struct radeon_bo *bo,
-                                        uint32_t read_domain,
-                                        uint32_t write_domain,
-                                        uint32_t flags)
-{
-    return cs->csm->funcs->cs_write_reloc(cs,
-                                          bo,
-                                          read_domain,
-                                          write_domain,
-                                          flags);
-}
-
-static inline int radeon_cs_begin(struct radeon_cs *cs,
-                                  uint32_t ndw,
-                                  const char *file,
-                                  const char *func,
-                                  int line)
-{
-    return cs->csm->funcs->cs_begin(cs, ndw, file, func, line);
-}
-
-static inline int radeon_cs_end(struct radeon_cs *cs,
-                                const char *file,
-                                const char *func,
-                                int line)
-{
-    return cs->csm->funcs->cs_end(cs, file, func, line);
-}
-
-static inline int radeon_cs_emit(struct radeon_cs *cs)
-{
-    return cs->csm->funcs->cs_emit(cs);
-}
-
-static inline int radeon_cs_destroy(struct radeon_cs *cs)
-{
-    return cs->csm->funcs->cs_destroy(cs);
-}
-
-static inline int radeon_cs_erase(struct radeon_cs *cs)
-{
-    return cs->csm->funcs->cs_erase(cs);
-}
-
-static inline int radeon_cs_need_flush(struct radeon_cs *cs)
-{
-    return cs->csm->funcs->cs_need_flush(cs);
-}
-
-static inline void radeon_cs_print(struct radeon_cs *cs, FILE *file)
-{
-    cs->csm->funcs->cs_print(cs, file);
-}
-
-static inline void radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit)
-{
-    
-    if (domain == RADEON_GEM_DOMAIN_VRAM)
-	cs->csm->vram_limit = limit;
-    else
-	cs->csm->gart_limit = limit;
-}
-
-static inline void radeon_cs_write_dword(struct radeon_cs *cs, uint32_t dword)
-{
-    cs->packets[cs->cdw++] = dword;
-    if (cs->section) {
-        cs->section_cdw++;
-    }
-}
-
-static inline void radeon_cs_write_qword(struct radeon_cs *cs, uint64_t qword)
-{
-
-    memcpy(cs->packets + cs->cdw, &qword, sizeof(qword));
-    cs->cdw+=2;
-    if (cs->section) {
-        cs->section_cdw+=2;
-    }
-}
-
-static inline void radeon_cs_write_table(struct radeon_cs *cs, void *data, uint32_t size)
-{
-    memcpy(cs->packets + cs->cdw, data, size * 4);
-    cs->cdw += size;
-    if (cs->section) {
-	    cs->section_cdw += size;
-    }
-}
-
-static inline void radeon_cs_space_set_flush(struct radeon_cs *cs, void (*fn)(void *), void *data)
-{
-    cs->space_flush_fn = fn;
-    cs->space_flush_data = data;
-}
-
+extern int radeon_cs_begin(struct radeon_cs *cs,
+			   uint32_t ndw,
+			   const char *file,
+			   const char *func, int line);
+extern int radeon_cs_end(struct radeon_cs *cs,
+			 const char *file,
+			 const char *func,
+			 int line);
+extern int radeon_cs_emit(struct radeon_cs *cs);
+extern int radeon_cs_destroy(struct radeon_cs *cs);
+extern int radeon_cs_erase(struct radeon_cs *cs);
+extern int radeon_cs_need_flush(struct radeon_cs *cs);
+extern void radeon_cs_print(struct radeon_cs *cs, FILE *file);
+extern void radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit);
+extern void radeon_cs_space_set_flush(struct radeon_cs *cs, void (*fn)(void *), void *data);
+extern int radeon_cs_write_reloc(struct radeon_cs *cs,
+				 struct radeon_bo *bo,
+				 uint32_t read_domain,
+				 uint32_t write_domain,
+				 uint32_t flags);
 
 /*
  * add a persistent BO to the list
@@ -243,4 +112,30 @@
 				  uint32_t read_domains,
 				  uint32_t write_domain);
 
+static inline void radeon_cs_write_dword(struct radeon_cs *cs, uint32_t dword)
+{
+    cs->packets[cs->cdw++] = dword;
+    if (cs->section_ndw) {
+        cs->section_cdw++;
+    }
+}
+
+static inline void radeon_cs_write_qword(struct radeon_cs *cs, uint64_t qword)
+{
+    memcpy(cs->packets + cs->cdw, &qword, sizeof(uint64_t));
+    cs->cdw += 2;
+    if (cs->section_ndw) {
+        cs->section_cdw += 2;
+    }
+}
+
+static inline void radeon_cs_write_table(struct radeon_cs *cs,
+					 void *data, uint32_t size)
+{
+    memcpy(cs->packets + cs->cdw, data, size * 4);
+    cs->cdw += size;
+    if (cs->section_ndw) {
+	cs->section_cdw += size;
+    }
+}
 #endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_int_drm.h b/src/mesa/drivers/dri/radeon/radeon_cs_int_drm.h
new file mode 100644
index 0000000..8ba76bf
--- /dev/null
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_int_drm.h
@@ -0,0 +1,66 @@
+
+#ifndef _RADEON_CS_INT_H_
+#define _RADEON_CS_INT_H_
+
+struct radeon_cs_space_check {
+    struct radeon_bo_int *bo;
+    uint32_t read_domains;
+    uint32_t write_domain;
+    uint32_t new_accounted;
+};
+
+struct radeon_cs_int {
+    /* keep first two in same place */
+    uint32_t                    *packets;    
+    unsigned                    cdw;
+    unsigned                    ndw;
+    unsigned                    section_ndw;
+    unsigned                    section_cdw;
+    /* private members */
+    struct radeon_cs_manager    *csm;
+    void                        *relocs;
+    unsigned                    crelocs;
+    unsigned                    relocs_total_size;
+    const char                  *section_file;
+    const char                  *section_func;
+    int                         section_line;
+    struct radeon_cs_space_check bos[MAX_SPACE_BOS];
+    int                         bo_count;
+    void                        (*space_flush_fn)(void *);
+    void                        *space_flush_data;
+};
+
+/* cs functions */
+struct radeon_cs_funcs {
+    struct radeon_cs_int *(*cs_create)(struct radeon_cs_manager *csm,
+                                   uint32_t ndw);
+    int (*cs_write_reloc)(struct radeon_cs_int *cs,
+                          struct radeon_bo *bo,
+                          uint32_t read_domain,
+                          uint32_t write_domain,
+                          uint32_t flags);
+    int (*cs_begin)(struct radeon_cs_int *cs,
+                    uint32_t ndw,
+		    const char *file,
+		    const char *func,
+		    int line);
+    int (*cs_end)(struct radeon_cs_int *cs,
+		  const char *file, const char *func,
+		  int line);
+
+
+    int (*cs_emit)(struct radeon_cs_int *cs);
+    int (*cs_destroy)(struct radeon_cs_int *cs);
+    int (*cs_erase)(struct radeon_cs_int *cs);
+    int (*cs_need_flush)(struct radeon_cs_int *cs);
+    void (*cs_print)(struct radeon_cs_int *cs, FILE *file);
+};
+
+struct radeon_cs_manager {
+    struct radeon_cs_funcs  *funcs;
+    int                     fd;
+    int32_t vram_limit, gart_limit;
+    int32_t vram_write_used, gart_write_used;
+    int32_t read_used;
+};
+#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
index f1addb2..bf46eb8 100644
--- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
@@ -30,10 +30,18 @@
  *      Jérôme Glisse <glisse@freedesktop.org>
  */
 #include <errno.h>
+#include <unistd.h>
+#include <stdint.h>
+#include "drm.h"
+#include "radeon_drm.h"
 
 #include "radeon_bocs_wrapper.h"
 #include "radeon_common.h"
-
+#ifdef HAVE_LIBDRM_RADEON
+#include "radeon_cs_int.h"
+#else
+#include "radeon_cs_int_drm.h"
+#endif
 struct cs_manager_legacy {
     struct radeon_cs_manager    base;
     struct radeon_context       *ctx;
@@ -51,27 +59,27 @@
 };
 
 
-static struct radeon_cs *cs_create(struct radeon_cs_manager *csm,
-                                   uint32_t ndw)
+static struct radeon_cs_int *cs_create(struct radeon_cs_manager *csm,
+				       uint32_t ndw)
 {
-    struct radeon_cs *cs;
+    struct radeon_cs_int *csi;
 
-    cs = (struct radeon_cs*)calloc(1, sizeof(struct radeon_cs));
-    if (cs == NULL) {
+    csi = (struct radeon_cs_int*)calloc(1, sizeof(struct radeon_cs_int));
+    if (csi == NULL) {
         return NULL;
     }
-    cs->csm = csm;
-    cs->ndw = (ndw + 0x3FF) & (~0x3FF);
-    cs->packets = (uint32_t*)malloc(4*cs->ndw);
-    if (cs->packets == NULL) {
-        free(cs);
+    csi->csm = csm;
+    csi->ndw = (ndw + 0x3FF) & (~0x3FF);
+    csi->packets = (uint32_t*)malloc(4*csi->ndw);
+    if (csi->packets == NULL) {
+        free(csi);
         return NULL;
     }
-    cs->relocs_total_size = 0;
-    return cs;
+    csi->relocs_total_size = 0;
+    return csi;
 }
 
-static int cs_write_reloc(struct radeon_cs *cs,
+static int cs_write_reloc(struct radeon_cs_int *cs,
                           struct radeon_bo *bo,
                           uint32_t read_domain,
                           uint32_t write_domain,
@@ -150,20 +158,19 @@
     return 0;
 }
 
-static int cs_begin(struct radeon_cs *cs,
+static int cs_begin(struct radeon_cs_int *cs,
                     uint32_t ndw,
                     const char *file,
                     const char *func,
                     int line)
 {
-    if (cs->section) {
+    if (cs->section_ndw) {
         fprintf(stderr, "CS already in a section(%s,%s,%d)\n",
                 cs->section_file, cs->section_func, cs->section_line);
         fprintf(stderr, "CS can't start section(%s,%s,%d)\n",
                 file, func, line);
         return -EPIPE;
     }
-    cs->section = 1;
     cs->section_ndw = ndw;
     cs->section_cdw = 0;
     cs->section_file = file;
@@ -175,7 +182,7 @@
         uint32_t tmp, *ptr;
 	int num = (ndw > 0x3FF) ? ndw : 0x3FF;
 
-        tmp = (cs->cdw + 1 + num) & (~num);
+        tmp = (cs->cdw + ndw + 0x3ff) & (~0x3ff);
         ptr = (uint32_t*)realloc(cs->packets, 4 * tmp);
         if (ptr == NULL) {
             return -ENOMEM;
@@ -187,18 +194,17 @@
     return 0;
 }
 
-static int cs_end(struct radeon_cs *cs,
+static int cs_end(struct radeon_cs_int *cs,
                   const char *file,
                   const char *func,
                   int line)
 
 {
-    if (!cs->section) {
+    if (!cs->section_ndw) {
         fprintf(stderr, "CS no section to end at (%s,%s,%d)\n",
                 file, func, line);
         return -EPIPE;
     }
-    cs->section = 0;
     if (cs->section_ndw != cs->section_cdw) {
         fprintf(stderr, "CS section size missmatch start at (%s,%s,%d) %d vs %d\n",
                 cs->section_file, cs->section_func, cs->section_line, cs->section_ndw, cs->section_cdw);
@@ -206,10 +212,12 @@
                 file, func, line);
         return -EPIPE;
     }
+    cs->section_ndw = 0;
+
     return 0;
 }
 
-static int cs_process_relocs(struct radeon_cs *cs)
+static int cs_process_relocs(struct radeon_cs_int *cs)
 {
     struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm;
     struct cs_reloc_legacy *relocs;
@@ -254,7 +262,7 @@
     return 0;
 }
 
-static int cs_set_age(struct radeon_cs *cs)
+static int cs_set_age(struct radeon_cs_int *cs)
 {
     struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm;
     struct cs_reloc_legacy *relocs;
@@ -268,7 +276,7 @@
     return 0;
 }
 
-static int cs_emit(struct radeon_cs *cs)
+static int cs_emit(struct radeon_cs_int *cs)
 {
     struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm;
     drm_radeon_cmd_buffer_t cmd;
@@ -276,7 +284,7 @@
     uint64_t ull;
     int r;
 
-    csm->ctx->vtbl.emit_cs_header(cs, csm->ctx);
+    csm->ctx->vtbl.emit_cs_header((struct radeon_cs *)cs, csm->ctx);
 
     /* append buffer age */
     if ( IS_R300_CLASS(csm->ctx->radeonScreen) )
@@ -289,9 +297,9 @@
       age.scratch.reg = 2;
       age.scratch.n_bufs = 1;
       age.scratch.flags = 0;
-      radeon_cs_write_dword(cs, age.u);
-      radeon_cs_write_qword(cs, ull);
-      radeon_cs_write_dword(cs, 0);
+      radeon_cs_write_dword((struct radeon_cs *)cs, age.u);
+      radeon_cs_write_qword((struct radeon_cs *)cs, ull);
+      radeon_cs_write_dword((struct radeon_cs *)cs, 0);
     }
 
     r = cs_process_relocs(cs);
@@ -342,7 +350,7 @@
       free(relocs[i].indices);
 }
 
-static int cs_destroy(struct radeon_cs *cs)
+static int cs_destroy(struct radeon_cs_int *cs)
 {
     cs_free_reloc(cs->relocs, cs->crelocs);
     free(cs->relocs);
@@ -351,7 +359,7 @@
     return 0;
 }
 
-static int cs_erase(struct radeon_cs *cs)
+static int cs_erase(struct radeon_cs_int *cs)
 {
     cs_free_reloc(cs->relocs, cs->crelocs);
     free(cs->relocs);
@@ -359,18 +367,18 @@
     cs->relocs = NULL;
     cs->crelocs = 0;
     cs->cdw = 0;
-    cs->section = 0;
+    cs->section_ndw = 0;
     return 0;
 }
 
-static int cs_need_flush(struct radeon_cs *cs)
+static int cs_need_flush(struct radeon_cs_int *cs)
 {
     /* this function used to flush when the BO usage got to
      * a certain size, now the higher levels handle this better */
     return 0;
 }
 
-static void cs_print(struct radeon_cs *cs, FILE *file)
+static void cs_print(struct radeon_cs_int *cs, FILE *file)
 {
 }
 
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c b/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c
index 89cbbb5..e22b437 100644
--- a/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c
@@ -29,6 +29,8 @@
 #include <errno.h>
 #include <stdlib.h>
 #include "radeon_bocs_wrapper.h"
+#include "radeon_bo_int_drm.h"
+#include "radeon_cs_int_drm.h"
 
 struct rad_sizes {
     int32_t op_read;
@@ -39,7 +41,7 @@
 static inline int radeon_cs_setup_bo(struct radeon_cs_space_check *sc, struct rad_sizes *sizes)
 {
     uint32_t read_domains, write_domain;
-    struct radeon_bo *bo;
+    struct radeon_bo_int *bo;
 
     bo = sc->bo;
     sc->new_accounted = 0;
@@ -47,7 +49,7 @@
     write_domain = sc->write_domain;
 
     /* legacy needs a static check */
-    if (radeon_bo_is_static(bo)) {
+    if (radeon_bo_is_static((struct radeon_bo *)sc->bo)) {
 	bo->space_accounted = sc->new_accounted = (read_domains << 16) | write_domain;
 	return 0;
     }
@@ -100,11 +102,11 @@
     return 0;
 }
 
-static int radeon_cs_do_space_check(struct radeon_cs *cs, struct radeon_cs_space_check *new_tmp)
+static int radeon_cs_do_space_check(struct radeon_cs_int *cs, struct radeon_cs_space_check *new_tmp)
 {
     struct radeon_cs_manager *csm = cs->csm;
     int i;
-    struct radeon_bo *bo;
+    struct radeon_bo_int *bo;
     struct rad_sizes sizes;
     int ret;
 
@@ -158,25 +160,28 @@
 
 void radeon_cs_space_add_persistent_bo(struct radeon_cs *cs, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain)
 {
+    struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
     int i;
-    for (i = 0; i < cs->bo_count; i++) {
-	if (cs->bos[i].bo == bo &&
-	    cs->bos[i].read_domains == read_domains &&
-	    cs->bos[i].write_domain == write_domain)
+    for (i = 0; i < csi->bo_count; i++) {
+	if (csi->bos[i].bo == boi &&
+	    csi->bos[i].read_domains == read_domains &&
+	    csi->bos[i].write_domain == write_domain)
 	    return;
     }
     radeon_bo_ref(bo);
-    i = cs->bo_count;
-    cs->bos[i].bo = bo;
-    cs->bos[i].read_domains = read_domains;
-    cs->bos[i].write_domain = write_domain;
-    cs->bos[i].new_accounted = 0;
-    cs->bo_count++;
+    i = csi->bo_count;
+    csi->bos[i].bo = boi;
+    csi->bos[i].read_domains = read_domains;
+    csi->bos[i].write_domain = write_domain;
+    csi->bos[i].new_accounted = 0;
+    csi->bo_count++;
 
-    assert(cs->bo_count < MAX_SPACE_BOS);
+    assert(csi->bo_count < MAX_SPACE_BOS);
 }
 
-static int radeon_cs_check_space_internal(struct radeon_cs *cs, struct radeon_cs_space_check *tmp_bo)
+static int radeon_cs_check_space_internal(struct radeon_cs_int *cs,
+					  struct radeon_cs_space_check *tmp_bo)
 {
     int ret;
     int flushed = 0;
@@ -198,37 +203,42 @@
 int radeon_cs_space_check_with_bo(struct radeon_cs *cs,
 				  struct radeon_bo *bo,
 				  uint32_t read_domains, uint32_t write_domain)
-{									
+{
+    struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
+    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
     struct radeon_cs_space_check temp_bo;
+    
     int ret = 0;
 
     if (bo) {
-	temp_bo.bo = bo;
+	temp_bo.bo = boi;
 	temp_bo.read_domains = read_domains;
 	temp_bo.write_domain = write_domain;
 	temp_bo.new_accounted = 0;
     }
 
-    ret = radeon_cs_check_space_internal(cs, bo ? &temp_bo : NULL);
+    ret = radeon_cs_check_space_internal(csi, bo ? &temp_bo : NULL);
     return ret;
 }
 
 int radeon_cs_space_check(struct radeon_cs *cs)
 {
-    return radeon_cs_check_space_internal(cs, NULL);
+    struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
+    return radeon_cs_check_space_internal(csi, NULL);
 }
 
 void radeon_cs_space_reset_bos(struct radeon_cs *cs)
 {
+    struct radeon_cs_int *csi = (struct radeon_cs_int *)cs;
     int i;
-    for (i = 0; i < cs->bo_count; i++) {
-	radeon_bo_unref(cs->bos[i].bo);
-	cs->bos[i].bo = NULL;
-	cs->bos[i].read_domains = 0;
-	cs->bos[i].write_domain = 0;
-	cs->bos[i].new_accounted = 0;
+    for (i = 0; i < csi->bo_count; i++) {
+	radeon_bo_unref((struct radeon_bo *)csi->bos[i].bo);
+	csi->bos[i].bo = NULL;
+	csi->bos[i].read_domains = 0;
+	csi->bos[i].write_domain = 0;
+	csi->bos[i].new_accounted = 0;
     }
-    cs->bo_count = 0;
+    csi->bo_count = 0;
 }
 
 
diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c
index c6edbae..d31e4e4 100644
--- a/src/mesa/drivers/dri/radeon/radeon_dma.c
+++ b/src/mesa/drivers/dri/radeon/radeon_dma.c
@@ -151,6 +151,7 @@
 	aos->components = size;
 	aos->count = count;
 
+	radeon_bo_map(aos->bo, 1);
 	out = (uint32_t*)((char*)aos->bo->ptr + aos->offset);
 	switch (size) {
 	case 1: radeonEmitVec4(out, data, stride, count); break;
@@ -161,6 +162,7 @@
 		assert(0);
 		break;
 	}
+	radeon_bo_unmap(aos->bo);
 }
 
 void radeon_init_dma(radeonContextPtr rmesa)
@@ -183,10 +185,6 @@
 			__FUNCTION__, size, rmesa->dma.minimum_size);
 
 
-	/* unmap old reserved bo */
-	if (!is_empty_list(&rmesa->dma.reserved))
-		radeon_bo_unmap(first_elem(&rmesa->dma.reserved)->bo);
-
 	if (is_empty_list(&rmesa->dma.free)
 	      || last_elem(&rmesa->dma.free)->bo->size < size) {
 		dma_bo = CALLOC_STRUCT(radeon_dma_bo);
@@ -223,8 +221,6 @@
         /* Cmd buff have been flushed in radeon_revalidate_bos */
 		goto again_alloc;
 	}
-
-	radeon_bo_map(first_elem(&rmesa->dma.reserved)->bo, 1);
 }
 
 /* Allocates a region from rmesa->dma.current.  If there isn't enough
@@ -281,7 +277,6 @@
 
 	foreach_s(dma_bo, temp, &rmesa->dma.reserved) {
 		remove_from_list(dma_bo);
-		radeon_bo_unmap(dma_bo->bo);
 	        radeon_bo_unref(dma_bo->bo);
 		FREE(dma_bo);
 	}
@@ -306,10 +301,6 @@
 		WARN_ONCE("Your libdrm or kernel doesn't have support for busy query.\n"
 			"This may cause small performance drop for you.\n");
 	}
-	/* Protect against bug in legacy bo handling that causes bos stay
-	 * referenced even after they should be freed */
-	if (bo->cref != 1)
-		return 0;
 	return ret != -EBUSY;
 }
 
@@ -346,9 +337,7 @@
 	foreach_s(dma_bo, temp, &rmesa->dma.wait) {
 		if (dma_bo->expire_counter == time) {
 			WARN_ONCE("Leaking dma buffer object!\n");
-			/* force free of buffer so we don't realy start
-			 * leaking stuff now*/
-			while ((dma_bo->bo = radeon_bo_unref(dma_bo->bo))) {}
+			radeon_bo_unref(dma_bo->bo);
 			remove_from_list(dma_bo);
 			FREE(dma_bo);
 			continue;
@@ -367,9 +356,6 @@
 		insert_at_tail(&rmesa->dma.free, dma_bo);
 	}
 
-	/* unmap the last dma region */
-	if (!is_empty_list(&rmesa->dma.reserved))
-		radeon_bo_unmap(first_elem(&rmesa->dma.reserved)->bo);
 	/* move reserved to wait list */
 	foreach_s(dma_bo, temp, &rmesa->dma.reserved) {
 		/* free objects that are too small to be used because of large request */
@@ -403,11 +389,12 @@
 	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
 	struct radeon_dma *dma = &rmesa->dma;
 		
-
 	if (RADEON_DEBUG & RADEON_IOCTL)
 		fprintf(stderr, "%s\n", __FUNCTION__);
 	dma->flush = NULL;
 
+	radeon_bo_unmap(rmesa->swtcl.bo);
+
 	if (!is_empty_list(&dma->reserved)) {
 	    GLuint current_offset = dma->current_used;
 
@@ -422,6 +409,8 @@
 	    }
 	    rmesa->swtcl.numverts = 0;
 	}
+	radeon_bo_unref(rmesa->swtcl.bo);
+	rmesa->swtcl.bo = NULL;
 }
 /* Alloc space in the current dma region.
  */
@@ -432,6 +421,7 @@
 	void *head;
 	if (RADEON_DEBUG & RADEON_IOCTL)
 		fprintf(stderr, "%s\n", __FUNCTION__);
+
 	if(is_empty_list(&rmesa->dma.reserved)
 	      ||rmesa->dma.current_vertexptr + bytes > first_elem(&rmesa->dma.reserved)->bo->size) {
 		if (rmesa->dma.flush) {
@@ -455,7 +445,13 @@
                 rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
                 rmesa->dma.current_vertexptr );
 
-	head = (first_elem(&rmesa->dma.reserved)->bo->ptr + rmesa->dma.current_vertexptr);
+	if (!rmesa->swtcl.bo) {
+		rmesa->swtcl.bo = first_elem(&rmesa->dma.reserved)->bo;
+		radeon_bo_ref(rmesa->swtcl.bo);
+		radeon_bo_map(rmesa->swtcl.bo, 1);
+	}
+
+	head = (rmesa->swtcl.bo->ptr + rmesa->dma.current_vertexptr);
 	rmesa->dma.current_vertexptr += bytes;
 	rmesa->swtcl.numverts += nverts;
 	return head;
diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c
index bf69cd9..7b1f84a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_fbo.c
+++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c
@@ -90,7 +90,7 @@
    case GL_R3_G3_B2:
    case GL_RGB4:
    case GL_RGB5:
-      rb->Format = MESA_FORMAT_RGB565;
+      rb->Format = _dri_texformat_rgb565;
       rb->DataType = GL_UNSIGNED_BYTE;
       cpp = 2;
       break;
@@ -99,7 +99,7 @@
    case GL_RGB10:
    case GL_RGB12:
    case GL_RGB16:
-      rb->Format = MESA_FORMAT_ARGB8888;
+      rb->Format = _dri_texformat_argb8888;
       rb->DataType = GL_UNSIGNED_BYTE;
       cpp = 4;
       break;
@@ -111,7 +111,7 @@
    case GL_RGB10_A2:
    case GL_RGBA12:
    case GL_RGBA16:
-      rb->Format = MESA_FORMAT_ARGB8888;
+      rb->Format = _dri_texformat_argb8888;
       rb->DataType = GL_UNSIGNED_BYTE;
       cpp = 4;
       break;
@@ -166,8 +166,9 @@
      uint32_t size;
      uint32_t pitch = ((cpp * width + 63) & ~63) / cpp;
 
-     fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width,
-	  height, pitch);
+     if (RADEON_DEBUG & RADEON_MEMORY)
+	     fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width,
+		     height, pitch);
 
      size = pitch * height * cpp;
      rrb->pitch = pitch * cpp;
@@ -246,7 +247,7 @@
  * Not used for user-created renderbuffers.
  */
 struct radeon_renderbuffer *
-radeon_create_renderbuffer(gl_format format, __DRIdrawablePrivate *driDrawPriv)
+radeon_create_renderbuffer(gl_format format, __DRIdrawable *driDrawPriv)
 {
     struct radeon_renderbuffer *rrb;
 
@@ -261,14 +262,32 @@
 
     switch (format) {
         case MESA_FORMAT_RGB565:
+	    assert(_mesa_little_endian());
+	    rrb->base.DataType = GL_UNSIGNED_BYTE;
+            rrb->base._BaseFormat = GL_RGB;
+	    break;
+        case MESA_FORMAT_RGB565_REV:
+	    assert(!_mesa_little_endian());
 	    rrb->base.DataType = GL_UNSIGNED_BYTE;
             rrb->base._BaseFormat = GL_RGB;
 	    break;
         case MESA_FORMAT_XRGB8888:
+	    assert(_mesa_little_endian());
+	    rrb->base.DataType = GL_UNSIGNED_BYTE;
+            rrb->base._BaseFormat = GL_RGB;
+	    break;
+        case MESA_FORMAT_XRGB8888_REV:
+	    assert(!_mesa_little_endian());
 	    rrb->base.DataType = GL_UNSIGNED_BYTE;
             rrb->base._BaseFormat = GL_RGB;
 	    break;
 	case MESA_FORMAT_ARGB8888:
+	    assert(_mesa_little_endian());
+	    rrb->base.DataType = GL_UNSIGNED_BYTE;
+            rrb->base._BaseFormat = GL_RGBA;
+	    break;
+	case MESA_FORMAT_ARGB8888_REV:
+	    assert(!_mesa_little_endian());
 	    rrb->base.DataType = GL_UNSIGNED_BYTE;
             rrb->base._BaseFormat = GL_RGBA;
 	    break;
@@ -351,6 +370,12 @@
 }
 
 
+/* TODO: According to EXT_fbo spec internal format of texture image
+ * once set during glTexImage call, should be preserved when
+ * attaching image to renderbuffer. When HW doesn't support
+ * rendering to format of attached image, set framebuffer
+ * completeness accordingly in radeon_validate_framebuffer (issue #79).
+ */
 static GLboolean
 radeon_update_wrapper(GLcontext *ctx, struct radeon_renderbuffer *rrb, 
 		     struct gl_texture_image *texImage)
@@ -359,21 +384,21 @@
 	gl_format texFormat;
 
 restart:
-	if (texImage->TexFormat == MESA_FORMAT_ARGB8888) {
+	if (texImage->TexFormat == _dri_texformat_argb8888) {
 		rrb->base.DataType = GL_UNSIGNED_BYTE;
 		DBG("Render to RGBA8 texture OK\n");
 	}
-	else if (texImage->TexFormat == MESA_FORMAT_RGB565) {
+	else if (texImage->TexFormat == _dri_texformat_rgb565) {
 		rrb->base.DataType = GL_UNSIGNED_BYTE;
 		DBG("Render to RGB5 texture OK\n");
 	}
-	else if (texImage->TexFormat == MESA_FORMAT_ARGB1555) {
+	else if (texImage->TexFormat == _dri_texformat_argb1555) {
 		rrb->base.DataType = GL_UNSIGNED_BYTE;
 		DBG("Render to ARGB1555 texture OK\n");
 	}
-	else if (texImage->TexFormat == MESA_FORMAT_ARGB4444) {
+	else if (texImage->TexFormat == _dri_texformat_argb4444) {
 		rrb->base.DataType = GL_UNSIGNED_BYTE;
-		DBG("Render to ARGB1555 texture OK\n");
+		DBG("Render to ARGB4444 texture OK\n");
 	}
 	else if (texImage->TexFormat == MESA_FORMAT_Z16) {
 		rrb->base.DataType = GL_UNSIGNED_SHORT;
diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
index a0106d0..a9d50c5 100644
--- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
@@ -449,7 +449,7 @@
 static void radeonKernelClear(GLcontext *ctx, GLuint flags)
 {
      r100ContextPtr rmesa = R100_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
+   __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
    drm_radeon_sarea_t *sarea = rmesa->radeon.sarea;
    uint32_t clear;
    GLint ret, i;
@@ -570,11 +570,15 @@
 static void radeonClear( GLcontext *ctx, GLbitfield mask )
 {
    r100ContextPtr rmesa = R100_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
+   __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
    GLuint flags = 0;
    GLuint color_mask = 0;
    GLuint orig_mask = mask;
 
+   if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT)) {
+      rmesa->radeon.front_buffer_dirty = GL_TRUE;
+   }
+
    if ( RADEON_DEBUG & RADEON_IOCTL ) {
       fprintf( stderr, "radeonClear\n");
    }
diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c
index 02de8e5..9dee691 100644
--- a/src/mesa/drivers/dri/radeon/radeon_lock.c
+++ b/src/mesa/drivers/dri/radeon/radeon_lock.c
@@ -58,11 +58,9 @@
  */
 void radeonGetLock(radeonContextPtr rmesa, GLuint flags)
 {
-	__DRIdrawablePrivate *const drawable = radeon_get_drawable(rmesa);
-	__DRIdrawablePrivate *const readable = radeon_get_readable(rmesa);
-	__DRIscreenPrivate *sPriv = rmesa->dri.screen;
-
-	assert(drawable != NULL);
+	__DRIdrawable *const drawable = radeon_get_drawable(rmesa);
+	__DRIdrawable *const readable = radeon_get_readable(rmesa);
+	__DRIscreen *sPriv = rmesa->dri.screen;
 
 	drmGetLock(rmesa->dri.fd, rmesa->dri.hwContext, flags);
 
@@ -74,12 +72,13 @@
 	 * Since the hardware state depends on having the latest drawable
 	 * clip rects, all state checking must be done _after_ this call.
 	 */
-	DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable);
-	if (drawable != readable) {
+	if (drawable)
+		DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable);
+	if (readable && drawable != readable) {
 		DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable);
 	}
 
-	if (rmesa->lastStamp != drawable->lastStamp) {
+	if (drawable && (rmesa->lastStamp != drawable->lastStamp)) {
 		radeon_window_moved(rmesa);
 		rmesa->lastStamp = drawable->lastStamp;
 	}
diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c b/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c
index 08e1c5d..d810e60 100644
--- a/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c
+++ b/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c
@@ -76,12 +76,14 @@
 
    /* Emit the data
     */
+   radeon_bo_map(aos->bo, 1);
    out = (uint32_t*)((char*)aos->bo->ptr + aos->offset);
    for (i = 0; i < count; i++) {
       out[0] = radeonComputeFogBlendFactor( ctx, *(GLfloat *)data );
       out++;
       data += stride;
    }
+   radeon_bo_unmap(aos->bo);
 }
 
 static void emit_s0_vec(uint32_t *out, GLvoid *data, int stride, int count)
@@ -151,6 +153,7 @@
 
    /* Emit the data
     */
+   radeon_bo_map(aos->bo, 1);
    out = (uint32_t*)((char*)aos->bo->ptr + aos->offset);
    switch (size) {
    case 1:
@@ -170,6 +173,7 @@
       exit(1);
       break;
    }
+   radeon_bo_unmap(aos->bo);
 }
 
 
@@ -196,12 +200,12 @@
       if (!rmesa->tcl.obj.buf) 
 	rcommon_emit_vector( ctx, 
 			     &(rmesa->tcl.aos[nr]),
-			     (char *)VB->ObjPtr->data,
-			     VB->ObjPtr->size,
-			     VB->ObjPtr->stride,
+			     (char *)VB->AttribPtr[_TNL_ATTRIB_POS]->data,
+			     VB->AttribPtr[_TNL_ATTRIB_POS]->size,
+			     VB->AttribPtr[_TNL_ATTRIB_POS]->stride,
 			     count);
 
-      switch( VB->ObjPtr->size ) {
+      switch( VB->AttribPtr[_TNL_ATTRIB_POS]->size ) {
       case 4: vfmt |= RADEON_CP_VC_FRMT_W0;
       case 3: vfmt |= RADEON_CP_VC_FRMT_Z;
       case 2: vfmt |= RADEON_CP_VC_FRMT_XY;
@@ -216,9 +220,9 @@
       if (!rmesa->tcl.norm.buf)
 	 rcommon_emit_vector( ctx, 
 			      &(rmesa->tcl.aos[nr]),
-			      (char *)VB->NormalPtr->data,
+			      (char *)VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data,
 			      3,
-			      VB->NormalPtr->stride,
+			      VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride,
 			      count);
 
       vfmt |= RADEON_CP_VC_FRMT_N0;
@@ -227,9 +231,9 @@
 
    if (inputs & VERT_BIT_COLOR0) {
       int emitsize;
-      if (VB->ColorPtr[0]->size == 4 &&
-	  (VB->ColorPtr[0]->stride != 0 ||
-	   VB->ColorPtr[0]->data[0][3] != 1.0)) {
+      if (VB->AttribPtr[_TNL_ATTRIB_COLOR0]->size == 4 &&
+	  (VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride != 0 ||
+	   VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data[0][3] != 1.0)) {
 	 vfmt |= RADEON_CP_VC_FRMT_FPCOLOR | RADEON_CP_VC_FRMT_FPALPHA;
 	 emitsize = 4;
       }
@@ -242,9 +246,9 @@
       if (!rmesa->tcl.rgba.buf)
 	rcommon_emit_vector( ctx,
 			     &(rmesa->tcl.aos[nr]),
-			     (char *)VB->ColorPtr[0]->data,
+			     (char *)VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data,
 			     emitsize,
-			     VB->ColorPtr[0]->stride,
+			     VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride,
 			     count);
 
       nr++;
@@ -256,9 +260,9 @@
 
 	rcommon_emit_vector( ctx,
 			     &(rmesa->tcl.aos[nr]),
-			     (char *)VB->SecondaryColorPtr[0]->data,
+			     (char *)VB->AttribPtr[_TNL_ATTRIB_COLOR1]->data,
 			     3,
-			     VB->SecondaryColorPtr[0]->stride,
+			     VB->AttribPtr[_TNL_ATTRIB_COLOR1]->stride,
 			     count);
       }
 
@@ -273,8 +277,8 @@
       if (!rmesa->tcl.fog.buf)
 	 emit_vecfog( ctx,
 		      &(rmesa->tcl.aos[nr]),
-		      (char *)VB->FogCoordPtr->data,
-		      VB->FogCoordPtr->stride,
+		      (char *)VB->AttribPtr[_TNL_ATTRIB_FOG]->data,
+		      VB->AttribPtr[_TNL_ATTRIB_FOG]->stride,
 		      count);
 
       vfmt |= RADEON_CP_VC_FRMT_FPFOG;
@@ -290,24 +294,24 @@
 	 if (!rmesa->tcl.tex[unit].buf)
 	    emit_tex_vector( ctx,
 			     &(rmesa->tcl.aos[nr]),
-			     (char *)VB->TexCoordPtr[unit]->data,
-			     VB->TexCoordPtr[unit]->size,
-			     VB->TexCoordPtr[unit]->stride,
+			     (char *)VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->data,
+			     VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size,
+			     VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->stride,
 			     count );
 	 nr++;
 
 	 vfmt |= RADEON_ST_BIT(unit);
          /* assume we need the 3rd coord if texgen is active for r/q OR at least
 	    3 coords are submitted. This may not be 100% correct */
-         if (VB->TexCoordPtr[unit]->size >= 3) {
+         if (VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size >= 3) {
 	    vtx |= RADEON_Q_BIT(unit);
 	    vfmt |= RADEON_Q_BIT(unit);
 	 }
 	 if ( (ctx->Texture.Unit[unit].TexGenEnabled & (R_BIT | Q_BIT)) )
 	    vtx |= RADEON_Q_BIT(unit);
-	 else if ((VB->TexCoordPtr[unit]->size >= 3) &&
+	 else if ((VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size >= 3) &&
 	          ((ctx->Texture.Unit[unit]._ReallyEnabled & (TEXTURE_CUBE_BIT)) == 0)) {
-	    GLuint swaptexmatcol = (VB->TexCoordPtr[unit]->size - 3);
+	    GLuint swaptexmatcol = (VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size - 3);
 	    if (((rmesa->NeedTexMatrix >> unit) & 1) &&
 		 (swaptexmatcol != ((rmesa->TexMatColSwap >> unit) & 1)))
 	       radeonUploadTexMatrix( rmesa, unit, swaptexmatcol ) ;
diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h b/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h
index 5157831..d764ccb 100644
--- a/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h
+++ b/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h
@@ -56,18 +56,18 @@
 
    radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s\n", __FUNCTION__);
 
-   coord = (GLuint (*)[4])VB->ObjPtr->data;
-   coord_stride = VB->ObjPtr->stride;
+   coord = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_POS]->data;
+   coord_stride = VB->AttribPtr[_TNL_ATTRIB_POS]->stride;
 
    if (DO_TEX2) {
-      if (VB->TexCoordPtr[2]) {
+      if (VB->AttribPtr[_TNL_ATTRIB_TEX2]) {
 	 const GLuint t2 = GET_TEXSOURCE(2);
-	 tc2 = (GLuint (*)[4])VB->TexCoordPtr[t2]->data;
-	 tc2_stride = VB->TexCoordPtr[t2]->stride;
-	 if (DO_PTEX && VB->TexCoordPtr[t2]->size < 3) {
+	 tc2 = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->data;
+	 tc2_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->stride;
+	 if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->size < 3) {
 	    fill_tex |= (1<<2);
 	 }
-	 else if (DO_PTEX && VB->TexCoordPtr[t2]->size < 4) {
+	 else if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->size < 4) {
 	    rqcoordsnoswap |= (1<<2);
 	 }
       } else {
@@ -77,14 +77,14 @@
    }
 
    if (DO_TEX1) {
-      if (VB->TexCoordPtr[1]) {
+      if (VB->AttribPtr[_TNL_ATTRIB_TEX1]) {
 	 const GLuint t1 = GET_TEXSOURCE(1);
-	 tc1 = (GLuint (*)[4])VB->TexCoordPtr[t1]->data;
-	 tc1_stride = VB->TexCoordPtr[t1]->stride;
-	 if (DO_PTEX && VB->TexCoordPtr[t1]->size < 3) {
+	 tc1 = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->data;
+	 tc1_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->stride;
+	 if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->size < 3) {
 	    fill_tex |= (1<<1);
 	 }
-	 else if (DO_PTEX && VB->TexCoordPtr[t1]->size < 4) {
+	 else if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->size < 4) {
 	    rqcoordsnoswap |= (1<<1);
 	 }
       } else {
@@ -94,14 +94,14 @@
    }
 
    if (DO_TEX0) {
-      if (VB->TexCoordPtr[0]) {
+      if (VB->AttribPtr[_TNL_ATTRIB_TEX0]) {
 	 const GLuint t0 = GET_TEXSOURCE(0);
-	 tc0_stride = VB->TexCoordPtr[t0]->stride;
-	 tc0 = (GLuint (*)[4])VB->TexCoordPtr[t0]->data;
-	 if (DO_PTEX && VB->TexCoordPtr[t0]->size < 3) {
+	 tc0_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->stride;
+	 tc0 = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->data;
+	 if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->size < 3) {
 	    fill_tex |= (1<<0);
 	 }
-	 else if (DO_PTEX && VB->TexCoordPtr[t0]->size < 4) {
+	 else if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->size < 4) {
 	    rqcoordsnoswap |= (1<<0);
 	 }
       } else {
@@ -112,9 +112,9 @@
    }
 
    if (DO_NORM) {
-      if (VB->NormalPtr) {
-	 norm_stride = VB->NormalPtr->stride;
-	 norm = (GLuint (*)[4])VB->NormalPtr->data;
+      if (VB->AttribPtr[_TNL_ATTRIB_NORMAL]) {
+	 norm_stride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride;
+	 norm = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data;
       } else {
 	 norm_stride = 0;
 	 norm = (GLuint (*)[4])&ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
@@ -122,9 +122,9 @@
    }
 
    if (DO_RGBA) {
-      if (VB->ColorPtr[0]) {
-	 col = VB->ColorPtr[0]->data;
-	 col_stride = VB->ColorPtr[0]->stride;
+      if (VB->AttribPtr[_TNL_ATTRIB_COLOR0]) {
+	 col = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;
+	 col_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride;
       } else {
 	 col = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
 	 col_stride = 0;
@@ -132,9 +132,9 @@
    }
 
    if (DO_SPEC_OR_FOG) {
-      if (VB->SecondaryColorPtr[0]) {
-	 spec = VB->SecondaryColorPtr[0]->data;
-	 spec_stride = VB->SecondaryColorPtr[0]->stride;
+      if (VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
+	 spec = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->data;
+	 spec_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->stride;
       } else {
 	 spec = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
 	 spec_stride = 0;
@@ -142,9 +142,9 @@
    }
 
    if (DO_SPEC_OR_FOG) {
-      if (VB->FogCoordPtr) {
-	 fog = VB->FogCoordPtr->data;
-	 fog_stride = VB->FogCoordPtr->stride;
+      if (VB->AttribPtr[_TNL_ATTRIB_FOG]) {
+	 fog = VB->AttribPtr[_TNL_ATTRIB_FOG]->data;
+	 fog_stride = VB->AttribPtr[_TNL_ATTRIB_FOG]->stride;
       } else {
 	 fog = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_FOG];
 	 fog_stride = 0;
diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c
index 78ec119..98f96ff 100644
--- a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c
+++ b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c
@@ -326,7 +326,7 @@
 
    if (1) {
       req |= RADEON_CP_VC_FRMT_Z;
-      if (VB->ObjPtr->size == 4) {
+      if (VB->AttribPtr[_TNL_ATTRIB_POS]->size == 4) {
 	 req |= RADEON_CP_VC_FRMT_W0;
       }
    }
@@ -348,15 +348,15 @@
 	 req |= RADEON_ST_BIT(unit);
 	 /* assume we need the 3rd coord if texgen is active for r/q OR at least
 	    3 coords are submitted. This may not be 100% correct */
-	 if (VB->TexCoordPtr[unit]->size >= 3) {
+	 if (VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size >= 3) {
 	    req |= RADEON_Q_BIT(unit);
 	    vtx |= RADEON_Q_BIT(unit);
 	 }
 	 if ( (ctx->Texture.Unit[unit].TexGenEnabled & (R_BIT | Q_BIT)) )
 	    vtx |= RADEON_Q_BIT(unit);
-	 else if ((VB->TexCoordPtr[unit]->size >= 3) &&
+	 else if ((VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size >= 3) &&
 	          ((ctx->Texture.Unit[unit]._ReallyEnabled & (TEXTURE_CUBE_BIT)) == 0)) {
-	    GLuint swaptexmatcol = (VB->TexCoordPtr[unit]->size - 3);
+	    GLuint swaptexmatcol = (VB->AttribPtr[_TNL_ATTRIB_TEX0 + unit]->size - 3);
 	    if (((rmesa->NeedTexMatrix >> unit) & 1) &&
 		 (swaptexmatcol != ((rmesa->TexMatColSwap >> unit) & 1)))
 	       radeonUploadTexMatrix( rmesa, unit, swaptexmatcol ) ;
@@ -390,19 +390,19 @@
     * this, add more vertex code (for obj-2, obj-3) or preferably move
     * to maos.  
     */
-   if (VB->ObjPtr->size < 3 || 
-       (VB->ObjPtr->size == 3 && 
+   if (VB->AttribPtr[_TNL_ATTRIB_POS]->size < 3 ||
+       (VB->AttribPtr[_TNL_ATTRIB_POS]->size == 3 &&
 	(setup_tab[i].vertex_format & RADEON_CP_VC_FRMT_W0))) {
 
       _math_trans_4f( rmesa->tcl.ObjClean.data,
-		      VB->ObjPtr->data,
-		      VB->ObjPtr->stride,
+		      VB->AttribPtr[_TNL_ATTRIB_POS]->data,
+		      VB->AttribPtr[_TNL_ATTRIB_POS]->stride,
 		      GL_FLOAT,
-		      VB->ObjPtr->size,
+		      VB->AttribPtr[_TNL_ATTRIB_POS]->size,
 		      0,
 		      VB->Count );
 
-      switch (VB->ObjPtr->size) {
+      switch (VB->AttribPtr[_TNL_ATTRIB_POS]->size) {
       case 1:
 	    _mesa_vector4f_clean_elem(&rmesa->tcl.ObjClean, VB->Count, 1);
       case 2:
@@ -416,14 +416,14 @@
 	 break;
       }
 
-      VB->ObjPtr = &rmesa->tcl.ObjClean;
+      VB->AttribPtr[_TNL_ATTRIB_POS] = &rmesa->tcl.ObjClean;
    }
 
 
-
+   radeon_bo_map(rmesa->radeon.tcl.aos[0].bo, 1);
    setup_tab[i].emit( ctx, 0, VB->Count, 
 		      rmesa->radeon.tcl.aos[0].bo->ptr + rmesa->radeon.tcl.aos[0].offset);
-
+   radeon_bo_unmap(rmesa->radeon.tcl.aos[0].bo);
    //   rmesa->radeon.tcl.aos[0].size = setup_tab[i].vertex_size;
    rmesa->radeon.tcl.aos[0].stride = setup_tab[i].vertex_size;
    rmesa->tcl.vertex_format = setup_tab[i].vertex_format;
diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
index dadc72f..033f26d 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2009 Maciej Cencora.
  * Copyright (C) 2008 Nicolai Haehnle.
  *
  * All Rights Reserved.
@@ -32,50 +33,52 @@
 
 #include "main/simple_list.h"
 #include "main/texcompress.h"
+#include "main/teximage.h"
+#include "main/texobj.h"
+#include "radeon_texture.h"
 
-static GLuint radeon_compressed_texture_size(GLcontext *ctx,
-		GLsizei width, GLsizei height, GLsizei depth,
-		GLuint mesaFormat)
+static unsigned get_aligned_compressed_row_stride(
+		gl_format format,
+		unsigned width,
+		unsigned minStride)
 {
-	GLuint size = _mesa_format_image_size(mesaFormat, width, height, depth);
+	const unsigned blockSize = _mesa_get_format_bytes(format);
+	unsigned blockWidth, blockHeight, numXBlocks;
 
-	if (mesaFormat == MESA_FORMAT_RGB_DXT1 ||
-	    mesaFormat == MESA_FORMAT_RGBA_DXT1) {
-		if (width + 3 < 8)	/* width one block */
-			size = size * 4;
-		else if (width + 3 < 16)
-			size = size * 2;
-	} else {
-		/* DXT3/5, 16 bytes per block */
-	  //		WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n");
-		if (width + 3 < 8)
-			size = size * 2;
+	_mesa_get_format_block_size(format, &blockWidth, &blockHeight);
+	numXBlocks = (width + blockWidth - 1) / blockWidth;
+
+	while (numXBlocks * blockSize < minStride)
+	{
+		++numXBlocks;
 	}
 
-	return size;
+	return numXBlocks * blockSize;
 }
 
-
-static int radeon_compressed_num_bytes(GLuint mesaFormat)
+static unsigned get_compressed_image_size(
+		gl_format format,
+		unsigned rowStride,
+		unsigned height)
 {
-   int bytes = 0;
-   switch(mesaFormat) {
-     
-   case MESA_FORMAT_RGB_FXT1:
-   case MESA_FORMAT_RGBA_FXT1:
-   case MESA_FORMAT_RGB_DXT1:
-   case MESA_FORMAT_RGBA_DXT1:
-     bytes = 2;
-     break;
-     
-   case MESA_FORMAT_RGBA_DXT3:
-   case MESA_FORMAT_RGBA_DXT5:
-     bytes = 4;
-   default:
-     break;
-   }
-   
-   return bytes;
+	unsigned blockWidth, blockHeight;
+
+	_mesa_get_format_block_size(format, &blockWidth, &blockHeight);
+
+	return rowStride * ((height + blockHeight - 1) / blockHeight);
+}
+
+static int find_next_power_of_two(GLuint value)
+{
+	int i, tmp;
+
+	i = 0;
+	tmp = value - 1;
+	while (tmp) {
+		tmp >>= 1;
+		i++;
+	}
+	return (1 << i);
 }
 
 /**
@@ -90,28 +93,28 @@
 {
 	radeon_mipmap_level *lvl = &mt->levels[level];
 	uint32_t row_align;
+	GLuint height;
+
+	height = find_next_power_of_two(lvl->height);
 
 	/* Find image size in bytes */
-	if (mt->compressed) {
-		/* TODO: Is this correct? Need test cases for compressed textures! */
-		row_align = rmesa->texture_compressed_row_align - 1;
-		lvl->rowstride = (lvl->width * mt->bpp + row_align) & ~row_align;
-		lvl->size = radeon_compressed_texture_size(mt->radeon->glCtx,
-							   lvl->width, lvl->height, lvl->depth, mt->compressed);
+	if (_mesa_is_format_compressed(mt->mesaFormat)) {
+		lvl->rowstride = get_aligned_compressed_row_stride(mt->mesaFormat, lvl->width, rmesa->texture_compressed_row_align);
+		lvl->size = get_compressed_image_size(mt->mesaFormat, lvl->rowstride, height);
 	} else if (mt->target == GL_TEXTURE_RECTANGLE_NV) {
 		row_align = rmesa->texture_rect_row_align - 1;
-		lvl->rowstride = (lvl->width * mt->bpp + row_align) & ~row_align;
-		lvl->size = lvl->rowstride * lvl->height;
+		lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align;
+		lvl->size = lvl->rowstride * height;
 	} else if (mt->tilebits & RADEON_TXO_MICRO_TILE) {
 		/* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
 		 * though the actual offset may be different (if texture is less than
 		 * 32 bytes width) to the untiled case */
-		lvl->rowstride = (lvl->width * mt->bpp * 2 + 31) & ~31;
-		lvl->size = lvl->rowstride * ((lvl->height + 1) / 2) * lvl->depth;
+		lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) * 2 + 31) & ~31;
+		lvl->size = lvl->rowstride * ((height + 1) / 2) * lvl->depth;
 	} else {
 		row_align = rmesa->texture_row_align - 1;
-		lvl->rowstride = (lvl->width * mt->bpp + row_align) & ~row_align;
-		lvl->size = lvl->rowstride * lvl->height * lvl->depth;
+		lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align;
+		lvl->size = lvl->rowstride * height * lvl->depth;
 	}
 	assert(lvl->size > 0);
 
@@ -123,7 +126,7 @@
 	if (RADEON_DEBUG & RADEON_TEXTURE)
 	  fprintf(stderr,
 		  "level %d, face %d: rs:%d %dx%d at %d\n",
-		  level, face, lvl->rowstride, lvl->width, lvl->height, lvl->faces[face].offset);
+		  level, face, lvl->rowstride, lvl->width, height, lvl->faces[face].offset);
 }
 
 static GLuint minify(GLuint size, GLuint levels)
@@ -137,22 +140,19 @@
 
 static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_tree *mt)
 {
-	GLuint curOffset;
-	GLuint numLevels;
-	GLuint i;
-	GLuint face;
+	GLuint curOffset, i, face, level;
 
-	numLevels = mt->lastLevel - mt->firstLevel + 1;
-	assert(numLevels <= rmesa->glCtx->Const.MaxTextureLevels);
+	assert(mt->numLevels <= rmesa->glCtx->Const.MaxTextureLevels);
 
 	curOffset = 0;
 	for(face = 0; face < mt->faces; face++) {
 
-		for(i = 0; i < numLevels; i++) {
-			mt->levels[i].width = minify(mt->width0, i);
-			mt->levels[i].height = minify(mt->height0, i);
-			mt->levels[i].depth = minify(mt->depth0, i);
-			compute_tex_image_offset(rmesa, mt, face, i, &curOffset);
+		for(i = 0, level = mt->baseLevel; i < mt->numLevels; i++, level++) {
+			mt->levels[level].valid = 1;
+			mt->levels[level].width = minify(mt->width0, i);
+			mt->levels[level].height = minify(mt->height0, i);
+			mt->levels[level].depth = minify(mt->depth0, i);
+			compute_tex_image_offset(rmesa, mt, face, level, &curOffset);
 		}
 	}
 
@@ -162,23 +162,21 @@
 
 static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_tree *mt)
 {
-	GLuint curOffset;
-	GLuint numLevels;
-	GLuint i;
+	GLuint curOffset, i, level;
 
-	numLevels = mt->lastLevel - mt->firstLevel + 1;
-	assert(numLevels <= rmesa->glCtx->Const.MaxTextureLevels);
+	assert(mt->numLevels <= rmesa->glCtx->Const.MaxTextureLevels);
 
 	curOffset = 0;
-	for(i = 0; i < numLevels; i++) {
+	for(i = 0, level = mt->baseLevel; i < mt->numLevels; i++, level++) {
 		GLuint face;
 
-		mt->levels[i].width = minify(mt->width0, i);
-		mt->levels[i].height = minify(mt->height0, i);
-		mt->levels[i].depth = minify(mt->depth0, i);
+		mt->levels[level].valid = 1;
+		mt->levels[level].width = minify(mt->width0, i);
+		mt->levels[level].height = minify(mt->height0, i);
+		mt->levels[level].depth = minify(mt->depth0, i);
 
 		for(face = 0; face < mt->faces; face++)
-			compute_tex_image_offset(rmesa, mt, face, i, &curOffset);
+			compute_tex_image_offset(rmesa, mt, face, level, &curOffset);
 	}
 
 	/* Note the required size in memory */
@@ -188,27 +186,22 @@
 /**
  * Create a new mipmap tree, calculate its layout and allocate memory.
  */
-radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj *t,
-		GLenum target, GLenum internal_format, GLuint firstLevel, GLuint lastLevel,
-		GLuint width0, GLuint height0, GLuint depth0,
-		GLuint bpp, GLuint tilebits, GLuint compressed)
+static radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa,
+		GLenum target, gl_format mesaFormat, GLuint baseLevel, GLuint numLevels,
+		GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits)
 {
 	radeon_mipmap_tree *mt = CALLOC_STRUCT(_radeon_mipmap_tree);
 
-	mt->radeon = rmesa;
-	mt->internal_format = internal_format;
+	mt->mesaFormat = mesaFormat;
 	mt->refcount = 1;
-	mt->t = t;
 	mt->target = target;
 	mt->faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
-	mt->firstLevel = firstLevel;
-	mt->lastLevel = lastLevel;
+	mt->baseLevel = baseLevel;
+	mt->numLevels = numLevels;
 	mt->width0 = width0;
 	mt->height0 = height0;
 	mt->depth0 = depth0;
-	mt->bpp = compressed ? radeon_compressed_num_bytes(compressed) : bpp;
 	mt->tilebits = tilebits;
-	mt->compressed = compressed;
 
 	if (rmesa->radeonScreen->chip_family >= CHIP_FAMILY_R300)
 		calculate_miptree_layout_r300(rmesa, mt);
@@ -223,53 +216,43 @@
 	return mt;
 }
 
-void radeon_miptree_reference(radeon_mipmap_tree *mt)
+void radeon_miptree_reference(radeon_mipmap_tree *mt, radeon_mipmap_tree **ptr)
 {
+	assert(!*ptr);
+
 	mt->refcount++;
 	assert(mt->refcount > 0);
+
+	*ptr = mt;
 }
 
-void radeon_miptree_unreference(radeon_mipmap_tree *mt)
+void radeon_miptree_unreference(radeon_mipmap_tree **ptr)
 {
+	radeon_mipmap_tree *mt = *ptr;
 	if (!mt)
 		return;
 
 	assert(mt->refcount > 0);
+
 	mt->refcount--;
 	if (!mt->refcount) {
 		radeon_bo_unref(mt->bo);
 		free(mt);
 	}
+
+	*ptr = 0;
 }
 
-
 /**
- * Calculate first and last mip levels for the given texture object,
- * where the dimensions are taken from the given texture image at
- * the given level.
- *
- * Note: level is the OpenGL level number, which is not necessarily the same
- * as the first level that is actually present.
- *
- * The base level image of the given texture face must be non-null,
- * or this will fail.
+ * Calculate min and max LOD for the given texture object.
+ * @param[in] tObj texture object whose LOD values to calculate
+ * @param[out] pminLod minimal LOD
+ * @param[out] pmaxLod maximal LOD
  */
-static void calculate_first_last_level(struct gl_texture_object *tObj,
-				       GLuint *pfirstLevel, GLuint *plastLevel,
-				       GLuint face, GLuint level)
+static void calculate_min_max_lod(struct gl_texture_object *tObj,
+				       unsigned *pminLod, unsigned *pmaxLod)
 {
-	const struct gl_texture_image * const baseImage =
-		tObj->Image[face][level];
-
-	assert(baseImage);
-	
-	/* These must be signed values.  MinLod and MaxLod can be negative numbers,
-	* and having firstLevel and lastLevel as signed prevents the need for
-	* extra sign checks.
-	*/
-	int   firstLevel;
-	int   lastLevel;
-
+	int minLod, maxLod;
 	/* Yes, this looks overly complicated, but it's all needed.
 	*/
 	switch (tObj->Target) {
@@ -280,32 +263,30 @@
 		if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
 			/* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
 			*/
-			firstLevel = lastLevel = tObj->BaseLevel;
+			minLod = maxLod = tObj->BaseLevel;
 		} else {
-			firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5);
-			firstLevel = MAX2(firstLevel, tObj->BaseLevel);
-			firstLevel = MIN2(firstLevel, level + baseImage->MaxLog2);
-			lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5);
-			lastLevel = MAX2(lastLevel, tObj->BaseLevel);
-			lastLevel = MIN2(lastLevel, level + baseImage->MaxLog2);
-			lastLevel = MIN2(lastLevel, tObj->MaxLevel);
-			lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
+			minLod = tObj->BaseLevel + (GLint)(tObj->MinLod);
+			minLod = MAX2(minLod, tObj->BaseLevel);
+			minLod = MIN2(minLod, tObj->MaxLevel);
+			maxLod = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5);
+			maxLod = MIN2(maxLod, tObj->MaxLevel);
+			maxLod = MIN2(maxLod, tObj->Image[0][minLod]->MaxLog2 + minLod);
+			maxLod = MAX2(maxLod, minLod); /* need at least one level */
 		}
 		break;
 	case GL_TEXTURE_RECTANGLE_NV:
 	case GL_TEXTURE_4D_SGIS:
-		firstLevel = lastLevel = 0;
+		minLod = maxLod = 0;
 		break;
 	default:
 		return;
 	}
 
 	/* save these values */
-	*pfirstLevel = firstLevel;
-	*plastLevel = lastLevel;
+	*pminLod = minLod;
+	*pmaxLod = maxLod;
 }
 
-
 /**
  * Checks whether the given miptree can hold the given texture image at the
  * given face and level.
@@ -313,23 +294,17 @@
 GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt,
 		struct gl_texture_image *texImage, GLuint face, GLuint level)
 {
-	GLboolean isCompressed = _mesa_is_format_compressed(texImage->TexFormat);
 	radeon_mipmap_level *lvl;
 
-	if (face >= mt->faces || level < mt->firstLevel || level > mt->lastLevel)
+	if (face >= mt->faces)
 		return GL_FALSE;
 
-	if (texImage->InternalFormat != mt->internal_format ||
-	    isCompressed != mt->compressed)
+	if (texImage->TexFormat != mt->mesaFormat)
 		return GL_FALSE;
 
-	if (!isCompressed &&
-	    !mt->compressed &&
-	    _mesa_get_format_bytes(texImage->TexFormat) != mt->bpp)
-		return GL_FALSE;
-
-	lvl = &mt->levels[level - mt->firstLevel];
-	if (lvl->width != texImage->Width ||
+	lvl = &mt->levels[level];
+	if (!lvl->valid ||
+	    lvl->width != texImage->Width ||
 	    lvl->height != texImage->Height ||
 	    lvl->depth != texImage->Depth)
 		return GL_FALSE;
@@ -337,64 +312,72 @@
 	return GL_TRUE;
 }
 
-
 /**
  * Checks whether the given miptree has the right format to store the given texture object.
  */
-GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_texture_object *texObj)
+static GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_texture_object *texObj)
 {
 	struct gl_texture_image *firstImage;
-	GLuint compressed;
-	GLuint numfaces = 1;
-	GLuint firstLevel, lastLevel;
-	GLuint texelBytes;
+	unsigned numLevels;
+	radeon_mipmap_level *mtBaseLevel;
 
-	calculate_first_last_level(texObj, &firstLevel, &lastLevel, 0, texObj->BaseLevel);
-	if (texObj->Target == GL_TEXTURE_CUBE_MAP)
-		numfaces = 6;
+	if (texObj->BaseLevel < mt->baseLevel)
+		return GL_FALSE;
 
-	firstImage = texObj->Image[0][firstLevel];
-	compressed = _mesa_is_format_compressed(firstImage->TexFormat) ? firstImage->TexFormat : 0;
-	texelBytes = _mesa_get_format_bytes(firstImage->TexFormat);
+	mtBaseLevel = &mt->levels[texObj->BaseLevel - mt->baseLevel];
+	firstImage = texObj->Image[0][texObj->BaseLevel];
+	numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, firstImage->MaxLog2 + 1);
 
-	return (mt->firstLevel == firstLevel &&
-	        mt->lastLevel == lastLevel &&
-	        mt->width0 == firstImage->Width &&
-	        mt->height0 == firstImage->Height &&
-	        mt->depth0 == firstImage->Depth &&
-	        mt->compressed == compressed &&
-	        (!mt->compressed ? (mt->bpp == texelBytes) : 1));
+	if (RADEON_DEBUG & RADEON_TEXTURE) {
+		fprintf(stderr, "Checking if miptree %p matches texObj %p\n", mt, texObj);
+		fprintf(stderr, "target %d vs %d\n", mt->target, texObj->Target);
+		fprintf(stderr, "format %d vs %d\n", mt->mesaFormat, firstImage->TexFormat);
+		fprintf(stderr, "numLevels %d vs %d\n", mt->numLevels, numLevels);
+		fprintf(stderr, "width0 %d vs %d\n", mtBaseLevel->width, firstImage->Width);
+		fprintf(stderr, "height0 %d vs %d\n", mtBaseLevel->height, firstImage->Height);
+		fprintf(stderr, "depth0 %d vs %d\n", mtBaseLevel->depth, firstImage->Depth);
+		if (mt->target == texObj->Target &&
+	        mt->mesaFormat == firstImage->TexFormat &&
+	        mt->numLevels >= numLevels &&
+	        mtBaseLevel->width == firstImage->Width &&
+	        mtBaseLevel->height == firstImage->Height &&
+	        mtBaseLevel->depth == firstImage->Depth) {
+			fprintf(stderr, "MATCHED\n");
+		} else {
+			fprintf(stderr, "NOT MATCHED\n");
+		}
+	}
+
+	return (mt->target == texObj->Target &&
+	        mt->mesaFormat == firstImage->TexFormat &&
+	        mt->numLevels >= numLevels &&
+	        mtBaseLevel->width == firstImage->Width &&
+	        mtBaseLevel->height == firstImage->Height &&
+	        mtBaseLevel->depth == firstImage->Depth);
 }
 
-
 /**
- * Try to allocate a mipmap tree for the given texture that will fit the
- * given image in the given position.
+ * Try to allocate a mipmap tree for the given texture object.
+ * @param[in] rmesa radeon context
+ * @param[in] t radeon texture object
  */
-void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t,
-		radeon_texture_image *image, GLuint face, GLuint level)
+void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t)
 {
-	GLuint compressed = _mesa_is_format_compressed(image->base.TexFormat) ? image->base.TexFormat : 0;
-	GLuint numfaces = 1;
-	GLuint firstLevel, lastLevel;
-	GLuint texelBytes;
+	struct gl_texture_object *texObj = &t->base;
+	struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel];
+	GLuint numLevels;
 
 	assert(!t->mt);
 
-	calculate_first_last_level(&t->base, &firstLevel, &lastLevel, face, level);
-	if (t->base.Target == GL_TEXTURE_CUBE_MAP)
-		numfaces = 6;
-
-	if (level != firstLevel || face >= numfaces)
+	if (!texImg)
 		return;
 
-	texelBytes = _mesa_get_format_bytes(image->base.TexFormat);
+	numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, texImg->MaxLog2 + 1);
 
-	t->mt = radeon_miptree_create(rmesa, t, t->base.Target,
-		image->base.InternalFormat,
-		firstLevel, lastLevel,
-		image->base.Width, image->base.Height, image->base.Depth,
-		texelBytes, t->tile_bits, compressed);
+	t->mt = radeon_miptree_create(rmesa, t->base.Target,
+		texImg->TexFormat, texObj->BaseLevel,
+		numLevels, texImg->Width, texImg->Height,
+		texImg->Depth, t->tile_bits);
 }
 
 /* Although we use the image_offset[] array to store relative offsets
@@ -406,21 +389,234 @@
 void
 radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets)
 {
-     if (mt->target != GL_TEXTURE_3D || mt->faces == 1)
-        offsets[0] = 0;
-     else {
-	int i;
-	for (i = 0; i < 6; i++)
-		offsets[i] = mt->levels[level].faces[i].offset;
-     }
+	if (mt->target != GL_TEXTURE_3D || mt->faces == 1) {
+		offsets[0] = 0;
+	} else {
+		int i;
+		for (i = 0; i < 6; i++) {
+			offsets[i] = mt->levels[level].faces[i].offset;
+		}
+	}
 }
 
 GLuint
 radeon_miptree_image_offset(radeon_mipmap_tree *mt,
 			    GLuint face, GLuint level)
 {
-   if (mt->target == GL_TEXTURE_CUBE_MAP_ARB)
-      return (mt->levels[level].faces[face].offset);
-   else
-      return mt->levels[level].faces[0].offset;
+	if (mt->target == GL_TEXTURE_CUBE_MAP_ARB)
+		return (mt->levels[level].faces[face].offset);
+	else
+		return mt->levels[level].faces[0].offset;
 }
+
+/**
+ * Ensure that the given image is stored in the given miptree from now on.
+ */
+static void migrate_image_to_miptree(radeon_mipmap_tree *mt,
+									 radeon_texture_image *image,
+									 int face, int level)
+{
+	radeon_mipmap_level *dstlvl = &mt->levels[level];
+	unsigned char *dest;
+
+	assert(image->mt != mt);
+	assert(dstlvl->valid);
+	assert(dstlvl->width == image->base.Width);
+	assert(dstlvl->height == image->base.Height);
+	assert(dstlvl->depth == image->base.Depth);
+
+	radeon_bo_map(mt->bo, GL_TRUE);
+	dest = mt->bo->ptr + dstlvl->faces[face].offset;
+
+	if (image->mt) {
+		/* Format etc. should match, so we really just need a memcpy().
+		 * In fact, that memcpy() could be done by the hardware in many
+		 * cases, provided that we have a proper memory manager.
+		 */
+		assert(mt->mesaFormat == image->base.TexFormat);
+
+		radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
+
+		/* TODO: bring back these assertions once the FBOs are fixed */
+#if 0
+		assert(image->mtlevel == level);
+		assert(srclvl->size == dstlvl->size);
+		assert(srclvl->rowstride == dstlvl->rowstride);
+#endif
+
+		radeon_bo_map(image->mt->bo, GL_FALSE);
+
+		memcpy(dest,
+			image->mt->bo->ptr + srclvl->faces[face].offset,
+			dstlvl->size);
+		radeon_bo_unmap(image->mt->bo);
+
+		radeon_miptree_unreference(&image->mt);
+	} else if (image->base.Data) {
+		/* This condition should be removed, it's here to workaround
+		 * a segfault when mapping textures during software fallbacks.
+		 */
+		const uint32_t srcrowstride = _mesa_format_row_stride(image->base.TexFormat, image->base.Width);
+		uint32_t rows = image->base.Height * image->base.Depth;
+
+		if (_mesa_is_format_compressed(image->base.TexFormat)) {
+			uint32_t blockWidth, blockHeight;
+			_mesa_get_format_block_size(image->base.TexFormat, &blockWidth, &blockHeight);
+			rows = (rows + blockHeight - 1) / blockHeight;
+		}
+
+		copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
+				  rows, srcrowstride);
+
+		_mesa_free_texmemory(image->base.Data);
+		image->base.Data = 0;
+	}
+
+	radeon_bo_unmap(mt->bo);
+
+	radeon_miptree_reference(mt, &image->mt);
+	image->mtface = face;
+	image->mtlevel = level;
+}
+
+/**
+ * Filter matching miptrees, and select one with the most of data.
+ * @param[in] texObj radeon texture object
+ * @param[in] firstLevel first texture level to check
+ * @param[in] lastLevel last texture level to check
+ */
+static radeon_mipmap_tree * get_biggest_matching_miptree(radeonTexObj *texObj,
+														 unsigned firstLevel,
+														 unsigned lastLevel)
+{
+	const unsigned numLevels = lastLevel - firstLevel + 1;
+	unsigned *mtSizes = calloc(numLevels, sizeof(unsigned));
+	radeon_mipmap_tree **mts = calloc(numLevels, sizeof(radeon_mipmap_tree *));
+	unsigned mtCount = 0;
+	unsigned maxMtIndex = 0;
+	radeon_mipmap_tree *tmp;
+
+	for (unsigned level = firstLevel; level <= lastLevel; ++level) {
+		radeon_texture_image *img = get_radeon_texture_image(texObj->base.Image[0][level]);
+		unsigned found = 0;
+		// TODO: why this hack??
+		if (!img)
+			break;
+
+		if (!img->mt)
+			continue;
+
+		for (int i = 0; i < mtCount; ++i) {
+			if (mts[i] == img->mt) {
+				found = 1;
+				mtSizes[i] += img->mt->levels[img->mtlevel].size;
+				break;
+			}
+		}
+
+		if (!found && radeon_miptree_matches_texture(img->mt, &texObj->base)) {
+			mtSizes[mtCount] = img->mt->levels[img->mtlevel].size;
+			mts[mtCount] = img->mt;
+			mtCount++;
+		}
+	}
+
+	if (mtCount == 0) {
+		return NULL;
+	}
+
+	for (int i = 1; i < mtCount; ++i) {
+		if (mtSizes[i] > mtSizes[maxMtIndex]) {
+			maxMtIndex = i;
+		}
+	}
+
+	tmp = mts[maxMtIndex];
+	free(mtSizes);
+	free(mts);
+
+	return tmp;
+}
+
+/**
+ * Validate texture mipmap tree.
+ * If individual images are stored in different mipmap trees
+ * use the mipmap tree that has the most of the correct data.
+ */
+int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj)
+{
+	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+	radeonTexObj *t = radeon_tex_obj(texObj);
+
+	if (t->validated || t->image_override) {
+		return GL_TRUE;
+	}
+
+	if (texObj->Image[0][texObj->BaseLevel]->Border > 0)
+		return GL_FALSE;
+
+	_mesa_test_texobj_completeness(rmesa->glCtx, texObj);
+	if (!texObj->_Complete) {
+		return GL_FALSE;
+	}
+
+	calculate_min_max_lod(&t->base, &t->minLod, &t->maxLod);
+
+	if (RADEON_DEBUG & RADEON_TEXTURE)
+		fprintf(stderr, "%s: Validating texture %p now, minLod = %d, maxLod = %d\n",
+				__FUNCTION__, texObj ,t->minLod, t->maxLod);
+
+	radeon_mipmap_tree *dst_miptree;
+	dst_miptree = get_biggest_matching_miptree(t, t->minLod, t->maxLod);
+
+	if (!dst_miptree) {
+		radeon_miptree_unreference(&t->mt);
+		radeon_try_alloc_miptree(rmesa, t);
+		dst_miptree = t->mt;
+		if (RADEON_DEBUG & RADEON_TEXTURE) {
+			fprintf(stderr, "%s: No matching miptree found, allocated new one %p\n", __FUNCTION__, t->mt);
+		}
+	} else if (RADEON_DEBUG & RADEON_TEXTURE) {
+		fprintf(stderr, "%s: Using miptree %p\n", __FUNCTION__, t->mt);
+	}
+
+	const unsigned faces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1;
+	unsigned face, level;
+	radeon_texture_image *img;
+	/* Validate only the levels that will actually be used during rendering */
+	for (face = 0; face < faces; ++face) {
+		for (level = t->minLod; level <= t->maxLod; ++level) {
+			img = get_radeon_texture_image(texObj->Image[face][level]);
+
+			if (RADEON_DEBUG & RADEON_TEXTURE) {
+				fprintf(stderr, "Checking image level %d, face %d, mt %p ... ", level, face, img->mt);
+			}
+			
+			if (img->mt != dst_miptree) {
+				if (RADEON_DEBUG & RADEON_TEXTURE) {
+					fprintf(stderr, "MIGRATING\n");
+				}
+				struct radeon_bo *src_bo = (img->mt) ? img->mt->bo : img->bo;
+				if (src_bo && radeon_bo_is_referenced_by_cs(src_bo, rmesa->cmdbuf.cs)) {
+					radeon_firevertices(rmesa);
+				}
+				migrate_image_to_miptree(dst_miptree, img, face, level);
+			} else if (RADEON_DEBUG & RADEON_TEXTURE) {
+				fprintf(stderr, "OK\n");
+			}
+		}
+	}
+
+	t->validated = GL_TRUE;
+
+	return GL_TRUE;
+}
+
+uint32_t get_base_teximage_offset(radeonTexObj *texObj)
+{
+	if (!texObj->mt) {
+		return 0;
+	} else {
+		return radeon_miptree_image_offset(texObj->mt, 0, texObj->minLod);
+	}
+}
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h
index db28252..a10649b 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h
@@ -44,6 +44,7 @@
 	GLuint depth;
 	GLuint size; /** Size of each image, in bytes */
 	GLuint rowstride; /** in bytes */
+	GLuint valid;
 	radeon_mipmap_image faces[6];
 };
 
@@ -59,43 +60,35 @@
  * changed.
  */
 struct _radeon_mipmap_tree {
-	radeonContextPtr radeon;
-	radeonTexObj *t;
 	struct radeon_bo *bo;
 	GLuint refcount;
 
 	GLuint totalsize; /** total size of the miptree, in bytes */
 
 	GLenum target; /** GL_TEXTURE_xxx */
-	GLenum internal_format;
+	GLenum mesaFormat; /** MESA_FORMAT_xxx */
 	GLuint faces; /** # of faces: 6 for cubemaps, 1 otherwise */
-	GLuint firstLevel; /** First mip level stored in this mipmap tree */
-	GLuint lastLevel; /** Last mip level stored in this mipmap tree */
+	GLuint baseLevel; /** gl_texture_object->baseLevel it was created for */
+	GLuint numLevels; /** Number of mip levels stored in this mipmap tree */
 
-	GLuint width0; /** Width of firstLevel image */
-	GLuint height0; /** Height of firstLevel image */
-	GLuint depth0; /** Depth of firstLevel image */
+	GLuint width0; /** Width of baseLevel image */
+	GLuint height0; /** Height of baseLevel image */
+	GLuint depth0; /** Depth of baseLevel image */
 
-	GLuint bpp; /** Bytes per texel */
 	GLuint tilebits; /** RADEON_TXO_xxx_TILE */
-	GLuint compressed; /** MESA_FORMAT_xxx indicating a compressed format, or 0 if uncompressed */
 
 	radeon_mipmap_level levels[RADEON_MIPTREE_MAX_TEXTURE_LEVELS];
 };
 
-radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj *t,
-		GLenum target, GLenum internal_format, GLuint firstLevel, GLuint lastLevel,
-		GLuint width0, GLuint height0, GLuint depth0,
-		GLuint bpp, GLuint tilebits, GLuint compressed);
-void radeon_miptree_reference(radeon_mipmap_tree *mt);
-void radeon_miptree_unreference(radeon_mipmap_tree *mt);
+void radeon_miptree_reference(radeon_mipmap_tree *mt, radeon_mipmap_tree **ptr);
+void radeon_miptree_unreference(radeon_mipmap_tree **ptr);
 
 GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt,
 		struct gl_texture_image *texImage, GLuint face, GLuint level);
-GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_texture_object *texObj);
-void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t,
-			      radeon_texture_image *texImage, GLuint face, GLuint level);
+void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t);
 GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt,
 				   GLuint face, GLuint level);
 void radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets);
+
+uint32_t get_base_teximage_offset(radeonTexObj *texObj);
 #endif /* __RADEON_MIPMAP_TREE_H_ */
diff --git a/src/mesa/drivers/dri/radeon/radeon_queryobj.c b/src/mesa/drivers/dri/radeon/radeon_queryobj.c
index 6539c36..98117cd 100644
--- a/src/mesa/drivers/dri/radeon/radeon_queryobj.c
+++ b/src/mesa/drivers/dri/radeon/radeon_queryobj.c
@@ -31,24 +31,11 @@
 #include "main/imports.h"
 #include "main/simple_list.h"
 
-static int radeonQueryIsFlushed(GLcontext *ctx, struct gl_query_object *q)
-{
-	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
-	struct radeon_query_object *tmp, *query = (struct radeon_query_object *)q;
-
-	foreach(tmp, &radeon->query.not_flushed_head) {
-		if (tmp == query) {
-			return 0;
-		}
-	}
-
-	return 1;
-}
-
 static void radeonQueryGetResult(GLcontext *ctx, struct gl_query_object *q)
 {
 	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
 	struct radeon_query_object *query = (struct radeon_query_object *)q;
+        uint32_t *result;
 	int i;
 
 	radeon_print(RADEON_STATE, RADEON_VERBOSE,
@@ -56,6 +43,7 @@
 			__FUNCTION__, query->Base.Id, (int) query->Base.Result);
 
 	radeon_bo_map(query->bo, GL_FALSE);
+        result = query->bo->ptr;
 
 	query->Base.Result = 0;
 	if (IS_R600_CLASS(radeon->radeonScreen)) {
@@ -66,10 +54,11 @@
 		 * hw writes zpass end counts to qwords 1, 3, 5, 7.
 		 * then we substract. MSB is the valid bit.
 		 */
-		uint64_t *result = query->bo->ptr;
-		for (i = 0; i < 8; i += 2) {
-			uint64_t start = result[i];
-			uint64_t end = result[i + 1];
+		for (i = 0; i < 16; i += 4) {
+			uint64_t start = (uint64_t)LE32_TO_CPU(result[i]) |
+					 (uint64_t)LE32_TO_CPU(result[i + 1]) << 32;
+			uint64_t end = (uint64_t)LE32_TO_CPU(result[i + 2]) |
+				       (uint64_t)LE32_TO_CPU(result[i + 3]) << 32;
 			if ((start & 0x8000000000000000) && (end & 0x8000000000000000)) {
 				uint64_t query_count = end - start;
 				query->Base.Result += query_count;
@@ -79,10 +68,9 @@
 				     "%d start: %lx, end: %lx %ld\n", i, start, end, end - start);
 		}
 	} else {
-		uint32_t *result = query->bo->ptr;
 		for (i = 0; i < query->curr_offset/sizeof(uint32_t); ++i) {
-			query->Base.Result += result[i];
-			radeon_print(RADEON_STATE, RADEON_TRACE, "result[%d] = %d\n", i, result[i]);
+			query->Base.Result += LE32_TO_CPU(result[i]);
+			radeon_print(RADEON_STATE, RADEON_TRACE, "result[%d] = %d\n", i, LE32_TO_CPU(result[i]));
 		}
 	}
 
@@ -120,10 +108,11 @@
 
 static void radeonWaitQuery(GLcontext *ctx, struct gl_query_object *q)
 {
+	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
 	struct radeon_query_object *query = (struct radeon_query_object *)q;
 
 	/* If the cmdbuf with packets for this query hasn't been flushed yet, do it now */
-	if (!radeonQueryIsFlushed(ctx, q))
+	if (radeon_bo_is_referenced_by_cs(query->bo, radeon->cmdbuf.cs))
 		ctx->Driver.Flush(ctx);
 
 	radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, q->Id, query->bo, query->curr_offset);
@@ -155,8 +144,6 @@
 
 	radeon->query.queryobj.dirty = GL_TRUE;
 	radeon->hw.is_dirty = GL_TRUE;
-	insert_at_tail(&radeon->query.not_flushed_head, query);
-
 }
 
 void radeonEmitQueryEnd(GLcontext *ctx)
@@ -204,7 +191,7 @@
 		uint32_t domain;
 
 		/* Need to perform a flush, as per ARB_occlusion_query spec */
-		if (!radeonQueryIsFlushed(ctx, q)) {
+		if (radeon_bo_is_referenced_by_cs(query->bo, radeon->cmdbuf.cs)) {
 			ctx->Driver.Flush(ctx);
 		}
 
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index 7a124a8..3080a0f 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -214,10 +214,10 @@
 
 #endif
 
-static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
+static int getSwapInfo( __DRIdrawable *dPriv, __DRIswapInfo * sInfo );
 
 static int
-radeonGetParam(__DRIscreenPrivate *sPriv, int param, void *value)
+radeonGetParam(__DRIscreen *sPriv, int param, void *value)
 {
   int ret;
   drm_radeon_getparam_t gp = { 0 };
@@ -249,7 +249,7 @@
 }
 
 static const __DRIconfig **
-radeonFillInModes( __DRIscreenPrivate *psp,
+radeonFillInModes( __DRIscreen *psp,
 		   unsigned pixel_bits, unsigned depth_bits,
 		   unsigned stencil_bits, GLboolean have_back_buffer )
 {
@@ -390,12 +390,14 @@
    screen->device_id = device_id;
    screen->chip_flags = 0;
    switch ( device_id ) {
+   case PCI_CHIP_RN50_515E:
+   case PCI_CHIP_RN50_5969:
+	return -1;
+
    case PCI_CHIP_RADEON_LY:
    case PCI_CHIP_RADEON_LZ:
    case PCI_CHIP_RADEON_QY:
    case PCI_CHIP_RADEON_QZ:
-   case PCI_CHIP_RN50_515E:
-   case PCI_CHIP_RN50_5969:
       screen->chip_family = CHIP_FAMILY_RV100;
       break;
 
@@ -909,7 +911,7 @@
 /* Create the device specific screen private data struct.
  */
 static radeonScreenPtr
-radeonCreateScreen( __DRIscreenPrivate *sPriv )
+radeonCreateScreen( __DRIscreen *sPriv )
 {
    radeonScreenPtr screen;
    RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv;
@@ -1248,7 +1250,7 @@
 }
 
 static radeonScreenPtr
-radeonCreateScreen2(__DRIscreenPrivate *sPriv)
+radeonCreateScreen2(__DRIscreen *sPriv)
 {
    radeonScreenPtr screen;
    int i;
@@ -1399,7 +1401,7 @@
 /* Destroy the device specific screen private data struct.
  */
 static void
-radeonDestroyScreen( __DRIscreenPrivate *sPriv )
+radeonDestroyScreen( __DRIscreen *sPriv )
 {
     radeonScreenPtr screen = (radeonScreenPtr)sPriv->private;
 
@@ -1433,7 +1435,7 @@
 /* Initialize the driver specific screen private data.
  */
 static GLboolean
-radeonInitDriver( __DRIscreenPrivate *sPriv )
+radeonInitDriver( __DRIscreen *sPriv )
 {
     if (sPriv->dri2.enabled) {
         sPriv->private = (void *) radeonCreateScreen2( sPriv );
@@ -1457,8 +1459,8 @@
  * pbuffers.
  */
 static GLboolean
-radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
-                    __DRIdrawablePrivate *driDrawPriv,
+radeonCreateBuffer( __DRIscreen *driScrnPriv,
+                    __DRIdrawable *driDrawPriv,
                     const __GLcontextModes *mesaVis,
                     GLboolean isPixmap )
 {
@@ -1482,11 +1484,11 @@
     _mesa_initialize_framebuffer(&rfb->base, mesaVis);
 
     if (mesaVis->redBits == 5)
-        rgbFormat = MESA_FORMAT_RGB565;
+        rgbFormat = _mesa_little_endian() ? MESA_FORMAT_RGB565 : MESA_FORMAT_RGB565_REV;
     else if (mesaVis->alphaBits == 0)
-        rgbFormat = MESA_FORMAT_XRGB8888;
+        rgbFormat = _mesa_little_endian() ? MESA_FORMAT_XRGB8888 : MESA_FORMAT_XRGB8888_REV;
     else
-        rgbFormat = MESA_FORMAT_ARGB8888;
+        rgbFormat = _mesa_little_endian() ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB8888_REV;
 
     /* front color renderbuffer */
     rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
@@ -1557,7 +1559,7 @@
 }
 
 void
-radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+radeonDestroyBuffer(__DRIdrawable *driDrawPriv)
 {
     struct radeon_framebuffer *rfb;
     if (!driDrawPriv)
@@ -1579,7 +1581,7 @@
  * \return the __GLcontextModes supported by this driver
  */
 static const __DRIconfig **
-radeonInitScreen(__DRIscreenPrivate *psp)
+radeonInitScreen(__DRIscreen *psp)
 {
 #if defined(RADEON_R100)
    static const char *driver_name = "Radeon";
@@ -1629,7 +1631,7 @@
  * \return the __GLcontextModes supported by this driver
  */
 static const
-__DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp)
+__DRIconfig **radeonInitScreen2(__DRIscreen *psp)
 {
    GLenum fb_format[3];
    GLenum fb_type[3];
@@ -1696,7 +1698,7 @@
  * Get information about previous buffer swaps.
  */
 static int
-getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
+getSwapInfo( __DRIdrawable *dPriv, __DRIswapInfo * sInfo )
 {
     struct radeon_framebuffer *rfb;
 
@@ -1749,3 +1751,10 @@
    .InitScreen2     = radeonInitScreen2,
 };
 
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driLegacyExtension.base,
+    &driDRI2Extension.base,
+    NULL
+};
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.h b/src/mesa/drivers/dri/radeon/radeon_screen.h
index 15744e8..5e6d432 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.h
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.h
@@ -86,7 +86,7 @@
 
    __volatile__ uint32_t *scratch;
 
-   __DRIscreenPrivate *driScreen;
+   __DRIscreen *driScreen;
    unsigned int sarea_priv_offset;
    unsigned int gart_buffer_offset;	/* offset in card memory space */
    unsigned int gart_texture_offset;	/* offset in card memory space */
@@ -123,5 +123,5 @@
 #define IS_R600_CLASS(screen) \
 	((screen->chip_flags & RADEON_CLASS_MASK) == RADEON_CLASS_R600)
 
-extern void radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv);
+extern void radeonDestroyBuffer(__DRIdrawable *driDrawPriv);
 #endif /* __RADEON_SCREEN_H__ */
diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c
index 2bc7d31..8db3d2b 100644
--- a/src/mesa/drivers/dri/radeon/radeon_span.c
+++ b/src/mesa/drivers/dri/radeon/radeon_span.c
@@ -41,6 +41,7 @@
  */
 
 #include "main/glheader.h"
+#include "main/texformat.h"
 #include "swrast/swrast.h"
 
 #include "radeon_common.h"
@@ -400,6 +401,18 @@
 #endif
 #include "spantmp2.h"
 
+#define SPANTMP_PIXEL_FMT GL_RGB
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5_REV
+
+#define TAG(x)    radeon##x##_RGB565_REV
+#define TAG2(x,y) radeon##x##_RGB565_REV##y
+#if defined(RADEON_R600)
+#define GET_PTR(X,Y) r600_ptr_color(rrb, (X) + x_off, (Y) + y_off)
+#else
+#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
+#endif
+#include "spantmp2.h"
+
 /* 16 bit, ARGB1555 color spanline and pixel functions
  */
 #define SPANTMP_PIXEL_FMT GL_BGRA
@@ -414,6 +427,18 @@
 #endif
 #include "spantmp2.h"
 
+#define SPANTMP_PIXEL_FMT GL_BGRA
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5
+
+#define TAG(x)    radeon##x##_ARGB1555_REV
+#define TAG2(x,y) radeon##x##_ARGB1555_REV##y
+#if defined(RADEON_R600)
+#define GET_PTR(X,Y) r600_ptr_color(rrb, (X) + x_off, (Y) + y_off)
+#else
+#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
+#endif
+#include "spantmp2.h"
+
 /* 16 bit, RGBA4 color spanline and pixel functions
  */
 #define SPANTMP_PIXEL_FMT GL_BGRA
@@ -428,6 +453,18 @@
 #endif
 #include "spantmp2.h"
 
+#define SPANTMP_PIXEL_FMT GL_BGRA
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4
+
+#define TAG(x)    radeon##x##_ARGB4444_REV
+#define TAG2(x,y) radeon##x##_ARGB4444_REV##y
+#if defined(RADEON_R600)
+#define GET_PTR(X,Y) r600_ptr_color(rrb, (X) + x_off, (Y) + y_off)
+#else
+#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
+#endif
+#include "spantmp2.h"
+
 /* 32 bit, xRGB8888 color spanline and pixel functions
  */
 #define SPANTMP_PIXEL_FMT GL_BGRA
@@ -472,6 +509,42 @@
 #endif
 #include "spantmp2.h"
 
+/* 32 bit, BGRx8888 color spanline and pixel functions
+ */
+#define SPANTMP_PIXEL_FMT GL_BGRA
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8
+
+#define TAG(x)    radeon##x##_BGRx8888
+#define TAG2(x,y) radeon##x##_BGRx8888##y
+#if defined(RADEON_R600)
+#define GET_VALUE(_x, _y) ((*(GLuint*)(r600_ptr_color(rrb, _x + x_off, _y + y_off)) | 0x000000ff))
+#define PUT_VALUE(_x, _y, d) { \
+   GLuint *_ptr = (GLuint*)r600_ptr_color( rrb, _x + x_off, _y + y_off );		\
+   *_ptr = d;								\
+} while (0)
+#else
+#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) | 0x000000ff))
+#define PUT_VALUE(_x, _y, d) { \
+   GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off );		\
+   *_ptr = d;								\
+} while (0)
+#endif
+#include "spantmp2.h"
+
+/* 32 bit, BGRA8888 color spanline and pixel functions
+ */
+#define SPANTMP_PIXEL_FMT GL_BGRA
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8
+
+#define TAG(x)    radeon##x##_BGRA8888
+#define TAG2(x,y) radeon##x##_BGRA8888##y
+#if defined(RADEON_R600)
+#define GET_PTR(X,Y) r600_ptr_color(rrb, (X) + x_off, (Y) + y_off)
+#else
+#define GET_PTR(X,Y) radeon_ptr_4byte(rrb, (X) + x_off, (Y) + y_off)
+#endif
+#include "spantmp2.h"
+
 /* ================================================================
  * Depth buffer
  */
@@ -526,10 +599,10 @@
 #define WRITE_DEPTH( _x, _y, d )					\
 do {									\
    GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off );		\
-   GLuint tmp = *_ptr;				\
+   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
    tmp &= 0x000000ff;							\
    tmp |= ((d << 8) & 0xffffff00);					\
-   *_ptr = tmp;					\
+   *_ptr = CPU_TO_LE32(tmp);                                            \
 } while (0)
 #elif defined(RADEON_R600)
 #define WRITE_DEPTH( _x, _y, d )					\
@@ -544,26 +617,26 @@
 #define WRITE_DEPTH( _x, _y, d )					\
 do {									\
    GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off );		\
-   GLuint tmp = *_ptr;				\
+   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
    tmp &= 0xff000000;							\
    tmp |= ((d) & 0x00ffffff);						\
-   *_ptr = tmp;					\
+   *_ptr = CPU_TO_LE32(tmp);                                            \
 } while (0)
 #else
 #define WRITE_DEPTH( _x, _y, d )					\
 do {									\
    GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off );	\
-   GLuint tmp = *_ptr;							\
+   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
    tmp &= 0xff000000;							\
    tmp |= ((d) & 0x00ffffff);						\
-   *_ptr = tmp;					\
+   *_ptr = CPU_TO_LE32(tmp);                                            \
 } while (0)
 #endif
 
 #if defined(RADEON_R300)
 #define READ_DEPTH( d, _x, _y )						\
   do {									\
-    d = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) & 0xffffff00) >> 8; \
+    d = (LE32_TO_CPU(*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))) & 0xffffff00) >> 8; \
   }while(0)
 #elif defined(RADEON_R600)
 #define READ_DEPTH( d, _x, _y )						\
@@ -573,11 +646,11 @@
 #elif defined(RADEON_R200)
 #define READ_DEPTH( d, _x, _y )						\
   do {									\
-    d = *(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off)) & 0x00ffffff; \
+    d = LE32_TO_CPU(*(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off))) & 0x00ffffff; \
   }while(0)
 #else
 #define READ_DEPTH( d, _x, _y )	\
-  d = *(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off,	_y + y_off)) & 0x00ffffff;
+  d = LE32_TO_CPU(*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off,	_y + y_off))) & 0x00ffffff;
 #endif
 
 #define TAG(x) radeon##x##_z24
@@ -595,7 +668,7 @@
 #define WRITE_DEPTH( _x, _y, d )					\
 do {									\
    GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off );		\
-   *_ptr = d;								\
+   *_ptr = CPU_TO_LE32((((d) & 0xff000000) >> 24) | (((d) & 0x00ffffff) << 8));   \
 } while (0)
 #elif defined(RADEON_R600)
 #define WRITE_DEPTH( _x, _y, d )					\
@@ -615,20 +688,21 @@
 #define WRITE_DEPTH( _x, _y, d )					\
 do {									\
    GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off );		\
-   *_ptr = d;								\
+   *_ptr = CPU_TO_LE32(d);						\
 } while (0)
 #else
 #define WRITE_DEPTH( _x, _y, d )					\
 do {									\
    GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off );	\
-   *_ptr = d;					\
+   *_ptr = CPU_TO_LE32(d);						\
 } while (0)
 #endif
 
 #if defined(RADEON_R300)
 #define READ_DEPTH( d, _x, _y )						\
   do { \
-    d = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)));	\
+    GLuint tmp = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)));	\
+    d = LE32_TO_CPU(((tmp & 0x000000ff) << 24) | ((tmp & 0xffffff00) >> 8));	\
   }while(0)
 #elif defined(RADEON_R600)
 #define READ_DEPTH( d, _x, _y )						\
@@ -639,11 +713,11 @@
 #elif defined(RADEON_R200)
 #define READ_DEPTH( d, _x, _y )						\
   do { \
-    d = *(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off));	\
+    d = LE32_TO_CPU(*(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off))); \
   }while(0)
 #else
 #define READ_DEPTH( d, _x, _y )	do {					\
-    d = *(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off,	_y + y_off )); \
+    d = LE32_TO_CPU(*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))); \
   } while (0)
 #endif
 
@@ -660,10 +734,10 @@
 #define WRITE_STENCIL( _x, _y, d )					\
 do {									\
    GLuint *_ptr = (GLuint*)radeon_ptr_4byte(rrb, _x + x_off, _y + y_off);		\
-   GLuint tmp = *_ptr;				\
+   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
    tmp &= 0xffffff00;							\
    tmp |= (d) & 0xff;							\
-   *_ptr = tmp;					\
+   *_ptr = CPU_TO_LE32(tmp);                                            \
 } while (0)
 #elif defined(RADEON_R600)
 #define WRITE_STENCIL( _x, _y, d )					\
@@ -678,19 +752,19 @@
 #define WRITE_STENCIL( _x, _y, d )					\
 do {									\
    GLuint *_ptr = (GLuint*)r200_depth_4byte(rrb, _x + x_off, _y + y_off);		\
-   GLuint tmp = *_ptr;				\
+   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
    tmp &= 0x00ffffff;							\
    tmp |= (((d) & 0xff) << 24);						\
-   *_ptr = tmp;					\
+   *_ptr = CPU_TO_LE32(tmp);                                            \
 } while (0)
 #else
 #define WRITE_STENCIL( _x, _y, d )					\
 do {									\
    GLuint *_ptr = (GLuint*)radeon_ptr_4byte(rrb, _x + x_off, _y + y_off);		\
-   GLuint tmp = *_ptr;				\
+   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
    tmp &= 0x00ffffff;							\
    tmp |= (((d) & 0xff) << 24);						\
-   *_ptr = tmp;					\
+   *_ptr = CPU_TO_LE32(tmp);                                            \
 } while (0)
 #endif
 
@@ -698,7 +772,7 @@
 #define READ_STENCIL( d, _x, _y )					\
 do {									\
    GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off );		\
-   GLuint tmp = *_ptr;				\
+   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
    d = tmp & 0x000000ff;						\
 } while (0)
 #elif defined(RADEON_R600)
@@ -712,14 +786,14 @@
 #define READ_STENCIL( d, _x, _y )					\
 do {									\
    GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off );		\
-   GLuint tmp = *_ptr;				\
+   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
    d = (tmp & 0xff000000) >> 24;					\
 } while (0)
 #else
 #define READ_STENCIL( d, _x, _y )					\
 do {									\
    GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off );		\
-   GLuint tmp = *_ptr;				\
+   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
    d = (tmp & 0xff000000) >> 24;					\
 } while (0)
 #endif
@@ -737,8 +811,7 @@
 		return;
 
 	if (flag) {
-		if (rrb->bo->bom->funcs->bo_wait)
-			radeon_bo_wait(rrb->bo);
+	        radeon_bo_wait(rrb->bo);
 		r = radeon_bo_map(rrb->bo, 1);
 		if (r) {
 			fprintf(stderr, "(%s) error(%d) mapping buffer.\n",
@@ -754,18 +827,21 @@
 }
 
 static void
-radeon_map_unmap_buffers(GLcontext *ctx, GLboolean map)
+radeon_map_unmap_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb,
+			     GLboolean map)
 {
 	GLuint i, j;
 
 	/* color draw buffers */
 	for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++)
-		map_unmap_rb(ctx->DrawBuffer->_ColorDrawBuffers[j], map);
+		map_unmap_rb(fb->_ColorDrawBuffers[j], map);
+
+	map_unmap_rb(fb->_ColorReadBuffer, map);
 
 	/* check for render to textures */
 	for (i = 0; i < BUFFER_COUNT; i++) {
 		struct gl_renderbuffer_attachment *att =
-			ctx->DrawBuffer->Attachment + i;
+			fb->Attachment + i;
 		struct gl_texture_object *tex = att->Texture;
 		if (tex) {
 			/* Render to texture. Note that a mipmapped texture need not
@@ -781,15 +857,15 @@
 				radeon_teximage_unmap(image);
 		}
 	}
-
-	map_unmap_rb(ctx->ReadBuffer->_ColorReadBuffer, map);
-
+	
 	/* depth buffer (Note wrapper!) */
-	if (ctx->DrawBuffer->_DepthBuffer)
-		map_unmap_rb(ctx->DrawBuffer->_DepthBuffer->Wrapped, map);
+	if (fb->_DepthBuffer)
+		map_unmap_rb(fb->_DepthBuffer->Wrapped, map);
 
-	if (ctx->DrawBuffer->_StencilBuffer)
-		map_unmap_rb(ctx->DrawBuffer->_StencilBuffer->Wrapped, map);
+	if (fb->_StencilBuffer)
+		map_unmap_rb(fb->_StencilBuffer->Wrapped, map);
+
+	radeon_check_front_buffer_rendering(ctx);
 }
 
 static void radeonSpanRenderStart(GLcontext * ctx)
@@ -814,23 +890,30 @@
 			ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current);
 	}
 
-	radeon_map_unmap_buffers(ctx, 1);
+	radeon_map_unmap_framebuffer(ctx, ctx->DrawBuffer, GL_TRUE);
+	if (ctx->ReadBuffer != ctx->DrawBuffer)
+		radeon_map_unmap_framebuffer(ctx, ctx->ReadBuffer, GL_TRUE);
 }
 
 static void radeonSpanRenderFinish(GLcontext * ctx)
 {
 	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
 	int i;
+
 	_swrast_flush(ctx);
-	if (!rmesa->radeonScreen->driScreen->dri2.enabled) {
-		UNLOCK_HARDWARE(rmesa);
-	}
+
 	for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
 		if (ctx->Texture.Unit[i]._ReallyEnabled)
 			ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[i]._Current);
 	}
 
-	radeon_map_unmap_buffers(ctx, 0);
+	radeon_map_unmap_framebuffer(ctx, ctx->DrawBuffer, GL_FALSE);
+	if (ctx->ReadBuffer != ctx->DrawBuffer)
+		radeon_map_unmap_framebuffer(ctx, ctx->ReadBuffer, GL_FALSE);
+
+	if (!rmesa->radeonScreen->driScreen->dri2.enabled) {
+		UNLOCK_HARDWARE(rmesa);
+	}
 }
 
 void radeonInitSpanFuncs(GLcontext * ctx)
@@ -848,14 +931,24 @@
 {
 	if (rrb->base.Format == MESA_FORMAT_RGB565) {
 		radeonInitPointers_RGB565(&rrb->base);
+	} else if (rrb->base.Format == MESA_FORMAT_RGB565_REV) {
+		radeonInitPointers_RGB565_REV(&rrb->base);
 	} else if (rrb->base.Format == MESA_FORMAT_XRGB8888) {
 		radeonInitPointers_xRGB8888(&rrb->base);
+        } else if (rrb->base.Format == MESA_FORMAT_XRGB8888_REV) {
+		radeonInitPointers_BGRx8888(&rrb->base);
 	} else if (rrb->base.Format == MESA_FORMAT_ARGB8888) {
 		radeonInitPointers_ARGB8888(&rrb->base);
+        } else if (rrb->base.Format == MESA_FORMAT_ARGB8888_REV) {
+		radeonInitPointers_BGRA8888(&rrb->base);
 	} else if (rrb->base.Format == MESA_FORMAT_ARGB4444) {
 		radeonInitPointers_ARGB4444(&rrb->base);
+	} else if (rrb->base.Format == MESA_FORMAT_ARGB4444_REV) {
+		radeonInitPointers_ARGB4444_REV(&rrb->base);
 	} else if (rrb->base.Format == MESA_FORMAT_ARGB1555) {
 		radeonInitPointers_ARGB1555(&rrb->base);
+	} else if (rrb->base.Format == MESA_FORMAT_ARGB1555_REV) {
+		radeonInitPointers_ARGB1555_REV(&rrb->base);
 	} else if (rrb->base.Format == MESA_FORMAT_Z16) {
 		radeonInitDepthPointers_z16(&rrb->base);
 	} else if (rrb->base.Format == MESA_FORMAT_X8_Z24) {
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
index 4d0d35e..1c9ec36 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state.c
@@ -521,10 +521,10 @@
      return;
 
    mask = radeonPackColor( rrb->cpp,
-			   ctx->Color.ColorMask[RCOMP],
-			   ctx->Color.ColorMask[GCOMP],
-			   ctx->Color.ColorMask[BCOMP],
-			   ctx->Color.ColorMask[ACOMP] );
+			   ctx->Color.ColorMask[0][RCOMP],
+			   ctx->Color.ColorMask[0][GCOMP],
+			   ctx->Color.ColorMask[0][BCOMP],
+			   ctx->Color.ColorMask[0][ACOMP] );
 
    if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) {
       RADEON_STATECHANGE( rmesa, msk );
@@ -550,6 +550,31 @@
    rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
 }
 
+static void radeonPolygonStipplePreKMS( GLcontext *ctx, const GLubyte *mask )
+{
+   r100ContextPtr rmesa = R100_CONTEXT(ctx);
+   GLuint i;
+   drm_radeon_stipple_t stipple;
+
+   /* Must flip pattern upside down.
+    */
+   for ( i = 0 ; i < 32 ; i++ ) {
+      rmesa->state.stipple.mask[31 - i] = ((GLuint *) mask)[i];
+   }
+
+   /* TODO: push this into cmd mechanism
+    */
+   radeon_firevertices(&rmesa->radeon);
+   LOCK_HARDWARE( &rmesa->radeon );
+
+   /* FIXME: Use window x,y offsets into stipple RAM.
+    */
+   stipple.mask = rmesa->state.stipple.mask;
+   drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_STIPPLE,
+		    &stipple, sizeof(drm_radeon_stipple_t) );
+   UNLOCK_HARDWARE( &rmesa->radeon );
+}
+
 static void radeonPolygonMode( GLcontext *ctx, GLenum face, GLenum mode )
 {
    r100ContextPtr rmesa = R100_CONTEXT(ctx);
@@ -1375,7 +1400,7 @@
 void radeonUpdateWindow( GLcontext *ctx )
 {
    r100ContextPtr rmesa = R100_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
+   __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
    GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
    GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
    const GLfloat *v = ctx->Viewport._WindowMap.m;
@@ -1430,7 +1455,7 @@
 void radeonUpdateViewportOffset( GLcontext *ctx )
 {
    r100ContextPtr rmesa = R100_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
+   __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
    GLfloat xoffset = (GLfloat)dPriv->x;
    GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
    const GLfloat *v = ctx->Viewport._WindowMap.m;
diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c
index 2d19220..dd82888 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state_init.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c
@@ -645,11 +645,11 @@
      OUT_BATCH(CP_PACKET0(RADEON_PP_TXOFFSET_0 + (24 * i), 0));
      if (t->mt && !t->image_override) {
         if ((ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_CUBE_BIT)) {
-            lvl = &t->mt->levels[0];
+            lvl = &t->mt->levels[t->minLod];
 	    OUT_BATCH_RELOC(lvl->faces[5].offset, t->mt->bo, lvl->faces[5].offset,
 			RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
         } else {
-           OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0,
+           OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, get_base_teximage_offset(t),
 		     RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
         }
       } else {
diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c
index e61f59e..8bf1bfb 100644
--- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c
@@ -179,7 +179,7 @@
 
       for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
 	 if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) {
-	    GLuint sz = VB->TexCoordPtr[i]->size;
+	    GLuint sz = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size;
 
 	    switch (sz) {
 	    case 1:
@@ -309,7 +309,7 @@
    radeonEmitState(&rmesa->radeon);
    radeonEmitVertexAOS( rmesa,
 			rmesa->radeon.swtcl.vertex_size,
-			first_elem(&rmesa->radeon.dma.reserved)->bo,
+			rmesa->radeon.swtcl.bo,
 			current_offset);
 
 		      
diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c
index b334ea0..cd02bfb 100644
--- a/src/mesa/drivers/dri/radeon/radeon_tcl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c
@@ -412,6 +412,7 @@
 	space_required += vbuf;
       else
 	space_required += index + elts;
+      space_required += VB->Primitive[i].count * 3;
       space_required += AOS_BUFSZ(nr_aos);
     }
     space_required += SCISSOR_BUFSZ;
diff --git a/src/mesa/drivers/dri/radeon/radeon_tex.c b/src/mesa/drivers/dri/radeon/radeon_tex.c
index 60981aa..14163f1 100644
--- a/src/mesa/drivers/dri/radeon/radeon_tex.c
+++ b/src/mesa/drivers/dri/radeon/radeon_tex.c
@@ -341,24 +341,14 @@
       break;
 
    case GL_TEXTURE_BORDER_COLOR:
-      radeonSetTexBorderColor( t, texObj->BorderColor );
+      radeonSetTexBorderColor( t, texObj->BorderColor.f );
       break;
 
    case GL_TEXTURE_BASE_LEVEL:
    case GL_TEXTURE_MAX_LEVEL:
    case GL_TEXTURE_MIN_LOD:
    case GL_TEXTURE_MAX_LOD:
-
-      /* This isn't the most efficient solution but there doesn't appear to
-       * be a nice alternative.  Since there's no LOD clamping,
-       * we just have to rely on loading the right subset of mipmap levels
-       * to simulate a clamped LOD.
-       */
-      if (t->mt) {
-         radeon_miptree_unreference(t->mt);
-	 t->mt = 0;
-	 t->validated = GL_FALSE;
-      }
+      t->validated = GL_FALSE;
       break;
 
    default:
@@ -388,10 +378,8 @@
      }
    }
 
-   if (t->mt) {
-      radeon_miptree_unreference(t->mt);
-      t->mt = 0;
-   }
+   radeon_miptree_unreference(&t->mt);
+
    /* Free mipmap images and the texture object itself */
    _mesa_delete_texture_object(ctx, texObj);
 }
@@ -440,7 +428,7 @@
    radeonSetTexWrap( t, t->base.WrapS, t->base.WrapT );
    radeonSetTexMaxAnisotropy( t, t->base.MaxAnisotropy );
    radeonSetTexFilter( t, t->base.MinFilter, t->base.MagFilter );
-   radeonSetTexBorderColor( t, t->base.BorderColor );
+   radeonSetTexBorderColor( t, t->base.BorderColor.f );
    return &t->base;
 }
 
diff --git a/src/mesa/drivers/dri/radeon/radeon_texstate.c b/src/mesa/drivers/dri/radeon/radeon_texstate.c
index 429977a..84ddcfd 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texstate.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texstate.c
@@ -672,24 +672,13 @@
     	    return;
     	}
 
-	radeon_update_renderbuffers(pDRICtx, dPriv);
-	/* back & depth buffer are useless free them right away */
-	rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
-	if (rb && rb->bo) {
-		radeon_bo_unref(rb->bo);
-        rb->bo = NULL;
-	}
-	rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
-	if (rb && rb->bo) {
-		radeon_bo_unref(rb->bo);
-		rb->bo = NULL;
-	}
+	radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE);
 	rb = rfb->color_rb[0];
 	if (rb->bo == NULL) {
 		/* Failed to BO for the buffer */
 		return;
 	}
-	
+
 	_mesa_lock_texture(radeon->glCtx, texObj);
 	if (t->bo) {
 		radeon_bo_unref(t->bo);
@@ -699,14 +688,10 @@
 		radeon_bo_unref(rImage->bo);
 		rImage->bo = NULL;
 	}
-	if (t->mt) {
-		radeon_miptree_unreference(t->mt);
-		t->mt = NULL;
-	}
-	if (rImage->mt) {
-		radeon_miptree_unreference(rImage->mt);
-		rImage->mt = NULL;
-	}
+
+	radeon_miptree_unreference(&t->mt);
+	radeon_miptree_unreference(&rImage->mt);
+
 	_mesa_init_teximage_fields(radeon->glCtx, target, texImage,
 				   rb->base.Width, rb->base.Height, 1, 0, rb->cpp);
 	texImage->RowStride = rb->pitch / rb->cpp;
@@ -718,8 +703,6 @@
 	t->tile_bits = 0;
 	t->image_override = GL_TRUE;
 	t->override_offset = 0;
-	t->pp_txpitch &= (1 << 13) -1;
-	pitch_val = rb->pitch;
 	switch (rb->cpp) {
 	case 4:
 		if (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT)
@@ -738,12 +721,17 @@
 		t->pp_txfilter |= tx_table[MESA_FORMAT_RGB565].filter;
 		break;
 	}
-        t->pp_txsize = ((rb->base.Width - 1) << RADEON_TEX_USIZE_SHIFT)
-		   | ((rb->base.Height - 1) << RADEON_TEX_VSIZE_SHIFT);
-        t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;
-	t->pp_txpitch = pitch_val;
-        t->pp_txpitch -= 32;
 
+	t->pp_txpitch &= (1 << 13) -1;
+	pitch_val = rb->pitch;
+
+        t->pp_txsize = ((rb->base.Width - 1) << RADEON_TEX_USIZE_SHIFT)
+		| ((rb->base.Height - 1) << RADEON_TEX_VSIZE_SHIFT);
+	if (target == GL_TEXTURE_RECTANGLE_NV) {
+		t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;
+		t->pp_txpitch = pitch_val;
+		t->pp_txpitch -= 32;
+	}
 	t->validated = GL_TRUE;
 	_mesa_unlock_texture(radeon->glCtx, texObj);
 	return;
@@ -1021,7 +1009,7 @@
 	return GL_TRUE;
    }
 
-   firstImage = t->base.Image[0][t->mt->firstLevel];   
+   firstImage = t->base.Image[0][t->minLod];
 
    if (firstImage->Border > 0) {
       fprintf(stderr, "%s: border\n", __FUNCTION__);
@@ -1049,9 +1037,9 @@
 	 return GL_FALSE;
       }
    }
-   
+
    t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK;
-   t->pp_txfilter |= (t->mt->lastLevel - t->mt->firstLevel) << RADEON_MAX_MIP_LEVEL_SHIFT;
+   t->pp_txfilter |= (t->maxLod - t->minLod) << RADEON_MAX_MIP_LEVEL_SHIFT;
 	
    t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
 		       RADEON_TXFORMAT_HEIGHT_MASK |
@@ -1060,9 +1048,9 @@
 		       RADEON_TXFORMAT_F5_HEIGHT_MASK);
    t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) |
 		      (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT));
-   
+
    t->tile_bits = 0;
-   
+
    if (t->base.Target == GL_TEXTURE_CUBE_MAP) {
       ASSERT(log2Width == log2Height);
       t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_F5_WIDTH_SHIFT) |
diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c
index baa99b7..0317811 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texture.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texture.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2009 Maciej Cencora.
  * Copyright (C) 2008 Nicolai Haehnle.
  * Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
  *
@@ -46,7 +47,7 @@
 #include "radeon_mipmap_tree.h"
 
 
-static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
+void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
 	GLuint numrows, GLuint rowsize)
 {
 	assert(rowsize <= dststride);
@@ -81,8 +82,7 @@
 	radeon_texture_image* image = get_radeon_texture_image(timage);
 
 	if (image->mt) {
-		radeon_miptree_unreference(image->mt);
-		image->mt = 0;
+		radeon_miptree_unreference(&image->mt);
 		assert(!image->base.Data);
 	} else {
 		_mesa_free_texture_image_data(ctx, timage);
@@ -108,7 +108,7 @@
 	lvl = &image->mt->levels[image->mtlevel];
 
 	image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset;
-	image->base.RowStride = lvl->rowstride / image->mt->bpp;
+	image->base.RowStride = lvl->rowstride / _mesa_get_format_bytes(image->base.TexFormat);
 }
 
 
@@ -174,7 +174,7 @@
 
 	radeon_bo_map(t->mt->bo, GL_FALSE);
 	for(face = 0; face < t->mt->faces; ++face) {
-		for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
+		for(level = t->minLod; level <= t->maxLod; ++level)
 			teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level]));
 	}
 }
@@ -191,7 +191,7 @@
 	  return;
 
 	for(face = 0; face < t->mt->faces; ++face) {
-		for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
+		for(level = t->minLod; level <= t->maxLod; ++level)
 			texObj->Image[face][level]->Data = 0;
 	}
 	radeon_bo_unmap(t->mt->bo);
@@ -240,8 +240,7 @@
 			image->mtlevel = i;
 			image->mtface = face;
 
-			radeon_miptree_unreference(image->mt);
-			image->mt = NULL;
+			radeon_miptree_unreference(&image->mt);
 		}
 	}
 	
@@ -473,6 +472,19 @@
 	case GL_RGBA32F_ARB:
 		return MESA_FORMAT_RGBA_FLOAT32;
 
+#ifdef RADEON_R300
+	case GL_DEPTH_COMPONENT:
+	case GL_DEPTH_COMPONENT16:
+		return MESA_FORMAT_Z16;
+	case GL_DEPTH_COMPONENT24:
+	case GL_DEPTH_COMPONENT32:
+	case GL_DEPTH_STENCIL_EXT:
+	case GL_DEPTH24_STENCIL8_EXT:
+		if (rmesa->radeonScreen->chip_family >= CHIP_FAMILY_RV515)
+			return MESA_FORMAT_S8_Z24;
+		else
+			return MESA_FORMAT_Z16;
+#else
 	case GL_DEPTH_COMPONENT:
 	case GL_DEPTH_COMPONENT16:
 	case GL_DEPTH_COMPONENT24:
@@ -480,6 +492,7 @@
 	case GL_DEPTH_STENCIL_EXT:
 	case GL_DEPTH24_STENCIL8_EXT:
 		return MESA_FORMAT_S8_Z24;
+#endif
 
 	/* EXT_texture_sRGB */
 	case GL_SRGB:
@@ -510,6 +523,173 @@
 	return MESA_FORMAT_NONE;		/* never get here */
 }
 
+/** Check if given image is valid within current texture object.
+ */
+static int image_matches_texture_obj(struct gl_texture_object *texObj,
+	struct gl_texture_image *texImage,
+	unsigned level)
+{
+	const struct gl_texture_image *baseImage = texObj->Image[0][texObj->BaseLevel];
+
+	if (!baseImage)
+		return 0;
+
+	if (level < texObj->BaseLevel || level > texObj->MaxLevel)
+		return 0;
+
+	const unsigned levelDiff = level - texObj->BaseLevel;
+	const unsigned refWidth = MAX2(baseImage->Width >> levelDiff, 1);
+	const unsigned refHeight = MAX2(baseImage->Height >> levelDiff, 1);
+	const unsigned refDepth = MAX2(baseImage->Depth >> levelDiff, 1);
+
+	return (texImage->Width == refWidth &&
+			texImage->Height == refHeight &&
+			texImage->Depth == refDepth);
+}
+
+static void teximage_assign_miptree(radeonContextPtr rmesa,
+	struct gl_texture_object *texObj,
+	struct gl_texture_image *texImage,
+	unsigned face,
+	unsigned level)
+{
+	radeonTexObj *t = radeon_tex_obj(texObj);
+	radeon_texture_image* image = get_radeon_texture_image(texImage);
+
+	/* Since miptree holds only images for levels <BaseLevel..MaxLevel>
+	 * don't allocate the miptree if the teximage won't fit.
+	 */
+	if (!image_matches_texture_obj(texObj, texImage, level))
+		return;
+
+	/* Try using current miptree, or create new if there isn't any */
+	if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) {
+		radeon_miptree_unreference(&t->mt);
+		radeon_try_alloc_miptree(rmesa, t);
+		if (RADEON_DEBUG & RADEON_TEXTURE) {
+			fprintf(stderr, "%s: texObj %p, texImage %p, face %d, level %d, "
+				"texObj miptree doesn't match, allocated new miptree %p\n",
+				__FUNCTION__, texObj, texImage, face, level, t->mt);
+		}
+	}
+
+	/* Miptree alocation may have failed,
+	 * when there was no image for baselevel specified */
+	if (t->mt) {
+		image->mtface = face;
+		image->mtlevel = level;
+		radeon_miptree_reference(t->mt, &image->mt);
+	}
+}
+
+static GLuint * allocate_image_offsets(GLcontext *ctx,
+	unsigned alignedWidth,
+	unsigned height,
+	unsigned depth)
+{
+	int i;
+	GLuint *offsets;
+
+	offsets = _mesa_malloc(depth * sizeof(GLuint)) ;
+	if (!offsets) {
+		_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex[Sub]Image");
+		return NULL;
+	}
+
+	for (i = 0; i < depth; ++i) {
+		offsets[i] = alignedWidth * height * i;
+	}
+
+	return offsets;
+}
+
+/**
+ * Update a subregion of the given texture image.
+ */
+static void radeon_store_teximage(GLcontext* ctx, int dims,
+		GLint xoffset, GLint yoffset, GLint zoffset,
+		GLsizei width, GLsizei height, GLsizei depth,
+		GLsizei imageSize,
+		GLenum format, GLenum type,
+		const GLvoid * pixels,
+		const struct gl_pixelstore_attrib *packing,
+		struct gl_texture_object *texObj,
+		struct gl_texture_image *texImage,
+		int compressed)
+{
+	radeonTexObj *t = radeon_tex_obj(texObj);
+	radeon_texture_image* image = get_radeon_texture_image(texImage);
+
+	GLuint dstRowStride;
+	GLuint *dstImageOffsets;
+
+	if (image->mt) {
+		dstRowStride = image->mt->levels[image->mtlevel].rowstride;
+	} else if (t->bo) {
+		/* TFP case */
+		/* TODO */
+		assert(0);
+	} else {
+		dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
+	}
+
+	assert(dstRowStride);
+
+	if (dims == 3) {
+		unsigned alignedWidth = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat);
+		dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, texImage->Height, texImage->Depth);
+		if (!dstImageOffsets) {
+			return;
+		}
+	} else {
+		dstImageOffsets = texImage->ImageOffsets;
+	}
+
+	radeon_teximage_map(image, GL_TRUE);
+
+	if (compressed) {
+		uint32_t srcRowStride, bytesPerRow, rows, block_width, block_height;
+		GLubyte *img_start;
+
+		_mesa_get_format_block_size(texImage->TexFormat, &block_width, &block_height);
+
+		if (!image->mt) {
+			dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
+			img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
+									texImage->TexFormat,
+									texImage->Width, texImage->Data);
+		}
+		else {
+			uint32_t offset;
+			offset = dstRowStride / _mesa_get_format_bytes(texImage->TexFormat) * yoffset / block_height + xoffset / block_width;
+			offset *= _mesa_get_format_bytes(texImage->TexFormat);
+			img_start = texImage->Data + offset;
+		}
+		srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
+		bytesPerRow = srcRowStride;
+		rows = (height + block_height - 1) / block_height;
+
+		copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow);
+	}
+	else {
+		if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
+					texImage->TexFormat, texImage->Data,
+					xoffset, yoffset, zoffset,
+					dstRowStride,
+					dstImageOffsets,
+					width, height, depth,
+					format, type, pixels, packing)) {
+			_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
+		}
+	}
+
+	if (dims == 3) {
+		_mesa_free(dstImageOffsets);
+	}
+
+	radeon_teximage_unmap(image);
+}
+
 /**
  * All glTexImage calls go through this function.
  */
@@ -528,13 +708,22 @@
 	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
 	radeonTexObj* t = radeon_tex_obj(texObj);
 	radeon_texture_image* image = get_radeon_texture_image(texImage);
-	GLuint dstRowStride;
 	GLint postConvWidth = width;
 	GLint postConvHeight = height;
-	GLuint texelBytes;
 	GLuint face = radeon_face_for_target(target);
 
-	radeon_firevertices(rmesa);
+	{
+		struct radeon_bo *bo;
+		bo = !image->mt ? image->bo : image->mt->bo;
+		if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
+			radeon_firevertices(rmesa);
+		}
+	}
+
+	if (RADEON_DEBUG & RADEON_TEXTURE) {
+		fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, face %d, level %d\n",
+				dims, texObj, texImage, face, level);
+	}
 
 	t->validated = GL_FALSE;
 
@@ -543,53 +732,35 @@
 						  &postConvHeight);
 	}
 
-	if (_mesa_is_format_compressed(texImage->TexFormat)) {
-		texelBytes = 0;
-	} else {
-		texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
+	if (!_mesa_is_format_compressed(texImage->TexFormat)) {
+		GLuint texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
 		/* Minimum pitch of 32 bytes */
 		if (postConvWidth * texelBytes < 32) {
-		  postConvWidth = 32 / texelBytes;
-		  texImage->RowStride = postConvWidth;
+			postConvWidth = 32 / texelBytes;
+			texImage->RowStride = postConvWidth;
 		}
-		if (!image->mt) {      
+		if (!image->mt) {
 			assert(texImage->RowStride == postConvWidth);
 		}
 	}
 
-	/* Allocate memory for image */
-	radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */
+	/* Mesa core only clears texImage->Data but not image->mt */
+	radeonFreeTexImageData(ctx, texImage);
 
-	if (t->mt &&
-	    t->mt->firstLevel == level &&
-	    t->mt->lastLevel == level &&
-	    t->mt->target != GL_TEXTURE_CUBE_MAP_ARB &&
-	    !radeon_miptree_matches_image(t->mt, texImage, face, level)) {
-	  radeon_miptree_unreference(t->mt);
-	  t->mt = NULL;
-	}
-
-	if (!t->mt)
-		radeon_try_alloc_miptree(rmesa, t, image, face, level);
-	if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) {
-		radeon_mipmap_level *lvl;
-		image->mt = t->mt;
-		image->mtlevel = level - t->mt->firstLevel;
-		image->mtface = face;
-		radeon_miptree_reference(t->mt);
-		lvl = &image->mt->levels[image->mtlevel];
-		dstRowStride = lvl->rowstride;
-	} else {
-		int size;
-		if (_mesa_is_format_compressed(texImage->TexFormat)) {
-			size = _mesa_format_image_size(texImage->TexFormat,
-						       texImage->Width,
-						       texImage->Height,
-						       texImage->Depth);
-		} else {
-			size = texImage->Width * texImage->Height * texImage->Depth * _mesa_get_format_bytes(texImage->TexFormat);
+	if (!t->bo) {
+		teximage_assign_miptree(rmesa, texObj, texImage, face, level);
+		if (!image->mt) {
+			int size = _mesa_format_image_size(texImage->TexFormat,
+								texImage->Width,
+								texImage->Height,
+								texImage->Depth);
+			texImage->Data = _mesa_alloc_texmemory(size);
+			if (RADEON_DEBUG & RADEON_TEXTURE) {
+				fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, "
+					" no miptree assigned, using local memory %p\n",
+					dims, texObj, texImage, texImage->Data);
+			}
 		}
-		texImage->Data = _mesa_alloc_texmemory(size);
 	}
 
 	/* Upload texture image; note that the spec allows pixels to be NULL */
@@ -603,65 +774,16 @@
 	}
 
 	if (pixels) {
-		radeon_teximage_map(image, GL_TRUE);
-		if (compressed) {
-			if (image->mt) {
-				uint32_t srcRowStride, bytesPerRow, rows;
-				srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
-				bytesPerRow = srcRowStride;
-				rows = (height + 3) / 4;
-				copy_rows(texImage->Data, image->mt->levels[level].rowstride,
-					  pixels, srcRowStride, rows, bytesPerRow);
-			} else {
-				memcpy(texImage->Data, pixels, imageSize);
-			}
-		} else {
-			GLuint dstRowStride;
-			GLuint *dstImageOffsets;
-
-			if (image->mt) {
-				radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
-				dstRowStride = lvl->rowstride;
-			} else {
-				dstRowStride = texImage->Width * _mesa_get_format_bytes(texImage->TexFormat);
-			}
-
-			if (dims == 3) {
-				int i;
-
-				dstImageOffsets = _mesa_malloc(depth * sizeof(GLuint)) ;
-				if (!dstImageOffsets)
-					_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
-
-				for (i = 0; i < depth; ++i) {
-					dstImageOffsets[i] = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat) * height * i;
-				}
-			} else {
-				dstImageOffsets = texImage->ImageOffsets;
-			}
-
-			if (!_mesa_texstore(ctx, dims,
-					    texImage->_BaseFormat,
-					    texImage->TexFormat,
-					    texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
-					    dstRowStride,
-					    dstImageOffsets,
-					    width, height, depth,
-					    format, type, pixels, packing)) {
-				_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
-			}
-
-			if (dims == 3)
-				_mesa_free(dstImageOffsets);
-		}
+		radeon_store_teximage(ctx, dims,
+			0, 0, 0,
+			width, height, depth,
+			imageSize, format, type,
+			pixels, packing,
+			texObj, texImage,
+			compressed);
 	}
 
 	_mesa_unmap_teximage_pbo(ctx, packing);
-
-	if (pixels)
-	  radeon_teximage_unmap(image);
-
-
 }
 
 void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
@@ -714,7 +836,7 @@
 }
 
 /**
- * Update a subregion of the given texture image.
+ * All glTexSubImage calls go through this function.
  */
 static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int level,
 		GLint xoffset, GLint yoffset, GLint zoffset,
@@ -731,66 +853,39 @@
 	radeonTexObj* t = radeon_tex_obj(texObj);
 	radeon_texture_image* image = get_radeon_texture_image(texImage);
 
-	radeon_firevertices(rmesa);
+	{
+		struct radeon_bo *bo;
+		bo = !image->mt ? image->bo : image->mt->bo;
+		if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
+			radeon_firevertices(rmesa);
+		}
+	}
+
+	if (RADEON_DEBUG & RADEON_TEXTURE) {
+		fprintf(stderr, "radeon_texsubimage%dd: texObj %p, texImage %p, face %d, level %d\n",
+				dims, texObj, texImage, radeon_face_for_target(target), level);
+	}
 
 	t->validated = GL_FALSE;
 	if (compressed) {
 		pixels = _mesa_validate_pbo_compressed_teximage(
-			ctx, imageSize, pixels, packing, "glCompressedTexImage");
+			ctx, imageSize, pixels, packing, "glCompressedTexSubImage");
 	} else {
 		pixels = _mesa_validate_pbo_teximage(ctx, dims,
-			width, height, depth, format, type, pixels, packing, "glTexSubImage1D");
+			width, height, depth, format, type, pixels, packing, "glTexSubImage");
 	}
 
 	if (pixels) {
-		GLint dstRowStride;
-		radeon_teximage_map(image, GL_TRUE);
-
-		if (image->mt) {
-			radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
-			dstRowStride = lvl->rowstride;
-		} else {
-			dstRowStride = texImage->RowStride * _mesa_get_format_bytes(texImage->TexFormat);
-		}
-
-		if (compressed) {
-			uint32_t srcRowStride, bytesPerRow, rows;
-			GLubyte *img_start;
-			if (!image->mt) {
-				dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
-				img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
-									   texImage->TexFormat,
-									   texImage->Width, texImage->Data);
-			}
-			else {
-				uint32_t blocks_x = dstRowStride / (image->mt->bpp * 4);
-				img_start = texImage->Data + image->mt->bpp * 4 * (blocks_x * (yoffset / 4) + xoffset / 4);
-			}
-			srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
-			bytesPerRow = srcRowStride;
-			rows = (height + 3) / 4;
-
-			copy_rows(img_start, dstRowStride,  pixels, srcRowStride, rows,  bytesPerRow);
-			
-		}
-		else {
-			if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
-					    texImage->TexFormat, texImage->Data,
-					    xoffset, yoffset, zoffset,
-					    dstRowStride,
-					    texImage->ImageOffsets,
-					    width, height, depth,
-					    format, type, pixels, packing)) {
-				_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
-			}
-		}
+		radeon_store_teximage(ctx, dims,
+			xoffset, yoffset, zoffset,
+			width, height, depth,
+			imageSize, format, type,
+			pixels, packing,
+			texObj, texImage,
+			compressed);
 	}
 
-	radeon_teximage_unmap(image);
-
 	_mesa_unmap_teximage_pbo(ctx, packing);
-
-
 }
 
 void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
@@ -846,143 +941,6 @@
 		format, type, pixels, packing, texObj, texImage, 0);
 }
 
-
-
-/**
- * Ensure that the given image is stored in the given miptree from now on.
- */
-static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level)
-{
-	radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel];
-	unsigned char *dest;
-
-	assert(image->mt != mt);
-	assert(dstlvl->width == image->base.Width);
-	assert(dstlvl->height == image->base.Height);
-	assert(dstlvl->depth == image->base.Depth);
-
-
-	radeon_bo_map(mt->bo, GL_TRUE);
-	dest = mt->bo->ptr + dstlvl->faces[face].offset;
-
-	if (image->mt) {
-		/* Format etc. should match, so we really just need a memcpy().
-		 * In fact, that memcpy() could be done by the hardware in many
-		 * cases, provided that we have a proper memory manager.
-		 */
-		radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel-image->mt->firstLevel];
-
-		assert(srclvl->size == dstlvl->size);
-		assert(srclvl->rowstride == dstlvl->rowstride);
-
-		radeon_bo_map(image->mt->bo, GL_FALSE);
-
-		memcpy(dest,
-			image->mt->bo->ptr + srclvl->faces[face].offset,
-			dstlvl->size);
-		radeon_bo_unmap(image->mt->bo);
-
-		radeon_miptree_unreference(image->mt);
-	} else {
-		uint32_t srcrowstride;
-		uint32_t height;
-		/* need to confirm this value is correct */
-		if (mt->compressed) {
-			height = (image->base.Height + 3) / 4;
-			srcrowstride = _mesa_format_row_stride(image->base.TexFormat, image->base.Width);
-		} else {
-			height = image->base.Height * image->base.Depth;
-			srcrowstride = image->base.Width * _mesa_get_format_bytes(image->base.TexFormat);
-		}
-
-//		if (mt->tilebits)
-//			WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
-
-		copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
-			  height, srcrowstride);
-
-		_mesa_free_texmemory(image->base.Data);
-		image->base.Data = 0;
-	}
-
-	radeon_bo_unmap(mt->bo);
-
-	image->mt = mt;
-	image->mtface = face;
-	image->mtlevel = level;
-	radeon_miptree_reference(image->mt);
-}
-
-int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj)
-{
-	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-	radeonTexObj *t = radeon_tex_obj(texObj);
-	radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]);
-	int face, level;
-
-	if (t->validated || t->image_override)
-		return GL_TRUE;
-
-	if (RADEON_DEBUG & RADEON_TEXTURE)
-		fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj);
-
-	if (baseimage->base.Border > 0)
-		return GL_FALSE;
-
-	/* Ensure a matching miptree exists.
-	 *
-	 * Differing mipmap trees can result when the app uses TexImage to
-	 * change texture dimensions.
-	 *
-	 * Prefer to use base image's miptree if it
-	 * exists, since that most likely contains more valid data (remember
-	 * that the base level is usually significantly larger than the rest
-	 * of the miptree, so cubemaps are the only possible exception).
-	 */
-	if (baseimage->mt &&
-	    baseimage->mt != t->mt &&
-	    radeon_miptree_matches_texture(baseimage->mt, &t->base)) {
-		radeon_miptree_unreference(t->mt);
-		t->mt = baseimage->mt;
-		radeon_miptree_reference(t->mt);
-	} else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) {
-		radeon_miptree_unreference(t->mt);
-		t->mt = 0;
-	}
-
-	if (!t->mt) {
-		if (RADEON_DEBUG & RADEON_TEXTURE)
-			fprintf(stderr, " Allocate new miptree\n");
-		radeon_try_alloc_miptree(rmesa, t, baseimage, 0, texObj->BaseLevel);
-		if (!t->mt) {
-			_mesa_problem(ctx, "radeon_validate_texture failed to alloc miptree");
-			return GL_FALSE;
-		}
-	}
-
-	/* Ensure all images are stored in the single main miptree */
-	for(face = 0; face < t->mt->faces; ++face) {
-		for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) {
-			radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]);
-			if (RADEON_DEBUG & RADEON_TEXTURE)
-				fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt);
-			if (t->mt == image->mt || (!image->mt && !image->base.Data)) {
-				if (RADEON_DEBUG & RADEON_TEXTURE)
-					fprintf(stderr, "OK\n");
-
-				continue;
-			}
-
-			if (RADEON_DEBUG & RADEON_TEXTURE)
-				fprintf(stderr, "migrating\n");
-			migrate_image_to_miptree(t->mt, image, face, level);
-		}
-	}
-
-	return GL_TRUE;
-}
-
-
 /**
  * Need to map texture image into memory before copying image data,
  * then unmap it.
diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.h b/src/mesa/drivers/dri/radeon/radeon_texture.h
index 8995546..906daf1 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texture.h
+++ b/src/mesa/drivers/dri/radeon/radeon_texture.h
@@ -33,7 +33,8 @@
 
 #include "main/formats.h"
 
-
+void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
+	GLuint numrows, GLuint rowsize);
 struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx);
 void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage);
 
diff --git a/src/mesa/drivers/dri/savage/savage_init.h b/src/mesa/drivers/dri/savage/savage_init.h
index abb8440..bfd3077 100644
--- a/src/mesa/drivers/dri/savage/savage_init.h
+++ b/src/mesa/drivers/dri/savage/savage_init.h
@@ -66,7 +66,7 @@
    unsigned int logTextureGranularity[SAVAGE_NR_TEX_HEAPS];
    drmAddress texVirtual[SAVAGE_NR_TEX_HEAPS];
   
-   __DRIscreenPrivate *driScrnPriv;
+   __DRIscreen *driScrnPriv;
 
    savageRegion aperture;
    savageRegion agpTextures;
diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c
index d307b81..8e879ca 100644
--- a/src/mesa/drivers/dri/savage/savage_xmesa.c
+++ b/src/mesa/drivers/dri/savage/savage_xmesa.c
@@ -168,7 +168,7 @@
 };
 
 static GLboolean
-savageInitDriver(__DRIscreenPrivate *sPriv)
+savageInitDriver(__DRIscreen *sPriv)
 {
   savageScreenPrivate *savageScreen;
   SAVAGEDRIPtr         gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv;
@@ -272,7 +272,7 @@
 /* Accessed by dlsym from dri_mesa_init.c
  */
 static void
-savageDestroyScreen(__DRIscreenPrivate *sPriv)
+savageDestroyScreen(__DRIscreen *sPriv)
 {
    savageScreenPrivate *savageScreen = (savageScreenPrivate *)sPriv->private;
 
@@ -288,12 +288,12 @@
 
 static GLboolean
 savageCreateContext( const __GLcontextModes *mesaVis,
-		     __DRIcontextPrivate *driContextPriv,
+		     __DRIcontext *driContextPriv,
 		     void *sharedContextPrivate )
 {
    GLcontext *ctx, *shareCtx;
    savageContextPtr imesa;
-   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
    struct dd_function_table functions;
    savageScreenPrivate *savageScreen = (savageScreenPrivate *)sPriv->private;
    drm_savage_sarea_t *saPriv=(drm_savage_sarea_t *)(((char*)sPriv->pSAREA)+
@@ -546,7 +546,7 @@
 }
 
 static void
-savageDestroyContext(__DRIcontextPrivate *driContextPriv)
+savageDestroyContext(__DRIcontext *driContextPriv)
 {
    savageContextPtr imesa = (savageContextPtr) driContextPriv->driverPrivate;
    GLuint i;
@@ -580,8 +580,8 @@
 
 
 static GLboolean
-savageCreateBuffer( __DRIscreenPrivate *driScrnPriv,
-		    __DRIdrawablePrivate *driDrawPriv,
+savageCreateBuffer( __DRIscreen *driScrnPriv,
+		    __DRIdrawable *driDrawPriv,
 		    const __GLcontextModes *mesaVis,
 		    GLboolean isPixmap)
 {
@@ -675,13 +675,13 @@
 }
 
 static void
-savageDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+savageDestroyBuffer(__DRIdrawable *driDrawPriv)
 {
    _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
 }
 
 #if 0
-void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv)
+void XMesaSwapBuffers(__DRIdrawable *driDrawPriv)
 {
    /* XXX should do swap according to the buffer, not the context! */
    savageContextPtr imesa = savageCtx; 
@@ -694,7 +694,7 @@
 
 void savageXMesaSetClipRects(savageContextPtr imesa)
 {
-   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+   __DRIdrawable *dPriv = imesa->driDrawable;
 
    if ((dPriv->numBackClipRects == 0)
        || (imesa->glCtx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT)) {
@@ -715,8 +715,8 @@
 
 static void savageXMesaWindowMoved( savageContextPtr imesa ) 
 {
-   __DRIdrawablePrivate *const drawable = imesa->driDrawable;
-   __DRIdrawablePrivate *const readable = imesa->driReadable;
+   __DRIdrawable *const drawable = imesa->driDrawable;
+   __DRIdrawable *const readable = imesa->driReadable;
 
    if (0)
       fprintf(stderr, "savageXMesaWindowMoved\n\n");
@@ -731,7 +731,7 @@
 
 
 static GLboolean
-savageUnbindContext(__DRIcontextPrivate *driContextPriv)
+savageUnbindContext(__DRIcontext *driContextPriv)
 {
    savageContextPtr savage = (savageContextPtr) driContextPriv->driverPrivate;
    if (savage)
@@ -742,7 +742,7 @@
 
 #if 0
 static GLboolean
-savageOpenFullScreen(__DRIcontextPrivate *driContextPriv)
+savageOpenFullScreen(__DRIcontext *driContextPriv)
 {
     
   
@@ -761,7 +761,7 @@
 }
 
 static GLboolean
-savageCloseFullScreen(__DRIcontextPrivate *driContextPriv)
+savageCloseFullScreen(__DRIcontext *driContextPriv)
 {
     
     if (driContextPriv) {
@@ -777,9 +777,9 @@
 #endif
 
 static GLboolean
-savageMakeCurrent(__DRIcontextPrivate *driContextPriv,
-		  __DRIdrawablePrivate *driDrawPriv,
-		  __DRIdrawablePrivate *driReadPriv)
+savageMakeCurrent(__DRIcontext *driContextPriv,
+		  __DRIdrawable *driDrawPriv,
+		  __DRIdrawable *driReadPriv)
 {
    if (driContextPriv) {
       savageContextPtr imesa
@@ -816,9 +816,9 @@
 
 void savageGetLock( savageContextPtr imesa, GLuint flags ) 
 {
-   __DRIdrawablePrivate *const drawable = imesa->driDrawable;
-   __DRIdrawablePrivate *const readable = imesa->driReadable;
-   __DRIscreenPrivate *sPriv = imesa->driScreen;
+   __DRIdrawable *const drawable = imesa->driDrawable;
+   __DRIdrawable *const readable = imesa->driReadable;
+   __DRIscreen *sPriv = imesa->driScreen;
    drm_savage_sarea_t *sarea = imesa->sarea;
    int me = imesa->hHWContext;
    int stamp = drawable->lastStamp; 
@@ -883,7 +883,7 @@
 }
 
 static const  __DRIconfig **
-savageFillInModes( __DRIscreenPrivate *psp,
+savageFillInModes( __DRIscreen *psp,
 		   unsigned pixel_bits, unsigned depth_bits,
 		   unsigned stencil_bits, GLboolean have_back_buffer )
 {
@@ -967,7 +967,7 @@
  * \return the __GLcontextModes supported by this driver
  */
 static const __DRIconfig **
-savageInitScreen(__DRIscreenPrivate *psp)
+savageInitScreen(__DRIscreen *psp)
 {
    static const __DRIversion ddx_expected = { 2, 0, 0 };
    static const __DRIversion dri_expected = { 4, 0, 0 };
@@ -1001,3 +1001,10 @@
    savageMakeCurrent,
    savageUnbindContext
 };
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driLegacyExtension.base,
+    NULL
+};
diff --git a/src/mesa/drivers/dri/savage/savagecontext.h b/src/mesa/drivers/dri/savage/savagecontext.h
index 53a37db..ba1e6e1 100644
--- a/src/mesa/drivers/dri/savage/savagecontext.h
+++ b/src/mesa/drivers/dri/savage/savagecontext.h
@@ -271,10 +271,10 @@
     drm_hw_lock_t *driHwLock;
     GLuint driFd;
 
-    __DRIdrawablePrivate *driDrawable;
-    __DRIdrawablePrivate *driReadable;
+    __DRIdrawable *driDrawable;
+    __DRIdrawable *driReadable;
 
-    __DRIscreenPrivate *driScreen;
+    __DRIscreen *driScreen;
     savageScreenPrivate *savageScreen; 
     drm_savage_sarea_t *sarea;
 
diff --git a/src/mesa/drivers/dri/savage/savageioctl.c b/src/mesa/drivers/dri/savage/savageioctl.c
index 948ed18..d0b64e8 100644
--- a/src/mesa/drivers/dri/savage/savageioctl.c
+++ b/src/mesa/drivers/dri/savage/savageioctl.c
@@ -337,6 +337,8 @@
    GLint ch = ctx->DrawBuffer->_Ymax - cy;
 
    /* XXX FIX ME: the cx,cy,cw,ch vars are currently ignored! */
+   (void) ch;
+   (void) cw;
 
    if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
        fprintf (stderr, "%s\n", __FUNCTION__);
@@ -358,15 +360,15 @@
    depthMask = 0;
    switch (imesa->savageScreen->cpp) {
    case 2:
-       colorMask = PACK_COLOR_565(ctx->Color.ColorMask[0],
-				  ctx->Color.ColorMask[1],
-				  ctx->Color.ColorMask[2]);
+       colorMask = PACK_COLOR_565(ctx->Color.ColorMask[0][0],
+				  ctx->Color.ColorMask[0][1],
+				  ctx->Color.ColorMask[0][2]);
        break;
    case 4:
-       colorMask = PACK_COLOR_8888(ctx->Color.ColorMask[3],
-				   ctx->Color.ColorMask[2],
-				   ctx->Color.ColorMask[1],
-				   ctx->Color.ColorMask[0]);
+       colorMask = PACK_COLOR_8888(ctx->Color.ColorMask[0][3],
+				   ctx->Color.ColorMask[0][2],
+				   ctx->Color.ColorMask[0][1],
+				   ctx->Color.ColorMask[0][0]);
        break;
    }
 
@@ -431,7 +433,7 @@
 /*
  * Copy the back buffer to the front buffer. 
  */
-void savageSwapBuffers( __DRIdrawablePrivate *dPriv )
+void savageSwapBuffers( __DRIdrawable *dPriv )
 {
    savageContextPtr imesa;
 
@@ -535,7 +537,7 @@
 
 void savageFlushCmdBufLocked( savageContextPtr imesa, GLboolean discard )
 {
-    __DRIdrawablePrivate *dPriv = imesa->driDrawable;
+    __DRIdrawable *dPriv = imesa->driDrawable;
 
     if (!imesa->dmaVtxBuf.total)
 	discard = GL_FALSE;
diff --git a/src/mesa/drivers/dri/savage/savageioctl.h b/src/mesa/drivers/dri/savage/savageioctl.h
index 639605c..e7e8081 100644
--- a/src/mesa/drivers/dri/savage/savageioctl.h
+++ b/src/mesa/drivers/dri/savage/savageioctl.h
@@ -39,7 +39,7 @@
 
 void savageDDInitIoctlFuncs( GLcontext *ctx );
 
-void savageSwapBuffers( __DRIdrawablePrivate *dPriv );
+void savageSwapBuffers( __DRIdrawable *dPriv );
 
 #define WAIT_IDLE_EMPTY(imesa) do { \
     if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG) \
diff --git a/src/mesa/drivers/dri/savage/savagerender.c b/src/mesa/drivers/dri/savage/savagerender.c
index 32c74f9..8221edf 100644
--- a/src/mesa/drivers/dri/savage/savagerender.c
+++ b/src/mesa/drivers/dri/savage/savagerender.c
@@ -252,13 +252,13 @@
          const GLboolean normalizeS = (texObj->WrapS == GL_REPEAT);
          const GLboolean normalizeT = (reallyEnabled & TEXTURE_2D_BIT) &&
             (texObj->WrapT == GL_REPEAT);
-         const GLfloat *in = (GLfloat *)VB->TexCoordPtr[i]->data;
-         const GLint instride = VB->TexCoordPtr[i]->stride;
+         const GLfloat *in = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->data;
+         const GLint instride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->stride;
          GLfloat (*out)[4] = store->texcoord[i].data;
          GLint j;
 
          if (!ctx->Texture.Unit[i]._ReallyEnabled ||
-             VB->TexCoordPtr[i]->size == 4)
+             VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size == 4)
             /* Never try to normalize homogenous tex coords! */
             continue;
 
@@ -297,7 +297,7 @@
          }
 
          if (normalizeS || normalizeT)
-            VB->AttribPtr[VERT_ATTRIB_TEX0+i] = VB->TexCoordPtr[i] = &store->texcoord[i];
+            VB->AttribPtr[_TNL_ATTRIB_TEX0 + i] = &store->texcoord[i];
       }
    }
 
diff --git a/src/mesa/drivers/dri/savage/savagespan.c b/src/mesa/drivers/dri/savage/savagespan.c
index 3bb6fbc..792e166 100644
--- a/src/mesa/drivers/dri/savage/savagespan.c
+++ b/src/mesa/drivers/dri/savage/savagespan.c
@@ -34,7 +34,7 @@
 
 #define LOCAL_VARS						\
    driRenderbuffer *drb = (driRenderbuffer *) rb;		\
-   __DRIdrawablePrivate *const dPriv = drb->dPriv;		\
+   __DRIdrawable *const dPriv = drb->dPriv;		\
    GLuint cpp   = drb->cpp;					\
    GLuint pitch = drb->pitch;					\
    GLuint height = dPriv->h;					\
@@ -44,7 +44,7 @@
 
 #define LOCAL_DEPTH_VARS					\
    driRenderbuffer *drb = (driRenderbuffer *) rb;		\
-   __DRIdrawablePrivate *const dPriv = drb->dPriv;		\
+   __DRIdrawable *const dPriv = drb->dPriv;		\
    GLuint zpp   = drb->cpp;					\
    GLuint pitch = drb->pitch;					\
    GLuint height = dPriv->h;					\
diff --git a/src/mesa/drivers/dri/savage/savagetex.c b/src/mesa/drivers/dri/savage/savagetex.c
index 6c97bb6..97598f5 100644
--- a/src/mesa/drivers/dri/savage/savagetex.c
+++ b/src/mesa/drivers/dri/savage/savagetex.c
@@ -507,7 +507,7 @@
 
       savageSetTexWrapping(t,texObj->WrapS,texObj->WrapT);
       savageSetTexFilter(t,texObj->MinFilter,texObj->MagFilter);
-      savageSetTexBorderColor(t,texObj->BorderColor);
+      savageSetTexBorderColor(t,texObj->BorderColor.f);
    }
 
    return t;
@@ -2044,7 +2044,7 @@
       break;
   
    case GL_TEXTURE_BORDER_COLOR:
-      savageSetTexBorderColor(t,tObj->BorderColor);
+      savageSetTexBorderColor(t,tObj->BorderColor.f);
       break;
 
    default:
diff --git a/src/mesa/drivers/dri/savage/savagetris.c b/src/mesa/drivers/dri/savage/savagetris.c
index c04763b..9a92541 100644
--- a/src/mesa/drivers/dri/savage/savagetris.c
+++ b/src/mesa/drivers/dri/savage/savagetris.c
@@ -435,7 +435,8 @@
 
 #define LOCAL_VARS(n)						\
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);		\
-   GLuint color[n], spec[n];					\
+   GLuint color[n] = { 0 };					\
+   GLuint spec[n] = { 0 };					\
    GLuint coloroffset =						\
       ((imesa->skip & SAVAGE_SKIP_W) ? 3 : 4);			\
    GLboolean specoffset =					\
@@ -879,13 +880,13 @@
 
    RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
 
-   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 ) && VB->TexCoordPtr[0]->size == 4) {
+   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 ) && VB->AttribPtr[_TNL_ATTRIB_TEX0]->size == 4) {
       if (!RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_ATTRIB_TEX1, _TNL_LAST_TEX ))
 	 return GL_TRUE; /* apply ptex hack */
       else
 	 FALLBACK(ctx, SAVAGE_FALLBACK_PROJ_TEXTURE, GL_TRUE);
    }
-   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 ) && VB->TexCoordPtr[1]->size == 4)
+   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 ) && VB->AttribPtr[_TNL_ATTRIB_TEX1]->size == 4)
       FALLBACK(ctx, SAVAGE_FALLBACK_PROJ_TEXTURE, GL_TRUE);
 
    return GL_FALSE; /* don't apply ptex hack */
@@ -976,13 +977,13 @@
    if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 )) {
       if (imesa->ptexHack)
 	 EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, SAVAGE_EMIT_STQ0, SAVAGE_SKIP_ST0);
-      else if (VB->TexCoordPtr[0]->size == 4)
+      else if (VB->AttribPtr[_TNL_ATTRIB_TEX0]->size == 4)
 	 assert (0); /* should be caught by savageCheckPTexHack */
-      else if (VB->TexCoordPtr[0]->size >= 2)
+      else if (VB->AttribPtr[_TNL_ATTRIB_TEX0]->size >= 2)
 	 /* The chromium menu emits some 3D tex coords even though no
 	  * 3D texture is enabled. Ignore the 3rd coordinate. */
 	 EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, SAVAGE_EMIT_ST0, SAVAGE_SKIP_ST0 );
-      else if (VB->TexCoordPtr[0]->size == 1) {
+      else if (VB->AttribPtr[_TNL_ATTRIB_TEX0]->size == 1) {
 	 EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_1F, SAVAGE_EMIT_S0, SAVAGE_SKIP_S0 );
 	 EMIT_PAD( 4 );
       } else
@@ -1025,9 +1026,9 @@
    if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 )) {
       if (imesa->ptexHack)
 	 NEED_ATTR( SAVAGE_EMIT_STQ0, SAVAGE_SKIP_ST0);
-      else if (VB->TexCoordPtr[0]->size == 4)
+      else if (VB->AttribPtr[_TNL_ATTRIB_TEX0]->size == 4)
 	 assert (0); /* should be caught by savageCheckPTexHack */
-      else if (VB->TexCoordPtr[0]->size >= 2)
+      else if (VB->AttribPtr[_TNL_ATTRIB_TEX0]->size >= 2)
 	 /* The chromium menu emits some 3D tex coords even though no
 	  * 3D texture is enabled. Ignore the 3rd coordinate. */
 	 NEED_ATTR( SAVAGE_EMIT_ST0, SAVAGE_SKIP_ST0 );
@@ -1035,10 +1036,10 @@
 	 NEED_ATTR( SAVAGE_EMIT_S0, SAVAGE_SKIP_S0 );
    }
    if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 )) {
-      if (VB->TexCoordPtr[1]->size == 4)
+      if (VB->AttribPtr[_TNL_ATTRIB_TEX1]->size == 4)
 	 /* projective textures are not supported by the hardware */
 	 assert (0); /* should be caught by savageCheckPTexHack */
-      else if (VB->TexCoordPtr[1]->size >= 2)
+      else if (VB->AttribPtr[_TNL_ATTRIB_TEX1]->size >= 2)
 	 NEED_ATTR( SAVAGE_EMIT_ST1, SAVAGE_SKIP_ST1 );
       else
 	 NEED_ATTR( SAVAGE_EMIT_S1, SAVAGE_SKIP_S1 );
diff --git a/src/mesa/drivers/dri/sis/sis_clear.c b/src/mesa/drivers/dri/sis/sis_clear.c
index 323383d..d358ef6 100644
--- a/src/mesa/drivers/dri/sis/sis_clear.c
+++ b/src/mesa/drivers/dri/sis/sis_clear.c
@@ -393,7 +393,6 @@
 			    GLint x, GLint y, GLint width, GLint height )
 {
    sisContextPtr smesa = SIS_CONTEXT(ctx);
-   int cmd;
 
    mWait3DCmdQueue (8);
    MMIO(REG_SRC_PITCH, (smesa->zFormat == SiS_ZFORMAT_Z16) ?
diff --git a/src/mesa/drivers/dri/sis/sis_context.c b/src/mesa/drivers/dri/sis/sis_context.c
index f501e7a..0944f4d 100644
--- a/src/mesa/drivers/dri/sis/sis_context.c
+++ b/src/mesa/drivers/dri/sis/sis_context.c
@@ -83,6 +83,7 @@
     { NULL,                                NULL }
 };
 
+#if 0
 static struct dri_extension card_extensions_6326[] =
 {
     /*{ "GL_ARB_texture_border_clamp",       NULL },*/
@@ -90,6 +91,7 @@
     /*{ "GL_MESA_ycbcr_texture",             NULL },*/
     { NULL,                                NULL }
 };
+#endif
 
 static const struct dri_debug_control debug_control[] =
 {
@@ -160,11 +162,11 @@
 
 GLboolean
 sisCreateContext( const __GLcontextModes *glVisual,
-		  __DRIcontextPrivate *driContextPriv,
+		  __DRIcontext *driContextPriv,
                   void *sharedContextPrivate )
 {
    GLcontext *ctx, *shareCtx;
-   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
    sisContextPtr smesa;
    sisScreenPtr sisScreen;
    int i;
@@ -337,7 +339,7 @@
 }
 
 void
-sisDestroyContext ( __DRIcontextPrivate *driContextPriv )
+sisDestroyContext ( __DRIcontext *driContextPriv )
 {
    sisContextPtr smesa = (sisContextPtr)driContextPriv->driverPrivate;
 
@@ -365,9 +367,9 @@
 }
 
 GLboolean
-sisMakeCurrent( __DRIcontextPrivate *driContextPriv,
-                __DRIdrawablePrivate *driDrawPriv,
-                __DRIdrawablePrivate *driReadPriv )
+sisMakeCurrent( __DRIcontext *driContextPriv,
+                __DRIdrawable *driDrawPriv,
+                __DRIdrawable *driReadPriv )
 {
    if ( driContextPriv ) {
       GET_CURRENT_CONTEXT(ctx);
@@ -396,7 +398,7 @@
 }
 
 GLboolean
-sisUnbindContext( __DRIcontextPrivate *driContextPriv )
+sisUnbindContext( __DRIcontext *driContextPriv )
 {
    return GL_TRUE;
 }
diff --git a/src/mesa/drivers/dri/sis/sis_context.h b/src/mesa/drivers/dri/sis/sis_context.h
index bc53cb5..4179ee0 100644
--- a/src/mesa/drivers/dri/sis/sis_context.h
+++ b/src/mesa/drivers/dri/sis/sis_context.h
@@ -359,9 +359,9 @@
 
   /* Mirrors of some DRI state
    */
-  __DRIcontextPrivate	*driContext;	/* DRI context */
-  __DRIscreenPrivate	*driScreen;	/* DRI screen */
-  __DRIdrawablePrivate	*driDrawable;	/* DRI drawable bound to this ctx */
+  __DRIcontext	*driContext;	/* DRI context */
+  __DRIscreen	*driScreen;	/* DRI screen */
+  __DRIdrawable	*driDrawable;	/* DRI drawable bound to this ctx */
 
   unsigned int lastStamp;	        /* mirror driDrawable->lastStamp */
 
@@ -439,18 +439,18 @@
 };
 
 extern GLboolean sisCreateContext( const __GLcontextModes *glVisual,
-				   __DRIcontextPrivate *driContextPriv,
+				   __DRIcontext *driContextPriv,
                                    void *sharedContextPrivate );
-extern void sisDestroyContext( __DRIcontextPrivate * );
+extern void sisDestroyContext( __DRIcontext * );
 
 void sisReAllocateBuffers(GLcontext *ctx, GLframebuffer *drawbuffer,
                           GLuint width, GLuint height);
 
-extern GLboolean sisMakeCurrent( __DRIcontextPrivate *driContextPriv,
-                                  __DRIdrawablePrivate *driDrawPriv,
-                                  __DRIdrawablePrivate *driReadPriv );
+extern GLboolean sisMakeCurrent( __DRIcontext *driContextPriv,
+                                  __DRIdrawable *driDrawPriv,
+                                  __DRIdrawable *driReadPriv );
 
-extern GLboolean sisUnbindContext( __DRIcontextPrivate *driContextPriv );
+extern GLboolean sisUnbindContext( __DRIcontext *driContextPriv );
 
 void WaitEngIdle (sisContextPtr smesa);
 void Wait2DEngIdle (sisContextPtr smesa);
diff --git a/src/mesa/drivers/dri/sis/sis_lock.c b/src/mesa/drivers/dri/sis/sis_lock.c
index 806110c..b8ff4e3 100644
--- a/src/mesa/drivers/dri/sis/sis_lock.c
+++ b/src/mesa/drivers/dri/sis/sis_lock.c
@@ -46,8 +46,8 @@
 void
 sisGetLock( sisContextPtr smesa, GLuint flags )
 {
-   __DRIdrawablePrivate *dPriv = smesa->driDrawable;
-   __DRIscreenPrivate *sPriv = smesa->driScreen;
+   __DRIdrawable *dPriv = smesa->driDrawable;
+   __DRIscreen *sPriv = smesa->driScreen;
    SISSAREAPrivPtr sarea = smesa->sarea;
 
    drmGetLock( smesa->driFd, smesa->hHWContext, flags );
diff --git a/src/mesa/drivers/dri/sis/sis_screen.c b/src/mesa/drivers/dri/sis/sis_screen.c
index fec9158..d38b93e 100644
--- a/src/mesa/drivers/dri/sis/sis_screen.c
+++ b/src/mesa/drivers/dri/sis/sis_screen.c
@@ -65,7 +65,7 @@
 extern const struct dri_extension card_extensions[];
 
 static const __DRIconfig **
-sisFillInModes(__DRIscreenPrivate *psp, int bpp)
+sisFillInModes(__DRIscreen *psp, int bpp)
 {
    __DRIconfig **configs;
    unsigned depth_buffer_factor;
@@ -117,7 +117,7 @@
 /* Create the device specific screen private data struct.
  */
 static sisScreenPtr
-sisCreateScreen( __DRIscreenPrivate *sPriv )
+sisCreateScreen( __DRIscreen *sPriv )
 {
    sisScreenPtr sisScreen;
    SISDRIPtr sisDRIPriv = (SISDRIPtr)sPriv->pDevPriv;
@@ -172,7 +172,7 @@
 /* Destroy the device specific screen private data struct.
  */
 static void
-sisDestroyScreen( __DRIscreenPrivate *sPriv )
+sisDestroyScreen( __DRIscreen *sPriv )
 {
    sisScreenPtr sisScreen = (sisScreenPtr)sPriv->private;
 
@@ -192,8 +192,8 @@
  * data.
  */
 static GLboolean
-sisCreateBuffer( __DRIscreenPrivate *driScrnPriv,
-                 __DRIdrawablePrivate *driDrawPriv,
+sisCreateBuffer( __DRIscreen *driScrnPriv,
+                 __DRIdrawable *driDrawPriv,
                  const __GLcontextModes *mesaVis,
                  GLboolean isPixmap )
 {
@@ -219,12 +219,12 @@
 
 
 static void
-sisDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+sisDestroyBuffer(__DRIdrawable *driDrawPriv)
 {
    _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
 }
 
-static void sisCopyBuffer( __DRIdrawablePrivate *dPriv )
+static void sisCopyBuffer( __DRIdrawable *dPriv )
 {
    sisContextPtr smesa = (sisContextPtr)dPriv->driContextPriv->driverPrivate;
    int i;
@@ -259,7 +259,7 @@
 
 /* Copy the back color buffer to the front color buffer */
 static void
-sisSwapBuffers(__DRIdrawablePrivate *dPriv)
+sisSwapBuffers(__DRIdrawable *dPriv)
 {
    if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
          sisContextPtr smesa = (sisContextPtr) dPriv->driContextPriv->driverPrivate;
@@ -284,7 +284,7 @@
  * \return the __GLcontextModes supported by this driver
  */
 static const __DRIconfig **
-sisInitScreen(__DRIscreenPrivate *psp)
+sisInitScreen(__DRIscreen *psp)
 {
    static const __DRIversion ddx_expected = {0, 8, 0};
    static const __DRIversion dri_expected = {4, 0, 0};
@@ -325,3 +325,10 @@
    .SwapBuffersMSC  = NULL
 
 };
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driLegacyExtension.base,
+    NULL
+};
diff --git a/src/mesa/drivers/dri/sis/sis_screen.h b/src/mesa/drivers/dri/sis/sis_screen.h
index 07c29cf..8009fec 100644
--- a/src/mesa/drivers/dri/sis/sis_screen.h
+++ b/src/mesa/drivers/dri/sis/sis_screen.h
@@ -50,7 +50,7 @@
    int cpp;
    unsigned int screenX, screenY;
 
-   __DRIscreenPrivate *driScreen;
+   __DRIscreen *driScreen;
    unsigned int sarea_priv_offset;
 
    /* Configuration cache with default values for all contexts */
diff --git a/src/mesa/drivers/dri/sis/sis_span.c b/src/mesa/drivers/dri/sis/sis_span.c
index cfbb510..008b001 100644
--- a/src/mesa/drivers/dri/sis/sis_span.c
+++ b/src/mesa/drivers/dri/sis/sis_span.c
@@ -42,7 +42,7 @@
 
 #define LOCAL_VARS							\
    sisContextPtr smesa = SIS_CONTEXT(ctx);				\
-   __DRIdrawablePrivate *dPriv = smesa->driDrawable;			\
+   __DRIdrawable *dPriv = smesa->driDrawable;			\
    struct sis_renderbuffer *srb = (struct sis_renderbuffer *) rb;	\
    GLuint pitch = srb->pitch;						\
    char *buf = srb->map;						\
@@ -52,7 +52,7 @@
 
 #define LOCAL_DEPTH_VARS						\
    sisContextPtr smesa = SIS_CONTEXT(ctx);				\
-   __DRIdrawablePrivate *dPriv = smesa->driDrawable;			\
+   __DRIdrawable *dPriv = smesa->driDrawable;			\
    struct sis_renderbuffer *srb = (struct sis_renderbuffer *) rb;	\
    char *buf = srb->map;
 
diff --git a/src/mesa/drivers/dri/sis/sis_texstate.c b/src/mesa/drivers/dri/sis/sis_texstate.c
index a507173..4c22a10 100644
--- a/src/mesa/drivers/dri/sis/sis_texstate.c
+++ b/src/mesa/drivers/dri/sis/sis_texstate.c
@@ -457,10 +457,10 @@
 
    {
       GLubyte c[4];
-      CLAMPED_FLOAT_TO_UBYTE(c[0], texObj->BorderColor[0]);
-      CLAMPED_FLOAT_TO_UBYTE(c[1], texObj->BorderColor[1]);
-      CLAMPED_FLOAT_TO_UBYTE(c[2], texObj->BorderColor[2]);
-      CLAMPED_FLOAT_TO_UBYTE(c[3], texObj->BorderColor[3]);
+      CLAMPED_FLOAT_TO_UBYTE(c[0], texObj->BorderColor.f[0]);
+      CLAMPED_FLOAT_TO_UBYTE(c[1], texObj->BorderColor.f[1]);
+      CLAMPED_FLOAT_TO_UBYTE(c[2], texObj->BorderColor.f[2]);
+      CLAMPED_FLOAT_TO_UBYTE(c[3], texObj->BorderColor.f[3]);
 
       current->texture[hw_unit].hwTextureBorderColor = 
          PACK_COLOR_8888(c[3], c[0], c[1], c[2]);
diff --git a/src/mesa/drivers/dri/sis/sis_tris.c b/src/mesa/drivers/dri/sis/sis_tris.c
index 76d12d0..4690274 100644
--- a/src/mesa/drivers/dri/sis/sis_tris.c
+++ b/src/mesa/drivers/dri/sis/sis_tris.c
@@ -430,7 +430,8 @@
 
 #define LOCAL_VARS(n)						\
    sisContextPtr smesa = SIS_CONTEXT(ctx);			\
-   GLuint color[n], spec[n];					\
+   GLuint color[n] = { 0 };					\
+   GLuint spec[n] = { 0 };					\
    GLuint coloroffset = smesa->coloroffset;			\
    GLuint specoffset = smesa->specoffset;			\
    (void) color; (void) spec; (void) coloroffset; (void) specoffset;
@@ -903,14 +904,14 @@
 
    /* projective textures are not supported by the hardware */
    if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 )) {
-      if (VB->TexCoordPtr[0]->size > 2)
+      if (VB->AttribPtr[_TNL_ATTRIB_TEX0]->size > 2)
 	 tex_fallback = GL_TRUE;
       EMIT_ATTR(_TNL_ATTRIB_TEX0, EMIT_2F);
       AGPParseSet |= SiS_PS_HAS_UV0;
    }
    /* Will only hit tex1 on SiS300 */
    if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 )) {
-      if (VB->TexCoordPtr[1]->size > 2)
+      if (VB->AttribPtr[_TNL_ATTRIB_TEX1]->size > 2)
 	 tex_fallback = GL_TRUE;
       EMIT_ATTR(_TNL_ATTRIB_TEX1, EMIT_2F);
       AGPParseSet |= SiS_PS_HAS_UV1;
diff --git a/src/mesa/drivers/dri/swrast/swrast_span.c b/src/mesa/drivers/dri/swrast/swrast_span.c
index 2d3c25d..f8e5034 100644
--- a/src/mesa/drivers/dri/swrast/swrast_span.c
+++ b/src/mesa/drivers/dri/swrast/swrast_span.c
@@ -63,56 +63,42 @@
 
 /* 32-bit BGRA */
 #define STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE) \
-   DST[3] = VALUE[ACOMP]; \
-   DST[2] = VALUE[RCOMP]; \
-   DST[1] = VALUE[GCOMP]; \
-   DST[0] = VALUE[BCOMP]
+   *DST = VALUE[ACOMP] << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP]
 #define STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE) \
-   DST[3] = 0xff; \
-   DST[2] = VALUE[RCOMP]; \
-   DST[1] = VALUE[GCOMP]; \
-   DST[0] = VALUE[BCOMP]
+   *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP]
 #define FETCH_PIXEL_A8R8G8B8(DST, SRC) \
-   DST[ACOMP] = SRC[3]; \
-   DST[RCOMP] = SRC[2]; \
-   DST[GCOMP] = SRC[1]; \
-   DST[BCOMP] = SRC[0]
+   DST[ACOMP] = *SRC >> 24;            \
+   DST[RCOMP] = (*SRC >> 16) & 0xff;   \
+   DST[GCOMP] = (*SRC >> 8) & 0xff;    \
+   DST[BCOMP] = *SRC & 0xff
 
 
 /* 32-bit BGRX */
 #define STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE) \
-   DST[3] = 0xff; \
-   DST[2] = VALUE[RCOMP]; \
-   DST[1] = VALUE[GCOMP]; \
-   DST[0] = VALUE[BCOMP]
+   *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP]
 #define STORE_PIXEL_RGB_X8R8G8B8(DST, X, Y, VALUE) \
-   DST[3] = 0xff; \
-   DST[2] = VALUE[RCOMP]; \
-   DST[1] = VALUE[GCOMP]; \
-   DST[0] = VALUE[BCOMP]
+   *DST = 0xff << 24 | VALUE[RCOMP] << 16 | VALUE[GCOMP] << 8 | VALUE[BCOMP]
 #define FETCH_PIXEL_X8R8G8B8(DST, SRC) \
-   DST[ACOMP] = 0xff; \
-   DST[RCOMP] = SRC[2]; \
-   DST[GCOMP] = SRC[1]; \
-   DST[BCOMP] = SRC[0]
+   DST[ACOMP] = 0xff;                  \
+   DST[RCOMP] = (*SRC >> 16) & 0xff;   \
+   DST[GCOMP] = (*SRC >> 8) & 0xff;    \
+   DST[BCOMP] = *SRC & 0xff
 
 
 /* 16-bit BGR */
 #define STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) \
    do { \
    int d = DITHER_COMP(X, Y) >> 6; \
-   GLushort *p = (GLushort *)DST; \
-   *p = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xf8) << 8) | \
-	  ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xfc) << 3) | \
-	  ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xf8) >> 3) ); \
+   *DST = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xf8) << 8) | \
+            ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xfc) << 3) | \
+            ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xf8) >> 3) ); \
    } while(0)
 #define FETCH_PIXEL_R5G6B5(DST, SRC) \
    do { \
-   GLushort p = *(GLushort *)SRC; \
    DST[ACOMP] = 0xff; \
-   DST[RCOMP] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
-   DST[GCOMP] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
-   DST[BCOMP] = ((p << 3) & 0xf8) * 255 / 0xf8; \
+   DST[RCOMP] = ((*SRC >> 8) & 0xf8) * 255 / 0xf8; \
+   DST[GCOMP] = ((*SRC >> 3) & 0xfc) * 255 / 0xfc; \
+   DST[BCOMP] = ((*SRC << 3) & 0xf8) * 255 / 0xf8; \
    } while(0)
 
 
@@ -145,8 +131,8 @@
 #define SPAN_VARS \
    struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
 #define INIT_PIXEL_PTR(P, X, Y) \
-   GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 4;
-#define INC_PIXEL_PTR(P) P += 4
+   GLuint *P = (GLuint *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 4 + (X)
+#define INC_PIXEL_PTR(P) P++
 #define STORE_PIXEL(DST, X, Y, VALUE) \
    STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE)
 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
@@ -163,8 +149,8 @@
 #define SPAN_VARS \
    struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
 #define INIT_PIXEL_PTR(P, X, Y) \
-   GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 4;
-#define INC_PIXEL_PTR(P) P += 4
+   GLuint *P = (GLuint *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 4 + (X);
+#define INC_PIXEL_PTR(P) P++
 #define STORE_PIXEL(DST, X, Y, VALUE) \
    STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE)
 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
@@ -181,8 +167,8 @@
 #define SPAN_VARS \
    struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
 #define INIT_PIXEL_PTR(P, X, Y) \
-   GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 2;
-#define INC_PIXEL_PTR(P) P += 2
+   GLushort *P = (GLushort *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch / 2 + (X);
+#define INC_PIXEL_PTR(P) P++
 #define STORE_PIXEL(DST, X, Y, VALUE) \
    STORE_PIXEL_R5G6B5(DST, X, Y, VALUE)
 #define FETCH_PIXEL(DST, SRC) \
@@ -234,8 +220,8 @@
 #define SPAN_VARS \
    struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
 #define INIT_PIXEL_PTR(P, X, Y) \
-   GLubyte *P = (GLubyte *)row;
-#define INC_PIXEL_PTR(P) P += 4
+   GLuint *P = (GLuint *)row;
+#define INC_PIXEL_PTR(P) P++
 #define STORE_PIXEL(DST, X, Y, VALUE) \
    STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE)
 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
@@ -252,8 +238,8 @@
 #define SPAN_VARS \
    struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
 #define INIT_PIXEL_PTR(P, X, Y) \
-   GLubyte *P = (GLubyte *)row;
-#define INC_PIXEL_PTR(P) P += 4
+   GLuint *P = (GLuint *)row;
+#define INC_PIXEL_PTR(P) P++
 #define STORE_PIXEL(DST, X, Y, VALUE) \
    STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE)
 #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
@@ -270,7 +256,7 @@
 #define SPAN_VARS \
    struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
 #define INIT_PIXEL_PTR(P, X, Y) \
-   GLubyte *P = (GLubyte *)row;
+   GLushort *P = (GLushort *)row;
 #define INC_PIXEL_PTR(P) P += 2
 #define STORE_PIXEL(DST, X, Y, VALUE) \
    STORE_PIXEL_R5G6B5(DST, X, Y, VALUE)
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_context.c b/src/mesa/drivers/dri/tdfx/tdfx_context.c
index e742d41..edb1875 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_context.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_context.c
@@ -165,12 +165,12 @@
 };
 
 GLboolean tdfxCreateContext( const __GLcontextModes *mesaVis,
-			     __DRIcontextPrivate *driContextPriv,
+			     __DRIcontext *driContextPriv,
                              void *sharedContextPrivate )
 {
    tdfxContextPtr fxMesa;
    GLcontext *ctx, *shareCtx;
-   __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
    tdfxScreenPrivate *fxScreen = (tdfxScreenPrivate *) sPriv->private;
    TDFXSAREAPriv *saPriv = (TDFXSAREAPriv *) ((char *) sPriv->pSAREA +
 					      sizeof(drm_sarea_t));
@@ -441,7 +441,7 @@
  * Initialize the state in an tdfxContextPtr struct.
  */
 static GLboolean
-tdfxInitContext( __DRIdrawablePrivate *driDrawPriv, tdfxContextPtr fxMesa )
+tdfxInitContext( __DRIdrawable *driDrawPriv, tdfxContextPtr fxMesa )
 {
    /* KW: Would be nice to make one of these a member of the other.
     */
@@ -563,7 +563,7 @@
 
 
 void
-tdfxDestroyContext( __DRIcontextPrivate *driContextPriv )
+tdfxDestroyContext( __DRIcontext *driContextPriv )
 {
    tdfxContextPtr fxMesa = (tdfxContextPtr) driContextPriv->driverPrivate;
 
@@ -607,7 +607,7 @@
 
 
 GLboolean
-tdfxUnbindContext( __DRIcontextPrivate *driContextPriv )
+tdfxUnbindContext( __DRIcontext *driContextPriv )
 {
    GET_CURRENT_CONTEXT(ctx);
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
@@ -626,9 +626,9 @@
 
 
 GLboolean
-tdfxMakeCurrent( __DRIcontextPrivate *driContextPriv,
-                 __DRIdrawablePrivate *driDrawPriv,
-                 __DRIdrawablePrivate *driReadPriv )
+tdfxMakeCurrent( __DRIcontext *driContextPriv,
+                 __DRIdrawable *driDrawPriv,
+                 __DRIdrawable *driReadPriv )
 {
    if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) {
       fprintf( stderr, "%s( %p )\n", __FUNCTION__, (void *)driContextPriv );
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_context.h b/src/mesa/drivers/dri/tdfx/tdfx_context.h
index 3bcb545..6e25cac 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_context.h
+++ b/src/mesa/drivers/dri/tdfx/tdfx_context.h
@@ -892,18 +892,18 @@
    char rendererString[100];
 
    /* stuff added for DRI */
-   __DRIscreenPrivate *driScreen;
-   __DRIcontextPrivate *driContext;
+   __DRIscreen *driScreen;
+   __DRIcontext *driContext;
 
    /**
     * DRI drawable bound to this context for drawing.
     */
-   __DRIdrawablePrivate	*driDrawable;
+   __DRIdrawable	*driDrawable;
 
    /**
     * DRI drawable bound to this context for reading.
     */
-   __DRIdrawablePrivate	*driReadable;
+   __DRIdrawable	*driReadable;
 
    drm_context_t hHWContext;
    drm_hw_lock_t *driHwLock;
@@ -938,19 +938,19 @@
 
 extern GLboolean
 tdfxCreateContext( const __GLcontextModes *mesaVis,
-                   __DRIcontextPrivate *driContextPriv,
+                   __DRIcontext *driContextPriv,
                    void *sharedContextPrivate );
 
 extern void
-tdfxDestroyContext( __DRIcontextPrivate *driContextPriv );
+tdfxDestroyContext( __DRIcontext *driContextPriv );
 
 extern GLboolean
-tdfxUnbindContext( __DRIcontextPrivate *driContextPriv );
+tdfxUnbindContext( __DRIcontext *driContextPriv );
 
 extern GLboolean
-tdfxMakeCurrent( __DRIcontextPrivate *driContextPriv,
-                 __DRIdrawablePrivate *driDrawPriv,
-                 __DRIdrawablePrivate *driReadPriv );
+tdfxMakeCurrent( __DRIcontext *driContextPriv,
+                 __DRIdrawable *driDrawPriv,
+                 __DRIdrawable *driReadPriv );
 
 extern GLboolean
 tdfxInitGlide( tdfxContextPtr tmesa );
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_dd.c b/src/mesa/drivers/dri/tdfx/tdfx_dd.c
index 8472df6..ed8a331 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_dd.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_dd.c
@@ -91,7 +91,7 @@
       else {
 	 /* unexpected result: replace spaces with hyphens */
 	 int i;
-	 for (i = 0; hardware[i] && (i < sizeof(hardware)); i++) {
+	 for (i = 0; i < sizeof(hardware) && hardware[i]; i++) {
 	    if (hardware[i] == ' ' || hardware[i] == '\t') {
 	       hardware[i] = '-';
 	    }
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_lock.c b/src/mesa/drivers/dri/tdfx/tdfx_lock.c
index 17cdc51..4f84240 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_lock.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_lock.c
@@ -45,10 +45,10 @@
 
 void tdfxGetLock( tdfxContextPtr fxMesa )
 {
-    __DRIcontextPrivate *cPriv = fxMesa->driContext;
-    __DRIdrawablePrivate *const drawable = cPriv->driDrawablePriv;
-    __DRIdrawablePrivate *const readable = cPriv->driReadablePriv;
-    __DRIscreenPrivate *sPriv = drawable->driScreenPriv;
+    __DRIcontext *cPriv = fxMesa->driContext;
+    __DRIdrawable *const drawable = cPriv->driDrawablePriv;
+    __DRIdrawable *const readable = cPriv->driReadablePriv;
+    __DRIscreen *sPriv = drawable->driScreenPriv;
     TDFXSAREAPriv *saPriv = (TDFXSAREAPriv *) (((char *) sPriv->pSAREA) +
 					fxMesa->fxScreen->sarea_priv_offset);
     unsigned int stamp = drawable->lastStamp;
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_pixels.c b/src/mesa/drivers/dri/tdfx/tdfx_pixels.c
index 18729d5..65f0464 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_pixels.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_pixels.c
@@ -495,7 +495,7 @@
    {
       tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
       GrLfbInfo_t info;
-      __DRIdrawablePrivate *const readable = fxMesa->driReadable;
+      __DRIdrawable *const readable = fxMesa->driReadable;
       const GLint winX = readable->x;
       const GLint winY = readable->y + readable->h - 1;
       const GLint scrX = winX + x;
@@ -553,7 +553,7 @@
    {
       tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
       GrLfbInfo_t info;
-      __DRIdrawablePrivate *const readable = fxMesa->driReadable;
+      __DRIdrawable *const readable = fxMesa->driReadable;
       const GLint winX = readable->x;
       const GLint winY = readable->y + readable->h - 1;
       const GLint scrX = winX + x;
@@ -611,10 +611,10 @@
        ctx->Fog.Enabled ||
        ctx->Scissor.Enabled ||
        ctx->Stencil._Enabled ||
-       !ctx->Color.ColorMask[0] ||
-       !ctx->Color.ColorMask[1] ||
-       !ctx->Color.ColorMask[2] ||
-       !ctx->Color.ColorMask[3] ||
+       !ctx->Color.ColorMask[0][0] ||
+       !ctx->Color.ColorMask[0][1] ||
+       !ctx->Color.ColorMask[0][2] ||
+       !ctx->Color.ColorMask[0][3] ||
        ctx->Color.ColorLogicOpEnabled ||
        ctx->Texture._EnabledUnits ||
        fxMesa->Fallback)       
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_render.c b/src/mesa/drivers/dri/tdfx/tdfx_render.c
index 2cd8e12..979bcd4 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_render.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_render.c
@@ -76,8 +76,8 @@
 
    if (fxMesa->glCtx->Visual.redBits != 8) {
       /* can only do color masking if running in 24/32bpp on Napalm */
-      if (ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP] ||
-          ctx->Color.ColorMask[GCOMP] != ctx->Color.ColorMask[BCOMP]) {
+      if (ctx->Color.ColorMask[0][RCOMP] != ctx->Color.ColorMask[0][GCOMP] ||
+          ctx->Color.ColorMask[0][GCOMP] != ctx->Color.ColorMask[0][BCOMP]) {
          softwareMask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT));
          mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT);
       }
@@ -556,7 +556,7 @@
  */
 void tdfxUploadClipping( tdfxContextPtr fxMesa )
 {
-   __DRIdrawablePrivate *dPriv = fxMesa->driDrawable;
+   __DRIdrawable *dPriv = fxMesa->driDrawable;
 
    assert(dPriv);
 
@@ -721,7 +721,7 @@
 	 fxMesa->Glide.grColorMask( fxMesa->Color.ColorMask[RCOMP] ||
                                     fxMesa->Color.ColorMask[GCOMP] ||
                                     fxMesa->Color.ColorMask[BCOMP],
-                                    /*fxMesa->Color.ColorMask[ACOMP]*/GL_FALSE/*[dBorca] no-no*/ );
+                                    /*fxMesa->Color.ColorMask[0][ACOMP]*/GL_FALSE/*[dBorca] no-no*/ );
       }
       fxMesa->dirty &= ~TDFX_UPLOAD_COLOR_MASK;
    }
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_screen.c b/src/mesa/drivers/dri/tdfx/tdfx_screen.c
index 2eb0024..4422b5d 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_screen.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_screen.c
@@ -70,7 +70,7 @@
 static const GLuint __driNConfigOptions = 1;
 
 static GLboolean
-tdfxCreateScreen( __DRIscreenPrivate *sPriv )
+tdfxCreateScreen( __DRIscreen *sPriv )
 {
    tdfxScreenPrivate *fxScreen;
    TDFXDRIPtr fxDRIPriv = (TDFXDRIPtr) sPriv->pDevPriv;
@@ -121,7 +121,7 @@
 
 
 static void
-tdfxDestroyScreen( __DRIscreenPrivate *sPriv )
+tdfxDestroyScreen( __DRIscreen *sPriv )
 {
    tdfxScreenPrivate *fxScreen = (tdfxScreenPrivate *) sPriv->private;
 
@@ -139,7 +139,7 @@
 
 
 static GLboolean
-tdfxInitDriver( __DRIscreenPrivate *sPriv )
+tdfxInitDriver( __DRIscreen *sPriv )
 {
    if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) {
       fprintf( stderr, "%s( %p )\n", __FUNCTION__, (void *)sPriv );
@@ -155,8 +155,8 @@
 
 
 static GLboolean
-tdfxCreateBuffer( __DRIscreenPrivate *driScrnPriv,
-                  __DRIdrawablePrivate *driDrawPriv,
+tdfxCreateBuffer( __DRIscreen *driScrnPriv,
+                  __DRIdrawable *driDrawPriv,
                   const __GLcontextModes *mesaVis,
                   GLboolean isPixmap )
 {
@@ -227,14 +227,14 @@
 
 
 static void
-tdfxDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+tdfxDestroyBuffer(__DRIdrawable *driDrawPriv)
 {
    _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
 }
 
 
 static void
-tdfxSwapBuffers( __DRIdrawablePrivate *driDrawPriv )
+tdfxSwapBuffers( __DRIdrawable *driDrawPriv )
 
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -253,7 +253,7 @@
     * we have to do a glFinish (per the GLX spec).
     */
    if ( ctx ) {
-      __DRIdrawablePrivate *curDrawPriv;
+      __DRIdrawable *curDrawPriv;
       fxMesa = TDFX_CONTEXT(ctx);
       curDrawPriv = fxMesa->driContext->driDrawablePriv;
 
@@ -341,7 +341,7 @@
 }
 
 static const __DRIconfig **
-tdfxFillInModes(__DRIscreenPrivate *psp,
+tdfxFillInModes(__DRIscreen *psp,
 		unsigned pixel_bits,
 		unsigned depth_bits,
 		unsigned stencil_bits,
@@ -440,3 +440,10 @@
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
 };
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driLegacyExtension.base,
+    NULL
+};
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_screen.h b/src/mesa/drivers/dri/tdfx/tdfx_screen.h
index 5a68898..6aa42e8 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_screen.h
+++ b/src/mesa/drivers/dri/tdfx/tdfx_screen.h
@@ -61,7 +61,7 @@
    int textureOffset;
    int textureSize;
 
-   __DRIscreenPrivate *driScrnPriv;
+   __DRIscreen *driScrnPriv;
    unsigned int sarea_priv_offset;
 
    /* Configuration cache with default values for all contexts */
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_span.c b/src/mesa/drivers/dri/tdfx/tdfx_span.c
index 6b38fa5..a17bcd9 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_span.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_span.c
@@ -47,7 +47,7 @@
 
 #define LOCAL_VARS							\
    driRenderbuffer *drb = (driRenderbuffer *) rb;			\
-   __DRIdrawablePrivate *const dPriv = drb->dPriv;			\
+   __DRIdrawable *const dPriv = drb->dPriv;			\
    GLuint pitch = drb->backBuffer ? info.strideInBytes			\
      : (drb->pitch * drb->cpp);						\
    const GLuint bottom = dPriv->h - 1;					\
@@ -104,7 +104,7 @@
 
 #define HW_READ_CLIPLOOP()						\
       do {								\
-         const __DRIdrawablePrivate *dPriv = fxMesa->driDrawable;	\
+         const __DRIdrawable *dPriv = fxMesa->driDrawable;	\
          drm_clip_rect_t *rect = dPriv->pClipRects;			\
          int _nc = dPriv->numClipRects;					\
          while (_nc--) {						\
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_state.c b/src/mesa/drivers/dri/tdfx/tdfx_state.c
index cf27127..cdb61a0 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_state.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_state.c
@@ -621,7 +621,7 @@
 void tdfxUpdateClipping( GLcontext *ctx )
 {
    tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = fxMesa->driDrawable;
+   __DRIdrawable *dPriv = fxMesa->driDrawable;
 
    if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
       fprintf( stderr, "%s()\n", __FUNCTION__ );
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tex.c b/src/mesa/drivers/dri/tdfx/tdfx_tex.c
index 0aa09e7..e31ae97 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_tex.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_tex.c
@@ -1572,7 +1572,7 @@
     tdfxTexInfo *ti;
     tdfxMipMapLevel *mml;
     gl_format mesaFormat;
-    GLuint compressedSize;
+    GLuint compressedSize = 0;
 
     if (TDFX_DEBUG & DEBUG_VERBOSE_DRI) {
         fprintf(stderr, "tdfxCompressedTexImage2D: id=%d int 0x%x  %dx%d\n",
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_texstate.c b/src/mesa/drivers/dri/tdfx/tdfx_texstate.c
index bbd2c8c..3f73787 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_texstate.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_texstate.c
@@ -1314,7 +1314,7 @@
       fxMesa->TexCombine[0].InvertRGB = FXFALSE;
       fxMesa->TexCombine[0].InvertAlpha = FXFALSE;
 
-      if ((baseFormat0 == GL_RGB) && (baseFormat0 == GL_LUMINANCE)) {
+      if ((baseFormat0 == GL_RGB) || (baseFormat0 == GL_LUMINANCE)) {
          fxMesa->AlphaCombine.Function = GR_COMBINE_FUNCTION_LOCAL;
          fxMesa->AlphaCombine.Factor = GR_COMBINE_FACTOR_NONE;
          fxMesa->AlphaCombine.Local = locala;
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_vb.c b/src/mesa/drivers/dri/tdfx/tdfx_vb.c
index 4928802..c200ba3 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_vb.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_vb.c
@@ -69,11 +69,11 @@
 
    /*fprintf(stderr, "%s\n", __FUNCTION__);*/
 
-   if (VB->ColorPtr[1]) {
+   if (VB->BackfaceColorPtr) {
       INTERP_4F( t,
-		    GET_COLOR(VB->ColorPtr[1], dst),
-		    GET_COLOR(VB->ColorPtr[1], out),
-		    GET_COLOR(VB->ColorPtr[1], in) );
+		 GET_COLOR(VB->BackfaceColorPtr, dst),
+		 GET_COLOR(VB->BackfaceColorPtr, out),
+		 GET_COLOR(VB->BackfaceColorPtr, in) );
    }
 
    if (VB->EdgeFlag) {
@@ -88,9 +88,9 @@
 {
    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
 
-   if (VB->ColorPtr[1]) {
-	 COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst), 
-		     GET_COLOR(VB->ColorPtr[1], src) );
+   if (VB->BackfaceColorPtr) {
+      COPY_4FV( GET_COLOR(VB->BackfaceColorPtr, dst),
+		GET_COLOR(VB->BackfaceColorPtr, src) );
    }
 
    setup_tab[TDFX_CONTEXT(ctx)->SetupIndex].copy_pv(ctx, dst, src);
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_vbtmp.h b/src/mesa/drivers/dri/tdfx/tdfx_vbtmp.h
index 9b78076..19baf7d 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_vbtmp.h
+++ b/src/mesa/drivers/dri/tdfx/tdfx_vbtmp.h
@@ -58,32 +58,32 @@
 /*     fprintf(stderr, "%s\n", __FUNCTION__); */
 
    if (IND & TDFX_TEX0_BIT) {
-      tc0_stride = VB->TexCoordPtr[tmu0_source]->stride;
-      tc0 = VB->TexCoordPtr[tmu0_source]->data;
+      tc0_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + tmu0_source]->stride;
+      tc0 = VB->AttribPtr[_TNL_ATTRIB_TEX0 + tmu0_source]->data;
       u0scale = fxMesa->sScale0;
       v0scale = fxMesa->tScale0;
       if (IND & TDFX_PTEX_BIT)
-	 tc0_size = VB->TexCoordPtr[tmu0_source]->size;
+	 tc0_size = VB->AttribPtr[_TNL_ATTRIB_TEX0 + tmu0_source]->size;
    }
 
    if (IND & TDFX_TEX1_BIT) {
-      tc1 = VB->TexCoordPtr[tmu1_source]->data;
-      tc1_stride = VB->TexCoordPtr[tmu1_source]->stride;
+      tc1 = VB->AttribPtr[_TNL_ATTRIB_TEX0 + tmu1_source]->data;
+      tc1_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + tmu1_source]->stride;
       u1scale = fxMesa->sScale1;
       v1scale = fxMesa->tScale1;
       if (IND & TDFX_PTEX_BIT)
-	 tc1_size = VB->TexCoordPtr[tmu1_source]->size;
+	 tc1_size = VB->AttribPtr[_TNL_ATTRIB_TEX0 + tmu1_source]->size;
    }
    
    if (IND & TDFX_RGBA_BIT) {
-      col = VB->ColorPtr[0]->data;
-      col_stride = VB->ColorPtr[0]->stride;
-      col_size = VB->ColorPtr[0]->size;
+      col = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;
+      col_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride;
+      col_size = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->size;
    }
    
    if (IND & TDFX_FOGC_BIT) {
-      fog = VB->FogCoordPtr->data;
-      fog_stride = VB->FogCoordPtr->stride;
+      fog = VB->AttribPtr[_TNL_ATTRIB_FOG]->data;
+      fog_stride = VB->AttribPtr[_TNL_ATTRIB_FOG]->stride;
    }
 
    {
@@ -168,14 +168,14 @@
       struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
 
       if (IND & TDFX_TEX1_BIT) {
-	 if (VB->TexCoordPtr[0] == 0)
-	    VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
+	 if (VB->AttribPtr[_TNL_ATTRIB_TEX0] == 0)
+	    VB->AttribPtr[_TNL_ATTRIB_TEX0] = VB->AttribPtr[_TNL_ATTRIB_TEX1];
 	 
-	 if (VB->TexCoordPtr[1]->size == 4)
+	 if (VB->AttribPtr[_TNL_ATTRIB_TEX1]->size == 4)
 	    return GL_FALSE;
       }
 
-      if (VB->TexCoordPtr[0]->size == 4)
+      if (VB->AttribPtr[_TNL_ATTRIB_TEX0]->size == 4)
 	 return GL_FALSE;
    }
 
diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c
index 0524bec..d17a160 100644
--- a/src/mesa/drivers/dri/unichrome/via_context.c
+++ b/src/mesa/drivers/dri/unichrome/via_context.c
@@ -148,7 +148,7 @@
 
 static void
 viaInitRenderbuffer(struct via_renderbuffer *vrb, GLenum format,
-		    __DRIdrawablePrivate *dPriv)
+		    __DRIdrawable *dPriv)
 {
    const GLuint name = 0;
    struct gl_renderbuffer *rb = & vrb->Base;
@@ -207,7 +207,7 @@
 static GLboolean
 calculate_buffer_parameters(struct via_context *vmesa,
 			    struct gl_framebuffer *fb,
-			    __DRIdrawablePrivate *dPriv)
+			    __DRIdrawable *dPriv)
 {
    const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16;
    const unsigned extra = 32;
@@ -460,12 +460,12 @@
 
 GLboolean
 viaCreateContext(const __GLcontextModes *visual,
-                 __DRIcontextPrivate *driContextPriv,
+                 __DRIcontext *driContextPriv,
                  void *sharedContextPrivate)
 {
     GLcontext *ctx, *shareCtx;
     struct via_context *vmesa;
-    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+    __DRIscreen *sPriv = driContextPriv->driScreenPriv;
     viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private;
     drm_via_sarea_t *saPriv = (drm_via_sarea_t *)
         (((GLubyte *)sPriv->pSAREA) + viaScreen->sareaPrivOffset);
@@ -679,7 +679,7 @@
 }
 
 void
-viaDestroyContext(__DRIcontextPrivate *driContextPriv)
+viaDestroyContext(__DRIcontext *driContextPriv)
 {
     GET_CURRENT_CONTEXT(ctx);
     struct via_context *vmesa =
@@ -729,8 +729,8 @@
 
 void viaXMesaWindowMoved(struct via_context *vmesa)
 {
-   __DRIdrawablePrivate *const drawable = vmesa->driDrawable;
-   __DRIdrawablePrivate *const readable = vmesa->driReadable;
+   __DRIdrawable *const drawable = vmesa->driDrawable;
+   __DRIdrawable *const readable = vmesa->driReadable;
    struct via_renderbuffer * draw_buffer;
    struct via_renderbuffer * read_buffer;
    GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
@@ -813,15 +813,15 @@
 }
 
 GLboolean
-viaUnbindContext(__DRIcontextPrivate *driContextPriv)
+viaUnbindContext(__DRIcontext *driContextPriv)
 {
     return GL_TRUE;
 }
 
 GLboolean
-viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
-               __DRIdrawablePrivate *driDrawPriv,
-               __DRIdrawablePrivate *driReadPriv)
+viaMakeCurrent(__DRIcontext *driContextPriv,
+               __DRIdrawable *driDrawPriv,
+               __DRIdrawable *driReadPriv)
 {
     if (VIA_DEBUG & DEBUG_DRI) {
 	fprintf(stderr, "driContextPriv = %016lx\n", (unsigned long)driContextPriv);
@@ -897,8 +897,8 @@
 
 void viaGetLock(struct via_context *vmesa, GLuint flags)
 {
-    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
-    __DRIscreenPrivate *sPriv = vmesa->driScreen;
+    __DRIdrawable *dPriv = vmesa->driDrawable;
+    __DRIscreen *sPriv = vmesa->driScreen;
 
     drmGetLock(vmesa->driFd, vmesa->hHWContext, flags);
 
@@ -928,9 +928,9 @@
 
 
 void
-viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
+viaSwapBuffers(__DRIdrawable *drawablePrivate)
 {
-    __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *)drawablePrivate;
+    __DRIdrawable *dPriv = (__DRIdrawable *)drawablePrivate;
 
     if (dPriv && 
 	dPriv->driContextPriv && 
diff --git a/src/mesa/drivers/dri/unichrome/via_context.h b/src/mesa/drivers/dri/unichrome/via_context.h
index 4cc9e47..4e1ab3a 100644
--- a/src/mesa/drivers/dri/unichrome/via_context.h
+++ b/src/mesa/drivers/dri/unichrome/via_context.h
@@ -105,7 +105,7 @@
    int drawW;                  
    int drawH;    
 
-   __DRIdrawablePrivate *dPriv;
+   __DRIdrawable *dPriv;
 };
 
 
@@ -294,14 +294,14 @@
    /**
     * DRI drawable bound to this context for drawing.
     */
-   __DRIdrawablePrivate	*driDrawable;
+   __DRIdrawable	*driDrawable;
 
    /**
     * DRI drawable bound to this context for reading.
     */
-   __DRIdrawablePrivate	*driReadable;
+   __DRIdrawable	*driReadable;
 
-   __DRIscreenPrivate *driScreen;
+   __DRIscreen *driScreen;
    viaScreenPrivate *viaScreen;
    drm_via_sarea_t *sarea;
    volatile GLuint* regMMIOBase;
diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c
index b34c133..8d4edfa 100644
--- a/src/mesa/drivers/dri/unichrome/via_ioctl.c
+++ b/src/mesa/drivers/dri/unichrome/via_ioctl.c
@@ -205,7 +205,7 @@
 static void viaClear(GLcontext *ctx, GLbitfield mask)
 {
    struct via_context *vmesa = VIA_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+   __DRIdrawable *dPriv = vmesa->driDrawable;
    struct via_renderbuffer *const vrb = 
      (struct via_renderbuffer *) dPriv->driverPrivate;
    int flag = 0;
@@ -507,12 +507,12 @@
  * except that WAIT_IDLE() will spin the CPU polling, while this is
  * IRQ driven.
  */
-static void viaWaitIdleVBlank(  __DRIdrawablePrivate *dPriv, 
+static void viaWaitIdleVBlank(  __DRIdrawable *dPriv, 
 			       struct via_context *vmesa,
 			       GLuint value )
 {
    GLboolean missed_target;
-   __DRIscreenPrivate *psp = dPriv->driScreenPriv;
+   __DRIscreen *psp = dPriv->driScreenPriv;
 
    VIA_FLUSH_DMA(vmesa); 
 
@@ -591,11 +591,11 @@
 /*
  * Copy the back buffer to the front buffer. 
  */
-void viaCopyBuffer(__DRIdrawablePrivate *dPriv)
+void viaCopyBuffer(__DRIdrawable *dPriv)
 {
    struct via_context *vmesa = 
       (struct via_context *)dPriv->driContextPriv->driverPrivate;
-   __DRIscreenPrivate *psp = dPriv->driScreenPriv;
+   __DRIscreen *psp = dPriv->driScreenPriv;
 
    if (VIA_DEBUG & DEBUG_IOCTL)
       fprintf(stderr, 
@@ -635,12 +635,12 @@
 }
 
 
-void viaPageFlip(__DRIdrawablePrivate *dPriv)
+void viaPageFlip(__DRIdrawable *dPriv)
 {
     struct via_context *vmesa = 
        (struct via_context *)dPriv->driContextPriv->driverPrivate;
     struct via_renderbuffer buffer_tmp;
-    __DRIscreenPrivate *psp = dPriv->driScreenPriv;
+    __DRIscreen *psp = dPriv->driScreenPriv;
 
     VIA_FLUSH_DMA(vmesa);
    if (dPriv->vblFlags == VBLANK_FLAG_SYNC &&
@@ -885,7 +885,6 @@
    }
    else if (vmesa->numClipRects) {
       drm_clip_rect_t *pbox = vmesa->pClipRects;
-      __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
 
       for (i = 0; i < vmesa->numClipRects; i++) {
 	 drm_clip_rect_t b;
diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.h b/src/mesa/drivers/dri/unichrome/via_ioctl.h
index 14a833a..c6b32cf 100644
--- a/src/mesa/drivers/dri/unichrome/via_ioctl.h
+++ b/src/mesa/drivers/dri/unichrome/via_ioctl.h
@@ -33,8 +33,8 @@
 void viaFlushDmaLocked(struct via_context *vmesa, GLuint flags);
 
 void viaInitIoctlFuncs(GLcontext *ctx);
-void viaCopyBuffer(__DRIdrawablePrivate *dpriv);
-void viaPageFlip(__DRIdrawablePrivate *dpriv);
+void viaCopyBuffer(__DRIdrawable *dpriv);
+void viaPageFlip(__DRIdrawable *dpriv);
 void viaCheckDma(struct via_context *vmesa, GLuint bytes);
 void viaResetPageFlippingLocked(struct via_context *vmesa);
 void viaWaitIdle(struct via_context *vmesa, GLboolean light);
diff --git a/src/mesa/drivers/dri/unichrome/via_screen.c b/src/mesa/drivers/dri/unichrome/via_screen.c
index e0bf58c..2cfb983 100644
--- a/src/mesa/drivers/dri/unichrome/via_screen.c
+++ b/src/mesa/drivers/dri/unichrome/via_screen.c
@@ -90,7 +90,7 @@
 
 
 static GLboolean
-viaInitDriver(__DRIscreenPrivate *sPriv)
+viaInitDriver(__DRIscreen *sPriv)
 {
     viaScreenPrivate *viaScreen;
     VIADRIPtr gDRIPriv = (VIADRIPtr)sPriv->pDevPriv;
@@ -184,7 +184,7 @@
 }
 
 static void
-viaDestroyScreen(__DRIscreenPrivate *sPriv)
+viaDestroyScreen(__DRIscreen *sPriv)
 {
     viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private;
     VIADRIPtr gDRIPriv = (VIADRIPtr)sPriv->pDevPriv;
@@ -203,8 +203,8 @@
 
 
 static GLboolean
-viaCreateBuffer(__DRIscreenPrivate *driScrnPriv,
-                __DRIdrawablePrivate *driDrawPriv,
+viaCreateBuffer(__DRIscreen *driScrnPriv,
+                __DRIdrawable *driDrawPriv,
                 const __GLcontextModes *mesaVis,
                 GLboolean isPixmap)
 {
@@ -314,13 +314,13 @@
 
 
 static void
-viaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+viaDestroyBuffer(__DRIdrawable *driDrawPriv)
 {
    _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
 }
 
 static const __DRIconfig **
-viaFillInModes( __DRIscreenPrivate *psp,
+viaFillInModes( __DRIscreen *psp,
 		unsigned pixel_bits, GLboolean have_back_buffer )
 {
     __DRIconfig **configs;
@@ -377,7 +377,7 @@
  * \return the __GLcontextModes supported by this driver
  */
 static const __DRIconfig **
-viaInitScreen(__DRIscreenPrivate *psp)
+viaInitScreen(__DRIscreen *psp)
 {
    static const __DRIversion ddx_expected = { VIA_DRIDDX_VERSION_MAJOR,
                                               VIA_DRIDDX_VERSION_MINOR,
@@ -405,7 +405,7 @@
  * Get information about previous buffer swaps.
  */
 static int
-getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
+getSwapInfo( __DRIdrawable *dPriv, __DRIswapInfo * sInfo )
 {
    struct via_context *vmesa;
 
@@ -443,3 +443,10 @@
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
 };
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driLegacyExtension.base,
+    NULL
+};
diff --git a/src/mesa/drivers/dri/unichrome/via_screen.h b/src/mesa/drivers/dri/unichrome/via_screen.h
index c3ef722..aa662e0 100644
--- a/src/mesa/drivers/dri/unichrome/via_screen.h
+++ b/src/mesa/drivers/dri/unichrome/via_screen.h
@@ -61,7 +61,7 @@
     drmAddress agpLinearStart;
     GLuint agpBase;
 
-    __DRIscreenPrivate *driScrnPriv;
+    __DRIscreen *driScrnPriv;
     drmBufMapPtr bufs;
     unsigned int sareaPrivOffset;
     /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/
@@ -77,21 +77,21 @@
 
 extern GLboolean
 viaCreateContext(const __GLcontextModes *mesaVis,
-                 __DRIcontextPrivate *driContextPriv,
+                 __DRIcontext *driContextPriv,
                  void *sharedContextPrivate);
 
 extern void
-viaDestroyContext(__DRIcontextPrivate *driContextPriv);
+viaDestroyContext(__DRIcontext *driContextPriv);
 
 extern GLboolean
-viaUnbindContext(__DRIcontextPrivate *driContextPriv);
+viaUnbindContext(__DRIcontext *driContextPriv);
 
 extern GLboolean
-viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
-               __DRIdrawablePrivate *driDrawPriv,
-               __DRIdrawablePrivate *driReadPriv);
+viaMakeCurrent(__DRIcontext *driContextPriv,
+               __DRIdrawable *driDrawPriv,
+               __DRIdrawable *driReadPriv);
 
 extern void
-viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate);
+viaSwapBuffers(__DRIdrawable *drawablePrivate);
 
 #endif
diff --git a/src/mesa/drivers/dri/unichrome/via_span.c b/src/mesa/drivers/dri/unichrome/via_span.c
index e847164..fa3cbf7 100644
--- a/src/mesa/drivers/dri/unichrome/via_span.c
+++ b/src/mesa/drivers/dri/unichrome/via_span.c
@@ -43,7 +43,7 @@
 #undef LOCAL_VARS
 #define LOCAL_VARS                                                   	\
     struct via_renderbuffer *vrb = (struct via_renderbuffer *) rb;   	\
-    __DRIdrawablePrivate *dPriv = vrb->dPriv;                           \
+    __DRIdrawable *dPriv = vrb->dPriv;                           \
     GLuint pitch = vrb->pitch;                                          \
     GLuint height = dPriv->h;                                        	\
     GLint p = 0;							\
@@ -80,7 +80,7 @@
  */
 #define LOCAL_DEPTH_VARS                                            \
     struct via_renderbuffer *vrb = (struct via_renderbuffer *) rb;  \
-    __DRIdrawablePrivate *dPriv = vrb->dPriv;                       \
+    __DRIdrawable *dPriv = vrb->dPriv;                       \
     GLuint depth_pitch = vrb->pitch;                                \
     GLuint height = dPriv->h;                                       \
     char *buf = (char *)(vrb->map)
diff --git a/src/mesa/drivers/dri/unichrome/via_state.c b/src/mesa/drivers/dri/unichrome/via_state.c
index 840e4e4..e6e5526 100644
--- a/src/mesa/drivers/dri/unichrome/via_state.c
+++ b/src/mesa/drivers/dri/unichrome/via_state.c
@@ -476,7 +476,7 @@
     */
    if (ctx->Polygon.StippleFlag) {
       GLuint *stipple = &ctx->PolygonStipple[0];
-      __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+      __DRIdrawable *dPriv = vmesa->driDrawable;
       struct via_renderbuffer *const vrb = 
 	(struct via_renderbuffer *) dPriv->driverPrivate;
       GLint i;
@@ -722,7 +722,7 @@
 void viaCalcViewport(GLcontext *ctx)
 {
     struct via_context *vmesa = VIA_CONTEXT(ctx);
-    __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
+    __DRIdrawable *dPriv = vmesa->driDrawable;
     struct via_renderbuffer *const vrb = 
       (struct via_renderbuffer *) dPriv->driverPrivate;
     const GLfloat *v = ctx->Viewport._WindowMap.m;
@@ -891,10 +891,10 @@
             if (texObj->Image[0][texObj->BaseLevel]->Border > 0) {
 	       vmesa->regHTXnTB[0] |= (HC_HTXnTB_TBC_S | HC_HTXnTB_TBC_T);
 	       vmesa->regHTXnTBC[0] = 
-		  PACK_COLOR_888(FLOAT_TO_UBYTE(texObj->BorderColor[0]),
-				 FLOAT_TO_UBYTE(texObj->BorderColor[1]),
-				 FLOAT_TO_UBYTE(texObj->BorderColor[2]));
-	       vmesa->regHTXnTRAH[0] = FLOAT_TO_UBYTE(texObj->BorderColor[3]);
+		  PACK_COLOR_888(FLOAT_TO_UBYTE(texObj->BorderColor.f[0]),
+				 FLOAT_TO_UBYTE(texObj->BorderColor.f[1]),
+				 FLOAT_TO_UBYTE(texObj->BorderColor.f[2]));
+	       vmesa->regHTXnTRAH[0] = FLOAT_TO_UBYTE(texObj->BorderColor.f[3]);
             }
 
 	    if (texUnit0->LodBias != 0.0f) {
@@ -924,10 +924,10 @@
             if (texObj->Image[0][texObj->BaseLevel]->Border > 0) {
 	       vmesa->regHTXnTB[1] |= (HC_HTXnTB_TBC_S | HC_HTXnTB_TBC_T);
 	       vmesa->regHTXnTBC[1] = 
-		  PACK_COLOR_888(FLOAT_TO_UBYTE(texObj->BorderColor[0]),
-				 FLOAT_TO_UBYTE(texObj->BorderColor[1]),
-				 FLOAT_TO_UBYTE(texObj->BorderColor[2]));
-	       vmesa->regHTXnTRAH[1] = FLOAT_TO_UBYTE(texObj->BorderColor[3]);
+		  PACK_COLOR_888(FLOAT_TO_UBYTE(texObj->BorderColor.f[0]),
+				 FLOAT_TO_UBYTE(texObj->BorderColor.f[1]),
+				 FLOAT_TO_UBYTE(texObj->BorderColor.f[2]));
+	       vmesa->regHTXnTRAH[1] = FLOAT_TO_UBYTE(texObj->BorderColor.f[3]);
             }
 
 
@@ -1238,12 +1238,12 @@
     else
         vmesa->regHROP = HC_HROP_P;
 
-    vmesa->regHFBBMSKL = PACK_COLOR_888(ctx->Color.ColorMask[0],
-					ctx->Color.ColorMask[1],
-					ctx->Color.ColorMask[2]);
-    vmesa->regHROP |= ctx->Color.ColorMask[3];
+    vmesa->regHFBBMSKL = PACK_COLOR_888(ctx->Color.ColorMask[0][0],
+					ctx->Color.ColorMask[0][1],
+					ctx->Color.ColorMask[0][2]);
+    vmesa->regHROP |= ctx->Color.ColorMask[0][3];
 
-    if (ctx->Color.ColorMask[3])
+    if (ctx->Color.ColorMask[0][3])
         vmesa->regEnable |= HC_HenAW_MASK;
     else
         vmesa->regEnable &= ~HC_HenAW_MASK;
diff --git a/src/mesa/drivers/dri/unichrome/via_tris.c b/src/mesa/drivers/dri/unichrome/via_tris.c
index 79e6762..01359d5 100644
--- a/src/mesa/drivers/dri/unichrome/via_tris.c
+++ b/src/mesa/drivers/dri/unichrome/via_tris.c
@@ -330,7 +330,8 @@
 
 #define LOCAL_VARS(n)                                                   \
     struct via_context *vmesa = VIA_CONTEXT(ctx);                             \
-    GLuint color[n], spec[n];                                           \
+    GLuint color[n] = { 0 };                                          \
+    GLuint spec[n] = { 0 };                                           \
     GLuint coloroffset = vmesa->coloroffset;              \
     GLuint specoffset = vmesa->specoffset;                       \
     (void)color; (void)spec; (void)coloroffset; (void)specoffset;
@@ -832,13 +833,13 @@
 
    RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
 
-   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 ) && VB->TexCoordPtr[0]->size == 4) {
+   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 ) && VB->AttribPtr[_TNL_ATTRIB_TEX0]->size == 4) {
       if (!RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_ATTRIB_TEX1, _TNL_LAST_TEX ))
 	 ptexHack = GL_TRUE; 
       else
 	 fallback = GL_TRUE;
    }
-   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 ) && VB->TexCoordPtr[1]->size == 4)
+   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 ) && VB->AttribPtr[_TNL_ATTRIB_TEX1]->size == 4)
       fallback = GL_TRUE;
 
    FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_PROJ_TEXTURE, fallback);
diff --git a/src/mesa/drivers/glide/fxddtex.c b/src/mesa/drivers/glide/fxddtex.c
index a863b02..9dd4f1e 100644
--- a/src/mesa/drivers/glide/fxddtex.c
+++ b/src/mesa/drivers/glide/fxddtex.c
@@ -275,8 +275,9 @@
    /* apply any lod biasing right now */
    if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
       GLfloat bias = *param;
-      CLAMP_SELF(bias, -ctx->Const.MaxTextureLodBias,
-                        ctx->Const.MaxTextureLodBias - 0.25);
+      bias = CLAMP(bias,
+		   -ctx->Const.MaxTextureLodBias,
+		   ctx->Const.MaxTextureLodBias - 0.25);
 
       grTexLodBiasValue(GR_TMU0, bias);
 
diff --git a/src/mesa/drivers/glide/fxvb.c b/src/mesa/drivers/glide/fxvb.c
index 1dc5f98..cc9ad0e 100644
--- a/src/mesa/drivers/glide/fxvb.c
+++ b/src/mesa/drivers/glide/fxvb.c
@@ -104,24 +104,24 @@
 {
    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
 
-   if (VB->ColorPtr[1]) {
-      /* If stride is zero, ColorPtr[1] is constant across the VB, so
+   if (VB->BackfaceColorPtr) {
+      /* If stride is zero, BackfaceColorPtr is constant across the VB, so
        * there is no point interpolating between two values as they will
        * be identical.  This case is handled in t_dd_tritmp.h
        */
-      if (VB->ColorPtr[1]->stride) {
-	 assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat));
+      if (VB->BackfaceColorPtr->stride) {
+	 assert(VB->BackfaceColorPtr->stride == 4 * sizeof(GLfloat));
 	 INTERP_4F( t,
-		    GET_COLOR(VB->ColorPtr[1], dst),
-		    GET_COLOR(VB->ColorPtr[1], out),
-		    GET_COLOR(VB->ColorPtr[1], in) );
+		    GET_COLOR(VB->BackfaceColorPtr, dst),
+		    GET_COLOR(VB->BackfaceColorPtr, out),
+		    GET_COLOR(VB->BackfaceColorPtr, in) );
       }
 
-      if (VB->SecondaryColorPtr[1]) {
+      if (VB->BackfaceSecondaryColorPtr) {
 	 INTERP_3F( t,
-		    GET_COLOR(VB->SecondaryColorPtr[1], dst),
-		    GET_COLOR(VB->SecondaryColorPtr[1], out),
-		    GET_COLOR(VB->SecondaryColorPtr[1], in) );
+		    GET_COLOR(VB->BackfaceSecondaryColorPtr, dst),
+		    GET_COLOR(VB->BackfaceSecondaryColorPtr, out),
+		    GET_COLOR(VB->BackfaceSecondaryColorPtr, in) );
       }
    }
 
@@ -137,13 +137,13 @@
 {
    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
 
-   if (VB->ColorPtr[1]) {
-	 COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst),
-		   GET_COLOR(VB->ColorPtr[1], src) );
+   if (VB->BackfaceColorPtr) {
+	 COPY_4FV( GET_COLOR(VB->BackfaceColorPtr, dst),
+		   GET_COLOR(VB->BackfaceColorPtr, src) );
 
-	 if (VB->SecondaryColorPtr[1]) {
-	    COPY_3FV( GET_COLOR(VB->SecondaryColorPtr[1], dst),
-		      GET_COLOR(VB->SecondaryColorPtr[1], src) );
+	 if (VB->BackfaceSecondaryColorPtr) {
+	    COPY_3FV( GET_COLOR(VB->BackfaceSecondaryColorPtr, dst),
+		      GET_COLOR(VB->BackfaceSecondaryColorPtr, src) );
 	 }
    }
 
diff --git a/src/mesa/drivers/glide/fxvbtmp.h b/src/mesa/drivers/glide/fxvbtmp.h
index f7970c7..f7893c1 100644
--- a/src/mesa/drivers/glide/fxvbtmp.h
+++ b/src/mesa/drivers/glide/fxvbtmp.h
@@ -62,37 +62,37 @@
    }
 
    if (IND & SETUP_TMU0) {
-      tc0 = VB->TexCoordPtr[tmu0_source]->data;
-      tc0_stride = VB->TexCoordPtr[tmu0_source]->stride;
+      tc0 = VB->AttribPtr[_TNL_ATTRIB_TEX0 + tmu0_source]->data;
+      tc0_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + tmu0_source]->stride;
       u0scale = fxMesa->s0scale;
       v0scale = fxMesa->t0scale;
       if (IND & SETUP_PTEX)
-	 tc0_size = VB->TexCoordPtr[tmu0_source]->size;
+	 tc0_size = VB->AttribPtr[_TNL_ATTRIB_TEX0 + tmu0_source]->size;
    }
 
    if (IND & SETUP_TMU1) {
-      tc1 = VB->TexCoordPtr[tmu1_source]->data;
-      tc1_stride = VB->TexCoordPtr[tmu1_source]->stride;
+      tc1 = VB->AttribPtr[_TNL_ATTRIB_TEX0 + tmu1_source]->data;
+      tc1_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + tmu1_source]->stride;
       u1scale = fxMesa->s1scale; /* wrong if tmu1_source == 0, possible? */
       v1scale = fxMesa->t1scale;
       if (IND & SETUP_PTEX)
-	 tc1_size = VB->TexCoordPtr[tmu1_source]->size;
+	 tc1_size = VB->AttribPtr[_TNL_ATTRIB_TEX0 + tmu1_source]->size;
    }
    
    if (IND & SETUP_RGBA) {
-      col = VB->ColorPtr[0]->data;
-      col_stride = VB->ColorPtr[0]->stride;
-      col_size = VB->ColorPtr[0]->size;
+      col = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;
+      col_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride;
+      col_size = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->size;
    }
 
    if (IND & SETUP_SPEC) {
-      spec = VB->SecondaryColorPtr[0]->data;
-      spec_stride = VB->SecondaryColorPtr[0]->stride;
+      spec = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->data;
+      spec_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->stride;
    }
 
    if (IND & SETUP_FOGC) {
-      fog = VB->FogCoordPtr->data;
-      fog_stride = VB->FogCoordPtr->stride;
+      fog = VB->AttribPtr[_TNL_ATTRIB_FOG]->data;
+      fog_stride = VB->AttribPtr[_TNL_ATTRIB_FOG]->stride;
    }
 
    if (start) {
@@ -220,14 +220,15 @@
       struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
 
       if (IND & SETUP_TMU1) {
-	 if (VB->TexCoordPtr[0] == 0)
-	    VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
+	 if (VB->AttribPtr[_TNL_ATTRIB_TEX0] == 0)
+	    VB->AttribPtr[_TNL_ATTRIB_TEX0] = VB->AttribPtr[_TNL_ATTRIB_TEX1];
 	 
-	 if (VB->TexCoordPtr[1]->size == 4)
+	 if (VB->AttribPtr[_TNL_ATTRIB_TEX1]->size == 4)
 	    return GL_FALSE;
       }
 
-      if (VB->TexCoordPtr[0] && VB->TexCoordPtr[0]->size == 4)
+      if (VB->AttribPtr[_TNL_ATTRIB_TEX0] &&
+	  VB->AttribPtr[_TNL_ATTRIB_TEX0]->size == 4)
 	 return GL_FALSE;
    }
 
diff --git a/src/mesa/drivers/osmesa/Makefile b/src/mesa/drivers/osmesa/Makefile
index 92d4149..9010bbd 100644
--- a/src/mesa/drivers/osmesa/Makefile
+++ b/src/mesa/drivers/osmesa/Makefile
@@ -21,7 +21,11 @@
 
 # Standalone osmesa needs to be linked with core Mesa APIs
 ifeq ($(DRIVER_DIRS), osmesa)
-CORE_MESA = $(TOP)/src/mesa/libmesa.a $(TOP)/src/mesa/libglapi.a
+CORE_MESA = \
+	$(TOP)/src/mesa/libmesa.a \
+	$(TOP)/src/mesa/libglapi.a \
+	$(TOP)/src/glsl/cl/libglslcl.a \
+	$(TOP)/src/glsl/pp/libglslpp.a
 else
 CORE_MESA =
 endif
diff --git a/src/mesa/drivers/windows/gdi/wmesa.c b/src/mesa/drivers/windows/gdi/wmesa.c
index 8929b22..76c825a 100644
--- a/src/mesa/drivers/windows/gdi/wmesa.c
+++ b/src/mesa/drivers/windows/gdi/wmesa.c
@@ -301,10 +301,10 @@
 
     /* Let swrast do all the work if the masks are not set to
      * clear all channels. */
-    if (ctx->Color.ColorMask[0] != 0xff ||
-	ctx->Color.ColorMask[1] != 0xff ||
-	ctx->Color.ColorMask[2] != 0xff ||
-	ctx->Color.ColorMask[3] != 0xff) {
+    if (!ctx->Color.ColorMask[0][0] ||
+	!ctx->Color.ColorMask[0][1] ||
+	!ctx->Color.ColorMask[0][2] ||
+	!ctx->Color.ColorMask[0][3]) {
 	_swrast_Clear(ctx, mask);
 	return;
     }
diff --git a/src/mesa/drivers/windows/gldirect/dx7/gld_driver_dx7.c b/src/mesa/drivers/windows/gldirect/dx7/gld_driver_dx7.c
index d5fa642..7b202df 100644
--- a/src/mesa/drivers/windows/gldirect/dx7/gld_driver_dx7.c
+++ b/src/mesa/drivers/windows/gldirect/dx7/gld_driver_dx7.c
@@ -269,7 +269,7 @@
 	D3DRECT		d3dClearRect;
 
 	// TODO: Colourmask
-	const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
+	const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask[0];
 
 	if (!gld->pDev)
 		return;
@@ -427,10 +427,10 @@
 
 /*
 	// Color mask - unsupported by DX7
-	if (ctx->Color.ColorMask[0]) dwFlags |= D3DCOLORWRITEENABLE_RED;
-	if (ctx->Color.ColorMask[1]) dwFlags |= D3DCOLORWRITEENABLE_GREEN;
-	if (ctx->Color.ColorMask[2]) dwFlags |= D3DCOLORWRITEENABLE_BLUE;
-	if (ctx->Color.ColorMask[3]) dwFlags |= D3DCOLORWRITEENABLE_ALPHA;
+	if (ctx->Color.ColorMask[0][0]) dwFlags |= D3DCOLORWRITEENABLE_RED;
+	if (ctx->Color.ColorMask[0][1]) dwFlags |= D3DCOLORWRITEENABLE_GREEN;
+	if (ctx->Color.ColorMask[0][2]) dwFlags |= D3DCOLORWRITEENABLE_BLUE;
+	if (ctx->Color.ColorMask[0][3]) dwFlags |= D3DCOLORWRITEENABLE_ALPHA;
 	_GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_COLORWRITEENABLE, dwFlags));
 */
 }
diff --git a/src/mesa/drivers/windows/gldirect/dx7/gld_primitive_dx7.c b/src/mesa/drivers/windows/gldirect/dx7/gld_primitive_dx7.c
index c99ba0b..0b37381 100644
--- a/src/mesa/drivers/windows/gldirect/dx7/gld_primitive_dx7.c
+++ b/src/mesa/drivers/windows/gldirect/dx7/gld_primitive_dx7.c
@@ -189,9 +189,9 @@
 		GLfloat		ex,ey,fx,fy,cc;							\
 		/* Get vars for later */							\
 		VB		= &TNL_CONTEXT(ctx)->vb;					\
-		vbcolor	= (GLchan (*)[4])VB->ColorPtr[1]->data;		\
-		if (VB->SecondaryColorPtr[1]) {						\
-			vbspec = (GLchan (*)[4])VB->SecondaryColorPtr[1]->data;	\
+		vbcolor	= (GLchan (*)[4])VB->BackfaceColorPtr->data;	\
+		if (VB->BackfaceSecondaryColorPtr) {			\
+			vbspec = (GLchan (*)[4])VB->BackfaceSecondaryColorPtr->data;	\
 		} else {													\
 			vbspec = NULL;											\
 		}															\
@@ -241,33 +241,33 @@
 	DWORD					dwColor;
 
 #define GLD_SETUP_3D_VERTEX(v)					\
-	p4f				= VB->ObjPtr->data;			\
+	p4f = VB->AttribPtr[_TNL_ATTRIB_POS]->data;		\
 	pV->Position.x	= p4f[##v][0];				\
 	pV->Position.y	= p4f[##v][1];				\
 	pV->Position.z	= p4f[##v][2];
 
 #define GLD_SETUP_SMOOTH_COLOUR_3D(v)															\
-	p4f			= (GLfloat (*)[4])VB->ColorPtr[0]->data;										\
+	p4f = (GLfloat (*)[4])VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;										\
 	pV->Diffuse	= D3DCOLOR_COLORVALUE(p4f[##v][0], p4f[##v][1], p4f[##v][2], p4f[##v][3]);
 
 
 #define GLD_SETUP_GET_FLAT_COLOUR_3D(v)													\
-	p4f		= (GLfloat (*)[4])VB->ColorPtr[0]->data;										\
+	p4f = (GLfloat (*)[4])VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;	\
 	dwColor	= D3DCOLOR_COLORVALUE(p4f[##v][0], p4f[##v][1], p4f[##v][2], p4f[##v][3]);
 
 #define GLD_SETUP_USE_FLAT_COLOUR_3D			\
 	pV->Diffuse = dwColor;
 
 #define GLD_SETUP_TEX0_3D(v)						\
-	if (VB->TexCoordPtr[0]) {						\
-		tc				= VB->TexCoordPtr[0]->data;	\
+	if (VB->AttribPtr[_TNL_ATTRIB_TEX0]) {				\
+		tc = VB->AttribPtr[_TNL_ATTRIB_TEX0]->data;		\
 		pV->TexUnit0.x	= tc[##v][0];				\
 		pV->TexUnit0.y	= tc[##v][1];				\
 	}
 
 #define GLD_SETUP_TEX1_3D(v)						\
-	if (VB->TexCoordPtr[1]) {						\
-		tc				= VB->TexCoordPtr[1]->data;	\
+	if (VB->AttribPtr[_TNL_ATTRIB_TEX1]) {				\
+		tc = VB->AttribPtr[_TNL_ATTRIB_TEX1]->data;		\
 		pV->TexUnit1.x	= tc[##v][0];				\
 		pV->TexUnit1.y	= tc[##v][1];				\
 	}
diff --git a/src/mesa/drivers/windows/gldirect/dx7/gld_vb_d3d_render_dx7.c b/src/mesa/drivers/windows/gldirect/dx7/gld_vb_d3d_render_dx7.c
index a85620d..c39775c 100644
--- a/src/mesa/drivers/windows/gldirect/dx7/gld_vb_d3d_render_dx7.c
+++ b/src/mesa/drivers/windows/gldirect/dx7/gld_vb_d3d_render_dx7.c
@@ -151,7 +151,7 @@
 #if 0
    // For debugging: Useful to see if an app passes colour data in
    // an unusual format.
-   switch (VB->ColorPtr[0]->Type) {
+   switch (VB->AttribPtr[_TNL_ATTRIB_COLOR0]->Type) {
    case GL_FLOAT:
 	   ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: GL_FLOAT\n");
 	   break;
diff --git a/src/mesa/drivers/windows/gldirect/dx8/gld_driver_dx8.c b/src/mesa/drivers/windows/gldirect/dx8/gld_driver_dx8.c
index 7afa919..7eeb9db 100644
--- a/src/mesa/drivers/windows/gldirect/dx8/gld_driver_dx8.c
+++ b/src/mesa/drivers/windows/gldirect/dx8/gld_driver_dx8.c
@@ -269,7 +269,7 @@
 	D3DRECT		d3dClearRect;
 
 	// TODO: Colourmask
-	const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
+	const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask[0];
 
 	if (!gld->pDev)
 		return;
@@ -426,10 +426,10 @@
 	_GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_DESTBLEND, dest));
 
 	// Color mask
-	if (ctx->Color.ColorMask[0]) dwFlags |= D3DCOLORWRITEENABLE_RED;
-	if (ctx->Color.ColorMask[1]) dwFlags |= D3DCOLORWRITEENABLE_GREEN;
-	if (ctx->Color.ColorMask[2]) dwFlags |= D3DCOLORWRITEENABLE_BLUE;
-	if (ctx->Color.ColorMask[3]) dwFlags |= D3DCOLORWRITEENABLE_ALPHA;
+	if (ctx->Color.ColorMask[0][0]) dwFlags |= D3DCOLORWRITEENABLE_RED;
+	if (ctx->Color.ColorMask[0][1]) dwFlags |= D3DCOLORWRITEENABLE_GREEN;
+	if (ctx->Color.ColorMask[0][2]) dwFlags |= D3DCOLORWRITEENABLE_BLUE;
+	if (ctx->Color.ColorMask[0][3]) dwFlags |= D3DCOLORWRITEENABLE_ALPHA;
 	_GLD_DX8_DEV(SetRenderState(gld->pDev, D3DRS_COLORWRITEENABLE, dwFlags));
 }
 
diff --git a/src/mesa/drivers/windows/gldirect/dx8/gld_primitive_dx8.c b/src/mesa/drivers/windows/gldirect/dx8/gld_primitive_dx8.c
index a5b5462..9909225 100644
--- a/src/mesa/drivers/windows/gldirect/dx8/gld_primitive_dx8.c
+++ b/src/mesa/drivers/windows/gldirect/dx8/gld_primitive_dx8.c
@@ -189,9 +189,9 @@
 		GLfloat		ex,ey,fx,fy,cc;							\
 		/* Get vars for later */							\
 		VB		= &TNL_CONTEXT(ctx)->vb;					\
-		vbcolor	= (GLchan (*)[4])VB->ColorPtr[1]->data;		\
-		if (VB->SecondaryColorPtr[1]) {						\
-			vbspec = (GLchan (*)[4])VB->SecondaryColorPtr[1]->data;	\
+		vbcolor	= (GLchan (*)[4])VB->BackfaceColorPtr->data;	\
+		if (VB->BackfaceSecondaryColorPtr) {			\
+			vbspec = (GLchan (*)[4])VB->BackfaceSecondaryColorPtr->data;	\
 		} else {													\
 			vbspec = NULL;											\
 		}															\
@@ -241,33 +241,33 @@
 	DWORD					dwColor;
 
 #define GLD_SETUP_3D_VERTEX(v)					\
-	p4f				= VB->ObjPtr->data;			\
+	p4f = VB->AttribPtr[_TNL_ATTRIB_POS]->data;		\
 	pV->Position.x	= p4f[##v][0];				\
 	pV->Position.y	= p4f[##v][1];				\
 	pV->Position.z	= p4f[##v][2];
 
 #define GLD_SETUP_SMOOTH_COLOUR_3D(v)															\
-	p4f			= (GLfloat (*)[4])VB->ColorPtr[0]->data;										\
+	p4f = (GLfloat (*)[4])VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;	\
 	pV->Diffuse	= D3DCOLOR_COLORVALUE(p4f[##v][0], p4f[##v][1], p4f[##v][2], p4f[##v][3]);
 
 
 #define GLD_SETUP_GET_FLAT_COLOUR_3D(v)													\
-	p4f		= (GLfloat (*)[4])VB->ColorPtr[0]->data;										\
+	p4f = (GLfloat (*)[4])VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;	\
 	dwColor	= D3DCOLOR_COLORVALUE(p4f[##v][0], p4f[##v][1], p4f[##v][2], p4f[##v][3]);
 
 #define GLD_SETUP_USE_FLAT_COLOUR_3D			\
 	pV->Diffuse = dwColor;
 
 #define GLD_SETUP_TEX0_3D(v)						\
-	if (VB->TexCoordPtr[0]) {						\
-		tc				= VB->TexCoordPtr[0]->data;	\
+	if (VB->AttribPtr[_TNL_ATTRIB_TEX0]) {				\
+		tc = VB->TnlAttribPtr[_TNL_ATTRIB_TEX0]->data;		\
 		pV->TexUnit0.x	= tc[##v][0];				\
 		pV->TexUnit0.y	= tc[##v][1];				\
 	}
 
 #define GLD_SETUP_TEX1_3D(v)						\
-	if (VB->TexCoordPtr[1]) {						\
-		tc				= VB->TexCoordPtr[1]->data;	\
+	if (VB->TnlAttribPtr[_TNL_ATTRIB_TEX1]) {			\
+		tc = VB->TnlAttribPtr[_TNL_ATTRIB_TEX1]->data;		\
 		pV->TexUnit1.x	= tc[##v][0];				\
 		pV->TexUnit1.y	= tc[##v][1];				\
 	}
diff --git a/src/mesa/drivers/windows/gldirect/dx8/gld_vb_d3d_render_dx8.c b/src/mesa/drivers/windows/gldirect/dx8/gld_vb_d3d_render_dx8.c
index cafbf4f..265c81f 100644
--- a/src/mesa/drivers/windows/gldirect/dx8/gld_vb_d3d_render_dx8.c
+++ b/src/mesa/drivers/windows/gldirect/dx8/gld_vb_d3d_render_dx8.c
@@ -149,7 +149,7 @@
 #if 0
    // For debugging: Useful to see if an app passes colour data in
    // an unusual format.
-   switch (VB->ColorPtr[0]->Type) {
+   switch (VB->AttribPtr[_TNL_ATTRIB_COLOR0]->Type) {
    case GL_FLOAT:
 	   ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: GL_FLOAT\n");
 	   break;
diff --git a/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c b/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c
index c191564..0558462 100644
--- a/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c
+++ b/src/mesa/drivers/windows/gldirect/dx9/gld_driver_dx9.c
@@ -269,7 +269,7 @@
 	D3DRECT		d3dClearRect;
 
 	// TODO: Colourmask
-	const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
+	const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask[0];
 
 	if (!gld->pDev)
 		return;
@@ -424,10 +424,10 @@
 	_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_DESTBLEND, dest));
 
 	// Color mask
-	if (ctx->Color.ColorMask[0]) dwFlags |= D3DCOLORWRITEENABLE_RED;
-	if (ctx->Color.ColorMask[1]) dwFlags |= D3DCOLORWRITEENABLE_GREEN;
-	if (ctx->Color.ColorMask[2]) dwFlags |= D3DCOLORWRITEENABLE_BLUE;
-	if (ctx->Color.ColorMask[3]) dwFlags |= D3DCOLORWRITEENABLE_ALPHA;
+	if (ctx->Color.ColorMask[0][0]) dwFlags |= D3DCOLORWRITEENABLE_RED;
+	if (ctx->Color.ColorMask[0][1]) dwFlags |= D3DCOLORWRITEENABLE_GREEN;
+	if (ctx->Color.ColorMask[0][2]) dwFlags |= D3DCOLORWRITEENABLE_BLUE;
+	if (ctx->Color.ColorMask[0][3]) dwFlags |= D3DCOLORWRITEENABLE_ALPHA;
 	_GLD_DX9_DEV(SetRenderState(gld->pDev, D3DRS_COLORWRITEENABLE, dwFlags));
 }
 
diff --git a/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c b/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c
index 403a9d5..fd4dd4e 100644
--- a/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c
+++ b/src/mesa/drivers/windows/gldirect/dx9/gld_primitive_dx9.c
@@ -189,9 +189,9 @@
 		GLfloat		ex,ey,fx,fy,cc;							\
 		/* Get vars for later */							\
 		VB		= &TNL_CONTEXT(ctx)->vb;					\
-		vbcolor	= (GLchan (*)[4])VB->ColorPtr[1]->data;		\
-		if (VB->SecondaryColorPtr[1]) {						\
-			vbspec = (GLchan (*)[4])VB->SecondaryColorPtr[1]->data;	\
+		vbcolor	= (GLchan (*)[4])VB->BackfaceColorPtr->data;	\
+		if (VB->BackfaceSecondaryColorPtr) {			\
+			vbspec = (GLchan (*)[4])VB->BackfaceSecondaryColorPtr->data;	\
 		} else {													\
 			vbspec = NULL;											\
 		}															\
@@ -241,33 +241,33 @@
 	DWORD					dwColor;
 
 #define GLD_SETUP_3D_VERTEX(v)					\
-	p4f				= VB->ObjPtr->data;			\
+	p4f = VB->AttribPtr[_TNL_ATTRIB_POS]->data;		\
 	pV->Position.x	= p4f[##v][0];				\
 	pV->Position.y	= p4f[##v][1];				\
 	pV->Position.z	= p4f[##v][2];
 
 #define GLD_SETUP_SMOOTH_COLOUR_3D(v)															\
-	p4f			= (GLfloat (*)[4])VB->ColorPtr[0]->data;										\
+	p4f = (GLfloat (*)[4])VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;										\
 	pV->Diffuse	= D3DCOLOR_COLORVALUE(p4f[##v][0], p4f[##v][1], p4f[##v][2], p4f[##v][3]);
 
 
 #define GLD_SETUP_GET_FLAT_COLOUR_3D(v)													\
-	p4f		= (GLfloat (*)[4])VB->ColorPtr[0]->data;										\
+	p4f = (GLfloat (*)[4])VB->AttribPtr[_TNL_ATTRIB_COLOR00]->data;	\
 	dwColor	= D3DCOLOR_COLORVALUE(p4f[##v][0], p4f[##v][1], p4f[##v][2], p4f[##v][3]);
 
 #define GLD_SETUP_USE_FLAT_COLOUR_3D			\
 	pV->Diffuse = dwColor;
 
 #define GLD_SETUP_TEX0_3D(v)						\
-	if (VB->TexCoordPtr[0]) {						\
-		tc				= VB->TexCoordPtr[0]->data;	\
+	if (VB->AttribPtr[_TNL_ATTRIB_TEX0]) {				\
+		tc = VB->AttribPtr[_TNL_ATTRIB_TEX0]->data;		\
 		pV->TexUnit0.x	= tc[##v][0];				\
 		pV->TexUnit0.y	= tc[##v][1];				\
 	}
 
 #define GLD_SETUP_TEX1_3D(v)						\
-	if (VB->TexCoordPtr[1]) {						\
-		tc				= VB->TexCoordPtr[1]->data;	\
+	if (VB->AttribPtr[_TNL_ATTRIB_TEX1]) {				\
+		tc = VB->AttribPtr[_TNL_ATTRIB_TEX1]->data;		\
 		pV->TexUnit1.x	= tc[##v][0];				\
 		pV->TexUnit1.y	= tc[##v][1];				\
 	}
diff --git a/src/mesa/drivers/windows/gldirect/dx9/gld_vb_d3d_render_dx9.c b/src/mesa/drivers/windows/gldirect/dx9/gld_vb_d3d_render_dx9.c
index 4fa6bca..91a68b3 100644
--- a/src/mesa/drivers/windows/gldirect/dx9/gld_vb_d3d_render_dx9.c
+++ b/src/mesa/drivers/windows/gldirect/dx9/gld_vb_d3d_render_dx9.c
@@ -149,7 +149,7 @@
 #if 0
    // For debugging: Useful to see if an app passes colour data in
    // an unusual format.
-   switch (VB->ColorPtr[0]->Type) {
+   switch (VB->AttribPtr[_TNL_ATTRIB_COLOR0]->Type) {
    case GL_FLOAT:
 	   ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: GL_FLOAT\n");
 	   break;
diff --git a/src/mesa/drivers/x11/glxapi.c b/src/mesa/drivers/x11/glxapi.c
index 66b9a41..5c7e8eb 100644
--- a/src/mesa/drivers/x11/glxapi.c
+++ b/src/mesa/drivers/x11/glxapi.c
@@ -1203,6 +1203,9 @@
 #ifdef GLX_EXT_texture_from_pixmap
       "GLX_EXT_texture_from_pixmap",
 #endif
+#ifdef GLX_INTEL_swap_event
+      "GLX_INTEL_swap_event",
+#endif
       NULL
    };
    return extensions;
diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c
index a27d704..df04e3a 100644
--- a/src/mesa/drivers/x11/xm_dd.c
+++ b/src/mesa/drivers/x11/xm_dd.c
@@ -381,7 +381,7 @@
 {
    if (ctx->DrawBuffer->Name == 0) {
       /* this is a window system framebuffer */
-      const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
+      const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask[0];
       XMesaBuffer b = XMESA_BUFFER(ctx->DrawBuffer);
       const GLint x = ctx->DrawBuffer->_Xmin;
       const GLint y = ctx->DrawBuffer->_Ymin;
diff --git a/src/mesa/drivers/x11/xm_span.c b/src/mesa/drivers/x11/xm_span.c
index 309cefc..c39d87c 100644
--- a/src/mesa/drivers/x11/xm_span.c
+++ b/src/mesa/drivers/x11/xm_span.c
@@ -3773,7 +3773,7 @@
  *          else return number of pixels to skip in the destination array.
  */
 static int
-clip_for_xgetimage(GLcontext *ctx, GLuint *n, GLint *x, GLint *y)
+clip_for_xgetimage(GLcontext *ctx, XMesaPixmap pixmap, GLuint *n, GLint *x, GLint *y)
 {
    XMesaContext xmesa = XMESA_CONTEXT(ctx);
    XMesaBuffer source = XMESA_BUFFER(ctx->DrawBuffer);
@@ -3783,7 +3783,7 @@
    GLint dx, dy;
    if (source->type == PBUFFER || source->type == PIXMAP)
       return 0;
-   XTranslateCoordinates(xmesa->display, source->frontxrb->pixmap, rootWin,
+   XTranslateCoordinates(xmesa->display, pixmap, rootWin,
                          *x, *y, &dx, &dy, &child);
    if (dx >= screenWidth) {
       /* totally clipped on right */
@@ -3827,7 +3827,7 @@
 #ifndef XFree86Server
       XMesaImage *span = NULL;
       int error;
-      int k = clip_for_xgetimage(ctx, &n, &x, &y);
+      int k = clip_for_xgetimage(ctx, xrb->pixmap, &n, &x, &y);
       if (k < 0)
          return;
       index += k;
@@ -3892,7 +3892,7 @@
 #else
       int k;
       y = YFLIP(xrb, y);
-      k = clip_for_xgetimage(ctx, &n, &x, &y);
+      k = clip_for_xgetimage(ctx, xrb->pixmap, &n, &x, &y);
       if (k < 0)
          return;
       rgba += k;
diff --git a/src/mesa/glapi/ARB_framebuffer_object.xml b/src/mesa/glapi/ARB_framebuffer_object.xml
index b700e7e..e6bdcd6 100644
--- a/src/mesa/glapi/ARB_framebuffer_object.xml
+++ b/src/mesa/glapi/ARB_framebuffer_object.xml
@@ -12,10 +12,10 @@
 
     <enum name="RENDERBUFFER"                             value="0x8D41"/>
 
-    <enum name="STENCIL_INDEX1_EXT"                       value="0x8D46"/>
-    <enum name="STENCIL_INDEX4_EXT"                       value="0x8D47"/>
-    <enum name="STENCIL_INDEX8_EXT"                       value="0x8D48"/>
-    <enum name="STENCIL_INDEX16_EXT"                      value="0x8D49"/>
+    <enum name="STENCIL_INDEX1"                           value="0x8D46"/>
+    <enum name="STENCIL_INDEX4"                           value="0x8D47"/>
+    <enum name="STENCIL_INDEX8"                           value="0x8D48"/>
+    <enum name="STENCIL_INDEX16"                          value="0x8D49"/>
 
     <enum name="RENDERBUFFER_WIDTH"              value="0x8D42"/>
     <enum name="RENDERBUFFER_HEIGHT"             value="0x8D43"/>
@@ -93,33 +93,35 @@
     <enum name="STENCIL_ATTACHMENT"                        value="0x8D20"/>
     <enum name="DEPTH_STENCIL_ATTACHMENT"                  value="0x821A"/>
 
-    <enum name="MAX_SAMPLES"                               value="0x8D57"/>
+    <enum name="MAX_SAMPLES"                     count="1" value="0x8D57">
+        <size name="Get" mode="get"/>
+    </enum>
 
     <enum name="FRAMEBUFFER_COMPLETE"                      value="0x8CD5"/>
     <enum name="FRAMEBUFFER_INCOMPLETE_ATTACHMENT"         value="0x8CD6"/>
     <enum name="FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT" value="0x8CD7"/>
-    <enum name="FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT"    value="0x8CDB"/>
-    <enum name="FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT"    value="0x8CDC"/>
+    <enum name="FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"        value="0x8CDB"/>
+    <enum name="FRAMEBUFFER_INCOMPLETE_READ_BUFFER"        value="0x8CDC"/>
     <enum name="FRAMEBUFFER_UNSUPPORTED"                   value="0x8CDD"/>
     <enum name="FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"        value="0x8D56"/>
     <enum name="FRAMEBUFFER_UNDEFINED"                     value="0x8219"/>
 
-    <enum name="FRAMEBUFFER_BINDING_EXT"         count="1" value="0x8CA6">
+    <enum name="FRAMEBUFFER_BINDING"             count="1" value="0x8CA6">
         <size name="Get" mode="get"/>
     </enum>
-    <enum name="DRAW_FRAMEBUFFER_BINDING_EXT"    count="1" value="0x8CA6">
+    <enum name="DRAW_FRAMEBUFFER_BINDING"        count="1" value="0x8CA6">
         <size name="Get" mode="get"/>
     </enum>
-    <enum name="READ_FRAMEBUFFER_BINDING_EXT"    count="1" value="0x8CAA">
+    <enum name="READ_FRAMEBUFFER_BINDING"        count="1" value="0x8CAA">
         <size name="Get" mode="get"/>
     </enum>
-    <enum name="RENDERBUFFER_BINDING_EXT"        count="1" value="0x8CA7">
+    <enum name="RENDERBUFFER_BINDING"            count="1" value="0x8CA7">
         <size name="Get" mode="get"/>
     </enum>
-    <enum name="MAX_COLOR_ATTACHMENTS_EXT"       count="1" value="0x8CDF">
+    <enum name="MAX_COLOR_ATTACHMENTS"           count="1" value="0x8CDF">
         <size name="Get" mode="get"/>
     </enum>
-    <enum name="MAX_RENDERBUFFER_SIZE_EXT"       count="1" value="0x84E8">
+    <enum name="MAX_RENDERBUFFER_SIZE"           count="1" value="0x84E8">
         <size name="Get" mode="get"/>
     </enum>
 
@@ -131,7 +133,10 @@
 
     <enum name="DEPTH24_STENCIL8"                         value="0x88F0"/>
 
-    <enum name="TEXTURE_STENCIL_SIZE"                     value="0x88F1"/>
+    <enum name="TEXTURE_STENCIL_SIZE"          count="1"  value="0x88F1">
+        <size name="GetTexLevelParameterfv" mode="get"/>
+        <size name="GetTexLevelParameteriv" mode="get"/>
+    </enum>
 
 
 
@@ -168,6 +173,7 @@
         <param name="internalformat" type="GLenum"/>
         <param name="width" type="GLsizei"/>
         <param name="height" type="GLsizei"/>
+        <glx rop="4331"/>
     </function>
 
     <function name="GetRenderbufferParameteriv" alias="GetRenderbufferParameterivEXT">
diff --git a/src/mesa/glapi/ARB_sync.xml b/src/mesa/glapi/ARB_sync.xml
index 37f4749..4e4eeba 100644
--- a/src/mesa/glapi/ARB_sync.xml
+++ b/src/mesa/glapi/ARB_sync.xml
@@ -33,8 +33,10 @@
     <enum name="WAIT_FAILED"                              value="0x911D"/>
 
     <enum name="SYNC_FLUSH_COMMANDS_BIT"                  value="0x00000001"/>
-    <enum name="TIMEOUT_IGNORED"                  value="0xFFFFFFFFFFFFFFFF"/>
 
+    <!-- Not really an enum:
+    <enum name="TIMEOUT_IGNORED"                  value="0xFFFFFFFFFFFFFFFF"/>
+    -->
 
 
     <function name="FenceSync" offset="assign">
diff --git a/src/mesa/glapi/EXT_draw_buffers2.xml b/src/mesa/glapi/EXT_draw_buffers2.xml
new file mode 100644
index 0000000..efbe61f
--- /dev/null
+++ b/src/mesa/glapi/EXT_draw_buffers2.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<!-- Note: no GLX protocol info yet. -->
+
+
+<OpenGLAPI>
+
+<category name="GL_EXT_draw_buffers2" number="340">
+
+    <function name="ColorMaskIndexedEXT" offset="assign">
+	<param name="buf" type="GLuint"/>
+	<param name="r" type="GLboolean"/>
+	<param name="g" type="GLboolean"/>
+	<param name="b" type="GLboolean"/>
+	<param name="a" type="GLboolean"/>
+    </function>
+
+    <function name="GetBooleanIndexedvEXT" offset="assign">
+        <param name="value" type="GLenum"/>
+	<param name="index" type="GLuint"/>
+	<param name="data" type="GLboolean *"/>
+    </function>
+
+    <function name="GetIntegerIndexedvEXT" offset="assign">
+        <param name="value" type="GLenum"/>
+	<param name="index" type="GLuint"/>
+	<param name="data" type="GLint *"/>
+    </function>
+
+    <function name="EnableIndexedEXT" offset="assign">
+        <param name="target" type="GLenum"/>
+	<param name="index" type="GLuint"/>
+    </function>
+
+    <function name="DisableIndexedEXT" offset="assign">
+        <param name="target" type="GLenum"/>
+	<param name="index" type="GLuint"/>
+    </function>
+
+    <function name ="IsEnabledIndexedEXT" offset="assign">
+        <param name="target" type="GLenum"/>
+	<param name="index" type="GLuint"/>
+	<return type="GLboolean"/>
+    </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/src/mesa/glapi/EXT_framebuffer_object.xml b/src/mesa/glapi/EXT_framebuffer_object.xml
index 5559b48..4f418f7 100644
--- a/src/mesa/glapi/EXT_framebuffer_object.xml
+++ b/src/mesa/glapi/EXT_framebuffer_object.xml
@@ -192,4 +192,44 @@
     </function>
 </category>
 
+<category name="GL_EXT_framebuffer_blit" number="316">
+    <enum name="READ_FRAMEBUFFER_EXT" value="0x8CA8"/>
+    <enum name="DRAW_FRAMEBUFFER_EXT" value="0x8CA9"/>
+    <enum name="DRAW_FRAMEBUFFER_BINDING_EXT" count="1" value="0x8CA6">
+        <size name="Get" mode="get"/>
+    </enum>
+    <enum name="READ_FRAMEBUFFER_BINDING_EXT" count="1" value="0x8CAA">
+        <size name="Get" mode="get"/>
+    </enum>
+    <function name="BlitFramebufferEXT" offset="assign" static_dispatch="false">
+        <param name="srcX0" type="GLint"/>
+        <param name="srcY0" type="GLint"/>
+        <param name="srcX1" type="GLint"/>
+        <param name="srcY1" type="GLint"/>
+        <param name="dstX0" type="GLint"/>
+        <param name="dstY0" type="GLint"/>
+        <param name="dstX1" type="GLint"/>
+        <param name="dstY1" type="GLint"/>
+        <param name="mask" type="GLbitfield"/>
+        <param name="filter" type="GLenum"/>
+        <glx rop="4330"/>
+    </function>
+</category>
+
+<category name="GL_EXT_framebuffer_multisample" number="317">
+    <enum name="RENDERBUFFER_SAMPLES_EXT"                  value="0x8CAB"/>
+    <enum name="FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT"    value="0x8D56"/>
+    <enum name="MAX_SAMPLES_EXT"                 count="1" value="0x8D57">
+        <size name="Get" mode="get"/>
+    </enum>
+
+    <function name="RenderbufferStorageMultisampleEXT" alias="RenderbufferStorageMultisample">
+        <param name="target" type="GLenum"/>
+        <param name="samples" type="GLsizei"/>
+        <param name="internalformat" type="GLenum"/>
+        <param name="width" type="GLsizei"/>
+        <param name="height" type="GLsizei"/>
+    </function>
+</category>
+
 </OpenGLAPI>
diff --git a/src/mesa/glapi/EXT_packed_depth_stencil.xml b/src/mesa/glapi/EXT_packed_depth_stencil.xml
new file mode 100644
index 0000000..5be8103
--- /dev/null
+++ b/src/mesa/glapi/EXT_packed_depth_stencil.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+<category name="GL_EXT_packed_depth_stencil" number="312">
+    <!-- These enums are shared with GL_NV_packed_depth_stencil. -->
+    <enum name="DEPTH_STENCIL_EXT"                        value="0x84F9"/>
+    <enum name="UNSIGNED_INT_24_8_EXT"                    value="0x84FA"/>
+
+    <enum name="DEPTH24_STENCIL8_EXT"                     value="0x88F0"/>
+
+    <enum name="TEXTURE_STENCIL_SIZE_EXT"      count="1"  value="0x88F1">
+        <size name="GetTexLevelParameterfv" mode="get"/>
+        <size name="GetTexLevelParameteriv" mode="get"/>
+    </enum>
+</category>
+
+</OpenGLAPI>
diff --git a/src/mesa/glapi/EXT_texture_array.xml b/src/mesa/glapi/EXT_texture_array.xml
index e5bd9f3..b5b8bd4 100644
--- a/src/mesa/glapi/EXT_texture_array.xml
+++ b/src/mesa/glapi/EXT_texture_array.xml
@@ -35,6 +35,7 @@
         <param name="texture" type="GLuint"/>
         <param name="level" type="GLint"/>
         <param name="layer" type="GLint"/>
+	<glx rop="237"/>
     </function>
 </category>
 
diff --git a/src/mesa/glapi/Makefile b/src/mesa/glapi/Makefile
index fb6be1a..4db0ff1 100644
--- a/src/mesa/glapi/Makefile
+++ b/src/mesa/glapi/Makefile
@@ -47,16 +47,21 @@
 	$(SERVER_GLAPI_FILES)
 
 API_XML = gl_API.xml \
-	EXT_framebuffer_object.xml \
 	ARB_copy_buffer.xml \
 	ARB_depth_clamp.xml \
+	ARB_draw_elements_base_vertex.xml \
 	ARB_framebuffer_object.xml \
 	ARB_map_buffer_range.xml \
 	ARB_seamless_cube_map.xml \
 	ARB_sync.xml \
 	ARB_vertex_array_object.xml \
 	APPLE_vertex_array_object.xml \
-	EXT_provoking_vertex.xml
+	EXT_draw_buffers2.xml \
+	EXT_framebuffer_object.xml \
+	EXT_packed_depth_stencil.xml \
+	EXT_provoking_vertex.xml \
+	EXT_texture_array.xml \
+	NV_conditional_render.xml
 
 COMMON = gl_XML.py glX_XML.py license.py $(API_XML) typeexpr.py
 COMMON_GLX = $(COMMON) glX_API.xml glX_XML.py glX_proto_common.py
diff --git a/src/mesa/glapi/NV_conditional_render.xml b/src/mesa/glapi/NV_conditional_render.xml
new file mode 100644
index 0000000..8bb31dd
--- /dev/null
+++ b/src/mesa/glapi/NV_conditional_render.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<!-- Note: no GLX protocol info yet. -->
+
+
+<OpenGLAPI>
+
+<category name="GL_NV_condtitional_render" number="346">
+
+    <enum name="QUERY_WAIT_NV"               value="0x8E13"/>
+    <enum name="QUERY_NO_WAIT_NV"            value="0x8E14"/>
+    <enum name="QUERY_BY_REGION_WAIT_NV"     value="0x8E15"/>
+    <enum name="QUERY_BY_REGION_NO_WAIT_NV"  value="0x8E16"/>
+
+    <function name="BeginConditionalRenderNV" offset="assign">
+	<param name="query" type="GLuint"/>
+	<param name="mode" type="GLenum"/>
+    </function>
+
+    <function name="EndConditionalRenderNV" offset="assign">
+    </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/src/mesa/glapi/gl_API.xml b/src/mesa/glapi/gl_API.xml
index da4be14..75d2f3c 100644
--- a/src/mesa/glapi/gl_API.xml
+++ b/src/mesa/glapi/gl_API.xml
@@ -7962,6 +7962,8 @@
 
 <xi:include href="ARB_draw_elements_base_vertex.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
 
+<xi:include href="NV_conditional_render.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
 
 <!-- Non-ARB extensions sorted by extension number. -->
 
@@ -12238,30 +12240,12 @@
 
 <xi:include href="EXT_framebuffer_object.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
 
+<xi:include href="EXT_packed_depth_stencil.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
 <xi:include href="EXT_provoking_vertex.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
 
-<category name="GL_EXT_framebuffer_blit" number="316">
-    <enum name="READ_FRAMEBUFFER_EXT" value="0x8CA8"/>
-    <enum name="DRAW_FRAMEBUFFER_EXT" value="0x8CA9"/>
-    <enum name="DRAW_FRAMEBUFFER_BINDING_EXT" count="1" value="0x8CA6">
-        <size name="Get" mode="get"/>
-    </enum>
-    <enum name="READ_FRAMEBUFFER_BINDING_EXT" count="1" value="0x8CAA">
-        <size name="Get" mode="get"/>
-    </enum>
-    <function name="BlitFramebufferEXT" offset="assign" static_dispatch="false">
-        <param name="srcX0" type="GLint"/>
-        <param name="srcY0" type="GLint"/>
-        <param name="srcX1" type="GLint"/>
-        <param name="srcY1" type="GLint"/>
-        <param name="dstX0" type="GLint"/>
-        <param name="dstY0" type="GLint"/>
-        <param name="dstX1" type="GLint"/>
-        <param name="dstY1" type="GLint"/>
-        <param name="mask" type="GLbitfield"/>
-        <param name="filter" type="GLenum"/>
-    </function>
-</category>
+<xi:include href="EXT_draw_buffers2.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
 
 <category name="GL_APPLE_flush_buffer_range" number="321">
     <enum name="BUFFER_SERIALIZED_MODIFY_APPLE" count="1" value="0x8A12">
diff --git a/src/mesa/glapi/glapi.c b/src/mesa/glapi/glapi.c
index ad72fe4..adb47f9 100644
--- a/src/mesa/glapi/glapi.c
+++ b/src/mesa/glapi/glapi.c
@@ -73,7 +73,6 @@
 #include "glapi/glapioffsets.h"
 #include "glapi/glapitable.h"
 
-
 /***** BEGIN NO-OP DISPATCH *****/
 
 static GLboolean WarnFlag = GL_FALSE;
@@ -97,22 +96,19 @@
    warning_func = func;
 }
 
-static GLboolean
-warn(void)
+static int
+warn(const char *func)
 {
 #if !defined(_WIN32_WCE)
    if ((WarnFlag || getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG"))
        && warning_func) {
-      return GL_TRUE;
+      warning_func(NULL, "GL User Error: called without context: %s", func);
    }
-   else {
-      return GL_FALSE;
-   }
-#else
-   return GL_FALSE;
 #endif
+   return 0;
 }
 
+#ifdef DEBUG
 
 #define KEYWORD1 static
 #define KEYWORD1_ALT static
@@ -122,27 +118,34 @@
 #define F NULL
 
 #define DISPATCH(func, args, msg)					      \
-   if (warn()) {							      \
-      warning_func(NULL, "GL User Error: called without context: %s", #func); \
-   }
+   warn(#func);
 
 #define RETURN_DISPATCH(func, args, msg)				      \
-   if (warn()) {							      \
-      warning_func(NULL, "GL User Error: called without context: %s", #func); \
-   }									      \
-   return 0
+   return warn(#func);
+
+#define TABLE_ENTRY(name) (_glapi_proc) NoOp##name
+
+#else
+
+static void
+NoOpGeneric(void)
+{
+   if ((WarnFlag || getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG"))
+       && warning_func) {
+      warning_func(NULL, "GL User Error: calling GL function");
+   }
+}
+
+#define TABLE_ENTRY(name) (_glapi_proc) NoOpGeneric
+
+#endif
 
 #define DISPATCH_TABLE_NAME __glapi_noop_table
 #define UNUSED_TABLE_NAME __unused_noop_functions
 
-#define TABLE_ENTRY(name) (_glapi_proc) NoOp##name
-
 static GLint NoOpUnused(void)
 {
-   if (warn()) {
-      warning_func(NULL, "GL User Error: calling extension function without a current context\n");
-   }
-   return 0;
+   return warn("extension function");
 }
 
 #include "glapi/glapitemp.h"
@@ -237,7 +240,7 @@
  * We should call this periodically from a function such as glXMakeCurrent
  * in order to test if multiple threads are being used.
  */
-void
+PUBLIC void
 _glapi_check_multithread(void)
 {
 #if defined(THREADS) && !defined(GLX_USE_TLS)
diff --git a/src/mesa/glapi/glapi_getproc.c b/src/mesa/glapi/glapi_getproc.c
index decdd05..eecfb9c 100644
--- a/src/mesa/glapi/glapi_getproc.c
+++ b/src/mesa/glapi/glapi_getproc.c
@@ -530,7 +530,7 @@
  * in the name of static functions, try generating a new API entrypoint on
  * the fly with assembly language.
  */
-_glapi_proc
+PUBLIC _glapi_proc
 _glapi_get_proc_address(const char *funcName)
 {
    struct _glapi_function * entry;
diff --git a/src/mesa/glapi/glapidispatch.h b/src/mesa/glapi/glapidispatch.h
index d6ba928..51ae7fe 100644
--- a/src/mesa/glapi/glapidispatch.h
+++ b/src/mesa/glapi/glapidispatch.h
@@ -2422,6 +2422,30 @@
 #define CALL_FramebufferTextureLayerEXT(disp, parameters) (*((disp)->FramebufferTextureLayerEXT)) parameters
 #define GET_FramebufferTextureLayerEXT(disp) ((disp)->FramebufferTextureLayerEXT)
 #define SET_FramebufferTextureLayerEXT(disp, fn) ((disp)->FramebufferTextureLayerEXT = fn)
+#define CALL_ColorMaskIndexedEXT(disp, parameters) (*((disp)->ColorMaskIndexedEXT)) parameters
+#define GET_ColorMaskIndexedEXT(disp) ((disp)->ColorMaskIndexedEXT)
+#define SET_ColorMaskIndexedEXT(disp, fn) ((disp)->ColorMaskIndexedEXT = fn)
+#define CALL_DisableIndexedEXT(disp, parameters) (*((disp)->DisableIndexedEXT)) parameters
+#define GET_DisableIndexedEXT(disp) ((disp)->DisableIndexedEXT)
+#define SET_DisableIndexedEXT(disp, fn) ((disp)->DisableIndexedEXT = fn)
+#define CALL_EnableIndexedEXT(disp, parameters) (*((disp)->EnableIndexedEXT)) parameters
+#define GET_EnableIndexedEXT(disp) ((disp)->EnableIndexedEXT)
+#define SET_EnableIndexedEXT(disp, fn) ((disp)->EnableIndexedEXT = fn)
+#define CALL_GetBooleanIndexedvEXT(disp, parameters) (*((disp)->GetBooleanIndexedvEXT)) parameters
+#define GET_GetBooleanIndexedvEXT(disp) ((disp)->GetBooleanIndexedvEXT)
+#define SET_GetBooleanIndexedvEXT(disp, fn) ((disp)->GetBooleanIndexedvEXT = fn)
+#define CALL_GetIntegerIndexedvEXT(disp, parameters) (*((disp)->GetIntegerIndexedvEXT)) parameters
+#define GET_GetIntegerIndexedvEXT(disp) ((disp)->GetIntegerIndexedvEXT)
+#define SET_GetIntegerIndexedvEXT(disp, fn) ((disp)->GetIntegerIndexedvEXT = fn)
+#define CALL_IsEnabledIndexedEXT(disp, parameters) (*((disp)->IsEnabledIndexedEXT)) parameters
+#define GET_IsEnabledIndexedEXT(disp) ((disp)->IsEnabledIndexedEXT)
+#define SET_IsEnabledIndexedEXT(disp, fn) ((disp)->IsEnabledIndexedEXT = fn)
+#define CALL_BeginConditionalRenderNV(disp, parameters) (*((disp)->BeginConditionalRenderNV)) parameters
+#define GET_BeginConditionalRenderNV(disp) ((disp)->BeginConditionalRenderNV)
+#define SET_BeginConditionalRenderNV(disp, fn) ((disp)->BeginConditionalRenderNV = fn)
+#define CALL_EndConditionalRenderNV(disp, parameters) (*((disp)->EndConditionalRenderNV)) parameters
+#define GET_EndConditionalRenderNV(disp) ((disp)->EndConditionalRenderNV)
+#define SET_EndConditionalRenderNV(disp, fn) ((disp)->EndConditionalRenderNV = fn)
 #define CALL_ProvokingVertexEXT(disp, parameters) (*((disp)->ProvokingVertexEXT)) parameters
 #define GET_ProvokingVertexEXT(disp) ((disp)->ProvokingVertexEXT)
 #define SET_ProvokingVertexEXT(disp, fn) ((disp)->ProvokingVertexEXT = fn)
@@ -2449,7 +2473,7 @@
 
 #else
 
-#define driDispatchRemapTable_size 387
+#define driDispatchRemapTable_size 395
 extern int driDispatchRemapTable[ driDispatchRemapTable_size ];
 
 #define AttachShader_remap_index 0
@@ -2831,14 +2855,22 @@
 #define BufferParameteriAPPLE_remap_index 376
 #define FlushMappedBufferRangeAPPLE_remap_index 377
 #define FramebufferTextureLayerEXT_remap_index 378
-#define ProvokingVertexEXT_remap_index 379
-#define GetTexParameterPointervAPPLE_remap_index 380
-#define TextureRangeAPPLE_remap_index 381
-#define StencilFuncSeparateATI_remap_index 382
-#define ProgramEnvParameters4fvEXT_remap_index 383
-#define ProgramLocalParameters4fvEXT_remap_index 384
-#define GetQueryObjecti64vEXT_remap_index 385
-#define GetQueryObjectui64vEXT_remap_index 386
+#define ColorMaskIndexedEXT_remap_index 379
+#define DisableIndexedEXT_remap_index 380
+#define EnableIndexedEXT_remap_index 381
+#define GetBooleanIndexedvEXT_remap_index 382
+#define GetIntegerIndexedvEXT_remap_index 383
+#define IsEnabledIndexedEXT_remap_index 384
+#define BeginConditionalRenderNV_remap_index 385
+#define EndConditionalRenderNV_remap_index 386
+#define ProvokingVertexEXT_remap_index 387
+#define GetTexParameterPointervAPPLE_remap_index 388
+#define TextureRangeAPPLE_remap_index 389
+#define StencilFuncSeparateATI_remap_index 390
+#define ProgramEnvParameters4fvEXT_remap_index 391
+#define ProgramLocalParameters4fvEXT_remap_index 392
+#define GetQueryObjecti64vEXT_remap_index 393
+#define GetQueryObjectui64vEXT_remap_index 394
 
 #define CALL_AttachShader(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLuint, GLuint)), driDispatchRemapTable[AttachShader_remap_index], parameters)
 #define GET_AttachShader(disp) GET_by_offset(disp, driDispatchRemapTable[AttachShader_remap_index])
@@ -3977,6 +4009,30 @@
 #define CALL_FramebufferTextureLayerEXT(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLenum, GLuint, GLint, GLint)), driDispatchRemapTable[FramebufferTextureLayerEXT_remap_index], parameters)
 #define GET_FramebufferTextureLayerEXT(disp) GET_by_offset(disp, driDispatchRemapTable[FramebufferTextureLayerEXT_remap_index])
 #define SET_FramebufferTextureLayerEXT(disp, fn) SET_by_offset(disp, driDispatchRemapTable[FramebufferTextureLayerEXT_remap_index], fn)
+#define CALL_ColorMaskIndexedEXT(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLuint, GLboolean, GLboolean, GLboolean, GLboolean)), driDispatchRemapTable[ColorMaskIndexedEXT_remap_index], parameters)
+#define GET_ColorMaskIndexedEXT(disp) GET_by_offset(disp, driDispatchRemapTable[ColorMaskIndexedEXT_remap_index])
+#define SET_ColorMaskIndexedEXT(disp, fn) SET_by_offset(disp, driDispatchRemapTable[ColorMaskIndexedEXT_remap_index], fn)
+#define CALL_DisableIndexedEXT(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLuint)), driDispatchRemapTable[DisableIndexedEXT_remap_index], parameters)
+#define GET_DisableIndexedEXT(disp) GET_by_offset(disp, driDispatchRemapTable[DisableIndexedEXT_remap_index])
+#define SET_DisableIndexedEXT(disp, fn) SET_by_offset(disp, driDispatchRemapTable[DisableIndexedEXT_remap_index], fn)
+#define CALL_EnableIndexedEXT(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLuint)), driDispatchRemapTable[EnableIndexedEXT_remap_index], parameters)
+#define GET_EnableIndexedEXT(disp) GET_by_offset(disp, driDispatchRemapTable[EnableIndexedEXT_remap_index])
+#define SET_EnableIndexedEXT(disp, fn) SET_by_offset(disp, driDispatchRemapTable[EnableIndexedEXT_remap_index], fn)
+#define CALL_GetBooleanIndexedvEXT(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLuint, GLboolean *)), driDispatchRemapTable[GetBooleanIndexedvEXT_remap_index], parameters)
+#define GET_GetBooleanIndexedvEXT(disp) GET_by_offset(disp, driDispatchRemapTable[GetBooleanIndexedvEXT_remap_index])
+#define SET_GetBooleanIndexedvEXT(disp, fn) SET_by_offset(disp, driDispatchRemapTable[GetBooleanIndexedvEXT_remap_index], fn)
+#define CALL_GetIntegerIndexedvEXT(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLuint, GLint *)), driDispatchRemapTable[GetIntegerIndexedvEXT_remap_index], parameters)
+#define GET_GetIntegerIndexedvEXT(disp) GET_by_offset(disp, driDispatchRemapTable[GetIntegerIndexedvEXT_remap_index])
+#define SET_GetIntegerIndexedvEXT(disp, fn) SET_by_offset(disp, driDispatchRemapTable[GetIntegerIndexedvEXT_remap_index], fn)
+#define CALL_IsEnabledIndexedEXT(disp, parameters) CALL_by_offset(disp, (GLboolean (GLAPIENTRYP)(GLenum, GLuint)), driDispatchRemapTable[IsEnabledIndexedEXT_remap_index], parameters)
+#define GET_IsEnabledIndexedEXT(disp) GET_by_offset(disp, driDispatchRemapTable[IsEnabledIndexedEXT_remap_index])
+#define SET_IsEnabledIndexedEXT(disp, fn) SET_by_offset(disp, driDispatchRemapTable[IsEnabledIndexedEXT_remap_index], fn)
+#define CALL_BeginConditionalRenderNV(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLuint, GLenum)), driDispatchRemapTable[BeginConditionalRenderNV_remap_index], parameters)
+#define GET_BeginConditionalRenderNV(disp) GET_by_offset(disp, driDispatchRemapTable[BeginConditionalRenderNV_remap_index])
+#define SET_BeginConditionalRenderNV(disp, fn) SET_by_offset(disp, driDispatchRemapTable[BeginConditionalRenderNV_remap_index], fn)
+#define CALL_EndConditionalRenderNV(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(void)), driDispatchRemapTable[EndConditionalRenderNV_remap_index], parameters)
+#define GET_EndConditionalRenderNV(disp) GET_by_offset(disp, driDispatchRemapTable[EndConditionalRenderNV_remap_index])
+#define SET_EndConditionalRenderNV(disp, fn) SET_by_offset(disp, driDispatchRemapTable[EndConditionalRenderNV_remap_index], fn)
 #define CALL_ProvokingVertexEXT(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum)), driDispatchRemapTable[ProvokingVertexEXT_remap_index], parameters)
 #define GET_ProvokingVertexEXT(disp) GET_by_offset(disp, driDispatchRemapTable[ProvokingVertexEXT_remap_index])
 #define SET_ProvokingVertexEXT(disp, fn) SET_by_offset(disp, driDispatchRemapTable[ProvokingVertexEXT_remap_index], fn)
diff --git a/src/mesa/glapi/glapioffsets.h b/src/mesa/glapi/glapioffsets.h
index 3d10260..c5d367f 100644
--- a/src/mesa/glapi/glapioffsets.h
+++ b/src/mesa/glapi/glapioffsets.h
@@ -821,15 +821,23 @@
 #define _gloffset_BufferParameteriAPPLE 784
 #define _gloffset_FlushMappedBufferRangeAPPLE 785
 #define _gloffset_FramebufferTextureLayerEXT 786
-#define _gloffset_ProvokingVertexEXT 787
-#define _gloffset_GetTexParameterPointervAPPLE 788
-#define _gloffset_TextureRangeAPPLE 789
-#define _gloffset_StencilFuncSeparateATI 790
-#define _gloffset_ProgramEnvParameters4fvEXT 791
-#define _gloffset_ProgramLocalParameters4fvEXT 792
-#define _gloffset_GetQueryObjecti64vEXT 793
-#define _gloffset_GetQueryObjectui64vEXT 794
-#define _gloffset_FIRST_DYNAMIC 795
+#define _gloffset_ColorMaskIndexedEXT 787
+#define _gloffset_DisableIndexedEXT 788
+#define _gloffset_EnableIndexedEXT 789
+#define _gloffset_GetBooleanIndexedvEXT 790
+#define _gloffset_GetIntegerIndexedvEXT 791
+#define _gloffset_IsEnabledIndexedEXT 792
+#define _gloffset_BeginConditionalRenderNV 793
+#define _gloffset_EndConditionalRenderNV 794
+#define _gloffset_ProvokingVertexEXT 795
+#define _gloffset_GetTexParameterPointervAPPLE 796
+#define _gloffset_TextureRangeAPPLE 797
+#define _gloffset_StencilFuncSeparateATI 798
+#define _gloffset_ProgramEnvParameters4fvEXT 799
+#define _gloffset_ProgramLocalParameters4fvEXT 800
+#define _gloffset_GetQueryObjecti64vEXT 801
+#define _gloffset_GetQueryObjectui64vEXT 802
+#define _gloffset_FIRST_DYNAMIC 803
 
 #else
 
@@ -1212,6 +1220,14 @@
 #define _gloffset_BufferParameteriAPPLE driDispatchRemapTable[BufferParameteriAPPLE_remap_index]
 #define _gloffset_FlushMappedBufferRangeAPPLE driDispatchRemapTable[FlushMappedBufferRangeAPPLE_remap_index]
 #define _gloffset_FramebufferTextureLayerEXT driDispatchRemapTable[FramebufferTextureLayerEXT_remap_index]
+#define _gloffset_ColorMaskIndexedEXT driDispatchRemapTable[ColorMaskIndexedEXT_remap_index]
+#define _gloffset_DisableIndexedEXT driDispatchRemapTable[DisableIndexedEXT_remap_index]
+#define _gloffset_EnableIndexedEXT driDispatchRemapTable[EnableIndexedEXT_remap_index]
+#define _gloffset_GetBooleanIndexedvEXT driDispatchRemapTable[GetBooleanIndexedvEXT_remap_index]
+#define _gloffset_GetIntegerIndexedvEXT driDispatchRemapTable[GetIntegerIndexedvEXT_remap_index]
+#define _gloffset_IsEnabledIndexedEXT driDispatchRemapTable[IsEnabledIndexedEXT_remap_index]
+#define _gloffset_BeginConditionalRenderNV driDispatchRemapTable[BeginConditionalRenderNV_remap_index]
+#define _gloffset_EndConditionalRenderNV driDispatchRemapTable[EndConditionalRenderNV_remap_index]
 #define _gloffset_ProvokingVertexEXT driDispatchRemapTable[ProvokingVertexEXT_remap_index]
 #define _gloffset_GetTexParameterPointervAPPLE driDispatchRemapTable[GetTexParameterPointervAPPLE_remap_index]
 #define _gloffset_TextureRangeAPPLE driDispatchRemapTable[TextureRangeAPPLE_remap_index]
diff --git a/src/mesa/glapi/glapitable.h b/src/mesa/glapi/glapitable.h
index 4f9e53b..0c5b46d 100644
--- a/src/mesa/glapi/glapitable.h
+++ b/src/mesa/glapi/glapitable.h
@@ -827,14 +827,22 @@
    void (GLAPIENTRYP BufferParameteriAPPLE)(GLenum target, GLenum pname, GLint param); /* 784 */
    void (GLAPIENTRYP FlushMappedBufferRangeAPPLE)(GLenum target, GLintptr offset, GLsizeiptr size); /* 785 */
    void (GLAPIENTRYP FramebufferTextureLayerEXT)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); /* 786 */
-   void (GLAPIENTRYP ProvokingVertexEXT)(GLenum mode); /* 787 */
-   void (GLAPIENTRYP GetTexParameterPointervAPPLE)(GLenum target, GLenum pname, GLvoid ** params); /* 788 */
-   void (GLAPIENTRYP TextureRangeAPPLE)(GLenum target, GLsizei length, GLvoid * pointer); /* 789 */
-   void (GLAPIENTRYP StencilFuncSeparateATI)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); /* 790 */
-   void (GLAPIENTRYP ProgramEnvParameters4fvEXT)(GLenum target, GLuint index, GLsizei count, const GLfloat * params); /* 791 */
-   void (GLAPIENTRYP ProgramLocalParameters4fvEXT)(GLenum target, GLuint index, GLsizei count, const GLfloat * params); /* 792 */
-   void (GLAPIENTRYP GetQueryObjecti64vEXT)(GLuint id, GLenum pname, GLint64EXT * params); /* 793 */
-   void (GLAPIENTRYP GetQueryObjectui64vEXT)(GLuint id, GLenum pname, GLuint64EXT * params); /* 794 */
+   void (GLAPIENTRYP ColorMaskIndexedEXT)(GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a); /* 787 */
+   void (GLAPIENTRYP DisableIndexedEXT)(GLenum target, GLuint index); /* 788 */
+   void (GLAPIENTRYP EnableIndexedEXT)(GLenum target, GLuint index); /* 789 */
+   void (GLAPIENTRYP GetBooleanIndexedvEXT)(GLenum value, GLuint index, GLboolean * data); /* 790 */
+   void (GLAPIENTRYP GetIntegerIndexedvEXT)(GLenum value, GLuint index, GLint * data); /* 791 */
+   GLboolean (GLAPIENTRYP IsEnabledIndexedEXT)(GLenum target, GLuint index); /* 792 */
+   void (GLAPIENTRYP BeginConditionalRenderNV)(GLuint query, GLenum mode); /* 793 */
+   void (GLAPIENTRYP EndConditionalRenderNV)(void); /* 794 */
+   void (GLAPIENTRYP ProvokingVertexEXT)(GLenum mode); /* 795 */
+   void (GLAPIENTRYP GetTexParameterPointervAPPLE)(GLenum target, GLenum pname, GLvoid ** params); /* 796 */
+   void (GLAPIENTRYP TextureRangeAPPLE)(GLenum target, GLsizei length, GLvoid * pointer); /* 797 */
+   void (GLAPIENTRYP StencilFuncSeparateATI)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); /* 798 */
+   void (GLAPIENTRYP ProgramEnvParameters4fvEXT)(GLenum target, GLuint index, GLsizei count, const GLfloat * params); /* 799 */
+   void (GLAPIENTRYP ProgramLocalParameters4fvEXT)(GLenum target, GLuint index, GLsizei count, const GLfloat * params); /* 800 */
+   void (GLAPIENTRYP GetQueryObjecti64vEXT)(GLuint id, GLenum pname, GLint64EXT * params); /* 801 */
+   void (GLAPIENTRYP GetQueryObjectui64vEXT)(GLuint id, GLenum pname, GLuint64EXT * params); /* 802 */
 };
 
 #endif /* !defined( _GLAPI_TABLE_H_ ) */
diff --git a/src/mesa/glapi/glapitemp.h b/src/mesa/glapi/glapitemp.h
index 0138abd..6767a07 100644
--- a/src/mesa/glapi/glapitemp.h
+++ b/src/mesa/glapi/glapitemp.h
@@ -3847,6 +3847,11 @@
    DISPATCH(RenderbufferStorageMultisample, (target, samples, internalformat, width, height), (F, "glRenderbufferStorageMultisample(0x%x, %d, 0x%x, %d, %d);\n", target, samples, internalformat, width, height));
 }
 
+KEYWORD1 void KEYWORD2 NAME(RenderbufferStorageMultisampleEXT)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+   DISPATCH(RenderbufferStorageMultisample, (target, samples, internalformat, width, height), (F, "glRenderbufferStorageMultisampleEXT(0x%x, %d, 0x%x, %d, %d);\n", target, samples, internalformat, width, height));
+}
+
 KEYWORD1 void KEYWORD2 NAME(FlushMappedBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length)
 {
    DISPATCH(FlushMappedBufferRange, (target, offset, length), (F, "glFlushMappedBufferRange(0x%x, %d, %d);\n", target, offset, length));
@@ -5508,6 +5513,46 @@
    DISPATCH(FramebufferTextureLayerEXT, (target, attachment, texture, level, layer), (F, "glFramebufferTextureLayerEXT(0x%x, 0x%x, %d, %d, %d);\n", target, attachment, texture, level, layer));
 }
 
+KEYWORD1 void KEYWORD2 NAME(ColorMaskIndexedEXT)(GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
+{
+   DISPATCH(ColorMaskIndexedEXT, (buf, r, g, b, a), (F, "glColorMaskIndexedEXT(%d, %d, %d, %d, %d);\n", buf, r, g, b, a));
+}
+
+KEYWORD1 void KEYWORD2 NAME(DisableIndexedEXT)(GLenum target, GLuint index)
+{
+   DISPATCH(DisableIndexedEXT, (target, index), (F, "glDisableIndexedEXT(0x%x, %d);\n", target, index));
+}
+
+KEYWORD1 void KEYWORD2 NAME(EnableIndexedEXT)(GLenum target, GLuint index)
+{
+   DISPATCH(EnableIndexedEXT, (target, index), (F, "glEnableIndexedEXT(0x%x, %d);\n", target, index));
+}
+
+KEYWORD1 void KEYWORD2 NAME(GetBooleanIndexedvEXT)(GLenum value, GLuint index, GLboolean * data)
+{
+   DISPATCH(GetBooleanIndexedvEXT, (value, index, data), (F, "glGetBooleanIndexedvEXT(0x%x, %d, %p);\n", value, index, (const void *) data));
+}
+
+KEYWORD1 void KEYWORD2 NAME(GetIntegerIndexedvEXT)(GLenum value, GLuint index, GLint * data)
+{
+   DISPATCH(GetIntegerIndexedvEXT, (value, index, data), (F, "glGetIntegerIndexedvEXT(0x%x, %d, %p);\n", value, index, (const void *) data));
+}
+
+KEYWORD1 GLboolean KEYWORD2 NAME(IsEnabledIndexedEXT)(GLenum target, GLuint index)
+{
+   RETURN_DISPATCH(IsEnabledIndexedEXT, (target, index), (F, "glIsEnabledIndexedEXT(0x%x, %d);\n", target, index));
+}
+
+KEYWORD1 void KEYWORD2 NAME(BeginConditionalRenderNV)(GLuint query, GLenum mode)
+{
+   DISPATCH(BeginConditionalRenderNV, (query, mode), (F, "glBeginConditionalRenderNV(%d, 0x%x);\n", query, mode));
+}
+
+KEYWORD1 void KEYWORD2 NAME(EndConditionalRenderNV)(void)
+{
+   DISPATCH(EndConditionalRenderNV, (), (F, "glEndConditionalRenderNV();\n"));
+}
+
 KEYWORD1 void KEYWORD2 NAME(ProvokingVertexEXT)(GLenum mode)
 {
    DISPATCH(ProvokingVertexEXT, (mode), (F, "glProvokingVertexEXT(0x%x);\n", mode));
@@ -5518,51 +5563,51 @@
    DISPATCH(ProvokingVertexEXT, (mode), (F, "glProvokingVertex(0x%x);\n", mode));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_788)(GLenum target, GLenum pname, GLvoid ** params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_796)(GLenum target, GLenum pname, GLvoid ** params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_788)(GLenum target, GLenum pname, GLvoid ** params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_796)(GLenum target, GLenum pname, GLvoid ** params)
 {
    DISPATCH(GetTexParameterPointervAPPLE, (target, pname, params), (F, "glGetTexParameterPointervAPPLE(0x%x, 0x%x, %p);\n", target, pname, (const void *) params));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_789)(GLenum target, GLsizei length, GLvoid * pointer);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_797)(GLenum target, GLsizei length, GLvoid * pointer);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_789)(GLenum target, GLsizei length, GLvoid * pointer)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_797)(GLenum target, GLsizei length, GLvoid * pointer)
 {
    DISPATCH(TextureRangeAPPLE, (target, length, pointer), (F, "glTextureRangeAPPLE(0x%x, %d, %p);\n", target, length, (const void *) pointer));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_790)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_798)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_790)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_798)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask)
 {
    DISPATCH(StencilFuncSeparateATI, (frontfunc, backfunc, ref, mask), (F, "glStencilFuncSeparateATI(0x%x, 0x%x, %d, %d);\n", frontfunc, backfunc, ref, mask));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_791)(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_799)(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_791)(GLenum target, GLuint index, GLsizei count, const GLfloat * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_799)(GLenum target, GLuint index, GLsizei count, const GLfloat * params)
 {
    DISPATCH(ProgramEnvParameters4fvEXT, (target, index, count, params), (F, "glProgramEnvParameters4fvEXT(0x%x, %d, %d, %p);\n", target, index, count, (const void *) params));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_792)(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_800)(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_792)(GLenum target, GLuint index, GLsizei count, const GLfloat * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_800)(GLenum target, GLuint index, GLsizei count, const GLfloat * params)
 {
    DISPATCH(ProgramLocalParameters4fvEXT, (target, index, count, params), (F, "glProgramLocalParameters4fvEXT(0x%x, %d, %d, %p);\n", target, index, count, (const void *) params));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_793)(GLuint id, GLenum pname, GLint64EXT * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_801)(GLuint id, GLenum pname, GLint64EXT * params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_793)(GLuint id, GLenum pname, GLint64EXT * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_801)(GLuint id, GLenum pname, GLint64EXT * params)
 {
    DISPATCH(GetQueryObjecti64vEXT, (id, pname, params), (F, "glGetQueryObjecti64vEXT(%d, 0x%x, %p);\n", id, pname, (const void *) params));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_794)(GLuint id, GLenum pname, GLuint64EXT * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_802)(GLuint id, GLenum pname, GLuint64EXT * params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_794)(GLuint id, GLenum pname, GLuint64EXT * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_802)(GLuint id, GLenum pname, GLuint64EXT * params)
 {
    DISPATCH(GetQueryObjectui64vEXT, (id, pname, params), (F, "glGetQueryObjectui64vEXT(%d, 0x%x, %p);\n", id, pname, (const void *) params));
 }
@@ -6507,14 +6552,22 @@
    TABLE_ENTRY(_dispatch_stub_784),
    TABLE_ENTRY(_dispatch_stub_785),
    TABLE_ENTRY(FramebufferTextureLayerEXT),
+   TABLE_ENTRY(ColorMaskIndexedEXT),
+   TABLE_ENTRY(DisableIndexedEXT),
+   TABLE_ENTRY(EnableIndexedEXT),
+   TABLE_ENTRY(GetBooleanIndexedvEXT),
+   TABLE_ENTRY(GetIntegerIndexedvEXT),
+   TABLE_ENTRY(IsEnabledIndexedEXT),
+   TABLE_ENTRY(BeginConditionalRenderNV),
+   TABLE_ENTRY(EndConditionalRenderNV),
    TABLE_ENTRY(ProvokingVertexEXT),
-   TABLE_ENTRY(_dispatch_stub_788),
-   TABLE_ENTRY(_dispatch_stub_789),
-   TABLE_ENTRY(_dispatch_stub_790),
-   TABLE_ENTRY(_dispatch_stub_791),
-   TABLE_ENTRY(_dispatch_stub_792),
-   TABLE_ENTRY(_dispatch_stub_793),
-   TABLE_ENTRY(_dispatch_stub_794),
+   TABLE_ENTRY(_dispatch_stub_796),
+   TABLE_ENTRY(_dispatch_stub_797),
+   TABLE_ENTRY(_dispatch_stub_798),
+   TABLE_ENTRY(_dispatch_stub_799),
+   TABLE_ENTRY(_dispatch_stub_800),
+   TABLE_ENTRY(_dispatch_stub_801),
+   TABLE_ENTRY(_dispatch_stub_802),
    /* A whole bunch of no-op functions.  These might be called
     * when someone tries to call a dynamically-registered
     * extension function without a current rendering context.
@@ -6812,6 +6865,7 @@
    TABLE_ENTRY(GetAttribLocation),
    TABLE_ENTRY(DrawBuffers),
    TABLE_ENTRY(DrawBuffersATI),
+   TABLE_ENTRY(RenderbufferStorageMultisampleEXT),
    TABLE_ENTRY(PointParameterf),
    TABLE_ENTRY(PointParameterfARB),
    TABLE_ENTRY(_dispatch_stub_592),
diff --git a/src/mesa/glapi/glprocs.h b/src/mesa/glapi/glprocs.h
index c29f8b5..b590a7c 100644
--- a/src/mesa/glapi/glprocs.h
+++ b/src/mesa/glapi/glprocs.h
@@ -839,6 +839,14 @@
     "glBufferParameteriAPPLE\0"
     "glFlushMappedBufferRangeAPPLE\0"
     "glFramebufferTextureLayerEXT\0"
+    "glColorMaskIndexedEXT\0"
+    "glDisableIndexedEXT\0"
+    "glEnableIndexedEXT\0"
+    "glGetBooleanIndexedvEXT\0"
+    "glGetIntegerIndexedvEXT\0"
+    "glIsEnabledIndexedEXT\0"
+    "glBeginConditionalRenderNV\0"
+    "glEndConditionalRenderNV\0"
     "glProvokingVertexEXT\0"
     "glGetTexParameterPointervAPPLE\0"
     "glTextureRangeAPPLE\0"
@@ -1050,6 +1058,7 @@
     "glGetAttribLocation\0"
     "glDrawBuffers\0"
     "glDrawBuffersATI\0"
+    "glRenderbufferStorageMultisampleEXT\0"
     "glSampleMaskEXT\0"
     "glSamplePatternEXT\0"
     "glPointParameterf\0"
@@ -1195,13 +1204,13 @@
 #define gl_dispatch_stub_783 mgl_dispatch_stub_783
 #define gl_dispatch_stub_784 mgl_dispatch_stub_784
 #define gl_dispatch_stub_785 mgl_dispatch_stub_785
-#define gl_dispatch_stub_788 mgl_dispatch_stub_788
-#define gl_dispatch_stub_789 mgl_dispatch_stub_789
-#define gl_dispatch_stub_790 mgl_dispatch_stub_790
-#define gl_dispatch_stub_791 mgl_dispatch_stub_791
-#define gl_dispatch_stub_792 mgl_dispatch_stub_792
-#define gl_dispatch_stub_793 mgl_dispatch_stub_793
-#define gl_dispatch_stub_794 mgl_dispatch_stub_794
+#define gl_dispatch_stub_796 mgl_dispatch_stub_796
+#define gl_dispatch_stub_797 mgl_dispatch_stub_797
+#define gl_dispatch_stub_798 mgl_dispatch_stub_798
+#define gl_dispatch_stub_799 mgl_dispatch_stub_799
+#define gl_dispatch_stub_800 mgl_dispatch_stub_800
+#define gl_dispatch_stub_801 mgl_dispatch_stub_801
+#define gl_dispatch_stub_802 mgl_dispatch_stub_802
 #endif /* USE_MGL_NAMESPACE */
 
 
@@ -1249,13 +1258,13 @@
 void GLAPIENTRY gl_dispatch_stub_783(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
 void GLAPIENTRY gl_dispatch_stub_784(GLenum target, GLenum pname, GLint param);
 void GLAPIENTRY gl_dispatch_stub_785(GLenum target, GLintptr offset, GLsizeiptr size);
-void GLAPIENTRY gl_dispatch_stub_788(GLenum target, GLenum pname, GLvoid ** params);
-void GLAPIENTRY gl_dispatch_stub_789(GLenum target, GLsizei length, GLvoid * pointer);
-void GLAPIENTRY gl_dispatch_stub_790(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
-void GLAPIENTRY gl_dispatch_stub_791(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
-void GLAPIENTRY gl_dispatch_stub_792(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
-void GLAPIENTRY gl_dispatch_stub_793(GLuint id, GLenum pname, GLint64EXT * params);
-void GLAPIENTRY gl_dispatch_stub_794(GLuint id, GLenum pname, GLuint64EXT * params);
+void GLAPIENTRY gl_dispatch_stub_796(GLenum target, GLenum pname, GLvoid ** params);
+void GLAPIENTRY gl_dispatch_stub_797(GLenum target, GLsizei length, GLvoid * pointer);
+void GLAPIENTRY gl_dispatch_stub_798(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+void GLAPIENTRY gl_dispatch_stub_799(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
+void GLAPIENTRY gl_dispatch_stub_800(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
+void GLAPIENTRY gl_dispatch_stub_801(GLuint id, GLenum pname, GLint64EXT * params);
+void GLAPIENTRY gl_dispatch_stub_802(GLuint id, GLenum pname, GLuint64EXT * params);
 #endif /* defined(NEED_FUNCTION_POINTER) || defined(GLX_INDIRECT_RENDERING) */
 
 static const glprocs_table_t static_functions[] = {
@@ -2046,315 +2055,324 @@
     NAME_FUNC_OFFSET(13784, gl_dispatch_stub_784, gl_dispatch_stub_784, NULL, _gloffset_BufferParameteriAPPLE),
     NAME_FUNC_OFFSET(13808, gl_dispatch_stub_785, gl_dispatch_stub_785, NULL, _gloffset_FlushMappedBufferRangeAPPLE),
     NAME_FUNC_OFFSET(13838, glFramebufferTextureLayerEXT, glFramebufferTextureLayerEXT, NULL, _gloffset_FramebufferTextureLayerEXT),
-    NAME_FUNC_OFFSET(13867, glProvokingVertexEXT, glProvokingVertexEXT, NULL, _gloffset_ProvokingVertexEXT),
-    NAME_FUNC_OFFSET(13888, gl_dispatch_stub_788, gl_dispatch_stub_788, NULL, _gloffset_GetTexParameterPointervAPPLE),
-    NAME_FUNC_OFFSET(13919, gl_dispatch_stub_789, gl_dispatch_stub_789, NULL, _gloffset_TextureRangeAPPLE),
-    NAME_FUNC_OFFSET(13939, gl_dispatch_stub_790, gl_dispatch_stub_790, NULL, _gloffset_StencilFuncSeparateATI),
-    NAME_FUNC_OFFSET(13964, gl_dispatch_stub_791, gl_dispatch_stub_791, NULL, _gloffset_ProgramEnvParameters4fvEXT),
-    NAME_FUNC_OFFSET(13993, gl_dispatch_stub_792, gl_dispatch_stub_792, NULL, _gloffset_ProgramLocalParameters4fvEXT),
-    NAME_FUNC_OFFSET(14024, gl_dispatch_stub_793, gl_dispatch_stub_793, NULL, _gloffset_GetQueryObjecti64vEXT),
-    NAME_FUNC_OFFSET(14048, gl_dispatch_stub_794, gl_dispatch_stub_794, NULL, _gloffset_GetQueryObjectui64vEXT),
-    NAME_FUNC_OFFSET(14073, glArrayElement, glArrayElement, NULL, _gloffset_ArrayElement),
-    NAME_FUNC_OFFSET(14091, glBindTexture, glBindTexture, NULL, _gloffset_BindTexture),
-    NAME_FUNC_OFFSET(14108, glDrawArrays, glDrawArrays, NULL, _gloffset_DrawArrays),
-    NAME_FUNC_OFFSET(14124, glAreTexturesResident, glAreTexturesResidentEXT, glAreTexturesResidentEXT, _gloffset_AreTexturesResident),
-    NAME_FUNC_OFFSET(14149, glCopyTexImage1D, glCopyTexImage1D, NULL, _gloffset_CopyTexImage1D),
-    NAME_FUNC_OFFSET(14169, glCopyTexImage2D, glCopyTexImage2D, NULL, _gloffset_CopyTexImage2D),
-    NAME_FUNC_OFFSET(14189, glCopyTexSubImage1D, glCopyTexSubImage1D, NULL, _gloffset_CopyTexSubImage1D),
-    NAME_FUNC_OFFSET(14212, glCopyTexSubImage2D, glCopyTexSubImage2D, NULL, _gloffset_CopyTexSubImage2D),
-    NAME_FUNC_OFFSET(14235, glDeleteTextures, glDeleteTexturesEXT, glDeleteTexturesEXT, _gloffset_DeleteTextures),
-    NAME_FUNC_OFFSET(14255, glGenTextures, glGenTexturesEXT, glGenTexturesEXT, _gloffset_GenTextures),
-    NAME_FUNC_OFFSET(14272, glGetPointerv, glGetPointerv, NULL, _gloffset_GetPointerv),
-    NAME_FUNC_OFFSET(14289, glIsTexture, glIsTextureEXT, glIsTextureEXT, _gloffset_IsTexture),
-    NAME_FUNC_OFFSET(14304, glPrioritizeTextures, glPrioritizeTextures, NULL, _gloffset_PrioritizeTextures),
-    NAME_FUNC_OFFSET(14328, glTexSubImage1D, glTexSubImage1D, NULL, _gloffset_TexSubImage1D),
-    NAME_FUNC_OFFSET(14347, glTexSubImage2D, glTexSubImage2D, NULL, _gloffset_TexSubImage2D),
-    NAME_FUNC_OFFSET(14366, glBlendColor, glBlendColor, NULL, _gloffset_BlendColor),
-    NAME_FUNC_OFFSET(14382, glBlendEquation, glBlendEquation, NULL, _gloffset_BlendEquation),
-    NAME_FUNC_OFFSET(14401, glDrawRangeElements, glDrawRangeElements, NULL, _gloffset_DrawRangeElements),
-    NAME_FUNC_OFFSET(14424, glColorTable, glColorTable, NULL, _gloffset_ColorTable),
-    NAME_FUNC_OFFSET(14440, glColorTable, glColorTable, NULL, _gloffset_ColorTable),
-    NAME_FUNC_OFFSET(14456, glColorTableParameterfv, glColorTableParameterfv, NULL, _gloffset_ColorTableParameterfv),
-    NAME_FUNC_OFFSET(14483, glColorTableParameteriv, glColorTableParameteriv, NULL, _gloffset_ColorTableParameteriv),
-    NAME_FUNC_OFFSET(14510, glCopyColorTable, glCopyColorTable, NULL, _gloffset_CopyColorTable),
-    NAME_FUNC_OFFSET(14530, glGetColorTable, glGetColorTableEXT, glGetColorTableEXT, _gloffset_GetColorTable),
-    NAME_FUNC_OFFSET(14549, glGetColorTable, glGetColorTableEXT, glGetColorTableEXT, _gloffset_GetColorTable),
-    NAME_FUNC_OFFSET(14568, glGetColorTableParameterfv, glGetColorTableParameterfvEXT, glGetColorTableParameterfvEXT, _gloffset_GetColorTableParameterfv),
-    NAME_FUNC_OFFSET(14598, glGetColorTableParameterfv, glGetColorTableParameterfvEXT, glGetColorTableParameterfvEXT, _gloffset_GetColorTableParameterfv),
-    NAME_FUNC_OFFSET(14628, glGetColorTableParameteriv, glGetColorTableParameterivEXT, glGetColorTableParameterivEXT, _gloffset_GetColorTableParameteriv),
-    NAME_FUNC_OFFSET(14658, glGetColorTableParameteriv, glGetColorTableParameterivEXT, glGetColorTableParameterivEXT, _gloffset_GetColorTableParameteriv),
-    NAME_FUNC_OFFSET(14688, glColorSubTable, glColorSubTable, NULL, _gloffset_ColorSubTable),
-    NAME_FUNC_OFFSET(14707, glCopyColorSubTable, glCopyColorSubTable, NULL, _gloffset_CopyColorSubTable),
-    NAME_FUNC_OFFSET(14730, glConvolutionFilter1D, glConvolutionFilter1D, NULL, _gloffset_ConvolutionFilter1D),
-    NAME_FUNC_OFFSET(14755, glConvolutionFilter2D, glConvolutionFilter2D, NULL, _gloffset_ConvolutionFilter2D),
-    NAME_FUNC_OFFSET(14780, glConvolutionParameterf, glConvolutionParameterf, NULL, _gloffset_ConvolutionParameterf),
-    NAME_FUNC_OFFSET(14807, glConvolutionParameterfv, glConvolutionParameterfv, NULL, _gloffset_ConvolutionParameterfv),
-    NAME_FUNC_OFFSET(14835, glConvolutionParameteri, glConvolutionParameteri, NULL, _gloffset_ConvolutionParameteri),
-    NAME_FUNC_OFFSET(14862, glConvolutionParameteriv, glConvolutionParameteriv, NULL, _gloffset_ConvolutionParameteriv),
-    NAME_FUNC_OFFSET(14890, glCopyConvolutionFilter1D, glCopyConvolutionFilter1D, NULL, _gloffset_CopyConvolutionFilter1D),
-    NAME_FUNC_OFFSET(14919, glCopyConvolutionFilter2D, glCopyConvolutionFilter2D, NULL, _gloffset_CopyConvolutionFilter2D),
-    NAME_FUNC_OFFSET(14948, glGetConvolutionFilter, gl_dispatch_stub_356, gl_dispatch_stub_356, _gloffset_GetConvolutionFilter),
-    NAME_FUNC_OFFSET(14974, glGetConvolutionParameterfv, gl_dispatch_stub_357, gl_dispatch_stub_357, _gloffset_GetConvolutionParameterfv),
-    NAME_FUNC_OFFSET(15005, glGetConvolutionParameteriv, gl_dispatch_stub_358, gl_dispatch_stub_358, _gloffset_GetConvolutionParameteriv),
-    NAME_FUNC_OFFSET(15036, glGetSeparableFilter, gl_dispatch_stub_359, gl_dispatch_stub_359, _gloffset_GetSeparableFilter),
-    NAME_FUNC_OFFSET(15060, glSeparableFilter2D, glSeparableFilter2D, NULL, _gloffset_SeparableFilter2D),
-    NAME_FUNC_OFFSET(15083, glGetHistogram, gl_dispatch_stub_361, gl_dispatch_stub_361, _gloffset_GetHistogram),
-    NAME_FUNC_OFFSET(15101, glGetHistogramParameterfv, gl_dispatch_stub_362, gl_dispatch_stub_362, _gloffset_GetHistogramParameterfv),
-    NAME_FUNC_OFFSET(15130, glGetHistogramParameteriv, gl_dispatch_stub_363, gl_dispatch_stub_363, _gloffset_GetHistogramParameteriv),
-    NAME_FUNC_OFFSET(15159, glGetMinmax, gl_dispatch_stub_364, gl_dispatch_stub_364, _gloffset_GetMinmax),
-    NAME_FUNC_OFFSET(15174, glGetMinmaxParameterfv, gl_dispatch_stub_365, gl_dispatch_stub_365, _gloffset_GetMinmaxParameterfv),
-    NAME_FUNC_OFFSET(15200, glGetMinmaxParameteriv, gl_dispatch_stub_366, gl_dispatch_stub_366, _gloffset_GetMinmaxParameteriv),
-    NAME_FUNC_OFFSET(15226, glHistogram, glHistogram, NULL, _gloffset_Histogram),
-    NAME_FUNC_OFFSET(15241, glMinmax, glMinmax, NULL, _gloffset_Minmax),
-    NAME_FUNC_OFFSET(15253, glResetHistogram, glResetHistogram, NULL, _gloffset_ResetHistogram),
-    NAME_FUNC_OFFSET(15273, glResetMinmax, glResetMinmax, NULL, _gloffset_ResetMinmax),
-    NAME_FUNC_OFFSET(15290, glTexImage3D, glTexImage3D, NULL, _gloffset_TexImage3D),
-    NAME_FUNC_OFFSET(15306, glTexSubImage3D, glTexSubImage3D, NULL, _gloffset_TexSubImage3D),
-    NAME_FUNC_OFFSET(15325, glCopyTexSubImage3D, glCopyTexSubImage3D, NULL, _gloffset_CopyTexSubImage3D),
-    NAME_FUNC_OFFSET(15348, glActiveTextureARB, glActiveTextureARB, NULL, _gloffset_ActiveTextureARB),
-    NAME_FUNC_OFFSET(15364, glClientActiveTextureARB, glClientActiveTextureARB, NULL, _gloffset_ClientActiveTextureARB),
-    NAME_FUNC_OFFSET(15386, glMultiTexCoord1dARB, glMultiTexCoord1dARB, NULL, _gloffset_MultiTexCoord1dARB),
-    NAME_FUNC_OFFSET(15404, glMultiTexCoord1dvARB, glMultiTexCoord1dvARB, NULL, _gloffset_MultiTexCoord1dvARB),
-    NAME_FUNC_OFFSET(15423, glMultiTexCoord1fARB, glMultiTexCoord1fARB, NULL, _gloffset_MultiTexCoord1fARB),
-    NAME_FUNC_OFFSET(15441, glMultiTexCoord1fvARB, glMultiTexCoord1fvARB, NULL, _gloffset_MultiTexCoord1fvARB),
-    NAME_FUNC_OFFSET(15460, glMultiTexCoord1iARB, glMultiTexCoord1iARB, NULL, _gloffset_MultiTexCoord1iARB),
-    NAME_FUNC_OFFSET(15478, glMultiTexCoord1ivARB, glMultiTexCoord1ivARB, NULL, _gloffset_MultiTexCoord1ivARB),
-    NAME_FUNC_OFFSET(15497, glMultiTexCoord1sARB, glMultiTexCoord1sARB, NULL, _gloffset_MultiTexCoord1sARB),
-    NAME_FUNC_OFFSET(15515, glMultiTexCoord1svARB, glMultiTexCoord1svARB, NULL, _gloffset_MultiTexCoord1svARB),
-    NAME_FUNC_OFFSET(15534, glMultiTexCoord2dARB, glMultiTexCoord2dARB, NULL, _gloffset_MultiTexCoord2dARB),
-    NAME_FUNC_OFFSET(15552, glMultiTexCoord2dvARB, glMultiTexCoord2dvARB, NULL, _gloffset_MultiTexCoord2dvARB),
-    NAME_FUNC_OFFSET(15571, glMultiTexCoord2fARB, glMultiTexCoord2fARB, NULL, _gloffset_MultiTexCoord2fARB),
-    NAME_FUNC_OFFSET(15589, glMultiTexCoord2fvARB, glMultiTexCoord2fvARB, NULL, _gloffset_MultiTexCoord2fvARB),
-    NAME_FUNC_OFFSET(15608, glMultiTexCoord2iARB, glMultiTexCoord2iARB, NULL, _gloffset_MultiTexCoord2iARB),
-    NAME_FUNC_OFFSET(15626, glMultiTexCoord2ivARB, glMultiTexCoord2ivARB, NULL, _gloffset_MultiTexCoord2ivARB),
-    NAME_FUNC_OFFSET(15645, glMultiTexCoord2sARB, glMultiTexCoord2sARB, NULL, _gloffset_MultiTexCoord2sARB),
-    NAME_FUNC_OFFSET(15663, glMultiTexCoord2svARB, glMultiTexCoord2svARB, NULL, _gloffset_MultiTexCoord2svARB),
-    NAME_FUNC_OFFSET(15682, glMultiTexCoord3dARB, glMultiTexCoord3dARB, NULL, _gloffset_MultiTexCoord3dARB),
-    NAME_FUNC_OFFSET(15700, glMultiTexCoord3dvARB, glMultiTexCoord3dvARB, NULL, _gloffset_MultiTexCoord3dvARB),
-    NAME_FUNC_OFFSET(15719, glMultiTexCoord3fARB, glMultiTexCoord3fARB, NULL, _gloffset_MultiTexCoord3fARB),
-    NAME_FUNC_OFFSET(15737, glMultiTexCoord3fvARB, glMultiTexCoord3fvARB, NULL, _gloffset_MultiTexCoord3fvARB),
-    NAME_FUNC_OFFSET(15756, glMultiTexCoord3iARB, glMultiTexCoord3iARB, NULL, _gloffset_MultiTexCoord3iARB),
-    NAME_FUNC_OFFSET(15774, glMultiTexCoord3ivARB, glMultiTexCoord3ivARB, NULL, _gloffset_MultiTexCoord3ivARB),
-    NAME_FUNC_OFFSET(15793, glMultiTexCoord3sARB, glMultiTexCoord3sARB, NULL, _gloffset_MultiTexCoord3sARB),
-    NAME_FUNC_OFFSET(15811, glMultiTexCoord3svARB, glMultiTexCoord3svARB, NULL, _gloffset_MultiTexCoord3svARB),
-    NAME_FUNC_OFFSET(15830, glMultiTexCoord4dARB, glMultiTexCoord4dARB, NULL, _gloffset_MultiTexCoord4dARB),
-    NAME_FUNC_OFFSET(15848, glMultiTexCoord4dvARB, glMultiTexCoord4dvARB, NULL, _gloffset_MultiTexCoord4dvARB),
-    NAME_FUNC_OFFSET(15867, glMultiTexCoord4fARB, glMultiTexCoord4fARB, NULL, _gloffset_MultiTexCoord4fARB),
-    NAME_FUNC_OFFSET(15885, glMultiTexCoord4fvARB, glMultiTexCoord4fvARB, NULL, _gloffset_MultiTexCoord4fvARB),
-    NAME_FUNC_OFFSET(15904, glMultiTexCoord4iARB, glMultiTexCoord4iARB, NULL, _gloffset_MultiTexCoord4iARB),
-    NAME_FUNC_OFFSET(15922, glMultiTexCoord4ivARB, glMultiTexCoord4ivARB, NULL, _gloffset_MultiTexCoord4ivARB),
-    NAME_FUNC_OFFSET(15941, glMultiTexCoord4sARB, glMultiTexCoord4sARB, NULL, _gloffset_MultiTexCoord4sARB),
-    NAME_FUNC_OFFSET(15959, glMultiTexCoord4svARB, glMultiTexCoord4svARB, NULL, _gloffset_MultiTexCoord4svARB),
-    NAME_FUNC_OFFSET(15978, glStencilOpSeparate, glStencilOpSeparate, NULL, _gloffset_StencilOpSeparate),
-    NAME_FUNC_OFFSET(16001, glLoadTransposeMatrixdARB, glLoadTransposeMatrixdARB, NULL, _gloffset_LoadTransposeMatrixdARB),
-    NAME_FUNC_OFFSET(16024, glLoadTransposeMatrixfARB, glLoadTransposeMatrixfARB, NULL, _gloffset_LoadTransposeMatrixfARB),
-    NAME_FUNC_OFFSET(16047, glMultTransposeMatrixdARB, glMultTransposeMatrixdARB, NULL, _gloffset_MultTransposeMatrixdARB),
-    NAME_FUNC_OFFSET(16070, glMultTransposeMatrixfARB, glMultTransposeMatrixfARB, NULL, _gloffset_MultTransposeMatrixfARB),
-    NAME_FUNC_OFFSET(16093, glSampleCoverageARB, glSampleCoverageARB, NULL, _gloffset_SampleCoverageARB),
-    NAME_FUNC_OFFSET(16110, glCompressedTexImage1DARB, glCompressedTexImage1DARB, NULL, _gloffset_CompressedTexImage1DARB),
-    NAME_FUNC_OFFSET(16133, glCompressedTexImage2DARB, glCompressedTexImage2DARB, NULL, _gloffset_CompressedTexImage2DARB),
-    NAME_FUNC_OFFSET(16156, glCompressedTexImage3DARB, glCompressedTexImage3DARB, NULL, _gloffset_CompressedTexImage3DARB),
-    NAME_FUNC_OFFSET(16179, glCompressedTexSubImage1DARB, glCompressedTexSubImage1DARB, NULL, _gloffset_CompressedTexSubImage1DARB),
-    NAME_FUNC_OFFSET(16205, glCompressedTexSubImage2DARB, glCompressedTexSubImage2DARB, NULL, _gloffset_CompressedTexSubImage2DARB),
-    NAME_FUNC_OFFSET(16231, glCompressedTexSubImage3DARB, glCompressedTexSubImage3DARB, NULL, _gloffset_CompressedTexSubImage3DARB),
-    NAME_FUNC_OFFSET(16257, glGetCompressedTexImageARB, glGetCompressedTexImageARB, NULL, _gloffset_GetCompressedTexImageARB),
-    NAME_FUNC_OFFSET(16281, glDisableVertexAttribArrayARB, glDisableVertexAttribArrayARB, NULL, _gloffset_DisableVertexAttribArrayARB),
-    NAME_FUNC_OFFSET(16308, glEnableVertexAttribArrayARB, glEnableVertexAttribArrayARB, NULL, _gloffset_EnableVertexAttribArrayARB),
-    NAME_FUNC_OFFSET(16334, glGetVertexAttribdvARB, glGetVertexAttribdvARB, NULL, _gloffset_GetVertexAttribdvARB),
-    NAME_FUNC_OFFSET(16354, glGetVertexAttribfvARB, glGetVertexAttribfvARB, NULL, _gloffset_GetVertexAttribfvARB),
-    NAME_FUNC_OFFSET(16374, glGetVertexAttribivARB, glGetVertexAttribivARB, NULL, _gloffset_GetVertexAttribivARB),
-    NAME_FUNC_OFFSET(16394, glProgramEnvParameter4dARB, glProgramEnvParameter4dARB, NULL, _gloffset_ProgramEnvParameter4dARB),
-    NAME_FUNC_OFFSET(16417, glProgramEnvParameter4dvARB, glProgramEnvParameter4dvARB, NULL, _gloffset_ProgramEnvParameter4dvARB),
-    NAME_FUNC_OFFSET(16441, glProgramEnvParameter4fARB, glProgramEnvParameter4fARB, NULL, _gloffset_ProgramEnvParameter4fARB),
-    NAME_FUNC_OFFSET(16464, glProgramEnvParameter4fvARB, glProgramEnvParameter4fvARB, NULL, _gloffset_ProgramEnvParameter4fvARB),
-    NAME_FUNC_OFFSET(16488, glVertexAttrib1dARB, glVertexAttrib1dARB, NULL, _gloffset_VertexAttrib1dARB),
-    NAME_FUNC_OFFSET(16505, glVertexAttrib1dvARB, glVertexAttrib1dvARB, NULL, _gloffset_VertexAttrib1dvARB),
-    NAME_FUNC_OFFSET(16523, glVertexAttrib1fARB, glVertexAttrib1fARB, NULL, _gloffset_VertexAttrib1fARB),
-    NAME_FUNC_OFFSET(16540, glVertexAttrib1fvARB, glVertexAttrib1fvARB, NULL, _gloffset_VertexAttrib1fvARB),
-    NAME_FUNC_OFFSET(16558, glVertexAttrib1sARB, glVertexAttrib1sARB, NULL, _gloffset_VertexAttrib1sARB),
-    NAME_FUNC_OFFSET(16575, glVertexAttrib1svARB, glVertexAttrib1svARB, NULL, _gloffset_VertexAttrib1svARB),
-    NAME_FUNC_OFFSET(16593, glVertexAttrib2dARB, glVertexAttrib2dARB, NULL, _gloffset_VertexAttrib2dARB),
-    NAME_FUNC_OFFSET(16610, glVertexAttrib2dvARB, glVertexAttrib2dvARB, NULL, _gloffset_VertexAttrib2dvARB),
-    NAME_FUNC_OFFSET(16628, glVertexAttrib2fARB, glVertexAttrib2fARB, NULL, _gloffset_VertexAttrib2fARB),
-    NAME_FUNC_OFFSET(16645, glVertexAttrib2fvARB, glVertexAttrib2fvARB, NULL, _gloffset_VertexAttrib2fvARB),
-    NAME_FUNC_OFFSET(16663, glVertexAttrib2sARB, glVertexAttrib2sARB, NULL, _gloffset_VertexAttrib2sARB),
-    NAME_FUNC_OFFSET(16680, glVertexAttrib2svARB, glVertexAttrib2svARB, NULL, _gloffset_VertexAttrib2svARB),
-    NAME_FUNC_OFFSET(16698, glVertexAttrib3dARB, glVertexAttrib3dARB, NULL, _gloffset_VertexAttrib3dARB),
-    NAME_FUNC_OFFSET(16715, glVertexAttrib3dvARB, glVertexAttrib3dvARB, NULL, _gloffset_VertexAttrib3dvARB),
-    NAME_FUNC_OFFSET(16733, glVertexAttrib3fARB, glVertexAttrib3fARB, NULL, _gloffset_VertexAttrib3fARB),
-    NAME_FUNC_OFFSET(16750, glVertexAttrib3fvARB, glVertexAttrib3fvARB, NULL, _gloffset_VertexAttrib3fvARB),
-    NAME_FUNC_OFFSET(16768, glVertexAttrib3sARB, glVertexAttrib3sARB, NULL, _gloffset_VertexAttrib3sARB),
-    NAME_FUNC_OFFSET(16785, glVertexAttrib3svARB, glVertexAttrib3svARB, NULL, _gloffset_VertexAttrib3svARB),
-    NAME_FUNC_OFFSET(16803, glVertexAttrib4NbvARB, glVertexAttrib4NbvARB, NULL, _gloffset_VertexAttrib4NbvARB),
-    NAME_FUNC_OFFSET(16822, glVertexAttrib4NivARB, glVertexAttrib4NivARB, NULL, _gloffset_VertexAttrib4NivARB),
-    NAME_FUNC_OFFSET(16841, glVertexAttrib4NsvARB, glVertexAttrib4NsvARB, NULL, _gloffset_VertexAttrib4NsvARB),
-    NAME_FUNC_OFFSET(16860, glVertexAttrib4NubARB, glVertexAttrib4NubARB, NULL, _gloffset_VertexAttrib4NubARB),
-    NAME_FUNC_OFFSET(16879, glVertexAttrib4NubvARB, glVertexAttrib4NubvARB, NULL, _gloffset_VertexAttrib4NubvARB),
-    NAME_FUNC_OFFSET(16899, glVertexAttrib4NuivARB, glVertexAttrib4NuivARB, NULL, _gloffset_VertexAttrib4NuivARB),
-    NAME_FUNC_OFFSET(16919, glVertexAttrib4NusvARB, glVertexAttrib4NusvARB, NULL, _gloffset_VertexAttrib4NusvARB),
-    NAME_FUNC_OFFSET(16939, glVertexAttrib4bvARB, glVertexAttrib4bvARB, NULL, _gloffset_VertexAttrib4bvARB),
-    NAME_FUNC_OFFSET(16957, glVertexAttrib4dARB, glVertexAttrib4dARB, NULL, _gloffset_VertexAttrib4dARB),
-    NAME_FUNC_OFFSET(16974, glVertexAttrib4dvARB, glVertexAttrib4dvARB, NULL, _gloffset_VertexAttrib4dvARB),
-    NAME_FUNC_OFFSET(16992, glVertexAttrib4fARB, glVertexAttrib4fARB, NULL, _gloffset_VertexAttrib4fARB),
-    NAME_FUNC_OFFSET(17009, glVertexAttrib4fvARB, glVertexAttrib4fvARB, NULL, _gloffset_VertexAttrib4fvARB),
-    NAME_FUNC_OFFSET(17027, glVertexAttrib4ivARB, glVertexAttrib4ivARB, NULL, _gloffset_VertexAttrib4ivARB),
-    NAME_FUNC_OFFSET(17045, glVertexAttrib4sARB, glVertexAttrib4sARB, NULL, _gloffset_VertexAttrib4sARB),
-    NAME_FUNC_OFFSET(17062, glVertexAttrib4svARB, glVertexAttrib4svARB, NULL, _gloffset_VertexAttrib4svARB),
-    NAME_FUNC_OFFSET(17080, glVertexAttrib4ubvARB, glVertexAttrib4ubvARB, NULL, _gloffset_VertexAttrib4ubvARB),
-    NAME_FUNC_OFFSET(17099, glVertexAttrib4uivARB, glVertexAttrib4uivARB, NULL, _gloffset_VertexAttrib4uivARB),
-    NAME_FUNC_OFFSET(17118, glVertexAttrib4usvARB, glVertexAttrib4usvARB, NULL, _gloffset_VertexAttrib4usvARB),
-    NAME_FUNC_OFFSET(17137, glVertexAttribPointerARB, glVertexAttribPointerARB, NULL, _gloffset_VertexAttribPointerARB),
-    NAME_FUNC_OFFSET(17159, glBindBufferARB, glBindBufferARB, NULL, _gloffset_BindBufferARB),
-    NAME_FUNC_OFFSET(17172, glBufferDataARB, glBufferDataARB, NULL, _gloffset_BufferDataARB),
-    NAME_FUNC_OFFSET(17185, glBufferSubDataARB, glBufferSubDataARB, NULL, _gloffset_BufferSubDataARB),
-    NAME_FUNC_OFFSET(17201, glDeleteBuffersARB, glDeleteBuffersARB, NULL, _gloffset_DeleteBuffersARB),
-    NAME_FUNC_OFFSET(17217, glGenBuffersARB, glGenBuffersARB, NULL, _gloffset_GenBuffersARB),
-    NAME_FUNC_OFFSET(17230, glGetBufferParameterivARB, glGetBufferParameterivARB, NULL, _gloffset_GetBufferParameterivARB),
-    NAME_FUNC_OFFSET(17253, glGetBufferPointervARB, glGetBufferPointervARB, NULL, _gloffset_GetBufferPointervARB),
-    NAME_FUNC_OFFSET(17273, glGetBufferSubDataARB, glGetBufferSubDataARB, NULL, _gloffset_GetBufferSubDataARB),
-    NAME_FUNC_OFFSET(17292, glIsBufferARB, glIsBufferARB, NULL, _gloffset_IsBufferARB),
-    NAME_FUNC_OFFSET(17303, glMapBufferARB, glMapBufferARB, NULL, _gloffset_MapBufferARB),
-    NAME_FUNC_OFFSET(17315, glUnmapBufferARB, glUnmapBufferARB, NULL, _gloffset_UnmapBufferARB),
-    NAME_FUNC_OFFSET(17329, glBeginQueryARB, glBeginQueryARB, NULL, _gloffset_BeginQueryARB),
-    NAME_FUNC_OFFSET(17342, glDeleteQueriesARB, glDeleteQueriesARB, NULL, _gloffset_DeleteQueriesARB),
-    NAME_FUNC_OFFSET(17358, glEndQueryARB, glEndQueryARB, NULL, _gloffset_EndQueryARB),
-    NAME_FUNC_OFFSET(17369, glGenQueriesARB, glGenQueriesARB, NULL, _gloffset_GenQueriesARB),
-    NAME_FUNC_OFFSET(17382, glGetQueryObjectivARB, glGetQueryObjectivARB, NULL, _gloffset_GetQueryObjectivARB),
-    NAME_FUNC_OFFSET(17401, glGetQueryObjectuivARB, glGetQueryObjectuivARB, NULL, _gloffset_GetQueryObjectuivARB),
-    NAME_FUNC_OFFSET(17421, glGetQueryivARB, glGetQueryivARB, NULL, _gloffset_GetQueryivARB),
-    NAME_FUNC_OFFSET(17434, glIsQueryARB, glIsQueryARB, NULL, _gloffset_IsQueryARB),
-    NAME_FUNC_OFFSET(17444, glCompileShaderARB, glCompileShaderARB, NULL, _gloffset_CompileShaderARB),
-    NAME_FUNC_OFFSET(17460, glGetActiveUniformARB, glGetActiveUniformARB, NULL, _gloffset_GetActiveUniformARB),
-    NAME_FUNC_OFFSET(17479, glGetShaderSourceARB, glGetShaderSourceARB, NULL, _gloffset_GetShaderSourceARB),
-    NAME_FUNC_OFFSET(17497, glGetUniformLocationARB, glGetUniformLocationARB, NULL, _gloffset_GetUniformLocationARB),
-    NAME_FUNC_OFFSET(17518, glGetUniformfvARB, glGetUniformfvARB, NULL, _gloffset_GetUniformfvARB),
-    NAME_FUNC_OFFSET(17533, glGetUniformivARB, glGetUniformivARB, NULL, _gloffset_GetUniformivARB),
-    NAME_FUNC_OFFSET(17548, glLinkProgramARB, glLinkProgramARB, NULL, _gloffset_LinkProgramARB),
-    NAME_FUNC_OFFSET(17562, glShaderSourceARB, glShaderSourceARB, NULL, _gloffset_ShaderSourceARB),
-    NAME_FUNC_OFFSET(17577, glUniform1fARB, glUniform1fARB, NULL, _gloffset_Uniform1fARB),
-    NAME_FUNC_OFFSET(17589, glUniform1fvARB, glUniform1fvARB, NULL, _gloffset_Uniform1fvARB),
-    NAME_FUNC_OFFSET(17602, glUniform1iARB, glUniform1iARB, NULL, _gloffset_Uniform1iARB),
-    NAME_FUNC_OFFSET(17614, glUniform1ivARB, glUniform1ivARB, NULL, _gloffset_Uniform1ivARB),
-    NAME_FUNC_OFFSET(17627, glUniform2fARB, glUniform2fARB, NULL, _gloffset_Uniform2fARB),
-    NAME_FUNC_OFFSET(17639, glUniform2fvARB, glUniform2fvARB, NULL, _gloffset_Uniform2fvARB),
-    NAME_FUNC_OFFSET(17652, glUniform2iARB, glUniform2iARB, NULL, _gloffset_Uniform2iARB),
-    NAME_FUNC_OFFSET(17664, glUniform2ivARB, glUniform2ivARB, NULL, _gloffset_Uniform2ivARB),
-    NAME_FUNC_OFFSET(17677, glUniform3fARB, glUniform3fARB, NULL, _gloffset_Uniform3fARB),
-    NAME_FUNC_OFFSET(17689, glUniform3fvARB, glUniform3fvARB, NULL, _gloffset_Uniform3fvARB),
-    NAME_FUNC_OFFSET(17702, glUniform3iARB, glUniform3iARB, NULL, _gloffset_Uniform3iARB),
-    NAME_FUNC_OFFSET(17714, glUniform3ivARB, glUniform3ivARB, NULL, _gloffset_Uniform3ivARB),
-    NAME_FUNC_OFFSET(17727, glUniform4fARB, glUniform4fARB, NULL, _gloffset_Uniform4fARB),
-    NAME_FUNC_OFFSET(17739, glUniform4fvARB, glUniform4fvARB, NULL, _gloffset_Uniform4fvARB),
-    NAME_FUNC_OFFSET(17752, glUniform4iARB, glUniform4iARB, NULL, _gloffset_Uniform4iARB),
-    NAME_FUNC_OFFSET(17764, glUniform4ivARB, glUniform4ivARB, NULL, _gloffset_Uniform4ivARB),
-    NAME_FUNC_OFFSET(17777, glUniformMatrix2fvARB, glUniformMatrix2fvARB, NULL, _gloffset_UniformMatrix2fvARB),
-    NAME_FUNC_OFFSET(17796, glUniformMatrix3fvARB, glUniformMatrix3fvARB, NULL, _gloffset_UniformMatrix3fvARB),
-    NAME_FUNC_OFFSET(17815, glUniformMatrix4fvARB, glUniformMatrix4fvARB, NULL, _gloffset_UniformMatrix4fvARB),
-    NAME_FUNC_OFFSET(17834, glUseProgramObjectARB, glUseProgramObjectARB, NULL, _gloffset_UseProgramObjectARB),
-    NAME_FUNC_OFFSET(17847, glValidateProgramARB, glValidateProgramARB, NULL, _gloffset_ValidateProgramARB),
-    NAME_FUNC_OFFSET(17865, glBindAttribLocationARB, glBindAttribLocationARB, NULL, _gloffset_BindAttribLocationARB),
-    NAME_FUNC_OFFSET(17886, glGetActiveAttribARB, glGetActiveAttribARB, NULL, _gloffset_GetActiveAttribARB),
-    NAME_FUNC_OFFSET(17904, glGetAttribLocationARB, glGetAttribLocationARB, NULL, _gloffset_GetAttribLocationARB),
-    NAME_FUNC_OFFSET(17924, glDrawBuffersARB, glDrawBuffersARB, NULL, _gloffset_DrawBuffersARB),
-    NAME_FUNC_OFFSET(17938, glDrawBuffersARB, glDrawBuffersARB, NULL, _gloffset_DrawBuffersARB),
-    NAME_FUNC_OFFSET(17955, gl_dispatch_stub_584, gl_dispatch_stub_584, NULL, _gloffset_SampleMaskSGIS),
-    NAME_FUNC_OFFSET(17971, gl_dispatch_stub_585, gl_dispatch_stub_585, NULL, _gloffset_SamplePatternSGIS),
-    NAME_FUNC_OFFSET(17990, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
-    NAME_FUNC_OFFSET(18008, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
-    NAME_FUNC_OFFSET(18029, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
-    NAME_FUNC_OFFSET(18051, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
-    NAME_FUNC_OFFSET(18070, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
-    NAME_FUNC_OFFSET(18092, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
-    NAME_FUNC_OFFSET(18115, glSecondaryColor3bEXT, glSecondaryColor3bEXT, NULL, _gloffset_SecondaryColor3bEXT),
-    NAME_FUNC_OFFSET(18134, glSecondaryColor3bvEXT, glSecondaryColor3bvEXT, NULL, _gloffset_SecondaryColor3bvEXT),
-    NAME_FUNC_OFFSET(18154, glSecondaryColor3dEXT, glSecondaryColor3dEXT, NULL, _gloffset_SecondaryColor3dEXT),
-    NAME_FUNC_OFFSET(18173, glSecondaryColor3dvEXT, glSecondaryColor3dvEXT, NULL, _gloffset_SecondaryColor3dvEXT),
-    NAME_FUNC_OFFSET(18193, glSecondaryColor3fEXT, glSecondaryColor3fEXT, NULL, _gloffset_SecondaryColor3fEXT),
-    NAME_FUNC_OFFSET(18212, glSecondaryColor3fvEXT, glSecondaryColor3fvEXT, NULL, _gloffset_SecondaryColor3fvEXT),
-    NAME_FUNC_OFFSET(18232, glSecondaryColor3iEXT, glSecondaryColor3iEXT, NULL, _gloffset_SecondaryColor3iEXT),
-    NAME_FUNC_OFFSET(18251, glSecondaryColor3ivEXT, glSecondaryColor3ivEXT, NULL, _gloffset_SecondaryColor3ivEXT),
-    NAME_FUNC_OFFSET(18271, glSecondaryColor3sEXT, glSecondaryColor3sEXT, NULL, _gloffset_SecondaryColor3sEXT),
-    NAME_FUNC_OFFSET(18290, glSecondaryColor3svEXT, glSecondaryColor3svEXT, NULL, _gloffset_SecondaryColor3svEXT),
-    NAME_FUNC_OFFSET(18310, glSecondaryColor3ubEXT, glSecondaryColor3ubEXT, NULL, _gloffset_SecondaryColor3ubEXT),
-    NAME_FUNC_OFFSET(18330, glSecondaryColor3ubvEXT, glSecondaryColor3ubvEXT, NULL, _gloffset_SecondaryColor3ubvEXT),
-    NAME_FUNC_OFFSET(18351, glSecondaryColor3uiEXT, glSecondaryColor3uiEXT, NULL, _gloffset_SecondaryColor3uiEXT),
-    NAME_FUNC_OFFSET(18371, glSecondaryColor3uivEXT, glSecondaryColor3uivEXT, NULL, _gloffset_SecondaryColor3uivEXT),
-    NAME_FUNC_OFFSET(18392, glSecondaryColor3usEXT, glSecondaryColor3usEXT, NULL, _gloffset_SecondaryColor3usEXT),
-    NAME_FUNC_OFFSET(18412, glSecondaryColor3usvEXT, glSecondaryColor3usvEXT, NULL, _gloffset_SecondaryColor3usvEXT),
-    NAME_FUNC_OFFSET(18433, glSecondaryColorPointerEXT, glSecondaryColorPointerEXT, NULL, _gloffset_SecondaryColorPointerEXT),
-    NAME_FUNC_OFFSET(18457, glMultiDrawArraysEXT, glMultiDrawArraysEXT, NULL, _gloffset_MultiDrawArraysEXT),
-    NAME_FUNC_OFFSET(18475, glMultiDrawElementsEXT, glMultiDrawElementsEXT, NULL, _gloffset_MultiDrawElementsEXT),
-    NAME_FUNC_OFFSET(18495, glFogCoordPointerEXT, glFogCoordPointerEXT, NULL, _gloffset_FogCoordPointerEXT),
-    NAME_FUNC_OFFSET(18513, glFogCoorddEXT, glFogCoorddEXT, NULL, _gloffset_FogCoorddEXT),
-    NAME_FUNC_OFFSET(18525, glFogCoorddvEXT, glFogCoorddvEXT, NULL, _gloffset_FogCoorddvEXT),
-    NAME_FUNC_OFFSET(18538, glFogCoordfEXT, glFogCoordfEXT, NULL, _gloffset_FogCoordfEXT),
-    NAME_FUNC_OFFSET(18550, glFogCoordfvEXT, glFogCoordfvEXT, NULL, _gloffset_FogCoordfvEXT),
-    NAME_FUNC_OFFSET(18563, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
-    NAME_FUNC_OFFSET(18583, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
-    NAME_FUNC_OFFSET(18607, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
-    NAME_FUNC_OFFSET(18621, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
-    NAME_FUNC_OFFSET(18638, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
-    NAME_FUNC_OFFSET(18653, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
-    NAME_FUNC_OFFSET(18671, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
-    NAME_FUNC_OFFSET(18685, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
-    NAME_FUNC_OFFSET(18702, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
-    NAME_FUNC_OFFSET(18717, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
-    NAME_FUNC_OFFSET(18735, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
-    NAME_FUNC_OFFSET(18749, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
-    NAME_FUNC_OFFSET(18766, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
-    NAME_FUNC_OFFSET(18781, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
-    NAME_FUNC_OFFSET(18799, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
-    NAME_FUNC_OFFSET(18813, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
-    NAME_FUNC_OFFSET(18830, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
-    NAME_FUNC_OFFSET(18845, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
-    NAME_FUNC_OFFSET(18863, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
-    NAME_FUNC_OFFSET(18877, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
-    NAME_FUNC_OFFSET(18894, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
-    NAME_FUNC_OFFSET(18909, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
-    NAME_FUNC_OFFSET(18927, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
-    NAME_FUNC_OFFSET(18941, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
-    NAME_FUNC_OFFSET(18958, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
-    NAME_FUNC_OFFSET(18973, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
-    NAME_FUNC_OFFSET(18991, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
-    NAME_FUNC_OFFSET(19005, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
-    NAME_FUNC_OFFSET(19022, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
-    NAME_FUNC_OFFSET(19037, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
-    NAME_FUNC_OFFSET(19055, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
-    NAME_FUNC_OFFSET(19069, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
-    NAME_FUNC_OFFSET(19086, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
-    NAME_FUNC_OFFSET(19101, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
-    NAME_FUNC_OFFSET(19119, glBindProgramNV, glBindProgramNV, NULL, _gloffset_BindProgramNV),
-    NAME_FUNC_OFFSET(19136, glDeleteProgramsNV, glDeleteProgramsNV, NULL, _gloffset_DeleteProgramsNV),
-    NAME_FUNC_OFFSET(19156, glGenProgramsNV, glGenProgramsNV, NULL, _gloffset_GenProgramsNV),
-    NAME_FUNC_OFFSET(19173, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
-    NAME_FUNC_OFFSET(19199, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
-    NAME_FUNC_OFFSET(19228, glIsProgramNV, glIsProgramNV, NULL, _gloffset_IsProgramNV),
-    NAME_FUNC_OFFSET(19243, glPointParameteriNV, glPointParameteriNV, NULL, _gloffset_PointParameteriNV),
-    NAME_FUNC_OFFSET(19261, glPointParameterivNV, glPointParameterivNV, NULL, _gloffset_PointParameterivNV),
-    NAME_FUNC_OFFSET(19280, gl_dispatch_stub_755, gl_dispatch_stub_755, NULL, _gloffset_DeleteVertexArraysAPPLE),
-    NAME_FUNC_OFFSET(19301, gl_dispatch_stub_757, gl_dispatch_stub_757, NULL, _gloffset_IsVertexArrayAPPLE),
-    NAME_FUNC_OFFSET(19317, gl_dispatch_stub_765, gl_dispatch_stub_765, NULL, _gloffset_BlendEquationSeparateEXT),
-    NAME_FUNC_OFFSET(19341, gl_dispatch_stub_765, gl_dispatch_stub_765, NULL, _gloffset_BlendEquationSeparateEXT),
-    NAME_FUNC_OFFSET(19368, glBindFramebufferEXT, glBindFramebufferEXT, NULL, _gloffset_BindFramebufferEXT),
-    NAME_FUNC_OFFSET(19386, glBindRenderbufferEXT, glBindRenderbufferEXT, NULL, _gloffset_BindRenderbufferEXT),
-    NAME_FUNC_OFFSET(19405, glCheckFramebufferStatusEXT, glCheckFramebufferStatusEXT, NULL, _gloffset_CheckFramebufferStatusEXT),
-    NAME_FUNC_OFFSET(19430, glDeleteFramebuffersEXT, glDeleteFramebuffersEXT, NULL, _gloffset_DeleteFramebuffersEXT),
-    NAME_FUNC_OFFSET(19451, glDeleteRenderbuffersEXT, glDeleteRenderbuffersEXT, NULL, _gloffset_DeleteRenderbuffersEXT),
-    NAME_FUNC_OFFSET(19473, glFramebufferRenderbufferEXT, glFramebufferRenderbufferEXT, NULL, _gloffset_FramebufferRenderbufferEXT),
-    NAME_FUNC_OFFSET(19499, glFramebufferTexture1DEXT, glFramebufferTexture1DEXT, NULL, _gloffset_FramebufferTexture1DEXT),
-    NAME_FUNC_OFFSET(19522, glFramebufferTexture2DEXT, glFramebufferTexture2DEXT, NULL, _gloffset_FramebufferTexture2DEXT),
-    NAME_FUNC_OFFSET(19545, glFramebufferTexture3DEXT, glFramebufferTexture3DEXT, NULL, _gloffset_FramebufferTexture3DEXT),
-    NAME_FUNC_OFFSET(19568, glGenFramebuffersEXT, glGenFramebuffersEXT, NULL, _gloffset_GenFramebuffersEXT),
-    NAME_FUNC_OFFSET(19586, glGenRenderbuffersEXT, glGenRenderbuffersEXT, NULL, _gloffset_GenRenderbuffersEXT),
-    NAME_FUNC_OFFSET(19605, glGenerateMipmapEXT, glGenerateMipmapEXT, NULL, _gloffset_GenerateMipmapEXT),
-    NAME_FUNC_OFFSET(19622, glGetFramebufferAttachmentParameterivEXT, glGetFramebufferAttachmentParameterivEXT, NULL, _gloffset_GetFramebufferAttachmentParameterivEXT),
-    NAME_FUNC_OFFSET(19660, glGetRenderbufferParameterivEXT, glGetRenderbufferParameterivEXT, NULL, _gloffset_GetRenderbufferParameterivEXT),
-    NAME_FUNC_OFFSET(19689, glIsFramebufferEXT, glIsFramebufferEXT, NULL, _gloffset_IsFramebufferEXT),
-    NAME_FUNC_OFFSET(19705, glIsRenderbufferEXT, glIsRenderbufferEXT, NULL, _gloffset_IsRenderbufferEXT),
-    NAME_FUNC_OFFSET(19722, glRenderbufferStorageEXT, glRenderbufferStorageEXT, NULL, _gloffset_RenderbufferStorageEXT),
-    NAME_FUNC_OFFSET(19744, gl_dispatch_stub_783, gl_dispatch_stub_783, NULL, _gloffset_BlitFramebufferEXT),
-    NAME_FUNC_OFFSET(19762, glFramebufferTextureLayerEXT, glFramebufferTextureLayerEXT, NULL, _gloffset_FramebufferTextureLayerEXT),
-    NAME_FUNC_OFFSET(19788, glProvokingVertexEXT, glProvokingVertexEXT, NULL, _gloffset_ProvokingVertexEXT),
+    NAME_FUNC_OFFSET(13867, glColorMaskIndexedEXT, glColorMaskIndexedEXT, NULL, _gloffset_ColorMaskIndexedEXT),
+    NAME_FUNC_OFFSET(13889, glDisableIndexedEXT, glDisableIndexedEXT, NULL, _gloffset_DisableIndexedEXT),
+    NAME_FUNC_OFFSET(13909, glEnableIndexedEXT, glEnableIndexedEXT, NULL, _gloffset_EnableIndexedEXT),
+    NAME_FUNC_OFFSET(13928, glGetBooleanIndexedvEXT, glGetBooleanIndexedvEXT, NULL, _gloffset_GetBooleanIndexedvEXT),
+    NAME_FUNC_OFFSET(13952, glGetIntegerIndexedvEXT, glGetIntegerIndexedvEXT, NULL, _gloffset_GetIntegerIndexedvEXT),
+    NAME_FUNC_OFFSET(13976, glIsEnabledIndexedEXT, glIsEnabledIndexedEXT, NULL, _gloffset_IsEnabledIndexedEXT),
+    NAME_FUNC_OFFSET(13998, glBeginConditionalRenderNV, glBeginConditionalRenderNV, NULL, _gloffset_BeginConditionalRenderNV),
+    NAME_FUNC_OFFSET(14025, glEndConditionalRenderNV, glEndConditionalRenderNV, NULL, _gloffset_EndConditionalRenderNV),
+    NAME_FUNC_OFFSET(14050, glProvokingVertexEXT, glProvokingVertexEXT, NULL, _gloffset_ProvokingVertexEXT),
+    NAME_FUNC_OFFSET(14071, gl_dispatch_stub_796, gl_dispatch_stub_796, NULL, _gloffset_GetTexParameterPointervAPPLE),
+    NAME_FUNC_OFFSET(14102, gl_dispatch_stub_797, gl_dispatch_stub_797, NULL, _gloffset_TextureRangeAPPLE),
+    NAME_FUNC_OFFSET(14122, gl_dispatch_stub_798, gl_dispatch_stub_798, NULL, _gloffset_StencilFuncSeparateATI),
+    NAME_FUNC_OFFSET(14147, gl_dispatch_stub_799, gl_dispatch_stub_799, NULL, _gloffset_ProgramEnvParameters4fvEXT),
+    NAME_FUNC_OFFSET(14176, gl_dispatch_stub_800, gl_dispatch_stub_800, NULL, _gloffset_ProgramLocalParameters4fvEXT),
+    NAME_FUNC_OFFSET(14207, gl_dispatch_stub_801, gl_dispatch_stub_801, NULL, _gloffset_GetQueryObjecti64vEXT),
+    NAME_FUNC_OFFSET(14231, gl_dispatch_stub_802, gl_dispatch_stub_802, NULL, _gloffset_GetQueryObjectui64vEXT),
+    NAME_FUNC_OFFSET(14256, glArrayElement, glArrayElement, NULL, _gloffset_ArrayElement),
+    NAME_FUNC_OFFSET(14274, glBindTexture, glBindTexture, NULL, _gloffset_BindTexture),
+    NAME_FUNC_OFFSET(14291, glDrawArrays, glDrawArrays, NULL, _gloffset_DrawArrays),
+    NAME_FUNC_OFFSET(14307, glAreTexturesResident, glAreTexturesResidentEXT, glAreTexturesResidentEXT, _gloffset_AreTexturesResident),
+    NAME_FUNC_OFFSET(14332, glCopyTexImage1D, glCopyTexImage1D, NULL, _gloffset_CopyTexImage1D),
+    NAME_FUNC_OFFSET(14352, glCopyTexImage2D, glCopyTexImage2D, NULL, _gloffset_CopyTexImage2D),
+    NAME_FUNC_OFFSET(14372, glCopyTexSubImage1D, glCopyTexSubImage1D, NULL, _gloffset_CopyTexSubImage1D),
+    NAME_FUNC_OFFSET(14395, glCopyTexSubImage2D, glCopyTexSubImage2D, NULL, _gloffset_CopyTexSubImage2D),
+    NAME_FUNC_OFFSET(14418, glDeleteTextures, glDeleteTexturesEXT, glDeleteTexturesEXT, _gloffset_DeleteTextures),
+    NAME_FUNC_OFFSET(14438, glGenTextures, glGenTexturesEXT, glGenTexturesEXT, _gloffset_GenTextures),
+    NAME_FUNC_OFFSET(14455, glGetPointerv, glGetPointerv, NULL, _gloffset_GetPointerv),
+    NAME_FUNC_OFFSET(14472, glIsTexture, glIsTextureEXT, glIsTextureEXT, _gloffset_IsTexture),
+    NAME_FUNC_OFFSET(14487, glPrioritizeTextures, glPrioritizeTextures, NULL, _gloffset_PrioritizeTextures),
+    NAME_FUNC_OFFSET(14511, glTexSubImage1D, glTexSubImage1D, NULL, _gloffset_TexSubImage1D),
+    NAME_FUNC_OFFSET(14530, glTexSubImage2D, glTexSubImage2D, NULL, _gloffset_TexSubImage2D),
+    NAME_FUNC_OFFSET(14549, glBlendColor, glBlendColor, NULL, _gloffset_BlendColor),
+    NAME_FUNC_OFFSET(14565, glBlendEquation, glBlendEquation, NULL, _gloffset_BlendEquation),
+    NAME_FUNC_OFFSET(14584, glDrawRangeElements, glDrawRangeElements, NULL, _gloffset_DrawRangeElements),
+    NAME_FUNC_OFFSET(14607, glColorTable, glColorTable, NULL, _gloffset_ColorTable),
+    NAME_FUNC_OFFSET(14623, glColorTable, glColorTable, NULL, _gloffset_ColorTable),
+    NAME_FUNC_OFFSET(14639, glColorTableParameterfv, glColorTableParameterfv, NULL, _gloffset_ColorTableParameterfv),
+    NAME_FUNC_OFFSET(14666, glColorTableParameteriv, glColorTableParameteriv, NULL, _gloffset_ColorTableParameteriv),
+    NAME_FUNC_OFFSET(14693, glCopyColorTable, glCopyColorTable, NULL, _gloffset_CopyColorTable),
+    NAME_FUNC_OFFSET(14713, glGetColorTable, glGetColorTableEXT, glGetColorTableEXT, _gloffset_GetColorTable),
+    NAME_FUNC_OFFSET(14732, glGetColorTable, glGetColorTableEXT, glGetColorTableEXT, _gloffset_GetColorTable),
+    NAME_FUNC_OFFSET(14751, glGetColorTableParameterfv, glGetColorTableParameterfvEXT, glGetColorTableParameterfvEXT, _gloffset_GetColorTableParameterfv),
+    NAME_FUNC_OFFSET(14781, glGetColorTableParameterfv, glGetColorTableParameterfvEXT, glGetColorTableParameterfvEXT, _gloffset_GetColorTableParameterfv),
+    NAME_FUNC_OFFSET(14811, glGetColorTableParameteriv, glGetColorTableParameterivEXT, glGetColorTableParameterivEXT, _gloffset_GetColorTableParameteriv),
+    NAME_FUNC_OFFSET(14841, glGetColorTableParameteriv, glGetColorTableParameterivEXT, glGetColorTableParameterivEXT, _gloffset_GetColorTableParameteriv),
+    NAME_FUNC_OFFSET(14871, glColorSubTable, glColorSubTable, NULL, _gloffset_ColorSubTable),
+    NAME_FUNC_OFFSET(14890, glCopyColorSubTable, glCopyColorSubTable, NULL, _gloffset_CopyColorSubTable),
+    NAME_FUNC_OFFSET(14913, glConvolutionFilter1D, glConvolutionFilter1D, NULL, _gloffset_ConvolutionFilter1D),
+    NAME_FUNC_OFFSET(14938, glConvolutionFilter2D, glConvolutionFilter2D, NULL, _gloffset_ConvolutionFilter2D),
+    NAME_FUNC_OFFSET(14963, glConvolutionParameterf, glConvolutionParameterf, NULL, _gloffset_ConvolutionParameterf),
+    NAME_FUNC_OFFSET(14990, glConvolutionParameterfv, glConvolutionParameterfv, NULL, _gloffset_ConvolutionParameterfv),
+    NAME_FUNC_OFFSET(15018, glConvolutionParameteri, glConvolutionParameteri, NULL, _gloffset_ConvolutionParameteri),
+    NAME_FUNC_OFFSET(15045, glConvolutionParameteriv, glConvolutionParameteriv, NULL, _gloffset_ConvolutionParameteriv),
+    NAME_FUNC_OFFSET(15073, glCopyConvolutionFilter1D, glCopyConvolutionFilter1D, NULL, _gloffset_CopyConvolutionFilter1D),
+    NAME_FUNC_OFFSET(15102, glCopyConvolutionFilter2D, glCopyConvolutionFilter2D, NULL, _gloffset_CopyConvolutionFilter2D),
+    NAME_FUNC_OFFSET(15131, glGetConvolutionFilter, gl_dispatch_stub_356, gl_dispatch_stub_356, _gloffset_GetConvolutionFilter),
+    NAME_FUNC_OFFSET(15157, glGetConvolutionParameterfv, gl_dispatch_stub_357, gl_dispatch_stub_357, _gloffset_GetConvolutionParameterfv),
+    NAME_FUNC_OFFSET(15188, glGetConvolutionParameteriv, gl_dispatch_stub_358, gl_dispatch_stub_358, _gloffset_GetConvolutionParameteriv),
+    NAME_FUNC_OFFSET(15219, glGetSeparableFilter, gl_dispatch_stub_359, gl_dispatch_stub_359, _gloffset_GetSeparableFilter),
+    NAME_FUNC_OFFSET(15243, glSeparableFilter2D, glSeparableFilter2D, NULL, _gloffset_SeparableFilter2D),
+    NAME_FUNC_OFFSET(15266, glGetHistogram, gl_dispatch_stub_361, gl_dispatch_stub_361, _gloffset_GetHistogram),
+    NAME_FUNC_OFFSET(15284, glGetHistogramParameterfv, gl_dispatch_stub_362, gl_dispatch_stub_362, _gloffset_GetHistogramParameterfv),
+    NAME_FUNC_OFFSET(15313, glGetHistogramParameteriv, gl_dispatch_stub_363, gl_dispatch_stub_363, _gloffset_GetHistogramParameteriv),
+    NAME_FUNC_OFFSET(15342, glGetMinmax, gl_dispatch_stub_364, gl_dispatch_stub_364, _gloffset_GetMinmax),
+    NAME_FUNC_OFFSET(15357, glGetMinmaxParameterfv, gl_dispatch_stub_365, gl_dispatch_stub_365, _gloffset_GetMinmaxParameterfv),
+    NAME_FUNC_OFFSET(15383, glGetMinmaxParameteriv, gl_dispatch_stub_366, gl_dispatch_stub_366, _gloffset_GetMinmaxParameteriv),
+    NAME_FUNC_OFFSET(15409, glHistogram, glHistogram, NULL, _gloffset_Histogram),
+    NAME_FUNC_OFFSET(15424, glMinmax, glMinmax, NULL, _gloffset_Minmax),
+    NAME_FUNC_OFFSET(15436, glResetHistogram, glResetHistogram, NULL, _gloffset_ResetHistogram),
+    NAME_FUNC_OFFSET(15456, glResetMinmax, glResetMinmax, NULL, _gloffset_ResetMinmax),
+    NAME_FUNC_OFFSET(15473, glTexImage3D, glTexImage3D, NULL, _gloffset_TexImage3D),
+    NAME_FUNC_OFFSET(15489, glTexSubImage3D, glTexSubImage3D, NULL, _gloffset_TexSubImage3D),
+    NAME_FUNC_OFFSET(15508, glCopyTexSubImage3D, glCopyTexSubImage3D, NULL, _gloffset_CopyTexSubImage3D),
+    NAME_FUNC_OFFSET(15531, glActiveTextureARB, glActiveTextureARB, NULL, _gloffset_ActiveTextureARB),
+    NAME_FUNC_OFFSET(15547, glClientActiveTextureARB, glClientActiveTextureARB, NULL, _gloffset_ClientActiveTextureARB),
+    NAME_FUNC_OFFSET(15569, glMultiTexCoord1dARB, glMultiTexCoord1dARB, NULL, _gloffset_MultiTexCoord1dARB),
+    NAME_FUNC_OFFSET(15587, glMultiTexCoord1dvARB, glMultiTexCoord1dvARB, NULL, _gloffset_MultiTexCoord1dvARB),
+    NAME_FUNC_OFFSET(15606, glMultiTexCoord1fARB, glMultiTexCoord1fARB, NULL, _gloffset_MultiTexCoord1fARB),
+    NAME_FUNC_OFFSET(15624, glMultiTexCoord1fvARB, glMultiTexCoord1fvARB, NULL, _gloffset_MultiTexCoord1fvARB),
+    NAME_FUNC_OFFSET(15643, glMultiTexCoord1iARB, glMultiTexCoord1iARB, NULL, _gloffset_MultiTexCoord1iARB),
+    NAME_FUNC_OFFSET(15661, glMultiTexCoord1ivARB, glMultiTexCoord1ivARB, NULL, _gloffset_MultiTexCoord1ivARB),
+    NAME_FUNC_OFFSET(15680, glMultiTexCoord1sARB, glMultiTexCoord1sARB, NULL, _gloffset_MultiTexCoord1sARB),
+    NAME_FUNC_OFFSET(15698, glMultiTexCoord1svARB, glMultiTexCoord1svARB, NULL, _gloffset_MultiTexCoord1svARB),
+    NAME_FUNC_OFFSET(15717, glMultiTexCoord2dARB, glMultiTexCoord2dARB, NULL, _gloffset_MultiTexCoord2dARB),
+    NAME_FUNC_OFFSET(15735, glMultiTexCoord2dvARB, glMultiTexCoord2dvARB, NULL, _gloffset_MultiTexCoord2dvARB),
+    NAME_FUNC_OFFSET(15754, glMultiTexCoord2fARB, glMultiTexCoord2fARB, NULL, _gloffset_MultiTexCoord2fARB),
+    NAME_FUNC_OFFSET(15772, glMultiTexCoord2fvARB, glMultiTexCoord2fvARB, NULL, _gloffset_MultiTexCoord2fvARB),
+    NAME_FUNC_OFFSET(15791, glMultiTexCoord2iARB, glMultiTexCoord2iARB, NULL, _gloffset_MultiTexCoord2iARB),
+    NAME_FUNC_OFFSET(15809, glMultiTexCoord2ivARB, glMultiTexCoord2ivARB, NULL, _gloffset_MultiTexCoord2ivARB),
+    NAME_FUNC_OFFSET(15828, glMultiTexCoord2sARB, glMultiTexCoord2sARB, NULL, _gloffset_MultiTexCoord2sARB),
+    NAME_FUNC_OFFSET(15846, glMultiTexCoord2svARB, glMultiTexCoord2svARB, NULL, _gloffset_MultiTexCoord2svARB),
+    NAME_FUNC_OFFSET(15865, glMultiTexCoord3dARB, glMultiTexCoord3dARB, NULL, _gloffset_MultiTexCoord3dARB),
+    NAME_FUNC_OFFSET(15883, glMultiTexCoord3dvARB, glMultiTexCoord3dvARB, NULL, _gloffset_MultiTexCoord3dvARB),
+    NAME_FUNC_OFFSET(15902, glMultiTexCoord3fARB, glMultiTexCoord3fARB, NULL, _gloffset_MultiTexCoord3fARB),
+    NAME_FUNC_OFFSET(15920, glMultiTexCoord3fvARB, glMultiTexCoord3fvARB, NULL, _gloffset_MultiTexCoord3fvARB),
+    NAME_FUNC_OFFSET(15939, glMultiTexCoord3iARB, glMultiTexCoord3iARB, NULL, _gloffset_MultiTexCoord3iARB),
+    NAME_FUNC_OFFSET(15957, glMultiTexCoord3ivARB, glMultiTexCoord3ivARB, NULL, _gloffset_MultiTexCoord3ivARB),
+    NAME_FUNC_OFFSET(15976, glMultiTexCoord3sARB, glMultiTexCoord3sARB, NULL, _gloffset_MultiTexCoord3sARB),
+    NAME_FUNC_OFFSET(15994, glMultiTexCoord3svARB, glMultiTexCoord3svARB, NULL, _gloffset_MultiTexCoord3svARB),
+    NAME_FUNC_OFFSET(16013, glMultiTexCoord4dARB, glMultiTexCoord4dARB, NULL, _gloffset_MultiTexCoord4dARB),
+    NAME_FUNC_OFFSET(16031, glMultiTexCoord4dvARB, glMultiTexCoord4dvARB, NULL, _gloffset_MultiTexCoord4dvARB),
+    NAME_FUNC_OFFSET(16050, glMultiTexCoord4fARB, glMultiTexCoord4fARB, NULL, _gloffset_MultiTexCoord4fARB),
+    NAME_FUNC_OFFSET(16068, glMultiTexCoord4fvARB, glMultiTexCoord4fvARB, NULL, _gloffset_MultiTexCoord4fvARB),
+    NAME_FUNC_OFFSET(16087, glMultiTexCoord4iARB, glMultiTexCoord4iARB, NULL, _gloffset_MultiTexCoord4iARB),
+    NAME_FUNC_OFFSET(16105, glMultiTexCoord4ivARB, glMultiTexCoord4ivARB, NULL, _gloffset_MultiTexCoord4ivARB),
+    NAME_FUNC_OFFSET(16124, glMultiTexCoord4sARB, glMultiTexCoord4sARB, NULL, _gloffset_MultiTexCoord4sARB),
+    NAME_FUNC_OFFSET(16142, glMultiTexCoord4svARB, glMultiTexCoord4svARB, NULL, _gloffset_MultiTexCoord4svARB),
+    NAME_FUNC_OFFSET(16161, glStencilOpSeparate, glStencilOpSeparate, NULL, _gloffset_StencilOpSeparate),
+    NAME_FUNC_OFFSET(16184, glLoadTransposeMatrixdARB, glLoadTransposeMatrixdARB, NULL, _gloffset_LoadTransposeMatrixdARB),
+    NAME_FUNC_OFFSET(16207, glLoadTransposeMatrixfARB, glLoadTransposeMatrixfARB, NULL, _gloffset_LoadTransposeMatrixfARB),
+    NAME_FUNC_OFFSET(16230, glMultTransposeMatrixdARB, glMultTransposeMatrixdARB, NULL, _gloffset_MultTransposeMatrixdARB),
+    NAME_FUNC_OFFSET(16253, glMultTransposeMatrixfARB, glMultTransposeMatrixfARB, NULL, _gloffset_MultTransposeMatrixfARB),
+    NAME_FUNC_OFFSET(16276, glSampleCoverageARB, glSampleCoverageARB, NULL, _gloffset_SampleCoverageARB),
+    NAME_FUNC_OFFSET(16293, glCompressedTexImage1DARB, glCompressedTexImage1DARB, NULL, _gloffset_CompressedTexImage1DARB),
+    NAME_FUNC_OFFSET(16316, glCompressedTexImage2DARB, glCompressedTexImage2DARB, NULL, _gloffset_CompressedTexImage2DARB),
+    NAME_FUNC_OFFSET(16339, glCompressedTexImage3DARB, glCompressedTexImage3DARB, NULL, _gloffset_CompressedTexImage3DARB),
+    NAME_FUNC_OFFSET(16362, glCompressedTexSubImage1DARB, glCompressedTexSubImage1DARB, NULL, _gloffset_CompressedTexSubImage1DARB),
+    NAME_FUNC_OFFSET(16388, glCompressedTexSubImage2DARB, glCompressedTexSubImage2DARB, NULL, _gloffset_CompressedTexSubImage2DARB),
+    NAME_FUNC_OFFSET(16414, glCompressedTexSubImage3DARB, glCompressedTexSubImage3DARB, NULL, _gloffset_CompressedTexSubImage3DARB),
+    NAME_FUNC_OFFSET(16440, glGetCompressedTexImageARB, glGetCompressedTexImageARB, NULL, _gloffset_GetCompressedTexImageARB),
+    NAME_FUNC_OFFSET(16464, glDisableVertexAttribArrayARB, glDisableVertexAttribArrayARB, NULL, _gloffset_DisableVertexAttribArrayARB),
+    NAME_FUNC_OFFSET(16491, glEnableVertexAttribArrayARB, glEnableVertexAttribArrayARB, NULL, _gloffset_EnableVertexAttribArrayARB),
+    NAME_FUNC_OFFSET(16517, glGetVertexAttribdvARB, glGetVertexAttribdvARB, NULL, _gloffset_GetVertexAttribdvARB),
+    NAME_FUNC_OFFSET(16537, glGetVertexAttribfvARB, glGetVertexAttribfvARB, NULL, _gloffset_GetVertexAttribfvARB),
+    NAME_FUNC_OFFSET(16557, glGetVertexAttribivARB, glGetVertexAttribivARB, NULL, _gloffset_GetVertexAttribivARB),
+    NAME_FUNC_OFFSET(16577, glProgramEnvParameter4dARB, glProgramEnvParameter4dARB, NULL, _gloffset_ProgramEnvParameter4dARB),
+    NAME_FUNC_OFFSET(16600, glProgramEnvParameter4dvARB, glProgramEnvParameter4dvARB, NULL, _gloffset_ProgramEnvParameter4dvARB),
+    NAME_FUNC_OFFSET(16624, glProgramEnvParameter4fARB, glProgramEnvParameter4fARB, NULL, _gloffset_ProgramEnvParameter4fARB),
+    NAME_FUNC_OFFSET(16647, glProgramEnvParameter4fvARB, glProgramEnvParameter4fvARB, NULL, _gloffset_ProgramEnvParameter4fvARB),
+    NAME_FUNC_OFFSET(16671, glVertexAttrib1dARB, glVertexAttrib1dARB, NULL, _gloffset_VertexAttrib1dARB),
+    NAME_FUNC_OFFSET(16688, glVertexAttrib1dvARB, glVertexAttrib1dvARB, NULL, _gloffset_VertexAttrib1dvARB),
+    NAME_FUNC_OFFSET(16706, glVertexAttrib1fARB, glVertexAttrib1fARB, NULL, _gloffset_VertexAttrib1fARB),
+    NAME_FUNC_OFFSET(16723, glVertexAttrib1fvARB, glVertexAttrib1fvARB, NULL, _gloffset_VertexAttrib1fvARB),
+    NAME_FUNC_OFFSET(16741, glVertexAttrib1sARB, glVertexAttrib1sARB, NULL, _gloffset_VertexAttrib1sARB),
+    NAME_FUNC_OFFSET(16758, glVertexAttrib1svARB, glVertexAttrib1svARB, NULL, _gloffset_VertexAttrib1svARB),
+    NAME_FUNC_OFFSET(16776, glVertexAttrib2dARB, glVertexAttrib2dARB, NULL, _gloffset_VertexAttrib2dARB),
+    NAME_FUNC_OFFSET(16793, glVertexAttrib2dvARB, glVertexAttrib2dvARB, NULL, _gloffset_VertexAttrib2dvARB),
+    NAME_FUNC_OFFSET(16811, glVertexAttrib2fARB, glVertexAttrib2fARB, NULL, _gloffset_VertexAttrib2fARB),
+    NAME_FUNC_OFFSET(16828, glVertexAttrib2fvARB, glVertexAttrib2fvARB, NULL, _gloffset_VertexAttrib2fvARB),
+    NAME_FUNC_OFFSET(16846, glVertexAttrib2sARB, glVertexAttrib2sARB, NULL, _gloffset_VertexAttrib2sARB),
+    NAME_FUNC_OFFSET(16863, glVertexAttrib2svARB, glVertexAttrib2svARB, NULL, _gloffset_VertexAttrib2svARB),
+    NAME_FUNC_OFFSET(16881, glVertexAttrib3dARB, glVertexAttrib3dARB, NULL, _gloffset_VertexAttrib3dARB),
+    NAME_FUNC_OFFSET(16898, glVertexAttrib3dvARB, glVertexAttrib3dvARB, NULL, _gloffset_VertexAttrib3dvARB),
+    NAME_FUNC_OFFSET(16916, glVertexAttrib3fARB, glVertexAttrib3fARB, NULL, _gloffset_VertexAttrib3fARB),
+    NAME_FUNC_OFFSET(16933, glVertexAttrib3fvARB, glVertexAttrib3fvARB, NULL, _gloffset_VertexAttrib3fvARB),
+    NAME_FUNC_OFFSET(16951, glVertexAttrib3sARB, glVertexAttrib3sARB, NULL, _gloffset_VertexAttrib3sARB),
+    NAME_FUNC_OFFSET(16968, glVertexAttrib3svARB, glVertexAttrib3svARB, NULL, _gloffset_VertexAttrib3svARB),
+    NAME_FUNC_OFFSET(16986, glVertexAttrib4NbvARB, glVertexAttrib4NbvARB, NULL, _gloffset_VertexAttrib4NbvARB),
+    NAME_FUNC_OFFSET(17005, glVertexAttrib4NivARB, glVertexAttrib4NivARB, NULL, _gloffset_VertexAttrib4NivARB),
+    NAME_FUNC_OFFSET(17024, glVertexAttrib4NsvARB, glVertexAttrib4NsvARB, NULL, _gloffset_VertexAttrib4NsvARB),
+    NAME_FUNC_OFFSET(17043, glVertexAttrib4NubARB, glVertexAttrib4NubARB, NULL, _gloffset_VertexAttrib4NubARB),
+    NAME_FUNC_OFFSET(17062, glVertexAttrib4NubvARB, glVertexAttrib4NubvARB, NULL, _gloffset_VertexAttrib4NubvARB),
+    NAME_FUNC_OFFSET(17082, glVertexAttrib4NuivARB, glVertexAttrib4NuivARB, NULL, _gloffset_VertexAttrib4NuivARB),
+    NAME_FUNC_OFFSET(17102, glVertexAttrib4NusvARB, glVertexAttrib4NusvARB, NULL, _gloffset_VertexAttrib4NusvARB),
+    NAME_FUNC_OFFSET(17122, glVertexAttrib4bvARB, glVertexAttrib4bvARB, NULL, _gloffset_VertexAttrib4bvARB),
+    NAME_FUNC_OFFSET(17140, glVertexAttrib4dARB, glVertexAttrib4dARB, NULL, _gloffset_VertexAttrib4dARB),
+    NAME_FUNC_OFFSET(17157, glVertexAttrib4dvARB, glVertexAttrib4dvARB, NULL, _gloffset_VertexAttrib4dvARB),
+    NAME_FUNC_OFFSET(17175, glVertexAttrib4fARB, glVertexAttrib4fARB, NULL, _gloffset_VertexAttrib4fARB),
+    NAME_FUNC_OFFSET(17192, glVertexAttrib4fvARB, glVertexAttrib4fvARB, NULL, _gloffset_VertexAttrib4fvARB),
+    NAME_FUNC_OFFSET(17210, glVertexAttrib4ivARB, glVertexAttrib4ivARB, NULL, _gloffset_VertexAttrib4ivARB),
+    NAME_FUNC_OFFSET(17228, glVertexAttrib4sARB, glVertexAttrib4sARB, NULL, _gloffset_VertexAttrib4sARB),
+    NAME_FUNC_OFFSET(17245, glVertexAttrib4svARB, glVertexAttrib4svARB, NULL, _gloffset_VertexAttrib4svARB),
+    NAME_FUNC_OFFSET(17263, glVertexAttrib4ubvARB, glVertexAttrib4ubvARB, NULL, _gloffset_VertexAttrib4ubvARB),
+    NAME_FUNC_OFFSET(17282, glVertexAttrib4uivARB, glVertexAttrib4uivARB, NULL, _gloffset_VertexAttrib4uivARB),
+    NAME_FUNC_OFFSET(17301, glVertexAttrib4usvARB, glVertexAttrib4usvARB, NULL, _gloffset_VertexAttrib4usvARB),
+    NAME_FUNC_OFFSET(17320, glVertexAttribPointerARB, glVertexAttribPointerARB, NULL, _gloffset_VertexAttribPointerARB),
+    NAME_FUNC_OFFSET(17342, glBindBufferARB, glBindBufferARB, NULL, _gloffset_BindBufferARB),
+    NAME_FUNC_OFFSET(17355, glBufferDataARB, glBufferDataARB, NULL, _gloffset_BufferDataARB),
+    NAME_FUNC_OFFSET(17368, glBufferSubDataARB, glBufferSubDataARB, NULL, _gloffset_BufferSubDataARB),
+    NAME_FUNC_OFFSET(17384, glDeleteBuffersARB, glDeleteBuffersARB, NULL, _gloffset_DeleteBuffersARB),
+    NAME_FUNC_OFFSET(17400, glGenBuffersARB, glGenBuffersARB, NULL, _gloffset_GenBuffersARB),
+    NAME_FUNC_OFFSET(17413, glGetBufferParameterivARB, glGetBufferParameterivARB, NULL, _gloffset_GetBufferParameterivARB),
+    NAME_FUNC_OFFSET(17436, glGetBufferPointervARB, glGetBufferPointervARB, NULL, _gloffset_GetBufferPointervARB),
+    NAME_FUNC_OFFSET(17456, glGetBufferSubDataARB, glGetBufferSubDataARB, NULL, _gloffset_GetBufferSubDataARB),
+    NAME_FUNC_OFFSET(17475, glIsBufferARB, glIsBufferARB, NULL, _gloffset_IsBufferARB),
+    NAME_FUNC_OFFSET(17486, glMapBufferARB, glMapBufferARB, NULL, _gloffset_MapBufferARB),
+    NAME_FUNC_OFFSET(17498, glUnmapBufferARB, glUnmapBufferARB, NULL, _gloffset_UnmapBufferARB),
+    NAME_FUNC_OFFSET(17512, glBeginQueryARB, glBeginQueryARB, NULL, _gloffset_BeginQueryARB),
+    NAME_FUNC_OFFSET(17525, glDeleteQueriesARB, glDeleteQueriesARB, NULL, _gloffset_DeleteQueriesARB),
+    NAME_FUNC_OFFSET(17541, glEndQueryARB, glEndQueryARB, NULL, _gloffset_EndQueryARB),
+    NAME_FUNC_OFFSET(17552, glGenQueriesARB, glGenQueriesARB, NULL, _gloffset_GenQueriesARB),
+    NAME_FUNC_OFFSET(17565, glGetQueryObjectivARB, glGetQueryObjectivARB, NULL, _gloffset_GetQueryObjectivARB),
+    NAME_FUNC_OFFSET(17584, glGetQueryObjectuivARB, glGetQueryObjectuivARB, NULL, _gloffset_GetQueryObjectuivARB),
+    NAME_FUNC_OFFSET(17604, glGetQueryivARB, glGetQueryivARB, NULL, _gloffset_GetQueryivARB),
+    NAME_FUNC_OFFSET(17617, glIsQueryARB, glIsQueryARB, NULL, _gloffset_IsQueryARB),
+    NAME_FUNC_OFFSET(17627, glCompileShaderARB, glCompileShaderARB, NULL, _gloffset_CompileShaderARB),
+    NAME_FUNC_OFFSET(17643, glGetActiveUniformARB, glGetActiveUniformARB, NULL, _gloffset_GetActiveUniformARB),
+    NAME_FUNC_OFFSET(17662, glGetShaderSourceARB, glGetShaderSourceARB, NULL, _gloffset_GetShaderSourceARB),
+    NAME_FUNC_OFFSET(17680, glGetUniformLocationARB, glGetUniformLocationARB, NULL, _gloffset_GetUniformLocationARB),
+    NAME_FUNC_OFFSET(17701, glGetUniformfvARB, glGetUniformfvARB, NULL, _gloffset_GetUniformfvARB),
+    NAME_FUNC_OFFSET(17716, glGetUniformivARB, glGetUniformivARB, NULL, _gloffset_GetUniformivARB),
+    NAME_FUNC_OFFSET(17731, glLinkProgramARB, glLinkProgramARB, NULL, _gloffset_LinkProgramARB),
+    NAME_FUNC_OFFSET(17745, glShaderSourceARB, glShaderSourceARB, NULL, _gloffset_ShaderSourceARB),
+    NAME_FUNC_OFFSET(17760, glUniform1fARB, glUniform1fARB, NULL, _gloffset_Uniform1fARB),
+    NAME_FUNC_OFFSET(17772, glUniform1fvARB, glUniform1fvARB, NULL, _gloffset_Uniform1fvARB),
+    NAME_FUNC_OFFSET(17785, glUniform1iARB, glUniform1iARB, NULL, _gloffset_Uniform1iARB),
+    NAME_FUNC_OFFSET(17797, glUniform1ivARB, glUniform1ivARB, NULL, _gloffset_Uniform1ivARB),
+    NAME_FUNC_OFFSET(17810, glUniform2fARB, glUniform2fARB, NULL, _gloffset_Uniform2fARB),
+    NAME_FUNC_OFFSET(17822, glUniform2fvARB, glUniform2fvARB, NULL, _gloffset_Uniform2fvARB),
+    NAME_FUNC_OFFSET(17835, glUniform2iARB, glUniform2iARB, NULL, _gloffset_Uniform2iARB),
+    NAME_FUNC_OFFSET(17847, glUniform2ivARB, glUniform2ivARB, NULL, _gloffset_Uniform2ivARB),
+    NAME_FUNC_OFFSET(17860, glUniform3fARB, glUniform3fARB, NULL, _gloffset_Uniform3fARB),
+    NAME_FUNC_OFFSET(17872, glUniform3fvARB, glUniform3fvARB, NULL, _gloffset_Uniform3fvARB),
+    NAME_FUNC_OFFSET(17885, glUniform3iARB, glUniform3iARB, NULL, _gloffset_Uniform3iARB),
+    NAME_FUNC_OFFSET(17897, glUniform3ivARB, glUniform3ivARB, NULL, _gloffset_Uniform3ivARB),
+    NAME_FUNC_OFFSET(17910, glUniform4fARB, glUniform4fARB, NULL, _gloffset_Uniform4fARB),
+    NAME_FUNC_OFFSET(17922, glUniform4fvARB, glUniform4fvARB, NULL, _gloffset_Uniform4fvARB),
+    NAME_FUNC_OFFSET(17935, glUniform4iARB, glUniform4iARB, NULL, _gloffset_Uniform4iARB),
+    NAME_FUNC_OFFSET(17947, glUniform4ivARB, glUniform4ivARB, NULL, _gloffset_Uniform4ivARB),
+    NAME_FUNC_OFFSET(17960, glUniformMatrix2fvARB, glUniformMatrix2fvARB, NULL, _gloffset_UniformMatrix2fvARB),
+    NAME_FUNC_OFFSET(17979, glUniformMatrix3fvARB, glUniformMatrix3fvARB, NULL, _gloffset_UniformMatrix3fvARB),
+    NAME_FUNC_OFFSET(17998, glUniformMatrix4fvARB, glUniformMatrix4fvARB, NULL, _gloffset_UniformMatrix4fvARB),
+    NAME_FUNC_OFFSET(18017, glUseProgramObjectARB, glUseProgramObjectARB, NULL, _gloffset_UseProgramObjectARB),
+    NAME_FUNC_OFFSET(18030, glValidateProgramARB, glValidateProgramARB, NULL, _gloffset_ValidateProgramARB),
+    NAME_FUNC_OFFSET(18048, glBindAttribLocationARB, glBindAttribLocationARB, NULL, _gloffset_BindAttribLocationARB),
+    NAME_FUNC_OFFSET(18069, glGetActiveAttribARB, glGetActiveAttribARB, NULL, _gloffset_GetActiveAttribARB),
+    NAME_FUNC_OFFSET(18087, glGetAttribLocationARB, glGetAttribLocationARB, NULL, _gloffset_GetAttribLocationARB),
+    NAME_FUNC_OFFSET(18107, glDrawBuffersARB, glDrawBuffersARB, NULL, _gloffset_DrawBuffersARB),
+    NAME_FUNC_OFFSET(18121, glDrawBuffersARB, glDrawBuffersARB, NULL, _gloffset_DrawBuffersARB),
+    NAME_FUNC_OFFSET(18138, glRenderbufferStorageMultisample, glRenderbufferStorageMultisample, NULL, _gloffset_RenderbufferStorageMultisample),
+    NAME_FUNC_OFFSET(18174, gl_dispatch_stub_584, gl_dispatch_stub_584, NULL, _gloffset_SampleMaskSGIS),
+    NAME_FUNC_OFFSET(18190, gl_dispatch_stub_585, gl_dispatch_stub_585, NULL, _gloffset_SamplePatternSGIS),
+    NAME_FUNC_OFFSET(18209, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
+    NAME_FUNC_OFFSET(18227, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
+    NAME_FUNC_OFFSET(18248, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
+    NAME_FUNC_OFFSET(18270, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
+    NAME_FUNC_OFFSET(18289, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
+    NAME_FUNC_OFFSET(18311, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
+    NAME_FUNC_OFFSET(18334, glSecondaryColor3bEXT, glSecondaryColor3bEXT, NULL, _gloffset_SecondaryColor3bEXT),
+    NAME_FUNC_OFFSET(18353, glSecondaryColor3bvEXT, glSecondaryColor3bvEXT, NULL, _gloffset_SecondaryColor3bvEXT),
+    NAME_FUNC_OFFSET(18373, glSecondaryColor3dEXT, glSecondaryColor3dEXT, NULL, _gloffset_SecondaryColor3dEXT),
+    NAME_FUNC_OFFSET(18392, glSecondaryColor3dvEXT, glSecondaryColor3dvEXT, NULL, _gloffset_SecondaryColor3dvEXT),
+    NAME_FUNC_OFFSET(18412, glSecondaryColor3fEXT, glSecondaryColor3fEXT, NULL, _gloffset_SecondaryColor3fEXT),
+    NAME_FUNC_OFFSET(18431, glSecondaryColor3fvEXT, glSecondaryColor3fvEXT, NULL, _gloffset_SecondaryColor3fvEXT),
+    NAME_FUNC_OFFSET(18451, glSecondaryColor3iEXT, glSecondaryColor3iEXT, NULL, _gloffset_SecondaryColor3iEXT),
+    NAME_FUNC_OFFSET(18470, glSecondaryColor3ivEXT, glSecondaryColor3ivEXT, NULL, _gloffset_SecondaryColor3ivEXT),
+    NAME_FUNC_OFFSET(18490, glSecondaryColor3sEXT, glSecondaryColor3sEXT, NULL, _gloffset_SecondaryColor3sEXT),
+    NAME_FUNC_OFFSET(18509, glSecondaryColor3svEXT, glSecondaryColor3svEXT, NULL, _gloffset_SecondaryColor3svEXT),
+    NAME_FUNC_OFFSET(18529, glSecondaryColor3ubEXT, glSecondaryColor3ubEXT, NULL, _gloffset_SecondaryColor3ubEXT),
+    NAME_FUNC_OFFSET(18549, glSecondaryColor3ubvEXT, glSecondaryColor3ubvEXT, NULL, _gloffset_SecondaryColor3ubvEXT),
+    NAME_FUNC_OFFSET(18570, glSecondaryColor3uiEXT, glSecondaryColor3uiEXT, NULL, _gloffset_SecondaryColor3uiEXT),
+    NAME_FUNC_OFFSET(18590, glSecondaryColor3uivEXT, glSecondaryColor3uivEXT, NULL, _gloffset_SecondaryColor3uivEXT),
+    NAME_FUNC_OFFSET(18611, glSecondaryColor3usEXT, glSecondaryColor3usEXT, NULL, _gloffset_SecondaryColor3usEXT),
+    NAME_FUNC_OFFSET(18631, glSecondaryColor3usvEXT, glSecondaryColor3usvEXT, NULL, _gloffset_SecondaryColor3usvEXT),
+    NAME_FUNC_OFFSET(18652, glSecondaryColorPointerEXT, glSecondaryColorPointerEXT, NULL, _gloffset_SecondaryColorPointerEXT),
+    NAME_FUNC_OFFSET(18676, glMultiDrawArraysEXT, glMultiDrawArraysEXT, NULL, _gloffset_MultiDrawArraysEXT),
+    NAME_FUNC_OFFSET(18694, glMultiDrawElementsEXT, glMultiDrawElementsEXT, NULL, _gloffset_MultiDrawElementsEXT),
+    NAME_FUNC_OFFSET(18714, glFogCoordPointerEXT, glFogCoordPointerEXT, NULL, _gloffset_FogCoordPointerEXT),
+    NAME_FUNC_OFFSET(18732, glFogCoorddEXT, glFogCoorddEXT, NULL, _gloffset_FogCoorddEXT),
+    NAME_FUNC_OFFSET(18744, glFogCoorddvEXT, glFogCoorddvEXT, NULL, _gloffset_FogCoorddvEXT),
+    NAME_FUNC_OFFSET(18757, glFogCoordfEXT, glFogCoordfEXT, NULL, _gloffset_FogCoordfEXT),
+    NAME_FUNC_OFFSET(18769, glFogCoordfvEXT, glFogCoordfvEXT, NULL, _gloffset_FogCoordfvEXT),
+    NAME_FUNC_OFFSET(18782, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
+    NAME_FUNC_OFFSET(18802, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
+    NAME_FUNC_OFFSET(18826, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
+    NAME_FUNC_OFFSET(18840, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
+    NAME_FUNC_OFFSET(18857, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
+    NAME_FUNC_OFFSET(18872, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
+    NAME_FUNC_OFFSET(18890, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
+    NAME_FUNC_OFFSET(18904, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
+    NAME_FUNC_OFFSET(18921, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
+    NAME_FUNC_OFFSET(18936, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
+    NAME_FUNC_OFFSET(18954, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
+    NAME_FUNC_OFFSET(18968, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
+    NAME_FUNC_OFFSET(18985, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
+    NAME_FUNC_OFFSET(19000, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
+    NAME_FUNC_OFFSET(19018, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
+    NAME_FUNC_OFFSET(19032, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
+    NAME_FUNC_OFFSET(19049, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
+    NAME_FUNC_OFFSET(19064, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
+    NAME_FUNC_OFFSET(19082, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
+    NAME_FUNC_OFFSET(19096, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
+    NAME_FUNC_OFFSET(19113, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
+    NAME_FUNC_OFFSET(19128, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
+    NAME_FUNC_OFFSET(19146, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
+    NAME_FUNC_OFFSET(19160, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
+    NAME_FUNC_OFFSET(19177, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
+    NAME_FUNC_OFFSET(19192, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
+    NAME_FUNC_OFFSET(19210, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
+    NAME_FUNC_OFFSET(19224, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
+    NAME_FUNC_OFFSET(19241, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
+    NAME_FUNC_OFFSET(19256, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
+    NAME_FUNC_OFFSET(19274, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
+    NAME_FUNC_OFFSET(19288, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
+    NAME_FUNC_OFFSET(19305, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
+    NAME_FUNC_OFFSET(19320, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
+    NAME_FUNC_OFFSET(19338, glBindProgramNV, glBindProgramNV, NULL, _gloffset_BindProgramNV),
+    NAME_FUNC_OFFSET(19355, glDeleteProgramsNV, glDeleteProgramsNV, NULL, _gloffset_DeleteProgramsNV),
+    NAME_FUNC_OFFSET(19375, glGenProgramsNV, glGenProgramsNV, NULL, _gloffset_GenProgramsNV),
+    NAME_FUNC_OFFSET(19392, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
+    NAME_FUNC_OFFSET(19418, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
+    NAME_FUNC_OFFSET(19447, glIsProgramNV, glIsProgramNV, NULL, _gloffset_IsProgramNV),
+    NAME_FUNC_OFFSET(19462, glPointParameteriNV, glPointParameteriNV, NULL, _gloffset_PointParameteriNV),
+    NAME_FUNC_OFFSET(19480, glPointParameterivNV, glPointParameterivNV, NULL, _gloffset_PointParameterivNV),
+    NAME_FUNC_OFFSET(19499, gl_dispatch_stub_755, gl_dispatch_stub_755, NULL, _gloffset_DeleteVertexArraysAPPLE),
+    NAME_FUNC_OFFSET(19520, gl_dispatch_stub_757, gl_dispatch_stub_757, NULL, _gloffset_IsVertexArrayAPPLE),
+    NAME_FUNC_OFFSET(19536, gl_dispatch_stub_765, gl_dispatch_stub_765, NULL, _gloffset_BlendEquationSeparateEXT),
+    NAME_FUNC_OFFSET(19560, gl_dispatch_stub_765, gl_dispatch_stub_765, NULL, _gloffset_BlendEquationSeparateEXT),
+    NAME_FUNC_OFFSET(19587, glBindFramebufferEXT, glBindFramebufferEXT, NULL, _gloffset_BindFramebufferEXT),
+    NAME_FUNC_OFFSET(19605, glBindRenderbufferEXT, glBindRenderbufferEXT, NULL, _gloffset_BindRenderbufferEXT),
+    NAME_FUNC_OFFSET(19624, glCheckFramebufferStatusEXT, glCheckFramebufferStatusEXT, NULL, _gloffset_CheckFramebufferStatusEXT),
+    NAME_FUNC_OFFSET(19649, glDeleteFramebuffersEXT, glDeleteFramebuffersEXT, NULL, _gloffset_DeleteFramebuffersEXT),
+    NAME_FUNC_OFFSET(19670, glDeleteRenderbuffersEXT, glDeleteRenderbuffersEXT, NULL, _gloffset_DeleteRenderbuffersEXT),
+    NAME_FUNC_OFFSET(19692, glFramebufferRenderbufferEXT, glFramebufferRenderbufferEXT, NULL, _gloffset_FramebufferRenderbufferEXT),
+    NAME_FUNC_OFFSET(19718, glFramebufferTexture1DEXT, glFramebufferTexture1DEXT, NULL, _gloffset_FramebufferTexture1DEXT),
+    NAME_FUNC_OFFSET(19741, glFramebufferTexture2DEXT, glFramebufferTexture2DEXT, NULL, _gloffset_FramebufferTexture2DEXT),
+    NAME_FUNC_OFFSET(19764, glFramebufferTexture3DEXT, glFramebufferTexture3DEXT, NULL, _gloffset_FramebufferTexture3DEXT),
+    NAME_FUNC_OFFSET(19787, glGenFramebuffersEXT, glGenFramebuffersEXT, NULL, _gloffset_GenFramebuffersEXT),
+    NAME_FUNC_OFFSET(19805, glGenRenderbuffersEXT, glGenRenderbuffersEXT, NULL, _gloffset_GenRenderbuffersEXT),
+    NAME_FUNC_OFFSET(19824, glGenerateMipmapEXT, glGenerateMipmapEXT, NULL, _gloffset_GenerateMipmapEXT),
+    NAME_FUNC_OFFSET(19841, glGetFramebufferAttachmentParameterivEXT, glGetFramebufferAttachmentParameterivEXT, NULL, _gloffset_GetFramebufferAttachmentParameterivEXT),
+    NAME_FUNC_OFFSET(19879, glGetRenderbufferParameterivEXT, glGetRenderbufferParameterivEXT, NULL, _gloffset_GetRenderbufferParameterivEXT),
+    NAME_FUNC_OFFSET(19908, glIsFramebufferEXT, glIsFramebufferEXT, NULL, _gloffset_IsFramebufferEXT),
+    NAME_FUNC_OFFSET(19924, glIsRenderbufferEXT, glIsRenderbufferEXT, NULL, _gloffset_IsRenderbufferEXT),
+    NAME_FUNC_OFFSET(19941, glRenderbufferStorageEXT, glRenderbufferStorageEXT, NULL, _gloffset_RenderbufferStorageEXT),
+    NAME_FUNC_OFFSET(19963, gl_dispatch_stub_783, gl_dispatch_stub_783, NULL, _gloffset_BlitFramebufferEXT),
+    NAME_FUNC_OFFSET(19981, glFramebufferTextureLayerEXT, glFramebufferTextureLayerEXT, NULL, _gloffset_FramebufferTextureLayerEXT),
+    NAME_FUNC_OFFSET(20007, glProvokingVertexEXT, glProvokingVertexEXT, NULL, _gloffset_ProvokingVertexEXT),
     NAME_FUNC_OFFSET(-1, NULL, NULL, NULL, 0)
 };
 
diff --git a/src/mesa/glapi/glthread.c b/src/mesa/glapi/glthread.c
index dc90b36..1c2c386 100644
--- a/src/mesa/glapi/glthread.c
+++ b/src/mesa/glapi/glthread.c
@@ -69,7 +69,7 @@
  */
 #ifdef PTHREADS
 
-unsigned long
+PUBLIC unsigned long
 _glthread_GetID(void)
 {
    return (unsigned long) pthread_self();
@@ -123,7 +123,7 @@
 #define USE_LOCK_FOR_KEY	/* undef this to try a version without
 				   lock for the global key... */
 
-unsigned long
+PUBLIC unsigned long
 _glthread_GetID(void)
 {
    abort();   /* XXX not implemented yet */
@@ -201,7 +201,7 @@
    DWORD dwErr=GetLastError();
 }
 
-unsigned long
+PUBLIC unsigned long
 _glthread_GetID(void)
 {
    return GetCurrentThreadId();
@@ -251,7 +251,7 @@
  */
 #ifdef BEOS_THREADS
 
-unsigned long
+PUBLIC unsigned long
 _glthread_GetID(void)
 {
    return (unsigned long) find_thread(NULL);
@@ -293,7 +293,7 @@
  * no-op functions
  */
 
-unsigned long
+PUBLIC unsigned long
 _glthread_GetID(void)
 {
    return 0;
diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c
index 1559984..c2d8a7f 100644
--- a/src/mesa/main/api_exec.c
+++ b/src/mesa/main/api_exec.c
@@ -51,6 +51,7 @@
 #include "clear.h"
 #include "clip.h"
 #include "colortab.h"
+#include "condrender.h"
 #include "context.h"
 #include "convolve.h"
 #include "depth.h"
@@ -746,4 +747,16 @@
    /* GL_ARB_vertex_array_object */
    SET_BindVertexArray(exec, _mesa_BindVertexArray);
    SET_GenVertexArrays(exec, _mesa_GenVertexArrays);
+
+   /* GL_EXT_draw_buffers2 */
+   SET_ColorMaskIndexedEXT(exec, _mesa_ColorMaskIndexed);
+   SET_GetBooleanIndexedvEXT(exec, _mesa_GetBooleanIndexedv);
+   SET_GetIntegerIndexedvEXT(exec, _mesa_GetIntegerIndexedv);
+   SET_EnableIndexedEXT(exec, _mesa_EnableIndexed);
+   SET_DisableIndexedEXT(exec, _mesa_DisableIndexed);
+   SET_IsEnabledIndexedEXT(exec, _mesa_IsEnabledIndexed);
+
+   /* GL_NV_conditional_render */
+   SET_BeginConditionalRenderNV(exec, _mesa_BeginConditionalRender);
+   SET_EndConditionalRenderNV(exec, _mesa_EndConditionalRender);
 }
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index 246c552..0641b98 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -499,7 +499,17 @@
 	}
 
    TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST);
-   TEST_AND_UPDATE(ctx->Color.BlendEnabled, enable->Blend, GL_BLEND);
+   if (ctx->Color.BlendEnabled != enable->Blend) {
+      if (ctx->Extensions.EXT_draw_buffers2) {
+         GLuint i;
+         for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
+            _mesa_set_enablei(ctx, GL_BLEND, i, (enable->Blend >> i) & 1);
+         }
+      }
+      else {
+         _mesa_set_enable(ctx, GL_BLEND, (enable->Blend & 1));
+      }
+   }
 
    for (i=0;i<MAX_CLIP_PLANES;i++) {
       const GLuint mask = 1 << i;
@@ -825,7 +835,7 @@
 
          _mesa_BindTexture(target, obj->Name);
 
-         _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, obj->BorderColor);
+         _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, obj->BorderColor.f);
          _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority);
          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, obj->WrapS);
          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, obj->WrapT);
@@ -906,6 +916,7 @@
          case GL_COLOR_BUFFER_BIT:
             {
                const struct gl_colorbuffer_attrib *color;
+
                color = (const struct gl_colorbuffer_attrib *) attr->data;
                _mesa_ClearIndex((GLfloat) color->ClearIndex);
                _mesa_ClearColor(color->ClearColor[0],
@@ -913,10 +924,22 @@
                                 color->ClearColor[2],
                                 color->ClearColor[3]);
                _mesa_IndexMask(color->IndexMask);
-               _mesa_ColorMask((GLboolean) (color->ColorMask[0] != 0),
-                               (GLboolean) (color->ColorMask[1] != 0),
-                               (GLboolean) (color->ColorMask[2] != 0),
-                               (GLboolean) (color->ColorMask[3] != 0));
+               if (!ctx->Extensions.EXT_draw_buffers2) {
+                  _mesa_ColorMask((GLboolean) (color->ColorMask[0][0] != 0),
+                                  (GLboolean) (color->ColorMask[0][1] != 0),
+                                  (GLboolean) (color->ColorMask[0][2] != 0),
+                                  (GLboolean) (color->ColorMask[0][3] != 0));
+               }
+               else {
+                  GLuint i;
+                  for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
+                     _mesa_ColorMaskIndexed(i, 
+                                  (GLboolean) (color->ColorMask[i][0] != 0),
+                                  (GLboolean) (color->ColorMask[i][1] != 0),
+                                  (GLboolean) (color->ColorMask[i][2] != 0),
+                                  (GLboolean) (color->ColorMask[i][3] != 0));
+                  }
+               }
                {
                   /* Need to determine if more than one color output is
                    * specified.  If so, call glDrawBuffersARB, else call
@@ -948,7 +971,18 @@
                }
                _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled);
                _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRef);
-               _mesa_set_enable(ctx, GL_BLEND, color->BlendEnabled);
+               if (ctx->Color.BlendEnabled != color->BlendEnabled) {
+                  if (ctx->Extensions.EXT_draw_buffers2) {
+                     GLuint i;
+                     for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
+                        _mesa_set_enablei(ctx, GL_BLEND, i,
+                                          (color->BlendEnabled >> i) & 1);
+                     }
+                  }
+                  else {
+                     _mesa_set_enable(ctx, GL_BLEND, (color->BlendEnabled & 1));
+                  }
+               }
                _mesa_BlendFuncSeparateEXT(color->BlendSrcRGB,
                                           color->BlendDstRGB,
                                           color->BlendSrcA,
@@ -1043,22 +1077,39 @@
                   _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
 	       
                for (i = 0; i < ctx->Const.MaxLights; i++) {
-		  const struct gl_light *l = &light->Light[i];
+                  const struct gl_light *l = &light->Light[i];
                   _mesa_set_enable(ctx, GL_LIGHT0 + i, l->Enabled);
-		  _mesa_light(ctx, i, GL_AMBIENT, l->Ambient);
-		  _mesa_light(ctx, i, GL_DIFFUSE, l->Diffuse);
-		  _mesa_light(ctx, i, GL_SPECULAR, l->Specular );
-		  _mesa_light(ctx, i, GL_POSITION, l->EyePosition);
-		  _mesa_light(ctx, i, GL_SPOT_DIRECTION, l->SpotDirection);
-		  _mesa_light(ctx, i, GL_SPOT_EXPONENT, &l->SpotExponent);
-		  _mesa_light(ctx, i, GL_SPOT_CUTOFF, &l->SpotCutoff);
-		  _mesa_light(ctx, i, GL_CONSTANT_ATTENUATION,
-                              &l->ConstantAttenuation);
-		  _mesa_light(ctx, i, GL_LINEAR_ATTENUATION,
-                              &l->LinearAttenuation);
-		  _mesa_light(ctx, i, GL_QUADRATIC_ATTENUATION,
-                              &l->QuadraticAttenuation);
-               }
+                  _mesa_light(ctx, i, GL_AMBIENT, l->Ambient);
+                  _mesa_light(ctx, i, GL_DIFFUSE, l->Diffuse);
+                  _mesa_light(ctx, i, GL_SPECULAR, l->Specular );
+                  _mesa_light(ctx, i, GL_POSITION, l->EyePosition);
+                  _mesa_light(ctx, i, GL_SPOT_DIRECTION, l->SpotDirection);
+                  {
+                     GLfloat p[4] = { 0 };
+                     p[0] = l->SpotExponent;
+                     _mesa_light(ctx, i, GL_SPOT_EXPONENT, p);
+                  }
+                  {
+                     GLfloat p[4] = { 0 };
+                     p[0] = l->SpotCutoff;
+                     _mesa_light(ctx, i, GL_SPOT_CUTOFF, p);
+                  }
+                  {
+                     GLfloat p[4] = { 0 };
+                     p[0] = l->ConstantAttenuation;
+                     _mesa_light(ctx, i, GL_CONSTANT_ATTENUATION, p);
+                  }
+                  {
+                     GLfloat p[4] = { 0 };
+                     p[0] = l->LinearAttenuation;
+                     _mesa_light(ctx, i, GL_LINEAR_ATTENUATION, p);
+                  }
+                  {
+                     GLfloat p[4] = { 0 };
+                     p[0] = l->QuadraticAttenuation;
+                     _mesa_light(ctx, i, GL_QUADRATIC_ATTENUATION, p);
+                  }
+                }
                /* light model */
                _mesa_LightModelfv(GL_LIGHT_MODEL_AMBIENT,
                                   light->Model.Ambient);
diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c
index 830e3b2..b8170dd 100644
--- a/src/mesa/main/blend.c
+++ b/src/mesa/main/blend.c
@@ -484,6 +484,8 @@
 {
    GET_CURRENT_CONTEXT(ctx);
    GLubyte tmp[4];
+   GLuint i;
+   GLboolean flushed;
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    if (MESA_VERBOSE & VERBOSE_API)
@@ -497,17 +499,61 @@
    tmp[BCOMP] = blue   ? 0xff : 0x0;
    tmp[ACOMP] = alpha  ? 0xff : 0x0;
 
-   if (TEST_EQ_4UBV(tmp, ctx->Color.ColorMask))
-      return;
-
-   FLUSH_VERTICES(ctx, _NEW_COLOR);
-   COPY_4UBV(ctx->Color.ColorMask, tmp);
+   flushed = GL_FALSE;
+   for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
+      if (!TEST_EQ_4V(tmp, ctx->Color.ColorMask[i])) {
+         if (!flushed) {
+            FLUSH_VERTICES(ctx, _NEW_COLOR);
+         }
+         flushed = GL_TRUE;
+         COPY_4UBV(ctx->Color.ColorMask[i], tmp);
+      }
+   }
 
    if (ctx->Driver.ColorMask)
       ctx->Driver.ColorMask( ctx, red, green, blue, alpha );
 }
 
 
+/**
+ * For GL_EXT_draw_buffers2 and GL3
+ */
+void GLAPIENTRY
+_mesa_ColorMaskIndexed( GLuint buf, GLboolean red, GLboolean green,
+                        GLboolean blue, GLboolean alpha )
+{
+   GLubyte tmp[4];
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glColorMaskIndexed %u %d %d %d %d\n",
+                  buf, red, green, blue, alpha);
+
+   if (buf >= ctx->Const.MaxDrawBuffers) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glColorMaskIndexed(buf=%u)", buf);
+      return;
+   }
+
+   /* Shouldn't have any information about channel depth in core mesa
+    * -- should probably store these as the native booleans:
+    */
+   tmp[RCOMP] = red    ? 0xff : 0x0;
+   tmp[GCOMP] = green  ? 0xff : 0x0;
+   tmp[BCOMP] = blue   ? 0xff : 0x0;
+   tmp[ACOMP] = alpha  ? 0xff : 0x0;
+
+   if (TEST_EQ_4V(tmp, ctx->Color.ColorMask[buf]))
+      return;
+
+   FLUSH_VERTICES(ctx, _NEW_COLOR);
+   COPY_4UBV(ctx->Color.ColorMask[buf], tmp);
+
+   if (ctx->Driver.ColorMaskIndexed)
+      ctx->Driver.ColorMaskIndexed(ctx, buf, red, green, blue, alpha);
+}
+
+
 extern void GLAPIENTRY
 _mesa_ClampColorARB(GLenum target, GLenum clamp)
 {
@@ -555,16 +601,13 @@
 {
    /* Color buffer group */
    ctx->Color.IndexMask = ~0u;
-   ctx->Color.ColorMask[0] = 0xff;
-   ctx->Color.ColorMask[1] = 0xff;
-   ctx->Color.ColorMask[2] = 0xff;
-   ctx->Color.ColorMask[3] = 0xff;
+   memset(ctx->Color.ColorMask, 0xff, sizeof(ctx->Color.ColorMask));
    ctx->Color.ClearIndex = 0;
    ASSIGN_4V( ctx->Color.ClearColor, 0, 0, 0, 0 );
    ctx->Color.AlphaEnabled = GL_FALSE;
    ctx->Color.AlphaFunc = GL_ALWAYS;
    ctx->Color.AlphaRef = 0;
-   ctx->Color.BlendEnabled = GL_FALSE;
+   ctx->Color.BlendEnabled = 0x0;
    ctx->Color.BlendSrcRGB = GL_ONE;
    ctx->Color.BlendDstRGB = GL_ZERO;
    ctx->Color.BlendSrcA = GL_ONE;
diff --git a/src/mesa/main/blend.h b/src/mesa/main/blend.h
index 5c0f278..b4fd747 100644
--- a/src/mesa/main/blend.h
+++ b/src/mesa/main/blend.h
@@ -72,6 +72,10 @@
 _mesa_ColorMask( GLboolean red, GLboolean green,
                  GLboolean blue, GLboolean alpha );
 
+extern void GLAPIENTRY
+_mesa_ColorMaskIndexed( GLuint buf, GLboolean red, GLboolean green,
+                        GLboolean blue, GLboolean alpha );
+
 
 extern void GLAPIENTRY
 _mesa_ClampColorARB(GLenum target, GLenum clamp);
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index 52c4995..9e765b2 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -1389,6 +1389,48 @@
 }
 
 
+/**
+ * New in GL 3.2
+ * This is pretty much a duplicate of GetBufferParameteriv() but the
+ * GL_BUFFER_SIZE_ARB attribute will be 64-bits on a 64-bit system.
+ */
+void GLAPIENTRY
+_mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_buffer_object *bufObj;
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   bufObj = get_buffer(ctx, target);
+   if (!bufObj) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "GetBufferParameteri64v(target)" );
+      return;
+   }
+   if (!_mesa_is_bufferobj(bufObj)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "GetBufferParameteri64v" );
+      return;
+   }
+
+   switch (pname) {
+      case GL_BUFFER_SIZE_ARB:
+         *params = bufObj->Size;
+         break;
+      case GL_BUFFER_USAGE_ARB:
+         *params = bufObj->Usage;
+         break;
+      case GL_BUFFER_ACCESS_ARB:
+         *params = simplified_access_mode(bufObj->AccessFlags);
+         break;
+      case GL_BUFFER_MAPPED_ARB:
+         *params = _mesa_bufferobj_mapped(bufObj);
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferParameteri64v(pname)");
+         return;
+   }
+}
+
+
 void GLAPIENTRY
 _mesa_GetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params)
 {
diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h
index 9f732ec..2931962 100644
--- a/src/mesa/main/bufferobj.h
+++ b/src/mesa/main/bufferobj.h
@@ -155,6 +155,9 @@
 _mesa_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params);
 
 extern void GLAPIENTRY
+_mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params);
+
+extern void GLAPIENTRY
 _mesa_GetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params);
 
 extern void GLAPIENTRY
diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c
index 7f77c5d..97f0659 100644
--- a/src/mesa/main/buffers.c
+++ b/src/mesa/main/buffers.c
@@ -382,8 +382,6 @@
     */
    if (n == 1) {
       GLuint count = 0, destMask0 = destMask[0];
-      /* init to -1 to help catch errors */
-      //fb->_ColorDrawBufferIndexes[0] = -1;
       while (destMask0) {
          GLint bufIndex = _mesa_ffs(destMask0) - 1;
          if (fb->_ColorDrawBufferIndexes[count] != bufIndex) {
diff --git a/src/mesa/main/clear.c b/src/mesa/main/clear.c
index 63388f4..4a3c111 100644
--- a/src/mesa/main/clear.c
+++ b/src/mesa/main/clear.c
@@ -34,6 +34,7 @@
 #include "clear.h"
 #include "context.h"
 #include "colormac.h"
+#include "enums.h"
 #include "state.h"
 
 
@@ -182,3 +183,346 @@
       ctx->Driver.Clear(ctx, bufferMask);
    }
 }
+
+
+/** Returned by make_color_buffer_mask() for errors */
+#define INVALID_MASK ~0x0
+
+
+/**
+ * Convert the glClearBuffer 'drawbuffer' parameter into a bitmask of
+ * BUFFER_BIT_x values.
+ * Return INVALID_MASK if the drawbuffer value is invalid.
+ */
+static GLbitfield
+make_color_buffer_mask(GLcontext *ctx, GLint drawbuffer)
+{
+   const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment;
+   GLbitfield mask = 0x0;
+
+   switch (drawbuffer) {
+   case GL_FRONT:
+      if (att[BUFFER_FRONT_LEFT].Renderbuffer)
+         mask |= BUFFER_BIT_FRONT_LEFT;
+      if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
+         mask |= BUFFER_BIT_FRONT_RIGHT;
+      break;
+   case GL_BACK:
+      if (att[BUFFER_BACK_LEFT].Renderbuffer)
+         mask |= BUFFER_BIT_BACK_LEFT;
+      if (att[BUFFER_BACK_RIGHT].Renderbuffer)
+         mask |= BUFFER_BIT_BACK_RIGHT;
+      break;
+   case GL_LEFT:
+      if (att[BUFFER_FRONT_LEFT].Renderbuffer)
+         mask |= BUFFER_BIT_FRONT_LEFT;
+      if (att[BUFFER_BACK_LEFT].Renderbuffer)
+         mask |= BUFFER_BIT_BACK_LEFT;
+      break;
+   case GL_RIGHT:
+      if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
+         mask |= BUFFER_BIT_FRONT_RIGHT;
+      if (att[BUFFER_BACK_RIGHT].Renderbuffer)
+         mask |= BUFFER_BIT_BACK_RIGHT;
+      break;
+   case GL_FRONT_AND_BACK:
+      if (att[BUFFER_FRONT_LEFT].Renderbuffer)
+         mask |= BUFFER_BIT_FRONT_LEFT;
+      if (att[BUFFER_BACK_LEFT].Renderbuffer)
+         mask |= BUFFER_BIT_BACK_LEFT;
+      if (att[BUFFER_FRONT_RIGHT].Renderbuffer)
+         mask |= BUFFER_BIT_FRONT_RIGHT;
+      if (att[BUFFER_BACK_RIGHT].Renderbuffer)
+         mask |= BUFFER_BIT_BACK_RIGHT;
+      break;
+   default:
+      if (drawbuffer < 0 || drawbuffer >= ctx->Const.MaxDrawBuffers) {
+         mask = INVALID_MASK;
+      }
+      else if (att[BUFFER_COLOR0 + drawbuffer].Renderbuffer) {
+         mask |= (BUFFER_BIT_COLOR0 << drawbuffer);
+      }
+   }
+
+   return mask;
+}
+
+
+
+/**
+ * New in GL 3.0
+ * Clear signed integer color buffer or stencil buffer (not depth).
+ */
+void GLAPIENTRY
+_mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   FLUSH_CURRENT(ctx, 0);
+
+   if (!ctx->DrawBuffer->Visual.rgbMode) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glClearBufferiv()");
+      return;
+   }
+
+   if (ctx->NewState) {
+      _mesa_update_state( ctx );
+   }
+
+   switch (buffer) {
+   case GL_STENCIL:
+      if (drawbuffer != 0) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
+                     drawbuffer);
+         return;
+      }
+      else {
+         /* Save current stencil clear value, set to 'value', do the
+          * stencil clear and restore the clear value.
+          * XXX in the future we may have a new ctx->Driver.ClearBuffer()
+          * hook instead.
+          */
+         const GLuint clearSave = ctx->Stencil.Clear;
+         ctx->Stencil.Clear = *value;
+         if (ctx->Driver.ClearStencil)
+            ctx->Driver.ClearStencil(ctx, *value);
+         ctx->Driver.Clear(ctx, BUFFER_BIT_STENCIL);
+         ctx->Stencil.Clear = clearSave;
+         if (ctx->Driver.ClearStencil)
+            ctx->Driver.ClearStencil(ctx, clearSave);
+      }
+      break;
+   case GL_COLOR:
+      {
+         const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
+         if (mask == INVALID_MASK) {
+            _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
+                        drawbuffer);
+            return;
+         }
+         else if (mask) {
+            /* XXX note: we're putting the integer clear values into the
+             * floating point state var.  This will not always work.  We'll
+             * need a new ctx->Driver.ClearBuffer() hook....
+             */
+            GLfloat clearSave[4];
+            /* save color */
+            COPY_4V(clearSave, ctx->Color.ClearColor);
+            /* set color */
+            COPY_4V(ctx->Color.ClearColor, value);
+            if (ctx->Driver.ClearColor)
+               ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor);
+            /* clear buffer(s) */
+            ctx->Driver.Clear(ctx, mask);
+            /* restore color */
+            COPY_4V(ctx->Color.ClearColor, clearSave);
+            if (ctx->Driver.ClearColor)
+               ctx->Driver.ClearColor(ctx, clearSave);
+         }
+      }
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)",
+                  _mesa_lookup_enum_by_nr(buffer));
+      return;
+   }
+}
+
+
+/**
+ * New in GL 3.0
+ * Clear unsigned integer color buffer (not depth, not stencil).
+ */
+void GLAPIENTRY
+_mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   FLUSH_CURRENT(ctx, 0);
+
+   if (!ctx->DrawBuffer->Visual.rgbMode) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glClearBufferuiv()");
+      return;
+   }
+
+   if (ctx->NewState) {
+      _mesa_update_state( ctx );
+   }
+
+   switch (buffer) {
+   case GL_COLOR:
+      {
+         const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
+         if (mask == INVALID_MASK) {
+            _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)",
+                        drawbuffer);
+            return;
+         }
+         else if (mask) {
+            /* XXX note: we're putting the uint clear values into the
+             * floating point state var.  This will not always work.  We'll
+             * need a new ctx->Driver.ClearBuffer() hook....
+             */
+            GLfloat clearSave[4];
+            /* save color */
+            COPY_4V(clearSave, ctx->Color.ClearColor);
+            /* set color */
+            COPY_4V(ctx->Color.ClearColor, value);
+            if (ctx->Driver.ClearColor)
+               ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor);
+            /* clear buffer(s) */
+            ctx->Driver.Clear(ctx, mask);
+            /* restore color */
+            COPY_4V(ctx->Color.ClearColor, clearSave);
+            if (ctx->Driver.ClearColor)
+               ctx->Driver.ClearColor(ctx, clearSave);
+         }
+      }
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)",
+                  _mesa_lookup_enum_by_nr(buffer));
+      return;
+   }
+}
+
+
+/**
+ * New in GL 3.0
+ * Clear fixed-pt or float color buffer or depth buffer (not stencil).
+ */
+void GLAPIENTRY
+_mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   FLUSH_CURRENT(ctx, 0);
+
+   if (!ctx->DrawBuffer->Visual.rgbMode) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glClearBufferfv()");
+      return;
+   }
+
+   if (ctx->NewState) {
+      _mesa_update_state( ctx );
+   }
+
+   switch (buffer) {
+   case GL_DEPTH:
+      if (drawbuffer != 0) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
+                     drawbuffer);
+         return;
+      }
+      else {
+         /* Save current depth clear value, set to 'value', do the
+          * depth clear and restore the clear value.
+          * XXX in the future we may have a new ctx->Driver.ClearBuffer()
+          * hook instead.
+          */
+         const GLfloat clearSave = ctx->Depth.Clear;
+         ctx->Depth.Clear = *value;
+         if (ctx->Driver.ClearDepth)
+            ctx->Driver.ClearDepth(ctx, *value);
+         ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH);
+         ctx->Depth.Clear = clearSave;
+         if (ctx->Driver.ClearDepth)
+            ctx->Driver.ClearDepth(ctx, clearSave);
+      }
+      /* clear depth buffer to value */
+      break;
+   case GL_COLOR:
+      {
+         const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer);
+         if (mask == INVALID_MASK) {
+            _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)",
+                        drawbuffer);
+            return;
+         }
+         else if (mask) {
+            GLfloat clearSave[4];
+            /* save color */
+            COPY_4V(clearSave, ctx->Color.ClearColor);
+            /* set color */
+            COPY_4V(ctx->Color.ClearColor, value);
+            if (ctx->Driver.ClearColor)
+               ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor);
+            /* clear buffer(s) */
+            ctx->Driver.Clear(ctx, mask);
+            /* restore color */
+            COPY_4V(ctx->Color.ClearColor, clearSave);
+            if (ctx->Driver.ClearColor)
+               ctx->Driver.ClearColor(ctx, clearSave);
+         }
+      }
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)",
+                  _mesa_lookup_enum_by_nr(buffer));
+      return;
+   }
+}
+
+
+/**
+ * New in GL 3.0
+ * Clear depth/stencil buffer only.
+ */
+void GLAPIENTRY
+_mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
+                    GLfloat depth, GLint stencil)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   FLUSH_CURRENT(ctx, 0);
+
+   if (!ctx->DrawBuffer->Visual.rgbMode) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glClearBufferfi()");
+      return;
+   }
+
+   if (buffer != GL_DEPTH_STENCIL) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)",
+                  _mesa_lookup_enum_by_nr(buffer));
+      return;
+   }
+
+   if (drawbuffer != 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfi(drawbuffer=%d)",
+                  drawbuffer);
+      return;
+   }
+
+   if (ctx->NewState) {
+      _mesa_update_state( ctx );
+   }
+
+   {
+      /* save current clear values */
+      const GLfloat clearDepthSave = ctx->Depth.Clear;
+      const GLuint clearStencilSave = ctx->Stencil.Clear;
+
+      /* set new clear values */
+      ctx->Depth.Clear = depth;
+      ctx->Stencil.Clear = stencil;
+      if (ctx->Driver.ClearDepth)
+         ctx->Driver.ClearDepth(ctx, depth);
+      if (ctx->Driver.ClearStencil)
+         ctx->Driver.ClearStencil(ctx, stencil);
+
+      /* clear buffers */
+      ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
+
+      /* restore */
+      ctx->Depth.Clear = clearDepthSave;
+      ctx->Stencil.Clear = clearStencilSave;
+      if (ctx->Driver.ClearDepth)
+         ctx->Driver.ClearDepth(ctx, clearDepthSave);
+      if (ctx->Driver.ClearStencil)
+         ctx->Driver.ClearStencil(ctx, clearStencilSave);
+   }
+}
diff --git a/src/mesa/main/clear.h b/src/mesa/main/clear.h
index 9a54ba1..4c78eed 100644
--- a/src/mesa/main/clear.h
+++ b/src/mesa/main/clear.h
@@ -41,4 +41,17 @@
 _mesa_Clear( GLbitfield mask );
 
 
+extern void GLAPIENTRY
+_mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value);
+
+extern void GLAPIENTRY
+_mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value);
+
+extern void GLAPIENTRY
+_mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
+                    GLfloat depth, GLint stencil);
+
 #endif
diff --git a/src/mesa/main/colormac.h b/src/mesa/main/colormac.h
index 7ae781a..905f4e2 100644
--- a/src/mesa/main/colormac.h
+++ b/src/mesa/main/colormac.h
@@ -210,6 +210,12 @@
 #define PACK_COLOR_88_REV( L, A )					\
    (((A) << 8) | (L))
 
+#define PACK_COLOR_1616( L, A )						\
+   (((L) << 16) | (A))
+
+#define PACK_COLOR_1616_REV( L, A )					\
+   (((A) << 16) | (L))
+
 #define PACK_COLOR_332( R, G, B )					\
    (((R) & 0xe0) | (((G) & 0xe0) >> 3) | (((B) & 0xc0) >> 6))
 
diff --git a/src/mesa/main/compiler.h b/src/mesa/main/compiler.h
index 380663e..4eb249b 100644
--- a/src/mesa/main/compiler.h
+++ b/src/mesa/main/compiler.h
@@ -234,7 +234,12 @@
 #elif defined(__APPLE__)
 #include <CoreFoundation/CFByteOrder.h>
 #define CPU_TO_LE32( x )	CFSwapInt32HostToLittle( x )
-#else /*__linux__ __APPLE__*/
+#elif (defined(_AIX) || defined(__blrts))
+#define CPU_TO_LE32( x )        x = ((x & 0x000000ff) << 24) | \
+                                    ((x & 0x0000ff00) <<  8) | \
+                                    ((x & 0x00ff0000) >>  8) | \
+                                    ((x & 0xff000000) >> 24);
+#else /*__linux__ */
 #include <sys/endian.h>
 #define CPU_TO_LE32( x )	bswap32( x )
 #endif /*__linux__*/
diff --git a/src/mesa/main/condrender.c b/src/mesa/main/condrender.c
new file mode 100644
index 0000000..8d9a91d
--- /dev/null
+++ b/src/mesa/main/condrender.c
@@ -0,0 +1,147 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.8
+ *
+ * Copyright (C) 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, sublicense,
+ * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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 condrender.c
+ * Conditional rendering functions
+ *
+ * \author Brian Paul
+ */
+
+#include "glheader.h"
+#include "condrender.h"
+#include "enums.h"
+#include "queryobj.h"
+
+
+void GLAPIENTRY
+_mesa_BeginConditionalRender(GLuint queryId, GLenum mode)
+{
+   struct gl_query_object *q;
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (!ctx->Extensions.NV_conditional_render || ctx->Query.CondRenderQuery) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginConditionalRender()");
+      return;
+   }
+
+   ASSERT(ctx->Query.CondRenderMode == GL_NONE);
+
+   switch (mode) {
+   case GL_QUERY_WAIT:
+   case GL_QUERY_NO_WAIT:
+   case GL_QUERY_BY_REGION_WAIT:
+   case GL_QUERY_BY_REGION_NO_WAIT:
+      /* OK */
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "glBeginConditionalRender(mode=%s)",
+                  _mesa_lookup_enum_by_nr(mode));
+      return;
+   }
+
+   q = _mesa_lookup_query_object(ctx, queryId);
+   if (!q) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glBeginConditionalRender(bad queryId=%u)", queryId);
+      return;
+   }
+   ASSERT(q->Id == queryId);
+
+   if (q->Target != GL_SAMPLES_PASSED) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginConditionalRender()");
+      return;
+   }
+
+   ctx->Query.CondRenderQuery = q;
+   ctx->Query.CondRenderMode = mode;
+
+   if (ctx->Driver.BeginConditionalRender)
+      ctx->Driver.BeginConditionalRender(ctx, q, mode);
+}
+
+
+void APIENTRY
+_mesa_EndConditionalRender(void)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   FLUSH_VERTICES(ctx, 0x0);
+
+   if (!ctx->Extensions.NV_conditional_render || !ctx->Query.CondRenderQuery) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glEndConditionalRender()");
+      return;
+   }
+
+   if (ctx->Driver.EndConditionalRender)
+      ctx->Driver.EndConditionalRender(ctx, ctx->Query.CondRenderQuery);
+
+   ctx->Query.CondRenderQuery = NULL;
+   ctx->Query.CondRenderMode = GL_NONE;
+}
+
+
+/**
+ * This function is called by software rendering commands (all point,
+ * line triangle drawing, glClear, glDrawPixels, glCopyPixels, and
+ * glBitmap, glBlitFramebuffer) to determine if subsequent drawing
+ * commands should be
+ * executed or discarded depending on the current conditional
+ * rendering state.  Ideally, this check would be implemented by the
+ * GPU when doing hardware rendering.  XXX should this function be
+ * called via a new driver hook?
+ *
+ * \return GL_TRUE if we should render, GL_FALSE if we should discard
+ */
+GLboolean
+_mesa_check_conditional_render(GLcontext *ctx)
+{
+   struct gl_query_object *q = ctx->Query.CondRenderQuery;
+
+   if (!q) {
+      /* no query in progress - draw normally */
+      return GL_TRUE;
+   }
+
+   switch (ctx->Query.CondRenderMode) {
+   case GL_QUERY_BY_REGION_WAIT:
+      /* fall-through */
+   case GL_QUERY_WAIT:
+      if (!q->Ready) {
+         ctx->Driver.WaitQuery(ctx, q);
+      }
+      return q->Result > 0;
+   case GL_QUERY_BY_REGION_NO_WAIT:
+      /* fall-through */
+   case GL_QUERY_NO_WAIT:
+      return q->Ready ? (q->Result > 0) : GL_TRUE;
+   default:
+      _mesa_problem(ctx, "Bad cond render mode %s in "
+                    " _mesa_check_conditional_render()",
+                    _mesa_lookup_enum_by_nr(ctx->Query.CondRenderMode));
+      return GL_TRUE;
+   }
+}
diff --git a/src/mesa/main/condrender.h b/src/mesa/main/condrender.h
new file mode 100644
index 0000000..d55e980
--- /dev/null
+++ b/src/mesa/main/condrender.h
@@ -0,0 +1,45 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.8
+ *
+ * Copyright (C) 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, sublicense,
+ * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#ifndef CONDRENDER_H
+#define CONDRENDER_H
+
+
+#include "glheader.h"
+#include "context.h"
+
+
+extern void GLAPIENTRY
+_mesa_BeginConditionalRender(GLuint queryId, GLenum mode);
+
+extern void APIENTRY
+_mesa_EndConditionalRender(void);
+
+extern GLboolean
+_mesa_check_conditional_render(GLcontext *ctx);
+
+
+#endif /* CONDRENDER_H */
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index 8a09efd..2eac1cc 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -205,7 +205,7 @@
 #define MAX_VARYING                    16    /**< number of float[4] vectors */
 #define MAX_SAMPLERS                   MAX_TEXTURE_IMAGE_UNITS
 #define MAX_PROGRAM_INPUTS             32
-#define MAX_PROGRAM_OUTPUTS            32
+#define MAX_PROGRAM_OUTPUTS            64
 /*@}*/
 
 /** For GL_ARB_vertex_program */
@@ -243,7 +243,8 @@
 /*@{*/
 #define MAX_VERTEX_GENERIC_ATTRIBS 16
 #define MAX_VERTEX_TEXTURE_IMAGE_UNITS MAX_TEXTURE_IMAGE_UNITS
-#define MAX_COMBINED_TEXTURE_IMAGE_UNITS MAX_TEXTURE_IMAGE_UNITS
+#define MAX_COMBINED_TEXTURE_IMAGE_UNITS (MAX_VERTEX_TEXTURE_IMAGE_UNITS + \
+					  MAX_TEXTURE_IMAGE_UNITS)
 /*@}*/
 
 
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 101d3c6..320c590 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -564,10 +564,6 @@
    /* GL_ARB_draw_buffers */
    ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS;
 
-   /* GL_OES_read_format */
-   ctx->Const.ColorReadFormat = GL_RGBA;
-   ctx->Const.ColorReadType = GL_UNSIGNED_BYTE;
-
 #if FEATURE_EXT_framebuffer_object
    ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
    ctx->Const.MaxRenderbufferSize = MAX_WIDTH;
@@ -575,6 +571,7 @@
 
 #if FEATURE_ARB_vertex_shader
    ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
+   ctx->Const.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
    ctx->Const.MaxVarying = MAX_VARYING;
 #endif
 
@@ -601,9 +598,11 @@
    ASSERT(MAX_NV_VERTEX_PROGRAM_INPUTS <= VERT_ATTRIB_MAX);
    ASSERT(MAX_NV_VERTEX_PROGRAM_OUTPUTS <= VERT_RESULT_MAX);
 
-   /* check that we don't exceed various 32-bit bitfields */
-   ASSERT(VERT_RESULT_MAX <= 32);
-   ASSERT(FRAG_ATTRIB_MAX <= 32);
+   /* check that we don't exceed the size of various bitfields */
+   ASSERT(VERT_RESULT_MAX <=
+	  (8 * sizeof(ctx->VertexProgram._Current->Base.OutputsWritten)));
+   ASSERT(FRAG_ATTRIB_MAX <=
+	  (8 * sizeof(ctx->FragmentProgram._Current->Base.InputsRead)));
 }
 
 
@@ -1016,6 +1015,9 @@
    if (ctx->Extensions.String)
       _mesa_free((void *) ctx->Extensions.String);
 
+   if (ctx->VersionString)
+      _mesa_free(ctx->VersionString);
+
    /* unbind the context if it's currently bound */
    if (ctx == _mesa_get_current_context()) {
       _mesa_make_current(NULL, NULL, NULL);
@@ -1375,6 +1377,8 @@
       }
 
       if (newCtx->FirstTimeCurrent) {
+         _mesa_compute_version(newCtx);
+
          check_context_limits(newCtx);
 
          /* We can use this to help debug user's problems.  Tell them to set
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 0488a69..6705c90 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -182,7 +182,7 @@
     * 
     * This is called by the \c _mesa_store_tex[sub]image[123]d() fallback
     * functions.  The driver should examine \p internalFormat and return a
-    * pointer to an appropriate gl_texture_format.
+    * gl_format value.
     */
    GLuint (*ChooseTextureFormat)( GLcontext *ctx, GLint internalFormat,
                                      GLenum srcFormat, GLenum srcType );
@@ -538,11 +538,6 @@
                                    struct gl_texture_object *t );
 
    /**
-    * Called by glActiveTextureARB() to set current texture unit.
-    */
-   void (*ActiveTexture)( GLcontext *ctx, GLuint texUnitNumber );
-
-   /**
     * Called when the texture's color lookup table is changed.
     * 
     * If \p tObj is NULL then the shared texture palette
@@ -630,6 +625,8 @@
    /** Enable and disable writing of frame buffer color components */
    void (*ColorMask)(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
                      GLboolean bmask, GLboolean amask );
+   void (*ColorMaskIndexed)(GLcontext *ctx, GLuint buf, GLboolean rmask,
+                            GLboolean gmask, GLboolean bmask, GLboolean amask);
    /** Cause a material color to track the current color */
    void (*ColorMaterial)(GLcontext *ctx, GLenum face, GLenum mode);
    /** Specify whether front- or back-facing facets can be culled */
@@ -709,34 +706,6 @@
    /*@}*/
 
 
-   /**
-    * \name Vertex array functions
-    *
-    * Called by the corresponding OpenGL functions.
-    */
-   /*@{*/
-   void (*VertexPointer)(GLcontext *ctx, GLint size, GLenum type,
-			 GLsizei stride, const GLvoid *ptr);
-   void (*NormalPointer)(GLcontext *ctx, GLenum type,
-			 GLsizei stride, const GLvoid *ptr);
-   void (*ColorPointer)(GLcontext *ctx, GLint size, GLenum type,
-			GLsizei stride, const GLvoid *ptr);
-   void (*FogCoordPointer)(GLcontext *ctx, GLenum type,
-			   GLsizei stride, const GLvoid *ptr);
-   void (*IndexPointer)(GLcontext *ctx, GLenum type,
-			GLsizei stride, const GLvoid *ptr);
-   void (*SecondaryColorPointer)(GLcontext *ctx, GLint size, GLenum type,
-				 GLsizei stride, const GLvoid *ptr);
-   void (*TexCoordPointer)(GLcontext *ctx, GLint size, GLenum type,
-			   GLsizei stride, const GLvoid *ptr);
-   void (*EdgeFlagPointer)(GLcontext *ctx, GLsizei stride, const GLvoid *ptr);
-   void (*VertexAttribPointer)(GLcontext *ctx, GLuint index, GLint size,
-                               GLenum type, GLsizei stride, const GLvoid *ptr);
-   void (*LockArraysEXT)( GLcontext *ctx, GLint first, GLsizei count );
-   void (*UnlockArraysEXT)( GLcontext *ctx );
-   /*@}*/
-
-
    /** 
     * \name State-query functions
     *
@@ -794,13 +763,13 @@
 
    /* May return NULL if MESA_MAP_NOWAIT_BIT is set in access:
     */
-   void * (*MapBufferRange)( GLcontext *ctx, GLenum target,
-                             GLintptr offset, GLsizeiptr length, GLbitfield access,
+   void * (*MapBufferRange)( GLcontext *ctx, GLenum target, GLintptr offset,
+                             GLsizeiptr length, GLbitfield access,
                              struct gl_buffer_object *obj);
 
-   void (*FlushMappedBufferRange) (GLcontext *ctx, GLenum target, 
-                                   GLintptr offset, GLsizeiptr length,
-                                   struct gl_buffer_object *obj);
+   void (*FlushMappedBufferRange)(GLcontext *ctx, GLenum target, 
+                                  GLintptr offset, GLsizeiptr length,
+                                  struct gl_buffer_object *obj);
 
    GLboolean (*UnmapBuffer)( GLcontext *ctx, GLenum target,
 			     struct gl_buffer_object *obj );
@@ -815,7 +784,8 @@
    struct gl_framebuffer * (*NewFramebuffer)(GLcontext *ctx, GLuint name);
    struct gl_renderbuffer * (*NewRenderbuffer)(GLcontext *ctx, GLuint name);
    void (*BindFramebuffer)(GLcontext *ctx, GLenum target,
-                           struct gl_framebuffer *fb, struct gl_framebuffer *fbread);
+                           struct gl_framebuffer *drawFb,
+                           struct gl_framebuffer *readFb);
    void (*FramebufferRenderbuffer)(GLcontext *ctx, 
                                    struct gl_framebuffer *fb,
                                    GLenum attachment,
@@ -1047,6 +1017,11 @@
    /*@}*/
 #endif
 
+   /** GL_NV_conditional_render */
+   void (*BeginConditionalRender)(GLcontext *ctx, struct gl_query_object *q,
+                                  GLenum mode);
+   void (*EndConditionalRender)(GLcontext *ctx, struct gl_query_object *q);
+
 #if FEATURE_OES_draw_texture
    /**
     * \name GL_OES_draw_texture interface
diff --git a/src/mesa/main/dispatch.c b/src/mesa/main/dispatch.c
index cd54105..a6a5702 100644
--- a/src/mesa/main/dispatch.c
+++ b/src/mesa/main/dispatch.c
@@ -37,8 +37,6 @@
  * \author Brian Paul <brian@precisioninsight.com>
  */
 
-#ifndef GLX_USE_APPLEGL
-
 #include "main/glheader.h"
 #include "main/compiler.h"
 #include "glapi/glapi.h"
@@ -96,5 +94,3 @@
 #include "glapi/glapitemp.h"
 
 #endif /* USE_X86_ASM */
-
-#endif /* !GLX_USE_APPLEGL */
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index b692c33..21a8216 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -218,8 +218,13 @@
    OPCODE_CLEAR_DEPTH,
    OPCODE_CLEAR_INDEX,
    OPCODE_CLEAR_STENCIL,
+   OPCODE_CLEAR_BUFFER_IV,
+   OPCODE_CLEAR_BUFFER_UIV,
+   OPCODE_CLEAR_BUFFER_FV,
+   OPCODE_CLEAR_BUFFER_FI,
    OPCODE_CLIP_PLANE,
    OPCODE_COLOR_MASK,
+   OPCODE_COLOR_MASK_INDEXED,
    OPCODE_COLOR_MATERIAL,
    OPCODE_COLOR_TABLE,
    OPCODE_COLOR_TABLE_PARAMETER_FV,
@@ -244,9 +249,11 @@
    OPCODE_DEPTH_MASK,
    OPCODE_DEPTH_RANGE,
    OPCODE_DISABLE,
+   OPCODE_DISABLE_INDEXED,
    OPCODE_DRAW_BUFFER,
    OPCODE_DRAW_PIXELS,
    OPCODE_ENABLE,
+   OPCODE_ENABLE_INDEXED,
    OPCODE_EVALMESH1,
    OPCODE_EVALMESH2,
    OPCODE_FOG,
@@ -1231,6 +1238,110 @@
 
 
 static void GLAPIENTRY
+save_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_IV, 6);
+   if (n) {
+      n[1].e = buffer;
+      n[2].i = drawbuffer;
+      n[3].i = value[0];
+      if (buffer == GL_COLOR) {
+         n[4].i = value[1];
+         n[5].i = value[2];
+         n[6].i = value[3];
+      }
+      else {
+         n[4].i = 0;
+         n[5].i = 0;
+         n[6].i = 0;
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      /*CALL_ClearBufferiv(ctx->Exec, (buffer, drawbuffer, value));*/
+   }
+}
+
+
+static void GLAPIENTRY
+save_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_UIV, 6);
+   if (n) {
+      n[1].e = buffer;
+      n[2].i = drawbuffer;
+      n[3].ui = value[0];
+      if (buffer == GL_COLOR) {
+         n[4].ui = value[1];
+         n[5].ui = value[2];
+         n[6].ui = value[3];
+      }
+      else {
+         n[4].ui = 0;
+         n[5].ui = 0;
+         n[6].ui = 0;
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      /*CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));*/
+   }
+}
+
+
+static void GLAPIENTRY
+save_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_FV, 6);
+   if (n) {
+      n[1].e = buffer;
+      n[2].i = drawbuffer;
+      n[3].f = value[0];
+      if (buffer == GL_COLOR) {
+         n[4].f = value[1];
+         n[5].f = value[2];
+         n[6].f = value[3];
+      }
+      else {
+         n[4].f = 0.0F;
+         n[5].f = 0.0F;
+         n[6].f = 0.0F;
+      }
+   }
+   if (ctx->ExecuteFlag) {
+      /*CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));*/
+   }
+}
+
+
+static void GLAPIENTRY
+save_ClearBufferfi(GLenum buffer, GLint drawbuffer,
+                   GLfloat depth, GLint stencil)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_CLEAR_BUFFER_FI, 4);
+   if (n) {
+      n[1].e = buffer;
+      n[2].i = drawbuffer;
+      n[3].f = depth;
+      n[4].i = stencil;
+   }
+   if (ctx->ExecuteFlag) {
+      /*CALL_ClearBufferfi(ctx->Exec, (buffer, drawbuffer, depth, stencil));*/
+   }
+}
+
+
+static void GLAPIENTRY
 save_ClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -1358,6 +1469,27 @@
 
 
 static void GLAPIENTRY
+save_ColorMaskIndexed(GLuint buf, GLboolean red, GLboolean green,
+                      GLboolean blue, GLboolean alpha)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_COLOR_MASK_INDEXED, 5);
+   if (n) {
+      n[1].ui = buf;
+      n[2].b = red;
+      n[3].b = green;
+      n[4].b = blue;
+      n[5].b = alpha;
+   }
+   if (ctx->ExecuteFlag) {
+      /*CALL_ColorMaskIndexedEXT(ctx->Exec, (buf, red, green, blue, alpha));*/
+   }
+}
+
+
+static void GLAPIENTRY
 save_ColorMaterial(GLenum face, GLenum mode)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -1916,6 +2048,23 @@
 
 
 static void GLAPIENTRY
+save_DisableIndexed(GLuint index, GLenum cap)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_DISABLE_INDEXED, 2);
+   if (n) {
+      n[1].ui = index;
+      n[2].e = cap;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_DisableIndexedEXT(ctx->Exec, (index, cap));
+   }
+}
+
+
+static void GLAPIENTRY
 save_DrawBuffer(GLenum mode)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -1974,6 +2123,24 @@
 
 
 static void GLAPIENTRY
+save_EnableIndexed(GLuint index, GLenum cap)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_ENABLE_INDEXED, 2);
+   if (n) {
+      n[1].ui = index;
+      n[2].e = cap;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_EnableIndexedEXT(ctx->Exec, (index, cap));
+   }
+}
+
+
+
+static void GLAPIENTRY
 save_EvalMesh1(GLenum mode, GLint i1, GLint i2)
 {
    GET_CURRENT_CONTEXT(ctx);
@@ -6596,6 +6763,39 @@
          case OPCODE_CLEAR:
             CALL_Clear(ctx->Exec, (n[1].bf));
             break;
+         case OPCODE_CLEAR_BUFFER_IV:
+            {
+               GLint value[4];
+               value[0] = n[3].i;
+               value[1] = n[4].i;
+               value[2] = n[5].i;
+               value[3] = n[6].i;
+               /*CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));*/
+            }
+            break;
+         case OPCODE_CLEAR_BUFFER_UIV:
+            {
+               GLuint value[4];
+               value[0] = n[3].ui;
+               value[1] = n[4].ui;
+               value[2] = n[5].ui;
+               value[3] = n[6].ui;
+               /*CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));*/
+            }
+            break;
+         case OPCODE_CLEAR_BUFFER_FV:
+            {
+               GLfloat value[4];
+               value[0] = n[3].f;
+               value[1] = n[4].f;
+               value[2] = n[5].f;
+               value[3] = n[6].f;
+               /*CALL_ClearBufferfv(ctx->Exec, (n[1].e, n[2].i, value));*/
+            }
+            break;
+         case OPCODE_CLEAR_BUFFER_FI:
+            /*CALL_ClearBufferfi(ctx->Exec, (n[1].e, n[2].i, n[3].f, n[4].i));*/
+            break;
          case OPCODE_CLEAR_COLOR:
             CALL_ClearColor(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
             break;
@@ -6624,6 +6824,10 @@
          case OPCODE_COLOR_MASK:
             CALL_ColorMask(ctx->Exec, (n[1].b, n[2].b, n[3].b, n[4].b));
             break;
+         case OPCODE_COLOR_MASK_INDEXED:
+            CALL_ColorMaskIndexedEXT(ctx->Exec, (n[1].ui, n[2].b, n[3].b,
+                                                 n[4].b, n[5].b));
+            break;
          case OPCODE_COLOR_MATERIAL:
             CALL_ColorMaterial(ctx->Exec, (n[1].e, n[2].e));
             break;
@@ -6766,6 +6970,9 @@
          case OPCODE_DISABLE:
             CALL_Disable(ctx->Exec, (n[1].e));
             break;
+         case OPCODE_DISABLE_INDEXED:
+            CALL_DisableIndexedEXT(ctx->Exec, (n[1].ui, n[2].e));
+            break;
          case OPCODE_DRAW_BUFFER:
             CALL_DrawBuffer(ctx->Exec, (n[1].e));
             break;
@@ -6781,6 +6988,9 @@
          case OPCODE_ENABLE:
             CALL_Enable(ctx->Exec, (n[1].e));
             break;
+         case OPCODE_ENABLE_INDEXED:
+            CALL_EnableIndexedEXT(ctx->Exec, (n[1].ui, n[2].e));
+            break;
          case OPCODE_EVALMESH1:
             CALL_EvalMesh1(ctx->Exec, (n[1].e, n[2].i, n[3].i));
             break;
@@ -8540,6 +8750,7 @@
    SET_ClearStencil(table, save_ClearStencil);
    SET_ClipPlane(table, save_ClipPlane);
    SET_ColorMask(table, save_ColorMask);
+   SET_ColorMaskIndexedEXT(table, save_ColorMaskIndexed);
    SET_ColorMaterial(table, save_ColorMaterial);
    SET_CopyPixels(table, save_CopyPixels);
    SET_CullFace(table, save_CullFace);
@@ -8548,9 +8759,11 @@
    SET_DepthMask(table, save_DepthMask);
    SET_DepthRange(table, save_DepthRange);
    SET_Disable(table, save_Disable);
+   SET_DisableIndexedEXT(table, save_DisableIndexed);
    SET_DrawBuffer(table, save_DrawBuffer);
    SET_DrawPixels(table, save_DrawPixels);
    SET_Enable(table, save_Enable);
+   SET_EnableIndexedEXT(table, save_EnableIndexed);
    SET_EndList(table, _mesa_EndList);
    SET_EvalMesh1(table, save_EvalMesh1);
    SET_EvalMesh2(table, save_EvalMesh2);
@@ -9094,6 +9307,19 @@
 
    /* 364. GL_EXT_provoking_vertex */
    SET_ProvokingVertexEXT(table, save_ProvokingVertexEXT);
+
+   /* GL 3.0 */
+#if 0
+   SET_ClearBufferiv(table, save_ClearBufferiv);
+   SET_ClearBufferuiv(table, save_ClearBufferuiv);
+   SET_ClearBufferfv(table, save_ClearBufferfv);
+   SET_ClearBufferfi(table, save_ClearBufferfi);
+#else
+   (void) save_ClearBufferiv;
+   (void) save_ClearBufferuiv;
+   (void) save_ClearBufferfv;
+   (void) save_ClearBufferfi;
+#endif
 }
 
 
diff --git a/src/mesa/main/dlopen.c b/src/mesa/main/dlopen.c
index 414cfad..81e0320 100644
--- a/src/mesa/main/dlopen.c
+++ b/src/mesa/main/dlopen.c
@@ -31,7 +31,7 @@
 #include "compiler.h"
 #include "dlopen.h"
 
-#if defined(_GNU_SOURCE) && !defined(__MINGW32__)
+#if defined(_GNU_SOURCE) && !defined(__MINGW32__) && !defined(__blrts)
 #include <dlfcn.h>
 #endif
 #if defined(_WIN32)
@@ -46,7 +46,9 @@
 void *
 _mesa_dlopen(const char *libname, int flags)
 {
-#if defined(_GNU_SOURCE)
+#if defined(__blrts)
+   return NULL;
+#elif defined(_GNU_SOURCE)
    flags = RTLD_LAZY | RTLD_GLOBAL; /* Overriding flags at this time */
    return dlopen(libname, flags);
 #elif defined(__MINGW32__)
@@ -65,7 +67,9 @@
 GenericFunc
 _mesa_dlsym(void *handle, const char *fname)
 {
-#if defined(__DJGPP__)
+#if defined(__blrts)
+   return (GenericFunc) NULL;
+#elif defined(__DJGPP__)
    /* need '_' prefix on symbol names */
    char fname2[1000];
    fname2[0] = '_';
@@ -88,7 +92,9 @@
 void
 _mesa_dlclose(void *handle)
 {
-#if defined(_GNU_SOURCE)
+#if defined(__blrts)
+   (void) handle;
+#elif defined(_GNU_SOURCE)
    dlclose(handle);
 #elif defined(__MINGW32__)
    FreeLibrary(handle);
diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c
index 12ce14c..cd6e881 100644
--- a/src/mesa/main/enable.c
+++ b/src/mesa/main/enable.c
@@ -278,10 +278,13 @@
          ctx->Eval.AutoNormal = state;
          break;
       case GL_BLEND:
-         if (ctx->Color.BlendEnabled == state)
-            return;
-         FLUSH_VERTICES(ctx, _NEW_COLOR);
-         ctx->Color.BlendEnabled = state;
+         {
+            GLbitfield newEnabled = state * ((1 << ctx->Const.MaxDrawBuffers) - 1);
+            if (newEnabled != ctx->Color.BlendEnabled) {
+               FLUSH_VERTICES(ctx, _NEW_COLOR);
+               ctx->Color.BlendEnabled = newEnabled;
+            }
+         }
          break;
 #if FEATURE_userclip
       case GL_CLIP_PLANE0:
@@ -1020,6 +1023,84 @@
 }
 
 
+
+/**
+ * Enable/disable an indexed state var.
+ */
+void
+_mesa_set_enablei(GLcontext *ctx, GLenum cap, GLuint index, GLboolean state)
+{
+   ASSERT(state == 0 || state == 1);
+   switch (cap) {
+   case GL_BLEND:
+      if (!ctx->Extensions.EXT_draw_buffers2) {
+         goto bad_cap_error;
+      }
+      if (index >= ctx->Const.MaxDrawBuffers) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)",
+                     state ? "glEnableIndexed" : "glDisableIndexed", index);
+         return;
+      }
+      if (((ctx->Color.BlendEnabled >> index) & 1) != state) {
+         FLUSH_VERTICES(ctx, _NEW_COLOR);
+         if (state)
+            ctx->Color.BlendEnabled |= (1 << index);
+         else
+            ctx->Color.BlendEnabled &= ~(1 << index);
+      }
+      break;
+   default:
+      goto bad_cap_error;
+   }
+   return;
+
+bad_cap_error:
+    _mesa_error(ctx, GL_INVALID_ENUM, "%s(cap=%s)",
+                state ? "glEnablei" : "glDisablei",
+                _mesa_lookup_enum_by_nr(cap));
+}
+
+
+void GLAPIENTRY
+_mesa_DisableIndexed( GLenum cap, GLuint index )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+   _mesa_set_enablei(ctx, cap, index, GL_FALSE);
+}
+
+
+void GLAPIENTRY
+_mesa_EnableIndexed( GLenum cap, GLuint index )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+   _mesa_set_enablei(ctx, cap, index, GL_TRUE);
+}
+
+
+GLboolean GLAPIENTRY
+_mesa_IsEnabledIndexed( GLenum cap, GLuint index )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   switch (cap) {
+   case GL_BLEND:
+      if (index >= ctx->Const.MaxDrawBuffers) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glIsEnabledIndexed(index=%u)",
+                     index);
+         return GL_FALSE;
+      }
+      return (ctx->Color.BlendEnabled >> index) & 1;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabledIndexed(cap=%s)",
+                  _mesa_lookup_enum_by_nr(cap));
+      return GL_FALSE;
+   }
+}
+
+
+
+
 #undef CHECK_EXTENSION
 #define CHECK_EXTENSION(EXTNAME)			\
    if (!ctx->Extensions.EXTNAME) {			\
@@ -1066,7 +1147,7 @@
       case GL_AUTO_NORMAL:
 	 return ctx->Eval.AutoNormal;
       case GL_BLEND:
-         return ctx->Color.BlendEnabled;
+         return ctx->Color.BlendEnabled & 1;  /* return state for buffer[0] */
       case GL_CLIP_PLANE0:
       case GL_CLIP_PLANE1:
       case GL_CLIP_PLANE2:
diff --git a/src/mesa/main/enable.h b/src/mesa/main/enable.h
index 25c90b0..24e3181 100644
--- a/src/mesa/main/enable.h
+++ b/src/mesa/main/enable.h
@@ -47,6 +47,18 @@
 extern GLboolean GLAPIENTRY
 _mesa_IsEnabled( GLenum cap );
 
+extern void
+_mesa_set_enablei(GLcontext *ctx, GLenum cap, GLuint index, GLboolean state);
+
+extern void GLAPIENTRY
+_mesa_DisableIndexed( GLenum cap, GLuint index );
+
+extern void GLAPIENTRY
+_mesa_EnableIndexed( GLenum cap, GLuint index );
+
+extern GLboolean GLAPIENTRY
+_mesa_IsEnabledIndexed( GLenum cap, GLuint index );
+
 extern void GLAPIENTRY
 _mesa_EnableClientState( GLenum cap );
 
diff --git a/src/mesa/main/enums.c b/src/mesa/main/enums.c
index dedb6af..aaf17aa 100644
--- a/src/mesa/main/enums.c
+++ b/src/mesa/main/enums.c
@@ -384,6 +384,7 @@
    "GL_DELETE_STATUS\0"
    "GL_DEPTH\0"
    "GL_DEPTH24_STENCIL8\0"
+   "GL_DEPTH24_STENCIL8_EXT\0"
    "GL_DEPTH_ATTACHMENT\0"
    "GL_DEPTH_ATTACHMENT_EXT\0"
    "GL_DEPTH_BIAS\0"
@@ -409,6 +410,7 @@
    "GL_DEPTH_SCALE\0"
    "GL_DEPTH_STENCIL\0"
    "GL_DEPTH_STENCIL_ATTACHMENT\0"
+   "GL_DEPTH_STENCIL_EXT\0"
    "GL_DEPTH_STENCIL_NV\0"
    "GL_DEPTH_STENCIL_TO_BGRA_NV\0"
    "GL_DEPTH_STENCIL_TO_RGBA_NV\0"
@@ -478,6 +480,7 @@
    "GL_DRAW_BUFFER9_ARB\0"
    "GL_DRAW_BUFFER9_ATI\0"
    "GL_DRAW_FRAMEBUFFER\0"
+   "GL_DRAW_FRAMEBUFFER_BINDING\0"
    "GL_DRAW_FRAMEBUFFER_BINDING_EXT\0"
    "GL_DRAW_FRAMEBUFFER_EXT\0"
    "GL_DRAW_PIXEL_TOKEN\0"
@@ -593,6 +596,7 @@
    "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT\0"
    "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL\0"
    "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT\0"
+   "GL_FRAMEBUFFER_BINDING\0"
    "GL_FRAMEBUFFER_BINDING_EXT\0"
    "GL_FRAMEBUFFER_COMPLETE\0"
    "GL_FRAMEBUFFER_COMPLETE_EXT\0"
@@ -601,12 +605,15 @@
    "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT\0"
    "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\0"
    "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\0"
+   "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER\0"
    "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\0"
    "GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT\0"
    "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\0"
    "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\0"
    "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\0"
    "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE\0"
+   "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT\0"
+   "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER\0"
    "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\0"
    "GL_FRAMEBUFFER_STATUS_ERROR_EXT\0"
    "GL_FRAMEBUFFER_UNDEFINED\0"
@@ -892,6 +899,7 @@
    "GL_MAX_CLIPMAP_DEPTH_SGIX\0"
    "GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX\0"
    "GL_MAX_CLIP_PLANES\0"
+   "GL_MAX_COLOR_ATTACHMENTS\0"
    "GL_MAX_COLOR_ATTACHMENTS_EXT\0"
    "GL_MAX_COLOR_MATRIX_STACK_DEPTH\0"
    "GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI\0"
@@ -947,8 +955,10 @@
    "GL_MAX_PROJECTION_STACK_DEPTH\0"
    "GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB\0"
    "GL_MAX_RECTANGLE_TEXTURE_SIZE_NV\0"
+   "GL_MAX_RENDERBUFFER_SIZE\0"
    "GL_MAX_RENDERBUFFER_SIZE_EXT\0"
    "GL_MAX_SAMPLES\0"
+   "GL_MAX_SAMPLES_EXT\0"
    "GL_MAX_SERVER_WAIT_TIMEOUT\0"
    "GL_MAX_SHININESS_NV\0"
    "GL_MAX_SPOT_EXPONENT_NV\0"
@@ -1316,17 +1326,22 @@
    "GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT\0"
    "GL_QUAD_MESH_SUN\0"
    "GL_QUAD_STRIP\0"
+   "GL_QUERY_BY_REGION_NO_WAIT_NV\0"
+   "GL_QUERY_BY_REGION_WAIT_NV\0"
    "GL_QUERY_COUNTER_BITS\0"
    "GL_QUERY_COUNTER_BITS_ARB\0"
+   "GL_QUERY_NO_WAIT_NV\0"
    "GL_QUERY_RESULT\0"
    "GL_QUERY_RESULT_ARB\0"
    "GL_QUERY_RESULT_AVAILABLE\0"
    "GL_QUERY_RESULT_AVAILABLE_ARB\0"
+   "GL_QUERY_WAIT_NV\0"
    "GL_R\0"
    "GL_R3_G3_B2\0"
    "GL_RASTER_POSITION_UNCLIPPED_IBM\0"
    "GL_READ_BUFFER\0"
    "GL_READ_FRAMEBUFFER\0"
+   "GL_READ_FRAMEBUFFER_BINDING\0"
    "GL_READ_FRAMEBUFFER_BINDING_EXT\0"
    "GL_READ_FRAMEBUFFER_EXT\0"
    "GL_READ_ONLY\0"
@@ -1345,6 +1360,7 @@
    "GL_RENDER\0"
    "GL_RENDERBUFFER\0"
    "GL_RENDERBUFFER_ALPHA_SIZE\0"
+   "GL_RENDERBUFFER_BINDING\0"
    "GL_RENDERBUFFER_BINDING_EXT\0"
    "GL_RENDERBUFFER_BLUE_SIZE\0"
    "GL_RENDERBUFFER_DEPTH_SIZE\0"
@@ -1356,6 +1372,7 @@
    "GL_RENDERBUFFER_INTERNAL_FORMAT_EXT\0"
    "GL_RENDERBUFFER_RED_SIZE\0"
    "GL_RENDERBUFFER_SAMPLES\0"
+   "GL_RENDERBUFFER_SAMPLES_EXT\0"
    "GL_RENDERBUFFER_STENCIL_SIZE\0"
    "GL_RENDERBUFFER_WIDTH\0"
    "GL_RENDERBUFFER_WIDTH_EXT\0"
@@ -1541,9 +1558,13 @@
    "GL_STENCIL_FAIL\0"
    "GL_STENCIL_FUNC\0"
    "GL_STENCIL_INDEX\0"
+   "GL_STENCIL_INDEX1\0"
+   "GL_STENCIL_INDEX16\0"
    "GL_STENCIL_INDEX16_EXT\0"
    "GL_STENCIL_INDEX1_EXT\0"
+   "GL_STENCIL_INDEX4\0"
    "GL_STENCIL_INDEX4_EXT\0"
+   "GL_STENCIL_INDEX8\0"
    "GL_STENCIL_INDEX8_EXT\0"
    "GL_STENCIL_INDEX_EXT\0"
    "GL_STENCIL_PASS_DEPTH_FAIL\0"
@@ -1761,6 +1782,7 @@
    "GL_TEXTURE_RESIDENT\0"
    "GL_TEXTURE_STACK_DEPTH\0"
    "GL_TEXTURE_STENCIL_SIZE\0"
+   "GL_TEXTURE_STENCIL_SIZE_EXT\0"
    "GL_TEXTURE_STORAGE_HINT_APPLE\0"
    "GL_TEXTURE_TOO_LARGE_EXT\0"
    "GL_TEXTURE_UNSIGNED_REMAP_MODE_NV\0"
@@ -1769,7 +1791,6 @@
    "GL_TEXTURE_WRAP_S\0"
    "GL_TEXTURE_WRAP_T\0"
    "GL_TIMEOUT_EXPIRED\0"
-   "GL_TIMEOUT_IGNORED\0"
    "GL_TIME_ELAPSED_EXT\0"
    "GL_TRACK_MATRIX_NV\0"
    "GL_TRACK_MATRIX_TRANSFORM_NV\0"
@@ -1804,6 +1825,7 @@
    "GL_UNSIGNED_INT\0"
    "GL_UNSIGNED_INT_10_10_10_2\0"
    "GL_UNSIGNED_INT_24_8\0"
+   "GL_UNSIGNED_INT_24_8_EXT\0"
    "GL_UNSIGNED_INT_24_8_NV\0"
    "GL_UNSIGNED_INT_2_10_10_10_REV\0"
    "GL_UNSIGNED_INT_8_8_8_8\0"
@@ -1900,7 +1922,7 @@
    "GL_ZOOM_Y\0"
    ;
 
-static const enum_elt all_enums[1862] =
+static const enum_elt all_enums[1884] =
 {
    {     0, 0x00000600 }, /* GL_2D */
    {     6, 0x00001407 }, /* GL_2_BYTES */
@@ -2250,1600 +2272,1622 @@
    {  7144, 0x00008B80 }, /* GL_DELETE_STATUS */
    {  7161, 0x00001801 }, /* GL_DEPTH */
    {  7170, 0x000088F0 }, /* GL_DEPTH24_STENCIL8 */
-   {  7190, 0x00008D00 }, /* GL_DEPTH_ATTACHMENT */
-   {  7210, 0x00008D00 }, /* GL_DEPTH_ATTACHMENT_EXT */
-   {  7234, 0x00000D1F }, /* GL_DEPTH_BIAS */
-   {  7248, 0x00000D56 }, /* GL_DEPTH_BITS */
-   {  7262, 0x00008891 }, /* GL_DEPTH_BOUNDS_EXT */
-   {  7282, 0x00008890 }, /* GL_DEPTH_BOUNDS_TEST_EXT */
-   {  7307, 0x00000100 }, /* GL_DEPTH_BUFFER_BIT */
-   {  7327, 0x0000864F }, /* GL_DEPTH_CLAMP */
-   {  7342, 0x0000864F }, /* GL_DEPTH_CLAMP_NV */
-   {  7360, 0x00000B73 }, /* GL_DEPTH_CLEAR_VALUE */
-   {  7381, 0x00001902 }, /* GL_DEPTH_COMPONENT */
-   {  7400, 0x000081A5 }, /* GL_DEPTH_COMPONENT16 */
-   {  7421, 0x000081A5 }, /* GL_DEPTH_COMPONENT16_ARB */
-   {  7446, 0x000081A5 }, /* GL_DEPTH_COMPONENT16_SGIX */
-   {  7472, 0x000081A6 }, /* GL_DEPTH_COMPONENT24 */
-   {  7493, 0x000081A6 }, /* GL_DEPTH_COMPONENT24_ARB */
-   {  7518, 0x000081A6 }, /* GL_DEPTH_COMPONENT24_SGIX */
-   {  7544, 0x000081A7 }, /* GL_DEPTH_COMPONENT32 */
-   {  7565, 0x000081A7 }, /* GL_DEPTH_COMPONENT32_ARB */
-   {  7590, 0x000081A7 }, /* GL_DEPTH_COMPONENT32_SGIX */
-   {  7616, 0x00000B74 }, /* GL_DEPTH_FUNC */
-   {  7630, 0x00000B70 }, /* GL_DEPTH_RANGE */
-   {  7645, 0x00000D1E }, /* GL_DEPTH_SCALE */
-   {  7660, 0x000084F9 }, /* GL_DEPTH_STENCIL */
-   {  7677, 0x0000821A }, /* GL_DEPTH_STENCIL_ATTACHMENT */
-   {  7705, 0x000084F9 }, /* GL_DEPTH_STENCIL_NV */
-   {  7725, 0x0000886F }, /* GL_DEPTH_STENCIL_TO_BGRA_NV */
-   {  7753, 0x0000886E }, /* GL_DEPTH_STENCIL_TO_RGBA_NV */
-   {  7781, 0x00000B71 }, /* GL_DEPTH_TEST */
-   {  7795, 0x0000884B }, /* GL_DEPTH_TEXTURE_MODE */
-   {  7817, 0x0000884B }, /* GL_DEPTH_TEXTURE_MODE_ARB */
-   {  7843, 0x00000B72 }, /* GL_DEPTH_WRITEMASK */
-   {  7862, 0x00001201 }, /* GL_DIFFUSE */
-   {  7873, 0x00000BD0 }, /* GL_DITHER */
-   {  7883, 0x00000A02 }, /* GL_DOMAIN */
-   {  7893, 0x00001100 }, /* GL_DONT_CARE */
-   {  7906, 0x000086AE }, /* GL_DOT3_RGB */
-   {  7918, 0x000086AF }, /* GL_DOT3_RGBA */
-   {  7931, 0x000086AF }, /* GL_DOT3_RGBA_ARB */
-   {  7948, 0x00008741 }, /* GL_DOT3_RGBA_EXT */
-   {  7965, 0x000086AE }, /* GL_DOT3_RGB_ARB */
-   {  7981, 0x00008740 }, /* GL_DOT3_RGB_EXT */
-   {  7997, 0x0000140A }, /* GL_DOUBLE */
-   {  8007, 0x00000C32 }, /* GL_DOUBLEBUFFER */
-   {  8023, 0x00000C01 }, /* GL_DRAW_BUFFER */
-   {  8038, 0x00008825 }, /* GL_DRAW_BUFFER0 */
-   {  8054, 0x00008825 }, /* GL_DRAW_BUFFER0_ARB */
-   {  8074, 0x00008825 }, /* GL_DRAW_BUFFER0_ATI */
-   {  8094, 0x00008826 }, /* GL_DRAW_BUFFER1 */
-   {  8110, 0x0000882F }, /* GL_DRAW_BUFFER10 */
-   {  8127, 0x0000882F }, /* GL_DRAW_BUFFER10_ARB */
-   {  8148, 0x0000882F }, /* GL_DRAW_BUFFER10_ATI */
-   {  8169, 0x00008830 }, /* GL_DRAW_BUFFER11 */
-   {  8186, 0x00008830 }, /* GL_DRAW_BUFFER11_ARB */
-   {  8207, 0x00008830 }, /* GL_DRAW_BUFFER11_ATI */
-   {  8228, 0x00008831 }, /* GL_DRAW_BUFFER12 */
-   {  8245, 0x00008831 }, /* GL_DRAW_BUFFER12_ARB */
-   {  8266, 0x00008831 }, /* GL_DRAW_BUFFER12_ATI */
-   {  8287, 0x00008832 }, /* GL_DRAW_BUFFER13 */
-   {  8304, 0x00008832 }, /* GL_DRAW_BUFFER13_ARB */
-   {  8325, 0x00008832 }, /* GL_DRAW_BUFFER13_ATI */
-   {  8346, 0x00008833 }, /* GL_DRAW_BUFFER14 */
-   {  8363, 0x00008833 }, /* GL_DRAW_BUFFER14_ARB */
-   {  8384, 0x00008833 }, /* GL_DRAW_BUFFER14_ATI */
-   {  8405, 0x00008834 }, /* GL_DRAW_BUFFER15 */
-   {  8422, 0x00008834 }, /* GL_DRAW_BUFFER15_ARB */
-   {  8443, 0x00008834 }, /* GL_DRAW_BUFFER15_ATI */
-   {  8464, 0x00008826 }, /* GL_DRAW_BUFFER1_ARB */
-   {  8484, 0x00008826 }, /* GL_DRAW_BUFFER1_ATI */
-   {  8504, 0x00008827 }, /* GL_DRAW_BUFFER2 */
-   {  8520, 0x00008827 }, /* GL_DRAW_BUFFER2_ARB */
-   {  8540, 0x00008827 }, /* GL_DRAW_BUFFER2_ATI */
-   {  8560, 0x00008828 }, /* GL_DRAW_BUFFER3 */
-   {  8576, 0x00008828 }, /* GL_DRAW_BUFFER3_ARB */
-   {  8596, 0x00008828 }, /* GL_DRAW_BUFFER3_ATI */
-   {  8616, 0x00008829 }, /* GL_DRAW_BUFFER4 */
-   {  8632, 0x00008829 }, /* GL_DRAW_BUFFER4_ARB */
-   {  8652, 0x00008829 }, /* GL_DRAW_BUFFER4_ATI */
-   {  8672, 0x0000882A }, /* GL_DRAW_BUFFER5 */
-   {  8688, 0x0000882A }, /* GL_DRAW_BUFFER5_ARB */
-   {  8708, 0x0000882A }, /* GL_DRAW_BUFFER5_ATI */
-   {  8728, 0x0000882B }, /* GL_DRAW_BUFFER6 */
-   {  8744, 0x0000882B }, /* GL_DRAW_BUFFER6_ARB */
-   {  8764, 0x0000882B }, /* GL_DRAW_BUFFER6_ATI */
-   {  8784, 0x0000882C }, /* GL_DRAW_BUFFER7 */
-   {  8800, 0x0000882C }, /* GL_DRAW_BUFFER7_ARB */
-   {  8820, 0x0000882C }, /* GL_DRAW_BUFFER7_ATI */
-   {  8840, 0x0000882D }, /* GL_DRAW_BUFFER8 */
-   {  8856, 0x0000882D }, /* GL_DRAW_BUFFER8_ARB */
-   {  8876, 0x0000882D }, /* GL_DRAW_BUFFER8_ATI */
-   {  8896, 0x0000882E }, /* GL_DRAW_BUFFER9 */
-   {  8912, 0x0000882E }, /* GL_DRAW_BUFFER9_ARB */
-   {  8932, 0x0000882E }, /* GL_DRAW_BUFFER9_ATI */
-   {  8952, 0x00008CA9 }, /* GL_DRAW_FRAMEBUFFER */
-   {  8972, 0x00008CA6 }, /* GL_DRAW_FRAMEBUFFER_BINDING_EXT */
-   {  9004, 0x00008CA9 }, /* GL_DRAW_FRAMEBUFFER_EXT */
-   {  9028, 0x00000705 }, /* GL_DRAW_PIXEL_TOKEN */
-   {  9048, 0x00000304 }, /* GL_DST_ALPHA */
-   {  9061, 0x00000306 }, /* GL_DST_COLOR */
-   {  9074, 0x0000877A }, /* GL_DU8DV8_ATI */
-   {  9088, 0x00008779 }, /* GL_DUDV_ATI */
-   {  9100, 0x000088EA }, /* GL_DYNAMIC_COPY */
-   {  9116, 0x000088EA }, /* GL_DYNAMIC_COPY_ARB */
-   {  9136, 0x000088E8 }, /* GL_DYNAMIC_DRAW */
-   {  9152, 0x000088E8 }, /* GL_DYNAMIC_DRAW_ARB */
-   {  9172, 0x000088E9 }, /* GL_DYNAMIC_READ */
-   {  9188, 0x000088E9 }, /* GL_DYNAMIC_READ_ARB */
-   {  9208, 0x00000B43 }, /* GL_EDGE_FLAG */
-   {  9221, 0x00008079 }, /* GL_EDGE_FLAG_ARRAY */
-   {  9240, 0x0000889B }, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */
-   {  9274, 0x0000889B }, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB */
-   {  9312, 0x00008093 }, /* GL_EDGE_FLAG_ARRAY_POINTER */
-   {  9339, 0x0000808C }, /* GL_EDGE_FLAG_ARRAY_STRIDE */
-   {  9365, 0x00008893 }, /* GL_ELEMENT_ARRAY_BUFFER */
-   {  9389, 0x00008895 }, /* GL_ELEMENT_ARRAY_BUFFER_BINDING */
-   {  9421, 0x00008895 }, /* GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB */
-   {  9457, 0x00001600 }, /* GL_EMISSION */
-   {  9469, 0x00002000 }, /* GL_ENABLE_BIT */
-   {  9483, 0x00000202 }, /* GL_EQUAL */
-   {  9492, 0x00001509 }, /* GL_EQUIV */
-   {  9501, 0x00010000 }, /* GL_EVAL_BIT */
-   {  9513, 0x00000800 }, /* GL_EXP */
-   {  9520, 0x00000801 }, /* GL_EXP2 */
-   {  9528, 0x00001F03 }, /* GL_EXTENSIONS */
-   {  9542, 0x00002400 }, /* GL_EYE_LINEAR */
-   {  9556, 0x00002502 }, /* GL_EYE_PLANE */
-   {  9569, 0x0000855C }, /* GL_EYE_PLANE_ABSOLUTE_NV */
-   {  9594, 0x0000855B }, /* GL_EYE_RADIAL_NV */
-   {  9611, 0x00000000 }, /* GL_FALSE */
-   {  9620, 0x00001101 }, /* GL_FASTEST */
-   {  9631, 0x00001C01 }, /* GL_FEEDBACK */
-   {  9643, 0x00000DF0 }, /* GL_FEEDBACK_BUFFER_POINTER */
-   {  9670, 0x00000DF1 }, /* GL_FEEDBACK_BUFFER_SIZE */
-   {  9694, 0x00000DF2 }, /* GL_FEEDBACK_BUFFER_TYPE */
-   {  9718, 0x00001B02 }, /* GL_FILL */
-   {  9726, 0x00008E4D }, /* GL_FIRST_VERTEX_CONVENTION */
-   {  9753, 0x00008E4D }, /* GL_FIRST_VERTEX_CONVENTION_EXT */
-   {  9784, 0x00001D00 }, /* GL_FLAT */
-   {  9792, 0x00001406 }, /* GL_FLOAT */
-   {  9801, 0x00008B5A }, /* GL_FLOAT_MAT2 */
-   {  9815, 0x00008B5A }, /* GL_FLOAT_MAT2_ARB */
-   {  9833, 0x00008B65 }, /* GL_FLOAT_MAT2x3 */
-   {  9849, 0x00008B66 }, /* GL_FLOAT_MAT2x4 */
-   {  9865, 0x00008B5B }, /* GL_FLOAT_MAT3 */
-   {  9879, 0x00008B5B }, /* GL_FLOAT_MAT3_ARB */
-   {  9897, 0x00008B67 }, /* GL_FLOAT_MAT3x2 */
-   {  9913, 0x00008B68 }, /* GL_FLOAT_MAT3x4 */
-   {  9929, 0x00008B5C }, /* GL_FLOAT_MAT4 */
-   {  9943, 0x00008B5C }, /* GL_FLOAT_MAT4_ARB */
-   {  9961, 0x00008B69 }, /* GL_FLOAT_MAT4x2 */
-   {  9977, 0x00008B6A }, /* GL_FLOAT_MAT4x3 */
-   {  9993, 0x00008B50 }, /* GL_FLOAT_VEC2 */
-   { 10007, 0x00008B50 }, /* GL_FLOAT_VEC2_ARB */
-   { 10025, 0x00008B51 }, /* GL_FLOAT_VEC3 */
-   { 10039, 0x00008B51 }, /* GL_FLOAT_VEC3_ARB */
-   { 10057, 0x00008B52 }, /* GL_FLOAT_VEC4 */
-   { 10071, 0x00008B52 }, /* GL_FLOAT_VEC4_ARB */
-   { 10089, 0x00000B60 }, /* GL_FOG */
-   { 10096, 0x00000080 }, /* GL_FOG_BIT */
-   { 10107, 0x00000B66 }, /* GL_FOG_COLOR */
-   { 10120, 0x00008451 }, /* GL_FOG_COORD */
-   { 10133, 0x00008451 }, /* GL_FOG_COORDINATE */
-   { 10151, 0x00008457 }, /* GL_FOG_COORDINATE_ARRAY */
-   { 10175, 0x0000889D }, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */
-   { 10214, 0x0000889D }, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB */
-   { 10257, 0x00008456 }, /* GL_FOG_COORDINATE_ARRAY_POINTER */
-   { 10289, 0x00008455 }, /* GL_FOG_COORDINATE_ARRAY_STRIDE */
-   { 10320, 0x00008454 }, /* GL_FOG_COORDINATE_ARRAY_TYPE */
-   { 10349, 0x00008450 }, /* GL_FOG_COORDINATE_SOURCE */
-   { 10374, 0x00008457 }, /* GL_FOG_COORD_ARRAY */
-   { 10393, 0x0000889D }, /* GL_FOG_COORD_ARRAY_BUFFER_BINDING */
-   { 10427, 0x00008456 }, /* GL_FOG_COORD_ARRAY_POINTER */
-   { 10454, 0x00008455 }, /* GL_FOG_COORD_ARRAY_STRIDE */
-   { 10480, 0x00008454 }, /* GL_FOG_COORD_ARRAY_TYPE */
-   { 10504, 0x00008450 }, /* GL_FOG_COORD_SRC */
-   { 10521, 0x00000B62 }, /* GL_FOG_DENSITY */
-   { 10536, 0x0000855A }, /* GL_FOG_DISTANCE_MODE_NV */
-   { 10560, 0x00000B64 }, /* GL_FOG_END */
-   { 10571, 0x00000C54 }, /* GL_FOG_HINT */
-   { 10583, 0x00000B61 }, /* GL_FOG_INDEX */
-   { 10596, 0x00000B65 }, /* GL_FOG_MODE */
-   { 10608, 0x00008198 }, /* GL_FOG_OFFSET_SGIX */
-   { 10627, 0x00008199 }, /* GL_FOG_OFFSET_VALUE_SGIX */
-   { 10652, 0x00000B63 }, /* GL_FOG_START */
-   { 10665, 0x00008452 }, /* GL_FRAGMENT_DEPTH */
-   { 10683, 0x00008804 }, /* GL_FRAGMENT_PROGRAM_ARB */
-   { 10707, 0x00008B30 }, /* GL_FRAGMENT_SHADER */
-   { 10726, 0x00008B30 }, /* GL_FRAGMENT_SHADER_ARB */
-   { 10749, 0x00008B8B }, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */
-   { 10784, 0x00008D40 }, /* GL_FRAMEBUFFER */
-   { 10799, 0x00008215 }, /* GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */
-   { 10836, 0x00008214 }, /* GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */
-   { 10872, 0x00008210 }, /* GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */
-   { 10913, 0x00008211 }, /* GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */
-   { 10954, 0x00008216 }, /* GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */
-   { 10991, 0x00008213 }, /* GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */
-   { 11028, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
-   { 11066, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT */
-   { 11108, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
-   { 11146, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT */
-   { 11188, 0x00008212 }, /* GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
-   { 11223, 0x00008217 }, /* GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
-   { 11262, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT */
-   { 11311, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
-   { 11359, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT */
-   { 11411, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
-   { 11451, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */
-   { 11495, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
-   { 11535, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT */
-   { 11579, 0x00008CA6 }, /* GL_FRAMEBUFFER_BINDING_EXT */
-   { 11606, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE */
-   { 11630, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE_EXT */
-   { 11658, 0x00008218 }, /* GL_FRAMEBUFFER_DEFAULT */
-   { 11681, 0x00008D40 }, /* GL_FRAMEBUFFER_EXT */
-   { 11700, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
-   { 11737, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT */
-   { 11778, 0x00008CD9 }, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
-   { 11819, 0x00008CDB }, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT */
-   { 11861, 0x00008CD8 }, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
-   { 11912, 0x00008CDA }, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
-   { 11950, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
-   { 11995, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT */
-   { 12044, 0x00008D56 }, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
-   { 12082, 0x00008CDC }, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT */
-   { 12124, 0x00008CDE }, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
-   { 12156, 0x00008219 }, /* GL_FRAMEBUFFER_UNDEFINED */
-   { 12181, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED */
-   { 12208, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED_EXT */
-   { 12239, 0x00000404 }, /* GL_FRONT */
-   { 12248, 0x00000408 }, /* GL_FRONT_AND_BACK */
-   { 12266, 0x00000B46 }, /* GL_FRONT_FACE */
-   { 12280, 0x00000400 }, /* GL_FRONT_LEFT */
-   { 12294, 0x00000401 }, /* GL_FRONT_RIGHT */
-   { 12309, 0x00008006 }, /* GL_FUNC_ADD */
-   { 12321, 0x00008006 }, /* GL_FUNC_ADD_EXT */
-   { 12337, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT */
-   { 12362, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT_EXT */
-   { 12391, 0x0000800A }, /* GL_FUNC_SUBTRACT */
-   { 12408, 0x0000800A }, /* GL_FUNC_SUBTRACT_EXT */
-   { 12429, 0x00008191 }, /* GL_GENERATE_MIPMAP */
-   { 12448, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT */
-   { 12472, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT_SGIS */
-   { 12501, 0x00008191 }, /* GL_GENERATE_MIPMAP_SGIS */
-   { 12525, 0x00000206 }, /* GL_GEQUAL */
-   { 12535, 0x00000204 }, /* GL_GREATER */
-   { 12546, 0x00001904 }, /* GL_GREEN */
-   { 12555, 0x00000D19 }, /* GL_GREEN_BIAS */
-   { 12569, 0x00000D53 }, /* GL_GREEN_BITS */
-   { 12583, 0x00000D18 }, /* GL_GREEN_SCALE */
-   { 12598, 0x00008000 }, /* GL_HINT_BIT */
-   { 12610, 0x00008024 }, /* GL_HISTOGRAM */
-   { 12623, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE */
-   { 12647, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE_EXT */
-   { 12675, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE */
-   { 12698, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE_EXT */
-   { 12725, 0x00008024 }, /* GL_HISTOGRAM_EXT */
-   { 12742, 0x00008027 }, /* GL_HISTOGRAM_FORMAT */
-   { 12762, 0x00008027 }, /* GL_HISTOGRAM_FORMAT_EXT */
-   { 12786, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE */
-   { 12810, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE_EXT */
-   { 12838, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE */
-   { 12866, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE_EXT */
-   { 12898, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE */
-   { 12920, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE_EXT */
-   { 12946, 0x0000802D }, /* GL_HISTOGRAM_SINK */
-   { 12964, 0x0000802D }, /* GL_HISTOGRAM_SINK_EXT */
-   { 12986, 0x00008026 }, /* GL_HISTOGRAM_WIDTH */
-   { 13005, 0x00008026 }, /* GL_HISTOGRAM_WIDTH_EXT */
-   { 13028, 0x0000862A }, /* GL_IDENTITY_NV */
-   { 13043, 0x00008150 }, /* GL_IGNORE_BORDER_HP */
-   { 13063, 0x00008B9B }, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
-   { 13103, 0x00008B9A }, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
-   { 13141, 0x00001E02 }, /* GL_INCR */
-   { 13149, 0x00008507 }, /* GL_INCR_WRAP */
-   { 13162, 0x00008507 }, /* GL_INCR_WRAP_EXT */
-   { 13179, 0x00008222 }, /* GL_INDEX */
-   { 13188, 0x00008077 }, /* GL_INDEX_ARRAY */
-   { 13203, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING */
-   { 13233, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING_ARB */
-   { 13267, 0x00008091 }, /* GL_INDEX_ARRAY_POINTER */
-   { 13290, 0x00008086 }, /* GL_INDEX_ARRAY_STRIDE */
-   { 13312, 0x00008085 }, /* GL_INDEX_ARRAY_TYPE */
-   { 13332, 0x00000D51 }, /* GL_INDEX_BITS */
-   { 13346, 0x00000C20 }, /* GL_INDEX_CLEAR_VALUE */
-   { 13367, 0x00000BF1 }, /* GL_INDEX_LOGIC_OP */
-   { 13385, 0x00000C30 }, /* GL_INDEX_MODE */
-   { 13399, 0x00000D13 }, /* GL_INDEX_OFFSET */
-   { 13415, 0x00000D12 }, /* GL_INDEX_SHIFT */
-   { 13430, 0x00000C21 }, /* GL_INDEX_WRITEMASK */
-   { 13449, 0x00008B84 }, /* GL_INFO_LOG_LENGTH */
-   { 13468, 0x00001404 }, /* GL_INT */
-   { 13475, 0x00008049 }, /* GL_INTENSITY */
-   { 13488, 0x0000804C }, /* GL_INTENSITY12 */
-   { 13503, 0x0000804C }, /* GL_INTENSITY12_EXT */
-   { 13522, 0x0000804D }, /* GL_INTENSITY16 */
-   { 13537, 0x0000804D }, /* GL_INTENSITY16_EXT */
-   { 13556, 0x0000804A }, /* GL_INTENSITY4 */
-   { 13570, 0x0000804A }, /* GL_INTENSITY4_EXT */
-   { 13588, 0x0000804B }, /* GL_INTENSITY8 */
-   { 13602, 0x0000804B }, /* GL_INTENSITY8_EXT */
-   { 13620, 0x00008049 }, /* GL_INTENSITY_EXT */
-   { 13637, 0x00008575 }, /* GL_INTERPOLATE */
-   { 13652, 0x00008575 }, /* GL_INTERPOLATE_ARB */
-   { 13671, 0x00008575 }, /* GL_INTERPOLATE_EXT */
-   { 13690, 0x00008B53 }, /* GL_INT_VEC2 */
-   { 13702, 0x00008B53 }, /* GL_INT_VEC2_ARB */
-   { 13718, 0x00008B54 }, /* GL_INT_VEC3 */
-   { 13730, 0x00008B54 }, /* GL_INT_VEC3_ARB */
-   { 13746, 0x00008B55 }, /* GL_INT_VEC4 */
-   { 13758, 0x00008B55 }, /* GL_INT_VEC4_ARB */
-   { 13774, 0x00000500 }, /* GL_INVALID_ENUM */
-   { 13790, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION */
-   { 13823, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION_EXT */
-   { 13860, 0x00000502 }, /* GL_INVALID_OPERATION */
-   { 13881, 0x00000501 }, /* GL_INVALID_VALUE */
-   { 13898, 0x0000862B }, /* GL_INVERSE_NV */
-   { 13912, 0x0000862D }, /* GL_INVERSE_TRANSPOSE_NV */
-   { 13936, 0x0000150A }, /* GL_INVERT */
-   { 13946, 0x00001E00 }, /* GL_KEEP */
-   { 13954, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION */
-   { 13980, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION_EXT */
-   { 14010, 0x00000406 }, /* GL_LEFT */
-   { 14018, 0x00000203 }, /* GL_LEQUAL */
-   { 14028, 0x00000201 }, /* GL_LESS */
-   { 14036, 0x00004000 }, /* GL_LIGHT0 */
-   { 14046, 0x00004001 }, /* GL_LIGHT1 */
-   { 14056, 0x00004002 }, /* GL_LIGHT2 */
-   { 14066, 0x00004003 }, /* GL_LIGHT3 */
-   { 14076, 0x00004004 }, /* GL_LIGHT4 */
-   { 14086, 0x00004005 }, /* GL_LIGHT5 */
-   { 14096, 0x00004006 }, /* GL_LIGHT6 */
-   { 14106, 0x00004007 }, /* GL_LIGHT7 */
-   { 14116, 0x00000B50 }, /* GL_LIGHTING */
-   { 14128, 0x00000040 }, /* GL_LIGHTING_BIT */
-   { 14144, 0x00000B53 }, /* GL_LIGHT_MODEL_AMBIENT */
-   { 14167, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL */
-   { 14196, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL_EXT */
-   { 14229, 0x00000B51 }, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
-   { 14257, 0x00000B52 }, /* GL_LIGHT_MODEL_TWO_SIDE */
-   { 14281, 0x00001B01 }, /* GL_LINE */
-   { 14289, 0x00002601 }, /* GL_LINEAR */
-   { 14299, 0x00001208 }, /* GL_LINEAR_ATTENUATION */
-   { 14321, 0x00008170 }, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
-   { 14351, 0x0000844F }, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
-   { 14382, 0x00002703 }, /* GL_LINEAR_MIPMAP_LINEAR */
-   { 14406, 0x00002701 }, /* GL_LINEAR_MIPMAP_NEAREST */
-   { 14431, 0x00000001 }, /* GL_LINES */
-   { 14440, 0x00000004 }, /* GL_LINE_BIT */
-   { 14452, 0x00000002 }, /* GL_LINE_LOOP */
-   { 14465, 0x00000707 }, /* GL_LINE_RESET_TOKEN */
-   { 14485, 0x00000B20 }, /* GL_LINE_SMOOTH */
-   { 14500, 0x00000C52 }, /* GL_LINE_SMOOTH_HINT */
-   { 14520, 0x00000B24 }, /* GL_LINE_STIPPLE */
-   { 14536, 0x00000B25 }, /* GL_LINE_STIPPLE_PATTERN */
-   { 14560, 0x00000B26 }, /* GL_LINE_STIPPLE_REPEAT */
-   { 14583, 0x00000003 }, /* GL_LINE_STRIP */
-   { 14597, 0x00000702 }, /* GL_LINE_TOKEN */
-   { 14611, 0x00000B21 }, /* GL_LINE_WIDTH */
-   { 14625, 0x00000B23 }, /* GL_LINE_WIDTH_GRANULARITY */
-   { 14651, 0x00000B22 }, /* GL_LINE_WIDTH_RANGE */
-   { 14671, 0x00008B82 }, /* GL_LINK_STATUS */
-   { 14686, 0x00000B32 }, /* GL_LIST_BASE */
-   { 14699, 0x00020000 }, /* GL_LIST_BIT */
-   { 14711, 0x00000B33 }, /* GL_LIST_INDEX */
-   { 14725, 0x00000B30 }, /* GL_LIST_MODE */
-   { 14738, 0x00000101 }, /* GL_LOAD */
-   { 14746, 0x00000BF1 }, /* GL_LOGIC_OP */
-   { 14758, 0x00000BF0 }, /* GL_LOGIC_OP_MODE */
-   { 14775, 0x00008CA1 }, /* GL_LOWER_LEFT */
-   { 14789, 0x00001909 }, /* GL_LUMINANCE */
-   { 14802, 0x00008041 }, /* GL_LUMINANCE12 */
-   { 14817, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12 */
-   { 14840, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12_EXT */
-   { 14867, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4 */
-   { 14889, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4_EXT */
-   { 14915, 0x00008041 }, /* GL_LUMINANCE12_EXT */
-   { 14934, 0x00008042 }, /* GL_LUMINANCE16 */
-   { 14949, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16 */
-   { 14972, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16_EXT */
-   { 14999, 0x00008042 }, /* GL_LUMINANCE16_EXT */
-   { 15018, 0x0000803F }, /* GL_LUMINANCE4 */
-   { 15032, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4 */
-   { 15053, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4_EXT */
-   { 15078, 0x0000803F }, /* GL_LUMINANCE4_EXT */
-   { 15096, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2 */
-   { 15117, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2_EXT */
-   { 15142, 0x00008040 }, /* GL_LUMINANCE8 */
-   { 15156, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8 */
-   { 15177, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8_EXT */
-   { 15202, 0x00008040 }, /* GL_LUMINANCE8_EXT */
-   { 15220, 0x0000190A }, /* GL_LUMINANCE_ALPHA */
-   { 15239, 0x00000D90 }, /* GL_MAP1_COLOR_4 */
-   { 15255, 0x00000DD0 }, /* GL_MAP1_GRID_DOMAIN */
-   { 15275, 0x00000DD1 }, /* GL_MAP1_GRID_SEGMENTS */
-   { 15297, 0x00000D91 }, /* GL_MAP1_INDEX */
-   { 15311, 0x00000D92 }, /* GL_MAP1_NORMAL */
-   { 15326, 0x00000D93 }, /* GL_MAP1_TEXTURE_COORD_1 */
-   { 15350, 0x00000D94 }, /* GL_MAP1_TEXTURE_COORD_2 */
-   { 15374, 0x00000D95 }, /* GL_MAP1_TEXTURE_COORD_3 */
-   { 15398, 0x00000D96 }, /* GL_MAP1_TEXTURE_COORD_4 */
-   { 15422, 0x00000D97 }, /* GL_MAP1_VERTEX_3 */
-   { 15439, 0x00000D98 }, /* GL_MAP1_VERTEX_4 */
-   { 15456, 0x00008660 }, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
-   { 15484, 0x0000866A }, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
-   { 15513, 0x0000866B }, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
-   { 15542, 0x0000866C }, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
-   { 15571, 0x0000866D }, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
-   { 15600, 0x0000866E }, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
-   { 15629, 0x0000866F }, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
-   { 15658, 0x00008661 }, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
-   { 15686, 0x00008662 }, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
-   { 15714, 0x00008663 }, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
-   { 15742, 0x00008664 }, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
-   { 15770, 0x00008665 }, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
-   { 15798, 0x00008666 }, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
-   { 15826, 0x00008667 }, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
-   { 15854, 0x00008668 }, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
-   { 15882, 0x00008669 }, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
-   { 15910, 0x00000DB0 }, /* GL_MAP2_COLOR_4 */
-   { 15926, 0x00000DD2 }, /* GL_MAP2_GRID_DOMAIN */
-   { 15946, 0x00000DD3 }, /* GL_MAP2_GRID_SEGMENTS */
-   { 15968, 0x00000DB1 }, /* GL_MAP2_INDEX */
-   { 15982, 0x00000DB2 }, /* GL_MAP2_NORMAL */
-   { 15997, 0x00000DB3 }, /* GL_MAP2_TEXTURE_COORD_1 */
-   { 16021, 0x00000DB4 }, /* GL_MAP2_TEXTURE_COORD_2 */
-   { 16045, 0x00000DB5 }, /* GL_MAP2_TEXTURE_COORD_3 */
-   { 16069, 0x00000DB6 }, /* GL_MAP2_TEXTURE_COORD_4 */
-   { 16093, 0x00000DB7 }, /* GL_MAP2_VERTEX_3 */
-   { 16110, 0x00000DB8 }, /* GL_MAP2_VERTEX_4 */
-   { 16127, 0x00008670 }, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
-   { 16155, 0x0000867A }, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
-   { 16184, 0x0000867B }, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
-   { 16213, 0x0000867C }, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
-   { 16242, 0x0000867D }, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
-   { 16271, 0x0000867E }, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
-   { 16300, 0x0000867F }, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
-   { 16329, 0x00008671 }, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
-   { 16357, 0x00008672 }, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
-   { 16385, 0x00008673 }, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
-   { 16413, 0x00008674 }, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
-   { 16441, 0x00008675 }, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
-   { 16469, 0x00008676 }, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
-   { 16497, 0x00008677 }, /* GL_MAP2_VERTEX_ATTRIB7_4_NV */
-   { 16525, 0x00008678 }, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
-   { 16553, 0x00008679 }, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
-   { 16581, 0x00000D10 }, /* GL_MAP_COLOR */
-   { 16594, 0x00000010 }, /* GL_MAP_FLUSH_EXPLICIT_BIT */
-   { 16620, 0x00000008 }, /* GL_MAP_INVALIDATE_BUFFER_BIT */
-   { 16649, 0x00000004 }, /* GL_MAP_INVALIDATE_RANGE_BIT */
-   { 16677, 0x00000001 }, /* GL_MAP_READ_BIT */
-   { 16693, 0x00000D11 }, /* GL_MAP_STENCIL */
-   { 16708, 0x00000020 }, /* GL_MAP_UNSYNCHRONIZED_BIT */
-   { 16734, 0x00000002 }, /* GL_MAP_WRITE_BIT */
-   { 16751, 0x000088C0 }, /* GL_MATRIX0_ARB */
-   { 16766, 0x00008630 }, /* GL_MATRIX0_NV */
-   { 16780, 0x000088CA }, /* GL_MATRIX10_ARB */
-   { 16796, 0x000088CB }, /* GL_MATRIX11_ARB */
-   { 16812, 0x000088CC }, /* GL_MATRIX12_ARB */
-   { 16828, 0x000088CD }, /* GL_MATRIX13_ARB */
-   { 16844, 0x000088CE }, /* GL_MATRIX14_ARB */
-   { 16860, 0x000088CF }, /* GL_MATRIX15_ARB */
-   { 16876, 0x000088D0 }, /* GL_MATRIX16_ARB */
-   { 16892, 0x000088D1 }, /* GL_MATRIX17_ARB */
-   { 16908, 0x000088D2 }, /* GL_MATRIX18_ARB */
-   { 16924, 0x000088D3 }, /* GL_MATRIX19_ARB */
-   { 16940, 0x000088C1 }, /* GL_MATRIX1_ARB */
-   { 16955, 0x00008631 }, /* GL_MATRIX1_NV */
-   { 16969, 0x000088D4 }, /* GL_MATRIX20_ARB */
-   { 16985, 0x000088D5 }, /* GL_MATRIX21_ARB */
-   { 17001, 0x000088D6 }, /* GL_MATRIX22_ARB */
-   { 17017, 0x000088D7 }, /* GL_MATRIX23_ARB */
-   { 17033, 0x000088D8 }, /* GL_MATRIX24_ARB */
-   { 17049, 0x000088D9 }, /* GL_MATRIX25_ARB */
-   { 17065, 0x000088DA }, /* GL_MATRIX26_ARB */
-   { 17081, 0x000088DB }, /* GL_MATRIX27_ARB */
-   { 17097, 0x000088DC }, /* GL_MATRIX28_ARB */
-   { 17113, 0x000088DD }, /* GL_MATRIX29_ARB */
-   { 17129, 0x000088C2 }, /* GL_MATRIX2_ARB */
-   { 17144, 0x00008632 }, /* GL_MATRIX2_NV */
-   { 17158, 0x000088DE }, /* GL_MATRIX30_ARB */
-   { 17174, 0x000088DF }, /* GL_MATRIX31_ARB */
-   { 17190, 0x000088C3 }, /* GL_MATRIX3_ARB */
-   { 17205, 0x00008633 }, /* GL_MATRIX3_NV */
-   { 17219, 0x000088C4 }, /* GL_MATRIX4_ARB */
-   { 17234, 0x00008634 }, /* GL_MATRIX4_NV */
-   { 17248, 0x000088C5 }, /* GL_MATRIX5_ARB */
-   { 17263, 0x00008635 }, /* GL_MATRIX5_NV */
-   { 17277, 0x000088C6 }, /* GL_MATRIX6_ARB */
-   { 17292, 0x00008636 }, /* GL_MATRIX6_NV */
-   { 17306, 0x000088C7 }, /* GL_MATRIX7_ARB */
-   { 17321, 0x00008637 }, /* GL_MATRIX7_NV */
-   { 17335, 0x000088C8 }, /* GL_MATRIX8_ARB */
-   { 17350, 0x000088C9 }, /* GL_MATRIX9_ARB */
-   { 17365, 0x00008844 }, /* GL_MATRIX_INDEX_ARRAY_ARB */
-   { 17391, 0x00008849 }, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
-   { 17425, 0x00008846 }, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
-   { 17456, 0x00008848 }, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
-   { 17489, 0x00008847 }, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
-   { 17520, 0x00000BA0 }, /* GL_MATRIX_MODE */
-   { 17535, 0x00008840 }, /* GL_MATRIX_PALETTE_ARB */
-   { 17557, 0x00008008 }, /* GL_MAX */
-   { 17564, 0x00008073 }, /* GL_MAX_3D_TEXTURE_SIZE */
-   { 17587, 0x000088FF }, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */
-   { 17619, 0x00000D35 }, /* GL_MAX_ATTRIB_STACK_DEPTH */
-   { 17645, 0x00000D3B }, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
-   { 17678, 0x00008177 }, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
-   { 17704, 0x00008178 }, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
-   { 17738, 0x00000D32 }, /* GL_MAX_CLIP_PLANES */
-   { 17757, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS_EXT */
-   { 17786, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
-   { 17818, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI */
-   { 17854, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */
-   { 17890, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB */
-   { 17930, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT */
-   { 17956, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT_EXT */
-   { 17986, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH */
-   { 18011, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH_EXT */
-   { 18040, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
-   { 18069, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB */
-   { 18102, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS */
-   { 18122, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ARB */
-   { 18146, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ATI */
-   { 18170, 0x000080E9 }, /* GL_MAX_ELEMENTS_INDICES */
-   { 18194, 0x000080E8 }, /* GL_MAX_ELEMENTS_VERTICES */
-   { 18219, 0x00000D30 }, /* GL_MAX_EVAL_ORDER */
-   { 18237, 0x00008008 }, /* GL_MAX_EXT */
-   { 18248, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */
-   { 18283, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB */
-   { 18322, 0x00000D31 }, /* GL_MAX_LIGHTS */
-   { 18336, 0x00000B31 }, /* GL_MAX_LIST_NESTING */
-   { 18356, 0x00008841 }, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
-   { 18394, 0x00000D36 }, /* GL_MAX_MODELVIEW_STACK_DEPTH */
-   { 18423, 0x00000D37 }, /* GL_MAX_NAME_STACK_DEPTH */
-   { 18447, 0x00008842 }, /* GL_MAX_PALETTE_MATRICES_ARB */
-   { 18475, 0x00000D34 }, /* GL_MAX_PIXEL_MAP_TABLE */
-   { 18498, 0x000088B1 }, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
-   { 18535, 0x0000880B }, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
-   { 18571, 0x000088AD }, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
-   { 18598, 0x000088F5 }, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
-   { 18627, 0x000088B5 }, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
-   { 18661, 0x000088F4 }, /* GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */
-   { 18697, 0x000088F6 }, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
-   { 18724, 0x000088A1 }, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
-   { 18756, 0x000088B4 }, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
-   { 18792, 0x000088F8 }, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
-   { 18821, 0x000088F7 }, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
-   { 18850, 0x0000862F }, /* GL_MAX_PROGRAM_MATRICES_ARB */
-   { 18878, 0x0000862E }, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
-   { 18916, 0x000088B3 }, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
-   { 18960, 0x0000880E }, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
-   { 19003, 0x000088AF }, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
-   { 19037, 0x000088A3 }, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
-   { 19076, 0x000088AB }, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
-   { 19113, 0x000088A7 }, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
-   { 19151, 0x00008810 }, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
-   { 19194, 0x0000880F }, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
-   { 19237, 0x000088A9 }, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
-   { 19267, 0x000088A5 }, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
-   { 19298, 0x0000880D }, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
-   { 19334, 0x0000880C }, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
-   { 19370, 0x00000D38 }, /* GL_MAX_PROJECTION_STACK_DEPTH */
-   { 19400, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */
-   { 19434, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_NV */
-   { 19467, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE_EXT */
-   { 19496, 0x00008D57 }, /* GL_MAX_SAMPLES */
-   { 19511, 0x00009111 }, /* GL_MAX_SERVER_WAIT_TIMEOUT */
-   { 19538, 0x00008504 }, /* GL_MAX_SHININESS_NV */
-   { 19558, 0x00008505 }, /* GL_MAX_SPOT_EXPONENT_NV */
-   { 19582, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS */
-   { 19604, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS_ARB */
-   { 19630, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS */
-   { 19657, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS_ARB */
-   { 19688, 0x000084FD }, /* GL_MAX_TEXTURE_LOD_BIAS */
-   { 19712, 0x000084FF }, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
-   { 19746, 0x00000D33 }, /* GL_MAX_TEXTURE_SIZE */
-   { 19766, 0x00000D39 }, /* GL_MAX_TEXTURE_STACK_DEPTH */
-   { 19793, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS */
-   { 19814, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS_ARB */
-   { 19839, 0x0000862F }, /* GL_MAX_TRACK_MATRICES_NV */
-   { 19864, 0x0000862E }, /* GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV */
-   { 19899, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS */
-   { 19921, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS_ARB */
-   { 19947, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS */
-   { 19969, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS_ARB */
-   { 19995, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */
-   { 20029, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */
-   { 20067, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */
-   { 20100, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB */
-   { 20137, 0x000086A4 }, /* GL_MAX_VERTEX_UNITS_ARB */
-   { 20161, 0x00000D3A }, /* GL_MAX_VIEWPORT_DIMS */
-   { 20182, 0x00008007 }, /* GL_MIN */
-   { 20189, 0x0000802E }, /* GL_MINMAX */
-   { 20199, 0x0000802E }, /* GL_MINMAX_EXT */
-   { 20213, 0x0000802F }, /* GL_MINMAX_FORMAT */
-   { 20230, 0x0000802F }, /* GL_MINMAX_FORMAT_EXT */
-   { 20251, 0x00008030 }, /* GL_MINMAX_SINK */
-   { 20266, 0x00008030 }, /* GL_MINMAX_SINK_EXT */
-   { 20285, 0x00008007 }, /* GL_MIN_EXT */
-   { 20296, 0x00008370 }, /* GL_MIRRORED_REPEAT */
-   { 20315, 0x00008370 }, /* GL_MIRRORED_REPEAT_ARB */
-   { 20338, 0x00008370 }, /* GL_MIRRORED_REPEAT_IBM */
-   { 20361, 0x00008742 }, /* GL_MIRROR_CLAMP_ATI */
-   { 20381, 0x00008742 }, /* GL_MIRROR_CLAMP_EXT */
-   { 20401, 0x00008912 }, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
-   { 20431, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_ATI */
-   { 20459, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
-   { 20487, 0x00001700 }, /* GL_MODELVIEW */
-   { 20500, 0x00001700 }, /* GL_MODELVIEW0_ARB */
-   { 20518, 0x0000872A }, /* GL_MODELVIEW10_ARB */
-   { 20537, 0x0000872B }, /* GL_MODELVIEW11_ARB */
-   { 20556, 0x0000872C }, /* GL_MODELVIEW12_ARB */
-   { 20575, 0x0000872D }, /* GL_MODELVIEW13_ARB */
-   { 20594, 0x0000872E }, /* GL_MODELVIEW14_ARB */
-   { 20613, 0x0000872F }, /* GL_MODELVIEW15_ARB */
-   { 20632, 0x00008730 }, /* GL_MODELVIEW16_ARB */
-   { 20651, 0x00008731 }, /* GL_MODELVIEW17_ARB */
-   { 20670, 0x00008732 }, /* GL_MODELVIEW18_ARB */
-   { 20689, 0x00008733 }, /* GL_MODELVIEW19_ARB */
-   { 20708, 0x0000850A }, /* GL_MODELVIEW1_ARB */
-   { 20726, 0x00008734 }, /* GL_MODELVIEW20_ARB */
-   { 20745, 0x00008735 }, /* GL_MODELVIEW21_ARB */
-   { 20764, 0x00008736 }, /* GL_MODELVIEW22_ARB */
-   { 20783, 0x00008737 }, /* GL_MODELVIEW23_ARB */
-   { 20802, 0x00008738 }, /* GL_MODELVIEW24_ARB */
-   { 20821, 0x00008739 }, /* GL_MODELVIEW25_ARB */
-   { 20840, 0x0000873A }, /* GL_MODELVIEW26_ARB */
-   { 20859, 0x0000873B }, /* GL_MODELVIEW27_ARB */
-   { 20878, 0x0000873C }, /* GL_MODELVIEW28_ARB */
-   { 20897, 0x0000873D }, /* GL_MODELVIEW29_ARB */
-   { 20916, 0x00008722 }, /* GL_MODELVIEW2_ARB */
-   { 20934, 0x0000873E }, /* GL_MODELVIEW30_ARB */
-   { 20953, 0x0000873F }, /* GL_MODELVIEW31_ARB */
-   { 20972, 0x00008723 }, /* GL_MODELVIEW3_ARB */
-   { 20990, 0x00008724 }, /* GL_MODELVIEW4_ARB */
-   { 21008, 0x00008725 }, /* GL_MODELVIEW5_ARB */
-   { 21026, 0x00008726 }, /* GL_MODELVIEW6_ARB */
-   { 21044, 0x00008727 }, /* GL_MODELVIEW7_ARB */
-   { 21062, 0x00008728 }, /* GL_MODELVIEW8_ARB */
-   { 21080, 0x00008729 }, /* GL_MODELVIEW9_ARB */
-   { 21098, 0x00000BA6 }, /* GL_MODELVIEW_MATRIX */
-   { 21118, 0x00008629 }, /* GL_MODELVIEW_PROJECTION_NV */
-   { 21145, 0x00000BA3 }, /* GL_MODELVIEW_STACK_DEPTH */
-   { 21170, 0x00002100 }, /* GL_MODULATE */
-   { 21182, 0x00008744 }, /* GL_MODULATE_ADD_ATI */
-   { 21202, 0x00008745 }, /* GL_MODULATE_SIGNED_ADD_ATI */
-   { 21229, 0x00008746 }, /* GL_MODULATE_SUBTRACT_ATI */
-   { 21254, 0x00000103 }, /* GL_MULT */
-   { 21262, 0x0000809D }, /* GL_MULTISAMPLE */
-   { 21277, 0x000086B2 }, /* GL_MULTISAMPLE_3DFX */
-   { 21297, 0x0000809D }, /* GL_MULTISAMPLE_ARB */
-   { 21316, 0x20000000 }, /* GL_MULTISAMPLE_BIT */
-   { 21335, 0x20000000 }, /* GL_MULTISAMPLE_BIT_3DFX */
-   { 21359, 0x20000000 }, /* GL_MULTISAMPLE_BIT_ARB */
-   { 21382, 0x00008534 }, /* GL_MULTISAMPLE_FILTER_HINT_NV */
-   { 21412, 0x00002A25 }, /* GL_N3F_V3F */
-   { 21423, 0x00000D70 }, /* GL_NAME_STACK_DEPTH */
-   { 21443, 0x0000150E }, /* GL_NAND */
-   { 21451, 0x00002600 }, /* GL_NEAREST */
-   { 21462, 0x0000844E }, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
-   { 21493, 0x0000844D }, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
-   { 21525, 0x00002702 }, /* GL_NEAREST_MIPMAP_LINEAR */
-   { 21550, 0x00002700 }, /* GL_NEAREST_MIPMAP_NEAREST */
-   { 21576, 0x00000200 }, /* GL_NEVER */
-   { 21585, 0x00001102 }, /* GL_NICEST */
-   { 21595, 0x00000000 }, /* GL_NONE */
-   { 21603, 0x00001505 }, /* GL_NOOP */
-   { 21611, 0x00001508 }, /* GL_NOR */
-   { 21618, 0x00000BA1 }, /* GL_NORMALIZE */
-   { 21631, 0x00008075 }, /* GL_NORMAL_ARRAY */
-   { 21647, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
-   { 21678, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING_ARB */
-   { 21713, 0x0000808F }, /* GL_NORMAL_ARRAY_POINTER */
-   { 21737, 0x0000807F }, /* GL_NORMAL_ARRAY_STRIDE */
-   { 21760, 0x0000807E }, /* GL_NORMAL_ARRAY_TYPE */
-   { 21781, 0x00008511 }, /* GL_NORMAL_MAP */
-   { 21795, 0x00008511 }, /* GL_NORMAL_MAP_ARB */
-   { 21813, 0x00008511 }, /* GL_NORMAL_MAP_NV */
-   { 21830, 0x00000205 }, /* GL_NOTEQUAL */
-   { 21842, 0x00000000 }, /* GL_NO_ERROR */
-   { 21854, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
-   { 21888, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB */
-   { 21926, 0x00008B89 }, /* GL_OBJECT_ACTIVE_ATTRIBUTES_ARB */
-   { 21958, 0x00008B8A }, /* GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB */
-   { 22000, 0x00008B86 }, /* GL_OBJECT_ACTIVE_UNIFORMS_ARB */
-   { 22030, 0x00008B87 }, /* GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB */
-   { 22070, 0x00008B85 }, /* GL_OBJECT_ATTACHED_OBJECTS_ARB */
-   { 22101, 0x00008B81 }, /* GL_OBJECT_COMPILE_STATUS_ARB */
-   { 22130, 0x00008B80 }, /* GL_OBJECT_DELETE_STATUS_ARB */
-   { 22158, 0x00008B84 }, /* GL_OBJECT_INFO_LOG_LENGTH_ARB */
-   { 22188, 0x00002401 }, /* GL_OBJECT_LINEAR */
-   { 22205, 0x00008B82 }, /* GL_OBJECT_LINK_STATUS_ARB */
-   { 22231, 0x00002501 }, /* GL_OBJECT_PLANE */
-   { 22247, 0x00008B88 }, /* GL_OBJECT_SHADER_SOURCE_LENGTH_ARB */
-   { 22282, 0x00008B4F }, /* GL_OBJECT_SUBTYPE_ARB */
-   { 22304, 0x00009112 }, /* GL_OBJECT_TYPE */
-   { 22319, 0x00008B4E }, /* GL_OBJECT_TYPE_ARB */
-   { 22338, 0x00008B83 }, /* GL_OBJECT_VALIDATE_STATUS_ARB */
-   { 22368, 0x00008165 }, /* GL_OCCLUSION_TEST_HP */
-   { 22389, 0x00008166 }, /* GL_OCCLUSION_TEST_RESULT_HP */
-   { 22417, 0x00000001 }, /* GL_ONE */
-   { 22424, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA */
-   { 22452, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA_EXT */
-   { 22484, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR */
-   { 22512, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR_EXT */
-   { 22544, 0x00000305 }, /* GL_ONE_MINUS_DST_ALPHA */
-   { 22567, 0x00000307 }, /* GL_ONE_MINUS_DST_COLOR */
-   { 22590, 0x00000303 }, /* GL_ONE_MINUS_SRC_ALPHA */
-   { 22613, 0x00000301 }, /* GL_ONE_MINUS_SRC_COLOR */
-   { 22636, 0x00008598 }, /* GL_OPERAND0_ALPHA */
-   { 22654, 0x00008598 }, /* GL_OPERAND0_ALPHA_ARB */
-   { 22676, 0x00008598 }, /* GL_OPERAND0_ALPHA_EXT */
-   { 22698, 0x00008590 }, /* GL_OPERAND0_RGB */
-   { 22714, 0x00008590 }, /* GL_OPERAND0_RGB_ARB */
-   { 22734, 0x00008590 }, /* GL_OPERAND0_RGB_EXT */
-   { 22754, 0x00008599 }, /* GL_OPERAND1_ALPHA */
-   { 22772, 0x00008599 }, /* GL_OPERAND1_ALPHA_ARB */
-   { 22794, 0x00008599 }, /* GL_OPERAND1_ALPHA_EXT */
-   { 22816, 0x00008591 }, /* GL_OPERAND1_RGB */
-   { 22832, 0x00008591 }, /* GL_OPERAND1_RGB_ARB */
-   { 22852, 0x00008591 }, /* GL_OPERAND1_RGB_EXT */
-   { 22872, 0x0000859A }, /* GL_OPERAND2_ALPHA */
-   { 22890, 0x0000859A }, /* GL_OPERAND2_ALPHA_ARB */
-   { 22912, 0x0000859A }, /* GL_OPERAND2_ALPHA_EXT */
-   { 22934, 0x00008592 }, /* GL_OPERAND2_RGB */
-   { 22950, 0x00008592 }, /* GL_OPERAND2_RGB_ARB */
-   { 22970, 0x00008592 }, /* GL_OPERAND2_RGB_EXT */
-   { 22990, 0x0000859B }, /* GL_OPERAND3_ALPHA_NV */
-   { 23011, 0x00008593 }, /* GL_OPERAND3_RGB_NV */
-   { 23030, 0x00001507 }, /* GL_OR */
-   { 23036, 0x00000A01 }, /* GL_ORDER */
-   { 23045, 0x0000150D }, /* GL_OR_INVERTED */
-   { 23060, 0x0000150B }, /* GL_OR_REVERSE */
-   { 23074, 0x00000505 }, /* GL_OUT_OF_MEMORY */
-   { 23091, 0x00000D05 }, /* GL_PACK_ALIGNMENT */
-   { 23109, 0x0000806C }, /* GL_PACK_IMAGE_HEIGHT */
-   { 23130, 0x00008758 }, /* GL_PACK_INVERT_MESA */
-   { 23150, 0x00000D01 }, /* GL_PACK_LSB_FIRST */
-   { 23168, 0x00000D02 }, /* GL_PACK_ROW_LENGTH */
-   { 23187, 0x0000806B }, /* GL_PACK_SKIP_IMAGES */
-   { 23207, 0x00000D04 }, /* GL_PACK_SKIP_PIXELS */
-   { 23227, 0x00000D03 }, /* GL_PACK_SKIP_ROWS */
-   { 23245, 0x00000D00 }, /* GL_PACK_SWAP_BYTES */
-   { 23264, 0x00008B92 }, /* GL_PALETTE4_R5_G6_B5_OES */
-   { 23289, 0x00008B94 }, /* GL_PALETTE4_RGB5_A1_OES */
-   { 23313, 0x00008B90 }, /* GL_PALETTE4_RGB8_OES */
-   { 23334, 0x00008B93 }, /* GL_PALETTE4_RGBA4_OES */
-   { 23356, 0x00008B91 }, /* GL_PALETTE4_RGBA8_OES */
-   { 23378, 0x00008B97 }, /* GL_PALETTE8_R5_G6_B5_OES */
-   { 23403, 0x00008B99 }, /* GL_PALETTE8_RGB5_A1_OES */
-   { 23427, 0x00008B95 }, /* GL_PALETTE8_RGB8_OES */
-   { 23448, 0x00008B98 }, /* GL_PALETTE8_RGBA4_OES */
-   { 23470, 0x00008B96 }, /* GL_PALETTE8_RGBA8_OES */
-   { 23492, 0x00000700 }, /* GL_PASS_THROUGH_TOKEN */
-   { 23514, 0x00000C50 }, /* GL_PERSPECTIVE_CORRECTION_HINT */
-   { 23545, 0x00000C79 }, /* GL_PIXEL_MAP_A_TO_A */
-   { 23565, 0x00000CB9 }, /* GL_PIXEL_MAP_A_TO_A_SIZE */
-   { 23590, 0x00000C78 }, /* GL_PIXEL_MAP_B_TO_B */
-   { 23610, 0x00000CB8 }, /* GL_PIXEL_MAP_B_TO_B_SIZE */
-   { 23635, 0x00000C77 }, /* GL_PIXEL_MAP_G_TO_G */
-   { 23655, 0x00000CB7 }, /* GL_PIXEL_MAP_G_TO_G_SIZE */
-   { 23680, 0x00000C75 }, /* GL_PIXEL_MAP_I_TO_A */
-   { 23700, 0x00000CB5 }, /* GL_PIXEL_MAP_I_TO_A_SIZE */
-   { 23725, 0x00000C74 }, /* GL_PIXEL_MAP_I_TO_B */
-   { 23745, 0x00000CB4 }, /* GL_PIXEL_MAP_I_TO_B_SIZE */
-   { 23770, 0x00000C73 }, /* GL_PIXEL_MAP_I_TO_G */
-   { 23790, 0x00000CB3 }, /* GL_PIXEL_MAP_I_TO_G_SIZE */
-   { 23815, 0x00000C70 }, /* GL_PIXEL_MAP_I_TO_I */
-   { 23835, 0x00000CB0 }, /* GL_PIXEL_MAP_I_TO_I_SIZE */
-   { 23860, 0x00000C72 }, /* GL_PIXEL_MAP_I_TO_R */
-   { 23880, 0x00000CB2 }, /* GL_PIXEL_MAP_I_TO_R_SIZE */
-   { 23905, 0x00000C76 }, /* GL_PIXEL_MAP_R_TO_R */
-   { 23925, 0x00000CB6 }, /* GL_PIXEL_MAP_R_TO_R_SIZE */
-   { 23950, 0x00000C71 }, /* GL_PIXEL_MAP_S_TO_S */
-   { 23970, 0x00000CB1 }, /* GL_PIXEL_MAP_S_TO_S_SIZE */
-   { 23995, 0x00000020 }, /* GL_PIXEL_MODE_BIT */
-   { 24013, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER */
-   { 24034, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING */
-   { 24063, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING_EXT */
-   { 24096, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER_EXT */
-   { 24121, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER */
-   { 24144, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING */
-   { 24175, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING_EXT */
-   { 24210, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER_EXT */
-   { 24237, 0x00001B00 }, /* GL_POINT */
-   { 24246, 0x00000000 }, /* GL_POINTS */
-   { 24256, 0x00000002 }, /* GL_POINT_BIT */
-   { 24269, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION */
-   { 24299, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_ARB */
-   { 24333, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_EXT */
-   { 24367, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_SGIS */
-   { 24402, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE */
-   { 24431, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_ARB */
-   { 24464, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_EXT */
-   { 24497, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_SGIS */
-   { 24531, 0x00000B11 }, /* GL_POINT_SIZE */
-   { 24545, 0x00000B13 }, /* GL_POINT_SIZE_GRANULARITY */
-   { 24571, 0x00008127 }, /* GL_POINT_SIZE_MAX */
-   { 24589, 0x00008127 }, /* GL_POINT_SIZE_MAX_ARB */
-   { 24611, 0x00008127 }, /* GL_POINT_SIZE_MAX_EXT */
-   { 24633, 0x00008127 }, /* GL_POINT_SIZE_MAX_SGIS */
-   { 24656, 0x00008126 }, /* GL_POINT_SIZE_MIN */
-   { 24674, 0x00008126 }, /* GL_POINT_SIZE_MIN_ARB */
-   { 24696, 0x00008126 }, /* GL_POINT_SIZE_MIN_EXT */
-   { 24718, 0x00008126 }, /* GL_POINT_SIZE_MIN_SGIS */
-   { 24741, 0x00000B12 }, /* GL_POINT_SIZE_RANGE */
-   { 24761, 0x00000B10 }, /* GL_POINT_SMOOTH */
-   { 24777, 0x00000C51 }, /* GL_POINT_SMOOTH_HINT */
-   { 24798, 0x00008861 }, /* GL_POINT_SPRITE */
-   { 24814, 0x00008861 }, /* GL_POINT_SPRITE_ARB */
-   { 24834, 0x00008CA0 }, /* GL_POINT_SPRITE_COORD_ORIGIN */
-   { 24863, 0x00008861 }, /* GL_POINT_SPRITE_NV */
-   { 24882, 0x00008863 }, /* GL_POINT_SPRITE_R_MODE_NV */
-   { 24908, 0x00000701 }, /* GL_POINT_TOKEN */
-   { 24923, 0x00000009 }, /* GL_POLYGON */
-   { 24934, 0x00000008 }, /* GL_POLYGON_BIT */
-   { 24949, 0x00000B40 }, /* GL_POLYGON_MODE */
-   { 24965, 0x00008039 }, /* GL_POLYGON_OFFSET_BIAS */
-   { 24988, 0x00008038 }, /* GL_POLYGON_OFFSET_FACTOR */
-   { 25013, 0x00008037 }, /* GL_POLYGON_OFFSET_FILL */
-   { 25036, 0x00002A02 }, /* GL_POLYGON_OFFSET_LINE */
-   { 25059, 0x00002A01 }, /* GL_POLYGON_OFFSET_POINT */
-   { 25083, 0x00002A00 }, /* GL_POLYGON_OFFSET_UNITS */
-   { 25107, 0x00000B41 }, /* GL_POLYGON_SMOOTH */
-   { 25125, 0x00000C53 }, /* GL_POLYGON_SMOOTH_HINT */
-   { 25148, 0x00000B42 }, /* GL_POLYGON_STIPPLE */
-   { 25167, 0x00000010 }, /* GL_POLYGON_STIPPLE_BIT */
-   { 25190, 0x00000703 }, /* GL_POLYGON_TOKEN */
-   { 25207, 0x00001203 }, /* GL_POSITION */
-   { 25219, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
-   { 25251, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI */
-   { 25287, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
-   { 25320, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI */
-   { 25357, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
-   { 25388, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI */
-   { 25423, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
-   { 25455, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI */
-   { 25491, 0x000080D2 }, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
-   { 25524, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
-   { 25556, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI */
-   { 25592, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
-   { 25625, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI */
-   { 25662, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS */
-   { 25692, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS_SGI */
-   { 25726, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE */
-   { 25757, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE_SGI */
-   { 25792, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
-   { 25823, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS_EXT */
-   { 25858, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
-   { 25890, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE_EXT */
-   { 25926, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS */
-   { 25956, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS_EXT */
-   { 25990, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE */
-   { 26021, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE_EXT */
-   { 26056, 0x000080D1 }, /* GL_POST_CONVOLUTION_COLOR_TABLE */
-   { 26088, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS */
-   { 26119, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS_EXT */
-   { 26154, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE */
-   { 26186, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE_EXT */
-   { 26222, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS */
-   { 26251, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS_EXT */
-   { 26284, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE */
-   { 26314, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE_EXT */
-   { 26348, 0x0000817B }, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
-   { 26387, 0x00008179 }, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
-   { 26420, 0x0000817C }, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
-   { 26460, 0x0000817A }, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
-   { 26494, 0x00008578 }, /* GL_PREVIOUS */
-   { 26506, 0x00008578 }, /* GL_PREVIOUS_ARB */
-   { 26522, 0x00008578 }, /* GL_PREVIOUS_EXT */
-   { 26538, 0x00008577 }, /* GL_PRIMARY_COLOR */
-   { 26555, 0x00008577 }, /* GL_PRIMARY_COLOR_ARB */
-   { 26576, 0x00008577 }, /* GL_PRIMARY_COLOR_EXT */
-   { 26597, 0x000088B0 }, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
-   { 26630, 0x00008805 }, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
-   { 26662, 0x000088AC }, /* GL_PROGRAM_ATTRIBS_ARB */
-   { 26685, 0x00008677 }, /* GL_PROGRAM_BINDING_ARB */
-   { 26708, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_ARB */
-   { 26738, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_NV */
-   { 26767, 0x00008874 }, /* GL_PROGRAM_ERROR_STRING_ARB */
-   { 26795, 0x00008876 }, /* GL_PROGRAM_FORMAT_ARB */
-   { 26817, 0x00008875 }, /* GL_PROGRAM_FORMAT_ASCII_ARB */
-   { 26845, 0x000088A0 }, /* GL_PROGRAM_INSTRUCTIONS_ARB */
-   { 26873, 0x00008627 }, /* GL_PROGRAM_LENGTH_ARB */
-   { 26895, 0x00008627 }, /* GL_PROGRAM_LENGTH_NV */
-   { 26916, 0x000088B2 }, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
-   { 26956, 0x00008808 }, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
-   { 26995, 0x000088AE }, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
-   { 27025, 0x000088A2 }, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
-   { 27060, 0x000088AA }, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
-   { 27093, 0x000088A6 }, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
-   { 27127, 0x0000880A }, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
-   { 27166, 0x00008809 }, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
-   { 27205, 0x00008B40 }, /* GL_PROGRAM_OBJECT_ARB */
-   { 27227, 0x000088A8 }, /* GL_PROGRAM_PARAMETERS_ARB */
-   { 27253, 0x00008644 }, /* GL_PROGRAM_PARAMETER_NV */
-   { 27277, 0x00008647 }, /* GL_PROGRAM_RESIDENT_NV */
-   { 27300, 0x00008628 }, /* GL_PROGRAM_STRING_ARB */
-   { 27322, 0x00008628 }, /* GL_PROGRAM_STRING_NV */
-   { 27343, 0x00008646 }, /* GL_PROGRAM_TARGET_NV */
-   { 27364, 0x000088A4 }, /* GL_PROGRAM_TEMPORARIES_ARB */
-   { 27391, 0x00008807 }, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
-   { 27423, 0x00008806 }, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
-   { 27455, 0x000088B6 }, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
-   { 27490, 0x00001701 }, /* GL_PROJECTION */
-   { 27504, 0x00000BA7 }, /* GL_PROJECTION_MATRIX */
-   { 27525, 0x00000BA4 }, /* GL_PROJECTION_STACK_DEPTH */
-   { 27551, 0x00008E4F }, /* GL_PROVOKING_VERTEX */
-   { 27571, 0x00008E4F }, /* GL_PROVOKING_VERTEX_EXT */
-   { 27595, 0x000080D3 }, /* GL_PROXY_COLOR_TABLE */
-   { 27616, 0x00008025 }, /* GL_PROXY_HISTOGRAM */
-   { 27635, 0x00008025 }, /* GL_PROXY_HISTOGRAM_EXT */
-   { 27658, 0x000080D5 }, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
-   { 27697, 0x000080D4 }, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
-   { 27735, 0x00008063 }, /* GL_PROXY_TEXTURE_1D */
-   { 27755, 0x00008C19 }, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */
-   { 27785, 0x00008063 }, /* GL_PROXY_TEXTURE_1D_EXT */
-   { 27809, 0x00008064 }, /* GL_PROXY_TEXTURE_2D */
-   { 27829, 0x00008C1B }, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */
-   { 27859, 0x00008064 }, /* GL_PROXY_TEXTURE_2D_EXT */
-   { 27883, 0x00008070 }, /* GL_PROXY_TEXTURE_3D */
-   { 27903, 0x000080BD }, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
-   { 27936, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP */
-   { 27962, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP_ARB */
-   { 27992, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */
-   { 28023, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_NV */
-   { 28053, 0x00002003 }, /* GL_Q */
-   { 28058, 0x00001209 }, /* GL_QUADRATIC_ATTENUATION */
-   { 28083, 0x00000007 }, /* GL_QUADS */
-   { 28092, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */
-   { 28136, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT */
-   { 28184, 0x00008614 }, /* GL_QUAD_MESH_SUN */
-   { 28201, 0x00000008 }, /* GL_QUAD_STRIP */
-   { 28215, 0x00008864 }, /* GL_QUERY_COUNTER_BITS */
-   { 28237, 0x00008864 }, /* GL_QUERY_COUNTER_BITS_ARB */
-   { 28263, 0x00008866 }, /* GL_QUERY_RESULT */
-   { 28279, 0x00008866 }, /* GL_QUERY_RESULT_ARB */
-   { 28299, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE */
-   { 28325, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE_ARB */
-   { 28355, 0x00002002 }, /* GL_R */
-   { 28360, 0x00002A10 }, /* GL_R3_G3_B2 */
-   { 28372, 0x00019262 }, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
-   { 28405, 0x00000C02 }, /* GL_READ_BUFFER */
-   { 28420, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER */
-   { 28440, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING_EXT */
-   { 28472, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER_EXT */
-   { 28496, 0x000088B8 }, /* GL_READ_ONLY */
-   { 28509, 0x000088B8 }, /* GL_READ_ONLY_ARB */
-   { 28526, 0x000088BA }, /* GL_READ_WRITE */
-   { 28540, 0x000088BA }, /* GL_READ_WRITE_ARB */
-   { 28558, 0x00001903 }, /* GL_RED */
-   { 28565, 0x00008016 }, /* GL_REDUCE */
-   { 28575, 0x00008016 }, /* GL_REDUCE_EXT */
-   { 28589, 0x00000D15 }, /* GL_RED_BIAS */
-   { 28601, 0x00000D52 }, /* GL_RED_BITS */
-   { 28613, 0x00000D14 }, /* GL_RED_SCALE */
-   { 28626, 0x00008512 }, /* GL_REFLECTION_MAP */
-   { 28644, 0x00008512 }, /* GL_REFLECTION_MAP_ARB */
-   { 28666, 0x00008512 }, /* GL_REFLECTION_MAP_NV */
-   { 28687, 0x00001C00 }, /* GL_RENDER */
-   { 28697, 0x00008D41 }, /* GL_RENDERBUFFER */
-   { 28713, 0x00008D53 }, /* GL_RENDERBUFFER_ALPHA_SIZE */
-   { 28740, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING_EXT */
-   { 28768, 0x00008D52 }, /* GL_RENDERBUFFER_BLUE_SIZE */
-   { 28794, 0x00008D54 }, /* GL_RENDERBUFFER_DEPTH_SIZE */
-   { 28821, 0x00008D41 }, /* GL_RENDERBUFFER_EXT */
-   { 28841, 0x00008D51 }, /* GL_RENDERBUFFER_GREEN_SIZE */
-   { 28868, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT */
-   { 28891, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT_EXT */
-   { 28918, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
-   { 28950, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT_EXT */
-   { 28986, 0x00008D50 }, /* GL_RENDERBUFFER_RED_SIZE */
-   { 29011, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES */
-   { 29035, 0x00008D55 }, /* GL_RENDERBUFFER_STENCIL_SIZE */
-   { 29064, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH */
-   { 29086, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH_EXT */
-   { 29112, 0x00001F01 }, /* GL_RENDERER */
-   { 29124, 0x00000C40 }, /* GL_RENDER_MODE */
-   { 29139, 0x00002901 }, /* GL_REPEAT */
-   { 29149, 0x00001E01 }, /* GL_REPLACE */
-   { 29160, 0x00008062 }, /* GL_REPLACE_EXT */
-   { 29175, 0x00008153 }, /* GL_REPLICATE_BORDER_HP */
-   { 29198, 0x0000803A }, /* GL_RESCALE_NORMAL */
-   { 29216, 0x0000803A }, /* GL_RESCALE_NORMAL_EXT */
-   { 29238, 0x00000102 }, /* GL_RETURN */
-   { 29248, 0x00001907 }, /* GL_RGB */
-   { 29255, 0x00008052 }, /* GL_RGB10 */
-   { 29264, 0x00008059 }, /* GL_RGB10_A2 */
-   { 29276, 0x00008059 }, /* GL_RGB10_A2_EXT */
-   { 29292, 0x00008052 }, /* GL_RGB10_EXT */
-   { 29305, 0x00008053 }, /* GL_RGB12 */
-   { 29314, 0x00008053 }, /* GL_RGB12_EXT */
-   { 29327, 0x00008054 }, /* GL_RGB16 */
-   { 29336, 0x00008054 }, /* GL_RGB16_EXT */
-   { 29349, 0x0000804E }, /* GL_RGB2_EXT */
-   { 29361, 0x0000804F }, /* GL_RGB4 */
-   { 29369, 0x0000804F }, /* GL_RGB4_EXT */
-   { 29381, 0x000083A1 }, /* GL_RGB4_S3TC */
-   { 29394, 0x00008050 }, /* GL_RGB5 */
-   { 29402, 0x00008057 }, /* GL_RGB5_A1 */
-   { 29413, 0x00008057 }, /* GL_RGB5_A1_EXT */
-   { 29428, 0x00008050 }, /* GL_RGB5_EXT */
-   { 29440, 0x00008051 }, /* GL_RGB8 */
-   { 29448, 0x00008051 }, /* GL_RGB8_EXT */
-   { 29460, 0x00001908 }, /* GL_RGBA */
-   { 29468, 0x0000805A }, /* GL_RGBA12 */
-   { 29478, 0x0000805A }, /* GL_RGBA12_EXT */
-   { 29492, 0x0000805B }, /* GL_RGBA16 */
-   { 29502, 0x0000805B }, /* GL_RGBA16_EXT */
-   { 29516, 0x00008055 }, /* GL_RGBA2 */
-   { 29525, 0x00008055 }, /* GL_RGBA2_EXT */
-   { 29538, 0x00008056 }, /* GL_RGBA4 */
-   { 29547, 0x000083A5 }, /* GL_RGBA4_DXT5_S3TC */
-   { 29566, 0x00008056 }, /* GL_RGBA4_EXT */
-   { 29579, 0x000083A3 }, /* GL_RGBA4_S3TC */
-   { 29593, 0x00008058 }, /* GL_RGBA8 */
-   { 29602, 0x00008058 }, /* GL_RGBA8_EXT */
-   { 29615, 0x00008F97 }, /* GL_RGBA8_SNORM */
-   { 29630, 0x000083A4 }, /* GL_RGBA_DXT5_S3TC */
-   { 29648, 0x00000C31 }, /* GL_RGBA_MODE */
-   { 29661, 0x000083A2 }, /* GL_RGBA_S3TC */
-   { 29674, 0x00008F93 }, /* GL_RGBA_SNORM */
-   { 29688, 0x000083A0 }, /* GL_RGB_S3TC */
-   { 29700, 0x00008573 }, /* GL_RGB_SCALE */
-   { 29713, 0x00008573 }, /* GL_RGB_SCALE_ARB */
-   { 29730, 0x00008573 }, /* GL_RGB_SCALE_EXT */
-   { 29747, 0x00000407 }, /* GL_RIGHT */
-   { 29756, 0x00002000 }, /* GL_S */
-   { 29761, 0x00008B5D }, /* GL_SAMPLER_1D */
-   { 29775, 0x00008B61 }, /* GL_SAMPLER_1D_SHADOW */
-   { 29796, 0x00008B5E }, /* GL_SAMPLER_2D */
-   { 29810, 0x00008B62 }, /* GL_SAMPLER_2D_SHADOW */
-   { 29831, 0x00008B5F }, /* GL_SAMPLER_3D */
-   { 29845, 0x00008B60 }, /* GL_SAMPLER_CUBE */
-   { 29861, 0x000080A9 }, /* GL_SAMPLES */
-   { 29872, 0x000086B4 }, /* GL_SAMPLES_3DFX */
-   { 29888, 0x000080A9 }, /* GL_SAMPLES_ARB */
-   { 29903, 0x00008914 }, /* GL_SAMPLES_PASSED */
-   { 29921, 0x00008914 }, /* GL_SAMPLES_PASSED_ARB */
-   { 29943, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
-   { 29971, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE_ARB */
-   { 30003, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE */
-   { 30026, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE_ARB */
-   { 30053, 0x000080A8 }, /* GL_SAMPLE_BUFFERS */
-   { 30071, 0x000086B3 }, /* GL_SAMPLE_BUFFERS_3DFX */
-   { 30094, 0x000080A8 }, /* GL_SAMPLE_BUFFERS_ARB */
-   { 30116, 0x000080A0 }, /* GL_SAMPLE_COVERAGE */
-   { 30135, 0x000080A0 }, /* GL_SAMPLE_COVERAGE_ARB */
-   { 30158, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT */
-   { 30184, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT_ARB */
-   { 30214, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE */
-   { 30239, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE_ARB */
-   { 30268, 0x00080000 }, /* GL_SCISSOR_BIT */
-   { 30283, 0x00000C10 }, /* GL_SCISSOR_BOX */
-   { 30298, 0x00000C11 }, /* GL_SCISSOR_TEST */
-   { 30314, 0x0000845E }, /* GL_SECONDARY_COLOR_ARRAY */
-   { 30339, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
-   { 30379, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB */
-   { 30423, 0x0000845D }, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
-   { 30456, 0x0000845A }, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
-   { 30486, 0x0000845C }, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
-   { 30518, 0x0000845B }, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
-   { 30548, 0x00001C02 }, /* GL_SELECT */
-   { 30558, 0x00000DF3 }, /* GL_SELECTION_BUFFER_POINTER */
-   { 30586, 0x00000DF4 }, /* GL_SELECTION_BUFFER_SIZE */
-   { 30611, 0x00008012 }, /* GL_SEPARABLE_2D */
-   { 30627, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR */
-   { 30654, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR_EXT */
-   { 30685, 0x0000150F }, /* GL_SET */
-   { 30692, 0x00008B48 }, /* GL_SHADER_OBJECT_ARB */
-   { 30713, 0x00008B88 }, /* GL_SHADER_SOURCE_LENGTH */
-   { 30737, 0x00008B4F }, /* GL_SHADER_TYPE */
-   { 30752, 0x00000B54 }, /* GL_SHADE_MODEL */
-   { 30767, 0x00008B8C }, /* GL_SHADING_LANGUAGE_VERSION */
-   { 30795, 0x000080BF }, /* GL_SHADOW_AMBIENT_SGIX */
-   { 30818, 0x000081FB }, /* GL_SHARED_TEXTURE_PALETTE_EXT */
-   { 30848, 0x00001601 }, /* GL_SHININESS */
-   { 30861, 0x00001402 }, /* GL_SHORT */
-   { 30870, 0x00009119 }, /* GL_SIGNALED */
-   { 30882, 0x00008F9C }, /* GL_SIGNED_NORMALIZED */
-   { 30903, 0x000081F9 }, /* GL_SINGLE_COLOR */
-   { 30919, 0x000081F9 }, /* GL_SINGLE_COLOR_EXT */
-   { 30939, 0x000085CC }, /* GL_SLICE_ACCUM_SUN */
-   { 30958, 0x00008C46 }, /* GL_SLUMINANCE */
-   { 30972, 0x00008C47 }, /* GL_SLUMINANCE8 */
-   { 30987, 0x00008C45 }, /* GL_SLUMINANCE8_ALPHA8 */
-   { 31009, 0x00008C44 }, /* GL_SLUMINANCE_ALPHA */
-   { 31029, 0x00001D01 }, /* GL_SMOOTH */
-   { 31039, 0x00000B23 }, /* GL_SMOOTH_LINE_WIDTH_GRANULARITY */
-   { 31072, 0x00000B22 }, /* GL_SMOOTH_LINE_WIDTH_RANGE */
-   { 31099, 0x00000B13 }, /* GL_SMOOTH_POINT_SIZE_GRANULARITY */
-   { 31132, 0x00000B12 }, /* GL_SMOOTH_POINT_SIZE_RANGE */
-   { 31159, 0x00008588 }, /* GL_SOURCE0_ALPHA */
-   { 31176, 0x00008588 }, /* GL_SOURCE0_ALPHA_ARB */
-   { 31197, 0x00008588 }, /* GL_SOURCE0_ALPHA_EXT */
-   { 31218, 0x00008580 }, /* GL_SOURCE0_RGB */
-   { 31233, 0x00008580 }, /* GL_SOURCE0_RGB_ARB */
-   { 31252, 0x00008580 }, /* GL_SOURCE0_RGB_EXT */
-   { 31271, 0x00008589 }, /* GL_SOURCE1_ALPHA */
-   { 31288, 0x00008589 }, /* GL_SOURCE1_ALPHA_ARB */
-   { 31309, 0x00008589 }, /* GL_SOURCE1_ALPHA_EXT */
-   { 31330, 0x00008581 }, /* GL_SOURCE1_RGB */
-   { 31345, 0x00008581 }, /* GL_SOURCE1_RGB_ARB */
-   { 31364, 0x00008581 }, /* GL_SOURCE1_RGB_EXT */
-   { 31383, 0x0000858A }, /* GL_SOURCE2_ALPHA */
-   { 31400, 0x0000858A }, /* GL_SOURCE2_ALPHA_ARB */
-   { 31421, 0x0000858A }, /* GL_SOURCE2_ALPHA_EXT */
-   { 31442, 0x00008582 }, /* GL_SOURCE2_RGB */
-   { 31457, 0x00008582 }, /* GL_SOURCE2_RGB_ARB */
-   { 31476, 0x00008582 }, /* GL_SOURCE2_RGB_EXT */
-   { 31495, 0x0000858B }, /* GL_SOURCE3_ALPHA_NV */
-   { 31515, 0x00008583 }, /* GL_SOURCE3_RGB_NV */
-   { 31533, 0x00001202 }, /* GL_SPECULAR */
-   { 31545, 0x00002402 }, /* GL_SPHERE_MAP */
-   { 31559, 0x00001206 }, /* GL_SPOT_CUTOFF */
-   { 31574, 0x00001204 }, /* GL_SPOT_DIRECTION */
-   { 31592, 0x00001205 }, /* GL_SPOT_EXPONENT */
-   { 31609, 0x00008588 }, /* GL_SRC0_ALPHA */
-   { 31623, 0x00008580 }, /* GL_SRC0_RGB */
-   { 31635, 0x00008589 }, /* GL_SRC1_ALPHA */
-   { 31649, 0x00008581 }, /* GL_SRC1_RGB */
-   { 31661, 0x0000858A }, /* GL_SRC2_ALPHA */
-   { 31675, 0x00008582 }, /* GL_SRC2_RGB */
-   { 31687, 0x00000302 }, /* GL_SRC_ALPHA */
-   { 31700, 0x00000308 }, /* GL_SRC_ALPHA_SATURATE */
-   { 31722, 0x00000300 }, /* GL_SRC_COLOR */
-   { 31735, 0x00008C40 }, /* GL_SRGB */
-   { 31743, 0x00008C41 }, /* GL_SRGB8 */
-   { 31752, 0x00008C43 }, /* GL_SRGB8_ALPHA8 */
-   { 31768, 0x00008C42 }, /* GL_SRGB_ALPHA */
-   { 31782, 0x00000503 }, /* GL_STACK_OVERFLOW */
-   { 31800, 0x00000504 }, /* GL_STACK_UNDERFLOW */
-   { 31819, 0x000088E6 }, /* GL_STATIC_COPY */
-   { 31834, 0x000088E6 }, /* GL_STATIC_COPY_ARB */
-   { 31853, 0x000088E4 }, /* GL_STATIC_DRAW */
-   { 31868, 0x000088E4 }, /* GL_STATIC_DRAW_ARB */
-   { 31887, 0x000088E5 }, /* GL_STATIC_READ */
-   { 31902, 0x000088E5 }, /* GL_STATIC_READ_ARB */
-   { 31921, 0x00001802 }, /* GL_STENCIL */
-   { 31932, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT */
-   { 31954, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT_EXT */
-   { 31980, 0x00008801 }, /* GL_STENCIL_BACK_FAIL */
-   { 32001, 0x00008801 }, /* GL_STENCIL_BACK_FAIL_ATI */
-   { 32026, 0x00008800 }, /* GL_STENCIL_BACK_FUNC */
-   { 32047, 0x00008800 }, /* GL_STENCIL_BACK_FUNC_ATI */
-   { 32072, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
-   { 32104, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI */
-   { 32140, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
-   { 32172, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI */
-   { 32208, 0x00008CA3 }, /* GL_STENCIL_BACK_REF */
-   { 32228, 0x00008CA4 }, /* GL_STENCIL_BACK_VALUE_MASK */
-   { 32255, 0x00008CA5 }, /* GL_STENCIL_BACK_WRITEMASK */
-   { 32281, 0x00000D57 }, /* GL_STENCIL_BITS */
-   { 32297, 0x00000400 }, /* GL_STENCIL_BUFFER_BIT */
-   { 32319, 0x00000B91 }, /* GL_STENCIL_CLEAR_VALUE */
-   { 32342, 0x00000B94 }, /* GL_STENCIL_FAIL */
-   { 32358, 0x00000B92 }, /* GL_STENCIL_FUNC */
-   { 32374, 0x00001901 }, /* GL_STENCIL_INDEX */
-   { 32391, 0x00008D49 }, /* GL_STENCIL_INDEX16_EXT */
-   { 32414, 0x00008D46 }, /* GL_STENCIL_INDEX1_EXT */
-   { 32436, 0x00008D47 }, /* GL_STENCIL_INDEX4_EXT */
-   { 32458, 0x00008D48 }, /* GL_STENCIL_INDEX8_EXT */
-   { 32480, 0x00008D45 }, /* GL_STENCIL_INDEX_EXT */
-   { 32501, 0x00000B95 }, /* GL_STENCIL_PASS_DEPTH_FAIL */
-   { 32528, 0x00000B96 }, /* GL_STENCIL_PASS_DEPTH_PASS */
-   { 32555, 0x00000B97 }, /* GL_STENCIL_REF */
-   { 32570, 0x00000B90 }, /* GL_STENCIL_TEST */
-   { 32586, 0x00008910 }, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
-   { 32615, 0x00000B93 }, /* GL_STENCIL_VALUE_MASK */
-   { 32637, 0x00000B98 }, /* GL_STENCIL_WRITEMASK */
-   { 32658, 0x00000C33 }, /* GL_STEREO */
-   { 32668, 0x000085BE }, /* GL_STORAGE_CACHED_APPLE */
-   { 32692, 0x000085BD }, /* GL_STORAGE_PRIVATE_APPLE */
-   { 32717, 0x000085BF }, /* GL_STORAGE_SHARED_APPLE */
-   { 32741, 0x000088E2 }, /* GL_STREAM_COPY */
-   { 32756, 0x000088E2 }, /* GL_STREAM_COPY_ARB */
-   { 32775, 0x000088E0 }, /* GL_STREAM_DRAW */
-   { 32790, 0x000088E0 }, /* GL_STREAM_DRAW_ARB */
-   { 32809, 0x000088E1 }, /* GL_STREAM_READ */
-   { 32824, 0x000088E1 }, /* GL_STREAM_READ_ARB */
-   { 32843, 0x00000D50 }, /* GL_SUBPIXEL_BITS */
-   { 32860, 0x000084E7 }, /* GL_SUBTRACT */
-   { 32872, 0x000084E7 }, /* GL_SUBTRACT_ARB */
-   { 32888, 0x00009113 }, /* GL_SYNC_CONDITION */
-   { 32906, 0x00009116 }, /* GL_SYNC_FENCE */
-   { 32920, 0x00009115 }, /* GL_SYNC_FLAGS */
-   { 32934, 0x00000001 }, /* GL_SYNC_FLUSH_COMMANDS_BIT */
-   { 32961, 0x00009117 }, /* GL_SYNC_GPU_COMMANDS_COMPLETE */
-   { 32991, 0x00009114 }, /* GL_SYNC_STATUS */
-   { 33006, 0x00002001 }, /* GL_T */
-   { 33011, 0x00002A2A }, /* GL_T2F_C3F_V3F */
-   { 33026, 0x00002A2C }, /* GL_T2F_C4F_N3F_V3F */
-   { 33045, 0x00002A29 }, /* GL_T2F_C4UB_V3F */
-   { 33061, 0x00002A2B }, /* GL_T2F_N3F_V3F */
-   { 33076, 0x00002A27 }, /* GL_T2F_V3F */
-   { 33087, 0x00002A2D }, /* GL_T4F_C4F_N3F_V4F */
-   { 33106, 0x00002A28 }, /* GL_T4F_V4F */
-   { 33117, 0x00008031 }, /* GL_TABLE_TOO_LARGE_EXT */
-   { 33140, 0x00001702 }, /* GL_TEXTURE */
-   { 33151, 0x000084C0 }, /* GL_TEXTURE0 */
-   { 33163, 0x000084C0 }, /* GL_TEXTURE0_ARB */
-   { 33179, 0x000084C1 }, /* GL_TEXTURE1 */
-   { 33191, 0x000084CA }, /* GL_TEXTURE10 */
-   { 33204, 0x000084CA }, /* GL_TEXTURE10_ARB */
-   { 33221, 0x000084CB }, /* GL_TEXTURE11 */
-   { 33234, 0x000084CB }, /* GL_TEXTURE11_ARB */
-   { 33251, 0x000084CC }, /* GL_TEXTURE12 */
-   { 33264, 0x000084CC }, /* GL_TEXTURE12_ARB */
-   { 33281, 0x000084CD }, /* GL_TEXTURE13 */
-   { 33294, 0x000084CD }, /* GL_TEXTURE13_ARB */
-   { 33311, 0x000084CE }, /* GL_TEXTURE14 */
-   { 33324, 0x000084CE }, /* GL_TEXTURE14_ARB */
-   { 33341, 0x000084CF }, /* GL_TEXTURE15 */
-   { 33354, 0x000084CF }, /* GL_TEXTURE15_ARB */
-   { 33371, 0x000084D0 }, /* GL_TEXTURE16 */
-   { 33384, 0x000084D0 }, /* GL_TEXTURE16_ARB */
-   { 33401, 0x000084D1 }, /* GL_TEXTURE17 */
-   { 33414, 0x000084D1 }, /* GL_TEXTURE17_ARB */
-   { 33431, 0x000084D2 }, /* GL_TEXTURE18 */
-   { 33444, 0x000084D2 }, /* GL_TEXTURE18_ARB */
-   { 33461, 0x000084D3 }, /* GL_TEXTURE19 */
-   { 33474, 0x000084D3 }, /* GL_TEXTURE19_ARB */
-   { 33491, 0x000084C1 }, /* GL_TEXTURE1_ARB */
-   { 33507, 0x000084C2 }, /* GL_TEXTURE2 */
-   { 33519, 0x000084D4 }, /* GL_TEXTURE20 */
-   { 33532, 0x000084D4 }, /* GL_TEXTURE20_ARB */
-   { 33549, 0x000084D5 }, /* GL_TEXTURE21 */
-   { 33562, 0x000084D5 }, /* GL_TEXTURE21_ARB */
-   { 33579, 0x000084D6 }, /* GL_TEXTURE22 */
-   { 33592, 0x000084D6 }, /* GL_TEXTURE22_ARB */
-   { 33609, 0x000084D7 }, /* GL_TEXTURE23 */
-   { 33622, 0x000084D7 }, /* GL_TEXTURE23_ARB */
-   { 33639, 0x000084D8 }, /* GL_TEXTURE24 */
-   { 33652, 0x000084D8 }, /* GL_TEXTURE24_ARB */
-   { 33669, 0x000084D9 }, /* GL_TEXTURE25 */
-   { 33682, 0x000084D9 }, /* GL_TEXTURE25_ARB */
-   { 33699, 0x000084DA }, /* GL_TEXTURE26 */
-   { 33712, 0x000084DA }, /* GL_TEXTURE26_ARB */
-   { 33729, 0x000084DB }, /* GL_TEXTURE27 */
-   { 33742, 0x000084DB }, /* GL_TEXTURE27_ARB */
-   { 33759, 0x000084DC }, /* GL_TEXTURE28 */
-   { 33772, 0x000084DC }, /* GL_TEXTURE28_ARB */
-   { 33789, 0x000084DD }, /* GL_TEXTURE29 */
-   { 33802, 0x000084DD }, /* GL_TEXTURE29_ARB */
-   { 33819, 0x000084C2 }, /* GL_TEXTURE2_ARB */
-   { 33835, 0x000084C3 }, /* GL_TEXTURE3 */
-   { 33847, 0x000084DE }, /* GL_TEXTURE30 */
-   { 33860, 0x000084DE }, /* GL_TEXTURE30_ARB */
-   { 33877, 0x000084DF }, /* GL_TEXTURE31 */
-   { 33890, 0x000084DF }, /* GL_TEXTURE31_ARB */
-   { 33907, 0x000084C3 }, /* GL_TEXTURE3_ARB */
-   { 33923, 0x000084C4 }, /* GL_TEXTURE4 */
-   { 33935, 0x000084C4 }, /* GL_TEXTURE4_ARB */
-   { 33951, 0x000084C5 }, /* GL_TEXTURE5 */
-   { 33963, 0x000084C5 }, /* GL_TEXTURE5_ARB */
-   { 33979, 0x000084C6 }, /* GL_TEXTURE6 */
-   { 33991, 0x000084C6 }, /* GL_TEXTURE6_ARB */
-   { 34007, 0x000084C7 }, /* GL_TEXTURE7 */
-   { 34019, 0x000084C7 }, /* GL_TEXTURE7_ARB */
-   { 34035, 0x000084C8 }, /* GL_TEXTURE8 */
-   { 34047, 0x000084C8 }, /* GL_TEXTURE8_ARB */
-   { 34063, 0x000084C9 }, /* GL_TEXTURE9 */
-   { 34075, 0x000084C9 }, /* GL_TEXTURE9_ARB */
-   { 34091, 0x00000DE0 }, /* GL_TEXTURE_1D */
-   { 34105, 0x00008C18 }, /* GL_TEXTURE_1D_ARRAY_EXT */
-   { 34129, 0x00000DE1 }, /* GL_TEXTURE_2D */
-   { 34143, 0x00008C1A }, /* GL_TEXTURE_2D_ARRAY_EXT */
-   { 34167, 0x0000806F }, /* GL_TEXTURE_3D */
-   { 34181, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE */
-   { 34203, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE_EXT */
-   { 34229, 0x0000813C }, /* GL_TEXTURE_BASE_LEVEL */
-   { 34251, 0x00008068 }, /* GL_TEXTURE_BINDING_1D */
-   { 34273, 0x00008C1C }, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */
-   { 34305, 0x00008069 }, /* GL_TEXTURE_BINDING_2D */
-   { 34327, 0x00008C1D }, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */
-   { 34359, 0x0000806A }, /* GL_TEXTURE_BINDING_3D */
-   { 34381, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP */
-   { 34409, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP_ARB */
-   { 34441, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
-   { 34474, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_NV */
-   { 34506, 0x00040000 }, /* GL_TEXTURE_BIT */
-   { 34521, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE */
-   { 34542, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE_EXT */
-   { 34567, 0x00001005 }, /* GL_TEXTURE_BORDER */
-   { 34585, 0x00001004 }, /* GL_TEXTURE_BORDER_COLOR */
-   { 34609, 0x00008171 }, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
-   { 34640, 0x00008176 }, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
-   { 34670, 0x00008172 }, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
-   { 34700, 0x00008175 }, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
-   { 34735, 0x00008173 }, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
-   { 34766, 0x00008174 }, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
-   { 34804, 0x000080BC }, /* GL_TEXTURE_COLOR_TABLE_SGI */
-   { 34831, 0x000081EF }, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
-   { 34863, 0x000080BF }, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
-   { 34897, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC */
-   { 34921, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC_ARB */
-   { 34949, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE */
-   { 34973, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE_ARB */
-   { 35001, 0x0000819B }, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
-   { 35034, 0x0000819A }, /* GL_TEXTURE_COMPARE_SGIX */
-   { 35058, 0x00001003 }, /* GL_TEXTURE_COMPONENTS */
-   { 35080, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED */
-   { 35102, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED_ARB */
-   { 35128, 0x000086A3 }, /* GL_TEXTURE_COMPRESSED_FORMATS_ARB */
-   { 35162, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
-   { 35195, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB */
-   { 35232, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT */
-   { 35260, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT_ARB */
-   { 35292, 0x00008078 }, /* GL_TEXTURE_COORD_ARRAY */
-   { 35315, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
-   { 35353, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB */
-   { 35395, 0x00008092 }, /* GL_TEXTURE_COORD_ARRAY_POINTER */
-   { 35426, 0x00008088 }, /* GL_TEXTURE_COORD_ARRAY_SIZE */
-   { 35454, 0x0000808A }, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
-   { 35484, 0x00008089 }, /* GL_TEXTURE_COORD_ARRAY_TYPE */
-   { 35512, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP */
-   { 35532, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP_ARB */
-   { 35556, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
-   { 35587, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB */
-   { 35622, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
-   { 35653, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB */
-   { 35688, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
-   { 35719, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB */
-   { 35754, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
-   { 35785, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB */
-   { 35820, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
-   { 35851, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB */
-   { 35886, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
-   { 35917, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB */
-   { 35952, 0x000088F4 }, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */
-   { 35981, 0x00008071 }, /* GL_TEXTURE_DEPTH */
-   { 35998, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE */
-   { 36020, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE_ARB */
-   { 36046, 0x00002300 }, /* GL_TEXTURE_ENV */
-   { 36061, 0x00002201 }, /* GL_TEXTURE_ENV_COLOR */
-   { 36082, 0x00002200 }, /* GL_TEXTURE_ENV_MODE */
-   { 36102, 0x00008500 }, /* GL_TEXTURE_FILTER_CONTROL */
-   { 36128, 0x00002500 }, /* GL_TEXTURE_GEN_MODE */
-   { 36148, 0x00000C63 }, /* GL_TEXTURE_GEN_Q */
-   { 36165, 0x00000C62 }, /* GL_TEXTURE_GEN_R */
-   { 36182, 0x00000C60 }, /* GL_TEXTURE_GEN_S */
-   { 36199, 0x00000C61 }, /* GL_TEXTURE_GEN_T */
-   { 36216, 0x0000819D }, /* GL_TEXTURE_GEQUAL_R_SGIX */
-   { 36241, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE */
-   { 36263, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE_EXT */
-   { 36289, 0x00001001 }, /* GL_TEXTURE_HEIGHT */
-   { 36307, 0x000080ED }, /* GL_TEXTURE_INDEX_SIZE_EXT */
-   { 36333, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE */
-   { 36359, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE_EXT */
-   { 36389, 0x00001003 }, /* GL_TEXTURE_INTERNAL_FORMAT */
-   { 36416, 0x0000819C }, /* GL_TEXTURE_LEQUAL_R_SGIX */
-   { 36441, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS */
-   { 36461, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS_EXT */
-   { 36485, 0x00008190 }, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
-   { 36512, 0x0000818E }, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
-   { 36539, 0x0000818F }, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
-   { 36566, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE */
-   { 36592, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE_EXT */
-   { 36622, 0x00002800 }, /* GL_TEXTURE_MAG_FILTER */
-   { 36644, 0x00000BA8 }, /* GL_TEXTURE_MATRIX */
-   { 36662, 0x000084FE }, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
-   { 36692, 0x0000836B }, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
-   { 36720, 0x00008369 }, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
-   { 36748, 0x0000836A }, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
-   { 36776, 0x0000813D }, /* GL_TEXTURE_MAX_LEVEL */
-   { 36797, 0x0000813B }, /* GL_TEXTURE_MAX_LOD */
-   { 36816, 0x00002801 }, /* GL_TEXTURE_MIN_FILTER */
-   { 36838, 0x0000813A }, /* GL_TEXTURE_MIN_LOD */
-   { 36857, 0x00008066 }, /* GL_TEXTURE_PRIORITY */
-   { 36877, 0x000085B7 }, /* GL_TEXTURE_RANGE_LENGTH_APPLE */
-   { 36907, 0x000085B8 }, /* GL_TEXTURE_RANGE_POINTER_APPLE */
-   { 36938, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_ARB */
-   { 36963, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_NV */
-   { 36987, 0x0000805C }, /* GL_TEXTURE_RED_SIZE */
-   { 37007, 0x0000805C }, /* GL_TEXTURE_RED_SIZE_EXT */
-   { 37031, 0x00008067 }, /* GL_TEXTURE_RESIDENT */
-   { 37051, 0x00000BA5 }, /* GL_TEXTURE_STACK_DEPTH */
-   { 37074, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE */
-   { 37098, 0x000085BC }, /* GL_TEXTURE_STORAGE_HINT_APPLE */
-   { 37128, 0x00008065 }, /* GL_TEXTURE_TOO_LARGE_EXT */
-   { 37153, 0x0000888F }, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
-   { 37187, 0x00001000 }, /* GL_TEXTURE_WIDTH */
-   { 37204, 0x00008072 }, /* GL_TEXTURE_WRAP_R */
-   { 37222, 0x00002802 }, /* GL_TEXTURE_WRAP_S */
-   { 37240, 0x00002803 }, /* GL_TEXTURE_WRAP_T */
-   { 37258, 0x0000911B }, /* GL_TIMEOUT_EXPIRED */
-   { 37277, 0xFFFFFFFFFFFFFFFF }, /* GL_TIMEOUT_IGNORED */
-   { 37296, 0x000088BF }, /* GL_TIME_ELAPSED_EXT */
-   { 37316, 0x00008648 }, /* GL_TRACK_MATRIX_NV */
-   { 37335, 0x00008649 }, /* GL_TRACK_MATRIX_TRANSFORM_NV */
-   { 37364, 0x00001000 }, /* GL_TRANSFORM_BIT */
-   { 37381, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX */
-   { 37407, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX_ARB */
-   { 37437, 0x000088B7 }, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
-   { 37469, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
-   { 37499, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX_ARB */
-   { 37533, 0x0000862C }, /* GL_TRANSPOSE_NV */
-   { 37549, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX */
-   { 37580, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX_ARB */
-   { 37615, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX */
-   { 37643, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX_ARB */
-   { 37675, 0x00000004 }, /* GL_TRIANGLES */
-   { 37688, 0x00000006 }, /* GL_TRIANGLE_FAN */
-   { 37704, 0x00008615 }, /* GL_TRIANGLE_MESH_SUN */
-   { 37725, 0x00000005 }, /* GL_TRIANGLE_STRIP */
-   { 37743, 0x00000001 }, /* GL_TRUE */
-   { 37751, 0x00000CF5 }, /* GL_UNPACK_ALIGNMENT */
-   { 37771, 0x0000806E }, /* GL_UNPACK_IMAGE_HEIGHT */
-   { 37794, 0x00000CF1 }, /* GL_UNPACK_LSB_FIRST */
-   { 37814, 0x00000CF2 }, /* GL_UNPACK_ROW_LENGTH */
-   { 37835, 0x0000806D }, /* GL_UNPACK_SKIP_IMAGES */
-   { 37857, 0x00000CF4 }, /* GL_UNPACK_SKIP_PIXELS */
-   { 37879, 0x00000CF3 }, /* GL_UNPACK_SKIP_ROWS */
-   { 37899, 0x00000CF0 }, /* GL_UNPACK_SWAP_BYTES */
-   { 37920, 0x00009118 }, /* GL_UNSIGNALED */
-   { 37934, 0x00001401 }, /* GL_UNSIGNED_BYTE */
-   { 37951, 0x00008362 }, /* GL_UNSIGNED_BYTE_2_3_3_REV */
-   { 37978, 0x00008032 }, /* GL_UNSIGNED_BYTE_3_3_2 */
-   { 38001, 0x00001405 }, /* GL_UNSIGNED_INT */
-   { 38017, 0x00008036 }, /* GL_UNSIGNED_INT_10_10_10_2 */
-   { 38044, 0x000084FA }, /* GL_UNSIGNED_INT_24_8 */
-   { 38065, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_NV */
-   { 38089, 0x00008368 }, /* GL_UNSIGNED_INT_2_10_10_10_REV */
-   { 38120, 0x00008035 }, /* GL_UNSIGNED_INT_8_8_8_8 */
-   { 38144, 0x00008367 }, /* GL_UNSIGNED_INT_8_8_8_8_REV */
-   { 38172, 0x00008C17 }, /* GL_UNSIGNED_NORMALIZED */
-   { 38195, 0x00001403 }, /* GL_UNSIGNED_SHORT */
-   { 38213, 0x00008366 }, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
-   { 38243, 0x00008033 }, /* GL_UNSIGNED_SHORT_4_4_4_4 */
-   { 38269, 0x00008365 }, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
-   { 38299, 0x00008034 }, /* GL_UNSIGNED_SHORT_5_5_5_1 */
-   { 38325, 0x00008363 }, /* GL_UNSIGNED_SHORT_5_6_5 */
-   { 38349, 0x00008364 }, /* GL_UNSIGNED_SHORT_5_6_5_REV */
-   { 38377, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_APPLE */
-   { 38405, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_MESA */
-   { 38432, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
-   { 38464, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_MESA */
-   { 38495, 0x00008CA2 }, /* GL_UPPER_LEFT */
-   { 38509, 0x00002A20 }, /* GL_V2F */
-   { 38516, 0x00002A21 }, /* GL_V3F */
-   { 38523, 0x00008B83 }, /* GL_VALIDATE_STATUS */
-   { 38542, 0x00001F00 }, /* GL_VENDOR */
-   { 38552, 0x00001F02 }, /* GL_VERSION */
-   { 38563, 0x00008074 }, /* GL_VERTEX_ARRAY */
-   { 38579, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING */
-   { 38603, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING_APPLE */
-   { 38633, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
-   { 38664, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING_ARB */
-   { 38699, 0x0000808E }, /* GL_VERTEX_ARRAY_POINTER */
-   { 38723, 0x0000807A }, /* GL_VERTEX_ARRAY_SIZE */
-   { 38744, 0x0000807C }, /* GL_VERTEX_ARRAY_STRIDE */
-   { 38767, 0x0000807B }, /* GL_VERTEX_ARRAY_TYPE */
-   { 38788, 0x00008650 }, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
-   { 38815, 0x0000865A }, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
-   { 38843, 0x0000865B }, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
-   { 38871, 0x0000865C }, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
-   { 38899, 0x0000865D }, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
-   { 38927, 0x0000865E }, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
-   { 38955, 0x0000865F }, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
-   { 38983, 0x00008651 }, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
-   { 39010, 0x00008652 }, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
-   { 39037, 0x00008653 }, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
-   { 39064, 0x00008654 }, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
-   { 39091, 0x00008655 }, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
-   { 39118, 0x00008656 }, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
-   { 39145, 0x00008657 }, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
-   { 39172, 0x00008658 }, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
-   { 39199, 0x00008659 }, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
-   { 39226, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
-   { 39264, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB */
-   { 39306, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
-   { 39337, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB */
-   { 39372, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
-   { 39406, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB */
-   { 39444, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
-   { 39475, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB */
-   { 39510, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
-   { 39538, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB */
-   { 39570, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
-   { 39600, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB */
-   { 39634, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
-   { 39662, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB */
-   { 39694, 0x000086A7 }, /* GL_VERTEX_BLEND_ARB */
-   { 39714, 0x00008620 }, /* GL_VERTEX_PROGRAM_ARB */
-   { 39736, 0x0000864A }, /* GL_VERTEX_PROGRAM_BINDING_NV */
-   { 39765, 0x00008620 }, /* GL_VERTEX_PROGRAM_NV */
-   { 39786, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE */
-   { 39815, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_ARB */
-   { 39848, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_NV */
-   { 39880, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE */
-   { 39907, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_ARB */
-   { 39938, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_NV */
-   { 39968, 0x00008B31 }, /* GL_VERTEX_SHADER */
-   { 39985, 0x00008B31 }, /* GL_VERTEX_SHADER_ARB */
-   { 40006, 0x00008621 }, /* GL_VERTEX_STATE_PROGRAM_NV */
-   { 40033, 0x00000BA2 }, /* GL_VIEWPORT */
-   { 40045, 0x00000800 }, /* GL_VIEWPORT_BIT */
-   { 40061, 0x0000911D }, /* GL_WAIT_FAILED */
-   { 40076, 0x000086AD }, /* GL_WEIGHT_ARRAY_ARB */
-   { 40096, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
-   { 40127, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB */
-   { 40162, 0x000086AC }, /* GL_WEIGHT_ARRAY_POINTER_ARB */
-   { 40190, 0x000086AB }, /* GL_WEIGHT_ARRAY_SIZE_ARB */
-   { 40215, 0x000086AA }, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
-   { 40242, 0x000086A9 }, /* GL_WEIGHT_ARRAY_TYPE_ARB */
-   { 40267, 0x000086A6 }, /* GL_WEIGHT_SUM_UNITY_ARB */
-   { 40291, 0x000081D4 }, /* GL_WRAP_BORDER_SUN */
-   { 40310, 0x000088B9 }, /* GL_WRITE_ONLY */
-   { 40324, 0x000088B9 }, /* GL_WRITE_ONLY_ARB */
-   { 40342, 0x00001506 }, /* GL_XOR */
-   { 40349, 0x000085B9 }, /* GL_YCBCR_422_APPLE */
-   { 40368, 0x00008757 }, /* GL_YCBCR_MESA */
-   { 40382, 0x00000000 }, /* GL_ZERO */
-   { 40390, 0x00000D16 }, /* GL_ZOOM_X */
-   { 40400, 0x00000D17 }, /* GL_ZOOM_Y */
+   {  7190, 0x000088F0 }, /* GL_DEPTH24_STENCIL8_EXT */
+   {  7214, 0x00008D00 }, /* GL_DEPTH_ATTACHMENT */
+   {  7234, 0x00008D00 }, /* GL_DEPTH_ATTACHMENT_EXT */
+   {  7258, 0x00000D1F }, /* GL_DEPTH_BIAS */
+   {  7272, 0x00000D56 }, /* GL_DEPTH_BITS */
+   {  7286, 0x00008891 }, /* GL_DEPTH_BOUNDS_EXT */
+   {  7306, 0x00008890 }, /* GL_DEPTH_BOUNDS_TEST_EXT */
+   {  7331, 0x00000100 }, /* GL_DEPTH_BUFFER_BIT */
+   {  7351, 0x0000864F }, /* GL_DEPTH_CLAMP */
+   {  7366, 0x0000864F }, /* GL_DEPTH_CLAMP_NV */
+   {  7384, 0x00000B73 }, /* GL_DEPTH_CLEAR_VALUE */
+   {  7405, 0x00001902 }, /* GL_DEPTH_COMPONENT */
+   {  7424, 0x000081A5 }, /* GL_DEPTH_COMPONENT16 */
+   {  7445, 0x000081A5 }, /* GL_DEPTH_COMPONENT16_ARB */
+   {  7470, 0x000081A5 }, /* GL_DEPTH_COMPONENT16_SGIX */
+   {  7496, 0x000081A6 }, /* GL_DEPTH_COMPONENT24 */
+   {  7517, 0x000081A6 }, /* GL_DEPTH_COMPONENT24_ARB */
+   {  7542, 0x000081A6 }, /* GL_DEPTH_COMPONENT24_SGIX */
+   {  7568, 0x000081A7 }, /* GL_DEPTH_COMPONENT32 */
+   {  7589, 0x000081A7 }, /* GL_DEPTH_COMPONENT32_ARB */
+   {  7614, 0x000081A7 }, /* GL_DEPTH_COMPONENT32_SGIX */
+   {  7640, 0x00000B74 }, /* GL_DEPTH_FUNC */
+   {  7654, 0x00000B70 }, /* GL_DEPTH_RANGE */
+   {  7669, 0x00000D1E }, /* GL_DEPTH_SCALE */
+   {  7684, 0x000084F9 }, /* GL_DEPTH_STENCIL */
+   {  7701, 0x0000821A }, /* GL_DEPTH_STENCIL_ATTACHMENT */
+   {  7729, 0x000084F9 }, /* GL_DEPTH_STENCIL_EXT */
+   {  7750, 0x000084F9 }, /* GL_DEPTH_STENCIL_NV */
+   {  7770, 0x0000886F }, /* GL_DEPTH_STENCIL_TO_BGRA_NV */
+   {  7798, 0x0000886E }, /* GL_DEPTH_STENCIL_TO_RGBA_NV */
+   {  7826, 0x00000B71 }, /* GL_DEPTH_TEST */
+   {  7840, 0x0000884B }, /* GL_DEPTH_TEXTURE_MODE */
+   {  7862, 0x0000884B }, /* GL_DEPTH_TEXTURE_MODE_ARB */
+   {  7888, 0x00000B72 }, /* GL_DEPTH_WRITEMASK */
+   {  7907, 0x00001201 }, /* GL_DIFFUSE */
+   {  7918, 0x00000BD0 }, /* GL_DITHER */
+   {  7928, 0x00000A02 }, /* GL_DOMAIN */
+   {  7938, 0x00001100 }, /* GL_DONT_CARE */
+   {  7951, 0x000086AE }, /* GL_DOT3_RGB */
+   {  7963, 0x000086AF }, /* GL_DOT3_RGBA */
+   {  7976, 0x000086AF }, /* GL_DOT3_RGBA_ARB */
+   {  7993, 0x00008741 }, /* GL_DOT3_RGBA_EXT */
+   {  8010, 0x000086AE }, /* GL_DOT3_RGB_ARB */
+   {  8026, 0x00008740 }, /* GL_DOT3_RGB_EXT */
+   {  8042, 0x0000140A }, /* GL_DOUBLE */
+   {  8052, 0x00000C32 }, /* GL_DOUBLEBUFFER */
+   {  8068, 0x00000C01 }, /* GL_DRAW_BUFFER */
+   {  8083, 0x00008825 }, /* GL_DRAW_BUFFER0 */
+   {  8099, 0x00008825 }, /* GL_DRAW_BUFFER0_ARB */
+   {  8119, 0x00008825 }, /* GL_DRAW_BUFFER0_ATI */
+   {  8139, 0x00008826 }, /* GL_DRAW_BUFFER1 */
+   {  8155, 0x0000882F }, /* GL_DRAW_BUFFER10 */
+   {  8172, 0x0000882F }, /* GL_DRAW_BUFFER10_ARB */
+   {  8193, 0x0000882F }, /* GL_DRAW_BUFFER10_ATI */
+   {  8214, 0x00008830 }, /* GL_DRAW_BUFFER11 */
+   {  8231, 0x00008830 }, /* GL_DRAW_BUFFER11_ARB */
+   {  8252, 0x00008830 }, /* GL_DRAW_BUFFER11_ATI */
+   {  8273, 0x00008831 }, /* GL_DRAW_BUFFER12 */
+   {  8290, 0x00008831 }, /* GL_DRAW_BUFFER12_ARB */
+   {  8311, 0x00008831 }, /* GL_DRAW_BUFFER12_ATI */
+   {  8332, 0x00008832 }, /* GL_DRAW_BUFFER13 */
+   {  8349, 0x00008832 }, /* GL_DRAW_BUFFER13_ARB */
+   {  8370, 0x00008832 }, /* GL_DRAW_BUFFER13_ATI */
+   {  8391, 0x00008833 }, /* GL_DRAW_BUFFER14 */
+   {  8408, 0x00008833 }, /* GL_DRAW_BUFFER14_ARB */
+   {  8429, 0x00008833 }, /* GL_DRAW_BUFFER14_ATI */
+   {  8450, 0x00008834 }, /* GL_DRAW_BUFFER15 */
+   {  8467, 0x00008834 }, /* GL_DRAW_BUFFER15_ARB */
+   {  8488, 0x00008834 }, /* GL_DRAW_BUFFER15_ATI */
+   {  8509, 0x00008826 }, /* GL_DRAW_BUFFER1_ARB */
+   {  8529, 0x00008826 }, /* GL_DRAW_BUFFER1_ATI */
+   {  8549, 0x00008827 }, /* GL_DRAW_BUFFER2 */
+   {  8565, 0x00008827 }, /* GL_DRAW_BUFFER2_ARB */
+   {  8585, 0x00008827 }, /* GL_DRAW_BUFFER2_ATI */
+   {  8605, 0x00008828 }, /* GL_DRAW_BUFFER3 */
+   {  8621, 0x00008828 }, /* GL_DRAW_BUFFER3_ARB */
+   {  8641, 0x00008828 }, /* GL_DRAW_BUFFER3_ATI */
+   {  8661, 0x00008829 }, /* GL_DRAW_BUFFER4 */
+   {  8677, 0x00008829 }, /* GL_DRAW_BUFFER4_ARB */
+   {  8697, 0x00008829 }, /* GL_DRAW_BUFFER4_ATI */
+   {  8717, 0x0000882A }, /* GL_DRAW_BUFFER5 */
+   {  8733, 0x0000882A }, /* GL_DRAW_BUFFER5_ARB */
+   {  8753, 0x0000882A }, /* GL_DRAW_BUFFER5_ATI */
+   {  8773, 0x0000882B }, /* GL_DRAW_BUFFER6 */
+   {  8789, 0x0000882B }, /* GL_DRAW_BUFFER6_ARB */
+   {  8809, 0x0000882B }, /* GL_DRAW_BUFFER6_ATI */
+   {  8829, 0x0000882C }, /* GL_DRAW_BUFFER7 */
+   {  8845, 0x0000882C }, /* GL_DRAW_BUFFER7_ARB */
+   {  8865, 0x0000882C }, /* GL_DRAW_BUFFER7_ATI */
+   {  8885, 0x0000882D }, /* GL_DRAW_BUFFER8 */
+   {  8901, 0x0000882D }, /* GL_DRAW_BUFFER8_ARB */
+   {  8921, 0x0000882D }, /* GL_DRAW_BUFFER8_ATI */
+   {  8941, 0x0000882E }, /* GL_DRAW_BUFFER9 */
+   {  8957, 0x0000882E }, /* GL_DRAW_BUFFER9_ARB */
+   {  8977, 0x0000882E }, /* GL_DRAW_BUFFER9_ATI */
+   {  8997, 0x00008CA9 }, /* GL_DRAW_FRAMEBUFFER */
+   {  9017, 0x00008CA6 }, /* GL_DRAW_FRAMEBUFFER_BINDING */
+   {  9045, 0x00008CA6 }, /* GL_DRAW_FRAMEBUFFER_BINDING_EXT */
+   {  9077, 0x00008CA9 }, /* GL_DRAW_FRAMEBUFFER_EXT */
+   {  9101, 0x00000705 }, /* GL_DRAW_PIXEL_TOKEN */
+   {  9121, 0x00000304 }, /* GL_DST_ALPHA */
+   {  9134, 0x00000306 }, /* GL_DST_COLOR */
+   {  9147, 0x0000877A }, /* GL_DU8DV8_ATI */
+   {  9161, 0x00008779 }, /* GL_DUDV_ATI */
+   {  9173, 0x000088EA }, /* GL_DYNAMIC_COPY */
+   {  9189, 0x000088EA }, /* GL_DYNAMIC_COPY_ARB */
+   {  9209, 0x000088E8 }, /* GL_DYNAMIC_DRAW */
+   {  9225, 0x000088E8 }, /* GL_DYNAMIC_DRAW_ARB */
+   {  9245, 0x000088E9 }, /* GL_DYNAMIC_READ */
+   {  9261, 0x000088E9 }, /* GL_DYNAMIC_READ_ARB */
+   {  9281, 0x00000B43 }, /* GL_EDGE_FLAG */
+   {  9294, 0x00008079 }, /* GL_EDGE_FLAG_ARRAY */
+   {  9313, 0x0000889B }, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */
+   {  9347, 0x0000889B }, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB */
+   {  9385, 0x00008093 }, /* GL_EDGE_FLAG_ARRAY_POINTER */
+   {  9412, 0x0000808C }, /* GL_EDGE_FLAG_ARRAY_STRIDE */
+   {  9438, 0x00008893 }, /* GL_ELEMENT_ARRAY_BUFFER */
+   {  9462, 0x00008895 }, /* GL_ELEMENT_ARRAY_BUFFER_BINDING */
+   {  9494, 0x00008895 }, /* GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB */
+   {  9530, 0x00001600 }, /* GL_EMISSION */
+   {  9542, 0x00002000 }, /* GL_ENABLE_BIT */
+   {  9556, 0x00000202 }, /* GL_EQUAL */
+   {  9565, 0x00001509 }, /* GL_EQUIV */
+   {  9574, 0x00010000 }, /* GL_EVAL_BIT */
+   {  9586, 0x00000800 }, /* GL_EXP */
+   {  9593, 0x00000801 }, /* GL_EXP2 */
+   {  9601, 0x00001F03 }, /* GL_EXTENSIONS */
+   {  9615, 0x00002400 }, /* GL_EYE_LINEAR */
+   {  9629, 0x00002502 }, /* GL_EYE_PLANE */
+   {  9642, 0x0000855C }, /* GL_EYE_PLANE_ABSOLUTE_NV */
+   {  9667, 0x0000855B }, /* GL_EYE_RADIAL_NV */
+   {  9684, 0x00000000 }, /* GL_FALSE */
+   {  9693, 0x00001101 }, /* GL_FASTEST */
+   {  9704, 0x00001C01 }, /* GL_FEEDBACK */
+   {  9716, 0x00000DF0 }, /* GL_FEEDBACK_BUFFER_POINTER */
+   {  9743, 0x00000DF1 }, /* GL_FEEDBACK_BUFFER_SIZE */
+   {  9767, 0x00000DF2 }, /* GL_FEEDBACK_BUFFER_TYPE */
+   {  9791, 0x00001B02 }, /* GL_FILL */
+   {  9799, 0x00008E4D }, /* GL_FIRST_VERTEX_CONVENTION */
+   {  9826, 0x00008E4D }, /* GL_FIRST_VERTEX_CONVENTION_EXT */
+   {  9857, 0x00001D00 }, /* GL_FLAT */
+   {  9865, 0x00001406 }, /* GL_FLOAT */
+   {  9874, 0x00008B5A }, /* GL_FLOAT_MAT2 */
+   {  9888, 0x00008B5A }, /* GL_FLOAT_MAT2_ARB */
+   {  9906, 0x00008B65 }, /* GL_FLOAT_MAT2x3 */
+   {  9922, 0x00008B66 }, /* GL_FLOAT_MAT2x4 */
+   {  9938, 0x00008B5B }, /* GL_FLOAT_MAT3 */
+   {  9952, 0x00008B5B }, /* GL_FLOAT_MAT3_ARB */
+   {  9970, 0x00008B67 }, /* GL_FLOAT_MAT3x2 */
+   {  9986, 0x00008B68 }, /* GL_FLOAT_MAT3x4 */
+   { 10002, 0x00008B5C }, /* GL_FLOAT_MAT4 */
+   { 10016, 0x00008B5C }, /* GL_FLOAT_MAT4_ARB */
+   { 10034, 0x00008B69 }, /* GL_FLOAT_MAT4x2 */
+   { 10050, 0x00008B6A }, /* GL_FLOAT_MAT4x3 */
+   { 10066, 0x00008B50 }, /* GL_FLOAT_VEC2 */
+   { 10080, 0x00008B50 }, /* GL_FLOAT_VEC2_ARB */
+   { 10098, 0x00008B51 }, /* GL_FLOAT_VEC3 */
+   { 10112, 0x00008B51 }, /* GL_FLOAT_VEC3_ARB */
+   { 10130, 0x00008B52 }, /* GL_FLOAT_VEC4 */
+   { 10144, 0x00008B52 }, /* GL_FLOAT_VEC4_ARB */
+   { 10162, 0x00000B60 }, /* GL_FOG */
+   { 10169, 0x00000080 }, /* GL_FOG_BIT */
+   { 10180, 0x00000B66 }, /* GL_FOG_COLOR */
+   { 10193, 0x00008451 }, /* GL_FOG_COORD */
+   { 10206, 0x00008451 }, /* GL_FOG_COORDINATE */
+   { 10224, 0x00008457 }, /* GL_FOG_COORDINATE_ARRAY */
+   { 10248, 0x0000889D }, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */
+   { 10287, 0x0000889D }, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB */
+   { 10330, 0x00008456 }, /* GL_FOG_COORDINATE_ARRAY_POINTER */
+   { 10362, 0x00008455 }, /* GL_FOG_COORDINATE_ARRAY_STRIDE */
+   { 10393, 0x00008454 }, /* GL_FOG_COORDINATE_ARRAY_TYPE */
+   { 10422, 0x00008450 }, /* GL_FOG_COORDINATE_SOURCE */
+   { 10447, 0x00008457 }, /* GL_FOG_COORD_ARRAY */
+   { 10466, 0x0000889D }, /* GL_FOG_COORD_ARRAY_BUFFER_BINDING */
+   { 10500, 0x00008456 }, /* GL_FOG_COORD_ARRAY_POINTER */
+   { 10527, 0x00008455 }, /* GL_FOG_COORD_ARRAY_STRIDE */
+   { 10553, 0x00008454 }, /* GL_FOG_COORD_ARRAY_TYPE */
+   { 10577, 0x00008450 }, /* GL_FOG_COORD_SRC */
+   { 10594, 0x00000B62 }, /* GL_FOG_DENSITY */
+   { 10609, 0x0000855A }, /* GL_FOG_DISTANCE_MODE_NV */
+   { 10633, 0x00000B64 }, /* GL_FOG_END */
+   { 10644, 0x00000C54 }, /* GL_FOG_HINT */
+   { 10656, 0x00000B61 }, /* GL_FOG_INDEX */
+   { 10669, 0x00000B65 }, /* GL_FOG_MODE */
+   { 10681, 0x00008198 }, /* GL_FOG_OFFSET_SGIX */
+   { 10700, 0x00008199 }, /* GL_FOG_OFFSET_VALUE_SGIX */
+   { 10725, 0x00000B63 }, /* GL_FOG_START */
+   { 10738, 0x00008452 }, /* GL_FRAGMENT_DEPTH */
+   { 10756, 0x00008804 }, /* GL_FRAGMENT_PROGRAM_ARB */
+   { 10780, 0x00008B30 }, /* GL_FRAGMENT_SHADER */
+   { 10799, 0x00008B30 }, /* GL_FRAGMENT_SHADER_ARB */
+   { 10822, 0x00008B8B }, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */
+   { 10857, 0x00008D40 }, /* GL_FRAMEBUFFER */
+   { 10872, 0x00008215 }, /* GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */
+   { 10909, 0x00008214 }, /* GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */
+   { 10945, 0x00008210 }, /* GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */
+   { 10986, 0x00008211 }, /* GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */
+   { 11027, 0x00008216 }, /* GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */
+   { 11064, 0x00008213 }, /* GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */
+   { 11101, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
+   { 11139, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT */
+   { 11181, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
+   { 11219, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT */
+   { 11261, 0x00008212 }, /* GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
+   { 11296, 0x00008217 }, /* GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
+   { 11335, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT */
+   { 11384, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
+   { 11432, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT */
+   { 11484, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+   { 11524, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */
+   { 11568, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
+   { 11608, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT */
+   { 11652, 0x00008CA6 }, /* GL_FRAMEBUFFER_BINDING */
+   { 11675, 0x00008CA6 }, /* GL_FRAMEBUFFER_BINDING_EXT */
+   { 11702, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE */
+   { 11726, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE_EXT */
+   { 11754, 0x00008218 }, /* GL_FRAMEBUFFER_DEFAULT */
+   { 11777, 0x00008D40 }, /* GL_FRAMEBUFFER_EXT */
+   { 11796, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
+   { 11833, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT */
+   { 11874, 0x00008CD9 }, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
+   { 11915, 0x00008CDB }, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER */
+   { 11953, 0x00008CDB }, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT */
+   { 11995, 0x00008CD8 }, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
+   { 12046, 0x00008CDA }, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
+   { 12084, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
+   { 12129, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT */
+   { 12178, 0x00008D56 }, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
+   { 12216, 0x00008D56 }, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT */
+   { 12258, 0x00008CDC }, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER */
+   { 12296, 0x00008CDC }, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT */
+   { 12338, 0x00008CDE }, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
+   { 12370, 0x00008219 }, /* GL_FRAMEBUFFER_UNDEFINED */
+   { 12395, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED */
+   { 12422, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED_EXT */
+   { 12453, 0x00000404 }, /* GL_FRONT */
+   { 12462, 0x00000408 }, /* GL_FRONT_AND_BACK */
+   { 12480, 0x00000B46 }, /* GL_FRONT_FACE */
+   { 12494, 0x00000400 }, /* GL_FRONT_LEFT */
+   { 12508, 0x00000401 }, /* GL_FRONT_RIGHT */
+   { 12523, 0x00008006 }, /* GL_FUNC_ADD */
+   { 12535, 0x00008006 }, /* GL_FUNC_ADD_EXT */
+   { 12551, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT */
+   { 12576, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT_EXT */
+   { 12605, 0x0000800A }, /* GL_FUNC_SUBTRACT */
+   { 12622, 0x0000800A }, /* GL_FUNC_SUBTRACT_EXT */
+   { 12643, 0x00008191 }, /* GL_GENERATE_MIPMAP */
+   { 12662, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT */
+   { 12686, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT_SGIS */
+   { 12715, 0x00008191 }, /* GL_GENERATE_MIPMAP_SGIS */
+   { 12739, 0x00000206 }, /* GL_GEQUAL */
+   { 12749, 0x00000204 }, /* GL_GREATER */
+   { 12760, 0x00001904 }, /* GL_GREEN */
+   { 12769, 0x00000D19 }, /* GL_GREEN_BIAS */
+   { 12783, 0x00000D53 }, /* GL_GREEN_BITS */
+   { 12797, 0x00000D18 }, /* GL_GREEN_SCALE */
+   { 12812, 0x00008000 }, /* GL_HINT_BIT */
+   { 12824, 0x00008024 }, /* GL_HISTOGRAM */
+   { 12837, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE */
+   { 12861, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE_EXT */
+   { 12889, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE */
+   { 12912, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE_EXT */
+   { 12939, 0x00008024 }, /* GL_HISTOGRAM_EXT */
+   { 12956, 0x00008027 }, /* GL_HISTOGRAM_FORMAT */
+   { 12976, 0x00008027 }, /* GL_HISTOGRAM_FORMAT_EXT */
+   { 13000, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE */
+   { 13024, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE_EXT */
+   { 13052, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE */
+   { 13080, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE_EXT */
+   { 13112, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE */
+   { 13134, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE_EXT */
+   { 13160, 0x0000802D }, /* GL_HISTOGRAM_SINK */
+   { 13178, 0x0000802D }, /* GL_HISTOGRAM_SINK_EXT */
+   { 13200, 0x00008026 }, /* GL_HISTOGRAM_WIDTH */
+   { 13219, 0x00008026 }, /* GL_HISTOGRAM_WIDTH_EXT */
+   { 13242, 0x0000862A }, /* GL_IDENTITY_NV */
+   { 13257, 0x00008150 }, /* GL_IGNORE_BORDER_HP */
+   { 13277, 0x00008B9B }, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
+   { 13317, 0x00008B9A }, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
+   { 13355, 0x00001E02 }, /* GL_INCR */
+   { 13363, 0x00008507 }, /* GL_INCR_WRAP */
+   { 13376, 0x00008507 }, /* GL_INCR_WRAP_EXT */
+   { 13393, 0x00008222 }, /* GL_INDEX */
+   { 13402, 0x00008077 }, /* GL_INDEX_ARRAY */
+   { 13417, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING */
+   { 13447, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING_ARB */
+   { 13481, 0x00008091 }, /* GL_INDEX_ARRAY_POINTER */
+   { 13504, 0x00008086 }, /* GL_INDEX_ARRAY_STRIDE */
+   { 13526, 0x00008085 }, /* GL_INDEX_ARRAY_TYPE */
+   { 13546, 0x00000D51 }, /* GL_INDEX_BITS */
+   { 13560, 0x00000C20 }, /* GL_INDEX_CLEAR_VALUE */
+   { 13581, 0x00000BF1 }, /* GL_INDEX_LOGIC_OP */
+   { 13599, 0x00000C30 }, /* GL_INDEX_MODE */
+   { 13613, 0x00000D13 }, /* GL_INDEX_OFFSET */
+   { 13629, 0x00000D12 }, /* GL_INDEX_SHIFT */
+   { 13644, 0x00000C21 }, /* GL_INDEX_WRITEMASK */
+   { 13663, 0x00008B84 }, /* GL_INFO_LOG_LENGTH */
+   { 13682, 0x00001404 }, /* GL_INT */
+   { 13689, 0x00008049 }, /* GL_INTENSITY */
+   { 13702, 0x0000804C }, /* GL_INTENSITY12 */
+   { 13717, 0x0000804C }, /* GL_INTENSITY12_EXT */
+   { 13736, 0x0000804D }, /* GL_INTENSITY16 */
+   { 13751, 0x0000804D }, /* GL_INTENSITY16_EXT */
+   { 13770, 0x0000804A }, /* GL_INTENSITY4 */
+   { 13784, 0x0000804A }, /* GL_INTENSITY4_EXT */
+   { 13802, 0x0000804B }, /* GL_INTENSITY8 */
+   { 13816, 0x0000804B }, /* GL_INTENSITY8_EXT */
+   { 13834, 0x00008049 }, /* GL_INTENSITY_EXT */
+   { 13851, 0x00008575 }, /* GL_INTERPOLATE */
+   { 13866, 0x00008575 }, /* GL_INTERPOLATE_ARB */
+   { 13885, 0x00008575 }, /* GL_INTERPOLATE_EXT */
+   { 13904, 0x00008B53 }, /* GL_INT_VEC2 */
+   { 13916, 0x00008B53 }, /* GL_INT_VEC2_ARB */
+   { 13932, 0x00008B54 }, /* GL_INT_VEC3 */
+   { 13944, 0x00008B54 }, /* GL_INT_VEC3_ARB */
+   { 13960, 0x00008B55 }, /* GL_INT_VEC4 */
+   { 13972, 0x00008B55 }, /* GL_INT_VEC4_ARB */
+   { 13988, 0x00000500 }, /* GL_INVALID_ENUM */
+   { 14004, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION */
+   { 14037, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION_EXT */
+   { 14074, 0x00000502 }, /* GL_INVALID_OPERATION */
+   { 14095, 0x00000501 }, /* GL_INVALID_VALUE */
+   { 14112, 0x0000862B }, /* GL_INVERSE_NV */
+   { 14126, 0x0000862D }, /* GL_INVERSE_TRANSPOSE_NV */
+   { 14150, 0x0000150A }, /* GL_INVERT */
+   { 14160, 0x00001E00 }, /* GL_KEEP */
+   { 14168, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION */
+   { 14194, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION_EXT */
+   { 14224, 0x00000406 }, /* GL_LEFT */
+   { 14232, 0x00000203 }, /* GL_LEQUAL */
+   { 14242, 0x00000201 }, /* GL_LESS */
+   { 14250, 0x00004000 }, /* GL_LIGHT0 */
+   { 14260, 0x00004001 }, /* GL_LIGHT1 */
+   { 14270, 0x00004002 }, /* GL_LIGHT2 */
+   { 14280, 0x00004003 }, /* GL_LIGHT3 */
+   { 14290, 0x00004004 }, /* GL_LIGHT4 */
+   { 14300, 0x00004005 }, /* GL_LIGHT5 */
+   { 14310, 0x00004006 }, /* GL_LIGHT6 */
+   { 14320, 0x00004007 }, /* GL_LIGHT7 */
+   { 14330, 0x00000B50 }, /* GL_LIGHTING */
+   { 14342, 0x00000040 }, /* GL_LIGHTING_BIT */
+   { 14358, 0x00000B53 }, /* GL_LIGHT_MODEL_AMBIENT */
+   { 14381, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL */
+   { 14410, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL_EXT */
+   { 14443, 0x00000B51 }, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
+   { 14471, 0x00000B52 }, /* GL_LIGHT_MODEL_TWO_SIDE */
+   { 14495, 0x00001B01 }, /* GL_LINE */
+   { 14503, 0x00002601 }, /* GL_LINEAR */
+   { 14513, 0x00001208 }, /* GL_LINEAR_ATTENUATION */
+   { 14535, 0x00008170 }, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
+   { 14565, 0x0000844F }, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
+   { 14596, 0x00002703 }, /* GL_LINEAR_MIPMAP_LINEAR */
+   { 14620, 0x00002701 }, /* GL_LINEAR_MIPMAP_NEAREST */
+   { 14645, 0x00000001 }, /* GL_LINES */
+   { 14654, 0x00000004 }, /* GL_LINE_BIT */
+   { 14666, 0x00000002 }, /* GL_LINE_LOOP */
+   { 14679, 0x00000707 }, /* GL_LINE_RESET_TOKEN */
+   { 14699, 0x00000B20 }, /* GL_LINE_SMOOTH */
+   { 14714, 0x00000C52 }, /* GL_LINE_SMOOTH_HINT */
+   { 14734, 0x00000B24 }, /* GL_LINE_STIPPLE */
+   { 14750, 0x00000B25 }, /* GL_LINE_STIPPLE_PATTERN */
+   { 14774, 0x00000B26 }, /* GL_LINE_STIPPLE_REPEAT */
+   { 14797, 0x00000003 }, /* GL_LINE_STRIP */
+   { 14811, 0x00000702 }, /* GL_LINE_TOKEN */
+   { 14825, 0x00000B21 }, /* GL_LINE_WIDTH */
+   { 14839, 0x00000B23 }, /* GL_LINE_WIDTH_GRANULARITY */
+   { 14865, 0x00000B22 }, /* GL_LINE_WIDTH_RANGE */
+   { 14885, 0x00008B82 }, /* GL_LINK_STATUS */
+   { 14900, 0x00000B32 }, /* GL_LIST_BASE */
+   { 14913, 0x00020000 }, /* GL_LIST_BIT */
+   { 14925, 0x00000B33 }, /* GL_LIST_INDEX */
+   { 14939, 0x00000B30 }, /* GL_LIST_MODE */
+   { 14952, 0x00000101 }, /* GL_LOAD */
+   { 14960, 0x00000BF1 }, /* GL_LOGIC_OP */
+   { 14972, 0x00000BF0 }, /* GL_LOGIC_OP_MODE */
+   { 14989, 0x00008CA1 }, /* GL_LOWER_LEFT */
+   { 15003, 0x00001909 }, /* GL_LUMINANCE */
+   { 15016, 0x00008041 }, /* GL_LUMINANCE12 */
+   { 15031, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12 */
+   { 15054, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12_EXT */
+   { 15081, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4 */
+   { 15103, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4_EXT */
+   { 15129, 0x00008041 }, /* GL_LUMINANCE12_EXT */
+   { 15148, 0x00008042 }, /* GL_LUMINANCE16 */
+   { 15163, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16 */
+   { 15186, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16_EXT */
+   { 15213, 0x00008042 }, /* GL_LUMINANCE16_EXT */
+   { 15232, 0x0000803F }, /* GL_LUMINANCE4 */
+   { 15246, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4 */
+   { 15267, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4_EXT */
+   { 15292, 0x0000803F }, /* GL_LUMINANCE4_EXT */
+   { 15310, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2 */
+   { 15331, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2_EXT */
+   { 15356, 0x00008040 }, /* GL_LUMINANCE8 */
+   { 15370, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8 */
+   { 15391, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8_EXT */
+   { 15416, 0x00008040 }, /* GL_LUMINANCE8_EXT */
+   { 15434, 0x0000190A }, /* GL_LUMINANCE_ALPHA */
+   { 15453, 0x00000D90 }, /* GL_MAP1_COLOR_4 */
+   { 15469, 0x00000DD0 }, /* GL_MAP1_GRID_DOMAIN */
+   { 15489, 0x00000DD1 }, /* GL_MAP1_GRID_SEGMENTS */
+   { 15511, 0x00000D91 }, /* GL_MAP1_INDEX */
+   { 15525, 0x00000D92 }, /* GL_MAP1_NORMAL */
+   { 15540, 0x00000D93 }, /* GL_MAP1_TEXTURE_COORD_1 */
+   { 15564, 0x00000D94 }, /* GL_MAP1_TEXTURE_COORD_2 */
+   { 15588, 0x00000D95 }, /* GL_MAP1_TEXTURE_COORD_3 */
+   { 15612, 0x00000D96 }, /* GL_MAP1_TEXTURE_COORD_4 */
+   { 15636, 0x00000D97 }, /* GL_MAP1_VERTEX_3 */
+   { 15653, 0x00000D98 }, /* GL_MAP1_VERTEX_4 */
+   { 15670, 0x00008660 }, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
+   { 15698, 0x0000866A }, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
+   { 15727, 0x0000866B }, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
+   { 15756, 0x0000866C }, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
+   { 15785, 0x0000866D }, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
+   { 15814, 0x0000866E }, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
+   { 15843, 0x0000866F }, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
+   { 15872, 0x00008661 }, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
+   { 15900, 0x00008662 }, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
+   { 15928, 0x00008663 }, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
+   { 15956, 0x00008664 }, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
+   { 15984, 0x00008665 }, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
+   { 16012, 0x00008666 }, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
+   { 16040, 0x00008667 }, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
+   { 16068, 0x00008668 }, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
+   { 16096, 0x00008669 }, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
+   { 16124, 0x00000DB0 }, /* GL_MAP2_COLOR_4 */
+   { 16140, 0x00000DD2 }, /* GL_MAP2_GRID_DOMAIN */
+   { 16160, 0x00000DD3 }, /* GL_MAP2_GRID_SEGMENTS */
+   { 16182, 0x00000DB1 }, /* GL_MAP2_INDEX */
+   { 16196, 0x00000DB2 }, /* GL_MAP2_NORMAL */
+   { 16211, 0x00000DB3 }, /* GL_MAP2_TEXTURE_COORD_1 */
+   { 16235, 0x00000DB4 }, /* GL_MAP2_TEXTURE_COORD_2 */
+   { 16259, 0x00000DB5 }, /* GL_MAP2_TEXTURE_COORD_3 */
+   { 16283, 0x00000DB6 }, /* GL_MAP2_TEXTURE_COORD_4 */
+   { 16307, 0x00000DB7 }, /* GL_MAP2_VERTEX_3 */
+   { 16324, 0x00000DB8 }, /* GL_MAP2_VERTEX_4 */
+   { 16341, 0x00008670 }, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
+   { 16369, 0x0000867A }, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
+   { 16398, 0x0000867B }, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
+   { 16427, 0x0000867C }, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
+   { 16456, 0x0000867D }, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
+   { 16485, 0x0000867E }, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
+   { 16514, 0x0000867F }, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
+   { 16543, 0x00008671 }, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
+   { 16571, 0x00008672 }, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
+   { 16599, 0x00008673 }, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
+   { 16627, 0x00008674 }, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
+   { 16655, 0x00008675 }, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
+   { 16683, 0x00008676 }, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
+   { 16711, 0x00008677 }, /* GL_MAP2_VERTEX_ATTRIB7_4_NV */
+   { 16739, 0x00008678 }, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
+   { 16767, 0x00008679 }, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
+   { 16795, 0x00000D10 }, /* GL_MAP_COLOR */
+   { 16808, 0x00000010 }, /* GL_MAP_FLUSH_EXPLICIT_BIT */
+   { 16834, 0x00000008 }, /* GL_MAP_INVALIDATE_BUFFER_BIT */
+   { 16863, 0x00000004 }, /* GL_MAP_INVALIDATE_RANGE_BIT */
+   { 16891, 0x00000001 }, /* GL_MAP_READ_BIT */
+   { 16907, 0x00000D11 }, /* GL_MAP_STENCIL */
+   { 16922, 0x00000020 }, /* GL_MAP_UNSYNCHRONIZED_BIT */
+   { 16948, 0x00000002 }, /* GL_MAP_WRITE_BIT */
+   { 16965, 0x000088C0 }, /* GL_MATRIX0_ARB */
+   { 16980, 0x00008630 }, /* GL_MATRIX0_NV */
+   { 16994, 0x000088CA }, /* GL_MATRIX10_ARB */
+   { 17010, 0x000088CB }, /* GL_MATRIX11_ARB */
+   { 17026, 0x000088CC }, /* GL_MATRIX12_ARB */
+   { 17042, 0x000088CD }, /* GL_MATRIX13_ARB */
+   { 17058, 0x000088CE }, /* GL_MATRIX14_ARB */
+   { 17074, 0x000088CF }, /* GL_MATRIX15_ARB */
+   { 17090, 0x000088D0 }, /* GL_MATRIX16_ARB */
+   { 17106, 0x000088D1 }, /* GL_MATRIX17_ARB */
+   { 17122, 0x000088D2 }, /* GL_MATRIX18_ARB */
+   { 17138, 0x000088D3 }, /* GL_MATRIX19_ARB */
+   { 17154, 0x000088C1 }, /* GL_MATRIX1_ARB */
+   { 17169, 0x00008631 }, /* GL_MATRIX1_NV */
+   { 17183, 0x000088D4 }, /* GL_MATRIX20_ARB */
+   { 17199, 0x000088D5 }, /* GL_MATRIX21_ARB */
+   { 17215, 0x000088D6 }, /* GL_MATRIX22_ARB */
+   { 17231, 0x000088D7 }, /* GL_MATRIX23_ARB */
+   { 17247, 0x000088D8 }, /* GL_MATRIX24_ARB */
+   { 17263, 0x000088D9 }, /* GL_MATRIX25_ARB */
+   { 17279, 0x000088DA }, /* GL_MATRIX26_ARB */
+   { 17295, 0x000088DB }, /* GL_MATRIX27_ARB */
+   { 17311, 0x000088DC }, /* GL_MATRIX28_ARB */
+   { 17327, 0x000088DD }, /* GL_MATRIX29_ARB */
+   { 17343, 0x000088C2 }, /* GL_MATRIX2_ARB */
+   { 17358, 0x00008632 }, /* GL_MATRIX2_NV */
+   { 17372, 0x000088DE }, /* GL_MATRIX30_ARB */
+   { 17388, 0x000088DF }, /* GL_MATRIX31_ARB */
+   { 17404, 0x000088C3 }, /* GL_MATRIX3_ARB */
+   { 17419, 0x00008633 }, /* GL_MATRIX3_NV */
+   { 17433, 0x000088C4 }, /* GL_MATRIX4_ARB */
+   { 17448, 0x00008634 }, /* GL_MATRIX4_NV */
+   { 17462, 0x000088C5 }, /* GL_MATRIX5_ARB */
+   { 17477, 0x00008635 }, /* GL_MATRIX5_NV */
+   { 17491, 0x000088C6 }, /* GL_MATRIX6_ARB */
+   { 17506, 0x00008636 }, /* GL_MATRIX6_NV */
+   { 17520, 0x000088C7 }, /* GL_MATRIX7_ARB */
+   { 17535, 0x00008637 }, /* GL_MATRIX7_NV */
+   { 17549, 0x000088C8 }, /* GL_MATRIX8_ARB */
+   { 17564, 0x000088C9 }, /* GL_MATRIX9_ARB */
+   { 17579, 0x00008844 }, /* GL_MATRIX_INDEX_ARRAY_ARB */
+   { 17605, 0x00008849 }, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
+   { 17639, 0x00008846 }, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
+   { 17670, 0x00008848 }, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
+   { 17703, 0x00008847 }, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
+   { 17734, 0x00000BA0 }, /* GL_MATRIX_MODE */
+   { 17749, 0x00008840 }, /* GL_MATRIX_PALETTE_ARB */
+   { 17771, 0x00008008 }, /* GL_MAX */
+   { 17778, 0x00008073 }, /* GL_MAX_3D_TEXTURE_SIZE */
+   { 17801, 0x000088FF }, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */
+   { 17833, 0x00000D35 }, /* GL_MAX_ATTRIB_STACK_DEPTH */
+   { 17859, 0x00000D3B }, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
+   { 17892, 0x00008177 }, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
+   { 17918, 0x00008178 }, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+   { 17952, 0x00000D32 }, /* GL_MAX_CLIP_PLANES */
+   { 17971, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS */
+   { 17996, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS_EXT */
+   { 18025, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
+   { 18057, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI */
+   { 18093, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */
+   { 18129, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB */
+   { 18169, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT */
+   { 18195, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT_EXT */
+   { 18225, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH */
+   { 18250, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH_EXT */
+   { 18279, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
+   { 18308, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB */
+   { 18341, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS */
+   { 18361, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ARB */
+   { 18385, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ATI */
+   { 18409, 0x000080E9 }, /* GL_MAX_ELEMENTS_INDICES */
+   { 18433, 0x000080E8 }, /* GL_MAX_ELEMENTS_VERTICES */
+   { 18458, 0x00000D30 }, /* GL_MAX_EVAL_ORDER */
+   { 18476, 0x00008008 }, /* GL_MAX_EXT */
+   { 18487, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */
+   { 18522, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB */
+   { 18561, 0x00000D31 }, /* GL_MAX_LIGHTS */
+   { 18575, 0x00000B31 }, /* GL_MAX_LIST_NESTING */
+   { 18595, 0x00008841 }, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
+   { 18633, 0x00000D36 }, /* GL_MAX_MODELVIEW_STACK_DEPTH */
+   { 18662, 0x00000D37 }, /* GL_MAX_NAME_STACK_DEPTH */
+   { 18686, 0x00008842 }, /* GL_MAX_PALETTE_MATRICES_ARB */
+   { 18714, 0x00000D34 }, /* GL_MAX_PIXEL_MAP_TABLE */
+   { 18737, 0x000088B1 }, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
+   { 18774, 0x0000880B }, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
+   { 18810, 0x000088AD }, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
+   { 18837, 0x000088F5 }, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
+   { 18866, 0x000088B5 }, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
+   { 18900, 0x000088F4 }, /* GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */
+   { 18936, 0x000088F6 }, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
+   { 18963, 0x000088A1 }, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
+   { 18995, 0x000088B4 }, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
+   { 19031, 0x000088F8 }, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
+   { 19060, 0x000088F7 }, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
+   { 19089, 0x0000862F }, /* GL_MAX_PROGRAM_MATRICES_ARB */
+   { 19117, 0x0000862E }, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
+   { 19155, 0x000088B3 }, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+   { 19199, 0x0000880E }, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+   { 19242, 0x000088AF }, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
+   { 19276, 0x000088A3 }, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+   { 19315, 0x000088AB }, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
+   { 19352, 0x000088A7 }, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
+   { 19390, 0x00008810 }, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+   { 19433, 0x0000880F }, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+   { 19476, 0x000088A9 }, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
+   { 19506, 0x000088A5 }, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
+   { 19537, 0x0000880D }, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
+   { 19573, 0x0000880C }, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
+   { 19609, 0x00000D38 }, /* GL_MAX_PROJECTION_STACK_DEPTH */
+   { 19639, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */
+   { 19673, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_NV */
+   { 19706, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE */
+   { 19731, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE_EXT */
+   { 19760, 0x00008D57 }, /* GL_MAX_SAMPLES */
+   { 19775, 0x00008D57 }, /* GL_MAX_SAMPLES_EXT */
+   { 19794, 0x00009111 }, /* GL_MAX_SERVER_WAIT_TIMEOUT */
+   { 19821, 0x00008504 }, /* GL_MAX_SHININESS_NV */
+   { 19841, 0x00008505 }, /* GL_MAX_SPOT_EXPONENT_NV */
+   { 19865, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS */
+   { 19887, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS_ARB */
+   { 19913, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS */
+   { 19940, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS_ARB */
+   { 19971, 0x000084FD }, /* GL_MAX_TEXTURE_LOD_BIAS */
+   { 19995, 0x000084FF }, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
+   { 20029, 0x00000D33 }, /* GL_MAX_TEXTURE_SIZE */
+   { 20049, 0x00000D39 }, /* GL_MAX_TEXTURE_STACK_DEPTH */
+   { 20076, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS */
+   { 20097, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS_ARB */
+   { 20122, 0x0000862F }, /* GL_MAX_TRACK_MATRICES_NV */
+   { 20147, 0x0000862E }, /* GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV */
+   { 20182, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS */
+   { 20204, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS_ARB */
+   { 20230, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS */
+   { 20252, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS_ARB */
+   { 20278, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */
+   { 20312, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */
+   { 20350, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */
+   { 20383, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB */
+   { 20420, 0x000086A4 }, /* GL_MAX_VERTEX_UNITS_ARB */
+   { 20444, 0x00000D3A }, /* GL_MAX_VIEWPORT_DIMS */
+   { 20465, 0x00008007 }, /* GL_MIN */
+   { 20472, 0x0000802E }, /* GL_MINMAX */
+   { 20482, 0x0000802E }, /* GL_MINMAX_EXT */
+   { 20496, 0x0000802F }, /* GL_MINMAX_FORMAT */
+   { 20513, 0x0000802F }, /* GL_MINMAX_FORMAT_EXT */
+   { 20534, 0x00008030 }, /* GL_MINMAX_SINK */
+   { 20549, 0x00008030 }, /* GL_MINMAX_SINK_EXT */
+   { 20568, 0x00008007 }, /* GL_MIN_EXT */
+   { 20579, 0x00008370 }, /* GL_MIRRORED_REPEAT */
+   { 20598, 0x00008370 }, /* GL_MIRRORED_REPEAT_ARB */
+   { 20621, 0x00008370 }, /* GL_MIRRORED_REPEAT_IBM */
+   { 20644, 0x00008742 }, /* GL_MIRROR_CLAMP_ATI */
+   { 20664, 0x00008742 }, /* GL_MIRROR_CLAMP_EXT */
+   { 20684, 0x00008912 }, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
+   { 20714, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_ATI */
+   { 20742, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
+   { 20770, 0x00001700 }, /* GL_MODELVIEW */
+   { 20783, 0x00001700 }, /* GL_MODELVIEW0_ARB */
+   { 20801, 0x0000872A }, /* GL_MODELVIEW10_ARB */
+   { 20820, 0x0000872B }, /* GL_MODELVIEW11_ARB */
+   { 20839, 0x0000872C }, /* GL_MODELVIEW12_ARB */
+   { 20858, 0x0000872D }, /* GL_MODELVIEW13_ARB */
+   { 20877, 0x0000872E }, /* GL_MODELVIEW14_ARB */
+   { 20896, 0x0000872F }, /* GL_MODELVIEW15_ARB */
+   { 20915, 0x00008730 }, /* GL_MODELVIEW16_ARB */
+   { 20934, 0x00008731 }, /* GL_MODELVIEW17_ARB */
+   { 20953, 0x00008732 }, /* GL_MODELVIEW18_ARB */
+   { 20972, 0x00008733 }, /* GL_MODELVIEW19_ARB */
+   { 20991, 0x0000850A }, /* GL_MODELVIEW1_ARB */
+   { 21009, 0x00008734 }, /* GL_MODELVIEW20_ARB */
+   { 21028, 0x00008735 }, /* GL_MODELVIEW21_ARB */
+   { 21047, 0x00008736 }, /* GL_MODELVIEW22_ARB */
+   { 21066, 0x00008737 }, /* GL_MODELVIEW23_ARB */
+   { 21085, 0x00008738 }, /* GL_MODELVIEW24_ARB */
+   { 21104, 0x00008739 }, /* GL_MODELVIEW25_ARB */
+   { 21123, 0x0000873A }, /* GL_MODELVIEW26_ARB */
+   { 21142, 0x0000873B }, /* GL_MODELVIEW27_ARB */
+   { 21161, 0x0000873C }, /* GL_MODELVIEW28_ARB */
+   { 21180, 0x0000873D }, /* GL_MODELVIEW29_ARB */
+   { 21199, 0x00008722 }, /* GL_MODELVIEW2_ARB */
+   { 21217, 0x0000873E }, /* GL_MODELVIEW30_ARB */
+   { 21236, 0x0000873F }, /* GL_MODELVIEW31_ARB */
+   { 21255, 0x00008723 }, /* GL_MODELVIEW3_ARB */
+   { 21273, 0x00008724 }, /* GL_MODELVIEW4_ARB */
+   { 21291, 0x00008725 }, /* GL_MODELVIEW5_ARB */
+   { 21309, 0x00008726 }, /* GL_MODELVIEW6_ARB */
+   { 21327, 0x00008727 }, /* GL_MODELVIEW7_ARB */
+   { 21345, 0x00008728 }, /* GL_MODELVIEW8_ARB */
+   { 21363, 0x00008729 }, /* GL_MODELVIEW9_ARB */
+   { 21381, 0x00000BA6 }, /* GL_MODELVIEW_MATRIX */
+   { 21401, 0x00008629 }, /* GL_MODELVIEW_PROJECTION_NV */
+   { 21428, 0x00000BA3 }, /* GL_MODELVIEW_STACK_DEPTH */
+   { 21453, 0x00002100 }, /* GL_MODULATE */
+   { 21465, 0x00008744 }, /* GL_MODULATE_ADD_ATI */
+   { 21485, 0x00008745 }, /* GL_MODULATE_SIGNED_ADD_ATI */
+   { 21512, 0x00008746 }, /* GL_MODULATE_SUBTRACT_ATI */
+   { 21537, 0x00000103 }, /* GL_MULT */
+   { 21545, 0x0000809D }, /* GL_MULTISAMPLE */
+   { 21560, 0x000086B2 }, /* GL_MULTISAMPLE_3DFX */
+   { 21580, 0x0000809D }, /* GL_MULTISAMPLE_ARB */
+   { 21599, 0x20000000 }, /* GL_MULTISAMPLE_BIT */
+   { 21618, 0x20000000 }, /* GL_MULTISAMPLE_BIT_3DFX */
+   { 21642, 0x20000000 }, /* GL_MULTISAMPLE_BIT_ARB */
+   { 21665, 0x00008534 }, /* GL_MULTISAMPLE_FILTER_HINT_NV */
+   { 21695, 0x00002A25 }, /* GL_N3F_V3F */
+   { 21706, 0x00000D70 }, /* GL_NAME_STACK_DEPTH */
+   { 21726, 0x0000150E }, /* GL_NAND */
+   { 21734, 0x00002600 }, /* GL_NEAREST */
+   { 21745, 0x0000844E }, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
+   { 21776, 0x0000844D }, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
+   { 21808, 0x00002702 }, /* GL_NEAREST_MIPMAP_LINEAR */
+   { 21833, 0x00002700 }, /* GL_NEAREST_MIPMAP_NEAREST */
+   { 21859, 0x00000200 }, /* GL_NEVER */
+   { 21868, 0x00001102 }, /* GL_NICEST */
+   { 21878, 0x00000000 }, /* GL_NONE */
+   { 21886, 0x00001505 }, /* GL_NOOP */
+   { 21894, 0x00001508 }, /* GL_NOR */
+   { 21901, 0x00000BA1 }, /* GL_NORMALIZE */
+   { 21914, 0x00008075 }, /* GL_NORMAL_ARRAY */
+   { 21930, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
+   { 21961, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING_ARB */
+   { 21996, 0x0000808F }, /* GL_NORMAL_ARRAY_POINTER */
+   { 22020, 0x0000807F }, /* GL_NORMAL_ARRAY_STRIDE */
+   { 22043, 0x0000807E }, /* GL_NORMAL_ARRAY_TYPE */
+   { 22064, 0x00008511 }, /* GL_NORMAL_MAP */
+   { 22078, 0x00008511 }, /* GL_NORMAL_MAP_ARB */
+   { 22096, 0x00008511 }, /* GL_NORMAL_MAP_NV */
+   { 22113, 0x00000205 }, /* GL_NOTEQUAL */
+   { 22125, 0x00000000 }, /* GL_NO_ERROR */
+   { 22137, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
+   { 22171, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB */
+   { 22209, 0x00008B89 }, /* GL_OBJECT_ACTIVE_ATTRIBUTES_ARB */
+   { 22241, 0x00008B8A }, /* GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB */
+   { 22283, 0x00008B86 }, /* GL_OBJECT_ACTIVE_UNIFORMS_ARB */
+   { 22313, 0x00008B87 }, /* GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB */
+   { 22353, 0x00008B85 }, /* GL_OBJECT_ATTACHED_OBJECTS_ARB */
+   { 22384, 0x00008B81 }, /* GL_OBJECT_COMPILE_STATUS_ARB */
+   { 22413, 0x00008B80 }, /* GL_OBJECT_DELETE_STATUS_ARB */
+   { 22441, 0x00008B84 }, /* GL_OBJECT_INFO_LOG_LENGTH_ARB */
+   { 22471, 0x00002401 }, /* GL_OBJECT_LINEAR */
+   { 22488, 0x00008B82 }, /* GL_OBJECT_LINK_STATUS_ARB */
+   { 22514, 0x00002501 }, /* GL_OBJECT_PLANE */
+   { 22530, 0x00008B88 }, /* GL_OBJECT_SHADER_SOURCE_LENGTH_ARB */
+   { 22565, 0x00008B4F }, /* GL_OBJECT_SUBTYPE_ARB */
+   { 22587, 0x00009112 }, /* GL_OBJECT_TYPE */
+   { 22602, 0x00008B4E }, /* GL_OBJECT_TYPE_ARB */
+   { 22621, 0x00008B83 }, /* GL_OBJECT_VALIDATE_STATUS_ARB */
+   { 22651, 0x00008165 }, /* GL_OCCLUSION_TEST_HP */
+   { 22672, 0x00008166 }, /* GL_OCCLUSION_TEST_RESULT_HP */
+   { 22700, 0x00000001 }, /* GL_ONE */
+   { 22707, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA */
+   { 22735, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA_EXT */
+   { 22767, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR */
+   { 22795, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR_EXT */
+   { 22827, 0x00000305 }, /* GL_ONE_MINUS_DST_ALPHA */
+   { 22850, 0x00000307 }, /* GL_ONE_MINUS_DST_COLOR */
+   { 22873, 0x00000303 }, /* GL_ONE_MINUS_SRC_ALPHA */
+   { 22896, 0x00000301 }, /* GL_ONE_MINUS_SRC_COLOR */
+   { 22919, 0x00008598 }, /* GL_OPERAND0_ALPHA */
+   { 22937, 0x00008598 }, /* GL_OPERAND0_ALPHA_ARB */
+   { 22959, 0x00008598 }, /* GL_OPERAND0_ALPHA_EXT */
+   { 22981, 0x00008590 }, /* GL_OPERAND0_RGB */
+   { 22997, 0x00008590 }, /* GL_OPERAND0_RGB_ARB */
+   { 23017, 0x00008590 }, /* GL_OPERAND0_RGB_EXT */
+   { 23037, 0x00008599 }, /* GL_OPERAND1_ALPHA */
+   { 23055, 0x00008599 }, /* GL_OPERAND1_ALPHA_ARB */
+   { 23077, 0x00008599 }, /* GL_OPERAND1_ALPHA_EXT */
+   { 23099, 0x00008591 }, /* GL_OPERAND1_RGB */
+   { 23115, 0x00008591 }, /* GL_OPERAND1_RGB_ARB */
+   { 23135, 0x00008591 }, /* GL_OPERAND1_RGB_EXT */
+   { 23155, 0x0000859A }, /* GL_OPERAND2_ALPHA */
+   { 23173, 0x0000859A }, /* GL_OPERAND2_ALPHA_ARB */
+   { 23195, 0x0000859A }, /* GL_OPERAND2_ALPHA_EXT */
+   { 23217, 0x00008592 }, /* GL_OPERAND2_RGB */
+   { 23233, 0x00008592 }, /* GL_OPERAND2_RGB_ARB */
+   { 23253, 0x00008592 }, /* GL_OPERAND2_RGB_EXT */
+   { 23273, 0x0000859B }, /* GL_OPERAND3_ALPHA_NV */
+   { 23294, 0x00008593 }, /* GL_OPERAND3_RGB_NV */
+   { 23313, 0x00001507 }, /* GL_OR */
+   { 23319, 0x00000A01 }, /* GL_ORDER */
+   { 23328, 0x0000150D }, /* GL_OR_INVERTED */
+   { 23343, 0x0000150B }, /* GL_OR_REVERSE */
+   { 23357, 0x00000505 }, /* GL_OUT_OF_MEMORY */
+   { 23374, 0x00000D05 }, /* GL_PACK_ALIGNMENT */
+   { 23392, 0x0000806C }, /* GL_PACK_IMAGE_HEIGHT */
+   { 23413, 0x00008758 }, /* GL_PACK_INVERT_MESA */
+   { 23433, 0x00000D01 }, /* GL_PACK_LSB_FIRST */
+   { 23451, 0x00000D02 }, /* GL_PACK_ROW_LENGTH */
+   { 23470, 0x0000806B }, /* GL_PACK_SKIP_IMAGES */
+   { 23490, 0x00000D04 }, /* GL_PACK_SKIP_PIXELS */
+   { 23510, 0x00000D03 }, /* GL_PACK_SKIP_ROWS */
+   { 23528, 0x00000D00 }, /* GL_PACK_SWAP_BYTES */
+   { 23547, 0x00008B92 }, /* GL_PALETTE4_R5_G6_B5_OES */
+   { 23572, 0x00008B94 }, /* GL_PALETTE4_RGB5_A1_OES */
+   { 23596, 0x00008B90 }, /* GL_PALETTE4_RGB8_OES */
+   { 23617, 0x00008B93 }, /* GL_PALETTE4_RGBA4_OES */
+   { 23639, 0x00008B91 }, /* GL_PALETTE4_RGBA8_OES */
+   { 23661, 0x00008B97 }, /* GL_PALETTE8_R5_G6_B5_OES */
+   { 23686, 0x00008B99 }, /* GL_PALETTE8_RGB5_A1_OES */
+   { 23710, 0x00008B95 }, /* GL_PALETTE8_RGB8_OES */
+   { 23731, 0x00008B98 }, /* GL_PALETTE8_RGBA4_OES */
+   { 23753, 0x00008B96 }, /* GL_PALETTE8_RGBA8_OES */
+   { 23775, 0x00000700 }, /* GL_PASS_THROUGH_TOKEN */
+   { 23797, 0x00000C50 }, /* GL_PERSPECTIVE_CORRECTION_HINT */
+   { 23828, 0x00000C79 }, /* GL_PIXEL_MAP_A_TO_A */
+   { 23848, 0x00000CB9 }, /* GL_PIXEL_MAP_A_TO_A_SIZE */
+   { 23873, 0x00000C78 }, /* GL_PIXEL_MAP_B_TO_B */
+   { 23893, 0x00000CB8 }, /* GL_PIXEL_MAP_B_TO_B_SIZE */
+   { 23918, 0x00000C77 }, /* GL_PIXEL_MAP_G_TO_G */
+   { 23938, 0x00000CB7 }, /* GL_PIXEL_MAP_G_TO_G_SIZE */
+   { 23963, 0x00000C75 }, /* GL_PIXEL_MAP_I_TO_A */
+   { 23983, 0x00000CB5 }, /* GL_PIXEL_MAP_I_TO_A_SIZE */
+   { 24008, 0x00000C74 }, /* GL_PIXEL_MAP_I_TO_B */
+   { 24028, 0x00000CB4 }, /* GL_PIXEL_MAP_I_TO_B_SIZE */
+   { 24053, 0x00000C73 }, /* GL_PIXEL_MAP_I_TO_G */
+   { 24073, 0x00000CB3 }, /* GL_PIXEL_MAP_I_TO_G_SIZE */
+   { 24098, 0x00000C70 }, /* GL_PIXEL_MAP_I_TO_I */
+   { 24118, 0x00000CB0 }, /* GL_PIXEL_MAP_I_TO_I_SIZE */
+   { 24143, 0x00000C72 }, /* GL_PIXEL_MAP_I_TO_R */
+   { 24163, 0x00000CB2 }, /* GL_PIXEL_MAP_I_TO_R_SIZE */
+   { 24188, 0x00000C76 }, /* GL_PIXEL_MAP_R_TO_R */
+   { 24208, 0x00000CB6 }, /* GL_PIXEL_MAP_R_TO_R_SIZE */
+   { 24233, 0x00000C71 }, /* GL_PIXEL_MAP_S_TO_S */
+   { 24253, 0x00000CB1 }, /* GL_PIXEL_MAP_S_TO_S_SIZE */
+   { 24278, 0x00000020 }, /* GL_PIXEL_MODE_BIT */
+   { 24296, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER */
+   { 24317, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING */
+   { 24346, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING_EXT */
+   { 24379, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER_EXT */
+   { 24404, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER */
+   { 24427, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING */
+   { 24458, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING_EXT */
+   { 24493, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER_EXT */
+   { 24520, 0x00001B00 }, /* GL_POINT */
+   { 24529, 0x00000000 }, /* GL_POINTS */
+   { 24539, 0x00000002 }, /* GL_POINT_BIT */
+   { 24552, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION */
+   { 24582, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_ARB */
+   { 24616, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_EXT */
+   { 24650, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_SGIS */
+   { 24685, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE */
+   { 24714, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_ARB */
+   { 24747, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_EXT */
+   { 24780, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_SGIS */
+   { 24814, 0x00000B11 }, /* GL_POINT_SIZE */
+   { 24828, 0x00000B13 }, /* GL_POINT_SIZE_GRANULARITY */
+   { 24854, 0x00008127 }, /* GL_POINT_SIZE_MAX */
+   { 24872, 0x00008127 }, /* GL_POINT_SIZE_MAX_ARB */
+   { 24894, 0x00008127 }, /* GL_POINT_SIZE_MAX_EXT */
+   { 24916, 0x00008127 }, /* GL_POINT_SIZE_MAX_SGIS */
+   { 24939, 0x00008126 }, /* GL_POINT_SIZE_MIN */
+   { 24957, 0x00008126 }, /* GL_POINT_SIZE_MIN_ARB */
+   { 24979, 0x00008126 }, /* GL_POINT_SIZE_MIN_EXT */
+   { 25001, 0x00008126 }, /* GL_POINT_SIZE_MIN_SGIS */
+   { 25024, 0x00000B12 }, /* GL_POINT_SIZE_RANGE */
+   { 25044, 0x00000B10 }, /* GL_POINT_SMOOTH */
+   { 25060, 0x00000C51 }, /* GL_POINT_SMOOTH_HINT */
+   { 25081, 0x00008861 }, /* GL_POINT_SPRITE */
+   { 25097, 0x00008861 }, /* GL_POINT_SPRITE_ARB */
+   { 25117, 0x00008CA0 }, /* GL_POINT_SPRITE_COORD_ORIGIN */
+   { 25146, 0x00008861 }, /* GL_POINT_SPRITE_NV */
+   { 25165, 0x00008863 }, /* GL_POINT_SPRITE_R_MODE_NV */
+   { 25191, 0x00000701 }, /* GL_POINT_TOKEN */
+   { 25206, 0x00000009 }, /* GL_POLYGON */
+   { 25217, 0x00000008 }, /* GL_POLYGON_BIT */
+   { 25232, 0x00000B40 }, /* GL_POLYGON_MODE */
+   { 25248, 0x00008039 }, /* GL_POLYGON_OFFSET_BIAS */
+   { 25271, 0x00008038 }, /* GL_POLYGON_OFFSET_FACTOR */
+   { 25296, 0x00008037 }, /* GL_POLYGON_OFFSET_FILL */
+   { 25319, 0x00002A02 }, /* GL_POLYGON_OFFSET_LINE */
+   { 25342, 0x00002A01 }, /* GL_POLYGON_OFFSET_POINT */
+   { 25366, 0x00002A00 }, /* GL_POLYGON_OFFSET_UNITS */
+   { 25390, 0x00000B41 }, /* GL_POLYGON_SMOOTH */
+   { 25408, 0x00000C53 }, /* GL_POLYGON_SMOOTH_HINT */
+   { 25431, 0x00000B42 }, /* GL_POLYGON_STIPPLE */
+   { 25450, 0x00000010 }, /* GL_POLYGON_STIPPLE_BIT */
+   { 25473, 0x00000703 }, /* GL_POLYGON_TOKEN */
+   { 25490, 0x00001203 }, /* GL_POSITION */
+   { 25502, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
+   { 25534, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI */
+   { 25570, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
+   { 25603, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI */
+   { 25640, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
+   { 25671, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI */
+   { 25706, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
+   { 25738, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI */
+   { 25774, 0x000080D2 }, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
+   { 25807, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
+   { 25839, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI */
+   { 25875, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
+   { 25908, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI */
+   { 25945, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS */
+   { 25975, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS_SGI */
+   { 26009, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE */
+   { 26040, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE_SGI */
+   { 26075, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
+   { 26106, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS_EXT */
+   { 26141, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
+   { 26173, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE_EXT */
+   { 26209, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS */
+   { 26239, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS_EXT */
+   { 26273, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE */
+   { 26304, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE_EXT */
+   { 26339, 0x000080D1 }, /* GL_POST_CONVOLUTION_COLOR_TABLE */
+   { 26371, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS */
+   { 26402, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS_EXT */
+   { 26437, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE */
+   { 26469, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE_EXT */
+   { 26505, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS */
+   { 26534, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS_EXT */
+   { 26567, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE */
+   { 26597, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE_EXT */
+   { 26631, 0x0000817B }, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
+   { 26670, 0x00008179 }, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
+   { 26703, 0x0000817C }, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
+   { 26743, 0x0000817A }, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
+   { 26777, 0x00008578 }, /* GL_PREVIOUS */
+   { 26789, 0x00008578 }, /* GL_PREVIOUS_ARB */
+   { 26805, 0x00008578 }, /* GL_PREVIOUS_EXT */
+   { 26821, 0x00008577 }, /* GL_PRIMARY_COLOR */
+   { 26838, 0x00008577 }, /* GL_PRIMARY_COLOR_ARB */
+   { 26859, 0x00008577 }, /* GL_PRIMARY_COLOR_EXT */
+   { 26880, 0x000088B0 }, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
+   { 26913, 0x00008805 }, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
+   { 26945, 0x000088AC }, /* GL_PROGRAM_ATTRIBS_ARB */
+   { 26968, 0x00008677 }, /* GL_PROGRAM_BINDING_ARB */
+   { 26991, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_ARB */
+   { 27021, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_NV */
+   { 27050, 0x00008874 }, /* GL_PROGRAM_ERROR_STRING_ARB */
+   { 27078, 0x00008876 }, /* GL_PROGRAM_FORMAT_ARB */
+   { 27100, 0x00008875 }, /* GL_PROGRAM_FORMAT_ASCII_ARB */
+   { 27128, 0x000088A0 }, /* GL_PROGRAM_INSTRUCTIONS_ARB */
+   { 27156, 0x00008627 }, /* GL_PROGRAM_LENGTH_ARB */
+   { 27178, 0x00008627 }, /* GL_PROGRAM_LENGTH_NV */
+   { 27199, 0x000088B2 }, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+   { 27239, 0x00008808 }, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+   { 27278, 0x000088AE }, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
+   { 27308, 0x000088A2 }, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+   { 27343, 0x000088AA }, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
+   { 27376, 0x000088A6 }, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
+   { 27410, 0x0000880A }, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+   { 27449, 0x00008809 }, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+   { 27488, 0x00008B40 }, /* GL_PROGRAM_OBJECT_ARB */
+   { 27510, 0x000088A8 }, /* GL_PROGRAM_PARAMETERS_ARB */
+   { 27536, 0x00008644 }, /* GL_PROGRAM_PARAMETER_NV */
+   { 27560, 0x00008647 }, /* GL_PROGRAM_RESIDENT_NV */
+   { 27583, 0x00008628 }, /* GL_PROGRAM_STRING_ARB */
+   { 27605, 0x00008628 }, /* GL_PROGRAM_STRING_NV */
+   { 27626, 0x00008646 }, /* GL_PROGRAM_TARGET_NV */
+   { 27647, 0x000088A4 }, /* GL_PROGRAM_TEMPORARIES_ARB */
+   { 27674, 0x00008807 }, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
+   { 27706, 0x00008806 }, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
+   { 27738, 0x000088B6 }, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
+   { 27773, 0x00001701 }, /* GL_PROJECTION */
+   { 27787, 0x00000BA7 }, /* GL_PROJECTION_MATRIX */
+   { 27808, 0x00000BA4 }, /* GL_PROJECTION_STACK_DEPTH */
+   { 27834, 0x00008E4F }, /* GL_PROVOKING_VERTEX */
+   { 27854, 0x00008E4F }, /* GL_PROVOKING_VERTEX_EXT */
+   { 27878, 0x000080D3 }, /* GL_PROXY_COLOR_TABLE */
+   { 27899, 0x00008025 }, /* GL_PROXY_HISTOGRAM */
+   { 27918, 0x00008025 }, /* GL_PROXY_HISTOGRAM_EXT */
+   { 27941, 0x000080D5 }, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
+   { 27980, 0x000080D4 }, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
+   { 28018, 0x00008063 }, /* GL_PROXY_TEXTURE_1D */
+   { 28038, 0x00008C19 }, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */
+   { 28068, 0x00008063 }, /* GL_PROXY_TEXTURE_1D_EXT */
+   { 28092, 0x00008064 }, /* GL_PROXY_TEXTURE_2D */
+   { 28112, 0x00008C1B }, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */
+   { 28142, 0x00008064 }, /* GL_PROXY_TEXTURE_2D_EXT */
+   { 28166, 0x00008070 }, /* GL_PROXY_TEXTURE_3D */
+   { 28186, 0x000080BD }, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
+   { 28219, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP */
+   { 28245, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP_ARB */
+   { 28275, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */
+   { 28306, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_NV */
+   { 28336, 0x00002003 }, /* GL_Q */
+   { 28341, 0x00001209 }, /* GL_QUADRATIC_ATTENUATION */
+   { 28366, 0x00000007 }, /* GL_QUADS */
+   { 28375, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */
+   { 28419, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT */
+   { 28467, 0x00008614 }, /* GL_QUAD_MESH_SUN */
+   { 28484, 0x00000008 }, /* GL_QUAD_STRIP */
+   { 28498, 0x00008E16 }, /* GL_QUERY_BY_REGION_NO_WAIT_NV */
+   { 28528, 0x00008E15 }, /* GL_QUERY_BY_REGION_WAIT_NV */
+   { 28555, 0x00008864 }, /* GL_QUERY_COUNTER_BITS */
+   { 28577, 0x00008864 }, /* GL_QUERY_COUNTER_BITS_ARB */
+   { 28603, 0x00008E14 }, /* GL_QUERY_NO_WAIT_NV */
+   { 28623, 0x00008866 }, /* GL_QUERY_RESULT */
+   { 28639, 0x00008866 }, /* GL_QUERY_RESULT_ARB */
+   { 28659, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE */
+   { 28685, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE_ARB */
+   { 28715, 0x00008E13 }, /* GL_QUERY_WAIT_NV */
+   { 28732, 0x00002002 }, /* GL_R */
+   { 28737, 0x00002A10 }, /* GL_R3_G3_B2 */
+   { 28749, 0x00019262 }, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
+   { 28782, 0x00000C02 }, /* GL_READ_BUFFER */
+   { 28797, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER */
+   { 28817, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING */
+   { 28845, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING_EXT */
+   { 28877, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER_EXT */
+   { 28901, 0x000088B8 }, /* GL_READ_ONLY */
+   { 28914, 0x000088B8 }, /* GL_READ_ONLY_ARB */
+   { 28931, 0x000088BA }, /* GL_READ_WRITE */
+   { 28945, 0x000088BA }, /* GL_READ_WRITE_ARB */
+   { 28963, 0x00001903 }, /* GL_RED */
+   { 28970, 0x00008016 }, /* GL_REDUCE */
+   { 28980, 0x00008016 }, /* GL_REDUCE_EXT */
+   { 28994, 0x00000D15 }, /* GL_RED_BIAS */
+   { 29006, 0x00000D52 }, /* GL_RED_BITS */
+   { 29018, 0x00000D14 }, /* GL_RED_SCALE */
+   { 29031, 0x00008512 }, /* GL_REFLECTION_MAP */
+   { 29049, 0x00008512 }, /* GL_REFLECTION_MAP_ARB */
+   { 29071, 0x00008512 }, /* GL_REFLECTION_MAP_NV */
+   { 29092, 0x00001C00 }, /* GL_RENDER */
+   { 29102, 0x00008D41 }, /* GL_RENDERBUFFER */
+   { 29118, 0x00008D53 }, /* GL_RENDERBUFFER_ALPHA_SIZE */
+   { 29145, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING */
+   { 29169, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING_EXT */
+   { 29197, 0x00008D52 }, /* GL_RENDERBUFFER_BLUE_SIZE */
+   { 29223, 0x00008D54 }, /* GL_RENDERBUFFER_DEPTH_SIZE */
+   { 29250, 0x00008D41 }, /* GL_RENDERBUFFER_EXT */
+   { 29270, 0x00008D51 }, /* GL_RENDERBUFFER_GREEN_SIZE */
+   { 29297, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT */
+   { 29320, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT_EXT */
+   { 29347, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
+   { 29379, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT_EXT */
+   { 29415, 0x00008D50 }, /* GL_RENDERBUFFER_RED_SIZE */
+   { 29440, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES */
+   { 29464, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES_EXT */
+   { 29492, 0x00008D55 }, /* GL_RENDERBUFFER_STENCIL_SIZE */
+   { 29521, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH */
+   { 29543, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH_EXT */
+   { 29569, 0x00001F01 }, /* GL_RENDERER */
+   { 29581, 0x00000C40 }, /* GL_RENDER_MODE */
+   { 29596, 0x00002901 }, /* GL_REPEAT */
+   { 29606, 0x00001E01 }, /* GL_REPLACE */
+   { 29617, 0x00008062 }, /* GL_REPLACE_EXT */
+   { 29632, 0x00008153 }, /* GL_REPLICATE_BORDER_HP */
+   { 29655, 0x0000803A }, /* GL_RESCALE_NORMAL */
+   { 29673, 0x0000803A }, /* GL_RESCALE_NORMAL_EXT */
+   { 29695, 0x00000102 }, /* GL_RETURN */
+   { 29705, 0x00001907 }, /* GL_RGB */
+   { 29712, 0x00008052 }, /* GL_RGB10 */
+   { 29721, 0x00008059 }, /* GL_RGB10_A2 */
+   { 29733, 0x00008059 }, /* GL_RGB10_A2_EXT */
+   { 29749, 0x00008052 }, /* GL_RGB10_EXT */
+   { 29762, 0x00008053 }, /* GL_RGB12 */
+   { 29771, 0x00008053 }, /* GL_RGB12_EXT */
+   { 29784, 0x00008054 }, /* GL_RGB16 */
+   { 29793, 0x00008054 }, /* GL_RGB16_EXT */
+   { 29806, 0x0000804E }, /* GL_RGB2_EXT */
+   { 29818, 0x0000804F }, /* GL_RGB4 */
+   { 29826, 0x0000804F }, /* GL_RGB4_EXT */
+   { 29838, 0x000083A1 }, /* GL_RGB4_S3TC */
+   { 29851, 0x00008050 }, /* GL_RGB5 */
+   { 29859, 0x00008057 }, /* GL_RGB5_A1 */
+   { 29870, 0x00008057 }, /* GL_RGB5_A1_EXT */
+   { 29885, 0x00008050 }, /* GL_RGB5_EXT */
+   { 29897, 0x00008051 }, /* GL_RGB8 */
+   { 29905, 0x00008051 }, /* GL_RGB8_EXT */
+   { 29917, 0x00001908 }, /* GL_RGBA */
+   { 29925, 0x0000805A }, /* GL_RGBA12 */
+   { 29935, 0x0000805A }, /* GL_RGBA12_EXT */
+   { 29949, 0x0000805B }, /* GL_RGBA16 */
+   { 29959, 0x0000805B }, /* GL_RGBA16_EXT */
+   { 29973, 0x00008055 }, /* GL_RGBA2 */
+   { 29982, 0x00008055 }, /* GL_RGBA2_EXT */
+   { 29995, 0x00008056 }, /* GL_RGBA4 */
+   { 30004, 0x000083A5 }, /* GL_RGBA4_DXT5_S3TC */
+   { 30023, 0x00008056 }, /* GL_RGBA4_EXT */
+   { 30036, 0x000083A3 }, /* GL_RGBA4_S3TC */
+   { 30050, 0x00008058 }, /* GL_RGBA8 */
+   { 30059, 0x00008058 }, /* GL_RGBA8_EXT */
+   { 30072, 0x00008F97 }, /* GL_RGBA8_SNORM */
+   { 30087, 0x000083A4 }, /* GL_RGBA_DXT5_S3TC */
+   { 30105, 0x00000C31 }, /* GL_RGBA_MODE */
+   { 30118, 0x000083A2 }, /* GL_RGBA_S3TC */
+   { 30131, 0x00008F93 }, /* GL_RGBA_SNORM */
+   { 30145, 0x000083A0 }, /* GL_RGB_S3TC */
+   { 30157, 0x00008573 }, /* GL_RGB_SCALE */
+   { 30170, 0x00008573 }, /* GL_RGB_SCALE_ARB */
+   { 30187, 0x00008573 }, /* GL_RGB_SCALE_EXT */
+   { 30204, 0x00000407 }, /* GL_RIGHT */
+   { 30213, 0x00002000 }, /* GL_S */
+   { 30218, 0x00008B5D }, /* GL_SAMPLER_1D */
+   { 30232, 0x00008B61 }, /* GL_SAMPLER_1D_SHADOW */
+   { 30253, 0x00008B5E }, /* GL_SAMPLER_2D */
+   { 30267, 0x00008B62 }, /* GL_SAMPLER_2D_SHADOW */
+   { 30288, 0x00008B5F }, /* GL_SAMPLER_3D */
+   { 30302, 0x00008B60 }, /* GL_SAMPLER_CUBE */
+   { 30318, 0x000080A9 }, /* GL_SAMPLES */
+   { 30329, 0x000086B4 }, /* GL_SAMPLES_3DFX */
+   { 30345, 0x000080A9 }, /* GL_SAMPLES_ARB */
+   { 30360, 0x00008914 }, /* GL_SAMPLES_PASSED */
+   { 30378, 0x00008914 }, /* GL_SAMPLES_PASSED_ARB */
+   { 30400, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
+   { 30428, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE_ARB */
+   { 30460, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE */
+   { 30483, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE_ARB */
+   { 30510, 0x000080A8 }, /* GL_SAMPLE_BUFFERS */
+   { 30528, 0x000086B3 }, /* GL_SAMPLE_BUFFERS_3DFX */
+   { 30551, 0x000080A8 }, /* GL_SAMPLE_BUFFERS_ARB */
+   { 30573, 0x000080A0 }, /* GL_SAMPLE_COVERAGE */
+   { 30592, 0x000080A0 }, /* GL_SAMPLE_COVERAGE_ARB */
+   { 30615, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT */
+   { 30641, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT_ARB */
+   { 30671, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE */
+   { 30696, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE_ARB */
+   { 30725, 0x00080000 }, /* GL_SCISSOR_BIT */
+   { 30740, 0x00000C10 }, /* GL_SCISSOR_BOX */
+   { 30755, 0x00000C11 }, /* GL_SCISSOR_TEST */
+   { 30771, 0x0000845E }, /* GL_SECONDARY_COLOR_ARRAY */
+   { 30796, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
+   { 30836, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB */
+   { 30880, 0x0000845D }, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
+   { 30913, 0x0000845A }, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
+   { 30943, 0x0000845C }, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
+   { 30975, 0x0000845B }, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
+   { 31005, 0x00001C02 }, /* GL_SELECT */
+   { 31015, 0x00000DF3 }, /* GL_SELECTION_BUFFER_POINTER */
+   { 31043, 0x00000DF4 }, /* GL_SELECTION_BUFFER_SIZE */
+   { 31068, 0x00008012 }, /* GL_SEPARABLE_2D */
+   { 31084, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR */
+   { 31111, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR_EXT */
+   { 31142, 0x0000150F }, /* GL_SET */
+   { 31149, 0x00008B48 }, /* GL_SHADER_OBJECT_ARB */
+   { 31170, 0x00008B88 }, /* GL_SHADER_SOURCE_LENGTH */
+   { 31194, 0x00008B4F }, /* GL_SHADER_TYPE */
+   { 31209, 0x00000B54 }, /* GL_SHADE_MODEL */
+   { 31224, 0x00008B8C }, /* GL_SHADING_LANGUAGE_VERSION */
+   { 31252, 0x000080BF }, /* GL_SHADOW_AMBIENT_SGIX */
+   { 31275, 0x000081FB }, /* GL_SHARED_TEXTURE_PALETTE_EXT */
+   { 31305, 0x00001601 }, /* GL_SHININESS */
+   { 31318, 0x00001402 }, /* GL_SHORT */
+   { 31327, 0x00009119 }, /* GL_SIGNALED */
+   { 31339, 0x00008F9C }, /* GL_SIGNED_NORMALIZED */
+   { 31360, 0x000081F9 }, /* GL_SINGLE_COLOR */
+   { 31376, 0x000081F9 }, /* GL_SINGLE_COLOR_EXT */
+   { 31396, 0x000085CC }, /* GL_SLICE_ACCUM_SUN */
+   { 31415, 0x00008C46 }, /* GL_SLUMINANCE */
+   { 31429, 0x00008C47 }, /* GL_SLUMINANCE8 */
+   { 31444, 0x00008C45 }, /* GL_SLUMINANCE8_ALPHA8 */
+   { 31466, 0x00008C44 }, /* GL_SLUMINANCE_ALPHA */
+   { 31486, 0x00001D01 }, /* GL_SMOOTH */
+   { 31496, 0x00000B23 }, /* GL_SMOOTH_LINE_WIDTH_GRANULARITY */
+   { 31529, 0x00000B22 }, /* GL_SMOOTH_LINE_WIDTH_RANGE */
+   { 31556, 0x00000B13 }, /* GL_SMOOTH_POINT_SIZE_GRANULARITY */
+   { 31589, 0x00000B12 }, /* GL_SMOOTH_POINT_SIZE_RANGE */
+   { 31616, 0x00008588 }, /* GL_SOURCE0_ALPHA */
+   { 31633, 0x00008588 }, /* GL_SOURCE0_ALPHA_ARB */
+   { 31654, 0x00008588 }, /* GL_SOURCE0_ALPHA_EXT */
+   { 31675, 0x00008580 }, /* GL_SOURCE0_RGB */
+   { 31690, 0x00008580 }, /* GL_SOURCE0_RGB_ARB */
+   { 31709, 0x00008580 }, /* GL_SOURCE0_RGB_EXT */
+   { 31728, 0x00008589 }, /* GL_SOURCE1_ALPHA */
+   { 31745, 0x00008589 }, /* GL_SOURCE1_ALPHA_ARB */
+   { 31766, 0x00008589 }, /* GL_SOURCE1_ALPHA_EXT */
+   { 31787, 0x00008581 }, /* GL_SOURCE1_RGB */
+   { 31802, 0x00008581 }, /* GL_SOURCE1_RGB_ARB */
+   { 31821, 0x00008581 }, /* GL_SOURCE1_RGB_EXT */
+   { 31840, 0x0000858A }, /* GL_SOURCE2_ALPHA */
+   { 31857, 0x0000858A }, /* GL_SOURCE2_ALPHA_ARB */
+   { 31878, 0x0000858A }, /* GL_SOURCE2_ALPHA_EXT */
+   { 31899, 0x00008582 }, /* GL_SOURCE2_RGB */
+   { 31914, 0x00008582 }, /* GL_SOURCE2_RGB_ARB */
+   { 31933, 0x00008582 }, /* GL_SOURCE2_RGB_EXT */
+   { 31952, 0x0000858B }, /* GL_SOURCE3_ALPHA_NV */
+   { 31972, 0x00008583 }, /* GL_SOURCE3_RGB_NV */
+   { 31990, 0x00001202 }, /* GL_SPECULAR */
+   { 32002, 0x00002402 }, /* GL_SPHERE_MAP */
+   { 32016, 0x00001206 }, /* GL_SPOT_CUTOFF */
+   { 32031, 0x00001204 }, /* GL_SPOT_DIRECTION */
+   { 32049, 0x00001205 }, /* GL_SPOT_EXPONENT */
+   { 32066, 0x00008588 }, /* GL_SRC0_ALPHA */
+   { 32080, 0x00008580 }, /* GL_SRC0_RGB */
+   { 32092, 0x00008589 }, /* GL_SRC1_ALPHA */
+   { 32106, 0x00008581 }, /* GL_SRC1_RGB */
+   { 32118, 0x0000858A }, /* GL_SRC2_ALPHA */
+   { 32132, 0x00008582 }, /* GL_SRC2_RGB */
+   { 32144, 0x00000302 }, /* GL_SRC_ALPHA */
+   { 32157, 0x00000308 }, /* GL_SRC_ALPHA_SATURATE */
+   { 32179, 0x00000300 }, /* GL_SRC_COLOR */
+   { 32192, 0x00008C40 }, /* GL_SRGB */
+   { 32200, 0x00008C41 }, /* GL_SRGB8 */
+   { 32209, 0x00008C43 }, /* GL_SRGB8_ALPHA8 */
+   { 32225, 0x00008C42 }, /* GL_SRGB_ALPHA */
+   { 32239, 0x00000503 }, /* GL_STACK_OVERFLOW */
+   { 32257, 0x00000504 }, /* GL_STACK_UNDERFLOW */
+   { 32276, 0x000088E6 }, /* GL_STATIC_COPY */
+   { 32291, 0x000088E6 }, /* GL_STATIC_COPY_ARB */
+   { 32310, 0x000088E4 }, /* GL_STATIC_DRAW */
+   { 32325, 0x000088E4 }, /* GL_STATIC_DRAW_ARB */
+   { 32344, 0x000088E5 }, /* GL_STATIC_READ */
+   { 32359, 0x000088E5 }, /* GL_STATIC_READ_ARB */
+   { 32378, 0x00001802 }, /* GL_STENCIL */
+   { 32389, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT */
+   { 32411, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT_EXT */
+   { 32437, 0x00008801 }, /* GL_STENCIL_BACK_FAIL */
+   { 32458, 0x00008801 }, /* GL_STENCIL_BACK_FAIL_ATI */
+   { 32483, 0x00008800 }, /* GL_STENCIL_BACK_FUNC */
+   { 32504, 0x00008800 }, /* GL_STENCIL_BACK_FUNC_ATI */
+   { 32529, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
+   { 32561, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI */
+   { 32597, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
+   { 32629, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI */
+   { 32665, 0x00008CA3 }, /* GL_STENCIL_BACK_REF */
+   { 32685, 0x00008CA4 }, /* GL_STENCIL_BACK_VALUE_MASK */
+   { 32712, 0x00008CA5 }, /* GL_STENCIL_BACK_WRITEMASK */
+   { 32738, 0x00000D57 }, /* GL_STENCIL_BITS */
+   { 32754, 0x00000400 }, /* GL_STENCIL_BUFFER_BIT */
+   { 32776, 0x00000B91 }, /* GL_STENCIL_CLEAR_VALUE */
+   { 32799, 0x00000B94 }, /* GL_STENCIL_FAIL */
+   { 32815, 0x00000B92 }, /* GL_STENCIL_FUNC */
+   { 32831, 0x00001901 }, /* GL_STENCIL_INDEX */
+   { 32848, 0x00008D46 }, /* GL_STENCIL_INDEX1 */
+   { 32866, 0x00008D49 }, /* GL_STENCIL_INDEX16 */
+   { 32885, 0x00008D49 }, /* GL_STENCIL_INDEX16_EXT */
+   { 32908, 0x00008D46 }, /* GL_STENCIL_INDEX1_EXT */
+   { 32930, 0x00008D47 }, /* GL_STENCIL_INDEX4 */
+   { 32948, 0x00008D47 }, /* GL_STENCIL_INDEX4_EXT */
+   { 32970, 0x00008D48 }, /* GL_STENCIL_INDEX8 */
+   { 32988, 0x00008D48 }, /* GL_STENCIL_INDEX8_EXT */
+   { 33010, 0x00008D45 }, /* GL_STENCIL_INDEX_EXT */
+   { 33031, 0x00000B95 }, /* GL_STENCIL_PASS_DEPTH_FAIL */
+   { 33058, 0x00000B96 }, /* GL_STENCIL_PASS_DEPTH_PASS */
+   { 33085, 0x00000B97 }, /* GL_STENCIL_REF */
+   { 33100, 0x00000B90 }, /* GL_STENCIL_TEST */
+   { 33116, 0x00008910 }, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
+   { 33145, 0x00000B93 }, /* GL_STENCIL_VALUE_MASK */
+   { 33167, 0x00000B98 }, /* GL_STENCIL_WRITEMASK */
+   { 33188, 0x00000C33 }, /* GL_STEREO */
+   { 33198, 0x000085BE }, /* GL_STORAGE_CACHED_APPLE */
+   { 33222, 0x000085BD }, /* GL_STORAGE_PRIVATE_APPLE */
+   { 33247, 0x000085BF }, /* GL_STORAGE_SHARED_APPLE */
+   { 33271, 0x000088E2 }, /* GL_STREAM_COPY */
+   { 33286, 0x000088E2 }, /* GL_STREAM_COPY_ARB */
+   { 33305, 0x000088E0 }, /* GL_STREAM_DRAW */
+   { 33320, 0x000088E0 }, /* GL_STREAM_DRAW_ARB */
+   { 33339, 0x000088E1 }, /* GL_STREAM_READ */
+   { 33354, 0x000088E1 }, /* GL_STREAM_READ_ARB */
+   { 33373, 0x00000D50 }, /* GL_SUBPIXEL_BITS */
+   { 33390, 0x000084E7 }, /* GL_SUBTRACT */
+   { 33402, 0x000084E7 }, /* GL_SUBTRACT_ARB */
+   { 33418, 0x00009113 }, /* GL_SYNC_CONDITION */
+   { 33436, 0x00009116 }, /* GL_SYNC_FENCE */
+   { 33450, 0x00009115 }, /* GL_SYNC_FLAGS */
+   { 33464, 0x00000001 }, /* GL_SYNC_FLUSH_COMMANDS_BIT */
+   { 33491, 0x00009117 }, /* GL_SYNC_GPU_COMMANDS_COMPLETE */
+   { 33521, 0x00009114 }, /* GL_SYNC_STATUS */
+   { 33536, 0x00002001 }, /* GL_T */
+   { 33541, 0x00002A2A }, /* GL_T2F_C3F_V3F */
+   { 33556, 0x00002A2C }, /* GL_T2F_C4F_N3F_V3F */
+   { 33575, 0x00002A29 }, /* GL_T2F_C4UB_V3F */
+   { 33591, 0x00002A2B }, /* GL_T2F_N3F_V3F */
+   { 33606, 0x00002A27 }, /* GL_T2F_V3F */
+   { 33617, 0x00002A2D }, /* GL_T4F_C4F_N3F_V4F */
+   { 33636, 0x00002A28 }, /* GL_T4F_V4F */
+   { 33647, 0x00008031 }, /* GL_TABLE_TOO_LARGE_EXT */
+   { 33670, 0x00001702 }, /* GL_TEXTURE */
+   { 33681, 0x000084C0 }, /* GL_TEXTURE0 */
+   { 33693, 0x000084C0 }, /* GL_TEXTURE0_ARB */
+   { 33709, 0x000084C1 }, /* GL_TEXTURE1 */
+   { 33721, 0x000084CA }, /* GL_TEXTURE10 */
+   { 33734, 0x000084CA }, /* GL_TEXTURE10_ARB */
+   { 33751, 0x000084CB }, /* GL_TEXTURE11 */
+   { 33764, 0x000084CB }, /* GL_TEXTURE11_ARB */
+   { 33781, 0x000084CC }, /* GL_TEXTURE12 */
+   { 33794, 0x000084CC }, /* GL_TEXTURE12_ARB */
+   { 33811, 0x000084CD }, /* GL_TEXTURE13 */
+   { 33824, 0x000084CD }, /* GL_TEXTURE13_ARB */
+   { 33841, 0x000084CE }, /* GL_TEXTURE14 */
+   { 33854, 0x000084CE }, /* GL_TEXTURE14_ARB */
+   { 33871, 0x000084CF }, /* GL_TEXTURE15 */
+   { 33884, 0x000084CF }, /* GL_TEXTURE15_ARB */
+   { 33901, 0x000084D0 }, /* GL_TEXTURE16 */
+   { 33914, 0x000084D0 }, /* GL_TEXTURE16_ARB */
+   { 33931, 0x000084D1 }, /* GL_TEXTURE17 */
+   { 33944, 0x000084D1 }, /* GL_TEXTURE17_ARB */
+   { 33961, 0x000084D2 }, /* GL_TEXTURE18 */
+   { 33974, 0x000084D2 }, /* GL_TEXTURE18_ARB */
+   { 33991, 0x000084D3 }, /* GL_TEXTURE19 */
+   { 34004, 0x000084D3 }, /* GL_TEXTURE19_ARB */
+   { 34021, 0x000084C1 }, /* GL_TEXTURE1_ARB */
+   { 34037, 0x000084C2 }, /* GL_TEXTURE2 */
+   { 34049, 0x000084D4 }, /* GL_TEXTURE20 */
+   { 34062, 0x000084D4 }, /* GL_TEXTURE20_ARB */
+   { 34079, 0x000084D5 }, /* GL_TEXTURE21 */
+   { 34092, 0x000084D5 }, /* GL_TEXTURE21_ARB */
+   { 34109, 0x000084D6 }, /* GL_TEXTURE22 */
+   { 34122, 0x000084D6 }, /* GL_TEXTURE22_ARB */
+   { 34139, 0x000084D7 }, /* GL_TEXTURE23 */
+   { 34152, 0x000084D7 }, /* GL_TEXTURE23_ARB */
+   { 34169, 0x000084D8 }, /* GL_TEXTURE24 */
+   { 34182, 0x000084D8 }, /* GL_TEXTURE24_ARB */
+   { 34199, 0x000084D9 }, /* GL_TEXTURE25 */
+   { 34212, 0x000084D9 }, /* GL_TEXTURE25_ARB */
+   { 34229, 0x000084DA }, /* GL_TEXTURE26 */
+   { 34242, 0x000084DA }, /* GL_TEXTURE26_ARB */
+   { 34259, 0x000084DB }, /* GL_TEXTURE27 */
+   { 34272, 0x000084DB }, /* GL_TEXTURE27_ARB */
+   { 34289, 0x000084DC }, /* GL_TEXTURE28 */
+   { 34302, 0x000084DC }, /* GL_TEXTURE28_ARB */
+   { 34319, 0x000084DD }, /* GL_TEXTURE29 */
+   { 34332, 0x000084DD }, /* GL_TEXTURE29_ARB */
+   { 34349, 0x000084C2 }, /* GL_TEXTURE2_ARB */
+   { 34365, 0x000084C3 }, /* GL_TEXTURE3 */
+   { 34377, 0x000084DE }, /* GL_TEXTURE30 */
+   { 34390, 0x000084DE }, /* GL_TEXTURE30_ARB */
+   { 34407, 0x000084DF }, /* GL_TEXTURE31 */
+   { 34420, 0x000084DF }, /* GL_TEXTURE31_ARB */
+   { 34437, 0x000084C3 }, /* GL_TEXTURE3_ARB */
+   { 34453, 0x000084C4 }, /* GL_TEXTURE4 */
+   { 34465, 0x000084C4 }, /* GL_TEXTURE4_ARB */
+   { 34481, 0x000084C5 }, /* GL_TEXTURE5 */
+   { 34493, 0x000084C5 }, /* GL_TEXTURE5_ARB */
+   { 34509, 0x000084C6 }, /* GL_TEXTURE6 */
+   { 34521, 0x000084C6 }, /* GL_TEXTURE6_ARB */
+   { 34537, 0x000084C7 }, /* GL_TEXTURE7 */
+   { 34549, 0x000084C7 }, /* GL_TEXTURE7_ARB */
+   { 34565, 0x000084C8 }, /* GL_TEXTURE8 */
+   { 34577, 0x000084C8 }, /* GL_TEXTURE8_ARB */
+   { 34593, 0x000084C9 }, /* GL_TEXTURE9 */
+   { 34605, 0x000084C9 }, /* GL_TEXTURE9_ARB */
+   { 34621, 0x00000DE0 }, /* GL_TEXTURE_1D */
+   { 34635, 0x00008C18 }, /* GL_TEXTURE_1D_ARRAY_EXT */
+   { 34659, 0x00000DE1 }, /* GL_TEXTURE_2D */
+   { 34673, 0x00008C1A }, /* GL_TEXTURE_2D_ARRAY_EXT */
+   { 34697, 0x0000806F }, /* GL_TEXTURE_3D */
+   { 34711, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE */
+   { 34733, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE_EXT */
+   { 34759, 0x0000813C }, /* GL_TEXTURE_BASE_LEVEL */
+   { 34781, 0x00008068 }, /* GL_TEXTURE_BINDING_1D */
+   { 34803, 0x00008C1C }, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */
+   { 34835, 0x00008069 }, /* GL_TEXTURE_BINDING_2D */
+   { 34857, 0x00008C1D }, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */
+   { 34889, 0x0000806A }, /* GL_TEXTURE_BINDING_3D */
+   { 34911, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP */
+   { 34939, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP_ARB */
+   { 34971, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
+   { 35004, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_NV */
+   { 35036, 0x00040000 }, /* GL_TEXTURE_BIT */
+   { 35051, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE */
+   { 35072, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE_EXT */
+   { 35097, 0x00001005 }, /* GL_TEXTURE_BORDER */
+   { 35115, 0x00001004 }, /* GL_TEXTURE_BORDER_COLOR */
+   { 35139, 0x00008171 }, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
+   { 35170, 0x00008176 }, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
+   { 35200, 0x00008172 }, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
+   { 35230, 0x00008175 }, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
+   { 35265, 0x00008173 }, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
+   { 35296, 0x00008174 }, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+   { 35334, 0x000080BC }, /* GL_TEXTURE_COLOR_TABLE_SGI */
+   { 35361, 0x000081EF }, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
+   { 35393, 0x000080BF }, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
+   { 35427, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC */
+   { 35451, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC_ARB */
+   { 35479, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE */
+   { 35503, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE_ARB */
+   { 35531, 0x0000819B }, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
+   { 35564, 0x0000819A }, /* GL_TEXTURE_COMPARE_SGIX */
+   { 35588, 0x00001003 }, /* GL_TEXTURE_COMPONENTS */
+   { 35610, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED */
+   { 35632, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED_ARB */
+   { 35658, 0x000086A3 }, /* GL_TEXTURE_COMPRESSED_FORMATS_ARB */
+   { 35692, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
+   { 35725, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB */
+   { 35762, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT */
+   { 35790, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT_ARB */
+   { 35822, 0x00008078 }, /* GL_TEXTURE_COORD_ARRAY */
+   { 35845, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
+   { 35883, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB */
+   { 35925, 0x00008092 }, /* GL_TEXTURE_COORD_ARRAY_POINTER */
+   { 35956, 0x00008088 }, /* GL_TEXTURE_COORD_ARRAY_SIZE */
+   { 35984, 0x0000808A }, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
+   { 36014, 0x00008089 }, /* GL_TEXTURE_COORD_ARRAY_TYPE */
+   { 36042, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP */
+   { 36062, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP_ARB */
+   { 36086, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
+   { 36117, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB */
+   { 36152, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
+   { 36183, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB */
+   { 36218, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
+   { 36249, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB */
+   { 36284, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
+   { 36315, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB */
+   { 36350, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
+   { 36381, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB */
+   { 36416, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
+   { 36447, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB */
+   { 36482, 0x000088F4 }, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */
+   { 36511, 0x00008071 }, /* GL_TEXTURE_DEPTH */
+   { 36528, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE */
+   { 36550, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE_ARB */
+   { 36576, 0x00002300 }, /* GL_TEXTURE_ENV */
+   { 36591, 0x00002201 }, /* GL_TEXTURE_ENV_COLOR */
+   { 36612, 0x00002200 }, /* GL_TEXTURE_ENV_MODE */
+   { 36632, 0x00008500 }, /* GL_TEXTURE_FILTER_CONTROL */
+   { 36658, 0x00002500 }, /* GL_TEXTURE_GEN_MODE */
+   { 36678, 0x00000C63 }, /* GL_TEXTURE_GEN_Q */
+   { 36695, 0x00000C62 }, /* GL_TEXTURE_GEN_R */
+   { 36712, 0x00000C60 }, /* GL_TEXTURE_GEN_S */
+   { 36729, 0x00000C61 }, /* GL_TEXTURE_GEN_T */
+   { 36746, 0x0000819D }, /* GL_TEXTURE_GEQUAL_R_SGIX */
+   { 36771, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE */
+   { 36793, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE_EXT */
+   { 36819, 0x00001001 }, /* GL_TEXTURE_HEIGHT */
+   { 36837, 0x000080ED }, /* GL_TEXTURE_INDEX_SIZE_EXT */
+   { 36863, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE */
+   { 36889, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE_EXT */
+   { 36919, 0x00001003 }, /* GL_TEXTURE_INTERNAL_FORMAT */
+   { 36946, 0x0000819C }, /* GL_TEXTURE_LEQUAL_R_SGIX */
+   { 36971, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS */
+   { 36991, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS_EXT */
+   { 37015, 0x00008190 }, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
+   { 37042, 0x0000818E }, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
+   { 37069, 0x0000818F }, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
+   { 37096, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE */
+   { 37122, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE_EXT */
+   { 37152, 0x00002800 }, /* GL_TEXTURE_MAG_FILTER */
+   { 37174, 0x00000BA8 }, /* GL_TEXTURE_MATRIX */
+   { 37192, 0x000084FE }, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
+   { 37222, 0x0000836B }, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
+   { 37250, 0x00008369 }, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
+   { 37278, 0x0000836A }, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
+   { 37306, 0x0000813D }, /* GL_TEXTURE_MAX_LEVEL */
+   { 37327, 0x0000813B }, /* GL_TEXTURE_MAX_LOD */
+   { 37346, 0x00002801 }, /* GL_TEXTURE_MIN_FILTER */
+   { 37368, 0x0000813A }, /* GL_TEXTURE_MIN_LOD */
+   { 37387, 0x00008066 }, /* GL_TEXTURE_PRIORITY */
+   { 37407, 0x000085B7 }, /* GL_TEXTURE_RANGE_LENGTH_APPLE */
+   { 37437, 0x000085B8 }, /* GL_TEXTURE_RANGE_POINTER_APPLE */
+   { 37468, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_ARB */
+   { 37493, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_NV */
+   { 37517, 0x0000805C }, /* GL_TEXTURE_RED_SIZE */
+   { 37537, 0x0000805C }, /* GL_TEXTURE_RED_SIZE_EXT */
+   { 37561, 0x00008067 }, /* GL_TEXTURE_RESIDENT */
+   { 37581, 0x00000BA5 }, /* GL_TEXTURE_STACK_DEPTH */
+   { 37604, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE */
+   { 37628, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE_EXT */
+   { 37656, 0x000085BC }, /* GL_TEXTURE_STORAGE_HINT_APPLE */
+   { 37686, 0x00008065 }, /* GL_TEXTURE_TOO_LARGE_EXT */
+   { 37711, 0x0000888F }, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
+   { 37745, 0x00001000 }, /* GL_TEXTURE_WIDTH */
+   { 37762, 0x00008072 }, /* GL_TEXTURE_WRAP_R */
+   { 37780, 0x00002802 }, /* GL_TEXTURE_WRAP_S */
+   { 37798, 0x00002803 }, /* GL_TEXTURE_WRAP_T */
+   { 37816, 0x0000911B }, /* GL_TIMEOUT_EXPIRED */
+   { 37835, 0x000088BF }, /* GL_TIME_ELAPSED_EXT */
+   { 37855, 0x00008648 }, /* GL_TRACK_MATRIX_NV */
+   { 37874, 0x00008649 }, /* GL_TRACK_MATRIX_TRANSFORM_NV */
+   { 37903, 0x00001000 }, /* GL_TRANSFORM_BIT */
+   { 37920, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX */
+   { 37946, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX_ARB */
+   { 37976, 0x000088B7 }, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
+   { 38008, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
+   { 38038, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX_ARB */
+   { 38072, 0x0000862C }, /* GL_TRANSPOSE_NV */
+   { 38088, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX */
+   { 38119, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX_ARB */
+   { 38154, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX */
+   { 38182, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX_ARB */
+   { 38214, 0x00000004 }, /* GL_TRIANGLES */
+   { 38227, 0x00000006 }, /* GL_TRIANGLE_FAN */
+   { 38243, 0x00008615 }, /* GL_TRIANGLE_MESH_SUN */
+   { 38264, 0x00000005 }, /* GL_TRIANGLE_STRIP */
+   { 38282, 0x00000001 }, /* GL_TRUE */
+   { 38290, 0x00000CF5 }, /* GL_UNPACK_ALIGNMENT */
+   { 38310, 0x0000806E }, /* GL_UNPACK_IMAGE_HEIGHT */
+   { 38333, 0x00000CF1 }, /* GL_UNPACK_LSB_FIRST */
+   { 38353, 0x00000CF2 }, /* GL_UNPACK_ROW_LENGTH */
+   { 38374, 0x0000806D }, /* GL_UNPACK_SKIP_IMAGES */
+   { 38396, 0x00000CF4 }, /* GL_UNPACK_SKIP_PIXELS */
+   { 38418, 0x00000CF3 }, /* GL_UNPACK_SKIP_ROWS */
+   { 38438, 0x00000CF0 }, /* GL_UNPACK_SWAP_BYTES */
+   { 38459, 0x00009118 }, /* GL_UNSIGNALED */
+   { 38473, 0x00001401 }, /* GL_UNSIGNED_BYTE */
+   { 38490, 0x00008362 }, /* GL_UNSIGNED_BYTE_2_3_3_REV */
+   { 38517, 0x00008032 }, /* GL_UNSIGNED_BYTE_3_3_2 */
+   { 38540, 0x00001405 }, /* GL_UNSIGNED_INT */
+   { 38556, 0x00008036 }, /* GL_UNSIGNED_INT_10_10_10_2 */
+   { 38583, 0x000084FA }, /* GL_UNSIGNED_INT_24_8 */
+   { 38604, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_EXT */
+   { 38629, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_NV */
+   { 38653, 0x00008368 }, /* GL_UNSIGNED_INT_2_10_10_10_REV */
+   { 38684, 0x00008035 }, /* GL_UNSIGNED_INT_8_8_8_8 */
+   { 38708, 0x00008367 }, /* GL_UNSIGNED_INT_8_8_8_8_REV */
+   { 38736, 0x00008C17 }, /* GL_UNSIGNED_NORMALIZED */
+   { 38759, 0x00001403 }, /* GL_UNSIGNED_SHORT */
+   { 38777, 0x00008366 }, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
+   { 38807, 0x00008033 }, /* GL_UNSIGNED_SHORT_4_4_4_4 */
+   { 38833, 0x00008365 }, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
+   { 38863, 0x00008034 }, /* GL_UNSIGNED_SHORT_5_5_5_1 */
+   { 38889, 0x00008363 }, /* GL_UNSIGNED_SHORT_5_6_5 */
+   { 38913, 0x00008364 }, /* GL_UNSIGNED_SHORT_5_6_5_REV */
+   { 38941, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_APPLE */
+   { 38969, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_MESA */
+   { 38996, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
+   { 39028, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_MESA */
+   { 39059, 0x00008CA2 }, /* GL_UPPER_LEFT */
+   { 39073, 0x00002A20 }, /* GL_V2F */
+   { 39080, 0x00002A21 }, /* GL_V3F */
+   { 39087, 0x00008B83 }, /* GL_VALIDATE_STATUS */
+   { 39106, 0x00001F00 }, /* GL_VENDOR */
+   { 39116, 0x00001F02 }, /* GL_VERSION */
+   { 39127, 0x00008074 }, /* GL_VERTEX_ARRAY */
+   { 39143, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING */
+   { 39167, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING_APPLE */
+   { 39197, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
+   { 39228, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING_ARB */
+   { 39263, 0x0000808E }, /* GL_VERTEX_ARRAY_POINTER */
+   { 39287, 0x0000807A }, /* GL_VERTEX_ARRAY_SIZE */
+   { 39308, 0x0000807C }, /* GL_VERTEX_ARRAY_STRIDE */
+   { 39331, 0x0000807B }, /* GL_VERTEX_ARRAY_TYPE */
+   { 39352, 0x00008650 }, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
+   { 39379, 0x0000865A }, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
+   { 39407, 0x0000865B }, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
+   { 39435, 0x0000865C }, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
+   { 39463, 0x0000865D }, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
+   { 39491, 0x0000865E }, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
+   { 39519, 0x0000865F }, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
+   { 39547, 0x00008651 }, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
+   { 39574, 0x00008652 }, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
+   { 39601, 0x00008653 }, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
+   { 39628, 0x00008654 }, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
+   { 39655, 0x00008655 }, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
+   { 39682, 0x00008656 }, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
+   { 39709, 0x00008657 }, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
+   { 39736, 0x00008658 }, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
+   { 39763, 0x00008659 }, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
+   { 39790, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
+   { 39828, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB */
+   { 39870, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
+   { 39901, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB */
+   { 39936, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
+   { 39970, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB */
+   { 40008, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
+   { 40039, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB */
+   { 40074, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
+   { 40102, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB */
+   { 40134, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
+   { 40164, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB */
+   { 40198, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
+   { 40226, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB */
+   { 40258, 0x000086A7 }, /* GL_VERTEX_BLEND_ARB */
+   { 40278, 0x00008620 }, /* GL_VERTEX_PROGRAM_ARB */
+   { 40300, 0x0000864A }, /* GL_VERTEX_PROGRAM_BINDING_NV */
+   { 40329, 0x00008620 }, /* GL_VERTEX_PROGRAM_NV */
+   { 40350, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE */
+   { 40379, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_ARB */
+   { 40412, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_NV */
+   { 40444, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE */
+   { 40471, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_ARB */
+   { 40502, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_NV */
+   { 40532, 0x00008B31 }, /* GL_VERTEX_SHADER */
+   { 40549, 0x00008B31 }, /* GL_VERTEX_SHADER_ARB */
+   { 40570, 0x00008621 }, /* GL_VERTEX_STATE_PROGRAM_NV */
+   { 40597, 0x00000BA2 }, /* GL_VIEWPORT */
+   { 40609, 0x00000800 }, /* GL_VIEWPORT_BIT */
+   { 40625, 0x0000911D }, /* GL_WAIT_FAILED */
+   { 40640, 0x000086AD }, /* GL_WEIGHT_ARRAY_ARB */
+   { 40660, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
+   { 40691, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB */
+   { 40726, 0x000086AC }, /* GL_WEIGHT_ARRAY_POINTER_ARB */
+   { 40754, 0x000086AB }, /* GL_WEIGHT_ARRAY_SIZE_ARB */
+   { 40779, 0x000086AA }, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
+   { 40806, 0x000086A9 }, /* GL_WEIGHT_ARRAY_TYPE_ARB */
+   { 40831, 0x000086A6 }, /* GL_WEIGHT_SUM_UNITY_ARB */
+   { 40855, 0x000081D4 }, /* GL_WRAP_BORDER_SUN */
+   { 40874, 0x000088B9 }, /* GL_WRITE_ONLY */
+   { 40888, 0x000088B9 }, /* GL_WRITE_ONLY_ARB */
+   { 40906, 0x00001506 }, /* GL_XOR */
+   { 40913, 0x000085B9 }, /* GL_YCBCR_422_APPLE */
+   { 40932, 0x00008757 }, /* GL_YCBCR_MESA */
+   { 40946, 0x00000000 }, /* GL_ZERO */
+   { 40954, 0x00000D16 }, /* GL_ZOOM_X */
+   { 40964, 0x00000D17 }, /* GL_ZOOM_Y */
 };
 
-static const unsigned reduced_enums[1347] =
+static const unsigned reduced_enums[1350] =
 {
-       476, /* GL_FALSE */
-       694, /* GL_LINES */
-       696, /* GL_LINE_LOOP */
-       703, /* GL_LINE_STRIP */
-      1748, /* GL_TRIANGLES */
-      1751, /* GL_TRIANGLE_STRIP */
-      1749, /* GL_TRIANGLE_FAN */
-      1275, /* GL_QUADS */
-      1279, /* GL_QUAD_STRIP */
-      1161, /* GL_POLYGON */
-      1173, /* GL_POLYGON_STIPPLE_BIT */
-      1122, /* GL_PIXEL_MODE_BIT */
-       681, /* GL_LIGHTING_BIT */
-       506, /* GL_FOG_BIT */
+       479, /* GL_FALSE */
+       701, /* GL_LINES */
+       703, /* GL_LINE_LOOP */
+       710, /* GL_LINE_STRIP */
+      1769, /* GL_TRIANGLES */
+      1772, /* GL_TRIANGLE_STRIP */
+      1770, /* GL_TRIANGLE_FAN */
+      1285, /* GL_QUADS */
+      1289, /* GL_QUAD_STRIP */
+      1171, /* GL_POLYGON */
+      1183, /* GL_POLYGON_STIPPLE_BIT */
+      1132, /* GL_PIXEL_MODE_BIT */
+       688, /* GL_LIGHTING_BIT */
+       509, /* GL_FOG_BIT */
          8, /* GL_ACCUM */
-       713, /* GL_LOAD */
-      1331, /* GL_RETURN */
-       994, /* GL_MULT */
+       720, /* GL_LOAD */
+      1348, /* GL_RETURN */
+      1004, /* GL_MULT */
         23, /* GL_ADD */
-      1010, /* GL_NEVER */
-       671, /* GL_LESS */
-       466, /* GL_EQUAL */
-       670, /* GL_LEQUAL */
-       592, /* GL_GREATER */
-      1025, /* GL_NOTEQUAL */
-       591, /* GL_GEQUAL */
+      1020, /* GL_NEVER */
+       678, /* GL_LESS */
+       469, /* GL_EQUAL */
+       677, /* GL_LEQUAL */
+       599, /* GL_GREATER */
+      1035, /* GL_NOTEQUAL */
+       598, /* GL_GEQUAL */
         47, /* GL_ALWAYS */
-      1472, /* GL_SRC_COLOR */
-      1055, /* GL_ONE_MINUS_SRC_COLOR */
-      1470, /* GL_SRC_ALPHA */
-      1054, /* GL_ONE_MINUS_SRC_ALPHA */
-       445, /* GL_DST_ALPHA */
-      1052, /* GL_ONE_MINUS_DST_ALPHA */
-       446, /* GL_DST_COLOR */
-      1053, /* GL_ONE_MINUS_DST_COLOR */
-      1471, /* GL_SRC_ALPHA_SATURATE */
-       579, /* GL_FRONT_LEFT */
-       580, /* GL_FRONT_RIGHT */
+      1489, /* GL_SRC_COLOR */
+      1065, /* GL_ONE_MINUS_SRC_COLOR */
+      1487, /* GL_SRC_ALPHA */
+      1064, /* GL_ONE_MINUS_SRC_ALPHA */
+       448, /* GL_DST_ALPHA */
+      1062, /* GL_ONE_MINUS_DST_ALPHA */
+       449, /* GL_DST_COLOR */
+      1063, /* GL_ONE_MINUS_DST_COLOR */
+      1488, /* GL_SRC_ALPHA_SATURATE */
+       586, /* GL_FRONT_LEFT */
+       587, /* GL_FRONT_RIGHT */
         69, /* GL_BACK_LEFT */
         70, /* GL_BACK_RIGHT */
-       576, /* GL_FRONT */
+       583, /* GL_FRONT */
         68, /* GL_BACK */
-       669, /* GL_LEFT */
-      1373, /* GL_RIGHT */
-       577, /* GL_FRONT_AND_BACK */
+       676, /* GL_LEFT */
+      1390, /* GL_RIGHT */
+       584, /* GL_FRONT_AND_BACK */
         63, /* GL_AUX0 */
         64, /* GL_AUX1 */
         65, /* GL_AUX2 */
         66, /* GL_AUX3 */
-       658, /* GL_INVALID_ENUM */
-       662, /* GL_INVALID_VALUE */
-       661, /* GL_INVALID_OPERATION */
-      1477, /* GL_STACK_OVERFLOW */
-      1478, /* GL_STACK_UNDERFLOW */
-      1080, /* GL_OUT_OF_MEMORY */
-       659, /* GL_INVALID_FRAMEBUFFER_OPERATION */
+       665, /* GL_INVALID_ENUM */
+       669, /* GL_INVALID_VALUE */
+       668, /* GL_INVALID_OPERATION */
+      1494, /* GL_STACK_OVERFLOW */
+      1495, /* GL_STACK_UNDERFLOW */
+      1090, /* GL_OUT_OF_MEMORY */
+       666, /* GL_INVALID_FRAMEBUFFER_OPERATION */
          0, /* GL_2D */
          2, /* GL_3D */
          3, /* GL_3D_COLOR */
          4, /* GL_3D_COLOR_TEXTURE */
          6, /* GL_4D_COLOR_TEXTURE */
-      1100, /* GL_PASS_THROUGH_TOKEN */
-      1160, /* GL_POINT_TOKEN */
-       704, /* GL_LINE_TOKEN */
-      1174, /* GL_POLYGON_TOKEN */
+      1110, /* GL_PASS_THROUGH_TOKEN */
+      1170, /* GL_POINT_TOKEN */
+       711, /* GL_LINE_TOKEN */
+      1184, /* GL_POLYGON_TOKEN */
         74, /* GL_BITMAP_TOKEN */
-       444, /* GL_DRAW_PIXEL_TOKEN */
+       447, /* GL_DRAW_PIXEL_TOKEN */
        301, /* GL_COPY_PIXEL_TOKEN */
-       697, /* GL_LINE_RESET_TOKEN */
-       469, /* GL_EXP */
-       470, /* GL_EXP2 */
+       704, /* GL_LINE_RESET_TOKEN */
+       472, /* GL_EXP */
+       473, /* GL_EXP2 */
        337, /* GL_CW */
        125, /* GL_CCW */
        146, /* GL_COEFF */
-      1077, /* GL_ORDER */
-       382, /* GL_DOMAIN */
+      1087, /* GL_ORDER */
+       384, /* GL_DOMAIN */
        311, /* GL_CURRENT_COLOR */
        314, /* GL_CURRENT_INDEX */
        320, /* GL_CURRENT_NORMAL */
@@ -3854,519 +3898,519 @@
        328, /* GL_CURRENT_RASTER_POSITION */
        329, /* GL_CURRENT_RASTER_POSITION_VALID */
        326, /* GL_CURRENT_RASTER_DISTANCE */
-      1153, /* GL_POINT_SMOOTH */
-      1142, /* GL_POINT_SIZE */
-      1152, /* GL_POINT_SIZE_RANGE */
-      1143, /* GL_POINT_SIZE_GRANULARITY */
-       698, /* GL_LINE_SMOOTH */
-       705, /* GL_LINE_WIDTH */
-       707, /* GL_LINE_WIDTH_RANGE */
-       706, /* GL_LINE_WIDTH_GRANULARITY */
-       700, /* GL_LINE_STIPPLE */
-       701, /* GL_LINE_STIPPLE_PATTERN */
-       702, /* GL_LINE_STIPPLE_REPEAT */
-       712, /* GL_LIST_MODE */
-       877, /* GL_MAX_LIST_NESTING */
-       709, /* GL_LIST_BASE */
-       711, /* GL_LIST_INDEX */
-      1163, /* GL_POLYGON_MODE */
-      1170, /* GL_POLYGON_SMOOTH */
-      1172, /* GL_POLYGON_STIPPLE */
-       455, /* GL_EDGE_FLAG */
+      1163, /* GL_POINT_SMOOTH */
+      1152, /* GL_POINT_SIZE */
+      1162, /* GL_POINT_SIZE_RANGE */
+      1153, /* GL_POINT_SIZE_GRANULARITY */
+       705, /* GL_LINE_SMOOTH */
+       712, /* GL_LINE_WIDTH */
+       714, /* GL_LINE_WIDTH_RANGE */
+       713, /* GL_LINE_WIDTH_GRANULARITY */
+       707, /* GL_LINE_STIPPLE */
+       708, /* GL_LINE_STIPPLE_PATTERN */
+       709, /* GL_LINE_STIPPLE_REPEAT */
+       719, /* GL_LIST_MODE */
+       885, /* GL_MAX_LIST_NESTING */
+       716, /* GL_LIST_BASE */
+       718, /* GL_LIST_INDEX */
+      1173, /* GL_POLYGON_MODE */
+      1180, /* GL_POLYGON_SMOOTH */
+      1182, /* GL_POLYGON_STIPPLE */
+       458, /* GL_EDGE_FLAG */
        304, /* GL_CULL_FACE */
        305, /* GL_CULL_FACE_MODE */
-       578, /* GL_FRONT_FACE */
-       680, /* GL_LIGHTING */
-       685, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
-       686, /* GL_LIGHT_MODEL_TWO_SIDE */
-       682, /* GL_LIGHT_MODEL_AMBIENT */
-      1419, /* GL_SHADE_MODEL */
+       585, /* GL_FRONT_FACE */
+       687, /* GL_LIGHTING */
+       692, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
+       693, /* GL_LIGHT_MODEL_TWO_SIDE */
+       689, /* GL_LIGHT_MODEL_AMBIENT */
+      1436, /* GL_SHADE_MODEL */
        193, /* GL_COLOR_MATERIAL_FACE */
        194, /* GL_COLOR_MATERIAL_PARAMETER */
        192, /* GL_COLOR_MATERIAL */
-       505, /* GL_FOG */
-       527, /* GL_FOG_INDEX */
-       523, /* GL_FOG_DENSITY */
-       531, /* GL_FOG_START */
-       525, /* GL_FOG_END */
-       528, /* GL_FOG_MODE */
-       507, /* GL_FOG_COLOR */
-       369, /* GL_DEPTH_RANGE */
-       376, /* GL_DEPTH_TEST */
-       379, /* GL_DEPTH_WRITEMASK */
-       357, /* GL_DEPTH_CLEAR_VALUE */
-       368, /* GL_DEPTH_FUNC */
+       508, /* GL_FOG */
+       530, /* GL_FOG_INDEX */
+       526, /* GL_FOG_DENSITY */
+       534, /* GL_FOG_START */
+       528, /* GL_FOG_END */
+       531, /* GL_FOG_MODE */
+       510, /* GL_FOG_COLOR */
+       370, /* GL_DEPTH_RANGE */
+       378, /* GL_DEPTH_TEST */
+       381, /* GL_DEPTH_WRITEMASK */
+       358, /* GL_DEPTH_CLEAR_VALUE */
+       369, /* GL_DEPTH_FUNC */
         12, /* GL_ACCUM_CLEAR_VALUE */
-      1513, /* GL_STENCIL_TEST */
-      1501, /* GL_STENCIL_CLEAR_VALUE */
-      1503, /* GL_STENCIL_FUNC */
-      1515, /* GL_STENCIL_VALUE_MASK */
-      1502, /* GL_STENCIL_FAIL */
-      1510, /* GL_STENCIL_PASS_DEPTH_FAIL */
-      1511, /* GL_STENCIL_PASS_DEPTH_PASS */
-      1512, /* GL_STENCIL_REF */
-      1516, /* GL_STENCIL_WRITEMASK */
-       846, /* GL_MATRIX_MODE */
-      1015, /* GL_NORMALIZE */
-      1842, /* GL_VIEWPORT */
-       989, /* GL_MODELVIEW_STACK_DEPTH */
-      1253, /* GL_PROJECTION_STACK_DEPTH */
-      1723, /* GL_TEXTURE_STACK_DEPTH */
-       987, /* GL_MODELVIEW_MATRIX */
-      1252, /* GL_PROJECTION_MATRIX */
-      1706, /* GL_TEXTURE_MATRIX */
+      1534, /* GL_STENCIL_TEST */
+      1518, /* GL_STENCIL_CLEAR_VALUE */
+      1520, /* GL_STENCIL_FUNC */
+      1536, /* GL_STENCIL_VALUE_MASK */
+      1519, /* GL_STENCIL_FAIL */
+      1531, /* GL_STENCIL_PASS_DEPTH_FAIL */
+      1532, /* GL_STENCIL_PASS_DEPTH_PASS */
+      1533, /* GL_STENCIL_REF */
+      1537, /* GL_STENCIL_WRITEMASK */
+       853, /* GL_MATRIX_MODE */
+      1025, /* GL_NORMALIZE */
+      1864, /* GL_VIEWPORT */
+       999, /* GL_MODELVIEW_STACK_DEPTH */
+      1263, /* GL_PROJECTION_STACK_DEPTH */
+      1744, /* GL_TEXTURE_STACK_DEPTH */
+       997, /* GL_MODELVIEW_MATRIX */
+      1262, /* GL_PROJECTION_MATRIX */
+      1727, /* GL_TEXTURE_MATRIX */
         61, /* GL_ATTRIB_STACK_DEPTH */
        136, /* GL_CLIENT_ATTRIB_STACK_DEPTH */
         43, /* GL_ALPHA_TEST */
         44, /* GL_ALPHA_TEST_FUNC */
         45, /* GL_ALPHA_TEST_REF */
-       381, /* GL_DITHER */
+       383, /* GL_DITHER */
         78, /* GL_BLEND_DST */
         87, /* GL_BLEND_SRC */
         75, /* GL_BLEND */
-       715, /* GL_LOGIC_OP_MODE */
-       632, /* GL_INDEX_LOGIC_OP */
+       722, /* GL_LOGIC_OP_MODE */
+       639, /* GL_INDEX_LOGIC_OP */
        191, /* GL_COLOR_LOGIC_OP */
         67, /* GL_AUX_BUFFERS */
-       392, /* GL_DRAW_BUFFER */
-      1289, /* GL_READ_BUFFER */
-      1400, /* GL_SCISSOR_BOX */
-      1401, /* GL_SCISSOR_TEST */
-       631, /* GL_INDEX_CLEAR_VALUE */
-       636, /* GL_INDEX_WRITEMASK */
+       394, /* GL_DRAW_BUFFER */
+      1303, /* GL_READ_BUFFER */
+      1417, /* GL_SCISSOR_BOX */
+      1418, /* GL_SCISSOR_TEST */
+       638, /* GL_INDEX_CLEAR_VALUE */
+       643, /* GL_INDEX_WRITEMASK */
        188, /* GL_COLOR_CLEAR_VALUE */
        230, /* GL_COLOR_WRITEMASK */
-       633, /* GL_INDEX_MODE */
-      1366, /* GL_RGBA_MODE */
-       391, /* GL_DOUBLEBUFFER */
-      1517, /* GL_STEREO */
-      1324, /* GL_RENDER_MODE */
-      1101, /* GL_PERSPECTIVE_CORRECTION_HINT */
-      1154, /* GL_POINT_SMOOTH_HINT */
-       699, /* GL_LINE_SMOOTH_HINT */
-      1171, /* GL_POLYGON_SMOOTH_HINT */
-       526, /* GL_FOG_HINT */
-      1687, /* GL_TEXTURE_GEN_S */
-      1688, /* GL_TEXTURE_GEN_T */
-      1686, /* GL_TEXTURE_GEN_R */
-      1685, /* GL_TEXTURE_GEN_Q */
-      1114, /* GL_PIXEL_MAP_I_TO_I */
-      1120, /* GL_PIXEL_MAP_S_TO_S */
-      1116, /* GL_PIXEL_MAP_I_TO_R */
-      1112, /* GL_PIXEL_MAP_I_TO_G */
-      1110, /* GL_PIXEL_MAP_I_TO_B */
-      1108, /* GL_PIXEL_MAP_I_TO_A */
-      1118, /* GL_PIXEL_MAP_R_TO_R */
-      1106, /* GL_PIXEL_MAP_G_TO_G */
-      1104, /* GL_PIXEL_MAP_B_TO_B */
-      1102, /* GL_PIXEL_MAP_A_TO_A */
-      1115, /* GL_PIXEL_MAP_I_TO_I_SIZE */
-      1121, /* GL_PIXEL_MAP_S_TO_S_SIZE */
-      1117, /* GL_PIXEL_MAP_I_TO_R_SIZE */
-      1113, /* GL_PIXEL_MAP_I_TO_G_SIZE */
-      1111, /* GL_PIXEL_MAP_I_TO_B_SIZE */
-      1109, /* GL_PIXEL_MAP_I_TO_A_SIZE */
-      1119, /* GL_PIXEL_MAP_R_TO_R_SIZE */
-      1107, /* GL_PIXEL_MAP_G_TO_G_SIZE */
-      1105, /* GL_PIXEL_MAP_B_TO_B_SIZE */
-      1103, /* GL_PIXEL_MAP_A_TO_A_SIZE */
-      1760, /* GL_UNPACK_SWAP_BYTES */
-      1755, /* GL_UNPACK_LSB_FIRST */
-      1756, /* GL_UNPACK_ROW_LENGTH */
-      1759, /* GL_UNPACK_SKIP_ROWS */
-      1758, /* GL_UNPACK_SKIP_PIXELS */
-      1753, /* GL_UNPACK_ALIGNMENT */
-      1089, /* GL_PACK_SWAP_BYTES */
-      1084, /* GL_PACK_LSB_FIRST */
-      1085, /* GL_PACK_ROW_LENGTH */
-      1088, /* GL_PACK_SKIP_ROWS */
-      1087, /* GL_PACK_SKIP_PIXELS */
-      1081, /* GL_PACK_ALIGNMENT */
-       793, /* GL_MAP_COLOR */
-       798, /* GL_MAP_STENCIL */
-       635, /* GL_INDEX_SHIFT */
-       634, /* GL_INDEX_OFFSET */
-      1302, /* GL_RED_SCALE */
-      1300, /* GL_RED_BIAS */
-      1860, /* GL_ZOOM_X */
-      1861, /* GL_ZOOM_Y */
-       596, /* GL_GREEN_SCALE */
-       594, /* GL_GREEN_BIAS */
+       640, /* GL_INDEX_MODE */
+      1383, /* GL_RGBA_MODE */
+       393, /* GL_DOUBLEBUFFER */
+      1538, /* GL_STEREO */
+      1341, /* GL_RENDER_MODE */
+      1111, /* GL_PERSPECTIVE_CORRECTION_HINT */
+      1164, /* GL_POINT_SMOOTH_HINT */
+       706, /* GL_LINE_SMOOTH_HINT */
+      1181, /* GL_POLYGON_SMOOTH_HINT */
+       529, /* GL_FOG_HINT */
+      1708, /* GL_TEXTURE_GEN_S */
+      1709, /* GL_TEXTURE_GEN_T */
+      1707, /* GL_TEXTURE_GEN_R */
+      1706, /* GL_TEXTURE_GEN_Q */
+      1124, /* GL_PIXEL_MAP_I_TO_I */
+      1130, /* GL_PIXEL_MAP_S_TO_S */
+      1126, /* GL_PIXEL_MAP_I_TO_R */
+      1122, /* GL_PIXEL_MAP_I_TO_G */
+      1120, /* GL_PIXEL_MAP_I_TO_B */
+      1118, /* GL_PIXEL_MAP_I_TO_A */
+      1128, /* GL_PIXEL_MAP_R_TO_R */
+      1116, /* GL_PIXEL_MAP_G_TO_G */
+      1114, /* GL_PIXEL_MAP_B_TO_B */
+      1112, /* GL_PIXEL_MAP_A_TO_A */
+      1125, /* GL_PIXEL_MAP_I_TO_I_SIZE */
+      1131, /* GL_PIXEL_MAP_S_TO_S_SIZE */
+      1127, /* GL_PIXEL_MAP_I_TO_R_SIZE */
+      1123, /* GL_PIXEL_MAP_I_TO_G_SIZE */
+      1121, /* GL_PIXEL_MAP_I_TO_B_SIZE */
+      1119, /* GL_PIXEL_MAP_I_TO_A_SIZE */
+      1129, /* GL_PIXEL_MAP_R_TO_R_SIZE */
+      1117, /* GL_PIXEL_MAP_G_TO_G_SIZE */
+      1115, /* GL_PIXEL_MAP_B_TO_B_SIZE */
+      1113, /* GL_PIXEL_MAP_A_TO_A_SIZE */
+      1781, /* GL_UNPACK_SWAP_BYTES */
+      1776, /* GL_UNPACK_LSB_FIRST */
+      1777, /* GL_UNPACK_ROW_LENGTH */
+      1780, /* GL_UNPACK_SKIP_ROWS */
+      1779, /* GL_UNPACK_SKIP_PIXELS */
+      1774, /* GL_UNPACK_ALIGNMENT */
+      1099, /* GL_PACK_SWAP_BYTES */
+      1094, /* GL_PACK_LSB_FIRST */
+      1095, /* GL_PACK_ROW_LENGTH */
+      1098, /* GL_PACK_SKIP_ROWS */
+      1097, /* GL_PACK_SKIP_PIXELS */
+      1091, /* GL_PACK_ALIGNMENT */
+       800, /* GL_MAP_COLOR */
+       805, /* GL_MAP_STENCIL */
+       642, /* GL_INDEX_SHIFT */
+       641, /* GL_INDEX_OFFSET */
+      1317, /* GL_RED_SCALE */
+      1315, /* GL_RED_BIAS */
+      1882, /* GL_ZOOM_X */
+      1883, /* GL_ZOOM_Y */
+       603, /* GL_GREEN_SCALE */
+       601, /* GL_GREEN_BIAS */
         93, /* GL_BLUE_SCALE */
         91, /* GL_BLUE_BIAS */
         42, /* GL_ALPHA_SCALE */
         40, /* GL_ALPHA_BIAS */
-       370, /* GL_DEPTH_SCALE */
-       350, /* GL_DEPTH_BIAS */
-       872, /* GL_MAX_EVAL_ORDER */
-       876, /* GL_MAX_LIGHTS */
-       855, /* GL_MAX_CLIP_PLANES */
-       922, /* GL_MAX_TEXTURE_SIZE */
-       882, /* GL_MAX_PIXEL_MAP_TABLE */
-       851, /* GL_MAX_ATTRIB_STACK_DEPTH */
-       879, /* GL_MAX_MODELVIEW_STACK_DEPTH */
-       880, /* GL_MAX_NAME_STACK_DEPTH */
-       908, /* GL_MAX_PROJECTION_STACK_DEPTH */
-       923, /* GL_MAX_TEXTURE_STACK_DEPTH */
-       937, /* GL_MAX_VIEWPORT_DIMS */
-       852, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
-      1527, /* GL_SUBPIXEL_BITS */
-       630, /* GL_INDEX_BITS */
-      1301, /* GL_RED_BITS */
-       595, /* GL_GREEN_BITS */
+       371, /* GL_DEPTH_SCALE */
+       351, /* GL_DEPTH_BIAS */
+       880, /* GL_MAX_EVAL_ORDER */
+       884, /* GL_MAX_LIGHTS */
+       862, /* GL_MAX_CLIP_PLANES */
+       932, /* GL_MAX_TEXTURE_SIZE */
+       890, /* GL_MAX_PIXEL_MAP_TABLE */
+       858, /* GL_MAX_ATTRIB_STACK_DEPTH */
+       887, /* GL_MAX_MODELVIEW_STACK_DEPTH */
+       888, /* GL_MAX_NAME_STACK_DEPTH */
+       916, /* GL_MAX_PROJECTION_STACK_DEPTH */
+       933, /* GL_MAX_TEXTURE_STACK_DEPTH */
+       947, /* GL_MAX_VIEWPORT_DIMS */
+       859, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
+      1548, /* GL_SUBPIXEL_BITS */
+       637, /* GL_INDEX_BITS */
+      1316, /* GL_RED_BITS */
+       602, /* GL_GREEN_BITS */
         92, /* GL_BLUE_BITS */
         41, /* GL_ALPHA_BITS */
-       351, /* GL_DEPTH_BITS */
-      1499, /* GL_STENCIL_BITS */
+       352, /* GL_DEPTH_BITS */
+      1516, /* GL_STENCIL_BITS */
         14, /* GL_ACCUM_RED_BITS */
         13, /* GL_ACCUM_GREEN_BITS */
         10, /* GL_ACCUM_BLUE_BITS */
          9, /* GL_ACCUM_ALPHA_BITS */
-      1003, /* GL_NAME_STACK_DEPTH */
+      1013, /* GL_NAME_STACK_DEPTH */
         62, /* GL_AUTO_NORMAL */
-       739, /* GL_MAP1_COLOR_4 */
-       742, /* GL_MAP1_INDEX */
-       743, /* GL_MAP1_NORMAL */
-       744, /* GL_MAP1_TEXTURE_COORD_1 */
-       745, /* GL_MAP1_TEXTURE_COORD_2 */
-       746, /* GL_MAP1_TEXTURE_COORD_3 */
-       747, /* GL_MAP1_TEXTURE_COORD_4 */
-       748, /* GL_MAP1_VERTEX_3 */
-       749, /* GL_MAP1_VERTEX_4 */
-       766, /* GL_MAP2_COLOR_4 */
-       769, /* GL_MAP2_INDEX */
-       770, /* GL_MAP2_NORMAL */
-       771, /* GL_MAP2_TEXTURE_COORD_1 */
-       772, /* GL_MAP2_TEXTURE_COORD_2 */
-       773, /* GL_MAP2_TEXTURE_COORD_3 */
-       774, /* GL_MAP2_TEXTURE_COORD_4 */
-       775, /* GL_MAP2_VERTEX_3 */
-       776, /* GL_MAP2_VERTEX_4 */
-       740, /* GL_MAP1_GRID_DOMAIN */
-       741, /* GL_MAP1_GRID_SEGMENTS */
-       767, /* GL_MAP2_GRID_DOMAIN */
-       768, /* GL_MAP2_GRID_SEGMENTS */
-      1610, /* GL_TEXTURE_1D */
-      1612, /* GL_TEXTURE_2D */
-       479, /* GL_FEEDBACK_BUFFER_POINTER */
-       480, /* GL_FEEDBACK_BUFFER_SIZE */
-       481, /* GL_FEEDBACK_BUFFER_TYPE */
-      1410, /* GL_SELECTION_BUFFER_POINTER */
-      1411, /* GL_SELECTION_BUFFER_SIZE */
-      1728, /* GL_TEXTURE_WIDTH */
-      1692, /* GL_TEXTURE_HEIGHT */
-      1647, /* GL_TEXTURE_COMPONENTS */
-      1631, /* GL_TEXTURE_BORDER_COLOR */
-      1630, /* GL_TEXTURE_BORDER */
-       383, /* GL_DONT_CARE */
-       477, /* GL_FASTEST */
-      1011, /* GL_NICEST */
+       746, /* GL_MAP1_COLOR_4 */
+       749, /* GL_MAP1_INDEX */
+       750, /* GL_MAP1_NORMAL */
+       751, /* GL_MAP1_TEXTURE_COORD_1 */
+       752, /* GL_MAP1_TEXTURE_COORD_2 */
+       753, /* GL_MAP1_TEXTURE_COORD_3 */
+       754, /* GL_MAP1_TEXTURE_COORD_4 */
+       755, /* GL_MAP1_VERTEX_3 */
+       756, /* GL_MAP1_VERTEX_4 */
+       773, /* GL_MAP2_COLOR_4 */
+       776, /* GL_MAP2_INDEX */
+       777, /* GL_MAP2_NORMAL */
+       778, /* GL_MAP2_TEXTURE_COORD_1 */
+       779, /* GL_MAP2_TEXTURE_COORD_2 */
+       780, /* GL_MAP2_TEXTURE_COORD_3 */
+       781, /* GL_MAP2_TEXTURE_COORD_4 */
+       782, /* GL_MAP2_VERTEX_3 */
+       783, /* GL_MAP2_VERTEX_4 */
+       747, /* GL_MAP1_GRID_DOMAIN */
+       748, /* GL_MAP1_GRID_SEGMENTS */
+       774, /* GL_MAP2_GRID_DOMAIN */
+       775, /* GL_MAP2_GRID_SEGMENTS */
+      1631, /* GL_TEXTURE_1D */
+      1633, /* GL_TEXTURE_2D */
+       482, /* GL_FEEDBACK_BUFFER_POINTER */
+       483, /* GL_FEEDBACK_BUFFER_SIZE */
+       484, /* GL_FEEDBACK_BUFFER_TYPE */
+      1427, /* GL_SELECTION_BUFFER_POINTER */
+      1428, /* GL_SELECTION_BUFFER_SIZE */
+      1750, /* GL_TEXTURE_WIDTH */
+      1713, /* GL_TEXTURE_HEIGHT */
+      1668, /* GL_TEXTURE_COMPONENTS */
+      1652, /* GL_TEXTURE_BORDER_COLOR */
+      1651, /* GL_TEXTURE_BORDER */
+       385, /* GL_DONT_CARE */
+       480, /* GL_FASTEST */
+      1021, /* GL_NICEST */
         48, /* GL_AMBIENT */
-       380, /* GL_DIFFUSE */
-      1459, /* GL_SPECULAR */
-      1175, /* GL_POSITION */
-      1462, /* GL_SPOT_DIRECTION */
-      1463, /* GL_SPOT_EXPONENT */
-      1461, /* GL_SPOT_CUTOFF */
+       382, /* GL_DIFFUSE */
+      1476, /* GL_SPECULAR */
+      1185, /* GL_POSITION */
+      1479, /* GL_SPOT_DIRECTION */
+      1480, /* GL_SPOT_EXPONENT */
+      1478, /* GL_SPOT_CUTOFF */
        275, /* GL_CONSTANT_ATTENUATION */
-       689, /* GL_LINEAR_ATTENUATION */
-      1274, /* GL_QUADRATIC_ATTENUATION */
+       696, /* GL_LINEAR_ATTENUATION */
+      1284, /* GL_QUADRATIC_ATTENUATION */
        244, /* GL_COMPILE */
        245, /* GL_COMPILE_AND_EXECUTE */
        120, /* GL_BYTE */
-      1762, /* GL_UNSIGNED_BYTE */
-      1424, /* GL_SHORT */
-      1773, /* GL_UNSIGNED_SHORT */
-       638, /* GL_INT */
-      1765, /* GL_UNSIGNED_INT */
-       486, /* GL_FLOAT */
+      1783, /* GL_UNSIGNED_BYTE */
+      1441, /* GL_SHORT */
+      1795, /* GL_UNSIGNED_SHORT */
+       645, /* GL_INT */
+      1786, /* GL_UNSIGNED_INT */
+       489, /* GL_FLOAT */
          1, /* GL_2_BYTES */
          5, /* GL_3_BYTES */
          7, /* GL_4_BYTES */
-       390, /* GL_DOUBLE */
+       392, /* GL_DOUBLE */
        132, /* GL_CLEAR */
         50, /* GL_AND */
         52, /* GL_AND_REVERSE */
        299, /* GL_COPY */
         51, /* GL_AND_INVERTED */
-      1013, /* GL_NOOP */
-      1856, /* GL_XOR */
-      1076, /* GL_OR */
-      1014, /* GL_NOR */
-       467, /* GL_EQUIV */
-       665, /* GL_INVERT */
-      1079, /* GL_OR_REVERSE */
+      1023, /* GL_NOOP */
+      1878, /* GL_XOR */
+      1086, /* GL_OR */
+      1024, /* GL_NOR */
+       470, /* GL_EQUIV */
+       672, /* GL_INVERT */
+      1089, /* GL_OR_REVERSE */
        300, /* GL_COPY_INVERTED */
-      1078, /* GL_OR_INVERTED */
-      1004, /* GL_NAND */
-      1415, /* GL_SET */
-       464, /* GL_EMISSION */
-      1423, /* GL_SHININESS */
+      1088, /* GL_OR_INVERTED */
+      1014, /* GL_NAND */
+      1432, /* GL_SET */
+       467, /* GL_EMISSION */
+      1440, /* GL_SHININESS */
         49, /* GL_AMBIENT_AND_DIFFUSE */
        190, /* GL_COLOR_INDEXES */
-       954, /* GL_MODELVIEW */
-      1251, /* GL_PROJECTION */
-      1545, /* GL_TEXTURE */
+       964, /* GL_MODELVIEW */
+      1261, /* GL_PROJECTION */
+      1566, /* GL_TEXTURE */
        147, /* GL_COLOR */
        346, /* GL_DEPTH */
-      1485, /* GL_STENCIL */
+      1502, /* GL_STENCIL */
        189, /* GL_COLOR_INDEX */
-      1504, /* GL_STENCIL_INDEX */
-       358, /* GL_DEPTH_COMPONENT */
-      1297, /* GL_RED */
-       593, /* GL_GREEN */
+      1521, /* GL_STENCIL_INDEX */
+       359, /* GL_DEPTH_COMPONENT */
+      1312, /* GL_RED */
+       600, /* GL_GREEN */
         90, /* GL_BLUE */
         31, /* GL_ALPHA */
-      1332, /* GL_RGB */
-      1351, /* GL_RGBA */
-       717, /* GL_LUMINANCE */
-       738, /* GL_LUMINANCE_ALPHA */
+      1349, /* GL_RGB */
+      1368, /* GL_RGBA */
+       724, /* GL_LUMINANCE */
+       745, /* GL_LUMINANCE_ALPHA */
         73, /* GL_BITMAP */
-      1131, /* GL_POINT */
-       687, /* GL_LINE */
-       482, /* GL_FILL */
-      1306, /* GL_RENDER */
-       478, /* GL_FEEDBACK */
-      1409, /* GL_SELECT */
-       485, /* GL_FLAT */
-      1434, /* GL_SMOOTH */
-       666, /* GL_KEEP */
-      1326, /* GL_REPLACE */
-       620, /* GL_INCR */
+      1141, /* GL_POINT */
+       694, /* GL_LINE */
+       485, /* GL_FILL */
+      1321, /* GL_RENDER */
+       481, /* GL_FEEDBACK */
+      1426, /* GL_SELECT */
+       488, /* GL_FLAT */
+      1451, /* GL_SMOOTH */
+       673, /* GL_KEEP */
+      1343, /* GL_REPLACE */
+       627, /* GL_INCR */
        342, /* GL_DECR */
-      1788, /* GL_VENDOR */
-      1323, /* GL_RENDERER */
-      1789, /* GL_VERSION */
-       471, /* GL_EXTENSIONS */
-      1374, /* GL_S */
-      1536, /* GL_T */
-      1286, /* GL_R */
-      1273, /* GL_Q */
-       990, /* GL_MODULATE */
+      1810, /* GL_VENDOR */
+      1340, /* GL_RENDERER */
+      1811, /* GL_VERSION */
+       474, /* GL_EXTENSIONS */
+      1391, /* GL_S */
+      1557, /* GL_T */
+      1300, /* GL_R */
+      1283, /* GL_Q */
+      1000, /* GL_MODULATE */
        341, /* GL_DECAL */
-      1682, /* GL_TEXTURE_ENV_MODE */
-      1681, /* GL_TEXTURE_ENV_COLOR */
-      1680, /* GL_TEXTURE_ENV */
-       472, /* GL_EYE_LINEAR */
-      1037, /* GL_OBJECT_LINEAR */
-      1460, /* GL_SPHERE_MAP */
-      1684, /* GL_TEXTURE_GEN_MODE */
-      1039, /* GL_OBJECT_PLANE */
-       473, /* GL_EYE_PLANE */
-      1005, /* GL_NEAREST */
-       688, /* GL_LINEAR */
-      1009, /* GL_NEAREST_MIPMAP_NEAREST */
-       693, /* GL_LINEAR_MIPMAP_NEAREST */
-      1008, /* GL_NEAREST_MIPMAP_LINEAR */
-       692, /* GL_LINEAR_MIPMAP_LINEAR */
-      1705, /* GL_TEXTURE_MAG_FILTER */
-      1713, /* GL_TEXTURE_MIN_FILTER */
-      1730, /* GL_TEXTURE_WRAP_S */
-      1731, /* GL_TEXTURE_WRAP_T */
+      1703, /* GL_TEXTURE_ENV_MODE */
+      1702, /* GL_TEXTURE_ENV_COLOR */
+      1701, /* GL_TEXTURE_ENV */
+       475, /* GL_EYE_LINEAR */
+      1047, /* GL_OBJECT_LINEAR */
+      1477, /* GL_SPHERE_MAP */
+      1705, /* GL_TEXTURE_GEN_MODE */
+      1049, /* GL_OBJECT_PLANE */
+       476, /* GL_EYE_PLANE */
+      1015, /* GL_NEAREST */
+       695, /* GL_LINEAR */
+      1019, /* GL_NEAREST_MIPMAP_NEAREST */
+       700, /* GL_LINEAR_MIPMAP_NEAREST */
+      1018, /* GL_NEAREST_MIPMAP_LINEAR */
+       699, /* GL_LINEAR_MIPMAP_LINEAR */
+      1726, /* GL_TEXTURE_MAG_FILTER */
+      1734, /* GL_TEXTURE_MIN_FILTER */
+      1752, /* GL_TEXTURE_WRAP_S */
+      1753, /* GL_TEXTURE_WRAP_T */
        126, /* GL_CLAMP */
-      1325, /* GL_REPEAT */
-      1169, /* GL_POLYGON_OFFSET_UNITS */
-      1168, /* GL_POLYGON_OFFSET_POINT */
-      1167, /* GL_POLYGON_OFFSET_LINE */
-      1287, /* GL_R3_G3_B2 */
-      1785, /* GL_V2F */
-      1786, /* GL_V3F */
+      1342, /* GL_REPEAT */
+      1179, /* GL_POLYGON_OFFSET_UNITS */
+      1178, /* GL_POLYGON_OFFSET_POINT */
+      1177, /* GL_POLYGON_OFFSET_LINE */
+      1301, /* GL_R3_G3_B2 */
+      1807, /* GL_V2F */
+      1808, /* GL_V3F */
        123, /* GL_C4UB_V2F */
        124, /* GL_C4UB_V3F */
        121, /* GL_C3F_V3F */
-      1002, /* GL_N3F_V3F */
+      1012, /* GL_N3F_V3F */
        122, /* GL_C4F_N3F_V3F */
-      1541, /* GL_T2F_V3F */
-      1543, /* GL_T4F_V4F */
-      1539, /* GL_T2F_C4UB_V3F */
-      1537, /* GL_T2F_C3F_V3F */
-      1540, /* GL_T2F_N3F_V3F */
-      1538, /* GL_T2F_C4F_N3F_V3F */
-      1542, /* GL_T4F_C4F_N3F_V4F */
+      1562, /* GL_T2F_V3F */
+      1564, /* GL_T4F_V4F */
+      1560, /* GL_T2F_C4UB_V3F */
+      1558, /* GL_T2F_C3F_V3F */
+      1561, /* GL_T2F_N3F_V3F */
+      1559, /* GL_T2F_C4F_N3F_V3F */
+      1563, /* GL_T4F_C4F_N3F_V4F */
        139, /* GL_CLIP_PLANE0 */
        140, /* GL_CLIP_PLANE1 */
        141, /* GL_CLIP_PLANE2 */
        142, /* GL_CLIP_PLANE3 */
        143, /* GL_CLIP_PLANE4 */
        144, /* GL_CLIP_PLANE5 */
-       672, /* GL_LIGHT0 */
-       673, /* GL_LIGHT1 */
-       674, /* GL_LIGHT2 */
-       675, /* GL_LIGHT3 */
-       676, /* GL_LIGHT4 */
-       677, /* GL_LIGHT5 */
-       678, /* GL_LIGHT6 */
-       679, /* GL_LIGHT7 */
-       597, /* GL_HINT_BIT */
+       679, /* GL_LIGHT0 */
+       680, /* GL_LIGHT1 */
+       681, /* GL_LIGHT2 */
+       682, /* GL_LIGHT3 */
+       683, /* GL_LIGHT4 */
+       684, /* GL_LIGHT5 */
+       685, /* GL_LIGHT6 */
+       686, /* GL_LIGHT7 */
+       604, /* GL_HINT_BIT */
        277, /* GL_CONSTANT_COLOR */
-      1050, /* GL_ONE_MINUS_CONSTANT_COLOR */
+      1060, /* GL_ONE_MINUS_CONSTANT_COLOR */
        272, /* GL_CONSTANT_ALPHA */
-      1048, /* GL_ONE_MINUS_CONSTANT_ALPHA */
+      1058, /* GL_ONE_MINUS_CONSTANT_ALPHA */
         76, /* GL_BLEND_COLOR */
-       581, /* GL_FUNC_ADD */
-       938, /* GL_MIN */
-       848, /* GL_MAX */
+       588, /* GL_FUNC_ADD */
+       948, /* GL_MIN */
+       855, /* GL_MAX */
         81, /* GL_BLEND_EQUATION */
-       585, /* GL_FUNC_SUBTRACT */
-       583, /* GL_FUNC_REVERSE_SUBTRACT */
+       592, /* GL_FUNC_SUBTRACT */
+       590, /* GL_FUNC_REVERSE_SUBTRACT */
        280, /* GL_CONVOLUTION_1D */
        281, /* GL_CONVOLUTION_2D */
-      1412, /* GL_SEPARABLE_2D */
+      1429, /* GL_SEPARABLE_2D */
        284, /* GL_CONVOLUTION_BORDER_MODE */
        288, /* GL_CONVOLUTION_FILTER_SCALE */
        286, /* GL_CONVOLUTION_FILTER_BIAS */
-      1298, /* GL_REDUCE */
+      1313, /* GL_REDUCE */
        290, /* GL_CONVOLUTION_FORMAT */
        294, /* GL_CONVOLUTION_WIDTH */
        292, /* GL_CONVOLUTION_HEIGHT */
-       863, /* GL_MAX_CONVOLUTION_WIDTH */
-       861, /* GL_MAX_CONVOLUTION_HEIGHT */
-      1208, /* GL_POST_CONVOLUTION_RED_SCALE */
-      1204, /* GL_POST_CONVOLUTION_GREEN_SCALE */
-      1199, /* GL_POST_CONVOLUTION_BLUE_SCALE */
-      1195, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
-      1206, /* GL_POST_CONVOLUTION_RED_BIAS */
-      1202, /* GL_POST_CONVOLUTION_GREEN_BIAS */
-      1197, /* GL_POST_CONVOLUTION_BLUE_BIAS */
-      1193, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
-       598, /* GL_HISTOGRAM */
-      1257, /* GL_PROXY_HISTOGRAM */
-       614, /* GL_HISTOGRAM_WIDTH */
-       604, /* GL_HISTOGRAM_FORMAT */
-       610, /* GL_HISTOGRAM_RED_SIZE */
-       606, /* GL_HISTOGRAM_GREEN_SIZE */
-       601, /* GL_HISTOGRAM_BLUE_SIZE */
-       599, /* GL_HISTOGRAM_ALPHA_SIZE */
-       608, /* GL_HISTOGRAM_LUMINANCE_SIZE */
-       612, /* GL_HISTOGRAM_SINK */
-       939, /* GL_MINMAX */
-       941, /* GL_MINMAX_FORMAT */
-       943, /* GL_MINMAX_SINK */
-      1544, /* GL_TABLE_TOO_LARGE_EXT */
-      1764, /* GL_UNSIGNED_BYTE_3_3_2 */
-      1775, /* GL_UNSIGNED_SHORT_4_4_4_4 */
-      1777, /* GL_UNSIGNED_SHORT_5_5_5_1 */
-      1770, /* GL_UNSIGNED_INT_8_8_8_8 */
-      1766, /* GL_UNSIGNED_INT_10_10_10_2 */
-      1166, /* GL_POLYGON_OFFSET_FILL */
-      1165, /* GL_POLYGON_OFFSET_FACTOR */
-      1164, /* GL_POLYGON_OFFSET_BIAS */
-      1329, /* GL_RESCALE_NORMAL */
+       871, /* GL_MAX_CONVOLUTION_WIDTH */
+       869, /* GL_MAX_CONVOLUTION_HEIGHT */
+      1218, /* GL_POST_CONVOLUTION_RED_SCALE */
+      1214, /* GL_POST_CONVOLUTION_GREEN_SCALE */
+      1209, /* GL_POST_CONVOLUTION_BLUE_SCALE */
+      1205, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
+      1216, /* GL_POST_CONVOLUTION_RED_BIAS */
+      1212, /* GL_POST_CONVOLUTION_GREEN_BIAS */
+      1207, /* GL_POST_CONVOLUTION_BLUE_BIAS */
+      1203, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
+       605, /* GL_HISTOGRAM */
+      1267, /* GL_PROXY_HISTOGRAM */
+       621, /* GL_HISTOGRAM_WIDTH */
+       611, /* GL_HISTOGRAM_FORMAT */
+       617, /* GL_HISTOGRAM_RED_SIZE */
+       613, /* GL_HISTOGRAM_GREEN_SIZE */
+       608, /* GL_HISTOGRAM_BLUE_SIZE */
+       606, /* GL_HISTOGRAM_ALPHA_SIZE */
+       615, /* GL_HISTOGRAM_LUMINANCE_SIZE */
+       619, /* GL_HISTOGRAM_SINK */
+       949, /* GL_MINMAX */
+       951, /* GL_MINMAX_FORMAT */
+       953, /* GL_MINMAX_SINK */
+      1565, /* GL_TABLE_TOO_LARGE_EXT */
+      1785, /* GL_UNSIGNED_BYTE_3_3_2 */
+      1797, /* GL_UNSIGNED_SHORT_4_4_4_4 */
+      1799, /* GL_UNSIGNED_SHORT_5_5_5_1 */
+      1792, /* GL_UNSIGNED_INT_8_8_8_8 */
+      1787, /* GL_UNSIGNED_INT_10_10_10_2 */
+      1176, /* GL_POLYGON_OFFSET_FILL */
+      1175, /* GL_POLYGON_OFFSET_FACTOR */
+      1174, /* GL_POLYGON_OFFSET_BIAS */
+      1346, /* GL_RESCALE_NORMAL */
         36, /* GL_ALPHA4 */
         38, /* GL_ALPHA8 */
         32, /* GL_ALPHA12 */
         34, /* GL_ALPHA16 */
-       728, /* GL_LUMINANCE4 */
-       734, /* GL_LUMINANCE8 */
-       718, /* GL_LUMINANCE12 */
-       724, /* GL_LUMINANCE16 */
-       729, /* GL_LUMINANCE4_ALPHA4 */
-       732, /* GL_LUMINANCE6_ALPHA2 */
-       735, /* GL_LUMINANCE8_ALPHA8 */
-       721, /* GL_LUMINANCE12_ALPHA4 */
-       719, /* GL_LUMINANCE12_ALPHA12 */
-       725, /* GL_LUMINANCE16_ALPHA16 */
-       639, /* GL_INTENSITY */
-       644, /* GL_INTENSITY4 */
-       646, /* GL_INTENSITY8 */
-       640, /* GL_INTENSITY12 */
-       642, /* GL_INTENSITY16 */
-      1341, /* GL_RGB2_EXT */
-      1342, /* GL_RGB4 */
-      1345, /* GL_RGB5 */
-      1349, /* GL_RGB8 */
-      1333, /* GL_RGB10 */
-      1337, /* GL_RGB12 */
-      1339, /* GL_RGB16 */
-      1356, /* GL_RGBA2 */
-      1358, /* GL_RGBA4 */
-      1346, /* GL_RGB5_A1 */
-      1362, /* GL_RGBA8 */
-      1334, /* GL_RGB10_A2 */
-      1352, /* GL_RGBA12 */
-      1354, /* GL_RGBA16 */
-      1720, /* GL_TEXTURE_RED_SIZE */
-      1690, /* GL_TEXTURE_GREEN_SIZE */
-      1628, /* GL_TEXTURE_BLUE_SIZE */
-      1615, /* GL_TEXTURE_ALPHA_SIZE */
-      1703, /* GL_TEXTURE_LUMINANCE_SIZE */
-      1694, /* GL_TEXTURE_INTENSITY_SIZE */
-      1327, /* GL_REPLACE_EXT */
-      1261, /* GL_PROXY_TEXTURE_1D */
-      1264, /* GL_PROXY_TEXTURE_2D */
-      1726, /* GL_TEXTURE_TOO_LARGE_EXT */
-      1715, /* GL_TEXTURE_PRIORITY */
-      1722, /* GL_TEXTURE_RESIDENT */
-      1618, /* GL_TEXTURE_BINDING_1D */
-      1620, /* GL_TEXTURE_BINDING_2D */
-      1622, /* GL_TEXTURE_BINDING_3D */
-      1086, /* GL_PACK_SKIP_IMAGES */
-      1082, /* GL_PACK_IMAGE_HEIGHT */
-      1757, /* GL_UNPACK_SKIP_IMAGES */
-      1754, /* GL_UNPACK_IMAGE_HEIGHT */
-      1614, /* GL_TEXTURE_3D */
-      1267, /* GL_PROXY_TEXTURE_3D */
-      1677, /* GL_TEXTURE_DEPTH */
-      1729, /* GL_TEXTURE_WRAP_R */
-       849, /* GL_MAX_3D_TEXTURE_SIZE */
-      1790, /* GL_VERTEX_ARRAY */
-      1016, /* GL_NORMAL_ARRAY */
+       735, /* GL_LUMINANCE4 */
+       741, /* GL_LUMINANCE8 */
+       725, /* GL_LUMINANCE12 */
+       731, /* GL_LUMINANCE16 */
+       736, /* GL_LUMINANCE4_ALPHA4 */
+       739, /* GL_LUMINANCE6_ALPHA2 */
+       742, /* GL_LUMINANCE8_ALPHA8 */
+       728, /* GL_LUMINANCE12_ALPHA4 */
+       726, /* GL_LUMINANCE12_ALPHA12 */
+       732, /* GL_LUMINANCE16_ALPHA16 */
+       646, /* GL_INTENSITY */
+       651, /* GL_INTENSITY4 */
+       653, /* GL_INTENSITY8 */
+       647, /* GL_INTENSITY12 */
+       649, /* GL_INTENSITY16 */
+      1358, /* GL_RGB2_EXT */
+      1359, /* GL_RGB4 */
+      1362, /* GL_RGB5 */
+      1366, /* GL_RGB8 */
+      1350, /* GL_RGB10 */
+      1354, /* GL_RGB12 */
+      1356, /* GL_RGB16 */
+      1373, /* GL_RGBA2 */
+      1375, /* GL_RGBA4 */
+      1363, /* GL_RGB5_A1 */
+      1379, /* GL_RGBA8 */
+      1351, /* GL_RGB10_A2 */
+      1369, /* GL_RGBA12 */
+      1371, /* GL_RGBA16 */
+      1741, /* GL_TEXTURE_RED_SIZE */
+      1711, /* GL_TEXTURE_GREEN_SIZE */
+      1649, /* GL_TEXTURE_BLUE_SIZE */
+      1636, /* GL_TEXTURE_ALPHA_SIZE */
+      1724, /* GL_TEXTURE_LUMINANCE_SIZE */
+      1715, /* GL_TEXTURE_INTENSITY_SIZE */
+      1344, /* GL_REPLACE_EXT */
+      1271, /* GL_PROXY_TEXTURE_1D */
+      1274, /* GL_PROXY_TEXTURE_2D */
+      1748, /* GL_TEXTURE_TOO_LARGE_EXT */
+      1736, /* GL_TEXTURE_PRIORITY */
+      1743, /* GL_TEXTURE_RESIDENT */
+      1639, /* GL_TEXTURE_BINDING_1D */
+      1641, /* GL_TEXTURE_BINDING_2D */
+      1643, /* GL_TEXTURE_BINDING_3D */
+      1096, /* GL_PACK_SKIP_IMAGES */
+      1092, /* GL_PACK_IMAGE_HEIGHT */
+      1778, /* GL_UNPACK_SKIP_IMAGES */
+      1775, /* GL_UNPACK_IMAGE_HEIGHT */
+      1635, /* GL_TEXTURE_3D */
+      1277, /* GL_PROXY_TEXTURE_3D */
+      1698, /* GL_TEXTURE_DEPTH */
+      1751, /* GL_TEXTURE_WRAP_R */
+       856, /* GL_MAX_3D_TEXTURE_SIZE */
+      1812, /* GL_VERTEX_ARRAY */
+      1026, /* GL_NORMAL_ARRAY */
        148, /* GL_COLOR_ARRAY */
-       624, /* GL_INDEX_ARRAY */
-      1655, /* GL_TEXTURE_COORD_ARRAY */
-       456, /* GL_EDGE_FLAG_ARRAY */
-      1796, /* GL_VERTEX_ARRAY_SIZE */
-      1798, /* GL_VERTEX_ARRAY_TYPE */
-      1797, /* GL_VERTEX_ARRAY_STRIDE */
-      1021, /* GL_NORMAL_ARRAY_TYPE */
-      1020, /* GL_NORMAL_ARRAY_STRIDE */
+       631, /* GL_INDEX_ARRAY */
+      1676, /* GL_TEXTURE_COORD_ARRAY */
+       459, /* GL_EDGE_FLAG_ARRAY */
+      1818, /* GL_VERTEX_ARRAY_SIZE */
+      1820, /* GL_VERTEX_ARRAY_TYPE */
+      1819, /* GL_VERTEX_ARRAY_STRIDE */
+      1031, /* GL_NORMAL_ARRAY_TYPE */
+      1030, /* GL_NORMAL_ARRAY_STRIDE */
        152, /* GL_COLOR_ARRAY_SIZE */
        154, /* GL_COLOR_ARRAY_TYPE */
        153, /* GL_COLOR_ARRAY_STRIDE */
-       629, /* GL_INDEX_ARRAY_TYPE */
-       628, /* GL_INDEX_ARRAY_STRIDE */
-      1659, /* GL_TEXTURE_COORD_ARRAY_SIZE */
-      1661, /* GL_TEXTURE_COORD_ARRAY_TYPE */
-      1660, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
-       460, /* GL_EDGE_FLAG_ARRAY_STRIDE */
-      1795, /* GL_VERTEX_ARRAY_POINTER */
-      1019, /* GL_NORMAL_ARRAY_POINTER */
+       636, /* GL_INDEX_ARRAY_TYPE */
+       635, /* GL_INDEX_ARRAY_STRIDE */
+      1680, /* GL_TEXTURE_COORD_ARRAY_SIZE */
+      1682, /* GL_TEXTURE_COORD_ARRAY_TYPE */
+      1681, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
+       463, /* GL_EDGE_FLAG_ARRAY_STRIDE */
+      1817, /* GL_VERTEX_ARRAY_POINTER */
+      1029, /* GL_NORMAL_ARRAY_POINTER */
        151, /* GL_COLOR_ARRAY_POINTER */
-       627, /* GL_INDEX_ARRAY_POINTER */
-      1658, /* GL_TEXTURE_COORD_ARRAY_POINTER */
-       459, /* GL_EDGE_FLAG_ARRAY_POINTER */
-       995, /* GL_MULTISAMPLE */
-      1386, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
-      1388, /* GL_SAMPLE_ALPHA_TO_ONE */
-      1393, /* GL_SAMPLE_COVERAGE */
-      1390, /* GL_SAMPLE_BUFFERS */
-      1381, /* GL_SAMPLES */
-      1397, /* GL_SAMPLE_COVERAGE_VALUE */
-      1395, /* GL_SAMPLE_COVERAGE_INVERT */
+       634, /* GL_INDEX_ARRAY_POINTER */
+      1679, /* GL_TEXTURE_COORD_ARRAY_POINTER */
+       462, /* GL_EDGE_FLAG_ARRAY_POINTER */
+      1005, /* GL_MULTISAMPLE */
+      1403, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
+      1405, /* GL_SAMPLE_ALPHA_TO_ONE */
+      1410, /* GL_SAMPLE_COVERAGE */
+      1407, /* GL_SAMPLE_BUFFERS */
+      1398, /* GL_SAMPLES */
+      1414, /* GL_SAMPLE_COVERAGE_VALUE */
+      1412, /* GL_SAMPLE_COVERAGE_INVERT */
        195, /* GL_COLOR_MATRIX */
        197, /* GL_COLOR_MATRIX_STACK_DEPTH */
-       857, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
-      1191, /* GL_POST_COLOR_MATRIX_RED_SCALE */
-      1187, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
-      1182, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
-      1178, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
-      1189, /* GL_POST_COLOR_MATRIX_RED_BIAS */
-      1185, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
-      1180, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
-      1176, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
-      1638, /* GL_TEXTURE_COLOR_TABLE_SGI */
-      1268, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
-      1640, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
+       865, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
+      1201, /* GL_POST_COLOR_MATRIX_RED_SCALE */
+      1197, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
+      1192, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
+      1188, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
+      1199, /* GL_POST_COLOR_MATRIX_RED_BIAS */
+      1195, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
+      1190, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
+      1186, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
+      1659, /* GL_TEXTURE_COLOR_TABLE_SGI */
+      1278, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
+      1661, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
         80, /* GL_BLEND_DST_RGB */
         89, /* GL_BLEND_SRC_RGB */
         79, /* GL_BLEND_DST_ALPHA */
         88, /* GL_BLEND_SRC_ALPHA */
        201, /* GL_COLOR_TABLE */
-      1201, /* GL_POST_CONVOLUTION_COLOR_TABLE */
-      1184, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
-      1256, /* GL_PROXY_COLOR_TABLE */
-      1260, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
-      1259, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
+      1211, /* GL_POST_CONVOLUTION_COLOR_TABLE */
+      1194, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
+      1266, /* GL_PROXY_COLOR_TABLE */
+      1270, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
+      1269, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
        225, /* GL_COLOR_TABLE_SCALE */
        205, /* GL_COLOR_TABLE_BIAS */
        210, /* GL_COLOR_TABLE_FORMAT */
@@ -4379,380 +4423,380 @@
        216, /* GL_COLOR_TABLE_INTENSITY_SIZE */
         71, /* GL_BGR */
         72, /* GL_BGRA */
-       871, /* GL_MAX_ELEMENTS_VERTICES */
-       870, /* GL_MAX_ELEMENTS_INDICES */
-      1693, /* GL_TEXTURE_INDEX_SIZE_EXT */
+       879, /* GL_MAX_ELEMENTS_VERTICES */
+       878, /* GL_MAX_ELEMENTS_INDICES */
+      1714, /* GL_TEXTURE_INDEX_SIZE_EXT */
        145, /* GL_CLIP_VOLUME_CLIPPING_HINT_EXT */
-      1148, /* GL_POINT_SIZE_MIN */
-      1144, /* GL_POINT_SIZE_MAX */
-      1138, /* GL_POINT_FADE_THRESHOLD_SIZE */
-      1134, /* GL_POINT_DISTANCE_ATTENUATION */
+      1158, /* GL_POINT_SIZE_MIN */
+      1154, /* GL_POINT_SIZE_MAX */
+      1148, /* GL_POINT_FADE_THRESHOLD_SIZE */
+      1144, /* GL_POINT_DISTANCE_ATTENUATION */
        127, /* GL_CLAMP_TO_BORDER */
        130, /* GL_CLAMP_TO_EDGE */
-      1714, /* GL_TEXTURE_MIN_LOD */
-      1712, /* GL_TEXTURE_MAX_LOD */
-      1617, /* GL_TEXTURE_BASE_LEVEL */
-      1711, /* GL_TEXTURE_MAX_LEVEL */
-       617, /* GL_IGNORE_BORDER_HP */
+      1735, /* GL_TEXTURE_MIN_LOD */
+      1733, /* GL_TEXTURE_MAX_LOD */
+      1638, /* GL_TEXTURE_BASE_LEVEL */
+      1732, /* GL_TEXTURE_MAX_LEVEL */
+       624, /* GL_IGNORE_BORDER_HP */
        276, /* GL_CONSTANT_BORDER_HP */
-      1328, /* GL_REPLICATE_BORDER_HP */
+      1345, /* GL_REPLICATE_BORDER_HP */
        282, /* GL_CONVOLUTION_BORDER_COLOR */
-      1045, /* GL_OCCLUSION_TEST_HP */
-      1046, /* GL_OCCLUSION_TEST_RESULT_HP */
-       690, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
-      1632, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
-      1634, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
-      1636, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
-      1637, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
-      1635, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
-      1633, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
-       853, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
-       854, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
-      1211, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
-      1213, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
-      1210, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
-      1212, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
-      1701, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
-      1702, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
-      1700, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
-       587, /* GL_GENERATE_MIPMAP */
-       588, /* GL_GENERATE_MIPMAP_HINT */
-       529, /* GL_FOG_OFFSET_SGIX */
-       530, /* GL_FOG_OFFSET_VALUE_SGIX */
-      1646, /* GL_TEXTURE_COMPARE_SGIX */
-      1645, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
-      1697, /* GL_TEXTURE_LEQUAL_R_SGIX */
-      1689, /* GL_TEXTURE_GEQUAL_R_SGIX */
-       359, /* GL_DEPTH_COMPONENT16 */
-       362, /* GL_DEPTH_COMPONENT24 */
-       365, /* GL_DEPTH_COMPONENT32 */
+      1055, /* GL_OCCLUSION_TEST_HP */
+      1056, /* GL_OCCLUSION_TEST_RESULT_HP */
+       697, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
+      1653, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
+      1655, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
+      1657, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
+      1658, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+      1656, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
+      1654, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
+       860, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
+       861, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+      1221, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
+      1223, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
+      1220, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
+      1222, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
+      1722, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
+      1723, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
+      1721, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
+       594, /* GL_GENERATE_MIPMAP */
+       595, /* GL_GENERATE_MIPMAP_HINT */
+       532, /* GL_FOG_OFFSET_SGIX */
+       533, /* GL_FOG_OFFSET_VALUE_SGIX */
+      1667, /* GL_TEXTURE_COMPARE_SGIX */
+      1666, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
+      1718, /* GL_TEXTURE_LEQUAL_R_SGIX */
+      1710, /* GL_TEXTURE_GEQUAL_R_SGIX */
+       360, /* GL_DEPTH_COMPONENT16 */
+       363, /* GL_DEPTH_COMPONENT24 */
+       366, /* GL_DEPTH_COMPONENT32 */
        306, /* GL_CULL_VERTEX_EXT */
        308, /* GL_CULL_VERTEX_OBJECT_POSITION_EXT */
        307, /* GL_CULL_VERTEX_EYE_POSITION_EXT */
-      1853, /* GL_WRAP_BORDER_SUN */
-      1639, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
-       683, /* GL_LIGHT_MODEL_COLOR_CONTROL */
-      1427, /* GL_SINGLE_COLOR */
-      1413, /* GL_SEPARATE_SPECULAR_COLOR */
-      1422, /* GL_SHARED_TEXTURE_PALETTE_EXT */
-       540, /* GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */
-       541, /* GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */
-       548, /* GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
-       543, /* GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */
-       539, /* GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */
-       538, /* GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */
-       542, /* GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */
-       549, /* GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
-       560, /* GL_FRAMEBUFFER_DEFAULT */
-       573, /* GL_FRAMEBUFFER_UNDEFINED */
-       372, /* GL_DEPTH_STENCIL_ATTACHMENT */
-       623, /* GL_INDEX */
-      1763, /* GL_UNSIGNED_BYTE_2_3_3_REV */
-      1778, /* GL_UNSIGNED_SHORT_5_6_5 */
-      1779, /* GL_UNSIGNED_SHORT_5_6_5_REV */
-      1776, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
-      1774, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
-      1771, /* GL_UNSIGNED_INT_8_8_8_8_REV */
-      1769, /* GL_UNSIGNED_INT_2_10_10_10_REV */
-      1709, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
-      1710, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
-      1708, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
-       946, /* GL_MIRRORED_REPEAT */
-      1369, /* GL_RGB_S3TC */
-      1344, /* GL_RGB4_S3TC */
-      1367, /* GL_RGBA_S3TC */
-      1361, /* GL_RGBA4_S3TC */
-      1365, /* GL_RGBA_DXT5_S3TC */
-      1359, /* GL_RGBA4_DXT5_S3TC */
+      1875, /* GL_WRAP_BORDER_SUN */
+      1660, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
+       690, /* GL_LIGHT_MODEL_COLOR_CONTROL */
+      1444, /* GL_SINGLE_COLOR */
+      1430, /* GL_SEPARATE_SPECULAR_COLOR */
+      1439, /* GL_SHARED_TEXTURE_PALETTE_EXT */
+       543, /* GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */
+       544, /* GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */
+       551, /* GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
+       546, /* GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */
+       542, /* GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */
+       541, /* GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */
+       545, /* GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */
+       552, /* GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
+       564, /* GL_FRAMEBUFFER_DEFAULT */
+       580, /* GL_FRAMEBUFFER_UNDEFINED */
+       373, /* GL_DEPTH_STENCIL_ATTACHMENT */
+       630, /* GL_INDEX */
+      1784, /* GL_UNSIGNED_BYTE_2_3_3_REV */
+      1800, /* GL_UNSIGNED_SHORT_5_6_5 */
+      1801, /* GL_UNSIGNED_SHORT_5_6_5_REV */
+      1798, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
+      1796, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
+      1793, /* GL_UNSIGNED_INT_8_8_8_8_REV */
+      1791, /* GL_UNSIGNED_INT_2_10_10_10_REV */
+      1730, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
+      1731, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
+      1729, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
+       956, /* GL_MIRRORED_REPEAT */
+      1386, /* GL_RGB_S3TC */
+      1361, /* GL_RGB4_S3TC */
+      1384, /* GL_RGBA_S3TC */
+      1378, /* GL_RGBA4_S3TC */
+      1382, /* GL_RGBA_DXT5_S3TC */
+      1376, /* GL_RGBA4_DXT5_S3TC */
        264, /* GL_COMPRESSED_RGB_S3TC_DXT1_EXT */
        259, /* GL_COMPRESSED_RGBA_S3TC_DXT1_EXT */
        260, /* GL_COMPRESSED_RGBA_S3TC_DXT3_EXT */
        261, /* GL_COMPRESSED_RGBA_S3TC_DXT5_EXT */
-      1007, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
-      1006, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
-       691, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
-       516, /* GL_FOG_COORDINATE_SOURCE */
-       508, /* GL_FOG_COORD */
-       532, /* GL_FRAGMENT_DEPTH */
+      1017, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
+      1016, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
+       698, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
+       519, /* GL_FOG_COORDINATE_SOURCE */
+       511, /* GL_FOG_COORD */
+       535, /* GL_FRAGMENT_DEPTH */
        312, /* GL_CURRENT_FOG_COORD */
-       515, /* GL_FOG_COORDINATE_ARRAY_TYPE */
-       514, /* GL_FOG_COORDINATE_ARRAY_STRIDE */
-       513, /* GL_FOG_COORDINATE_ARRAY_POINTER */
-       510, /* GL_FOG_COORDINATE_ARRAY */
+       518, /* GL_FOG_COORDINATE_ARRAY_TYPE */
+       517, /* GL_FOG_COORDINATE_ARRAY_STRIDE */
+       516, /* GL_FOG_COORDINATE_ARRAY_POINTER */
+       513, /* GL_FOG_COORDINATE_ARRAY */
        199, /* GL_COLOR_SUM */
        332, /* GL_CURRENT_SECONDARY_COLOR */
-      1406, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
-      1408, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
-      1407, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
-      1405, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
-      1402, /* GL_SECONDARY_COLOR_ARRAY */
+      1423, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
+      1425, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
+      1424, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
+      1422, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
+      1419, /* GL_SECONDARY_COLOR_ARRAY */
        330, /* GL_CURRENT_RASTER_SECONDARY_COLOR */
         28, /* GL_ALIASED_POINT_SIZE_RANGE */
         27, /* GL_ALIASED_LINE_WIDTH_RANGE */
-      1546, /* GL_TEXTURE0 */
-      1548, /* GL_TEXTURE1 */
-      1570, /* GL_TEXTURE2 */
-      1592, /* GL_TEXTURE3 */
-      1598, /* GL_TEXTURE4 */
-      1600, /* GL_TEXTURE5 */
-      1602, /* GL_TEXTURE6 */
-      1604, /* GL_TEXTURE7 */
-      1606, /* GL_TEXTURE8 */
-      1608, /* GL_TEXTURE9 */
-      1549, /* GL_TEXTURE10 */
-      1551, /* GL_TEXTURE11 */
-      1553, /* GL_TEXTURE12 */
-      1555, /* GL_TEXTURE13 */
-      1557, /* GL_TEXTURE14 */
-      1559, /* GL_TEXTURE15 */
-      1561, /* GL_TEXTURE16 */
-      1563, /* GL_TEXTURE17 */
-      1565, /* GL_TEXTURE18 */
-      1567, /* GL_TEXTURE19 */
-      1571, /* GL_TEXTURE20 */
-      1573, /* GL_TEXTURE21 */
-      1575, /* GL_TEXTURE22 */
-      1577, /* GL_TEXTURE23 */
-      1579, /* GL_TEXTURE24 */
-      1581, /* GL_TEXTURE25 */
-      1583, /* GL_TEXTURE26 */
-      1585, /* GL_TEXTURE27 */
-      1587, /* GL_TEXTURE28 */
-      1589, /* GL_TEXTURE29 */
-      1593, /* GL_TEXTURE30 */
-      1595, /* GL_TEXTURE31 */
+      1567, /* GL_TEXTURE0 */
+      1569, /* GL_TEXTURE1 */
+      1591, /* GL_TEXTURE2 */
+      1613, /* GL_TEXTURE3 */
+      1619, /* GL_TEXTURE4 */
+      1621, /* GL_TEXTURE5 */
+      1623, /* GL_TEXTURE6 */
+      1625, /* GL_TEXTURE7 */
+      1627, /* GL_TEXTURE8 */
+      1629, /* GL_TEXTURE9 */
+      1570, /* GL_TEXTURE10 */
+      1572, /* GL_TEXTURE11 */
+      1574, /* GL_TEXTURE12 */
+      1576, /* GL_TEXTURE13 */
+      1578, /* GL_TEXTURE14 */
+      1580, /* GL_TEXTURE15 */
+      1582, /* GL_TEXTURE16 */
+      1584, /* GL_TEXTURE17 */
+      1586, /* GL_TEXTURE18 */
+      1588, /* GL_TEXTURE19 */
+      1592, /* GL_TEXTURE20 */
+      1594, /* GL_TEXTURE21 */
+      1596, /* GL_TEXTURE22 */
+      1598, /* GL_TEXTURE23 */
+      1600, /* GL_TEXTURE24 */
+      1602, /* GL_TEXTURE25 */
+      1604, /* GL_TEXTURE26 */
+      1606, /* GL_TEXTURE27 */
+      1608, /* GL_TEXTURE28 */
+      1610, /* GL_TEXTURE29 */
+      1614, /* GL_TEXTURE30 */
+      1616, /* GL_TEXTURE31 */
         18, /* GL_ACTIVE_TEXTURE */
        133, /* GL_CLIENT_ACTIVE_TEXTURE */
-       924, /* GL_MAX_TEXTURE_UNITS */
-      1741, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
-      1744, /* GL_TRANSPOSE_PROJECTION_MATRIX */
-      1746, /* GL_TRANSPOSE_TEXTURE_MATRIX */
-      1738, /* GL_TRANSPOSE_COLOR_MATRIX */
-      1528, /* GL_SUBTRACT */
-       911, /* GL_MAX_RENDERBUFFER_SIZE_EXT */
+       934, /* GL_MAX_TEXTURE_UNITS */
+      1762, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
+      1765, /* GL_TRANSPOSE_PROJECTION_MATRIX */
+      1767, /* GL_TRANSPOSE_TEXTURE_MATRIX */
+      1759, /* GL_TRANSPOSE_COLOR_MATRIX */
+      1549, /* GL_SUBTRACT */
+       919, /* GL_MAX_RENDERBUFFER_SIZE */
        247, /* GL_COMPRESSED_ALPHA */
        251, /* GL_COMPRESSED_LUMINANCE */
        252, /* GL_COMPRESSED_LUMINANCE_ALPHA */
        249, /* GL_COMPRESSED_INTENSITY */
        255, /* GL_COMPRESSED_RGB */
        256, /* GL_COMPRESSED_RGBA */
-      1653, /* GL_TEXTURE_COMPRESSION_HINT */
-      1718, /* GL_TEXTURE_RECTANGLE_ARB */
-      1625, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
-      1271, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */
-       909, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */
-       371, /* GL_DEPTH_STENCIL */
-      1767, /* GL_UNSIGNED_INT_24_8 */
-       920, /* GL_MAX_TEXTURE_LOD_BIAS */
-      1707, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
-       921, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
-      1683, /* GL_TEXTURE_FILTER_CONTROL */
-      1698, /* GL_TEXTURE_LOD_BIAS */
+      1674, /* GL_TEXTURE_COMPRESSION_HINT */
+      1739, /* GL_TEXTURE_RECTANGLE_ARB */
+      1646, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
+      1281, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */
+       917, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */
+       372, /* GL_DEPTH_STENCIL */
+      1788, /* GL_UNSIGNED_INT_24_8 */
+       930, /* GL_MAX_TEXTURE_LOD_BIAS */
+      1728, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
+       931, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
+      1704, /* GL_TEXTURE_FILTER_CONTROL */
+      1719, /* GL_TEXTURE_LOD_BIAS */
        232, /* GL_COMBINE4 */
-       914, /* GL_MAX_SHININESS_NV */
-       915, /* GL_MAX_SPOT_EXPONENT_NV */
-       621, /* GL_INCR_WRAP */
+       924, /* GL_MAX_SHININESS_NV */
+       925, /* GL_MAX_SPOT_EXPONENT_NV */
+       628, /* GL_INCR_WRAP */
        343, /* GL_DECR_WRAP */
-       966, /* GL_MODELVIEW1_ARB */
-      1022, /* GL_NORMAL_MAP */
-      1303, /* GL_REFLECTION_MAP */
-      1662, /* GL_TEXTURE_CUBE_MAP */
-      1623, /* GL_TEXTURE_BINDING_CUBE_MAP */
-      1670, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
-      1664, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
-      1672, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
-      1666, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
-      1674, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
-      1668, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
-      1269, /* GL_PROXY_TEXTURE_CUBE_MAP */
-       865, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
-      1001, /* GL_MULTISAMPLE_FILTER_HINT_NV */
-       524, /* GL_FOG_DISTANCE_MODE_NV */
-       475, /* GL_EYE_RADIAL_NV */
-       474, /* GL_EYE_PLANE_ABSOLUTE_NV */
+       976, /* GL_MODELVIEW1_ARB */
+      1032, /* GL_NORMAL_MAP */
+      1318, /* GL_REFLECTION_MAP */
+      1683, /* GL_TEXTURE_CUBE_MAP */
+      1644, /* GL_TEXTURE_BINDING_CUBE_MAP */
+      1691, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
+      1685, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
+      1693, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
+      1687, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
+      1695, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
+      1689, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
+      1279, /* GL_PROXY_TEXTURE_CUBE_MAP */
+       873, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
+      1011, /* GL_MULTISAMPLE_FILTER_HINT_NV */
+       527, /* GL_FOG_DISTANCE_MODE_NV */
+       478, /* GL_EYE_RADIAL_NV */
+       477, /* GL_EYE_PLANE_ABSOLUTE_NV */
        231, /* GL_COMBINE */
        238, /* GL_COMBINE_RGB */
        233, /* GL_COMBINE_ALPHA */
-      1370, /* GL_RGB_SCALE */
+      1387, /* GL_RGB_SCALE */
         24, /* GL_ADD_SIGNED */
-       649, /* GL_INTERPOLATE */
+       656, /* GL_INTERPOLATE */
        271, /* GL_CONSTANT */
-      1217, /* GL_PRIMARY_COLOR */
-      1214, /* GL_PREVIOUS */
-      1442, /* GL_SOURCE0_RGB */
-      1448, /* GL_SOURCE1_RGB */
-      1454, /* GL_SOURCE2_RGB */
-      1458, /* GL_SOURCE3_RGB_NV */
-      1439, /* GL_SOURCE0_ALPHA */
-      1445, /* GL_SOURCE1_ALPHA */
-      1451, /* GL_SOURCE2_ALPHA */
-      1457, /* GL_SOURCE3_ALPHA_NV */
-      1059, /* GL_OPERAND0_RGB */
-      1065, /* GL_OPERAND1_RGB */
-      1071, /* GL_OPERAND2_RGB */
-      1075, /* GL_OPERAND3_RGB_NV */
-      1056, /* GL_OPERAND0_ALPHA */
-      1062, /* GL_OPERAND1_ALPHA */
-      1068, /* GL_OPERAND2_ALPHA */
-      1074, /* GL_OPERAND3_ALPHA_NV */
-      1791, /* GL_VERTEX_ARRAY_BINDING */
-      1716, /* GL_TEXTURE_RANGE_LENGTH_APPLE */
-      1717, /* GL_TEXTURE_RANGE_POINTER_APPLE */
-      1857, /* GL_YCBCR_422_APPLE */
-      1780, /* GL_UNSIGNED_SHORT_8_8_APPLE */
-      1782, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
-      1725, /* GL_TEXTURE_STORAGE_HINT_APPLE */
-      1519, /* GL_STORAGE_PRIVATE_APPLE */
-      1518, /* GL_STORAGE_CACHED_APPLE */
-      1520, /* GL_STORAGE_SHARED_APPLE */
-      1429, /* GL_SLICE_ACCUM_SUN */
-      1278, /* GL_QUAD_MESH_SUN */
-      1750, /* GL_TRIANGLE_MESH_SUN */
-      1830, /* GL_VERTEX_PROGRAM_ARB */
-      1841, /* GL_VERTEX_STATE_PROGRAM_NV */
-      1817, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
-      1823, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
-      1825, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
-      1827, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
+      1227, /* GL_PRIMARY_COLOR */
+      1224, /* GL_PREVIOUS */
+      1459, /* GL_SOURCE0_RGB */
+      1465, /* GL_SOURCE1_RGB */
+      1471, /* GL_SOURCE2_RGB */
+      1475, /* GL_SOURCE3_RGB_NV */
+      1456, /* GL_SOURCE0_ALPHA */
+      1462, /* GL_SOURCE1_ALPHA */
+      1468, /* GL_SOURCE2_ALPHA */
+      1474, /* GL_SOURCE3_ALPHA_NV */
+      1069, /* GL_OPERAND0_RGB */
+      1075, /* GL_OPERAND1_RGB */
+      1081, /* GL_OPERAND2_RGB */
+      1085, /* GL_OPERAND3_RGB_NV */
+      1066, /* GL_OPERAND0_ALPHA */
+      1072, /* GL_OPERAND1_ALPHA */
+      1078, /* GL_OPERAND2_ALPHA */
+      1084, /* GL_OPERAND3_ALPHA_NV */
+      1813, /* GL_VERTEX_ARRAY_BINDING */
+      1737, /* GL_TEXTURE_RANGE_LENGTH_APPLE */
+      1738, /* GL_TEXTURE_RANGE_POINTER_APPLE */
+      1879, /* GL_YCBCR_422_APPLE */
+      1802, /* GL_UNSIGNED_SHORT_8_8_APPLE */
+      1804, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
+      1747, /* GL_TEXTURE_STORAGE_HINT_APPLE */
+      1540, /* GL_STORAGE_PRIVATE_APPLE */
+      1539, /* GL_STORAGE_CACHED_APPLE */
+      1541, /* GL_STORAGE_SHARED_APPLE */
+      1446, /* GL_SLICE_ACCUM_SUN */
+      1288, /* GL_QUAD_MESH_SUN */
+      1771, /* GL_TRIANGLE_MESH_SUN */
+      1852, /* GL_VERTEX_PROGRAM_ARB */
+      1863, /* GL_VERTEX_STATE_PROGRAM_NV */
+      1839, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
+      1845, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
+      1847, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
+      1849, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
        334, /* GL_CURRENT_VERTEX_ATTRIB */
-      1230, /* GL_PROGRAM_LENGTH_ARB */
-      1244, /* GL_PROGRAM_STRING_ARB */
-       988, /* GL_MODELVIEW_PROJECTION_NV */
-       616, /* GL_IDENTITY_NV */
-       663, /* GL_INVERSE_NV */
-      1743, /* GL_TRANSPOSE_NV */
-       664, /* GL_INVERSE_TRANSPOSE_NV */
-       895, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
-       894, /* GL_MAX_PROGRAM_MATRICES_ARB */
-       802, /* GL_MATRIX0_NV */
-       814, /* GL_MATRIX1_NV */
-       826, /* GL_MATRIX2_NV */
-       830, /* GL_MATRIX3_NV */
-       832, /* GL_MATRIX4_NV */
-       834, /* GL_MATRIX5_NV */
-       836, /* GL_MATRIX6_NV */
-       838, /* GL_MATRIX7_NV */
+      1240, /* GL_PROGRAM_LENGTH_ARB */
+      1254, /* GL_PROGRAM_STRING_ARB */
+       998, /* GL_MODELVIEW_PROJECTION_NV */
+       623, /* GL_IDENTITY_NV */
+       670, /* GL_INVERSE_NV */
+      1764, /* GL_TRANSPOSE_NV */
+       671, /* GL_INVERSE_TRANSPOSE_NV */
+       903, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
+       902, /* GL_MAX_PROGRAM_MATRICES_ARB */
+       809, /* GL_MATRIX0_NV */
+       821, /* GL_MATRIX1_NV */
+       833, /* GL_MATRIX2_NV */
+       837, /* GL_MATRIX3_NV */
+       839, /* GL_MATRIX4_NV */
+       841, /* GL_MATRIX5_NV */
+       843, /* GL_MATRIX6_NV */
+       845, /* GL_MATRIX7_NV */
        318, /* GL_CURRENT_MATRIX_STACK_DEPTH_ARB */
        315, /* GL_CURRENT_MATRIX_ARB */
-      1833, /* GL_VERTEX_PROGRAM_POINT_SIZE */
-      1836, /* GL_VERTEX_PROGRAM_TWO_SIDE */
-      1242, /* GL_PROGRAM_PARAMETER_NV */
-      1821, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
-      1246, /* GL_PROGRAM_TARGET_NV */
-      1243, /* GL_PROGRAM_RESIDENT_NV */
-      1735, /* GL_TRACK_MATRIX_NV */
-      1736, /* GL_TRACK_MATRIX_TRANSFORM_NV */
-      1831, /* GL_VERTEX_PROGRAM_BINDING_NV */
-      1224, /* GL_PROGRAM_ERROR_POSITION_ARB */
-       355, /* GL_DEPTH_CLAMP */
-      1799, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
-      1806, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
-      1807, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
-      1808, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
-      1809, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
-      1810, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
-      1811, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
-      1812, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
-      1813, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
-      1814, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
-      1800, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
-      1801, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
-      1802, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
-      1803, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
-      1804, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
-      1805, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
-       750, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
-       757, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
-       758, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
-       759, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
-       760, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
-       761, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
-       762, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
-       763, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
-       764, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
-       765, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
-       751, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
-       752, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
-       753, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
-       754, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
-       755, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
-       756, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
-       777, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
-       784, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
-       785, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
-       786, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
-       787, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
-       788, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
-       789, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
-      1223, /* GL_PROGRAM_BINDING_ARB */
-       791, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
-       792, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
-       778, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
-       779, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
-       780, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
-       781, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
-       782, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
-       783, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
-      1651, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
-      1648, /* GL_TEXTURE_COMPRESSED */
-      1027, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
+      1855, /* GL_VERTEX_PROGRAM_POINT_SIZE */
+      1858, /* GL_VERTEX_PROGRAM_TWO_SIDE */
+      1252, /* GL_PROGRAM_PARAMETER_NV */
+      1843, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
+      1256, /* GL_PROGRAM_TARGET_NV */
+      1253, /* GL_PROGRAM_RESIDENT_NV */
+      1756, /* GL_TRACK_MATRIX_NV */
+      1757, /* GL_TRACK_MATRIX_TRANSFORM_NV */
+      1853, /* GL_VERTEX_PROGRAM_BINDING_NV */
+      1234, /* GL_PROGRAM_ERROR_POSITION_ARB */
+       356, /* GL_DEPTH_CLAMP */
+      1821, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
+      1828, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
+      1829, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
+      1830, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
+      1831, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
+      1832, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
+      1833, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
+      1834, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
+      1835, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
+      1836, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
+      1822, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
+      1823, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
+      1824, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
+      1825, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
+      1826, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
+      1827, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
+       757, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
+       764, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
+       765, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
+       766, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
+       767, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
+       768, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
+       769, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
+       770, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
+       771, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
+       772, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
+       758, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
+       759, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
+       760, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
+       761, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
+       762, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
+       763, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
+       784, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
+       791, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
+       792, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
+       793, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
+       794, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
+       795, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
+       796, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
+      1233, /* GL_PROGRAM_BINDING_ARB */
+       798, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
+       799, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
+       785, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
+       786, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
+       787, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
+       788, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
+       789, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
+       790, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
+      1672, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
+      1669, /* GL_TEXTURE_COMPRESSED */
+      1037, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
        269, /* GL_COMPRESSED_TEXTURE_FORMATS */
-       936, /* GL_MAX_VERTEX_UNITS_ARB */
+       946, /* GL_MAX_VERTEX_UNITS_ARB */
         22, /* GL_ACTIVE_VERTEX_UNITS_ARB */
-      1852, /* GL_WEIGHT_SUM_UNITY_ARB */
-      1829, /* GL_VERTEX_BLEND_ARB */
+      1874, /* GL_WEIGHT_SUM_UNITY_ARB */
+      1851, /* GL_VERTEX_BLEND_ARB */
        336, /* GL_CURRENT_WEIGHT_ARB */
-      1851, /* GL_WEIGHT_ARRAY_TYPE_ARB */
-      1850, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
-      1849, /* GL_WEIGHT_ARRAY_SIZE_ARB */
-      1848, /* GL_WEIGHT_ARRAY_POINTER_ARB */
-      1845, /* GL_WEIGHT_ARRAY_ARB */
-       384, /* GL_DOT3_RGB */
-       385, /* GL_DOT3_RGBA */
+      1873, /* GL_WEIGHT_ARRAY_TYPE_ARB */
+      1872, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
+      1871, /* GL_WEIGHT_ARRAY_SIZE_ARB */
+      1870, /* GL_WEIGHT_ARRAY_POINTER_ARB */
+      1867, /* GL_WEIGHT_ARRAY_ARB */
+       386, /* GL_DOT3_RGB */
+       387, /* GL_DOT3_RGBA */
        263, /* GL_COMPRESSED_RGB_FXT1_3DFX */
        258, /* GL_COMPRESSED_RGBA_FXT1_3DFX */
-       996, /* GL_MULTISAMPLE_3DFX */
-      1391, /* GL_SAMPLE_BUFFERS_3DFX */
-      1382, /* GL_SAMPLES_3DFX */
-       977, /* GL_MODELVIEW2_ARB */
-       980, /* GL_MODELVIEW3_ARB */
-       981, /* GL_MODELVIEW4_ARB */
-       982, /* GL_MODELVIEW5_ARB */
-       983, /* GL_MODELVIEW6_ARB */
-       984, /* GL_MODELVIEW7_ARB */
-       985, /* GL_MODELVIEW8_ARB */
-       986, /* GL_MODELVIEW9_ARB */
-       956, /* GL_MODELVIEW10_ARB */
-       957, /* GL_MODELVIEW11_ARB */
-       958, /* GL_MODELVIEW12_ARB */
-       959, /* GL_MODELVIEW13_ARB */
-       960, /* GL_MODELVIEW14_ARB */
-       961, /* GL_MODELVIEW15_ARB */
-       962, /* GL_MODELVIEW16_ARB */
-       963, /* GL_MODELVIEW17_ARB */
-       964, /* GL_MODELVIEW18_ARB */
-       965, /* GL_MODELVIEW19_ARB */
-       967, /* GL_MODELVIEW20_ARB */
-       968, /* GL_MODELVIEW21_ARB */
-       969, /* GL_MODELVIEW22_ARB */
-       970, /* GL_MODELVIEW23_ARB */
-       971, /* GL_MODELVIEW24_ARB */
-       972, /* GL_MODELVIEW25_ARB */
-       973, /* GL_MODELVIEW26_ARB */
-       974, /* GL_MODELVIEW27_ARB */
-       975, /* GL_MODELVIEW28_ARB */
-       976, /* GL_MODELVIEW29_ARB */
-       978, /* GL_MODELVIEW30_ARB */
-       979, /* GL_MODELVIEW31_ARB */
-       389, /* GL_DOT3_RGB_EXT */
-       387, /* GL_DOT3_RGBA_EXT */
-       950, /* GL_MIRROR_CLAMP_EXT */
-       953, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
-       991, /* GL_MODULATE_ADD_ATI */
-       992, /* GL_MODULATE_SIGNED_ADD_ATI */
-       993, /* GL_MODULATE_SUBTRACT_ATI */
-      1858, /* GL_YCBCR_MESA */
-      1083, /* GL_PACK_INVERT_MESA */
+      1006, /* GL_MULTISAMPLE_3DFX */
+      1408, /* GL_SAMPLE_BUFFERS_3DFX */
+      1399, /* GL_SAMPLES_3DFX */
+       987, /* GL_MODELVIEW2_ARB */
+       990, /* GL_MODELVIEW3_ARB */
+       991, /* GL_MODELVIEW4_ARB */
+       992, /* GL_MODELVIEW5_ARB */
+       993, /* GL_MODELVIEW6_ARB */
+       994, /* GL_MODELVIEW7_ARB */
+       995, /* GL_MODELVIEW8_ARB */
+       996, /* GL_MODELVIEW9_ARB */
+       966, /* GL_MODELVIEW10_ARB */
+       967, /* GL_MODELVIEW11_ARB */
+       968, /* GL_MODELVIEW12_ARB */
+       969, /* GL_MODELVIEW13_ARB */
+       970, /* GL_MODELVIEW14_ARB */
+       971, /* GL_MODELVIEW15_ARB */
+       972, /* GL_MODELVIEW16_ARB */
+       973, /* GL_MODELVIEW17_ARB */
+       974, /* GL_MODELVIEW18_ARB */
+       975, /* GL_MODELVIEW19_ARB */
+       977, /* GL_MODELVIEW20_ARB */
+       978, /* GL_MODELVIEW21_ARB */
+       979, /* GL_MODELVIEW22_ARB */
+       980, /* GL_MODELVIEW23_ARB */
+       981, /* GL_MODELVIEW24_ARB */
+       982, /* GL_MODELVIEW25_ARB */
+       983, /* GL_MODELVIEW26_ARB */
+       984, /* GL_MODELVIEW27_ARB */
+       985, /* GL_MODELVIEW28_ARB */
+       986, /* GL_MODELVIEW29_ARB */
+       988, /* GL_MODELVIEW30_ARB */
+       989, /* GL_MODELVIEW31_ARB */
+       391, /* GL_DOT3_RGB_EXT */
+       389, /* GL_DOT3_RGBA_EXT */
+       960, /* GL_MIRROR_CLAMP_EXT */
+       963, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
+      1001, /* GL_MODULATE_ADD_ATI */
+      1002, /* GL_MODULATE_SIGNED_ADD_ATI */
+      1003, /* GL_MODULATE_SUBTRACT_ATI */
+      1880, /* GL_YCBCR_MESA */
+      1093, /* GL_PACK_INVERT_MESA */
        339, /* GL_DEBUG_OBJECT_MESA */
        340, /* GL_DEBUG_PRINT_MESA */
        338, /* GL_DEBUG_ASSERT_MESA */
@@ -4762,292 +4806,292 @@
        117, /* GL_BUMP_ROT_MATRIX_SIZE_ATI */
        115, /* GL_BUMP_NUM_TEX_UNITS_ATI */
        119, /* GL_BUMP_TEX_UNITS_ATI */
-       448, /* GL_DUDV_ATI */
-       447, /* GL_DU8DV8_ATI */
+       451, /* GL_DUDV_ATI */
+       450, /* GL_DU8DV8_ATI */
        114, /* GL_BUMP_ENVMAP_ATI */
        118, /* GL_BUMP_TARGET_ATI */
-      1490, /* GL_STENCIL_BACK_FUNC */
-      1488, /* GL_STENCIL_BACK_FAIL */
-      1492, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
-      1494, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
-       533, /* GL_FRAGMENT_PROGRAM_ARB */
-      1221, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
-      1249, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
-      1248, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
-      1233, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
-      1239, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
-      1238, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
-       884, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
-       907, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
-       906, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
-       897, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
-       903, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
-       902, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
-       867, /* GL_MAX_DRAW_BUFFERS */
-       393, /* GL_DRAW_BUFFER0 */
-       396, /* GL_DRAW_BUFFER1 */
-       417, /* GL_DRAW_BUFFER2 */
-       420, /* GL_DRAW_BUFFER3 */
-       423, /* GL_DRAW_BUFFER4 */
-       426, /* GL_DRAW_BUFFER5 */
-       429, /* GL_DRAW_BUFFER6 */
-       432, /* GL_DRAW_BUFFER7 */
-       435, /* GL_DRAW_BUFFER8 */
-       438, /* GL_DRAW_BUFFER9 */
-       397, /* GL_DRAW_BUFFER10 */
-       400, /* GL_DRAW_BUFFER11 */
-       403, /* GL_DRAW_BUFFER12 */
-       406, /* GL_DRAW_BUFFER13 */
-       409, /* GL_DRAW_BUFFER14 */
-       412, /* GL_DRAW_BUFFER15 */
+      1507, /* GL_STENCIL_BACK_FUNC */
+      1505, /* GL_STENCIL_BACK_FAIL */
+      1509, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
+      1511, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
+       536, /* GL_FRAGMENT_PROGRAM_ARB */
+      1231, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
+      1259, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
+      1258, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
+      1243, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+      1249, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+      1248, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+       892, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
+       915, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
+       914, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
+       905, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+       911, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+       910, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+       875, /* GL_MAX_DRAW_BUFFERS */
+       395, /* GL_DRAW_BUFFER0 */
+       398, /* GL_DRAW_BUFFER1 */
+       419, /* GL_DRAW_BUFFER2 */
+       422, /* GL_DRAW_BUFFER3 */
+       425, /* GL_DRAW_BUFFER4 */
+       428, /* GL_DRAW_BUFFER5 */
+       431, /* GL_DRAW_BUFFER6 */
+       434, /* GL_DRAW_BUFFER7 */
+       437, /* GL_DRAW_BUFFER8 */
+       440, /* GL_DRAW_BUFFER9 */
+       399, /* GL_DRAW_BUFFER10 */
+       402, /* GL_DRAW_BUFFER11 */
+       405, /* GL_DRAW_BUFFER12 */
+       408, /* GL_DRAW_BUFFER13 */
+       411, /* GL_DRAW_BUFFER14 */
+       414, /* GL_DRAW_BUFFER15 */
         82, /* GL_BLEND_EQUATION_ALPHA */
-       847, /* GL_MATRIX_PALETTE_ARB */
-       878, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
-       881, /* GL_MAX_PALETTE_MATRICES_ARB */
+       854, /* GL_MATRIX_PALETTE_ARB */
+       886, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
+       889, /* GL_MAX_PALETTE_MATRICES_ARB */
        321, /* GL_CURRENT_PALETTE_MATRIX_ARB */
-       841, /* GL_MATRIX_INDEX_ARRAY_ARB */
+       848, /* GL_MATRIX_INDEX_ARRAY_ARB */
        316, /* GL_CURRENT_MATRIX_INDEX_ARB */
-       843, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
-       845, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
-       844, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
-       842, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
-      1678, /* GL_TEXTURE_DEPTH_SIZE */
-       377, /* GL_DEPTH_TEXTURE_MODE */
-      1643, /* GL_TEXTURE_COMPARE_MODE */
-      1641, /* GL_TEXTURE_COMPARE_FUNC */
+       850, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
+       852, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
+       851, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
+       849, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
+      1699, /* GL_TEXTURE_DEPTH_SIZE */
+       379, /* GL_DEPTH_TEXTURE_MODE */
+      1664, /* GL_TEXTURE_COMPARE_MODE */
+      1662, /* GL_TEXTURE_COMPARE_FUNC */
        242, /* GL_COMPARE_R_TO_TEXTURE */
-      1155, /* GL_POINT_SPRITE */
+      1165, /* GL_POINT_SPRITE */
        296, /* GL_COORD_REPLACE */
-      1159, /* GL_POINT_SPRITE_R_MODE_NV */
-      1280, /* GL_QUERY_COUNTER_BITS */
+      1169, /* GL_POINT_SPRITE_R_MODE_NV */
+      1292, /* GL_QUERY_COUNTER_BITS */
        323, /* GL_CURRENT_QUERY */
-      1282, /* GL_QUERY_RESULT */
-      1284, /* GL_QUERY_RESULT_AVAILABLE */
-       930, /* GL_MAX_VERTEX_ATTRIBS */
-      1819, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
-       375, /* GL_DEPTH_STENCIL_TO_RGBA_NV */
-       374, /* GL_DEPTH_STENCIL_TO_BGRA_NV */
-       916, /* GL_MAX_TEXTURE_COORDS */
-       918, /* GL_MAX_TEXTURE_IMAGE_UNITS */
-      1226, /* GL_PROGRAM_ERROR_STRING_ARB */
-      1228, /* GL_PROGRAM_FORMAT_ASCII_ARB */
-      1227, /* GL_PROGRAM_FORMAT_ARB */
-      1727, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
-       353, /* GL_DEPTH_BOUNDS_TEST_EXT */
-       352, /* GL_DEPTH_BOUNDS_EXT */
+      1295, /* GL_QUERY_RESULT */
+      1297, /* GL_QUERY_RESULT_AVAILABLE */
+       940, /* GL_MAX_VERTEX_ATTRIBS */
+      1841, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
+       377, /* GL_DEPTH_STENCIL_TO_RGBA_NV */
+       376, /* GL_DEPTH_STENCIL_TO_BGRA_NV */
+       926, /* GL_MAX_TEXTURE_COORDS */
+       928, /* GL_MAX_TEXTURE_IMAGE_UNITS */
+      1236, /* GL_PROGRAM_ERROR_STRING_ARB */
+      1238, /* GL_PROGRAM_FORMAT_ASCII_ARB */
+      1237, /* GL_PROGRAM_FORMAT_ARB */
+      1749, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
+       354, /* GL_DEPTH_BOUNDS_TEST_EXT */
+       353, /* GL_DEPTH_BOUNDS_EXT */
         53, /* GL_ARRAY_BUFFER */
-       461, /* GL_ELEMENT_ARRAY_BUFFER */
+       464, /* GL_ELEMENT_ARRAY_BUFFER */
         54, /* GL_ARRAY_BUFFER_BINDING */
-       462, /* GL_ELEMENT_ARRAY_BUFFER_BINDING */
-      1793, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
-      1017, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
+       465, /* GL_ELEMENT_ARRAY_BUFFER_BINDING */
+      1815, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
+      1027, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
        149, /* GL_COLOR_ARRAY_BUFFER_BINDING */
-       625, /* GL_INDEX_ARRAY_BUFFER_BINDING */
-      1656, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
-       457, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */
-      1403, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
-       511, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */
-      1846, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
-      1815, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
-      1229, /* GL_PROGRAM_INSTRUCTIONS_ARB */
-       890, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
-      1235, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
-       899, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
-      1247, /* GL_PROGRAM_TEMPORARIES_ARB */
-       905, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
-      1237, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
-       901, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
-      1241, /* GL_PROGRAM_PARAMETERS_ARB */
-       904, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
-      1236, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
-       900, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
-      1222, /* GL_PROGRAM_ATTRIBS_ARB */
-       885, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
-      1234, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
-       898, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
-      1220, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
-       883, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
-      1232, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
-       896, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
-       891, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
-       887, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
-      1250, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
-      1740, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
-      1293, /* GL_READ_ONLY */
-      1854, /* GL_WRITE_ONLY */
-      1295, /* GL_READ_WRITE */
+       632, /* GL_INDEX_ARRAY_BUFFER_BINDING */
+      1677, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
+       460, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */
+      1420, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
+       514, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */
+      1868, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
+      1837, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
+      1239, /* GL_PROGRAM_INSTRUCTIONS_ARB */
+       898, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
+      1245, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+       907, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+      1257, /* GL_PROGRAM_TEMPORARIES_ARB */
+       913, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
+      1247, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
+       909, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
+      1251, /* GL_PROGRAM_PARAMETERS_ARB */
+       912, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
+      1246, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
+       908, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
+      1232, /* GL_PROGRAM_ATTRIBS_ARB */
+       893, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
+      1244, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
+       906, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
+      1230, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
+       891, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
+      1242, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+       904, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+       899, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
+       895, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
+      1260, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
+      1761, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
+      1308, /* GL_READ_ONLY */
+      1876, /* GL_WRITE_ONLY */
+      1310, /* GL_READ_WRITE */
        102, /* GL_BUFFER_ACCESS */
        105, /* GL_BUFFER_MAPPED */
        107, /* GL_BUFFER_MAP_POINTER */
-      1734, /* GL_TIME_ELAPSED_EXT */
-       801, /* GL_MATRIX0_ARB */
-       813, /* GL_MATRIX1_ARB */
-       825, /* GL_MATRIX2_ARB */
-       829, /* GL_MATRIX3_ARB */
-       831, /* GL_MATRIX4_ARB */
-       833, /* GL_MATRIX5_ARB */
-       835, /* GL_MATRIX6_ARB */
-       837, /* GL_MATRIX7_ARB */
-       839, /* GL_MATRIX8_ARB */
-       840, /* GL_MATRIX9_ARB */
-       803, /* GL_MATRIX10_ARB */
-       804, /* GL_MATRIX11_ARB */
-       805, /* GL_MATRIX12_ARB */
-       806, /* GL_MATRIX13_ARB */
-       807, /* GL_MATRIX14_ARB */
-       808, /* GL_MATRIX15_ARB */
-       809, /* GL_MATRIX16_ARB */
-       810, /* GL_MATRIX17_ARB */
-       811, /* GL_MATRIX18_ARB */
-       812, /* GL_MATRIX19_ARB */
-       815, /* GL_MATRIX20_ARB */
-       816, /* GL_MATRIX21_ARB */
-       817, /* GL_MATRIX22_ARB */
-       818, /* GL_MATRIX23_ARB */
-       819, /* GL_MATRIX24_ARB */
-       820, /* GL_MATRIX25_ARB */
-       821, /* GL_MATRIX26_ARB */
-       822, /* GL_MATRIX27_ARB */
-       823, /* GL_MATRIX28_ARB */
-       824, /* GL_MATRIX29_ARB */
-       827, /* GL_MATRIX30_ARB */
-       828, /* GL_MATRIX31_ARB */
-      1523, /* GL_STREAM_DRAW */
-      1525, /* GL_STREAM_READ */
-      1521, /* GL_STREAM_COPY */
-      1481, /* GL_STATIC_DRAW */
-      1483, /* GL_STATIC_READ */
-      1479, /* GL_STATIC_COPY */
-       451, /* GL_DYNAMIC_DRAW */
-       453, /* GL_DYNAMIC_READ */
-       449, /* GL_DYNAMIC_COPY */
-      1123, /* GL_PIXEL_PACK_BUFFER */
-      1127, /* GL_PIXEL_UNPACK_BUFFER */
-      1124, /* GL_PIXEL_PACK_BUFFER_BINDING */
-      1128, /* GL_PIXEL_UNPACK_BUFFER_BINDING */
+      1755, /* GL_TIME_ELAPSED_EXT */
+       808, /* GL_MATRIX0_ARB */
+       820, /* GL_MATRIX1_ARB */
+       832, /* GL_MATRIX2_ARB */
+       836, /* GL_MATRIX3_ARB */
+       838, /* GL_MATRIX4_ARB */
+       840, /* GL_MATRIX5_ARB */
+       842, /* GL_MATRIX6_ARB */
+       844, /* GL_MATRIX7_ARB */
+       846, /* GL_MATRIX8_ARB */
+       847, /* GL_MATRIX9_ARB */
+       810, /* GL_MATRIX10_ARB */
+       811, /* GL_MATRIX11_ARB */
+       812, /* GL_MATRIX12_ARB */
+       813, /* GL_MATRIX13_ARB */
+       814, /* GL_MATRIX14_ARB */
+       815, /* GL_MATRIX15_ARB */
+       816, /* GL_MATRIX16_ARB */
+       817, /* GL_MATRIX17_ARB */
+       818, /* GL_MATRIX18_ARB */
+       819, /* GL_MATRIX19_ARB */
+       822, /* GL_MATRIX20_ARB */
+       823, /* GL_MATRIX21_ARB */
+       824, /* GL_MATRIX22_ARB */
+       825, /* GL_MATRIX23_ARB */
+       826, /* GL_MATRIX24_ARB */
+       827, /* GL_MATRIX25_ARB */
+       828, /* GL_MATRIX26_ARB */
+       829, /* GL_MATRIX27_ARB */
+       830, /* GL_MATRIX28_ARB */
+       831, /* GL_MATRIX29_ARB */
+       834, /* GL_MATRIX30_ARB */
+       835, /* GL_MATRIX31_ARB */
+      1544, /* GL_STREAM_DRAW */
+      1546, /* GL_STREAM_READ */
+      1542, /* GL_STREAM_COPY */
+      1498, /* GL_STATIC_DRAW */
+      1500, /* GL_STATIC_READ */
+      1496, /* GL_STATIC_COPY */
+       454, /* GL_DYNAMIC_DRAW */
+       456, /* GL_DYNAMIC_READ */
+       452, /* GL_DYNAMIC_COPY */
+      1133, /* GL_PIXEL_PACK_BUFFER */
+      1137, /* GL_PIXEL_UNPACK_BUFFER */
+      1134, /* GL_PIXEL_PACK_BUFFER_BINDING */
+      1138, /* GL_PIXEL_UNPACK_BUFFER_BINDING */
        347, /* GL_DEPTH24_STENCIL8 */
-      1724, /* GL_TEXTURE_STENCIL_SIZE */
-      1676, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */
-       886, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
-       889, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
-       893, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
-       892, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
-       850, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */
-      1514, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
+      1745, /* GL_TEXTURE_STENCIL_SIZE */
+      1697, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */
+       894, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
+       897, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
+       901, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
+       900, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
+       857, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */
+      1535, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
         17, /* GL_ACTIVE_STENCIL_FACE_EXT */
-       951, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
-      1384, /* GL_SAMPLES_PASSED */
+       961, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
+      1401, /* GL_SAMPLES_PASSED */
        109, /* GL_BUFFER_SERIALIZED_MODIFY_APPLE */
        104, /* GL_BUFFER_FLUSHING_UNMAP_APPLE */
-       534, /* GL_FRAGMENT_SHADER */
-      1839, /* GL_VERTEX_SHADER */
-      1240, /* GL_PROGRAM_OBJECT_ARB */
-      1416, /* GL_SHADER_OBJECT_ARB */
-       874, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */
-       934, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */
-       928, /* GL_MAX_VARYING_FLOATS */
-       932, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */
-       859, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */
-      1043, /* GL_OBJECT_TYPE_ARB */
-      1418, /* GL_SHADER_TYPE */
-       499, /* GL_FLOAT_VEC2 */
-       501, /* GL_FLOAT_VEC3 */
-       503, /* GL_FLOAT_VEC4 */
-       652, /* GL_INT_VEC2 */
-       654, /* GL_INT_VEC3 */
-       656, /* GL_INT_VEC4 */
+       537, /* GL_FRAGMENT_SHADER */
+      1861, /* GL_VERTEX_SHADER */
+      1250, /* GL_PROGRAM_OBJECT_ARB */
+      1433, /* GL_SHADER_OBJECT_ARB */
+       882, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */
+       944, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */
+       938, /* GL_MAX_VARYING_FLOATS */
+       942, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */
+       867, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */
+      1053, /* GL_OBJECT_TYPE_ARB */
+      1435, /* GL_SHADER_TYPE */
+       502, /* GL_FLOAT_VEC2 */
+       504, /* GL_FLOAT_VEC3 */
+       506, /* GL_FLOAT_VEC4 */
+       659, /* GL_INT_VEC2 */
+       661, /* GL_INT_VEC3 */
+       663, /* GL_INT_VEC4 */
         94, /* GL_BOOL */
         96, /* GL_BOOL_VEC2 */
         98, /* GL_BOOL_VEC3 */
        100, /* GL_BOOL_VEC4 */
-       487, /* GL_FLOAT_MAT2 */
-       491, /* GL_FLOAT_MAT3 */
-       495, /* GL_FLOAT_MAT4 */
-      1375, /* GL_SAMPLER_1D */
-      1377, /* GL_SAMPLER_2D */
-      1379, /* GL_SAMPLER_3D */
-      1380, /* GL_SAMPLER_CUBE */
-      1376, /* GL_SAMPLER_1D_SHADOW */
-      1378, /* GL_SAMPLER_2D_SHADOW */
-       489, /* GL_FLOAT_MAT2x3 */
-       490, /* GL_FLOAT_MAT2x4 */
-       493, /* GL_FLOAT_MAT3x2 */
-       494, /* GL_FLOAT_MAT3x4 */
-       497, /* GL_FLOAT_MAT4x2 */
-       498, /* GL_FLOAT_MAT4x3 */
+       490, /* GL_FLOAT_MAT2 */
+       494, /* GL_FLOAT_MAT3 */
+       498, /* GL_FLOAT_MAT4 */
+      1392, /* GL_SAMPLER_1D */
+      1394, /* GL_SAMPLER_2D */
+      1396, /* GL_SAMPLER_3D */
+      1397, /* GL_SAMPLER_CUBE */
+      1393, /* GL_SAMPLER_1D_SHADOW */
+      1395, /* GL_SAMPLER_2D_SHADOW */
+       492, /* GL_FLOAT_MAT2x3 */
+       493, /* GL_FLOAT_MAT2x4 */
+       496, /* GL_FLOAT_MAT3x2 */
+       497, /* GL_FLOAT_MAT3x4 */
+       500, /* GL_FLOAT_MAT4x2 */
+       501, /* GL_FLOAT_MAT4x3 */
        345, /* GL_DELETE_STATUS */
        246, /* GL_COMPILE_STATUS */
-       708, /* GL_LINK_STATUS */
-      1787, /* GL_VALIDATE_STATUS */
-       637, /* GL_INFO_LOG_LENGTH */
+       715, /* GL_LINK_STATUS */
+      1809, /* GL_VALIDATE_STATUS */
+       644, /* GL_INFO_LOG_LENGTH */
         56, /* GL_ATTACHED_SHADERS */
         20, /* GL_ACTIVE_UNIFORMS */
         21, /* GL_ACTIVE_UNIFORM_MAX_LENGTH */
-      1417, /* GL_SHADER_SOURCE_LENGTH */
+      1434, /* GL_SHADER_SOURCE_LENGTH */
         15, /* GL_ACTIVE_ATTRIBUTES */
         16, /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */
-       536, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */
-      1420, /* GL_SHADING_LANGUAGE_VERSION */
+       539, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */
+      1437, /* GL_SHADING_LANGUAGE_VERSION */
        322, /* GL_CURRENT_PROGRAM */
-      1092, /* GL_PALETTE4_RGB8_OES */
-      1094, /* GL_PALETTE4_RGBA8_OES */
-      1090, /* GL_PALETTE4_R5_G6_B5_OES */
-      1093, /* GL_PALETTE4_RGBA4_OES */
-      1091, /* GL_PALETTE4_RGB5_A1_OES */
-      1097, /* GL_PALETTE8_RGB8_OES */
-      1099, /* GL_PALETTE8_RGBA8_OES */
-      1095, /* GL_PALETTE8_R5_G6_B5_OES */
-      1098, /* GL_PALETTE8_RGBA4_OES */
-      1096, /* GL_PALETTE8_RGB5_A1_OES */
-       619, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
-       618, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
-      1772, /* GL_UNSIGNED_NORMALIZED */
-      1611, /* GL_TEXTURE_1D_ARRAY_EXT */
-      1262, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */
-      1613, /* GL_TEXTURE_2D_ARRAY_EXT */
-      1265, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */
-      1619, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */
-      1621, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */
-      1473, /* GL_SRGB */
-      1474, /* GL_SRGB8 */
-      1476, /* GL_SRGB_ALPHA */
-      1475, /* GL_SRGB8_ALPHA8 */
-      1433, /* GL_SLUMINANCE_ALPHA */
-      1432, /* GL_SLUMINANCE8_ALPHA8 */
-      1430, /* GL_SLUMINANCE */
-      1431, /* GL_SLUMINANCE8 */
+      1102, /* GL_PALETTE4_RGB8_OES */
+      1104, /* GL_PALETTE4_RGBA8_OES */
+      1100, /* GL_PALETTE4_R5_G6_B5_OES */
+      1103, /* GL_PALETTE4_RGBA4_OES */
+      1101, /* GL_PALETTE4_RGB5_A1_OES */
+      1107, /* GL_PALETTE8_RGB8_OES */
+      1109, /* GL_PALETTE8_RGBA8_OES */
+      1105, /* GL_PALETTE8_R5_G6_B5_OES */
+      1108, /* GL_PALETTE8_RGBA4_OES */
+      1106, /* GL_PALETTE8_RGB5_A1_OES */
+       626, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
+       625, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
+      1794, /* GL_UNSIGNED_NORMALIZED */
+      1632, /* GL_TEXTURE_1D_ARRAY_EXT */
+      1272, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */
+      1634, /* GL_TEXTURE_2D_ARRAY_EXT */
+      1275, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */
+      1640, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */
+      1642, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */
+      1490, /* GL_SRGB */
+      1491, /* GL_SRGB8 */
+      1493, /* GL_SRGB_ALPHA */
+      1492, /* GL_SRGB8_ALPHA8 */
+      1450, /* GL_SLUMINANCE_ALPHA */
+      1449, /* GL_SLUMINANCE8_ALPHA8 */
+      1447, /* GL_SLUMINANCE */
+      1448, /* GL_SLUMINANCE8 */
        267, /* GL_COMPRESSED_SRGB */
        268, /* GL_COMPRESSED_SRGB_ALPHA */
        265, /* GL_COMPRESSED_SLUMINANCE */
        266, /* GL_COMPRESSED_SLUMINANCE_ALPHA */
-      1157, /* GL_POINT_SPRITE_COORD_ORIGIN */
-       716, /* GL_LOWER_LEFT */
-      1784, /* GL_UPPER_LEFT */
-      1496, /* GL_STENCIL_BACK_REF */
-      1497, /* GL_STENCIL_BACK_VALUE_MASK */
-      1498, /* GL_STENCIL_BACK_WRITEMASK */
-       442, /* GL_DRAW_FRAMEBUFFER_BINDING_EXT */
-      1309, /* GL_RENDERBUFFER_BINDING_EXT */
-      1290, /* GL_READ_FRAMEBUFFER */
-       441, /* GL_DRAW_FRAMEBUFFER */
-      1291, /* GL_READ_FRAMEBUFFER_BINDING_EXT */
-      1319, /* GL_RENDERBUFFER_SAMPLES */
-       546, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
-       544, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
-       555, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
-       551, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
-       553, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
-       558, /* GL_FRAMEBUFFER_COMPLETE */
-       562, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
-       568, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
-       566, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
-       564, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
-       567, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
-       565, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT */
-       571, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT */
-       574, /* GL_FRAMEBUFFER_UNSUPPORTED */
-       572, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
-       856, /* GL_MAX_COLOR_ATTACHMENTS_EXT */
+      1167, /* GL_POINT_SPRITE_COORD_ORIGIN */
+       723, /* GL_LOWER_LEFT */
+      1806, /* GL_UPPER_LEFT */
+      1513, /* GL_STENCIL_BACK_REF */
+      1514, /* GL_STENCIL_BACK_VALUE_MASK */
+      1515, /* GL_STENCIL_BACK_WRITEMASK */
+       444, /* GL_DRAW_FRAMEBUFFER_BINDING */
+      1324, /* GL_RENDERBUFFER_BINDING */
+      1304, /* GL_READ_FRAMEBUFFER */
+       443, /* GL_DRAW_FRAMEBUFFER */
+      1305, /* GL_READ_FRAMEBUFFER_BINDING */
+      1335, /* GL_RENDERBUFFER_SAMPLES */
+       549, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
+       547, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
+       558, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
+       554, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
+       556, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+       562, /* GL_FRAMEBUFFER_COMPLETE */
+       566, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
+       573, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
+       571, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
+       568, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
+       572, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
+       569, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER */
+       577, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER */
+       581, /* GL_FRAMEBUFFER_UNSUPPORTED */
+       579, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
+       863, /* GL_MAX_COLOR_ATTACHMENTS */
        155, /* GL_COLOR_ATTACHMENT0 */
        157, /* GL_COLOR_ATTACHMENT1 */
        171, /* GL_COLOR_ATTACHMENT2 */
@@ -5064,57 +5108,60 @@
        164, /* GL_COLOR_ATTACHMENT13 */
        166, /* GL_COLOR_ATTACHMENT14 */
        168, /* GL_COLOR_ATTACHMENT15 */
-       348, /* GL_DEPTH_ATTACHMENT */
-      1486, /* GL_STENCIL_ATTACHMENT */
-       537, /* GL_FRAMEBUFFER */
-      1307, /* GL_RENDERBUFFER */
-      1321, /* GL_RENDERBUFFER_WIDTH */
-      1314, /* GL_RENDERBUFFER_HEIGHT */
-      1316, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
-      1509, /* GL_STENCIL_INDEX_EXT */
-      1506, /* GL_STENCIL_INDEX1_EXT */
-      1507, /* GL_STENCIL_INDEX4_EXT */
-      1508, /* GL_STENCIL_INDEX8_EXT */
-      1505, /* GL_STENCIL_INDEX16_EXT */
-      1318, /* GL_RENDERBUFFER_RED_SIZE */
-      1313, /* GL_RENDERBUFFER_GREEN_SIZE */
-      1310, /* GL_RENDERBUFFER_BLUE_SIZE */
-      1308, /* GL_RENDERBUFFER_ALPHA_SIZE */
-      1311, /* GL_RENDERBUFFER_DEPTH_SIZE */
-      1320, /* GL_RENDERBUFFER_STENCIL_SIZE */
-       570, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
-       912, /* GL_MAX_SAMPLES */
-      1276, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */
-       483, /* GL_FIRST_VERTEX_CONVENTION */
-       667, /* GL_LAST_VERTEX_CONVENTION */
-      1254, /* GL_PROVOKING_VERTEX */
+       349, /* GL_DEPTH_ATTACHMENT */
+      1503, /* GL_STENCIL_ATTACHMENT */
+       540, /* GL_FRAMEBUFFER */
+      1322, /* GL_RENDERBUFFER */
+      1338, /* GL_RENDERBUFFER_WIDTH */
+      1330, /* GL_RENDERBUFFER_HEIGHT */
+      1332, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
+      1530, /* GL_STENCIL_INDEX_EXT */
+      1522, /* GL_STENCIL_INDEX1 */
+      1526, /* GL_STENCIL_INDEX4 */
+      1528, /* GL_STENCIL_INDEX8 */
+      1523, /* GL_STENCIL_INDEX16 */
+      1334, /* GL_RENDERBUFFER_RED_SIZE */
+      1329, /* GL_RENDERBUFFER_GREEN_SIZE */
+      1326, /* GL_RENDERBUFFER_BLUE_SIZE */
+      1323, /* GL_RENDERBUFFER_ALPHA_SIZE */
+      1327, /* GL_RENDERBUFFER_DEPTH_SIZE */
+      1337, /* GL_RENDERBUFFER_STENCIL_SIZE */
+       575, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
+       921, /* GL_MAX_SAMPLES */
+      1299, /* GL_QUERY_WAIT_NV */
+      1294, /* GL_QUERY_NO_WAIT_NV */
+      1291, /* GL_QUERY_BY_REGION_WAIT_NV */
+      1290, /* GL_QUERY_BY_REGION_NO_WAIT_NV */
+      1286, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */
+       486, /* GL_FIRST_VERTEX_CONVENTION */
+       674, /* GL_LAST_VERTEX_CONVENTION */
+      1264, /* GL_PROVOKING_VERTEX */
        302, /* GL_COPY_READ_BUFFER */
        303, /* GL_COPY_WRITE_BUFFER */
-      1368, /* GL_RGBA_SNORM */
-      1364, /* GL_RGBA8_SNORM */
-      1426, /* GL_SIGNED_NORMALIZED */
-       913, /* GL_MAX_SERVER_WAIT_TIMEOUT */
-      1042, /* GL_OBJECT_TYPE */
-      1530, /* GL_SYNC_CONDITION */
-      1535, /* GL_SYNC_STATUS */
-      1532, /* GL_SYNC_FLAGS */
-      1531, /* GL_SYNC_FENCE */
-      1534, /* GL_SYNC_GPU_COMMANDS_COMPLETE */
-      1761, /* GL_UNSIGNALED */
-      1425, /* GL_SIGNALED */
+      1385, /* GL_RGBA_SNORM */
+      1381, /* GL_RGBA8_SNORM */
+      1443, /* GL_SIGNED_NORMALIZED */
+       923, /* GL_MAX_SERVER_WAIT_TIMEOUT */
+      1052, /* GL_OBJECT_TYPE */
+      1551, /* GL_SYNC_CONDITION */
+      1556, /* GL_SYNC_STATUS */
+      1553, /* GL_SYNC_FLAGS */
+      1552, /* GL_SYNC_FENCE */
+      1555, /* GL_SYNC_GPU_COMMANDS_COMPLETE */
+      1782, /* GL_UNSIGNALED */
+      1442, /* GL_SIGNALED */
         46, /* GL_ALREADY_SIGNALED */
-      1732, /* GL_TIMEOUT_EXPIRED */
+      1754, /* GL_TIMEOUT_EXPIRED */
        270, /* GL_CONDITION_SATISFIED */
-      1844, /* GL_WAIT_FAILED */
-       468, /* GL_EVAL_BIT */
-      1288, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
-       710, /* GL_LIST_BIT */
-      1627, /* GL_TEXTURE_BIT */
-      1399, /* GL_SCISSOR_BIT */
+      1866, /* GL_WAIT_FAILED */
+       471, /* GL_EVAL_BIT */
+      1302, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
+       717, /* GL_LIST_BIT */
+      1648, /* GL_TEXTURE_BIT */
+      1416, /* GL_SCISSOR_BIT */
         29, /* GL_ALL_ATTRIB_BITS */
-       998, /* GL_MULTISAMPLE_BIT */
+      1008, /* GL_MULTISAMPLE_BIT */
         30, /* GL_ALL_CLIENT_ATTRIB_BITS */
-      1733, /* GL_TIMEOUT_IGNORED */
 };
 
 typedef int (*cfunc)(const void *, const void *);
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 7a8184f..00427aa 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -103,9 +103,11 @@
    { OFF, "GL_EXT_convolution",                F(EXT_convolution) },
    { ON,  "GL_EXT_copy_texture",               F(EXT_copy_texture) },
    { OFF, "GL_EXT_depth_bounds_test",          F(EXT_depth_bounds_test) },
+   { OFF, "GL_EXT_draw_buffers2",              F(EXT_draw_buffers2) },
    { ON,  "GL_EXT_draw_range_elements",        F(EXT_draw_range_elements) },
-   { OFF, "GL_EXT_framebuffer_object",         F(EXT_framebuffer_object) },
    { OFF, "GL_EXT_framebuffer_blit",           F(EXT_framebuffer_blit) },
+   { OFF, "GL_EXT_framebuffer_multisample",    F(EXT_framebuffer_multisample) },
+   { OFF, "GL_EXT_framebuffer_object",         F(EXT_framebuffer_object) },
    { OFF, "GL_EXT_fog_coord",                  F(EXT_fog_coord) },
    { OFF, "GL_EXT_gpu_program_parameters",     F(EXT_gpu_program_parameters) },
    { OFF, "GL_EXT_histogram",                  F(EXT_histogram) },
@@ -165,10 +167,12 @@
    { OFF, "GL_MESA_ycbcr_texture",             F(MESA_ycbcr_texture) },
    { ON,  "GL_MESA_window_pos",                F(ARB_window_pos) },
    { OFF, "GL_NV_blend_square",                F(NV_blend_square) },
+   { OFF, "GL_NV_conditional_render",          F(NV_conditional_render) },
    { OFF, "GL_NV_depth_clamp",                 F(ARB_depth_clamp) },
    { OFF, "GL_NV_fragment_program",            F(NV_fragment_program) },
    { OFF, "GL_NV_fragment_program_option",     F(NV_fragment_program_option) },
    { ON,  "GL_NV_light_max_exponent",          F(NV_light_max_exponent) },
+   { OFF, "GL_NV_packed_depth_stencil",        F(EXT_packed_depth_stencil) },
    { OFF, "GL_NV_point_sprite",                F(NV_point_sprite) },
    { OFF, "GL_NV_texture_env_combine4",        F(NV_texture_env_combine4) },
    { OFF, "GL_NV_texture_rectangle",           F(NV_texture_rectangle) },
@@ -270,6 +274,7 @@
    ctx->Extensions.EXT_blend_subtract = GL_TRUE;
    ctx->Extensions.EXT_convolution = GL_TRUE;
    ctx->Extensions.EXT_depth_bounds_test = GL_TRUE;
+   ctx->Extensions.EXT_draw_buffers2 = GL_TRUE;
    ctx->Extensions.EXT_fog_coord = GL_TRUE;
 #if FEATURE_EXT_framebuffer_object
    ctx->Extensions.EXT_framebuffer_object = GL_TRUE;
@@ -277,6 +282,9 @@
 #if FEATURE_EXT_framebuffer_blit
    ctx->Extensions.EXT_framebuffer_blit = GL_TRUE;
 #endif
+#if FEATURE_ARB_framebuffer_object
+   ctx->Extensions.EXT_framebuffer_multisample = GL_TRUE;
+#endif
    ctx->Extensions.EXT_histogram = GL_TRUE;
    /*ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE;*/
    ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE;
@@ -307,6 +315,7 @@
    ctx->Extensions.MESA_texture_array = GL_TRUE;
    ctx->Extensions.MESA_ycbcr_texture = GL_TRUE;
    ctx->Extensions.NV_blend_square = GL_TRUE;
+   ctx->Extensions.NV_conditional_render = GL_TRUE;
    /*ctx->Extensions.NV_light_max_exponent = GL_TRUE;*/
    ctx->Extensions.NV_point_sprite = GL_TRUE;
    ctx->Extensions.NV_texture_env_combine4 = GL_TRUE;
@@ -521,19 +530,33 @@
 
 
 /**
+ * Check if the i-th extension is enabled.
+ */
+static GLboolean
+extension_enabled(GLcontext *ctx, GLuint index)
+{
+   const GLboolean *base = (const GLboolean *) &ctx->Extensions;
+   if (!default_extensions[index].flag_offset ||
+       *(base + default_extensions[index].flag_offset)) {
+      return GL_TRUE;
+   }
+   else {
+      return GL_FALSE;
+   }
+}
+
+
+/**
  * Test if the named extension is enabled in this context.
  */
 GLboolean
 _mesa_extension_is_enabled( GLcontext *ctx, const char *name )
 {
-   const GLboolean *base = (const GLboolean *) &ctx->Extensions;
    GLuint i;
 
    for (i = 0 ; i < Elements(default_extensions) ; i++) {
       if (_mesa_strcmp(default_extensions[i].name, name) == 0) {
-         if (!default_extensions[i].flag_offset)
-            return GL_TRUE;
-         return *(base + default_extensions[i].flag_offset);
+         return extension_enabled(ctx, i);
       }
    }
    return GL_FALSE;
@@ -641,7 +664,6 @@
 GLubyte *
 _mesa_make_extension_string( GLcontext *ctx )
 {
-   const GLboolean *base = (const GLboolean *) &ctx->Extensions;
    const char *extraExt = get_extension_override(ctx);
    GLuint extStrLen = 0;
    char *s;
@@ -649,8 +671,7 @@
 
    /* first, compute length of the extension string */
    for (i = 0 ; i < Elements(default_extensions) ; i++) {
-      if (!default_extensions[i].flag_offset ||
-          *(base + default_extensions[i].flag_offset)) {
+      if (extension_enabled(ctx, i)) {
          extStrLen += (GLuint)_mesa_strlen(default_extensions[i].name) + 1;
       }
    }
@@ -666,8 +687,7 @@
    /* second, build the extension string */
    extStrLen = 0;
    for (i = 0 ; i < Elements(default_extensions) ; i++) {
-      if (!default_extensions[i].flag_offset ||
-          *(base + default_extensions[i].flag_offset)) {
+      if (extension_enabled(ctx, i)) {
          GLuint len = (GLuint)_mesa_strlen(default_extensions[i].name);
          _mesa_memcpy(s + extStrLen, default_extensions[i].name, len);
          extStrLen += len;
@@ -686,3 +706,48 @@
 
    return (GLubyte *) s;
 }
+
+
+/**
+ * Return number of enabled extensions.
+ */
+GLuint
+_mesa_get_extension_count(GLcontext *ctx)
+{
+   GLuint i;
+
+   /* only count once */
+   if (!ctx->Extensions.Count) {
+      for (i = 0; i < Elements(default_extensions); i++) {
+         if (extension_enabled(ctx, i)) {
+            ctx->Extensions.Count++;
+         }
+      }
+   }
+
+   if (0)
+      _mesa_debug(ctx, "%u of %d extensions enabled\n", ctx->Extensions.Count,
+                  Elements(default_extensions));
+
+   return ctx->Extensions.Count;
+}
+
+
+/**
+ * Return name of i-th enabled extension
+ */
+const GLubyte *
+_mesa_get_enabled_extension(GLcontext *ctx, GLuint index)
+{
+   GLuint i;
+
+   for (i = 0; i < Elements(default_extensions); i++) {
+      if (extension_enabled(ctx, i)) {
+         if (index == 0)
+            return (const GLubyte *) default_extensions[i].name;
+         index--;
+      }
+   }
+
+   return NULL;
+}
diff --git a/src/mesa/main/extensions.h b/src/mesa/main/extensions.h
index 05ad859..a254724 100644
--- a/src/mesa/main/extensions.h
+++ b/src/mesa/main/extensions.h
@@ -64,6 +64,13 @@
 
 extern GLubyte *_mesa_make_extension_string(GLcontext *ctx);
 
+extern GLuint
+_mesa_get_extension_count(GLcontext *ctx);
+
+extern const GLubyte *
+_mesa_get_enabled_extension(GLcontext *ctx, GLuint index);
+
+
 #else
 
 /** No-op */
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 319d0f2..7b3599f 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -233,9 +233,13 @@
    if (att->Texture == texObj) {
       /* re-attaching same texture */
       ASSERT(att->Type == GL_TEXTURE);
+      if (ctx->Driver.FinishRenderTexture)
+	 ctx->Driver.FinishRenderTexture(ctx, att);
    }
    else {
       /* new attachment */
+      if (ctx->Driver.FinishRenderTexture && att->Texture)
+	 ctx->Driver.FinishRenderTexture(ctx, att);
       _mesa_remove_attachment(ctx, att);
       att->Type = GL_TEXTURE;
       assert(!att->Texture);
@@ -1145,11 +1149,20 @@
 }
 
 
+/**
+ * Check if any of the attachments of the given framebuffer are textures
+ * (render to texture).  Call ctx->Driver.RenderTexture() for such
+ * attachments.
+ */
 static void
 check_begin_texture_render(GLcontext *ctx, struct gl_framebuffer *fb)
 {
    GLuint i;
    ASSERT(ctx->Driver.RenderTexture);
+
+   if (fb->Name == 0)
+      return; /* can't render to texture with winsys framebuffers */
+
    for (i = 0; i < BUFFER_COUNT; i++) {
       struct gl_renderbuffer_attachment *att = fb->Attachment + i;
       struct gl_texture_object *texObj = att->Texture;
@@ -1169,6 +1182,9 @@
 static void
 check_end_texture_render(GLcontext *ctx, struct gl_framebuffer *fb)
 {
+   if (fb->Name == 0)
+      return; /* can't render to texture with winsys framebuffers */
+
    if (ctx->Driver.FinishRenderTexture) {
       GLuint i;
       for (i = 0; i < BUFFER_COUNT; i++) {
@@ -1184,7 +1200,8 @@
 void GLAPIENTRY
 _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
 {
-   struct gl_framebuffer *newFb, *newFbread;
+   struct gl_framebuffer *newDrawFb, *newReadFb;
+   struct gl_framebuffer *oldDrawFb, *oldReadFb;
    GLboolean bindReadBuf, bindDrawBuf;
    GET_CURRENT_CONTEXT(ctx);
 
@@ -1233,74 +1250,88 @@
 
    if (framebuffer) {
       /* Binding a user-created framebuffer object */
-      newFb = _mesa_lookup_framebuffer(ctx, framebuffer);
-      if (newFb == &DummyFramebuffer) {
+      newDrawFb = _mesa_lookup_framebuffer(ctx, framebuffer);
+      if (newDrawFb == &DummyFramebuffer) {
          /* ID was reserved, but no real framebuffer object made yet */
-         newFb = NULL;
+         newDrawFb = NULL;
       }
-      else if (!newFb && ctx->Extensions.ARB_framebuffer_object) {
+      else if (!newDrawFb && ctx->Extensions.ARB_framebuffer_object) {
          /* All FBO IDs must be Gen'd */
          _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFramebuffer(buffer)");
          return;
       }
 
-      if (!newFb) {
+      if (!newDrawFb) {
 	 /* create new framebuffer object */
-	 newFb = ctx->Driver.NewFramebuffer(ctx, framebuffer);
-	 if (!newFb) {
+	 newDrawFb = ctx->Driver.NewFramebuffer(ctx, framebuffer);
+	 if (!newDrawFb) {
 	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT");
 	    return;
 	 }
-         _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newFb);
+         _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newDrawFb);
       }
-      newFbread = newFb;
+      newReadFb = newDrawFb;
    }
    else {
       /* Binding the window system framebuffer (which was originally set
        * with MakeCurrent).
        */
-      newFb = ctx->WinSysDrawBuffer;
-      newFbread = ctx->WinSysReadBuffer;
+      newDrawFb = ctx->WinSysDrawBuffer;
+      newReadFb = ctx->WinSysReadBuffer;
    }
 
-   ASSERT(newFb);
-   ASSERT(newFb != &DummyFramebuffer);
+   ASSERT(newDrawFb);
+   ASSERT(newDrawFb != &DummyFramebuffer);
+
+   /* save pointers to current/old framebuffers */
+   oldDrawFb = ctx->DrawBuffer;
+   oldReadFb = ctx->ReadBuffer;
+
+   /* check if really changing bindings */
+   if (oldDrawFb == newDrawFb)
+      bindDrawBuf = GL_FALSE;
+   if (oldReadFb == newReadFb)
+      bindReadBuf = GL_FALSE;
 
    /*
     * OK, now bind the new Draw/Read framebuffers, if they're changing.
+    *
+    * We also check if we're beginning and/or ending render-to-texture.
+    * When a framebuffer with texture attachments is unbound, call
+    * ctx->Driver.FinishRenderTexture().
+    * When a framebuffer with texture attachments is bound, call
+    * ctx->Driver.RenderTexture().
+    *
+    * Note that if the ReadBuffer has texture attachments we don't consider
+    * that a render-to-texture case.
     */
    if (bindReadBuf) {
-      if (ctx->ReadBuffer == newFbread) {
-         bindReadBuf = GL_FALSE; /* no change */
-      }
-      else {
-         FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-         _mesa_reference_framebuffer(&ctx->ReadBuffer, newFbread);
-      }
+      FLUSH_VERTICES(ctx, _NEW_BUFFERS);
+
+      /* check if old readbuffer was render-to-texture */
+      check_end_texture_render(ctx, oldReadFb);
+
+      _mesa_reference_framebuffer(&ctx->ReadBuffer, newReadFb);
    }
 
    if (bindDrawBuf) {
-      /* check if old FB had any texture attachments */
-      if (ctx->DrawBuffer->Name != 0) {
-         check_end_texture_render(ctx, ctx->DrawBuffer);
-      }
+      FLUSH_VERTICES(ctx, _NEW_BUFFERS);
 
-      if (ctx->DrawBuffer == newFb) {
-         bindDrawBuf = GL_FALSE; /* no change */
-      }
-      else {
-         FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-         _mesa_reference_framebuffer(&ctx->DrawBuffer, newFb);
-      }
+      /* check if old read/draw buffers were render-to-texture */
+      if (!bindReadBuf)
+         check_end_texture_render(ctx, oldReadFb);
 
-      if (newFb->Name != 0) {
-         /* check if newly bound framebuffer has any texture attachments */
-         check_begin_texture_render(ctx, newFb);
-      }
+      if (oldDrawFb != oldReadFb)
+         check_end_texture_render(ctx, oldDrawFb);
+
+      /* check if newly bound framebuffer has any texture attachments */
+      check_begin_texture_render(ctx, newDrawFb);
+
+      _mesa_reference_framebuffer(&ctx->DrawBuffer, newDrawFb);
    }
 
    if ((bindDrawBuf || bindReadBuf) && ctx->Driver.BindFramebuffer) {
-      ctx->Driver.BindFramebuffer(ctx, target, newFb, newFbread);
+      ctx->Driver.BindFramebuffer(ctx, target, newDrawFb, newReadFb);
    }
 }
 
@@ -1911,7 +1942,6 @@
 void GLAPIENTRY
 _mesa_GenerateMipmapEXT(GLenum target)
 {
-   struct gl_texture_unit *texUnit;
    struct gl_texture_object *texObj;
    GET_CURRENT_CONTEXT(ctx);
 
@@ -1930,8 +1960,12 @@
       return;
    }
 
-   texUnit = _mesa_get_current_tex_unit(ctx);
-   texObj = _mesa_select_tex_object(ctx, texUnit, target);
+   texObj = _mesa_get_current_tex_object(ctx, target);
+
+   if (texObj->BaseLevel >= texObj->MaxLevel) {
+      /* nothing to do */
+      return;
+   }
 
    _mesa_lock_texture(ctx, texObj);
    if (target == GL_TEXTURE_CUBE_MAP) {
diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c
index 356476e..2d1db29 100644
--- a/src/mesa/main/ffvertex_prog.c
+++ b/src/mesa/main/ffvertex_prog.c
@@ -357,7 +357,7 @@
    int bit = _mesa_ffs( ~p->temp_in_use );
    if (!bit) {
       _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__);
-      _mesa_exit(1);
+      exit(1);
    }
 
    if ((GLuint) bit > p->program->Base.NumTemporaries)
@@ -438,7 +438,7 @@
  */
 static struct ureg register_output( struct tnl_program *p, GLuint output )
 {
-   p->program->Base.OutputsWritten |= (1<<output);
+   p->program->Base.OutputsWritten |= BITFIELD64_BIT(output);
    return make_ureg(PROGRAM_OUTPUT, output);
 }
 
@@ -523,7 +523,6 @@
    dst->CondMask = COND_TR;  /* always pass cond test */
    dst->CondSwizzle = SWIZZLE_NOOP;
    dst->CondSrc = 0;
-   dst->pad = 0;
    /* Check that bitfield sizes aren't exceeded */
    ASSERT(dst->Index == reg.idx);
 }
diff --git a/src/mesa/main/fog.c b/src/mesa/main/fog.c
index 4323d3d..269ff3f 100644
--- a/src/mesa/main/fog.c
+++ b/src/mesa/main/fog.c
@@ -34,15 +34,20 @@
 void GLAPIENTRY
 _mesa_Fogf(GLenum pname, GLfloat param)
 {
-   _mesa_Fogfv(pname, &param);
+   GLfloat fparam[4];
+   fparam[0] = param;
+   fparam[1] = fparam[2] = fparam[3] = 0.0F;
+   _mesa_Fogfv(pname, fparam);
 }
 
 
 void GLAPIENTRY
 _mesa_Fogi(GLenum pname, GLint param )
 {
-   GLfloat fparam = (GLfloat) param;
-   _mesa_Fogfv(pname, &fparam);
+   GLfloat fparam[4];
+   fparam[0] = (GLfloat) param;
+   fparam[1] = fparam[2] = fparam[3] = 0.0F;
+   _mesa_Fogfv(pname, fparam);
 }
 
 
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
index 7d0e2d2..5983f00 100644
--- a/src/mesa/main/formats.c
+++ b/src/mesa/main/formats.c
@@ -133,6 +133,15 @@
       1, 1, 4                      /* BlockWidth/Height,Bytes */
    },
    {
+      MESA_FORMAT_XRGB8888_REV,    /* Name */
+      "MESA_FORMAT_XRGB8888_REV",  /* StrName */
+      GL_RGB,                      /* BaseFormat */
+      GL_UNSIGNED_NORMALIZED,      /* DataType */
+      8, 8, 8, 0,                  /* Red/Green/Blue/AlphaBits */
+      0, 0, 0, 0, 0,               /* Lum/Int/Index/Depth/StencilBits */
+      1, 1, 4                      /* BlockWidth/Height,Bytes */
+   },
+   {
       MESA_FORMAT_RGB888,          /* Name */
       "MESA_FORMAT_RGB888",        /* StrName */
       GL_RGB,                      /* BaseFormat */
@@ -232,6 +241,24 @@
       1, 1, 2                      /* BlockWidth/Height,Bytes */
    },
    {
+      MESA_FORMAT_AL1616,          /* Name */
+      "MESA_FORMAT_AL1616",        /* StrName */
+      GL_LUMINANCE_ALPHA,          /* BaseFormat */
+      GL_UNSIGNED_NORMALIZED,      /* DataType */
+      0, 0, 0, 16,                 /* Red/Green/Blue/AlphaBits */
+      16, 0, 0, 0, 0,              /* Lum/Int/Index/Depth/StencilBits */
+      1, 1, 4                      /* BlockWidth/Height,Bytes */
+   },
+   {
+      MESA_FORMAT_AL1616_REV,      /* Name */
+      "MESA_FORMAT_AL1616_REV",    /* StrName */
+      GL_LUMINANCE_ALPHA,          /* BaseFormat */
+      GL_UNSIGNED_NORMALIZED,      /* DataType */
+      0, 0, 0, 16,                 /* Red/Green/Blue/AlphaBits */
+      16, 0, 0, 0, 0,              /* Lum/Int/Index/Depth/StencilBits */
+      1, 1, 4                      /* BlockWidth/Height,Bytes */
+   },
+   {
       MESA_FORMAT_RGB332,          /* Name */
       "MESA_FORMAT_RGB332",        /* StrName */
       GL_RGB,                      /* BaseFormat */
@@ -883,6 +910,7 @@
             GLuint t = info->RedBits + info->GreenBits
                + info->BlueBits + info->AlphaBits;
             assert(t / 8 == info->BytesPerBlock);
+            (void) t;
          }
       }
 
@@ -974,6 +1002,13 @@
       *datatype = GL_UNSIGNED_BYTE;
       *comps = 2;
       return;
+
+   case MESA_FORMAT_AL1616:
+   case MESA_FORMAT_AL1616_REV:
+      *datatype = GL_UNSIGNED_SHORT;
+      *comps = 2;
+      return;
+
    case MESA_FORMAT_RGB332:
       *datatype = GL_UNSIGNED_BYTE_3_3_2;
       *comps = 3;
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
index fa6359f..0eeeb8b 100644
--- a/src/mesa/main/formats.h
+++ b/src/mesa/main/formats.h
@@ -55,6 +55,7 @@
    MESA_FORMAT_ARGB8888,	/* AAAA AAAA RRRR RRRR GGGG GGGG BBBB BBBB */
    MESA_FORMAT_ARGB8888_REV,	/* BBBB BBBB GGGG GGGG RRRR RRRR AAAA AAAA */
    MESA_FORMAT_XRGB8888,	/* xxxx xxxx RRRR RRRR GGGG GGGG BBBB BBBB */
+   MESA_FORMAT_XRGB8888_REV,	/* BBBB BBBB GGGG GGGG RRRR RRRR xxxx xxxx */
    MESA_FORMAT_RGB888,		/*           RRRR RRRR GGGG GGGG BBBB BBBB */
    MESA_FORMAT_BGR888,		/*           BBBB BBBB GGGG GGGG RRRR RRRR */
    MESA_FORMAT_RGB565,		/*                     RRRR RGGG GGGB BBBB */
@@ -66,6 +67,8 @@
    MESA_FORMAT_ARGB1555_REV,	/*                     GGGB BBBB ARRR RRGG */
    MESA_FORMAT_AL88,		/*                     AAAA AAAA LLLL LLLL */
    MESA_FORMAT_AL88_REV,	/*                     LLLL LLLL AAAA AAAA */
+   MESA_FORMAT_AL1616,          /* AAAA AAAA AAAA AAAA LLLL LLLL LLLL LLLL */
+   MESA_FORMAT_AL1616_REV,      /* LLLL LLLL LLLL LLLL AAAA AAAA AAAA AAAA */
    MESA_FORMAT_RGB332,		/*                               RRRG GGBB */
    MESA_FORMAT_A8,		/*                               AAAA AAAA */
    MESA_FORMAT_L8,		/*                               LLLL LLLL */
@@ -137,7 +140,7 @@
    MESA_FORMAT_SIGNED_RGBA_16,
    /*@}*/
 
-   MESA_FORMAT_COUNT,
+   MESA_FORMAT_COUNT
 } gl_format;
 
 
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index 154deda..d958dbf 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -969,3 +969,29 @@
    /* OK */
    return GL_TRUE;
 }
+
+GLenum
+_mesa_get_color_read_format(GLcontext *ctx)
+{
+   switch (ctx->ReadBuffer->_ColorReadBuffer->Format) {
+   case MESA_FORMAT_ARGB8888:
+      return GL_BGRA;
+   case MESA_FORMAT_RGB565:
+      return GL_BGR;
+   default:
+      return GL_RGBA;
+   }
+}
+
+GLenum
+_mesa_get_color_read_type(GLcontext *ctx)
+{
+   switch (ctx->ReadBuffer->_ColorReadBuffer->Format) {
+   case MESA_FORMAT_ARGB8888:
+      return GL_UNSIGNED_BYTE;
+   case MESA_FORMAT_RGB565:
+      return GL_UNSIGNED_SHORT_5_6_5_REV;
+   default:
+      return GL_UNSIGNED_BYTE;
+   }
+}
diff --git a/src/mesa/main/framebuffer.h b/src/mesa/main/framebuffer.h
index 45a4703..ef21dd9 100644
--- a/src/mesa/main/framebuffer.h
+++ b/src/mesa/main/framebuffer.h
@@ -81,5 +81,10 @@
 extern GLboolean
 _mesa_dest_buffer_exists(GLcontext *ctx, GLenum format);
 
+extern GLenum
+_mesa_get_color_read_type(GLcontext *ctx);
+
+extern GLenum
+_mesa_get_color_read_format(GLcontext *ctx);
 
 #endif /* FRAMEBUFFER_H */
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 6c5ce02..22cf75f 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -13,6 +13,7 @@
 #include "mtypes.h"
 #include "state.h"
 #include "texcompress.h"
+#include "framebuffer.h"
 
 
 #define FLOAT_TO_BOOLEAN(X)   ( (X) ? GL_TRUE : GL_FALSE )
@@ -131,7 +132,7 @@
          params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.numAuxBuffers);
          break;
       case GL_BLEND:
-         params[0] = ctx->Color.BlendEnabled;
+         params[0] = (ctx->Color.BlendEnabled & 1);
          break;
       case GL_BLEND_DST:
          params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendDstRGB);
@@ -209,10 +210,10 @@
          params[0] = ENUM_TO_BOOLEAN(ctx->Light.ColorMaterialMode);
          break;
       case GL_COLOR_WRITEMASK:
-         params[0] = INT_TO_BOOLEAN(ctx->Color.ColorMask[RCOMP] ? 1 : 0);
-         params[1] = INT_TO_BOOLEAN(ctx->Color.ColorMask[GCOMP] ? 1 : 0);
-         params[2] = INT_TO_BOOLEAN(ctx->Color.ColorMask[BCOMP] ? 1 : 0);
-         params[3] = INT_TO_BOOLEAN(ctx->Color.ColorMask[ACOMP] ? 1 : 0);
+         params[0] = INT_TO_BOOLEAN(ctx->Color.ColorMask[0][RCOMP] ? 1 : 0);
+         params[1] = INT_TO_BOOLEAN(ctx->Color.ColorMask[0][GCOMP] ? 1 : 0);
+         params[2] = INT_TO_BOOLEAN(ctx->Color.ColorMask[0][BCOMP] ? 1 : 0);
+         params[3] = INT_TO_BOOLEAN(ctx->Color.ColorMask[0][ACOMP] ? 1 : 0);
          break;
       case GL_CULL_FACE:
          params[0] = ctx->Polygon.CullFlag;
@@ -1767,11 +1768,11 @@
          break;
       case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
          CHECK_EXT1(OES_read_format, "GetBooleanv");
-         params[0] = INT_TO_BOOLEAN(ctx->Const.ColorReadType);
+         params[0] = INT_TO_BOOLEAN(_mesa_get_color_read_type(ctx));
          break;
       case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
          CHECK_EXT1(OES_read_format, "GetBooleanv");
-         params[0] = INT_TO_BOOLEAN(ctx->Const.ColorReadFormat);
+         params[0] = INT_TO_BOOLEAN(_mesa_get_color_read_format(ctx));
          break;
       case GL_NUM_FRAGMENT_REGISTERS_ATI:
          CHECK_EXT1(ATI_fragment_shader, "GetBooleanv");
@@ -1876,7 +1877,7 @@
          break;
       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB:
          CHECK_EXT1(ARB_vertex_shader, "GetBooleanv");
-         params[0] = INT_TO_BOOLEAN(MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+         params[0] = INT_TO_BOOLEAN(ctx->Const.MaxCombinedTextureImageUnits);
          break;
       case GL_CURRENT_PROGRAM:
          CHECK_EXT1(ARB_shader_objects, "GetBooleanv");
@@ -1898,6 +1899,15 @@
          CHECK_EXT1(ARB_sync, "GetBooleanv");
          params[0] = INT64_TO_BOOLEAN(ctx->Const.MaxServerWaitTimeout);
          break;
+      case GL_NUM_EXTENSIONS:
+         params[0] = INT_TO_BOOLEAN(_mesa_get_extension_count(ctx));
+         break;
+      case GL_MAJOR_VERSION:
+         params[0] = INT_TO_BOOLEAN(ctx->VersionMajor);
+         break;
+      case GL_MINOR_VERSION:
+         params[0] = INT_TO_BOOLEAN(ctx->VersionMinor);
+         break;
       default:
          _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv(pname=0x%x)", pname);
    }
@@ -1966,7 +1976,7 @@
          params[0] = (GLfloat)(ctx->DrawBuffer->Visual.numAuxBuffers);
          break;
       case GL_BLEND:
-         params[0] = BOOLEAN_TO_FLOAT(ctx->Color.BlendEnabled);
+         params[0] = BOOLEAN_TO_FLOAT((ctx->Color.BlendEnabled & 1));
          break;
       case GL_BLEND_DST:
          params[0] = ENUM_TO_FLOAT(ctx->Color.BlendDstRGB);
@@ -2044,10 +2054,10 @@
          params[0] = ENUM_TO_FLOAT(ctx->Light.ColorMaterialMode);
          break;
       case GL_COLOR_WRITEMASK:
-         params[0] = (GLfloat)(ctx->Color.ColorMask[RCOMP] ? 1 : 0);
-         params[1] = (GLfloat)(ctx->Color.ColorMask[GCOMP] ? 1 : 0);
-         params[2] = (GLfloat)(ctx->Color.ColorMask[BCOMP] ? 1 : 0);
-         params[3] = (GLfloat)(ctx->Color.ColorMask[ACOMP] ? 1 : 0);
+         params[0] = (GLfloat)(ctx->Color.ColorMask[0][RCOMP] ? 1 : 0);
+         params[1] = (GLfloat)(ctx->Color.ColorMask[0][GCOMP] ? 1 : 0);
+         params[2] = (GLfloat)(ctx->Color.ColorMask[0][BCOMP] ? 1 : 0);
+         params[3] = (GLfloat)(ctx->Color.ColorMask[0][ACOMP] ? 1 : 0);
          break;
       case GL_CULL_FACE:
          params[0] = BOOLEAN_TO_FLOAT(ctx->Polygon.CullFlag);
@@ -3602,11 +3612,11 @@
          break;
       case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
          CHECK_EXT1(OES_read_format, "GetFloatv");
-         params[0] = (GLfloat)(ctx->Const.ColorReadType);
+         params[0] = (GLfloat)(_mesa_get_color_read_type(ctx));
          break;
       case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
          CHECK_EXT1(OES_read_format, "GetFloatv");
-         params[0] = (GLfloat)(ctx->Const.ColorReadFormat);
+         params[0] = (GLfloat)(_mesa_get_color_read_format(ctx));
          break;
       case GL_NUM_FRAGMENT_REGISTERS_ATI:
          CHECK_EXT1(ATI_fragment_shader, "GetFloatv");
@@ -3711,7 +3721,7 @@
          break;
       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB:
          CHECK_EXT1(ARB_vertex_shader, "GetFloatv");
-         params[0] = (GLfloat)(MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+         params[0] = (GLfloat)(ctx->Const.MaxCombinedTextureImageUnits);
          break;
       case GL_CURRENT_PROGRAM:
          CHECK_EXT1(ARB_shader_objects, "GetFloatv");
@@ -3733,6 +3743,15 @@
          CHECK_EXT1(ARB_sync, "GetFloatv");
          params[0] = (GLfloat)(ctx->Const.MaxServerWaitTimeout);
          break;
+      case GL_NUM_EXTENSIONS:
+         params[0] = (GLfloat)(_mesa_get_extension_count(ctx));
+         break;
+      case GL_MAJOR_VERSION:
+         params[0] = (GLfloat)(ctx->VersionMajor);
+         break;
+      case GL_MINOR_VERSION:
+         params[0] = (GLfloat)(ctx->VersionMinor);
+         break;
       default:
          _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv(pname=0x%x)", pname);
    }
@@ -3801,7 +3820,7 @@
          params[0] = ctx->DrawBuffer->Visual.numAuxBuffers;
          break;
       case GL_BLEND:
-         params[0] = BOOLEAN_TO_INT(ctx->Color.BlendEnabled);
+         params[0] = BOOLEAN_TO_INT((ctx->Color.BlendEnabled & 1));
          break;
       case GL_BLEND_DST:
          params[0] = ENUM_TO_INT(ctx->Color.BlendDstRGB);
@@ -3879,10 +3898,10 @@
          params[0] = ENUM_TO_INT(ctx->Light.ColorMaterialMode);
          break;
       case GL_COLOR_WRITEMASK:
-         params[0] = ctx->Color.ColorMask[RCOMP] ? 1 : 0;
-         params[1] = ctx->Color.ColorMask[GCOMP] ? 1 : 0;
-         params[2] = ctx->Color.ColorMask[BCOMP] ? 1 : 0;
-         params[3] = ctx->Color.ColorMask[ACOMP] ? 1 : 0;
+         params[0] = ctx->Color.ColorMask[0][RCOMP] ? 1 : 0;
+         params[1] = ctx->Color.ColorMask[0][GCOMP] ? 1 : 0;
+         params[2] = ctx->Color.ColorMask[0][BCOMP] ? 1 : 0;
+         params[3] = ctx->Color.ColorMask[0][ACOMP] ? 1 : 0;
          break;
       case GL_CULL_FACE:
          params[0] = BOOLEAN_TO_INT(ctx->Polygon.CullFlag);
@@ -5437,11 +5456,11 @@
          break;
       case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
          CHECK_EXT1(OES_read_format, "GetIntegerv");
-         params[0] = ctx->Const.ColorReadType;
+         params[0] = _mesa_get_color_read_type(ctx);
          break;
       case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
          CHECK_EXT1(OES_read_format, "GetIntegerv");
-         params[0] = ctx->Const.ColorReadFormat;
+         params[0] = _mesa_get_color_read_format(ctx);
          break;
       case GL_NUM_FRAGMENT_REGISTERS_ATI:
          CHECK_EXT1(ATI_fragment_shader, "GetIntegerv");
@@ -5546,7 +5565,7 @@
          break;
       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB:
          CHECK_EXT1(ARB_vertex_shader, "GetIntegerv");
-         params[0] = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
+         params[0] = ctx->Const.MaxCombinedTextureImageUnits;
          break;
       case GL_CURRENT_PROGRAM:
          CHECK_EXT1(ARB_shader_objects, "GetIntegerv");
@@ -5568,6 +5587,15 @@
          CHECK_EXT1(ARB_sync, "GetIntegerv");
          params[0] = INT64_TO_INT(ctx->Const.MaxServerWaitTimeout);
          break;
+      case GL_NUM_EXTENSIONS:
+         params[0] = _mesa_get_extension_count(ctx);
+         break;
+      case GL_MAJOR_VERSION:
+         params[0] = ctx->VersionMajor;
+         break;
+      case GL_MINOR_VERSION:
+         params[0] = ctx->VersionMinor;
+         break;
       default:
          _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv(pname=0x%x)", pname);
    }
@@ -5637,7 +5665,7 @@
          params[0] = (GLint64)(ctx->DrawBuffer->Visual.numAuxBuffers);
          break;
       case GL_BLEND:
-         params[0] = BOOLEAN_TO_INT64(ctx->Color.BlendEnabled);
+         params[0] = BOOLEAN_TO_INT64((ctx->Color.BlendEnabled & 1));
          break;
       case GL_BLEND_DST:
          params[0] = ENUM_TO_INT64(ctx->Color.BlendDstRGB);
@@ -5715,10 +5743,10 @@
          params[0] = ENUM_TO_INT64(ctx->Light.ColorMaterialMode);
          break;
       case GL_COLOR_WRITEMASK:
-         params[0] = (GLint64)(ctx->Color.ColorMask[RCOMP] ? 1 : 0);
-         params[1] = (GLint64)(ctx->Color.ColorMask[GCOMP] ? 1 : 0);
-         params[2] = (GLint64)(ctx->Color.ColorMask[BCOMP] ? 1 : 0);
-         params[3] = (GLint64)(ctx->Color.ColorMask[ACOMP] ? 1 : 0);
+         params[0] = (GLint64)(ctx->Color.ColorMask[0][RCOMP] ? 1 : 0);
+         params[1] = (GLint64)(ctx->Color.ColorMask[0][GCOMP] ? 1 : 0);
+         params[2] = (GLint64)(ctx->Color.ColorMask[0][BCOMP] ? 1 : 0);
+         params[3] = (GLint64)(ctx->Color.ColorMask[0][ACOMP] ? 1 : 0);
          break;
       case GL_CULL_FACE:
          params[0] = BOOLEAN_TO_INT64(ctx->Polygon.CullFlag);
@@ -7273,11 +7301,11 @@
          break;
       case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
          CHECK_EXT1(OES_read_format, "GetInteger64v");
-         params[0] = (GLint64)(ctx->Const.ColorReadType);
+         params[0] = (GLint64)(_mesa_get_color_read_type(ctx));
          break;
       case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
          CHECK_EXT1(OES_read_format, "GetInteger64v");
-         params[0] = (GLint64)(ctx->Const.ColorReadFormat);
+         params[0] = (GLint64)(_mesa_get_color_read_format(ctx));
          break;
       case GL_NUM_FRAGMENT_REGISTERS_ATI:
          CHECK_EXT1(ATI_fragment_shader, "GetInteger64v");
@@ -7382,7 +7410,7 @@
          break;
       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB:
          CHECK_EXT1(ARB_vertex_shader, "GetInteger64v");
-         params[0] = (GLint64)(MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+         params[0] = (GLint64)(ctx->Const.MaxCombinedTextureImageUnits);
          break;
       case GL_CURRENT_PROGRAM:
          CHECK_EXT1(ARB_shader_objects, "GetInteger64v");
@@ -7404,6 +7432,15 @@
          CHECK_EXT1(ARB_sync, "GetInteger64v");
          params[0] = ctx->Const.MaxServerWaitTimeout;
          break;
+      case GL_NUM_EXTENSIONS:
+         params[0] = (GLint64)(_mesa_get_extension_count(ctx));
+         break;
+      case GL_MAJOR_VERSION:
+         params[0] = (GLint64)(ctx->VersionMajor);
+         break;
+      case GL_MINOR_VERSION:
+         params[0] = (GLint64)(ctx->VersionMinor);
+         break;
       default:
          _mesa_error(ctx, GL_INVALID_ENUM, "glGetInteger64v(pname=0x%x)", pname);
    }
@@ -7433,3 +7470,110 @@
       params[i] = (GLdouble) values[i];
 }
 
+void GLAPIENTRY
+_mesa_GetBooleanIndexedv( GLenum pname, GLuint index, GLboolean *params )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (!params)
+      return;
+
+   if (ctx->NewState)
+      _mesa_update_state(ctx);
+
+   switch (pname) {
+      case GL_BLEND:
+         CHECK_EXT1(EXT_draw_buffers2, "GetBooleanIndexedv");
+         if (index >= ctx->Const.MaxDrawBuffers) {
+            _mesa_error(ctx, GL_INVALID_VALUE, "glGetBooleanIndexedv(index=%u), index", pname);
+         }
+         params[0] = INT_TO_BOOLEAN(((ctx->Color.BlendEnabled >> index) & 1));
+         break;
+      case GL_COLOR_WRITEMASK:
+         CHECK_EXT1(EXT_draw_buffers2, "GetBooleanIndexedv");
+         if (index >= ctx->Const.MaxDrawBuffers) {
+            _mesa_error(ctx, GL_INVALID_VALUE, "glGetBooleanIndexedv(index=%u), index", pname);
+         }
+         params[0] = INT_TO_BOOLEAN(ctx->Color.ColorMask[index][RCOMP] ? 1 : 0);
+         params[1] = INT_TO_BOOLEAN(ctx->Color.ColorMask[index][GCOMP] ? 1 : 0);
+         params[2] = INT_TO_BOOLEAN(ctx->Color.ColorMask[index][BCOMP] ? 1 : 0);
+         params[3] = INT_TO_BOOLEAN(ctx->Color.ColorMask[index][ACOMP] ? 1 : 0);
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanIndexedv(pname=0x%x)", pname);
+   }
+}
+
+void GLAPIENTRY
+_mesa_GetIntegerIndexedv( GLenum pname, GLuint index, GLint *params )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (!params)
+      return;
+
+   if (ctx->NewState)
+      _mesa_update_state(ctx);
+
+   switch (pname) {
+      case GL_BLEND:
+         CHECK_EXT1(EXT_draw_buffers2, "GetIntegerIndexedv");
+         if (index >= ctx->Const.MaxDrawBuffers) {
+            _mesa_error(ctx, GL_INVALID_VALUE, "glGetIntegerIndexedv(index=%u), index", pname);
+         }
+         params[0] = ((ctx->Color.BlendEnabled >> index) & 1);
+         break;
+      case GL_COLOR_WRITEMASK:
+         CHECK_EXT1(EXT_draw_buffers2, "GetIntegerIndexedv");
+         if (index >= ctx->Const.MaxDrawBuffers) {
+            _mesa_error(ctx, GL_INVALID_VALUE, "glGetIntegerIndexedv(index=%u), index", pname);
+         }
+         params[0] = ctx->Color.ColorMask[index][RCOMP] ? 1 : 0;
+         params[1] = ctx->Color.ColorMask[index][GCOMP] ? 1 : 0;
+         params[2] = ctx->Color.ColorMask[index][BCOMP] ? 1 : 0;
+         params[3] = ctx->Color.ColorMask[index][ACOMP] ? 1 : 0;
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerIndexedv(pname=0x%x)", pname);
+   }
+}
+
+#if FEATURE_ARB_sync
+void GLAPIENTRY
+_mesa_GetInteger64Indexedv( GLenum pname, GLuint index, GLint64 *params )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (!params)
+      return;
+
+   if (ctx->NewState)
+      _mesa_update_state(ctx);
+
+   switch (pname) {
+      case GL_BLEND:
+         CHECK_EXT1(EXT_draw_buffers2, "GetInteger64Indexedv");
+         if (index >= ctx->Const.MaxDrawBuffers) {
+            _mesa_error(ctx, GL_INVALID_VALUE, "glGetInteger64Indexedv(index=%u), index", pname);
+         }
+         params[0] = (GLint64)(((ctx->Color.BlendEnabled >> index) & 1));
+         break;
+      case GL_COLOR_WRITEMASK:
+         CHECK_EXT1(EXT_draw_buffers2, "GetInteger64Indexedv");
+         if (index >= ctx->Const.MaxDrawBuffers) {
+            _mesa_error(ctx, GL_INVALID_VALUE, "glGetInteger64Indexedv(index=%u), index", pname);
+         }
+         params[0] = (GLint64)(ctx->Color.ColorMask[index][RCOMP] ? 1 : 0);
+         params[1] = (GLint64)(ctx->Color.ColorMask[index][GCOMP] ? 1 : 0);
+         params[2] = (GLint64)(ctx->Color.ColorMask[index][BCOMP] ? 1 : 0);
+         params[3] = (GLint64)(ctx->Color.ColorMask[index][ACOMP] ? 1 : 0);
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetInteger64Indexedv(pname=0x%x)", pname);
+   }
+}
+#endif /* FEATURE_ARB_sync */
+
diff --git a/src/mesa/main/get.h b/src/mesa/main/get.h
index 77a9a7d..cc426fc 100644
--- a/src/mesa/main/get.h
+++ b/src/mesa/main/get.h
@@ -51,11 +51,23 @@
 _mesa_GetInteger64v( GLenum pname, GLint64 *params );
 
 extern void GLAPIENTRY
+_mesa_GetBooleanIndexedv( GLenum pname, GLuint index, GLboolean *params );
+
+extern void GLAPIENTRY
+_mesa_GetIntegerIndexedv( GLenum pname, GLuint index, GLint *params );
+
+extern void GLAPIENTRY
+_mesa_GetInteger64Indexedv( GLenum pname, GLuint index, GLint64 *params );
+
+extern void GLAPIENTRY
 _mesa_GetPointerv( GLenum pname, GLvoid **params );
 
 extern const GLubyte * GLAPIENTRY
 _mesa_GetString( GLenum name );
 
+extern const GLubyte * GLAPIENTRY
+_mesa_GetStringi(GLenum name, GLuint index);
+
 extern GLenum GLAPIENTRY
 _mesa_GetError( void );
 
diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py
index 930c336..b0beb59 100644
--- a/src/mesa/main/get_gen.py
+++ b/src/mesa/main/get_gen.py
@@ -82,7 +82,7 @@
 	( "GL_AUTO_NORMAL", GLboolean, ["ctx->Eval.AutoNormal"], "", None ),
 	( "GL_AUX_BUFFERS", GLint, ["ctx->DrawBuffer->Visual.numAuxBuffers"],
 	  "", None ),
-	( "GL_BLEND", GLboolean, ["ctx->Color.BlendEnabled"], "", None ),
+	( "GL_BLEND", GLboolean, ["(ctx->Color.BlendEnabled & 1)"], "", None ),
 	( "GL_BLEND_DST", GLenum, ["ctx->Color.BlendDstRGB"], "", None ),
 	( "GL_BLEND_SRC", GLenum, ["ctx->Color.BlendSrcRGB"], "", None ),
 	( "GL_BLEND_SRC_RGB_EXT", GLenum, ["ctx->Color.BlendSrcRGB"], "", None ),
@@ -126,10 +126,10 @@
 	( "GL_COLOR_MATERIAL_PARAMETER", GLenum,
 	  ["ctx->Light.ColorMaterialMode"], "", None ),
 	( "GL_COLOR_WRITEMASK", GLint,
-	  [ "ctx->Color.ColorMask[RCOMP] ? 1 : 0",
-		"ctx->Color.ColorMask[GCOMP] ? 1 : 0",
-		"ctx->Color.ColorMask[BCOMP] ? 1 : 0",
-		"ctx->Color.ColorMask[ACOMP] ? 1 : 0" ], "", None ),
+	  [ "ctx->Color.ColorMask[0][RCOMP] ? 1 : 0",
+		"ctx->Color.ColorMask[0][GCOMP] ? 1 : 0",
+		"ctx->Color.ColorMask[0][BCOMP] ? 1 : 0",
+		"ctx->Color.ColorMask[0][ACOMP] ? 1 : 0" ], "", None ),
 	( "GL_CULL_FACE", GLboolean, ["ctx->Polygon.CullFlag"], "", None ),
 	( "GL_CULL_FACE_MODE", GLenum, ["ctx->Polygon.CullFaceMode"], "", None ),
 	( "GL_CURRENT_COLOR", GLfloatN,
@@ -942,9 +942,9 @@
 
 	# GL_OES_read_format
 	( "GL_IMPLEMENTATION_COLOR_READ_TYPE_OES", GLint,
-	  ["ctx->Const.ColorReadType"], "", ["OES_read_format"] ),
+	  ["_mesa_get_color_read_type(ctx)"], "", ["OES_read_format"] ),
 	( "GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES", GLint,
-	  ["ctx->Const.ColorReadFormat"], "", ["OES_read_format"] ),
+	  ["_mesa_get_color_read_format(ctx)"], "", ["OES_read_format"] ),
 
 	# GL_ATI_fragment_shader
 	( "GL_NUM_FRAGMENT_REGISTERS_ATI", GLint, ["6"], "", ["ATI_fragment_shader"] ),
@@ -1006,7 +1006,7 @@
 	( "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB", GLint,
 	  ["ctx->Const.MaxVertexTextureImageUnits"], "", ["ARB_vertex_shader"] ),
 	( "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB", GLint,
-	  ["MAX_COMBINED_TEXTURE_IMAGE_UNITS"], "", ["ARB_vertex_shader"] ),
+	  ["ctx->Const.MaxCombinedTextureImageUnits"], "", ["ARB_vertex_shader"] ),
 
 	# GL_ARB_shader_objects
 	# Actually, this token isn't part of GL_ARB_shader_objects, but is
@@ -1030,9 +1030,29 @@
 	# GL_ARB_sync
 	( "GL_MAX_SERVER_WAIT_TIMEOUT", GLint64, ["ctx->Const.MaxServerWaitTimeout"], "",
 	  ["ARB_sync"] ),
+
+	# GL3
+	( "GL_NUM_EXTENSIONS", GLint, ["_mesa_get_extension_count(ctx)"], "", None ),
+	( "GL_MAJOR_VERSION", GLint, ["ctx->VersionMajor"], "", None ),
+	( "GL_MINOR_VERSION", GLint, ["ctx->VersionMinor"], "", None )
 ]
 
 
+# These are queried via glGetIntegetIndexdvEXT() or glGetIntegeri_v()
+IndexedStateVars = [
+	( "GL_BLEND", GLint, ["((ctx->Color.BlendEnabled >> index) & 1)"],
+	  "ctx->Const.MaxDrawBuffers", ["EXT_draw_buffers2"] ),
+	( "GL_COLOR_WRITEMASK", GLint,
+	  [ "ctx->Color.ColorMask[index][RCOMP] ? 1 : 0",
+		"ctx->Color.ColorMask[index][GCOMP] ? 1 : 0",
+		"ctx->Color.ColorMask[index][BCOMP] ? 1 : 0",
+		"ctx->Color.ColorMask[index][ACOMP] ? 1 : 0" ],
+	  "ctx->Const.MaxDrawBuffers", ["EXT_draw_buffers2"] ),
+	# XXX more to come...
+]
+
+
+
 def ConversionFunc(fromType, toType):
 	"""Return the name of the macro to convert between two data types."""
 	if fromType == toType:
@@ -1059,7 +1079,7 @@
 		return fromStr + "_TO_" + toStr
 
 
-def EmitGetFunction(stateVars, returnType):
+def EmitGetFunction(stateVars, returnType, indexed):
 	"""Emit the code to implement glGetBooleanv, glGetIntegerv or glGetFloatv."""
 	assert (returnType == GLboolean or
 			returnType == GLint or
@@ -1068,22 +1088,35 @@
 
 	strType = TypeStrings[returnType]
 	# Capitalize first letter of return type
-	if returnType == GLint:
-		function = "GetIntegerv"
-	elif returnType == GLboolean:
-		function = "GetBooleanv"
-	elif returnType == GLfloat:
-		function = "GetFloatv"
-	elif returnType == GLint64:
-		function = "GetInteger64v"
+	if indexed:
+		if returnType == GLint:
+			function = "GetIntegerIndexedv"
+		elif returnType == GLboolean:
+			function = "GetBooleanIndexedv"
+		elif returnType == GLint64:
+			function = "GetInteger64Indexedv"
+		else:
+			function = "Foo"
 	else:
-		abort()
+		if returnType == GLint:
+			function = "GetIntegerv"
+		elif returnType == GLboolean:
+			function = "GetBooleanv"
+		elif returnType == GLfloat:
+			function = "GetFloatv"
+		elif returnType == GLint64:
+			function = "GetInteger64v"
+		else:
+			abort()
 
 	if returnType == GLint64:
 		print "#if FEATURE_ARB_sync"
 
 	print "void GLAPIENTRY"
-	print "_mesa_%s( GLenum pname, %s *params )" % (function, strType)
+	if indexed:
+		print "_mesa_%s( GLenum pname, GLuint index, %s *params )" % (function, strType)
+	else:
+		print "_mesa_%s( GLenum pname, %s *params )" % (function, strType)
 	print "{"
 	print "   GET_CURRENT_CONTEXT(ctx);"
 	print "   ASSERT_OUTSIDE_BEGIN_END(ctx);"
@@ -1094,13 +1127,20 @@
 	print "   if (ctx->NewState)"
 	print "      _mesa_update_state(ctx);"
 	print ""
-	print "   if (ctx->Driver.%s &&" % function
-	print "       ctx->Driver.%s(ctx, pname, params))" % function
-	print "      return;"
-	print ""
+	if indexed == 0:
+		print "   if (ctx->Driver.%s &&" % function
+		print "       ctx->Driver.%s(ctx, pname, params))" % function
+		print "      return;"
+		print ""
 	print "   switch (pname) {"
 
-	for (name, varType, state, optionalCode, extensions) in stateVars:
+	for state in stateVars:
+		if indexed:
+			(name, varType, state, indexMax, extensions) = state
+			optionalCode = 0
+		else:
+			(name, varType, state, optionalCode, extensions) = state
+			indexMax = 0
 		print "      case " + name + ":"
 		if extensions:
 			if len(extensions) == 1:
@@ -1116,6 +1156,11 @@
 				assert len(extensions) == 4
 				print ('         CHECK_EXT4(%s, %s, %s, %s, "%s");' %
 					   (extensions[0], extensions[1], extensions[2], extensions[3], function))
+		if indexMax:
+			print ('         if (index >= %s) {' % indexMax)
+			print ('            _mesa_error(ctx, GL_INVALID_VALUE, "gl%s(index=%%u), index", pname);' % function)
+			print ('         }')
+
 		conversion = ConversionFunc(varType, returnType)
 		if optionalCode:
 			optionalCode = string.replace(optionalCode, "CONVERSION", conversion);	
@@ -1159,6 +1204,7 @@
 #include "mtypes.h"
 #include "state.h"
 #include "texcompress.h"
+#include "framebuffer.h"
 
 
 #define FLOAT_TO_BOOLEAN(X)   ( (X) ? GL_TRUE : GL_FALSE )
@@ -1248,9 +1294,13 @@
 
 EmitHeader()
 # XXX Maybe sort the StateVars list
-EmitGetFunction(StateVars, GLboolean)
-EmitGetFunction(StateVars, GLfloat)
-EmitGetFunction(StateVars, GLint)
-EmitGetFunction(StateVars, GLint64)
+EmitGetFunction(StateVars, GLboolean, 0)
+EmitGetFunction(StateVars, GLfloat, 0)
+EmitGetFunction(StateVars, GLint, 0)
+EmitGetFunction(StateVars, GLint64, 0)
 EmitGetDoublev()
 
+EmitGetFunction(IndexedStateVars, GLboolean, 1)
+EmitGetFunction(IndexedStateVars, GLint, 1)
+EmitGetFunction(IndexedStateVars, GLint64, 1)
+
diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c
index 4b1f4b0..c203b04 100644
--- a/src/mesa/main/getstring.c
+++ b/src/mesa/main/getstring.c
@@ -33,85 +33,6 @@
 
 
 /**
- * Examine enabled GL extensions to determine GL version.
- * \return version string
- */
-static const char *
-compute_version(const GLcontext *ctx)
-{
-   static const char *version_1_2 = "1.2 Mesa " MESA_VERSION_STRING;
-   static const char *version_1_3 = "1.3 Mesa " MESA_VERSION_STRING;
-   static const char *version_1_4 = "1.4 Mesa " MESA_VERSION_STRING;
-   static const char *version_1_5 = "1.5 Mesa " MESA_VERSION_STRING;
-   static const char *version_2_0 = "2.0 Mesa " MESA_VERSION_STRING;
-   static const char *version_2_1 = "2.1 Mesa " MESA_VERSION_STRING;
-
-   const GLboolean ver_1_3 = (ctx->Extensions.ARB_multisample &&
-                              ctx->Extensions.ARB_multitexture &&
-                              ctx->Extensions.ARB_texture_border_clamp &&
-                              ctx->Extensions.ARB_texture_compression &&
-                              ctx->Extensions.ARB_texture_cube_map &&
-                              ctx->Extensions.EXT_texture_env_add &&
-                              ctx->Extensions.ARB_texture_env_combine &&
-                              ctx->Extensions.ARB_texture_env_dot3);
-   const GLboolean ver_1_4 = (ver_1_3 &&
-                              ctx->Extensions.ARB_depth_texture &&
-                              ctx->Extensions.ARB_shadow &&
-                              ctx->Extensions.ARB_texture_env_crossbar &&
-                              ctx->Extensions.ARB_texture_mirrored_repeat &&
-                              ctx->Extensions.ARB_window_pos &&
-                              ctx->Extensions.EXT_blend_color &&
-                              ctx->Extensions.EXT_blend_func_separate &&
-                              ctx->Extensions.EXT_blend_minmax &&
-                              ctx->Extensions.EXT_blend_subtract &&
-                              ctx->Extensions.EXT_fog_coord &&
-                              ctx->Extensions.EXT_multi_draw_arrays &&
-                              ctx->Extensions.EXT_point_parameters &&
-                              ctx->Extensions.EXT_secondary_color &&
-                              ctx->Extensions.EXT_stencil_wrap &&
-                              ctx->Extensions.EXT_texture_lod_bias &&
-                              ctx->Extensions.SGIS_generate_mipmap);
-   const GLboolean ver_1_5 = (ver_1_4 &&
-                              ctx->Extensions.ARB_occlusion_query &&
-                              ctx->Extensions.ARB_vertex_buffer_object &&
-                              ctx->Extensions.EXT_shadow_funcs);
-   const GLboolean ver_2_0 = (ver_1_5 &&
-                              ctx->Extensions.ARB_draw_buffers &&
-                              ctx->Extensions.ARB_point_sprite &&
-                              ctx->Extensions.ARB_shader_objects &&
-                              ctx->Extensions.ARB_vertex_shader &&
-                              ctx->Extensions.ARB_fragment_shader &&
-                              ctx->Extensions.ARB_texture_non_power_of_two &&
-                              ctx->Extensions.EXT_blend_equation_separate &&
-
-			      /* Technically, 2.0 requires the functionality
-			       * of the EXT version.  Enable 2.0 if either
-			       * extension is available, and assume that a
-			       * driver that only exposes the ATI extension
-			       * will fallback to software when necessary.
-			       */
-			      (ctx->Extensions.EXT_stencil_two_side
-			       || ctx->Extensions.ATI_separate_stencil));
-   const GLboolean ver_2_1 = (ver_2_0 &&
-                              ctx->Extensions.ARB_shading_language_120 &&
-                              ctx->Extensions.EXT_pixel_buffer_object &&
-                              ctx->Extensions.EXT_texture_sRGB);
-   if (ver_2_1)
-      return version_2_1;
-   if (ver_2_0)
-      return version_2_0;
-   if (ver_1_5)
-      return version_1_5;
-   if (ver_1_4)
-      return version_1_4;
-   if (ver_1_3)
-      return version_1_3;
-   return version_1_2;
-}
-
-
-
-/**
  * Query string-valued state.  The return value should _not_ be freed by
  * the caller.
  *
@@ -149,7 +70,7 @@
       case GL_RENDERER:
          return (const GLubyte *) renderer;
       case GL_VERSION:
-         return (const GLubyte *) compute_version(ctx);
+         return (const GLubyte *) ctx->VersionString;
       case GL_EXTENSIONS:
          if (!ctx->Extensions.String)
             ctx->Extensions.String = _mesa_make_extension_string(ctx);
@@ -184,6 +105,34 @@
 
 
 /**
+ * GL3
+ */
+const GLubyte * GLAPIENTRY
+_mesa_GetStringi(GLenum name, GLuint index)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (!ctx)
+      return NULL;
+
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL);
+
+   switch (name) {
+   case GL_EXTENSIONS:
+      if (index >= _mesa_get_extension_count(ctx)) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glGetStringi(index=%u)", index);
+         return (const GLubyte *) 0;
+      }
+      return _mesa_get_enabled_extension(ctx, index);
+   default:
+      _mesa_error( ctx, GL_INVALID_ENUM, "glGetString" );
+      return (const GLubyte *) 0;
+   }
+}
+
+
+
+/**
  * Return pointer-valued state, such as a vertex array pointer.
  *
  * \param pname  names state to be queried
diff --git a/src/mesa/main/histogram.c b/src/mesa/main/histogram.c
index dfbe910..c7304e8 100644
--- a/src/mesa/main/histogram.c
+++ b/src/mesa/main/histogram.c
@@ -190,7 +190,7 @@
             /* temporarily store as GLuints */
             GLuint temp[4*HISTOGRAM_TABLE_SIZE];
             GLuint *dst = temp;
-            GLhalfARB *half = destination;
+            GLhalfARB *half = (GLhalfARB *) destination;
             GLuint i;
             /* get GLuint values */
             PACK_MACRO(GLuint);
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c
index 139e56a..fc278bb 100644
--- a/src/mesa/main/image.c
+++ b/src/mesa/main/image.c
@@ -33,6 +33,7 @@
 #include "glheader.h"
 #include "colormac.h"
 #include "context.h"
+#include "enums.h"
 #include "image.h"
 #include "imports.h"
 #include "macros.h"
@@ -3228,6 +3229,7 @@
           srcFormat == GL_RGBA ||
           srcFormat == GL_BGRA ||
           srcFormat == GL_ABGR_EXT ||
+          srcFormat == GL_DU8DV8_ATI ||
           srcFormat == GL_DUDV_ATI);
 
    ASSERT(srcType == GL_UNSIGNED_BYTE ||
@@ -3343,6 +3345,7 @@
          aComp = 0;
          stride = 4;
          break;
+      case GL_DU8DV8_ATI:
       case GL_DUDV_ATI:
          redIndex = 0;
          greenIndex = 1;
@@ -3351,7 +3354,8 @@
          stride = 2;
          break;
       default:
-         _mesa_problem(NULL, "bad srcFormat in extract float data");
+         _mesa_problem(NULL, "bad srcFormat %s in extract float data",
+                       _mesa_lookup_enum_by_nr(srcFormat));
          return;
    }
 
diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c
index 46ffb92..def0452 100644
--- a/src/mesa/main/imports.c
+++ b/src/mesa/main/imports.c
@@ -460,7 +460,7 @@
 #if 0 /* not used, see below -BP */
         float r3, x3, y3;
 #endif
-        union { float f; unsigned int i; } u;
+        fi_type u;
         unsigned int magic;
 
         /*
@@ -629,11 +629,15 @@
 unsigned int
 _mesa_bitcount(unsigned int n)
 {
+#if defined(__GNUC__)
+   return __builtin_popcount(n);
+#else
    unsigned int bits;
    for (bits = 0; n > 0; n = n >> 1) {
       bits += (n & 1);
    }
    return bits;
+#endif
 }
 
 
@@ -645,10 +649,10 @@
 GLhalfARB
 _mesa_float_to_half(float val)
 {
-   const int flt = *((int *) (void *) &val);
-   const int flt_m = flt & 0x7fffff;
-   const int flt_e = (flt >> 23) & 0xff;
-   const int flt_s = (flt >> 31) & 0x1;
+   const fi_type fi = {val};
+   const int flt_m = fi.i & 0x7fffff;
+   const int flt_e = (fi.i >> 23) & 0xff;
+   const int flt_s = (fi.i >> 31) & 0x1;
    int s, e, m = 0;
    GLhalfARB result;
    
@@ -735,7 +739,8 @@
    const int m = val & 0x3ff;
    const int e = (val >> 10) & 0x1f;
    const int s = (val >> 15) & 0x1;
-   int flt_m, flt_e, flt_s, flt;
+   int flt_m, flt_e, flt_s;
+   fi_type fi;
    float result;
 
    /* sign bit */
@@ -770,8 +775,8 @@
       flt_m = m << 13;
    }
 
-   flt = (flt_s << 31) | (flt_e << 23) | flt_m;
-   result = *((float *) (void *) &flt);
+   fi.i = (flt_s << 31) | (flt_e << 23) | flt_m;
+   result = fi.f;
    return result;
 }
 
@@ -1234,13 +1239,3 @@
 }
 
 /*@}*/
-
-
-/**
- * Wrapper for exit().
- */
-void
-_mesa_exit( int status )
-{
-   exit(status);
-}
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index 7d4012a..b01fe5b 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -618,10 +618,6 @@
 extern void
 _mesa_debug( const __GLcontext *ctx, const char *fmtString, ... );
 
-extern void 
-_mesa_exit( int status );
-
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c
index 1c8a081..654faa5 100644
--- a/src/mesa/main/light.c
+++ b/src/mesa/main/light.c
@@ -206,7 +206,10 @@
 void GLAPIENTRY
 _mesa_Lightf( GLenum light, GLenum pname, GLfloat param )
 {
-   _mesa_Lightfv( light, pname, &param );
+   GLfloat fparam[4];
+   fparam[0] = param;
+   fparam[1] = fparam[2] = fparam[3] = 0.0F;
+   _mesa_Lightfv( light, pname, fparam );
 }
 
 
@@ -285,7 +288,10 @@
 void GLAPIENTRY
 _mesa_Lighti( GLenum light, GLenum pname, GLint param )
 {
-   _mesa_Lightiv( light, pname, &param );
+   GLint iparam[4];
+   iparam[0] = param;
+   iparam[1] = iparam[2] = iparam[3] = 0;
+   _mesa_Lightiv( light, pname, iparam );
 }
 
 
@@ -537,14 +543,20 @@
 void GLAPIENTRY
 _mesa_LightModeli( GLenum pname, GLint param )
 {
-   _mesa_LightModeliv( pname, &param );
+   GLint iparam[4];
+   iparam[0] = param;
+   iparam[1] = iparam[2] = iparam[3] = 0;
+   _mesa_LightModeliv( pname, iparam );
 }
 
 
 void GLAPIENTRY
 _mesa_LightModelf( GLenum pname, GLfloat param )
 {
-   _mesa_LightModelfv( pname, &param );
+   GLfloat fparam[4];
+   fparam[0] = param;
+   fparam[1] = fparam[2] = fparam[3] = 0.0F;
+   _mesa_LightModelfv( pname, fparam );
 }
 
 
diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h
index 3d9a1ab..55578ad 100644
--- a/src/mesa/main/macros.h
+++ b/src/mesa/main/macros.h
@@ -202,17 +202,12 @@
 #endif
 
 /**
- * Copy a 4-element float vector (avoid using FPU registers)
- * XXX Could use two 64-bit moves on 64-bit systems
+ * Copy a 4-element float vector
+ * memcpy seems to be most efficient
  */
 #define COPY_4FV( DST, SRC )                  \
 do {                                          \
-   const GLuint *_s = (const GLuint *) (SRC); \
-   GLuint *_d = (GLuint *) (DST);             \
-   _d[0] = _s[0];                             \
-   _d[1] = _s[1];                             \
-   _d[2] = _s[2];                             \
-   _d[3] = _s[3];                             \
+   _mesa_memcpy(DST, SRC, sizeof(GLfloat) * 4);       \
 } while (0)
 
 /** Copy \p SZ elements into a 4-element vector */
@@ -631,12 +626,6 @@
 /** Clamp X to [MIN,MAX] */
 #define CLAMP( X, MIN, MAX )  ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
 
-/** Assign X to CLAMP(X, MIN, MAX) */
-#define CLAMP_SELF(x, mn, mx)  \
-   ( (x)<(mn) ? ((x) = (mn)) : ((x)>(mx) ? ((x)=(mx)) : (x)) )
-
-
-
 /** Minimum of two values: */
 #define MIN2( A, B )   ( (A)<(B) ? (A) : (B) )
 
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index e91c7e5..7eff5ca 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -79,6 +79,31 @@
 
 
 /**
+ * \name 64-bit extension of GLbitfield.
+ */
+/*@{*/
+typedef GLuint64 GLbitfield64;
+
+#define BITFIELD64_ONE         1ULL
+#define BITFIELD64_ALLONES     ~0ULL
+
+/** Set a single bit */
+#define BITFIELD64_BIT(b)      (BITFIELD64_ONE << (b))
+
+/** Set a mask of the least significant \c b bits */
+#define BITFIELD64_MASK(b)     (((b) >= 64) ? BITFIELD64_ALLONES : \
+				(BITFIELD64_BIT(b) - 1))
+
+/**
+ * Set all bits from l (low bit) to h (high bit), inclusive.
+ *
+ * \note \C BITFIELD_64_RANGE(0, 63) return 64 set bits.
+ */
+#define BITFIELD64_RANGE(l, h) (BITFIELD64_MASK((h) + 1) & ~BITFIELD64_MASK(l))
+/*@}*/
+
+
+/**
  * \name Some forward type declarations
  */
 /*@{*/
@@ -539,7 +564,7 @@
    GLclampf ClearColor[4];		/**< Color to use for glClear */
 
    GLuint IndexMask;			/**< Color index write mask */
-   GLubyte ColorMask[4];		/**< Each flag is 0xff or 0x0 */
+   GLubyte ColorMask[MAX_DRAW_BUFFERS][4];/**< Each flag is 0xff or 0x0 */
 
    GLenum DrawBuffer[MAX_DRAW_BUFFERS];	/**< Which buffer to draw into */
 
@@ -556,7 +581,7 @@
     * \name Blending
     */
    /*@{*/
-   GLboolean BlendEnabled;		/**< Blending enabled flag */
+   GLbitfield BlendEnabled;		/**< Per-buffer blend enable flags */
    GLenum BlendSrcRGB;			/**< Blending source operator */
    GLenum BlendDstRGB;			/**< Blending destination operator */
    GLenum BlendSrcA;			/**< GL_INGR_blend_func_separate */
@@ -1192,7 +1217,11 @@
    GLuint Name;			/**< the user-visible texture object ID */
    GLenum Target;               /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */
    GLfloat Priority;		/**< in [0,1] */
-   GLfloat BorderColor[4];	/**< unclamped */
+   union {
+      GLfloat f[4];
+      GLuint ui[4];
+      GLint i[4];
+   } BorderColor;               /**< Interpreted according to texture format */
    GLenum WrapS;		/**< S-axis texture image wrap mode */
    GLenum WrapT;		/**< T-axis texture image wrap mode */
    GLenum WrapR;		/**< R-axis texture image wrap mode */
@@ -1670,7 +1699,7 @@
    struct prog_instruction *Instructions;
 
    GLbitfield InputsRead;     /**< Bitmask of which input regs are read */
-   GLbitfield OutputsWritten; /**< Bitmask of which output regs are written to */
+   GLbitfield64 OutputsWritten; /**< Bitmask of which output regs are written */
    GLbitfield InputFlags[MAX_PROGRAM_INPUTS];   /**< PROG_PARAM_BIT_x flags */
    GLbitfield OutputFlags[MAX_PROGRAM_OUTPUTS]; /**< PROG_PARAM_BIT_x flags */
    GLbitfield TexturesUsed[MAX_TEXTURE_UNITS];  /**< TEXTURE_x_BIT bitmask */
@@ -1874,6 +1903,10 @@
    struct _mesa_HashTable *QueryObjects;
    struct gl_query_object *CurrentOcclusionObject; /* GL_ARB_occlusion_query */
    struct gl_query_object *CurrentTimerObject;     /* GL_EXT_timer_query */
+
+   /** GL_NV_conditional_render */
+   struct gl_query_object *CondRenderQuery;
+   GLenum CondRenderMode;
 };
 
 
@@ -2294,6 +2327,7 @@
    GLuint MaxTextureCoordUnits;
    GLuint MaxTextureImageUnits;
    GLuint MaxVertexTextureImageUnits;
+   GLuint MaxCombinedTextureImageUnits;
    GLuint MaxTextureUnits;           /**< = MIN(CoordUnits, ImageUnits) */
    GLfloat MaxTextureMaxAnisotropy;  /**< GL_EXT_texture_filter_anisotropic */
    GLfloat MaxTextureLodBias;        /**< GL_EXT_texture_lod_bias */
@@ -2330,9 +2364,6 @@
 
    GLuint MaxDrawBuffers;    /**< GL_ARB_draw_buffers */
 
-   GLenum ColorReadFormat;   /**< GL_OES_read_format */
-   GLenum ColorReadType;     /**< GL_OES_read_format */
-
    GLuint MaxColorAttachments;   /**< GL_EXT_framebuffer_object */
    GLuint MaxRenderbufferSize;   /**< GL_EXT_framebuffer_object */
    GLuint MaxSamples;            /**< GL_ARB_framebuffer_object */
@@ -2411,10 +2442,12 @@
    GLboolean EXT_compiled_vertex_array;
    GLboolean EXT_copy_texture;
    GLboolean EXT_depth_bounds_test;
+   GLboolean EXT_draw_buffers2;
    GLboolean EXT_draw_range_elements;
-   GLboolean EXT_framebuffer_object;
    GLboolean EXT_fog_coord;
    GLboolean EXT_framebuffer_blit;
+   GLboolean EXT_framebuffer_multisample;
+   GLboolean EXT_framebuffer_object;
    GLboolean EXT_gpu_program_parameters;
    GLboolean EXT_histogram;
    GLboolean EXT_multi_draw_arrays;
@@ -2467,6 +2500,7 @@
    GLboolean MESA_texture_array;
    GLboolean MESA_texture_signed_rgba;
    GLboolean NV_blend_square;
+   GLboolean NV_conditional_render;
    GLboolean NV_fragment_program;
    GLboolean NV_fragment_program_option;
    GLboolean NV_light_max_exponent;
@@ -2490,6 +2524,8 @@
 #endif /* FEATURE_OES_draw_texture */
    /** The extension string */
    const GLubyte *String;
+   /** Number of supported extensions */
+   GLuint Count;
 };
 
 
@@ -2831,6 +2867,10 @@
    /** Extension information */
    struct gl_extensions Extensions;
 
+   /** Version info */
+   GLuint VersionMajor, VersionMinor;
+   char *VersionString;
+
    /** \name State attribute stack (for glPush/PopAttrib) */
    /*@{*/
    GLuint AttribStackDepth;
diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c
index 4c8fc1f..dcaeccd 100644
--- a/src/mesa/main/points.c
+++ b/src/mesa/main/points.c
@@ -69,8 +69,10 @@
 void GLAPIENTRY
 _mesa_PointParameteri( GLenum pname, GLint param )
 {
-   const GLfloat value = (GLfloat) param;
-   _mesa_PointParameterfv(pname, &value);
+   GLfloat p[3];
+   p[0] = (GLfloat) param;
+   p[1] = p[2] = 0.0F;
+   _mesa_PointParameterfv(pname, p);
 }
 
 
@@ -90,7 +92,10 @@
 void GLAPIENTRY
 _mesa_PointParameterf( GLenum pname, GLfloat param)
 {
-   _mesa_PointParameterfv(pname, &param);
+   GLfloat p[3];
+   p[0] = param;
+   p[1] = p[2] = 0.0F;
+   _mesa_PointParameterfv(pname, p);
 }
 
 
@@ -200,7 +205,12 @@
          }
          break;
       case GL_POINT_SPRITE_COORD_ORIGIN:
-         if (ctx->Extensions.ARB_point_sprite || ctx->Extensions.NV_point_sprite) {
+	 /* This is not completely correct.  GL_POINT_SPRITE_COORD_ORIGIN was
+	  * added to point sprites when the extension was merged into OpenGL
+	  * 2.0.  It is expected that an implementation supporting OpenGL 1.4
+	  * and GL_ARB_point_sprite will generate an error here.
+	  */
+         if (ctx->Extensions.ARB_point_sprite) {
             GLenum value = (GLenum) params[0];
             if (value != GL_LOWER_LEFT && value != GL_UPPER_LEFT) {
                _mesa_error(ctx, GL_INVALID_VALUE,
diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c
index f6eb4ee..387a82f 100644
--- a/src/mesa/main/queryobj.c
+++ b/src/mesa/main/queryobj.c
@@ -118,15 +118,6 @@
 }
 
 
-static struct gl_query_object *
-lookup_query_object(GLcontext *ctx, GLuint id)
-{
-   return (struct gl_query_object *)
-      _mesa_HashLookup(ctx->Query.QueryObjects, id);
-}
-
-
-
 void
 _mesa_init_query_object_functions(struct dd_function_table *driver)
 {
@@ -196,7 +187,7 @@
 
    for (i = 0; i < n; i++) {
       if (ids[i] > 0) {
-         struct gl_query_object *q = lookup_query_object(ctx, ids[i]);
+         struct gl_query_object *q = _mesa_lookup_query_object(ctx, ids[i]);
          if (q) {
             ASSERT(!q->Active); /* should be caught earlier */
             _mesa_HashRemove(ctx->Query.QueryObjects, ids[i]);
@@ -213,7 +204,7 @@
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
 
-   if (id && lookup_query_object(ctx, id))
+   if (id && _mesa_lookup_query_object(ctx, id))
       return GL_TRUE;
    else
       return GL_FALSE;
@@ -260,7 +251,7 @@
       return;
    }
 
-   q = lookup_query_object(ctx, id);
+   q = _mesa_lookup_query_object(ctx, id);
    if (!q) {
       /* create new object */
       q = ctx->Driver.NewQueryObject(ctx, id);
@@ -386,7 +377,7 @@
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    if (id)
-      q = lookup_query_object(ctx, id);
+      q = _mesa_lookup_query_object(ctx, id);
 
    if (!q || q->Active) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
@@ -426,7 +417,7 @@
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    if (id)
-      q = lookup_query_object(ctx, id);
+      q = _mesa_lookup_query_object(ctx, id);
 
    if (!q || q->Active) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
@@ -469,7 +460,7 @@
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    if (id)
-      q = lookup_query_object(ctx, id);
+      q = _mesa_lookup_query_object(ctx, id);
 
    if (!q || q->Active) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
@@ -506,7 +497,7 @@
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    if (id)
-      q = lookup_query_object(ctx, id);
+      q = _mesa_lookup_query_object(ctx, id);
 
    if (!q || q->Active) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
diff --git a/src/mesa/main/queryobj.h b/src/mesa/main/queryobj.h
index 6cf3c76..ba8b5dd 100644
--- a/src/mesa/main/queryobj.h
+++ b/src/mesa/main/queryobj.h
@@ -28,6 +28,7 @@
 
 
 #include "main/mtypes.h"
+#include "main/hash.h"
 
 
 #if FEATURE_queryobj
@@ -42,6 +43,15 @@
       (driver)->CheckQuery     = impl ## CheckQuery;     \
    } while (0)
 
+
+static INLINE struct gl_query_object *
+_mesa_lookup_query_object(GLcontext *ctx, GLuint id)
+{
+   return (struct gl_query_object *)
+      _mesa_HashLookup(ctx->Query.QueryObjects, id);
+}
+
+
 extern void GLAPIENTRY
 _mesa_GenQueriesARB(GLsizei n, GLuint *ids);
 
diff --git a/src/mesa/main/remap_helper.h b/src/mesa/main/remap_helper.h
index 3886f41..fe2bebd 100644
--- a/src/mesa/main/remap_helper.h
+++ b/src/mesa/main/remap_helper.h
@@ -605,3721 +605,3754 @@
    "glFogCoordd\0"
    "glFogCoorddEXT\0"
    "\0"
-   /* _mesa_function_pool[4074]: Color4ubVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[4074]: BeginConditionalRenderNV (will be remapped) */
+   "ii\0"
+   "glBeginConditionalRenderNV\0"
+   "\0"
+   /* _mesa_function_pool[4105]: Color4ubVertex3fSUN (dynamic) */
    "iiiifff\0"
    "glColor4ubVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[4105]: FogCoordfEXT (will be remapped) */
+   /* _mesa_function_pool[4136]: FogCoordfEXT (will be remapped) */
    "f\0"
    "glFogCoordf\0"
    "glFogCoordfEXT\0"
    "\0"
-   /* _mesa_function_pool[4135]: PointSize (offset 173) */
+   /* _mesa_function_pool[4166]: PointSize (offset 173) */
    "f\0"
    "glPointSize\0"
    "\0"
-   /* _mesa_function_pool[4150]: TexCoord2fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[4181]: TexCoord2fVertex3fSUN (dynamic) */
    "fffff\0"
    "glTexCoord2fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[4181]: PopName (offset 200) */
+   /* _mesa_function_pool[4212]: PopName (offset 200) */
    "\0"
    "glPopName\0"
    "\0"
-   /* _mesa_function_pool[4193]: GlobalAlphaFactoriSUN (dynamic) */
+   /* _mesa_function_pool[4224]: GlobalAlphaFactoriSUN (dynamic) */
    "i\0"
    "glGlobalAlphaFactoriSUN\0"
    "\0"
-   /* _mesa_function_pool[4220]: VertexAttrib2dNV (will be remapped) */
+   /* _mesa_function_pool[4251]: VertexAttrib2dNV (will be remapped) */
    "idd\0"
    "glVertexAttrib2dNV\0"
    "\0"
-   /* _mesa_function_pool[4244]: GetProgramInfoLog (will be remapped) */
+   /* _mesa_function_pool[4275]: GetProgramInfoLog (will be remapped) */
    "iipp\0"
    "glGetProgramInfoLog\0"
    "\0"
-   /* _mesa_function_pool[4270]: VertexAttrib4NbvARB (will be remapped) */
+   /* _mesa_function_pool[4301]: VertexAttrib4NbvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4Nbv\0"
    "glVertexAttrib4NbvARB\0"
    "\0"
-   /* _mesa_function_pool[4315]: GetActiveAttribARB (will be remapped) */
+   /* _mesa_function_pool[4346]: GetActiveAttribARB (will be remapped) */
    "iiipppp\0"
    "glGetActiveAttrib\0"
    "glGetActiveAttribARB\0"
    "\0"
-   /* _mesa_function_pool[4363]: Vertex4sv (offset 149) */
+   /* _mesa_function_pool[4394]: Vertex4sv (offset 149) */
    "p\0"
    "glVertex4sv\0"
    "\0"
-   /* _mesa_function_pool[4378]: VertexAttrib4ubNV (will be remapped) */
+   /* _mesa_function_pool[4409]: VertexAttrib4ubNV (will be remapped) */
    "iiiii\0"
    "glVertexAttrib4ubNV\0"
    "\0"
-   /* _mesa_function_pool[4405]: TextureRangeAPPLE (will be remapped) */
+   /* _mesa_function_pool[4436]: TextureRangeAPPLE (will be remapped) */
    "iip\0"
    "glTextureRangeAPPLE\0"
    "\0"
-   /* _mesa_function_pool[4430]: GetTexEnvfv (offset 276) */
+   /* _mesa_function_pool[4461]: GetTexEnvfv (offset 276) */
    "iip\0"
    "glGetTexEnvfv\0"
    "\0"
-   /* _mesa_function_pool[4449]: TexCoord2fColor4fNormal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[4480]: TexCoord2fColor4fNormal3fVertex3fSUN (dynamic) */
    "ffffffffffff\0"
    "glTexCoord2fColor4fNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[4502]: Indexub (offset 315) */
+   /* _mesa_function_pool[4533]: Indexub (offset 315) */
    "i\0"
    "glIndexub\0"
    "\0"
-   /* _mesa_function_pool[4515]: TexEnvi (offset 186) */
+   /* _mesa_function_pool[4546]: TexEnvi (offset 186) */
    "iii\0"
    "glTexEnvi\0"
    "\0"
-   /* _mesa_function_pool[4530]: GetClipPlane (offset 259) */
+   /* _mesa_function_pool[4561]: GetClipPlane (offset 259) */
    "ip\0"
    "glGetClipPlane\0"
    "\0"
-   /* _mesa_function_pool[4549]: CombinerParameterfvNV (will be remapped) */
+   /* _mesa_function_pool[4580]: CombinerParameterfvNV (will be remapped) */
    "ip\0"
    "glCombinerParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[4577]: VertexAttribs3dvNV (will be remapped) */
+   /* _mesa_function_pool[4608]: VertexAttribs3dvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs3dvNV\0"
    "\0"
-   /* _mesa_function_pool[4603]: VertexAttribs4fvNV (will be remapped) */
+   /* _mesa_function_pool[4634]: VertexAttribs4fvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs4fvNV\0"
    "\0"
-   /* _mesa_function_pool[4629]: VertexArrayRangeNV (will be remapped) */
+   /* _mesa_function_pool[4660]: VertexArrayRangeNV (will be remapped) */
    "ip\0"
    "glVertexArrayRangeNV\0"
    "\0"
-   /* _mesa_function_pool[4654]: FragmentLightiSGIX (dynamic) */
+   /* _mesa_function_pool[4685]: FragmentLightiSGIX (dynamic) */
    "iii\0"
    "glFragmentLightiSGIX\0"
    "\0"
-   /* _mesa_function_pool[4680]: PolygonOffsetEXT (will be remapped) */
+   /* _mesa_function_pool[4711]: PolygonOffsetEXT (will be remapped) */
    "ff\0"
    "glPolygonOffsetEXT\0"
    "\0"
-   /* _mesa_function_pool[4703]: PollAsyncSGIX (dynamic) */
+   /* _mesa_function_pool[4734]: PollAsyncSGIX (dynamic) */
    "p\0"
    "glPollAsyncSGIX\0"
    "\0"
-   /* _mesa_function_pool[4722]: DeleteFragmentShaderATI (will be remapped) */
+   /* _mesa_function_pool[4753]: DeleteFragmentShaderATI (will be remapped) */
    "i\0"
    "glDeleteFragmentShaderATI\0"
    "\0"
-   /* _mesa_function_pool[4751]: Scaled (offset 301) */
+   /* _mesa_function_pool[4782]: Scaled (offset 301) */
    "ddd\0"
    "glScaled\0"
    "\0"
-   /* _mesa_function_pool[4765]: Scalef (offset 302) */
+   /* _mesa_function_pool[4796]: Scalef (offset 302) */
    "fff\0"
    "glScalef\0"
    "\0"
-   /* _mesa_function_pool[4779]: TexCoord2fNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[4810]: TexCoord2fNormal3fVertex3fvSUN (dynamic) */
    "ppp\0"
    "glTexCoord2fNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[4817]: MultTransposeMatrixdARB (will be remapped) */
+   /* _mesa_function_pool[4848]: MultTransposeMatrixdARB (will be remapped) */
    "p\0"
    "glMultTransposeMatrixd\0"
    "glMultTransposeMatrixdARB\0"
    "\0"
-   /* _mesa_function_pool[4869]: AlphaFunc (offset 240) */
+   /* _mesa_function_pool[4900]: AlphaFunc (offset 240) */
    "if\0"
    "glAlphaFunc\0"
    "\0"
-   /* _mesa_function_pool[4885]: WindowPos2svMESA (will be remapped) */
+   /* _mesa_function_pool[4916]: WindowPos2svMESA (will be remapped) */
    "p\0"
    "glWindowPos2sv\0"
    "glWindowPos2svARB\0"
    "glWindowPos2svMESA\0"
    "\0"
-   /* _mesa_function_pool[4940]: EdgeFlag (offset 41) */
+   /* _mesa_function_pool[4971]: EdgeFlag (offset 41) */
    "i\0"
    "glEdgeFlag\0"
    "\0"
-   /* _mesa_function_pool[4954]: TexCoord2iv (offset 107) */
+   /* _mesa_function_pool[4985]: TexCoord2iv (offset 107) */
    "p\0"
    "glTexCoord2iv\0"
    "\0"
-   /* _mesa_function_pool[4971]: CompressedTexImage1DARB (will be remapped) */
+   /* _mesa_function_pool[5002]: CompressedTexImage1DARB (will be remapped) */
    "iiiiiip\0"
    "glCompressedTexImage1D\0"
    "glCompressedTexImage1DARB\0"
    "\0"
-   /* _mesa_function_pool[5029]: Rotated (offset 299) */
+   /* _mesa_function_pool[5060]: Rotated (offset 299) */
    "dddd\0"
    "glRotated\0"
    "\0"
-   /* _mesa_function_pool[5045]: VertexAttrib2sNV (will be remapped) */
+   /* _mesa_function_pool[5076]: VertexAttrib2sNV (will be remapped) */
    "iii\0"
    "glVertexAttrib2sNV\0"
    "\0"
-   /* _mesa_function_pool[5069]: ReadPixels (offset 256) */
+   /* _mesa_function_pool[5100]: ReadPixels (offset 256) */
    "iiiiiip\0"
    "glReadPixels\0"
    "\0"
-   /* _mesa_function_pool[5091]: EdgeFlagv (offset 42) */
+   /* _mesa_function_pool[5122]: EdgeFlagv (offset 42) */
    "p\0"
    "glEdgeFlagv\0"
    "\0"
-   /* _mesa_function_pool[5106]: NormalPointerListIBM (dynamic) */
+   /* _mesa_function_pool[5137]: NormalPointerListIBM (dynamic) */
    "iipi\0"
    "glNormalPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[5135]: IndexPointerEXT (will be remapped) */
+   /* _mesa_function_pool[5166]: IndexPointerEXT (will be remapped) */
    "iiip\0"
    "glIndexPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[5159]: Color4iv (offset 32) */
+   /* _mesa_function_pool[5190]: Color4iv (offset 32) */
    "p\0"
    "glColor4iv\0"
    "\0"
-   /* _mesa_function_pool[5173]: TexParameterf (offset 178) */
+   /* _mesa_function_pool[5204]: TexParameterf (offset 178) */
    "iif\0"
    "glTexParameterf\0"
    "\0"
-   /* _mesa_function_pool[5194]: TexParameteri (offset 180) */
+   /* _mesa_function_pool[5225]: TexParameteri (offset 180) */
    "iii\0"
    "glTexParameteri\0"
    "\0"
-   /* _mesa_function_pool[5215]: NormalPointerEXT (will be remapped) */
+   /* _mesa_function_pool[5246]: NormalPointerEXT (will be remapped) */
    "iiip\0"
    "glNormalPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[5240]: MultiTexCoord3dARB (offset 392) */
+   /* _mesa_function_pool[5271]: MultiTexCoord3dARB (offset 392) */
    "iddd\0"
    "glMultiTexCoord3d\0"
    "glMultiTexCoord3dARB\0"
    "\0"
-   /* _mesa_function_pool[5285]: MultiTexCoord2iARB (offset 388) */
+   /* _mesa_function_pool[5316]: MultiTexCoord2iARB (offset 388) */
    "iii\0"
    "glMultiTexCoord2i\0"
    "glMultiTexCoord2iARB\0"
    "\0"
-   /* _mesa_function_pool[5329]: DrawPixels (offset 257) */
+   /* _mesa_function_pool[5360]: DrawPixels (offset 257) */
    "iiiip\0"
    "glDrawPixels\0"
    "\0"
-   /* _mesa_function_pool[5349]: ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[5380]: ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (dynamic) */
    "iffffffff\0"
    "glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[5409]: MultiTexCoord2svARB (offset 391) */
+   /* _mesa_function_pool[5440]: MultiTexCoord2svARB (offset 391) */
    "ip\0"
    "glMultiTexCoord2sv\0"
    "glMultiTexCoord2svARB\0"
    "\0"
-   /* _mesa_function_pool[5454]: ReplacementCodeubvSUN (dynamic) */
+   /* _mesa_function_pool[5485]: ReplacementCodeubvSUN (dynamic) */
    "p\0"
    "glReplacementCodeubvSUN\0"
    "\0"
-   /* _mesa_function_pool[5481]: Uniform3iARB (will be remapped) */
+   /* _mesa_function_pool[5512]: Uniform3iARB (will be remapped) */
    "iiii\0"
    "glUniform3i\0"
    "glUniform3iARB\0"
    "\0"
-   /* _mesa_function_pool[5514]: GetFragmentMaterialfvSGIX (dynamic) */
+   /* _mesa_function_pool[5545]: GetFragmentMaterialfvSGIX (dynamic) */
    "iip\0"
    "glGetFragmentMaterialfvSGIX\0"
    "\0"
-   /* _mesa_function_pool[5547]: GetShaderInfoLog (will be remapped) */
+   /* _mesa_function_pool[5578]: GetShaderInfoLog (will be remapped) */
    "iipp\0"
    "glGetShaderInfoLog\0"
    "\0"
-   /* _mesa_function_pool[5572]: WeightivARB (dynamic) */
+   /* _mesa_function_pool[5603]: WeightivARB (dynamic) */
    "ip\0"
    "glWeightivARB\0"
    "\0"
-   /* _mesa_function_pool[5590]: PollInstrumentsSGIX (dynamic) */
+   /* _mesa_function_pool[5621]: PollInstrumentsSGIX (dynamic) */
    "p\0"
    "glPollInstrumentsSGIX\0"
    "\0"
-   /* _mesa_function_pool[5615]: GlobalAlphaFactordSUN (dynamic) */
+   /* _mesa_function_pool[5646]: GlobalAlphaFactordSUN (dynamic) */
    "d\0"
    "glGlobalAlphaFactordSUN\0"
    "\0"
-   /* _mesa_function_pool[5642]: GetFinalCombinerInputParameterfvNV (will be remapped) */
+   /* _mesa_function_pool[5673]: GetFinalCombinerInputParameterfvNV (will be remapped) */
    "iip\0"
    "glGetFinalCombinerInputParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[5684]: GenerateMipmapEXT (will be remapped) */
+   /* _mesa_function_pool[5715]: GenerateMipmapEXT (will be remapped) */
    "i\0"
    "glGenerateMipmap\0"
    "glGenerateMipmapEXT\0"
    "\0"
-   /* _mesa_function_pool[5724]: GenLists (offset 5) */
+   /* _mesa_function_pool[5755]: GenLists (offset 5) */
    "i\0"
    "glGenLists\0"
    "\0"
-   /* _mesa_function_pool[5738]: SetFragmentShaderConstantATI (will be remapped) */
+   /* _mesa_function_pool[5769]: SetFragmentShaderConstantATI (will be remapped) */
    "ip\0"
    "glSetFragmentShaderConstantATI\0"
    "\0"
-   /* _mesa_function_pool[5773]: GetMapAttribParameterivNV (dynamic) */
+   /* _mesa_function_pool[5804]: GetMapAttribParameterivNV (dynamic) */
    "iiip\0"
    "glGetMapAttribParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[5807]: CreateShaderObjectARB (will be remapped) */
+   /* _mesa_function_pool[5838]: CreateShaderObjectARB (will be remapped) */
    "i\0"
    "glCreateShaderObjectARB\0"
    "\0"
-   /* _mesa_function_pool[5834]: GetSharpenTexFuncSGIS (dynamic) */
+   /* _mesa_function_pool[5865]: GetSharpenTexFuncSGIS (dynamic) */
    "ip\0"
    "glGetSharpenTexFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[5862]: BufferDataARB (will be remapped) */
+   /* _mesa_function_pool[5893]: BufferDataARB (will be remapped) */
    "iipi\0"
    "glBufferData\0"
    "glBufferDataARB\0"
    "\0"
-   /* _mesa_function_pool[5897]: FlushVertexArrayRangeNV (will be remapped) */
+   /* _mesa_function_pool[5928]: FlushVertexArrayRangeNV (will be remapped) */
    "\0"
    "glFlushVertexArrayRangeNV\0"
    "\0"
-   /* _mesa_function_pool[5925]: MapGrid2d (offset 226) */
+   /* _mesa_function_pool[5956]: MapGrid2d (offset 226) */
    "iddidd\0"
    "glMapGrid2d\0"
    "\0"
-   /* _mesa_function_pool[5945]: MapGrid2f (offset 227) */
+   /* _mesa_function_pool[5976]: MapGrid2f (offset 227) */
    "iffiff\0"
    "glMapGrid2f\0"
    "\0"
-   /* _mesa_function_pool[5965]: SampleMapATI (will be remapped) */
+   /* _mesa_function_pool[5996]: SampleMapATI (will be remapped) */
    "iii\0"
    "glSampleMapATI\0"
    "\0"
-   /* _mesa_function_pool[5985]: VertexPointerEXT (will be remapped) */
+   /* _mesa_function_pool[6016]: VertexPointerEXT (will be remapped) */
    "iiiip\0"
    "glVertexPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[6011]: GetTexFilterFuncSGIS (dynamic) */
+   /* _mesa_function_pool[6042]: GetTexFilterFuncSGIS (dynamic) */
    "iip\0"
    "glGetTexFilterFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[6039]: Scissor (offset 176) */
+   /* _mesa_function_pool[6070]: Scissor (offset 176) */
    "iiii\0"
    "glScissor\0"
    "\0"
-   /* _mesa_function_pool[6055]: Fogf (offset 153) */
+   /* _mesa_function_pool[6086]: Fogf (offset 153) */
    "if\0"
    "glFogf\0"
    "\0"
-   /* _mesa_function_pool[6066]: GetCombinerOutputParameterfvNV (will be remapped) */
+   /* _mesa_function_pool[6097]: GetCombinerOutputParameterfvNV (will be remapped) */
    "iiip\0"
    "glGetCombinerOutputParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[6105]: TexSubImage1D (offset 332) */
+   /* _mesa_function_pool[6136]: TexSubImage1D (offset 332) */
    "iiiiiip\0"
    "glTexSubImage1D\0"
    "glTexSubImage1DEXT\0"
    "\0"
-   /* _mesa_function_pool[6149]: VertexAttrib1sARB (will be remapped) */
+   /* _mesa_function_pool[6180]: VertexAttrib1sARB (will be remapped) */
    "ii\0"
    "glVertexAttrib1s\0"
    "glVertexAttrib1sARB\0"
    "\0"
-   /* _mesa_function_pool[6190]: FenceSync (will be remapped) */
+   /* _mesa_function_pool[6221]: FenceSync (will be remapped) */
    "ii\0"
    "glFenceSync\0"
    "\0"
-   /* _mesa_function_pool[6206]: Color4usv (offset 40) */
+   /* _mesa_function_pool[6237]: Color4usv (offset 40) */
    "p\0"
    "glColor4usv\0"
    "\0"
-   /* _mesa_function_pool[6221]: Fogi (offset 155) */
+   /* _mesa_function_pool[6252]: Fogi (offset 155) */
    "ii\0"
    "glFogi\0"
    "\0"
-   /* _mesa_function_pool[6232]: DepthRange (offset 288) */
+   /* _mesa_function_pool[6263]: DepthRange (offset 288) */
    "dd\0"
    "glDepthRange\0"
    "\0"
-   /* _mesa_function_pool[6249]: RasterPos3iv (offset 75) */
+   /* _mesa_function_pool[6280]: RasterPos3iv (offset 75) */
    "p\0"
    "glRasterPos3iv\0"
    "\0"
-   /* _mesa_function_pool[6267]: FinalCombinerInputNV (will be remapped) */
+   /* _mesa_function_pool[6298]: FinalCombinerInputNV (will be remapped) */
    "iiii\0"
    "glFinalCombinerInputNV\0"
    "\0"
-   /* _mesa_function_pool[6296]: TexCoord2i (offset 106) */
+   /* _mesa_function_pool[6327]: TexCoord2i (offset 106) */
    "ii\0"
    "glTexCoord2i\0"
    "\0"
-   /* _mesa_function_pool[6313]: PixelMapfv (offset 251) */
+   /* _mesa_function_pool[6344]: PixelMapfv (offset 251) */
    "iip\0"
    "glPixelMapfv\0"
    "\0"
-   /* _mesa_function_pool[6331]: Color4ui (offset 37) */
+   /* _mesa_function_pool[6362]: Color4ui (offset 37) */
    "iiii\0"
    "glColor4ui\0"
    "\0"
-   /* _mesa_function_pool[6348]: RasterPos3s (offset 76) */
+   /* _mesa_function_pool[6379]: RasterPos3s (offset 76) */
    "iii\0"
    "glRasterPos3s\0"
    "\0"
-   /* _mesa_function_pool[6367]: Color3usv (offset 24) */
+   /* _mesa_function_pool[6398]: Color3usv (offset 24) */
    "p\0"
    "glColor3usv\0"
    "\0"
-   /* _mesa_function_pool[6382]: FlushRasterSGIX (dynamic) */
+   /* _mesa_function_pool[6413]: FlushRasterSGIX (dynamic) */
    "\0"
    "glFlushRasterSGIX\0"
    "\0"
-   /* _mesa_function_pool[6402]: TexCoord2f (offset 104) */
+   /* _mesa_function_pool[6433]: TexCoord2f (offset 104) */
    "ff\0"
    "glTexCoord2f\0"
    "\0"
-   /* _mesa_function_pool[6419]: ReplacementCodeuiTexCoord2fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[6450]: ReplacementCodeuiTexCoord2fVertex3fSUN (dynamic) */
    "ifffff\0"
    "glReplacementCodeuiTexCoord2fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[6468]: TexCoord2d (offset 102) */
+   /* _mesa_function_pool[6499]: TexCoord2d (offset 102) */
    "dd\0"
    "glTexCoord2d\0"
    "\0"
-   /* _mesa_function_pool[6485]: RasterPos3d (offset 70) */
+   /* _mesa_function_pool[6516]: RasterPos3d (offset 70) */
    "ddd\0"
    "glRasterPos3d\0"
    "\0"
-   /* _mesa_function_pool[6504]: RasterPos3f (offset 72) */
+   /* _mesa_function_pool[6535]: RasterPos3f (offset 72) */
    "fff\0"
    "glRasterPos3f\0"
    "\0"
-   /* _mesa_function_pool[6523]: Uniform1fARB (will be remapped) */
+   /* _mesa_function_pool[6554]: Uniform1fARB (will be remapped) */
    "if\0"
    "glUniform1f\0"
    "glUniform1fARB\0"
    "\0"
-   /* _mesa_function_pool[6554]: AreTexturesResident (offset 322) */
+   /* _mesa_function_pool[6585]: AreTexturesResident (offset 322) */
    "ipp\0"
    "glAreTexturesResident\0"
    "glAreTexturesResidentEXT\0"
    "\0"
-   /* _mesa_function_pool[6606]: TexCoord2s (offset 108) */
+   /* _mesa_function_pool[6637]: TexCoord2s (offset 108) */
    "ii\0"
    "glTexCoord2s\0"
    "\0"
-   /* _mesa_function_pool[6623]: StencilOpSeparate (will be remapped) */
+   /* _mesa_function_pool[6654]: StencilOpSeparate (will be remapped) */
    "iiii\0"
    "glStencilOpSeparate\0"
    "glStencilOpSeparateATI\0"
    "\0"
-   /* _mesa_function_pool[6672]: ColorTableParameteriv (offset 341) */
+   /* _mesa_function_pool[6703]: ColorTableParameteriv (offset 341) */
    "iip\0"
    "glColorTableParameteriv\0"
    "glColorTableParameterivSGI\0"
    "\0"
-   /* _mesa_function_pool[6728]: FogCoordPointerListIBM (dynamic) */
+   /* _mesa_function_pool[6759]: FogCoordPointerListIBM (dynamic) */
    "iipi\0"
    "glFogCoordPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[6759]: WindowPos3dMESA (will be remapped) */
+   /* _mesa_function_pool[6790]: WindowPos3dMESA (will be remapped) */
    "ddd\0"
    "glWindowPos3d\0"
    "glWindowPos3dARB\0"
    "glWindowPos3dMESA\0"
    "\0"
-   /* _mesa_function_pool[6813]: Color4us (offset 39) */
+   /* _mesa_function_pool[6844]: Color4us (offset 39) */
    "iiii\0"
    "glColor4us\0"
    "\0"
-   /* _mesa_function_pool[6830]: PointParameterfvEXT (will be remapped) */
+   /* _mesa_function_pool[6861]: PointParameterfvEXT (will be remapped) */
    "ip\0"
    "glPointParameterfv\0"
    "glPointParameterfvARB\0"
    "glPointParameterfvEXT\0"
    "glPointParameterfvSGIS\0"
    "\0"
-   /* _mesa_function_pool[6920]: Color3bv (offset 10) */
+   /* _mesa_function_pool[6951]: Color3bv (offset 10) */
    "p\0"
    "glColor3bv\0"
    "\0"
-   /* _mesa_function_pool[6934]: WindowPos2fvMESA (will be remapped) */
+   /* _mesa_function_pool[6965]: WindowPos2fvMESA (will be remapped) */
    "p\0"
    "glWindowPos2fv\0"
    "glWindowPos2fvARB\0"
    "glWindowPos2fvMESA\0"
    "\0"
-   /* _mesa_function_pool[6989]: SecondaryColor3bvEXT (will be remapped) */
+   /* _mesa_function_pool[7020]: SecondaryColor3bvEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3bv\0"
    "glSecondaryColor3bvEXT\0"
    "\0"
-   /* _mesa_function_pool[7035]: VertexPointerListIBM (dynamic) */
+   /* _mesa_function_pool[7066]: VertexPointerListIBM (dynamic) */
    "iiipi\0"
    "glVertexPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[7065]: GetProgramLocalParameterfvARB (will be remapped) */
+   /* _mesa_function_pool[7096]: GetProgramLocalParameterfvARB (will be remapped) */
    "iip\0"
    "glGetProgramLocalParameterfvARB\0"
    "\0"
-   /* _mesa_function_pool[7102]: FragmentMaterialfSGIX (dynamic) */
+   /* _mesa_function_pool[7133]: FragmentMaterialfSGIX (dynamic) */
    "iif\0"
    "glFragmentMaterialfSGIX\0"
    "\0"
-   /* _mesa_function_pool[7131]: TexCoord2fNormal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[7162]: TexCoord2fNormal3fVertex3fSUN (dynamic) */
    "ffffffff\0"
    "glTexCoord2fNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[7173]: RenderbufferStorageEXT (will be remapped) */
+   /* _mesa_function_pool[7204]: RenderbufferStorageEXT (will be remapped) */
    "iiii\0"
    "glRenderbufferStorage\0"
    "glRenderbufferStorageEXT\0"
    "\0"
-   /* _mesa_function_pool[7226]: IsFenceNV (will be remapped) */
+   /* _mesa_function_pool[7257]: IsFenceNV (will be remapped) */
    "i\0"
    "glIsFenceNV\0"
    "\0"
-   /* _mesa_function_pool[7241]: AttachObjectARB (will be remapped) */
+   /* _mesa_function_pool[7272]: AttachObjectARB (will be remapped) */
    "ii\0"
    "glAttachObjectARB\0"
    "\0"
-   /* _mesa_function_pool[7263]: GetFragmentLightivSGIX (dynamic) */
+   /* _mesa_function_pool[7294]: GetFragmentLightivSGIX (dynamic) */
    "iip\0"
    "glGetFragmentLightivSGIX\0"
    "\0"
-   /* _mesa_function_pool[7293]: UniformMatrix2fvARB (will be remapped) */
+   /* _mesa_function_pool[7324]: UniformMatrix2fvARB (will be remapped) */
    "iiip\0"
    "glUniformMatrix2fv\0"
    "glUniformMatrix2fvARB\0"
    "\0"
-   /* _mesa_function_pool[7340]: MultiTexCoord2fARB (offset 386) */
+   /* _mesa_function_pool[7371]: MultiTexCoord2fARB (offset 386) */
    "iff\0"
    "glMultiTexCoord2f\0"
    "glMultiTexCoord2fARB\0"
    "\0"
-   /* _mesa_function_pool[7384]: ColorTable (offset 339) */
+   /* _mesa_function_pool[7415]: ColorTable (offset 339) */
    "iiiiip\0"
    "glColorTable\0"
    "glColorTableSGI\0"
    "glColorTableEXT\0"
    "\0"
-   /* _mesa_function_pool[7437]: IndexPointer (offset 314) */
+   /* _mesa_function_pool[7468]: IndexPointer (offset 314) */
    "iip\0"
    "glIndexPointer\0"
    "\0"
-   /* _mesa_function_pool[7457]: Accum (offset 213) */
+   /* _mesa_function_pool[7488]: Accum (offset 213) */
    "if\0"
    "glAccum\0"
    "\0"
-   /* _mesa_function_pool[7469]: GetTexImage (offset 281) */
+   /* _mesa_function_pool[7500]: GetTexImage (offset 281) */
    "iiiip\0"
    "glGetTexImage\0"
    "\0"
-   /* _mesa_function_pool[7490]: MapControlPointsNV (dynamic) */
+   /* _mesa_function_pool[7521]: MapControlPointsNV (dynamic) */
    "iiiiiiiip\0"
    "glMapControlPointsNV\0"
    "\0"
-   /* _mesa_function_pool[7522]: ConvolutionFilter2D (offset 349) */
+   /* _mesa_function_pool[7553]: ConvolutionFilter2D (offset 349) */
    "iiiiiip\0"
    "glConvolutionFilter2D\0"
    "glConvolutionFilter2DEXT\0"
    "\0"
-   /* _mesa_function_pool[7578]: Finish (offset 216) */
+   /* _mesa_function_pool[7609]: Finish (offset 216) */
    "\0"
    "glFinish\0"
    "\0"
-   /* _mesa_function_pool[7589]: MapParameterfvNV (dynamic) */
+   /* _mesa_function_pool[7620]: MapParameterfvNV (dynamic) */
    "iip\0"
    "glMapParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[7613]: ClearStencil (offset 207) */
+   /* _mesa_function_pool[7644]: ClearStencil (offset 207) */
    "i\0"
    "glClearStencil\0"
    "\0"
-   /* _mesa_function_pool[7631]: VertexAttrib3dvARB (will be remapped) */
+   /* _mesa_function_pool[7662]: VertexAttrib3dvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib3dv\0"
    "glVertexAttrib3dvARB\0"
    "\0"
-   /* _mesa_function_pool[7674]: HintPGI (dynamic) */
+   /* _mesa_function_pool[7705]: HintPGI (dynamic) */
    "ii\0"
    "glHintPGI\0"
    "\0"
-   /* _mesa_function_pool[7688]: ConvolutionParameteriv (offset 353) */
+   /* _mesa_function_pool[7719]: ConvolutionParameteriv (offset 353) */
    "iip\0"
    "glConvolutionParameteriv\0"
    "glConvolutionParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[7746]: Color4s (offset 33) */
+   /* _mesa_function_pool[7777]: Color4s (offset 33) */
    "iiii\0"
    "glColor4s\0"
    "\0"
-   /* _mesa_function_pool[7762]: InterleavedArrays (offset 317) */
+   /* _mesa_function_pool[7793]: InterleavedArrays (offset 317) */
    "iip\0"
    "glInterleavedArrays\0"
    "\0"
-   /* _mesa_function_pool[7787]: RasterPos2fv (offset 65) */
+   /* _mesa_function_pool[7818]: RasterPos2fv (offset 65) */
    "p\0"
    "glRasterPos2fv\0"
    "\0"
-   /* _mesa_function_pool[7805]: TexCoord1fv (offset 97) */
+   /* _mesa_function_pool[7836]: TexCoord1fv (offset 97) */
    "p\0"
    "glTexCoord1fv\0"
    "\0"
-   /* _mesa_function_pool[7822]: Vertex2d (offset 126) */
+   /* _mesa_function_pool[7853]: Vertex2d (offset 126) */
    "dd\0"
    "glVertex2d\0"
    "\0"
-   /* _mesa_function_pool[7837]: CullParameterdvEXT (will be remapped) */
+   /* _mesa_function_pool[7868]: CullParameterdvEXT (will be remapped) */
    "ip\0"
    "glCullParameterdvEXT\0"
    "\0"
-   /* _mesa_function_pool[7862]: ProgramNamedParameter4fNV (will be remapped) */
+   /* _mesa_function_pool[7893]: ProgramNamedParameter4fNV (will be remapped) */
    "iipffff\0"
    "glProgramNamedParameter4fNV\0"
    "\0"
-   /* _mesa_function_pool[7899]: Color3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[7930]: Color3fVertex3fSUN (dynamic) */
    "ffffff\0"
    "glColor3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[7928]: ProgramEnvParameter4fvARB (will be remapped) */
+   /* _mesa_function_pool[7959]: ProgramEnvParameter4fvARB (will be remapped) */
    "iip\0"
    "glProgramEnvParameter4fvARB\0"
    "glProgramParameter4fvNV\0"
    "\0"
-   /* _mesa_function_pool[7985]: Color4i (offset 31) */
+   /* _mesa_function_pool[8016]: Color4i (offset 31) */
    "iiii\0"
    "glColor4i\0"
    "\0"
-   /* _mesa_function_pool[8001]: Color4f (offset 29) */
+   /* _mesa_function_pool[8032]: Color4f (offset 29) */
    "ffff\0"
    "glColor4f\0"
    "\0"
-   /* _mesa_function_pool[8017]: RasterPos4fv (offset 81) */
+   /* _mesa_function_pool[8048]: RasterPos4fv (offset 81) */
    "p\0"
    "glRasterPos4fv\0"
    "\0"
-   /* _mesa_function_pool[8035]: Color4d (offset 27) */
+   /* _mesa_function_pool[8066]: Color4d (offset 27) */
    "dddd\0"
    "glColor4d\0"
    "\0"
-   /* _mesa_function_pool[8051]: ClearIndex (offset 205) */
+   /* _mesa_function_pool[8082]: ClearIndex (offset 205) */
    "f\0"
    "glClearIndex\0"
    "\0"
-   /* _mesa_function_pool[8067]: Color4b (offset 25) */
+   /* _mesa_function_pool[8098]: Color4b (offset 25) */
    "iiii\0"
    "glColor4b\0"
    "\0"
-   /* _mesa_function_pool[8083]: LoadMatrixd (offset 292) */
+   /* _mesa_function_pool[8114]: LoadMatrixd (offset 292) */
    "p\0"
    "glLoadMatrixd\0"
    "\0"
-   /* _mesa_function_pool[8100]: FragmentLightModeliSGIX (dynamic) */
+   /* _mesa_function_pool[8131]: FragmentLightModeliSGIX (dynamic) */
    "ii\0"
    "glFragmentLightModeliSGIX\0"
    "\0"
-   /* _mesa_function_pool[8130]: RasterPos2dv (offset 63) */
+   /* _mesa_function_pool[8161]: RasterPos2dv (offset 63) */
    "p\0"
    "glRasterPos2dv\0"
    "\0"
-   /* _mesa_function_pool[8148]: ConvolutionParameterfv (offset 351) */
+   /* _mesa_function_pool[8179]: ConvolutionParameterfv (offset 351) */
    "iip\0"
    "glConvolutionParameterfv\0"
    "glConvolutionParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[8206]: TbufferMask3DFX (dynamic) */
+   /* _mesa_function_pool[8237]: TbufferMask3DFX (dynamic) */
    "i\0"
    "glTbufferMask3DFX\0"
    "\0"
-   /* _mesa_function_pool[8227]: GetTexGendv (offset 278) */
+   /* _mesa_function_pool[8258]: GetTexGendv (offset 278) */
    "iip\0"
    "glGetTexGendv\0"
    "\0"
-   /* _mesa_function_pool[8246]: LoadProgramNV (will be remapped) */
+   /* _mesa_function_pool[8277]: ColorMaskIndexedEXT (will be remapped) */
+   "iiiii\0"
+   "glColorMaskIndexedEXT\0"
+   "\0"
+   /* _mesa_function_pool[8306]: LoadProgramNV (will be remapped) */
    "iiip\0"
    "glLoadProgramNV\0"
    "\0"
-   /* _mesa_function_pool[8268]: WaitSync (will be remapped) */
+   /* _mesa_function_pool[8328]: WaitSync (will be remapped) */
    "iii\0"
    "glWaitSync\0"
    "\0"
-   /* _mesa_function_pool[8284]: EndList (offset 1) */
+   /* _mesa_function_pool[8344]: EndList (offset 1) */
    "\0"
    "glEndList\0"
    "\0"
-   /* _mesa_function_pool[8296]: VertexAttrib4fvNV (will be remapped) */
+   /* _mesa_function_pool[8356]: VertexAttrib4fvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib4fvNV\0"
    "\0"
-   /* _mesa_function_pool[8320]: GetAttachedObjectsARB (will be remapped) */
+   /* _mesa_function_pool[8380]: GetAttachedObjectsARB (will be remapped) */
    "iipp\0"
    "glGetAttachedObjectsARB\0"
    "\0"
-   /* _mesa_function_pool[8350]: Uniform3fvARB (will be remapped) */
+   /* _mesa_function_pool[8410]: Uniform3fvARB (will be remapped) */
    "iip\0"
    "glUniform3fv\0"
    "glUniform3fvARB\0"
    "\0"
-   /* _mesa_function_pool[8384]: EvalCoord1fv (offset 231) */
+   /* _mesa_function_pool[8444]: EvalCoord1fv (offset 231) */
    "p\0"
    "glEvalCoord1fv\0"
    "\0"
-   /* _mesa_function_pool[8402]: DrawRangeElements (offset 338) */
+   /* _mesa_function_pool[8462]: DrawRangeElements (offset 338) */
    "iiiiip\0"
    "glDrawRangeElements\0"
    "glDrawRangeElementsEXT\0"
    "\0"
-   /* _mesa_function_pool[8453]: EvalMesh2 (offset 238) */
+   /* _mesa_function_pool[8513]: EvalMesh2 (offset 238) */
    "iiiii\0"
    "glEvalMesh2\0"
    "\0"
-   /* _mesa_function_pool[8472]: Vertex4fv (offset 145) */
+   /* _mesa_function_pool[8532]: Vertex4fv (offset 145) */
    "p\0"
    "glVertex4fv\0"
    "\0"
-   /* _mesa_function_pool[8487]: SpriteParameterfvSGIX (dynamic) */
+   /* _mesa_function_pool[8547]: SpriteParameterfvSGIX (dynamic) */
    "ip\0"
    "glSpriteParameterfvSGIX\0"
    "\0"
-   /* _mesa_function_pool[8515]: CheckFramebufferStatusEXT (will be remapped) */
+   /* _mesa_function_pool[8575]: CheckFramebufferStatusEXT (will be remapped) */
    "i\0"
    "glCheckFramebufferStatus\0"
    "glCheckFramebufferStatusEXT\0"
    "\0"
-   /* _mesa_function_pool[8571]: GlobalAlphaFactoruiSUN (dynamic) */
+   /* _mesa_function_pool[8631]: GlobalAlphaFactoruiSUN (dynamic) */
    "i\0"
    "glGlobalAlphaFactoruiSUN\0"
    "\0"
-   /* _mesa_function_pool[8599]: GetHandleARB (will be remapped) */
+   /* _mesa_function_pool[8659]: GetHandleARB (will be remapped) */
    "i\0"
    "glGetHandleARB\0"
    "\0"
-   /* _mesa_function_pool[8617]: GetVertexAttribivARB (will be remapped) */
+   /* _mesa_function_pool[8677]: GetVertexAttribivARB (will be remapped) */
    "iip\0"
    "glGetVertexAttribiv\0"
    "glGetVertexAttribivARB\0"
    "\0"
-   /* _mesa_function_pool[8665]: GetCombinerInputParameterfvNV (will be remapped) */
+   /* _mesa_function_pool[8725]: GetCombinerInputParameterfvNV (will be remapped) */
    "iiiip\0"
    "glGetCombinerInputParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[8704]: CreateProgram (will be remapped) */
+   /* _mesa_function_pool[8764]: CreateProgram (will be remapped) */
    "\0"
    "glCreateProgram\0"
    "\0"
-   /* _mesa_function_pool[8722]: LoadTransposeMatrixdARB (will be remapped) */
+   /* _mesa_function_pool[8782]: LoadTransposeMatrixdARB (will be remapped) */
    "p\0"
    "glLoadTransposeMatrixd\0"
    "glLoadTransposeMatrixdARB\0"
    "\0"
-   /* _mesa_function_pool[8774]: GetMinmax (offset 364) */
+   /* _mesa_function_pool[8834]: GetMinmax (offset 364) */
    "iiiip\0"
    "glGetMinmax\0"
    "glGetMinmaxEXT\0"
    "\0"
-   /* _mesa_function_pool[8808]: StencilFuncSeparate (will be remapped) */
+   /* _mesa_function_pool[8868]: StencilFuncSeparate (will be remapped) */
    "iiii\0"
    "glStencilFuncSeparate\0"
    "\0"
-   /* _mesa_function_pool[8836]: SecondaryColor3sEXT (will be remapped) */
+   /* _mesa_function_pool[8896]: SecondaryColor3sEXT (will be remapped) */
    "iii\0"
    "glSecondaryColor3s\0"
    "glSecondaryColor3sEXT\0"
    "\0"
-   /* _mesa_function_pool[8882]: Color3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[8942]: Color3fVertex3fvSUN (dynamic) */
    "pp\0"
    "glColor3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[8908]: Normal3fv (offset 57) */
+   /* _mesa_function_pool[8968]: Normal3fv (offset 57) */
    "p\0"
    "glNormal3fv\0"
    "\0"
-   /* _mesa_function_pool[8923]: GlobalAlphaFactorbSUN (dynamic) */
+   /* _mesa_function_pool[8983]: GlobalAlphaFactorbSUN (dynamic) */
    "i\0"
    "glGlobalAlphaFactorbSUN\0"
    "\0"
-   /* _mesa_function_pool[8950]: Color3us (offset 23) */
+   /* _mesa_function_pool[9010]: Color3us (offset 23) */
    "iii\0"
    "glColor3us\0"
    "\0"
-   /* _mesa_function_pool[8966]: ImageTransformParameterfvHP (dynamic) */
+   /* _mesa_function_pool[9026]: ImageTransformParameterfvHP (dynamic) */
    "iip\0"
    "glImageTransformParameterfvHP\0"
    "\0"
-   /* _mesa_function_pool[9001]: VertexAttrib4ivARB (will be remapped) */
+   /* _mesa_function_pool[9061]: VertexAttrib4ivARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4iv\0"
    "glVertexAttrib4ivARB\0"
    "\0"
-   /* _mesa_function_pool[9044]: End (offset 43) */
+   /* _mesa_function_pool[9104]: End (offset 43) */
    "\0"
    "glEnd\0"
    "\0"
-   /* _mesa_function_pool[9052]: VertexAttrib3fNV (will be remapped) */
+   /* _mesa_function_pool[9112]: VertexAttrib3fNV (will be remapped) */
    "ifff\0"
    "glVertexAttrib3fNV\0"
    "\0"
-   /* _mesa_function_pool[9077]: VertexAttribs2dvNV (will be remapped) */
+   /* _mesa_function_pool[9137]: VertexAttribs2dvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs2dvNV\0"
    "\0"
-   /* _mesa_function_pool[9103]: GetQueryObjectui64vEXT (will be remapped) */
+   /* _mesa_function_pool[9163]: GetQueryObjectui64vEXT (will be remapped) */
    "iip\0"
    "glGetQueryObjectui64vEXT\0"
    "\0"
-   /* _mesa_function_pool[9133]: MultiTexCoord3fvARB (offset 395) */
+   /* _mesa_function_pool[9193]: MultiTexCoord3fvARB (offset 395) */
    "ip\0"
    "glMultiTexCoord3fv\0"
    "glMultiTexCoord3fvARB\0"
    "\0"
-   /* _mesa_function_pool[9178]: SecondaryColor3dEXT (will be remapped) */
+   /* _mesa_function_pool[9238]: SecondaryColor3dEXT (will be remapped) */
    "ddd\0"
    "glSecondaryColor3d\0"
    "glSecondaryColor3dEXT\0"
    "\0"
-   /* _mesa_function_pool[9224]: Color3ub (offset 19) */
+   /* _mesa_function_pool[9284]: Color3ub (offset 19) */
    "iii\0"
    "glColor3ub\0"
    "\0"
-   /* _mesa_function_pool[9240]: GetProgramParameterfvNV (will be remapped) */
+   /* _mesa_function_pool[9300]: GetProgramParameterfvNV (will be remapped) */
    "iiip\0"
    "glGetProgramParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[9272]: TangentPointerEXT (dynamic) */
+   /* _mesa_function_pool[9332]: TangentPointerEXT (dynamic) */
    "iip\0"
    "glTangentPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[9297]: Color4fNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[9357]: Color4fNormal3fVertex3fvSUN (dynamic) */
    "ppp\0"
    "glColor4fNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[9332]: GetInstrumentsSGIX (dynamic) */
+   /* _mesa_function_pool[9392]: GetInstrumentsSGIX (dynamic) */
    "\0"
    "glGetInstrumentsSGIX\0"
    "\0"
-   /* _mesa_function_pool[9355]: Color3ui (offset 21) */
+   /* _mesa_function_pool[9415]: Color3ui (offset 21) */
    "iii\0"
    "glColor3ui\0"
    "\0"
-   /* _mesa_function_pool[9371]: EvalMapsNV (dynamic) */
+   /* _mesa_function_pool[9431]: EvalMapsNV (dynamic) */
    "ii\0"
    "glEvalMapsNV\0"
    "\0"
-   /* _mesa_function_pool[9388]: TexSubImage2D (offset 333) */
+   /* _mesa_function_pool[9448]: TexSubImage2D (offset 333) */
    "iiiiiiiip\0"
    "glTexSubImage2D\0"
    "glTexSubImage2DEXT\0"
    "\0"
-   /* _mesa_function_pool[9434]: FragmentLightivSGIX (dynamic) */
+   /* _mesa_function_pool[9494]: FragmentLightivSGIX (dynamic) */
    "iip\0"
    "glFragmentLightivSGIX\0"
    "\0"
-   /* _mesa_function_pool[9461]: GetTexParameterPointervAPPLE (will be remapped) */
+   /* _mesa_function_pool[9521]: GetTexParameterPointervAPPLE (will be remapped) */
    "iip\0"
    "glGetTexParameterPointervAPPLE\0"
    "\0"
-   /* _mesa_function_pool[9497]: TexGenfv (offset 191) */
+   /* _mesa_function_pool[9557]: TexGenfv (offset 191) */
    "iip\0"
    "glTexGenfv\0"
    "\0"
-   /* _mesa_function_pool[9513]: PixelTransformParameterfvEXT (dynamic) */
+   /* _mesa_function_pool[9573]: PixelTransformParameterfvEXT (dynamic) */
    "iip\0"
    "glPixelTransformParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[9549]: VertexAttrib4bvARB (will be remapped) */
+   /* _mesa_function_pool[9609]: VertexAttrib4bvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4bv\0"
    "glVertexAttrib4bvARB\0"
    "\0"
-   /* _mesa_function_pool[9592]: AlphaFragmentOp2ATI (will be remapped) */
+   /* _mesa_function_pool[9652]: AlphaFragmentOp2ATI (will be remapped) */
    "iiiiiiiii\0"
    "glAlphaFragmentOp2ATI\0"
    "\0"
-   /* _mesa_function_pool[9625]: MultiTexCoord4sARB (offset 406) */
+   /* _mesa_function_pool[9685]: GetIntegerIndexedvEXT (will be remapped) */
+   "iip\0"
+   "glGetIntegerIndexedvEXT\0"
+   "\0"
+   /* _mesa_function_pool[9714]: MultiTexCoord4sARB (offset 406) */
    "iiiii\0"
    "glMultiTexCoord4s\0"
    "glMultiTexCoord4sARB\0"
    "\0"
-   /* _mesa_function_pool[9671]: GetFragmentMaterialivSGIX (dynamic) */
+   /* _mesa_function_pool[9760]: GetFragmentMaterialivSGIX (dynamic) */
    "iip\0"
    "glGetFragmentMaterialivSGIX\0"
    "\0"
-   /* _mesa_function_pool[9704]: WindowPos4dMESA (will be remapped) */
+   /* _mesa_function_pool[9793]: WindowPos4dMESA (will be remapped) */
    "dddd\0"
    "glWindowPos4dMESA\0"
    "\0"
-   /* _mesa_function_pool[9728]: WeightPointerARB (dynamic) */
+   /* _mesa_function_pool[9817]: WeightPointerARB (dynamic) */
    "iiip\0"
    "glWeightPointerARB\0"
    "\0"
-   /* _mesa_function_pool[9753]: WindowPos2dMESA (will be remapped) */
+   /* _mesa_function_pool[9842]: WindowPos2dMESA (will be remapped) */
    "dd\0"
    "glWindowPos2d\0"
    "glWindowPos2dARB\0"
    "glWindowPos2dMESA\0"
    "\0"
-   /* _mesa_function_pool[9806]: FramebufferTexture3DEXT (will be remapped) */
+   /* _mesa_function_pool[9895]: FramebufferTexture3DEXT (will be remapped) */
    "iiiiii\0"
    "glFramebufferTexture3D\0"
    "glFramebufferTexture3DEXT\0"
    "\0"
-   /* _mesa_function_pool[9863]: BlendEquation (offset 337) */
+   /* _mesa_function_pool[9952]: BlendEquation (offset 337) */
    "i\0"
    "glBlendEquation\0"
    "glBlendEquationEXT\0"
    "\0"
-   /* _mesa_function_pool[9901]: VertexAttrib3dNV (will be remapped) */
+   /* _mesa_function_pool[9990]: VertexAttrib3dNV (will be remapped) */
    "iddd\0"
    "glVertexAttrib3dNV\0"
    "\0"
-   /* _mesa_function_pool[9926]: VertexAttrib3dARB (will be remapped) */
+   /* _mesa_function_pool[10015]: VertexAttrib3dARB (will be remapped) */
    "iddd\0"
    "glVertexAttrib3d\0"
    "glVertexAttrib3dARB\0"
    "\0"
-   /* _mesa_function_pool[9969]: ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[10058]: ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (dynamic) */
    "ppppp\0"
    "glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[10033]: VertexAttrib4fARB (will be remapped) */
+   /* _mesa_function_pool[10122]: VertexAttrib4fARB (will be remapped) */
    "iffff\0"
    "glVertexAttrib4f\0"
    "glVertexAttrib4fARB\0"
    "\0"
-   /* _mesa_function_pool[10077]: GetError (offset 261) */
+   /* _mesa_function_pool[10166]: GetError (offset 261) */
    "\0"
    "glGetError\0"
    "\0"
-   /* _mesa_function_pool[10090]: IndexFuncEXT (dynamic) */
+   /* _mesa_function_pool[10179]: IndexFuncEXT (dynamic) */
    "if\0"
    "glIndexFuncEXT\0"
    "\0"
-   /* _mesa_function_pool[10109]: TexCoord3dv (offset 111) */
+   /* _mesa_function_pool[10198]: TexCoord3dv (offset 111) */
    "p\0"
    "glTexCoord3dv\0"
    "\0"
-   /* _mesa_function_pool[10126]: Indexdv (offset 45) */
+   /* _mesa_function_pool[10215]: Indexdv (offset 45) */
    "p\0"
    "glIndexdv\0"
    "\0"
-   /* _mesa_function_pool[10139]: FramebufferTexture2DEXT (will be remapped) */
+   /* _mesa_function_pool[10228]: FramebufferTexture2DEXT (will be remapped) */
    "iiiii\0"
    "glFramebufferTexture2D\0"
    "glFramebufferTexture2DEXT\0"
    "\0"
-   /* _mesa_function_pool[10195]: Normal3s (offset 60) */
+   /* _mesa_function_pool[10284]: Normal3s (offset 60) */
    "iii\0"
    "glNormal3s\0"
    "\0"
-   /* _mesa_function_pool[10211]: PushName (offset 201) */
+   /* _mesa_function_pool[10300]: PushName (offset 201) */
    "i\0"
    "glPushName\0"
    "\0"
-   /* _mesa_function_pool[10225]: MultiTexCoord2dvARB (offset 385) */
+   /* _mesa_function_pool[10314]: MultiTexCoord2dvARB (offset 385) */
    "ip\0"
    "glMultiTexCoord2dv\0"
    "glMultiTexCoord2dvARB\0"
    "\0"
-   /* _mesa_function_pool[10270]: CullParameterfvEXT (will be remapped) */
+   /* _mesa_function_pool[10359]: CullParameterfvEXT (will be remapped) */
    "ip\0"
    "glCullParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[10295]: Normal3i (offset 58) */
+   /* _mesa_function_pool[10384]: Normal3i (offset 58) */
    "iii\0"
    "glNormal3i\0"
    "\0"
-   /* _mesa_function_pool[10311]: ProgramNamedParameter4fvNV (will be remapped) */
+   /* _mesa_function_pool[10400]: ProgramNamedParameter4fvNV (will be remapped) */
    "iipp\0"
    "glProgramNamedParameter4fvNV\0"
    "\0"
-   /* _mesa_function_pool[10346]: SecondaryColorPointerEXT (will be remapped) */
+   /* _mesa_function_pool[10435]: SecondaryColorPointerEXT (will be remapped) */
    "iiip\0"
    "glSecondaryColorPointer\0"
    "glSecondaryColorPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[10403]: VertexAttrib4fvARB (will be remapped) */
+   /* _mesa_function_pool[10492]: VertexAttrib4fvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4fv\0"
    "glVertexAttrib4fvARB\0"
    "\0"
-   /* _mesa_function_pool[10446]: ColorPointerListIBM (dynamic) */
+   /* _mesa_function_pool[10535]: ColorPointerListIBM (dynamic) */
    "iiipi\0"
    "glColorPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[10475]: GetActiveUniformARB (will be remapped) */
+   /* _mesa_function_pool[10564]: GetActiveUniformARB (will be remapped) */
    "iiipppp\0"
    "glGetActiveUniform\0"
    "glGetActiveUniformARB\0"
    "\0"
-   /* _mesa_function_pool[10525]: ImageTransformParameteriHP (dynamic) */
+   /* _mesa_function_pool[10614]: ImageTransformParameteriHP (dynamic) */
    "iii\0"
    "glImageTransformParameteriHP\0"
    "\0"
-   /* _mesa_function_pool[10559]: Normal3b (offset 52) */
+   /* _mesa_function_pool[10648]: Normal3b (offset 52) */
    "iii\0"
    "glNormal3b\0"
    "\0"
-   /* _mesa_function_pool[10575]: Normal3d (offset 54) */
+   /* _mesa_function_pool[10664]: Normal3d (offset 54) */
    "ddd\0"
    "glNormal3d\0"
    "\0"
-   /* _mesa_function_pool[10591]: Normal3f (offset 56) */
+   /* _mesa_function_pool[10680]: Normal3f (offset 56) */
    "fff\0"
    "glNormal3f\0"
    "\0"
-   /* _mesa_function_pool[10607]: MultiTexCoord1svARB (offset 383) */
+   /* _mesa_function_pool[10696]: MultiTexCoord1svARB (offset 383) */
    "ip\0"
    "glMultiTexCoord1sv\0"
    "glMultiTexCoord1svARB\0"
    "\0"
-   /* _mesa_function_pool[10652]: Indexi (offset 48) */
+   /* _mesa_function_pool[10741]: Indexi (offset 48) */
    "i\0"
    "glIndexi\0"
    "\0"
-   /* _mesa_function_pool[10664]: EndQueryARB (will be remapped) */
+   /* _mesa_function_pool[10753]: EndQueryARB (will be remapped) */
    "i\0"
    "glEndQuery\0"
    "glEndQueryARB\0"
    "\0"
-   /* _mesa_function_pool[10692]: DeleteFencesNV (will be remapped) */
+   /* _mesa_function_pool[10781]: DeleteFencesNV (will be remapped) */
    "ip\0"
    "glDeleteFencesNV\0"
    "\0"
-   /* _mesa_function_pool[10713]: DepthMask (offset 211) */
+   /* _mesa_function_pool[10802]: DeformationMap3dSGIX (dynamic) */
+   "iddiiddiiddiip\0"
+   "glDeformationMap3dSGIX\0"
+   "\0"
+   /* _mesa_function_pool[10841]: DepthMask (offset 211) */
    "i\0"
    "glDepthMask\0"
    "\0"
-   /* _mesa_function_pool[10728]: IsShader (will be remapped) */
+   /* _mesa_function_pool[10856]: IsShader (will be remapped) */
    "i\0"
    "glIsShader\0"
    "\0"
-   /* _mesa_function_pool[10742]: Indexf (offset 46) */
+   /* _mesa_function_pool[10870]: Indexf (offset 46) */
    "f\0"
    "glIndexf\0"
    "\0"
-   /* _mesa_function_pool[10754]: GetImageTransformParameterivHP (dynamic) */
+   /* _mesa_function_pool[10882]: GetImageTransformParameterivHP (dynamic) */
    "iip\0"
    "glGetImageTransformParameterivHP\0"
    "\0"
-   /* _mesa_function_pool[10792]: Indexd (offset 44) */
+   /* _mesa_function_pool[10920]: Indexd (offset 44) */
    "d\0"
    "glIndexd\0"
    "\0"
-   /* _mesa_function_pool[10804]: GetMaterialiv (offset 270) */
+   /* _mesa_function_pool[10932]: GetMaterialiv (offset 270) */
    "iip\0"
    "glGetMaterialiv\0"
    "\0"
-   /* _mesa_function_pool[10825]: StencilOp (offset 244) */
+   /* _mesa_function_pool[10953]: StencilOp (offset 244) */
    "iii\0"
    "glStencilOp\0"
    "\0"
-   /* _mesa_function_pool[10842]: WindowPos4ivMESA (will be remapped) */
+   /* _mesa_function_pool[10970]: WindowPos4ivMESA (will be remapped) */
    "p\0"
    "glWindowPos4ivMESA\0"
    "\0"
-   /* _mesa_function_pool[10864]: MultiTexCoord3svARB (offset 399) */
+   /* _mesa_function_pool[10992]: MultiTexCoord3svARB (offset 399) */
    "ip\0"
    "glMultiTexCoord3sv\0"
    "glMultiTexCoord3svARB\0"
    "\0"
-   /* _mesa_function_pool[10909]: TexEnvfv (offset 185) */
+   /* _mesa_function_pool[11037]: TexEnvfv (offset 185) */
    "iip\0"
    "glTexEnvfv\0"
    "\0"
-   /* _mesa_function_pool[10925]: MultiTexCoord4iARB (offset 404) */
+   /* _mesa_function_pool[11053]: MultiTexCoord4iARB (offset 404) */
    "iiiii\0"
    "glMultiTexCoord4i\0"
    "glMultiTexCoord4iARB\0"
    "\0"
-   /* _mesa_function_pool[10971]: Indexs (offset 50) */
+   /* _mesa_function_pool[11099]: Indexs (offset 50) */
    "i\0"
    "glIndexs\0"
    "\0"
-   /* _mesa_function_pool[10983]: Binormal3ivEXT (dynamic) */
+   /* _mesa_function_pool[11111]: Binormal3ivEXT (dynamic) */
    "p\0"
    "glBinormal3ivEXT\0"
    "\0"
-   /* _mesa_function_pool[11003]: ResizeBuffersMESA (will be remapped) */
+   /* _mesa_function_pool[11131]: ResizeBuffersMESA (will be remapped) */
    "\0"
    "glResizeBuffersMESA\0"
    "\0"
-   /* _mesa_function_pool[11025]: GetUniformivARB (will be remapped) */
+   /* _mesa_function_pool[11153]: GetUniformivARB (will be remapped) */
    "iip\0"
    "glGetUniformiv\0"
    "glGetUniformivARB\0"
    "\0"
-   /* _mesa_function_pool[11063]: PixelTexGenParameteriSGIS (will be remapped) */
+   /* _mesa_function_pool[11191]: PixelTexGenParameteriSGIS (will be remapped) */
    "ii\0"
    "glPixelTexGenParameteriSGIS\0"
    "\0"
-   /* _mesa_function_pool[11095]: VertexPointervINTEL (dynamic) */
+   /* _mesa_function_pool[11223]: VertexPointervINTEL (dynamic) */
    "iip\0"
    "glVertexPointervINTEL\0"
    "\0"
-   /* _mesa_function_pool[11122]: Vertex2i (offset 130) */
+   /* _mesa_function_pool[11250]: Vertex2i (offset 130) */
    "ii\0"
    "glVertex2i\0"
    "\0"
-   /* _mesa_function_pool[11137]: LoadMatrixf (offset 291) */
+   /* _mesa_function_pool[11265]: LoadMatrixf (offset 291) */
    "p\0"
    "glLoadMatrixf\0"
    "\0"
-   /* _mesa_function_pool[11154]: Vertex2f (offset 128) */
+   /* _mesa_function_pool[11282]: Vertex2f (offset 128) */
    "ff\0"
    "glVertex2f\0"
    "\0"
-   /* _mesa_function_pool[11169]: ReplacementCodeuiColor4fNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[11297]: ReplacementCodeuiColor4fNormal3fVertex3fvSUN (dynamic) */
    "pppp\0"
    "glReplacementCodeuiColor4fNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[11222]: Color4bv (offset 26) */
+   /* _mesa_function_pool[11350]: Color4bv (offset 26) */
    "p\0"
    "glColor4bv\0"
    "\0"
-   /* _mesa_function_pool[11236]: VertexPointer (offset 321) */
+   /* _mesa_function_pool[11364]: VertexPointer (offset 321) */
    "iiip\0"
    "glVertexPointer\0"
    "\0"
-   /* _mesa_function_pool[11258]: SecondaryColor3uiEXT (will be remapped) */
+   /* _mesa_function_pool[11386]: SecondaryColor3uiEXT (will be remapped) */
    "iii\0"
    "glSecondaryColor3ui\0"
    "glSecondaryColor3uiEXT\0"
    "\0"
-   /* _mesa_function_pool[11306]: StartInstrumentsSGIX (dynamic) */
+   /* _mesa_function_pool[11434]: StartInstrumentsSGIX (dynamic) */
    "\0"
    "glStartInstrumentsSGIX\0"
    "\0"
-   /* _mesa_function_pool[11331]: SecondaryColor3usvEXT (will be remapped) */
+   /* _mesa_function_pool[11459]: SecondaryColor3usvEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3usv\0"
    "glSecondaryColor3usvEXT\0"
    "\0"
-   /* _mesa_function_pool[11379]: VertexAttrib2fvNV (will be remapped) */
+   /* _mesa_function_pool[11507]: VertexAttrib2fvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib2fvNV\0"
    "\0"
-   /* _mesa_function_pool[11403]: ProgramLocalParameter4dvARB (will be remapped) */
+   /* _mesa_function_pool[11531]: ProgramLocalParameter4dvARB (will be remapped) */
    "iip\0"
    "glProgramLocalParameter4dvARB\0"
    "\0"
-   /* _mesa_function_pool[11438]: DeleteLists (offset 4) */
+   /* _mesa_function_pool[11566]: DeleteLists (offset 4) */
    "ii\0"
    "glDeleteLists\0"
    "\0"
-   /* _mesa_function_pool[11456]: LogicOp (offset 242) */
+   /* _mesa_function_pool[11584]: LogicOp (offset 242) */
    "i\0"
    "glLogicOp\0"
    "\0"
-   /* _mesa_function_pool[11469]: MatrixIndexuivARB (dynamic) */
+   /* _mesa_function_pool[11597]: MatrixIndexuivARB (dynamic) */
    "ip\0"
    "glMatrixIndexuivARB\0"
    "\0"
-   /* _mesa_function_pool[11493]: Vertex2s (offset 132) */
+   /* _mesa_function_pool[11621]: Vertex2s (offset 132) */
    "ii\0"
    "glVertex2s\0"
    "\0"
-   /* _mesa_function_pool[11508]: RenderbufferStorageMultisample (will be remapped) */
+   /* _mesa_function_pool[11636]: RenderbufferStorageMultisample (will be remapped) */
    "iiiii\0"
    "glRenderbufferStorageMultisample\0"
+   "glRenderbufferStorageMultisampleEXT\0"
    "\0"
-   /* _mesa_function_pool[11548]: TexCoord4fv (offset 121) */
+   /* _mesa_function_pool[11712]: TexCoord4fv (offset 121) */
    "p\0"
    "glTexCoord4fv\0"
    "\0"
-   /* _mesa_function_pool[11565]: Tangent3sEXT (dynamic) */
+   /* _mesa_function_pool[11729]: Tangent3sEXT (dynamic) */
    "iii\0"
    "glTangent3sEXT\0"
    "\0"
-   /* _mesa_function_pool[11585]: GlobalAlphaFactorfSUN (dynamic) */
+   /* _mesa_function_pool[11749]: GlobalAlphaFactorfSUN (dynamic) */
    "f\0"
    "glGlobalAlphaFactorfSUN\0"
    "\0"
-   /* _mesa_function_pool[11612]: MultiTexCoord3iARB (offset 396) */
+   /* _mesa_function_pool[11776]: MultiTexCoord3iARB (offset 396) */
    "iiii\0"
    "glMultiTexCoord3i\0"
    "glMultiTexCoord3iARB\0"
    "\0"
-   /* _mesa_function_pool[11657]: IsProgram (will be remapped) */
+   /* _mesa_function_pool[11821]: IsProgram (will be remapped) */
    "i\0"
    "glIsProgram\0"
    "\0"
-   /* _mesa_function_pool[11672]: TexCoordPointerListIBM (dynamic) */
+   /* _mesa_function_pool[11836]: TexCoordPointerListIBM (dynamic) */
    "iiipi\0"
    "glTexCoordPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[11704]: GlobalAlphaFactorusSUN (dynamic) */
+   /* _mesa_function_pool[11868]: GlobalAlphaFactorusSUN (dynamic) */
    "i\0"
    "glGlobalAlphaFactorusSUN\0"
    "\0"
-   /* _mesa_function_pool[11732]: VertexAttrib2dvNV (will be remapped) */
+   /* _mesa_function_pool[11896]: VertexAttrib2dvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib2dvNV\0"
    "\0"
-   /* _mesa_function_pool[11756]: FramebufferRenderbufferEXT (will be remapped) */
+   /* _mesa_function_pool[11920]: FramebufferRenderbufferEXT (will be remapped) */
    "iiii\0"
    "glFramebufferRenderbuffer\0"
    "glFramebufferRenderbufferEXT\0"
    "\0"
-   /* _mesa_function_pool[11817]: VertexAttrib1dvNV (will be remapped) */
+   /* _mesa_function_pool[11981]: VertexAttrib1dvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib1dvNV\0"
    "\0"
-   /* _mesa_function_pool[11841]: GenTextures (offset 328) */
+   /* _mesa_function_pool[12005]: GenTextures (offset 328) */
    "ip\0"
    "glGenTextures\0"
    "glGenTexturesEXT\0"
    "\0"
-   /* _mesa_function_pool[11876]: SetFenceNV (will be remapped) */
+   /* _mesa_function_pool[12040]: SetFenceNV (will be remapped) */
    "ii\0"
    "glSetFenceNV\0"
    "\0"
-   /* _mesa_function_pool[11893]: FramebufferTexture1DEXT (will be remapped) */
+   /* _mesa_function_pool[12057]: FramebufferTexture1DEXT (will be remapped) */
    "iiiii\0"
    "glFramebufferTexture1D\0"
    "glFramebufferTexture1DEXT\0"
    "\0"
-   /* _mesa_function_pool[11949]: GetCombinerOutputParameterivNV (will be remapped) */
+   /* _mesa_function_pool[12113]: GetCombinerOutputParameterivNV (will be remapped) */
    "iiip\0"
    "glGetCombinerOutputParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[11988]: MultiModeDrawArraysIBM (will be remapped) */
-   "pppii\0"
-   "glMultiModeDrawArraysIBM\0"
-   "\0"
-   /* _mesa_function_pool[12020]: PixelTexGenParameterivSGIS (will be remapped) */
+   /* _mesa_function_pool[12152]: PixelTexGenParameterivSGIS (will be remapped) */
    "ip\0"
    "glPixelTexGenParameterivSGIS\0"
    "\0"
-   /* _mesa_function_pool[12053]: TextureNormalEXT (dynamic) */
+   /* _mesa_function_pool[12185]: TextureNormalEXT (dynamic) */
    "i\0"
    "glTextureNormalEXT\0"
    "\0"
-   /* _mesa_function_pool[12075]: IndexPointerListIBM (dynamic) */
+   /* _mesa_function_pool[12207]: IndexPointerListIBM (dynamic) */
    "iipi\0"
    "glIndexPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[12103]: WeightfvARB (dynamic) */
+   /* _mesa_function_pool[12235]: WeightfvARB (dynamic) */
    "ip\0"
    "glWeightfvARB\0"
    "\0"
-   /* _mesa_function_pool[12121]: RasterPos2sv (offset 69) */
+   /* _mesa_function_pool[12253]: RasterPos2sv (offset 69) */
    "p\0"
    "glRasterPos2sv\0"
    "\0"
-   /* _mesa_function_pool[12139]: Color4ubv (offset 36) */
+   /* _mesa_function_pool[12271]: Color4ubv (offset 36) */
    "p\0"
    "glColor4ubv\0"
    "\0"
-   /* _mesa_function_pool[12154]: DrawBuffer (offset 202) */
+   /* _mesa_function_pool[12286]: DrawBuffer (offset 202) */
    "i\0"
    "glDrawBuffer\0"
    "\0"
-   /* _mesa_function_pool[12170]: TexCoord2fv (offset 105) */
+   /* _mesa_function_pool[12302]: TexCoord2fv (offset 105) */
    "p\0"
    "glTexCoord2fv\0"
    "\0"
-   /* _mesa_function_pool[12187]: WindowPos4fMESA (will be remapped) */
+   /* _mesa_function_pool[12319]: WindowPos4fMESA (will be remapped) */
    "ffff\0"
    "glWindowPos4fMESA\0"
    "\0"
-   /* _mesa_function_pool[12211]: TexCoord1sv (offset 101) */
+   /* _mesa_function_pool[12343]: TexCoord1sv (offset 101) */
    "p\0"
    "glTexCoord1sv\0"
    "\0"
-   /* _mesa_function_pool[12228]: WindowPos3dvMESA (will be remapped) */
+   /* _mesa_function_pool[12360]: WindowPos3dvMESA (will be remapped) */
    "p\0"
    "glWindowPos3dv\0"
    "glWindowPos3dvARB\0"
    "glWindowPos3dvMESA\0"
    "\0"
-   /* _mesa_function_pool[12283]: DepthFunc (offset 245) */
+   /* _mesa_function_pool[12415]: DepthFunc (offset 245) */
    "i\0"
    "glDepthFunc\0"
    "\0"
-   /* _mesa_function_pool[12298]: PixelMapusv (offset 253) */
+   /* _mesa_function_pool[12430]: PixelMapusv (offset 253) */
    "iip\0"
    "glPixelMapusv\0"
    "\0"
-   /* _mesa_function_pool[12317]: GetQueryObjecti64vEXT (will be remapped) */
+   /* _mesa_function_pool[12449]: GetQueryObjecti64vEXT (will be remapped) */
    "iip\0"
    "glGetQueryObjecti64vEXT\0"
    "\0"
-   /* _mesa_function_pool[12346]: MultiTexCoord1dARB (offset 376) */
+   /* _mesa_function_pool[12478]: MultiTexCoord1dARB (offset 376) */
    "id\0"
    "glMultiTexCoord1d\0"
    "glMultiTexCoord1dARB\0"
    "\0"
-   /* _mesa_function_pool[12389]: PointParameterivNV (will be remapped) */
+   /* _mesa_function_pool[12521]: PointParameterivNV (will be remapped) */
    "ip\0"
    "glPointParameteriv\0"
    "glPointParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[12433]: BlendFunc (offset 241) */
+   /* _mesa_function_pool[12565]: BlendFunc (offset 241) */
    "ii\0"
    "glBlendFunc\0"
    "\0"
-   /* _mesa_function_pool[12449]: Uniform2fvARB (will be remapped) */
+   /* _mesa_function_pool[12581]: Uniform2fvARB (will be remapped) */
    "iip\0"
    "glUniform2fv\0"
    "glUniform2fvARB\0"
    "\0"
-   /* _mesa_function_pool[12483]: BufferParameteriAPPLE (will be remapped) */
+   /* _mesa_function_pool[12615]: BufferParameteriAPPLE (will be remapped) */
    "iii\0"
    "glBufferParameteriAPPLE\0"
    "\0"
-   /* _mesa_function_pool[12512]: MultiTexCoord3dvARB (offset 393) */
+   /* _mesa_function_pool[12644]: MultiTexCoord3dvARB (offset 393) */
    "ip\0"
    "glMultiTexCoord3dv\0"
    "glMultiTexCoord3dvARB\0"
    "\0"
-   /* _mesa_function_pool[12557]: ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[12689]: ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (dynamic) */
    "pppp\0"
    "glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[12613]: DeleteObjectARB (will be remapped) */
+   /* _mesa_function_pool[12745]: DeleteObjectARB (will be remapped) */
    "i\0"
    "glDeleteObjectARB\0"
    "\0"
-   /* _mesa_function_pool[12634]: MatrixIndexPointerARB (dynamic) */
+   /* _mesa_function_pool[12766]: MatrixIndexPointerARB (dynamic) */
    "iiip\0"
    "glMatrixIndexPointerARB\0"
    "\0"
-   /* _mesa_function_pool[12664]: ProgramNamedParameter4dvNV (will be remapped) */
+   /* _mesa_function_pool[12796]: ProgramNamedParameter4dvNV (will be remapped) */
    "iipp\0"
    "glProgramNamedParameter4dvNV\0"
    "\0"
-   /* _mesa_function_pool[12699]: Tangent3fvEXT (dynamic) */
+   /* _mesa_function_pool[12831]: Tangent3fvEXT (dynamic) */
    "p\0"
    "glTangent3fvEXT\0"
    "\0"
-   /* _mesa_function_pool[12718]: Flush (offset 217) */
+   /* _mesa_function_pool[12850]: Flush (offset 217) */
    "\0"
    "glFlush\0"
    "\0"
-   /* _mesa_function_pool[12728]: Color4uiv (offset 38) */
+   /* _mesa_function_pool[12860]: Color4uiv (offset 38) */
    "p\0"
    "glColor4uiv\0"
    "\0"
-   /* _mesa_function_pool[12743]: GenVertexArrays (will be remapped) */
+   /* _mesa_function_pool[12875]: GenVertexArrays (will be remapped) */
    "ip\0"
    "glGenVertexArrays\0"
    "\0"
-   /* _mesa_function_pool[12765]: RasterPos3sv (offset 77) */
+   /* _mesa_function_pool[12897]: RasterPos3sv (offset 77) */
    "p\0"
    "glRasterPos3sv\0"
    "\0"
-   /* _mesa_function_pool[12783]: BindFramebufferEXT (will be remapped) */
+   /* _mesa_function_pool[12915]: BindFramebufferEXT (will be remapped) */
    "ii\0"
    "glBindFramebuffer\0"
    "glBindFramebufferEXT\0"
    "\0"
-   /* _mesa_function_pool[12826]: ReferencePlaneSGIX (dynamic) */
+   /* _mesa_function_pool[12958]: ReferencePlaneSGIX (dynamic) */
    "p\0"
    "glReferencePlaneSGIX\0"
    "\0"
-   /* _mesa_function_pool[12850]: PushAttrib (offset 219) */
+   /* _mesa_function_pool[12982]: PushAttrib (offset 219) */
    "i\0"
    "glPushAttrib\0"
    "\0"
-   /* _mesa_function_pool[12866]: RasterPos2i (offset 66) */
+   /* _mesa_function_pool[12998]: RasterPos2i (offset 66) */
    "ii\0"
    "glRasterPos2i\0"
    "\0"
-   /* _mesa_function_pool[12884]: ValidateProgramARB (will be remapped) */
+   /* _mesa_function_pool[13016]: ValidateProgramARB (will be remapped) */
    "i\0"
    "glValidateProgram\0"
    "glValidateProgramARB\0"
    "\0"
-   /* _mesa_function_pool[12926]: TexParameteriv (offset 181) */
+   /* _mesa_function_pool[13058]: TexParameteriv (offset 181) */
    "iip\0"
    "glTexParameteriv\0"
    "\0"
-   /* _mesa_function_pool[12948]: UnlockArraysEXT (will be remapped) */
+   /* _mesa_function_pool[13080]: UnlockArraysEXT (will be remapped) */
    "\0"
    "glUnlockArraysEXT\0"
    "\0"
-   /* _mesa_function_pool[12968]: TexCoord2fColor3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[13100]: TexCoord2fColor3fVertex3fSUN (dynamic) */
    "ffffffff\0"
    "glTexCoord2fColor3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[13009]: WindowPos3fvMESA (will be remapped) */
+   /* _mesa_function_pool[13141]: WindowPos3fvMESA (will be remapped) */
    "p\0"
    "glWindowPos3fv\0"
    "glWindowPos3fvARB\0"
    "glWindowPos3fvMESA\0"
    "\0"
-   /* _mesa_function_pool[13064]: RasterPos2f (offset 64) */
+   /* _mesa_function_pool[13196]: RasterPos2f (offset 64) */
    "ff\0"
    "glRasterPos2f\0"
    "\0"
-   /* _mesa_function_pool[13082]: VertexAttrib1svNV (will be remapped) */
+   /* _mesa_function_pool[13214]: VertexAttrib1svNV (will be remapped) */
    "ip\0"
    "glVertexAttrib1svNV\0"
    "\0"
-   /* _mesa_function_pool[13106]: RasterPos2d (offset 62) */
+   /* _mesa_function_pool[13238]: RasterPos2d (offset 62) */
    "dd\0"
    "glRasterPos2d\0"
    "\0"
-   /* _mesa_function_pool[13124]: RasterPos3fv (offset 73) */
+   /* _mesa_function_pool[13256]: RasterPos3fv (offset 73) */
    "p\0"
    "glRasterPos3fv\0"
    "\0"
-   /* _mesa_function_pool[13142]: CopyTexSubImage3D (offset 373) */
+   /* _mesa_function_pool[13274]: CopyTexSubImage3D (offset 373) */
    "iiiiiiiii\0"
    "glCopyTexSubImage3D\0"
    "glCopyTexSubImage3DEXT\0"
    "\0"
-   /* _mesa_function_pool[13196]: VertexAttrib2dARB (will be remapped) */
+   /* _mesa_function_pool[13328]: VertexAttrib2dARB (will be remapped) */
    "idd\0"
    "glVertexAttrib2d\0"
    "glVertexAttrib2dARB\0"
    "\0"
-   /* _mesa_function_pool[13238]: Color4ub (offset 35) */
+   /* _mesa_function_pool[13370]: Color4ub (offset 35) */
    "iiii\0"
    "glColor4ub\0"
    "\0"
-   /* _mesa_function_pool[13255]: GetInteger64v (will be remapped) */
+   /* _mesa_function_pool[13387]: GetInteger64v (will be remapped) */
    "ip\0"
    "glGetInteger64v\0"
    "\0"
-   /* _mesa_function_pool[13275]: TextureColorMaskSGIS (dynamic) */
+   /* _mesa_function_pool[13407]: TextureColorMaskSGIS (dynamic) */
    "iiii\0"
    "glTextureColorMaskSGIS\0"
    "\0"
-   /* _mesa_function_pool[13304]: RasterPos2s (offset 68) */
+   /* _mesa_function_pool[13436]: RasterPos2s (offset 68) */
    "ii\0"
    "glRasterPos2s\0"
    "\0"
-   /* _mesa_function_pool[13322]: GetColorTable (offset 343) */
+   /* _mesa_function_pool[13454]: GetColorTable (offset 343) */
    "iiip\0"
    "glGetColorTable\0"
    "glGetColorTableSGI\0"
    "glGetColorTableEXT\0"
    "\0"
-   /* _mesa_function_pool[13382]: SelectBuffer (offset 195) */
+   /* _mesa_function_pool[13514]: SelectBuffer (offset 195) */
    "ip\0"
    "glSelectBuffer\0"
    "\0"
-   /* _mesa_function_pool[13401]: Indexiv (offset 49) */
+   /* _mesa_function_pool[13533]: Indexiv (offset 49) */
    "p\0"
    "glIndexiv\0"
    "\0"
-   /* _mesa_function_pool[13414]: TexCoord3i (offset 114) */
+   /* _mesa_function_pool[13546]: TexCoord3i (offset 114) */
    "iii\0"
    "glTexCoord3i\0"
    "\0"
-   /* _mesa_function_pool[13432]: CopyColorTable (offset 342) */
+   /* _mesa_function_pool[13564]: CopyColorTable (offset 342) */
    "iiiii\0"
    "glCopyColorTable\0"
    "glCopyColorTableSGI\0"
    "\0"
-   /* _mesa_function_pool[13476]: GetHistogramParameterfv (offset 362) */
+   /* _mesa_function_pool[13608]: GetHistogramParameterfv (offset 362) */
    "iip\0"
    "glGetHistogramParameterfv\0"
    "glGetHistogramParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[13536]: Frustum (offset 289) */
+   /* _mesa_function_pool[13668]: Frustum (offset 289) */
    "dddddd\0"
    "glFrustum\0"
    "\0"
-   /* _mesa_function_pool[13554]: GetString (offset 275) */
+   /* _mesa_function_pool[13686]: GetString (offset 275) */
    "i\0"
    "glGetString\0"
    "\0"
-   /* _mesa_function_pool[13569]: ColorPointervINTEL (dynamic) */
+   /* _mesa_function_pool[13701]: ColorPointervINTEL (dynamic) */
    "iip\0"
    "glColorPointervINTEL\0"
    "\0"
-   /* _mesa_function_pool[13595]: TexEnvf (offset 184) */
+   /* _mesa_function_pool[13727]: TexEnvf (offset 184) */
    "iif\0"
    "glTexEnvf\0"
    "\0"
-   /* _mesa_function_pool[13610]: TexCoord3d (offset 110) */
+   /* _mesa_function_pool[13742]: TexCoord3d (offset 110) */
    "ddd\0"
    "glTexCoord3d\0"
    "\0"
-   /* _mesa_function_pool[13628]: AlphaFragmentOp1ATI (will be remapped) */
+   /* _mesa_function_pool[13760]: AlphaFragmentOp1ATI (will be remapped) */
    "iiiiii\0"
    "glAlphaFragmentOp1ATI\0"
    "\0"
-   /* _mesa_function_pool[13658]: TexCoord3f (offset 112) */
+   /* _mesa_function_pool[13790]: TexCoord3f (offset 112) */
    "fff\0"
    "glTexCoord3f\0"
    "\0"
-   /* _mesa_function_pool[13676]: MultiTexCoord3ivARB (offset 397) */
+   /* _mesa_function_pool[13808]: MultiTexCoord3ivARB (offset 397) */
    "ip\0"
    "glMultiTexCoord3iv\0"
    "glMultiTexCoord3ivARB\0"
    "\0"
-   /* _mesa_function_pool[13721]: MultiTexCoord2sARB (offset 390) */
+   /* _mesa_function_pool[13853]: MultiTexCoord2sARB (offset 390) */
    "iii\0"
    "glMultiTexCoord2s\0"
    "glMultiTexCoord2sARB\0"
    "\0"
-   /* _mesa_function_pool[13765]: VertexAttrib1dvARB (will be remapped) */
+   /* _mesa_function_pool[13897]: VertexAttrib1dvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib1dv\0"
    "glVertexAttrib1dvARB\0"
    "\0"
-   /* _mesa_function_pool[13808]: DeleteTextures (offset 327) */
+   /* _mesa_function_pool[13940]: DeleteTextures (offset 327) */
    "ip\0"
    "glDeleteTextures\0"
    "glDeleteTexturesEXT\0"
    "\0"
-   /* _mesa_function_pool[13849]: TexCoordPointerEXT (will be remapped) */
+   /* _mesa_function_pool[13981]: TexCoordPointerEXT (will be remapped) */
    "iiiip\0"
    "glTexCoordPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[13877]: TexSubImage4DSGIS (dynamic) */
+   /* _mesa_function_pool[14009]: TexSubImage4DSGIS (dynamic) */
    "iiiiiiiiiiiip\0"
    "glTexSubImage4DSGIS\0"
    "\0"
-   /* _mesa_function_pool[13912]: TexCoord3s (offset 116) */
+   /* _mesa_function_pool[14044]: TexCoord3s (offset 116) */
    "iii\0"
    "glTexCoord3s\0"
    "\0"
-   /* _mesa_function_pool[13930]: GetTexLevelParameteriv (offset 285) */
+   /* _mesa_function_pool[14062]: GetTexLevelParameteriv (offset 285) */
    "iiip\0"
    "glGetTexLevelParameteriv\0"
    "\0"
-   /* _mesa_function_pool[13961]: CombinerStageParameterfvNV (dynamic) */
+   /* _mesa_function_pool[14093]: CombinerStageParameterfvNV (dynamic) */
    "iip\0"
    "glCombinerStageParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[13995]: StopInstrumentsSGIX (dynamic) */
+   /* _mesa_function_pool[14127]: StopInstrumentsSGIX (dynamic) */
    "i\0"
    "glStopInstrumentsSGIX\0"
    "\0"
-   /* _mesa_function_pool[14020]: TexCoord4fColor4fNormal3fVertex4fSUN (dynamic) */
+   /* _mesa_function_pool[14152]: TexCoord4fColor4fNormal3fVertex4fSUN (dynamic) */
    "fffffffffffffff\0"
    "glTexCoord4fColor4fNormal3fVertex4fSUN\0"
    "\0"
-   /* _mesa_function_pool[14076]: ClearAccum (offset 204) */
+   /* _mesa_function_pool[14208]: ClearAccum (offset 204) */
    "ffff\0"
    "glClearAccum\0"
    "\0"
-   /* _mesa_function_pool[14095]: DeformSGIX (dynamic) */
+   /* _mesa_function_pool[14227]: DeformSGIX (dynamic) */
    "i\0"
    "glDeformSGIX\0"
    "\0"
-   /* _mesa_function_pool[14111]: GetVertexAttribfvARB (will be remapped) */
+   /* _mesa_function_pool[14243]: GetVertexAttribfvARB (will be remapped) */
    "iip\0"
    "glGetVertexAttribfv\0"
    "glGetVertexAttribfvARB\0"
    "\0"
-   /* _mesa_function_pool[14159]: SecondaryColor3ivEXT (will be remapped) */
+   /* _mesa_function_pool[14291]: SecondaryColor3ivEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3iv\0"
    "glSecondaryColor3ivEXT\0"
    "\0"
-   /* _mesa_function_pool[14205]: TexCoord4iv (offset 123) */
+   /* _mesa_function_pool[14337]: TexCoord4iv (offset 123) */
    "p\0"
    "glTexCoord4iv\0"
    "\0"
-   /* _mesa_function_pool[14222]: UniformMatrix4x2fv (will be remapped) */
+   /* _mesa_function_pool[14354]: UniformMatrix4x2fv (will be remapped) */
    "iiip\0"
    "glUniformMatrix4x2fv\0"
    "\0"
-   /* _mesa_function_pool[14249]: GetDetailTexFuncSGIS (dynamic) */
+   /* _mesa_function_pool[14381]: GetDetailTexFuncSGIS (dynamic) */
    "ip\0"
    "glGetDetailTexFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[14276]: GetCombinerStageParameterfvNV (dynamic) */
+   /* _mesa_function_pool[14408]: GetCombinerStageParameterfvNV (dynamic) */
    "iip\0"
    "glGetCombinerStageParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[14313]: PolygonOffset (offset 319) */
+   /* _mesa_function_pool[14445]: PolygonOffset (offset 319) */
    "ff\0"
    "glPolygonOffset\0"
    "\0"
-   /* _mesa_function_pool[14333]: BindVertexArray (will be remapped) */
+   /* _mesa_function_pool[14465]: BindVertexArray (will be remapped) */
    "i\0"
    "glBindVertexArray\0"
    "\0"
-   /* _mesa_function_pool[14354]: Color4ubVertex2fvSUN (dynamic) */
+   /* _mesa_function_pool[14486]: Color4ubVertex2fvSUN (dynamic) */
    "pp\0"
    "glColor4ubVertex2fvSUN\0"
    "\0"
-   /* _mesa_function_pool[14381]: Rectd (offset 86) */
+   /* _mesa_function_pool[14513]: Rectd (offset 86) */
    "dddd\0"
    "glRectd\0"
    "\0"
-   /* _mesa_function_pool[14395]: TexFilterFuncSGIS (dynamic) */
+   /* _mesa_function_pool[14527]: TexFilterFuncSGIS (dynamic) */
    "iiip\0"
    "glTexFilterFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[14421]: SampleMaskSGIS (will be remapped) */
+   /* _mesa_function_pool[14553]: SampleMaskSGIS (will be remapped) */
    "fi\0"
    "glSampleMaskSGIS\0"
    "glSampleMaskEXT\0"
    "\0"
-   /* _mesa_function_pool[14458]: GetAttribLocationARB (will be remapped) */
+   /* _mesa_function_pool[14590]: GetAttribLocationARB (will be remapped) */
    "ip\0"
    "glGetAttribLocation\0"
    "glGetAttribLocationARB\0"
    "\0"
-   /* _mesa_function_pool[14505]: RasterPos3i (offset 74) */
+   /* _mesa_function_pool[14637]: RasterPos3i (offset 74) */
    "iii\0"
    "glRasterPos3i\0"
    "\0"
-   /* _mesa_function_pool[14524]: VertexAttrib4ubvARB (will be remapped) */
+   /* _mesa_function_pool[14656]: VertexAttrib4ubvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4ubv\0"
    "glVertexAttrib4ubvARB\0"
    "\0"
-   /* _mesa_function_pool[14569]: DetailTexFuncSGIS (dynamic) */
+   /* _mesa_function_pool[14701]: DetailTexFuncSGIS (dynamic) */
    "iip\0"
    "glDetailTexFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[14594]: Normal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[14726]: Normal3fVertex3fSUN (dynamic) */
    "ffffff\0"
    "glNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[14624]: CopyTexImage2D (offset 324) */
+   /* _mesa_function_pool[14756]: CopyTexImage2D (offset 324) */
    "iiiiiiii\0"
    "glCopyTexImage2D\0"
    "glCopyTexImage2DEXT\0"
    "\0"
-   /* _mesa_function_pool[14671]: GetBufferPointervARB (will be remapped) */
+   /* _mesa_function_pool[14803]: GetBufferPointervARB (will be remapped) */
    "iip\0"
    "glGetBufferPointerv\0"
    "glGetBufferPointervARB\0"
    "\0"
-   /* _mesa_function_pool[14719]: ProgramEnvParameter4fARB (will be remapped) */
+   /* _mesa_function_pool[14851]: ProgramEnvParameter4fARB (will be remapped) */
    "iiffff\0"
    "glProgramEnvParameter4fARB\0"
    "glProgramParameter4fNV\0"
    "\0"
-   /* _mesa_function_pool[14777]: Uniform3ivARB (will be remapped) */
+   /* _mesa_function_pool[14909]: Uniform3ivARB (will be remapped) */
    "iip\0"
    "glUniform3iv\0"
    "glUniform3ivARB\0"
    "\0"
-   /* _mesa_function_pool[14811]: Lightfv (offset 160) */
+   /* _mesa_function_pool[14943]: Lightfv (offset 160) */
    "iip\0"
    "glLightfv\0"
    "\0"
-   /* _mesa_function_pool[14826]: ClearDepth (offset 208) */
+   /* _mesa_function_pool[14958]: ClearDepth (offset 208) */
    "d\0"
    "glClearDepth\0"
    "\0"
-   /* _mesa_function_pool[14842]: GetFenceivNV (will be remapped) */
+   /* _mesa_function_pool[14974]: GetFenceivNV (will be remapped) */
    "iip\0"
    "glGetFenceivNV\0"
    "\0"
-   /* _mesa_function_pool[14862]: WindowPos4dvMESA (will be remapped) */
+   /* _mesa_function_pool[14994]: WindowPos4dvMESA (will be remapped) */
    "p\0"
    "glWindowPos4dvMESA\0"
    "\0"
-   /* _mesa_function_pool[14884]: ColorSubTable (offset 346) */
+   /* _mesa_function_pool[15016]: ColorSubTable (offset 346) */
    "iiiiip\0"
    "glColorSubTable\0"
    "glColorSubTableEXT\0"
    "\0"
-   /* _mesa_function_pool[14927]: Color4fv (offset 30) */
+   /* _mesa_function_pool[15059]: Color4fv (offset 30) */
    "p\0"
    "glColor4fv\0"
    "\0"
-   /* _mesa_function_pool[14941]: MultiTexCoord4ivARB (offset 405) */
+   /* _mesa_function_pool[15073]: MultiTexCoord4ivARB (offset 405) */
    "ip\0"
    "glMultiTexCoord4iv\0"
    "glMultiTexCoord4ivARB\0"
    "\0"
-   /* _mesa_function_pool[14986]: ProgramLocalParameters4fvEXT (will be remapped) */
+   /* _mesa_function_pool[15118]: ProgramLocalParameters4fvEXT (will be remapped) */
    "iiip\0"
    "glProgramLocalParameters4fvEXT\0"
    "\0"
-   /* _mesa_function_pool[15023]: ColorPointer (offset 308) */
+   /* _mesa_function_pool[15155]: ColorPointer (offset 308) */
    "iiip\0"
    "glColorPointer\0"
    "\0"
-   /* _mesa_function_pool[15044]: Rects (offset 92) */
+   /* _mesa_function_pool[15176]: Rects (offset 92) */
    "iiii\0"
    "glRects\0"
    "\0"
-   /* _mesa_function_pool[15058]: GetMapAttribParameterfvNV (dynamic) */
+   /* _mesa_function_pool[15190]: GetMapAttribParameterfvNV (dynamic) */
    "iiip\0"
    "glGetMapAttribParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[15092]: Lightiv (offset 162) */
+   /* _mesa_function_pool[15224]: Lightiv (offset 162) */
    "iip\0"
    "glLightiv\0"
    "\0"
-   /* _mesa_function_pool[15107]: VertexAttrib4sARB (will be remapped) */
+   /* _mesa_function_pool[15239]: VertexAttrib4sARB (will be remapped) */
    "iiiii\0"
    "glVertexAttrib4s\0"
    "glVertexAttrib4sARB\0"
    "\0"
-   /* _mesa_function_pool[15151]: GetQueryObjectuivARB (will be remapped) */
+   /* _mesa_function_pool[15283]: GetQueryObjectuivARB (will be remapped) */
    "iip\0"
    "glGetQueryObjectuiv\0"
    "glGetQueryObjectuivARB\0"
    "\0"
-   /* _mesa_function_pool[15199]: GetTexParameteriv (offset 283) */
+   /* _mesa_function_pool[15331]: GetTexParameteriv (offset 283) */
    "iip\0"
    "glGetTexParameteriv\0"
    "\0"
-   /* _mesa_function_pool[15224]: MapParameterivNV (dynamic) */
+   /* _mesa_function_pool[15356]: MapParameterivNV (dynamic) */
    "iip\0"
    "glMapParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[15248]: GenRenderbuffersEXT (will be remapped) */
+   /* _mesa_function_pool[15380]: GenRenderbuffersEXT (will be remapped) */
    "ip\0"
    "glGenRenderbuffers\0"
    "glGenRenderbuffersEXT\0"
    "\0"
-   /* _mesa_function_pool[15293]: VertexAttrib2dvARB (will be remapped) */
+   /* _mesa_function_pool[15425]: VertexAttrib2dvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib2dv\0"
    "glVertexAttrib2dvARB\0"
    "\0"
-   /* _mesa_function_pool[15336]: EdgeFlagPointerEXT (will be remapped) */
+   /* _mesa_function_pool[15468]: EdgeFlagPointerEXT (will be remapped) */
    "iip\0"
    "glEdgeFlagPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[15362]: VertexAttribs2svNV (will be remapped) */
+   /* _mesa_function_pool[15494]: VertexAttribs2svNV (will be remapped) */
    "iip\0"
    "glVertexAttribs2svNV\0"
    "\0"
-   /* _mesa_function_pool[15388]: WeightbvARB (dynamic) */
+   /* _mesa_function_pool[15520]: WeightbvARB (dynamic) */
    "ip\0"
    "glWeightbvARB\0"
    "\0"
-   /* _mesa_function_pool[15406]: VertexAttrib2fvARB (will be remapped) */
+   /* _mesa_function_pool[15538]: VertexAttrib2fvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib2fv\0"
    "glVertexAttrib2fvARB\0"
    "\0"
-   /* _mesa_function_pool[15449]: GetBufferParameterivARB (will be remapped) */
+   /* _mesa_function_pool[15581]: GetBufferParameterivARB (will be remapped) */
    "iip\0"
    "glGetBufferParameteriv\0"
    "glGetBufferParameterivARB\0"
    "\0"
-   /* _mesa_function_pool[15503]: Rectdv (offset 87) */
+   /* _mesa_function_pool[15635]: Rectdv (offset 87) */
    "pp\0"
    "glRectdv\0"
    "\0"
-   /* _mesa_function_pool[15516]: ListParameteriSGIX (dynamic) */
+   /* _mesa_function_pool[15648]: ListParameteriSGIX (dynamic) */
    "iii\0"
    "glListParameteriSGIX\0"
    "\0"
-   /* _mesa_function_pool[15542]: ReplacementCodeuiColor4fNormal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[15674]: ReplacementCodeuiColor4fNormal3fVertex3fSUN (dynamic) */
    "iffffffffff\0"
    "glReplacementCodeuiColor4fNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[15601]: InstrumentsBufferSGIX (dynamic) */
+   /* _mesa_function_pool[15733]: InstrumentsBufferSGIX (dynamic) */
    "ip\0"
    "glInstrumentsBufferSGIX\0"
    "\0"
-   /* _mesa_function_pool[15629]: VertexAttrib4NivARB (will be remapped) */
+   /* _mesa_function_pool[15761]: VertexAttrib4NivARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4Niv\0"
    "glVertexAttrib4NivARB\0"
    "\0"
-   /* _mesa_function_pool[15674]: GetAttachedShaders (will be remapped) */
+   /* _mesa_function_pool[15806]: GetAttachedShaders (will be remapped) */
    "iipp\0"
    "glGetAttachedShaders\0"
    "\0"
-   /* _mesa_function_pool[15701]: GenVertexArraysAPPLE (will be remapped) */
+   /* _mesa_function_pool[15833]: GenVertexArraysAPPLE (will be remapped) */
    "ip\0"
    "glGenVertexArraysAPPLE\0"
    "\0"
-   /* _mesa_function_pool[15728]: Materialiv (offset 172) */
+   /* _mesa_function_pool[15860]: Materialiv (offset 172) */
    "iip\0"
    "glMaterialiv\0"
    "\0"
-   /* _mesa_function_pool[15746]: PushClientAttrib (offset 335) */
+   /* _mesa_function_pool[15878]: PushClientAttrib (offset 335) */
    "i\0"
    "glPushClientAttrib\0"
    "\0"
-   /* _mesa_function_pool[15768]: ProgramEnvParameters4fvEXT (will be remapped) */
+   /* _mesa_function_pool[15900]: ProgramEnvParameters4fvEXT (will be remapped) */
    "iiip\0"
    "glProgramEnvParameters4fvEXT\0"
    "\0"
-   /* _mesa_function_pool[15803]: TexCoord2fColor4fNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[15935]: TexCoord2fColor4fNormal3fVertex3fvSUN (dynamic) */
    "pppp\0"
    "glTexCoord2fColor4fNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[15849]: WindowPos2iMESA (will be remapped) */
+   /* _mesa_function_pool[15981]: WindowPos2iMESA (will be remapped) */
    "ii\0"
    "glWindowPos2i\0"
    "glWindowPos2iARB\0"
    "glWindowPos2iMESA\0"
    "\0"
-   /* _mesa_function_pool[15902]: SecondaryColor3fvEXT (will be remapped) */
+   /* _mesa_function_pool[16034]: SecondaryColor3fvEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3fv\0"
    "glSecondaryColor3fvEXT\0"
    "\0"
-   /* _mesa_function_pool[15948]: PolygonMode (offset 174) */
+   /* _mesa_function_pool[16080]: PolygonMode (offset 174) */
    "ii\0"
    "glPolygonMode\0"
    "\0"
-   /* _mesa_function_pool[15966]: CompressedTexSubImage1DARB (will be remapped) */
+   /* _mesa_function_pool[16098]: CompressedTexSubImage1DARB (will be remapped) */
    "iiiiiip\0"
    "glCompressedTexSubImage1D\0"
    "glCompressedTexSubImage1DARB\0"
    "\0"
-   /* _mesa_function_pool[16030]: GetVertexAttribivNV (will be remapped) */
+   /* _mesa_function_pool[16162]: GetVertexAttribivNV (will be remapped) */
    "iip\0"
    "glGetVertexAttribivNV\0"
    "\0"
-   /* _mesa_function_pool[16057]: GetProgramStringARB (will be remapped) */
+   /* _mesa_function_pool[16189]: GetProgramStringARB (will be remapped) */
    "iip\0"
    "glGetProgramStringARB\0"
    "\0"
-   /* _mesa_function_pool[16084]: TexBumpParameterfvATI (will be remapped) */
+   /* _mesa_function_pool[16216]: TexBumpParameterfvATI (will be remapped) */
    "ip\0"
    "glTexBumpParameterfvATI\0"
    "\0"
-   /* _mesa_function_pool[16112]: CompileShaderARB (will be remapped) */
+   /* _mesa_function_pool[16244]: CompileShaderARB (will be remapped) */
    "i\0"
    "glCompileShader\0"
    "glCompileShaderARB\0"
    "\0"
-   /* _mesa_function_pool[16150]: DeleteShader (will be remapped) */
+   /* _mesa_function_pool[16282]: DeleteShader (will be remapped) */
    "i\0"
    "glDeleteShader\0"
    "\0"
-   /* _mesa_function_pool[16168]: DisableClientState (offset 309) */
+   /* _mesa_function_pool[16300]: DisableClientState (offset 309) */
    "i\0"
    "glDisableClientState\0"
    "\0"
-   /* _mesa_function_pool[16192]: TexGeni (offset 192) */
+   /* _mesa_function_pool[16324]: TexGeni (offset 192) */
    "iii\0"
    "glTexGeni\0"
    "\0"
-   /* _mesa_function_pool[16207]: TexGenf (offset 190) */
+   /* _mesa_function_pool[16339]: TexGenf (offset 190) */
    "iif\0"
    "glTexGenf\0"
    "\0"
-   /* _mesa_function_pool[16222]: Uniform3fARB (will be remapped) */
+   /* _mesa_function_pool[16354]: Uniform3fARB (will be remapped) */
    "ifff\0"
    "glUniform3f\0"
    "glUniform3fARB\0"
    "\0"
-   /* _mesa_function_pool[16255]: TexGend (offset 188) */
+   /* _mesa_function_pool[16387]: TexGend (offset 188) */
    "iid\0"
    "glTexGend\0"
    "\0"
-   /* _mesa_function_pool[16270]: ListParameterfvSGIX (dynamic) */
+   /* _mesa_function_pool[16402]: ListParameterfvSGIX (dynamic) */
    "iip\0"
    "glListParameterfvSGIX\0"
    "\0"
-   /* _mesa_function_pool[16297]: GetPolygonStipple (offset 274) */
+   /* _mesa_function_pool[16429]: GetPolygonStipple (offset 274) */
    "p\0"
    "glGetPolygonStipple\0"
    "\0"
-   /* _mesa_function_pool[16320]: Tangent3dvEXT (dynamic) */
+   /* _mesa_function_pool[16452]: Tangent3dvEXT (dynamic) */
    "p\0"
    "glTangent3dvEXT\0"
    "\0"
-   /* _mesa_function_pool[16339]: GetVertexAttribfvNV (will be remapped) */
+   /* _mesa_function_pool[16471]: GetVertexAttribfvNV (will be remapped) */
    "iip\0"
    "glGetVertexAttribfvNV\0"
    "\0"
-   /* _mesa_function_pool[16366]: WindowPos3sMESA (will be remapped) */
+   /* _mesa_function_pool[16498]: WindowPos3sMESA (will be remapped) */
    "iii\0"
    "glWindowPos3s\0"
    "glWindowPos3sARB\0"
    "glWindowPos3sMESA\0"
    "\0"
-   /* _mesa_function_pool[16420]: VertexAttrib2svNV (will be remapped) */
+   /* _mesa_function_pool[16552]: VertexAttrib2svNV (will be remapped) */
    "ip\0"
    "glVertexAttrib2svNV\0"
    "\0"
-   /* _mesa_function_pool[16444]: VertexAttribs1fvNV (will be remapped) */
+   /* _mesa_function_pool[16576]: VertexAttribs1fvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs1fvNV\0"
    "\0"
-   /* _mesa_function_pool[16470]: TexCoord2fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[16602]: TexCoord2fVertex3fvSUN (dynamic) */
    "pp\0"
    "glTexCoord2fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[16499]: WindowPos4sMESA (will be remapped) */
+   /* _mesa_function_pool[16631]: WindowPos4sMESA (will be remapped) */
    "iiii\0"
    "glWindowPos4sMESA\0"
    "\0"
-   /* _mesa_function_pool[16523]: VertexAttrib4NuivARB (will be remapped) */
+   /* _mesa_function_pool[16655]: VertexAttrib4NuivARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4Nuiv\0"
    "glVertexAttrib4NuivARB\0"
    "\0"
-   /* _mesa_function_pool[16570]: ClientActiveTextureARB (offset 375) */
+   /* _mesa_function_pool[16702]: ClientActiveTextureARB (offset 375) */
    "i\0"
    "glClientActiveTexture\0"
    "glClientActiveTextureARB\0"
    "\0"
-   /* _mesa_function_pool[16620]: PixelTexGenSGIX (will be remapped) */
+   /* _mesa_function_pool[16752]: PixelTexGenSGIX (will be remapped) */
    "i\0"
    "glPixelTexGenSGIX\0"
    "\0"
-   /* _mesa_function_pool[16641]: ReplacementCodeusvSUN (dynamic) */
+   /* _mesa_function_pool[16773]: ReplacementCodeusvSUN (dynamic) */
    "p\0"
    "glReplacementCodeusvSUN\0"
    "\0"
-   /* _mesa_function_pool[16668]: Uniform4fARB (will be remapped) */
+   /* _mesa_function_pool[16800]: Uniform4fARB (will be remapped) */
    "iffff\0"
    "glUniform4f\0"
    "glUniform4fARB\0"
    "\0"
-   /* _mesa_function_pool[16702]: Color4sv (offset 34) */
+   /* _mesa_function_pool[16834]: Color4sv (offset 34) */
    "p\0"
    "glColor4sv\0"
    "\0"
-   /* _mesa_function_pool[16716]: FlushMappedBufferRange (will be remapped) */
+   /* _mesa_function_pool[16848]: FlushMappedBufferRange (will be remapped) */
    "iii\0"
    "glFlushMappedBufferRange\0"
    "\0"
-   /* _mesa_function_pool[16746]: IsProgramNV (will be remapped) */
+   /* _mesa_function_pool[16878]: IsProgramNV (will be remapped) */
    "i\0"
    "glIsProgramARB\0"
    "glIsProgramNV\0"
    "\0"
-   /* _mesa_function_pool[16778]: FlushMappedBufferRangeAPPLE (will be remapped) */
+   /* _mesa_function_pool[16910]: FlushMappedBufferRangeAPPLE (will be remapped) */
    "iii\0"
    "glFlushMappedBufferRangeAPPLE\0"
    "\0"
-   /* _mesa_function_pool[16813]: PixelZoom (offset 246) */
+   /* _mesa_function_pool[16945]: PixelZoom (offset 246) */
    "ff\0"
    "glPixelZoom\0"
    "\0"
-   /* _mesa_function_pool[16829]: ReplacementCodePointerSUN (dynamic) */
+   /* _mesa_function_pool[16961]: ReplacementCodePointerSUN (dynamic) */
    "iip\0"
    "glReplacementCodePointerSUN\0"
    "\0"
-   /* _mesa_function_pool[16862]: ProgramEnvParameter4dARB (will be remapped) */
+   /* _mesa_function_pool[16994]: ProgramEnvParameter4dARB (will be remapped) */
    "iidddd\0"
    "glProgramEnvParameter4dARB\0"
    "glProgramParameter4dNV\0"
    "\0"
-   /* _mesa_function_pool[16920]: ColorTableParameterfv (offset 340) */
+   /* _mesa_function_pool[17052]: ColorTableParameterfv (offset 340) */
    "iip\0"
    "glColorTableParameterfv\0"
    "glColorTableParameterfvSGI\0"
    "\0"
-   /* _mesa_function_pool[16976]: FragmentLightModelfSGIX (dynamic) */
+   /* _mesa_function_pool[17108]: FragmentLightModelfSGIX (dynamic) */
    "if\0"
    "glFragmentLightModelfSGIX\0"
    "\0"
-   /* _mesa_function_pool[17006]: Binormal3bvEXT (dynamic) */
+   /* _mesa_function_pool[17138]: Binormal3bvEXT (dynamic) */
    "p\0"
    "glBinormal3bvEXT\0"
    "\0"
-   /* _mesa_function_pool[17026]: PixelMapuiv (offset 252) */
+   /* _mesa_function_pool[17158]: PixelMapuiv (offset 252) */
    "iip\0"
    "glPixelMapuiv\0"
    "\0"
-   /* _mesa_function_pool[17045]: Color3dv (offset 12) */
+   /* _mesa_function_pool[17177]: Color3dv (offset 12) */
    "p\0"
    "glColor3dv\0"
    "\0"
-   /* _mesa_function_pool[17059]: IsTexture (offset 330) */
+   /* _mesa_function_pool[17191]: IsTexture (offset 330) */
    "i\0"
    "glIsTexture\0"
    "glIsTextureEXT\0"
    "\0"
-   /* _mesa_function_pool[17089]: VertexWeightfvEXT (dynamic) */
+   /* _mesa_function_pool[17221]: VertexWeightfvEXT (dynamic) */
    "p\0"
    "glVertexWeightfvEXT\0"
    "\0"
-   /* _mesa_function_pool[17112]: VertexAttrib1dARB (will be remapped) */
+   /* _mesa_function_pool[17244]: VertexAttrib1dARB (will be remapped) */
    "id\0"
    "glVertexAttrib1d\0"
    "glVertexAttrib1dARB\0"
    "\0"
-   /* _mesa_function_pool[17153]: ImageTransformParameterivHP (dynamic) */
+   /* _mesa_function_pool[17285]: ImageTransformParameterivHP (dynamic) */
    "iip\0"
    "glImageTransformParameterivHP\0"
    "\0"
-   /* _mesa_function_pool[17188]: TexCoord4i (offset 122) */
+   /* _mesa_function_pool[17320]: TexCoord4i (offset 122) */
    "iiii\0"
    "glTexCoord4i\0"
    "\0"
-   /* _mesa_function_pool[17207]: DeleteQueriesARB (will be remapped) */
+   /* _mesa_function_pool[17339]: DeleteQueriesARB (will be remapped) */
    "ip\0"
    "glDeleteQueries\0"
    "glDeleteQueriesARB\0"
    "\0"
-   /* _mesa_function_pool[17246]: Color4ubVertex2fSUN (dynamic) */
+   /* _mesa_function_pool[17378]: Color4ubVertex2fSUN (dynamic) */
    "iiiiff\0"
    "glColor4ubVertex2fSUN\0"
    "\0"
-   /* _mesa_function_pool[17276]: FragmentColorMaterialSGIX (dynamic) */
+   /* _mesa_function_pool[17408]: FragmentColorMaterialSGIX (dynamic) */
    "ii\0"
    "glFragmentColorMaterialSGIX\0"
    "\0"
-   /* _mesa_function_pool[17308]: CurrentPaletteMatrixARB (dynamic) */
+   /* _mesa_function_pool[17440]: CurrentPaletteMatrixARB (dynamic) */
    "i\0"
    "glCurrentPaletteMatrixARB\0"
    "\0"
-   /* _mesa_function_pool[17337]: GetMapdv (offset 266) */
+   /* _mesa_function_pool[17469]: GetMapdv (offset 266) */
    "iip\0"
    "glGetMapdv\0"
    "\0"
-   /* _mesa_function_pool[17353]: SamplePatternSGIS (will be remapped) */
+   /* _mesa_function_pool[17485]: SamplePatternSGIS (will be remapped) */
    "i\0"
    "glSamplePatternSGIS\0"
    "glSamplePatternEXT\0"
    "\0"
-   /* _mesa_function_pool[17395]: PixelStoref (offset 249) */
+   /* _mesa_function_pool[17527]: PixelStoref (offset 249) */
    "if\0"
    "glPixelStoref\0"
    "\0"
-   /* _mesa_function_pool[17413]: IsQueryARB (will be remapped) */
+   /* _mesa_function_pool[17545]: IsQueryARB (will be remapped) */
    "i\0"
    "glIsQuery\0"
    "glIsQueryARB\0"
    "\0"
-   /* _mesa_function_pool[17439]: ReplacementCodeuiColor4ubVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[17571]: ReplacementCodeuiColor4ubVertex3fSUN (dynamic) */
    "iiiiifff\0"
    "glReplacementCodeuiColor4ubVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[17488]: PixelStorei (offset 250) */
+   /* _mesa_function_pool[17620]: PixelStorei (offset 250) */
    "ii\0"
    "glPixelStorei\0"
    "\0"
-   /* _mesa_function_pool[17506]: VertexAttrib4usvARB (will be remapped) */
+   /* _mesa_function_pool[17638]: VertexAttrib4usvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4usv\0"
    "glVertexAttrib4usvARB\0"
    "\0"
-   /* _mesa_function_pool[17551]: LinkProgramARB (will be remapped) */
+   /* _mesa_function_pool[17683]: LinkProgramARB (will be remapped) */
    "i\0"
    "glLinkProgram\0"
    "glLinkProgramARB\0"
    "\0"
-   /* _mesa_function_pool[17585]: VertexAttrib2fNV (will be remapped) */
+   /* _mesa_function_pool[17717]: VertexAttrib2fNV (will be remapped) */
    "iff\0"
    "glVertexAttrib2fNV\0"
    "\0"
-   /* _mesa_function_pool[17609]: ShaderSourceARB (will be remapped) */
+   /* _mesa_function_pool[17741]: ShaderSourceARB (will be remapped) */
    "iipp\0"
    "glShaderSource\0"
    "glShaderSourceARB\0"
    "\0"
-   /* _mesa_function_pool[17648]: FragmentMaterialiSGIX (dynamic) */
+   /* _mesa_function_pool[17780]: FragmentMaterialiSGIX (dynamic) */
    "iii\0"
    "glFragmentMaterialiSGIX\0"
    "\0"
-   /* _mesa_function_pool[17677]: EvalCoord2dv (offset 233) */
+   /* _mesa_function_pool[17809]: EvalCoord2dv (offset 233) */
    "p\0"
    "glEvalCoord2dv\0"
    "\0"
-   /* _mesa_function_pool[17695]: VertexAttrib3svARB (will be remapped) */
+   /* _mesa_function_pool[17827]: VertexAttrib3svARB (will be remapped) */
    "ip\0"
    "glVertexAttrib3sv\0"
    "glVertexAttrib3svARB\0"
    "\0"
-   /* _mesa_function_pool[17738]: ColorMaterial (offset 151) */
+   /* _mesa_function_pool[17870]: ColorMaterial (offset 151) */
    "ii\0"
    "glColorMaterial\0"
    "\0"
-   /* _mesa_function_pool[17758]: CompressedTexSubImage3DARB (will be remapped) */
+   /* _mesa_function_pool[17890]: CompressedTexSubImage3DARB (will be remapped) */
    "iiiiiiiiiip\0"
    "glCompressedTexSubImage3D\0"
    "glCompressedTexSubImage3DARB\0"
    "\0"
-   /* _mesa_function_pool[17826]: WindowPos2ivMESA (will be remapped) */
+   /* _mesa_function_pool[17958]: WindowPos2ivMESA (will be remapped) */
    "p\0"
    "glWindowPos2iv\0"
    "glWindowPos2ivARB\0"
    "glWindowPos2ivMESA\0"
    "\0"
-   /* _mesa_function_pool[17881]: IsFramebufferEXT (will be remapped) */
+   /* _mesa_function_pool[18013]: IsFramebufferEXT (will be remapped) */
    "i\0"
    "glIsFramebuffer\0"
    "glIsFramebufferEXT\0"
    "\0"
-   /* _mesa_function_pool[17919]: Uniform4ivARB (will be remapped) */
+   /* _mesa_function_pool[18051]: Uniform4ivARB (will be remapped) */
    "iip\0"
    "glUniform4iv\0"
    "glUniform4ivARB\0"
    "\0"
-   /* _mesa_function_pool[17953]: GetVertexAttribdvARB (will be remapped) */
+   /* _mesa_function_pool[18085]: GetVertexAttribdvARB (will be remapped) */
    "iip\0"
    "glGetVertexAttribdv\0"
    "glGetVertexAttribdvARB\0"
    "\0"
-   /* _mesa_function_pool[18001]: TexBumpParameterivATI (will be remapped) */
+   /* _mesa_function_pool[18133]: TexBumpParameterivATI (will be remapped) */
    "ip\0"
    "glTexBumpParameterivATI\0"
    "\0"
-   /* _mesa_function_pool[18029]: GetSeparableFilter (offset 359) */
+   /* _mesa_function_pool[18161]: GetSeparableFilter (offset 359) */
    "iiippp\0"
    "glGetSeparableFilter\0"
    "glGetSeparableFilterEXT\0"
    "\0"
-   /* _mesa_function_pool[18082]: Binormal3dEXT (dynamic) */
+   /* _mesa_function_pool[18214]: Binormal3dEXT (dynamic) */
    "ddd\0"
    "glBinormal3dEXT\0"
    "\0"
-   /* _mesa_function_pool[18103]: SpriteParameteriSGIX (dynamic) */
+   /* _mesa_function_pool[18235]: SpriteParameteriSGIX (dynamic) */
    "ii\0"
    "glSpriteParameteriSGIX\0"
    "\0"
-   /* _mesa_function_pool[18130]: RequestResidentProgramsNV (will be remapped) */
+   /* _mesa_function_pool[18262]: RequestResidentProgramsNV (will be remapped) */
    "ip\0"
    "glRequestResidentProgramsNV\0"
    "\0"
-   /* _mesa_function_pool[18162]: TagSampleBufferSGIX (dynamic) */
+   /* _mesa_function_pool[18294]: TagSampleBufferSGIX (dynamic) */
    "\0"
    "glTagSampleBufferSGIX\0"
    "\0"
-   /* _mesa_function_pool[18186]: ReplacementCodeusSUN (dynamic) */
+   /* _mesa_function_pool[18318]: ReplacementCodeusSUN (dynamic) */
    "i\0"
    "glReplacementCodeusSUN\0"
    "\0"
-   /* _mesa_function_pool[18212]: FeedbackBuffer (offset 194) */
+   /* _mesa_function_pool[18344]: FeedbackBuffer (offset 194) */
    "iip\0"
    "glFeedbackBuffer\0"
    "\0"
-   /* _mesa_function_pool[18234]: RasterPos2iv (offset 67) */
+   /* _mesa_function_pool[18366]: RasterPos2iv (offset 67) */
    "p\0"
    "glRasterPos2iv\0"
    "\0"
-   /* _mesa_function_pool[18252]: TexImage1D (offset 182) */
+   /* _mesa_function_pool[18384]: TexImage1D (offset 182) */
    "iiiiiiip\0"
    "glTexImage1D\0"
    "\0"
-   /* _mesa_function_pool[18275]: ListParameterivSGIX (dynamic) */
+   /* _mesa_function_pool[18407]: ListParameterivSGIX (dynamic) */
    "iip\0"
    "glListParameterivSGIX\0"
    "\0"
-   /* _mesa_function_pool[18302]: MultiDrawElementsEXT (will be remapped) */
+   /* _mesa_function_pool[18434]: MultiDrawElementsEXT (will be remapped) */
    "ipipi\0"
    "glMultiDrawElements\0"
    "glMultiDrawElementsEXT\0"
    "\0"
-   /* _mesa_function_pool[18352]: Color3s (offset 17) */
+   /* _mesa_function_pool[18484]: Color3s (offset 17) */
    "iii\0"
    "glColor3s\0"
    "\0"
-   /* _mesa_function_pool[18367]: Uniform1ivARB (will be remapped) */
+   /* _mesa_function_pool[18499]: Uniform1ivARB (will be remapped) */
    "iip\0"
    "glUniform1iv\0"
    "glUniform1ivARB\0"
    "\0"
-   /* _mesa_function_pool[18401]: WindowPos2sMESA (will be remapped) */
+   /* _mesa_function_pool[18533]: WindowPos2sMESA (will be remapped) */
    "ii\0"
    "glWindowPos2s\0"
    "glWindowPos2sARB\0"
    "glWindowPos2sMESA\0"
    "\0"
-   /* _mesa_function_pool[18454]: WeightusvARB (dynamic) */
+   /* _mesa_function_pool[18586]: WeightusvARB (dynamic) */
    "ip\0"
    "glWeightusvARB\0"
    "\0"
-   /* _mesa_function_pool[18473]: TexCoordPointer (offset 320) */
+   /* _mesa_function_pool[18605]: TexCoordPointer (offset 320) */
    "iiip\0"
    "glTexCoordPointer\0"
    "\0"
-   /* _mesa_function_pool[18497]: FogCoordPointerEXT (will be remapped) */
+   /* _mesa_function_pool[18629]: FogCoordPointerEXT (will be remapped) */
    "iip\0"
    "glFogCoordPointer\0"
    "glFogCoordPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[18541]: IndexMaterialEXT (dynamic) */
+   /* _mesa_function_pool[18673]: IndexMaterialEXT (dynamic) */
    "ii\0"
    "glIndexMaterialEXT\0"
    "\0"
-   /* _mesa_function_pool[18564]: Color3i (offset 15) */
+   /* _mesa_function_pool[18696]: Color3i (offset 15) */
    "iii\0"
    "glColor3i\0"
    "\0"
-   /* _mesa_function_pool[18579]: FrontFace (offset 157) */
+   /* _mesa_function_pool[18711]: FrontFace (offset 157) */
    "i\0"
    "glFrontFace\0"
    "\0"
-   /* _mesa_function_pool[18594]: EvalCoord2d (offset 232) */
+   /* _mesa_function_pool[18726]: EvalCoord2d (offset 232) */
    "dd\0"
    "glEvalCoord2d\0"
    "\0"
-   /* _mesa_function_pool[18612]: SecondaryColor3ubvEXT (will be remapped) */
+   /* _mesa_function_pool[18744]: SecondaryColor3ubvEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3ubv\0"
    "glSecondaryColor3ubvEXT\0"
    "\0"
-   /* _mesa_function_pool[18660]: EvalCoord2f (offset 234) */
+   /* _mesa_function_pool[18792]: EvalCoord2f (offset 234) */
    "ff\0"
    "glEvalCoord2f\0"
    "\0"
-   /* _mesa_function_pool[18678]: VertexAttrib4dvARB (will be remapped) */
+   /* _mesa_function_pool[18810]: VertexAttrib4dvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4dv\0"
    "glVertexAttrib4dvARB\0"
    "\0"
-   /* _mesa_function_pool[18721]: BindAttribLocationARB (will be remapped) */
+   /* _mesa_function_pool[18853]: BindAttribLocationARB (will be remapped) */
    "iip\0"
    "glBindAttribLocation\0"
    "glBindAttribLocationARB\0"
    "\0"
-   /* _mesa_function_pool[18771]: Color3b (offset 9) */
+   /* _mesa_function_pool[18903]: Color3b (offset 9) */
    "iii\0"
    "glColor3b\0"
    "\0"
-   /* _mesa_function_pool[18786]: MultiTexCoord2dARB (offset 384) */
+   /* _mesa_function_pool[18918]: MultiTexCoord2dARB (offset 384) */
    "idd\0"
    "glMultiTexCoord2d\0"
    "glMultiTexCoord2dARB\0"
    "\0"
-   /* _mesa_function_pool[18830]: ExecuteProgramNV (will be remapped) */
+   /* _mesa_function_pool[18962]: ExecuteProgramNV (will be remapped) */
    "iip\0"
    "glExecuteProgramNV\0"
    "\0"
-   /* _mesa_function_pool[18854]: Color3f (offset 13) */
+   /* _mesa_function_pool[18986]: Color3f (offset 13) */
    "fff\0"
    "glColor3f\0"
    "\0"
-   /* _mesa_function_pool[18869]: LightEnviSGIX (dynamic) */
+   /* _mesa_function_pool[19001]: LightEnviSGIX (dynamic) */
    "ii\0"
    "glLightEnviSGIX\0"
    "\0"
-   /* _mesa_function_pool[18889]: Color3d (offset 11) */
+   /* _mesa_function_pool[19021]: Color3d (offset 11) */
    "ddd\0"
    "glColor3d\0"
    "\0"
-   /* _mesa_function_pool[18904]: Normal3dv (offset 55) */
+   /* _mesa_function_pool[19036]: Normal3dv (offset 55) */
    "p\0"
    "glNormal3dv\0"
    "\0"
-   /* _mesa_function_pool[18919]: Lightf (offset 159) */
+   /* _mesa_function_pool[19051]: Lightf (offset 159) */
    "iif\0"
    "glLightf\0"
    "\0"
-   /* _mesa_function_pool[18933]: ReplacementCodeuiSUN (dynamic) */
+   /* _mesa_function_pool[19065]: ReplacementCodeuiSUN (dynamic) */
    "i\0"
    "glReplacementCodeuiSUN\0"
    "\0"
-   /* _mesa_function_pool[18959]: MatrixMode (offset 293) */
+   /* _mesa_function_pool[19091]: MatrixMode (offset 293) */
    "i\0"
    "glMatrixMode\0"
    "\0"
-   /* _mesa_function_pool[18975]: GetPixelMapusv (offset 273) */
+   /* _mesa_function_pool[19107]: GetPixelMapusv (offset 273) */
    "ip\0"
    "glGetPixelMapusv\0"
    "\0"
-   /* _mesa_function_pool[18996]: Lighti (offset 161) */
+   /* _mesa_function_pool[19128]: Lighti (offset 161) */
    "iii\0"
    "glLighti\0"
    "\0"
-   /* _mesa_function_pool[19010]: VertexAttribPointerNV (will be remapped) */
+   /* _mesa_function_pool[19142]: VertexAttribPointerNV (will be remapped) */
    "iiiip\0"
    "glVertexAttribPointerNV\0"
    "\0"
-   /* _mesa_function_pool[19041]: GetFramebufferAttachmentParameterivEXT (will be remapped) */
+   /* _mesa_function_pool[19173]: GetBooleanIndexedvEXT (will be remapped) */
+   "iip\0"
+   "glGetBooleanIndexedvEXT\0"
+   "\0"
+   /* _mesa_function_pool[19202]: GetFramebufferAttachmentParameterivEXT (will be remapped) */
    "iiip\0"
    "glGetFramebufferAttachmentParameteriv\0"
    "glGetFramebufferAttachmentParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[19126]: PixelTransformParameterfEXT (dynamic) */
+   /* _mesa_function_pool[19287]: PixelTransformParameterfEXT (dynamic) */
    "iif\0"
    "glPixelTransformParameterfEXT\0"
    "\0"
-   /* _mesa_function_pool[19161]: MultiTexCoord4dvARB (offset 401) */
+   /* _mesa_function_pool[19322]: MultiTexCoord4dvARB (offset 401) */
    "ip\0"
    "glMultiTexCoord4dv\0"
    "glMultiTexCoord4dvARB\0"
    "\0"
-   /* _mesa_function_pool[19206]: PixelTransformParameteriEXT (dynamic) */
+   /* _mesa_function_pool[19367]: PixelTransformParameteriEXT (dynamic) */
    "iii\0"
    "glPixelTransformParameteriEXT\0"
    "\0"
-   /* _mesa_function_pool[19241]: GetDoublev (offset 260) */
+   /* _mesa_function_pool[19402]: GetDoublev (offset 260) */
    "ip\0"
    "glGetDoublev\0"
    "\0"
-   /* _mesa_function_pool[19258]: MultMatrixd (offset 295) */
+   /* _mesa_function_pool[19419]: MultMatrixd (offset 295) */
    "p\0"
    "glMultMatrixd\0"
    "\0"
-   /* _mesa_function_pool[19275]: MultMatrixf (offset 294) */
+   /* _mesa_function_pool[19436]: MultMatrixf (offset 294) */
    "p\0"
    "glMultMatrixf\0"
    "\0"
-   /* _mesa_function_pool[19292]: TexCoord2fColor4ubVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[19453]: TexCoord2fColor4ubVertex3fSUN (dynamic) */
    "ffiiiifff\0"
    "glTexCoord2fColor4ubVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[19335]: Uniform1iARB (will be remapped) */
+   /* _mesa_function_pool[19496]: Uniform1iARB (will be remapped) */
    "ii\0"
    "glUniform1i\0"
    "glUniform1iARB\0"
    "\0"
-   /* _mesa_function_pool[19366]: VertexAttribPointerARB (will be remapped) */
+   /* _mesa_function_pool[19527]: VertexAttribPointerARB (will be remapped) */
    "iiiiip\0"
    "glVertexAttribPointer\0"
    "glVertexAttribPointerARB\0"
    "\0"
-   /* _mesa_function_pool[19421]: SharpenTexFuncSGIS (dynamic) */
+   /* _mesa_function_pool[19582]: SharpenTexFuncSGIS (dynamic) */
    "iip\0"
    "glSharpenTexFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[19447]: MultiTexCoord4fvARB (offset 403) */
+   /* _mesa_function_pool[19608]: MultiTexCoord4fvARB (offset 403) */
    "ip\0"
    "glMultiTexCoord4fv\0"
    "glMultiTexCoord4fvARB\0"
    "\0"
-   /* _mesa_function_pool[19492]: UniformMatrix2x3fv (will be remapped) */
+   /* _mesa_function_pool[19653]: UniformMatrix2x3fv (will be remapped) */
    "iiip\0"
    "glUniformMatrix2x3fv\0"
    "\0"
-   /* _mesa_function_pool[19519]: TrackMatrixNV (will be remapped) */
+   /* _mesa_function_pool[19680]: TrackMatrixNV (will be remapped) */
    "iiii\0"
    "glTrackMatrixNV\0"
    "\0"
-   /* _mesa_function_pool[19541]: CombinerParameteriNV (will be remapped) */
+   /* _mesa_function_pool[19702]: CombinerParameteriNV (will be remapped) */
    "ii\0"
    "glCombinerParameteriNV\0"
    "\0"
-   /* _mesa_function_pool[19568]: DeleteAsyncMarkersSGIX (dynamic) */
+   /* _mesa_function_pool[19729]: DeleteAsyncMarkersSGIX (dynamic) */
    "ii\0"
    "glDeleteAsyncMarkersSGIX\0"
    "\0"
-   /* _mesa_function_pool[19597]: IsAsyncMarkerSGIX (dynamic) */
+   /* _mesa_function_pool[19758]: IsAsyncMarkerSGIX (dynamic) */
    "i\0"
    "glIsAsyncMarkerSGIX\0"
    "\0"
-   /* _mesa_function_pool[19620]: FrameZoomSGIX (dynamic) */
+   /* _mesa_function_pool[19781]: FrameZoomSGIX (dynamic) */
    "i\0"
    "glFrameZoomSGIX\0"
    "\0"
-   /* _mesa_function_pool[19639]: Normal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[19800]: Normal3fVertex3fvSUN (dynamic) */
    "pp\0"
    "glNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[19666]: RasterPos4sv (offset 85) */
+   /* _mesa_function_pool[19827]: RasterPos4sv (offset 85) */
    "p\0"
    "glRasterPos4sv\0"
    "\0"
-   /* _mesa_function_pool[19684]: VertexAttrib4NsvARB (will be remapped) */
+   /* _mesa_function_pool[19845]: VertexAttrib4NsvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4Nsv\0"
    "glVertexAttrib4NsvARB\0"
    "\0"
-   /* _mesa_function_pool[19729]: VertexAttrib3fvARB (will be remapped) */
+   /* _mesa_function_pool[19890]: VertexAttrib3fvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib3fv\0"
    "glVertexAttrib3fvARB\0"
    "\0"
-   /* _mesa_function_pool[19772]: ClearColor (offset 206) */
+   /* _mesa_function_pool[19933]: ClearColor (offset 206) */
    "ffff\0"
    "glClearColor\0"
    "\0"
-   /* _mesa_function_pool[19791]: GetSynciv (will be remapped) */
+   /* _mesa_function_pool[19952]: GetSynciv (will be remapped) */
    "iiipp\0"
    "glGetSynciv\0"
    "\0"
-   /* _mesa_function_pool[19810]: DeleteFramebuffersEXT (will be remapped) */
+   /* _mesa_function_pool[19971]: DeleteFramebuffersEXT (will be remapped) */
    "ip\0"
    "glDeleteFramebuffers\0"
    "glDeleteFramebuffersEXT\0"
    "\0"
-   /* _mesa_function_pool[19859]: GlobalAlphaFactorsSUN (dynamic) */
+   /* _mesa_function_pool[20020]: GlobalAlphaFactorsSUN (dynamic) */
    "i\0"
    "glGlobalAlphaFactorsSUN\0"
    "\0"
-   /* _mesa_function_pool[19886]: TexEnviv (offset 187) */
+   /* _mesa_function_pool[20047]: IsEnabledIndexedEXT (will be remapped) */
+   "ii\0"
+   "glIsEnabledIndexedEXT\0"
+   "\0"
+   /* _mesa_function_pool[20073]: TexEnviv (offset 187) */
    "iip\0"
    "glTexEnviv\0"
    "\0"
-   /* _mesa_function_pool[19902]: TexSubImage3D (offset 372) */
+   /* _mesa_function_pool[20089]: TexSubImage3D (offset 372) */
    "iiiiiiiiiip\0"
    "glTexSubImage3D\0"
    "glTexSubImage3DEXT\0"
    "\0"
-   /* _mesa_function_pool[19950]: Tangent3fEXT (dynamic) */
+   /* _mesa_function_pool[20137]: Tangent3fEXT (dynamic) */
    "fff\0"
    "glTangent3fEXT\0"
    "\0"
-   /* _mesa_function_pool[19970]: SecondaryColor3uivEXT (will be remapped) */
+   /* _mesa_function_pool[20157]: SecondaryColor3uivEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3uiv\0"
    "glSecondaryColor3uivEXT\0"
    "\0"
-   /* _mesa_function_pool[20018]: MatrixIndexubvARB (dynamic) */
+   /* _mesa_function_pool[20205]: MatrixIndexubvARB (dynamic) */
    "ip\0"
    "glMatrixIndexubvARB\0"
    "\0"
-   /* _mesa_function_pool[20042]: Color4fNormal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[20229]: Color4fNormal3fVertex3fSUN (dynamic) */
    "ffffffffff\0"
    "glColor4fNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[20083]: PixelTexGenParameterfSGIS (will be remapped) */
+   /* _mesa_function_pool[20270]: PixelTexGenParameterfSGIS (will be remapped) */
    "if\0"
    "glPixelTexGenParameterfSGIS\0"
    "\0"
-   /* _mesa_function_pool[20115]: CreateShader (will be remapped) */
+   /* _mesa_function_pool[20302]: CreateShader (will be remapped) */
    "i\0"
    "glCreateShader\0"
    "\0"
-   /* _mesa_function_pool[20133]: GetColorTableParameterfv (offset 344) */
+   /* _mesa_function_pool[20320]: GetColorTableParameterfv (offset 344) */
    "iip\0"
    "glGetColorTableParameterfv\0"
    "glGetColorTableParameterfvSGI\0"
    "glGetColorTableParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[20225]: FragmentLightModelfvSGIX (dynamic) */
+   /* _mesa_function_pool[20412]: FragmentLightModelfvSGIX (dynamic) */
    "ip\0"
    "glFragmentLightModelfvSGIX\0"
    "\0"
-   /* _mesa_function_pool[20256]: Bitmap (offset 8) */
+   /* _mesa_function_pool[20443]: Bitmap (offset 8) */
    "iiffffp\0"
    "glBitmap\0"
    "\0"
-   /* _mesa_function_pool[20274]: MultiTexCoord3fARB (offset 394) */
+   /* _mesa_function_pool[20461]: MultiTexCoord3fARB (offset 394) */
    "ifff\0"
    "glMultiTexCoord3f\0"
    "glMultiTexCoord3fARB\0"
    "\0"
-   /* _mesa_function_pool[20319]: GetTexLevelParameterfv (offset 284) */
+   /* _mesa_function_pool[20506]: GetTexLevelParameterfv (offset 284) */
    "iiip\0"
    "glGetTexLevelParameterfv\0"
    "\0"
-   /* _mesa_function_pool[20350]: GetPixelTexGenParameterfvSGIS (will be remapped) */
+   /* _mesa_function_pool[20537]: GetPixelTexGenParameterfvSGIS (will be remapped) */
    "ip\0"
    "glGetPixelTexGenParameterfvSGIS\0"
    "\0"
-   /* _mesa_function_pool[20386]: GenFramebuffersEXT (will be remapped) */
+   /* _mesa_function_pool[20573]: GenFramebuffersEXT (will be remapped) */
    "ip\0"
    "glGenFramebuffers\0"
    "glGenFramebuffersEXT\0"
    "\0"
-   /* _mesa_function_pool[20429]: GetProgramParameterdvNV (will be remapped) */
+   /* _mesa_function_pool[20616]: GetProgramParameterdvNV (will be remapped) */
    "iiip\0"
    "glGetProgramParameterdvNV\0"
    "\0"
-   /* _mesa_function_pool[20461]: Vertex2sv (offset 133) */
+   /* _mesa_function_pool[20648]: Vertex2sv (offset 133) */
    "p\0"
    "glVertex2sv\0"
    "\0"
-   /* _mesa_function_pool[20476]: GetIntegerv (offset 263) */
+   /* _mesa_function_pool[20663]: GetIntegerv (offset 263) */
    "ip\0"
    "glGetIntegerv\0"
    "\0"
-   /* _mesa_function_pool[20494]: IsVertexArrayAPPLE (will be remapped) */
+   /* _mesa_function_pool[20681]: IsVertexArrayAPPLE (will be remapped) */
    "i\0"
    "glIsVertexArray\0"
    "glIsVertexArrayAPPLE\0"
    "\0"
-   /* _mesa_function_pool[20534]: FragmentLightfvSGIX (dynamic) */
+   /* _mesa_function_pool[20721]: FragmentLightfvSGIX (dynamic) */
    "iip\0"
    "glFragmentLightfvSGIX\0"
    "\0"
-   /* _mesa_function_pool[20561]: DetachShader (will be remapped) */
+   /* _mesa_function_pool[20748]: DetachShader (will be remapped) */
    "ii\0"
    "glDetachShader\0"
    "\0"
-   /* _mesa_function_pool[20580]: VertexAttrib4NubARB (will be remapped) */
+   /* _mesa_function_pool[20767]: VertexAttrib4NubARB (will be remapped) */
    "iiiii\0"
    "glVertexAttrib4Nub\0"
    "glVertexAttrib4NubARB\0"
    "\0"
-   /* _mesa_function_pool[20628]: GetProgramEnvParameterfvARB (will be remapped) */
+   /* _mesa_function_pool[20815]: GetProgramEnvParameterfvARB (will be remapped) */
    "iip\0"
    "glGetProgramEnvParameterfvARB\0"
    "\0"
-   /* _mesa_function_pool[20663]: GetTrackMatrixivNV (will be remapped) */
+   /* _mesa_function_pool[20850]: GetTrackMatrixivNV (will be remapped) */
    "iiip\0"
    "glGetTrackMatrixivNV\0"
    "\0"
-   /* _mesa_function_pool[20690]: VertexAttrib3svNV (will be remapped) */
+   /* _mesa_function_pool[20877]: VertexAttrib3svNV (will be remapped) */
    "ip\0"
    "glVertexAttrib3svNV\0"
    "\0"
-   /* _mesa_function_pool[20714]: Uniform4fvARB (will be remapped) */
+   /* _mesa_function_pool[20901]: Uniform4fvARB (will be remapped) */
    "iip\0"
    "glUniform4fv\0"
    "glUniform4fvARB\0"
    "\0"
-   /* _mesa_function_pool[20748]: MultTransposeMatrixfARB (will be remapped) */
+   /* _mesa_function_pool[20935]: MultTransposeMatrixfARB (will be remapped) */
    "p\0"
    "glMultTransposeMatrixf\0"
    "glMultTransposeMatrixfARB\0"
    "\0"
-   /* _mesa_function_pool[20800]: GetTexEnviv (offset 277) */
+   /* _mesa_function_pool[20987]: GetTexEnviv (offset 277) */
    "iip\0"
    "glGetTexEnviv\0"
    "\0"
-   /* _mesa_function_pool[20819]: ColorFragmentOp1ATI (will be remapped) */
+   /* _mesa_function_pool[21006]: ColorFragmentOp1ATI (will be remapped) */
    "iiiiiii\0"
    "glColorFragmentOp1ATI\0"
    "\0"
-   /* _mesa_function_pool[20850]: GetUniformfvARB (will be remapped) */
+   /* _mesa_function_pool[21037]: GetUniformfvARB (will be remapped) */
    "iip\0"
    "glGetUniformfv\0"
    "glGetUniformfvARB\0"
    "\0"
-   /* _mesa_function_pool[20888]: PopClientAttrib (offset 334) */
+   /* _mesa_function_pool[21075]: PopClientAttrib (offset 334) */
    "\0"
    "glPopClientAttrib\0"
    "\0"
-   /* _mesa_function_pool[20908]: ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[21095]: ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (dynamic) */
    "iffffffffffff\0"
    "glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[20979]: DetachObjectARB (will be remapped) */
+   /* _mesa_function_pool[21166]: DetachObjectARB (will be remapped) */
    "ii\0"
    "glDetachObjectARB\0"
    "\0"
-   /* _mesa_function_pool[21001]: VertexBlendARB (dynamic) */
+   /* _mesa_function_pool[21188]: VertexBlendARB (dynamic) */
    "i\0"
    "glVertexBlendARB\0"
    "\0"
-   /* _mesa_function_pool[21021]: WindowPos3iMESA (will be remapped) */
+   /* _mesa_function_pool[21208]: WindowPos3iMESA (will be remapped) */
    "iii\0"
    "glWindowPos3i\0"
    "glWindowPos3iARB\0"
    "glWindowPos3iMESA\0"
    "\0"
-   /* _mesa_function_pool[21075]: SeparableFilter2D (offset 360) */
+   /* _mesa_function_pool[21262]: SeparableFilter2D (offset 360) */
    "iiiiiipp\0"
    "glSeparableFilter2D\0"
    "glSeparableFilter2DEXT\0"
    "\0"
-   /* _mesa_function_pool[21128]: ReplacementCodeuiColor4ubVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[21315]: ReplacementCodeuiColor4ubVertex3fvSUN (dynamic) */
    "ppp\0"
    "glReplacementCodeuiColor4ubVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[21173]: Map1d (offset 220) */
+   /* _mesa_function_pool[21360]: Map1d (offset 220) */
    "iddiip\0"
    "glMap1d\0"
    "\0"
-   /* _mesa_function_pool[21189]: Map1f (offset 221) */
+   /* _mesa_function_pool[21376]: Map1f (offset 221) */
    "iffiip\0"
    "glMap1f\0"
    "\0"
-   /* _mesa_function_pool[21205]: CompressedTexImage2DARB (will be remapped) */
+   /* _mesa_function_pool[21392]: CompressedTexImage2DARB (will be remapped) */
    "iiiiiiip\0"
    "glCompressedTexImage2D\0"
    "glCompressedTexImage2DARB\0"
    "\0"
-   /* _mesa_function_pool[21264]: ArrayElement (offset 306) */
+   /* _mesa_function_pool[21451]: ArrayElement (offset 306) */
    "i\0"
    "glArrayElement\0"
    "glArrayElementEXT\0"
    "\0"
-   /* _mesa_function_pool[21300]: TexImage2D (offset 183) */
+   /* _mesa_function_pool[21487]: TexImage2D (offset 183) */
    "iiiiiiiip\0"
    "glTexImage2D\0"
    "\0"
-   /* _mesa_function_pool[21324]: DepthBoundsEXT (will be remapped) */
+   /* _mesa_function_pool[21511]: DepthBoundsEXT (will be remapped) */
    "dd\0"
    "glDepthBoundsEXT\0"
    "\0"
-   /* _mesa_function_pool[21345]: ProgramParameters4fvNV (will be remapped) */
+   /* _mesa_function_pool[21532]: ProgramParameters4fvNV (will be remapped) */
    "iiip\0"
    "glProgramParameters4fvNV\0"
    "\0"
-   /* _mesa_function_pool[21376]: DeformationMap3fSGIX (dynamic) */
+   /* _mesa_function_pool[21563]: DeformationMap3fSGIX (dynamic) */
    "iffiiffiiffiip\0"
    "glDeformationMap3fSGIX\0"
    "\0"
-   /* _mesa_function_pool[21415]: GetProgramivNV (will be remapped) */
+   /* _mesa_function_pool[21602]: GetProgramivNV (will be remapped) */
    "iip\0"
    "glGetProgramivNV\0"
    "\0"
-   /* _mesa_function_pool[21437]: GetMinmaxParameteriv (offset 366) */
+   /* _mesa_function_pool[21624]: GetMinmaxParameteriv (offset 366) */
    "iip\0"
    "glGetMinmaxParameteriv\0"
    "glGetMinmaxParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[21491]: PixelTransferf (offset 247) */
+   /* _mesa_function_pool[21678]: PixelTransferf (offset 247) */
    "if\0"
    "glPixelTransferf\0"
    "\0"
-   /* _mesa_function_pool[21512]: CopyTexImage1D (offset 323) */
+   /* _mesa_function_pool[21699]: CopyTexImage1D (offset 323) */
    "iiiiiii\0"
    "glCopyTexImage1D\0"
    "glCopyTexImage1DEXT\0"
    "\0"
-   /* _mesa_function_pool[21558]: PushMatrix (offset 298) */
+   /* _mesa_function_pool[21745]: PushMatrix (offset 298) */
    "\0"
    "glPushMatrix\0"
    "\0"
-   /* _mesa_function_pool[21573]: Fogiv (offset 156) */
+   /* _mesa_function_pool[21760]: Fogiv (offset 156) */
    "ip\0"
    "glFogiv\0"
    "\0"
-   /* _mesa_function_pool[21585]: TexCoord1dv (offset 95) */
+   /* _mesa_function_pool[21772]: TexCoord1dv (offset 95) */
    "p\0"
    "glTexCoord1dv\0"
    "\0"
-   /* _mesa_function_pool[21602]: AlphaFragmentOp3ATI (will be remapped) */
+   /* _mesa_function_pool[21789]: AlphaFragmentOp3ATI (will be remapped) */
    "iiiiiiiiiiii\0"
    "glAlphaFragmentOp3ATI\0"
    "\0"
-   /* _mesa_function_pool[21638]: PixelTransferi (offset 248) */
+   /* _mesa_function_pool[21825]: PixelTransferi (offset 248) */
    "ii\0"
    "glPixelTransferi\0"
    "\0"
-   /* _mesa_function_pool[21659]: GetVertexAttribdvNV (will be remapped) */
+   /* _mesa_function_pool[21846]: GetVertexAttribdvNV (will be remapped) */
    "iip\0"
    "glGetVertexAttribdvNV\0"
    "\0"
-   /* _mesa_function_pool[21686]: VertexAttrib3fvNV (will be remapped) */
+   /* _mesa_function_pool[21873]: VertexAttrib3fvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib3fvNV\0"
    "\0"
-   /* _mesa_function_pool[21710]: Rotatef (offset 300) */
+   /* _mesa_function_pool[21897]: Rotatef (offset 300) */
    "ffff\0"
    "glRotatef\0"
    "\0"
-   /* _mesa_function_pool[21726]: GetFinalCombinerInputParameterivNV (will be remapped) */
+   /* _mesa_function_pool[21913]: GetFinalCombinerInputParameterivNV (will be remapped) */
    "iip\0"
    "glGetFinalCombinerInputParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[21768]: Vertex3i (offset 138) */
+   /* _mesa_function_pool[21955]: Vertex3i (offset 138) */
    "iii\0"
    "glVertex3i\0"
    "\0"
-   /* _mesa_function_pool[21784]: Vertex3f (offset 136) */
+   /* _mesa_function_pool[21971]: Vertex3f (offset 136) */
    "fff\0"
    "glVertex3f\0"
    "\0"
-   /* _mesa_function_pool[21800]: Clear (offset 203) */
+   /* _mesa_function_pool[21987]: Clear (offset 203) */
    "i\0"
    "glClear\0"
    "\0"
-   /* _mesa_function_pool[21811]: Vertex3d (offset 134) */
+   /* _mesa_function_pool[21998]: Vertex3d (offset 134) */
    "ddd\0"
    "glVertex3d\0"
    "\0"
-   /* _mesa_function_pool[21827]: GetMapParameterivNV (dynamic) */
+   /* _mesa_function_pool[22014]: GetMapParameterivNV (dynamic) */
    "iip\0"
    "glGetMapParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[21854]: Uniform4iARB (will be remapped) */
+   /* _mesa_function_pool[22041]: Uniform4iARB (will be remapped) */
    "iiiii\0"
    "glUniform4i\0"
    "glUniform4iARB\0"
    "\0"
-   /* _mesa_function_pool[21888]: ReadBuffer (offset 254) */
+   /* _mesa_function_pool[22075]: ReadBuffer (offset 254) */
    "i\0"
    "glReadBuffer\0"
    "\0"
-   /* _mesa_function_pool[21904]: ConvolutionParameteri (offset 352) */
+   /* _mesa_function_pool[22091]: ConvolutionParameteri (offset 352) */
    "iii\0"
    "glConvolutionParameteri\0"
    "glConvolutionParameteriEXT\0"
    "\0"
-   /* _mesa_function_pool[21960]: Ortho (offset 296) */
+   /* _mesa_function_pool[22147]: Ortho (offset 296) */
    "dddddd\0"
    "glOrtho\0"
    "\0"
-   /* _mesa_function_pool[21976]: Binormal3sEXT (dynamic) */
+   /* _mesa_function_pool[22163]: Binormal3sEXT (dynamic) */
    "iii\0"
    "glBinormal3sEXT\0"
    "\0"
-   /* _mesa_function_pool[21997]: ListBase (offset 6) */
+   /* _mesa_function_pool[22184]: ListBase (offset 6) */
    "i\0"
    "glListBase\0"
    "\0"
-   /* _mesa_function_pool[22011]: Vertex3s (offset 140) */
+   /* _mesa_function_pool[22198]: Vertex3s (offset 140) */
    "iii\0"
    "glVertex3s\0"
    "\0"
-   /* _mesa_function_pool[22027]: ConvolutionParameterf (offset 350) */
+   /* _mesa_function_pool[22214]: ConvolutionParameterf (offset 350) */
    "iif\0"
    "glConvolutionParameterf\0"
    "glConvolutionParameterfEXT\0"
    "\0"
-   /* _mesa_function_pool[22083]: GetColorTableParameteriv (offset 345) */
+   /* _mesa_function_pool[22270]: GetColorTableParameteriv (offset 345) */
    "iip\0"
    "glGetColorTableParameteriv\0"
    "glGetColorTableParameterivSGI\0"
    "glGetColorTableParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[22175]: ProgramEnvParameter4dvARB (will be remapped) */
+   /* _mesa_function_pool[22362]: ProgramEnvParameter4dvARB (will be remapped) */
    "iip\0"
    "glProgramEnvParameter4dvARB\0"
    "glProgramParameter4dvNV\0"
    "\0"
-   /* _mesa_function_pool[22232]: ShadeModel (offset 177) */
+   /* _mesa_function_pool[22419]: ShadeModel (offset 177) */
    "i\0"
    "glShadeModel\0"
    "\0"
-   /* _mesa_function_pool[22248]: VertexAttribs2fvNV (will be remapped) */
+   /* _mesa_function_pool[22435]: VertexAttribs2fvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs2fvNV\0"
    "\0"
-   /* _mesa_function_pool[22274]: Rectiv (offset 91) */
+   /* _mesa_function_pool[22461]: Rectiv (offset 91) */
    "pp\0"
    "glRectiv\0"
    "\0"
-   /* _mesa_function_pool[22287]: UseProgramObjectARB (will be remapped) */
+   /* _mesa_function_pool[22474]: UseProgramObjectARB (will be remapped) */
    "i\0"
    "glUseProgram\0"
    "glUseProgramObjectARB\0"
    "\0"
-   /* _mesa_function_pool[22325]: GetMapParameterfvNV (dynamic) */
+   /* _mesa_function_pool[22512]: GetMapParameterfvNV (dynamic) */
    "iip\0"
    "glGetMapParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[22352]: PassTexCoordATI (will be remapped) */
+   /* _mesa_function_pool[22539]: EndConditionalRenderNV (will be remapped) */
+   "\0"
+   "glEndConditionalRenderNV\0"
+   "\0"
+   /* _mesa_function_pool[22566]: PassTexCoordATI (will be remapped) */
    "iii\0"
    "glPassTexCoordATI\0"
    "\0"
-   /* _mesa_function_pool[22375]: DeleteProgram (will be remapped) */
+   /* _mesa_function_pool[22589]: DeleteProgram (will be remapped) */
    "i\0"
    "glDeleteProgram\0"
    "\0"
-   /* _mesa_function_pool[22394]: Tangent3ivEXT (dynamic) */
+   /* _mesa_function_pool[22608]: Tangent3ivEXT (dynamic) */
    "p\0"
    "glTangent3ivEXT\0"
    "\0"
-   /* _mesa_function_pool[22413]: Tangent3dEXT (dynamic) */
+   /* _mesa_function_pool[22627]: Tangent3dEXT (dynamic) */
    "ddd\0"
    "glTangent3dEXT\0"
    "\0"
-   /* _mesa_function_pool[22433]: SecondaryColor3dvEXT (will be remapped) */
+   /* _mesa_function_pool[22647]: SecondaryColor3dvEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3dv\0"
    "glSecondaryColor3dvEXT\0"
    "\0"
-   /* _mesa_function_pool[22479]: Vertex2fv (offset 129) */
+   /* _mesa_function_pool[22693]: Vertex2fv (offset 129) */
    "p\0"
    "glVertex2fv\0"
    "\0"
-   /* _mesa_function_pool[22494]: MultiDrawArraysEXT (will be remapped) */
+   /* _mesa_function_pool[22708]: MultiDrawArraysEXT (will be remapped) */
    "ippi\0"
    "glMultiDrawArrays\0"
    "glMultiDrawArraysEXT\0"
    "\0"
-   /* _mesa_function_pool[22539]: BindRenderbufferEXT (will be remapped) */
+   /* _mesa_function_pool[22753]: BindRenderbufferEXT (will be remapped) */
    "ii\0"
    "glBindRenderbuffer\0"
    "glBindRenderbufferEXT\0"
    "\0"
-   /* _mesa_function_pool[22584]: MultiTexCoord4dARB (offset 400) */
+   /* _mesa_function_pool[22798]: MultiTexCoord4dARB (offset 400) */
    "idddd\0"
    "glMultiTexCoord4d\0"
    "glMultiTexCoord4dARB\0"
    "\0"
-   /* _mesa_function_pool[22630]: Vertex3sv (offset 141) */
+   /* _mesa_function_pool[22844]: Vertex3sv (offset 141) */
    "p\0"
    "glVertex3sv\0"
    "\0"
-   /* _mesa_function_pool[22645]: SecondaryColor3usEXT (will be remapped) */
+   /* _mesa_function_pool[22859]: SecondaryColor3usEXT (will be remapped) */
    "iii\0"
    "glSecondaryColor3us\0"
    "glSecondaryColor3usEXT\0"
    "\0"
-   /* _mesa_function_pool[22693]: ProgramLocalParameter4fvARB (will be remapped) */
+   /* _mesa_function_pool[22907]: ProgramLocalParameter4fvARB (will be remapped) */
    "iip\0"
    "glProgramLocalParameter4fvARB\0"
    "\0"
-   /* _mesa_function_pool[22728]: DeleteProgramsNV (will be remapped) */
+   /* _mesa_function_pool[22942]: DeleteProgramsNV (will be remapped) */
    "ip\0"
    "glDeleteProgramsARB\0"
    "glDeleteProgramsNV\0"
    "\0"
-   /* _mesa_function_pool[22771]: EvalMesh1 (offset 236) */
+   /* _mesa_function_pool[22985]: EvalMesh1 (offset 236) */
    "iii\0"
    "glEvalMesh1\0"
    "\0"
-   /* _mesa_function_pool[22788]: MultiTexCoord1sARB (offset 382) */
+   /* _mesa_function_pool[23002]: MultiTexCoord1sARB (offset 382) */
    "ii\0"
    "glMultiTexCoord1s\0"
    "glMultiTexCoord1sARB\0"
    "\0"
-   /* _mesa_function_pool[22831]: ReplacementCodeuiColor3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[23045]: ReplacementCodeuiColor3fVertex3fSUN (dynamic) */
    "iffffff\0"
    "glReplacementCodeuiColor3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[22878]: GetVertexAttribPointervNV (will be remapped) */
+   /* _mesa_function_pool[23092]: GetVertexAttribPointervNV (will be remapped) */
    "iip\0"
    "glGetVertexAttribPointerv\0"
    "glGetVertexAttribPointervARB\0"
    "glGetVertexAttribPointervNV\0"
    "\0"
-   /* _mesa_function_pool[22966]: MultiTexCoord1dvARB (offset 377) */
+   /* _mesa_function_pool[23180]: DisableIndexedEXT (will be remapped) */
+   "ii\0"
+   "glDisableIndexedEXT\0"
+   "\0"
+   /* _mesa_function_pool[23204]: MultiTexCoord1dvARB (offset 377) */
    "ip\0"
    "glMultiTexCoord1dv\0"
    "glMultiTexCoord1dvARB\0"
    "\0"
-   /* _mesa_function_pool[23011]: Uniform2iARB (will be remapped) */
+   /* _mesa_function_pool[23249]: Uniform2iARB (will be remapped) */
    "iii\0"
    "glUniform2i\0"
    "glUniform2iARB\0"
    "\0"
-   /* _mesa_function_pool[23043]: Vertex2iv (offset 131) */
+   /* _mesa_function_pool[23281]: Vertex2iv (offset 131) */
    "p\0"
    "glVertex2iv\0"
    "\0"
-   /* _mesa_function_pool[23058]: GetProgramStringNV (will be remapped) */
+   /* _mesa_function_pool[23296]: GetProgramStringNV (will be remapped) */
    "iip\0"
    "glGetProgramStringNV\0"
    "\0"
-   /* _mesa_function_pool[23084]: ColorPointerEXT (will be remapped) */
+   /* _mesa_function_pool[23322]: ColorPointerEXT (will be remapped) */
    "iiiip\0"
    "glColorPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[23109]: LineWidth (offset 168) */
+   /* _mesa_function_pool[23347]: LineWidth (offset 168) */
    "f\0"
    "glLineWidth\0"
    "\0"
-   /* _mesa_function_pool[23124]: MapBufferARB (will be remapped) */
+   /* _mesa_function_pool[23362]: MapBufferARB (will be remapped) */
    "ii\0"
    "glMapBuffer\0"
    "glMapBufferARB\0"
    "\0"
-   /* _mesa_function_pool[23155]: MultiDrawElementsBaseVertex (will be remapped) */
+   /* _mesa_function_pool[23393]: MultiDrawElementsBaseVertex (will be remapped) */
    "ipipip\0"
    "glMultiDrawElementsBaseVertex\0"
    "\0"
-   /* _mesa_function_pool[23193]: Binormal3svEXT (dynamic) */
+   /* _mesa_function_pool[23431]: Binormal3svEXT (dynamic) */
    "p\0"
    "glBinormal3svEXT\0"
    "\0"
-   /* _mesa_function_pool[23213]: ApplyTextureEXT (dynamic) */
+   /* _mesa_function_pool[23451]: ApplyTextureEXT (dynamic) */
    "i\0"
    "glApplyTextureEXT\0"
    "\0"
-   /* _mesa_function_pool[23234]: TexGendv (offset 189) */
+   /* _mesa_function_pool[23472]: TexGendv (offset 189) */
    "iip\0"
    "glTexGendv\0"
    "\0"
-   /* _mesa_function_pool[23250]: TextureMaterialEXT (dynamic) */
+   /* _mesa_function_pool[23488]: EnableIndexedEXT (will be remapped) */
+   "ii\0"
+   "glEnableIndexedEXT\0"
+   "\0"
+   /* _mesa_function_pool[23511]: TextureMaterialEXT (dynamic) */
    "ii\0"
    "glTextureMaterialEXT\0"
    "\0"
-   /* _mesa_function_pool[23275]: TextureLightEXT (dynamic) */
+   /* _mesa_function_pool[23536]: TextureLightEXT (dynamic) */
    "i\0"
    "glTextureLightEXT\0"
    "\0"
-   /* _mesa_function_pool[23296]: ResetMinmax (offset 370) */
+   /* _mesa_function_pool[23557]: ResetMinmax (offset 370) */
    "i\0"
    "glResetMinmax\0"
    "glResetMinmaxEXT\0"
    "\0"
-   /* _mesa_function_pool[23330]: SpriteParameterfSGIX (dynamic) */
+   /* _mesa_function_pool[23591]: SpriteParameterfSGIX (dynamic) */
    "if\0"
    "glSpriteParameterfSGIX\0"
    "\0"
-   /* _mesa_function_pool[23357]: EnableClientState (offset 313) */
+   /* _mesa_function_pool[23618]: EnableClientState (offset 313) */
    "i\0"
    "glEnableClientState\0"
    "\0"
-   /* _mesa_function_pool[23380]: VertexAttrib4sNV (will be remapped) */
+   /* _mesa_function_pool[23641]: VertexAttrib4sNV (will be remapped) */
    "iiiii\0"
    "glVertexAttrib4sNV\0"
    "\0"
-   /* _mesa_function_pool[23406]: GetConvolutionParameterfv (offset 357) */
+   /* _mesa_function_pool[23667]: GetConvolutionParameterfv (offset 357) */
    "iip\0"
    "glGetConvolutionParameterfv\0"
    "glGetConvolutionParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[23470]: VertexAttribs4dvNV (will be remapped) */
+   /* _mesa_function_pool[23731]: VertexAttribs4dvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs4dvNV\0"
    "\0"
-   /* _mesa_function_pool[23496]: VertexAttrib4dARB (will be remapped) */
+   /* _mesa_function_pool[23757]: MultiModeDrawArraysIBM (will be remapped) */
+   "pppii\0"
+   "glMultiModeDrawArraysIBM\0"
+   "\0"
+   /* _mesa_function_pool[23789]: VertexAttrib4dARB (will be remapped) */
    "idddd\0"
    "glVertexAttrib4d\0"
    "glVertexAttrib4dARB\0"
    "\0"
-   /* _mesa_function_pool[23540]: GetTexBumpParameterfvATI (will be remapped) */
+   /* _mesa_function_pool[23833]: GetTexBumpParameterfvATI (will be remapped) */
    "ip\0"
    "glGetTexBumpParameterfvATI\0"
    "\0"
-   /* _mesa_function_pool[23571]: ProgramNamedParameter4dNV (will be remapped) */
+   /* _mesa_function_pool[23864]: ProgramNamedParameter4dNV (will be remapped) */
    "iipdddd\0"
    "glProgramNamedParameter4dNV\0"
    "\0"
-   /* _mesa_function_pool[23608]: GetMaterialfv (offset 269) */
+   /* _mesa_function_pool[23901]: GetMaterialfv (offset 269) */
    "iip\0"
    "glGetMaterialfv\0"
    "\0"
-   /* _mesa_function_pool[23629]: VertexWeightfEXT (dynamic) */
+   /* _mesa_function_pool[23922]: VertexWeightfEXT (dynamic) */
    "f\0"
    "glVertexWeightfEXT\0"
    "\0"
-   /* _mesa_function_pool[23651]: Binormal3fEXT (dynamic) */
+   /* _mesa_function_pool[23944]: Binormal3fEXT (dynamic) */
    "fff\0"
    "glBinormal3fEXT\0"
    "\0"
-   /* _mesa_function_pool[23672]: CallList (offset 2) */
+   /* _mesa_function_pool[23965]: CallList (offset 2) */
    "i\0"
    "glCallList\0"
    "\0"
-   /* _mesa_function_pool[23686]: Materialfv (offset 170) */
+   /* _mesa_function_pool[23979]: Materialfv (offset 170) */
    "iip\0"
    "glMaterialfv\0"
    "\0"
-   /* _mesa_function_pool[23704]: TexCoord3fv (offset 113) */
+   /* _mesa_function_pool[23997]: TexCoord3fv (offset 113) */
    "p\0"
    "glTexCoord3fv\0"
    "\0"
-   /* _mesa_function_pool[23721]: FogCoordfvEXT (will be remapped) */
+   /* _mesa_function_pool[24014]: FogCoordfvEXT (will be remapped) */
    "p\0"
    "glFogCoordfv\0"
    "glFogCoordfvEXT\0"
    "\0"
-   /* _mesa_function_pool[23753]: MultiTexCoord1ivARB (offset 381) */
+   /* _mesa_function_pool[24046]: MultiTexCoord1ivARB (offset 381) */
    "ip\0"
    "glMultiTexCoord1iv\0"
    "glMultiTexCoord1ivARB\0"
    "\0"
-   /* _mesa_function_pool[23798]: SecondaryColor3ubEXT (will be remapped) */
+   /* _mesa_function_pool[24091]: SecondaryColor3ubEXT (will be remapped) */
    "iii\0"
    "glSecondaryColor3ub\0"
    "glSecondaryColor3ubEXT\0"
    "\0"
-   /* _mesa_function_pool[23846]: MultiTexCoord2ivARB (offset 389) */
+   /* _mesa_function_pool[24139]: MultiTexCoord2ivARB (offset 389) */
    "ip\0"
    "glMultiTexCoord2iv\0"
    "glMultiTexCoord2ivARB\0"
    "\0"
-   /* _mesa_function_pool[23891]: FogFuncSGIS (dynamic) */
+   /* _mesa_function_pool[24184]: FogFuncSGIS (dynamic) */
    "ip\0"
    "glFogFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[23909]: CopyTexSubImage2D (offset 326) */
+   /* _mesa_function_pool[24202]: CopyTexSubImage2D (offset 326) */
    "iiiiiiii\0"
    "glCopyTexSubImage2D\0"
    "glCopyTexSubImage2DEXT\0"
    "\0"
-   /* _mesa_function_pool[23962]: GetObjectParameterivARB (will be remapped) */
+   /* _mesa_function_pool[24255]: GetObjectParameterivARB (will be remapped) */
    "iip\0"
    "glGetObjectParameterivARB\0"
    "\0"
-   /* _mesa_function_pool[23993]: Color3iv (offset 16) */
+   /* _mesa_function_pool[24286]: Color3iv (offset 16) */
    "p\0"
    "glColor3iv\0"
    "\0"
-   /* _mesa_function_pool[24007]: TexCoord4fVertex4fSUN (dynamic) */
+   /* _mesa_function_pool[24300]: TexCoord4fVertex4fSUN (dynamic) */
    "ffffffff\0"
    "glTexCoord4fVertex4fSUN\0"
    "\0"
-   /* _mesa_function_pool[24041]: DrawElements (offset 311) */
+   /* _mesa_function_pool[24334]: DrawElements (offset 311) */
    "iiip\0"
    "glDrawElements\0"
    "\0"
-   /* _mesa_function_pool[24062]: BindVertexArrayAPPLE (will be remapped) */
+   /* _mesa_function_pool[24355]: BindVertexArrayAPPLE (will be remapped) */
    "i\0"
    "glBindVertexArrayAPPLE\0"
    "\0"
-   /* _mesa_function_pool[24088]: GetProgramLocalParameterdvARB (will be remapped) */
+   /* _mesa_function_pool[24381]: GetProgramLocalParameterdvARB (will be remapped) */
    "iip\0"
    "glGetProgramLocalParameterdvARB\0"
    "\0"
-   /* _mesa_function_pool[24125]: GetHistogramParameteriv (offset 363) */
+   /* _mesa_function_pool[24418]: GetHistogramParameteriv (offset 363) */
    "iip\0"
    "glGetHistogramParameteriv\0"
    "glGetHistogramParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[24185]: MultiTexCoord1iARB (offset 380) */
+   /* _mesa_function_pool[24478]: MultiTexCoord1iARB (offset 380) */
    "ii\0"
    "glMultiTexCoord1i\0"
    "glMultiTexCoord1iARB\0"
    "\0"
-   /* _mesa_function_pool[24228]: GetConvolutionFilter (offset 356) */
+   /* _mesa_function_pool[24521]: GetConvolutionFilter (offset 356) */
    "iiip\0"
    "glGetConvolutionFilter\0"
    "glGetConvolutionFilterEXT\0"
    "\0"
-   /* _mesa_function_pool[24283]: GetProgramivARB (will be remapped) */
+   /* _mesa_function_pool[24576]: GetProgramivARB (will be remapped) */
    "iip\0"
    "glGetProgramivARB\0"
    "\0"
-   /* _mesa_function_pool[24306]: BlendFuncSeparateEXT (will be remapped) */
+   /* _mesa_function_pool[24599]: BlendFuncSeparateEXT (will be remapped) */
    "iiii\0"
    "glBlendFuncSeparate\0"
    "glBlendFuncSeparateEXT\0"
    "glBlendFuncSeparateINGR\0"
    "\0"
-   /* _mesa_function_pool[24379]: MapBufferRange (will be remapped) */
+   /* _mesa_function_pool[24672]: MapBufferRange (will be remapped) */
    "iiii\0"
    "glMapBufferRange\0"
    "\0"
-   /* _mesa_function_pool[24402]: ProgramParameters4dvNV (will be remapped) */
+   /* _mesa_function_pool[24695]: ProgramParameters4dvNV (will be remapped) */
    "iiip\0"
    "glProgramParameters4dvNV\0"
    "\0"
-   /* _mesa_function_pool[24433]: TexCoord2fColor3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[24726]: TexCoord2fColor3fVertex3fvSUN (dynamic) */
    "ppp\0"
    "glTexCoord2fColor3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[24470]: EvalPoint2 (offset 239) */
+   /* _mesa_function_pool[24763]: EvalPoint2 (offset 239) */
    "ii\0"
    "glEvalPoint2\0"
    "\0"
-   /* _mesa_function_pool[24487]: EvalPoint1 (offset 237) */
+   /* _mesa_function_pool[24780]: EvalPoint1 (offset 237) */
    "i\0"
    "glEvalPoint1\0"
    "\0"
-   /* _mesa_function_pool[24503]: Binormal3dvEXT (dynamic) */
+   /* _mesa_function_pool[24796]: Binormal3dvEXT (dynamic) */
    "p\0"
    "glBinormal3dvEXT\0"
    "\0"
-   /* _mesa_function_pool[24523]: PopMatrix (offset 297) */
+   /* _mesa_function_pool[24816]: PopMatrix (offset 297) */
    "\0"
    "glPopMatrix\0"
    "\0"
-   /* _mesa_function_pool[24537]: FinishFenceNV (will be remapped) */
+   /* _mesa_function_pool[24830]: FinishFenceNV (will be remapped) */
    "i\0"
    "glFinishFenceNV\0"
    "\0"
-   /* _mesa_function_pool[24556]: GetFogFuncSGIS (dynamic) */
+   /* _mesa_function_pool[24849]: GetFogFuncSGIS (dynamic) */
    "p\0"
    "glGetFogFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[24576]: GetUniformLocationARB (will be remapped) */
+   /* _mesa_function_pool[24869]: GetUniformLocationARB (will be remapped) */
    "ip\0"
    "glGetUniformLocation\0"
    "glGetUniformLocationARB\0"
    "\0"
-   /* _mesa_function_pool[24625]: SecondaryColor3fEXT (will be remapped) */
+   /* _mesa_function_pool[24918]: SecondaryColor3fEXT (will be remapped) */
    "fff\0"
    "glSecondaryColor3f\0"
    "glSecondaryColor3fEXT\0"
    "\0"
-   /* _mesa_function_pool[24671]: GetTexGeniv (offset 280) */
+   /* _mesa_function_pool[24964]: GetTexGeniv (offset 280) */
    "iip\0"
    "glGetTexGeniv\0"
    "\0"
-   /* _mesa_function_pool[24690]: CombinerInputNV (will be remapped) */
+   /* _mesa_function_pool[24983]: CombinerInputNV (will be remapped) */
    "iiiiii\0"
    "glCombinerInputNV\0"
    "\0"
-   /* _mesa_function_pool[24716]: VertexAttrib3sARB (will be remapped) */
+   /* _mesa_function_pool[25009]: VertexAttrib3sARB (will be remapped) */
    "iiii\0"
    "glVertexAttrib3s\0"
    "glVertexAttrib3sARB\0"
    "\0"
-   /* _mesa_function_pool[24759]: ReplacementCodeuiNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[25052]: ReplacementCodeuiNormal3fVertex3fvSUN (dynamic) */
    "ppp\0"
    "glReplacementCodeuiNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[24804]: Map2d (offset 222) */
+   /* _mesa_function_pool[25097]: Map2d (offset 222) */
    "iddiiddiip\0"
    "glMap2d\0"
    "\0"
-   /* _mesa_function_pool[24824]: Map2f (offset 223) */
+   /* _mesa_function_pool[25117]: Map2f (offset 223) */
    "iffiiffiip\0"
    "glMap2f\0"
    "\0"
-   /* _mesa_function_pool[24844]: ProgramStringARB (will be remapped) */
+   /* _mesa_function_pool[25137]: ProgramStringARB (will be remapped) */
    "iiip\0"
    "glProgramStringARB\0"
    "\0"
-   /* _mesa_function_pool[24869]: Vertex4s (offset 148) */
+   /* _mesa_function_pool[25162]: Vertex4s (offset 148) */
    "iiii\0"
    "glVertex4s\0"
    "\0"
-   /* _mesa_function_pool[24886]: TexCoord4fVertex4fvSUN (dynamic) */
+   /* _mesa_function_pool[25179]: TexCoord4fVertex4fvSUN (dynamic) */
    "pp\0"
    "glTexCoord4fVertex4fvSUN\0"
    "\0"
-   /* _mesa_function_pool[24915]: VertexAttrib3sNV (will be remapped) */
+   /* _mesa_function_pool[25208]: VertexAttrib3sNV (will be remapped) */
    "iiii\0"
    "glVertexAttrib3sNV\0"
    "\0"
-   /* _mesa_function_pool[24940]: VertexAttrib1fNV (will be remapped) */
+   /* _mesa_function_pool[25233]: VertexAttrib1fNV (will be remapped) */
    "if\0"
    "glVertexAttrib1fNV\0"
    "\0"
-   /* _mesa_function_pool[24963]: Vertex4f (offset 144) */
+   /* _mesa_function_pool[25256]: Vertex4f (offset 144) */
    "ffff\0"
    "glVertex4f\0"
    "\0"
-   /* _mesa_function_pool[24980]: EvalCoord1d (offset 228) */
+   /* _mesa_function_pool[25273]: EvalCoord1d (offset 228) */
    "d\0"
    "glEvalCoord1d\0"
    "\0"
-   /* _mesa_function_pool[24997]: Vertex4d (offset 142) */
+   /* _mesa_function_pool[25290]: Vertex4d (offset 142) */
    "dddd\0"
    "glVertex4d\0"
    "\0"
-   /* _mesa_function_pool[25014]: RasterPos4dv (offset 79) */
+   /* _mesa_function_pool[25307]: RasterPos4dv (offset 79) */
    "p\0"
    "glRasterPos4dv\0"
    "\0"
-   /* _mesa_function_pool[25032]: FragmentLightfSGIX (dynamic) */
+   /* _mesa_function_pool[25325]: FragmentLightfSGIX (dynamic) */
    "iif\0"
    "glFragmentLightfSGIX\0"
    "\0"
-   /* _mesa_function_pool[25058]: GetCompressedTexImageARB (will be remapped) */
+   /* _mesa_function_pool[25351]: GetCompressedTexImageARB (will be remapped) */
    "iip\0"
    "glGetCompressedTexImage\0"
    "glGetCompressedTexImageARB\0"
    "\0"
-   /* _mesa_function_pool[25114]: GetTexGenfv (offset 279) */
+   /* _mesa_function_pool[25407]: GetTexGenfv (offset 279) */
    "iip\0"
    "glGetTexGenfv\0"
    "\0"
-   /* _mesa_function_pool[25133]: Vertex4i (offset 146) */
+   /* _mesa_function_pool[25426]: Vertex4i (offset 146) */
    "iiii\0"
    "glVertex4i\0"
    "\0"
-   /* _mesa_function_pool[25150]: VertexWeightPointerEXT (dynamic) */
+   /* _mesa_function_pool[25443]: VertexWeightPointerEXT (dynamic) */
    "iiip\0"
    "glVertexWeightPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[25181]: GetHistogram (offset 361) */
+   /* _mesa_function_pool[25474]: GetHistogram (offset 361) */
    "iiiip\0"
    "glGetHistogram\0"
    "glGetHistogramEXT\0"
    "\0"
-   /* _mesa_function_pool[25221]: ActiveStencilFaceEXT (will be remapped) */
+   /* _mesa_function_pool[25514]: ActiveStencilFaceEXT (will be remapped) */
    "i\0"
    "glActiveStencilFaceEXT\0"
    "\0"
-   /* _mesa_function_pool[25247]: StencilFuncSeparateATI (will be remapped) */
+   /* _mesa_function_pool[25540]: StencilFuncSeparateATI (will be remapped) */
    "iiii\0"
    "glStencilFuncSeparateATI\0"
    "\0"
-   /* _mesa_function_pool[25278]: Materialf (offset 169) */
+   /* _mesa_function_pool[25571]: Materialf (offset 169) */
    "iif\0"
    "glMaterialf\0"
    "\0"
-   /* _mesa_function_pool[25295]: GetShaderSourceARB (will be remapped) */
+   /* _mesa_function_pool[25588]: GetShaderSourceARB (will be remapped) */
    "iipp\0"
    "glGetShaderSource\0"
    "glGetShaderSourceARB\0"
    "\0"
-   /* _mesa_function_pool[25340]: IglooInterfaceSGIX (dynamic) */
+   /* _mesa_function_pool[25633]: IglooInterfaceSGIX (dynamic) */
    "ip\0"
    "glIglooInterfaceSGIX\0"
    "\0"
-   /* _mesa_function_pool[25365]: Materiali (offset 171) */
+   /* _mesa_function_pool[25658]: Materiali (offset 171) */
    "iii\0"
    "glMateriali\0"
    "\0"
-   /* _mesa_function_pool[25382]: VertexAttrib4dNV (will be remapped) */
+   /* _mesa_function_pool[25675]: VertexAttrib4dNV (will be remapped) */
    "idddd\0"
    "glVertexAttrib4dNV\0"
    "\0"
-   /* _mesa_function_pool[25408]: MultiModeDrawElementsIBM (will be remapped) */
+   /* _mesa_function_pool[25701]: MultiModeDrawElementsIBM (will be remapped) */
    "ppipii\0"
    "glMultiModeDrawElementsIBM\0"
    "\0"
-   /* _mesa_function_pool[25443]: Indexsv (offset 51) */
+   /* _mesa_function_pool[25736]: Indexsv (offset 51) */
    "p\0"
    "glIndexsv\0"
    "\0"
-   /* _mesa_function_pool[25456]: MultiTexCoord4svARB (offset 407) */
+   /* _mesa_function_pool[25749]: MultiTexCoord4svARB (offset 407) */
    "ip\0"
    "glMultiTexCoord4sv\0"
    "glMultiTexCoord4svARB\0"
    "\0"
-   /* _mesa_function_pool[25501]: LightModelfv (offset 164) */
+   /* _mesa_function_pool[25794]: LightModelfv (offset 164) */
    "ip\0"
    "glLightModelfv\0"
    "\0"
-   /* _mesa_function_pool[25520]: TexCoord2dv (offset 103) */
+   /* _mesa_function_pool[25813]: TexCoord2dv (offset 103) */
    "p\0"
    "glTexCoord2dv\0"
    "\0"
-   /* _mesa_function_pool[25537]: GenQueriesARB (will be remapped) */
+   /* _mesa_function_pool[25830]: GenQueriesARB (will be remapped) */
    "ip\0"
    "glGenQueries\0"
    "glGenQueriesARB\0"
    "\0"
-   /* _mesa_function_pool[25570]: EvalCoord1dv (offset 229) */
+   /* _mesa_function_pool[25863]: EvalCoord1dv (offset 229) */
    "p\0"
    "glEvalCoord1dv\0"
    "\0"
-   /* _mesa_function_pool[25588]: ReplacementCodeuiVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[25881]: ReplacementCodeuiVertex3fSUN (dynamic) */
    "ifff\0"
    "glReplacementCodeuiVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[25625]: Translated (offset 303) */
+   /* _mesa_function_pool[25918]: Translated (offset 303) */
    "ddd\0"
    "glTranslated\0"
    "\0"
-   /* _mesa_function_pool[25643]: Translatef (offset 304) */
+   /* _mesa_function_pool[25936]: Translatef (offset 304) */
    "fff\0"
    "glTranslatef\0"
    "\0"
-   /* _mesa_function_pool[25661]: StencilMask (offset 209) */
+   /* _mesa_function_pool[25954]: StencilMask (offset 209) */
    "i\0"
    "glStencilMask\0"
    "\0"
-   /* _mesa_function_pool[25678]: Tangent3iEXT (dynamic) */
+   /* _mesa_function_pool[25971]: Tangent3iEXT (dynamic) */
    "iii\0"
    "glTangent3iEXT\0"
    "\0"
-   /* _mesa_function_pool[25698]: GetLightiv (offset 265) */
+   /* _mesa_function_pool[25991]: GetLightiv (offset 265) */
    "iip\0"
    "glGetLightiv\0"
    "\0"
-   /* _mesa_function_pool[25716]: DrawMeshArraysSUN (dynamic) */
+   /* _mesa_function_pool[26009]: DrawMeshArraysSUN (dynamic) */
    "iiii\0"
    "glDrawMeshArraysSUN\0"
    "\0"
-   /* _mesa_function_pool[25742]: IsList (offset 287) */
+   /* _mesa_function_pool[26035]: IsList (offset 287) */
    "i\0"
    "glIsList\0"
    "\0"
-   /* _mesa_function_pool[25754]: IsSync (will be remapped) */
+   /* _mesa_function_pool[26047]: IsSync (will be remapped) */
    "i\0"
    "glIsSync\0"
    "\0"
-   /* _mesa_function_pool[25766]: RenderMode (offset 196) */
+   /* _mesa_function_pool[26059]: RenderMode (offset 196) */
    "i\0"
    "glRenderMode\0"
    "\0"
-   /* _mesa_function_pool[25782]: GetMapControlPointsNV (dynamic) */
+   /* _mesa_function_pool[26075]: GetMapControlPointsNV (dynamic) */
    "iiiiiip\0"
    "glGetMapControlPointsNV\0"
    "\0"
-   /* _mesa_function_pool[25815]: DrawBuffersARB (will be remapped) */
+   /* _mesa_function_pool[26108]: DrawBuffersARB (will be remapped) */
    "ip\0"
    "glDrawBuffers\0"
    "glDrawBuffersARB\0"
    "glDrawBuffersATI\0"
    "\0"
-   /* _mesa_function_pool[25867]: ProgramLocalParameter4fARB (will be remapped) */
+   /* _mesa_function_pool[26160]: ProgramLocalParameter4fARB (will be remapped) */
    "iiffff\0"
    "glProgramLocalParameter4fARB\0"
    "\0"
-   /* _mesa_function_pool[25904]: SpriteParameterivSGIX (dynamic) */
+   /* _mesa_function_pool[26197]: SpriteParameterivSGIX (dynamic) */
    "ip\0"
    "glSpriteParameterivSGIX\0"
    "\0"
-   /* _mesa_function_pool[25932]: ProvokingVertexEXT (will be remapped) */
+   /* _mesa_function_pool[26225]: ProvokingVertexEXT (will be remapped) */
    "i\0"
    "glProvokingVertexEXT\0"
    "glProvokingVertex\0"
    "\0"
-   /* _mesa_function_pool[25974]: MultiTexCoord1fARB (offset 378) */
+   /* _mesa_function_pool[26267]: MultiTexCoord1fARB (offset 378) */
    "if\0"
    "glMultiTexCoord1f\0"
    "glMultiTexCoord1fARB\0"
    "\0"
-   /* _mesa_function_pool[26017]: LoadName (offset 198) */
+   /* _mesa_function_pool[26310]: LoadName (offset 198) */
    "i\0"
    "glLoadName\0"
    "\0"
-   /* _mesa_function_pool[26031]: VertexAttribs4ubvNV (will be remapped) */
+   /* _mesa_function_pool[26324]: VertexAttribs4ubvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs4ubvNV\0"
    "\0"
-   /* _mesa_function_pool[26058]: WeightsvARB (dynamic) */
+   /* _mesa_function_pool[26351]: WeightsvARB (dynamic) */
    "ip\0"
    "glWeightsvARB\0"
    "\0"
-   /* _mesa_function_pool[26076]: Uniform1fvARB (will be remapped) */
+   /* _mesa_function_pool[26369]: Uniform1fvARB (will be remapped) */
    "iip\0"
    "glUniform1fv\0"
    "glUniform1fvARB\0"
    "\0"
-   /* _mesa_function_pool[26110]: CopyTexSubImage1D (offset 325) */
+   /* _mesa_function_pool[26403]: CopyTexSubImage1D (offset 325) */
    "iiiiii\0"
    "glCopyTexSubImage1D\0"
    "glCopyTexSubImage1DEXT\0"
    "\0"
-   /* _mesa_function_pool[26161]: CullFace (offset 152) */
+   /* _mesa_function_pool[26454]: CullFace (offset 152) */
    "i\0"
    "glCullFace\0"
    "\0"
-   /* _mesa_function_pool[26175]: BindTexture (offset 307) */
+   /* _mesa_function_pool[26468]: BindTexture (offset 307) */
    "ii\0"
    "glBindTexture\0"
    "glBindTextureEXT\0"
    "\0"
-   /* _mesa_function_pool[26210]: BeginFragmentShaderATI (will be remapped) */
+   /* _mesa_function_pool[26503]: BeginFragmentShaderATI (will be remapped) */
    "\0"
    "glBeginFragmentShaderATI\0"
    "\0"
-   /* _mesa_function_pool[26237]: MultiTexCoord4fARB (offset 402) */
+   /* _mesa_function_pool[26530]: MultiTexCoord4fARB (offset 402) */
    "iffff\0"
    "glMultiTexCoord4f\0"
    "glMultiTexCoord4fARB\0"
    "\0"
-   /* _mesa_function_pool[26283]: VertexAttribs3svNV (will be remapped) */
+   /* _mesa_function_pool[26576]: VertexAttribs3svNV (will be remapped) */
    "iip\0"
    "glVertexAttribs3svNV\0"
    "\0"
-   /* _mesa_function_pool[26309]: StencilFunc (offset 243) */
+   /* _mesa_function_pool[26602]: StencilFunc (offset 243) */
    "iii\0"
    "glStencilFunc\0"
    "\0"
-   /* _mesa_function_pool[26328]: CopyPixels (offset 255) */
+   /* _mesa_function_pool[26621]: CopyPixels (offset 255) */
    "iiiii\0"
    "glCopyPixels\0"
    "\0"
-   /* _mesa_function_pool[26348]: Rectsv (offset 93) */
+   /* _mesa_function_pool[26641]: Rectsv (offset 93) */
    "pp\0"
    "glRectsv\0"
    "\0"
-   /* _mesa_function_pool[26361]: ReplacementCodeuivSUN (dynamic) */
+   /* _mesa_function_pool[26654]: ReplacementCodeuivSUN (dynamic) */
    "p\0"
    "glReplacementCodeuivSUN\0"
    "\0"
-   /* _mesa_function_pool[26388]: EnableVertexAttribArrayARB (will be remapped) */
+   /* _mesa_function_pool[26681]: EnableVertexAttribArrayARB (will be remapped) */
    "i\0"
    "glEnableVertexAttribArray\0"
    "glEnableVertexAttribArrayARB\0"
    "\0"
-   /* _mesa_function_pool[26446]: NormalPointervINTEL (dynamic) */
+   /* _mesa_function_pool[26739]: NormalPointervINTEL (dynamic) */
    "ip\0"
    "glNormalPointervINTEL\0"
    "\0"
-   /* _mesa_function_pool[26472]: CopyConvolutionFilter2D (offset 355) */
+   /* _mesa_function_pool[26765]: CopyConvolutionFilter2D (offset 355) */
    "iiiiii\0"
    "glCopyConvolutionFilter2D\0"
    "glCopyConvolutionFilter2DEXT\0"
    "\0"
-   /* _mesa_function_pool[26535]: WindowPos3ivMESA (will be remapped) */
+   /* _mesa_function_pool[26828]: WindowPos3ivMESA (will be remapped) */
    "p\0"
    "glWindowPos3iv\0"
    "glWindowPos3ivARB\0"
    "glWindowPos3ivMESA\0"
    "\0"
-   /* _mesa_function_pool[26590]: CopyBufferSubData (will be remapped) */
+   /* _mesa_function_pool[26883]: CopyBufferSubData (will be remapped) */
    "iiiii\0"
    "glCopyBufferSubData\0"
    "\0"
-   /* _mesa_function_pool[26617]: NormalPointer (offset 318) */
+   /* _mesa_function_pool[26910]: NormalPointer (offset 318) */
    "iip\0"
    "glNormalPointer\0"
    "\0"
-   /* _mesa_function_pool[26638]: TexParameterfv (offset 179) */
+   /* _mesa_function_pool[26931]: TexParameterfv (offset 179) */
    "iip\0"
    "glTexParameterfv\0"
    "\0"
-   /* _mesa_function_pool[26660]: IsBufferARB (will be remapped) */
+   /* _mesa_function_pool[26953]: IsBufferARB (will be remapped) */
    "i\0"
    "glIsBuffer\0"
    "glIsBufferARB\0"
    "\0"
-   /* _mesa_function_pool[26688]: WindowPos4iMESA (will be remapped) */
+   /* _mesa_function_pool[26981]: WindowPos4iMESA (will be remapped) */
    "iiii\0"
    "glWindowPos4iMESA\0"
    "\0"
-   /* _mesa_function_pool[26712]: VertexAttrib4uivARB (will be remapped) */
+   /* _mesa_function_pool[27005]: VertexAttrib4uivARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4uiv\0"
    "glVertexAttrib4uivARB\0"
    "\0"
-   /* _mesa_function_pool[26757]: Tangent3bvEXT (dynamic) */
+   /* _mesa_function_pool[27050]: Tangent3bvEXT (dynamic) */
    "p\0"
    "glTangent3bvEXT\0"
    "\0"
-   /* _mesa_function_pool[26776]: UniformMatrix3x4fv (will be remapped) */
+   /* _mesa_function_pool[27069]: UniformMatrix3x4fv (will be remapped) */
    "iiip\0"
    "glUniformMatrix3x4fv\0"
    "\0"
-   /* _mesa_function_pool[26803]: ClipPlane (offset 150) */
+   /* _mesa_function_pool[27096]: ClipPlane (offset 150) */
    "ip\0"
    "glClipPlane\0"
    "\0"
-   /* _mesa_function_pool[26819]: Recti (offset 90) */
+   /* _mesa_function_pool[27112]: Recti (offset 90) */
    "iiii\0"
    "glRecti\0"
    "\0"
-   /* _mesa_function_pool[26833]: DrawRangeElementsBaseVertex (will be remapped) */
+   /* _mesa_function_pool[27126]: DrawRangeElementsBaseVertex (will be remapped) */
    "iiiiipi\0"
    "glDrawRangeElementsBaseVertex\0"
    "\0"
-   /* _mesa_function_pool[26872]: TexCoordPointervINTEL (dynamic) */
+   /* _mesa_function_pool[27165]: TexCoordPointervINTEL (dynamic) */
    "iip\0"
    "glTexCoordPointervINTEL\0"
    "\0"
-   /* _mesa_function_pool[26901]: DeleteBuffersARB (will be remapped) */
+   /* _mesa_function_pool[27194]: DeleteBuffersARB (will be remapped) */
    "ip\0"
    "glDeleteBuffers\0"
    "glDeleteBuffersARB\0"
    "\0"
-   /* _mesa_function_pool[26940]: WindowPos4fvMESA (will be remapped) */
+   /* _mesa_function_pool[27233]: WindowPos4fvMESA (will be remapped) */
    "p\0"
    "glWindowPos4fvMESA\0"
    "\0"
-   /* _mesa_function_pool[26962]: GetPixelMapuiv (offset 272) */
+   /* _mesa_function_pool[27255]: GetPixelMapuiv (offset 272) */
    "ip\0"
    "glGetPixelMapuiv\0"
    "\0"
-   /* _mesa_function_pool[26983]: Rectf (offset 88) */
+   /* _mesa_function_pool[27276]: Rectf (offset 88) */
    "ffff\0"
    "glRectf\0"
    "\0"
-   /* _mesa_function_pool[26997]: VertexAttrib1sNV (will be remapped) */
+   /* _mesa_function_pool[27290]: VertexAttrib1sNV (will be remapped) */
    "ii\0"
    "glVertexAttrib1sNV\0"
    "\0"
-   /* _mesa_function_pool[27020]: Indexfv (offset 47) */
+   /* _mesa_function_pool[27313]: Indexfv (offset 47) */
    "p\0"
    "glIndexfv\0"
    "\0"
-   /* _mesa_function_pool[27033]: SecondaryColor3svEXT (will be remapped) */
+   /* _mesa_function_pool[27326]: SecondaryColor3svEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3sv\0"
    "glSecondaryColor3svEXT\0"
    "\0"
-   /* _mesa_function_pool[27079]: LoadTransposeMatrixfARB (will be remapped) */
+   /* _mesa_function_pool[27372]: LoadTransposeMatrixfARB (will be remapped) */
    "p\0"
    "glLoadTransposeMatrixf\0"
    "glLoadTransposeMatrixfARB\0"
    "\0"
-   /* _mesa_function_pool[27131]: GetPointerv (offset 329) */
+   /* _mesa_function_pool[27424]: GetPointerv (offset 329) */
    "ip\0"
    "glGetPointerv\0"
    "glGetPointervEXT\0"
    "\0"
-   /* _mesa_function_pool[27166]: Tangent3bEXT (dynamic) */
+   /* _mesa_function_pool[27459]: Tangent3bEXT (dynamic) */
    "iii\0"
    "glTangent3bEXT\0"
    "\0"
-   /* _mesa_function_pool[27186]: CombinerParameterfNV (will be remapped) */
+   /* _mesa_function_pool[27479]: CombinerParameterfNV (will be remapped) */
    "if\0"
    "glCombinerParameterfNV\0"
    "\0"
-   /* _mesa_function_pool[27213]: IndexMask (offset 212) */
+   /* _mesa_function_pool[27506]: IndexMask (offset 212) */
    "i\0"
    "glIndexMask\0"
    "\0"
-   /* _mesa_function_pool[27228]: BindProgramNV (will be remapped) */
+   /* _mesa_function_pool[27521]: BindProgramNV (will be remapped) */
    "ii\0"
    "glBindProgramARB\0"
    "glBindProgramNV\0"
    "\0"
-   /* _mesa_function_pool[27265]: VertexAttrib4svARB (will be remapped) */
+   /* _mesa_function_pool[27558]: VertexAttrib4svARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4sv\0"
    "glVertexAttrib4svARB\0"
    "\0"
-   /* _mesa_function_pool[27308]: GetFloatv (offset 262) */
+   /* _mesa_function_pool[27601]: GetFloatv (offset 262) */
    "ip\0"
    "glGetFloatv\0"
    "\0"
-   /* _mesa_function_pool[27324]: CreateDebugObjectMESA (dynamic) */
+   /* _mesa_function_pool[27617]: CreateDebugObjectMESA (dynamic) */
    "\0"
    "glCreateDebugObjectMESA\0"
    "\0"
-   /* _mesa_function_pool[27350]: GetShaderiv (will be remapped) */
+   /* _mesa_function_pool[27643]: GetShaderiv (will be remapped) */
    "iip\0"
    "glGetShaderiv\0"
    "\0"
-   /* _mesa_function_pool[27369]: ClientWaitSync (will be remapped) */
+   /* _mesa_function_pool[27662]: ClientWaitSync (will be remapped) */
    "iii\0"
    "glClientWaitSync\0"
    "\0"
-   /* _mesa_function_pool[27391]: TexCoord4s (offset 124) */
+   /* _mesa_function_pool[27684]: TexCoord4s (offset 124) */
    "iiii\0"
    "glTexCoord4s\0"
    "\0"
-   /* _mesa_function_pool[27410]: TexCoord3sv (offset 117) */
+   /* _mesa_function_pool[27703]: TexCoord3sv (offset 117) */
    "p\0"
    "glTexCoord3sv\0"
    "\0"
-   /* _mesa_function_pool[27427]: BindFragmentShaderATI (will be remapped) */
+   /* _mesa_function_pool[27720]: BindFragmentShaderATI (will be remapped) */
    "i\0"
    "glBindFragmentShaderATI\0"
    "\0"
-   /* _mesa_function_pool[27454]: PopAttrib (offset 218) */
+   /* _mesa_function_pool[27747]: PopAttrib (offset 218) */
    "\0"
    "glPopAttrib\0"
    "\0"
-   /* _mesa_function_pool[27468]: Fogfv (offset 154) */
+   /* _mesa_function_pool[27761]: Fogfv (offset 154) */
    "ip\0"
    "glFogfv\0"
    "\0"
-   /* _mesa_function_pool[27480]: UnmapBufferARB (will be remapped) */
+   /* _mesa_function_pool[27773]: UnmapBufferARB (will be remapped) */
    "i\0"
    "glUnmapBuffer\0"
    "glUnmapBufferARB\0"
    "\0"
-   /* _mesa_function_pool[27514]: InitNames (offset 197) */
+   /* _mesa_function_pool[27807]: InitNames (offset 197) */
    "\0"
    "glInitNames\0"
    "\0"
-   /* _mesa_function_pool[27528]: Normal3sv (offset 61) */
+   /* _mesa_function_pool[27821]: Normal3sv (offset 61) */
    "p\0"
    "glNormal3sv\0"
    "\0"
-   /* _mesa_function_pool[27543]: Minmax (offset 368) */
+   /* _mesa_function_pool[27836]: Minmax (offset 368) */
    "iii\0"
    "glMinmax\0"
    "glMinmaxEXT\0"
    "\0"
-   /* _mesa_function_pool[27569]: TexCoord4d (offset 118) */
+   /* _mesa_function_pool[27862]: TexCoord4d (offset 118) */
    "dddd\0"
    "glTexCoord4d\0"
    "\0"
-   /* _mesa_function_pool[27588]: DeformationMap3dSGIX (dynamic) */
-   "iddiiddiiddiip\0"
-   "glDeformationMap3dSGIX\0"
-   "\0"
-   /* _mesa_function_pool[27627]: TexCoord4f (offset 120) */
+   /* _mesa_function_pool[27881]: TexCoord4f (offset 120) */
    "ffff\0"
    "glTexCoord4f\0"
    "\0"
-   /* _mesa_function_pool[27646]: FogCoorddvEXT (will be remapped) */
+   /* _mesa_function_pool[27900]: FogCoorddvEXT (will be remapped) */
    "p\0"
    "glFogCoorddv\0"
    "glFogCoorddvEXT\0"
    "\0"
-   /* _mesa_function_pool[27678]: FinishTextureSUNX (dynamic) */
+   /* _mesa_function_pool[27932]: FinishTextureSUNX (dynamic) */
    "\0"
    "glFinishTextureSUNX\0"
    "\0"
-   /* _mesa_function_pool[27700]: GetFragmentLightfvSGIX (dynamic) */
+   /* _mesa_function_pool[27954]: GetFragmentLightfvSGIX (dynamic) */
    "iip\0"
    "glGetFragmentLightfvSGIX\0"
    "\0"
-   /* _mesa_function_pool[27730]: Binormal3fvEXT (dynamic) */
+   /* _mesa_function_pool[27984]: Binormal3fvEXT (dynamic) */
    "p\0"
    "glBinormal3fvEXT\0"
    "\0"
-   /* _mesa_function_pool[27750]: GetBooleanv (offset 258) */
+   /* _mesa_function_pool[28004]: GetBooleanv (offset 258) */
    "ip\0"
    "glGetBooleanv\0"
    "\0"
-   /* _mesa_function_pool[27768]: ColorFragmentOp3ATI (will be remapped) */
+   /* _mesa_function_pool[28022]: ColorFragmentOp3ATI (will be remapped) */
    "iiiiiiiiiiiii\0"
    "glColorFragmentOp3ATI\0"
    "\0"
-   /* _mesa_function_pool[27805]: Hint (offset 158) */
+   /* _mesa_function_pool[28059]: Hint (offset 158) */
    "ii\0"
    "glHint\0"
    "\0"
-   /* _mesa_function_pool[27816]: Color4dv (offset 28) */
+   /* _mesa_function_pool[28070]: Color4dv (offset 28) */
    "p\0"
    "glColor4dv\0"
    "\0"
-   /* _mesa_function_pool[27830]: VertexAttrib2svARB (will be remapped) */
+   /* _mesa_function_pool[28084]: VertexAttrib2svARB (will be remapped) */
    "ip\0"
    "glVertexAttrib2sv\0"
    "glVertexAttrib2svARB\0"
    "\0"
-   /* _mesa_function_pool[27873]: AreProgramsResidentNV (will be remapped) */
+   /* _mesa_function_pool[28127]: AreProgramsResidentNV (will be remapped) */
    "ipp\0"
    "glAreProgramsResidentNV\0"
    "\0"
-   /* _mesa_function_pool[27902]: WindowPos3svMESA (will be remapped) */
+   /* _mesa_function_pool[28156]: WindowPos3svMESA (will be remapped) */
    "p\0"
    "glWindowPos3sv\0"
    "glWindowPos3svARB\0"
    "glWindowPos3svMESA\0"
    "\0"
-   /* _mesa_function_pool[27957]: CopyColorSubTable (offset 347) */
+   /* _mesa_function_pool[28211]: CopyColorSubTable (offset 347) */
    "iiiii\0"
    "glCopyColorSubTable\0"
    "glCopyColorSubTableEXT\0"
    "\0"
-   /* _mesa_function_pool[28007]: WeightdvARB (dynamic) */
+   /* _mesa_function_pool[28261]: WeightdvARB (dynamic) */
    "ip\0"
    "glWeightdvARB\0"
    "\0"
-   /* _mesa_function_pool[28025]: DeleteRenderbuffersEXT (will be remapped) */
+   /* _mesa_function_pool[28279]: DeleteRenderbuffersEXT (will be remapped) */
    "ip\0"
    "glDeleteRenderbuffers\0"
    "glDeleteRenderbuffersEXT\0"
    "\0"
-   /* _mesa_function_pool[28076]: VertexAttrib4NubvARB (will be remapped) */
+   /* _mesa_function_pool[28330]: VertexAttrib4NubvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4Nubv\0"
    "glVertexAttrib4NubvARB\0"
    "\0"
-   /* _mesa_function_pool[28123]: VertexAttrib3dvNV (will be remapped) */
+   /* _mesa_function_pool[28377]: VertexAttrib3dvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib3dvNV\0"
    "\0"
-   /* _mesa_function_pool[28147]: GetObjectParameterfvARB (will be remapped) */
+   /* _mesa_function_pool[28401]: GetObjectParameterfvARB (will be remapped) */
    "iip\0"
    "glGetObjectParameterfvARB\0"
    "\0"
-   /* _mesa_function_pool[28178]: Vertex4iv (offset 147) */
+   /* _mesa_function_pool[28432]: Vertex4iv (offset 147) */
    "p\0"
    "glVertex4iv\0"
    "\0"
-   /* _mesa_function_pool[28193]: GetProgramEnvParameterdvARB (will be remapped) */
+   /* _mesa_function_pool[28447]: GetProgramEnvParameterdvARB (will be remapped) */
    "iip\0"
    "glGetProgramEnvParameterdvARB\0"
    "\0"
-   /* _mesa_function_pool[28228]: TexCoord4dv (offset 119) */
+   /* _mesa_function_pool[28482]: TexCoord4dv (offset 119) */
    "p\0"
    "glTexCoord4dv\0"
    "\0"
-   /* _mesa_function_pool[28245]: LockArraysEXT (will be remapped) */
+   /* _mesa_function_pool[28499]: LockArraysEXT (will be remapped) */
    "ii\0"
    "glLockArraysEXT\0"
    "\0"
-   /* _mesa_function_pool[28265]: Begin (offset 7) */
+   /* _mesa_function_pool[28519]: Begin (offset 7) */
    "i\0"
    "glBegin\0"
    "\0"
-   /* _mesa_function_pool[28276]: LightModeli (offset 165) */
+   /* _mesa_function_pool[28530]: LightModeli (offset 165) */
    "ii\0"
    "glLightModeli\0"
    "\0"
-   /* _mesa_function_pool[28294]: Rectfv (offset 89) */
+   /* _mesa_function_pool[28548]: Rectfv (offset 89) */
    "pp\0"
    "glRectfv\0"
    "\0"
-   /* _mesa_function_pool[28307]: LightModelf (offset 163) */
+   /* _mesa_function_pool[28561]: LightModelf (offset 163) */
    "if\0"
    "glLightModelf\0"
    "\0"
-   /* _mesa_function_pool[28325]: GetTexParameterfv (offset 282) */
+   /* _mesa_function_pool[28579]: GetTexParameterfv (offset 282) */
    "iip\0"
    "glGetTexParameterfv\0"
    "\0"
-   /* _mesa_function_pool[28350]: GetLightfv (offset 264) */
+   /* _mesa_function_pool[28604]: GetLightfv (offset 264) */
    "iip\0"
    "glGetLightfv\0"
    "\0"
-   /* _mesa_function_pool[28368]: PixelTransformParameterivEXT (dynamic) */
+   /* _mesa_function_pool[28622]: PixelTransformParameterivEXT (dynamic) */
    "iip\0"
    "glPixelTransformParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[28404]: BinormalPointerEXT (dynamic) */
+   /* _mesa_function_pool[28658]: BinormalPointerEXT (dynamic) */
    "iip\0"
    "glBinormalPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[28430]: VertexAttrib1dNV (will be remapped) */
+   /* _mesa_function_pool[28684]: VertexAttrib1dNV (will be remapped) */
    "id\0"
    "glVertexAttrib1dNV\0"
    "\0"
-   /* _mesa_function_pool[28453]: GetCombinerInputParameterivNV (will be remapped) */
+   /* _mesa_function_pool[28707]: GetCombinerInputParameterivNV (will be remapped) */
    "iiiip\0"
    "glGetCombinerInputParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[28492]: Disable (offset 214) */
+   /* _mesa_function_pool[28746]: Disable (offset 214) */
    "i\0"
    "glDisable\0"
    "\0"
-   /* _mesa_function_pool[28505]: MultiTexCoord2fvARB (offset 387) */
+   /* _mesa_function_pool[28759]: MultiTexCoord2fvARB (offset 387) */
    "ip\0"
    "glMultiTexCoord2fv\0"
    "glMultiTexCoord2fvARB\0"
    "\0"
-   /* _mesa_function_pool[28550]: GetRenderbufferParameterivEXT (will be remapped) */
+   /* _mesa_function_pool[28804]: GetRenderbufferParameterivEXT (will be remapped) */
    "iip\0"
    "glGetRenderbufferParameteriv\0"
    "glGetRenderbufferParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[28616]: CombinerParameterivNV (will be remapped) */
+   /* _mesa_function_pool[28870]: CombinerParameterivNV (will be remapped) */
    "ip\0"
    "glCombinerParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[28644]: GenFragmentShadersATI (will be remapped) */
+   /* _mesa_function_pool[28898]: GenFragmentShadersATI (will be remapped) */
    "i\0"
    "glGenFragmentShadersATI\0"
    "\0"
-   /* _mesa_function_pool[28671]: DrawArrays (offset 310) */
+   /* _mesa_function_pool[28925]: DrawArrays (offset 310) */
    "iii\0"
    "glDrawArrays\0"
    "glDrawArraysEXT\0"
    "\0"
-   /* _mesa_function_pool[28705]: WeightuivARB (dynamic) */
+   /* _mesa_function_pool[28959]: WeightuivARB (dynamic) */
    "ip\0"
    "glWeightuivARB\0"
    "\0"
-   /* _mesa_function_pool[28724]: VertexAttrib2sARB (will be remapped) */
+   /* _mesa_function_pool[28978]: VertexAttrib2sARB (will be remapped) */
    "iii\0"
    "glVertexAttrib2s\0"
    "glVertexAttrib2sARB\0"
    "\0"
-   /* _mesa_function_pool[28766]: ColorMask (offset 210) */
+   /* _mesa_function_pool[29020]: ColorMask (offset 210) */
    "iiii\0"
    "glColorMask\0"
    "\0"
-   /* _mesa_function_pool[28784]: GenAsyncMarkersSGIX (dynamic) */
+   /* _mesa_function_pool[29038]: GenAsyncMarkersSGIX (dynamic) */
    "i\0"
    "glGenAsyncMarkersSGIX\0"
    "\0"
-   /* _mesa_function_pool[28809]: Tangent3svEXT (dynamic) */
+   /* _mesa_function_pool[29063]: Tangent3svEXT (dynamic) */
    "p\0"
    "glTangent3svEXT\0"
    "\0"
-   /* _mesa_function_pool[28828]: GetListParameterivSGIX (dynamic) */
+   /* _mesa_function_pool[29082]: GetListParameterivSGIX (dynamic) */
    "iip\0"
    "glGetListParameterivSGIX\0"
    "\0"
-   /* _mesa_function_pool[28858]: BindBufferARB (will be remapped) */
+   /* _mesa_function_pool[29112]: BindBufferARB (will be remapped) */
    "ii\0"
    "glBindBuffer\0"
    "glBindBufferARB\0"
    "\0"
-   /* _mesa_function_pool[28891]: GetInfoLogARB (will be remapped) */
+   /* _mesa_function_pool[29145]: GetInfoLogARB (will be remapped) */
    "iipp\0"
    "glGetInfoLogARB\0"
    "\0"
-   /* _mesa_function_pool[28913]: RasterPos4iv (offset 83) */
+   /* _mesa_function_pool[29167]: RasterPos4iv (offset 83) */
    "p\0"
    "glRasterPos4iv\0"
    "\0"
-   /* _mesa_function_pool[28931]: Enable (offset 215) */
+   /* _mesa_function_pool[29185]: Enable (offset 215) */
    "i\0"
    "glEnable\0"
    "\0"
-   /* _mesa_function_pool[28943]: LineStipple (offset 167) */
+   /* _mesa_function_pool[29197]: LineStipple (offset 167) */
    "ii\0"
    "glLineStipple\0"
    "\0"
-   /* _mesa_function_pool[28961]: VertexAttribs4svNV (will be remapped) */
+   /* _mesa_function_pool[29215]: VertexAttribs4svNV (will be remapped) */
    "iip\0"
    "glVertexAttribs4svNV\0"
    "\0"
-   /* _mesa_function_pool[28987]: EdgeFlagPointerListIBM (dynamic) */
+   /* _mesa_function_pool[29241]: EdgeFlagPointerListIBM (dynamic) */
    "ipi\0"
    "glEdgeFlagPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[29017]: UniformMatrix3x2fv (will be remapped) */
+   /* _mesa_function_pool[29271]: UniformMatrix3x2fv (will be remapped) */
    "iiip\0"
    "glUniformMatrix3x2fv\0"
    "\0"
-   /* _mesa_function_pool[29044]: GetMinmaxParameterfv (offset 365) */
+   /* _mesa_function_pool[29298]: GetMinmaxParameterfv (offset 365) */
    "iip\0"
    "glGetMinmaxParameterfv\0"
    "glGetMinmaxParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[29098]: VertexAttrib1fvARB (will be remapped) */
+   /* _mesa_function_pool[29352]: VertexAttrib1fvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib1fv\0"
    "glVertexAttrib1fvARB\0"
    "\0"
-   /* _mesa_function_pool[29141]: GenBuffersARB (will be remapped) */
+   /* _mesa_function_pool[29395]: GenBuffersARB (will be remapped) */
    "ip\0"
    "glGenBuffers\0"
    "glGenBuffersARB\0"
    "\0"
-   /* _mesa_function_pool[29174]: VertexAttribs1svNV (will be remapped) */
+   /* _mesa_function_pool[29428]: VertexAttribs1svNV (will be remapped) */
    "iip\0"
    "glVertexAttribs1svNV\0"
    "\0"
-   /* _mesa_function_pool[29200]: Vertex3fv (offset 137) */
+   /* _mesa_function_pool[29454]: Vertex3fv (offset 137) */
    "p\0"
    "glVertex3fv\0"
    "\0"
-   /* _mesa_function_pool[29215]: GetTexBumpParameterivATI (will be remapped) */
+   /* _mesa_function_pool[29469]: GetTexBumpParameterivATI (will be remapped) */
    "ip\0"
    "glGetTexBumpParameterivATI\0"
    "\0"
-   /* _mesa_function_pool[29246]: Binormal3bEXT (dynamic) */
+   /* _mesa_function_pool[29500]: Binormal3bEXT (dynamic) */
    "iii\0"
    "glBinormal3bEXT\0"
    "\0"
-   /* _mesa_function_pool[29267]: FragmentMaterialivSGIX (dynamic) */
+   /* _mesa_function_pool[29521]: FragmentMaterialivSGIX (dynamic) */
    "iip\0"
    "glFragmentMaterialivSGIX\0"
    "\0"
-   /* _mesa_function_pool[29297]: IsRenderbufferEXT (will be remapped) */
+   /* _mesa_function_pool[29551]: IsRenderbufferEXT (will be remapped) */
    "i\0"
    "glIsRenderbuffer\0"
    "glIsRenderbufferEXT\0"
    "\0"
-   /* _mesa_function_pool[29337]: GenProgramsNV (will be remapped) */
+   /* _mesa_function_pool[29591]: GenProgramsNV (will be remapped) */
    "ip\0"
    "glGenProgramsARB\0"
    "glGenProgramsNV\0"
    "\0"
-   /* _mesa_function_pool[29374]: VertexAttrib4dvNV (will be remapped) */
+   /* _mesa_function_pool[29628]: VertexAttrib4dvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib4dvNV\0"
    "\0"
-   /* _mesa_function_pool[29398]: EndFragmentShaderATI (will be remapped) */
+   /* _mesa_function_pool[29652]: EndFragmentShaderATI (will be remapped) */
    "\0"
    "glEndFragmentShaderATI\0"
    "\0"
-   /* _mesa_function_pool[29423]: Binormal3iEXT (dynamic) */
+   /* _mesa_function_pool[29677]: Binormal3iEXT (dynamic) */
    "iii\0"
    "glBinormal3iEXT\0"
    "\0"
-   /* _mesa_function_pool[29444]: WindowPos2fMESA (will be remapped) */
+   /* _mesa_function_pool[29698]: WindowPos2fMESA (will be remapped) */
    "ff\0"
    "glWindowPos2f\0"
    "glWindowPos2fARB\0"
@@ -4333,392 +4366,400 @@
    GLint remap_index;
 } MESA_remap_table_functions[] = {
    {  1461, AttachShader_remap_index },
-   {  8704, CreateProgram_remap_index },
-   { 20115, CreateShader_remap_index },
-   { 22375, DeleteProgram_remap_index },
-   { 16150, DeleteShader_remap_index },
-   { 20561, DetachShader_remap_index },
-   { 15674, GetAttachedShaders_remap_index },
-   {  4244, GetProgramInfoLog_remap_index },
+   {  8764, CreateProgram_remap_index },
+   { 20302, CreateShader_remap_index },
+   { 22589, DeleteProgram_remap_index },
+   { 16282, DeleteShader_remap_index },
+   { 20748, DetachShader_remap_index },
+   { 15806, GetAttachedShaders_remap_index },
+   {  4275, GetProgramInfoLog_remap_index },
    {   361, GetProgramiv_remap_index },
-   {  5547, GetShaderInfoLog_remap_index },
-   { 27350, GetShaderiv_remap_index },
-   { 11657, IsProgram_remap_index },
-   { 10728, IsShader_remap_index },
-   {  8808, StencilFuncSeparate_remap_index },
+   {  5578, GetShaderInfoLog_remap_index },
+   { 27643, GetShaderiv_remap_index },
+   { 11821, IsProgram_remap_index },
+   { 10856, IsShader_remap_index },
+   {  8868, StencilFuncSeparate_remap_index },
    {  3487, StencilMaskSeparate_remap_index },
-   {  6623, StencilOpSeparate_remap_index },
-   { 19492, UniformMatrix2x3fv_remap_index },
+   {  6654, StencilOpSeparate_remap_index },
+   { 19653, UniformMatrix2x3fv_remap_index },
    {  2615, UniformMatrix2x4fv_remap_index },
-   { 29017, UniformMatrix3x2fv_remap_index },
-   { 26776, UniformMatrix3x4fv_remap_index },
-   { 14222, UniformMatrix4x2fv_remap_index },
+   { 29271, UniformMatrix3x2fv_remap_index },
+   { 27069, UniformMatrix3x4fv_remap_index },
+   { 14354, UniformMatrix4x2fv_remap_index },
    {  2937, UniformMatrix4x3fv_remap_index },
-   {  8722, LoadTransposeMatrixdARB_remap_index },
-   { 27079, LoadTransposeMatrixfARB_remap_index },
-   {  4817, MultTransposeMatrixdARB_remap_index },
-   { 20748, MultTransposeMatrixfARB_remap_index },
+   {  8782, LoadTransposeMatrixdARB_remap_index },
+   { 27372, LoadTransposeMatrixfARB_remap_index },
+   {  4848, MultTransposeMatrixdARB_remap_index },
+   { 20935, MultTransposeMatrixfARB_remap_index },
    {   172, SampleCoverageARB_remap_index },
-   {  4971, CompressedTexImage1DARB_remap_index },
-   { 21205, CompressedTexImage2DARB_remap_index },
+   {  5002, CompressedTexImage1DARB_remap_index },
+   { 21392, CompressedTexImage2DARB_remap_index },
    {  3550, CompressedTexImage3DARB_remap_index },
-   { 15966, CompressedTexSubImage1DARB_remap_index },
+   { 16098, CompressedTexSubImage1DARB_remap_index },
    {  1880, CompressedTexSubImage2DARB_remap_index },
-   { 17758, CompressedTexSubImage3DARB_remap_index },
-   { 25058, GetCompressedTexImageARB_remap_index },
+   { 17890, CompressedTexSubImage3DARB_remap_index },
+   { 25351, GetCompressedTexImageARB_remap_index },
    {  3395, DisableVertexAttribArrayARB_remap_index },
-   { 26388, EnableVertexAttribArrayARB_remap_index },
-   { 28193, GetProgramEnvParameterdvARB_remap_index },
-   { 20628, GetProgramEnvParameterfvARB_remap_index },
-   { 24088, GetProgramLocalParameterdvARB_remap_index },
-   {  7065, GetProgramLocalParameterfvARB_remap_index },
-   { 16057, GetProgramStringARB_remap_index },
-   { 24283, GetProgramivARB_remap_index },
-   { 17953, GetVertexAttribdvARB_remap_index },
-   { 14111, GetVertexAttribfvARB_remap_index },
-   {  8617, GetVertexAttribivARB_remap_index },
-   { 16862, ProgramEnvParameter4dARB_remap_index },
-   { 22175, ProgramEnvParameter4dvARB_remap_index },
-   { 14719, ProgramEnvParameter4fARB_remap_index },
-   {  7928, ProgramEnvParameter4fvARB_remap_index },
+   { 26681, EnableVertexAttribArrayARB_remap_index },
+   { 28447, GetProgramEnvParameterdvARB_remap_index },
+   { 20815, GetProgramEnvParameterfvARB_remap_index },
+   { 24381, GetProgramLocalParameterdvARB_remap_index },
+   {  7096, GetProgramLocalParameterfvARB_remap_index },
+   { 16189, GetProgramStringARB_remap_index },
+   { 24576, GetProgramivARB_remap_index },
+   { 18085, GetVertexAttribdvARB_remap_index },
+   { 14243, GetVertexAttribfvARB_remap_index },
+   {  8677, GetVertexAttribivARB_remap_index },
+   { 16994, ProgramEnvParameter4dARB_remap_index },
+   { 22362, ProgramEnvParameter4dvARB_remap_index },
+   { 14851, ProgramEnvParameter4fARB_remap_index },
+   {  7959, ProgramEnvParameter4fvARB_remap_index },
    {  3513, ProgramLocalParameter4dARB_remap_index },
-   { 11403, ProgramLocalParameter4dvARB_remap_index },
-   { 25867, ProgramLocalParameter4fARB_remap_index },
-   { 22693, ProgramLocalParameter4fvARB_remap_index },
-   { 24844, ProgramStringARB_remap_index },
-   { 17112, VertexAttrib1dARB_remap_index },
-   { 13765, VertexAttrib1dvARB_remap_index },
+   { 11531, ProgramLocalParameter4dvARB_remap_index },
+   { 26160, ProgramLocalParameter4fARB_remap_index },
+   { 22907, ProgramLocalParameter4fvARB_remap_index },
+   { 25137, ProgramStringARB_remap_index },
+   { 17244, VertexAttrib1dARB_remap_index },
+   { 13897, VertexAttrib1dvARB_remap_index },
    {  3688, VertexAttrib1fARB_remap_index },
-   { 29098, VertexAttrib1fvARB_remap_index },
-   {  6149, VertexAttrib1sARB_remap_index },
+   { 29352, VertexAttrib1fvARB_remap_index },
+   {  6180, VertexAttrib1sARB_remap_index },
    {  2054, VertexAttrib1svARB_remap_index },
-   { 13196, VertexAttrib2dARB_remap_index },
-   { 15293, VertexAttrib2dvARB_remap_index },
+   { 13328, VertexAttrib2dARB_remap_index },
+   { 15425, VertexAttrib2dvARB_remap_index },
    {  1480, VertexAttrib2fARB_remap_index },
-   { 15406, VertexAttrib2fvARB_remap_index },
-   { 28724, VertexAttrib2sARB_remap_index },
-   { 27830, VertexAttrib2svARB_remap_index },
-   {  9926, VertexAttrib3dARB_remap_index },
-   {  7631, VertexAttrib3dvARB_remap_index },
+   { 15538, VertexAttrib2fvARB_remap_index },
+   { 28978, VertexAttrib2sARB_remap_index },
+   { 28084, VertexAttrib2svARB_remap_index },
+   { 10015, VertexAttrib3dARB_remap_index },
+   {  7662, VertexAttrib3dvARB_remap_index },
    {  1567, VertexAttrib3fARB_remap_index },
-   { 19729, VertexAttrib3fvARB_remap_index },
-   { 24716, VertexAttrib3sARB_remap_index },
-   { 17695, VertexAttrib3svARB_remap_index },
-   {  4270, VertexAttrib4NbvARB_remap_index },
-   { 15629, VertexAttrib4NivARB_remap_index },
-   { 19684, VertexAttrib4NsvARB_remap_index },
-   { 20580, VertexAttrib4NubARB_remap_index },
-   { 28076, VertexAttrib4NubvARB_remap_index },
-   { 16523, VertexAttrib4NuivARB_remap_index },
+   { 19890, VertexAttrib3fvARB_remap_index },
+   { 25009, VertexAttrib3sARB_remap_index },
+   { 17827, VertexAttrib3svARB_remap_index },
+   {  4301, VertexAttrib4NbvARB_remap_index },
+   { 15761, VertexAttrib4NivARB_remap_index },
+   { 19845, VertexAttrib4NsvARB_remap_index },
+   { 20767, VertexAttrib4NubARB_remap_index },
+   { 28330, VertexAttrib4NubvARB_remap_index },
+   { 16655, VertexAttrib4NuivARB_remap_index },
    {  2810, VertexAttrib4NusvARB_remap_index },
-   {  9549, VertexAttrib4bvARB_remap_index },
-   { 23496, VertexAttrib4dARB_remap_index },
-   { 18678, VertexAttrib4dvARB_remap_index },
-   { 10033, VertexAttrib4fARB_remap_index },
-   { 10403, VertexAttrib4fvARB_remap_index },
-   {  9001, VertexAttrib4ivARB_remap_index },
-   { 15107, VertexAttrib4sARB_remap_index },
-   { 27265, VertexAttrib4svARB_remap_index },
-   { 14524, VertexAttrib4ubvARB_remap_index },
-   { 26712, VertexAttrib4uivARB_remap_index },
-   { 17506, VertexAttrib4usvARB_remap_index },
-   { 19366, VertexAttribPointerARB_remap_index },
-   { 28858, BindBufferARB_remap_index },
-   {  5862, BufferDataARB_remap_index },
+   {  9609, VertexAttrib4bvARB_remap_index },
+   { 23789, VertexAttrib4dARB_remap_index },
+   { 18810, VertexAttrib4dvARB_remap_index },
+   { 10122, VertexAttrib4fARB_remap_index },
+   { 10492, VertexAttrib4fvARB_remap_index },
+   {  9061, VertexAttrib4ivARB_remap_index },
+   { 15239, VertexAttrib4sARB_remap_index },
+   { 27558, VertexAttrib4svARB_remap_index },
+   { 14656, VertexAttrib4ubvARB_remap_index },
+   { 27005, VertexAttrib4uivARB_remap_index },
+   { 17638, VertexAttrib4usvARB_remap_index },
+   { 19527, VertexAttribPointerARB_remap_index },
+   { 29112, BindBufferARB_remap_index },
+   {  5893, BufferDataARB_remap_index },
    {  1382, BufferSubDataARB_remap_index },
-   { 26901, DeleteBuffersARB_remap_index },
-   { 29141, GenBuffersARB_remap_index },
-   { 15449, GetBufferParameterivARB_remap_index },
-   { 14671, GetBufferPointervARB_remap_index },
+   { 27194, DeleteBuffersARB_remap_index },
+   { 29395, GenBuffersARB_remap_index },
+   { 15581, GetBufferParameterivARB_remap_index },
+   { 14803, GetBufferPointervARB_remap_index },
    {  1335, GetBufferSubDataARB_remap_index },
-   { 26660, IsBufferARB_remap_index },
-   { 23124, MapBufferARB_remap_index },
-   { 27480, UnmapBufferARB_remap_index },
+   { 26953, IsBufferARB_remap_index },
+   { 23362, MapBufferARB_remap_index },
+   { 27773, UnmapBufferARB_remap_index },
    {   268, BeginQueryARB_remap_index },
-   { 17207, DeleteQueriesARB_remap_index },
-   { 10664, EndQueryARB_remap_index },
-   { 25537, GenQueriesARB_remap_index },
+   { 17339, DeleteQueriesARB_remap_index },
+   { 10753, EndQueryARB_remap_index },
+   { 25830, GenQueriesARB_remap_index },
    {  1772, GetQueryObjectivARB_remap_index },
-   { 15151, GetQueryObjectuivARB_remap_index },
+   { 15283, GetQueryObjectuivARB_remap_index },
    {  1624, GetQueryivARB_remap_index },
-   { 17413, IsQueryARB_remap_index },
-   {  7241, AttachObjectARB_remap_index },
-   { 16112, CompileShaderARB_remap_index },
+   { 17545, IsQueryARB_remap_index },
+   {  7272, AttachObjectARB_remap_index },
+   { 16244, CompileShaderARB_remap_index },
    {  2879, CreateProgramObjectARB_remap_index },
-   {  5807, CreateShaderObjectARB_remap_index },
-   { 12613, DeleteObjectARB_remap_index },
-   { 20979, DetachObjectARB_remap_index },
-   { 10475, GetActiveUniformARB_remap_index },
-   {  8320, GetAttachedObjectsARB_remap_index },
-   {  8599, GetHandleARB_remap_index },
-   { 28891, GetInfoLogARB_remap_index },
-   { 28147, GetObjectParameterfvARB_remap_index },
-   { 23962, GetObjectParameterivARB_remap_index },
-   { 25295, GetShaderSourceARB_remap_index },
-   { 24576, GetUniformLocationARB_remap_index },
-   { 20850, GetUniformfvARB_remap_index },
-   { 11025, GetUniformivARB_remap_index },
-   { 17551, LinkProgramARB_remap_index },
-   { 17609, ShaderSourceARB_remap_index },
-   {  6523, Uniform1fARB_remap_index },
-   { 26076, Uniform1fvARB_remap_index },
-   { 19335, Uniform1iARB_remap_index },
-   { 18367, Uniform1ivARB_remap_index },
+   {  5838, CreateShaderObjectARB_remap_index },
+   { 12745, DeleteObjectARB_remap_index },
+   { 21166, DetachObjectARB_remap_index },
+   { 10564, GetActiveUniformARB_remap_index },
+   {  8380, GetAttachedObjectsARB_remap_index },
+   {  8659, GetHandleARB_remap_index },
+   { 29145, GetInfoLogARB_remap_index },
+   { 28401, GetObjectParameterfvARB_remap_index },
+   { 24255, GetObjectParameterivARB_remap_index },
+   { 25588, GetShaderSourceARB_remap_index },
+   { 24869, GetUniformLocationARB_remap_index },
+   { 21037, GetUniformfvARB_remap_index },
+   { 11153, GetUniformivARB_remap_index },
+   { 17683, LinkProgramARB_remap_index },
+   { 17741, ShaderSourceARB_remap_index },
+   {  6554, Uniform1fARB_remap_index },
+   { 26369, Uniform1fvARB_remap_index },
+   { 19496, Uniform1iARB_remap_index },
+   { 18499, Uniform1ivARB_remap_index },
    {  2003, Uniform2fARB_remap_index },
-   { 12449, Uniform2fvARB_remap_index },
-   { 23011, Uniform2iARB_remap_index },
+   { 12581, Uniform2fvARB_remap_index },
+   { 23249, Uniform2iARB_remap_index },
    {  2123, Uniform2ivARB_remap_index },
-   { 16222, Uniform3fARB_remap_index },
-   {  8350, Uniform3fvARB_remap_index },
-   {  5481, Uniform3iARB_remap_index },
-   { 14777, Uniform3ivARB_remap_index },
-   { 16668, Uniform4fARB_remap_index },
-   { 20714, Uniform4fvARB_remap_index },
-   { 21854, Uniform4iARB_remap_index },
-   { 17919, Uniform4ivARB_remap_index },
-   {  7293, UniformMatrix2fvARB_remap_index },
+   { 16354, Uniform3fARB_remap_index },
+   {  8410, Uniform3fvARB_remap_index },
+   {  5512, Uniform3iARB_remap_index },
+   { 14909, Uniform3ivARB_remap_index },
+   { 16800, Uniform4fARB_remap_index },
+   { 20901, Uniform4fvARB_remap_index },
+   { 22041, Uniform4iARB_remap_index },
+   { 18051, Uniform4ivARB_remap_index },
+   {  7324, UniformMatrix2fvARB_remap_index },
    {    17, UniformMatrix3fvARB_remap_index },
    {  2475, UniformMatrix4fvARB_remap_index },
-   { 22287, UseProgramObjectARB_remap_index },
-   { 12884, ValidateProgramARB_remap_index },
-   { 18721, BindAttribLocationARB_remap_index },
-   {  4315, GetActiveAttribARB_remap_index },
-   { 14458, GetAttribLocationARB_remap_index },
-   { 25815, DrawBuffersARB_remap_index },
-   { 11508, RenderbufferStorageMultisample_remap_index },
-   { 16716, FlushMappedBufferRange_remap_index },
-   { 24379, MapBufferRange_remap_index },
-   { 14333, BindVertexArray_remap_index },
-   { 12743, GenVertexArrays_remap_index },
-   { 26590, CopyBufferSubData_remap_index },
-   { 27369, ClientWaitSync_remap_index },
+   { 22474, UseProgramObjectARB_remap_index },
+   { 13016, ValidateProgramARB_remap_index },
+   { 18853, BindAttribLocationARB_remap_index },
+   {  4346, GetActiveAttribARB_remap_index },
+   { 14590, GetAttribLocationARB_remap_index },
+   { 26108, DrawBuffersARB_remap_index },
+   { 11636, RenderbufferStorageMultisample_remap_index },
+   { 16848, FlushMappedBufferRange_remap_index },
+   { 24672, MapBufferRange_remap_index },
+   { 14465, BindVertexArray_remap_index },
+   { 12875, GenVertexArrays_remap_index },
+   { 26883, CopyBufferSubData_remap_index },
+   { 27662, ClientWaitSync_remap_index },
    {  2394, DeleteSync_remap_index },
-   {  6190, FenceSync_remap_index },
-   { 13255, GetInteger64v_remap_index },
-   { 19791, GetSynciv_remap_index },
-   { 25754, IsSync_remap_index },
-   {  8268, WaitSync_remap_index },
+   {  6221, FenceSync_remap_index },
+   { 13387, GetInteger64v_remap_index },
+   { 19952, GetSynciv_remap_index },
+   { 26047, IsSync_remap_index },
+   {  8328, WaitSync_remap_index },
    {  3363, DrawElementsBaseVertex_remap_index },
-   { 26833, DrawRangeElementsBaseVertex_remap_index },
-   { 23155, MultiDrawElementsBaseVertex_remap_index },
-   {  4680, PolygonOffsetEXT_remap_index },
-   { 20350, GetPixelTexGenParameterfvSGIS_remap_index },
+   { 27126, DrawRangeElementsBaseVertex_remap_index },
+   { 23393, MultiDrawElementsBaseVertex_remap_index },
+   {  4711, PolygonOffsetEXT_remap_index },
+   { 20537, GetPixelTexGenParameterfvSGIS_remap_index },
    {  3895, GetPixelTexGenParameterivSGIS_remap_index },
-   { 20083, PixelTexGenParameterfSGIS_remap_index },
+   { 20270, PixelTexGenParameterfSGIS_remap_index },
    {   580, PixelTexGenParameterfvSGIS_remap_index },
-   { 11063, PixelTexGenParameteriSGIS_remap_index },
-   { 12020, PixelTexGenParameterivSGIS_remap_index },
-   { 14421, SampleMaskSGIS_remap_index },
-   { 17353, SamplePatternSGIS_remap_index },
-   { 23084, ColorPointerEXT_remap_index },
-   { 15336, EdgeFlagPointerEXT_remap_index },
-   {  5135, IndexPointerEXT_remap_index },
-   {  5215, NormalPointerEXT_remap_index },
-   { 13849, TexCoordPointerEXT_remap_index },
-   {  5985, VertexPointerEXT_remap_index },
+   { 11191, PixelTexGenParameteriSGIS_remap_index },
+   { 12152, PixelTexGenParameterivSGIS_remap_index },
+   { 14553, SampleMaskSGIS_remap_index },
+   { 17485, SamplePatternSGIS_remap_index },
+   { 23322, ColorPointerEXT_remap_index },
+   { 15468, EdgeFlagPointerEXT_remap_index },
+   {  5166, IndexPointerEXT_remap_index },
+   {  5246, NormalPointerEXT_remap_index },
+   { 13981, TexCoordPointerEXT_remap_index },
+   {  6016, VertexPointerEXT_remap_index },
    {  3165, PointParameterfEXT_remap_index },
-   {  6830, PointParameterfvEXT_remap_index },
-   { 28245, LockArraysEXT_remap_index },
-   { 12948, UnlockArraysEXT_remap_index },
-   {  7837, CullParameterdvEXT_remap_index },
-   { 10270, CullParameterfvEXT_remap_index },
+   {  6861, PointParameterfvEXT_remap_index },
+   { 28499, LockArraysEXT_remap_index },
+   { 13080, UnlockArraysEXT_remap_index },
+   {  7868, CullParameterdvEXT_remap_index },
+   { 10359, CullParameterfvEXT_remap_index },
    {  1151, SecondaryColor3bEXT_remap_index },
-   {  6989, SecondaryColor3bvEXT_remap_index },
-   {  9178, SecondaryColor3dEXT_remap_index },
-   { 22433, SecondaryColor3dvEXT_remap_index },
-   { 24625, SecondaryColor3fEXT_remap_index },
-   { 15902, SecondaryColor3fvEXT_remap_index },
+   {  7020, SecondaryColor3bvEXT_remap_index },
+   {  9238, SecondaryColor3dEXT_remap_index },
+   { 22647, SecondaryColor3dvEXT_remap_index },
+   { 24918, SecondaryColor3fEXT_remap_index },
+   { 16034, SecondaryColor3fvEXT_remap_index },
    {   426, SecondaryColor3iEXT_remap_index },
-   { 14159, SecondaryColor3ivEXT_remap_index },
-   {  8836, SecondaryColor3sEXT_remap_index },
-   { 27033, SecondaryColor3svEXT_remap_index },
-   { 23798, SecondaryColor3ubEXT_remap_index },
-   { 18612, SecondaryColor3ubvEXT_remap_index },
-   { 11258, SecondaryColor3uiEXT_remap_index },
-   { 19970, SecondaryColor3uivEXT_remap_index },
-   { 22645, SecondaryColor3usEXT_remap_index },
-   { 11331, SecondaryColor3usvEXT_remap_index },
-   { 10346, SecondaryColorPointerEXT_remap_index },
-   { 22494, MultiDrawArraysEXT_remap_index },
-   { 18302, MultiDrawElementsEXT_remap_index },
-   { 18497, FogCoordPointerEXT_remap_index },
+   { 14291, SecondaryColor3ivEXT_remap_index },
+   {  8896, SecondaryColor3sEXT_remap_index },
+   { 27326, SecondaryColor3svEXT_remap_index },
+   { 24091, SecondaryColor3ubEXT_remap_index },
+   { 18744, SecondaryColor3ubvEXT_remap_index },
+   { 11386, SecondaryColor3uiEXT_remap_index },
+   { 20157, SecondaryColor3uivEXT_remap_index },
+   { 22859, SecondaryColor3usEXT_remap_index },
+   { 11459, SecondaryColor3usvEXT_remap_index },
+   { 10435, SecondaryColorPointerEXT_remap_index },
+   { 22708, MultiDrawArraysEXT_remap_index },
+   { 18434, MultiDrawElementsEXT_remap_index },
+   { 18629, FogCoordPointerEXT_remap_index },
    {  4044, FogCoorddEXT_remap_index },
-   { 27646, FogCoorddvEXT_remap_index },
-   {  4105, FogCoordfEXT_remap_index },
-   { 23721, FogCoordfvEXT_remap_index },
-   { 16620, PixelTexGenSGIX_remap_index },
-   { 24306, BlendFuncSeparateEXT_remap_index },
-   {  5897, FlushVertexArrayRangeNV_remap_index },
-   {  4629, VertexArrayRangeNV_remap_index },
-   { 24690, CombinerInputNV_remap_index },
+   { 27900, FogCoorddvEXT_remap_index },
+   {  4136, FogCoordfEXT_remap_index },
+   { 24014, FogCoordfvEXT_remap_index },
+   { 16752, PixelTexGenSGIX_remap_index },
+   { 24599, BlendFuncSeparateEXT_remap_index },
+   {  5928, FlushVertexArrayRangeNV_remap_index },
+   {  4660, VertexArrayRangeNV_remap_index },
+   { 24983, CombinerInputNV_remap_index },
    {  1946, CombinerOutputNV_remap_index },
-   { 27186, CombinerParameterfNV_remap_index },
-   {  4549, CombinerParameterfvNV_remap_index },
-   { 19541, CombinerParameteriNV_remap_index },
-   { 28616, CombinerParameterivNV_remap_index },
-   {  6267, FinalCombinerInputNV_remap_index },
-   {  8665, GetCombinerInputParameterfvNV_remap_index },
-   { 28453, GetCombinerInputParameterivNV_remap_index },
-   {  6066, GetCombinerOutputParameterfvNV_remap_index },
-   { 11949, GetCombinerOutputParameterivNV_remap_index },
-   {  5642, GetFinalCombinerInputParameterfvNV_remap_index },
-   { 21726, GetFinalCombinerInputParameterivNV_remap_index },
-   { 11003, ResizeBuffersMESA_remap_index },
-   {  9753, WindowPos2dMESA_remap_index },
+   { 27479, CombinerParameterfNV_remap_index },
+   {  4580, CombinerParameterfvNV_remap_index },
+   { 19702, CombinerParameteriNV_remap_index },
+   { 28870, CombinerParameterivNV_remap_index },
+   {  6298, FinalCombinerInputNV_remap_index },
+   {  8725, GetCombinerInputParameterfvNV_remap_index },
+   { 28707, GetCombinerInputParameterivNV_remap_index },
+   {  6097, GetCombinerOutputParameterfvNV_remap_index },
+   { 12113, GetCombinerOutputParameterivNV_remap_index },
+   {  5673, GetFinalCombinerInputParameterfvNV_remap_index },
+   { 21913, GetFinalCombinerInputParameterivNV_remap_index },
+   { 11131, ResizeBuffersMESA_remap_index },
+   {  9842, WindowPos2dMESA_remap_index },
    {   944, WindowPos2dvMESA_remap_index },
-   { 29444, WindowPos2fMESA_remap_index },
-   {  6934, WindowPos2fvMESA_remap_index },
-   { 15849, WindowPos2iMESA_remap_index },
-   { 17826, WindowPos2ivMESA_remap_index },
-   { 18401, WindowPos2sMESA_remap_index },
-   {  4885, WindowPos2svMESA_remap_index },
-   {  6759, WindowPos3dMESA_remap_index },
-   { 12228, WindowPos3dvMESA_remap_index },
+   { 29698, WindowPos2fMESA_remap_index },
+   {  6965, WindowPos2fvMESA_remap_index },
+   { 15981, WindowPos2iMESA_remap_index },
+   { 17958, WindowPos2ivMESA_remap_index },
+   { 18533, WindowPos2sMESA_remap_index },
+   {  4916, WindowPos2svMESA_remap_index },
+   {  6790, WindowPos3dMESA_remap_index },
+   { 12360, WindowPos3dvMESA_remap_index },
    {   472, WindowPos3fMESA_remap_index },
-   { 13009, WindowPos3fvMESA_remap_index },
-   { 21021, WindowPos3iMESA_remap_index },
-   { 26535, WindowPos3ivMESA_remap_index },
-   { 16366, WindowPos3sMESA_remap_index },
-   { 27902, WindowPos3svMESA_remap_index },
-   {  9704, WindowPos4dMESA_remap_index },
-   { 14862, WindowPos4dvMESA_remap_index },
-   { 12187, WindowPos4fMESA_remap_index },
-   { 26940, WindowPos4fvMESA_remap_index },
-   { 26688, WindowPos4iMESA_remap_index },
-   { 10842, WindowPos4ivMESA_remap_index },
-   { 16499, WindowPos4sMESA_remap_index },
+   { 13141, WindowPos3fvMESA_remap_index },
+   { 21208, WindowPos3iMESA_remap_index },
+   { 26828, WindowPos3ivMESA_remap_index },
+   { 16498, WindowPos3sMESA_remap_index },
+   { 28156, WindowPos3svMESA_remap_index },
+   {  9793, WindowPos4dMESA_remap_index },
+   { 14994, WindowPos4dvMESA_remap_index },
+   { 12319, WindowPos4fMESA_remap_index },
+   { 27233, WindowPos4fvMESA_remap_index },
+   { 26981, WindowPos4iMESA_remap_index },
+   { 10970, WindowPos4ivMESA_remap_index },
+   { 16631, WindowPos4sMESA_remap_index },
    {  2857, WindowPos4svMESA_remap_index },
-   { 11988, MultiModeDrawArraysIBM_remap_index },
-   { 25408, MultiModeDrawElementsIBM_remap_index },
-   { 10692, DeleteFencesNV_remap_index },
-   { 24537, FinishFenceNV_remap_index },
+   { 23757, MultiModeDrawArraysIBM_remap_index },
+   { 25701, MultiModeDrawElementsIBM_remap_index },
+   { 10781, DeleteFencesNV_remap_index },
+   { 24830, FinishFenceNV_remap_index },
    {  3287, GenFencesNV_remap_index },
-   { 14842, GetFenceivNV_remap_index },
-   {  7226, IsFenceNV_remap_index },
-   { 11876, SetFenceNV_remap_index },
+   { 14974, GetFenceivNV_remap_index },
+   {  7257, IsFenceNV_remap_index },
+   { 12040, SetFenceNV_remap_index },
    {  3744, TestFenceNV_remap_index },
-   { 27873, AreProgramsResidentNV_remap_index },
-   { 27228, BindProgramNV_remap_index },
-   { 22728, DeleteProgramsNV_remap_index },
-   { 18830, ExecuteProgramNV_remap_index },
-   { 29337, GenProgramsNV_remap_index },
-   { 20429, GetProgramParameterdvNV_remap_index },
-   {  9240, GetProgramParameterfvNV_remap_index },
-   { 23058, GetProgramStringNV_remap_index },
-   { 21415, GetProgramivNV_remap_index },
-   { 20663, GetTrackMatrixivNV_remap_index },
-   { 22878, GetVertexAttribPointervNV_remap_index },
-   { 21659, GetVertexAttribdvNV_remap_index },
-   { 16339, GetVertexAttribfvNV_remap_index },
-   { 16030, GetVertexAttribivNV_remap_index },
-   { 16746, IsProgramNV_remap_index },
-   {  8246, LoadProgramNV_remap_index },
-   { 24402, ProgramParameters4dvNV_remap_index },
-   { 21345, ProgramParameters4fvNV_remap_index },
-   { 18130, RequestResidentProgramsNV_remap_index },
-   { 19519, TrackMatrixNV_remap_index },
-   { 28430, VertexAttrib1dNV_remap_index },
-   { 11817, VertexAttrib1dvNV_remap_index },
-   { 24940, VertexAttrib1fNV_remap_index },
+   { 28127, AreProgramsResidentNV_remap_index },
+   { 27521, BindProgramNV_remap_index },
+   { 22942, DeleteProgramsNV_remap_index },
+   { 18962, ExecuteProgramNV_remap_index },
+   { 29591, GenProgramsNV_remap_index },
+   { 20616, GetProgramParameterdvNV_remap_index },
+   {  9300, GetProgramParameterfvNV_remap_index },
+   { 23296, GetProgramStringNV_remap_index },
+   { 21602, GetProgramivNV_remap_index },
+   { 20850, GetTrackMatrixivNV_remap_index },
+   { 23092, GetVertexAttribPointervNV_remap_index },
+   { 21846, GetVertexAttribdvNV_remap_index },
+   { 16471, GetVertexAttribfvNV_remap_index },
+   { 16162, GetVertexAttribivNV_remap_index },
+   { 16878, IsProgramNV_remap_index },
+   {  8306, LoadProgramNV_remap_index },
+   { 24695, ProgramParameters4dvNV_remap_index },
+   { 21532, ProgramParameters4fvNV_remap_index },
+   { 18262, RequestResidentProgramsNV_remap_index },
+   { 19680, TrackMatrixNV_remap_index },
+   { 28684, VertexAttrib1dNV_remap_index },
+   { 11981, VertexAttrib1dvNV_remap_index },
+   { 25233, VertexAttrib1fNV_remap_index },
    {  2245, VertexAttrib1fvNV_remap_index },
-   { 26997, VertexAttrib1sNV_remap_index },
-   { 13082, VertexAttrib1svNV_remap_index },
-   {  4220, VertexAttrib2dNV_remap_index },
-   { 11732, VertexAttrib2dvNV_remap_index },
-   { 17585, VertexAttrib2fNV_remap_index },
-   { 11379, VertexAttrib2fvNV_remap_index },
-   {  5045, VertexAttrib2sNV_remap_index },
-   { 16420, VertexAttrib2svNV_remap_index },
-   {  9901, VertexAttrib3dNV_remap_index },
-   { 28123, VertexAttrib3dvNV_remap_index },
-   {  9052, VertexAttrib3fNV_remap_index },
-   { 21686, VertexAttrib3fvNV_remap_index },
-   { 24915, VertexAttrib3sNV_remap_index },
-   { 20690, VertexAttrib3svNV_remap_index },
-   { 25382, VertexAttrib4dNV_remap_index },
-   { 29374, VertexAttrib4dvNV_remap_index },
+   { 27290, VertexAttrib1sNV_remap_index },
+   { 13214, VertexAttrib1svNV_remap_index },
+   {  4251, VertexAttrib2dNV_remap_index },
+   { 11896, VertexAttrib2dvNV_remap_index },
+   { 17717, VertexAttrib2fNV_remap_index },
+   { 11507, VertexAttrib2fvNV_remap_index },
+   {  5076, VertexAttrib2sNV_remap_index },
+   { 16552, VertexAttrib2svNV_remap_index },
+   {  9990, VertexAttrib3dNV_remap_index },
+   { 28377, VertexAttrib3dvNV_remap_index },
+   {  9112, VertexAttrib3fNV_remap_index },
+   { 21873, VertexAttrib3fvNV_remap_index },
+   { 25208, VertexAttrib3sNV_remap_index },
+   { 20877, VertexAttrib3svNV_remap_index },
+   { 25675, VertexAttrib4dNV_remap_index },
+   { 29628, VertexAttrib4dvNV_remap_index },
    {  3945, VertexAttrib4fNV_remap_index },
-   {  8296, VertexAttrib4fvNV_remap_index },
-   { 23380, VertexAttrib4sNV_remap_index },
+   {  8356, VertexAttrib4fvNV_remap_index },
+   { 23641, VertexAttrib4sNV_remap_index },
    {  1293, VertexAttrib4svNV_remap_index },
-   {  4378, VertexAttrib4ubNV_remap_index },
+   {  4409, VertexAttrib4ubNV_remap_index },
    {   734, VertexAttrib4ubvNV_remap_index },
-   { 19010, VertexAttribPointerNV_remap_index },
+   { 19142, VertexAttribPointerNV_remap_index },
    {  2097, VertexAttribs1dvNV_remap_index },
-   { 16444, VertexAttribs1fvNV_remap_index },
-   { 29174, VertexAttribs1svNV_remap_index },
-   {  9077, VertexAttribs2dvNV_remap_index },
-   { 22248, VertexAttribs2fvNV_remap_index },
-   { 15362, VertexAttribs2svNV_remap_index },
-   {  4577, VertexAttribs3dvNV_remap_index },
+   { 16576, VertexAttribs1fvNV_remap_index },
+   { 29428, VertexAttribs1svNV_remap_index },
+   {  9137, VertexAttribs2dvNV_remap_index },
+   { 22435, VertexAttribs2fvNV_remap_index },
+   { 15494, VertexAttribs2svNV_remap_index },
+   {  4608, VertexAttribs3dvNV_remap_index },
    {  1977, VertexAttribs3fvNV_remap_index },
-   { 26283, VertexAttribs3svNV_remap_index },
-   { 23470, VertexAttribs4dvNV_remap_index },
-   {  4603, VertexAttribs4fvNV_remap_index },
-   { 28961, VertexAttribs4svNV_remap_index },
-   { 26031, VertexAttribs4ubvNV_remap_index },
-   { 23540, GetTexBumpParameterfvATI_remap_index },
-   { 29215, GetTexBumpParameterivATI_remap_index },
-   { 16084, TexBumpParameterfvATI_remap_index },
-   { 18001, TexBumpParameterivATI_remap_index },
-   { 13628, AlphaFragmentOp1ATI_remap_index },
-   {  9592, AlphaFragmentOp2ATI_remap_index },
-   { 21602, AlphaFragmentOp3ATI_remap_index },
-   { 26210, BeginFragmentShaderATI_remap_index },
-   { 27427, BindFragmentShaderATI_remap_index },
-   { 20819, ColorFragmentOp1ATI_remap_index },
+   { 26576, VertexAttribs3svNV_remap_index },
+   { 23731, VertexAttribs4dvNV_remap_index },
+   {  4634, VertexAttribs4fvNV_remap_index },
+   { 29215, VertexAttribs4svNV_remap_index },
+   { 26324, VertexAttribs4ubvNV_remap_index },
+   { 23833, GetTexBumpParameterfvATI_remap_index },
+   { 29469, GetTexBumpParameterivATI_remap_index },
+   { 16216, TexBumpParameterfvATI_remap_index },
+   { 18133, TexBumpParameterivATI_remap_index },
+   { 13760, AlphaFragmentOp1ATI_remap_index },
+   {  9652, AlphaFragmentOp2ATI_remap_index },
+   { 21789, AlphaFragmentOp3ATI_remap_index },
+   { 26503, BeginFragmentShaderATI_remap_index },
+   { 27720, BindFragmentShaderATI_remap_index },
+   { 21006, ColorFragmentOp1ATI_remap_index },
    {  3823, ColorFragmentOp2ATI_remap_index },
-   { 27768, ColorFragmentOp3ATI_remap_index },
-   {  4722, DeleteFragmentShaderATI_remap_index },
-   { 29398, EndFragmentShaderATI_remap_index },
-   { 28644, GenFragmentShadersATI_remap_index },
-   { 22352, PassTexCoordATI_remap_index },
-   {  5965, SampleMapATI_remap_index },
-   {  5738, SetFragmentShaderConstantATI_remap_index },
+   { 28022, ColorFragmentOp3ATI_remap_index },
+   {  4753, DeleteFragmentShaderATI_remap_index },
+   { 29652, EndFragmentShaderATI_remap_index },
+   { 28898, GenFragmentShadersATI_remap_index },
+   { 22566, PassTexCoordATI_remap_index },
+   {  5996, SampleMapATI_remap_index },
+   {  5769, SetFragmentShaderConstantATI_remap_index },
    {   319, PointParameteriNV_remap_index },
-   { 12389, PointParameterivNV_remap_index },
-   { 25221, ActiveStencilFaceEXT_remap_index },
-   { 24062, BindVertexArrayAPPLE_remap_index },
+   { 12521, PointParameterivNV_remap_index },
+   { 25514, ActiveStencilFaceEXT_remap_index },
+   { 24355, BindVertexArrayAPPLE_remap_index },
    {  2522, DeleteVertexArraysAPPLE_remap_index },
-   { 15701, GenVertexArraysAPPLE_remap_index },
-   { 20494, IsVertexArrayAPPLE_remap_index },
+   { 15833, GenVertexArraysAPPLE_remap_index },
+   { 20681, IsVertexArrayAPPLE_remap_index },
    {   775, GetProgramNamedParameterdvNV_remap_index },
    {  3128, GetProgramNamedParameterfvNV_remap_index },
-   { 23571, ProgramNamedParameter4dNV_remap_index },
-   { 12664, ProgramNamedParameter4dvNV_remap_index },
-   {  7862, ProgramNamedParameter4fNV_remap_index },
-   { 10311, ProgramNamedParameter4fvNV_remap_index },
-   { 21324, DepthBoundsEXT_remap_index },
+   { 23864, ProgramNamedParameter4dNV_remap_index },
+   { 12796, ProgramNamedParameter4dvNV_remap_index },
+   {  7893, ProgramNamedParameter4fNV_remap_index },
+   { 10400, ProgramNamedParameter4fvNV_remap_index },
+   { 21511, DepthBoundsEXT_remap_index },
    {  1043, BlendEquationSeparateEXT_remap_index },
-   { 12783, BindFramebufferEXT_remap_index },
-   { 22539, BindRenderbufferEXT_remap_index },
-   {  8515, CheckFramebufferStatusEXT_remap_index },
-   { 19810, DeleteFramebuffersEXT_remap_index },
-   { 28025, DeleteRenderbuffersEXT_remap_index },
-   { 11756, FramebufferRenderbufferEXT_remap_index },
-   { 11893, FramebufferTexture1DEXT_remap_index },
-   { 10139, FramebufferTexture2DEXT_remap_index },
-   {  9806, FramebufferTexture3DEXT_remap_index },
-   { 20386, GenFramebuffersEXT_remap_index },
-   { 15248, GenRenderbuffersEXT_remap_index },
-   {  5684, GenerateMipmapEXT_remap_index },
-   { 19041, GetFramebufferAttachmentParameterivEXT_remap_index },
-   { 28550, GetRenderbufferParameterivEXT_remap_index },
-   { 17881, IsFramebufferEXT_remap_index },
-   { 29297, IsRenderbufferEXT_remap_index },
-   {  7173, RenderbufferStorageEXT_remap_index },
+   { 12915, BindFramebufferEXT_remap_index },
+   { 22753, BindRenderbufferEXT_remap_index },
+   {  8575, CheckFramebufferStatusEXT_remap_index },
+   { 19971, DeleteFramebuffersEXT_remap_index },
+   { 28279, DeleteRenderbuffersEXT_remap_index },
+   { 11920, FramebufferRenderbufferEXT_remap_index },
+   { 12057, FramebufferTexture1DEXT_remap_index },
+   { 10228, FramebufferTexture2DEXT_remap_index },
+   {  9895, FramebufferTexture3DEXT_remap_index },
+   { 20573, GenFramebuffersEXT_remap_index },
+   { 15380, GenRenderbuffersEXT_remap_index },
+   {  5715, GenerateMipmapEXT_remap_index },
+   { 19202, GetFramebufferAttachmentParameterivEXT_remap_index },
+   { 28804, GetRenderbufferParameterivEXT_remap_index },
+   { 18013, IsFramebufferEXT_remap_index },
+   { 29551, IsRenderbufferEXT_remap_index },
+   {  7204, RenderbufferStorageEXT_remap_index },
    {   651, BlitFramebufferEXT_remap_index },
-   { 12483, BufferParameteriAPPLE_remap_index },
-   { 16778, FlushMappedBufferRangeAPPLE_remap_index },
+   { 12615, BufferParameteriAPPLE_remap_index },
+   { 16910, FlushMappedBufferRangeAPPLE_remap_index },
    {  2701, FramebufferTextureLayerEXT_remap_index },
-   { 25932, ProvokingVertexEXT_remap_index },
-   {  9461, GetTexParameterPointervAPPLE_remap_index },
-   {  4405, TextureRangeAPPLE_remap_index },
-   { 25247, StencilFuncSeparateATI_remap_index },
-   { 15768, ProgramEnvParameters4fvEXT_remap_index },
-   { 14986, ProgramLocalParameters4fvEXT_remap_index },
-   { 12317, GetQueryObjecti64vEXT_remap_index },
-   {  9103, GetQueryObjectui64vEXT_remap_index },
+   {  8277, ColorMaskIndexedEXT_remap_index },
+   { 23180, DisableIndexedEXT_remap_index },
+   { 23488, EnableIndexedEXT_remap_index },
+   { 19173, GetBooleanIndexedvEXT_remap_index },
+   {  9685, GetIntegerIndexedvEXT_remap_index },
+   { 20047, IsEnabledIndexedEXT_remap_index },
+   {  4074, BeginConditionalRenderNV_remap_index },
+   { 22539, EndConditionalRenderNV_remap_index },
+   { 26225, ProvokingVertexEXT_remap_index },
+   {  9521, GetTexParameterPointervAPPLE_remap_index },
+   {  4436, TextureRangeAPPLE_remap_index },
+   { 25540, StencilFuncSeparateATI_remap_index },
+   { 15900, ProgramEnvParameters4fvEXT_remap_index },
+   { 15118, ProgramLocalParameters4fvEXT_remap_index },
+   { 12449, GetQueryObjecti64vEXT_remap_index },
+   {  9163, GetQueryObjectui64vEXT_remap_index },
    {    -1, -1 }
 };
 
@@ -4727,108 +4768,108 @@
    /* from GL_EXT_blend_color */
    {  2440, _gloffset_BlendColor },
    /* from GL_EXT_blend_minmax */
-   {  9863, _gloffset_BlendEquation },
+   {  9952, _gloffset_BlendEquation },
    /* from GL_EXT_color_subtable */
-   { 14884, _gloffset_ColorSubTable },
-   { 27957, _gloffset_CopyColorSubTable },
+   { 15016, _gloffset_ColorSubTable },
+   { 28211, _gloffset_CopyColorSubTable },
    /* from GL_EXT_convolution */
    {   213, _gloffset_ConvolutionFilter1D },
    {  2284, _gloffset_CopyConvolutionFilter1D },
    {  3624, _gloffset_GetConvolutionParameteriv },
-   {  7522, _gloffset_ConvolutionFilter2D },
-   {  7688, _gloffset_ConvolutionParameteriv },
-   {  8148, _gloffset_ConvolutionParameterfv },
-   { 18029, _gloffset_GetSeparableFilter },
-   { 21075, _gloffset_SeparableFilter2D },
-   { 21904, _gloffset_ConvolutionParameteri },
-   { 22027, _gloffset_ConvolutionParameterf },
-   { 23406, _gloffset_GetConvolutionParameterfv },
-   { 24228, _gloffset_GetConvolutionFilter },
-   { 26472, _gloffset_CopyConvolutionFilter2D },
+   {  7553, _gloffset_ConvolutionFilter2D },
+   {  7719, _gloffset_ConvolutionParameteriv },
+   {  8179, _gloffset_ConvolutionParameterfv },
+   { 18161, _gloffset_GetSeparableFilter },
+   { 21262, _gloffset_SeparableFilter2D },
+   { 22091, _gloffset_ConvolutionParameteri },
+   { 22214, _gloffset_ConvolutionParameterf },
+   { 23667, _gloffset_GetConvolutionParameterfv },
+   { 24521, _gloffset_GetConvolutionFilter },
+   { 26765, _gloffset_CopyConvolutionFilter2D },
    /* from GL_EXT_copy_texture */
-   { 13142, _gloffset_CopyTexSubImage3D },
-   { 14624, _gloffset_CopyTexImage2D },
-   { 21512, _gloffset_CopyTexImage1D },
-   { 23909, _gloffset_CopyTexSubImage2D },
-   { 26110, _gloffset_CopyTexSubImage1D },
+   { 13274, _gloffset_CopyTexSubImage3D },
+   { 14756, _gloffset_CopyTexImage2D },
+   { 21699, _gloffset_CopyTexImage1D },
+   { 24202, _gloffset_CopyTexSubImage2D },
+   { 26403, _gloffset_CopyTexSubImage1D },
    /* from GL_EXT_draw_range_elements */
-   {  8402, _gloffset_DrawRangeElements },
+   {  8462, _gloffset_DrawRangeElements },
    /* from GL_EXT_histogram */
    {   812, _gloffset_Histogram },
    {  3088, _gloffset_ResetHistogram },
-   {  8774, _gloffset_GetMinmax },
-   { 13476, _gloffset_GetHistogramParameterfv },
-   { 21437, _gloffset_GetMinmaxParameteriv },
-   { 23296, _gloffset_ResetMinmax },
-   { 24125, _gloffset_GetHistogramParameteriv },
-   { 25181, _gloffset_GetHistogram },
-   { 27543, _gloffset_Minmax },
-   { 29044, _gloffset_GetMinmaxParameterfv },
+   {  8834, _gloffset_GetMinmax },
+   { 13608, _gloffset_GetHistogramParameterfv },
+   { 21624, _gloffset_GetMinmaxParameteriv },
+   { 23557, _gloffset_ResetMinmax },
+   { 24418, _gloffset_GetHistogramParameteriv },
+   { 25474, _gloffset_GetHistogram },
+   { 27836, _gloffset_Minmax },
+   { 29298, _gloffset_GetMinmaxParameterfv },
    /* from GL_EXT_paletted_texture */
-   {  7384, _gloffset_ColorTable },
-   { 13322, _gloffset_GetColorTable },
-   { 20133, _gloffset_GetColorTableParameterfv },
-   { 22083, _gloffset_GetColorTableParameteriv },
+   {  7415, _gloffset_ColorTable },
+   { 13454, _gloffset_GetColorTable },
+   { 20320, _gloffset_GetColorTableParameterfv },
+   { 22270, _gloffset_GetColorTableParameteriv },
    /* from GL_EXT_subtexture */
-   {  6105, _gloffset_TexSubImage1D },
-   {  9388, _gloffset_TexSubImage2D },
+   {  6136, _gloffset_TexSubImage1D },
+   {  9448, _gloffset_TexSubImage2D },
    /* from GL_EXT_texture3D */
    {  1658, _gloffset_TexImage3D },
-   { 19902, _gloffset_TexSubImage3D },
+   { 20089, _gloffset_TexSubImage3D },
    /* from GL_EXT_texture_object */
    {  2964, _gloffset_PrioritizeTextures },
-   {  6554, _gloffset_AreTexturesResident },
-   { 11841, _gloffset_GenTextures },
-   { 13808, _gloffset_DeleteTextures },
-   { 17059, _gloffset_IsTexture },
-   { 26175, _gloffset_BindTexture },
+   {  6585, _gloffset_AreTexturesResident },
+   { 12005, _gloffset_GenTextures },
+   { 13940, _gloffset_DeleteTextures },
+   { 17191, _gloffset_IsTexture },
+   { 26468, _gloffset_BindTexture },
    /* from GL_EXT_vertex_array */
-   { 21264, _gloffset_ArrayElement },
-   { 27131, _gloffset_GetPointerv },
-   { 28671, _gloffset_DrawArrays },
+   { 21451, _gloffset_ArrayElement },
+   { 27424, _gloffset_GetPointerv },
+   { 28925, _gloffset_DrawArrays },
    /* from GL_SGI_color_table */
-   {  6672, _gloffset_ColorTableParameteriv },
-   {  7384, _gloffset_ColorTable },
-   { 13322, _gloffset_GetColorTable },
-   { 13432, _gloffset_CopyColorTable },
-   { 16920, _gloffset_ColorTableParameterfv },
-   { 20133, _gloffset_GetColorTableParameterfv },
-   { 22083, _gloffset_GetColorTableParameteriv },
+   {  6703, _gloffset_ColorTableParameteriv },
+   {  7415, _gloffset_ColorTable },
+   { 13454, _gloffset_GetColorTable },
+   { 13564, _gloffset_CopyColorTable },
+   { 17052, _gloffset_ColorTableParameterfv },
+   { 20320, _gloffset_GetColorTableParameterfv },
+   { 22270, _gloffset_GetColorTableParameteriv },
    /* from GL_VERSION_1_3 */
    {   381, _gloffset_MultiTexCoord3sARB },
    {   613, _gloffset_ActiveTextureARB },
    {  3761, _gloffset_MultiTexCoord1fvARB },
-   {  5240, _gloffset_MultiTexCoord3dARB },
-   {  5285, _gloffset_MultiTexCoord2iARB },
-   {  5409, _gloffset_MultiTexCoord2svARB },
-   {  7340, _gloffset_MultiTexCoord2fARB },
-   {  9133, _gloffset_MultiTexCoord3fvARB },
-   {  9625, _gloffset_MultiTexCoord4sARB },
-   { 10225, _gloffset_MultiTexCoord2dvARB },
-   { 10607, _gloffset_MultiTexCoord1svARB },
-   { 10864, _gloffset_MultiTexCoord3svARB },
-   { 10925, _gloffset_MultiTexCoord4iARB },
-   { 11612, _gloffset_MultiTexCoord3iARB },
-   { 12346, _gloffset_MultiTexCoord1dARB },
-   { 12512, _gloffset_MultiTexCoord3dvARB },
-   { 13676, _gloffset_MultiTexCoord3ivARB },
-   { 13721, _gloffset_MultiTexCoord2sARB },
-   { 14941, _gloffset_MultiTexCoord4ivARB },
-   { 16570, _gloffset_ClientActiveTextureARB },
-   { 18786, _gloffset_MultiTexCoord2dARB },
-   { 19161, _gloffset_MultiTexCoord4dvARB },
-   { 19447, _gloffset_MultiTexCoord4fvARB },
-   { 20274, _gloffset_MultiTexCoord3fARB },
-   { 22584, _gloffset_MultiTexCoord4dARB },
-   { 22788, _gloffset_MultiTexCoord1sARB },
-   { 22966, _gloffset_MultiTexCoord1dvARB },
-   { 23753, _gloffset_MultiTexCoord1ivARB },
-   { 23846, _gloffset_MultiTexCoord2ivARB },
-   { 24185, _gloffset_MultiTexCoord1iARB },
-   { 25456, _gloffset_MultiTexCoord4svARB },
-   { 25974, _gloffset_MultiTexCoord1fARB },
-   { 26237, _gloffset_MultiTexCoord4fARB },
-   { 28505, _gloffset_MultiTexCoord2fvARB },
+   {  5271, _gloffset_MultiTexCoord3dARB },
+   {  5316, _gloffset_MultiTexCoord2iARB },
+   {  5440, _gloffset_MultiTexCoord2svARB },
+   {  7371, _gloffset_MultiTexCoord2fARB },
+   {  9193, _gloffset_MultiTexCoord3fvARB },
+   {  9714, _gloffset_MultiTexCoord4sARB },
+   { 10314, _gloffset_MultiTexCoord2dvARB },
+   { 10696, _gloffset_MultiTexCoord1svARB },
+   { 10992, _gloffset_MultiTexCoord3svARB },
+   { 11053, _gloffset_MultiTexCoord4iARB },
+   { 11776, _gloffset_MultiTexCoord3iARB },
+   { 12478, _gloffset_MultiTexCoord1dARB },
+   { 12644, _gloffset_MultiTexCoord3dvARB },
+   { 13808, _gloffset_MultiTexCoord3ivARB },
+   { 13853, _gloffset_MultiTexCoord2sARB },
+   { 15073, _gloffset_MultiTexCoord4ivARB },
+   { 16702, _gloffset_ClientActiveTextureARB },
+   { 18918, _gloffset_MultiTexCoord2dARB },
+   { 19322, _gloffset_MultiTexCoord4dvARB },
+   { 19608, _gloffset_MultiTexCoord4fvARB },
+   { 20461, _gloffset_MultiTexCoord3fARB },
+   { 22798, _gloffset_MultiTexCoord4dARB },
+   { 23002, _gloffset_MultiTexCoord1sARB },
+   { 23204, _gloffset_MultiTexCoord1dvARB },
+   { 24046, _gloffset_MultiTexCoord1ivARB },
+   { 24139, _gloffset_MultiTexCoord2ivARB },
+   { 24478, _gloffset_MultiTexCoord1iARB },
+   { 25749, _gloffset_MultiTexCoord4svARB },
+   { 26267, _gloffset_MultiTexCoord1fARB },
+   { 26530, _gloffset_MultiTexCoord4fARB },
+   { 28759, _gloffset_MultiTexCoord2fvARB },
    {    -1, -1 }
 };
 
@@ -4836,7 +4877,7 @@
 
 #if defined(need_GL_3DFX_tbuffer)
 static const struct gl_function_remap GL_3DFX_tbuffer_functions[] = {
-   {  8206, -1 }, /* TbufferMask3DFX */
+   {  8237, -1 }, /* TbufferMask3DFX */
    {    -1, -1 }
 };
 #endif
@@ -4900,10 +4941,10 @@
 #if defined(need_GL_ARB_matrix_palette)
 static const struct gl_function_remap GL_ARB_matrix_palette_functions[] = {
    {  3339, -1 }, /* MatrixIndexusvARB */
-   { 11469, -1 }, /* MatrixIndexuivARB */
-   { 12634, -1 }, /* MatrixIndexPointerARB */
-   { 17308, -1 }, /* CurrentPaletteMatrixARB */
-   { 20018, -1 }, /* MatrixIndexubvARB */
+   { 11597, -1 }, /* MatrixIndexuivARB */
+   { 12766, -1 }, /* MatrixIndexPointerARB */
+   { 17440, -1 }, /* CurrentPaletteMatrixARB */
+   { 20205, -1 }, /* MatrixIndexubvARB */
    {    -1, -1 }
 };
 #endif
@@ -4974,15 +5015,15 @@
 #if defined(need_GL_ARB_vertex_blend)
 static const struct gl_function_remap GL_ARB_vertex_blend_functions[] = {
    {  2226, -1 }, /* WeightubvARB */
-   {  5572, -1 }, /* WeightivARB */
-   {  9728, -1 }, /* WeightPointerARB */
-   { 12103, -1 }, /* WeightfvARB */
-   { 15388, -1 }, /* WeightbvARB */
-   { 18454, -1 }, /* WeightusvARB */
-   { 21001, -1 }, /* VertexBlendARB */
-   { 26058, -1 }, /* WeightsvARB */
-   { 28007, -1 }, /* WeightdvARB */
-   { 28705, -1 }, /* WeightuivARB */
+   {  5603, -1 }, /* WeightivARB */
+   {  9817, -1 }, /* WeightPointerARB */
+   { 12235, -1 }, /* WeightfvARB */
+   { 15520, -1 }, /* WeightbvARB */
+   { 18586, -1 }, /* WeightusvARB */
+   { 21188, -1 }, /* VertexBlendARB */
+   { 26351, -1 }, /* WeightsvARB */
+   { 28261, -1 }, /* WeightdvARB */
+   { 28959, -1 }, /* WeightuivARB */
    {    -1, -1 }
 };
 #endif
@@ -5073,15 +5114,15 @@
 
 #if defined(need_GL_EXT_blend_minmax)
 static const struct gl_function_remap GL_EXT_blend_minmax_functions[] = {
-   {  9863, _gloffset_BlendEquation },
+   {  9952, _gloffset_BlendEquation },
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_color_subtable)
 static const struct gl_function_remap GL_EXT_color_subtable_functions[] = {
-   { 14884, _gloffset_ColorSubTable },
-   { 27957, _gloffset_CopyColorSubTable },
+   { 15016, _gloffset_ColorSubTable },
+   { 28211, _gloffset_CopyColorSubTable },
    {    -1, -1 }
 };
 #endif
@@ -5098,55 +5139,55 @@
    {   213, _gloffset_ConvolutionFilter1D },
    {  2284, _gloffset_CopyConvolutionFilter1D },
    {  3624, _gloffset_GetConvolutionParameteriv },
-   {  7522, _gloffset_ConvolutionFilter2D },
-   {  7688, _gloffset_ConvolutionParameteriv },
-   {  8148, _gloffset_ConvolutionParameterfv },
-   { 18029, _gloffset_GetSeparableFilter },
-   { 21075, _gloffset_SeparableFilter2D },
-   { 21904, _gloffset_ConvolutionParameteri },
-   { 22027, _gloffset_ConvolutionParameterf },
-   { 23406, _gloffset_GetConvolutionParameterfv },
-   { 24228, _gloffset_GetConvolutionFilter },
-   { 26472, _gloffset_CopyConvolutionFilter2D },
+   {  7553, _gloffset_ConvolutionFilter2D },
+   {  7719, _gloffset_ConvolutionParameteriv },
+   {  8179, _gloffset_ConvolutionParameterfv },
+   { 18161, _gloffset_GetSeparableFilter },
+   { 21262, _gloffset_SeparableFilter2D },
+   { 22091, _gloffset_ConvolutionParameteri },
+   { 22214, _gloffset_ConvolutionParameterf },
+   { 23667, _gloffset_GetConvolutionParameterfv },
+   { 24521, _gloffset_GetConvolutionFilter },
+   { 26765, _gloffset_CopyConvolutionFilter2D },
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_coordinate_frame)
 static const struct gl_function_remap GL_EXT_coordinate_frame_functions[] = {
-   {  9272, -1 }, /* TangentPointerEXT */
-   { 10983, -1 }, /* Binormal3ivEXT */
-   { 11565, -1 }, /* Tangent3sEXT */
-   { 12699, -1 }, /* Tangent3fvEXT */
-   { 16320, -1 }, /* Tangent3dvEXT */
-   { 17006, -1 }, /* Binormal3bvEXT */
-   { 18082, -1 }, /* Binormal3dEXT */
-   { 19950, -1 }, /* Tangent3fEXT */
-   { 21976, -1 }, /* Binormal3sEXT */
-   { 22394, -1 }, /* Tangent3ivEXT */
-   { 22413, -1 }, /* Tangent3dEXT */
-   { 23193, -1 }, /* Binormal3svEXT */
-   { 23651, -1 }, /* Binormal3fEXT */
-   { 24503, -1 }, /* Binormal3dvEXT */
-   { 25678, -1 }, /* Tangent3iEXT */
-   { 26757, -1 }, /* Tangent3bvEXT */
-   { 27166, -1 }, /* Tangent3bEXT */
-   { 27730, -1 }, /* Binormal3fvEXT */
-   { 28404, -1 }, /* BinormalPointerEXT */
-   { 28809, -1 }, /* Tangent3svEXT */
-   { 29246, -1 }, /* Binormal3bEXT */
-   { 29423, -1 }, /* Binormal3iEXT */
+   {  9332, -1 }, /* TangentPointerEXT */
+   { 11111, -1 }, /* Binormal3ivEXT */
+   { 11729, -1 }, /* Tangent3sEXT */
+   { 12831, -1 }, /* Tangent3fvEXT */
+   { 16452, -1 }, /* Tangent3dvEXT */
+   { 17138, -1 }, /* Binormal3bvEXT */
+   { 18214, -1 }, /* Binormal3dEXT */
+   { 20137, -1 }, /* Tangent3fEXT */
+   { 22163, -1 }, /* Binormal3sEXT */
+   { 22608, -1 }, /* Tangent3ivEXT */
+   { 22627, -1 }, /* Tangent3dEXT */
+   { 23431, -1 }, /* Binormal3svEXT */
+   { 23944, -1 }, /* Binormal3fEXT */
+   { 24796, -1 }, /* Binormal3dvEXT */
+   { 25971, -1 }, /* Tangent3iEXT */
+   { 27050, -1 }, /* Tangent3bvEXT */
+   { 27459, -1 }, /* Tangent3bEXT */
+   { 27984, -1 }, /* Binormal3fvEXT */
+   { 28658, -1 }, /* BinormalPointerEXT */
+   { 29063, -1 }, /* Tangent3svEXT */
+   { 29500, -1 }, /* Binormal3bEXT */
+   { 29677, -1 }, /* Binormal3iEXT */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_copy_texture)
 static const struct gl_function_remap GL_EXT_copy_texture_functions[] = {
-   { 13142, _gloffset_CopyTexSubImage3D },
-   { 14624, _gloffset_CopyTexImage2D },
-   { 21512, _gloffset_CopyTexImage1D },
-   { 23909, _gloffset_CopyTexSubImage2D },
-   { 26110, _gloffset_CopyTexSubImage1D },
+   { 13274, _gloffset_CopyTexSubImage3D },
+   { 14756, _gloffset_CopyTexImage2D },
+   { 21699, _gloffset_CopyTexImage1D },
+   { 24202, _gloffset_CopyTexSubImage2D },
+   { 26403, _gloffset_CopyTexSubImage1D },
    {    -1, -1 }
 };
 #endif
@@ -5165,9 +5206,16 @@
 };
 #endif
 
+#if defined(need_GL_EXT_draw_buffers2)
+/* functions defined in MESA_remap_table_functions are excluded */
+static const struct gl_function_remap GL_EXT_draw_buffers2_functions[] = {
+   {    -1, -1 }
+};
+#endif
+
 #if defined(need_GL_EXT_draw_range_elements)
 static const struct gl_function_remap GL_EXT_draw_range_elements_functions[] = {
-   {  8402, _gloffset_DrawRangeElements },
+   {  8462, _gloffset_DrawRangeElements },
    {    -1, -1 }
 };
 #endif
@@ -5186,6 +5234,13 @@
 };
 #endif
 
+#if defined(need_GL_EXT_framebuffer_multisample)
+/* functions defined in MESA_remap_table_functions are excluded */
+static const struct gl_function_remap GL_EXT_framebuffer_multisample_functions[] = {
+   {    -1, -1 }
+};
+#endif
+
 #if defined(need_GL_EXT_framebuffer_object)
 /* functions defined in MESA_remap_table_functions are excluded */
 static const struct gl_function_remap GL_EXT_framebuffer_object_functions[] = {
@@ -5204,37 +5259,37 @@
 static const struct gl_function_remap GL_EXT_histogram_functions[] = {
    {   812, _gloffset_Histogram },
    {  3088, _gloffset_ResetHistogram },
-   {  8774, _gloffset_GetMinmax },
-   { 13476, _gloffset_GetHistogramParameterfv },
-   { 21437, _gloffset_GetMinmaxParameteriv },
-   { 23296, _gloffset_ResetMinmax },
-   { 24125, _gloffset_GetHistogramParameteriv },
-   { 25181, _gloffset_GetHistogram },
-   { 27543, _gloffset_Minmax },
-   { 29044, _gloffset_GetMinmaxParameterfv },
+   {  8834, _gloffset_GetMinmax },
+   { 13608, _gloffset_GetHistogramParameterfv },
+   { 21624, _gloffset_GetMinmaxParameteriv },
+   { 23557, _gloffset_ResetMinmax },
+   { 24418, _gloffset_GetHistogramParameteriv },
+   { 25474, _gloffset_GetHistogram },
+   { 27836, _gloffset_Minmax },
+   { 29298, _gloffset_GetMinmaxParameterfv },
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_index_func)
 static const struct gl_function_remap GL_EXT_index_func_functions[] = {
-   { 10090, -1 }, /* IndexFuncEXT */
+   { 10179, -1 }, /* IndexFuncEXT */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_index_material)
 static const struct gl_function_remap GL_EXT_index_material_functions[] = {
-   { 18541, -1 }, /* IndexMaterialEXT */
+   { 18673, -1 }, /* IndexMaterialEXT */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_light_texture)
 static const struct gl_function_remap GL_EXT_light_texture_functions[] = {
-   { 23213, -1 }, /* ApplyTextureEXT */
-   { 23250, -1 }, /* TextureMaterialEXT */
-   { 23275, -1 }, /* TextureLightEXT */
+   { 23451, -1 }, /* ApplyTextureEXT */
+   { 23511, -1 }, /* TextureMaterialEXT */
+   { 23536, -1 }, /* TextureLightEXT */
    {    -1, -1 }
 };
 #endif
@@ -5255,20 +5310,20 @@
 
 #if defined(need_GL_EXT_paletted_texture)
 static const struct gl_function_remap GL_EXT_paletted_texture_functions[] = {
-   {  7384, _gloffset_ColorTable },
-   { 13322, _gloffset_GetColorTable },
-   { 20133, _gloffset_GetColorTableParameterfv },
-   { 22083, _gloffset_GetColorTableParameteriv },
+   {  7415, _gloffset_ColorTable },
+   { 13454, _gloffset_GetColorTable },
+   { 20320, _gloffset_GetColorTableParameterfv },
+   { 22270, _gloffset_GetColorTableParameteriv },
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_pixel_transform)
 static const struct gl_function_remap GL_EXT_pixel_transform_functions[] = {
-   {  9513, -1 }, /* PixelTransformParameterfvEXT */
-   { 19126, -1 }, /* PixelTransformParameterfEXT */
-   { 19206, -1 }, /* PixelTransformParameteriEXT */
-   { 28368, -1 }, /* PixelTransformParameterivEXT */
+   {  9573, -1 }, /* PixelTransformParameterfvEXT */
+   { 19287, -1 }, /* PixelTransformParameterfEXT */
+   { 19367, -1 }, /* PixelTransformParameteriEXT */
+   { 28622, -1 }, /* PixelTransformParameterivEXT */
    {    -1, -1 }
 };
 #endif
@@ -5310,8 +5365,8 @@
 
 #if defined(need_GL_EXT_subtexture)
 static const struct gl_function_remap GL_EXT_subtexture_functions[] = {
-   {  6105, _gloffset_TexSubImage1D },
-   {  9388, _gloffset_TexSubImage2D },
+   {  6136, _gloffset_TexSubImage1D },
+   {  9448, _gloffset_TexSubImage2D },
    {    -1, -1 }
 };
 #endif
@@ -5319,7 +5374,7 @@
 #if defined(need_GL_EXT_texture3D)
 static const struct gl_function_remap GL_EXT_texture3D_functions[] = {
    {  1658, _gloffset_TexImage3D },
-   { 19902, _gloffset_TexSubImage3D },
+   { 20089, _gloffset_TexSubImage3D },
    {    -1, -1 }
 };
 #endif
@@ -5334,18 +5389,18 @@
 #if defined(need_GL_EXT_texture_object)
 static const struct gl_function_remap GL_EXT_texture_object_functions[] = {
    {  2964, _gloffset_PrioritizeTextures },
-   {  6554, _gloffset_AreTexturesResident },
-   { 11841, _gloffset_GenTextures },
-   { 13808, _gloffset_DeleteTextures },
-   { 17059, _gloffset_IsTexture },
-   { 26175, _gloffset_BindTexture },
+   {  6585, _gloffset_AreTexturesResident },
+   { 12005, _gloffset_GenTextures },
+   { 13940, _gloffset_DeleteTextures },
+   { 17191, _gloffset_IsTexture },
+   { 26468, _gloffset_BindTexture },
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_texture_perturb_normal)
 static const struct gl_function_remap GL_EXT_texture_perturb_normal_functions[] = {
-   { 12053, -1 }, /* TextureNormalEXT */
+   { 12185, -1 }, /* TextureNormalEXT */
    {    -1, -1 }
 };
 #endif
@@ -5360,18 +5415,18 @@
 #if defined(need_GL_EXT_vertex_array)
 /* functions defined in MESA_remap_table_functions are excluded */
 static const struct gl_function_remap GL_EXT_vertex_array_functions[] = {
-   { 21264, _gloffset_ArrayElement },
-   { 27131, _gloffset_GetPointerv },
-   { 28671, _gloffset_DrawArrays },
+   { 21451, _gloffset_ArrayElement },
+   { 27424, _gloffset_GetPointerv },
+   { 28925, _gloffset_DrawArrays },
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_vertex_weighting)
 static const struct gl_function_remap GL_EXT_vertex_weighting_functions[] = {
-   { 17089, -1 }, /* VertexWeightfvEXT */
-   { 23629, -1 }, /* VertexWeightfEXT */
-   { 25150, -1 }, /* VertexWeightPointerEXT */
+   { 17221, -1 }, /* VertexWeightfvEXT */
+   { 23922, -1 }, /* VertexWeightfEXT */
+   { 25443, -1 }, /* VertexWeightPointerEXT */
    {    -1, -1 }
 };
 #endif
@@ -5380,10 +5435,10 @@
 static const struct gl_function_remap GL_HP_image_transform_functions[] = {
    {  2157, -1 }, /* GetImageTransformParameterfvHP */
    {  3305, -1 }, /* ImageTransformParameterfHP */
-   {  8966, -1 }, /* ImageTransformParameterfvHP */
-   { 10525, -1 }, /* ImageTransformParameteriHP */
-   { 10754, -1 }, /* GetImageTransformParameterivHP */
-   { 17153, -1 }, /* ImageTransformParameterivHP */
+   {  9026, -1 }, /* ImageTransformParameterfvHP */
+   { 10614, -1 }, /* ImageTransformParameteriHP */
+   { 10882, -1 }, /* GetImageTransformParameterivHP */
+   { 17285, -1 }, /* ImageTransformParameterivHP */
    {    -1, -1 }
 };
 #endif
@@ -5398,13 +5453,13 @@
 #if defined(need_GL_IBM_vertex_array_lists)
 static const struct gl_function_remap GL_IBM_vertex_array_lists_functions[] = {
    {  3857, -1 }, /* SecondaryColorPointerListIBM */
-   {  5106, -1 }, /* NormalPointerListIBM */
-   {  6728, -1 }, /* FogCoordPointerListIBM */
-   {  7035, -1 }, /* VertexPointerListIBM */
-   { 10446, -1 }, /* ColorPointerListIBM */
-   { 11672, -1 }, /* TexCoordPointerListIBM */
-   { 12075, -1 }, /* IndexPointerListIBM */
-   { 28987, -1 }, /* EdgeFlagPointerListIBM */
+   {  5137, -1 }, /* NormalPointerListIBM */
+   {  6759, -1 }, /* FogCoordPointerListIBM */
+   {  7066, -1 }, /* VertexPointerListIBM */
+   { 10535, -1 }, /* ColorPointerListIBM */
+   { 11836, -1 }, /* TexCoordPointerListIBM */
+   { 12207, -1 }, /* IndexPointerListIBM */
+   { 29241, -1 }, /* EdgeFlagPointerListIBM */
    {    -1, -1 }
 };
 #endif
@@ -5418,10 +5473,10 @@
 
 #if defined(need_GL_INTEL_parallel_arrays)
 static const struct gl_function_remap GL_INTEL_parallel_arrays_functions[] = {
-   { 11095, -1 }, /* VertexPointervINTEL */
-   { 13569, -1 }, /* ColorPointervINTEL */
-   { 26446, -1 }, /* NormalPointervINTEL */
-   { 26872, -1 }, /* TexCoordPointervINTEL */
+   { 11223, -1 }, /* VertexPointervINTEL */
+   { 13701, -1 }, /* ColorPointervINTEL */
+   { 26739, -1 }, /* NormalPointervINTEL */
+   { 27165, -1 }, /* TexCoordPointervINTEL */
    {    -1, -1 }
 };
 #endif
@@ -5438,7 +5493,7 @@
    {  1522, -1 }, /* GetDebugLogLengthMESA */
    {  3063, -1 }, /* ClearDebugLogMESA */
    {  4018, -1 }, /* GetDebugLogMESA */
-   { 27324, -1 }, /* CreateDebugObjectMESA */
+   { 27617, -1 }, /* CreateDebugObjectMESA */
    {    -1, -1 }
 };
 #endif
@@ -5450,17 +5505,24 @@
 };
 #endif
 
+#if defined(need_GL_NV_condtitional_render)
+/* functions defined in MESA_remap_table_functions are excluded */
+static const struct gl_function_remap GL_NV_condtitional_render_functions[] = {
+   {    -1, -1 }
+};
+#endif
+
 #if defined(need_GL_NV_evaluators)
 static const struct gl_function_remap GL_NV_evaluators_functions[] = {
-   {  5773, -1 }, /* GetMapAttribParameterivNV */
-   {  7490, -1 }, /* MapControlPointsNV */
-   {  7589, -1 }, /* MapParameterfvNV */
-   {  9371, -1 }, /* EvalMapsNV */
-   { 15058, -1 }, /* GetMapAttribParameterfvNV */
-   { 15224, -1 }, /* MapParameterivNV */
-   { 21827, -1 }, /* GetMapParameterivNV */
-   { 22325, -1 }, /* GetMapParameterfvNV */
-   { 25782, -1 }, /* GetMapControlPointsNV */
+   {  5804, -1 }, /* GetMapAttribParameterivNV */
+   {  7521, -1 }, /* MapControlPointsNV */
+   {  7620, -1 }, /* MapParameterfvNV */
+   {  9431, -1 }, /* EvalMapsNV */
+   { 15190, -1 }, /* GetMapAttribParameterfvNV */
+   { 15356, -1 }, /* MapParameterivNV */
+   { 22014, -1 }, /* GetMapParameterivNV */
+   { 22512, -1 }, /* GetMapParameterfvNV */
+   { 26075, -1 }, /* GetMapControlPointsNV */
    {    -1, -1 }
 };
 #endif
@@ -5495,8 +5557,8 @@
 
 #if defined(need_GL_NV_register_combiners2)
 static const struct gl_function_remap GL_NV_register_combiners2_functions[] = {
-   { 13961, -1 }, /* CombinerStageParameterfvNV */
-   { 14276, -1 }, /* GetCombinerStageParameterfvNV */
+   { 14093, -1 }, /* CombinerStageParameterfvNV */
+   { 14408, -1 }, /* GetCombinerStageParameterfvNV */
    {    -1, -1 }
 };
 #endif
@@ -5517,23 +5579,23 @@
 
 #if defined(need_GL_PGI_misc_hints)
 static const struct gl_function_remap GL_PGI_misc_hints_functions[] = {
-   {  7674, -1 }, /* HintPGI */
+   {  7705, -1 }, /* HintPGI */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIS_detail_texture)
 static const struct gl_function_remap GL_SGIS_detail_texture_functions[] = {
-   { 14249, -1 }, /* GetDetailTexFuncSGIS */
-   { 14569, -1 }, /* DetailTexFuncSGIS */
+   { 14381, -1 }, /* GetDetailTexFuncSGIS */
+   { 14701, -1 }, /* DetailTexFuncSGIS */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIS_fog_function)
 static const struct gl_function_remap GL_SGIS_fog_function_functions[] = {
-   { 23891, -1 }, /* FogFuncSGIS */
-   { 24556, -1 }, /* GetFogFuncSGIS */
+   { 24184, -1 }, /* FogFuncSGIS */
+   { 24849, -1 }, /* GetFogFuncSGIS */
    {    -1, -1 }
 };
 #endif
@@ -5561,8 +5623,8 @@
 
 #if defined(need_GL_SGIS_sharpen_texture)
 static const struct gl_function_remap GL_SGIS_sharpen_texture_functions[] = {
-   {  5834, -1 }, /* GetSharpenTexFuncSGIS */
-   { 19421, -1 }, /* SharpenTexFuncSGIS */
+   {  5865, -1 }, /* GetSharpenTexFuncSGIS */
+   { 19582, -1 }, /* SharpenTexFuncSGIS */
    {    -1, -1 }
 };
 #endif
@@ -5570,22 +5632,22 @@
 #if defined(need_GL_SGIS_texture4D)
 static const struct gl_function_remap GL_SGIS_texture4D_functions[] = {
    {   894, -1 }, /* TexImage4DSGIS */
-   { 13877, -1 }, /* TexSubImage4DSGIS */
+   { 14009, -1 }, /* TexSubImage4DSGIS */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIS_texture_color_mask)
 static const struct gl_function_remap GL_SGIS_texture_color_mask_functions[] = {
-   { 13275, -1 }, /* TextureColorMaskSGIS */
+   { 13407, -1 }, /* TextureColorMaskSGIS */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIS_texture_filter4)
 static const struct gl_function_remap GL_SGIS_texture_filter4_functions[] = {
-   {  6011, -1 }, /* GetTexFilterFuncSGIS */
-   { 14395, -1 }, /* TexFilterFuncSGIS */
+   {  6042, -1 }, /* GetTexFilterFuncSGIS */
+   { 14527, -1 }, /* TexFilterFuncSGIS */
    {    -1, -1 }
 };
 #endif
@@ -5594,17 +5656,17 @@
 static const struct gl_function_remap GL_SGIX_async_functions[] = {
    {  3014, -1 }, /* AsyncMarkerSGIX */
    {  3997, -1 }, /* FinishAsyncSGIX */
-   {  4703, -1 }, /* PollAsyncSGIX */
-   { 19568, -1 }, /* DeleteAsyncMarkersSGIX */
-   { 19597, -1 }, /* IsAsyncMarkerSGIX */
-   { 28784, -1 }, /* GenAsyncMarkersSGIX */
+   {  4734, -1 }, /* PollAsyncSGIX */
+   { 19729, -1 }, /* DeleteAsyncMarkersSGIX */
+   { 19758, -1 }, /* IsAsyncMarkerSGIX */
+   { 29038, -1 }, /* GenAsyncMarkersSGIX */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIX_flush_raster)
 static const struct gl_function_remap GL_SGIX_flush_raster_functions[] = {
-   {  6382, -1 }, /* FlushRasterSGIX */
+   {  6413, -1 }, /* FlushRasterSGIX */
    {    -1, -1 }
 };
 #endif
@@ -5613,36 +5675,36 @@
 static const struct gl_function_remap GL_SGIX_fragment_lighting_functions[] = {
    {  2410, -1 }, /* FragmentMaterialfvSGIX */
    {  2906, -1 }, /* FragmentLightModelivSGIX */
-   {  4654, -1 }, /* FragmentLightiSGIX */
-   {  5514, -1 }, /* GetFragmentMaterialfvSGIX */
-   {  7102, -1 }, /* FragmentMaterialfSGIX */
-   {  7263, -1 }, /* GetFragmentLightivSGIX */
-   {  8100, -1 }, /* FragmentLightModeliSGIX */
-   {  9434, -1 }, /* FragmentLightivSGIX */
-   {  9671, -1 }, /* GetFragmentMaterialivSGIX */
-   { 16976, -1 }, /* FragmentLightModelfSGIX */
-   { 17276, -1 }, /* FragmentColorMaterialSGIX */
-   { 17648, -1 }, /* FragmentMaterialiSGIX */
-   { 18869, -1 }, /* LightEnviSGIX */
-   { 20225, -1 }, /* FragmentLightModelfvSGIX */
-   { 20534, -1 }, /* FragmentLightfvSGIX */
-   { 25032, -1 }, /* FragmentLightfSGIX */
-   { 27700, -1 }, /* GetFragmentLightfvSGIX */
-   { 29267, -1 }, /* FragmentMaterialivSGIX */
+   {  4685, -1 }, /* FragmentLightiSGIX */
+   {  5545, -1 }, /* GetFragmentMaterialfvSGIX */
+   {  7133, -1 }, /* FragmentMaterialfSGIX */
+   {  7294, -1 }, /* GetFragmentLightivSGIX */
+   {  8131, -1 }, /* FragmentLightModeliSGIX */
+   {  9494, -1 }, /* FragmentLightivSGIX */
+   {  9760, -1 }, /* GetFragmentMaterialivSGIX */
+   { 17108, -1 }, /* FragmentLightModelfSGIX */
+   { 17408, -1 }, /* FragmentColorMaterialSGIX */
+   { 17780, -1 }, /* FragmentMaterialiSGIX */
+   { 19001, -1 }, /* LightEnviSGIX */
+   { 20412, -1 }, /* FragmentLightModelfvSGIX */
+   { 20721, -1 }, /* FragmentLightfvSGIX */
+   { 25325, -1 }, /* FragmentLightfSGIX */
+   { 27954, -1 }, /* GetFragmentLightfvSGIX */
+   { 29521, -1 }, /* FragmentMaterialivSGIX */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIX_framezoom)
 static const struct gl_function_remap GL_SGIX_framezoom_functions[] = {
-   { 19620, -1 }, /* FrameZoomSGIX */
+   { 19781, -1 }, /* FrameZoomSGIX */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIX_igloo_interface)
 static const struct gl_function_remap GL_SGIX_igloo_interface_functions[] = {
-   { 25340, -1 }, /* IglooInterfaceSGIX */
+   { 25633, -1 }, /* IglooInterfaceSGIX */
    {    -1, -1 }
 };
 #endif
@@ -5650,11 +5712,11 @@
 #if defined(need_GL_SGIX_instruments)
 static const struct gl_function_remap GL_SGIX_instruments_functions[] = {
    {  2573, -1 }, /* ReadInstrumentsSGIX */
-   {  5590, -1 }, /* PollInstrumentsSGIX */
-   {  9332, -1 }, /* GetInstrumentsSGIX */
-   { 11306, -1 }, /* StartInstrumentsSGIX */
-   { 13995, -1 }, /* StopInstrumentsSGIX */
-   { 15601, -1 }, /* InstrumentsBufferSGIX */
+   {  5621, -1 }, /* PollInstrumentsSGIX */
+   {  9392, -1 }, /* GetInstrumentsSGIX */
+   { 11434, -1 }, /* StartInstrumentsSGIX */
+   { 14127, -1 }, /* StopInstrumentsSGIX */
+   { 15733, -1 }, /* InstrumentsBufferSGIX */
    {    -1, -1 }
 };
 #endif
@@ -5663,10 +5725,10 @@
 static const struct gl_function_remap GL_SGIX_list_priority_functions[] = {
    {  1125, -1 }, /* ListParameterfSGIX */
    {  2763, -1 }, /* GetListParameterfvSGIX */
-   { 15516, -1 }, /* ListParameteriSGIX */
-   { 16270, -1 }, /* ListParameterfvSGIX */
-   { 18275, -1 }, /* ListParameterivSGIX */
-   { 28828, -1 }, /* GetListParameterivSGIX */
+   { 15648, -1 }, /* ListParameteriSGIX */
+   { 16402, -1 }, /* ListParameterfvSGIX */
+   { 18407, -1 }, /* ListParameterivSGIX */
+   { 29082, -1 }, /* GetListParameterivSGIX */
    {    -1, -1 }
 };
 #endif
@@ -5681,53 +5743,53 @@
 #if defined(need_GL_SGIX_polynomial_ffd)
 static const struct gl_function_remap GL_SGIX_polynomial_ffd_functions[] = {
    {  3251, -1 }, /* LoadIdentityDeformationMapSGIX */
-   { 14095, -1 }, /* DeformSGIX */
-   { 21376, -1 }, /* DeformationMap3fSGIX */
-   { 27588, -1 }, /* DeformationMap3dSGIX */
+   { 10802, -1 }, /* DeformationMap3dSGIX */
+   { 14227, -1 }, /* DeformSGIX */
+   { 21563, -1 }, /* DeformationMap3fSGIX */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIX_reference_plane)
 static const struct gl_function_remap GL_SGIX_reference_plane_functions[] = {
-   { 12826, -1 }, /* ReferencePlaneSGIX */
+   { 12958, -1 }, /* ReferencePlaneSGIX */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIX_sprite)
 static const struct gl_function_remap GL_SGIX_sprite_functions[] = {
-   {  8487, -1 }, /* SpriteParameterfvSGIX */
-   { 18103, -1 }, /* SpriteParameteriSGIX */
-   { 23330, -1 }, /* SpriteParameterfSGIX */
-   { 25904, -1 }, /* SpriteParameterivSGIX */
+   {  8547, -1 }, /* SpriteParameterfvSGIX */
+   { 18235, -1 }, /* SpriteParameteriSGIX */
+   { 23591, -1 }, /* SpriteParameterfSGIX */
+   { 26197, -1 }, /* SpriteParameterivSGIX */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIX_tag_sample_buffer)
 static const struct gl_function_remap GL_SGIX_tag_sample_buffer_functions[] = {
-   { 18162, -1 }, /* TagSampleBufferSGIX */
+   { 18294, -1 }, /* TagSampleBufferSGIX */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGI_color_table)
 static const struct gl_function_remap GL_SGI_color_table_functions[] = {
-   {  6672, _gloffset_ColorTableParameteriv },
-   {  7384, _gloffset_ColorTable },
-   { 13322, _gloffset_GetColorTable },
-   { 13432, _gloffset_CopyColorTable },
-   { 16920, _gloffset_ColorTableParameterfv },
-   { 20133, _gloffset_GetColorTableParameterfv },
-   { 22083, _gloffset_GetColorTableParameteriv },
+   {  6703, _gloffset_ColorTableParameteriv },
+   {  7415, _gloffset_ColorTable },
+   { 13454, _gloffset_GetColorTable },
+   { 13564, _gloffset_CopyColorTable },
+   { 17052, _gloffset_ColorTableParameterfv },
+   { 20320, _gloffset_GetColorTableParameterfv },
+   { 22270, _gloffset_GetColorTableParameteriv },
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SUNX_constant_data)
 static const struct gl_function_remap GL_SUNX_constant_data_functions[] = {
-   { 27678, -1 }, /* FinishTextureSUNX */
+   { 27932, -1 }, /* FinishTextureSUNX */
    {    -1, -1 }
 };
 #endif
@@ -5735,20 +5797,20 @@
 #if defined(need_GL_SUN_global_alpha)
 static const struct gl_function_remap GL_SUN_global_alpha_functions[] = {
    {  3035, -1 }, /* GlobalAlphaFactorubSUN */
-   {  4193, -1 }, /* GlobalAlphaFactoriSUN */
-   {  5615, -1 }, /* GlobalAlphaFactordSUN */
-   {  8571, -1 }, /* GlobalAlphaFactoruiSUN */
-   {  8923, -1 }, /* GlobalAlphaFactorbSUN */
-   { 11585, -1 }, /* GlobalAlphaFactorfSUN */
-   { 11704, -1 }, /* GlobalAlphaFactorusSUN */
-   { 19859, -1 }, /* GlobalAlphaFactorsSUN */
+   {  4224, -1 }, /* GlobalAlphaFactoriSUN */
+   {  5646, -1 }, /* GlobalAlphaFactordSUN */
+   {  8631, -1 }, /* GlobalAlphaFactoruiSUN */
+   {  8983, -1 }, /* GlobalAlphaFactorbSUN */
+   { 11749, -1 }, /* GlobalAlphaFactorfSUN */
+   { 11868, -1 }, /* GlobalAlphaFactorusSUN */
+   { 20020, -1 }, /* GlobalAlphaFactorsSUN */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SUN_mesh_array)
 static const struct gl_function_remap GL_SUN_mesh_array_functions[] = {
-   { 25716, -1 }, /* DrawMeshArraysSUN */
+   { 26009, -1 }, /* DrawMeshArraysSUN */
    {    -1, -1 }
 };
 #endif
@@ -5756,12 +5818,12 @@
 #if defined(need_GL_SUN_triangle_list)
 static const struct gl_function_remap GL_SUN_triangle_list_functions[] = {
    {  3971, -1 }, /* ReplacementCodeubSUN */
-   {  5454, -1 }, /* ReplacementCodeubvSUN */
-   { 16641, -1 }, /* ReplacementCodeusvSUN */
-   { 16829, -1 }, /* ReplacementCodePointerSUN */
-   { 18186, -1 }, /* ReplacementCodeusSUN */
-   { 18933, -1 }, /* ReplacementCodeuiSUN */
-   { 26361, -1 }, /* ReplacementCodeuivSUN */
+   {  5485, -1 }, /* ReplacementCodeubvSUN */
+   { 16773, -1 }, /* ReplacementCodeusvSUN */
+   { 16961, -1 }, /* ReplacementCodePointerSUN */
+   { 18318, -1 }, /* ReplacementCodeusSUN */
+   { 19065, -1 }, /* ReplacementCodeuiSUN */
+   { 26654, -1 }, /* ReplacementCodeuivSUN */
    {    -1, -1 }
 };
 #endif
@@ -5775,39 +5837,39 @@
    {  1833, -1 }, /* ReplacementCodeuiTexCoord2fVertex3fvSUN */
    {  2346, -1 }, /* ReplacementCodeuiNormal3fVertex3fSUN */
    {  2642, -1 }, /* Color4ubVertex3fvSUN */
-   {  4074, -1 }, /* Color4ubVertex3fSUN */
-   {  4150, -1 }, /* TexCoord2fVertex3fSUN */
-   {  4449, -1 }, /* TexCoord2fColor4fNormal3fVertex3fSUN */
-   {  4779, -1 }, /* TexCoord2fNormal3fVertex3fvSUN */
-   {  5349, -1 }, /* ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN */
-   {  6419, -1 }, /* ReplacementCodeuiTexCoord2fVertex3fSUN */
-   {  7131, -1 }, /* TexCoord2fNormal3fVertex3fSUN */
-   {  7899, -1 }, /* Color3fVertex3fSUN */
-   {  8882, -1 }, /* Color3fVertex3fvSUN */
-   {  9297, -1 }, /* Color4fNormal3fVertex3fvSUN */
-   {  9969, -1 }, /* ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN */
-   { 11169, -1 }, /* ReplacementCodeuiColor4fNormal3fVertex3fvSUN */
-   { 12557, -1 }, /* ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN */
-   { 12968, -1 }, /* TexCoord2fColor3fVertex3fSUN */
-   { 14020, -1 }, /* TexCoord4fColor4fNormal3fVertex4fSUN */
-   { 14354, -1 }, /* Color4ubVertex2fvSUN */
-   { 14594, -1 }, /* Normal3fVertex3fSUN */
-   { 15542, -1 }, /* ReplacementCodeuiColor4fNormal3fVertex3fSUN */
-   { 15803, -1 }, /* TexCoord2fColor4fNormal3fVertex3fvSUN */
-   { 16470, -1 }, /* TexCoord2fVertex3fvSUN */
-   { 17246, -1 }, /* Color4ubVertex2fSUN */
-   { 17439, -1 }, /* ReplacementCodeuiColor4ubVertex3fSUN */
-   { 19292, -1 }, /* TexCoord2fColor4ubVertex3fSUN */
-   { 19639, -1 }, /* Normal3fVertex3fvSUN */
-   { 20042, -1 }, /* Color4fNormal3fVertex3fSUN */
-   { 20908, -1 }, /* ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN */
-   { 21128, -1 }, /* ReplacementCodeuiColor4ubVertex3fvSUN */
-   { 22831, -1 }, /* ReplacementCodeuiColor3fVertex3fSUN */
-   { 24007, -1 }, /* TexCoord4fVertex4fSUN */
-   { 24433, -1 }, /* TexCoord2fColor3fVertex3fvSUN */
-   { 24759, -1 }, /* ReplacementCodeuiNormal3fVertex3fvSUN */
-   { 24886, -1 }, /* TexCoord4fVertex4fvSUN */
-   { 25588, -1 }, /* ReplacementCodeuiVertex3fSUN */
+   {  4105, -1 }, /* Color4ubVertex3fSUN */
+   {  4181, -1 }, /* TexCoord2fVertex3fSUN */
+   {  4480, -1 }, /* TexCoord2fColor4fNormal3fVertex3fSUN */
+   {  4810, -1 }, /* TexCoord2fNormal3fVertex3fvSUN */
+   {  5380, -1 }, /* ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN */
+   {  6450, -1 }, /* ReplacementCodeuiTexCoord2fVertex3fSUN */
+   {  7162, -1 }, /* TexCoord2fNormal3fVertex3fSUN */
+   {  7930, -1 }, /* Color3fVertex3fSUN */
+   {  8942, -1 }, /* Color3fVertex3fvSUN */
+   {  9357, -1 }, /* Color4fNormal3fVertex3fvSUN */
+   { 10058, -1 }, /* ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN */
+   { 11297, -1 }, /* ReplacementCodeuiColor4fNormal3fVertex3fvSUN */
+   { 12689, -1 }, /* ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN */
+   { 13100, -1 }, /* TexCoord2fColor3fVertex3fSUN */
+   { 14152, -1 }, /* TexCoord4fColor4fNormal3fVertex4fSUN */
+   { 14486, -1 }, /* Color4ubVertex2fvSUN */
+   { 14726, -1 }, /* Normal3fVertex3fSUN */
+   { 15674, -1 }, /* ReplacementCodeuiColor4fNormal3fVertex3fSUN */
+   { 15935, -1 }, /* TexCoord2fColor4fNormal3fVertex3fvSUN */
+   { 16602, -1 }, /* TexCoord2fVertex3fvSUN */
+   { 17378, -1 }, /* Color4ubVertex2fSUN */
+   { 17571, -1 }, /* ReplacementCodeuiColor4ubVertex3fSUN */
+   { 19453, -1 }, /* TexCoord2fColor4ubVertex3fSUN */
+   { 19800, -1 }, /* Normal3fVertex3fvSUN */
+   { 20229, -1 }, /* Color4fNormal3fVertex3fSUN */
+   { 21095, -1 }, /* ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN */
+   { 21315, -1 }, /* ReplacementCodeuiColor4ubVertex3fvSUN */
+   { 23045, -1 }, /* ReplacementCodeuiColor3fVertex3fSUN */
+   { 24300, -1 }, /* TexCoord4fVertex4fSUN */
+   { 24726, -1 }, /* TexCoord2fColor3fVertex3fvSUN */
+   { 25052, -1 }, /* ReplacementCodeuiNormal3fVertex3fvSUN */
+   { 25179, -1 }, /* TexCoord4fVertex4fvSUN */
+   { 25881, -1 }, /* ReplacementCodeuiVertex3fSUN */
    {    -1, -1 }
 };
 #endif
@@ -5818,37 +5880,37 @@
    {   381, _gloffset_MultiTexCoord3sARB },
    {   613, _gloffset_ActiveTextureARB },
    {  3761, _gloffset_MultiTexCoord1fvARB },
-   {  5240, _gloffset_MultiTexCoord3dARB },
-   {  5285, _gloffset_MultiTexCoord2iARB },
-   {  5409, _gloffset_MultiTexCoord2svARB },
-   {  7340, _gloffset_MultiTexCoord2fARB },
-   {  9133, _gloffset_MultiTexCoord3fvARB },
-   {  9625, _gloffset_MultiTexCoord4sARB },
-   { 10225, _gloffset_MultiTexCoord2dvARB },
-   { 10607, _gloffset_MultiTexCoord1svARB },
-   { 10864, _gloffset_MultiTexCoord3svARB },
-   { 10925, _gloffset_MultiTexCoord4iARB },
-   { 11612, _gloffset_MultiTexCoord3iARB },
-   { 12346, _gloffset_MultiTexCoord1dARB },
-   { 12512, _gloffset_MultiTexCoord3dvARB },
-   { 13676, _gloffset_MultiTexCoord3ivARB },
-   { 13721, _gloffset_MultiTexCoord2sARB },
-   { 14941, _gloffset_MultiTexCoord4ivARB },
-   { 16570, _gloffset_ClientActiveTextureARB },
-   { 18786, _gloffset_MultiTexCoord2dARB },
-   { 19161, _gloffset_MultiTexCoord4dvARB },
-   { 19447, _gloffset_MultiTexCoord4fvARB },
-   { 20274, _gloffset_MultiTexCoord3fARB },
-   { 22584, _gloffset_MultiTexCoord4dARB },
-   { 22788, _gloffset_MultiTexCoord1sARB },
-   { 22966, _gloffset_MultiTexCoord1dvARB },
-   { 23753, _gloffset_MultiTexCoord1ivARB },
-   { 23846, _gloffset_MultiTexCoord2ivARB },
-   { 24185, _gloffset_MultiTexCoord1iARB },
-   { 25456, _gloffset_MultiTexCoord4svARB },
-   { 25974, _gloffset_MultiTexCoord1fARB },
-   { 26237, _gloffset_MultiTexCoord4fARB },
-   { 28505, _gloffset_MultiTexCoord2fvARB },
+   {  5271, _gloffset_MultiTexCoord3dARB },
+   {  5316, _gloffset_MultiTexCoord2iARB },
+   {  5440, _gloffset_MultiTexCoord2svARB },
+   {  7371, _gloffset_MultiTexCoord2fARB },
+   {  9193, _gloffset_MultiTexCoord3fvARB },
+   {  9714, _gloffset_MultiTexCoord4sARB },
+   { 10314, _gloffset_MultiTexCoord2dvARB },
+   { 10696, _gloffset_MultiTexCoord1svARB },
+   { 10992, _gloffset_MultiTexCoord3svARB },
+   { 11053, _gloffset_MultiTexCoord4iARB },
+   { 11776, _gloffset_MultiTexCoord3iARB },
+   { 12478, _gloffset_MultiTexCoord1dARB },
+   { 12644, _gloffset_MultiTexCoord3dvARB },
+   { 13808, _gloffset_MultiTexCoord3ivARB },
+   { 13853, _gloffset_MultiTexCoord2sARB },
+   { 15073, _gloffset_MultiTexCoord4ivARB },
+   { 16702, _gloffset_ClientActiveTextureARB },
+   { 18918, _gloffset_MultiTexCoord2dARB },
+   { 19322, _gloffset_MultiTexCoord4dvARB },
+   { 19608, _gloffset_MultiTexCoord4fvARB },
+   { 20461, _gloffset_MultiTexCoord3fARB },
+   { 22798, _gloffset_MultiTexCoord4dARB },
+   { 23002, _gloffset_MultiTexCoord1sARB },
+   { 23204, _gloffset_MultiTexCoord1dvARB },
+   { 24046, _gloffset_MultiTexCoord1ivARB },
+   { 24139, _gloffset_MultiTexCoord2ivARB },
+   { 24478, _gloffset_MultiTexCoord1iARB },
+   { 25749, _gloffset_MultiTexCoord4svARB },
+   { 26267, _gloffset_MultiTexCoord1fARB },
+   { 26530, _gloffset_MultiTexCoord4fARB },
+   { 28759, _gloffset_MultiTexCoord2fvARB },
    {    -1, -1 }
 };
 #endif
diff --git a/src/mesa/main/texenv.c b/src/mesa/main/texenv.c
index 6d86a42..4442fb8 100644
--- a/src/mesa/main/texenv.c
+++ b/src/mesa/main/texenv.c
@@ -598,7 +598,10 @@
 void GLAPIENTRY
 _mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param )
 {
-   _mesa_TexEnvfv( target, pname, &param );
+   GLfloat p[4];
+   p[0] = param;
+   p[1] = p[2] = p[3] = 0.0;
+   _mesa_TexEnvfv( target, pname, p );
 }
 
 
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index d7e77e7..499b733 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -367,7 +367,7 @@
    else {
       /* calculate from vp->outputs */
       struct gl_vertex_program *vprog;
-      GLbitfield vp_outputs;
+      GLbitfield64 vp_outputs;
 
       /* Choose GLSL vertex shader over ARB vertex program.  Need this
        * since vertex shader state validation comes after fragment state
@@ -606,7 +606,7 @@
 
    if (!bit) {
       _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__);
-      _mesa_exit(1);
+      exit(1);
    }
 
    if ((GLuint) bit > p->program->Base.NumTemporaries)
@@ -634,7 +634,7 @@
 
    if (!bit) {
       _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__);
-      _mesa_exit(1);
+      exit(1);
    }
 
    if ((GLuint) bit > p->program->Base.NumTemporaries)
@@ -1040,8 +1040,6 @@
 
    assert(nr <= MAX_COMBINER_TERMS);
 
-   tmp = undef; /* silence warning (bug 5318) */
-
    for (i = 0; i < nr; i++)
       src[i] = emit_combine_source( p, mask, unit, opt[i].Source, opt[i].Operand );
 
diff --git a/src/mesa/main/texfetch.c b/src/mesa/main/texfetch.c
index 314ccb7..b370394 100644
--- a/src/mesa/main/texfetch.c
+++ b/src/mesa/main/texfetch.c
@@ -376,6 +376,13 @@
       store_texel_xrgb8888
    },
    {
+      MESA_FORMAT_XRGB8888_REV,
+      fetch_texel_1d_f_xrgb8888_rev,
+      fetch_texel_2d_f_xrgb8888_rev,
+      fetch_texel_3d_f_xrgb8888_rev,
+      store_texel_xrgb8888_rev,
+   },
+   {
       MESA_FORMAT_RGB888,
       fetch_texel_1d_f_rgb888,
       fetch_texel_2d_f_rgb888,
@@ -453,6 +460,20 @@
       store_texel_al88_rev
    },
    {
+      MESA_FORMAT_AL1616,
+      fetch_texel_1d_f_al1616,
+      fetch_texel_2d_f_al1616,
+      fetch_texel_3d_f_al1616,
+      store_texel_al1616
+   },
+   {
+      MESA_FORMAT_AL1616_REV,
+      fetch_texel_1d_f_al1616_rev,
+      fetch_texel_2d_f_al1616_rev,
+      fetch_texel_3d_f_al1616_rev,
+      store_texel_al1616_rev
+   },
+   {
       MESA_FORMAT_RGB332,
       fetch_texel_1d_f_rgb332,
       fetch_texel_2d_f_rgb332,
@@ -549,7 +570,7 @@
 static FetchTexelFuncF
 _mesa_get_texel_fetch_func(gl_format format, GLuint dims)
 {
-   FetchTexelFuncF f;
+   FetchTexelFuncF f = NULL;
    GLuint i;
    /* XXX replace loop with direct table lookup */
    for (i = 0; i < MESA_FORMAT_COUNT; i++) {
diff --git a/src/mesa/main/texfetch_tmp.h b/src/mesa/main/texfetch_tmp.h
index 2743494..e6772c8 100644
--- a/src/mesa/main/texfetch_tmp.h
+++ b/src/mesa/main/texfetch_tmp.h
@@ -559,6 +559,30 @@
 #endif
 
 
+/* MESA_FORMAT_XRGB8888_REV **************************************************/
+
+/* Fetch texel from 1D, 2D or 3D xrgb8888_rev texture, return 4 GLfloats */
+static void FETCH(f_xrgb8888_rev)( const struct gl_texture_image *texImage,
+                                   GLint i, GLint j, GLint k, GLfloat *texel )
+{
+   const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+   texel[RCOMP] = UBYTE_TO_FLOAT( (s >>  8) & 0xff );
+   texel[GCOMP] = UBYTE_TO_FLOAT( (s >> 16) & 0xff );
+   texel[BCOMP] = UBYTE_TO_FLOAT( (s >> 24)        );
+   texel[ACOMP] = 1.0f;
+}
+
+#if DIM == 3
+static void store_texel_xrgb8888_rev(struct gl_texture_image *texImage,
+                                     GLint i, GLint j, GLint k, const void *texel)
+{
+   const GLubyte *rgba = (const GLubyte *) texel;
+   GLuint *dst = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+   *dst = PACK_COLOR_8888(rgba[BCOMP], rgba[GCOMP], rgba[RCOMP], 0xff);
+}
+#endif
+
+
 /* MESA_FORMAT_RGB888 ********************************************************/
 
 /* Fetch texel from 1D, 2D or 3D rgb888 texture, return 4 GLchans */
@@ -834,6 +858,54 @@
 #endif
 
 
+/* MESA_FORMAT_AL1616 ********************************************************/
+
+/* Fetch texel from 1D, 2D or 3D al1616 texture, return 4 GLchans */
+static void FETCH(f_al1616)( const struct gl_texture_image *texImage,
+			     GLint i, GLint j, GLint k, GLfloat *texel )
+{
+   const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+   texel[RCOMP] =
+   texel[GCOMP] =
+   texel[BCOMP] = USHORT_TO_FLOAT( s & 0xffff );
+   texel[ACOMP] = USHORT_TO_FLOAT( s >> 16 );
+}
+
+#if DIM == 3
+static void store_texel_al1616(struct gl_texture_image *texImage,
+                             GLint i, GLint j, GLint k, const void *texel)
+{
+   const GLushort *rgba = (const GLushort *) texel;
+   GLuint *dst = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+   *dst = PACK_COLOR_1616(rgba[ACOMP], rgba[RCOMP]);
+}
+#endif
+
+
+/* MESA_FORMAT_AL1616_REV ****************************************************/
+
+/* Fetch texel from 1D, 2D or 3D al1616_rev texture, return 4 GLchans */
+static void FETCH(f_al1616_rev)( const struct gl_texture_image *texImage,
+				 GLint i, GLint j, GLint k, GLfloat *texel )
+{
+   const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+   texel[RCOMP] =
+   texel[GCOMP] =
+   texel[BCOMP] = USHORT_TO_FLOAT( s >> 16 );
+   texel[ACOMP] = USHORT_TO_FLOAT( s & 0xffff );
+}
+
+#if DIM == 3
+static void store_texel_al1616_rev(struct gl_texture_image *texImage,
+				   GLint i, GLint j, GLint k, const void *texel)
+{
+   const GLushort *rgba = (const GLushort *) texel;
+   GLuint *dst = TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
+   *dst = PACK_COLOR_1616(rgba[RCOMP], rgba[ACOMP]);
+}
+#endif
+
+
 /* MESA_FORMAT_RGB332 ********************************************************/
 
 /* Fetch texel from 1D, 2D or 3D rgb332 texture, return 4 GLchans */
diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c
index 39c561e..1a374e7 100644
--- a/src/mesa/main/texformat.c
+++ b/src/mesa/main/texformat.c
@@ -115,11 +115,13 @@
       case GL_LUMINANCE_ALPHA:
       case GL_LUMINANCE4_ALPHA4:
       case GL_LUMINANCE6_ALPHA2:
+      case GL_LUMINANCE8_ALPHA8:
+         return MESA_FORMAT_AL88;
+
       case GL_LUMINANCE12_ALPHA4:
       case GL_LUMINANCE12_ALPHA12:
       case GL_LUMINANCE16_ALPHA16:
-      case GL_LUMINANCE8_ALPHA8:
-         return MESA_FORMAT_AL88;
+         return MESA_FORMAT_AL1616;
 
       case GL_INTENSITY:
       case GL_INTENSITY4:
diff --git a/src/mesa/main/texgen.c b/src/mesa/main/texgen.c
index 8d11410..2ae839b 100644
--- a/src/mesa/main/texgen.c
+++ b/src/mesa/main/texgen.c
@@ -186,8 +186,10 @@
 static void GLAPIENTRY
 _mesa_TexGend(GLenum coord, GLenum pname, GLdouble param )
 {
-   GLfloat p = (GLfloat) param;
-   _mesa_TexGenfv( coord, pname, &p );
+   GLfloat p[4];
+   p[0] = (GLfloat) param;
+   p[1] = p[2] = p[3] = 0.0F;
+   _mesa_TexGenfv( coord, pname, p );
 }
 
 
@@ -211,14 +213,20 @@
 void GLAPIENTRY
 _mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param )
 {
-   _mesa_TexGenfv(coord, pname, &param);
+   GLfloat p[4];
+   p[0] = param;
+   p[1] = p[2] = p[3] = 0.0F;
+   _mesa_TexGenfv(coord, pname, p);
 }
 
 
 void GLAPIENTRY
 _mesa_TexGeni( GLenum coord, GLenum pname, GLint param )
 {
-   _mesa_TexGeniv( coord, pname, &param );
+   GLint p[4];
+   p[0] = param;
+   p[1] = p[2] = p[3] = 0;
+   _mesa_TexGeniv( coord, pname, p );
 }
 
 
diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c
index 4b0915b..d7943ea 100644
--- a/src/mesa/main/texgetimage.c
+++ b/src/mesa/main/texgetimage.c
@@ -79,7 +79,7 @@
 
    for (img = 0; img < depth; img++) {
       for (row = 0; row < height; row++) {
-         GLuint indexRow[MAX_WIDTH];
+         GLuint indexRow[MAX_WIDTH] = { 0 };
          void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
                                           width, height, format, type,
                                           img, row, 0);
@@ -535,10 +535,11 @@
                               struct gl_texture_object *texObj,
                               struct gl_texture_image *texImage)
 {
-   const GLuint size = _mesa_format_image_size(texImage->TexFormat,
-                                               texImage->Width,
-                                               texImage->Height,
-                                               texImage->Depth);
+   const GLuint row_stride = _mesa_format_row_stride(texImage->TexFormat,
+                                                     texImage->Width);
+   const GLuint row_stride_stored = _mesa_format_row_stride(texImage->TexFormat,
+                                                            texImage->RowStride);
+   GLuint i;
 
    if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
       /* pack texture image into a PBO */
@@ -554,8 +555,24 @@
       img = ADD_POINTERS(buf, img);
    }
 
-   /* just memcpy, no pixelstore or pixel transfer */
-   _mesa_memcpy(img, texImage->Data, size);
+   /* no pixelstore or pixel transfer, but respect stride */
+
+   if (row_stride == row_stride_stored) {
+      const GLuint size = _mesa_format_image_size(texImage->TexFormat,
+                                                  texImage->Width,
+                                                  texImage->Height,
+                                                  texImage->Depth);
+      _mesa_memcpy(img, texImage->Data, size);
+   }
+   else {
+      GLuint bw, bh;
+      _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
+      for (i = 0; i < (texImage->Height + bh - 1) / bh; i++) {
+         memcpy((GLubyte *)img + i * row_stride,
+                (GLubyte *)texImage->Data + i * row_stride_stored,
+                row_stride);
+      }
+   }
 
    if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
       ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index b100768..b946f3c 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -2035,7 +2035,9 @@
                  struct gl_texture_object *texObj, GLint level)
 {
    ASSERT(target != GL_TEXTURE_CUBE_MAP);
-   if (texObj->GenerateMipmap && level == texObj->BaseLevel) {
+   if (texObj->GenerateMipmap &&
+       level == texObj->BaseLevel &&
+       level < texObj->MaxLevel) {
       ASSERT(ctx->Driver.GenerateMipmap);
       ctx->Driver.GenerateMipmap(ctx, target, texObj);
    }
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index aaccc03..7f0a246 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -228,10 +228,10 @@
    dest->Target = src->Target;
    dest->Name = src->Name;
    dest->Priority = src->Priority;
-   dest->BorderColor[0] = src->BorderColor[0];
-   dest->BorderColor[1] = src->BorderColor[1];
-   dest->BorderColor[2] = src->BorderColor[2];
-   dest->BorderColor[3] = src->BorderColor[3];
+   dest->BorderColor.f[0] = src->BorderColor.f[0];
+   dest->BorderColor.f[1] = src->BorderColor.f[1];
+   dest->BorderColor.f[2] = src->BorderColor.f[2];
+   dest->BorderColor.f[3] = src->BorderColor.f[3];
    dest->WrapS = src->WrapS;
    dest->WrapT = src->WrapT;
    dest->WrapR = src->WrapR;
@@ -415,7 +415,7 @@
    /* Detect cases where the application set the base level to an invalid
     * value.
     */
-   if ((baseLevel < 0) || (baseLevel > MAX_TEXTURE_LEVELS)) {
+   if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) {
       char s[100];
       _mesa_sprintf(s, "base level = %d is invalid", baseLevel);
       incomplete(t, s);
@@ -940,7 +940,8 @@
 /**
  * Convert a GL texture target enum such as GL_TEXTURE_2D or GL_TEXTURE_3D
  * into the corresponding Mesa texture target index.
- * Return -1 if target is invalid.
+ * Note that proxy targets are not valid here.
+ * \return TEXTURE_x_INDEX or -1 if target is invalid
  */
 static GLint
 target_enum_to_index(GLenum target)
diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c
index ab170cd..d917e21 100644
--- a/src/mesa/main/texparam.c
+++ b/src/mesa/main/texparam.c
@@ -78,17 +78,19 @@
 
 /**
  * Get current texture object for given target.
- * Return NULL if any error.
+ * Return NULL if any error (and record the error).
  * Note that this is different from _mesa_select_tex_object() in that proxy
  * targets are not accepted.
+ * Only the glGetTexLevelParameter() functions accept proxy targets.
  */
 static struct gl_texture_object *
-get_texobj(GLcontext *ctx, GLenum target)
+get_texobj(GLcontext *ctx, GLenum target, GLboolean get)
 {
    struct gl_texture_unit *texUnit;
 
    if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(current unit)");
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "gl%sTexParameter(current unit)", get ? "Get" : "");
       return NULL;
    }
 
@@ -125,7 +127,8 @@
       ;
    }
 
-   _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(target)");
+   _mesa_error(ctx, GL_INVALID_ENUM,
+                  "gl%sTexParameter(target)", get ? "Get" : "");
    return NULL;
 }
 
@@ -508,10 +511,10 @@
 
    case GL_TEXTURE_BORDER_COLOR:
       flush(ctx, texObj);
-      texObj->BorderColor[RCOMP] = params[0];
-      texObj->BorderColor[GCOMP] = params[1];
-      texObj->BorderColor[BCOMP] = params[2];
-      texObj->BorderColor[ACOMP] = params[3];
+      texObj->BorderColor.f[RCOMP] = params[0];
+      texObj->BorderColor.f[GCOMP] = params[1];
+      texObj->BorderColor.f[BCOMP] = params[2];
+      texObj->BorderColor.f[ACOMP] = params[3];
       return GL_TRUE;
 
    default:
@@ -529,7 +532,7 @@
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   texObj = get_texobj(ctx, target);
+   texObj = get_texobj(ctx, target, GL_FALSE);
    if (!texObj)
       return;
 
@@ -547,13 +550,20 @@
    case GL_DEPTH_TEXTURE_MODE_ARB:
       {
          /* convert float param to int */
-         GLint p = (GLint) param;
-         need_update = set_tex_parameteri(ctx, texObj, pname, &p);
+         GLint p[4];
+         p[0] = (GLint) param;
+         p[1] = p[2] = p[3] = 0;
+         need_update = set_tex_parameteri(ctx, texObj, pname, p);
       }
       break;
    default:
-      /* this will generate an error if pname is illegal */
-      need_update = set_tex_parameterf(ctx, texObj, pname, &param);
+      {
+         /* this will generate an error if pname is illegal */
+         GLfloat p[4];
+         p[0] = param;
+         p[1] = p[2] = p[3] = 0.0F;
+         need_update = set_tex_parameterf(ctx, texObj, pname, p);
+      }
    }
 
    if (ctx->Driver.TexParameter && need_update) {
@@ -570,7 +580,7 @@
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   texObj = get_texobj(ctx, target);
+   texObj = get_texobj(ctx, target, GL_FALSE);
    if (!texObj)
       return;
 
@@ -588,8 +598,10 @@
    case GL_DEPTH_TEXTURE_MODE_ARB:
       {
          /* convert float param to int */
-         GLint p = (GLint) params[0];
-         need_update = set_tex_parameteri(ctx, texObj, pname, &p);
+         GLint p[4];
+         p[0] = (GLint) params[0];
+         p[1] = p[2] = p[3] = 0;
+         need_update = set_tex_parameteri(ctx, texObj, pname, p);
       }
       break;
 
@@ -626,7 +638,7 @@
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   texObj = get_texobj(ctx, target);
+   texObj = get_texobj(ctx, target, GL_FALSE);
    if (!texObj)
       return;
 
@@ -638,14 +650,21 @@
    case GL_TEXTURE_LOD_BIAS:
    case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
       {
-         GLfloat fparam = (GLfloat) param;
+         GLfloat fparam[4];
+         fparam[0] = (GLfloat) param;
+         fparam[1] = fparam[2] = fparam[3] = 0.0F;
          /* convert int param to float */
-         need_update = set_tex_parameterf(ctx, texObj, pname, &fparam);
+         need_update = set_tex_parameterf(ctx, texObj, pname, fparam);
       }
       break;
    default:
       /* this will generate an error if pname is illegal */
-      need_update = set_tex_parameteri(ctx, texObj, pname, &param);
+      {
+         GLint iparam[4];
+         iparam[0] = param;
+         iparam[1] = iparam[2] = iparam[3] = 0;
+         need_update = set_tex_parameteri(ctx, texObj, pname, iparam);
+      }
    }
 
    if (ctx->Driver.TexParameter && need_update) {
@@ -663,7 +682,7 @@
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   texObj = get_texobj(ctx, target);
+   texObj = get_texobj(ctx, target, GL_FALSE);
    if (!texObj)
       return;
 
@@ -687,8 +706,10 @@
    case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
       {
          /* convert int param to float */
-         GLfloat fparam = (GLfloat) params[0];
-         need_update = set_tex_parameterf(ctx, texObj, pname, &fparam);
+         GLfloat fparams[4];
+         fparams[0] = (GLfloat) params[0];
+         fparams[1] = fparams[2] = fparams[3] = 0.0F;
+         need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
       }
       break;
    default:
@@ -710,6 +731,68 @@
 }
 
 
+/**
+ * Set tex parameter to integer value(s).  Primarily intended to set
+ * integer-valued texture border color (for integer-valued textures).
+ * New in GL 3.0.
+ */
+void GLAPIENTRY
+_mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
+{
+   struct gl_texture_object *texObj;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   texObj = get_texobj(ctx, target, GL_FALSE);
+   if (!texObj)
+      return;
+
+   switch (pname) {
+   case GL_TEXTURE_BORDER_COLOR:
+      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+      /* set the integer-valued border color */
+      COPY_4V(texObj->BorderColor.i, params);
+      break;
+   default:
+      _mesa_TexParameteriv(target, pname, params);
+      break;
+   }
+   /* XXX no driver hook for TexParameterIiv() yet */
+}
+
+
+/**
+ * Set tex parameter to unsigned integer value(s).  Primarily intended to set
+ * uint-valued texture border color (for integer-valued textures).
+ * New in GL 3.0
+ */
+void GLAPIENTRY
+_mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
+{
+   struct gl_texture_object *texObj;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   texObj = get_texobj(ctx, target, GL_FALSE);
+   if (!texObj)
+      return;
+
+   switch (pname) {
+   case GL_TEXTURE_BORDER_COLOR:
+      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+      /* set the unsigned integer-valued border color */
+      COPY_4V(texObj->BorderColor.ui, params);
+      break;
+   default:
+      _mesa_TexParameteriv(target, pname, (const GLint *) params);
+      break;
+   }
+   /* XXX no driver hook for TexParameterIuiv() yet */
+}
+
+
+
+
 void GLAPIENTRY
 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
                               GLenum pname, GLfloat *params )
@@ -960,25 +1043,14 @@
 void GLAPIENTRY
 _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
 {
-   struct gl_texture_unit *texUnit;
    struct gl_texture_object *obj;
    GLboolean error = GL_FALSE;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glGetTexParameterfv(current unit)");
+   obj = get_texobj(ctx, target, GL_TRUE);
+   if (!obj)
       return;
-   }
-
-   texUnit = _mesa_get_current_tex_unit(ctx);
-
-   obj = _mesa_select_tex_object(ctx, texUnit, target);
-   if (!obj) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
-      return;
-   }
 
    _mesa_lock_texture(ctx, obj);
    switch (pname) {
@@ -998,10 +1070,10 @@
          *params = ENUM_TO_FLOAT(obj->WrapR);
          break;
       case GL_TEXTURE_BORDER_COLOR:
-         params[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
-         params[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
-         params[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
-         params[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
+         params[0] = CLAMP(obj->BorderColor.f[0], 0.0F, 1.0F);
+         params[1] = CLAMP(obj->BorderColor.f[1], 0.0F, 1.0F);
+         params[2] = CLAMP(obj->BorderColor.f[2], 0.0F, 1.0F);
+         params[3] = CLAMP(obj->BorderColor.f[3], 0.0F, 1.0F);
          break;
       case GL_TEXTURE_RESIDENT:
          {
@@ -1127,26 +1199,16 @@
 void GLAPIENTRY
 _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
 {
-   struct gl_texture_unit *texUnit;
    struct gl_texture_object *obj;
    GLboolean error = GL_FALSE;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glGetTexParameteriv(current unit)");
-      return;
-   }
+    obj = get_texobj(ctx, target, GL_TRUE);
+    if (!obj)
+       return;
 
-   texUnit = _mesa_get_current_tex_unit(ctx);
-
-   obj = _mesa_select_tex_object(ctx, texUnit, target);
-   if (!obj) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)");
-      return;
-   }
-
+   _mesa_lock_texture(ctx, obj);
    switch (pname) {
       case GL_TEXTURE_MAG_FILTER:
          *params = (GLint) obj->MagFilter;
@@ -1166,10 +1228,10 @@
       case GL_TEXTURE_BORDER_COLOR:
          {
             GLfloat b[4];
-            b[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
-            b[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
-            b[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
-            b[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
+            b[0] = CLAMP(obj->BorderColor.f[0], 0.0F, 1.0F);
+            b[1] = CLAMP(obj->BorderColor.f[1], 0.0F, 1.0F);
+            b[2] = CLAMP(obj->BorderColor.f[2], 0.0F, 1.0F);
+            b[3] = CLAMP(obj->BorderColor.f[3], 0.0F, 1.0F);
             params[0] = FLOAT_TO_INT(b[0]);
             params[1] = FLOAT_TO_INT(b[1]);
             params[2] = FLOAT_TO_INT(b[2]);
@@ -1297,3 +1359,53 @@
 
    _mesa_unlock_texture(ctx, obj);
 }
+
+
+/** New in GL 3.0 */
+void GLAPIENTRY
+_mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
+{
+   struct gl_texture_object *texObj;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   texObj = get_texobj(ctx, target, GL_TRUE);
+   
+   switch (pname) {
+   case GL_TEXTURE_BORDER_COLOR:
+      COPY_4V(params, texObj->BorderColor.i);
+      break;
+   default:
+      _mesa_GetTexParameteriv(target, pname, params);
+   }
+}
+
+
+/** New in GL 3.0 */
+void GLAPIENTRY
+_mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
+{
+   struct gl_texture_object *texObj;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   texObj = get_texobj(ctx, target, GL_TRUE);
+   
+   switch (pname) {
+   case GL_TEXTURE_BORDER_COLOR:
+      COPY_4V(params, texObj->BorderColor.i);
+      break;
+   default:
+      {
+         GLint ip[4];
+         _mesa_GetTexParameteriv(target, pname, ip);
+         params[0] = ip[0];
+         if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT || 
+             pname == GL_TEXTURE_CROP_RECT_OES) {
+            params[1] = ip[1];
+            params[2] = ip[2];
+            params[3] = ip[3];
+         }
+      }
+   }
+}
diff --git a/src/mesa/main/texparam.h b/src/mesa/main/texparam.h
index 454b963..19b4116 100644
--- a/src/mesa/main/texparam.h
+++ b/src/mesa/main/texparam.h
@@ -44,6 +44,11 @@
 extern void GLAPIENTRY
 _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params );
 
+extern void GLAPIENTRY
+_mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params);
 
 
 extern void GLAPIENTRY
@@ -60,4 +65,11 @@
 _mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params );
 
 
+extern void GLAPIENTRY
+_mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params);
+
+extern void GLAPIENTRY
+_mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params);
+
+
 #endif /* TEXPARAM_H */
diff --git a/src/mesa/main/texrender.c b/src/mesa/main/texrender.c
index e2432be..cf603d4 100644
--- a/src/mesa/main/texrender.c
+++ b/src/mesa/main/texrender.c
@@ -467,7 +467,6 @@
 {
    struct texture_renderbuffer *trb
       = (struct texture_renderbuffer *) att->Renderbuffer;
-   gl_format texFormat;
 
    (void) ctx;
    ASSERT(trb);
@@ -490,8 +489,6 @@
       trb->Zoffset = att->Zoffset;
    }
 
-   texFormat = trb->TexImage->TexFormat;
-
    trb->Base.Width = trb->TexImage->Width;
    trb->Base.Height = trb->TexImage->Height;
    trb->Base.InternalFormat = trb->TexImage->InternalFormat;
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index e48d472..792c831 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -1410,7 +1410,8 @@
 
    ASSERT(dstFormat == MESA_FORMAT_ARGB8888 ||
           dstFormat == MESA_FORMAT_ARGB8888_REV ||
-          dstFormat == MESA_FORMAT_XRGB8888);
+          dstFormat == MESA_FORMAT_XRGB8888 ||
+          dstFormat == MESA_FORMAT_XRGB8888_REV );
    ASSERT(texelBytes == 4);
 
    if (!ctx->_ImageTransferState &&
@@ -1431,7 +1432,8 @@
    }
    else if (!ctx->_ImageTransferState &&
        !srcPacking->SwapBytes &&
-       dstFormat == MESA_FORMAT_ARGB8888_REV &&
+       (dstFormat == MESA_FORMAT_ARGB8888_REV ||
+        dstFormat == MESA_FORMAT_XRGB8888_REV) &&
        baseInternalFormat == GL_RGBA &&
        srcFormat == GL_BGRA &&
        ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
@@ -1524,7 +1526,8 @@
        */
       if ((littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
           (littleEndian && dstFormat == MESA_FORMAT_XRGB8888) ||
-	  (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV)) {
+	  (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
+	  (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV)) {
 	 dstmap[3] = 3;		/* alpha */
 	 dstmap[2] = 0;		/* red */
 	 dstmap[1] = 1;		/* green */
@@ -1533,6 +1536,7 @@
       else {
 	 assert((littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
 		(!littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
+		(littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV) ||
 		(!littleEndian && dstFormat == MESA_FORMAT_XRGB8888));
 	 dstmap[3] = 2;
 	 dstmap[2] = 1;
@@ -2146,6 +2150,81 @@
 
 
 static GLboolean
+_mesa_texstore_al1616(TEXSTORE_PARAMS)
+{
+   const GLboolean littleEndian = _mesa_little_endian();
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_AL1616 ||
+          dstFormat == MESA_FORMAT_AL1616_REV);
+   ASSERT(texelBytes == 4);
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       dstFormat == MESA_FORMAT_AL1616 &&
+       baseInternalFormat == GL_LUMINANCE_ALPHA &&
+       srcFormat == GL_LUMINANCE_ALPHA &&
+       srcType == GL_UNSIGNED_SHORT &&
+       littleEndian) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking);
+      const GLfloat *src = tempImage;
+      GLint img, row, col;
+      if (!tempImage)
+         return GL_FALSE;
+      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLuint *dstUI = (GLuint *) dstRow;
+            if (dstFormat == MESA_FORMAT_AL1616) {
+               for (col = 0; col < srcWidth; col++) {
+		  GLushort l, a;
+
+		  UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
+		  UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
+		  dstUI[col] = PACK_COLOR_1616(a, l);
+		  src += 2;
+               }
+            }
+            else {
+               for (col = 0; col < srcWidth; col++) {
+		  GLushort l, a;
+
+		  UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
+		  UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
+		  dstUI[col] = PACK_COLOR_1616_REV(a, l);
+		  src += 2;
+               }
+            }
+            dstRow += dstRowStride;
+         }
+      }
+      _mesa_free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+static GLboolean
 _mesa_texstore_rgb332(TEXSTORE_PARAMS)
 {
    const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
@@ -3050,7 +3129,7 @@
  * Table mapping MESA_FORMAT_8 to _mesa_texstore_*()
  * XXX this is somewhat temporary.
  */
-const static struct {
+static const struct {
    gl_format Name;
    StoreTexImageFunc Store;
 }
@@ -3062,6 +3141,7 @@
    { MESA_FORMAT_ARGB8888, _mesa_texstore_argb8888 },
    { MESA_FORMAT_ARGB8888_REV, _mesa_texstore_argb8888 },
    { MESA_FORMAT_XRGB8888, _mesa_texstore_argb8888 },
+   { MESA_FORMAT_XRGB8888_REV, _mesa_texstore_argb8888 },
    { MESA_FORMAT_RGB888, _mesa_texstore_rgb888 },
    { MESA_FORMAT_BGR888, _mesa_texstore_bgr888 },
    { MESA_FORMAT_RGB565, _mesa_texstore_rgb565 },
@@ -3073,6 +3153,8 @@
    { MESA_FORMAT_ARGB1555_REV, _mesa_texstore_argb1555 },
    { MESA_FORMAT_AL88, _mesa_texstore_al88 },
    { MESA_FORMAT_AL88_REV, _mesa_texstore_al88 },
+   { MESA_FORMAT_AL1616, _mesa_texstore_al1616 },
+   { MESA_FORMAT_AL1616_REV, _mesa_texstore_al1616 },
    { MESA_FORMAT_RGB332, _mesa_texstore_rgb332 },
    { MESA_FORMAT_A8, _mesa_texstore_a8 },
    { MESA_FORMAT_L8, _mesa_texstore_a8 },
diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c
index 6cd2a2f..c219307 100644
--- a/src/mesa/main/varray.c
+++ b/src/mesa/main/varray.c
@@ -51,9 +51,8 @@
  * \param stride  stride between elements, in elements
  * \param normalized  are integer types converted to floats in [-1, 1]?
  * \param ptr  the address (or offset inside VBO) of the array data
- * \return GL_TRUE if no error, GL_FALSE if error
  */
-static GLboolean
+static void
 update_array(GLcontext *ctx, struct gl_client_array *array,
              GLbitfield dirtyBit, GLsizei elementSize,
              GLint size, GLenum type, GLenum format,
@@ -68,7 +67,7 @@
        */
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glVertex/Normal/EtcPointer(non-VBO array)");
-      return GL_FALSE;
+      return;
    }
 
    array->Size = size;
@@ -85,8 +84,6 @@
 
    ctx->NewState |= _NEW_ARRAY;
    ctx->Array.NewState |= dirtyBit;
-
-   return GL_TRUE;
 }
 
 
@@ -140,12 +137,8 @@
          return;
    }
 
-   if (!update_array(ctx, &ctx->Array.ArrayObj->Vertex, _NEW_ARRAY_VERTEX,
-                     elementSize, size, type, GL_RGBA, stride, GL_FALSE, ptr))
-      return;
-
-   if (ctx->Driver.VertexPointer)
-      ctx->Driver.VertexPointer( ctx, size, type, stride, ptr );
+   update_array(ctx, &ctx->Array.ArrayObj->Vertex, _NEW_ARRAY_VERTEX,
+                elementSize, size, type, GL_RGBA, stride, GL_FALSE, ptr);
 }
 
 
@@ -192,12 +185,8 @@
          return;
    }
 
-   if (!update_array(ctx, &ctx->Array.ArrayObj->Normal, _NEW_ARRAY_NORMAL,
-                     elementSize, 3, type, GL_RGBA, stride, GL_TRUE, ptr))
-      return;
-
-   if (ctx->Driver.NormalPointer)
-      ctx->Driver.NormalPointer( ctx, type, stride, ptr );
+   update_array(ctx, &ctx->Array.ArrayObj->Normal, _NEW_ARRAY_NORMAL,
+                elementSize, 3, type, GL_RGBA, stride, GL_TRUE, ptr);
 }
 
 
@@ -272,12 +261,8 @@
          return;
    }
 
-   if (!update_array(ctx, &ctx->Array.ArrayObj->Color, _NEW_ARRAY_COLOR0,
-                     elementSize, size, type, format, stride, GL_TRUE, ptr))
-      return;
-
-   if (ctx->Driver.ColorPointer)
-      ctx->Driver.ColorPointer( ctx, size, type, stride, ptr );
+   update_array(ctx, &ctx->Array.ArrayObj->Color, _NEW_ARRAY_COLOR0,
+                elementSize, size, type, format, stride, GL_TRUE, ptr);
 }
 
 
@@ -305,12 +290,8 @@
          return;
    }
 
-   if (!update_array(ctx, &ctx->Array.ArrayObj->FogCoord, _NEW_ARRAY_FOGCOORD,
-                     elementSize, 1, type, GL_RGBA, stride, GL_FALSE, ptr))
-      return;
-
-   if (ctx->Driver.FogCoordPointer)
-      ctx->Driver.FogCoordPointer( ctx, type, stride, ptr );
+   update_array(ctx, &ctx->Array.ArrayObj->FogCoord, _NEW_ARRAY_FOGCOORD,
+                elementSize, 1, type, GL_RGBA, stride, GL_FALSE, ptr);
 }
 
 
@@ -347,12 +328,8 @@
          return;
    }
 
-   if (!update_array(ctx, &ctx->Array.ArrayObj->Index, _NEW_ARRAY_INDEX,
-                     elementSize, 1, type, GL_RGBA, stride, GL_FALSE, ptr))
-      return;
-
-   if (ctx->Driver.IndexPointer)
-      ctx->Driver.IndexPointer( ctx, type, stride, ptr );
+   update_array(ctx, &ctx->Array.ArrayObj->Index, _NEW_ARRAY_INDEX,
+                elementSize, 1, type, GL_RGBA, stride, GL_FALSE, ptr);
 }
 
 
@@ -423,13 +400,8 @@
          return;
    }
 
-   if (!update_array(ctx, &ctx->Array.ArrayObj->SecondaryColor,
-                     _NEW_ARRAY_COLOR1, elementSize, size, type,
-                     format, stride, GL_TRUE, ptr))
-      return;
-
-   if (ctx->Driver.SecondaryColorPointer)
-      ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr );
+   update_array(ctx, &ctx->Array.ArrayObj->SecondaryColor, _NEW_ARRAY_COLOR1,
+                elementSize, size, type, format, stride, GL_TRUE, ptr);
 }
 
 
@@ -485,13 +457,9 @@
          return;
    }
 
-   if (!update_array(ctx, &ctx->Array.ArrayObj->TexCoord[unit],
-                     _NEW_ARRAY_TEXCOORD(unit),
-                     elementSize, size, type, GL_RGBA, stride, GL_FALSE, ptr))
-      return;
-
-   if (ctx->Driver.TexCoordPointer)
-      ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr );
+   update_array(ctx, &ctx->Array.ArrayObj->TexCoord[unit],
+                _NEW_ARRAY_TEXCOORD(unit),
+                elementSize, size, type, GL_RGBA, stride, GL_FALSE, ptr);
 }
 
 
@@ -506,13 +474,9 @@
       return;
    }
 
-   if (!update_array(ctx, &ctx->Array.ArrayObj->EdgeFlag, _NEW_ARRAY_EDGEFLAG,
-                     sizeof(GLboolean), 1, GL_UNSIGNED_BYTE, GL_RGBA,
-                     stride, GL_FALSE, ptr))
-      return;
-
-   if (ctx->Driver.EdgeFlagPointer)
-      ctx->Driver.EdgeFlagPointer( ctx, stride, ptr );
+   update_array(ctx, &ctx->Array.ArrayObj->EdgeFlag, _NEW_ARRAY_EDGEFLAG,
+                sizeof(GLboolean), 1, GL_UNSIGNED_BYTE, GL_RGBA,
+                stride, GL_FALSE, ptr);
 }
 
 
@@ -620,13 +584,9 @@
          return;
    }
 
-   if (!update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index],
-                     _NEW_ARRAY_ATTRIB(index),
-                     elementSize, size, type, format, stride, normalized, ptr))
-      return;
-
-   if (ctx->Driver.VertexAttribPointer)
-      ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr );
+   update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index],
+                _NEW_ARRAY_ATTRIB(index),
+                elementSize, size, type, format, stride, normalized, ptr);
 }
 #endif
 
@@ -720,13 +680,9 @@
          return;
    }
 
-   if (!update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index],
-                     _NEW_ARRAY_ATTRIB(index),
-                     elementSize, size, type, format, stride, normalized, ptr))
-      return;
-
-   if (ctx->Driver.VertexAttribPointer)
-      ctx->Driver.VertexAttribPointer(ctx, index, size, type, stride, ptr);
+   update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index],
+                _NEW_ARRAY_ATTRIB(index),
+                elementSize, size, type, format, stride, normalized, ptr);
 }
 #endif
 
@@ -989,9 +945,6 @@
 
    ctx->NewState |= _NEW_ARRAY;
    ctx->Array.NewState |= _NEW_ARRAY_ALL;
-
-   if (ctx->Driver.LockArraysEXT)
-      ctx->Driver.LockArraysEXT( ctx, first, count );
 }
 
 
@@ -1013,9 +966,6 @@
    ctx->Array.LockCount = 0;
    ctx->NewState |= _NEW_ARRAY;
    ctx->Array.NewState |= _NEW_ARRAY_ALL;
-
-   if (ctx->Driver.UnlockArraysEXT)
-      ctx->Driver.UnlockArraysEXT( ctx );
 }
 
 
diff --git a/src/mesa/main/version.c b/src/mesa/main/version.c
new file mode 100644
index 0000000..9d23c57
--- /dev/null
+++ b/src/mesa/main/version.c
@@ -0,0 +1,130 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 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, sublicense,
+ * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS 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 "context.h"
+#include "version.h"
+
+
+
+/**
+ * Examine enabled GL extensions to determine GL version.
+ * Return major and minor version numbers.
+ */
+static void
+compute_version(const GLcontext *ctx, GLuint *major, GLuint *minor)
+{
+   const GLboolean ver_1_3 = (ctx->Extensions.ARB_multisample &&
+                              ctx->Extensions.ARB_multitexture &&
+                              ctx->Extensions.ARB_texture_border_clamp &&
+                              ctx->Extensions.ARB_texture_compression &&
+                              ctx->Extensions.ARB_texture_cube_map &&
+                              ctx->Extensions.EXT_texture_env_add &&
+                              ctx->Extensions.ARB_texture_env_combine &&
+                              ctx->Extensions.ARB_texture_env_dot3);
+   const GLboolean ver_1_4 = (ver_1_3 &&
+                              ctx->Extensions.ARB_depth_texture &&
+                              ctx->Extensions.ARB_shadow &&
+                              ctx->Extensions.ARB_texture_env_crossbar &&
+                              ctx->Extensions.ARB_texture_mirrored_repeat &&
+                              ctx->Extensions.ARB_window_pos &&
+                              ctx->Extensions.EXT_blend_color &&
+                              ctx->Extensions.EXT_blend_func_separate &&
+                              ctx->Extensions.EXT_blend_minmax &&
+                              ctx->Extensions.EXT_blend_subtract &&
+                              ctx->Extensions.EXT_fog_coord &&
+                              ctx->Extensions.EXT_multi_draw_arrays &&
+                              ctx->Extensions.EXT_point_parameters &&
+                              ctx->Extensions.EXT_secondary_color &&
+                              ctx->Extensions.EXT_stencil_wrap &&
+                              ctx->Extensions.EXT_texture_lod_bias &&
+                              ctx->Extensions.SGIS_generate_mipmap);
+   const GLboolean ver_1_5 = (ver_1_4 &&
+                              ctx->Extensions.ARB_occlusion_query &&
+                              ctx->Extensions.ARB_vertex_buffer_object &&
+                              ctx->Extensions.EXT_shadow_funcs);
+   const GLboolean ver_2_0 = (ver_1_5 &&
+                              ctx->Extensions.ARB_draw_buffers &&
+                              ctx->Extensions.ARB_point_sprite &&
+                              ctx->Extensions.ARB_shader_objects &&
+                              ctx->Extensions.ARB_vertex_shader &&
+                              ctx->Extensions.ARB_fragment_shader &&
+                              ctx->Extensions.ARB_texture_non_power_of_two &&
+                              ctx->Extensions.EXT_blend_equation_separate &&
+
+			      /* Technically, 2.0 requires the functionality
+			       * of the EXT version.  Enable 2.0 if either
+			       * extension is available, and assume that a
+			       * driver that only exposes the ATI extension
+			       * will fallback to software when necessary.
+			       */
+			      (ctx->Extensions.EXT_stencil_two_side
+			       || ctx->Extensions.ATI_separate_stencil));
+   const GLboolean ver_2_1 = (ver_2_0 &&
+                              ctx->Extensions.ARB_shading_language_120 &&
+                              ctx->Extensions.EXT_pixel_buffer_object &&
+                              ctx->Extensions.EXT_texture_sRGB);
+   if (ver_2_1) {
+      *major = 2;
+      *minor = 1;
+   }
+   else if (ver_2_0) {
+      *major = 2;
+      *minor = 0;
+   }
+   else if (ver_1_5) {
+      *major = 1;
+      *minor = 5;
+   }
+   else if (ver_1_4) {
+      *major = 1;
+      *minor = 4;
+   }
+   else if (ver_1_3) {
+      *major = 1;
+      *minor = 3;
+   }
+   else {
+      *major = 1;
+      *minor = 2;
+   }
+}
+
+
+/**
+ * Set the context's VersionMajor, VersionMinor, VersionString fields.
+ * This should only be called once as part of context initialization.
+ */
+void
+_mesa_compute_version(GLcontext *ctx)
+{
+   static const int max = 100;
+
+   compute_version(ctx, &ctx->VersionMajor, &ctx->VersionMinor);
+   
+   ctx->VersionString = (char *) _mesa_malloc(max);
+   if (ctx->VersionString) {
+      _mesa_snprintf(ctx->VersionString, max, "%u.%u Mesa " MESA_VERSION_STRING,
+                     ctx->VersionMajor, ctx->VersionMinor);
+   }
+}
diff --git a/src/mesa/main/version.h b/src/mesa/main/version.h
index 0cae186..d521569 100644
--- a/src/mesa/main/version.h
+++ b/src/mesa/main/version.h
@@ -1,6 +1,6 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.7
+ * Version:  7.8
  *
  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
@@ -28,11 +28,14 @@
 #define VERSION_H
 
 
+#include "mtypes.h"
+
+
 /* Mesa version */
 #define MESA_MAJOR 7
-#define MESA_MINOR 7
+#define MESA_MINOR 8
 #define MESA_PATCH 0
-#define MESA_VERSION_STRING "7.7-devel"
+#define MESA_VERSION_STRING "7.8-devel"
 
 /* To make version comparison easy */
 #define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
@@ -50,4 +53,8 @@
 #define OPENGL_VERSION_CODE OPENGL_VERSION(OPENGL_MAJOR, OPENGL_MINOR, OPENGL_PATCH)
 
 
+extern void
+_mesa_compute_version(GLcontext *ctx);
+
+
 #endif /* VERSION_H */
diff --git a/src/mesa/math/m_debug_norm.c b/src/mesa/math/m_debug_norm.c
index 89c632e..f9b26d8 100644
--- a/src/mesa/math/m_debug_norm.c
+++ b/src/mesa/math/m_debug_norm.c
@@ -230,7 +230,7 @@
          case VAR:
             break;
          default:
-            _mesa_exit(1);
+            exit(1);
          }
       }
    }
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c
index 05ee4f5..a09be71 100644
--- a/src/mesa/shader/arbprogparse.c
+++ b/src/mesa/shader/arbprogparse.c
@@ -56,7 +56,6 @@
 #include "main/context.h"
 #include "main/macros.h"
 #include "main/mtypes.h"
-#include "shader/grammar/grammar_mesa.h"
 #include "arbprogparse.h"
 #include "program.h"
 #include "programopt.h"
@@ -87,6 +86,9 @@
       return;
    }
 
+   if (program->Base.String != NULL)
+      _mesa_free(program->Base.String);
+
    /* Copy the relevant contents of the arb_program struct into the
     * fragment_program struct.
     */
@@ -178,6 +180,9 @@
       return;
    }
 
+   if (program->Base.String != NULL)
+      _mesa_free(program->Base.String);
+
    /* Copy the relevant contents of the arb_program struct into the 
     * vertex_program struct.
     */
diff --git a/src/mesa/shader/arbprogram.c b/src/mesa/shader/arbprogram.c
index 4d8cff0..eb537cd 100644
--- a/src/mesa/shader/arbprogram.c
+++ b/src/mesa/shader/arbprogram.c
@@ -37,6 +37,8 @@
 #include "main/mtypes.h"
 #include "arbprogram.h"
 #include "arbprogparse.h"
+#include "nvfragparse.h"
+#include "nvvertparse.h"
 #include "program.h"
 
 
@@ -428,36 +430,66 @@
 _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
                        const GLvoid *string)
 {
+   struct gl_program *base;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    FLUSH_VERTICES(ctx, _NEW_PROGRAM);
 
+   if (!ctx->Extensions.ARB_vertex_program
+       && !ctx->Extensions.ARB_fragment_program) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramStringARB()");
+      return;
+   }
+
    if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
       return;
    }
 
+   /* The first couple cases are complicated.  The same enum value is used for
+    * ARB and NV vertex programs.  If the target is a vertex program, parse it
+    * using the ARB grammar if the string starts with "!!ARB" or if
+    * NV_vertex_program is not supported.
+    */
    if (target == GL_VERTEX_PROGRAM_ARB
-       && ctx->Extensions.ARB_vertex_program) {
+       && ctx->Extensions.ARB_vertex_program
+       && ((strncmp(string, "!!ARB", 5) == 0)
+	   || !ctx->Extensions.NV_vertex_program)) {
       struct gl_vertex_program *prog = ctx->VertexProgram.Current;
       _mesa_parse_arb_vertex_program(ctx, target, string, len, prog);
-      
-      if (ctx->Program.ErrorPos == -1 && ctx->Driver.ProgramStringNotify)
-	 ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base );
+
+      base = & prog->Base;
+   }
+   else if ((target == GL_VERTEX_PROGRAM_ARB
+	     || target == GL_VERTEX_STATE_PROGRAM_NV)
+	    && ctx->Extensions.NV_vertex_program) {
+      struct gl_vertex_program *prog = ctx->VertexProgram.Current;
+      _mesa_parse_nv_vertex_program(ctx, target, string, len, prog);
+
+      base = & prog->Base;
    }
    else if (target == GL_FRAGMENT_PROGRAM_ARB
             && ctx->Extensions.ARB_fragment_program) {
       struct gl_fragment_program *prog = ctx->FragmentProgram.Current;
       _mesa_parse_arb_fragment_program(ctx, target, string, len, prog);
 
-      if (ctx->Program.ErrorPos == -1 && ctx->Driver.ProgramStringNotify)
-	 ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base );
+      base = & prog->Base;
+   }
+   else if (target == GL_FRAGMENT_PROGRAM_NV
+            && ctx->Extensions.NV_fragment_program) {
+      struct gl_fragment_program *prog = ctx->FragmentProgram.Current;
+      _mesa_parse_nv_fragment_program(ctx, target, string, len, prog);
+
+      base = & prog->Base;
    }
    else {
       _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
       return;
    }
+
+   if (ctx->Program.ErrorPos == -1 && ctx->Driver.ProgramStringNotify)
+      ctx->Driver.ProgramStringNotify( ctx, target, base );
 }
 
 
diff --git a/src/mesa/shader/atifragshader.c b/src/mesa/shader/atifragshader.c
index ac087d4..e04a05b 100644
--- a/src/mesa/shader/atifragshader.c
+++ b/src/mesa/shader/atifragshader.c
@@ -290,9 +290,11 @@
 
       /* The ID is immediately available for re-use now */
       _mesa_HashRemove(ctx->Shared->ATIShaders, id);
-      prog->RefCount--;
-      if (prog->RefCount <= 0) {
-         _mesa_free(prog);
+      if (prog) {
+	 prog->RefCount--;
+	 if (prog->RefCount <= 0) {
+	    _mesa_free(prog);
+	 }
       }
    }
 }
diff --git a/src/mesa/shader/descrip.mms b/src/mesa/shader/descrip.mms
index 19bafd4..5973002 100644
--- a/src/mesa/shader/descrip.mms
+++ b/src/mesa/shader/descrip.mms
@@ -16,7 +16,7 @@
 
 VPATH = RCS
 
-INCDIR = [---.include],[.grammar],[-.main],[-.glapi],[.slang]
+INCDIR = [---.include],[-.main],[-.glapi],[.slang]
 LIBDIR = [---.lib]
 CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1,"__extension__=")/name=(as_is,short)/float=ieee/ieee=denorm
 
@@ -64,8 +64,6 @@
 	$(MMS)$(MMSQUALIFIERS) $(LIBDIR)$(GL_LIB)
 	set def [.slang]
 	$(MMS)$(MMSQUALIFIERS)
-	set def [-.grammar]
-	$(MMS)$(MMSQUALIFIERS)
 	set def [-]
 
 # Make the library
diff --git a/src/mesa/shader/grammar/grammar.c b/src/mesa/shader/grammar/grammar.c
deleted file mode 100644
index a977596..0000000
--- a/src/mesa/shader/grammar/grammar.c
+++ /dev/null
@@ -1,3178 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.6
- *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL 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 grammar.c
- * syntax parsing engine
- * \author Michal Krol
- */
-
-#ifndef GRAMMAR_PORT_BUILD
-#error Do not build this file directly, build your grammar_XXX.c instead, which includes this file
-#endif
-
-/*
-*/
-
-/*
-    INTRODUCTION
-    ------------
-
-    The task is to check the syntax of an input string. Input string is a stream of ASCII
-    characters terminated with a null-character ('\0'). Checking it using C language is
-    difficult and hard to implement without bugs. It is hard to maintain and make changes when
-    the syntax changes.
-
-    This is because of a high redundancy of the C code. Large blocks of code are duplicated with
-    only small changes. Even use of macros does not solve the problem because macros cannot
-    erase the complexity of the problem.
-
-    The resolution is to create a new language that will be highly oriented to our task. Once
-    we describe a particular syntax, we are done. We can then focus on the code that implements
-    the language. The size and complexity of it is relatively small than the code that directly
-    checks the syntax.
-
-    First, we must implement our new language. Here, the language is implemented in C, but it
-    could also be implemented in any other language. The code is listed below. We must take
-    a good care that it is bug free. This is simple because the code is simple and clean.
-
-    Next, we must describe the syntax of our new language in itself. Once created and checked
-    manually that it is correct, we can use it to check another scripts.
-
-    Note that our new language loading code does not have to check the syntax. It is because we
-    assume that the script describing itself is correct, and other scripts can be syntactically
-    checked by the former script. The loading code must only do semantic checking which leads us to
-    simple resolving references.
-
-    THE LANGUAGE
-    ------------
-
-    Here I will describe the syntax of the new language (further called "Synek"). It is mainly a
-    sequence of declarations terminated by a semicolon. The declaration consists of a symbol,
-    which is an identifier, and its definition. A definition is in turn a sequence of specifiers
-    connected with ".and" or ".or" operator. These operators cannot be mixed together in a one
-    definition. Specifier can be a symbol, string, character, character range or a special
-    keyword ".true" or ".false".
-
-    On the very beginning of the script there is a declaration of a root symbol and is in the form:
-        .syntax <root_symbol>;
-    The <root_symbol> must be on of the symbols in declaration sequence. The syntax is correct if
-    the root symbol evaluates to true. A symbol evaluates to true if the definition associated with
-    the symbol evaluates to true. Definition evaluation depends on the operator used to connect
-    specifiers in the definition. If ".and" operator is used, definition evaluates to true if and
-    only if all the specifiers evaluate to true. If ".or" operator is used, definition evalutes to
-    true if any of the specifiers evaluates to true. If definition contains only one specifier,
-    it is evaluated as if it was connected with ".true" keyword by ".and" operator.
-
-    If specifier is a ".true" keyword, it always evaluates to true.
-
-    If specifier is a ".false" keyword, it always evaluates to false. Specifier evaluates to false
-    when it does not evaluate to true.
-
-    Character range specifier is in the form:
-        '<first_character>' - '<second_character>'
-    If specifier is a character range, it evaluates to true if character in the stream is greater
-    or equal to <first_character> and less or equal to <second_character>. In that situation 
-    the stream pointer is advanced to point to next character in the stream. All C-style escape
-    sequences are supported although trigraph sequences are not. The comparisions are performed
-    on 8-bit unsigned integers.
-
-    Character specifier is in the form:
-        '<single_character>'
-    It evaluates to true if the following character range specifier evaluates to true:
-        '<single_character>' - '<single_character>'
-
-    String specifier is in the form:
-        "<string>"
-    Let N be the number of characters in <string>. Let <string>[i] designate i-th character in
-    <string>. Then the string specifier evaluates to true if and only if for i in the range [0, N)
-    the following character specifier evaluates to true:
-        '<string>[i]'
-    If <string>[i] is a quotation mark, '<string>[i]' is replaced with '\<string>[i]'.
-
-    Symbol specifier can be optionally preceded by a ".loop" keyword in the form:
-        .loop <symbol>                  (1)
-    where <symbol> is defined as follows:
-        <symbol> <definition>;          (2)
-    Construction (1) is replaced by the following code:
-        <symbol$1>
-    and declaration (2) is replaced by the following:
-        <symbol$1> <symbol$2> .or .true;
-        <symbol$2> <symbol> .and <symbol$1>;
-        <symbol> <definition>;
-
-    Synek supports also a register mechanizm. User can, in its SYN file, declare a number of
-    registers that can be accessed in the syn body. Each reg has its name and a default value.
-    The register is one byte wide. The C code can change the default value by calling
-    grammar_set_reg8() with grammar id, register name and a new value. As we know, each rule is
-    a sequence of specifiers joined with .and or .or operator. And now each specifier can be
-    prefixed with a condition expression in a form ".if (<reg_name> <operator> <hex_literal>)"
-    where <operator> can be == or !=. If the condition evaluates to false, the specifier
-    evaluates to .false. Otherwise it evalutes to the specifier.
-
-    ESCAPE SEQUENCES
-    ----------------
-
-    Synek supports all escape sequences in character specifiers. The mapping table is listed below.
-    All occurences of the characters in the first column are replaced with the corresponding
-    character in the second column.
-
-        Escape sequence         Represents
-    ------------------------------------------------------------------------------------------------
-        \a                      Bell (alert)
-        \b                      Backspace
-        \f                      Formfeed
-        \n                      New line
-        \r                      Carriage return
-        \t                      Horizontal tab
-        \v                      Vertical tab
-        \'                      Single quotation mark
-        \"                      Double quotation mark
-        \\                      Backslash
-        \?                      Literal question mark
-        \ooo                    ASCII character in octal notation
-        \xhhh                   ASCII character in hexadecimal notation
-    ------------------------------------------------------------------------------------------------
-
-    RAISING ERRORS
-    --------------
-
-    Any specifier can be followed by a special construction that is executed when the specifier
-    evaluates to false. The construction is in the form:
-        .error <ERROR_TEXT>
-    <ERROR_TEXT> is an identifier declared earlier by error text declaration. The declaration is
-    in the form:
-        .errtext <ERROR_TEXT> "<error_desc>"
-    When specifier evaluates to false and this construction is present, parsing is stopped
-    immediately and <error_desc> is returned as a result of parsing. The error position is also
-    returned and it is meant as an offset from the beggining of the stream to the character that
-    was valid so far. Example:
-
-        (**** syntax script ****)
-
-        .syntax program;
-        .errtext MISSING_SEMICOLON      "missing ';'"
-        program         declaration .and .loop space .and ';' .error MISSING_SEMICOLON .and
-                        .loop space .and '\0';
-        declaration     "declare" .and .loop space .and identifier;
-        space           ' ';
-
-        (**** sample code ****)
-
-        declare foo ,
-
-    In the example above checking the sample code will result in error message "missing ';'" and
-    error position 12. The sample code is not correct. Note the presence of '\0' specifier to
-    assure that there is no code after semicolon - only spaces.
-    <error_desc> can optionally contain identifier surrounded by dollar signs $. In such a case,
-    the identifier and dollar signs are replaced by a string retrieved by invoking symbol with
-    the identifier name. The starting position is the error position. The lenght of the resulting
-    string is the position after invoking the symbol.
-
-    PRODUCTION
-    ----------
-
-    Synek not only checks the syntax but it can also produce (emit) bytes associated with specifiers
-    that evaluate to true. That is, every specifier and optional error construction can be followed
-    by a number of emit constructions that are in the form:
-        .emit <parameter>
-    <paramater> can be a HEX number, identifier, a star * or a dollar $. HEX number is preceded by
-    0x or 0X. If <parameter> is an identifier, it must be earlier declared by emit code declaration
-    in the form:
-        .emtcode <identifier> <hex_number>
-
-    When given specifier evaluates to true, all emits associated with the specifier are output
-    in order they were declared. A star means that last-read character should be output instead
-    of constant value. Example:
-
-        (**** syntax script ****)
-
-        .syntax foobar;
-        .emtcode WORD_FOO       0x01
-        .emtcode WORD_BAR       0x02
-        foobar      FOO .emit WORD_FOO .or BAR .emit WORD_BAR .or .true .emit 0x00;
-        FOO         "foo" .and SPACE;
-        BAR         "bar" .and SPACE;
-        SPACE       ' ' .or '\0';
-
-        (**** sample text 1 ****)
-
-        foo
-
-        (**** sample text 2 ****)
-
-        foobar
-
-    For both samples the result will be one-element array. For first sample text it will be
-    value 1, for second - 0. Note that every text will be accepted because of presence of
-    .true as an alternative.
-
-    Another example:
-
-        (**** syntax script ****)
-
-        .syntax declaration;
-        .emtcode VARIABLE       0x01
-        declaration     "declare" .and .loop space .and
-                        identifier .emit VARIABLE .and          (1)
-                        .true .emit 0x00 .and                   (2)
-                        .loop space .and ';';
-        space           ' ' .or '\t';
-        identifier      .loop id_char .emit *;                  (3)
-        id_char         'a'-'z' .or 'A'-'Z' .or '_';
-
-        (**** sample code ****)
-
-        declare    fubar;
-
-    In specifier (1) symbol <identifier> is followed by .emit VARIABLE. If it evaluates to
-    true, VARIABLE constant and then production of the symbol is output. Specifier (2) is used
-    to terminate the string with null to signal when the string ends. Specifier (3) outputs
-    all characters that make declared identifier. The result of sample code will be the
-    following array:
-        { 1, 'f', 'u', 'b', 'a', 'r', 0 }
-
-    If .emit is followed by dollar $, it means that current position should be output. Current
-    position is a 32-bit unsigned integer distance from the very beginning of the parsed string to
-    first character consumed by the specifier associated with the .emit instruction. Current
-    position is stored in the output buffer in Little-Endian convention (the lowest byte comes
-    first).
-*/
-
-#include <stdio.h>
-
-static void mem_free (void **);
-
-/*
-    internal error messages
-*/
-static const byte *OUT_OF_MEMORY =          (byte *) "internal error 1001: out of physical memory";
-static const byte *UNRESOLVED_REFERENCE =   (byte *) "internal error 1002: unresolved reference '$'";
-static const byte *INVALID_GRAMMAR_ID =     (byte *) "internal error 1003: invalid grammar object";
-static const byte *INVALID_REGISTER_NAME =  (byte *) "internal error 1004: invalid register name: '$'";
-/*static const byte *DUPLICATE_IDENTIFIER =   (byte *) "internal error 1005: identifier '$' already defined";*/
-static const byte *UNREFERENCED_IDENTIFIER =(byte *) "internal error 1006: unreferenced identifier '$'";
-
-static const byte *error_message = NULL;    /* points to one of the error messages above */
-static byte *error_param = NULL;        /* this is inserted into error_message in place of $ */
-static int error_position = -1;
-
-static byte *unknown = (byte *) "???";
-
-static void clear_last_error (void)
-{
-    /* reset error message */
-    error_message = NULL;
-
-    /* free error parameter - if error_param is a "???" don't free it - it's static */
-    if (error_param != unknown)
-        mem_free ((void **) (void *) &error_param);
-    else
-        error_param = NULL;
-
-    /* reset error position */
-    error_position = -1;
-}
-
-static void set_last_error (const byte *msg, byte *param, int pos)
-{
-    /* error message can be set only once */
-    if (error_message != NULL)
-    {
-        mem_free ((void **) (void *) &param);
-        return;
-    }
-
-    error_message = msg;
-
-    /* if param is NULL, set error_param to unknown ("???") */
-    /* note: do not try to strdup the "???" - it may be that we are here because of */
-    /* out of memory error so strdup can fail */
-    if (param != NULL)
-        error_param = param;
-    else
-        error_param = unknown;
-
-    error_position = pos;
-}
-
-/*
-    memory management routines
-*/
-static void *mem_alloc (size_t size)
-{
-    void *ptr = grammar_alloc_malloc (size);
-    if (ptr == NULL)
-        set_last_error (OUT_OF_MEMORY, NULL, -1);
-    return ptr;
-}
-
-static void *mem_copy (void *dst, const void *src, size_t size)
-{
-    return grammar_memory_copy (dst, src, size);
-}
-
-static void mem_free (void **ptr)
-{
-    grammar_alloc_free (*ptr);
-    *ptr = NULL;
-}
-
-static void *mem_realloc (void *ptr, size_t old_size, size_t new_size)
-{
-    void *ptr2 = grammar_alloc_realloc (ptr, old_size, new_size);
-    if (ptr2 == NULL)
-        set_last_error (OUT_OF_MEMORY, NULL, -1);
-    return ptr2;
-}
-
-static byte *str_copy_n (byte *dst, const byte *src, size_t max_len)
-{
-    return grammar_string_copy_n (dst, src, max_len);
-}
-
-static byte *str_duplicate (const byte *str)
-{
-    byte *new_str = grammar_string_duplicate (str);
-    if (new_str == NULL)
-        set_last_error (OUT_OF_MEMORY, NULL, -1);
-    return new_str;
-}
-
-static int str_equal (const byte *str1, const byte *str2)
-{
-    return grammar_string_compare (str1, str2) == 0;
-}
-
-static int str_equal_n (const byte *str1, const byte *str2, unsigned int n)
-{
-    return grammar_string_compare_n (str1, str2, n) == 0;
-}
-
-static int
-str_length (const byte *str)
-{
-   return (int) (grammar_string_length (str));
-}
-
-/*
-    useful macros
-*/
-#define GRAMMAR_IMPLEMENT_LIST_APPEND(_Ty)\
-    static void _Ty##_append (_Ty **x, _Ty *nx) {\
-        while (*x) x = &(**x).next;\
-        *x = nx;\
-    }
-
-/*
-    string to byte map typedef
-*/
-typedef struct map_byte_
-{
-    byte *key;
-    byte data;
-    struct map_byte_ *next;
-} map_byte;
-
-static void map_byte_create (map_byte **ma)
-{
-    *ma = (map_byte *) mem_alloc (sizeof (map_byte));
-    if (*ma)
-    {
-        (**ma).key = NULL;
-        (**ma).data = '\0';
-        (**ma).next = NULL;
-    }
-}
-
-static void map_byte_destroy (map_byte **ma)
-{
-    if (*ma)
-    {
-        map_byte_destroy (&(**ma).next);
-        mem_free ((void **) &(**ma).key);
-        mem_free ((void **) ma);
-    }
-}
-
-GRAMMAR_IMPLEMENT_LIST_APPEND(map_byte)
-
-/*
-    searches the map for the specified key,
-    returns pointer to the element with the specified key if it exists
-    returns NULL otherwise
-*/
-static map_byte *map_byte_locate (map_byte **ma, const byte *key)
-{
-    while (*ma)
-    {
-        if (str_equal ((**ma).key, key))
-            return *ma;
-
-        ma = &(**ma).next;
-    }
-
-    set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);
-    return NULL;
-}
-
-/*
-    searches the map for specified key,
-    if the key is matched, *data is filled with data associated with the key,
-    returns 0 if the key is matched,
-    returns 1 otherwise
-*/
-static int map_byte_find (map_byte **ma, const byte *key, byte *data)
-{
-    map_byte *found = map_byte_locate (ma, key);
-    if (found != NULL)
-    {
-        *data = found->data;
-
-        return 0;
-    }
-
-    return 1;
-}
-
-/*
-    regbyte context typedef
-
-    Each regbyte consists of its name and a default value. These are static and created at
-    grammar script compile-time, for example the following line:
-        .regbyte vertex_blend      0x00
-    adds a new regbyte named "vertex_blend" to the static list and initializes it to 0.
-    When the script is executed, this regbyte can be accessed by name for read and write. When a
-    particular regbyte is written, a new regbyte_ctx entry is added to the top of the regbyte_ctx
-    stack. The new entry contains information abot which regbyte it references and its new value.
-    When a given regbyte is accessed for read, the stack is searched top-down to find an
-    entry that references the regbyte. The first matching entry is used to return the current
-    value it holds. If no entry is found, the default value is returned.
-*/
-typedef struct regbyte_ctx_
-{
-    map_byte *m_regbyte;
-    byte m_current_value;
-    struct regbyte_ctx_ *m_prev;
-} regbyte_ctx;
-
-static void regbyte_ctx_create (regbyte_ctx **re)
-{
-    *re = (regbyte_ctx *) mem_alloc (sizeof (regbyte_ctx));
-    if (*re)
-    {
-        (**re).m_regbyte = NULL;
-        (**re).m_prev = NULL;
-    }
-}
-
-static void regbyte_ctx_destroy (regbyte_ctx **re)
-{
-    if (*re)
-    {
-        mem_free ((void **) re);
-    }
-}
-
-static byte regbyte_ctx_extract (regbyte_ctx **re, map_byte *reg)
-{
-    /* first lookup in the register stack */
-    while (*re != NULL)
-    {
-        if ((**re).m_regbyte == reg)
-            return (**re).m_current_value;
-
-        re = &(**re).m_prev;
-    }
-
-    /* if not found - return the default value */
-    return reg->data;
-}
-
-/*
-    emit type typedef
-*/
-typedef enum emit_type_
-{
-    et_byte,            /* explicit number */
-    et_stream,          /* eaten character */
-    et_position         /* current position */
-} emit_type;
-
-/*
-    emit destination typedef
-*/
-typedef enum emit_dest_
-{
-    ed_output,          /* write to the output buffer */
-    ed_regbyte          /* write a particular regbyte */
-} emit_dest;
-
-/*
-    emit typedef
-*/
-typedef struct emit_
-{
-    emit_dest m_emit_dest;
-    emit_type m_emit_type;      /* ed_output */
-    byte m_byte;                /* et_byte */
-    map_byte *m_regbyte;        /* ed_regbyte */
-    byte *m_regname;            /* ed_regbyte - temporary */
-    struct emit_ *m_next;
-} emit;
-
-static void emit_create (emit **em)
-{
-    *em = (emit *) mem_alloc (sizeof (emit));
-    if (*em)
-    {
-        (**em).m_emit_dest = ed_output;
-        (**em).m_emit_type = et_byte;
-        (**em).m_byte = '\0';
-        (**em).m_regbyte = NULL;
-        (**em).m_regname = NULL;
-        (**em).m_next = NULL;
-    }
-}
-
-static void emit_destroy (emit **em)
-{
-    if (*em)
-    {
-        emit_destroy (&(**em).m_next);
-        mem_free ((void **) &(**em).m_regname);
-        mem_free ((void **) em);
-    }
-}
-
-static unsigned int emit_size (emit *_E)
-{
-    unsigned int n = 0;
-
-    while (_E != NULL)
-    {
-        if (_E->m_emit_dest == ed_output)
-        {
-            if (_E->m_emit_type == et_position)
-                n += 4;     /* position is a 32-bit unsigned integer */
-            else
-                n++;
-        }
-        _E = _E->m_next;
-    }
-
-    return n;
-}
-
-static int emit_push (emit *_E, byte *_P, byte c, unsigned int _Pos, regbyte_ctx **_Ctx)
-{
-    while (_E != NULL)
-    {
-        if (_E->m_emit_dest == ed_output)
-        {
-            if (_E->m_emit_type == et_byte)
-                *_P++ = _E->m_byte;
-            else if (_E->m_emit_type == et_stream)
-                *_P++ = c;
-            else /* _Em->type == et_position */
-            {
-                *_P++ = (byte) (_Pos);
-                *_P++ = (byte) (_Pos >> 8);
-                *_P++ = (byte) (_Pos >> 16);
-                *_P++ = (byte) (_Pos >> 24);
-            }
-        }
-        else
-        {
-            regbyte_ctx *new_rbc;
-            regbyte_ctx_create (&new_rbc);
-            if (new_rbc == NULL)
-                return 1;
-
-            new_rbc->m_prev = *_Ctx;
-            new_rbc->m_regbyte = _E->m_regbyte;
-            *_Ctx = new_rbc;
-
-            if (_E->m_emit_type == et_byte)
-                new_rbc->m_current_value = _E->m_byte;
-            else if (_E->m_emit_type == et_stream)
-                new_rbc->m_current_value = c;
-        }
-
-        _E = _E->m_next;
-    }
-
-    return 0;
-}
-
-/*
-    error typedef
-*/
-typedef struct error_
-{
-    byte *m_text;
-    byte *m_token_name;
-    struct rule_ *m_token;
-} error;
-
-static void error_create (error **er)
-{
-    *er = (error *) mem_alloc (sizeof (error));
-    if (*er)
-    {
-        (**er).m_text = NULL;
-        (**er).m_token_name = NULL;
-        (**er).m_token = NULL;
-    }
-}
-
-static void error_destroy (error **er)
-{
-    if (*er)
-    {
-        mem_free ((void **) &(**er).m_text);
-        mem_free ((void **) &(**er).m_token_name);
-        mem_free ((void **) er);
-    }
-}
-
-struct dict_;
-
-static byte *
-error_get_token (error *, struct dict_ *, const byte *, int);
-
-/*
-    condition operand type typedef
-*/
-typedef enum cond_oper_type_
-{
-    cot_byte,               /* constant 8-bit unsigned integer */
-    cot_regbyte             /* pointer to byte register containing the current value */
-} cond_oper_type;
-
-/*
-    condition operand typedef
-*/
-typedef struct cond_oper_
-{
-    cond_oper_type m_type;
-    byte m_byte;            /* cot_byte */
-    map_byte *m_regbyte;    /* cot_regbyte */
-    byte *m_regname;        /* cot_regbyte - temporary */
-} cond_oper;
-
-/*
-    condition type typedef
-*/
-typedef enum cond_type_
-{
-    ct_equal,
-    ct_not_equal
-} cond_type;
-
-/*
-    condition typedef
-*/
-typedef struct cond_
-{
-    cond_type m_type;
-    cond_oper m_operands[2];
-} cond;
-
-static void cond_create (cond **co)
-{
-    *co = (cond *) mem_alloc (sizeof (cond));
-    if (*co)
-    {
-        (**co).m_operands[0].m_regname = NULL;
-        (**co).m_operands[1].m_regname = NULL;
-    }
-}
-
-static void cond_destroy (cond **co)
-{
-    if (*co)
-    {
-        mem_free ((void **) &(**co).m_operands[0].m_regname);
-        mem_free ((void **) &(**co).m_operands[1].m_regname);
-        mem_free ((void **) co);
-    }
-}
-
-/*
-    specifier type typedef
-*/
-typedef enum spec_type_
-{
-    st_false,
-    st_true,
-    st_byte,
-    st_byte_range,
-    st_string,
-    st_identifier,
-    st_identifier_loop,
-    st_debug
-} spec_type;
-
-/*
-    specifier typedef
-*/
-typedef struct spec_
-{
-    spec_type m_spec_type;
-    byte m_byte[2];                 /* st_byte, st_byte_range */
-    byte *m_string;                 /* st_string */
-    struct rule_ *m_rule;           /* st_identifier, st_identifier_loop */
-    emit *m_emits;
-    error *m_errtext;
-    cond *m_cond;
-    struct spec_ *next;
-} spec;
-
-static void spec_create (spec **sp)
-{
-    *sp = (spec *) mem_alloc (sizeof (spec));
-    if (*sp)
-    {
-        (**sp).m_spec_type = st_false;
-        (**sp).m_byte[0] = '\0';
-        (**sp).m_byte[1] = '\0';
-        (**sp).m_string = NULL;
-        (**sp).m_rule = NULL;
-        (**sp).m_emits = NULL;
-        (**sp).m_errtext = NULL;
-        (**sp).m_cond = NULL;
-        (**sp).next = NULL;
-    }
-}
-
-static void spec_destroy (spec **sp)
-{
-    if (*sp)
-    {
-        spec_destroy (&(**sp).next);
-        emit_destroy (&(**sp).m_emits);
-        error_destroy (&(**sp).m_errtext);
-        mem_free ((void **) &(**sp).m_string);
-        cond_destroy (&(**sp).m_cond);
-        mem_free ((void **) sp);
-    }
-}
-
-GRAMMAR_IMPLEMENT_LIST_APPEND(spec)
-
-/*
-    operator typedef
-*/
-typedef enum oper_
-{
-    op_none,
-    op_and,
-    op_or
-} oper;
-
-/*
-    rule typedef
-*/
-typedef struct rule_
-{
-    oper m_oper;
-    spec *m_specs;
-    struct rule_ *next;
-    int m_referenced;
-} rule;
-
-static void rule_create (rule **ru)
-{
-    *ru = (rule *) mem_alloc (sizeof (rule));
-    if (*ru)
-    {
-        (**ru).m_oper = op_none;
-        (**ru).m_specs = NULL;
-        (**ru).next = NULL;
-        (**ru).m_referenced = 0;
-    }
-}
-
-static void rule_destroy (rule **ru)
-{
-    if (*ru)
-    {
-        rule_destroy (&(**ru).next);
-        spec_destroy (&(**ru).m_specs);
-        mem_free ((void **) ru);
-    }
-}
-
-GRAMMAR_IMPLEMENT_LIST_APPEND(rule)
-
-/*
-    returns unique grammar id
-*/
-static grammar next_valid_grammar_id (void)
-{
-    static grammar id = 0;
-
-    return ++id;
-}
-
-/*
-    dictionary typedef
-*/
-typedef struct dict_
-{
-    rule *m_rulez;
-    rule *m_syntax;
-    rule *m_string;
-    map_byte *m_regbytes;
-    grammar m_id;
-    struct dict_ *next;
-} dict;
-
-static void dict_create (dict **di)
-{
-    *di = (dict *) mem_alloc (sizeof (dict));
-    if (*di)
-    {
-        (**di).m_rulez = NULL;
-        (**di).m_syntax = NULL;
-        (**di).m_string = NULL;
-        (**di).m_regbytes = NULL;
-        (**di).m_id = next_valid_grammar_id ();
-        (**di).next = NULL;
-    }
-}
-
-static void dict_destroy (dict **di)
-{
-    if (*di)
-    {
-        rule_destroy (&(**di).m_rulez);
-        map_byte_destroy (&(**di).m_regbytes);
-        mem_free ((void **) di);
-    }
-}
-
-GRAMMAR_IMPLEMENT_LIST_APPEND(dict)
-
-static void dict_find (dict **di, grammar key, dict **data)
-{
-    while (*di)
-    {
-        if ((**di).m_id == key)
-        {
-            *data = *di;
-            return;
-        }
-
-        di = &(**di).next;
-    }
-
-    *data = NULL;
-}
-
-static dict *g_dicts = NULL;
-
-/*
-    byte array typedef
-*/
-typedef struct barray_
-{
-    byte *data;
-    unsigned int len;
-} barray;
-
-static void barray_create (barray **ba)
-{
-    *ba = (barray *) mem_alloc (sizeof (barray));
-    if (*ba)
-    {
-        (**ba).data = NULL;
-        (**ba).len = 0;
-    }
-}
-
-static void barray_destroy (barray **ba)
-{
-    if (*ba)
-    {
-        mem_free ((void **) &(**ba).data);
-        mem_free ((void **) ba);
-    }
-}
-
-/*
-    reallocates byte array to requested size,
-    returns 0 on success,
-    returns 1 otherwise
-*/
-static int barray_resize (barray **ba, unsigned int nlen)
-{
-    byte *new_pointer;
-
-    if (nlen == 0)
-    {
-        mem_free ((void **) &(**ba).data);
-        (**ba).data = NULL;
-        (**ba).len = 0;
-
-        return 0;
-    }
-    else
-    {
-        new_pointer = (byte *) mem_realloc ((**ba).data, (**ba).len * sizeof (byte),
-            nlen * sizeof (byte));
-        if (new_pointer)
-        {
-            (**ba).data = new_pointer;
-            (**ba).len = nlen;
-
-            return 0;
-        }
-    }
-
-    return 1;
-}
-
-/*
-    adds byte array pointed by *nb to the end of array pointed by *ba,
-    returns 0 on success,
-    returns 1 otherwise
-*/
-static int barray_append (barray **ba, barray **nb)
-{
-    const unsigned int len = (**ba).len;
-
-    if (barray_resize (ba, (**ba).len + (**nb).len))
-        return 1;
-
-    mem_copy ((**ba).data + len, (**nb).data, (**nb).len);
-
-    return 0;
-}
-
-/*
-    adds emit chain pointed by em to the end of array pointed by *ba,
-    returns 0 on success,
-    returns 1 otherwise
-*/
-static int barray_push (barray **ba, emit *em, byte c, unsigned int pos, regbyte_ctx **rbc)
-{
-    unsigned int count = emit_size (em);
-
-    if (barray_resize (ba, (**ba).len + count))
-        return 1;
-
-    return emit_push (em, (**ba).data + ((**ba).len - count), c, pos, rbc);
-}
-
-/*
-    byte pool typedef
-*/
-typedef struct bytepool_
-{
-    byte *_F;
-    unsigned int _Siz;
-} bytepool;
-
-static void bytepool_destroy (bytepool **by)
-{
-    if (*by != NULL)
-    {
-        mem_free ((void **) &(**by)._F);
-        mem_free ((void **) by);
-    }
-}
-
-static void bytepool_create (bytepool **by, int len)
-{
-    *by = (bytepool *) (mem_alloc (sizeof (bytepool)));
-    if (*by != NULL)
-    {
-        (**by)._F = (byte *) (mem_alloc (sizeof (byte) * len));
-        (**by)._Siz = len;
-
-        if ((**by)._F == NULL)
-            bytepool_destroy (by);
-    }
-}
-
-static int bytepool_reserve (bytepool *by, unsigned int n)
-{
-    byte *_P;
-
-    if (n <= by->_Siz)
-        return 0;
-
-    /* byte pool can only grow and at least by doubling its size */
-    n = n >= by->_Siz * 2 ? n : by->_Siz * 2;
-
-    /* reallocate the memory and adjust pointers to the new memory location */
-    _P = (byte *) (mem_realloc (by->_F, sizeof (byte) * by->_Siz, sizeof (byte) * n));
-    if (_P != NULL)
-    {
-        by->_F = _P;
-        by->_Siz = n;
-        return 0;
-    }
-
-    return 1;
-}
-
-/*
-    string to string map typedef
-*/
-typedef struct map_str_
-{
-    byte *key;
-    byte *data;
-    struct map_str_ *next;
-} map_str;
-
-static void map_str_create (map_str **ma)
-{
-    *ma = (map_str *) mem_alloc (sizeof (map_str));
-    if (*ma)
-    {
-        (**ma).key = NULL;
-        (**ma).data = NULL;
-        (**ma).next = NULL;
-    }
-}
-
-static void map_str_destroy (map_str **ma)
-{
-    if (*ma)
-    {
-        map_str_destroy (&(**ma).next);
-        mem_free ((void **) &(**ma).key);
-        mem_free ((void **) &(**ma).data);
-        mem_free ((void **) ma);
-    }
-}
-
-GRAMMAR_IMPLEMENT_LIST_APPEND(map_str)
-
-/*
-    searches the map for specified key,
-    if the key is matched, *data is filled with data associated with the key,
-    returns 0 if the key is matched,
-    returns 1 otherwise
-*/
-static int map_str_find (map_str **ma, const byte *key, byte **data)
-{
-    while (*ma)
-    {
-        if (str_equal ((**ma).key, key))
-        {
-            *data = str_duplicate ((**ma).data);
-            if (*data == NULL)
-                return 1;
-
-            return 0;
-        }
-
-        ma = &(**ma).next;
-    }
-
-    set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);
-    return 1;
-}
-
-/*
-    string to rule map typedef
-*/
-typedef struct map_rule_
-{
-    byte *key;
-    rule *data;
-    struct map_rule_ *next;
-} map_rule;
-
-static void map_rule_create (map_rule **ma)
-{
-    *ma = (map_rule *) mem_alloc (sizeof (map_rule));
-    if (*ma)
-    {
-        (**ma).key = NULL;
-        (**ma).data = NULL;
-        (**ma).next = NULL;
-    }
-}
-
-static void map_rule_destroy (map_rule **ma)
-{
-    if (*ma)
-    {
-        map_rule_destroy (&(**ma).next);
-        mem_free ((void **) &(**ma).key);
-        mem_free ((void **) ma);
-    }
-}
-
-GRAMMAR_IMPLEMENT_LIST_APPEND(map_rule)
-
-/*
-    searches the map for specified key,
-    if the key is matched, *data is filled with data associated with the key,
-    returns 0 if the is matched,
-    returns 1 otherwise
-*/
-static int map_rule_find (map_rule **ma, const byte *key, rule **data)
-{
-    while (*ma)
-    {
-        if (str_equal ((**ma).key, key))
-        {
-            *data = (**ma).data;
-
-            return 0;
-        }
-
-        ma = &(**ma).next;
-    }
-
-    set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1);
-    return 1;
-}
-
-/*
-    returns 1 if given character is a white space,
-    returns 0 otherwise
-*/
-static int is_space (byte c)
-{
-    return c == ' ' || c == '\t' || c == '\n' || c == '\r';
-}
-
-/*
-    advances text pointer by 1 if character pointed by *text is a space,
-    returns 1 if a space has been eaten,
-    returns 0 otherwise
-*/
-static int eat_space (const byte **text)
-{
-    if (is_space (**text))
-    {
-        (*text)++;
-
-        return 1;
-    }
-
-    return 0;
-}
-
-/*
-    returns 1 if text points to C-style comment start string,
-    returns 0 otherwise
-*/
-static int is_comment_start (const byte *text)
-{
-    return text[0] == '/' && text[1] == '*';
-}
-
-/*
-    advances text pointer to first character after C-style comment block - if any,
-    returns 1 if C-style comment block has been encountered and eaten,
-    returns 0 otherwise
-*/
-static int eat_comment (const byte **text)
-{
-    if (is_comment_start (*text))
-    {
-        /* *text points to comment block - skip two characters to enter comment body */
-        *text += 2;
-        /* skip any character except consecutive '*' and '/' */
-        while (!((*text)[0] == '*' && (*text)[1] == '/'))
-            (*text)++;
-        /* skip those two terminating characters */
-        *text += 2;
-
-        return 1;
-    }
-
-    return 0;
-}
-
-/*
-    advances text pointer to first character that is neither space nor C-style comment block
-*/
-static void eat_spaces (const byte **text)
-{
-    while (eat_space (text) || eat_comment (text))
-        ;
-}
-
-/*
-    resizes string pointed by *ptr to successfully add character c to the end of the string,
-    returns 0 on success,
-    returns 1 otherwise
-*/
-static int string_grow (byte **ptr, unsigned int *len, byte c)
-{
-    /* reallocate the string in 16-byte increments */
-    if ((*len & 0x0F) == 0x0F || *ptr == NULL)
-    {
-        byte *tmp = (byte *) mem_realloc (*ptr, ((*len + 1) & ~0x0F) * sizeof (byte),
-            ((*len + 1 + 0x10) & ~0x0F) * sizeof (byte));
-        if (tmp == NULL)
-            return 1;
-
-        *ptr = tmp;
-    }
-
-    if (c)
-    {
-        /* append given character */
-        (*ptr)[*len] = c;
-        (*len)++;
-    }
-    (*ptr)[*len] = '\0';
-
-    return 0;
-}
-
-/*
-    returns 1 if given character is a valid identifier character a-z, A-Z, 0-9 or _
-    returns 0 otherwise
-*/
-static int is_identifier (byte c)
-{
-    return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
-}
-
-/*
-    copies characters from *text to *id until non-identifier character is encountered,
-    assumes that *id points to NULL object - caller is responsible for later freeing the string,
-    text pointer is advanced to point past the copied identifier,
-    returns 0 if identifier was successfully copied,
-    returns 1 otherwise
-*/
-static int get_identifier (const byte **text, byte **id)
-{
-    const byte *t = *text;
-    byte *p = NULL;
-    unsigned int len = 0;
-
-    if (string_grow (&p, &len, '\0'))
-        return 1;
-
-    /* loop while next character in buffer is valid for identifiers */
-    while (is_identifier (*t))
-    {
-        if (string_grow (&p, &len, *t++))
-        {
-            mem_free ((void **) (void *) &p);
-            return 1;
-        }
-    }
-
-    *text = t;
-    *id = p;
-
-    return 0;
-}
-
-/*
-    converts sequence of DEC digits pointed by *text until non-DEC digit is encountered,
-    advances text pointer past the converted sequence,
-    returns the converted value
-*/
-static unsigned int dec_convert (const byte **text)
-{
-    unsigned int value = 0;
-
-    while (**text >= '0' && **text <= '9')
-    {
-        value = value * 10 + **text - '0';
-        (*text)++;
-    }
-
-    return value;
-}
-
-/*
-    returns 1 if given character is HEX digit 0-9, A-F or a-f,
-    returns 0 otherwise
-*/
-static int is_hex (byte c)
-{
-    return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
-}
-
-/*
-    returns value of passed character as if it was HEX digit
-*/
-static unsigned int hex2dec (byte c)
-{
-    if (c >= '0' && c <= '9')
-        return c - '0';
-    if (c >= 'A' && c <= 'F')
-        return c - 'A' + 10;
-    return c - 'a' + 10;
-}
-
-/*
-    converts sequence of HEX digits pointed by *text until non-HEX digit is encountered,
-    advances text pointer past the converted sequence,
-    returns the converted value
-*/
-static unsigned int hex_convert (const byte **text)
-{
-    unsigned int value = 0;
-
-    while (is_hex (**text))
-    {
-        value = value * 0x10 + hex2dec (**text);
-        (*text)++;
-    }
-
-    return value;
-}
-
-/*
-    returns 1 if given character is OCT digit 0-7,
-    returns 0 otherwise
-*/
-static int is_oct (byte c)
-{
-    return c >= '0' && c <= '7';
-}
-
-/*
-    returns value of passed character as if it was OCT digit
-*/
-static int oct2dec (byte c)
-{
-    return c - '0';
-}
-
-static byte get_escape_sequence (const byte **text)
-{
-    int value = 0;
-
-    /* skip '\' character */
-    (*text)++;
-
-    switch (*(*text)++)
-    {
-    case '\'':
-        return '\'';
-    case '"':
-        return '\"';
-    case '?':
-        return '\?';
-    case '\\':
-        return '\\';
-    case 'a':
-        return '\a';
-    case 'b':
-        return '\b';
-    case 'f':
-        return '\f';
-    case 'n':
-        return '\n';
-    case 'r':
-        return '\r';
-    case 't':
-        return '\t';
-    case 'v':
-        return '\v';
-    case 'x':
-        return (byte) hex_convert (text);
-    }
-
-    (*text)--;
-    if (is_oct (**text))
-    {
-        value = oct2dec (*(*text)++);
-        if (is_oct (**text))
-        {
-            value = value * 010 + oct2dec (*(*text)++);
-            if (is_oct (**text))
-                value = value * 010 + oct2dec (*(*text)++);
-        }
-    }
-
-    return (byte) value;
-}
-
-/*
-    copies characters from *text to *str until " or ' character is encountered,
-    assumes that *str points to NULL object - caller is responsible for later freeing the string,
-    assumes that *text points to " or ' character that starts the string,
-    text pointer is advanced to point past the " or ' character,
-    returns 0 if string was successfully copied,
-    returns 1 otherwise
-*/
-static int get_string (const byte **text, byte **str)
-{
-    const byte *t = *text;
-    byte *p = NULL;
-    unsigned int len = 0;
-    byte term_char;
-
-    if (string_grow (&p, &len, '\0'))
-        return 1;
-
-    /* read " or ' character that starts the string */
-    term_char = *t++;
-    /* while next character is not the terminating character */
-    while (*t && *t != term_char)
-    {
-        byte c;
-
-        if (*t == '\\')
-            c = get_escape_sequence (&t);
-        else
-            c = *t++;
-
-        if (string_grow (&p, &len, c))
-        {
-            mem_free ((void **) (void *) &p);
-            return 1;
-        }
-    }
-    /* skip " or ' character that ends the string */
-    t++;
-
-    *text = t;
-    *str = p;
-    return 0;
-}
-
-/*
-    gets emit code, the syntax is:
-    ".emtcode" " " <symbol> " " (("0x" | "0X") <hex_value>) | <dec_value> | <character>
-    assumes that *text already points to <symbol>,
-    returns 0 if emit code is successfully read,
-    returns 1 otherwise
-*/
-static int get_emtcode (const byte **text, map_byte **ma)
-{
-    const byte *t = *text;
-    map_byte *m = NULL;
-
-    map_byte_create (&m);
-    if (m == NULL)
-        return 1;
-
-    if (get_identifier (&t, &m->key))
-    {
-        map_byte_destroy (&m);
-        return 1;
-    }
-    eat_spaces (&t);
-
-    if (*t == '\'')
-    {
-        byte *c;
-
-        if (get_string (&t, &c))
-        {
-            map_byte_destroy (&m);
-            return 1;
-        }
-
-        m->data = (byte) c[0];
-        mem_free ((void **) (void *) &c);
-    }
-    else if (t[0] == '0' && (t[1] == 'x' || t[1] == 'X'))
-    {
-        /* skip HEX "0x" or "0X" prefix */
-        t += 2;
-        m->data = (byte) hex_convert (&t);
-    }
-    else
-    {
-        m->data = (byte) dec_convert (&t);
-    }
-
-    eat_spaces (&t);
-
-    *text = t;
-    *ma = m;
-    return 0;
-}
-
-/*
-    gets regbyte declaration, the syntax is:
-    ".regbyte" " " <symbol> " " (("0x" | "0X") <hex_value>) | <dec_value> | <character>
-    assumes that *text already points to <symbol>,
-    returns 0 if regbyte is successfully read,
-    returns 1 otherwise
-*/
-static int get_regbyte (const byte **text, map_byte **ma)
-{
-    /* pass it to the emtcode parser as it has the same syntax starting at <symbol> */
-    return get_emtcode (text, ma);
-}
-
-/*
-    returns 0 on success,
-    returns 1 otherwise
-*/
-static int get_errtext (const byte **text, map_str **ma)
-{
-    const byte *t = *text;
-    map_str *m = NULL;
-
-    map_str_create (&m);
-    if (m == NULL)
-        return 1;
-
-    if (get_identifier (&t, &m->key))
-    {
-        map_str_destroy (&m);
-        return 1;
-    }
-    eat_spaces (&t);
-
-    if (get_string (&t, &m->data))
-    {
-        map_str_destroy (&m);
-        return 1;
-    }
-    eat_spaces (&t);
-
-    *text = t;
-    *ma = m;
-    return 0;
-}
-
-/*
-    returns 0 on success,
-    returns 1 otherwise,
-*/
-static int get_error (const byte **text, error **er, map_str *maps)
-{
-    const byte *t = *text;
-    byte *temp = NULL;
-
-    if (*t != '.')
-        return 0;
-
-    t++;
-    if (get_identifier (&t, &temp))
-        return 1;
-    eat_spaces (&t);
-
-    if (!str_equal ((byte *) "error", temp))
-    {
-        mem_free ((void **) (void *) &temp);
-        return 0;
-    }
-
-    mem_free ((void **) (void *) &temp);
-
-    error_create (er);
-    if (*er == NULL)
-        return 1;
-
-    if (*t == '\"')
-    {
-        if (get_string (&t, &(**er).m_text))
-        {
-            error_destroy (er);
-            return 1;
-        }
-        eat_spaces (&t);
-    }
-    else
-    {
-        if (get_identifier (&t, &temp))
-        {
-            error_destroy (er);
-            return 1;
-        }
-        eat_spaces (&t);
-
-        if (map_str_find (&maps, temp, &(**er).m_text))
-        {
-            mem_free ((void **) (void *) &temp);
-            error_destroy (er);
-            return 1;
-        }
-
-        mem_free ((void **) (void *) &temp);
-    }
-
-    /* try to extract "token" from "...$token$..." */
-    {
-        byte *processed = NULL;
-        unsigned int len = 0;
-      int i = 0;
-
-        if (string_grow (&processed, &len, '\0'))
-        {
-            error_destroy (er);
-            return 1;
-        }
-
-        while (i < str_length ((**er).m_text))
-        {
-            /* check if the dollar sign is repeated - if so skip it */
-            if ((**er).m_text[i] == '$' && (**er).m_text[i + 1] == '$')
-            {
-                if (string_grow (&processed, &len, '$'))
-                {
-                    mem_free ((void **) (void *) &processed);
-                    error_destroy (er);
-                    return 1;
-                }
-
-                i += 2;
-            }
-            else if ((**er).m_text[i] != '$')
-            {
-                if (string_grow (&processed, &len, (**er).m_text[i]))
-                {
-                    mem_free ((void **) (void *) &processed);
-                    error_destroy (er);
-                    return 1;
-                }
-
-                i++;
-            }
-            else
-            {
-                if (string_grow (&processed, &len, '$'))
-                {
-                    mem_free ((void **) (void *) &processed);
-                    error_destroy (er);
-                    return 1;
-                }
-
-                {
-                    /* length of token being extracted */
-                    unsigned int tlen = 0;
-
-                    if (string_grow (&(**er).m_token_name, &tlen, '\0'))
-                    {
-                        mem_free ((void **) (void *) &processed);
-                        error_destroy (er);
-                        return 1;
-                    }
-
-                    /* skip the dollar sign */
-                    i++;
-
-                    while ((**er).m_text[i] != '$')
-                    {
-                        if (string_grow (&(**er).m_token_name, &tlen, (**er).m_text[i]))
-                        {
-                            mem_free ((void **) (void *) &processed);
-                            error_destroy (er);
-                            return 1;
-                        }
-
-                        i++;
-                    }
-
-                    /* skip the dollar sign */
-                    i++;
-                }
-            }
-        }
-
-        mem_free ((void **) &(**er).m_text);
-        (**er).m_text = processed;
-    }
-
-    *text = t;
-    return 0;
-}
-
-/*
-    returns 0 on success,
-    returns 1 otherwise,
-*/
-static int get_emits (const byte **text, emit **em, map_byte *mapb)
-{
-    const byte *t = *text;
-    byte *temp = NULL;
-    emit *e = NULL;
-    emit_dest dest;
-
-    if (*t != '.')
-        return 0;
-
-    t++;
-    if (get_identifier (&t, &temp))
-        return 1;
-    eat_spaces (&t);
-
-    /* .emit */
-    if (str_equal ((byte *) "emit", temp))
-        dest = ed_output;
-    /* .load */
-    else if (str_equal ((byte *) "load", temp))
-        dest = ed_regbyte;
-    else
-    {
-        mem_free ((void **) (void *) &temp);
-        return 0;
-    }
-
-    mem_free ((void **) (void *) &temp);
-
-    emit_create (&e);
-    if (e == NULL)
-        return 1;
-
-    e->m_emit_dest = dest;
-
-    if (dest == ed_regbyte)
-    {
-        if (get_identifier (&t, &e->m_regname))
-        {
-            emit_destroy (&e);
-            return 1;
-        }
-        eat_spaces (&t);
-    }
-
-    /* 0xNN */
-    if (*t == '0' && (t[1] == 'x' || t[1] == 'X'))
-    {
-        t += 2;
-        e->m_byte = (byte) hex_convert (&t);
-
-        e->m_emit_type = et_byte;
-    }
-    /* NNN */
-    else if (*t >= '0' && *t <= '9')
-    {
-        e->m_byte = (byte) dec_convert (&t);
-
-        e->m_emit_type = et_byte;
-    }
-    /* * */
-    else if (*t == '*')
-    {
-        t++;
-
-        e->m_emit_type = et_stream;
-    }
-    /* $ */
-    else if (*t == '$')
-    {
-        t++;
-
-        e->m_emit_type = et_position;
-    }
-    /* 'c' */
-    else if (*t == '\'')
-    {
-        if (get_string (&t, &temp))
-        {
-            emit_destroy (&e);
-            return 1;
-        }
-        e->m_byte = (byte) temp[0];
-
-        mem_free ((void **) (void *) &temp);
-
-        e->m_emit_type = et_byte;
-    }
-    else
-    {
-        if (get_identifier (&t, &temp))
-        {
-            emit_destroy (&e);
-            return 1;
-        }
-
-        if (map_byte_find (&mapb, temp, &e->m_byte))
-        {
-            mem_free ((void **) (void *) &temp);
-            emit_destroy (&e);
-            return 1;
-        }
-
-        mem_free ((void **) (void *) &temp);
-
-        e->m_emit_type = et_byte;
-    }
-
-    eat_spaces (&t);
-
-    if (get_emits (&t, &e->m_next, mapb))
-    {
-        emit_destroy (&e);
-        return 1;
-    }
-
-    *text = t;
-    *em = e;
-    return 0;
-}
-
-/*
-    returns 0 on success,
-    returns 1 otherwise,
-*/
-static int get_spec (const byte **text, spec **sp, map_str *maps, map_byte *mapb)
-{
-    const byte *t = *text;
-    spec *s = NULL;
-
-    spec_create (&s);
-    if (s == NULL)
-        return 1;
-
-    /* first - read optional .if statement */
-    if (*t == '.')
-    {
-        const byte *u = t;
-        byte *keyword = NULL;
-
-        /* skip the dot */
-        u++;
-
-        if (get_identifier (&u, &keyword))
-        {
-            spec_destroy (&s);
-            return 1;
-        }
-
-        /* .if */
-        if (str_equal ((byte *) "if", keyword))
-        {
-            cond_create (&s->m_cond);
-            if (s->m_cond == NULL)
-            {
-                spec_destroy (&s);
-                return 1;
-            }
-
-            /* skip the left paren */
-            eat_spaces (&u);
-            u++;
-
-            /* get the left operand */
-            eat_spaces (&u);
-            if (get_identifier (&u, &s->m_cond->m_operands[0].m_regname))
-            {
-                spec_destroy (&s);
-                return 1;
-            }
-            s->m_cond->m_operands[0].m_type = cot_regbyte;
-
-            /* get the operator (!= or ==) */
-            eat_spaces (&u);
-            if (*u == '!')
-                s->m_cond->m_type = ct_not_equal;
-            else
-                s->m_cond->m_type = ct_equal;
-            u += 2;
-            eat_spaces (&u);
-
-            if (u[0] == '0' && (u[1] == 'x' || u[1] == 'X'))
-            {
-                /* skip the 0x prefix */
-                u += 2;
-
-                /* get the right operand */
-                s->m_cond->m_operands[1].m_byte = hex_convert (&u);
-                s->m_cond->m_operands[1].m_type = cot_byte;
-            }
-            else /*if (*u >= '0' && *u <= '9')*/
-            {
-                /* get the right operand */
-                s->m_cond->m_operands[1].m_byte = dec_convert (&u);
-                s->m_cond->m_operands[1].m_type = cot_byte;
-            }
-
-            /* skip the right paren */
-            eat_spaces (&u);
-            u++;
-
-            eat_spaces (&u);
-
-            t = u;
-        }
-
-        mem_free ((void **) (void *) &keyword);
-    }
-
-    if (*t == '\'')
-    {
-        byte *temp = NULL;
-
-        if (get_string (&t, &temp))
-        {
-            spec_destroy (&s);
-            return 1;
-        }
-        eat_spaces (&t);
-
-        if (*t == '-')
-        {
-            byte *temp2 = NULL;
-
-            /* skip the '-' character */
-            t++;
-            eat_spaces (&t);
-
-            if (get_string (&t, &temp2))
-            {
-                mem_free ((void **) (void *) &temp);
-                spec_destroy (&s);
-                return 1;
-            }
-            eat_spaces (&t);
-
-            s->m_spec_type = st_byte_range;
-            s->m_byte[0] = *temp;
-            s->m_byte[1] = *temp2;
-
-            mem_free ((void **) (void *) &temp2);
-        }
-        else
-        {
-            s->m_spec_type = st_byte;
-            *s->m_byte = *temp;
-        }
-
-        mem_free ((void **) (void *) &temp);
-    }
-    else if (*t == '"')
-    {
-        if (get_string (&t, &s->m_string))
-        {
-            spec_destroy (&s);
-            return 1;
-        }
-        eat_spaces (&t);
-
-        s->m_spec_type = st_string;
-    }
-    else if (*t == '.')
-    {
-        byte *keyword = NULL;
-
-        /* skip the dot */
-        t++;
-
-        if (get_identifier (&t, &keyword))
-        {
-            spec_destroy (&s);
-            return 1;
-        }
-        eat_spaces (&t);
-
-        /* .true */
-        if (str_equal ((byte *) "true", keyword))
-        {
-            s->m_spec_type = st_true;
-        }
-        /* .false */
-        else if (str_equal ((byte *) "false", keyword))
-        {
-            s->m_spec_type = st_false;
-        }
-        /* .debug */
-        else if (str_equal ((byte *) "debug", keyword))
-        {
-            s->m_spec_type = st_debug;
-        }
-        /* .loop */
-        else if (str_equal ((byte *) "loop", keyword))
-        {
-            if (get_identifier (&t, &s->m_string))
-            {
-                mem_free ((void **) (void *) &keyword);
-                spec_destroy (&s);
-                return 1;
-            }
-            eat_spaces (&t);
-
-            s->m_spec_type = st_identifier_loop;
-        }
-        mem_free ((void **) (void *) &keyword);
-    }
-    else
-    {
-        if (get_identifier (&t, &s->m_string))
-        {
-            spec_destroy (&s);
-            return 1;
-        }
-        eat_spaces (&t);
-
-        s->m_spec_type = st_identifier;
-    }
-
-    if (get_error (&t, &s->m_errtext, maps))
-    {
-        spec_destroy (&s);
-        return 1;
-    }
-
-    if (get_emits (&t, &s->m_emits, mapb))
-    {
-        spec_destroy (&s);
-        return 1;
-    }
-
-    *text = t;
-    *sp = s;
-    return 0;
-}
-
-/*
-    returns 0 on success,
-    returns 1 otherwise,
-*/
-static int get_rule (const byte **text, rule **ru, map_str *maps, map_byte *mapb)
-{
-    const byte *t = *text;
-    rule *r = NULL;
-
-    rule_create (&r);
-    if (r == NULL)
-        return 1;
-
-    if (get_spec (&t, &r->m_specs, maps, mapb))
-    {
-        rule_destroy (&r);
-        return 1;
-    }
-
-    while (*t != ';')
-    {
-        byte *op = NULL;
-        spec *sp = NULL;
-
-        /* skip the dot that precedes "and" or "or" */
-        t++;
-
-        /* read "and" or "or" keyword */
-        if (get_identifier (&t, &op))
-        {
-            rule_destroy (&r);
-            return 1;
-        }
-        eat_spaces (&t);
-
-        if (r->m_oper == op_none)
-        {
-            /* .and */
-            if (str_equal ((byte *) "and", op))
-                r->m_oper = op_and;
-            /* .or */
-            else
-                r->m_oper = op_or;
-        }
-
-        mem_free ((void **) (void *) &op);
-
-        if (get_spec (&t, &sp, maps, mapb))
-        {
-            rule_destroy (&r);
-            return 1;
-        }
-
-        spec_append (&r->m_specs, sp);
-    }
-
-    /* skip the semicolon */
-    t++;
-    eat_spaces (&t);
-
-    *text = t;
-    *ru = r;
-    return 0;
-}
-
-/*
-    returns 0 on success,
-    returns 1 otherwise,
-*/
-static int update_dependency (map_rule *mapr, byte *symbol, rule **ru)
-{
-    if (map_rule_find (&mapr, symbol, ru))
-        return 1;
-
-    (**ru).m_referenced = 1;
-
-    return 0;
-}
-
-/*
-    returns 0 on success,
-    returns 1 otherwise,
-*/
-static int update_dependencies (dict *di, map_rule *mapr, byte **syntax_symbol,
-    byte **string_symbol, map_byte *regbytes)
-{
-    rule *rulez = di->m_rulez;
-
-    /* update dependecies for the root and lexer symbols */
-    if (update_dependency (mapr, *syntax_symbol, &di->m_syntax) ||
-        (*string_symbol != NULL && update_dependency (mapr, *string_symbol, &di->m_string)))
-        return 1;
-
-    mem_free ((void **) syntax_symbol);
-    mem_free ((void **) string_symbol);
-
-    /* update dependecies for the rest of the rules */
-    while (rulez)
-    {
-        spec *sp = rulez->m_specs;
-
-        /* iterate through all the specifiers */
-        while (sp)
-        {
-            /* update dependency for identifier */
-            if (sp->m_spec_type == st_identifier || sp->m_spec_type == st_identifier_loop)
-            {
-                if (update_dependency (mapr, sp->m_string, &sp->m_rule))
-                    return 1;
-
-                mem_free ((void **) &sp->m_string);
-            }
-
-            /* some errtexts reference to a rule */
-            if (sp->m_errtext && sp->m_errtext->m_token_name)
-            {
-                if (update_dependency (mapr, sp->m_errtext->m_token_name, &sp->m_errtext->m_token))
-                    return 1;
-
-                mem_free ((void **) &sp->m_errtext->m_token_name);
-            }
-
-            /* update dependency for condition */
-            if (sp->m_cond)
-            {
-                int i;
-                for (i = 0; i < 2; i++)
-                    if (sp->m_cond->m_operands[i].m_type == cot_regbyte)
-                    {
-                        sp->m_cond->m_operands[i].m_regbyte = map_byte_locate (&regbytes,
-                            sp->m_cond->m_operands[i].m_regname);
-
-                        if (sp->m_cond->m_operands[i].m_regbyte == NULL)
-                            return 1;
-
-                        mem_free ((void **) &sp->m_cond->m_operands[i].m_regname);
-                    }
-            }
-
-            /* update dependency for all .load instructions */
-            if (sp->m_emits)
-            {
-                emit *em = sp->m_emits;
-                while (em != NULL)
-                {
-                    if (em->m_emit_dest == ed_regbyte)
-                    {
-                        em->m_regbyte = map_byte_locate (&regbytes, em->m_regname);
-
-                        if (em->m_regbyte == NULL)
-                            return 1;
-
-                        mem_free ((void **) &em->m_regname);
-                    }
-
-                    em = em->m_next;
-                }
-            }
-
-            sp = sp->next;
-        }
-
-        rulez = rulez->next;
-    }
-
-    /* check for unreferenced symbols */
-    rulez = di->m_rulez;
-    while (rulez != NULL)
-    {
-        if (!rulez->m_referenced)
-        {
-            map_rule *ma = mapr;
-            while (ma)
-            {
-                if (ma->data == rulez)
-                {
-                    set_last_error (UNREFERENCED_IDENTIFIER, str_duplicate (ma->key), -1);
-                    return 1;
-                }
-                ma = ma->next;
-            }
-        }
-        rulez = rulez->next;
-    }
-
-    return 0;
-}
-
-static int satisfies_condition (cond *co, regbyte_ctx *ctx)
-{
-    byte values[2];
-    int i;
-
-    if (co == NULL)
-        return 1;
-
-    for (i = 0; i < 2; i++)
-        switch (co->m_operands[i].m_type)
-        {
-        case cot_byte:
-            values[i] = co->m_operands[i].m_byte;
-            break;
-        case cot_regbyte:
-            values[i] = regbyte_ctx_extract (&ctx, co->m_operands[i].m_regbyte);
-            break;
-        }
-
-    switch (co->m_type)
-    {
-    case ct_equal:
-        return values[0] == values[1];
-    case ct_not_equal:
-        return values[0] != values[1];
-    }
-
-    return 0;
-}
-
-static void free_regbyte_ctx_stack (regbyte_ctx *top, regbyte_ctx *limit)
-{
-    while (top != limit)
-    {
-        regbyte_ctx *rbc = top->m_prev;
-        regbyte_ctx_destroy (&top);
-        top = rbc;
-    }
-}
-
-typedef enum match_result_
-{
-    mr_not_matched,     /* the examined string does not match */
-    mr_matched,         /* the examined string matches */
-    mr_error_raised,    /* mr_not_matched + error has been raised */
-    mr_dont_emit,       /* used by identifier loops only */
-    mr_internal_error   /* an internal error has occured such as out of memory */
-} match_result;
-
-/*
- * This function does the main job. It parses the text and generates output data.
- */
-static match_result
-match (dict *di, const byte *text, int *index, rule *ru, barray **ba, int filtering_string,
-       regbyte_ctx **rbc)
-{
-   int ind = *index;
-    match_result status = mr_not_matched;
-    spec *sp = ru->m_specs;
-    regbyte_ctx *ctx = *rbc;
-
-    /* for every specifier in the rule */
-    while (sp)
-    {
-      int i, len, save_ind = ind;
-        barray *array = NULL;
-
-        if (satisfies_condition (sp->m_cond, ctx))
-        {
-            switch (sp->m_spec_type)
-            {
-            case st_identifier:
-                barray_create (&array);
-                if (array == NULL)
-                {
-                    free_regbyte_ctx_stack (ctx, *rbc);
-                    return mr_internal_error;
-                }
-
-                status = match (di, text, &ind, sp->m_rule, &array, filtering_string, &ctx);
-
-                if (status == mr_internal_error)
-                {
-                    free_regbyte_ctx_stack (ctx, *rbc);
-                    barray_destroy (&array);
-                    return mr_internal_error;
-                }
-                break;
-            case st_string:
-                len = str_length (sp->m_string);
-
-                /* prefilter the stream */
-                if (!filtering_string && di->m_string)
-                {
-                    barray *ba;
-               int filter_index = 0;
-                    match_result result;
-                    regbyte_ctx *null_ctx = NULL;
-
-                    barray_create (&ba);
-                    if (ba == NULL)
-                    {
-                        free_regbyte_ctx_stack (ctx, *rbc);
-                        return mr_internal_error;
-                    }
-
-                    result = match (di, text + ind, &filter_index, di->m_string, &ba, 1, &null_ctx);
-
-                    if (result == mr_internal_error)
-                    {
-                        free_regbyte_ctx_stack (ctx, *rbc);
-                        barray_destroy (&ba);
-                        return mr_internal_error;
-                    }
-
-                    if (result != mr_matched)
-                    {
-                        barray_destroy (&ba);
-                        status = mr_not_matched;
-                        break;
-                    }
-
-                    barray_destroy (&ba);
-
-                    if (filter_index != len || !str_equal_n (sp->m_string, text + ind, len))
-                    {
-                        status = mr_not_matched;
-                        break;
-                    }
-
-                    status = mr_matched;
-                    ind += len;
-                }
-                else
-                {
-                    status = mr_matched;
-                    for (i = 0; status == mr_matched && i < len; i++)
-                        if (text[ind + i] != sp->m_string[i])
-                            status = mr_not_matched;
-
-                    if (status == mr_matched)
-                        ind += len;
-                }
-                break;
-            case st_byte:
-                status = text[ind] == *sp->m_byte ? mr_matched : mr_not_matched;
-                if (status == mr_matched)
-                    ind++;
-                break;
-            case st_byte_range:
-                status = (text[ind] >= sp->m_byte[0] && text[ind] <= sp->m_byte[1]) ?
-                    mr_matched : mr_not_matched;
-                if (status == mr_matched)
-                    ind++;
-                break;
-            case st_true:
-                status = mr_matched;
-                break;
-            case st_false:
-                status = mr_not_matched;
-                break;
-            case st_debug:
-                status = ru->m_oper == op_and ? mr_matched : mr_not_matched;
-                break;
-            case st_identifier_loop:
-                barray_create (&array);
-                if (array == NULL)
-                {
-                    free_regbyte_ctx_stack (ctx, *rbc);
-                    return mr_internal_error;
-                }
-
-                status = mr_dont_emit;
-                for (;;)
-                {
-                    match_result result;
-
-                    save_ind = ind;
-                    result = match (di, text, &ind, sp->m_rule, &array, filtering_string, &ctx);
-
-                    if (result == mr_error_raised)
-                    {
-                        status = result;
-                        break;
-                    }
-                    else if (result == mr_matched)
-                    {
-                        if (barray_push (ba, sp->m_emits, text[ind - 1], save_ind, &ctx) ||
-                            barray_append (ba, &array))
-                        {
-                            free_regbyte_ctx_stack (ctx, *rbc);
-                            barray_destroy (&array);
-                            return mr_internal_error;
-                        }
-                        barray_destroy (&array);
-                        barray_create (&array);
-                        if (array == NULL)
-                        {
-                            free_regbyte_ctx_stack (ctx, *rbc);
-                            return mr_internal_error;
-                        }
-                    }
-                    else if (result == mr_internal_error)
-                    {
-                        free_regbyte_ctx_stack (ctx, *rbc);
-                        barray_destroy (&array);
-                        return mr_internal_error;
-                    }
-                    else
-                        break;
-                }
-                break;
-            }
-        }
-        else
-        {
-            status = mr_not_matched;
-        }
-
-        if (status == mr_error_raised)
-        {
-            free_regbyte_ctx_stack (ctx, *rbc);
-            barray_destroy (&array);
-
-            return mr_error_raised;
-        }
-
-        if (ru->m_oper == op_and && status != mr_matched && status != mr_dont_emit)
-        {
-            free_regbyte_ctx_stack (ctx, *rbc);
-            barray_destroy (&array);
-
-            if (sp->m_errtext)
-            {
-                set_last_error (sp->m_errtext->m_text, error_get_token (sp->m_errtext, di, text,
-                    ind), ind);
-
-                return mr_error_raised;
-            }
-
-            return mr_not_matched;
-        }
-
-        if (status == mr_matched)
-        {
-            if (sp->m_emits)
-                if (barray_push (ba, sp->m_emits, text[ind - 1], save_ind, &ctx))
-                {
-                    free_regbyte_ctx_stack (ctx, *rbc);
-                    barray_destroy (&array);
-                    return mr_internal_error;
-                }
-
-            if (array)
-                if (barray_append (ba, &array))
-                {
-                    free_regbyte_ctx_stack (ctx, *rbc);
-                    barray_destroy (&array);
-                    return mr_internal_error;
-                }
-        }
-
-        barray_destroy (&array);
-
-        /* if the rule operator is a logical or, we pick up the first matching specifier */
-        if (ru->m_oper == op_or && (status == mr_matched || status == mr_dont_emit))
-        {
-            *index = ind;
-            *rbc = ctx;
-            return mr_matched;
-        }
-
-        sp = sp->next;
-    }
-
-    /* everything went fine - all specifiers match up */
-    if (ru->m_oper == op_and && (status == mr_matched || status == mr_dont_emit))
-    {
-        *index = ind;
-        *rbc = ctx;
-        return mr_matched;
-    }
-
-    free_regbyte_ctx_stack (ctx, *rbc);
-    return mr_not_matched;
-}
-
-static match_result
-fast_match (dict *di, const byte *text, int *index, rule *ru, int *_PP, bytepool *_BP,
-            int filtering_string, regbyte_ctx **rbc)
-{
-   int ind = *index;
-    int _P = filtering_string ? 0 : *_PP;
-    int _P2;
-    match_result status = mr_not_matched;
-    spec *sp = ru->m_specs;
-    regbyte_ctx *ctx = *rbc;
-
-    /* for every specifier in the rule */
-    while (sp)
-    {
-      int i, len, save_ind = ind;
-
-        _P2 = _P + (sp->m_emits ? emit_size (sp->m_emits) : 0);
-        if (bytepool_reserve (_BP, _P2))
-        {
-            free_regbyte_ctx_stack (ctx, *rbc);
-            return mr_internal_error;
-        }
-
-        if (satisfies_condition (sp->m_cond, ctx))
-        {
-            switch (sp->m_spec_type)
-            {
-            case st_identifier:
-                status = fast_match (di, text, &ind, sp->m_rule, &_P2, _BP, filtering_string, &ctx);
-
-                if (status == mr_internal_error)
-                {
-                    free_regbyte_ctx_stack (ctx, *rbc);
-                    return mr_internal_error;
-                }
-                break;
-            case st_string:
-                len = str_length (sp->m_string);
-
-                /* prefilter the stream */
-                if (!filtering_string && di->m_string)
-                {
-               int filter_index = 0;
-                    match_result result;
-                    regbyte_ctx *null_ctx = NULL;
-
-                    result = fast_match (di, text + ind, &filter_index, di->m_string, NULL, _BP, 1, &null_ctx);
-
-                    if (result == mr_internal_error)
-                    {
-                        free_regbyte_ctx_stack (ctx, *rbc);
-                        return mr_internal_error;
-                    }
-
-                    if (result != mr_matched)
-                    {
-                        status = mr_not_matched;
-                        break;
-                    }
-
-                    if (filter_index != len || !str_equal_n (sp->m_string, text + ind, len))
-                    {
-                        status = mr_not_matched;
-                        break;
-                    }
-
-                    status = mr_matched;
-                    ind += len;
-                }
-                else
-                {
-                    status = mr_matched;
-                    for (i = 0; status == mr_matched && i < len; i++)
-                        if (text[ind + i] != sp->m_string[i])
-                            status = mr_not_matched;
-
-                    if (status == mr_matched)
-                        ind += len;
-                }
-                break;
-            case st_byte:
-                status = text[ind] == *sp->m_byte ? mr_matched : mr_not_matched;
-                if (status == mr_matched)
-                    ind++;
-                break;
-            case st_byte_range:
-                status = (text[ind] >= sp->m_byte[0] && text[ind] <= sp->m_byte[1]) ?
-                    mr_matched : mr_not_matched;
-                if (status == mr_matched)
-                    ind++;
-                break;
-            case st_true:
-                status = mr_matched;
-                break;
-            case st_false:
-                status = mr_not_matched;
-                break;
-            case st_debug:
-                status = ru->m_oper == op_and ? mr_matched : mr_not_matched;
-                break;
-            case st_identifier_loop:
-                status = mr_dont_emit;
-                for (;;)
-                {
-                    match_result result;
-
-                    save_ind = ind;
-                    result = fast_match (di, text, &ind, sp->m_rule, &_P2, _BP, filtering_string, &ctx);
-
-                    if (result == mr_error_raised)
-                    {
-                        status = result;
-                        break;
-                    }
-                    else if (result == mr_matched)
-                    {
-                        if (!filtering_string)
-                        {
-                            if (sp->m_emits != NULL)
-                            {
-                                if (emit_push (sp->m_emits, _BP->_F + _P, text[ind - 1], save_ind, &ctx))
-                                {
-                                    free_regbyte_ctx_stack (ctx, *rbc);
-                                    return mr_internal_error;
-                                }
-                            }
-
-                            _P = _P2;
-                            _P2 += sp->m_emits ? emit_size (sp->m_emits) : 0;
-                            if (bytepool_reserve (_BP, _P2))
-                            {
-                                free_regbyte_ctx_stack (ctx, *rbc);
-                                return mr_internal_error;
-                            }
-                        }
-                    }
-                    else if (result == mr_internal_error)
-                    {
-                        free_regbyte_ctx_stack (ctx, *rbc);
-                        return mr_internal_error;
-                    }
-                    else
-                        break;
-                }
-                break;
-            }
-        }
-        else
-        {
-            status = mr_not_matched;
-        }
-
-        if (status == mr_error_raised)
-        {
-            free_regbyte_ctx_stack (ctx, *rbc);
-
-            return mr_error_raised;
-        }
-
-        if (ru->m_oper == op_and && status != mr_matched && status != mr_dont_emit)
-        {
-            free_regbyte_ctx_stack (ctx, *rbc);
-
-            if (sp->m_errtext)
-            {
-                set_last_error (sp->m_errtext->m_text, error_get_token (sp->m_errtext, di, text,
-                    ind), ind);
-
-                return mr_error_raised;
-            }
-
-            return mr_not_matched;
-        }
-
-        if (status == mr_matched)
-        {
-            if (sp->m_emits != NULL) {
-                const byte ch = (ind <= 0) ? 0 : text[ind - 1];
-                if (emit_push (sp->m_emits, _BP->_F + _P, ch, save_ind, &ctx))
-                {
-                    free_regbyte_ctx_stack (ctx, *rbc);
-                    return mr_internal_error;
-                }
-
-           }
-           _P = _P2;
-        }
-
-        /* if the rule operator is a logical or, we pick up the first matching specifier */
-        if (ru->m_oper == op_or && (status == mr_matched || status == mr_dont_emit))
-        {
-            *index = ind;
-            *rbc = ctx;
-            if (!filtering_string)
-                *_PP = _P;
-            return mr_matched;
-        }
-
-        sp = sp->next;
-    }
-
-    /* everything went fine - all specifiers match up */
-    if (ru->m_oper == op_and && (status == mr_matched || status == mr_dont_emit))
-    {
-        *index = ind;
-        *rbc = ctx;
-        if (!filtering_string)
-            *_PP = _P;
-        return mr_matched;
-    }
-
-    free_regbyte_ctx_stack (ctx, *rbc);
-    return mr_not_matched;
-}
-
-static byte *
-error_get_token (error *er, dict *di, const byte *text, int ind)
-{
-    byte *str = NULL;
-
-    if (er->m_token)
-    {
-        barray *ba;
-      int filter_index = 0;
-        regbyte_ctx *ctx = NULL;
-
-        barray_create (&ba);
-        if (ba != NULL)
-        {
-            if (match (di, text + ind, &filter_index, er->m_token, &ba, 0, &ctx) == mr_matched &&
-                filter_index)
-            {
-                str = (byte *) mem_alloc (filter_index + 1);
-                if (str != NULL)
-                {
-                    str_copy_n (str, text + ind, filter_index);
-                    str[filter_index] = '\0';
-                }
-            }
-            barray_destroy (&ba);
-        }
-    }
-
-    return str;
-}
-
-typedef struct grammar_load_state_
-{
-    dict *di;
-    byte *syntax_symbol;
-    byte *string_symbol;
-    map_str *maps;
-    map_byte *mapb;
-    map_rule *mapr;
-} grammar_load_state;
-
-static void grammar_load_state_create (grammar_load_state **gr)
-{
-    *gr = (grammar_load_state *) mem_alloc (sizeof (grammar_load_state));
-    if (*gr)
-    {
-        (**gr).di = NULL;
-        (**gr).syntax_symbol = NULL;
-        (**gr).string_symbol = NULL;
-        (**gr).maps = NULL;
-        (**gr).mapb = NULL;
-        (**gr).mapr = NULL;
-    }
-}
-
-static void grammar_load_state_destroy (grammar_load_state **gr)
-{
-    if (*gr)
-    {
-        dict_destroy (&(**gr).di);
-        mem_free ((void **) &(**gr).syntax_symbol);
-        mem_free ((void **) &(**gr).string_symbol);
-        map_str_destroy (&(**gr).maps);
-        map_byte_destroy (&(**gr).mapb);
-        map_rule_destroy (&(**gr).mapr);
-        mem_free ((void **) gr);
-    }
-}
-
-
-static void error_msg(int line, const char *msg)
-{
-   fprintf(stderr, "Error in grammar_load_from_text() at line %d: %s\n", line, msg);
-}
-
-
-/*
-    the API
-*/
-grammar grammar_load_from_text (const byte *text)
-{
-    grammar_load_state *g = NULL;
-    grammar id = 0;
-
-    clear_last_error ();
-
-    grammar_load_state_create (&g);
-    if (g == NULL) {
-        error_msg(__LINE__, "");
-        return 0;
-    }
-
-    dict_create (&g->di);
-    if (g->di == NULL)
-    {
-        grammar_load_state_destroy (&g);
-        error_msg(__LINE__, "");
-        return 0;
-    }
-
-    eat_spaces (&text);
-
-    /* skip ".syntax" keyword */
-    text += 7;
-    eat_spaces (&text);
-
-    /* retrieve root symbol */
-    if (get_identifier (&text, &g->syntax_symbol))
-    {
-        grammar_load_state_destroy (&g);
-        error_msg(__LINE__, "");
-        return 0;
-    }
-    eat_spaces (&text);
-
-    /* skip semicolon */
-    text++;
-    eat_spaces (&text);
-
-    while (*text)
-    {
-        byte *symbol = NULL;
-        int is_dot = *text == '.';
-
-        if (is_dot)
-            text++;
-
-        if (get_identifier (&text, &symbol))
-        {
-            grammar_load_state_destroy (&g);
-            error_msg(__LINE__, "");
-            return 0;
-        }
-        eat_spaces (&text);
-
-        /* .emtcode */
-        if (is_dot && str_equal (symbol, (byte *) "emtcode"))
-        {
-            map_byte *ma = NULL;
-
-            mem_free ((void **) (void *) &symbol);
-
-            if (get_emtcode (&text, &ma))
-            {
-                grammar_load_state_destroy (&g);
-                error_msg(__LINE__, "");
-                return 0;
-            }
-
-            map_byte_append (&g->mapb, ma);
-        }
-        /* .regbyte */
-        else if (is_dot && str_equal (symbol, (byte *) "regbyte"))
-        {
-            map_byte *ma = NULL;
-
-            mem_free ((void **) (void *) &symbol);
-
-            if (get_regbyte (&text, &ma))
-            {
-                grammar_load_state_destroy (&g);
-                error_msg(__LINE__, "");
-                return 0;
-            }
-
-            map_byte_append (&g->di->m_regbytes, ma);
-        }
-        /* .errtext */
-        else if (is_dot && str_equal (symbol, (byte *) "errtext"))
-        {
-            map_str *ma = NULL;
-
-            mem_free ((void **) (void *) &symbol);
-
-            if (get_errtext (&text, &ma))
-            {
-                grammar_load_state_destroy (&g);
-                error_msg(__LINE__, "");
-                return 0;
-            }
-
-            map_str_append (&g->maps, ma);
-        }
-        /* .string */
-        else if (is_dot && str_equal (symbol, (byte *) "string"))
-        {
-            mem_free ((void **) (void *) &symbol);
-
-            if (g->di->m_string != NULL)
-            {
-                grammar_load_state_destroy (&g);
-                error_msg(__LINE__, "");
-                return 0;
-            }
-
-            if (get_identifier (&text, &g->string_symbol))
-            {
-                grammar_load_state_destroy (&g);
-                error_msg(__LINE__, "");
-                return 0;
-            }
-
-            /* skip semicolon */
-            eat_spaces (&text);
-            text++;
-            eat_spaces (&text);
-        }
-        else
-        {
-            rule *ru = NULL;
-            map_rule *ma = NULL;
-
-            if (get_rule (&text, &ru, g->maps, g->mapb))
-            {
-                grammar_load_state_destroy (&g);
-                error_msg(__LINE__, "");
-                return 0;
-            }
-
-            rule_append (&g->di->m_rulez, ru);
-
-            /* if a rule consist of only one specifier, give it an ".and" operator */
-            if (ru->m_oper == op_none)
-                ru->m_oper = op_and;
-
-            map_rule_create (&ma);
-            if (ma == NULL)
-            {
-                grammar_load_state_destroy (&g);
-                error_msg(__LINE__, "");
-                return 0;
-            }
-
-            ma->key = symbol;
-            ma->data = ru;
-            map_rule_append (&g->mapr, ma);
-        }
-    }
-
-    if (update_dependencies (g->di, g->mapr, &g->syntax_symbol, &g->string_symbol,
-        g->di->m_regbytes))
-    {
-        grammar_load_state_destroy (&g);
-        error_msg(__LINE__, "update_dependencies() failed");
-        return 0;
-    }
-
-    dict_append (&g_dicts, g->di);
-    id = g->di->m_id;
-    g->di = NULL;
-
-    grammar_load_state_destroy (&g);
-
-    return id;
-}
-
-int grammar_set_reg8 (grammar id, const byte *name, byte value)
-{
-    dict *di = NULL;
-    map_byte *reg = NULL;
-
-    clear_last_error ();
-
-    dict_find (&g_dicts, id, &di);
-    if (di == NULL)
-    {
-        set_last_error (INVALID_GRAMMAR_ID, NULL, -1);
-        return 0;
-    }
-
-    reg = map_byte_locate (&di->m_regbytes, name);
-    if (reg == NULL)
-    {
-        set_last_error (INVALID_REGISTER_NAME, str_duplicate (name), -1);
-        return 0;
-    }
-
-    reg->data = value;
-    return 1;
-}
-
-/*
-    internal checking function used by both grammar_check and grammar_fast_check functions
-*/
-static int _grammar_check (grammar id, const byte *text, byte **prod, unsigned int *size,
-    unsigned int estimate_prod_size, int use_fast_path)
-{
-    dict *di = NULL;
-   int index = 0;
-
-    clear_last_error ();
-
-    dict_find (&g_dicts, id, &di);
-    if (di == NULL)
-    {
-        set_last_error (INVALID_GRAMMAR_ID, NULL, -1);
-        return 0;
-    }
-
-    *prod = NULL;
-    *size = 0;
-
-    if (use_fast_path)
-    {
-        regbyte_ctx *rbc = NULL;
-        bytepool *bp = NULL;
-        int _P = 0;
-
-        bytepool_create (&bp, estimate_prod_size);
-        if (bp == NULL)
-            return 0;
-
-        if (fast_match (di, text, &index, di->m_syntax, &_P, bp, 0, &rbc) != mr_matched)
-        {
-            bytepool_destroy (&bp);
-            free_regbyte_ctx_stack (rbc, NULL);
-            return 0;
-        }
-
-        free_regbyte_ctx_stack (rbc, NULL);
-
-        *prod = bp->_F;
-        *size = _P;
-        bp->_F = NULL;
-        bytepool_destroy (&bp);
-    }
-    else
-    {
-        regbyte_ctx *rbc = NULL;
-        barray *ba = NULL;
-
-        barray_create (&ba);
-        if (ba == NULL)
-            return 0;
-
-        if (match (di, text, &index, di->m_syntax, &ba, 0, &rbc) != mr_matched)
-        {
-            barray_destroy (&ba);
-            free_regbyte_ctx_stack (rbc, NULL);
-            return 0;
-        }
-
-        free_regbyte_ctx_stack (rbc, NULL);
-
-        *prod = (byte *) mem_alloc (ba->len * sizeof (byte));
-        if (*prod == NULL)
-        {
-            barray_destroy (&ba);
-            return 0;
-        }
-
-        mem_copy (*prod, ba->data, ba->len * sizeof (byte));
-        *size = ba->len;
-        barray_destroy (&ba);
-    }
-
-    return 1;
-}
-
-int grammar_check (grammar id, const byte *text, byte **prod, unsigned int *size)
-{
-    return _grammar_check (id, text, prod, size, 0, 0);
-}
-
-int grammar_fast_check (grammar id, const byte *text, byte **prod, unsigned int *size,
-    unsigned int estimate_prod_size)
-{
-    return _grammar_check (id, text, prod, size, estimate_prod_size, 1);
-}
-
-int grammar_destroy (grammar id)
-{
-    dict **di = &g_dicts;
-
-    clear_last_error ();
-
-    while (*di != NULL)
-    {
-        if ((**di).m_id == id)
-        {
-            dict *tmp = *di;
-            *di = (**di).next;
-            dict_destroy (&tmp);
-            return 1;
-        }
-
-        di = &(**di).next;
-    }
-
-    set_last_error (INVALID_GRAMMAR_ID, NULL, -1);
-    return 0;
-}
-
-static void append_character (const char x, byte *text, int *dots_made, int *len, int size)
-{
-    if (*dots_made == 0)
-    {
-        if (*len < size - 1)
-        {
-            text[(*len)++] = x;
-            text[*len] = '\0';
-        }
-        else
-        {
-            int i;
-            for (i = 0; i < 3; i++)
-                if (--(*len) >= 0)
-                    text[*len] = '.';
-            *dots_made = 1;
-        }
-    }
-}
-
-void grammar_get_last_error (byte *text, unsigned int size, int *pos)
-{
-    int len = 0, dots_made = 0;
-    const byte *p = error_message;
-
-    *text = '\0';
-
-    if (p)
-    {
-        while (*p)
-        {
-            if (*p == '$')
-            {
-                const byte *r = error_param;
-
-                while (*r)
-                {
-                    append_character (*r++, text, &dots_made, &len, (int) size);
-                }
-
-                p++;
-            }
-            else
-            {
-                append_character (*p++, text, &dots_made, &len, size);
-            }
-        }
-    }
-
-    *pos = error_position;
-}
diff --git a/src/mesa/shader/grammar/grammar.h b/src/mesa/shader/grammar/grammar.h
deleted file mode 100644
index 591e38a..0000000
--- a/src/mesa/shader/grammar/grammar.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.2
- *
- * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL 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.
- */
-
-#ifndef GRAMMAR_H
-#define GRAMMAR_H
-
-
-#ifndef GRAMMAR_PORT_INCLUDE
-#error Do not include this file directly, include your grammar_XXX.h instead
-#endif
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void grammar_alloc_free (void *);
-void *grammar_alloc_malloc (size_t);
-void *grammar_alloc_realloc (void *, size_t, size_t);
-void *grammar_memory_copy (void *, const void *, size_t);
-int grammar_string_compare (const byte *, const byte *);
-int grammar_string_compare_n (const byte *, const byte *, size_t);
-byte *grammar_string_copy (byte *, const byte *);
-byte *grammar_string_copy_n (byte *, const byte *, size_t);
-byte *grammar_string_duplicate (const byte *);
-unsigned int grammar_string_length (const byte *);
-
-/*
-    loads grammar script from null-terminated ASCII <text>
-    returns unique grammar id to grammar object
-    returns 0 if an error occurs (call grammar_get_last_error to retrieve the error text)
-*/
-grammar grammar_load_from_text (const byte *text);
-
-/*
-    sets a new <value> to a register <name> for grammar <id>
-    returns 0 on error (call grammar_get_last_error to retrieve the error text)
-    returns 1 on success
-*/
-int grammar_set_reg8 (grammar id, const byte *name, byte value);
-
-/*
-    this function is obsolete, use only for debugging purposes
-
-    checks if a null-terminated <text> matches given grammar <id>
-    returns 0 on error (call grammar_get_last_error to retrieve the error text)
-    returns 1 on success, the <prod> points to newly allocated buffer with production and <size>
-    is filled with the production size
-    call grammar_alloc_free to free the memory block pointed by <prod>
-*/
-int grammar_check (grammar id, const byte *text, byte **prod, unsigned int *size);
-
-/*
-    does the same what grammar_check does but much more (approx. 4 times) faster
-    use this function instead of grammar_check
-    <estimate_prod_size> is a hint - the initial production buffer size will be of this size,
-    but if more room is needed it will be safely resized; set it to 0x1000 or so
-*/
-int grammar_fast_check (grammar id, const byte *text, byte **prod, unsigned int *size,
-    unsigned int estimate_prod_size);
-
-/*
-    destroys grammar object identified by <id>
-    returns 0 on error (call grammar_get_last_error to retrieve the error text)
-    returns 1 on success
-*/
-int grammar_destroy (grammar id);
-
-/*
-    retrieves last grammar error reported either by grammar_load_from_text, grammar_check
-    or grammar_destroy
-    the user allocated <text> buffer receives error description, <pos> points to error position,
-    <size> is the size of the text buffer to fill in - it must be at least 4 bytes long,
-*/
-void grammar_get_last_error (byte *text, unsigned int size, int *pos);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/src/mesa/shader/grammar/grammar.syn b/src/mesa/shader/grammar/grammar.syn
deleted file mode 100644
index 5d99f65..0000000
--- a/src/mesa/shader/grammar/grammar.syn
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.2
- *
- * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL 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 grammar.syn
- * syntax of .syn script - used to validate other syntax files
- * \author Michal Krol
- */
- 
-.syntax grammar;
-
-/* declaration */
-.emtcode DECLARATION_END                            0
-.emtcode DECLARATION_EMITCODE                       1
-.emtcode DECLARATION_ERRORTEXT                      2
-.emtcode DECLARATION_REGBYTE                        3
-.emtcode DECLARATION_LEXER                          4
-.emtcode DECLARATION_RULE                           5
-
-/* specifier */
-.emtcode SPECIFIER_END                              0
-.emtcode SPECIFIER_AND_TAG                          1
-.emtcode SPECIFIER_OR_TAG                           2
-.emtcode SPECIFIER_CHARACTER_RANGE                  3
-.emtcode SPECIFIER_CHARACTER                        4
-.emtcode SPECIFIER_STRING                           5
-.emtcode SPECIFIER_IDENTIFIER                       6
-.emtcode SPECIFIER_TRUE                             7
-.emtcode SPECIFIER_FALSE                            8
-.emtcode SPECIFIER_DEBUG                            9
-
-/* identifier */
-.emtcode IDENTIFIER_SIMPLE                          0
-.emtcode IDENTIFIER_LOOP                            1
-
-/* error */
-.emtcode ERROR_NOT_PRESENT                          0
-.emtcode ERROR_PRESENT                              1
-
-/* emit */
-.emtcode EMIT_NULL                                  0
-.emtcode EMIT_INTEGER                               1
-.emtcode EMIT_IDENTIFIER                            2
-.emtcode EMIT_CHARACTER                             3
-.emtcode EMIT_LAST_CHARACTER                        4
-.emtcode EMIT_CURRENT_POSITION                      5
-
-.errtext INVALID_GRAMMAR                            "internal error 2001: invalid grammar script"
-.errtext SYNTAX_EXPECTED                            "internal error 2002: '.syntax' keyword expected"
-.errtext IDENTIFIER_EXPECTED                        "internal error 2003: identifier expected"
-.errtext MISSING_SEMICOLON                          "internal error 2004: missing ';'"
-.errtext INTEGER_EXPECTED                           "internal error 2005: integer value expected"
-.errtext STRING_EXPECTED                            "internal error 2006: string expected"
-
-/*
-    <grammar>                           ::= ".syntax" <identifier> ";" <declaration_list>
-*/
-grammar
-    grammar_1 .error INVALID_GRAMMAR;
-grammar_1
-    optional_space .and ".syntax" .error SYNTAX_EXPECTED .and space .and identifier .and
-    semicolon .and declaration_list .and optional_space .and '\0' .emit DECLARATION_END;
-
-/*
-    <optional_space>                    ::= <space>
-                                          | ""
-*/
-optional_space
-    space .or .true;
-
-/*
-    <space>                             ::= <single_space> <single_space>*
-*/
-space
-    single_space .and .loop single_space;
-
-/*
-    <single_space>                      ::= <white_char>
-                                          | <comment_block>
-*/
-single_space
-    white_char .or comment_block;
-
-/*
-    <white_char>                        ::= " " 
-                                          | "\t"
-                                          | "\n"
-                                          | "\r"
-*/
-white_char
-    ' ' .or '\t' .or '\n' .or '\r';
-
-/*
-    <comment_block>                     ::= "/" "*" <comment_rest>
-*/
-comment_block
-    '/' .and '*' .and comment_rest;
-
-/*
-    <comment_rest>                      ::= <comment_char_no_star>* <comment_end>
-                                          | <comment_char_no_star>* "*" <comment_rest>
-*/
-comment_rest
-    .loop comment_char_no_star .and comment_rest_1;
-comment_rest_1
-    comment_end .or comment_rest_2;
-comment_rest_2
-    '*' .and comment_rest;
-
-/*
-    <comment_char_no_star>              ::= All ASCII characters except "*" and "\0"
-*/
-comment_char_no_star
-    '\x2B'-'\xFF' .or '\x01'-'\x29';
-
-/*
-    <comment_end>                       ::= "*" "/"
-*/
-comment_end
-    '*' .and '/';
-
-/*
-    <identifier>                        ::= <identifier>
-*/
-identifier
-    identifier_ne .error IDENTIFIER_EXPECTED;
-
-/*
-    <identifier_ne>                     ::= <first_idchar> <follow_idchar>*
-*/
-identifier_ne
-    first_idchar .emit * .and .loop follow_idchar .emit * .and .true .emit '\0';
-
-/*
-    <first_idchar>                      ::= "a"-"z"
-                                          | "A"-"Z"
-                                          | "_"
-*/
-first_idchar
-    'a'-'z' .or 'A'-'Z' .or '_';
-
-/*
-    <follow_idchar>                     ::= <first_idchar>
-                                          | <digit_dec>
-*/
-follow_idchar
-    first_idchar .or digit_dec;
-
-/*
-    <digit_dec>                         ::= "0"-"9"
-*/
-digit_dec
-    '0'-'9';
-
-/*
-    <semicolon>                         ::= ";"
-*/
-semicolon
-    optional_space .and ';' .error MISSING_SEMICOLON .and optional_space;
-
-/*
-    <declaration_list>                  ::= <declaration>
-                                          | <declaration_list> <declaration>
-*/
-declaration_list
-    declaration .and .loop declaration;
-
-/*
-    <declaration>                       ::= <emitcode_definition>
-                                          | <errortext_definition>
-                                          | <lexer_definition>
-                                          | <rule_definition>
-*/
-declaration
-    emitcode_definition .emit DECLARATION_EMITCODE .or
-    errortext_definition .emit DECLARATION_ERRORTEXT .or
-    regbyte_definition .emit DECLARATION_REGBYTE .or
-    lexer_definition .emit DECLARATION_LEXER .or
-    rule_definition .emit DECLARATION_RULE;
-
-/*
-    <emitcode_definition>               ::= ".emtcode" <identifier> <integer>
-*/
-emitcode_definition
-    ".emtcode" .and space .and identifier .and space .and integer .and space_or_null;
-
-/*
-    <integer>                           ::= <integer_ne>
-*/
-integer
-    integer_ne .error INTEGER_EXPECTED;
-
-/*
-    <integer_ne>                        ::= <hex_integer>
-                                          | <dec_integer>
-*/
-integer_ne
-    hex_integer .emit 0x10 .or dec_integer .emit 10;
-
-/*
-    <hex_integer>                       :: <hex_prefix> <digit_hex> <digit_hex>*
-*/
-hex_integer
-    hex_prefix .and digit_hex .emit * .and .loop digit_hex .emit * .and .true .emit '\0';
-
-/*
-    <hex_prefix>                        ::= "0x"
-                                          | "0X"
-*/
-hex_prefix
-    '0' .and hex_prefix_1;
-hex_prefix_1
-    'x' .or 'X';
-
-/*
-    <digit_hex>                         ::= "0"-"9"
-                                          | "a"-"f"
-                                          | "A"-"F"
-*/
-digit_hex
-    '0'-'9' .or 'a'-'f' .or 'A'-'F';
-
-/*
-    <dec_integer>                       :: <digit_dec> <digit_dec>*
-*/
-dec_integer
-    digit_dec .emit * .and .loop digit_dec .emit * .and .true .emit '\0';
-
-/*
-    <space_or_null>                     ::= <space>
-                                          | "\0"
-*/
-space_or_null
-    space .or '\0';
-
-/*
-    <errortext_definition>              ::= ".errtext" <identifier> <string>
-*/
-errortext_definition
-    ".errtext" .and space .and identifier .and space .and string .and space_or_null;
-
-/*
-    <string>                            ::= <string_ne>
-*/
-string
-    string_ne .error STRING_EXPECTED;
-
-/*
-    <string_ne>                         ::= "\"" <string_char_double_quotes> "\""
-*/
-string_ne
-    '"' .and .loop string_char_double_quotes .and '"' .emit '\0';
-
-/*
-    <string_char_double_quotes>         ::= <escape_sequence>
-                                          | <string_char>
-                                          | "\'"
-*/
-string_char_double_quotes
-    escape_sequence .or string_char .emit * .or '\'' .emit *;
-
-/*
-    <string_char>                       ::= All ASCII characters except "\'", "\"", "\n", "\r",
-                                            "\0" and "\\"
-*/
-string_char
-    '\x5D'-'\xFF' .or '\x28'-'\x5B' .or '\x23'-'\x26' .or '\x0E'-'\x21' .or '\x0B'-'\x0C' .or
-    '\x01'-'\x09';
-
-/*
-    <escape_sequence>                   ::= "\\" <escape_code>
-*/
-escape_sequence
-    '\\' .emit * .and escape_code;
-
-/*
-    <escape_code>                       ::= <simple_escape_code>
-                                          | <hex_escape_code>
-                                          | <oct_escape_code>
-*/
-escape_code
-    simple_escape_code .emit * .or hex_escape_code .or oct_escape_code;
-
-/*
-    <simple_escape_code>                ::= "\'"
-                                          | "\""
-                                          | "?"
-                                          | "\\"
-                                          | "a"
-                                          | "b"
-                                          | "f"
-                                          | "n"
-                                          | "r"
-                                          | "t"
-                                          | "v"
-*/
-simple_escape_code
-    '\'' .or '"' .or '?' .or '\\' .or 'a' .or 'b' .or 'f' .or 'n' .or 'r' .or 't' .or 'v';
-
-/*
-    <hex_escape_code>                   ::= "x" <digit_hex> <digit_hex>*
-*/
-hex_escape_code
-    'x' .emit * .and digit_hex .emit * .and .loop digit_hex .emit *;
-
-/*
-    <oct_escape_code>                   ::= <digit_oct> <optional_digit_oct> <optional_digit_oct>
-*/
-oct_escape_code
-    digit_oct .emit * .and optional_digit_oct .and optional_digit_oct;
-
-/*
-    <digit_oct>                         ::= "0"-"7"
-*/
-digit_oct
-    '0'-'7';
-
-/*
-    <optional_digit_oct>                ::= <digit_oct>
-                                          | ""
-*/
-optional_digit_oct
-    digit_oct .emit * .or .true;
-
-/*
-    <regbyte_definition>                ::= ".regbyte" <identifier> <integer>
-*/
-regbyte_definition
-    ".regbyte" .and space .and identifier .and space .and integer .and space_or_null;
-
-/*
-    <lexer_definition>                  ::= ".string" <identifier> ";"
-*/
-lexer_definition
-    ".string" .and space .and identifier .and semicolon;
-
-/*
-    <rule_definition>                   ::= <identifier_ne> <definition>
-*/
-rule_definition
-    identifier_ne .and space .and definition;
-
-/*
-    <definition>                        ::= <specifier> <optional_specifiers_and_or> ";"
-*/
-definition
-    specifier .and optional_specifiers_and_or .and semicolon .emit SPECIFIER_END;
-
-/*
-    <optional_specifiers_and_or>        ::= <and_specifiers>
-                                          | <or_specifiers>
-                                          | ""
-*/
-optional_specifiers_and_or
-    and_specifiers .emit SPECIFIER_AND_TAG .or or_specifiers .emit SPECIFIER_OR_TAG .or .true;
-
-/*
-    <specifier>                         ::= <specifier_condition> <specifier_rule>
-*/
-specifier
-    specifier_condition .and optional_space .and specifier_rule;
-
-/*
-    <specifier_condition>               ::= ".if" "(" <left_operand> <operator> <right_operand> ")"
-*/
-specifier_condition
-    specifier_condition_1 .or .true;
-specifier_condition_1
-    ".if" .and optional_space .and '(' .and optional_space .and left_operand .and operator .and
-    right_operand .and optional_space .and ')';
-
-/*
-    <left_operand>                      ::= <identifier>
-*/
-left_operand
-    identifier;
-
-/*
-    <operator>                          ::= "!="
-                                          | "=="
-*/
-operator
-    operator_1 .or operator_2;
-operator_1
-    optional_space .and '!' .and '=' .and optional_space;
-operator_2
-    optional_space .and '=' .and '=' .and optional_space;
-
-/*
-    <right_operand>                     ::= <integer>
-*/
-right_operand
-    integer;
-
-/*
-    <specifier_rule>                    ::= <character_range> <optional_error> <emit>*
-                                          | <character> <optional_error> <emit>*
-                                          | <string> <optional_error> <emit>*
-                                          | ".true" <optional_error> <emit>*
-                                          | ".false" <optional_error> <emit>*
-                                          | ".debug" <optional_error> <emit>*
-                                          | <advanced_identifier> <optional_error> <emit>*
-*/
-specifier_rule
-    specifier_rule_1 .and optional_error .and .loop emit .and .true .emit EMIT_NULL;
-specifier_rule_1
-    character_range .emit SPECIFIER_CHARACTER_RANGE .or
-    character .emit SPECIFIER_CHARACTER .or
-    string_ne .emit SPECIFIER_STRING .or
-    ".true" .emit SPECIFIER_TRUE .or
-    ".false" .emit SPECIFIER_FALSE .or
-    ".debug" .emit SPECIFIER_DEBUG .or
-    advanced_identifier .emit SPECIFIER_IDENTIFIER;
-
-/*
-    <character>                         ::= "\'" <string_char_single_quotes "\'"
-*/
-character
-    '\'' .and string_char_single_quotes .and '\'' .emit '\0';
-
-/*
-    <string_char_single_quotes>         ::= <escape_sequence>
-                                          | <string_char>
-                                          | "\""
-*/
-string_char_single_quotes
-    escape_sequence .or string_char .emit * .or '"' .emit *;
-
-/*
-    <character_range>                   ::= <character> "-" <character>
-*/
-character_range
-    character .and optional_space .and '-' .and optional_space .and character;
-
-/*
-    <advanced_identifier>               ::= <optional_loop> <identifier>
-*/
-advanced_identifier
-    optional_loop .and identifier;
-
-/*
-    <optional_loop>                     ::= ".loop"
-                                          | ""
-*/
-optional_loop
-    optional_loop_1 .emit IDENTIFIER_LOOP .or .true .emit IDENTIFIER_SIMPLE;
-optional_loop_1
-    ".loop" .and space;
-
-/*
-    <optional_error>                    ::= <error>
-                                          | ""
-*/
-optional_error
-    error .emit ERROR_PRESENT .or .true .emit ERROR_NOT_PRESENT;
-
-/*
-    <error>                             :: ".error" <identifier>
-*/
-error
-    space .and ".error" .and space .and identifier;
-
-/*
-    <emit>                              ::= <emit_output>
-                                          | <emit_regbyte>
-*/
-emit
-    emit_output .or emit_regbyte;
-
-/*
-    <emit_output>                       ::= ".emit" <emit_param>
-*/
-emit_output
-    space .and ".emit" .and space .and emit_param;
-
-/*
-    <emit_param>                        ::= <integer>
-                                          | <identifier>
-                                          | <character>
-                                          | "*"
-                                          | "$"
-*/
-emit_param
-    integer_ne .emit EMIT_INTEGER .or
-    identifier_ne .emit EMIT_IDENTIFIER .or
-    character .emit EMIT_CHARACTER .or
-    '*' .emit EMIT_LAST_CHARACTER .or
-    '$' .emit EMIT_CURRENT_POSITION;
-
-/*
-    <emit_regbyte>                      ::= ".load" <identifier> <emit_param>
-*/
-emit_regbyte
-    space .and ".load" .and space .and identifier .and space .and emit_param;
-
-/*
-    <and_specifiers>                    ::= <and_specifier> <and_specifier>*
-*/
-and_specifiers
-    and_specifier .and .loop and_specifier;
-
-/*
-    <or_specifiers>                     ::= <or_specifier> <or_specifier>*
-*/
-or_specifiers
-    or_specifier .and .loop or_specifier;
-
-/*
-    <and_specifier>                     ::= ".and" <specifier>
-*/
-and_specifier
-    space .and ".and" .and space .and specifier;
-
-/*
-    <or_specifier>                      ::= ".or" <specifier>
-*/
-or_specifier
-    space .and ".or" .and space .and specifier;
-
-
-.string __string_filter;
-
-/*
-    <__string_filter>                   ::= <__first_identifier_char> <__next_identifier_char>*
-*/
-__string_filter
-    __first_identifier_char .and .loop __next_identifier_char;
-
-/*
-    <__first_identifier_char>           ::= "a"-"z"
-                                          | "A"-"Z"
-                                          | "_"
-                                          | "."
-*/
-__first_identifier_char
-    'a'-'z' .or 'A'-'Z' .or '_' .or '.';
-
-/*
-    <__next_identifier_char>            ::= "a"-"z"
-                                          | "A"-"Z"
-                                          | "_"
-                                          | "0"-"9"
-*/
-__next_identifier_char
-    'a'-'z' .or 'A'-'Z' .or '_' .or '0'-'9';
-
diff --git a/src/mesa/shader/grammar/grammar_crt.c b/src/mesa/shader/grammar/grammar_crt.c
deleted file mode 100644
index d2c95d1..0000000
--- a/src/mesa/shader/grammar/grammar_crt.c
+++ /dev/null
@@ -1,64 +0,0 @@
-#include "grammar_crt.h"
-
-#define GRAMMAR_PORT_BUILD 1
-#include "grammar.c"
-#undef GRAMMAR_PORT_BUILD
-
-
-void grammar_alloc_free (void *ptr)
-{
-    free (ptr);
-}
-
-void *grammar_alloc_malloc (size_t size)
-{
-    return malloc (size);
-}
-
-void *grammar_alloc_realloc (void *ptr, size_t old_size, size_t size)
-{
-    return realloc (ptr, size);
-}
-
-void *grammar_memory_copy (void *dst, const void * src, size_t size)
-{
-    return memcpy (dst, src, size);
-}
-
-int grammar_string_compare (const byte *str1, const byte *str2)
-{
-    return strcmp ((const char *) str1, (const char *) str2);
-}
-
-int grammar_string_compare_n (const byte *str1, const byte *str2, size_t n)
-{
-    return strncmp ((const char *) str1, (const char *) str2, n);
-}
-
-byte *grammar_string_copy (byte *dst, const byte *src)
-{
-    return (byte *) strcpy ((char *) dst, (const char *) src);
-}
-
-byte *grammar_string_copy_n (byte *dst, const byte *src, size_t n)
-{
-    return (byte *) strncpy ((char *) dst, (const char *) src, n);
-}
-
-unsigned int grammar_string_length (const byte *str)
-{
-    return strlen ((const char *) str);
-}
-
-byte *grammar_string_duplicate (const byte *src)
-{
-    const unsigned int size = grammar_string_length (src);
-    byte *str = grammar_alloc_malloc (size + 1);
-    if (str != NULL)
-    {
-        grammar_memory_copy (str, src, size);
-        str[size] = '\0';
-    }
-    return str;
-}
-
diff --git a/src/mesa/shader/grammar/grammar_crt.h b/src/mesa/shader/grammar/grammar_crt.h
deleted file mode 100644
index 492711e..0000000
--- a/src/mesa/shader/grammar/grammar_crt.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef GRAMMAR_CRT_H
-#define GRAMMAR_CRT_H
-
-
-#include <stdlib.h>
-#include <malloc.h>
-#include <string.h>
-
-
-typedef unsigned long grammar;
-typedef unsigned char byte;
-
-
-#define GRAMMAR_PORT_INCLUDE 1
-#include "grammar.h"
-#undef GRAMMAR_PORT_INCLUDE
-
-
-#endif
-
diff --git a/src/mesa/shader/grammar/grammar_mesa.c b/src/mesa/shader/grammar/grammar_mesa.c
deleted file mode 100644
index eb96250..0000000
--- a/src/mesa/shader/grammar/grammar_mesa.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.1
- *
- * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL 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 grammar_mesa.c
- * mesa3d port to syntax parsing engine
- * \author Michal Krol
- */
-
-#include "grammar_mesa.h"
-
-#define GRAMMAR_PORT_BUILD 1
-#include "grammar.c"
-#undef GRAMMAR_PORT_BUILD
-
-
-void grammar_alloc_free (void *ptr)
-{
-    _mesa_free (ptr);
-}
-
-void *grammar_alloc_malloc (size_t size)
-{
-    return _mesa_malloc (size);
-}
-
-void *grammar_alloc_realloc (void *ptr, size_t old_size, size_t size)
-{
-    return _mesa_realloc (ptr, old_size, size);
-}
-
-void *grammar_memory_copy (void *dst, const void * src, size_t size)
-{
-    return _mesa_memcpy (dst, src, size);
-}
-
-int grammar_string_compare (const byte *str1, const byte *str2)
-{
-    return _mesa_strcmp ((const char *) str1, (const char *) str2);
-}
-
-int grammar_string_compare_n (const byte *str1, const byte *str2, size_t n)
-{
-    return _mesa_strncmp ((const char *) str1, (const char *) str2, n);
-}
-
-byte *grammar_string_copy (byte *dst, const byte *src)
-{
-    return (byte *) _mesa_strcpy ((char *) dst, (const char *) src);
-}
-
-byte *grammar_string_copy_n (byte *dst, const byte *src, size_t n)
-{
-    return (byte *) _mesa_strncpy ((char *) dst, (const char *) src, n);
-}
-
-byte *grammar_string_duplicate (const byte *src)
-{
-    return (byte *) _mesa_strdup ((const char *) src);
-}
-
-unsigned int grammar_string_length (const byte *str)
-{
-    return (unsigned int)_mesa_strlen ((const char *) str);
-}
-
diff --git a/src/mesa/shader/grammar/grammar_syn.h b/src/mesa/shader/grammar/grammar_syn.h
deleted file mode 100644
index 840a1ab..0000000
--- a/src/mesa/shader/grammar/grammar_syn.h
+++ /dev/null
@@ -1,202 +0,0 @@
-".syntax grammar;\n"
-".emtcode DECLARATION_END 0\n"
-".emtcode DECLARATION_EMITCODE 1\n"
-".emtcode DECLARATION_ERRORTEXT 2\n"
-".emtcode DECLARATION_REGBYTE 3\n"
-".emtcode DECLARATION_LEXER 4\n"
-".emtcode DECLARATION_RULE 5\n"
-".emtcode SPECIFIER_END 0\n"
-".emtcode SPECIFIER_AND_TAG 1\n"
-".emtcode SPECIFIER_OR_TAG 2\n"
-".emtcode SPECIFIER_CHARACTER_RANGE 3\n"
-".emtcode SPECIFIER_CHARACTER 4\n"
-".emtcode SPECIFIER_STRING 5\n"
-".emtcode SPECIFIER_IDENTIFIER 6\n"
-".emtcode SPECIFIER_TRUE 7\n"
-".emtcode SPECIFIER_FALSE 8\n"
-".emtcode SPECIFIER_DEBUG 9\n"
-".emtcode IDENTIFIER_SIMPLE 0\n"
-".emtcode IDENTIFIER_LOOP 1\n"
-".emtcode ERROR_NOT_PRESENT 0\n"
-".emtcode ERROR_PRESENT 1\n"
-".emtcode EMIT_NULL 0\n"
-".emtcode EMIT_INTEGER 1\n"
-".emtcode EMIT_IDENTIFIER 2\n"
-".emtcode EMIT_CHARACTER 3\n"
-".emtcode EMIT_LAST_CHARACTER 4\n"
-".emtcode EMIT_CURRENT_POSITION 5\n"
-".errtext INVALID_GRAMMAR \"internal error 2001: invalid grammar script\"\n"
-".errtext SYNTAX_EXPECTED \"internal error 2002: '.syntax' keyword expected\"\n"
-".errtext IDENTIFIER_EXPECTED \"internal error 2003: identifier expected\"\n"
-".errtext MISSING_SEMICOLON \"internal error 2004: missing ';'\"\n"
-".errtext INTEGER_EXPECTED \"internal error 2005: integer value expected\"\n"
-".errtext STRING_EXPECTED \"internal error 2006: string expected\"\n"
-"grammar\n"
-" grammar_1 .error INVALID_GRAMMAR;\n"
-"grammar_1\n"
-" optional_space .and \".syntax\" .error SYNTAX_EXPECTED .and space .and identifier .and\n"
-" semicolon .and declaration_list .and optional_space .and '\\0' .emit DECLARATION_END;\n"
-"optional_space\n"
-" space .or .true;\n"
-"space\n"
-" single_space .and .loop single_space;\n"
-"single_space\n"
-" white_char .or comment_block;\n"
-"white_char\n"
-" ' ' .or '\\t' .or '\\n' .or '\\r';\n"
-"comment_block\n"
-" '/' .and '*' .and comment_rest;\n"
-"comment_rest\n"
-" .loop comment_char_no_star .and comment_rest_1;\n"
-"comment_rest_1\n"
-" comment_end .or comment_rest_2;\n"
-"comment_rest_2\n"
-" '*' .and comment_rest;\n"
-"comment_char_no_star\n"
-" '\\x2B'-'\\xFF' .or '\\x01'-'\\x29';\n"
-"comment_end\n"
-" '*' .and '/';\n"
-"identifier\n"
-" identifier_ne .error IDENTIFIER_EXPECTED;\n"
-"identifier_ne\n"
-" first_idchar .emit * .and .loop follow_idchar .emit * .and .true .emit '\\0';\n"
-"first_idchar\n"
-" 'a'-'z' .or 'A'-'Z' .or '_';\n"
-"follow_idchar\n"
-" first_idchar .or digit_dec;\n"
-"digit_dec\n"
-" '0'-'9';\n"
-"semicolon\n"
-" optional_space .and ';' .error MISSING_SEMICOLON .and optional_space;\n"
-"declaration_list\n"
-" declaration .and .loop declaration;\n"
-"declaration\n"
-" emitcode_definition .emit DECLARATION_EMITCODE .or\n"
-" errortext_definition .emit DECLARATION_ERRORTEXT .or\n"
-" regbyte_definition .emit DECLARATION_REGBYTE .or\n"
-" lexer_definition .emit DECLARATION_LEXER .or\n"
-" rule_definition .emit DECLARATION_RULE;\n"
-"emitcode_definition\n"
-" \".emtcode\" .and space .and identifier .and space .and integer .and space_or_null;\n"
-"integer\n"
-" integer_ne .error INTEGER_EXPECTED;\n"
-"integer_ne\n"
-" hex_integer .emit 0x10 .or dec_integer .emit 10;\n"
-"hex_integer\n"
-" hex_prefix .and digit_hex .emit * .and .loop digit_hex .emit * .and .true .emit '\\0';\n"
-"hex_prefix\n"
-" '0' .and hex_prefix_1;\n"
-"hex_prefix_1\n"
-" 'x' .or 'X';\n"
-"digit_hex\n"
-" '0'-'9' .or 'a'-'f' .or 'A'-'F';\n"
-"dec_integer\n"
-" digit_dec .emit * .and .loop digit_dec .emit * .and .true .emit '\\0';\n"
-"space_or_null\n"
-" space .or '\\0';\n"
-"errortext_definition\n"
-" \".errtext\" .and space .and identifier .and space .and string .and space_or_null;\n"
-"string\n"
-" string_ne .error STRING_EXPECTED;\n"
-"string_ne\n"
-" '\"' .and .loop string_char_double_quotes .and '\"' .emit '\\0';\n"
-"string_char_double_quotes\n"
-" escape_sequence .or string_char .emit * .or '\\'' .emit *;\n"
-"string_char\n"
-" '\\x5D'-'\\xFF' .or '\\x28'-'\\x5B' .or '\\x23'-'\\x26' .or '\\x0E'-'\\x21' .or '\\x0B'-'\\x0C' .or\n"
-" '\\x01'-'\\x09';\n"
-"escape_sequence\n"
-" '\\\\' .emit * .and escape_code;\n"
-"escape_code\n"
-" simple_escape_code .emit * .or hex_escape_code .or oct_escape_code;\n"
-"simple_escape_code\n"
-" '\\'' .or '\"' .or '?' .or '\\\\' .or 'a' .or 'b' .or 'f' .or 'n' .or 'r' .or 't' .or 'v';\n"
-"hex_escape_code\n"
-" 'x' .emit * .and digit_hex .emit * .and .loop digit_hex .emit *;\n"
-"oct_escape_code\n"
-" digit_oct .emit * .and optional_digit_oct .and optional_digit_oct;\n"
-"digit_oct\n"
-" '0'-'7';\n"
-"optional_digit_oct\n"
-" digit_oct .emit * .or .true;\n"
-"regbyte_definition\n"
-" \".regbyte\" .and space .and identifier .and space .and integer .and space_or_null;\n"
-"lexer_definition\n"
-" \".string\" .and space .and identifier .and semicolon;\n"
-"rule_definition\n"
-" identifier_ne .and space .and definition;\n"
-"definition\n"
-" specifier .and optional_specifiers_and_or .and semicolon .emit SPECIFIER_END;\n"
-"optional_specifiers_and_or\n"
-" and_specifiers .emit SPECIFIER_AND_TAG .or or_specifiers .emit SPECIFIER_OR_TAG .or .true;\n"
-"specifier\n"
-" specifier_condition .and optional_space .and specifier_rule;\n"
-"specifier_condition\n"
-" specifier_condition_1 .or .true;\n"
-"specifier_condition_1\n"
-" \".if\" .and optional_space .and '(' .and optional_space .and left_operand .and operator .and\n"
-" right_operand .and optional_space .and ')';\n"
-"left_operand\n"
-" identifier;\n"
-"operator\n"
-" operator_1 .or operator_2;\n"
-"operator_1\n"
-" optional_space .and '!' .and '=' .and optional_space;\n"
-"operator_2\n"
-" optional_space .and '=' .and '=' .and optional_space;\n"
-"right_operand\n"
-" integer;\n"
-"specifier_rule\n"
-" specifier_rule_1 .and optional_error .and .loop emit .and .true .emit EMIT_NULL;\n"
-"specifier_rule_1\n"
-" character_range .emit SPECIFIER_CHARACTER_RANGE .or\n"
-" character .emit SPECIFIER_CHARACTER .or\n"
-" string_ne .emit SPECIFIER_STRING .or\n"
-" \".true\" .emit SPECIFIER_TRUE .or\n"
-" \".false\" .emit SPECIFIER_FALSE .or\n"
-" \".debug\" .emit SPECIFIER_DEBUG .or\n"
-" advanced_identifier .emit SPECIFIER_IDENTIFIER;\n"
-"character\n"
-" '\\'' .and string_char_single_quotes .and '\\'' .emit '\\0';\n"
-"string_char_single_quotes\n"
-" escape_sequence .or string_char .emit * .or '\"' .emit *;\n"
-"character_range\n"
-" character .and optional_space .and '-' .and optional_space .and character;\n"
-"advanced_identifier\n"
-" optional_loop .and identifier;\n"
-"optional_loop\n"
-" optional_loop_1 .emit IDENTIFIER_LOOP .or .true .emit IDENTIFIER_SIMPLE;\n"
-"optional_loop_1\n"
-" \".loop\" .and space;\n"
-"optional_error\n"
-" error .emit ERROR_PRESENT .or .true .emit ERROR_NOT_PRESENT;\n"
-"error\n"
-" space .and \".error\" .and space .and identifier;\n"
-"emit\n"
-" emit_output .or emit_regbyte;\n"
-"emit_output\n"
-" space .and \".emit\" .and space .and emit_param;\n"
-"emit_param\n"
-" integer_ne .emit EMIT_INTEGER .or\n"
-" identifier_ne .emit EMIT_IDENTIFIER .or\n"
-" character .emit EMIT_CHARACTER .or\n"
-" '*' .emit EMIT_LAST_CHARACTER .or\n"
-" '$' .emit EMIT_CURRENT_POSITION;\n"
-"emit_regbyte\n"
-" space .and \".load\" .and space .and identifier .and space .and emit_param;\n"
-"and_specifiers\n"
-" and_specifier .and .loop and_specifier;\n"
-"or_specifiers\n"
-" or_specifier .and .loop or_specifier;\n"
-"and_specifier\n"
-" space .and \".and\" .and space .and specifier;\n"
-"or_specifier\n"
-" space .and \".or\" .and space .and specifier;\n"
-".string __string_filter;\n"
-"__string_filter\n"
-" __first_identifier_char .and .loop __next_identifier_char;\n"
-"__first_identifier_char\n"
-" 'a'-'z' .or 'A'-'Z' .or '_' .or '.';\n"
-"__next_identifier_char\n"
-" 'a'-'z' .or 'A'-'Z' .or '_' .or '0'-'9';\n"
-""
diff --git a/src/mesa/shader/lex.yy.c b/src/mesa/shader/lex.yy.c
index fc78b30..68543ae 100644
--- a/src/mesa/shader/lex.yy.c
+++ b/src/mesa/shader/lex.yy.c
@@ -1097,45 +1097,6 @@
 #define SWIZZLE_INVAL  MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
 				     SWIZZLE_NIL, SWIZZLE_NIL)
 
-/**
- * Send a string to the parser using asm_parser_state::string_dumpster
- *
- * Sends a string to the parser using asm_parser_state::string_dumpster as a
- * temporary storage buffer.  Data previously stored in
- * asm_parser_state::string_dumpster will be lost.  If
- * asm_parser_state::string_dumpster is not large enough to hold the new
- * string, the buffer size will be increased.  The buffer size is \b never
- * decreased.
- *
- * \param state   Assembler parser state tracking
- * \param str     String to be passed to the parser
- *
- * \return
- * A pointer to asm_parser_state::string_dumpster on success or \c NULL on
- * failure.  Currently the only failure case is \c ENOMEM.
- */
-static char *
-return_string(struct asm_parser_state *state, const char *str)
-{
-   const size_t len = strlen(str);
-
-   if (len >= state->dumpster_size) {
-      char *const dumpster = _mesa_realloc(state->string_dumpster,
-					   state->dumpster_size,
-					   len + 1);
-      if (dumpster == NULL) {
-	 return NULL;
-      }
-
-      state->string_dumpster = dumpster;
-      state->dumpster_size = len + 1;
-   }
-
-   memcpy(state->string_dumpster, str, len + 1);
-   return state->string_dumpster;
-}
-
-
 static unsigned
 mask_from_char(char c)
 {
@@ -1181,7 +1142,7 @@
 static int
 handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval)
 {
-   lval->string = return_string(state, text);
+   lval->string = strdup(text);
 
    return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL)
       ? IDENTIFIER : USED_IDENTIFIER;
@@ -1200,7 +1161,7 @@
    } while(0);
 
 #define YY_EXTRA_TYPE struct asm_parser_state *
-#line 1204 "lex.yy.c"
+#line 1165 "lex.yy.c"
 
 #define INITIAL 0
 
@@ -1446,10 +1407,10 @@
 	register int yy_act;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
-#line 196 "program_lexer.l"
+#line 157 "program_lexer.l"
 
 
-#line 1453 "lex.yy.c"
+#line 1414 "lex.yy.c"
 
     yylval = yylval_param;
 
@@ -1538,17 +1499,17 @@
 
 case 1:
 YY_RULE_SETUP
-#line 198 "program_lexer.l"
+#line 159 "program_lexer.l"
 { return ARBvp_10; }
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 199 "program_lexer.l"
+#line 160 "program_lexer.l"
 { return ARBfp_10; }
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 200 "program_lexer.l"
+#line 161 "program_lexer.l"
 {
    yylval->integer = at_address;
    return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS);
@@ -1556,692 +1517,692 @@
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 204 "program_lexer.l"
+#line 165 "program_lexer.l"
 { return ALIAS; }
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 205 "program_lexer.l"
+#line 166 "program_lexer.l"
 { return ATTRIB; }
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 206 "program_lexer.l"
+#line 167 "program_lexer.l"
 { return END; }
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 207 "program_lexer.l"
+#line 168 "program_lexer.l"
 { return OPTION; }
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 208 "program_lexer.l"
+#line 169 "program_lexer.l"
 { return OUTPUT; }
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 209 "program_lexer.l"
+#line 170 "program_lexer.l"
 { return PARAM; }
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 210 "program_lexer.l"
+#line 171 "program_lexer.l"
 { yylval->integer = at_temp; return TEMP; }
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 212 "program_lexer.l"
+#line 173 "program_lexer.l"
 { return_opcode(             1, VECTOR_OP, ABS, 3); }
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 213 "program_lexer.l"
+#line 174 "program_lexer.l"
 { return_opcode(             1, BIN_OP, ADD, 3); }
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 214 "program_lexer.l"
+#line 175 "program_lexer.l"
 { return_opcode(require_ARB_vp, ARL, ARL, 3); }
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 216 "program_lexer.l"
+#line 177 "program_lexer.l"
 { return_opcode(require_ARB_fp, TRI_OP, CMP, 3); }
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 217 "program_lexer.l"
+#line 178 "program_lexer.l"
 { return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); }
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 219 "program_lexer.l"
+#line 180 "program_lexer.l"
 { return_opcode(require_NV_fp,  VECTOR_OP, DDX, 3); }
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 220 "program_lexer.l"
+#line 181 "program_lexer.l"
 { return_opcode(require_NV_fp,  VECTOR_OP, DDY, 3); }
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 221 "program_lexer.l"
+#line 182 "program_lexer.l"
 { return_opcode(             1, BIN_OP, DP3, 3); }
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 222 "program_lexer.l"
+#line 183 "program_lexer.l"
 { return_opcode(             1, BIN_OP, DP4, 3); }
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 223 "program_lexer.l"
+#line 184 "program_lexer.l"
 { return_opcode(             1, BIN_OP, DPH, 3); }
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 224 "program_lexer.l"
+#line 185 "program_lexer.l"
 { return_opcode(             1, BIN_OP, DST, 3); }
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 226 "program_lexer.l"
+#line 187 "program_lexer.l"
 { return_opcode(             1, SCALAR_OP, EX2, 3); }
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 227 "program_lexer.l"
+#line 188 "program_lexer.l"
 { return_opcode(require_ARB_vp, SCALAR_OP, EXP, 3); }
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 229 "program_lexer.l"
+#line 190 "program_lexer.l"
 { return_opcode(             1, VECTOR_OP, FLR, 3); }
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 230 "program_lexer.l"
+#line 191 "program_lexer.l"
 { return_opcode(             1, VECTOR_OP, FRC, 3); }
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 232 "program_lexer.l"
+#line 193 "program_lexer.l"
 { return_opcode(require_ARB_fp, KIL, KIL, 3); }
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 234 "program_lexer.l"
+#line 195 "program_lexer.l"
 { return_opcode(             1, VECTOR_OP, LIT, 3); }
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 235 "program_lexer.l"
+#line 196 "program_lexer.l"
 { return_opcode(             1, SCALAR_OP, LG2, 3); }
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 236 "program_lexer.l"
+#line 197 "program_lexer.l"
 { return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); }
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 237 "program_lexer.l"
+#line 198 "program_lexer.l"
 { return_opcode(require_ARB_fp, TRI_OP, LRP, 3); }
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 239 "program_lexer.l"
+#line 200 "program_lexer.l"
 { return_opcode(             1, TRI_OP, MAD, 3); }
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 240 "program_lexer.l"
+#line 201 "program_lexer.l"
 { return_opcode(             1, BIN_OP, MAX, 3); }
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 241 "program_lexer.l"
+#line 202 "program_lexer.l"
 { return_opcode(             1, BIN_OP, MIN, 3); }
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 242 "program_lexer.l"
+#line 203 "program_lexer.l"
 { return_opcode(             1, VECTOR_OP, MOV, 3); }
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 243 "program_lexer.l"
+#line 204 "program_lexer.l"
 { return_opcode(             1, BIN_OP, MUL, 3); }
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 245 "program_lexer.l"
+#line 206 "program_lexer.l"
 { return_opcode(require_NV_fp,  VECTOR_OP, PK2H, 4); }
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 246 "program_lexer.l"
+#line 207 "program_lexer.l"
 { return_opcode(require_NV_fp,  VECTOR_OP, PK2US, 5); }
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 247 "program_lexer.l"
+#line 208 "program_lexer.l"
 { return_opcode(require_NV_fp,  VECTOR_OP, PK4B, 4); }
 	YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 248 "program_lexer.l"
+#line 209 "program_lexer.l"
 { return_opcode(require_NV_fp,  VECTOR_OP, PK4UB, 5); }
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 249 "program_lexer.l"
+#line 210 "program_lexer.l"
 { return_opcode(             1, BINSC_OP, POW, 3); }
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 251 "program_lexer.l"
+#line 212 "program_lexer.l"
 { return_opcode(             1, SCALAR_OP, RCP, 3); }
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 252 "program_lexer.l"
+#line 213 "program_lexer.l"
 { return_opcode(require_NV_fp,  BIN_OP,    RFL, 3); }
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 253 "program_lexer.l"
+#line 214 "program_lexer.l"
 { return_opcode(             1, SCALAR_OP, RSQ, 3); }
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 255 "program_lexer.l"
+#line 216 "program_lexer.l"
 { return_opcode(require_ARB_fp, SCALAR_OP, SCS, 3); }
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 256 "program_lexer.l"
+#line 217 "program_lexer.l"
 { return_opcode(require_NV_fp,  BIN_OP, SEQ, 3); }
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 257 "program_lexer.l"
+#line 218 "program_lexer.l"
 { return_opcode(require_NV_fp,  BIN_OP, SFL, 3); }
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 258 "program_lexer.l"
+#line 219 "program_lexer.l"
 { return_opcode(             1, BIN_OP, SGE, 3); }
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 259 "program_lexer.l"
+#line 220 "program_lexer.l"
 { return_opcode(require_NV_fp,  BIN_OP, SGT, 3); }
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 260 "program_lexer.l"
+#line 221 "program_lexer.l"
 { return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); }
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 261 "program_lexer.l"
+#line 222 "program_lexer.l"
 { return_opcode(require_NV_fp,  BIN_OP, SLE, 3); }
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 262 "program_lexer.l"
+#line 223 "program_lexer.l"
 { return_opcode(             1, BIN_OP, SLT, 3); }
 	YY_BREAK
 case 52:
 YY_RULE_SETUP
-#line 263 "program_lexer.l"
+#line 224 "program_lexer.l"
 { return_opcode(require_NV_fp,  BIN_OP, SNE, 3); }
 	YY_BREAK
 case 53:
 YY_RULE_SETUP
-#line 264 "program_lexer.l"
+#line 225 "program_lexer.l"
 { return_opcode(require_NV_fp,  BIN_OP, STR, 3); }
 	YY_BREAK
 case 54:
 YY_RULE_SETUP
-#line 265 "program_lexer.l"
+#line 226 "program_lexer.l"
 { return_opcode(             1, BIN_OP, SUB, 3); }
 	YY_BREAK
 case 55:
 YY_RULE_SETUP
-#line 266 "program_lexer.l"
+#line 227 "program_lexer.l"
 { return_opcode(             1, SWZ, SWZ, 3); }
 	YY_BREAK
 case 56:
 YY_RULE_SETUP
-#line 268 "program_lexer.l"
+#line 229 "program_lexer.l"
 { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); }
 	YY_BREAK
 case 57:
 YY_RULE_SETUP
-#line 269 "program_lexer.l"
+#line 230 "program_lexer.l"
 { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); }
 	YY_BREAK
 case 58:
 YY_RULE_SETUP
-#line 270 "program_lexer.l"
+#line 231 "program_lexer.l"
 { return_opcode(require_NV_fp,  TXD_OP, TXD, 3); }
 	YY_BREAK
 case 59:
 YY_RULE_SETUP
-#line 271 "program_lexer.l"
+#line 232 "program_lexer.l"
 { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); }
 	YY_BREAK
 case 60:
 YY_RULE_SETUP
-#line 273 "program_lexer.l"
+#line 234 "program_lexer.l"
 { return_opcode(require_NV_fp,  SCALAR_OP, UP2H, 4); }
 	YY_BREAK
 case 61:
 YY_RULE_SETUP
-#line 274 "program_lexer.l"
+#line 235 "program_lexer.l"
 { return_opcode(require_NV_fp,  SCALAR_OP, UP2US, 5); }
 	YY_BREAK
 case 62:
 YY_RULE_SETUP
-#line 275 "program_lexer.l"
+#line 236 "program_lexer.l"
 { return_opcode(require_NV_fp,  SCALAR_OP, UP4B, 4); }
 	YY_BREAK
 case 63:
 YY_RULE_SETUP
-#line 276 "program_lexer.l"
+#line 237 "program_lexer.l"
 { return_opcode(require_NV_fp,  SCALAR_OP, UP4UB, 5); }
 	YY_BREAK
 case 64:
 YY_RULE_SETUP
-#line 278 "program_lexer.l"
+#line 239 "program_lexer.l"
 { return_opcode(require_NV_fp,  TRI_OP, X2D, 3); }
 	YY_BREAK
 case 65:
 YY_RULE_SETUP
-#line 279 "program_lexer.l"
+#line 240 "program_lexer.l"
 { return_opcode(             1, BIN_OP, XPD, 3); }
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
-#line 281 "program_lexer.l"
+#line 242 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
 	YY_BREAK
 case 67:
 YY_RULE_SETUP
-#line 282 "program_lexer.l"
+#line 243 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
 	YY_BREAK
 case 68:
 YY_RULE_SETUP
-#line 283 "program_lexer.l"
+#line 244 "program_lexer.l"
 { return PROGRAM; }
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
-#line 284 "program_lexer.l"
+#line 245 "program_lexer.l"
 { return STATE; }
 	YY_BREAK
 case 70:
 YY_RULE_SETUP
-#line 285 "program_lexer.l"
+#line 246 "program_lexer.l"
 { return RESULT; }
 	YY_BREAK
 case 71:
 YY_RULE_SETUP
-#line 287 "program_lexer.l"
+#line 248 "program_lexer.l"
 { return AMBIENT; }
 	YY_BREAK
 case 72:
 YY_RULE_SETUP
-#line 288 "program_lexer.l"
+#line 249 "program_lexer.l"
 { return ATTENUATION; }
 	YY_BREAK
 case 73:
 YY_RULE_SETUP
-#line 289 "program_lexer.l"
+#line 250 "program_lexer.l"
 { return BACK; }
 	YY_BREAK
 case 74:
 YY_RULE_SETUP
-#line 290 "program_lexer.l"
+#line 251 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, CLIP); }
 	YY_BREAK
 case 75:
 YY_RULE_SETUP
-#line 291 "program_lexer.l"
+#line 252 "program_lexer.l"
 { return COLOR; }
 	YY_BREAK
 case 76:
 YY_RULE_SETUP
-#line 292 "program_lexer.l"
+#line 253 "program_lexer.l"
 { return_token_or_DOT(require_ARB_fp, DEPTH); }
 	YY_BREAK
 case 77:
 YY_RULE_SETUP
-#line 293 "program_lexer.l"
+#line 254 "program_lexer.l"
 { return DIFFUSE; }
 	YY_BREAK
 case 78:
 YY_RULE_SETUP
-#line 294 "program_lexer.l"
+#line 255 "program_lexer.l"
 { return DIRECTION; }
 	YY_BREAK
 case 79:
 YY_RULE_SETUP
-#line 295 "program_lexer.l"
+#line 256 "program_lexer.l"
 { return EMISSION; }
 	YY_BREAK
 case 80:
 YY_RULE_SETUP
-#line 296 "program_lexer.l"
+#line 257 "program_lexer.l"
 { return ENV; }
 	YY_BREAK
 case 81:
 YY_RULE_SETUP
-#line 297 "program_lexer.l"
+#line 258 "program_lexer.l"
 { return EYE; }
 	YY_BREAK
 case 82:
 YY_RULE_SETUP
-#line 298 "program_lexer.l"
+#line 259 "program_lexer.l"
 { return FOGCOORD; }
 	YY_BREAK
 case 83:
 YY_RULE_SETUP
-#line 299 "program_lexer.l"
+#line 260 "program_lexer.l"
 { return FOG; }
 	YY_BREAK
 case 84:
 YY_RULE_SETUP
-#line 300 "program_lexer.l"
+#line 261 "program_lexer.l"
 { return FRONT; }
 	YY_BREAK
 case 85:
 YY_RULE_SETUP
-#line 301 "program_lexer.l"
+#line 262 "program_lexer.l"
 { return HALF; }
 	YY_BREAK
 case 86:
 YY_RULE_SETUP
-#line 302 "program_lexer.l"
+#line 263 "program_lexer.l"
 { return INVERSE; }
 	YY_BREAK
 case 87:
 YY_RULE_SETUP
-#line 303 "program_lexer.l"
+#line 264 "program_lexer.l"
 { return INVTRANS; }
 	YY_BREAK
 case 88:
 YY_RULE_SETUP
-#line 304 "program_lexer.l"
+#line 265 "program_lexer.l"
 { return LIGHT; }
 	YY_BREAK
 case 89:
 YY_RULE_SETUP
-#line 305 "program_lexer.l"
+#line 266 "program_lexer.l"
 { return LIGHTMODEL; }
 	YY_BREAK
 case 90:
 YY_RULE_SETUP
-#line 306 "program_lexer.l"
+#line 267 "program_lexer.l"
 { return LIGHTPROD; }
 	YY_BREAK
 case 91:
 YY_RULE_SETUP
-#line 307 "program_lexer.l"
+#line 268 "program_lexer.l"
 { return LOCAL; }
 	YY_BREAK
 case 92:
 YY_RULE_SETUP
-#line 308 "program_lexer.l"
+#line 269 "program_lexer.l"
 { return MATERIAL; }
 	YY_BREAK
 case 93:
 YY_RULE_SETUP
-#line 309 "program_lexer.l"
+#line 270 "program_lexer.l"
 { return MAT_PROGRAM; }
 	YY_BREAK
 case 94:
 YY_RULE_SETUP
-#line 310 "program_lexer.l"
+#line 271 "program_lexer.l"
 { return MATRIX; }
 	YY_BREAK
 case 95:
 YY_RULE_SETUP
-#line 311 "program_lexer.l"
+#line 272 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, MATRIXINDEX); }
 	YY_BREAK
 case 96:
 YY_RULE_SETUP
-#line 312 "program_lexer.l"
+#line 273 "program_lexer.l"
 { return MODELVIEW; }
 	YY_BREAK
 case 97:
 YY_RULE_SETUP
-#line 313 "program_lexer.l"
+#line 274 "program_lexer.l"
 { return MVP; }
 	YY_BREAK
 case 98:
 YY_RULE_SETUP
-#line 314 "program_lexer.l"
+#line 275 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, NORMAL); }
 	YY_BREAK
 case 99:
 YY_RULE_SETUP
-#line 315 "program_lexer.l"
+#line 276 "program_lexer.l"
 { return OBJECT; }
 	YY_BREAK
 case 100:
 YY_RULE_SETUP
-#line 316 "program_lexer.l"
+#line 277 "program_lexer.l"
 { return PALETTE; }
 	YY_BREAK
 case 101:
 YY_RULE_SETUP
-#line 317 "program_lexer.l"
+#line 278 "program_lexer.l"
 { return PARAMS; }
 	YY_BREAK
 case 102:
 YY_RULE_SETUP
-#line 318 "program_lexer.l"
+#line 279 "program_lexer.l"
 { return PLANE; }
 	YY_BREAK
 case 103:
 YY_RULE_SETUP
-#line 319 "program_lexer.l"
+#line 280 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, POINT_TOK); }
 	YY_BREAK
 case 104:
 YY_RULE_SETUP
-#line 320 "program_lexer.l"
+#line 281 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, POINTSIZE); }
 	YY_BREAK
 case 105:
 YY_RULE_SETUP
-#line 321 "program_lexer.l"
+#line 282 "program_lexer.l"
 { return POSITION; }
 	YY_BREAK
 case 106:
 YY_RULE_SETUP
-#line 322 "program_lexer.l"
+#line 283 "program_lexer.l"
 { return PRIMARY; }
 	YY_BREAK
 case 107:
 YY_RULE_SETUP
-#line 323 "program_lexer.l"
+#line 284 "program_lexer.l"
 { return PROJECTION; }
 	YY_BREAK
 case 108:
 YY_RULE_SETUP
-#line 324 "program_lexer.l"
+#line 285 "program_lexer.l"
 { return_token_or_DOT(require_ARB_fp, RANGE); }
 	YY_BREAK
 case 109:
 YY_RULE_SETUP
-#line 325 "program_lexer.l"
+#line 286 "program_lexer.l"
 { return ROW; }
 	YY_BREAK
 case 110:
 YY_RULE_SETUP
-#line 326 "program_lexer.l"
+#line 287 "program_lexer.l"
 { return SCENECOLOR; }
 	YY_BREAK
 case 111:
 YY_RULE_SETUP
-#line 327 "program_lexer.l"
+#line 288 "program_lexer.l"
 { return SECONDARY; }
 	YY_BREAK
 case 112:
 YY_RULE_SETUP
-#line 328 "program_lexer.l"
+#line 289 "program_lexer.l"
 { return SHININESS; }
 	YY_BREAK
 case 113:
 YY_RULE_SETUP
-#line 329 "program_lexer.l"
+#line 290 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, SIZE_TOK); }
 	YY_BREAK
 case 114:
 YY_RULE_SETUP
-#line 330 "program_lexer.l"
+#line 291 "program_lexer.l"
 { return SPECULAR; }
 	YY_BREAK
 case 115:
 YY_RULE_SETUP
-#line 331 "program_lexer.l"
+#line 292 "program_lexer.l"
 { return SPOT; }
 	YY_BREAK
 case 116:
 YY_RULE_SETUP
-#line 332 "program_lexer.l"
+#line 293 "program_lexer.l"
 { return TEXCOORD; }
 	YY_BREAK
 case 117:
 YY_RULE_SETUP
-#line 333 "program_lexer.l"
+#line 294 "program_lexer.l"
 { return_token_or_DOT(require_ARB_fp, TEXENV); }
 	YY_BREAK
 case 118:
 YY_RULE_SETUP
-#line 334 "program_lexer.l"
+#line 295 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, TEXGEN); }
 	YY_BREAK
 case 119:
 YY_RULE_SETUP
-#line 335 "program_lexer.l"
+#line 296 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, TEXGEN_Q); }
 	YY_BREAK
 case 120:
 YY_RULE_SETUP
-#line 336 "program_lexer.l"
+#line 297 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, TEXGEN_S); }
 	YY_BREAK
 case 121:
 YY_RULE_SETUP
-#line 337 "program_lexer.l"
+#line 298 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, TEXGEN_T); }
 	YY_BREAK
 case 122:
 YY_RULE_SETUP
-#line 338 "program_lexer.l"
+#line 299 "program_lexer.l"
 { return TEXTURE; }
 	YY_BREAK
 case 123:
 YY_RULE_SETUP
-#line 339 "program_lexer.l"
+#line 300 "program_lexer.l"
 { return TRANSPOSE; }
 	YY_BREAK
 case 124:
 YY_RULE_SETUP
-#line 340 "program_lexer.l"
+#line 301 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, VTXATTRIB); }
 	YY_BREAK
 case 125:
 YY_RULE_SETUP
-#line 341 "program_lexer.l"
+#line 302 "program_lexer.l"
 { return_token_or_DOT(require_ARB_vp, WEIGHT); }
 	YY_BREAK
 case 126:
 YY_RULE_SETUP
-#line 343 "program_lexer.l"
+#line 304 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); }
 	YY_BREAK
 case 127:
 YY_RULE_SETUP
-#line 344 "program_lexer.l"
+#line 305 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); }
 	YY_BREAK
 case 128:
 YY_RULE_SETUP
-#line 345 "program_lexer.l"
+#line 306 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); }
 	YY_BREAK
 case 129:
 YY_RULE_SETUP
-#line 346 "program_lexer.l"
+#line 307 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); }
 	YY_BREAK
 case 130:
 YY_RULE_SETUP
-#line 347 "program_lexer.l"
+#line 308 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); }
 	YY_BREAK
 case 131:
 YY_RULE_SETUP
-#line 348 "program_lexer.l"
+#line 309 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); }
 	YY_BREAK
 case 132:
 YY_RULE_SETUP
-#line 349 "program_lexer.l"
+#line 310 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); }
 	YY_BREAK
 case 133:
 YY_RULE_SETUP
-#line 350 "program_lexer.l"
+#line 311 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); }
 	YY_BREAK
 case 134:
 YY_RULE_SETUP
-#line 351 "program_lexer.l"
+#line 312 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); }
 	YY_BREAK
 case 135:
 YY_RULE_SETUP
-#line 352 "program_lexer.l"
+#line 313 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); }
 	YY_BREAK
 case 136:
 YY_RULE_SETUP
-#line 353 "program_lexer.l"
+#line 314 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); }
 	YY_BREAK
 case 137:
 YY_RULE_SETUP
-#line 354 "program_lexer.l"
+#line 315 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); }
 	YY_BREAK
 case 138:
 YY_RULE_SETUP
-#line 355 "program_lexer.l"
+#line 316 "program_lexer.l"
 { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
 	YY_BREAK
 case 139:
 YY_RULE_SETUP
-#line 357 "program_lexer.l"
+#line 318 "program_lexer.l"
 { return handle_ident(yyextra, yytext, yylval); }
 	YY_BREAK
 case 140:
 YY_RULE_SETUP
-#line 359 "program_lexer.l"
+#line 320 "program_lexer.l"
 { return DOT_DOT; }
 	YY_BREAK
 case 141:
 YY_RULE_SETUP
-#line 361 "program_lexer.l"
+#line 322 "program_lexer.l"
 {
    yylval->integer = strtol(yytext, NULL, 10);
    return INTEGER;
@@ -2249,7 +2210,7 @@
 	YY_BREAK
 case 142:
 YY_RULE_SETUP
-#line 365 "program_lexer.l"
+#line 326 "program_lexer.l"
 {
    yylval->real = _mesa_strtod(yytext, NULL);
    return REAL;
@@ -2261,7 +2222,7 @@
 yyg->yy_c_buf_p = yy_cp -= 1;
 YY_DO_BEFORE_ACTION; /* set up yytext again */
 YY_RULE_SETUP
-#line 369 "program_lexer.l"
+#line 330 "program_lexer.l"
 {
    yylval->real = _mesa_strtod(yytext, NULL);
    return REAL;
@@ -2269,7 +2230,7 @@
 	YY_BREAK
 case 144:
 YY_RULE_SETUP
-#line 373 "program_lexer.l"
+#line 334 "program_lexer.l"
 {
    yylval->real = _mesa_strtod(yytext, NULL);
    return REAL;
@@ -2277,7 +2238,7 @@
 	YY_BREAK
 case 145:
 YY_RULE_SETUP
-#line 377 "program_lexer.l"
+#line 338 "program_lexer.l"
 {
    yylval->real = _mesa_strtod(yytext, NULL);
    return REAL;
@@ -2285,7 +2246,7 @@
 	YY_BREAK
 case 146:
 YY_RULE_SETUP
-#line 382 "program_lexer.l"
+#line 343 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
    yylval->swiz_mask.mask = WRITEMASK_XYZW;
@@ -2294,7 +2255,7 @@
 	YY_BREAK
 case 147:
 YY_RULE_SETUP
-#line 388 "program_lexer.l"
+#line 349 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_XY
@@ -2304,7 +2265,7 @@
 	YY_BREAK
 case 148:
 YY_RULE_SETUP
-#line 394 "program_lexer.l"
+#line 355 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_XZW;
@@ -2313,7 +2274,7 @@
 	YY_BREAK
 case 149:
 YY_RULE_SETUP
-#line 399 "program_lexer.l"
+#line 360 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_YZW;
@@ -2322,7 +2283,7 @@
 	YY_BREAK
 case 150:
 YY_RULE_SETUP
-#line 405 "program_lexer.l"
+#line 366 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_X
@@ -2332,7 +2293,7 @@
 	YY_BREAK
 case 151:
 YY_RULE_SETUP
-#line 411 "program_lexer.l"
+#line 372 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_Y
@@ -2342,7 +2303,7 @@
 	YY_BREAK
 case 152:
 YY_RULE_SETUP
-#line 417 "program_lexer.l"
+#line 378 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_ZW;
@@ -2351,7 +2312,7 @@
 	YY_BREAK
 case 153:
 YY_RULE_SETUP
-#line 423 "program_lexer.l"
+#line 384 "program_lexer.l"
 {
    const unsigned s = swiz_from_char(yytext[1]);
    yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
@@ -2361,7 +2322,7 @@
 	YY_BREAK
 case 154:
 YY_RULE_SETUP
-#line 430 "program_lexer.l"
+#line 391 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
 					    swiz_from_char(yytext[2]),
@@ -2373,7 +2334,7 @@
 	YY_BREAK
 case 155:
 YY_RULE_SETUP
-#line 439 "program_lexer.l"
+#line 400 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
    yylval->swiz_mask.mask = WRITEMASK_XYZW;
@@ -2382,7 +2343,7 @@
 	YY_BREAK
 case 156:
 YY_RULE_SETUP
-#line 445 "program_lexer.l"
+#line 406 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_XY
@@ -2392,7 +2353,7 @@
 	YY_BREAK
 case 157:
 YY_RULE_SETUP
-#line 451 "program_lexer.l"
+#line 412 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_XZW;
@@ -2401,7 +2362,7 @@
 	YY_BREAK
 case 158:
 YY_RULE_SETUP
-#line 456 "program_lexer.l"
+#line 417 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_YZW;
@@ -2410,7 +2371,7 @@
 	YY_BREAK
 case 159:
 YY_RULE_SETUP
-#line 462 "program_lexer.l"
+#line 423 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_X
@@ -2420,7 +2381,7 @@
 	YY_BREAK
 case 160:
 YY_RULE_SETUP
-#line 468 "program_lexer.l"
+#line 429 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_Y
@@ -2430,7 +2391,7 @@
 	YY_BREAK
 case 161:
 YY_RULE_SETUP
-#line 474 "program_lexer.l"
+#line 435 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
    yylval->swiz_mask.mask = WRITEMASK_ZW;
@@ -2439,7 +2400,7 @@
 	YY_BREAK
 case 162:
 YY_RULE_SETUP
-#line 480 "program_lexer.l"
+#line 441 "program_lexer.l"
 {
    const unsigned s = swiz_from_char(yytext[1]);
    yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
@@ -2449,7 +2410,7 @@
 	YY_BREAK
 case 163:
 YY_RULE_SETUP
-#line 488 "program_lexer.l"
+#line 449 "program_lexer.l"
 {
    if (require_ARB_vp) {
       return TEXGEN_R;
@@ -2463,7 +2424,7 @@
 	YY_BREAK
 case 164:
 YY_RULE_SETUP
-#line 499 "program_lexer.l"
+#line 460 "program_lexer.l"
 {
    yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
 					    swiz_from_char(yytext[2]),
@@ -2475,13 +2436,13 @@
 	YY_BREAK
 case 165:
 YY_RULE_SETUP
-#line 508 "program_lexer.l"
+#line 469 "program_lexer.l"
 { return DOT; }
 	YY_BREAK
 case 166:
 /* rule 166 can match eol */
 YY_RULE_SETUP
-#line 510 "program_lexer.l"
+#line 471 "program_lexer.l"
 {
    yylloc->first_line++;
    yylloc->first_column = 1;
@@ -2492,7 +2453,7 @@
 	YY_BREAK
 case 167:
 YY_RULE_SETUP
-#line 517 "program_lexer.l"
+#line 478 "program_lexer.l"
 /* eat whitespace */ ;
 	YY_BREAK
 case 168:
@@ -2500,20 +2461,20 @@
 yyg->yy_c_buf_p = yy_cp -= 1;
 YY_DO_BEFORE_ACTION; /* set up yytext again */
 YY_RULE_SETUP
-#line 518 "program_lexer.l"
+#line 479 "program_lexer.l"
 /* eat comments */ ;
 	YY_BREAK
 case 169:
 YY_RULE_SETUP
-#line 519 "program_lexer.l"
+#line 480 "program_lexer.l"
 { return yytext[0]; }
 	YY_BREAK
 case 170:
 YY_RULE_SETUP
-#line 520 "program_lexer.l"
+#line 481 "program_lexer.l"
 ECHO;
 	YY_BREAK
-#line 2517 "lex.yy.c"
+#line 2478 "lex.yy.c"
 case YY_STATE_EOF(INITIAL):
 	yyterminate();
 
@@ -3688,7 +3649,7 @@
 
 #define YYTABLES_NAME "yytables"
 
-#line 520 "program_lexer.l"
+#line 481 "program_lexer.l"
 
 
 
diff --git a/src/mesa/shader/nvfragparse.c b/src/mesa/shader/nvfragparse.c
index 0fd5552..8ee7c93 100644
--- a/src/mesa/shader/nvfragparse.c
+++ b/src/mesa/shader/nvfragparse.c
@@ -217,6 +217,12 @@
    const struct instruction_pattern *inst;
    struct instruction_pattern result;
 
+   result.name = NULL;
+   result.opcode = MAX_OPCODE; /* i.e. invalid instruction */
+   result.inputs = 0;
+   result.outputs = 0;
+   result.suffixes = 0;
+
    for (inst = Instructions; inst->name; inst++) {
       if (_mesa_strncmp((const char *) token, inst->name, 3) == 0) {
          /* matched! */
@@ -247,7 +253,7 @@
          return result;
       }
    }
-   result.opcode = MAX_OPCODE; /* i.e. invalid instruction */
+
    return result;
 }
 
@@ -636,7 +642,7 @@
    else {
       /* 4-component swizzle (vector) */
       GLint k;
-      for (k = 0; token[k] && k < 4; k++) {
+      for (k = 0; k < 4 && token[k]; k++) {
          if (token[k] == 'x')
             swizzle[k] = 0;
          else if (token[k] == 'y')
diff --git a/src/mesa/shader/nvprogram.c b/src/mesa/shader/nvprogram.c
index 471a735..fd6cbb0 100644
--- a/src/mesa/shader/nvprogram.c
+++ b/src/mesa/shader/nvprogram.c
@@ -47,6 +47,7 @@
 #include "prog_instruction.h"
 #include "nvfragparse.h"
 #include "nvvertparse.h"
+#include "arbprogparse.h"
 #include "nvprogram.h"
 
 
@@ -595,6 +596,12 @@
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
+   if (!ctx->Extensions.NV_vertex_program
+       && !ctx->Extensions.NV_fragment_program) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV()");
+      return;
+   }
+
    if (id == 0) {
       _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(id)");
       return;
@@ -627,7 +634,13 @@
          }
          _mesa_HashInsert(ctx->Shared->Programs, id, vprog);
       }
-      _mesa_parse_nv_vertex_program(ctx, target, program, len, vprog);
+
+      if (ctx->Extensions.ARB_vertex_program
+	  && (strncmp((char *) program, "!!ARB", 5) == 0)) {
+	 _mesa_parse_arb_vertex_program(ctx, target, program, len, vprog);
+      } else {
+	 _mesa_parse_nv_vertex_program(ctx, target, program, len, vprog);
+      }
    }
    else if (target == GL_FRAGMENT_PROGRAM_NV
             && ctx->Extensions.NV_fragment_program) {
@@ -643,6 +656,20 @@
       }
       _mesa_parse_nv_fragment_program(ctx, target, program, len, fprog);
    }
+   else if (target == GL_FRAGMENT_PROGRAM_ARB
+            && ctx->Extensions.ARB_fragment_program) {
+      struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog;
+      if (!fprog || prog == &_mesa_DummyProgram) {
+         fprog = (struct gl_fragment_program *)
+            ctx->Driver.NewProgram(ctx, target, id);
+         if (!fprog) {
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
+            return;
+         }
+         _mesa_HashInsert(ctx->Shared->Programs, id, fprog);
+      }
+      _mesa_parse_arb_fragment_program(ctx, target, program, len, fprog);
+   }
    else {
       _mesa_error(ctx, GL_INVALID_ENUM, "glLoadProgramNV(target)");
    }
diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c
index 192d39a..7f03452 100644
--- a/src/mesa/shader/prog_execute.c
+++ b/src/mesa/shader/prog_execute.c
@@ -54,8 +54,18 @@
  * Set x to positive or negative infinity.
  */
 #if defined(USE_IEEE) || defined(_WIN32)
-#define SET_POS_INFINITY(x)  ( *((GLuint *) (void *)&x) = 0x7F800000 )
-#define SET_NEG_INFINITY(x)  ( *((GLuint *) (void *)&x) = 0xFF800000 )
+#define SET_POS_INFINITY(x)                  \
+   do {                                      \
+         fi_type fi;                         \
+         fi.i = 0x7F800000;                  \
+         x = fi.f;                           \
+   } while (0)
+#define SET_NEG_INFINITY(x)                  \
+   do {                                      \
+         fi_type fi;                         \
+         fi.i = 0xFF800000;                  \
+         x = fi.f;                           \
+   } while (0)
 #elif defined(VMS)
 #define SET_POS_INFINITY(x)  x = __MAXFLOAT
 #define SET_NEG_INFINITY(x)  x = -__MAXFLOAT
@@ -674,9 +684,13 @@
          break;
       case OPCODE_BGNLOOP:
          /* no-op */
+         ASSERT(program->Instructions[inst->BranchTarget].Opcode
+                == OPCODE_ENDLOOP);
          break;
       case OPCODE_ENDLOOP:
          /* subtract 1 here since pc is incremented by for(pc) loop */
+         ASSERT(program->Instructions[inst->BranchTarget].Opcode
+                == OPCODE_BGNLOOP);
          pc = inst->BranchTarget - 1;   /* go to matching BNGLOOP */
          break;
       case OPCODE_BGNSUB:      /* begin subroutine */
@@ -684,12 +698,26 @@
       case OPCODE_ENDSUB:      /* end subroutine */
          break;
       case OPCODE_BRA:         /* branch (conditional) */
-         /* fall-through */
-      case OPCODE_BRK:         /* break out of loop (conditional) */
-         /* fall-through */
-      case OPCODE_CONT:        /* continue loop (conditional) */
          if (eval_condition(machine, inst)) {
             /* take branch */
+            /* Subtract 1 here since we'll do pc++ below */
+            pc = inst->BranchTarget - 1;
+         }
+         break;
+      case OPCODE_BRK:         /* break out of loop (conditional) */
+         ASSERT(program->Instructions[inst->BranchTarget].Opcode
+                == OPCODE_ENDLOOP);
+         if (eval_condition(machine, inst)) {
+            /* break out of loop */
+            /* pc++ at end of for-loop will put us after the ENDLOOP inst */
+            pc = inst->BranchTarget;
+         }
+         break;
+      case OPCODE_CONT:        /* continue loop (conditional) */
+         ASSERT(program->Instructions[inst->BranchTarget].Opcode
+                == OPCODE_ENDLOOP);
+         if (eval_condition(machine, inst)) {
+            /* continue at ENDLOOP */
             /* Subtract 1 here since we'll do pc++ at end of for-loop */
             pc = inst->BranchTarget - 1;
          }
@@ -882,6 +910,10 @@
       case OPCODE_IF:
          {
             GLboolean cond;
+            ASSERT(program->Instructions[inst->BranchTarget].Opcode
+                   == OPCODE_ELSE ||
+                   program->Instructions[inst->BranchTarget].Opcode
+                   == OPCODE_ENDIF);
             /* eval condition */
             if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
                GLfloat a[4];
@@ -901,14 +933,16 @@
             else {
                /* go to the instruction after ELSE or ENDIF */
                assert(inst->BranchTarget >= 0);
-               pc = inst->BranchTarget - 1;
+               pc = inst->BranchTarget;
             }
          }
          break;
       case OPCODE_ELSE:
          /* goto ENDIF */
+         ASSERT(program->Instructions[inst->BranchTarget].Opcode
+                == OPCODE_ENDIF);
          assert(inst->BranchTarget >= 0);
-         pc = inst->BranchTarget - 1;
+         pc = inst->BranchTarget;
          break;
       case OPCODE_ENDIF:
          /* nothing */
@@ -1635,11 +1669,12 @@
       case OPCODE_UP2H:        /* unpack two 16-bit floats */
          {
             GLfloat a[4], result[4];
-            const GLuint *rawBits = (const GLuint *) a;
+            fi_type fi;
             GLhalfNV hx, hy;
             fetch_vector1(&inst->SrcReg[0], machine, a);
-            hx = rawBits[0] & 0xffff;
-            hy = rawBits[0] >> 16;
+            fi.f = a[0];
+            hx = fi.i & 0xffff;
+            hy = fi.i >> 16;
             result[0] = result[2] = _mesa_half_to_float(hx);
             result[1] = result[3] = _mesa_half_to_float(hy);
             store_vector4(inst, machine, result);
@@ -1648,11 +1683,12 @@
       case OPCODE_UP2US:       /* unpack two GLushorts */
          {
             GLfloat a[4], result[4];
-            const GLuint *rawBits = (const GLuint *) a;
+            fi_type fi;
             GLushort usx, usy;
             fetch_vector1(&inst->SrcReg[0], machine, a);
-            usx = rawBits[0] & 0xffff;
-            usy = rawBits[0] >> 16;
+            fi.f = a[0];
+            usx = fi.i & 0xffff;
+            usy = fi.i >> 16;
             result[0] = result[2] = usx * (1.0f / 65535.0f);
             result[1] = result[3] = usy * (1.0f / 65535.0f);
             store_vector4(inst, machine, result);
@@ -1661,24 +1697,26 @@
       case OPCODE_UP4B:        /* unpack four GLbytes */
          {
             GLfloat a[4], result[4];
-            const GLuint *rawBits = (const GLuint *) a;
+            fi_type fi;
             fetch_vector1(&inst->SrcReg[0], machine, a);
-            result[0] = (((rawBits[0] >> 0) & 0xff) - 128) / 127.0F;
-            result[1] = (((rawBits[0] >> 8) & 0xff) - 128) / 127.0F;
-            result[2] = (((rawBits[0] >> 16) & 0xff) - 128) / 127.0F;
-            result[3] = (((rawBits[0] >> 24) & 0xff) - 128) / 127.0F;
+            fi.f = a[0];
+            result[0] = (((fi.i >> 0) & 0xff) - 128) / 127.0F;
+            result[1] = (((fi.i >> 8) & 0xff) - 128) / 127.0F;
+            result[2] = (((fi.i >> 16) & 0xff) - 128) / 127.0F;
+            result[3] = (((fi.i >> 24) & 0xff) - 128) / 127.0F;
             store_vector4(inst, machine, result);
          }
          break;
       case OPCODE_UP4UB:       /* unpack four GLubytes */
          {
             GLfloat a[4], result[4];
-            const GLuint *rawBits = (const GLuint *) a;
+            fi_type fi;
             fetch_vector1(&inst->SrcReg[0], machine, a);
-            result[0] = ((rawBits[0] >> 0) & 0xff) / 255.0F;
-            result[1] = ((rawBits[0] >> 8) & 0xff) / 255.0F;
-            result[2] = ((rawBits[0] >> 16) & 0xff) / 255.0F;
-            result[3] = ((rawBits[0] >> 24) & 0xff) / 255.0F;
+            fi.f = a[0];
+            result[0] = ((fi.i >> 0) & 0xff) / 255.0F;
+            result[1] = ((fi.i >> 8) & 0xff) / 255.0F;
+            result[2] = ((fi.i >> 16) & 0xff) / 255.0F;
+            result[3] = ((fi.i >> 24) & 0xff) / 255.0F;
             store_vector4(inst, machine, result);
          }
          break;
diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h
index 1c687bc..224350c 100644
--- a/src/mesa/shader/prog_instruction.h
+++ b/src/mesa/shader/prog_instruction.h
@@ -312,7 +312,6 @@
     */
    GLuint CondSrc:1;
    /*@}*/
-   GLuint pad:28;
 };
 
 
diff --git a/src/mesa/shader/prog_optimize.c b/src/mesa/shader/prog_optimize.c
index 9d93748..ce41173 100644
--- a/src/mesa/shader/prog_optimize.c
+++ b/src/mesa/shader/prog_optimize.c
@@ -38,6 +38,39 @@
 
 static GLboolean dbg = GL_FALSE;
 
+/* Returns the mask of channels read from the given srcreg in this instruction.
+ */
+static GLuint
+get_src_arg_mask(const struct prog_instruction *inst, int arg)
+{
+   int writemask = inst->DstReg.WriteMask;
+
+   if (inst->CondUpdate)
+      writemask = WRITEMASK_XYZW;
+
+   switch (inst->Opcode) {
+   case OPCODE_MOV:
+   case OPCODE_ABS:
+   case OPCODE_ADD:
+   case OPCODE_MUL:
+   case OPCODE_SUB:
+      return writemask;
+   case OPCODE_RCP:
+   case OPCODE_SIN:
+   case OPCODE_COS:
+   case OPCODE_RSQ:
+   case OPCODE_POW:
+   case OPCODE_EX2:
+      return WRITEMASK_X;
+   case OPCODE_DP2:
+      return WRITEMASK_XY;
+   case OPCODE_DP3:
+   case OPCODE_XPD:
+      return WRITEMASK_XYZ;
+   default:
+      return WRITEMASK_XYZW;
+   }
+}
 
 /**
  * In 'prog' remove instruction[i] if removeFlags[i] == TRUE.
@@ -74,6 +107,11 @@
          }
       }
    }
+   /* Finish removing if the first instruction was to be removed. */
+   if (removeCount > 0) {
+      GLint removeStart = removeEnd - removeCount + 1;
+      _mesa_delete_instructions(prog, removeStart, removeCount);
+   }
    return totalRemoved;
 }
 
@@ -187,11 +225,10 @@
 static void
 _mesa_remove_dead_code(struct gl_program *prog)
 {
-   GLboolean tempWritten[MAX_PROGRAM_TEMPS], tempRead[MAX_PROGRAM_TEMPS];
+   GLboolean tempRead[MAX_PROGRAM_TEMPS][4];
    GLboolean *removeInst; /* per-instruction removal flag */
-   GLuint i, rem;
+   GLuint i, rem = 0, comp;
 
-   memset(tempWritten, 0, sizeof(tempWritten));
    memset(tempRead, 0, sizeof(tempRead));
 
    if (dbg) {
@@ -212,16 +249,37 @@
       for (j = 0; j < numSrc; j++) {
          if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
             const GLuint index = inst->SrcReg[j].Index;
+            GLuint read_mask;
             ASSERT(index < MAX_PROGRAM_TEMPS);
+	    read_mask = get_src_arg_mask(inst, j);
 
             if (inst->SrcReg[j].RelAddr) {
                if (dbg)
                   _mesa_printf("abort remove dead code (indirect temp)\n");
-               _mesa_free(removeInst);
-               return;
+               goto done;
             }
 
-            tempRead[index] = GL_TRUE;
+	    for (comp = 0; comp < 4; comp++) {
+	       GLuint swz = (inst->SrcReg[j].Swizzle >> (3 * comp)) & 0x7;
+
+	       if ((read_mask & (1 << comp)) == 0)
+		  continue;
+
+	       switch (swz) {
+	       case SWIZZLE_X:
+		  tempRead[index][0] = GL_TRUE;
+		  break;
+	       case SWIZZLE_Y:
+		  tempRead[index][1] = GL_TRUE;
+		  break;
+	       case SWIZZLE_Z:
+		  tempRead[index][2] = GL_TRUE;
+		  break;
+	       case SWIZZLE_W:
+		  tempRead[index][3] = GL_TRUE;
+		  break;
+	       }
+	    }
          }
       }
 
@@ -233,50 +291,63 @@
          if (inst->DstReg.RelAddr) {
             if (dbg)
                _mesa_printf("abort remove dead code (indirect temp)\n");
-            _mesa_free(removeInst);
-            return;
+            goto done;
          }
 
-         tempWritten[index] = GL_TRUE;
          if (inst->CondUpdate) {
             /* If we're writing to this register and setting condition
              * codes we cannot remove the instruction.  Prevent removal
              * by setting the 'read' flag.
              */
-            tempRead[index] = GL_TRUE;
+            tempRead[index][0] = GL_TRUE;
+            tempRead[index][1] = GL_TRUE;
+            tempRead[index][2] = GL_TRUE;
+            tempRead[index][3] = GL_TRUE;
          }
       }
    }
 
-   if (dbg) {
-      for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
-         if (tempWritten[i] && !tempRead[i])
-            _mesa_printf("Remove writes to tmp %u\n", i);
-      }
-   }
-
    /* find instructions that write to dead registers, flag for removal */
    for (i = 0; i < prog->NumInstructions; i++) {
-      const struct prog_instruction *inst = prog->Instructions + i;
-      if (inst->DstReg.File == PROGRAM_TEMPORARY) {
-         GLint index = inst->DstReg.Index;
-         removeInst[i] = (tempWritten[index] && !tempRead[index]);
-         if (dbg && removeInst[i]) {
-            _mesa_printf("Remove inst %u: ", i);
-            _mesa_print_instruction(inst);
-         }
+      struct prog_instruction *inst = prog->Instructions + i;
+      const GLuint numDst = _mesa_num_inst_dst_regs(inst->Opcode);
+
+      if (numDst != 0 && inst->DstReg.File == PROGRAM_TEMPORARY) {
+         GLint chan, index = inst->DstReg.Index;
+
+	 for (chan = 0; chan < 4; chan++) {
+	    if (!tempRead[index][chan] &&
+		inst->DstReg.WriteMask & (1 << chan)) {
+	       if (dbg) {
+		  _mesa_printf("Remove writemask on %u.%c\n", i,
+			       chan == 3 ? 'w' : 'x' + chan);
+	       }
+	       inst->DstReg.WriteMask &= ~(1 << chan);
+	       rem++;
+	    }
+	 }
+
+	 if (inst->DstReg.WriteMask == 0) {
+	    /* If we cleared all writes, the instruction can be removed. */
+	    if (dbg)
+	       _mesa_printf("Remove instruction %u: \n", i);
+	    removeInst[i] = GL_TRUE;
+	 }
       }
    }
 
    /* now remove the instructions which aren't needed */
    rem = remove_instructions(prog, removeInst);
 
-   _mesa_free(removeInst);
-
    if (dbg) {
-      _mesa_printf("Optimize: End dead code removal.  %u instructions removed\n", rem);
+      _mesa_printf("Optimize: End dead code removal.\n");
+      _mesa_printf("  %u channel writes removed\n", rem);
+      _mesa_printf("  %u instructions removed\n", rem);
       /*_mesa_print_program(prog);*/
    }
+
+done:
+   _mesa_free(removeInst);
 }
 
 
@@ -325,6 +396,132 @@
    return END;
 }
 
+static GLboolean _mesa_is_flow_control_opcode(enum prog_opcode opcode)
+{
+   switch (opcode) {
+   case OPCODE_BGNLOOP:
+   case OPCODE_BGNSUB:
+   case OPCODE_BRA:
+   case OPCODE_CAL:
+   case OPCODE_CONT:
+   case OPCODE_IF:
+   case OPCODE_ELSE:
+   case OPCODE_END:
+   case OPCODE_ENDIF:
+   case OPCODE_ENDLOOP:
+   case OPCODE_ENDSUB:
+   case OPCODE_RET:
+      return GL_TRUE;
+   default:
+      return GL_FALSE;
+   }
+}
+
+/**
+ * Try to remove use of extraneous MOV instructions, to free them up for dead
+ * code removal.
+ */
+static void
+_mesa_remove_extra_move_use(struct gl_program *prog)
+{
+   GLuint i, j;
+
+   if (dbg) {
+      _mesa_printf("Optimize: Begin remove extra move use\n");
+      _mesa_print_program(prog);
+   }
+
+   /*
+    * Look for sequences such as this:
+    *    MOV tmpX, arg0;
+    *    ...
+    *    FOO tmpY, tmpX, arg1;
+    * and convert into:
+    *    MOV tmpX, arg0;
+    *    ...
+    *    FOO tmpY, arg0, arg1;
+    */
+
+   for (i = 0; i + 1 < prog->NumInstructions; i++) {
+      const struct prog_instruction *mov = prog->Instructions + i;
+
+      if (mov->Opcode != OPCODE_MOV ||
+	  mov->DstReg.File != PROGRAM_TEMPORARY ||
+	  mov->DstReg.RelAddr ||
+	  mov->DstReg.CondMask != COND_TR ||
+	  mov->SaturateMode != SATURATE_OFF ||
+	  mov->SrcReg[0].RelAddr)
+	 continue;
+
+      /* Walk through remaining instructions until the or src reg gets
+       * rewritten or we get into some flow-control, eliminating the use of
+       * this MOV.
+       */
+      for (j = i + 1; j < prog->NumInstructions; j++) {
+	 struct prog_instruction *inst2 = prog->Instructions + j;
+	 int arg;
+
+	 if (_mesa_is_flow_control_opcode(inst2->Opcode))
+	     break;
+
+	 /* First rewrite this instruction's args if appropriate. */
+	 for (arg = 0; arg < _mesa_num_inst_src_regs(inst2->Opcode); arg++) {
+	    int comp;
+	    int read_mask = get_src_arg_mask(inst2, arg);
+
+	    if (inst2->SrcReg[arg].File != mov->DstReg.File ||
+		inst2->SrcReg[arg].Index != mov->DstReg.Index ||
+		inst2->SrcReg[arg].RelAddr ||
+		inst2->SrcReg[arg].Abs)
+	       continue;
+
+	    /* Check that all the sources for this arg of inst2 come from inst1
+	     * or constants.
+	     */
+	    for (comp = 0; comp < 4; comp++) {
+	       int src_swz = GET_SWZ(inst2->SrcReg[arg].Swizzle, comp);
+
+	       /* If the MOV didn't write that channel, can't use it. */
+	       if ((read_mask & (1 << comp)) &&
+		   src_swz <= SWIZZLE_W &&
+		   (mov->DstReg.WriteMask & (1 << src_swz)) == 0)
+		  break;
+	    }
+	    if (comp != 4)
+	       continue;
+
+	    /* Adjust the swizzles of inst2 to point at MOV's source */
+	    for (comp = 0; comp < 4; comp++) {
+	       int inst2_swz = GET_SWZ(inst2->SrcReg[arg].Swizzle, comp);
+
+	       if (inst2_swz <= SWIZZLE_W) {
+		  GLuint s = GET_SWZ(mov->SrcReg[0].Swizzle, inst2_swz);
+		  inst2->SrcReg[arg].Swizzle &= ~(7 << (3 * comp));
+		  inst2->SrcReg[arg].Swizzle |= s << (3 * comp);
+		  inst2->SrcReg[arg].Negate ^= (((mov->SrcReg[0].Negate >>
+						  inst2_swz) & 0x1) << comp);
+	       }
+	    }
+	    inst2->SrcReg[arg].File = mov->SrcReg[0].File;
+	    inst2->SrcReg[arg].Index = mov->SrcReg[0].Index;
+	 }
+
+	 /* If this instruction overwrote part of the move, our time is up. */
+	 if ((inst2->DstReg.File == mov->DstReg.File &&
+	      (inst2->DstReg.RelAddr ||
+	       inst2->DstReg.Index == mov->DstReg.Index)) ||
+	     (inst2->DstReg.File == mov->SrcReg[0].File &&
+	      (inst2->DstReg.RelAddr ||
+	       inst2->DstReg.Index == mov->SrcReg[0].Index)))
+	    break;
+      }
+   }
+
+   if (dbg) {
+      _mesa_printf("Optimize: End remove extra move use.\n");
+      /*_mesa_print_program(prog);*/
+   }
+}
 
 /**
  * Try to remove extraneous MOV instructions from the given program.
@@ -380,7 +577,7 @@
 
             /* get pointer to previous instruction */
             prevI = i - 1;
-            while (removeInst[prevI] && prevI > 0)
+            while (prevI > 0 && removeInst[prevI])
                prevI--;
             prevInst = prog->Instructions + prevI;
 
@@ -823,6 +1020,8 @@
 void
 _mesa_optimize_program(GLcontext *ctx, struct gl_program *program)
 {
+   _mesa_remove_extra_move_use(program);
+
    if (1)
       _mesa_remove_dead_code(program);
 
diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c
index 2f029b0..5822510 100644
--- a/src/mesa/shader/prog_parameter.c
+++ b/src/mesa/shader/prog_parameter.c
@@ -230,9 +230,8 @@
  * Add a new unnamed constant to the parameter list.  This will be used
  * when a fragment/vertex program contains something like this:
  *    MOV r, { 0, 1, 2, 3 };
- * We'll search the parameter list for an existing instance of the
- * constant.  If swizzleOut is non-null, we'll try swizzling when
- * looking for a match.
+ * If swizzleOut is non-null we'll search the parameter list for an
+ * existing instance of the constant which matches with a swizzle.
  *
  * \param paramList  the parameter list
  * \param values  four float values
@@ -248,7 +247,8 @@
    ASSERT(size >= 1);
    ASSERT(size <= 4);
 
-   if (_mesa_lookup_parameter_constant(paramList, values,
+   if (swizzleOut &&
+       _mesa_lookup_parameter_constant(paramList, values,
                                        size, &pos, swizzleOut)) {
       return pos;
    }
@@ -500,7 +500,7 @@
 _mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList,
                              GLsizei nameLen, const char *name)
 {
-   GLuint i = _mesa_lookup_parameter_index(paramList, nameLen, name);
+   GLint i = _mesa_lookup_parameter_index(paramList, nameLen, name);
    if (i < 0)
       return NULL;
    else
diff --git a/src/mesa/shader/prog_parameter_layout.c b/src/mesa/shader/prog_parameter_layout.c
index 1c37b3a..a888573 100644
--- a/src/mesa/shader/prog_parameter_layout.c
+++ b/src/mesa/shader/prog_parameter_layout.c
@@ -72,14 +72,11 @@
 			     unsigned first, unsigned count)
 {
    const int base = dst->NumParameters;
-   unsigned i;
-   unsigned j;
-
+   unsigned i, j;
 
    for (i = first; i < (first + count); i++) {
       struct gl_program_parameter *curr = & src->Parameters[i];
 
-
       if (curr->Type == PROGRAM_CONSTANT) {
 	 j = dst->NumParameters;
       } else {
@@ -93,10 +90,15 @@
 
       assert(j == dst->NumParameters);
 
+      /* copy src parameter [i] to dest parameter [j] */
       memcpy(& dst->Parameters[j], curr,
 	     sizeof(dst->Parameters[j]));
       memcpy(dst->ParameterValues[j], src->ParameterValues[i],
 	     sizeof(GLfloat) * 4);
+
+      /* Pointer to the string name was copied.  Null-out src param name
+       * to prevent double free later.
+       */
       curr->Name = NULL;
 
       dst->NumParameters++;
@@ -117,11 +119,9 @@
    struct asm_instruction *inst;
    unsigned i;
 
-
    layout =
       _mesa_new_parameter_list_sized(state->prog->Parameters->NumParameters);
 
-
    /* PASS 1:  Move any parameters that are accessed indirectly from the
     * original parameter list to the new parameter list.
     */
@@ -155,7 +155,6 @@
       }
    }
 
-
    /* PASS 2:  Move any parameters that are not accessed indirectly from the
     * original parameter list to the new parameter list.
     */
@@ -165,7 +164,6 @@
 	 const int idx = inst->SrcReg[i].Base.Index;
 	 unsigned swizzle = SWIZZLE_NOOP;
 
-
 	 /* All relative addressed operands were processed on the first
 	  * pass.  Just skip them here.
 	  */
@@ -173,7 +171,6 @@
 	    continue;
 	 }
 
-
 	 if ((inst->SrcReg[i].Base.File <= PROGRAM_VARYING )
 	     || (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) {
 	    continue;
@@ -209,7 +206,6 @@
       }
    }
 
-
    _mesa_free_parameter_list(state->prog->Parameters);
    state->prog->Parameters = layout;
 
diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
index ba4d394..9f9789e 100644
--- a/src/mesa/shader/prog_print.c
+++ b/src/mesa/shader/prog_print.c
@@ -821,17 +821,19 @@
 
 
 /**
- * Return binary representation of value (as a string).
+ * Return binary representation of 64-bit value (as a string).
  * Insert a comma to separate each group of 8 bits.
+ * Note we return a pointer to local static storage so this is not
+ * re-entrant, etc.
  * XXX move to imports.[ch] if useful elsewhere.
  */
 static const char *
-binary(GLbitfield val)
+binary(GLbitfield64 val)
 {
-   static char buf[50];
+   static char buf[80];
    GLint i, len = 0;
-   for (i = 31; i >= 0; --i) {
-      if (val & (1 << i))
+   for (i = 63; i >= 0; --i) {
+      if (val & (1ULL << i))
          buf[len++] = '1';
       else if (len > 0 || i == 0)
          buf[len++] = '0';
@@ -855,7 +857,7 @@
 
    _mesa_fprintf(f, "InputsRead: 0x%x (0b%s)\n",
                  prog->InputsRead, binary(prog->InputsRead));
-   _mesa_fprintf(f, "OutputsWritten: 0x%x (0b%s)\n",
+   _mesa_fprintf(f, "OutputsWritten: 0x%llx (0b%s)\n",
                  prog->OutputsWritten, binary(prog->OutputsWritten));
    _mesa_fprintf(f, "NumInstructions=%d\n", prog->NumInstructions);
    _mesa_fprintf(f, "NumTemporaries=%d\n", prog->NumTemporaries);
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index 532adf4..6b8d94e 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -806,9 +806,17 @@
       const struct prog_instruction *inst = prog->Instructions + i;
       const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
 
-      for (k = 0; k < n; k++) {
-         if (inst->SrcReg[k].File == regFile) {
-            used[inst->SrcReg[k].Index] = GL_TRUE;
+      /* check dst reg first */
+      if (inst->DstReg.File == regFile) {
+         used[inst->DstReg.Index] = GL_TRUE;
+      }
+      else {
+         /* check src regs otherwise */
+         for (k = 0; k < n; k++) {
+            if (inst->SrcReg[k].File == regFile) {
+               used[inst->SrcReg[k].Index] = GL_TRUE;
+               break;
+            }
          }
       }
    }
diff --git a/src/mesa/shader/program_lexer.l b/src/mesa/shader/program_lexer.l
index e8dae7b..e2acb3c 100644
--- a/src/mesa/shader/program_lexer.l
+++ b/src/mesa/shader/program_lexer.l
@@ -77,45 +77,6 @@
 #define SWIZZLE_INVAL  MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
 				     SWIZZLE_NIL, SWIZZLE_NIL)
 
-/**
- * Send a string to the parser using asm_parser_state::string_dumpster
- *
- * Sends a string to the parser using asm_parser_state::string_dumpster as a
- * temporary storage buffer.  Data previously stored in
- * asm_parser_state::string_dumpster will be lost.  If
- * asm_parser_state::string_dumpster is not large enough to hold the new
- * string, the buffer size will be increased.  The buffer size is \b never
- * decreased.
- *
- * \param state   Assembler parser state tracking
- * \param str     String to be passed to the parser
- *
- * \return
- * A pointer to asm_parser_state::string_dumpster on success or \c NULL on
- * failure.  Currently the only failure case is \c ENOMEM.
- */
-static char *
-return_string(struct asm_parser_state *state, const char *str)
-{
-   const size_t len = strlen(str);
-
-   if (len >= state->dumpster_size) {
-      char *const dumpster = _mesa_realloc(state->string_dumpster,
-					   state->dumpster_size,
-					   len + 1);
-      if (dumpster == NULL) {
-	 return NULL;
-      }
-
-      state->string_dumpster = dumpster;
-      state->dumpster_size = len + 1;
-   }
-
-   memcpy(state->string_dumpster, str, len + 1);
-   return state->string_dumpster;
-}
-
-
 static unsigned
 mask_from_char(char c)
 {
@@ -161,7 +122,7 @@
 static int
 handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval)
 {
-   lval->string = return_string(state, text);
+   lval->string = strdup(text);
 
    return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL)
       ? IDENTIFIER : USED_IDENTIFIER;
diff --git a/src/mesa/shader/program_parse.tab.c b/src/mesa/shader/program_parse.tab.c
index e57c83e..b12dcee 100644
--- a/src/mesa/shader/program_parse.tab.c
+++ b/src/mesa/shader/program_parse.tab.c
@@ -123,7 +123,8 @@
     struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
 
 static int initialize_symbol_from_const(struct gl_program *prog,
-    struct asm_symbol *param_var, const struct asm_vector *vec);
+    struct asm_symbol *param_var, const struct asm_vector *vec,
+    GLboolean allowSwizzle);
 
 static int yyparse(struct asm_parser_state *state);
 
@@ -145,6 +146,9 @@
 static void set_src_reg(struct asm_src_register *r,
                         gl_register_file file, GLint index);
 
+static void set_src_reg_swz(struct asm_src_register *r,
+                            gl_register_file file, GLint index, GLuint swizzle);
+
 static void asm_instruction_set_operands(struct asm_instruction *inst,
     const struct prog_dst_register *dst, const struct asm_src_register *src0,
     const struct asm_src_register *src1, const struct asm_src_register *src2);
@@ -185,7 +189,7 @@
 
 
 /* Line 189 of yacc.c  */
-#line 189 "program_parse.tab.c"
+#line 193 "program_parse.tab.c"
 
 /* Enabling traces.  */
 #ifndef YYDEBUG
@@ -327,7 +331,7 @@
 {
 
 /* Line 214 of yacc.c  */
-#line 122 "program_parse.y"
+#line 126 "program_parse.y"
 
    struct asm_instruction *inst;
    struct asm_symbol *sym;
@@ -356,7 +360,7 @@
 
 
 /* Line 214 of yacc.c  */
-#line 360 "program_parse.tab.c"
+#line 364 "program_parse.tab.c"
 } YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
@@ -380,14 +384,14 @@
 /* Copy the second part of user declarations.  */
 
 /* Line 264 of yacc.c  */
-#line 267 "program_parse.y"
+#line 271 "program_parse.y"
 
 extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
     void *yyscanner);
 
 
 /* Line 264 of yacc.c  */
-#line 391 "program_parse.tab.c"
+#line 395 "program_parse.tab.c"
 
 #ifdef short
 # undef short
@@ -788,35 +792,35 @@
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   274,   274,   277,   285,   297,   298,   301,   323,   324,
-     327,   342,   345,   350,   357,   358,   359,   360,   361,   362,
-     363,   366,   367,   368,   371,   377,   383,   389,   396,   402,
-     409,   453,   458,   468,   512,   518,   519,   520,   521,   522,
-     523,   524,   525,   526,   527,   528,   529,   532,   544,   552,
-     569,   576,   593,   604,   624,   649,   656,   689,   696,   711,
-     761,   800,   809,   830,   839,   843,   870,   887,   887,   889,
-     896,   908,   909,   910,   913,   927,   941,   959,   970,   982,
-     984,   985,   986,   987,   990,   990,   990,   990,   991,   994,
-     998,  1003,  1010,  1017,  1024,  1047,  1070,  1071,  1072,  1073,
-    1074,  1075,  1078,  1096,  1100,  1106,  1110,  1114,  1118,  1127,
-    1136,  1140,  1145,  1151,  1162,  1162,  1163,  1165,  1169,  1173,
-    1177,  1183,  1183,  1185,  1201,  1224,  1227,  1238,  1244,  1250,
-    1251,  1258,  1264,  1270,  1278,  1284,  1290,  1298,  1304,  1310,
-    1318,  1319,  1322,  1323,  1324,  1325,  1326,  1327,  1328,  1329,
-    1330,  1331,  1332,  1335,  1344,  1348,  1352,  1358,  1367,  1371,
-    1375,  1384,  1388,  1394,  1400,  1407,  1412,  1420,  1430,  1432,
-    1440,  1446,  1450,  1454,  1460,  1471,  1480,  1484,  1489,  1493,
-    1497,  1501,  1507,  1514,  1518,  1524,  1532,  1543,  1550,  1554,
-    1560,  1570,  1581,  1585,  1603,  1612,  1615,  1621,  1625,  1629,
-    1635,  1646,  1651,  1656,  1661,  1666,  1671,  1679,  1682,  1687,
-    1700,  1708,  1719,  1727,  1727,  1729,  1729,  1731,  1741,  1746,
-    1753,  1763,  1772,  1777,  1784,  1794,  1804,  1816,  1816,  1817,
-    1817,  1819,  1829,  1837,  1847,  1855,  1863,  1872,  1883,  1887,
-    1893,  1894,  1895,  1898,  1898,  1901,  1936,  1940,  1940,  1943,
-    1949,  1957,  1970,  1979,  1988,  1992,  2001,  2010,  2021,  2028,
-    2033,  2042,  2054,  2057,  2066,  2077,  2078,  2079,  2082,  2083,
-    2084,  2087,  2088,  2091,  2092,  2095,  2096,  2099,  2110,  2121,
-    2132,  2154,  2155
+       0,   278,   278,   281,   289,   301,   302,   305,   329,   330,
+     333,   348,   351,   356,   363,   364,   365,   366,   367,   368,
+     369,   372,   373,   374,   377,   383,   389,   395,   402,   408,
+     415,   459,   464,   474,   518,   524,   525,   526,   527,   528,
+     529,   530,   531,   532,   533,   534,   535,   538,   550,   558,
+     575,   582,   601,   612,   632,   657,   664,   697,   704,   719,
+     774,   817,   826,   847,   857,   861,   890,   909,   909,   911,
+     918,   930,   931,   932,   935,   949,   963,   983,   994,  1006,
+    1008,  1009,  1010,  1011,  1014,  1014,  1014,  1014,  1015,  1018,
+    1022,  1027,  1034,  1041,  1048,  1071,  1094,  1095,  1096,  1097,
+    1098,  1099,  1102,  1121,  1125,  1131,  1135,  1139,  1143,  1152,
+    1161,  1165,  1170,  1176,  1187,  1187,  1188,  1190,  1194,  1198,
+    1202,  1208,  1208,  1210,  1228,  1254,  1257,  1268,  1274,  1280,
+    1281,  1288,  1294,  1300,  1308,  1314,  1320,  1328,  1334,  1340,
+    1348,  1349,  1352,  1353,  1354,  1355,  1356,  1357,  1358,  1359,
+    1360,  1361,  1362,  1365,  1374,  1378,  1382,  1388,  1397,  1401,
+    1405,  1414,  1418,  1424,  1430,  1437,  1442,  1450,  1460,  1462,
+    1470,  1476,  1480,  1484,  1490,  1501,  1510,  1514,  1519,  1523,
+    1527,  1531,  1537,  1544,  1548,  1554,  1562,  1573,  1580,  1584,
+    1590,  1600,  1611,  1615,  1633,  1642,  1645,  1651,  1655,  1659,
+    1665,  1676,  1681,  1686,  1691,  1696,  1701,  1709,  1712,  1717,
+    1730,  1738,  1749,  1757,  1757,  1759,  1759,  1761,  1771,  1776,
+    1783,  1793,  1802,  1807,  1814,  1824,  1834,  1846,  1846,  1847,
+    1847,  1849,  1859,  1867,  1877,  1885,  1893,  1902,  1913,  1917,
+    1923,  1924,  1925,  1928,  1928,  1931,  1966,  1970,  1970,  1973,
+    1980,  1989,  2003,  2012,  2021,  2025,  2034,  2043,  2054,  2061,
+    2066,  2075,  2087,  2090,  2099,  2110,  2111,  2112,  2115,  2116,
+    2117,  2120,  2121,  2124,  2125,  2128,  2129,  2132,  2143,  2154,
+    2165,  2191,  2192
 };
 #endif
 
@@ -2125,7 +2129,7 @@
         case 3:
 
 /* Line 1455 of yacc.c  */
-#line 278 "program_parse.y"
+#line 282 "program_parse.y"
     {
 	   if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid fragment program header");
@@ -2138,7 +2142,7 @@
   case 4:
 
 /* Line 1455 of yacc.c  */
-#line 286 "program_parse.y"
+#line 290 "program_parse.y"
     {
 	   if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex program header");
@@ -2153,7 +2157,7 @@
   case 7:
 
 /* Line 1455 of yacc.c  */
-#line 302 "program_parse.y"
+#line 306 "program_parse.y"
     {
 	   int valid = 0;
 
@@ -2164,6 +2168,8 @@
 	   }
 
 
+	   free((yyvsp[(2) - (3)].string));
+
 	   if (!valid) {
 	      const char *const err_str = (state->mode == ARB_vertex)
 		 ? "invalid ARB vertex program option"
@@ -2178,7 +2184,7 @@
   case 10:
 
 /* Line 1455 of yacc.c  */
-#line 328 "program_parse.y"
+#line 334 "program_parse.y"
     {
 	   if ((yyvsp[(1) - (2)].inst) != NULL) {
 	      if (state->inst_tail == NULL) {
@@ -2198,7 +2204,7 @@
   case 12:
 
 /* Line 1455 of yacc.c  */
-#line 346 "program_parse.y"
+#line 352 "program_parse.y"
     {
 	   (yyval.inst) = (yyvsp[(1) - (1)].inst);
 	   state->prog->NumAluInstructions++;
@@ -2208,7 +2214,7 @@
   case 13:
 
 /* Line 1455 of yacc.c  */
-#line 351 "program_parse.y"
+#line 357 "program_parse.y"
     {
 	   (yyval.inst) = (yyvsp[(1) - (1)].inst);
 	   state->prog->NumTexInstructions++;
@@ -2218,7 +2224,7 @@
   case 24:
 
 /* Line 1455 of yacc.c  */
-#line 372 "program_parse.y"
+#line 378 "program_parse.y"
     {
 	   (yyval.inst) = asm_instruction_ctor(OPCODE_ARL, & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL);
 	;}
@@ -2227,7 +2233,7 @@
   case 25:
 
 /* Line 1455 of yacc.c  */
-#line 378 "program_parse.y"
+#line 384 "program_parse.y"
     {
 	   (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (4)].temp_inst), & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL);
 	;}
@@ -2236,7 +2242,7 @@
   case 26:
 
 /* Line 1455 of yacc.c  */
-#line 384 "program_parse.y"
+#line 390 "program_parse.y"
     {
 	   (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (4)].temp_inst), & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL);
 	;}
@@ -2245,7 +2251,7 @@
   case 27:
 
 /* Line 1455 of yacc.c  */
-#line 390 "program_parse.y"
+#line 396 "program_parse.y"
     {
 	   (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (6)].temp_inst), & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), & (yyvsp[(6) - (6)].src_reg), NULL);
 	;}
@@ -2254,7 +2260,7 @@
   case 28:
 
 /* Line 1455 of yacc.c  */
-#line 397 "program_parse.y"
+#line 403 "program_parse.y"
     {
 	   (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (6)].temp_inst), & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), & (yyvsp[(6) - (6)].src_reg), NULL);
 	;}
@@ -2263,7 +2269,7 @@
   case 29:
 
 /* Line 1455 of yacc.c  */
-#line 404 "program_parse.y"
+#line 410 "program_parse.y"
     {
 	   (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (8)].temp_inst), & (yyvsp[(2) - (8)].dst_reg), & (yyvsp[(4) - (8)].src_reg), & (yyvsp[(6) - (8)].src_reg), & (yyvsp[(8) - (8)].src_reg));
 	;}
@@ -2272,7 +2278,7 @@
   case 30:
 
 /* Line 1455 of yacc.c  */
-#line 410 "program_parse.y"
+#line 416 "program_parse.y"
     {
 	   (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (8)].temp_inst), & (yyvsp[(2) - (8)].dst_reg), & (yyvsp[(4) - (8)].src_reg), NULL, NULL);
 	   if ((yyval.inst) != NULL) {
@@ -2319,7 +2325,7 @@
   case 31:
 
 /* Line 1455 of yacc.c  */
-#line 454 "program_parse.y"
+#line 460 "program_parse.y"
     {
 	   (yyval.inst) = asm_instruction_ctor(OPCODE_KIL, NULL, & (yyvsp[(2) - (2)].src_reg), NULL, NULL);
 	   state->fragment.UsesKill = 1;
@@ -2329,7 +2335,7 @@
   case 32:
 
 /* Line 1455 of yacc.c  */
-#line 459 "program_parse.y"
+#line 465 "program_parse.y"
     {
 	   (yyval.inst) = asm_instruction_ctor(OPCODE_KIL_NV, NULL, NULL, NULL, NULL);
 	   (yyval.inst)->Base.DstReg.CondMask = (yyvsp[(2) - (2)].dst_reg).CondMask;
@@ -2342,7 +2348,7 @@
   case 33:
 
 /* Line 1455 of yacc.c  */
-#line 469 "program_parse.y"
+#line 475 "program_parse.y"
     {
 	   (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (12)].temp_inst), & (yyvsp[(2) - (12)].dst_reg), & (yyvsp[(4) - (12)].src_reg), & (yyvsp[(6) - (12)].src_reg), & (yyvsp[(8) - (12)].src_reg));
 	   if ((yyval.inst) != NULL) {
@@ -2389,7 +2395,7 @@
   case 34:
 
 /* Line 1455 of yacc.c  */
-#line 513 "program_parse.y"
+#line 519 "program_parse.y"
     {
 	   (yyval.integer) = (yyvsp[(2) - (2)].integer);
 	;}
@@ -2398,91 +2404,91 @@
   case 35:
 
 /* Line 1455 of yacc.c  */
-#line 518 "program_parse.y"
+#line 524 "program_parse.y"
     { (yyval.integer) = TEXTURE_1D_INDEX; ;}
     break;
 
   case 36:
 
 /* Line 1455 of yacc.c  */
-#line 519 "program_parse.y"
+#line 525 "program_parse.y"
     { (yyval.integer) = TEXTURE_2D_INDEX; ;}
     break;
 
   case 37:
 
 /* Line 1455 of yacc.c  */
-#line 520 "program_parse.y"
+#line 526 "program_parse.y"
     { (yyval.integer) = TEXTURE_3D_INDEX; ;}
     break;
 
   case 38:
 
 /* Line 1455 of yacc.c  */
-#line 521 "program_parse.y"
+#line 527 "program_parse.y"
     { (yyval.integer) = TEXTURE_CUBE_INDEX; ;}
     break;
 
   case 39:
 
 /* Line 1455 of yacc.c  */
-#line 522 "program_parse.y"
+#line 528 "program_parse.y"
     { (yyval.integer) = TEXTURE_RECT_INDEX; ;}
     break;
 
   case 40:
 
 /* Line 1455 of yacc.c  */
-#line 523 "program_parse.y"
+#line 529 "program_parse.y"
     { (yyval.integer) = -TEXTURE_1D_INDEX; ;}
     break;
 
   case 41:
 
 /* Line 1455 of yacc.c  */
-#line 524 "program_parse.y"
+#line 530 "program_parse.y"
     { (yyval.integer) = -TEXTURE_2D_INDEX; ;}
     break;
 
   case 42:
 
 /* Line 1455 of yacc.c  */
-#line 525 "program_parse.y"
+#line 531 "program_parse.y"
     { (yyval.integer) = -TEXTURE_RECT_INDEX; ;}
     break;
 
   case 43:
 
 /* Line 1455 of yacc.c  */
-#line 526 "program_parse.y"
+#line 532 "program_parse.y"
     { (yyval.integer) = TEXTURE_1D_ARRAY_INDEX; ;}
     break;
 
   case 44:
 
 /* Line 1455 of yacc.c  */
-#line 527 "program_parse.y"
+#line 533 "program_parse.y"
     { (yyval.integer) = TEXTURE_2D_ARRAY_INDEX; ;}
     break;
 
   case 45:
 
 /* Line 1455 of yacc.c  */
-#line 528 "program_parse.y"
+#line 534 "program_parse.y"
     { (yyval.integer) = -TEXTURE_1D_ARRAY_INDEX; ;}
     break;
 
   case 46:
 
 /* Line 1455 of yacc.c  */
-#line 529 "program_parse.y"
+#line 535 "program_parse.y"
     { (yyval.integer) = -TEXTURE_2D_ARRAY_INDEX; ;}
     break;
 
   case 47:
 
 /* Line 1455 of yacc.c  */
-#line 533 "program_parse.y"
+#line 539 "program_parse.y"
     {
 	   /* FIXME: Is this correct?  Should the extenedSwizzle be applied
 	    * FIXME: to the existing swizzle?
@@ -2497,7 +2503,7 @@
   case 48:
 
 /* Line 1455 of yacc.c  */
-#line 545 "program_parse.y"
+#line 551 "program_parse.y"
     {
 	   (yyval.src_reg) = (yyvsp[(2) - (2)].src_reg);
 
@@ -2510,7 +2516,7 @@
   case 49:
 
 /* Line 1455 of yacc.c  */
-#line 553 "program_parse.y"
+#line 559 "program_parse.y"
     {
 	   (yyval.src_reg) = (yyvsp[(3) - (4)].src_reg);
 
@@ -2530,7 +2536,7 @@
   case 50:
 
 /* Line 1455 of yacc.c  */
-#line 570 "program_parse.y"
+#line 576 "program_parse.y"
     {
 	   (yyval.src_reg) = (yyvsp[(1) - (2)].src_reg);
 
@@ -2542,7 +2548,7 @@
   case 51:
 
 /* Line 1455 of yacc.c  */
-#line 577 "program_parse.y"
+#line 583 "program_parse.y"
     {
 	   struct asm_symbol temp_sym;
 
@@ -2553,16 +2559,18 @@
 
 	   memset(& temp_sym, 0, sizeof(temp_sym));
 	   temp_sym.param_binding_begin = ~0;
-	   initialize_symbol_from_const(state->prog, & temp_sym, & (yyvsp[(1) - (1)].vector));
+	   initialize_symbol_from_const(state->prog, & temp_sym, & (yyvsp[(1) - (1)].vector), GL_TRUE);
 
-	   set_src_reg(& (yyval.src_reg), PROGRAM_CONSTANT, temp_sym.param_binding_begin);
+	   set_src_reg_swz(& (yyval.src_reg), PROGRAM_CONSTANT,
+                           temp_sym.param_binding_begin,
+                           temp_sym.param_binding_swizzle);
 	;}
     break;
 
   case 52:
 
 /* Line 1455 of yacc.c  */
-#line 594 "program_parse.y"
+#line 602 "program_parse.y"
     {
 	   (yyval.src_reg) = (yyvsp[(2) - (3)].src_reg);
 
@@ -2578,7 +2586,7 @@
   case 53:
 
 /* Line 1455 of yacc.c  */
-#line 605 "program_parse.y"
+#line 613 "program_parse.y"
     {
 	   (yyval.src_reg) = (yyvsp[(3) - (5)].src_reg);
 
@@ -2600,7 +2608,7 @@
   case 54:
 
 /* Line 1455 of yacc.c  */
-#line 625 "program_parse.y"
+#line 633 "program_parse.y"
     {
 	   (yyval.dst_reg) = (yyvsp[(1) - (3)].dst_reg);
 	   (yyval.dst_reg).WriteMask = (yyvsp[(2) - (3)].swiz_mask).mask;
@@ -2620,7 +2628,7 @@
 		 YYERROR;
 	      }
 
-	      state->prog->OutputsWritten |= (1U << (yyval.dst_reg).Index);
+	      state->prog->OutputsWritten |= BITFIELD64_BIT((yyval.dst_reg).Index);
 	   }
 	;}
     break;
@@ -2628,7 +2636,7 @@
   case 55:
 
 /* Line 1455 of yacc.c  */
-#line 650 "program_parse.y"
+#line 658 "program_parse.y"
     {
 	   set_dst_reg(& (yyval.dst_reg), PROGRAM_ADDRESS, 0);
 	   (yyval.dst_reg).WriteMask = (yyvsp[(2) - (2)].swiz_mask).mask;
@@ -2638,7 +2646,7 @@
   case 56:
 
 /* Line 1455 of yacc.c  */
-#line 657 "program_parse.y"
+#line 665 "program_parse.y"
     {
 	   const unsigned xyzw_valid =
 	      ((yyvsp[(1) - (7)].ext_swizzle).xyzw_valid << 0)
@@ -2674,7 +2682,7 @@
   case 57:
 
 /* Line 1455 of yacc.c  */
-#line 690 "program_parse.y"
+#line 698 "program_parse.y"
     {
 	   (yyval.ext_swizzle) = (yyvsp[(2) - (2)].ext_swizzle);
 	   (yyval.ext_swizzle).negate = ((yyvsp[(1) - (2)].negate)) ? 1 : 0;
@@ -2684,7 +2692,7 @@
   case 58:
 
 /* Line 1455 of yacc.c  */
-#line 697 "program_parse.y"
+#line 705 "program_parse.y"
     {
 	   if (((yyvsp[(1) - (1)].integer) != 0) && ((yyvsp[(1) - (1)].integer) != 1)) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector");
@@ -2704,14 +2712,19 @@
   case 59:
 
 /* Line 1455 of yacc.c  */
-#line 712 "program_parse.y"
+#line 720 "program_parse.y"
     {
+	   char s;
+
 	   if (strlen((yyvsp[(1) - (1)].string)) > 1) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector");
 	      YYERROR;
 	   }
 
-	   switch ((yyvsp[(1) - (1)].string)[0]) {
+	   s = (yyvsp[(1) - (1)].string)[0];
+	   free((yyvsp[(1) - (1)].string));
+
+	   switch (s) {
 	   case 'x':
 	      (yyval.ext_swizzle).swz = SWIZZLE_X;
 	      (yyval.ext_swizzle).xyzw_valid = 1;
@@ -2757,11 +2770,13 @@
   case 60:
 
 /* Line 1455 of yacc.c  */
-#line 762 "program_parse.y"
+#line 775 "program_parse.y"
     {
 	   struct asm_symbol *const s = (struct asm_symbol *)
 	      _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
 
+	   free((yyvsp[(1) - (1)].string));
+
 	   if (s == NULL) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
 	      YYERROR;
@@ -2780,7 +2795,9 @@
 	      set_src_reg(& (yyval.src_reg), PROGRAM_TEMPORARY, s->temp_binding);
 	      break;
 	   case at_param:
-	      set_src_reg(& (yyval.src_reg), s->param_binding_type, s->param_binding_begin);
+              set_src_reg_swz(& (yyval.src_reg), s->param_binding_type,
+                              s->param_binding_begin,
+                              s->param_binding_swizzle);
 	      break;
 	   case at_attrib:
 	      set_src_reg(& (yyval.src_reg), PROGRAM_INPUT, s->attrib_binding);
@@ -2801,7 +2818,7 @@
   case 61:
 
 /* Line 1455 of yacc.c  */
-#line 801 "program_parse.y"
+#line 818 "program_parse.y"
     {
 	   set_src_reg(& (yyval.src_reg), PROGRAM_INPUT, (yyvsp[(1) - (1)].attrib));
 	   state->prog->InputsRead |= (1U << (yyval.src_reg).Base.Index);
@@ -2815,7 +2832,7 @@
   case 62:
 
 /* Line 1455 of yacc.c  */
-#line 810 "program_parse.y"
+#line 827 "program_parse.y"
     {
 	   if (! (yyvsp[(3) - (4)].src_reg).Base.RelAddr
 	       && ((unsigned) (yyvsp[(3) - (4)].src_reg).Base.Index >= (yyvsp[(1) - (4)].sym)->param_binding_length)) {
@@ -2841,19 +2858,20 @@
   case 63:
 
 /* Line 1455 of yacc.c  */
-#line 831 "program_parse.y"
+#line 848 "program_parse.y"
     {
            gl_register_file file = ((yyvsp[(1) - (1)].temp_sym).name != NULL) 
 	      ? (yyvsp[(1) - (1)].temp_sym).param_binding_type
 	      : PROGRAM_CONSTANT;
-	   set_src_reg(& (yyval.src_reg), file, (yyvsp[(1) - (1)].temp_sym).param_binding_begin);
+           set_src_reg_swz(& (yyval.src_reg), file, (yyvsp[(1) - (1)].temp_sym).param_binding_begin,
+                           (yyvsp[(1) - (1)].temp_sym).param_binding_swizzle);
 	;}
     break;
 
   case 64:
 
 /* Line 1455 of yacc.c  */
-#line 840 "program_parse.y"
+#line 858 "program_parse.y"
     {
 	   set_dst_reg(& (yyval.dst_reg), PROGRAM_OUTPUT, (yyvsp[(1) - (1)].result));
 	;}
@@ -2862,11 +2880,13 @@
   case 65:
 
 /* Line 1455 of yacc.c  */
-#line 844 "program_parse.y"
+#line 862 "program_parse.y"
     {
 	   struct asm_symbol *const s = (struct asm_symbol *)
 	      _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
 
+	   free((yyvsp[(1) - (1)].string));
+
 	   if (s == NULL) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
 	      YYERROR;
@@ -2892,11 +2912,13 @@
   case 66:
 
 /* Line 1455 of yacc.c  */
-#line 871 "program_parse.y"
+#line 891 "program_parse.y"
     {
 	   struct asm_symbol *const s = (struct asm_symbol *)
 	      _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
 
+	   free((yyvsp[(1) - (1)].string));
+
 	   if (s == NULL) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
 	      YYERROR;
@@ -2912,7 +2934,7 @@
   case 69:
 
 /* Line 1455 of yacc.c  */
-#line 890 "program_parse.y"
+#line 912 "program_parse.y"
     {
 	   init_src_reg(& (yyval.src_reg));
 	   (yyval.src_reg).Base.Index = (yyvsp[(1) - (1)].integer);
@@ -2922,7 +2944,7 @@
   case 70:
 
 /* Line 1455 of yacc.c  */
-#line 897 "program_parse.y"
+#line 919 "program_parse.y"
     {
 	   /* FINISHME: Add support for multiple address registers.
 	    */
@@ -2937,28 +2959,28 @@
   case 71:
 
 /* Line 1455 of yacc.c  */
-#line 908 "program_parse.y"
+#line 930 "program_parse.y"
     { (yyval.integer) = 0; ;}
     break;
 
   case 72:
 
 /* Line 1455 of yacc.c  */
-#line 909 "program_parse.y"
+#line 931 "program_parse.y"
     { (yyval.integer) = (yyvsp[(2) - (2)].integer); ;}
     break;
 
   case 73:
 
 /* Line 1455 of yacc.c  */
-#line 910 "program_parse.y"
+#line 932 "program_parse.y"
     { (yyval.integer) = -(yyvsp[(2) - (2)].integer); ;}
     break;
 
   case 74:
 
 /* Line 1455 of yacc.c  */
-#line 914 "program_parse.y"
+#line 936 "program_parse.y"
     {
 	   if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 63)) {
               char s[100];
@@ -2975,7 +2997,7 @@
   case 75:
 
 /* Line 1455 of yacc.c  */
-#line 928 "program_parse.y"
+#line 950 "program_parse.y"
     {
 	   if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 64)) {
               char s[100];
@@ -2992,11 +3014,13 @@
   case 76:
 
 /* Line 1455 of yacc.c  */
-#line 942 "program_parse.y"
+#line 964 "program_parse.y"
     {
 	   struct asm_symbol *const s = (struct asm_symbol *)
 	      _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
 
+	   free((yyvsp[(1) - (1)].string));
+
 	   if (s == NULL) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid array member");
 	      YYERROR;
@@ -3013,7 +3037,7 @@
   case 77:
 
 /* Line 1455 of yacc.c  */
-#line 960 "program_parse.y"
+#line 984 "program_parse.y"
     {
 	   if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid address component selector");
@@ -3027,7 +3051,7 @@
   case 78:
 
 /* Line 1455 of yacc.c  */
-#line 971 "program_parse.y"
+#line 995 "program_parse.y"
     {
 	   if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) {
 	      yyerror(& (yylsp[(1) - (1)]), state,
@@ -3042,21 +3066,21 @@
   case 83:
 
 /* Line 1455 of yacc.c  */
-#line 987 "program_parse.y"
+#line 1011 "program_parse.y"
     { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;}
     break;
 
   case 88:
 
 /* Line 1455 of yacc.c  */
-#line 991 "program_parse.y"
+#line 1015 "program_parse.y"
     { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;}
     break;
 
   case 89:
 
 /* Line 1455 of yacc.c  */
-#line 995 "program_parse.y"
+#line 1019 "program_parse.y"
     {
 	   (yyval.dst_reg) = (yyvsp[(2) - (3)].dst_reg);
 	;}
@@ -3065,7 +3089,7 @@
   case 90:
 
 /* Line 1455 of yacc.c  */
-#line 999 "program_parse.y"
+#line 1023 "program_parse.y"
     {
 	   (yyval.dst_reg) = (yyvsp[(2) - (3)].dst_reg);
 	;}
@@ -3074,7 +3098,7 @@
   case 91:
 
 /* Line 1455 of yacc.c  */
-#line 1003 "program_parse.y"
+#line 1027 "program_parse.y"
     {
 	   (yyval.dst_reg).CondMask = COND_TR;
 	   (yyval.dst_reg).CondSwizzle = SWIZZLE_NOOP;
@@ -3085,7 +3109,7 @@
   case 92:
 
 /* Line 1455 of yacc.c  */
-#line 1011 "program_parse.y"
+#line 1035 "program_parse.y"
     {
 	   (yyval.dst_reg) = (yyvsp[(1) - (2)].dst_reg);
 	   (yyval.dst_reg).CondSwizzle = (yyvsp[(2) - (2)].swiz_mask).swizzle;
@@ -3095,7 +3119,7 @@
   case 93:
 
 /* Line 1455 of yacc.c  */
-#line 1018 "program_parse.y"
+#line 1042 "program_parse.y"
     {
 	   (yyval.dst_reg) = (yyvsp[(1) - (2)].dst_reg);
 	   (yyval.dst_reg).CondSwizzle = (yyvsp[(2) - (2)].swiz_mask).swizzle;
@@ -3105,7 +3129,7 @@
   case 94:
 
 /* Line 1455 of yacc.c  */
-#line 1025 "program_parse.y"
+#line 1049 "program_parse.y"
     {
 	   const int cond = _mesa_parse_cc((yyvsp[(1) - (1)].string));
 	   if ((cond == 0) || ((yyvsp[(1) - (1)].string)[2] != '\0')) {
@@ -3131,7 +3155,7 @@
   case 95:
 
 /* Line 1455 of yacc.c  */
-#line 1048 "program_parse.y"
+#line 1072 "program_parse.y"
     {
 	   const int cond = _mesa_parse_cc((yyvsp[(1) - (1)].string));
 	   if ((cond == 0) || ((yyvsp[(1) - (1)].string)[2] != '\0')) {
@@ -3157,12 +3181,13 @@
   case 102:
 
 /* Line 1455 of yacc.c  */
-#line 1079 "program_parse.y"
+#line 1103 "program_parse.y"
     {
 	   struct asm_symbol *const s =
 	      declare_variable(state, (yyvsp[(2) - (4)].string), at_attrib, & (yylsp[(2) - (4)]));
 
 	   if (s == NULL) {
+	      free((yyvsp[(2) - (4)].string));
 	      YYERROR;
 	   } else {
 	      s->attrib_binding = (yyvsp[(4) - (4)].attrib);
@@ -3178,7 +3203,7 @@
   case 103:
 
 /* Line 1455 of yacc.c  */
-#line 1097 "program_parse.y"
+#line 1122 "program_parse.y"
     {
 	   (yyval.attrib) = (yyvsp[(2) - (2)].attrib);
 	;}
@@ -3187,7 +3212,7 @@
   case 104:
 
 /* Line 1455 of yacc.c  */
-#line 1101 "program_parse.y"
+#line 1126 "program_parse.y"
     {
 	   (yyval.attrib) = (yyvsp[(2) - (2)].attrib);
 	;}
@@ -3196,7 +3221,7 @@
   case 105:
 
 /* Line 1455 of yacc.c  */
-#line 1107 "program_parse.y"
+#line 1132 "program_parse.y"
     {
 	   (yyval.attrib) = VERT_ATTRIB_POS;
 	;}
@@ -3205,7 +3230,7 @@
   case 106:
 
 /* Line 1455 of yacc.c  */
-#line 1111 "program_parse.y"
+#line 1136 "program_parse.y"
     {
 	   (yyval.attrib) = VERT_ATTRIB_WEIGHT;
 	;}
@@ -3214,7 +3239,7 @@
   case 107:
 
 /* Line 1455 of yacc.c  */
-#line 1115 "program_parse.y"
+#line 1140 "program_parse.y"
     {
 	   (yyval.attrib) = VERT_ATTRIB_NORMAL;
 	;}
@@ -3223,7 +3248,7 @@
   case 108:
 
 /* Line 1455 of yacc.c  */
-#line 1119 "program_parse.y"
+#line 1144 "program_parse.y"
     {
 	   if (!state->ctx->Extensions.EXT_secondary_color) {
 	      yyerror(& (yylsp[(2) - (2)]), state, "GL_EXT_secondary_color not supported");
@@ -3237,7 +3262,7 @@
   case 109:
 
 /* Line 1455 of yacc.c  */
-#line 1128 "program_parse.y"
+#line 1153 "program_parse.y"
     {
 	   if (!state->ctx->Extensions.EXT_fog_coord) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "GL_EXT_fog_coord not supported");
@@ -3251,7 +3276,7 @@
   case 110:
 
 /* Line 1455 of yacc.c  */
-#line 1137 "program_parse.y"
+#line 1162 "program_parse.y"
     {
 	   (yyval.attrib) = VERT_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer);
 	;}
@@ -3260,7 +3285,7 @@
   case 111:
 
 /* Line 1455 of yacc.c  */
-#line 1141 "program_parse.y"
+#line 1166 "program_parse.y"
     {
 	   yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported");
 	   YYERROR;
@@ -3270,7 +3295,7 @@
   case 112:
 
 /* Line 1455 of yacc.c  */
-#line 1146 "program_parse.y"
+#line 1171 "program_parse.y"
     {
 	   (yyval.attrib) = VERT_ATTRIB_GENERIC0 + (yyvsp[(3) - (4)].integer);
 	;}
@@ -3279,7 +3304,7 @@
   case 113:
 
 /* Line 1455 of yacc.c  */
-#line 1152 "program_parse.y"
+#line 1177 "program_parse.y"
     {
 	   if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxAttribs) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex attribute reference");
@@ -3293,7 +3318,7 @@
   case 117:
 
 /* Line 1455 of yacc.c  */
-#line 1166 "program_parse.y"
+#line 1191 "program_parse.y"
     {
 	   (yyval.attrib) = FRAG_ATTRIB_WPOS;
 	;}
@@ -3302,7 +3327,7 @@
   case 118:
 
 /* Line 1455 of yacc.c  */
-#line 1170 "program_parse.y"
+#line 1195 "program_parse.y"
     {
 	   (yyval.attrib) = FRAG_ATTRIB_COL0 + (yyvsp[(2) - (2)].integer);
 	;}
@@ -3311,7 +3336,7 @@
   case 119:
 
 /* Line 1455 of yacc.c  */
-#line 1174 "program_parse.y"
+#line 1199 "program_parse.y"
     {
 	   (yyval.attrib) = FRAG_ATTRIB_FOGC;
 	;}
@@ -3320,7 +3345,7 @@
   case 120:
 
 /* Line 1455 of yacc.c  */
-#line 1178 "program_parse.y"
+#line 1203 "program_parse.y"
     {
 	   (yyval.attrib) = FRAG_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer);
 	;}
@@ -3329,17 +3354,19 @@
   case 123:
 
 /* Line 1455 of yacc.c  */
-#line 1186 "program_parse.y"
+#line 1211 "program_parse.y"
     {
 	   struct asm_symbol *const s =
 	      declare_variable(state, (yyvsp[(2) - (3)].string), at_param, & (yylsp[(2) - (3)]));
 
 	   if (s == NULL) {
+	      free((yyvsp[(2) - (3)].string));
 	      YYERROR;
 	   } else {
 	      s->param_binding_type = (yyvsp[(3) - (3)].temp_sym).param_binding_type;
 	      s->param_binding_begin = (yyvsp[(3) - (3)].temp_sym).param_binding_begin;
 	      s->param_binding_length = (yyvsp[(3) - (3)].temp_sym).param_binding_length;
+              s->param_binding_swizzle = SWIZZLE_XYZW;
 	      s->param_is_array = 0;
 	   }
 	;}
@@ -3348,9 +3375,10 @@
   case 124:
 
 /* Line 1455 of yacc.c  */
-#line 1202 "program_parse.y"
+#line 1229 "program_parse.y"
     {
 	   if (((yyvsp[(4) - (6)].integer) != 0) && ((unsigned) (yyvsp[(4) - (6)].integer) != (yyvsp[(6) - (6)].temp_sym).param_binding_length)) {
+	      free((yyvsp[(2) - (6)].string));
 	      yyerror(& (yylsp[(4) - (6)]), state, 
 		      "parameter array size and number of bindings must match");
 	      YYERROR;
@@ -3359,11 +3387,13 @@
 		 declare_variable(state, (yyvsp[(2) - (6)].string), (yyvsp[(6) - (6)].temp_sym).type, & (yylsp[(2) - (6)]));
 
 	      if (s == NULL) {
+		 free((yyvsp[(2) - (6)].string));
 		 YYERROR;
 	      } else {
 		 s->param_binding_type = (yyvsp[(6) - (6)].temp_sym).param_binding_type;
 		 s->param_binding_begin = (yyvsp[(6) - (6)].temp_sym).param_binding_begin;
 		 s->param_binding_length = (yyvsp[(6) - (6)].temp_sym).param_binding_length;
+                 s->param_binding_swizzle = SWIZZLE_XYZW;
 		 s->param_is_array = 1;
 	      }
 	   }
@@ -3373,7 +3403,7 @@
   case 125:
 
 /* Line 1455 of yacc.c  */
-#line 1224 "program_parse.y"
+#line 1254 "program_parse.y"
     {
 	   (yyval.integer) = 0;
 	;}
@@ -3382,7 +3412,7 @@
   case 126:
 
 /* Line 1455 of yacc.c  */
-#line 1228 "program_parse.y"
+#line 1258 "program_parse.y"
     {
 	   if (((yyvsp[(1) - (1)].integer) < 1) || ((unsigned) (yyvsp[(1) - (1)].integer) > state->limits->MaxParameters)) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid parameter array size");
@@ -3396,7 +3426,7 @@
   case 127:
 
 /* Line 1455 of yacc.c  */
-#line 1239 "program_parse.y"
+#line 1269 "program_parse.y"
     {
 	   (yyval.temp_sym) = (yyvsp[(2) - (2)].temp_sym);
 	;}
@@ -3405,7 +3435,7 @@
   case 128:
 
 /* Line 1455 of yacc.c  */
-#line 1245 "program_parse.y"
+#line 1275 "program_parse.y"
     {
 	   (yyval.temp_sym) = (yyvsp[(3) - (4)].temp_sym);
 	;}
@@ -3414,7 +3444,7 @@
   case 130:
 
 /* Line 1455 of yacc.c  */
-#line 1252 "program_parse.y"
+#line 1282 "program_parse.y"
     {
 	   (yyvsp[(1) - (3)].temp_sym).param_binding_length += (yyvsp[(3) - (3)].temp_sym).param_binding_length;
 	   (yyval.temp_sym) = (yyvsp[(1) - (3)].temp_sym);
@@ -3424,7 +3454,7 @@
   case 131:
 
 /* Line 1455 of yacc.c  */
-#line 1259 "program_parse.y"
+#line 1289 "program_parse.y"
     {
 	   memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
 	   (yyval.temp_sym).param_binding_begin = ~0;
@@ -3435,7 +3465,7 @@
   case 132:
 
 /* Line 1455 of yacc.c  */
-#line 1265 "program_parse.y"
+#line 1295 "program_parse.y"
     {
 	   memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
 	   (yyval.temp_sym).param_binding_begin = ~0;
@@ -3446,18 +3476,18 @@
   case 133:
 
 /* Line 1455 of yacc.c  */
-#line 1271 "program_parse.y"
+#line 1301 "program_parse.y"
     {
 	   memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
 	   (yyval.temp_sym).param_binding_begin = ~0;
-	   initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector));
+	   initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector), GL_TRUE);
 	;}
     break;
 
   case 134:
 
 /* Line 1455 of yacc.c  */
-#line 1279 "program_parse.y"
+#line 1309 "program_parse.y"
     {
 	   memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
 	   (yyval.temp_sym).param_binding_begin = ~0;
@@ -3468,7 +3498,7 @@
   case 135:
 
 /* Line 1455 of yacc.c  */
-#line 1285 "program_parse.y"
+#line 1315 "program_parse.y"
     {
 	   memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
 	   (yyval.temp_sym).param_binding_begin = ~0;
@@ -3479,18 +3509,18 @@
   case 136:
 
 /* Line 1455 of yacc.c  */
-#line 1291 "program_parse.y"
+#line 1321 "program_parse.y"
     {
 	   memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
 	   (yyval.temp_sym).param_binding_begin = ~0;
-	   initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector));
+	   initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector), GL_TRUE);
 	;}
     break;
 
   case 137:
 
 /* Line 1455 of yacc.c  */
-#line 1299 "program_parse.y"
+#line 1329 "program_parse.y"
     {
 	   memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
 	   (yyval.temp_sym).param_binding_begin = ~0;
@@ -3501,7 +3531,7 @@
   case 138:
 
 /* Line 1455 of yacc.c  */
-#line 1305 "program_parse.y"
+#line 1335 "program_parse.y"
     {
 	   memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
 	   (yyval.temp_sym).param_binding_begin = ~0;
@@ -3512,109 +3542,109 @@
   case 139:
 
 /* Line 1455 of yacc.c  */
-#line 1311 "program_parse.y"
+#line 1341 "program_parse.y"
     {
 	   memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
 	   (yyval.temp_sym).param_binding_begin = ~0;
-	   initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector));
+	   initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector), GL_FALSE);
 	;}
     break;
 
   case 140:
 
 /* Line 1455 of yacc.c  */
-#line 1318 "program_parse.y"
+#line 1348 "program_parse.y"
     { memcpy((yyval.state), (yyvsp[(1) - (1)].state), sizeof((yyval.state))); ;}
     break;
 
   case 141:
 
 /* Line 1455 of yacc.c  */
-#line 1319 "program_parse.y"
+#line 1349 "program_parse.y"
     { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
     break;
 
   case 142:
 
 /* Line 1455 of yacc.c  */
-#line 1322 "program_parse.y"
+#line 1352 "program_parse.y"
     { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
     break;
 
   case 143:
 
 /* Line 1455 of yacc.c  */
-#line 1323 "program_parse.y"
+#line 1353 "program_parse.y"
     { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
     break;
 
   case 144:
 
 /* Line 1455 of yacc.c  */
-#line 1324 "program_parse.y"
+#line 1354 "program_parse.y"
     { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
     break;
 
   case 145:
 
 /* Line 1455 of yacc.c  */
-#line 1325 "program_parse.y"
+#line 1355 "program_parse.y"
     { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
     break;
 
   case 146:
 
 /* Line 1455 of yacc.c  */
-#line 1326 "program_parse.y"
+#line 1356 "program_parse.y"
     { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
     break;
 
   case 147:
 
 /* Line 1455 of yacc.c  */
-#line 1327 "program_parse.y"
+#line 1357 "program_parse.y"
     { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
     break;
 
   case 148:
 
 /* Line 1455 of yacc.c  */
-#line 1328 "program_parse.y"
+#line 1358 "program_parse.y"
     { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
     break;
 
   case 149:
 
 /* Line 1455 of yacc.c  */
-#line 1329 "program_parse.y"
+#line 1359 "program_parse.y"
     { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
     break;
 
   case 150:
 
 /* Line 1455 of yacc.c  */
-#line 1330 "program_parse.y"
+#line 1360 "program_parse.y"
     { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
     break;
 
   case 151:
 
 /* Line 1455 of yacc.c  */
-#line 1331 "program_parse.y"
+#line 1361 "program_parse.y"
     { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
     break;
 
   case 152:
 
 /* Line 1455 of yacc.c  */
-#line 1332 "program_parse.y"
+#line 1362 "program_parse.y"
     { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
     break;
 
   case 153:
 
 /* Line 1455 of yacc.c  */
-#line 1336 "program_parse.y"
+#line 1366 "program_parse.y"
     {
 	   memset((yyval.state), 0, sizeof((yyval.state)));
 	   (yyval.state)[0] = STATE_MATERIAL;
@@ -3626,7 +3656,7 @@
   case 154:
 
 /* Line 1455 of yacc.c  */
-#line 1345 "program_parse.y"
+#line 1375 "program_parse.y"
     {
 	   (yyval.integer) = (yyvsp[(1) - (1)].integer);
 	;}
@@ -3635,7 +3665,7 @@
   case 155:
 
 /* Line 1455 of yacc.c  */
-#line 1349 "program_parse.y"
+#line 1379 "program_parse.y"
     {
 	   (yyval.integer) = STATE_EMISSION;
 	;}
@@ -3644,7 +3674,7 @@
   case 156:
 
 /* Line 1455 of yacc.c  */
-#line 1353 "program_parse.y"
+#line 1383 "program_parse.y"
     {
 	   (yyval.integer) = STATE_SHININESS;
 	;}
@@ -3653,7 +3683,7 @@
   case 157:
 
 /* Line 1455 of yacc.c  */
-#line 1359 "program_parse.y"
+#line 1389 "program_parse.y"
     {
 	   memset((yyval.state), 0, sizeof((yyval.state)));
 	   (yyval.state)[0] = STATE_LIGHT;
@@ -3665,7 +3695,7 @@
   case 158:
 
 /* Line 1455 of yacc.c  */
-#line 1368 "program_parse.y"
+#line 1398 "program_parse.y"
     {
 	   (yyval.integer) = (yyvsp[(1) - (1)].integer);
 	;}
@@ -3674,7 +3704,7 @@
   case 159:
 
 /* Line 1455 of yacc.c  */
-#line 1372 "program_parse.y"
+#line 1402 "program_parse.y"
     {
 	   (yyval.integer) = STATE_POSITION;
 	;}
@@ -3683,7 +3713,7 @@
   case 160:
 
 /* Line 1455 of yacc.c  */
-#line 1376 "program_parse.y"
+#line 1406 "program_parse.y"
     {
 	   if (!state->ctx->Extensions.EXT_point_parameters) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "GL_ARB_point_parameters not supported");
@@ -3697,7 +3727,7 @@
   case 161:
 
 /* Line 1455 of yacc.c  */
-#line 1385 "program_parse.y"
+#line 1415 "program_parse.y"
     {
 	   (yyval.integer) = (yyvsp[(2) - (2)].integer);
 	;}
@@ -3706,7 +3736,7 @@
   case 162:
 
 /* Line 1455 of yacc.c  */
-#line 1389 "program_parse.y"
+#line 1419 "program_parse.y"
     {
 	   (yyval.integer) = STATE_HALF_VECTOR;
 	;}
@@ -3715,7 +3745,7 @@
   case 163:
 
 /* Line 1455 of yacc.c  */
-#line 1395 "program_parse.y"
+#line 1425 "program_parse.y"
     {
 	   (yyval.integer) = STATE_SPOT_DIRECTION;
 	;}
@@ -3724,7 +3754,7 @@
   case 164:
 
 /* Line 1455 of yacc.c  */
-#line 1401 "program_parse.y"
+#line 1431 "program_parse.y"
     {
 	   (yyval.state)[0] = (yyvsp[(2) - (2)].state)[0];
 	   (yyval.state)[1] = (yyvsp[(2) - (2)].state)[1];
@@ -3734,7 +3764,7 @@
   case 165:
 
 /* Line 1455 of yacc.c  */
-#line 1408 "program_parse.y"
+#line 1438 "program_parse.y"
     {
 	   memset((yyval.state), 0, sizeof((yyval.state)));
 	   (yyval.state)[0] = STATE_LIGHTMODEL_AMBIENT;
@@ -3744,7 +3774,7 @@
   case 166:
 
 /* Line 1455 of yacc.c  */
-#line 1413 "program_parse.y"
+#line 1443 "program_parse.y"
     {
 	   memset((yyval.state), 0, sizeof((yyval.state)));
 	   (yyval.state)[0] = STATE_LIGHTMODEL_SCENECOLOR;
@@ -3755,7 +3785,7 @@
   case 167:
 
 /* Line 1455 of yacc.c  */
-#line 1421 "program_parse.y"
+#line 1451 "program_parse.y"
     {
 	   memset((yyval.state), 0, sizeof((yyval.state)));
 	   (yyval.state)[0] = STATE_LIGHTPROD;
@@ -3768,7 +3798,7 @@
   case 169:
 
 /* Line 1455 of yacc.c  */
-#line 1433 "program_parse.y"
+#line 1463 "program_parse.y"
     {
 	   memset((yyval.state), 0, sizeof((yyval.state)));
 	   (yyval.state)[0] = (yyvsp[(3) - (3)].integer);
@@ -3779,7 +3809,7 @@
   case 170:
 
 /* Line 1455 of yacc.c  */
-#line 1441 "program_parse.y"
+#line 1471 "program_parse.y"
     {
 	   (yyval.integer) = STATE_TEXENV_COLOR;
 	;}
@@ -3788,7 +3818,7 @@
   case 171:
 
 /* Line 1455 of yacc.c  */
-#line 1447 "program_parse.y"
+#line 1477 "program_parse.y"
     {
 	   (yyval.integer) = STATE_AMBIENT;
 	;}
@@ -3797,7 +3827,7 @@
   case 172:
 
 /* Line 1455 of yacc.c  */
-#line 1451 "program_parse.y"
+#line 1481 "program_parse.y"
     {
 	   (yyval.integer) = STATE_DIFFUSE;
 	;}
@@ -3806,7 +3836,7 @@
   case 173:
 
 /* Line 1455 of yacc.c  */
-#line 1455 "program_parse.y"
+#line 1485 "program_parse.y"
     {
 	   (yyval.integer) = STATE_SPECULAR;
 	;}
@@ -3815,7 +3845,7 @@
   case 174:
 
 /* Line 1455 of yacc.c  */
-#line 1461 "program_parse.y"
+#line 1491 "program_parse.y"
     {
 	   if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxLights) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid light selector");
@@ -3829,7 +3859,7 @@
   case 175:
 
 /* Line 1455 of yacc.c  */
-#line 1472 "program_parse.y"
+#line 1502 "program_parse.y"
     {
 	   memset((yyval.state), 0, sizeof((yyval.state)));
 	   (yyval.state)[0] = STATE_TEXGEN;
@@ -3841,7 +3871,7 @@
   case 176:
 
 /* Line 1455 of yacc.c  */
-#line 1481 "program_parse.y"
+#line 1511 "program_parse.y"
     {
 	   (yyval.integer) = STATE_TEXGEN_EYE_S;
 	;}
@@ -3850,7 +3880,7 @@
   case 177:
 
 /* Line 1455 of yacc.c  */
-#line 1485 "program_parse.y"
+#line 1515 "program_parse.y"
     {
 	   (yyval.integer) = STATE_TEXGEN_OBJECT_S;
 	;}
@@ -3859,7 +3889,7 @@
   case 178:
 
 /* Line 1455 of yacc.c  */
-#line 1490 "program_parse.y"
+#line 1520 "program_parse.y"
     {
 	   (yyval.integer) = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S;
 	;}
@@ -3868,7 +3898,7 @@
   case 179:
 
 /* Line 1455 of yacc.c  */
-#line 1494 "program_parse.y"
+#line 1524 "program_parse.y"
     {
 	   (yyval.integer) = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S;
 	;}
@@ -3877,7 +3907,7 @@
   case 180:
 
 /* Line 1455 of yacc.c  */
-#line 1498 "program_parse.y"
+#line 1528 "program_parse.y"
     {
 	   (yyval.integer) = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S;
 	;}
@@ -3886,7 +3916,7 @@
   case 181:
 
 /* Line 1455 of yacc.c  */
-#line 1502 "program_parse.y"
+#line 1532 "program_parse.y"
     {
 	   (yyval.integer) = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S;
 	;}
@@ -3895,7 +3925,7 @@
   case 182:
 
 /* Line 1455 of yacc.c  */
-#line 1508 "program_parse.y"
+#line 1538 "program_parse.y"
     {
 	   memset((yyval.state), 0, sizeof((yyval.state)));
 	   (yyval.state)[0] = (yyvsp[(2) - (2)].integer);
@@ -3905,7 +3935,7 @@
   case 183:
 
 /* Line 1455 of yacc.c  */
-#line 1515 "program_parse.y"
+#line 1545 "program_parse.y"
     {
 	   (yyval.integer) = STATE_FOG_COLOR;
 	;}
@@ -3914,7 +3944,7 @@
   case 184:
 
 /* Line 1455 of yacc.c  */
-#line 1519 "program_parse.y"
+#line 1549 "program_parse.y"
     {
 	   (yyval.integer) = STATE_FOG_PARAMS;
 	;}
@@ -3923,7 +3953,7 @@
   case 185:
 
 /* Line 1455 of yacc.c  */
-#line 1525 "program_parse.y"
+#line 1555 "program_parse.y"
     {
 	   memset((yyval.state), 0, sizeof((yyval.state)));
 	   (yyval.state)[0] = STATE_CLIPPLANE;
@@ -3934,7 +3964,7 @@
   case 186:
 
 /* Line 1455 of yacc.c  */
-#line 1533 "program_parse.y"
+#line 1563 "program_parse.y"
     {
 	   if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxClipPlanes) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid clip plane selector");
@@ -3948,7 +3978,7 @@
   case 187:
 
 /* Line 1455 of yacc.c  */
-#line 1544 "program_parse.y"
+#line 1574 "program_parse.y"
     {
 	   memset((yyval.state), 0, sizeof((yyval.state)));
 	   (yyval.state)[0] = (yyvsp[(2) - (2)].integer);
@@ -3958,7 +3988,7 @@
   case 188:
 
 /* Line 1455 of yacc.c  */
-#line 1551 "program_parse.y"
+#line 1581 "program_parse.y"
     {
 	   (yyval.integer) = STATE_POINT_SIZE;
 	;}
@@ -3967,7 +3997,7 @@
   case 189:
 
 /* Line 1455 of yacc.c  */
-#line 1555 "program_parse.y"
+#line 1585 "program_parse.y"
     {
 	   (yyval.integer) = STATE_POINT_ATTENUATION;
 	;}
@@ -3976,7 +4006,7 @@
   case 190:
 
 /* Line 1455 of yacc.c  */
-#line 1561 "program_parse.y"
+#line 1591 "program_parse.y"
     {
 	   (yyval.state)[0] = (yyvsp[(1) - (5)].state)[0];
 	   (yyval.state)[1] = (yyvsp[(1) - (5)].state)[1];
@@ -3989,7 +4019,7 @@
   case 191:
 
 /* Line 1455 of yacc.c  */
-#line 1571 "program_parse.y"
+#line 1601 "program_parse.y"
     {
 	   (yyval.state)[0] = (yyvsp[(1) - (2)].state)[0];
 	   (yyval.state)[1] = (yyvsp[(1) - (2)].state)[1];
@@ -4002,7 +4032,7 @@
   case 192:
 
 /* Line 1455 of yacc.c  */
-#line 1581 "program_parse.y"
+#line 1611 "program_parse.y"
     {
 	   (yyval.state)[2] = 0;
 	   (yyval.state)[3] = 3;
@@ -4012,7 +4042,7 @@
   case 193:
 
 /* Line 1455 of yacc.c  */
-#line 1586 "program_parse.y"
+#line 1616 "program_parse.y"
     {
 	   /* It seems logical that the matrix row range specifier would have
 	    * to specify a range or more than one row (i.e., $5 > $3).
@@ -4033,7 +4063,7 @@
   case 194:
 
 /* Line 1455 of yacc.c  */
-#line 1604 "program_parse.y"
+#line 1634 "program_parse.y"
     {
 	   (yyval.state)[0] = (yyvsp[(2) - (3)].state)[0];
 	   (yyval.state)[1] = (yyvsp[(2) - (3)].state)[1];
@@ -4044,7 +4074,7 @@
   case 195:
 
 /* Line 1455 of yacc.c  */
-#line 1612 "program_parse.y"
+#line 1642 "program_parse.y"
     {
 	   (yyval.integer) = 0;
 	;}
@@ -4053,7 +4083,7 @@
   case 196:
 
 /* Line 1455 of yacc.c  */
-#line 1616 "program_parse.y"
+#line 1646 "program_parse.y"
     {
 	   (yyval.integer) = (yyvsp[(1) - (1)].integer);
 	;}
@@ -4062,7 +4092,7 @@
   case 197:
 
 /* Line 1455 of yacc.c  */
-#line 1622 "program_parse.y"
+#line 1652 "program_parse.y"
     {
 	   (yyval.integer) = STATE_MATRIX_INVERSE;
 	;}
@@ -4071,7 +4101,7 @@
   case 198:
 
 /* Line 1455 of yacc.c  */
-#line 1626 "program_parse.y"
+#line 1656 "program_parse.y"
     {
 	   (yyval.integer) = STATE_MATRIX_TRANSPOSE;
 	;}
@@ -4080,7 +4110,7 @@
   case 199:
 
 /* Line 1455 of yacc.c  */
-#line 1630 "program_parse.y"
+#line 1660 "program_parse.y"
     {
 	   (yyval.integer) = STATE_MATRIX_INVTRANS;
 	;}
@@ -4089,7 +4119,7 @@
   case 200:
 
 /* Line 1455 of yacc.c  */
-#line 1636 "program_parse.y"
+#line 1666 "program_parse.y"
     {
 	   if ((yyvsp[(1) - (1)].integer) > 3) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid matrix row reference");
@@ -4103,7 +4133,7 @@
   case 201:
 
 /* Line 1455 of yacc.c  */
-#line 1647 "program_parse.y"
+#line 1677 "program_parse.y"
     {
 	   (yyval.state)[0] = STATE_MODELVIEW_MATRIX;
 	   (yyval.state)[1] = (yyvsp[(2) - (2)].integer);
@@ -4113,7 +4143,7 @@
   case 202:
 
 /* Line 1455 of yacc.c  */
-#line 1652 "program_parse.y"
+#line 1682 "program_parse.y"
     {
 	   (yyval.state)[0] = STATE_PROJECTION_MATRIX;
 	   (yyval.state)[1] = 0;
@@ -4123,7 +4153,7 @@
   case 203:
 
 /* Line 1455 of yacc.c  */
-#line 1657 "program_parse.y"
+#line 1687 "program_parse.y"
     {
 	   (yyval.state)[0] = STATE_MVP_MATRIX;
 	   (yyval.state)[1] = 0;
@@ -4133,7 +4163,7 @@
   case 204:
 
 /* Line 1455 of yacc.c  */
-#line 1662 "program_parse.y"
+#line 1692 "program_parse.y"
     {
 	   (yyval.state)[0] = STATE_TEXTURE_MATRIX;
 	   (yyval.state)[1] = (yyvsp[(2) - (2)].integer);
@@ -4143,7 +4173,7 @@
   case 205:
 
 /* Line 1455 of yacc.c  */
-#line 1667 "program_parse.y"
+#line 1697 "program_parse.y"
     {
 	   yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported");
 	   YYERROR;
@@ -4153,7 +4183,7 @@
   case 206:
 
 /* Line 1455 of yacc.c  */
-#line 1672 "program_parse.y"
+#line 1702 "program_parse.y"
     {
 	   (yyval.state)[0] = STATE_PROGRAM_MATRIX;
 	   (yyval.state)[1] = (yyvsp[(3) - (4)].integer);
@@ -4163,7 +4193,7 @@
   case 207:
 
 /* Line 1455 of yacc.c  */
-#line 1679 "program_parse.y"
+#line 1709 "program_parse.y"
     {
 	   (yyval.integer) = 0;
 	;}
@@ -4172,7 +4202,7 @@
   case 208:
 
 /* Line 1455 of yacc.c  */
-#line 1683 "program_parse.y"
+#line 1713 "program_parse.y"
     {
 	   (yyval.integer) = (yyvsp[(2) - (3)].integer);
 	;}
@@ -4181,7 +4211,7 @@
   case 209:
 
 /* Line 1455 of yacc.c  */
-#line 1688 "program_parse.y"
+#line 1718 "program_parse.y"
     {
 	   /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix
 	    * zero is valid.
@@ -4198,7 +4228,7 @@
   case 210:
 
 /* Line 1455 of yacc.c  */
-#line 1701 "program_parse.y"
+#line 1731 "program_parse.y"
     {
 	   /* Since GL_ARB_matrix_palette isn't supported, just let any value
 	    * through here.  The error will be generated later.
@@ -4210,7 +4240,7 @@
   case 211:
 
 /* Line 1455 of yacc.c  */
-#line 1709 "program_parse.y"
+#line 1739 "program_parse.y"
     {
 	   if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxProgramMatrices) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid program matrix selector");
@@ -4224,7 +4254,7 @@
   case 212:
 
 /* Line 1455 of yacc.c  */
-#line 1720 "program_parse.y"
+#line 1750 "program_parse.y"
     {
 	   memset((yyval.state), 0, sizeof((yyval.state)));
 	   (yyval.state)[0] = STATE_DEPTH_RANGE;
@@ -4234,7 +4264,7 @@
   case 217:
 
 /* Line 1455 of yacc.c  */
-#line 1732 "program_parse.y"
+#line 1762 "program_parse.y"
     {
 	   memset((yyval.state), 0, sizeof((yyval.state)));
 	   (yyval.state)[0] = state->state_param_enum;
@@ -4247,7 +4277,7 @@
   case 218:
 
 /* Line 1455 of yacc.c  */
-#line 1742 "program_parse.y"
+#line 1772 "program_parse.y"
     {
 	   (yyval.state)[0] = (yyvsp[(1) - (1)].integer);
 	   (yyval.state)[1] = (yyvsp[(1) - (1)].integer);
@@ -4257,7 +4287,7 @@
   case 219:
 
 /* Line 1455 of yacc.c  */
-#line 1747 "program_parse.y"
+#line 1777 "program_parse.y"
     {
 	   (yyval.state)[0] = (yyvsp[(1) - (3)].integer);
 	   (yyval.state)[1] = (yyvsp[(3) - (3)].integer);
@@ -4267,7 +4297,7 @@
   case 220:
 
 /* Line 1455 of yacc.c  */
-#line 1754 "program_parse.y"
+#line 1784 "program_parse.y"
     {
 	   memset((yyval.state), 0, sizeof((yyval.state)));
 	   (yyval.state)[0] = state->state_param_enum;
@@ -4280,7 +4310,7 @@
   case 221:
 
 /* Line 1455 of yacc.c  */
-#line 1764 "program_parse.y"
+#line 1794 "program_parse.y"
     {
 	   memset((yyval.state), 0, sizeof((yyval.state)));
 	   (yyval.state)[0] = state->state_param_enum;
@@ -4293,7 +4323,7 @@
   case 222:
 
 /* Line 1455 of yacc.c  */
-#line 1773 "program_parse.y"
+#line 1803 "program_parse.y"
     {
 	   (yyval.state)[0] = (yyvsp[(1) - (1)].integer);
 	   (yyval.state)[1] = (yyvsp[(1) - (1)].integer);
@@ -4303,7 +4333,7 @@
   case 223:
 
 /* Line 1455 of yacc.c  */
-#line 1778 "program_parse.y"
+#line 1808 "program_parse.y"
     {
 	   (yyval.state)[0] = (yyvsp[(1) - (3)].integer);
 	   (yyval.state)[1] = (yyvsp[(3) - (3)].integer);
@@ -4313,7 +4343,7 @@
   case 224:
 
 /* Line 1455 of yacc.c  */
-#line 1785 "program_parse.y"
+#line 1815 "program_parse.y"
     {
 	   memset((yyval.state), 0, sizeof((yyval.state)));
 	   (yyval.state)[0] = state->state_param_enum;
@@ -4326,7 +4356,7 @@
   case 225:
 
 /* Line 1455 of yacc.c  */
-#line 1795 "program_parse.y"
+#line 1825 "program_parse.y"
     {
 	   if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxEnvParams) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid environment parameter reference");
@@ -4339,7 +4369,7 @@
   case 226:
 
 /* Line 1455 of yacc.c  */
-#line 1805 "program_parse.y"
+#line 1835 "program_parse.y"
     {
 	   if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxLocalParams) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid local parameter reference");
@@ -4352,7 +4382,7 @@
   case 231:
 
 /* Line 1455 of yacc.c  */
-#line 1820 "program_parse.y"
+#line 1850 "program_parse.y"
     {
 	   (yyval.vector).count = 4;
 	   (yyval.vector).data[0] = (yyvsp[(1) - (1)].real);
@@ -4365,7 +4395,7 @@
   case 232:
 
 /* Line 1455 of yacc.c  */
-#line 1830 "program_parse.y"
+#line 1860 "program_parse.y"
     {
 	   (yyval.vector).count = 1;
 	   (yyval.vector).data[0] = (yyvsp[(1) - (1)].real);
@@ -4378,7 +4408,7 @@
   case 233:
 
 /* Line 1455 of yacc.c  */
-#line 1838 "program_parse.y"
+#line 1868 "program_parse.y"
     {
 	   (yyval.vector).count = 1;
 	   (yyval.vector).data[0] = (float) (yyvsp[(1) - (1)].integer);
@@ -4391,7 +4421,7 @@
   case 234:
 
 /* Line 1455 of yacc.c  */
-#line 1848 "program_parse.y"
+#line 1878 "program_parse.y"
     {
 	   (yyval.vector).count = 4;
 	   (yyval.vector).data[0] = (yyvsp[(2) - (3)].real);
@@ -4404,7 +4434,7 @@
   case 235:
 
 /* Line 1455 of yacc.c  */
-#line 1856 "program_parse.y"
+#line 1886 "program_parse.y"
     {
 	   (yyval.vector).count = 4;
 	   (yyval.vector).data[0] = (yyvsp[(2) - (5)].real);
@@ -4417,7 +4447,7 @@
   case 236:
 
 /* Line 1455 of yacc.c  */
-#line 1865 "program_parse.y"
+#line 1895 "program_parse.y"
     {
 	   (yyval.vector).count = 4;
 	   (yyval.vector).data[0] = (yyvsp[(2) - (7)].real);
@@ -4430,7 +4460,7 @@
   case 237:
 
 /* Line 1455 of yacc.c  */
-#line 1874 "program_parse.y"
+#line 1904 "program_parse.y"
     {
 	   (yyval.vector).count = 4;
 	   (yyval.vector).data[0] = (yyvsp[(2) - (9)].real);
@@ -4443,7 +4473,7 @@
   case 238:
 
 /* Line 1455 of yacc.c  */
-#line 1884 "program_parse.y"
+#line 1914 "program_parse.y"
     {
 	   (yyval.real) = ((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].real) : (yyvsp[(2) - (2)].real);
 	;}
@@ -4452,7 +4482,7 @@
   case 239:
 
 /* Line 1455 of yacc.c  */
-#line 1888 "program_parse.y"
+#line 1918 "program_parse.y"
     {
 	   (yyval.real) = (float)(((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].integer) : (yyvsp[(2) - (2)].integer));
 	;}
@@ -4461,35 +4491,35 @@
   case 240:
 
 /* Line 1455 of yacc.c  */
-#line 1893 "program_parse.y"
+#line 1923 "program_parse.y"
     { (yyval.negate) = FALSE; ;}
     break;
 
   case 241:
 
 /* Line 1455 of yacc.c  */
-#line 1894 "program_parse.y"
+#line 1924 "program_parse.y"
     { (yyval.negate) = TRUE;  ;}
     break;
 
   case 242:
 
 /* Line 1455 of yacc.c  */
-#line 1895 "program_parse.y"
+#line 1925 "program_parse.y"
     { (yyval.negate) = FALSE; ;}
     break;
 
   case 243:
 
 /* Line 1455 of yacc.c  */
-#line 1898 "program_parse.y"
+#line 1928 "program_parse.y"
     { (yyval.integer) = (yyvsp[(2) - (2)].integer); ;}
     break;
 
   case 245:
 
 /* Line 1455 of yacc.c  */
-#line 1902 "program_parse.y"
+#line 1932 "program_parse.y"
     {
 	   /* NV_fragment_program_option defines the size qualifiers in a
 	    * fairly broken way.  "SHORT" or "LONG" can optionally be used
@@ -4528,7 +4558,7 @@
   case 246:
 
 /* Line 1455 of yacc.c  */
-#line 1936 "program_parse.y"
+#line 1966 "program_parse.y"
     {
 	;}
     break;
@@ -4536,16 +4566,17 @@
   case 247:
 
 /* Line 1455 of yacc.c  */
-#line 1940 "program_parse.y"
+#line 1970 "program_parse.y"
     { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;}
     break;
 
   case 249:
 
 /* Line 1455 of yacc.c  */
-#line 1944 "program_parse.y"
+#line 1974 "program_parse.y"
     {
 	   if (!declare_variable(state, (yyvsp[(3) - (3)].string), (yyvsp[(0) - (3)].integer), & (yylsp[(3) - (3)]))) {
+	      free((yyvsp[(3) - (3)].string));
 	      YYERROR;
 	   }
 	;}
@@ -4554,9 +4585,10 @@
   case 250:
 
 /* Line 1455 of yacc.c  */
-#line 1950 "program_parse.y"
+#line 1981 "program_parse.y"
     {
 	   if (!declare_variable(state, (yyvsp[(1) - (1)].string), (yyvsp[(0) - (1)].integer), & (yylsp[(1) - (1)]))) {
+	      free((yyvsp[(1) - (1)].string));
 	      YYERROR;
 	   }
 	;}
@@ -4565,12 +4597,13 @@
   case 251:
 
 /* Line 1455 of yacc.c  */
-#line 1958 "program_parse.y"
+#line 1990 "program_parse.y"
     {
 	   struct asm_symbol *const s =
 	      declare_variable(state, (yyvsp[(3) - (5)].string), at_output, & (yylsp[(3) - (5)]));
 
 	   if (s == NULL) {
+	      free((yyvsp[(3) - (5)].string));
 	      YYERROR;
 	   } else {
 	      s->output_binding = (yyvsp[(5) - (5)].result);
@@ -4581,7 +4614,7 @@
   case 252:
 
 /* Line 1455 of yacc.c  */
-#line 1971 "program_parse.y"
+#line 2004 "program_parse.y"
     {
 	   if (state->mode == ARB_vertex) {
 	      (yyval.result) = VERT_RESULT_HPOS;
@@ -4595,7 +4628,7 @@
   case 253:
 
 /* Line 1455 of yacc.c  */
-#line 1980 "program_parse.y"
+#line 2013 "program_parse.y"
     {
 	   if (state->mode == ARB_vertex) {
 	      (yyval.result) = VERT_RESULT_FOGC;
@@ -4609,7 +4642,7 @@
   case 254:
 
 /* Line 1455 of yacc.c  */
-#line 1989 "program_parse.y"
+#line 2022 "program_parse.y"
     {
 	   (yyval.result) = (yyvsp[(2) - (2)].result);
 	;}
@@ -4618,7 +4651,7 @@
   case 255:
 
 /* Line 1455 of yacc.c  */
-#line 1993 "program_parse.y"
+#line 2026 "program_parse.y"
     {
 	   if (state->mode == ARB_vertex) {
 	      (yyval.result) = VERT_RESULT_PSIZ;
@@ -4632,7 +4665,7 @@
   case 256:
 
 /* Line 1455 of yacc.c  */
-#line 2002 "program_parse.y"
+#line 2035 "program_parse.y"
     {
 	   if (state->mode == ARB_vertex) {
 	      (yyval.result) = VERT_RESULT_TEX0 + (yyvsp[(3) - (3)].integer);
@@ -4646,7 +4679,7 @@
   case 257:
 
 /* Line 1455 of yacc.c  */
-#line 2011 "program_parse.y"
+#line 2044 "program_parse.y"
     {
 	   if (state->mode == ARB_fragment) {
 	      (yyval.result) = FRAG_RESULT_DEPTH;
@@ -4660,7 +4693,7 @@
   case 258:
 
 /* Line 1455 of yacc.c  */
-#line 2022 "program_parse.y"
+#line 2055 "program_parse.y"
     {
 	   (yyval.result) = (yyvsp[(2) - (3)].integer) + (yyvsp[(3) - (3)].integer);
 	;}
@@ -4669,7 +4702,7 @@
   case 259:
 
 /* Line 1455 of yacc.c  */
-#line 2028 "program_parse.y"
+#line 2061 "program_parse.y"
     {
 	   (yyval.integer) = (state->mode == ARB_vertex)
 	      ? VERT_RESULT_COL0
@@ -4680,7 +4713,7 @@
   case 260:
 
 /* Line 1455 of yacc.c  */
-#line 2034 "program_parse.y"
+#line 2067 "program_parse.y"
     {
 	   if (state->mode == ARB_vertex) {
 	      (yyval.integer) = VERT_RESULT_COL0;
@@ -4694,7 +4727,7 @@
   case 261:
 
 /* Line 1455 of yacc.c  */
-#line 2043 "program_parse.y"
+#line 2076 "program_parse.y"
     {
 	   if (state->mode == ARB_vertex) {
 	      (yyval.integer) = VERT_RESULT_BFC0;
@@ -4708,7 +4741,7 @@
   case 262:
 
 /* Line 1455 of yacc.c  */
-#line 2054 "program_parse.y"
+#line 2087 "program_parse.y"
     {
 	   (yyval.integer) = 0; 
 	;}
@@ -4717,7 +4750,7 @@
   case 263:
 
 /* Line 1455 of yacc.c  */
-#line 2058 "program_parse.y"
+#line 2091 "program_parse.y"
     {
 	   if (state->mode == ARB_vertex) {
 	      (yyval.integer) = 0;
@@ -4731,7 +4764,7 @@
   case 264:
 
 /* Line 1455 of yacc.c  */
-#line 2067 "program_parse.y"
+#line 2100 "program_parse.y"
     {
 	   if (state->mode == ARB_vertex) {
 	      (yyval.integer) = 1;
@@ -4745,91 +4778,91 @@
   case 265:
 
 /* Line 1455 of yacc.c  */
-#line 2077 "program_parse.y"
+#line 2110 "program_parse.y"
     { (yyval.integer) = 0; ;}
     break;
 
   case 266:
 
 /* Line 1455 of yacc.c  */
-#line 2078 "program_parse.y"
+#line 2111 "program_parse.y"
     { (yyval.integer) = 0; ;}
     break;
 
   case 267:
 
 /* Line 1455 of yacc.c  */
-#line 2079 "program_parse.y"
+#line 2112 "program_parse.y"
     { (yyval.integer) = 1; ;}
     break;
 
   case 268:
 
 /* Line 1455 of yacc.c  */
-#line 2082 "program_parse.y"
+#line 2115 "program_parse.y"
     { (yyval.integer) = 0; ;}
     break;
 
   case 269:
 
 /* Line 1455 of yacc.c  */
-#line 2083 "program_parse.y"
+#line 2116 "program_parse.y"
     { (yyval.integer) = 0; ;}
     break;
 
   case 270:
 
 /* Line 1455 of yacc.c  */
-#line 2084 "program_parse.y"
+#line 2117 "program_parse.y"
     { (yyval.integer) = 1; ;}
     break;
 
   case 271:
 
 /* Line 1455 of yacc.c  */
-#line 2087 "program_parse.y"
+#line 2120 "program_parse.y"
     { (yyval.integer) = 0; ;}
     break;
 
   case 272:
 
 /* Line 1455 of yacc.c  */
-#line 2088 "program_parse.y"
+#line 2121 "program_parse.y"
     { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;}
     break;
 
   case 273:
 
 /* Line 1455 of yacc.c  */
-#line 2091 "program_parse.y"
+#line 2124 "program_parse.y"
     { (yyval.integer) = 0; ;}
     break;
 
   case 274:
 
 /* Line 1455 of yacc.c  */
-#line 2092 "program_parse.y"
+#line 2125 "program_parse.y"
     { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;}
     break;
 
   case 275:
 
 /* Line 1455 of yacc.c  */
-#line 2095 "program_parse.y"
+#line 2128 "program_parse.y"
     { (yyval.integer) = 0; ;}
     break;
 
   case 276:
 
 /* Line 1455 of yacc.c  */
-#line 2096 "program_parse.y"
+#line 2129 "program_parse.y"
     { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;}
     break;
 
   case 277:
 
 /* Line 1455 of yacc.c  */
-#line 2100 "program_parse.y"
+#line 2133 "program_parse.y"
     {
 	   if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureCoordUnits) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid texture coordinate unit selector");
@@ -4843,7 +4876,7 @@
   case 278:
 
 /* Line 1455 of yacc.c  */
-#line 2111 "program_parse.y"
+#line 2144 "program_parse.y"
     {
 	   if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureImageUnits) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid texture image unit selector");
@@ -4857,7 +4890,7 @@
   case 279:
 
 /* Line 1455 of yacc.c  */
-#line 2122 "program_parse.y"
+#line 2155 "program_parse.y"
     {
 	   if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureUnits) {
 	      yyerror(& (yylsp[(1) - (1)]), state, "invalid texture unit selector");
@@ -4871,24 +4904,28 @@
   case 280:
 
 /* Line 1455 of yacc.c  */
-#line 2133 "program_parse.y"
+#line 2166 "program_parse.y"
     {
 	   struct asm_symbol *exist = (struct asm_symbol *)
 	      _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(2) - (4)].string));
 	   struct asm_symbol *target = (struct asm_symbol *)
 	      _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(4) - (4)].string));
 
+	   free((yyvsp[(4) - (4)].string));
+
 	   if (exist != NULL) {
 	      char m[1000];
 	      _mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", (yyvsp[(2) - (4)].string));
+	      free((yyvsp[(2) - (4)].string));
 	      yyerror(& (yylsp[(2) - (4)]), state, m);
 	      YYERROR;
 	   } else if (target == NULL) {
+	      free((yyvsp[(2) - (4)].string));
 	      yyerror(& (yylsp[(4) - (4)]), state,
 		      "undefined variable binding in ALIAS statement");
 	      YYERROR;
 	   } else {
-	      _mesa_symbol_table_add_symbol(state->st, 0, strdup((yyvsp[(2) - (4)].string)), target);
+	      _mesa_symbol_table_add_symbol(state->st, 0, (yyvsp[(2) - (4)].string), target);
 	   }
 	;}
     break;
@@ -4896,7 +4933,7 @@
 
 
 /* Line 1455 of yacc.c  */
-#line 4900 "program_parse.tab.c"
+#line 4937 "program_parse.tab.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -5115,7 +5152,7 @@
 
 
 /* Line 1675 of yacc.c  */
-#line 2158 "program_parse.y"
+#line 2195 "program_parse.y"
 
 
 void
@@ -5222,7 +5259,9 @@
    const GLint maxIndex = 1 << INST_INDEX_BITS;
    const GLint minIndex = 0;
    ASSERT(index >= minIndex);
+   (void) minIndex;
    ASSERT(index <= maxIndex);
+   (void) maxIndex;
    ASSERT(file == PROGRAM_TEMPORARY ||
 	  file == PROGRAM_ADDRESS ||
 	  file == PROGRAM_OUTPUT);
@@ -5245,19 +5284,31 @@
 }
 
 
-/** Like init_src_reg() but set the File and Index fields. */
+/** Like init_src_reg() but set the File and Index fields.
+ * \return GL_TRUE if a valid src register, GL_FALSE otherwise
+ */
 void
 set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index)
 {
+   set_src_reg_swz(r, file, index, SWIZZLE_XYZW);
+}
+
+
+void
+set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index,
+                GLuint swizzle)
+{
    const GLint maxIndex = (1 << INST_INDEX_BITS) - 1;
    const GLint minIndex = -(1 << INST_INDEX_BITS);
-   ASSERT(index >= minIndex);
-   ASSERT(index <= maxIndex);
    ASSERT(file < PROGRAM_FILE_MAX);
+   ASSERT(index >= minIndex);
+   (void) minIndex;
+   ASSERT(index <= maxIndex);
+   (void) maxIndex;
    memset(r, 0, sizeof(*r));
    r->Base.File = file;
    r->Base.Index = index;
-   r->Base.Swizzle = SWIZZLE_NOOP;
+   r->Base.Swizzle = swizzle;
    r->Symbol = NULL;
 }
 
@@ -5298,14 +5349,10 @@
    if (exist != NULL) {
       yyerror(locp, state, "redeclared identifier");
    } else {
-      const size_t name_len = strlen(name);
-
-      s = calloc(1, sizeof(struct asm_symbol) + name_len + 1);
-      s->name = (char *)(s + 1);
+      s = calloc(1, sizeof(struct asm_symbol));
+      s->name = name;
       s->type = t;
 
-      memcpy((char *) s->name, name, name_len + 1);
-
       switch (t) {
       case at_temp:
 	 if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
@@ -5393,15 +5440,20 @@
 	 state_tokens[2] = state_tokens[3] = row;
 
 	 idx = add_state_reference(prog->Parameters, state_tokens);
-	 if (param_var->param_binding_begin == ~0U)
+	 if (param_var->param_binding_begin == ~0U) {
 	    param_var->param_binding_begin = idx;
+            param_var->param_binding_swizzle = SWIZZLE_XYZW;
+         }
+
 	 param_var->param_binding_length++;
       }
    }
    else {
       idx = add_state_reference(prog->Parameters, state_tokens);
-      if (param_var->param_binding_begin == ~0U)
+      if (param_var->param_binding_begin == ~0U) {
 	 param_var->param_binding_begin = idx;
+         param_var->param_binding_swizzle = SWIZZLE_XYZW;
+      }
       param_var->param_binding_length++;
    }
 
@@ -5425,9 +5477,12 @@
    assert((state_tokens[1] == STATE_ENV)
 	  || (state_tokens[1] == STATE_LOCAL));
 
+   /*
+    * The param type is STATE_VAR.  The program parameter entry will
+    * effectively be a pointer into the LOCAL or ENV parameter array.
+    */
    param_var->type = at_param;
-   param_var->param_binding_type = (state_tokens[1] == STATE_ENV)
-     ? PROGRAM_ENV_PARAM : PROGRAM_LOCAL_PARAM;
+   param_var->param_binding_type = PROGRAM_STATE_VAR;
 
    /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements,
     * we need to unroll it and call add_state_reference() for each row
@@ -5441,15 +5496,19 @@
 	 state_tokens[2] = state_tokens[3] = row;
 
 	 idx = add_state_reference(prog->Parameters, state_tokens);
-	 if (param_var->param_binding_begin == ~0U)
+	 if (param_var->param_binding_begin == ~0U) {
 	    param_var->param_binding_begin = idx;
+            param_var->param_binding_swizzle = SWIZZLE_XYZW;
+         }
 	 param_var->param_binding_length++;
       }
    }
    else {
       idx = add_state_reference(prog->Parameters, state_tokens);
-      if (param_var->param_binding_begin == ~0U)
+      if (param_var->param_binding_begin == ~0U) {
 	 param_var->param_binding_begin = idx;
+         param_var->param_binding_swizzle = SWIZZLE_XYZW;
+      }
       param_var->param_binding_length++;
    }
 
@@ -5457,20 +5516,34 @@
 }
 
 
+/**
+ * Put a float/vector constant/literal into the parameter list.
+ * \param param_var  returns info about the parameter/constant's location,
+ *                   binding, type, etc.
+ * \param vec  the vector/constant to add
+ * \param allowSwizzle  if true, try to consolidate constants which only differ
+ *                      by a swizzle.  We don't want to do this when building
+ *                      arrays of constants that may be indexed indirectly.
+ * \return index of the constant in the parameter list.
+ */
 int
 initialize_symbol_from_const(struct gl_program *prog,
 			     struct asm_symbol *param_var, 
-			     const struct asm_vector *vec)
+			     const struct asm_vector *vec,
+                             GLboolean allowSwizzle)
 {
-   const int idx = _mesa_add_parameter(prog->Parameters, PROGRAM_CONSTANT,
-				       NULL, vec->count, GL_NONE, vec->data,
-				       NULL, 0x0);
+   unsigned swizzle;
+   const int idx = _mesa_add_unnamed_constant(prog->Parameters,
+                                              vec->data, vec->count,
+                                              allowSwizzle ? &swizzle : NULL);
 
    param_var->type = at_param;
    param_var->param_binding_type = PROGRAM_CONSTANT;
 
-   if (param_var->param_binding_begin == ~0U)
+   if (param_var->param_binding_begin == ~0U) {
       param_var->param_binding_begin = idx;
+      param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW;
+   }
    param_var->param_binding_length++;
 
    return idx;
@@ -5553,11 +5626,6 @@
    _mesa_memcpy (strz, str, len);
    strz[len] = '\0';
 
-   if (state->prog->String != NULL) {
-      _mesa_free(state->prog->String);
-      state->prog->String = NULL;
-   }
-
    state->prog->String = strz;
 
    state->st = _mesa_symbol_table_ctor();
@@ -5647,6 +5715,7 @@
    for (sym = state->sym; sym != NULL; sym = temp) {
       temp = sym->next;
 
+      _mesa_free((void *) sym->name);
       _mesa_free(sym);
    }
    state->sym = NULL;
@@ -5654,11 +5723,6 @@
    _mesa_symbol_table_dtor(state->st);
    state->st = NULL;
 
-   if (state->string_dumpster != NULL) {
-      _mesa_free(state->string_dumpster);
-      state->dumpster_size = 0;
-   }
-
    return result;
 }
 
diff --git a/src/mesa/shader/program_parse.tab.h b/src/mesa/shader/program_parse.tab.h
index 406100c..045241d 100644
--- a/src/mesa/shader/program_parse.tab.h
+++ b/src/mesa/shader/program_parse.tab.h
@@ -154,7 +154,7 @@
 {
 
 /* Line 1676 of yacc.c  */
-#line 122 "program_parse.y"
+#line 126 "program_parse.y"
 
    struct asm_instruction *inst;
    struct asm_symbol *sym;
diff --git a/src/mesa/shader/program_parse.y b/src/mesa/shader/program_parse.y
index 5767c51..5c5d8d7 100644
--- a/src/mesa/shader/program_parse.y
+++ b/src/mesa/shader/program_parse.y
@@ -52,7 +52,8 @@
     struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
 
 static int initialize_symbol_from_const(struct gl_program *prog,
-    struct asm_symbol *param_var, const struct asm_vector *vec);
+    struct asm_symbol *param_var, const struct asm_vector *vec,
+    GLboolean allowSwizzle);
 
 static int yyparse(struct asm_parser_state *state);
 
@@ -74,6 +75,9 @@
 static void set_src_reg(struct asm_src_register *r,
                         gl_register_file file, GLint index);
 
+static void set_src_reg_swz(struct asm_src_register *r,
+                            gl_register_file file, GLint index, GLuint swizzle);
+
 static void asm_instruction_set_operands(struct asm_instruction *inst,
     const struct prog_dst_register *dst, const struct asm_src_register *src0,
     const struct asm_src_register *src1, const struct asm_src_register *src2);
@@ -309,6 +313,8 @@
 	   }
 
 
+	   free($2);
+
 	   if (!valid) {
 	      const char *const err_str = (state->mode == ARB_vertex)
 		 ? "invalid ARB vertex program option"
@@ -584,9 +590,11 @@
 
 	   memset(& temp_sym, 0, sizeof(temp_sym));
 	   temp_sym.param_binding_begin = ~0;
-	   initialize_symbol_from_const(state->prog, & temp_sym, & $1);
+	   initialize_symbol_from_const(state->prog, & temp_sym, & $1, GL_TRUE);
 
-	   set_src_reg(& $$, PROGRAM_CONSTANT, temp_sym.param_binding_begin);
+	   set_src_reg_swz(& $$, PROGRAM_CONSTANT,
+                           temp_sym.param_binding_begin,
+                           temp_sym.param_binding_swizzle);
 	}
 	;
 
@@ -641,7 +649,7 @@
 		 YYERROR;
 	      }
 
-	      state->prog->OutputsWritten |= (1U << $$.Index);
+	      state->prog->OutputsWritten |= BITFIELD64_BIT($$.Index);
 	   }
 	}
 	;
@@ -710,12 +718,17 @@
 	}
 	| string
 	{
+	   char s;
+
 	   if (strlen($1) > 1) {
 	      yyerror(& @1, state, "invalid extended swizzle selector");
 	      YYERROR;
 	   }
 
-	   switch ($1[0]) {
+	   s = $1[0];
+	   free($1);
+
+	   switch (s) {
 	   case 'x':
 	      $$.swz = SWIZZLE_X;
 	      $$.xyzw_valid = 1;
@@ -763,6 +776,8 @@
 	   struct asm_symbol *const s = (struct asm_symbol *)
 	      _mesa_symbol_table_find_symbol(state->st, 0, $1);
 
+	   free($1);
+
 	   if (s == NULL) {
 	      yyerror(& @1, state, "invalid operand variable");
 	      YYERROR;
@@ -781,7 +796,9 @@
 	      set_src_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
 	      break;
 	   case at_param:
-	      set_src_reg(& $$, s->param_binding_type, s->param_binding_begin);
+              set_src_reg_swz(& $$, s->param_binding_type,
+                              s->param_binding_begin,
+                              s->param_binding_swizzle);
 	      break;
 	   case at_attrib:
 	      set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding);
@@ -832,7 +849,8 @@
            gl_register_file file = ($1.name != NULL) 
 	      ? $1.param_binding_type
 	      : PROGRAM_CONSTANT;
-	   set_src_reg(& $$, file, $1.param_binding_begin);
+           set_src_reg_swz(& $$, file, $1.param_binding_begin,
+                           $1.param_binding_swizzle);
 	}
 	;
 
@@ -845,6 +863,8 @@
 	   struct asm_symbol *const s = (struct asm_symbol *)
 	      _mesa_symbol_table_find_symbol(state->st, 0, $1);
 
+	   free($1);
+
 	   if (s == NULL) {
 	      yyerror(& @1, state, "invalid operand variable");
 	      YYERROR;
@@ -872,6 +892,8 @@
 	   struct asm_symbol *const s = (struct asm_symbol *)
 	      _mesa_symbol_table_find_symbol(state->st, 0, $1);
 
+	   free($1);
+
 	   if (s == NULL) {
 	      yyerror(& @1, state, "invalid operand variable");
 	      YYERROR;
@@ -943,6 +965,8 @@
 	   struct asm_symbol *const s = (struct asm_symbol *)
 	      _mesa_symbol_table_find_symbol(state->st, 0, $1);
 
+	   free($1);
+
 	   if (s == NULL) {
 	      yyerror(& @1, state, "invalid array member");
 	      YYERROR;
@@ -1081,6 +1105,7 @@
 	      declare_variable(state, $2, at_attrib, & @2);
 
 	   if (s == NULL) {
+	      free($2);
 	      YYERROR;
 	   } else {
 	      s->attrib_binding = $4;
@@ -1188,11 +1213,13 @@
 	      declare_variable(state, $2, at_param, & @2);
 
 	   if (s == NULL) {
+	      free($2);
 	      YYERROR;
 	   } else {
 	      s->param_binding_type = $3.param_binding_type;
 	      s->param_binding_begin = $3.param_binding_begin;
 	      s->param_binding_length = $3.param_binding_length;
+              s->param_binding_swizzle = SWIZZLE_XYZW;
 	      s->param_is_array = 0;
 	   }
 	}
@@ -1201,6 +1228,7 @@
 PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit
 	{
 	   if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) {
+	      free($2);
 	      yyerror(& @4, state, 
 		      "parameter array size and number of bindings must match");
 	      YYERROR;
@@ -1209,11 +1237,13 @@
 		 declare_variable(state, $2, $6.type, & @2);
 
 	      if (s == NULL) {
+		 free($2);
 		 YYERROR;
 	      } else {
 		 s->param_binding_type = $6.param_binding_type;
 		 s->param_binding_begin = $6.param_binding_begin;
 		 s->param_binding_length = $6.param_binding_length;
+                 s->param_binding_swizzle = SWIZZLE_XYZW;
 		 s->param_is_array = 1;
 	      }
 	   }
@@ -1271,7 +1301,7 @@
 	{
 	   memset(& $$, 0, sizeof($$));
 	   $$.param_binding_begin = ~0;
-	   initialize_symbol_from_const(state->prog, & $$, & $1);
+	   initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
 	}
 	;
 
@@ -1291,7 +1321,7 @@
 	{
 	   memset(& $$, 0, sizeof($$));
 	   $$.param_binding_begin = ~0;
-	   initialize_symbol_from_const(state->prog, & $$, & $1);
+	   initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
 	}
 	;
 
@@ -1311,7 +1341,7 @@
 	{
 	   memset(& $$, 0, sizeof($$));
 	   $$.param_binding_begin = ~0;
-	   initialize_symbol_from_const(state->prog, & $$, & $1);
+	   initialize_symbol_from_const(state->prog, & $$, & $1, GL_FALSE);
 	}
 	;
 
@@ -1943,12 +1973,14 @@
 varNameList: varNameList ',' IDENTIFIER
 	{
 	   if (!declare_variable(state, $3, $<integer>0, & @3)) {
+	      free($3);
 	      YYERROR;
 	   }
 	}
 	| IDENTIFIER
 	{
 	   if (!declare_variable(state, $1, $<integer>0, & @1)) {
+	      free($1);
 	      YYERROR;
 	   }
 	}
@@ -1960,6 +1992,7 @@
 	      declare_variable(state, $3, at_output, & @3);
 
 	   if (s == NULL) {
+	      free($3);
 	      YYERROR;
 	   } else {
 	      s->output_binding = $5;
@@ -2136,17 +2169,21 @@
 	   struct asm_symbol *target = (struct asm_symbol *)
 	      _mesa_symbol_table_find_symbol(state->st, 0, $4);
 
+	   free($4);
+
 	   if (exist != NULL) {
 	      char m[1000];
 	      _mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", $2);
+	      free($2);
 	      yyerror(& @2, state, m);
 	      YYERROR;
 	   } else if (target == NULL) {
+	      free($2);
 	      yyerror(& @4, state,
 		      "undefined variable binding in ALIAS statement");
 	      YYERROR;
 	   } else {
-	      _mesa_symbol_table_add_symbol(state->st, 0, strdup($2), target);
+	      _mesa_symbol_table_add_symbol(state->st, 0, $2, target);
 	   }
 	}
 	;
@@ -2261,7 +2298,9 @@
    const GLint maxIndex = 1 << INST_INDEX_BITS;
    const GLint minIndex = 0;
    ASSERT(index >= minIndex);
+   (void) minIndex;
    ASSERT(index <= maxIndex);
+   (void) maxIndex;
    ASSERT(file == PROGRAM_TEMPORARY ||
 	  file == PROGRAM_ADDRESS ||
 	  file == PROGRAM_OUTPUT);
@@ -2284,19 +2323,31 @@
 }
 
 
-/** Like init_src_reg() but set the File and Index fields. */
+/** Like init_src_reg() but set the File and Index fields.
+ * \return GL_TRUE if a valid src register, GL_FALSE otherwise
+ */
 void
 set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index)
 {
+   set_src_reg_swz(r, file, index, SWIZZLE_XYZW);
+}
+
+
+void
+set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index,
+                GLuint swizzle)
+{
    const GLint maxIndex = (1 << INST_INDEX_BITS) - 1;
    const GLint minIndex = -(1 << INST_INDEX_BITS);
-   ASSERT(index >= minIndex);
-   ASSERT(index <= maxIndex);
    ASSERT(file < PROGRAM_FILE_MAX);
+   ASSERT(index >= minIndex);
+   (void) minIndex;
+   ASSERT(index <= maxIndex);
+   (void) maxIndex;
    memset(r, 0, sizeof(*r));
    r->Base.File = file;
    r->Base.Index = index;
-   r->Base.Swizzle = SWIZZLE_NOOP;
+   r->Base.Swizzle = swizzle;
    r->Symbol = NULL;
 }
 
@@ -2337,14 +2388,10 @@
    if (exist != NULL) {
       yyerror(locp, state, "redeclared identifier");
    } else {
-      const size_t name_len = strlen(name);
-
-      s = calloc(1, sizeof(struct asm_symbol) + name_len + 1);
-      s->name = (char *)(s + 1);
+      s = calloc(1, sizeof(struct asm_symbol));
+      s->name = name;
       s->type = t;
 
-      memcpy((char *) s->name, name, name_len + 1);
-
       switch (t) {
       case at_temp:
 	 if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
@@ -2432,15 +2479,20 @@
 	 state_tokens[2] = state_tokens[3] = row;
 
 	 idx = add_state_reference(prog->Parameters, state_tokens);
-	 if (param_var->param_binding_begin == ~0U)
+	 if (param_var->param_binding_begin == ~0U) {
 	    param_var->param_binding_begin = idx;
+            param_var->param_binding_swizzle = SWIZZLE_XYZW;
+         }
+
 	 param_var->param_binding_length++;
       }
    }
    else {
       idx = add_state_reference(prog->Parameters, state_tokens);
-      if (param_var->param_binding_begin == ~0U)
+      if (param_var->param_binding_begin == ~0U) {
 	 param_var->param_binding_begin = idx;
+         param_var->param_binding_swizzle = SWIZZLE_XYZW;
+      }
       param_var->param_binding_length++;
    }
 
@@ -2464,9 +2516,12 @@
    assert((state_tokens[1] == STATE_ENV)
 	  || (state_tokens[1] == STATE_LOCAL));
 
+   /*
+    * The param type is STATE_VAR.  The program parameter entry will
+    * effectively be a pointer into the LOCAL or ENV parameter array.
+    */
    param_var->type = at_param;
-   param_var->param_binding_type = (state_tokens[1] == STATE_ENV)
-     ? PROGRAM_ENV_PARAM : PROGRAM_LOCAL_PARAM;
+   param_var->param_binding_type = PROGRAM_STATE_VAR;
 
    /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements,
     * we need to unroll it and call add_state_reference() for each row
@@ -2480,15 +2535,19 @@
 	 state_tokens[2] = state_tokens[3] = row;
 
 	 idx = add_state_reference(prog->Parameters, state_tokens);
-	 if (param_var->param_binding_begin == ~0U)
+	 if (param_var->param_binding_begin == ~0U) {
 	    param_var->param_binding_begin = idx;
+            param_var->param_binding_swizzle = SWIZZLE_XYZW;
+         }
 	 param_var->param_binding_length++;
       }
    }
    else {
       idx = add_state_reference(prog->Parameters, state_tokens);
-      if (param_var->param_binding_begin == ~0U)
+      if (param_var->param_binding_begin == ~0U) {
 	 param_var->param_binding_begin = idx;
+         param_var->param_binding_swizzle = SWIZZLE_XYZW;
+      }
       param_var->param_binding_length++;
    }
 
@@ -2496,20 +2555,34 @@
 }
 
 
+/**
+ * Put a float/vector constant/literal into the parameter list.
+ * \param param_var  returns info about the parameter/constant's location,
+ *                   binding, type, etc.
+ * \param vec  the vector/constant to add
+ * \param allowSwizzle  if true, try to consolidate constants which only differ
+ *                      by a swizzle.  We don't want to do this when building
+ *                      arrays of constants that may be indexed indirectly.
+ * \return index of the constant in the parameter list.
+ */
 int
 initialize_symbol_from_const(struct gl_program *prog,
 			     struct asm_symbol *param_var, 
-			     const struct asm_vector *vec)
+			     const struct asm_vector *vec,
+                             GLboolean allowSwizzle)
 {
-   const int idx = _mesa_add_parameter(prog->Parameters, PROGRAM_CONSTANT,
-				       NULL, vec->count, GL_NONE, vec->data,
-				       NULL, 0x0);
+   unsigned swizzle;
+   const int idx = _mesa_add_unnamed_constant(prog->Parameters,
+                                              vec->data, vec->count,
+                                              allowSwizzle ? &swizzle : NULL);
 
    param_var->type = at_param;
    param_var->param_binding_type = PROGRAM_CONSTANT;
 
-   if (param_var->param_binding_begin == ~0U)
+   if (param_var->param_binding_begin == ~0U) {
       param_var->param_binding_begin = idx;
+      param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW;
+   }
    param_var->param_binding_length++;
 
    return idx;
@@ -2592,11 +2665,6 @@
    _mesa_memcpy (strz, str, len);
    strz[len] = '\0';
 
-   if (state->prog->String != NULL) {
-      _mesa_free(state->prog->String);
-      state->prog->String = NULL;
-   }
-
    state->prog->String = strz;
 
    state->st = _mesa_symbol_table_ctor();
@@ -2686,6 +2754,7 @@
    for (sym = state->sym; sym != NULL; sym = temp) {
       temp = sym->next;
 
+      _mesa_free((void *) sym->name);
       _mesa_free(sym);
    }
    state->sym = NULL;
@@ -2693,10 +2762,5 @@
    _mesa_symbol_table_dtor(state->st);
    state->st = NULL;
 
-   if (state->string_dumpster != NULL) {
-      _mesa_free(state->string_dumpster);
-      state->dumpster_size = 0;
-   }
-
    return result;
 }
diff --git a/src/mesa/shader/program_parser.h b/src/mesa/shader/program_parser.h
index 25b4139..69396ca 100644
--- a/src/mesa/shader/program_parser.h
+++ b/src/mesa/shader/program_parser.h
@@ -35,16 +35,9 @@
    at_attrib,
    at_param,
    at_temp,
-   at_output,
+   at_output
 };
 
-/**
- * \note
- * Objects of this type are allocated as the object plus the name of the
- * symbol.  That is, malloc(sizeof(struct asm_symbol) + strlen(name) + 1).
- * Alternately, asm_symbol::name could be moved to the bottom of the structure
- * and declared as 'char name[0];'.
- */
 struct asm_symbol {
    struct asm_symbol *next;    /**< List linkage for freeing. */
    const char *name;
@@ -63,6 +56,12 @@
     */
    unsigned param_binding_begin;
 
+   /**
+    * Constants put into the parameter list may be swizzled.  This
+    * field contain's the symbol's swizzle. (SWIZZLE_X/Y/Z/W)
+    */
+   unsigned param_binding_swizzle;
+
    /* This is how many entries in the the program_parameter_list we take up
     * with our state tokens or constants. Note that this is _not_ the same as
     * the number of param registers we eventually use.
@@ -165,15 +164,6 @@
 
 
    /**
-    * Buffer to hold strings transfered from the lexer to the parser
-    */
-   /*@{*/
-   char *string_dumpster;      /**< String data transfered. */
-   size_t dumpster_size;       /**< Total size, in bytes, of the buffer. */
-   /*@}*/
-
-
-   /**
     * Selected limits copied from gl_constants
     *
     * These are limits from the GL context, but various bits in the program
diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c
index 3b85295..9514545 100644
--- a/src/mesa/shader/programopt.c
+++ b/src/mesa/shader/programopt.c
@@ -109,7 +109,7 @@
    vprog->Base.Instructions = newInst;
    vprog->Base.NumInstructions = newLen;
    vprog->Base.InputsRead |= VERT_BIT_POS;
-   vprog->Base.OutputsWritten |= (1 << VERT_RESULT_HPOS);
+   vprog->Base.OutputsWritten |= BITFIELD64_BIT(VERT_RESULT_HPOS);
 }
 
 
@@ -211,7 +211,7 @@
    vprog->Base.Instructions = newInst;
    vprog->Base.NumInstructions = newLen;
    vprog->Base.InputsRead |= VERT_BIT_POS;
-   vprog->Base.OutputsWritten |= (1 << VERT_RESULT_HPOS);
+   vprog->Base.OutputsWritten |= BITFIELD64_BIT(VERT_RESULT_HPOS);
 }
 
 
@@ -528,15 +528,11 @@
    /* look for instructions which write to the varying vars identified above */
    for (i = 0; i < prog->NumInstructions; i++) {
       struct prog_instruction *inst = prog->Instructions + i;
-      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
-      GLuint j;
-      for (j = 0; j < numSrc; j++) {
-         if (inst->DstReg.File == type &&
-             outputMap[inst->DstReg.Index] >= 0) {
-            /* change inst to write to the temp reg, instead of the varying */
-            inst->DstReg.File = PROGRAM_TEMPORARY;
-            inst->DstReg.Index = outputMap[inst->DstReg.Index];
-         }
+      if (inst->DstReg.File == type &&
+          outputMap[inst->DstReg.Index] >= 0) {
+         /* change inst to write to the temp reg, instead of the varying */
+         inst->DstReg.File = PROGRAM_TEMPORARY;
+         inst->DstReg.Index = outputMap[inst->DstReg.Index];
       }
    }
 
@@ -613,7 +609,7 @@
    prog->Base.Instructions = inst;
    prog->Base.NumInstructions = 2;
    prog->Base.InputsRead = 1 << inputAttr;
-   prog->Base.OutputsWritten = 1 << FRAG_RESULT_COLOR;
+   prog->Base.OutputsWritten = BITFIELD64_BIT(FRAG_RESULT_COLOR);
 }
 
 
@@ -657,7 +653,7 @@
    prog->Base.Instructions = inst;
    prog->Base.NumInstructions = 2;
    prog->Base.InputsRead = 1 << inputAttr;
-   prog->Base.OutputsWritten = 1 << VERT_RESULT_COL0;
+   prog->Base.OutputsWritten = BITFIELD64_BIT(VERT_RESULT_COL0);
 
    /*
     * Now insert code to do standard modelview/projection transformation.
diff --git a/src/mesa/shader/slang/descrip.mms b/src/mesa/shader/slang/descrip.mms
index 6eefbcf..674b786 100644
--- a/src/mesa/shader/slang/descrip.mms
+++ b/src/mesa/shader/slang/descrip.mms
@@ -17,12 +17,12 @@
 
 VPATH = RCS
 
-INCDIR = [----.include],[--.main],[--.glapi],[-.slang],[-.grammar],[-]
+INCDIR = [----.include],[--.main],[--.glapi],[-.slang],[-]
 LIBDIR = [----.lib]
 CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)/float=ieee/ieee=denorm
 
 SOURCES = \
-	slang_compile.c,slang_preprocess.c
+	slang_compile.c
 
 OBJECTS = slang_builtin.obj,slang_codegen.obj,slang_compile.obj,\
 	slang_compile_function.obj,slang_compile_operation.obj,\
@@ -59,7 +59,6 @@
 slang_link.obj : slang_link.c
 slang_log.obj : slang_log.c
 slang_mem.obj : slang_mem.c
-slang_preprocess.obj : slang_preprocess.c
 slang_print.obj : slang_print.c
 slang_simplify.obj : slang_simplify.c
 slang_storage.obj : slang_storage.c
diff --git a/src/mesa/shader/slang/library/.gitignore b/src/mesa/shader/slang/library/.gitignore
new file mode 100644
index 0000000..02a89fc
--- /dev/null
+++ b/src/mesa/shader/slang/library/.gitignore
@@ -0,0 +1 @@
+*_gc.h
diff --git a/src/mesa/shader/slang/library/Makefile b/src/mesa/shader/slang/library/Makefile
index 0e03fac..c696451 100644
--- a/src/mesa/shader/slang/library/Makefile
+++ b/src/mesa/shader/slang/library/Makefile
@@ -4,9 +4,7 @@
 
 include $(TOP)/configs/current
 
-INCDIR = $(TOP)/include
-
-LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
+GLSL_CL = $(TOP)/src/glsl/apps/compile
 
 #
 # targets
@@ -14,42 +12,14 @@
 
 .PHONY: default clean
 
-default: syntax builtin
+default: builtin
 
 clean:
-	-rm -f syn_to_c gc_to_bin *_syn.h *_gc.h
-
-syntax: slang_pp_directives_syn.h slang_pp_expression_syn.h slang_shader_syn.h slang_pp_version_syn.h
+	-rm -f *_gc.h
 
 builtin: builtin_110 builtin_120
 
 #
-# executables
-#
-
-syn_to_c: syn_to_c.c
-	$(CC) syn_to_c.c -o syn_to_c
-
-gc_to_bin: gc_to_bin.c slang_shader_syn.h
-	$(CC) gc_to_bin.c -o gc_to_bin
-
-#
-# syntax scripts
-#
-
-slang_pp_directives_syn.h: syn_to_c slang_pp_directives.syn
-	./syn_to_c slang_pp_directives.syn > slang_pp_directives_syn.h
-
-slang_pp_expression_syn.h: syn_to_c slang_pp_expression.syn
-	./syn_to_c slang_pp_expression.syn > slang_pp_expression_syn.h
-
-slang_shader_syn.h: syn_to_c slang_shader.syn
-	./syn_to_c slang_shader.syn > slang_shader_syn.h
-
-slang_pp_version_syn.h: syn_to_c slang_pp_version.syn
-	./syn_to_c slang_pp_version.syn > slang_pp_version_syn.h
-
-#
 # builtin library sources
 #
 
@@ -58,24 +28,24 @@
 builtin_120: slang_120_core_gc.h slang_builtin_120_common_gc.h slang_builtin_120_fragment_gc.h
 
 
-slang_120_core_gc.h: gc_to_bin slang_120_core.gc
-	./gc_to_bin 1 slang_120_core.gc slang_120_core_gc.h
+slang_120_core_gc.h: slang_120_core.gc
+	$(GLSL_CL) fragment slang_120_core.gc slang_120_core_gc.h
 
-slang_builtin_120_common_gc.h: gc_to_bin slang_builtin_120_common.gc
-	./gc_to_bin 1 slang_builtin_120_common.gc slang_builtin_120_common_gc.h
+slang_builtin_120_common_gc.h: slang_builtin_120_common.gc
+	$(GLSL_CL) fragment slang_builtin_120_common.gc slang_builtin_120_common_gc.h
 
-slang_builtin_120_fragment_gc.h: gc_to_bin slang_builtin_120_fragment.gc
-	./gc_to_bin 1 slang_builtin_120_fragment.gc slang_builtin_120_fragment_gc.h
+slang_builtin_120_fragment_gc.h: slang_builtin_120_fragment.gc
+	$(GLSL_CL) fragment slang_builtin_120_fragment.gc slang_builtin_120_fragment_gc.h
 
-slang_common_builtin_gc.h: gc_to_bin slang_common_builtin.gc
-	./gc_to_bin 1 slang_common_builtin.gc slang_common_builtin_gc.h
+slang_common_builtin_gc.h: slang_common_builtin.gc
+	$(GLSL_CL) fragment slang_common_builtin.gc slang_common_builtin_gc.h
 
-slang_core_gc.h: gc_to_bin slang_core.gc
-	./gc_to_bin 1 slang_core.gc slang_core_gc.h
+slang_core_gc.h: slang_core.gc
+	$(GLSL_CL) fragment slang_core.gc slang_core_gc.h
 
-slang_fragment_builtin_gc.h: gc_to_bin slang_fragment_builtin.gc
-	./gc_to_bin 1 slang_fragment_builtin.gc slang_fragment_builtin_gc.h
+slang_fragment_builtin_gc.h: slang_fragment_builtin.gc
+	$(GLSL_CL) fragment slang_fragment_builtin.gc slang_fragment_builtin_gc.h
 
-slang_vertex_builtin_gc.h: gc_to_bin slang_vertex_builtin.gc
-	./gc_to_bin 2 slang_vertex_builtin.gc slang_vertex_builtin_gc.h
+slang_vertex_builtin_gc.h: slang_vertex_builtin.gc
+	$(GLSL_CL) vertex slang_vertex_builtin.gc slang_vertex_builtin_gc.h
 
diff --git a/src/mesa/shader/slang/library/SConscript b/src/mesa/shader/slang/library/SConscript
new file mode 100644
index 0000000..ef13114
--- /dev/null
+++ b/src/mesa/shader/slang/library/SConscript
@@ -0,0 +1,52 @@
+#######################################################################
+# SConscript for GLSL builtin library
+
+Import('*')
+
+env = env.Clone()
+
+# See also http://www.scons.org/wiki/UsingCodeGenerators
+
+def glsl_compile_emitter(target, source, env):
+	env.Depends(target, glsl_compile)
+	return (target, source)
+ 
+bld_frag = Builder(
+	action = glsl_compile[0].abspath + ' fragment $SOURCE $TARGET',
+	emitter = glsl_compile_emitter,
+	suffix = '.gc',
+	src_suffix = '_gc.h')
+	
+bld_vert = Builder(
+	action = glsl_compile[0].abspath + ' vertex $SOURCE $TARGET',
+	emitter = glsl_compile_emitter,
+	suffix = '.gc',
+	src_suffix = '_gc.h')
+
+env['BUILDERS']['bld_frag'] = bld_frag
+env['BUILDERS']['bld_vert'] = bld_vert
+
+# Generate GLSL builtin library binaries
+env.bld_frag(
+	'#src/mesa/shader/slang/library/slang_core_gc.h',
+	'#src/mesa/shader/slang/library/slang_core.gc')
+env.bld_frag(
+	'#src/mesa/shader/slang/library/slang_common_builtin_gc.h',
+	'#src/mesa/shader/slang/library/slang_common_builtin.gc')
+env.bld_frag(
+	'#src/mesa/shader/slang/library/slang_fragment_builtin_gc.h',
+	'#src/mesa/shader/slang/library/slang_fragment_builtin.gc')
+env.bld_vert(
+	'#src/mesa/shader/slang/library/slang_vertex_builtin_gc.h',
+	'#src/mesa/shader/slang/library/slang_vertex_builtin.gc')
+
+# Generate GLSL 1.20 builtin library binaries
+env.bld_frag(
+	'#src/mesa/shader/slang/library/slang_120_core_gc.h',
+	'#src/mesa/shader/slang/library/slang_120_core.gc')
+env.bld_frag(
+	'#src/mesa/shader/slang/library/slang_builtin_120_common_gc.h',
+	'#src/mesa/shader/slang/library/slang_builtin_120_common.gc')
+env.bld_frag(
+	'#src/mesa/shader/slang/library/slang_builtin_120_fragment_gc.h',
+	'#src/mesa/shader/slang/library/slang_builtin_120_fragment.gc')
diff --git a/src/mesa/shader/slang/library/gc_to_bin.c b/src/mesa/shader/slang/library/gc_to_bin.c
deleted file mode 100644
index 8aef7b5..0000000
--- a/src/mesa/shader/slang/library/gc_to_bin.c
+++ /dev/null
@@ -1,85 +0,0 @@
-#include "../../grammar/grammar_crt.h"
-#include "../../grammar/grammar_crt.c"
-#include <stdlib.h>
-#include <stdio.h>
-
-static const char *slang_shader_syn =
-#include "slang_shader_syn.h"
-;
-
-static int gc_to_bin (grammar id, const char *in, const char *out)
-{
-	FILE *f;
-	byte *source, *prod;
-	unsigned int size, i, line = 0;
-
-	printf ("Precompiling %s\n", in);
-
-	f = fopen (in, "r");
-	if (f == NULL)
-		return 1;
-	fseek (f, 0, SEEK_END);
-	size = ftell (f);
-	fseek (f, 0, SEEK_SET);
-	source = (byte *) grammar_alloc_malloc (size + 1);
-	source[fread (source, 1, size, f)] = '\0';
-	fclose (f);
-
-	if (!grammar_fast_check (id, source, &prod, &size, 65536))
-	{
-		grammar_alloc_free (source);
-		return 1;
-	}
-
-	f = fopen (out, "w");
-	fprintf (f, "\n");
-	fprintf (f, "/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE FOLLOWING FILE: */\n");
-	fprintf (f, "/* %s */\n", in);
-	fprintf (f, "\n");
-	for (i = 0; i < size; i++)
-	{
-		unsigned int a;
-		if (prod[i] < 10)
-			a = 1;
-		else if (prod[i] < 100)
-			a = 2;
-		else
-			a = 3;
-		if (i < size - 1)
-			a++;
-		if (line + a >= 100)
-		{
-			fprintf (f, "\n");
-			line = 0;
-		}
-		line += a;
-		fprintf (f, "%d", prod[i]);
-		if (i < size - 1)
-			fprintf (f, ",");
-	}
-	fprintf (f, "\n");
-	fclose (f);
-	grammar_alloc_free (prod);
-   return 0;
-}
-
-int main (int argc, char *argv[])
-{
-   grammar id;
-
-   id = grammar_load_from_text ((const byte *) slang_shader_syn);
-   if (id == 0) {
-      fprintf(stderr, "Error loading grammar from text\n");
-      return 1;
-   }
-   grammar_set_reg8 (id, (const byte *) "parsing_builtin", 1);
-   grammar_set_reg8 (id, (const byte *) "shader_type", atoi (argv[1]));
-   if (gc_to_bin (id, argv[2], argv[3])) {
-      fprintf(stderr, "Error in gc_to_bin %s %s\n", argv[2], argv[3]);
-      grammar_destroy (id);
-      return 1;
-   }
-   grammar_destroy (id);
-   return 0;
-}
-
diff --git a/src/mesa/shader/slang/library/slang_120_core_gc.h b/src/mesa/shader/slang/library/slang_120_core_gc.h
deleted file mode 100644
index 1fdbddf..0000000
--- a/src/mesa/shader/slang/library/slang_120_core_gc.h
+++ /dev/null
@@ -1,764 +0,0 @@
-
-/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE FOLLOWING FILE: */
-/* slang_120_core.gc */
-
-5,1,90,95,0,0,26,0,1,1,1,0,0,9,0,102,48,48,0,0,1,1,0,0,9,0,102,49,48,0,0,1,1,0,0,9,0,102,50,48,0,0,
-1,1,0,0,9,0,102,48,49,0,0,1,1,0,0,9,0,102,49,49,0,0,1,1,0,0,9,0,102,50,49,0,0,0,1,9,18,95,95,114,
-101,116,86,97,108,0,16,8,48,0,57,59,120,0,18,102,48,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,
-16,8,48,0,57,59,121,0,18,102,49,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,122,0,
-18,102,50,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,120,0,18,102,48,49,0,20,0,
-9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,121,0,18,102,49,49,0,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,49,0,57,59,122,0,18,102,50,49,0,20,0,0,1,90,95,0,0,26,0,1,1,1,0,0,9,0,102,0,
-0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,50,120,51,0,0,18,102,0,0,17,48,0,48,0,0,0,
-17,48,0,48,0,0,0,17,48,0,48,0,0,0,18,102,0,0,17,48,0,48,0,0,0,0,20,0,0,1,90,95,0,0,26,0,1,1,1,0,0,
-5,0,105,0,0,0,1,3,2,90,95,1,0,9,0,1,102,0,2,58,102,108,111,97,116,0,0,18,105,0,0,0,0,0,9,18,95,95,
-114,101,116,86,97,108,0,58,109,97,116,50,120,51,0,0,18,102,0,0,0,20,0,0,1,90,95,0,0,26,0,1,1,1,0,0,
-1,0,98,0,0,0,1,3,2,90,95,1,0,9,0,1,102,0,2,58,102,108,111,97,116,0,0,18,98,0,0,0,0,0,9,18,95,95,
-114,101,116,86,97,108,0,58,109,97,116,50,120,51,0,0,18,102,0,0,0,20,0,0,1,90,95,0,0,26,0,1,1,1,0,0,
-11,0,99,48,0,0,1,1,0,0,11,0,99,49,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,99,48,
-0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,99,49,0,20,0,0,1,90,95,0,0,28,0,1,1,1,0,
-0,9,0,102,48,48,0,0,1,1,0,0,9,0,102,49,48,0,0,1,1,0,0,9,0,102,50,48,0,0,1,1,0,0,9,0,102,51,48,0,0,
-1,1,0,0,9,0,102,48,49,0,0,1,1,0,0,9,0,102,49,49,0,0,1,1,0,0,9,0,102,50,49,0,0,1,1,0,0,9,0,102,51,
-49,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,120,0,18,102,48,48,0,20,0,9,18,95,95,
-114,101,116,86,97,108,0,16,8,48,0,57,59,121,0,18,102,49,48,0,20,0,9,18,95,95,114,101,116,86,97,108,
-0,16,8,48,0,57,59,122,0,18,102,50,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,119,
-0,18,102,51,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,120,0,18,102,48,49,0,20,
-0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,121,0,18,102,49,49,0,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,49,0,57,59,122,0,18,102,50,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,
-10,49,0,57,59,119,0,18,102,51,49,0,20,0,0,1,90,95,0,0,28,0,1,1,1,0,0,9,0,102,0,0,0,1,9,18,95,95,
-114,101,116,86,97,108,0,58,109,97,116,50,120,52,0,0,18,102,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,
-17,48,0,48,0,0,0,17,48,0,48,0,0,0,18,102,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,0,20,0,0,1,90,95,0,
-0,28,0,1,1,1,0,0,5,0,105,0,0,0,1,3,2,90,95,1,0,9,0,1,102,0,2,58,102,108,111,97,116,0,0,18,105,0,0,
-0,0,0,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,50,120,52,0,0,18,102,0,0,0,20,0,0,1,90,95,0,
-0,28,0,1,1,1,0,0,1,0,98,0,0,0,1,3,2,90,95,1,0,9,0,1,102,0,2,58,102,108,111,97,116,0,0,18,98,0,0,0,
-0,0,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,50,120,52,0,0,18,102,0,0,0,20,0,0,1,90,95,0,0,
-28,0,1,1,1,0,0,12,0,99,48,0,0,1,1,0,0,12,0,99,49,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,
-48,0,57,18,99,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,99,49,0,20,0,0,1,90,95,
-0,0,27,0,1,1,1,0,0,9,0,102,48,48,0,0,1,1,0,0,9,0,102,49,48,0,0,1,1,0,0,9,0,102,48,49,0,0,1,1,0,0,9,
-0,102,49,49,0,0,1,1,0,0,9,0,102,48,50,0,0,1,1,0,0,9,0,102,49,50,0,0,0,1,9,18,95,95,114,101,116,86,
-97,108,0,16,8,48,0,57,59,120,0,18,102,48,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,
-59,121,0,18,102,49,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,120,0,18,102,48,
-49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,121,0,18,102,49,49,0,20,0,9,18,95,95,
-114,101,116,86,97,108,0,16,10,50,0,57,59,120,0,18,102,48,50,0,20,0,9,18,95,95,114,101,116,86,97,
-108,0,16,10,50,0,57,59,121,0,18,102,49,50,0,20,0,0,1,90,95,0,0,27,0,1,1,1,0,0,9,0,102,0,0,0,1,9,18,
-95,95,114,101,116,86,97,108,0,58,109,97,116,51,120,50,0,0,18,102,0,0,17,48,0,48,0,0,0,17,48,0,48,0,
-0,0,18,102,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,0,20,0,0,1,90,95,0,0,27,0,1,1,1,0,0,5,0,105,0,0,0,
-1,3,2,90,95,1,0,9,0,1,102,0,2,58,102,108,111,97,116,0,0,18,105,0,0,0,0,0,9,18,95,95,114,101,116,86,
-97,108,0,58,109,97,116,51,120,50,0,0,18,102,0,0,0,20,0,0,1,90,95,0,0,27,0,1,1,1,0,0,1,0,98,0,0,0,1,
-3,2,90,95,1,0,9,0,1,102,0,2,58,102,108,111,97,116,0,0,18,98,0,0,0,0,0,9,18,95,95,114,101,116,86,97,
-108,0,58,109,97,116,51,120,50,0,0,18,102,0,0,0,20,0,0,1,90,95,0,0,27,0,1,1,1,0,0,10,0,99,48,0,0,1,
-1,0,0,10,0,99,49,0,0,1,1,0,0,10,0,99,50,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,
-99,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,99,49,0,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,50,0,57,18,99,50,0,20,0,0,1,90,95,0,0,30,0,1,1,1,0,0,9,0,102,48,48,0,0,1,1,0,
-0,9,0,102,49,48,0,0,1,1,0,0,9,0,102,50,48,0,0,1,1,0,0,9,0,102,51,48,0,0,1,1,0,0,9,0,102,48,49,0,0,
-1,1,0,0,9,0,102,49,49,0,0,1,1,0,0,9,0,102,50,49,0,0,1,1,0,0,9,0,102,51,49,0,0,1,1,0,0,9,0,102,48,
-50,0,0,1,1,0,0,9,0,102,49,50,0,0,1,1,0,0,9,0,102,50,50,0,0,1,1,0,0,9,0,102,51,50,0,0,0,1,9,18,95,
-95,114,101,116,86,97,108,0,16,8,48,0,57,59,120,0,18,102,48,48,0,20,0,9,18,95,95,114,101,116,86,97,
-108,0,16,8,48,0,57,59,121,0,18,102,49,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,
-122,0,18,102,50,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,119,0,18,102,51,48,0,
-20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,120,0,18,102,48,49,0,20,0,9,18,95,95,114,
-101,116,86,97,108,0,16,10,49,0,57,59,121,0,18,102,49,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,
-16,10,49,0,57,59,122,0,18,102,50,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,119,
-0,18,102,51,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,59,120,0,18,102,48,50,0,20,
-0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,59,121,0,18,102,49,50,0,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,50,0,57,59,122,0,18,102,50,50,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,
-10,50,0,57,59,119,0,18,102,51,50,0,20,0,0,1,90,95,0,0,30,0,1,1,1,0,0,9,0,102,0,0,0,1,9,18,95,95,
-114,101,116,86,97,108,0,58,109,97,116,51,120,52,0,0,18,102,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,
-17,48,0,48,0,0,0,17,48,0,48,0,0,0,18,102,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,17,
-48,0,48,0,0,0,18,102,0,0,17,48,0,48,0,0,0,0,20,0,0,1,90,95,0,0,30,0,1,1,1,0,0,5,0,105,0,0,0,1,3,2,
-90,95,1,0,9,0,1,102,0,2,58,102,108,111,97,116,0,0,18,105,0,0,0,0,0,9,18,95,95,114,101,116,86,97,
-108,0,58,109,97,116,51,120,52,0,0,18,102,0,0,0,20,0,0,1,90,95,0,0,30,0,1,1,1,0,0,1,0,98,0,0,0,1,3,
-2,90,95,1,0,9,0,1,102,0,2,58,102,108,111,97,116,0,0,18,98,0,0,0,0,0,9,18,95,95,114,101,116,86,97,
-108,0,58,109,97,116,51,120,52,0,0,18,102,0,0,0,20,0,0,1,90,95,0,0,30,0,1,1,1,0,0,12,0,99,48,0,0,1,
-1,0,0,12,0,99,49,0,0,1,1,0,0,12,0,99,50,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,
-99,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,99,49,0,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,50,0,57,18,99,50,0,20,0,0,1,90,95,0,0,29,0,1,1,1,0,0,9,0,102,48,48,0,0,1,1,0,
-0,9,0,102,49,48,0,0,1,1,0,0,9,0,102,48,49,0,0,1,1,0,0,9,0,102,49,49,0,0,1,1,0,0,9,0,102,48,50,0,0,
-1,1,0,0,9,0,102,49,50,0,0,1,1,0,0,9,0,102,48,51,0,0,1,1,0,0,9,0,102,49,51,0,0,0,1,9,18,95,95,114,
-101,116,86,97,108,0,16,8,48,0,57,59,120,0,18,102,48,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,
-16,8,48,0,57,59,121,0,18,102,49,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,120,
-0,18,102,48,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,121,0,18,102,49,49,0,20,
-0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,59,120,0,18,102,48,50,0,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,50,0,57,59,121,0,18,102,49,50,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,
-10,51,0,57,59,120,0,18,102,48,51,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,59,121,0,
-18,102,49,51,0,20,0,0,1,90,95,0,0,29,0,1,1,1,0,0,9,0,102,0,0,0,1,9,18,95,95,114,101,116,86,97,108,
-0,58,109,97,116,52,120,50,0,0,18,102,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,16,10,52,0,0,17,48,0,48,
-0,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,0,20,0,0,1,90,95,0,0,29,0,1,1,1,0,0,5,0,
-105,0,0,0,1,3,2,90,95,1,0,9,0,1,102,0,2,58,102,108,111,97,116,0,0,18,105,0,0,0,0,0,9,18,95,95,114,
-101,116,86,97,108,0,58,109,97,116,52,120,50,0,0,18,102,0,0,0,20,0,0,1,90,95,0,0,29,0,1,1,1,0,0,1,0,
-98,0,0,0,1,3,2,90,95,1,0,9,0,1,102,0,2,58,102,108,111,97,116,0,0,18,98,0,0,0,0,0,9,18,95,95,114,
-101,116,86,97,108,0,58,109,97,116,52,120,50,0,0,18,102,0,0,0,20,0,0,1,90,95,0,0,29,0,1,1,1,0,0,10,
-0,99,48,0,0,1,1,0,0,10,0,99,49,0,0,1,1,0,0,10,0,99,50,0,0,1,1,0,0,10,0,99,51,0,0,0,1,9,18,95,95,
-114,101,116,86,97,108,0,16,8,48,0,57,18,99,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,
-57,18,99,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,99,50,0,20,0,9,18,95,95,114,
-101,116,86,97,108,0,16,10,51,0,57,18,99,51,0,20,0,0,1,90,95,0,0,31,0,1,1,1,0,0,9,0,102,48,48,0,0,1,
-1,0,0,9,0,102,49,48,0,0,1,1,0,0,9,0,102,50,48,0,0,1,1,0,0,9,0,102,48,49,0,0,1,1,0,0,9,0,102,49,49,
-0,0,1,1,0,0,9,0,102,50,49,0,0,1,1,0,0,9,0,102,48,50,0,0,1,1,0,0,9,0,102,49,50,0,0,1,1,0,0,9,0,102,
-50,50,0,0,1,1,0,0,9,0,102,48,51,0,0,1,1,0,0,9,0,102,49,51,0,0,1,1,0,0,9,0,102,50,51,0,0,0,1,9,18,
-95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,120,0,18,102,48,48,0,20,0,9,18,95,95,114,101,116,86,
-97,108,0,16,8,48,0,57,59,121,0,18,102,49,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,
-59,122,0,18,102,50,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,120,0,18,102,48,
-49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,121,0,18,102,49,49,0,20,0,9,18,95,95,
-114,101,116,86,97,108,0,16,10,49,0,57,59,122,0,18,102,50,49,0,20,0,9,18,95,95,114,101,116,86,97,
-108,0,16,10,50,0,57,59,120,0,18,102,48,50,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,
-59,121,0,18,102,49,50,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,59,122,0,18,102,50,
-50,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,59,120,0,18,102,48,51,0,20,0,9,18,95,95,
-114,101,116,86,97,108,0,16,10,51,0,57,59,121,0,18,102,49,51,0,20,0,9,18,95,95,114,101,116,86,97,
-108,0,16,10,51,0,57,59,122,0,18,102,50,51,0,20,0,0,1,90,95,0,0,31,0,1,1,1,0,0,9,0,102,0,0,0,1,9,18,
-95,95,114,101,116,86,97,108,0,58,109,97,116,52,120,51,0,0,18,102,0,0,17,48,0,48,0,0,0,17,48,0,48,0,
-0,0,17,48,0,48,0,0,0,18,102,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,18,102,0,0,17,
-48,0,48,0,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,0,20,0,0,1,90,95,0,0,31,0,1,1,1,0,0,5,0,105,0,0,0,
-1,3,2,90,95,1,0,9,0,1,102,0,2,58,102,108,111,97,116,0,0,18,105,0,0,0,0,0,9,18,95,95,114,101,116,86,
-97,108,0,58,109,97,116,52,120,51,0,0,18,102,0,0,0,20,0,0,1,90,95,0,0,31,0,1,1,1,0,0,1,0,98,0,0,0,1,
-3,2,90,95,1,0,9,0,1,102,0,2,58,102,108,111,97,116,0,0,18,98,0,0,0,0,0,9,18,95,95,114,101,116,86,97,
-108,0,58,109,97,116,52,120,51,0,0,18,102,0,0,0,20,0,0,1,90,95,0,0,31,0,1,1,1,0,0,11,0,99,48,0,0,1,
-1,0,0,11,0,99,49,0,0,1,1,0,0,11,0,99,50,0,0,1,1,0,0,11,0,99,51,0,0,0,1,9,18,95,95,114,101,116,86,
-97,108,0,16,8,48,0,57,18,99,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,99,49,0,
-20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,99,50,0,20,0,9,18,95,95,114,101,116,86,97,
-108,0,16,10,51,0,57,18,99,51,0,20,0,0,1,90,95,0,0,13,0,1,1,1,0,0,13,0,109,0,0,0,1,9,18,95,95,114,
-101,116,86,97,108,0,18,109,0,20,0,0,1,90,95,0,0,13,0,1,1,1,0,0,27,0,109,0,0,0,1,9,18,95,95,114,101,
-116,86,97,108,0,58,109,97,116,50,0,0,18,109,0,16,8,48,0,57,0,18,109,0,16,10,49,0,57,0,0,20,0,0,1,
-90,95,0,0,13,0,1,1,1,0,0,29,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,50,0,0,
-18,109,0,16,8,48,0,57,0,18,109,0,16,10,49,0,57,0,0,20,0,0,1,90,95,0,0,13,0,1,1,1,0,0,26,0,109,0,0,
-0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,50,0,0,18,109,0,16,8,48,0,57,59,120,121,0,0,
-18,109,0,16,10,49,0,57,59,120,121,0,0,0,20,0,0,1,90,95,0,0,13,0,1,1,1,0,0,28,0,109,0,0,0,1,9,18,95,
-95,114,101,116,86,97,108,0,58,109,97,116,50,0,0,18,109,0,16,8,48,0,57,59,120,121,0,0,18,109,0,16,
-10,49,0,57,59,120,121,0,0,0,20,0,0,1,90,95,0,0,13,0,1,1,1,0,0,14,0,109,0,0,0,1,9,18,95,95,114,101,
-116,86,97,108,0,58,109,97,116,50,0,0,18,109,0,16,8,48,0,57,59,120,121,0,0,18,109,0,16,10,49,0,57,
-59,120,121,0,0,0,20,0,0,1,90,95,0,0,13,0,1,1,1,0,0,30,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,
-108,0,58,109,97,116,50,0,0,18,109,0,16,8,48,0,57,59,120,121,0,0,18,109,0,16,10,49,0,57,59,120,121,
-0,0,0,20,0,0,1,90,95,0,0,13,0,1,1,1,0,0,31,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,
-97,116,50,0,0,18,109,0,16,8,48,0,57,59,120,121,0,0,18,109,0,16,10,49,0,57,59,120,121,0,0,0,20,0,0,
-1,90,95,0,0,13,0,1,1,1,0,0,15,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,50,0,
-0,18,109,0,16,8,48,0,57,59,120,121,0,0,18,109,0,16,10,49,0,57,59,120,121,0,0,0,20,0,0,1,90,95,0,0,
-26,0,1,1,1,0,0,26,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,90,95,0,0,26,
-0,1,1,1,0,0,14,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,50,120,51,0,0,18,109,
-0,16,8,48,0,57,0,18,109,0,16,10,49,0,57,0,0,20,0,0,1,90,95,0,0,26,0,1,1,1,0,0,31,0,109,0,0,0,1,9,
-18,95,95,114,101,116,86,97,108,0,58,109,97,116,50,120,51,0,0,18,109,0,16,8,48,0,57,0,18,109,0,16,
-10,49,0,57,0,0,20,0,0,1,90,95,0,0,26,0,1,1,1,0,0,28,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,
-0,58,109,97,116,50,120,51,0,0,18,109,0,16,8,48,0,57,59,120,121,122,0,0,18,109,0,16,10,49,0,57,59,
-120,121,122,0,0,0,20,0,0,1,90,95,0,0,26,0,1,1,1,0,0,30,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,
-108,0,58,109,97,116,50,120,51,0,0,18,109,0,16,8,48,0,57,59,120,121,122,0,0,18,109,0,16,10,49,0,57,
-59,120,121,122,0,0,0,20,0,0,1,90,95,0,0,26,0,1,1,1,0,0,15,0,109,0,0,0,1,9,18,95,95,114,101,116,86,
-97,108,0,58,109,97,116,50,120,51,0,0,18,109,0,16,8,48,0,57,59,120,121,122,0,0,18,109,0,16,10,49,0,
-57,59,120,121,122,0,0,0,20,0,0,1,90,95,0,0,26,0,1,1,1,0,0,13,0,109,0,0,0,1,9,18,95,95,114,101,116,
-86,97,108,0,58,109,97,116,50,120,51,0,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,
-121,0,0,17,48,0,48,0,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,121,0,0,17,48,
-0,48,0,0,0,0,20,0,0,1,90,95,0,0,26,0,1,1,1,0,0,27,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,
-58,109,97,116,50,120,51,0,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,17,
-48,0,48,0,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,121,0,0,17,48,0,48,0,0,0,
-0,20,0,0,1,90,95,0,0,26,0,1,1,1,0,0,29,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,
-116,50,120,51,0,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,17,48,0,48,0,0,
-0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,121,0,0,17,48,0,48,0,0,0,0,20,0,0,1,
-90,95,0,0,28,0,1,1,1,0,0,28,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,90,
-95,0,0,28,0,1,1,1,0,0,30,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,50,120,52,
-0,0,18,109,0,16,8,48,0,57,0,18,109,0,16,10,49,0,57,0,0,20,0,0,1,90,95,0,0,28,0,1,1,1,0,0,15,0,109,
-0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,50,120,52,0,0,18,109,0,16,8,48,0,57,0,18,
-109,0,16,10,49,0,57,0,0,20,0,0,1,90,95,0,0,28,0,1,1,1,0,0,26,0,109,0,0,0,1,9,18,95,95,114,101,116,
-86,97,108,0,58,109,97,116,50,120,52,0,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,
-121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,17,48,0,48,0,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,
-0,16,10,49,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,122,0,0,17,48,0,48,0,0,0,0,20,0,0,1,90,95,0,0,
-28,0,1,1,1,0,0,14,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,50,120,52,0,0,18,
-109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,17,
-48,0,48,0,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,10,
-49,0,57,59,122,0,0,17,48,0,48,0,0,0,0,20,0,0,1,90,95,0,0,28,0,1,1,1,0,0,31,0,109,0,0,0,1,9,18,95,
-95,114,101,116,86,97,108,0,58,109,97,116,50,120,52,0,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,
-16,8,48,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,17,48,0,48,0,0,0,18,109,0,16,10,49,0,57,
-59,120,0,0,18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,122,0,0,17,48,0,48,0,0,0,0,
-20,0,0,1,90,95,0,0,28,0,1,1,1,0,0,13,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,
-116,50,120,52,0,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,121,0,0,17,48,0,48,0,
-0,0,17,48,0,48,0,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,121,0,0,17,48,0,
-48,0,0,0,17,48,0,48,0,0,0,0,20,0,0,1,90,95,0,0,28,0,1,1,1,0,0,27,0,109,0,0,0,1,9,18,95,95,114,101,
-116,86,97,108,0,58,109,97,116,50,120,52,0,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,8,48,0,57,
-59,121,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,49,0,
-57,59,121,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,0,20,0,0,1,90,95,0,0,28,0,1,1,1,0,0,29,0,109,0,0,0,
-1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,50,120,52,0,0,18,109,0,16,8,48,0,57,59,120,0,0,
-18,109,0,16,8,48,0,57,59,121,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,18,109,0,16,10,49,0,57,59,120,0,
-0,18,109,0,16,10,49,0,57,59,121,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,0,20,0,0,1,90,95,0,0,27,0,1,
-1,1,0,0,27,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,90,95,0,0,27,0,1,1,1,
-0,0,29,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,51,120,50,0,0,18,109,0,16,8,
-48,0,57,0,18,109,0,16,10,49,0,57,0,18,109,0,16,10,50,0,57,0,0,20,0,0,1,90,95,0,0,27,0,1,1,1,0,0,14,
-0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,51,120,50,0,0,18,109,0,16,8,48,0,57,
-0,18,109,0,16,10,49,0,57,0,18,109,0,16,10,50,0,57,0,0,20,0,0,1,90,95,0,0,27,0,1,1,1,0,0,30,0,109,0,
-0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,51,120,50,0,0,18,109,0,16,8,48,0,57,59,120,
-0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,
-121,0,0,18,109,0,16,10,50,0,57,59,120,0,0,18,109,0,16,10,50,0,57,59,121,0,0,0,20,0,0,1,90,95,0,0,
-27,0,1,1,1,0,0,31,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,51,120,50,0,0,18,
-109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,120,0,0,
-18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,10,50,0,57,59,120,0,0,18,109,0,16,10,50,0,57,59,121,
-0,0,0,20,0,0,1,90,95,0,0,27,0,1,1,1,0,0,15,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,
-97,116,51,120,50,0,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,
-10,49,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,121,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,0,20,0,0,
-1,90,95,0,0,27,0,1,1,1,0,0,13,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,51,
-120,50,0,0,18,109,0,16,8,48,0,57,0,18,109,0,16,10,49,0,57,0,58,118,101,99,50,0,0,17,48,0,48,0,0,0,
-0,0,0,20,0,0,1,90,95,0,0,27,0,1,1,1,0,0,26,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,
-97,116,51,120,50,0,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,
-10,49,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,121,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,0,20,0,0,
-1,90,95,0,0,27,0,1,1,1,0,0,28,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,51,
-120,50,0,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,
-57,59,120,0,0,18,109,0,16,10,49,0,57,59,121,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,0,20,0,0,1,90,95,
-0,0,14,0,1,1,1,0,0,14,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,90,95,0,0,
-14,0,1,1,1,0,0,31,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,51,0,0,18,109,0,
-16,8,48,0,57,0,18,109,0,16,10,49,0,57,0,18,109,0,16,10,50,0,57,0,0,20,0,0,1,90,95,0,0,14,0,1,1,1,0,
-0,30,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,51,0,0,18,109,0,16,8,48,0,57,
-59,120,121,122,0,0,18,109,0,16,10,49,0,57,59,120,121,122,0,0,18,109,0,16,10,50,0,57,59,120,121,122,
-0,0,0,20,0,0,1,90,95,0,0,14,0,1,1,1,0,0,15,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,
-97,116,51,0,0,18,109,0,16,8,48,0,57,59,120,121,122,0,0,18,109,0,16,10,49,0,57,59,120,121,122,0,0,
-18,109,0,16,10,50,0,57,59,120,121,122,0,0,0,20,0,0,1,90,95,0,0,14,0,1,1,1,0,0,26,0,109,0,0,0,1,9,
-18,95,95,114,101,116,86,97,108,0,58,109,97,116,51,0,0,18,109,0,16,8,48,0,57,0,18,109,0,16,10,49,0,
-57,0,17,48,0,0,0,0,17,48,0,0,0,0,17,49,0,0,0,0,0,20,0,0,1,90,95,0,0,14,0,1,1,1,0,0,28,0,109,0,0,0,
-1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,51,0,0,18,109,0,16,8,48,0,57,59,120,121,122,0,0,
-18,109,0,16,10,49,0,57,59,120,121,122,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,49,0,0,0,0,0,20,0,0,1,90,
-95,0,0,14,0,1,1,1,0,0,27,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,51,0,0,18,
-109,0,16,8,48,0,57,0,17,48,0,0,0,0,18,109,0,16,10,49,0,57,0,17,48,0,0,0,0,18,109,0,16,10,50,0,57,0,
-17,49,0,0,0,0,0,20,0,0,1,90,95,0,0,14,0,1,1,1,0,0,29,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,
-108,0,58,109,97,116,51,0,0,18,109,0,16,8,48,0,57,0,17,48,0,0,0,0,18,109,0,16,10,49,0,57,0,17,48,0,
-0,0,0,18,109,0,16,10,50,0,57,0,17,49,0,0,0,0,0,20,0,0,1,90,95,0,0,14,0,1,1,1,0,0,13,0,109,0,0,0,1,
-9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,51,0,0,18,109,0,16,8,48,0,57,0,17,48,0,0,0,0,18,
-109,0,16,10,49,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,49,0,0,0,0,0,20,0,0,1,90,95,0,0,
-30,0,1,1,1,0,0,30,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,90,95,0,0,30,
-0,1,1,1,0,0,15,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,51,120,52,0,0,18,109,
-0,16,8,48,0,57,0,18,109,0,16,10,49,0,57,0,18,109,0,16,10,50,0,57,0,0,20,0,0,1,90,95,0,0,30,0,1,1,1,
-0,0,14,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,51,120,52,0,0,18,109,0,16,8,
-48,0,57,0,17,48,0,0,0,0,18,109,0,16,10,49,0,57,0,17,48,0,0,0,0,18,109,0,16,10,50,0,57,0,17,48,0,0,
-0,0,0,20,0,0,1,90,95,0,0,30,0,1,1,1,0,0,31,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,
-97,116,51,120,52,0,0,18,109,0,16,8,48,0,57,0,17,48,0,0,0,0,18,109,0,16,10,49,0,57,0,17,48,0,0,0,0,
-18,109,0,16,10,50,0,57,0,17,48,0,0,0,0,0,20,0,0,1,90,95,0,0,30,0,1,1,1,0,0,28,0,109,0,0,0,1,9,18,
-95,95,114,101,116,86,97,108,0,58,109,97,116,51,120,52,0,0,18,109,0,16,8,48,0,57,0,18,109,0,16,10,
-49,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,17,49,0,0,0,0,17,48,0,0,0,0,0,20,0,0,1,90,95,0,0,30,0,1,1,1,
-0,0,26,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,51,120,52,0,0,18,109,0,16,8,
-48,0,57,0,17,48,0,0,0,0,18,109,0,16,10,49,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,49,0,
-0,0,0,17,48,0,0,0,0,0,20,0,0,1,90,95,0,0,30,0,1,1,1,0,0,27,0,109,0,0,0,1,9,18,95,95,114,101,116,86,
-97,108,0,58,109,97,116,51,120,52,0,0,18,109,0,16,8,48,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,18,109,0,
-16,10,49,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,18,109,0,16,10,50,0,57,0,17,49,0,0,0,0,17,48,0,0,0,0,0,
-20,0,0,1,90,95,0,0,30,0,1,1,1,0,0,29,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,
-116,51,120,52,0,0,18,109,0,16,8,48,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,18,109,0,16,10,49,0,57,0,17,
-48,0,0,0,0,17,48,0,0,0,0,18,109,0,16,10,50,0,57,0,17,49,0,0,0,0,17,48,0,0,0,0,0,20,0,0,1,90,95,0,0,
-30,0,1,1,1,0,0,13,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,51,120,52,0,0,18,
-109,0,16,8,48,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,18,109,0,16,10,49,0,57,0,17,48,0,0,0,0,17,48,0,0,
-0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,49,0,0,0,0,17,48,0,0,0,0,0,20,0,0,1,90,95,0,0,29,0,1,1,1,0,0,29,
-0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,90,95,0,0,29,0,1,1,1,0,0,31,0,
-109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,52,120,50,0,0,18,109,0,16,8,48,0,57,
-59,120,121,0,0,18,109,0,16,10,49,0,57,59,120,121,0,0,18,109,0,16,10,50,0,57,59,120,121,0,0,18,109,
-0,16,10,51,0,57,59,120,121,0,0,0,20,0,0,1,90,95,0,0,29,0,1,1,1,0,0,15,0,109,0,0,0,1,9,18,95,95,114,
-101,116,86,97,108,0,58,109,97,116,52,120,50,0,0,18,109,0,16,8,48,0,57,59,120,121,0,0,18,109,0,16,
-10,49,0,57,59,120,121,0,0,18,109,0,16,10,50,0,57,59,120,121,0,0,18,109,0,16,10,51,0,57,59,120,121,
-0,0,0,20,0,0,1,90,95,0,0,29,0,1,1,1,0,0,27,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,
-97,116,52,120,50,0,0,18,109,0,16,8,48,0,57,0,18,109,0,16,10,49,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,
-0,20,0,0,1,90,95,0,0,29,0,1,1,1,0,0,14,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,
-116,52,120,50,0,0,18,109,0,16,8,48,0,57,59,120,121,0,0,18,109,0,16,10,49,0,57,59,120,121,0,0,18,
-109,0,16,10,50,0,57,59,120,121,0,0,17,48,0,0,0,0,17,48,0,0,0,0,0,20,0,0,1,90,95,0,0,29,0,1,1,1,0,0,
-30,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,52,120,50,0,0,18,109,0,16,8,48,0,
-57,59,120,121,0,0,18,109,0,16,10,49,0,57,59,120,121,0,0,18,109,0,16,10,50,0,57,59,120,121,0,0,17,
-48,0,0,0,0,17,48,0,0,0,0,0,20,0,0,1,90,95,0,0,29,0,1,1,1,0,0,13,0,109,0,0,0,1,9,18,95,95,114,101,
-116,86,97,108,0,58,109,97,116,52,120,50,0,0,18,109,0,16,8,48,0,57,0,18,109,0,16,10,49,0,57,0,17,48,
-0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,0,20,0,0,1,90,95,0,0,29,0,1,1,1,0,0,26,0,109,0,0,
-0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,52,120,50,0,0,18,109,0,16,8,48,0,57,59,120,
-121,0,0,18,109,0,16,10,49,0,57,59,120,121,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,
-0,0,0,20,0,0,1,90,95,0,0,29,0,1,1,1,0,0,28,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,
-97,116,52,120,50,0,0,18,109,0,16,8,48,0,57,59,120,121,0,0,18,109,0,16,10,49,0,57,59,120,121,0,0,17,
-48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,0,20,0,0,1,90,95,0,0,31,0,1,1,1,0,0,31,0,109,
-0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,90,95,0,0,31,0,1,1,1,0,0,15,0,109,0,0,
-0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,52,120,51,0,0,18,109,0,16,8,48,0,57,59,120,
-121,122,0,0,18,109,0,16,10,49,0,57,59,120,121,122,0,0,18,109,0,16,10,50,0,57,59,120,121,122,0,0,18,
-109,0,16,10,51,0,57,59,120,121,122,0,0,0,20,0,0,1,90,95,0,0,31,0,1,1,1,0,0,14,0,109,0,0,0,1,9,18,
-95,95,114,101,116,86,97,108,0,58,109,97,116,52,120,51,0,0,18,109,0,16,8,48,0,57,0,18,109,0,16,10,
-49,0,57,0,18,109,0,16,10,50,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,0,20,0,0,1,90,95,0,0,
-31,0,1,1,1,0,0,30,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,52,120,51,0,0,18,
-109,0,16,8,48,0,57,59,120,121,122,0,0,18,109,0,16,10,49,0,57,59,120,121,122,0,0,18,109,0,16,10,50,
-0,57,59,120,121,122,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,0,20,0,0,1,90,95,0,0,31,0,1,1,1,
-0,0,29,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,52,120,51,0,0,18,109,0,16,8,
-48,0,57,0,17,48,0,0,0,0,18,109,0,16,10,49,0,57,0,17,48,0,0,0,0,18,109,0,16,10,50,0,57,0,17,49,0,0,
-0,0,18,109,0,16,10,51,0,57,0,17,48,0,0,0,0,0,20,0,0,1,90,95,0,0,31,0,1,1,1,0,0,26,0,109,0,0,0,1,9,
-18,95,95,114,101,116,86,97,108,0,58,109,97,116,52,120,51,0,0,18,109,0,16,8,48,0,57,0,18,109,0,16,
-10,49,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,17,49,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,0,
-20,0,0,1,90,95,0,0,31,0,1,1,1,0,0,27,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,
-116,52,120,51,0,0,18,109,0,16,8,48,0,57,0,17,48,0,0,0,0,18,109,0,16,10,49,0,57,0,17,48,0,0,0,0,18,
-109,0,16,10,50,0,57,0,17,49,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,0,20,0,0,1,90,95,0,0,
-31,0,1,1,1,0,0,28,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,52,120,51,0,0,18,
-109,0,16,8,48,0,57,59,120,121,122,0,0,18,109,0,16,10,49,0,57,59,120,121,122,0,0,17,48,0,0,0,0,17,
-48,0,0,0,0,17,49,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,0,20,0,0,1,90,95,0,0,31,0,1,1,1,
-0,0,13,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,52,120,51,0,0,18,109,0,16,8,
-48,0,57,0,17,48,0,0,0,0,18,109,0,16,10,49,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,49,0,
-0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,0,20,0,0,1,90,95,0,0,15,0,1,1,1,0,0,15,0,109,0,0,0,
-1,9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,90,95,0,0,15,0,1,1,1,0,0,30,0,109,0,0,0,1,9,
-18,95,95,114,101,116,86,97,108,0,58,109,97,116,52,0,0,18,109,0,16,8,48,0,57,0,18,109,0,16,10,49,0,
-57,0,18,109,0,16,10,50,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,49,0,0,0,0,0,20,0,0,1,
-90,95,0,0,15,0,1,1,1,0,0,31,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,52,0,0,
-18,109,0,16,8,48,0,57,0,17,48,0,0,0,0,18,109,0,16,10,49,0,57,0,17,48,0,0,0,0,18,109,0,16,10,50,0,
-57,0,17,48,0,0,0,0,18,109,0,16,10,51,0,57,0,17,49,0,0,0,0,0,20,0,0,1,90,95,0,0,15,0,1,1,1,0,0,28,0,
-109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,52,0,0,18,109,0,16,8,48,0,57,0,18,109,
-0,16,10,49,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,17,49,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,
-0,0,17,48,0,0,0,0,17,49,0,0,0,0,0,20,0,0,1,90,95,0,0,15,0,1,1,1,0,0,29,0,109,0,0,0,1,9,18,95,95,
-114,101,116,86,97,108,0,58,109,97,116,52,0,0,18,109,0,16,8,48,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,
-18,109,0,16,10,49,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,18,109,0,16,10,50,0,57,0,17,49,0,0,0,0,17,48,
-0,0,0,0,18,109,0,16,10,51,0,57,0,17,48,0,0,0,0,17,49,0,0,0,0,0,20,0,0,1,90,95,0,0,15,0,1,1,1,0,0,
-14,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,52,0,0,18,109,0,16,8,48,0,57,0,
-17,48,0,0,0,0,18,109,0,16,10,49,0,57,0,17,48,0,0,0,0,18,109,0,16,10,50,0,57,0,17,48,0,0,0,0,17,48,
-0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,49,0,0,0,0,0,20,0,0,1,90,95,0,0,15,0,1,1,1,0,0,26,0,109,0,0,
-0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,52,0,0,18,109,0,16,8,48,0,57,0,17,48,0,0,0,0,
-18,109,0,16,10,49,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,49,0,0,0,0,17,48,0,0,0,0,17,
-48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,49,0,0,0,0,0,20,0,0,1,90,95,0,0,15,0,1,1,1,0,0,27,0,109,
-0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,52,0,0,18,109,0,16,8,48,0,57,0,17,48,0,0,
-0,0,17,48,0,0,0,0,18,109,0,16,10,49,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,18,109,0,16,10,50,0,57,0,17,
-49,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,49,0,0,0,0,0,20,0,0,1,90,95,
-0,0,15,0,1,1,1,0,0,13,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,109,97,116,52,0,0,18,109,
-0,16,8,48,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,18,109,0,16,10,49,0,57,0,17,48,0,0,0,0,17,48,0,0,0,0,
-17,48,0,0,0,0,17,48,0,0,0,0,17,49,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,17,48,0,0,0,0,
-17,49,0,0,0,0,0,20,0,0,1,90,95,0,0,0,0,2,1,1,0,2,0,26,0,109,0,0,1,1,0,0,26,0,110,0,0,0,1,9,18,109,
-0,16,8,48,0,57,18,110,0,16,8,48,0,57,21,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,21,0,0,1,
-90,95,0,0,0,0,2,1,1,0,2,0,28,0,109,0,0,1,1,0,0,28,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,
-16,8,48,0,57,21,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,21,0,0,1,90,95,0,0,0,0,2,1,1,0,2,
-0,27,0,109,0,0,1,1,0,0,27,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,21,0,9,18,
-109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,21,0,9,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,21,
-0,0,1,90,95,0,0,0,0,2,1,1,0,2,0,30,0,109,0,0,1,1,0,0,30,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,
-110,0,16,8,48,0,57,21,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,21,0,9,18,109,0,16,10,50,0,
-57,18,110,0,16,10,50,0,57,21,0,0,1,90,95,0,0,0,0,2,1,1,0,2,0,29,0,109,0,0,1,1,0,0,29,0,110,0,0,0,1,
-9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,21,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,
-21,0,9,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,21,0,9,18,109,0,16,10,51,0,57,18,110,0,16,10,
-51,0,57,21,0,0,1,90,95,0,0,0,0,2,1,1,0,2,0,31,0,109,0,0,1,1,0,0,31,0,110,0,0,0,1,9,18,109,0,16,8,
-48,0,57,18,110,0,16,8,48,0,57,21,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,21,0,9,18,109,0,
-16,10,50,0,57,18,110,0,16,10,50,0,57,21,0,9,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,21,0,0,1,
-90,95,0,0,0,0,2,2,1,0,2,0,26,0,109,0,0,1,1,0,0,26,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,
-16,8,48,0,57,22,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,22,0,0,1,90,95,0,0,0,0,2,2,1,0,2,
-0,28,0,109,0,0,1,1,0,0,28,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,22,0,9,18,
-109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,22,0,0,1,90,95,0,0,0,0,2,2,1,0,2,0,27,0,109,0,0,1,1,0,0,
-27,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,22,0,9,18,109,0,16,10,49,0,57,18,
-110,0,16,10,49,0,57,22,0,9,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,22,0,0,1,90,95,0,0,0,0,2,
-2,1,0,2,0,30,0,109,0,0,1,1,0,0,30,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,22,0,
-9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,22,0,9,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,
-57,22,0,0,1,90,95,0,0,0,0,2,2,1,0,2,0,29,0,109,0,0,1,1,0,0,29,0,110,0,0,0,1,9,18,109,0,16,8,48,0,
-57,18,110,0,16,8,48,0,57,22,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,22,0,9,18,109,0,16,
-10,50,0,57,18,110,0,16,10,50,0,57,22,0,9,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,22,0,0,1,90,
-95,0,0,0,0,2,2,1,0,2,0,31,0,109,0,0,1,1,0,0,31,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,
-48,0,57,22,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,22,0,9,18,109,0,16,10,50,0,57,18,110,
-0,16,10,50,0,57,22,0,9,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,22,0,0,1,90,95,0,0,0,0,2,4,1,
-0,2,0,26,0,109,0,0,1,1,0,0,26,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,24,0,9,
-18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,24,0,0,1,90,95,0,0,0,0,2,4,1,0,2,0,28,0,109,0,0,1,1,
-0,0,28,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,24,0,9,18,109,0,16,10,49,0,57,
-18,110,0,16,10,49,0,57,24,0,0,1,90,95,0,0,0,0,2,4,1,0,2,0,27,0,109,0,0,1,1,0,0,27,0,110,0,0,0,1,9,
-18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,24,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,
-24,0,9,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,24,0,0,1,90,95,0,0,0,0,2,4,1,0,2,0,30,0,109,0,
-0,1,1,0,0,30,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,24,0,9,18,109,0,16,10,49,
-0,57,18,110,0,16,10,49,0,57,24,0,9,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,24,0,0,1,90,95,0,
-0,0,0,2,4,1,0,2,0,29,0,109,0,0,1,1,0,0,29,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,
-57,24,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,24,0,9,18,109,0,16,10,50,0,57,18,110,0,16,
-10,50,0,57,24,0,9,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,24,0,0,1,90,95,0,0,0,0,2,4,1,0,2,0,
-31,0,109,0,0,1,1,0,0,31,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,24,0,9,18,109,
-0,16,10,49,0,57,18,110,0,16,10,49,0,57,24,0,9,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,24,0,9,
-18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,24,0,0,1,90,95,0,0,11,0,2,21,1,1,0,0,26,0,109,0,0,1,
-1,0,0,10,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,18,118,0,59,120,0,18,109,0,16,8,
-48,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,120,0,48,46,20,0,9,18,95,95,114,
-101,116,86,97,108,0,59,121,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,121,0,48,18,118,0,59,121,0,
-18,109,0,16,10,49,0,57,59,121,0,48,46,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,18,118,0,59,
-120,0,18,109,0,16,8,48,0,57,59,122,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,122,0,48,46,20,
-0,0,1,90,95,0,0,12,0,2,21,1,1,0,0,28,0,109,0,0,1,1,0,0,10,0,118,0,0,0,1,9,18,95,95,114,101,116,86,
-97,108,0,59,120,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,
-16,10,49,0,57,59,120,0,48,46,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,18,118,0,59,120,0,18,
-109,0,16,8,48,0,57,59,121,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,48,46,20,0,9,18,
-95,95,114,101,116,86,97,108,0,59,122,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,122,0,48,18,118,
-0,59,121,0,18,109,0,16,10,49,0,57,59,122,0,48,46,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,
-18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,119,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,
-119,0,48,46,20,0,0,1,90,95,0,0,10,0,2,21,1,1,0,0,27,0,109,0,0,1,1,0,0,11,0,118,0,0,0,1,9,18,95,95,
-114,101,116,86,97,108,0,59,120,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,120,0,48,18,118,0,59,
-121,0,18,109,0,16,10,49,0,57,59,120,0,48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,57,59,120,0,48,
-46,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,121,
-0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,
-57,59,121,0,48,46,20,0,0,1,90,95,0,0,12,0,2,21,1,1,0,0,30,0,109,0,0,1,1,0,0,11,0,118,0,0,0,1,9,18,
-95,95,114,101,116,86,97,108,0,59,120,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,120,0,48,18,118,
-0,59,121,0,18,109,0,16,10,49,0,57,59,120,0,48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,57,59,120,0,
-48,46,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,
-121,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,48,46,18,118,0,59,122,0,18,109,0,16,10,
-50,0,57,59,121,0,48,46,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,18,118,0,59,120,0,18,109,0,
-16,8,48,0,57,59,122,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,122,0,48,46,18,118,0,59,122,0,
-18,109,0,16,10,50,0,57,59,122,0,48,46,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,18,118,0,59,
-120,0,18,109,0,16,8,48,0,57,59,119,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,119,0,48,46,18,
-118,0,59,122,0,18,109,0,16,10,50,0,57,59,119,0,48,46,20,0,0,1,90,95,0,0,10,0,2,21,1,1,0,0,29,0,109,
-0,0,1,1,0,0,12,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,18,118,0,59,120,0,18,109,
-0,16,8,48,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,120,0,48,46,18,118,0,59,122,
-0,18,109,0,16,10,50,0,57,59,120,0,48,46,18,118,0,59,119,0,18,109,0,16,10,51,0,57,59,120,0,48,46,20,
-0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,121,0,48,
-18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,57,
-59,121,0,48,46,18,118,0,59,119,0,18,109,0,16,10,51,0,57,59,121,0,48,46,20,0,0,1,90,95,0,0,11,0,2,
-21,1,1,0,0,31,0,109,0,0,1,1,0,0,12,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,18,
-118,0,59,120,0,18,109,0,16,8,48,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,120,0,
-48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,57,59,120,0,48,46,18,118,0,59,119,0,18,109,0,16,10,51,
-0,57,59,120,0,48,46,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,18,118,0,59,120,0,18,109,0,16,
-8,48,0,57,59,121,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,48,46,18,118,0,59,122,0,18,
-109,0,16,10,50,0,57,59,121,0,48,46,18,118,0,59,119,0,18,109,0,16,10,51,0,57,59,121,0,48,46,20,0,9,
-18,95,95,114,101,116,86,97,108,0,59,122,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,122,0,48,18,
-118,0,59,121,0,18,109,0,16,10,49,0,57,59,122,0,48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,57,59,
-122,0,48,46,18,118,0,59,119,0,18,109,0,16,10,51,0,57,59,122,0,48,46,20,0,0,1,90,95,0,0,27,0,2,21,1,
-1,0,0,13,0,109,0,0,1,1,0,0,27,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,
-0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,18,110,0,
-16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,18,110,0,16,10,50,
-0,57,48,20,0,0,1,90,95,0,0,29,0,2,21,1,1,0,0,13,0,109,0,0,1,1,0,0,29,0,110,0,0,0,1,9,18,95,95,114,
-101,116,86,97,108,0,16,8,48,0,57,18,109,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,
-97,108,0,16,10,49,0,57,18,109,0,18,110,0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,
-16,10,50,0,57,18,109,0,18,110,0,16,10,50,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,
-0,57,18,109,0,18,110,0,16,10,51,0,57,48,20,0,0,1,90,95,0,0,26,0,2,21,1,1,0,0,26,0,109,0,0,1,1,0,0,
-13,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,18,110,0,16,8,48,0,57,48,
-20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,18,110,0,16,10,49,0,57,48,20,0,0,1,
-90,95,0,0,14,0,2,21,1,1,0,0,26,0,109,0,0,1,1,0,0,27,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,
-0,16,8,48,0,57,18,109,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,
-0,57,18,109,0,18,110,0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,
-109,0,18,110,0,16,10,50,0,57,48,20,0,0,1,90,95,0,0,31,0,2,21,1,1,0,0,26,0,109,0,0,1,1,0,0,29,0,110,
-0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,18,110,0,16,8,48,0,57,48,20,0,9,
-18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,18,110,0,16,10,49,0,57,48,20,0,9,18,95,95,
-114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,18,110,0,16,10,50,0,57,48,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,51,0,57,18,109,0,18,110,0,16,10,51,0,57,48,20,0,0,1,90,95,0,0,28,0,2,21,1,1,
-0,0,28,0,109,0,0,1,1,0,0,13,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,
-18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,18,110,0,
-16,10,49,0,57,48,20,0,0,1,90,95,0,0,30,0,2,21,1,1,0,0,28,0,109,0,0,1,1,0,0,27,0,110,0,0,0,1,9,18,
-95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,
-101,116,86,97,108,0,16,10,49,0,57,18,109,0,18,110,0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,
-86,97,108,0,16,10,50,0,57,18,109,0,18,110,0,16,10,50,0,57,48,20,0,0,1,90,95,0,0,15,0,2,21,1,1,0,0,
-28,0,109,0,0,1,1,0,0,29,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,18,
-110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,18,110,0,16,
-10,49,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,18,110,0,16,10,50,0,
-57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,109,0,18,110,0,16,10,51,0,57,48,20,
-0,0,1,90,95,0,0,13,0,2,21,1,1,0,0,27,0,109,0,0,1,1,0,0,26,0,110,0,0,0,1,9,18,95,95,114,101,116,86,
-97,108,0,16,8,48,0,57,18,109,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,
-10,49,0,57,18,109,0,18,110,0,16,10,49,0,57,48,20,0,0,1,90,95,0,0,27,0,2,21,1,1,0,0,27,0,109,0,0,1,
-1,0,0,14,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,18,110,0,16,8,48,0,
-57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,18,110,0,16,10,49,0,57,48,20,
-0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,18,110,0,16,10,50,0,57,48,20,0,0,1,90,
-95,0,0,29,0,2,21,1,1,0,0,27,0,109,0,0,1,1,0,0,31,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,
-16,8,48,0,57,18,109,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,
-57,18,109,0,18,110,0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,
-0,18,110,0,16,10,50,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,109,0,18,110,
-0,16,10,51,0,57,48,20,0,0,1,90,95,0,0,26,0,2,21,1,1,0,0,14,0,109,0,0,1,1,0,0,26,0,110,0,0,0,1,9,18,
-95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,
-101,116,86,97,108,0,16,10,49,0,57,18,109,0,18,110,0,16,10,49,0,57,48,20,0,0,1,90,95,0,0,31,0,2,21,
-1,1,0,0,14,0,109,0,0,1,1,0,0,31,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,
-109,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,18,
-110,0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,18,110,0,16,
-10,50,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,109,0,18,110,0,16,10,51,0,
-57,48,20,0,0,1,90,95,0,0,28,0,2,21,1,1,0,0,30,0,109,0,0,1,1,0,0,26,0,110,0,0,0,1,9,18,95,95,114,
-101,116,86,97,108,0,16,8,48,0,57,18,109,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,
-97,108,0,16,10,49,0,57,18,109,0,18,110,0,16,10,49,0,57,48,20,0,0,1,90,95,0,0,30,0,2,21,1,1,0,0,30,
-0,109,0,0,1,1,0,0,14,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,18,110,
-0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,18,110,0,16,10,49,
-0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,18,110,0,16,10,50,0,57,48,
-20,0,0,1,90,95,0,0,15,0,2,21,1,1,0,0,30,0,109,0,0,1,1,0,0,31,0,110,0,0,0,1,9,18,95,95,114,101,116,
-86,97,108,0,16,8,48,0,57,18,109,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,
-16,10,49,0,57,18,109,0,18,110,0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,
-0,57,18,109,0,18,110,0,16,10,50,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,
-109,0,18,110,0,16,10,51,0,57,48,20,0,0,1,90,95,0,0,13,0,2,21,1,1,0,0,29,0,109,0,0,1,1,0,0,28,0,110,
-0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,18,110,0,16,8,48,0,57,48,20,0,9,
-18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,18,110,0,16,10,49,0,57,48,20,0,0,1,90,95,0,
-0,27,0,2,21,1,1,0,0,29,0,109,0,0,1,1,0,0,30,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,
-48,0,57,18,109,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,
-109,0,18,110,0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,18,
-110,0,16,10,50,0,57,48,20,0,0,1,90,95,0,0,29,0,2,21,1,1,0,0,29,0,109,0,0,1,1,0,0,15,0,110,0,0,0,1,
-9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,
-114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,18,110,0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,50,0,57,18,109,0,18,110,0,16,10,50,0,57,48,20,0,9,18,95,95,114,101,116,86,97,
-108,0,16,10,51,0,57,18,109,0,18,110,0,16,10,51,0,57,48,20,0,0,1,90,95,0,0,26,0,2,21,1,1,0,0,31,0,
-109,0,0,1,1,0,0,28,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,18,110,0,
-16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,18,110,0,16,10,49,0,
-57,48,20,0,0,1,90,95,0,0,14,0,2,21,1,1,0,0,31,0,109,0,0,1,1,0,0,30,0,110,0,0,0,1,9,18,95,95,114,
-101,116,86,97,108,0,16,8,48,0,57,18,109,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,
-97,108,0,16,10,49,0,57,18,109,0,18,110,0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,
-16,10,50,0,57,18,109,0,18,110,0,16,10,50,0,57,48,20,0,0,1,90,95,0,0,31,0,2,21,1,1,0,0,31,0,109,0,0,
-1,1,0,0,15,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,18,110,0,16,8,48,
-0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,18,110,0,16,10,49,0,57,48,
-20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,18,110,0,16,10,50,0,57,48,20,0,9,18,
-95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,109,0,18,110,0,16,10,51,0,57,48,20,0,0,1,90,95,0,0,
-28,0,2,21,1,1,0,0,15,0,109,0,0,1,1,0,0,28,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,
-0,57,18,109,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,
-109,0,18,110,0,16,10,49,0,57,48,20,0,0,1,90,95,0,0,30,0,2,21,1,1,0,0,15,0,109,0,0,1,1,0,0,30,0,110,
-0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,18,110,0,16,8,48,0,57,48,20,0,9,
-18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,18,110,0,16,10,49,0,57,48,20,0,9,18,95,95,
-114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,18,110,0,16,10,50,0,57,48,20,0,0,1,90,95,0,0,0,0,2,
-3,1,0,2,0,26,0,109,0,0,1,1,0,0,13,0,110,0,0,0,1,9,18,109,0,18,109,0,18,110,0,48,20,0,0,1,90,95,0,0,
-0,0,2,3,1,0,2,0,28,0,109,0,0,1,1,0,0,13,0,110,0,0,0,1,9,18,109,0,18,109,0,18,110,0,48,20,0,0,1,90,
-95,0,0,0,0,2,3,1,0,2,0,27,0,109,0,0,1,1,0,0,14,0,110,0,0,0,1,9,18,109,0,18,109,0,18,110,0,48,20,0,
-0,1,90,95,0,0,0,0,2,3,1,0,2,0,30,0,109,0,0,1,1,0,0,14,0,110,0,0,0,1,9,18,109,0,18,109,0,18,110,0,
-48,20,0,0,1,90,95,0,0,0,0,2,3,1,0,2,0,29,0,109,0,0,1,1,0,0,15,0,110,0,0,0,1,9,18,109,0,18,109,0,18,
-110,0,48,20,0,0,1,90,95,0,0,0,0,2,3,1,0,2,0,31,0,109,0,0,1,1,0,0,15,0,110,0,0,0,1,9,18,109,0,18,
-109,0,18,110,0,48,20,0,0,1,90,95,0,0,11,0,2,21,1,1,0,0,10,0,118,0,0,1,1,0,0,27,0,109,0,0,0,1,9,18,
-95,95,114,101,116,86,97,108,0,59,120,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,8,48,0,57,0,0,20,
-0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,10,49,0,57,
-0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,10,
-50,0,57,0,0,20,0,0,1,90,95,0,0,12,0,2,21,1,1,0,0,10,0,118,0,0,1,1,0,0,29,0,109,0,0,0,1,9,18,95,95,
-114,101,116,86,97,108,0,59,120,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,8,48,0,57,0,0,20,0,9,18,
-95,95,114,101,116,86,97,108,0,59,121,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,10,49,0,57,0,0,20,
-0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,10,50,0,57,
-0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,10,
-51,0,57,0,0,20,0,0,1,90,95,0,0,10,0,2,21,1,1,0,0,11,0,118,0,0,1,1,0,0,26,0,109,0,0,0,1,9,18,95,95,
-114,101,116,86,97,108,0,59,120,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,8,48,0,57,0,0,20,0,9,18,
-95,95,114,101,116,86,97,108,0,59,121,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,10,49,0,57,0,0,20,
-0,0,1,90,95,0,0,12,0,2,21,1,1,0,0,11,0,118,0,0,1,1,0,0,31,0,109,0,0,0,1,9,18,95,95,114,101,116,86,
-97,108,0,59,120,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,8,48,0,57,0,0,20,0,9,18,95,95,114,101,
-116,86,97,108,0,59,121,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,10,49,0,57,0,0,20,0,9,18,95,95,
-114,101,116,86,97,108,0,59,122,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,10,50,0,57,0,0,20,0,9,
-18,95,95,114,101,116,86,97,108,0,59,119,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,10,51,0,57,0,0,
-20,0,0,1,90,95,0,0,10,0,2,21,1,1,0,0,12,0,118,0,0,1,1,0,0,28,0,109,0,0,0,1,9,18,95,95,114,101,116,
-86,97,108,0,59,120,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,8,48,0,57,0,0,20,0,9,18,95,95,114,
-101,116,86,97,108,0,59,121,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,10,49,0,57,0,0,20,0,0,1,90,
-95,0,0,11,0,2,21,1,1,0,0,12,0,118,0,0,1,1,0,0,30,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,
-59,120,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,8,48,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,
-108,0,59,121,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,10,49,0,57,0,0,20,0,9,18,95,95,114,101,
-116,86,97,108,0,59,122,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,10,50,0,57,0,0,20,0,0,1,90,95,0,
-0,0,0,2,1,1,0,2,0,26,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,21,0,9,18,
-109,0,16,10,49,0,57,18,97,0,21,0,0,1,90,95,0,0,0,0,2,1,1,0,2,0,28,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,
-9,18,109,0,16,8,48,0,57,18,97,0,21,0,9,18,109,0,16,10,49,0,57,18,97,0,21,0,0,1,90,95,0,0,0,0,2,1,1,
-0,2,0,27,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,21,0,9,18,109,0,16,10,49,
-0,57,18,97,0,21,0,9,18,109,0,16,10,50,0,57,18,97,0,21,0,0,1,90,95,0,0,0,0,2,1,1,0,2,0,30,0,109,0,0,
-1,1,0,0,9,0,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,21,0,9,18,109,0,16,10,49,0,57,18,97,0,21,0,
-9,18,109,0,16,10,50,0,57,18,97,0,21,0,0,1,90,95,0,0,0,0,2,1,1,0,2,0,29,0,109,0,0,1,1,0,0,9,0,97,0,
-0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,21,0,9,18,109,0,16,10,49,0,57,18,97,0,21,0,9,18,109,0,16,10,
-50,0,57,18,97,0,21,0,9,18,109,0,16,10,51,0,57,18,97,0,21,0,0,1,90,95,0,0,0,0,2,1,1,0,2,0,31,0,109,
-0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,21,0,9,18,109,0,16,10,49,0,57,18,97,0,
-21,0,9,18,109,0,16,10,50,0,57,18,97,0,21,0,9,18,109,0,16,10,51,0,57,18,97,0,21,0,0,1,90,95,0,0,0,0,
-2,2,1,0,2,0,26,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,22,0,9,18,109,0,16,
-10,49,0,57,18,97,0,22,0,0,1,90,95,0,0,0,0,2,2,1,0,2,0,28,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,109,
-0,16,8,48,0,57,18,97,0,22,0,9,18,109,0,16,10,49,0,57,18,97,0,22,0,0,1,90,95,0,0,0,0,2,2,1,0,2,0,27,
-0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,22,0,9,18,109,0,16,10,49,0,57,18,
-97,0,22,0,9,18,109,0,16,10,50,0,57,18,97,0,22,0,0,1,90,95,0,0,0,0,2,2,1,0,2,0,30,0,109,0,0,1,1,0,0,
-9,0,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,22,0,9,18,109,0,16,10,49,0,57,18,97,0,22,0,9,18,109,
-0,16,10,50,0,57,18,97,0,22,0,0,1,90,95,0,0,0,0,2,2,1,0,2,0,29,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,9,
-18,109,0,16,8,48,0,57,18,97,0,22,0,9,18,109,0,16,10,49,0,57,18,97,0,22,0,9,18,109,0,16,10,50,0,57,
-18,97,0,22,0,9,18,109,0,16,10,51,0,57,18,97,0,22,0,0,1,90,95,0,0,0,0,2,2,1,0,2,0,31,0,109,0,0,1,1,
-0,0,9,0,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,22,0,9,18,109,0,16,10,49,0,57,18,97,0,22,0,9,18,
-109,0,16,10,50,0,57,18,97,0,22,0,9,18,109,0,16,10,51,0,57,18,97,0,22,0,0,1,90,95,0,0,0,0,2,3,1,0,2,
-0,26,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,23,0,9,18,109,0,16,10,49,0,
-57,18,97,0,23,0,0,1,90,95,0,0,0,0,2,3,1,0,2,0,28,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,109,0,16,8,
-48,0,57,18,97,0,23,0,9,18,109,0,16,10,49,0,57,18,97,0,23,0,0,1,90,95,0,0,0,0,2,3,1,0,2,0,27,0,109,
-0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,23,0,9,18,109,0,16,10,49,0,57,18,97,0,
-23,0,9,18,109,0,16,10,50,0,57,18,97,0,23,0,0,1,90,95,0,0,0,0,2,3,1,0,2,0,30,0,109,0,0,1,1,0,0,9,0,
-97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,23,0,9,18,109,0,16,10,49,0,57,18,97,0,23,0,9,18,109,0,
-16,10,50,0,57,18,97,0,23,0,0,1,90,95,0,0,0,0,2,3,1,0,2,0,29,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,
-109,0,16,8,48,0,57,18,97,0,23,0,9,18,109,0,16,10,49,0,57,18,97,0,23,0,9,18,109,0,16,10,50,0,57,18,
-97,0,23,0,9,18,109,0,16,10,51,0,57,18,97,0,23,0,0,1,90,95,0,0,0,0,2,3,1,0,2,0,31,0,109,0,0,1,1,0,0,
-9,0,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,23,0,9,18,109,0,16,10,49,0,57,18,97,0,23,0,9,18,109,
-0,16,10,50,0,57,18,97,0,23,0,9,18,109,0,16,10,51,0,57,18,97,0,23,0,0,1,90,95,0,0,0,0,2,4,1,0,2,0,
-26,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,24,0,9,18,109,0,16,10,49,0,57,
-18,97,0,24,0,0,1,90,95,0,0,0,0,2,4,1,0,2,0,28,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,109,0,16,8,48,
-0,57,18,97,0,24,0,9,18,109,0,16,10,49,0,57,18,97,0,24,0,0,1,90,95,0,0,0,0,2,4,1,0,2,0,27,0,109,0,0,
-1,1,0,0,9,0,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,24,0,9,18,109,0,16,10,49,0,57,18,97,0,24,0,
-9,18,109,0,16,10,50,0,57,18,97,0,24,0,0,1,90,95,0,0,0,0,2,4,1,0,2,0,30,0,109,0,0,1,1,0,0,9,0,97,0,
-0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,24,0,9,18,109,0,16,10,49,0,57,18,97,0,24,0,9,18,109,0,16,10,
-50,0,57,18,97,0,24,0,0,1,90,95,0,0,0,0,2,4,1,0,2,0,29,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,109,0,
-16,8,48,0,57,18,97,0,24,0,9,18,109,0,16,10,49,0,57,18,97,0,24,0,9,18,109,0,16,10,50,0,57,18,97,0,
-24,0,9,18,109,0,16,10,51,0,57,18,97,0,24,0,0,1,90,95,0,0,0,0,2,4,1,0,2,0,31,0,109,0,0,1,1,0,0,9,0,
-97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,24,0,9,18,109,0,16,10,49,0,57,18,97,0,24,0,9,18,109,0,
-16,10,50,0,57,18,97,0,24,0,9,18,109,0,16,10,51,0,57,18,97,0,24,0,0,1,90,95,0,0,26,0,2,26,1,1,0,0,
-26,0,109,0,0,1,1,0,0,26,0,110,0,0,0,1,8,58,109,97,116,50,120,51,0,0,18,109,0,16,8,48,0,57,18,110,0,
-16,8,48,0,57,46,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,46,0,0,0,0,1,90,95,0,0,28,0,2,26,1,
-1,0,0,28,0,109,0,0,1,1,0,0,28,0,110,0,0,0,1,8,58,109,97,116,50,120,52,0,0,18,109,0,16,8,48,0,57,18,
-110,0,16,8,48,0,57,46,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,46,0,0,0,0,1,90,95,0,0,27,0,
-2,26,1,1,0,0,27,0,109,0,0,1,1,0,0,27,0,110,0,0,0,1,8,58,109,97,116,51,120,50,0,0,18,109,0,16,8,48,
-0,57,18,110,0,16,8,48,0,57,46,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,46,0,18,109,0,16,10,
-50,0,57,18,110,0,16,10,50,0,57,46,0,0,0,0,1,90,95,0,0,30,0,2,26,1,1,0,0,30,0,109,0,0,1,1,0,0,30,0,
-110,0,0,0,1,8,58,109,97,116,51,120,52,0,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,46,0,18,109,
-0,16,10,49,0,57,18,110,0,16,10,49,0,57,46,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,46,0,0,0,
-0,1,90,95,0,0,29,0,2,26,1,1,0,0,29,0,109,0,0,1,1,0,0,29,0,110,0,0,0,1,8,58,109,97,116,52,120,50,0,
-0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,46,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,
-46,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,46,0,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,
-57,46,0,0,0,0,1,90,95,0,0,31,0,2,26,1,1,0,0,31,0,109,0,0,1,1,0,0,31,0,110,0,0,0,1,8,58,109,97,116,
-52,120,51,0,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,46,0,18,109,0,16,10,49,0,57,18,110,0,16,
-10,49,0,57,46,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,46,0,18,109,0,16,10,51,0,57,18,110,0,
-16,10,51,0,57,46,0,0,0,0,1,90,95,0,0,26,0,2,27,1,1,0,0,26,0,109,0,0,1,1,0,0,26,0,110,0,0,0,1,8,58,
-109,97,116,50,120,51,0,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,47,0,18,109,0,16,10,49,0,57,
-18,110,0,16,10,49,0,57,47,0,0,0,0,1,90,95,0,0,28,0,2,27,1,1,0,0,28,0,109,0,0,1,1,0,0,28,0,110,0,0,
-0,1,8,58,109,97,116,50,120,52,0,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,47,0,18,109,0,16,10,
-49,0,57,18,110,0,16,10,49,0,57,47,0,0,0,0,1,90,95,0,0,27,0,2,27,1,1,0,0,27,0,109,0,0,1,1,0,0,27,0,
-110,0,0,0,1,8,58,109,97,116,51,120,50,0,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,47,0,18,109,
-0,16,10,49,0,57,18,110,0,16,10,49,0,57,47,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,47,0,0,0,
-0,1,90,95,0,0,30,0,2,27,1,1,0,0,30,0,109,0,0,1,1,0,0,30,0,110,0,0,0,1,8,58,109,97,116,51,120,52,0,
-0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,47,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,
-47,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,47,0,0,0,0,1,90,95,0,0,29,0,2,27,1,1,0,0,29,0,
-109,0,0,1,1,0,0,29,0,110,0,0,0,1,8,58,109,97,116,52,120,50,0,0,18,109,0,16,8,48,0,57,18,110,0,16,8,
-48,0,57,47,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,47,0,18,109,0,16,10,50,0,57,18,110,0,16,
-10,50,0,57,47,0,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,47,0,0,0,0,1,90,95,0,0,31,0,2,27,1,1,
-0,0,31,0,109,0,0,1,1,0,0,31,0,110,0,0,0,1,8,58,109,97,116,52,120,51,0,0,18,109,0,16,8,48,0,57,18,
-110,0,16,8,48,0,57,47,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,47,0,18,109,0,16,10,50,0,57,
-18,110,0,16,10,50,0,57,47,0,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,47,0,0,0,0,1,90,95,0,0,
-26,0,2,22,1,1,0,0,26,0,109,0,0,1,1,0,0,26,0,110,0,0,0,1,8,58,109,97,116,50,120,51,0,0,18,109,0,16,
-8,48,0,57,18,110,0,16,8,48,0,57,49,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,49,0,0,0,0,1,90,
-95,0,0,28,0,2,22,1,1,0,0,28,0,109,0,0,1,1,0,0,28,0,110,0,0,0,1,8,58,109,97,116,50,120,52,0,0,18,
-109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,49,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,49,0,0,
-0,0,1,90,95,0,0,27,0,2,22,1,1,0,0,27,0,109,0,0,1,1,0,0,27,0,110,0,0,0,1,8,58,109,97,116,51,120,50,
-0,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,49,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,
-49,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,49,0,0,0,0,1,90,95,0,0,30,0,2,22,1,1,0,0,30,0,
-109,0,0,1,1,0,0,30,0,110,0,0,0,1,8,58,109,97,116,51,120,52,0,0,18,109,0,16,8,48,0,57,18,110,0,16,8,
-48,0,57,49,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,49,0,18,109,0,16,10,50,0,57,18,110,0,16,
-10,50,0,57,49,0,0,0,0,1,90,95,0,0,29,0,2,22,1,1,0,0,29,0,109,0,0,1,1,0,0,29,0,110,0,0,0,1,8,58,109,
-97,116,52,120,50,0,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,49,0,18,109,0,16,10,49,0,57,18,
-110,0,16,10,49,0,57,49,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,49,0,18,109,0,16,10,51,0,57,
-18,110,0,16,10,51,0,57,49,0,0,0,0,1,90,95,0,0,31,0,2,22,1,1,0,0,31,0,109,0,0,1,1,0,0,31,0,110,0,0,
-0,1,8,58,109,97,116,52,120,51,0,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,49,0,18,109,0,16,10,
-49,0,57,18,110,0,16,10,49,0,57,49,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,49,0,18,109,0,16,
-10,51,0,57,18,110,0,16,10,51,0,57,49,0,0,0,0,1,90,95,0,0,26,0,2,26,1,1,0,0,9,0,97,0,0,1,1,0,0,26,0,
-110,0,0,0,1,8,58,109,97,116,50,120,51,0,0,18,97,0,18,110,0,16,8,48,0,57,46,0,18,97,0,18,110,0,16,
-10,49,0,57,46,0,0,0,0,1,90,95,0,0,26,0,2,26,1,1,0,0,26,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,8,58,109,
-97,116,50,120,51,0,0,18,109,0,16,8,48,0,57,18,98,0,46,0,18,109,0,16,10,49,0,57,18,98,0,46,0,0,0,0,
-1,90,95,0,0,28,0,2,26,1,1,0,0,9,0,97,0,0,1,1,0,0,28,0,110,0,0,0,1,8,58,109,97,116,50,120,52,0,0,18,
-97,0,18,110,0,16,8,48,0,57,46,0,18,97,0,18,110,0,16,10,49,0,57,46,0,0,0,0,1,90,95,0,0,28,0,2,26,1,
-1,0,0,28,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,8,58,109,97,116,50,120,52,0,0,18,109,0,16,8,48,0,57,18,
-98,0,46,0,18,109,0,16,10,49,0,57,18,98,0,46,0,0,0,0,1,90,95,0,0,27,0,2,26,1,1,0,0,9,0,97,0,0,1,1,0,
-0,27,0,110,0,0,0,1,8,58,109,97,116,51,120,50,0,0,18,97,0,18,110,0,16,8,48,0,57,46,0,18,97,0,18,110,
-0,16,10,49,0,57,46,0,18,97,0,18,110,0,16,10,50,0,57,46,0,0,0,0,1,90,95,0,0,27,0,2,26,1,1,0,0,27,0,
-109,0,0,1,1,0,0,9,0,98,0,0,0,1,8,58,109,97,116,51,120,50,0,0,18,109,0,16,8,48,0,57,18,98,0,46,0,18,
-109,0,16,10,49,0,57,18,98,0,46,0,18,109,0,16,10,50,0,57,18,98,0,46,0,0,0,0,1,90,95,0,0,30,0,2,26,1,
-1,0,0,9,0,97,0,0,1,1,0,0,30,0,110,0,0,0,1,8,58,109,97,116,51,120,52,0,0,18,97,0,18,110,0,16,8,48,0,
-57,46,0,18,97,0,18,110,0,16,10,49,0,57,46,0,18,97,0,18,110,0,16,10,50,0,57,46,0,0,0,0,1,90,95,0,0,
-30,0,2,26,1,1,0,0,30,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,8,58,109,97,116,51,120,52,0,0,18,109,0,16,8,
-48,0,57,18,98,0,46,0,18,109,0,16,10,49,0,57,18,98,0,46,0,18,109,0,16,10,50,0,57,18,98,0,46,0,0,0,0,
-1,90,95,0,0,29,0,2,26,1,1,0,0,29,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,8,58,109,97,116,52,120,50,0,0,18,
-109,0,16,8,48,0,57,18,98,0,46,0,18,109,0,16,10,49,0,57,18,98,0,46,0,18,109,0,16,10,50,0,57,18,98,0,
-46,0,18,109,0,16,10,51,0,57,18,98,0,46,0,0,0,0,1,90,95,0,0,29,0,2,26,1,1,0,0,9,0,97,0,0,1,1,0,0,29,
-0,110,0,0,0,1,8,58,109,97,116,52,120,50,0,0,18,97,0,18,110,0,16,8,48,0,57,46,0,18,97,0,18,110,0,16,
-10,49,0,57,46,0,18,97,0,18,110,0,16,10,50,0,57,46,0,18,97,0,18,110,0,16,10,51,0,57,46,0,0,0,0,1,90,
-95,0,0,31,0,2,26,1,1,0,0,31,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,8,58,109,97,116,52,120,51,0,0,18,109,
-0,16,8,48,0,57,18,98,0,46,0,18,109,0,16,10,49,0,57,18,98,0,46,0,18,109,0,16,10,50,0,57,18,98,0,46,
-0,18,109,0,16,10,51,0,57,18,98,0,46,0,0,0,0,1,90,95,0,0,31,0,2,26,1,1,0,0,9,0,97,0,0,1,1,0,0,31,0,
-110,0,0,0,1,8,58,109,97,116,52,120,51,0,0,18,97,0,18,110,0,16,8,48,0,57,46,0,18,97,0,18,110,0,16,
-10,49,0,57,46,0,18,97,0,18,110,0,16,10,50,0,57,46,0,18,97,0,18,110,0,16,10,51,0,57,46,0,0,0,0,1,90,
-95,0,0,26,0,2,27,1,1,0,0,9,0,97,0,0,1,1,0,0,26,0,110,0,0,0,1,8,58,109,97,116,50,120,51,0,0,18,97,0,
-18,110,0,16,8,48,0,57,47,0,18,97,0,18,110,0,16,10,49,0,57,47,0,0,0,0,1,90,95,0,0,26,0,2,27,1,1,0,0,
-26,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,8,58,109,97,116,50,120,51,0,0,18,109,0,16,8,48,0,57,18,98,0,47,
-0,18,109,0,16,10,49,0,57,18,98,0,47,0,0,0,0,1,90,95,0,0,28,0,2,27,1,1,0,0,9,0,97,0,0,1,1,0,0,28,0,
-110,0,0,0,1,8,58,109,97,116,50,120,52,0,0,18,97,0,18,110,0,16,8,48,0,57,47,0,18,97,0,18,110,0,16,
-10,49,0,57,47,0,0,0,0,1,90,95,0,0,28,0,2,27,1,1,0,0,28,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,8,58,109,
-97,116,50,120,52,0,0,18,109,0,16,8,48,0,57,18,98,0,47,0,18,109,0,16,10,49,0,57,18,98,0,47,0,0,0,0,
-1,90,95,0,0,27,0,2,27,1,1,0,0,9,0,97,0,0,1,1,0,0,27,0,110,0,0,0,1,8,58,109,97,116,51,120,50,0,0,18,
-97,0,18,110,0,16,8,48,0,57,47,0,18,97,0,18,110,0,16,10,49,0,57,47,0,18,97,0,18,110,0,16,10,50,0,57,
-47,0,0,0,0,1,90,95,0,0,27,0,2,27,1,1,0,0,27,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,8,58,109,97,116,51,
-120,50,0,0,18,109,0,16,8,48,0,57,18,98,0,47,0,18,109,0,16,10,49,0,57,18,98,0,47,0,18,109,0,16,10,
-50,0,57,18,98,0,47,0,0,0,0,1,90,95,0,0,30,0,2,27,1,1,0,0,9,0,97,0,0,1,1,0,0,30,0,110,0,0,0,1,8,58,
-109,97,116,51,120,52,0,0,18,97,0,18,110,0,16,8,48,0,57,47,0,18,97,0,18,110,0,16,10,49,0,57,47,0,18,
-97,0,18,110,0,16,10,50,0,57,47,0,0,0,0,1,90,95,0,0,30,0,2,27,1,1,0,0,30,0,109,0,0,1,1,0,0,9,0,98,0,
-0,0,1,8,58,109,97,116,51,120,52,0,0,18,109,0,16,8,48,0,57,18,98,0,47,0,18,109,0,16,10,49,0,57,18,
-98,0,47,0,18,109,0,16,10,50,0,57,18,98,0,47,0,0,0,0,1,90,95,0,0,29,0,2,27,1,1,0,0,29,0,109,0,0,1,1,
-0,0,9,0,98,0,0,0,1,8,58,109,97,116,52,120,50,0,0,18,109,0,16,8,48,0,57,18,98,0,47,0,18,109,0,16,10,
-49,0,57,18,98,0,47,0,18,109,0,16,10,50,0,57,18,98,0,47,0,18,109,0,16,10,51,0,57,18,98,0,47,0,0,0,0,
-1,90,95,0,0,29,0,2,27,1,1,0,0,9,0,97,0,0,1,1,0,0,29,0,110,0,0,0,1,8,58,109,97,116,52,120,50,0,0,18,
-97,0,18,110,0,16,8,48,0,57,47,0,18,97,0,18,110,0,16,10,49,0,57,47,0,18,97,0,18,110,0,16,10,50,0,57,
-47,0,18,97,0,18,110,0,16,10,51,0,57,47,0,0,0,0,1,90,95,0,0,31,0,2,27,1,1,0,0,31,0,109,0,0,1,1,0,0,
-9,0,98,0,0,0,1,8,58,109,97,116,52,120,51,0,0,18,109,0,16,8,48,0,57,18,98,0,47,0,18,109,0,16,10,49,
-0,57,18,98,0,47,0,18,109,0,16,10,50,0,57,18,98,0,47,0,18,109,0,16,10,51,0,57,18,98,0,47,0,0,0,0,1,
-90,95,0,0,31,0,2,27,1,1,0,0,9,0,97,0,0,1,1,0,0,31,0,110,0,0,0,1,8,58,109,97,116,52,120,51,0,0,18,
-97,0,18,110,0,16,8,48,0,57,47,0,18,97,0,18,110,0,16,10,49,0,57,47,0,18,97,0,18,110,0,16,10,50,0,57,
-47,0,18,97,0,18,110,0,16,10,51,0,57,47,0,0,0,0,1,90,95,0,0,26,0,2,21,1,1,0,0,9,0,97,0,0,1,1,0,0,26,
-0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,48,20,
-0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,0,16,10,49,0,57,48,20,0,0,1,90,
-95,0,0,26,0,2,21,1,1,0,0,26,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,
-8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,
-18,109,0,16,10,49,0,57,18,98,0,48,20,0,0,1,90,95,0,0,28,0,2,21,1,1,0,0,9,0,97,0,0,1,1,0,0,28,0,110,
-0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,48,20,0,9,18,
-95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,0,16,10,49,0,57,48,20,0,0,1,90,95,0,0,
-28,0,2,21,1,1,0,0,28,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,
-57,18,109,0,16,8,48,0,57,18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,
-16,10,49,0,57,18,98,0,48,20,0,0,1,90,95,0,0,27,0,2,21,1,1,0,0,9,0,97,0,0,1,1,0,0,27,0,110,0,0,0,1,
-9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,
-114,101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,50,0,57,18,97,0,18,110,0,16,10,50,0,57,48,20,0,0,1,90,95,0,0,27,0,2,21,1,1,0,
-0,27,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,
-8,48,0,57,18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,
-18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,98,0,48,
-20,0,0,1,90,95,0,0,30,0,2,21,1,1,0,0,9,0,97,0,0,1,1,0,0,30,0,110,0,0,0,1,9,18,95,95,114,101,116,86,
-97,108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,
-10,49,0,57,18,97,0,18,110,0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,
-18,97,0,18,110,0,16,10,50,0,57,48,20,0,0,1,90,95,0,0,30,0,2,21,1,1,0,0,30,0,109,0,0,1,1,0,0,9,0,98,
-0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,48,20,0,9,18,
-95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,48,20,0,9,18,95,95,114,
-101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,98,0,48,20,0,0,1,90,95,0,0,29,0,2,21,1,
-1,0,0,29,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,
-16,8,48,0,57,18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,
-57,18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,98,0,
-48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,109,0,16,10,51,0,57,18,98,0,48,20,0,0,
-1,90,95,0,0,29,0,2,21,1,1,0,0,9,0,97,0,0,1,1,0,0,29,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,
-0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,
-57,18,97,0,18,110,0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,97,0,
-18,110,0,16,10,50,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,97,0,18,110,0,
-16,10,51,0,57,48,20,0,0,1,90,95,0,0,31,0,2,21,1,1,0,0,31,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,9,18,95,
-95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,48,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,
-108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,
-10,51,0,57,18,109,0,16,10,51,0,57,18,98,0,48,20,0,0,1,90,95,0,0,31,0,2,21,1,1,0,0,9,0,97,0,0,1,1,0,
-0,31,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,
-48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,0,16,10,49,0,57,48,20,0,9,
-18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,97,0,18,110,0,16,10,50,0,57,48,20,0,9,18,95,95,
-114,101,116,86,97,108,0,16,10,51,0,57,18,97,0,18,110,0,16,10,51,0,57,48,20,0,0,1,90,95,0,0,26,0,2,
-22,1,1,0,0,9,0,97,0,0,1,1,0,0,26,0,110,0,0,0,1,3,2,90,95,1,0,9,0,1,105,110,118,0,2,17,49,0,48,0,0,
-18,97,0,49,0,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,105,110,118,0,18,110,0,16,8,48,0,
-57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,105,110,118,0,18,110,0,16,10,49,0,
-57,48,20,0,0,1,90,95,0,0,26,0,2,22,1,1,0,0,26,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,3,2,90,95,1,0,9,0,1,
-105,110,118,0,2,17,49,0,48,0,0,18,98,0,49,0,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,
-109,0,16,8,48,0,57,18,105,110,118,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,
-109,0,16,10,49,0,57,18,105,110,118,0,48,20,0,0,1,90,95,0,0,28,0,2,22,1,1,0,0,9,0,97,0,0,1,1,0,0,28,
-0,110,0,0,0,1,3,2,90,95,1,0,9,0,1,105,110,118,0,2,17,49,0,48,0,0,18,97,0,49,0,0,9,18,95,95,114,101,
-116,86,97,108,0,16,8,48,0,57,18,105,110,118,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,
-86,97,108,0,16,10,49,0,57,18,105,110,118,0,18,110,0,16,10,49,0,57,48,20,0,0,1,90,95,0,0,28,0,2,22,
-1,1,0,0,28,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,3,2,90,95,1,0,9,0,1,105,110,118,0,2,17,49,0,48,0,0,18,
-98,0,49,0,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,105,110,118,0,
-48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,105,110,118,0,
-48,20,0,0,1,90,95,0,0,27,0,2,22,1,1,0,0,9,0,97,0,0,1,1,0,0,27,0,110,0,0,0,1,3,2,90,95,1,0,9,0,1,
-105,110,118,0,2,17,49,0,48,0,0,18,97,0,49,0,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,
-105,110,118,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,
-105,110,118,0,18,110,0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,
-105,110,118,0,18,110,0,16,10,50,0,57,48,20,0,0,1,90,95,0,0,27,0,2,22,1,1,0,0,27,0,109,0,0,1,1,0,0,
-9,0,98,0,0,0,1,3,2,90,95,1,0,9,0,1,105,110,118,0,2,17,49,0,48,0,0,18,98,0,49,0,0,9,18,95,95,114,
-101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,105,110,118,0,48,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,105,110,118,0,48,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,105,110,118,0,48,20,0,0,1,90,95,0,0,30,0,2,
-22,1,1,0,0,9,0,97,0,0,1,1,0,0,30,0,110,0,0,0,1,3,2,90,95,1,0,9,0,1,105,110,118,0,2,17,49,0,48,0,0,
-18,97,0,49,0,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,105,110,118,0,18,110,0,16,8,48,0,
-57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,105,110,118,0,18,110,0,16,10,49,0,
-57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,105,110,118,0,18,110,0,16,10,50,0,
-57,48,20,0,0,1,90,95,0,0,30,0,2,22,1,1,0,0,30,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,3,2,90,95,1,0,9,0,1,
-105,110,118,0,2,17,49,0,48,0,0,18,98,0,49,0,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,
-109,0,16,8,48,0,57,18,105,110,118,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,
-109,0,16,10,49,0,57,18,105,110,118,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,
-109,0,16,10,50,0,57,18,105,110,118,0,48,20,0,0,1,90,95,0,0,29,0,2,22,1,1,0,0,29,0,109,0,0,1,1,0,0,
-9,0,98,0,0,0,1,3,2,90,95,1,0,9,0,1,105,110,118,0,2,17,49,0,48,0,0,18,98,0,49,0,0,9,18,95,95,114,
-101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,105,110,118,0,48,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,105,110,118,0,48,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,105,110,118,0,48,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,51,0,57,18,109,0,16,10,51,0,57,18,105,110,118,0,48,20,0,0,1,90,95,0,0,29,0,2,
-22,1,1,0,0,9,0,97,0,0,1,1,0,0,29,0,110,0,0,0,1,3,2,90,95,1,0,9,0,1,105,110,118,0,2,17,49,0,48,0,0,
-18,97,0,49,0,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,105,110,118,0,18,110,0,16,8,48,0,
-57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,105,110,118,0,18,110,0,16,10,49,0,
-57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,105,110,118,0,18,110,0,16,10,50,0,
-57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,105,110,118,0,18,110,0,16,10,51,0,
-57,48,20,0,0,1,90,95,0,0,31,0,2,22,1,1,0,0,31,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,3,2,90,95,1,0,9,0,1,
-105,110,118,0,2,17,49,0,48,0,0,18,98,0,49,0,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,
-109,0,16,8,48,0,57,18,105,110,118,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,
-109,0,16,10,49,0,57,18,105,110,118,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,
-109,0,16,10,50,0,57,18,105,110,118,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,
-109,0,16,10,51,0,57,18,105,110,118,0,48,20,0,0,1,90,95,0,0,31,0,2,22,1,1,0,0,9,0,97,0,0,1,1,0,0,31,
-0,110,0,0,0,1,3,2,90,95,1,0,9,0,1,105,110,118,0,2,17,49,0,48,0,0,18,97,0,49,0,0,9,18,95,95,114,101,
-116,86,97,108,0,16,8,48,0,57,18,105,110,118,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,
-86,97,108,0,16,10,49,0,57,18,105,110,118,0,18,110,0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,
-86,97,108,0,16,10,50,0,57,18,105,110,118,0,18,110,0,16,10,50,0,57,48,20,0,9,18,95,95,114,101,116,
-86,97,108,0,16,10,51,0,57,18,105,110,118,0,18,110,0,16,10,51,0,57,48,20,0,0,1,90,95,0,0,26,0,2,27,
-1,1,0,0,26,0,109,0,0,0,1,8,58,109,97,116,50,120,51,0,0,18,109,0,16,8,48,0,57,54,0,18,109,0,16,10,
-49,0,57,54,0,0,0,0,1,90,95,0,0,28,0,2,27,1,1,0,0,28,0,109,0,0,0,1,8,58,109,97,116,50,120,52,0,0,18,
-109,0,16,8,48,0,57,54,0,18,109,0,16,10,49,0,57,54,0,0,0,0,1,90,95,0,0,27,0,2,27,1,1,0,0,27,0,109,0,
-0,0,1,8,58,109,97,116,51,120,50,0,0,18,109,0,16,8,48,0,57,54,0,18,109,0,16,10,49,0,57,54,0,18,109,
-0,16,10,50,0,57,54,0,0,0,0,1,90,95,0,0,30,0,2,27,1,1,0,0,30,0,109,0,0,0,1,8,58,109,97,116,51,120,
-52,0,0,18,109,0,16,8,48,0,57,54,0,18,109,0,16,10,49,0,57,54,0,18,109,0,16,10,50,0,57,54,0,0,0,0,1,
-90,95,0,0,29,0,2,27,1,1,0,0,29,0,109,0,0,0,1,8,58,109,97,116,52,120,50,0,0,18,109,0,16,8,48,0,57,
-54,0,18,109,0,16,10,49,0,57,54,0,18,109,0,16,10,50,0,57,54,0,18,109,0,16,10,51,0,57,54,0,0,0,0,1,
-90,95,0,0,31,0,2,27,1,1,0,0,31,0,109,0,0,0,1,8,58,109,97,116,52,120,51,0,0,18,109,0,16,8,48,0,57,
-54,0,18,109,0,16,10,49,0,57,54,0,18,109,0,16,10,50,0,57,54,0,18,109,0,16,10,51,0,57,54,0,0,0,0,1,
-90,95,0,0,0,0,2,25,1,0,2,0,26,0,109,0,0,0,1,9,18,109,0,16,8,48,0,57,52,0,9,18,109,0,16,10,49,0,57,
-52,0,0,1,90,95,0,0,0,0,2,25,1,0,2,0,28,0,109,0,0,0,1,9,18,109,0,16,8,48,0,57,52,0,9,18,109,0,16,10,
-49,0,57,52,0,0,1,90,95,0,0,0,0,2,25,1,0,2,0,27,0,109,0,0,0,1,9,18,109,0,16,8,48,0,57,52,0,9,18,109,
-0,16,10,49,0,57,52,0,9,18,109,0,16,10,50,0,57,52,0,0,1,90,95,0,0,0,0,2,25,1,0,2,0,30,0,109,0,0,0,1,
-9,18,109,0,16,8,48,0,57,52,0,9,18,109,0,16,10,49,0,57,52,0,9,18,109,0,16,10,50,0,57,52,0,0,1,90,95,
-0,0,0,0,2,25,1,0,2,0,29,0,109,0,0,0,1,9,18,109,0,16,8,48,0,57,52,0,9,18,109,0,16,10,49,0,57,52,0,9,
-18,109,0,16,10,50,0,57,52,0,9,18,109,0,16,10,51,0,57,52,0,0,1,90,95,0,0,0,0,2,25,1,0,2,0,31,0,109,
-0,0,0,1,9,18,109,0,16,8,48,0,57,52,0,9,18,109,0,16,10,49,0,57,52,0,9,18,109,0,16,10,50,0,57,52,0,9,
-18,109,0,16,10,51,0,57,52,0,0,1,90,95,0,0,0,0,2,24,1,0,2,0,26,0,109,0,0,0,1,9,18,109,0,16,8,48,0,
-57,51,0,9,18,109,0,16,10,49,0,57,51,0,0,1,90,95,0,0,0,0,2,24,1,0,2,0,28,0,109,0,0,0,1,9,18,109,0,
-16,8,48,0,57,51,0,9,18,109,0,16,10,49,0,57,51,0,0,1,90,95,0,0,0,0,2,24,1,0,2,0,27,0,109,0,0,0,1,9,
-18,109,0,16,8,48,0,57,51,0,9,18,109,0,16,10,49,0,57,51,0,9,18,109,0,16,10,50,0,57,51,0,0,1,90,95,0,
-0,0,0,2,24,1,0,2,0,30,0,109,0,0,0,1,9,18,109,0,16,8,48,0,57,51,0,9,18,109,0,16,10,49,0,57,51,0,9,
-18,109,0,16,10,50,0,57,51,0,0,1,90,95,0,0,0,0,2,24,1,0,2,0,29,0,109,0,0,0,1,9,18,109,0,16,8,48,0,
-57,51,0,9,18,109,0,16,10,49,0,57,51,0,9,18,109,0,16,10,50,0,57,51,0,9,18,109,0,16,10,51,0,57,51,0,
-0,1,90,95,0,0,0,0,2,24,1,0,2,0,31,0,109,0,0,0,1,9,18,109,0,16,8,48,0,57,51,0,9,18,109,0,16,10,49,0,
-57,51,0,9,18,109,0,16,10,50,0,57,51,0,9,18,109,0,16,10,51,0,57,51,0,0,0
diff --git a/src/mesa/shader/slang/library/slang_builtin_120_common_gc.h b/src/mesa/shader/slang/library/slang_builtin_120_common_gc.h
deleted file mode 100644
index c397b9f..0000000
--- a/src/mesa/shader/slang/library/slang_builtin_120_common_gc.h
+++ /dev/null
@@ -1,108 +0,0 @@
-
-/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE FOLLOWING FILE: */
-/* slang_builtin_120_common.gc */
-
-5,1,90,95,0,0,26,0,0,109,97,116,114,105,120,67,111,109,112,77,117,108,116,0,1,0,0,0,26,0,109,0,0,1,
-0,0,0,26,0,110,0,0,0,1,8,58,109,97,116,50,120,51,0,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,
-48,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,48,0,0,0,0,1,90,95,0,0,28,0,0,109,97,116,114,
-105,120,67,111,109,112,77,117,108,116,0,1,0,0,0,28,0,109,0,0,1,0,0,0,28,0,110,0,0,0,1,8,58,109,97,
-116,50,120,52,0,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,
-16,10,49,0,57,48,0,0,0,0,1,90,95,0,0,27,0,0,109,97,116,114,105,120,67,111,109,112,77,117,108,116,0,
-1,0,0,0,27,0,109,0,0,1,0,0,0,27,0,110,0,0,0,1,8,58,109,97,116,51,120,50,0,0,18,109,0,16,8,48,0,57,
-18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,48,0,18,109,0,16,10,50,0,
-57,18,110,0,16,10,50,0,57,48,0,0,0,0,1,90,95,0,0,30,0,0,109,97,116,114,105,120,67,111,109,112,77,
-117,108,116,0,1,0,0,0,30,0,109,0,0,1,0,0,0,30,0,110,0,0,0,1,8,58,109,97,116,51,120,52,0,0,18,109,0,
-16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,48,0,18,109,
-0,16,10,50,0,57,18,110,0,16,10,50,0,57,48,0,0,0,0,1,90,95,0,0,29,0,0,109,97,116,114,105,120,67,111,
-109,112,77,117,108,116,0,1,0,0,0,29,0,109,0,0,1,0,0,0,29,0,110,0,0,0,1,8,58,109,97,116,52,120,50,0,
-0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,
-48,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,48,0,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,
-57,48,0,0,0,0,1,90,95,0,0,31,0,0,109,97,116,114,105,120,67,111,109,112,77,117,108,116,0,1,0,0,0,31,
-0,109,0,0,1,0,0,0,31,0,110,0,0,0,1,8,58,109,97,116,52,120,51,0,0,18,109,0,16,8,48,0,57,18,110,0,16,
-8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,48,0,18,109,0,16,10,50,0,57,18,110,0,
-16,10,50,0,57,48,0,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,48,0,0,0,0,1,90,95,0,0,13,0,0,111,
-117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,0,10,0,99,0,0,1,0,0,0,10,0,114,0,0,0,1,8,58,109,
-97,116,50,0,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,59,120,0,48,0,18,
-99,0,59,120,0,18,114,0,59,121,0,48,0,18,99,0,59,121,0,18,114,0,59,121,0,48,0,0,0,0,1,90,95,0,0,14,
-0,0,111,117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,0,11,0,99,0,0,1,0,0,0,11,0,114,0,0,0,1,8,
-58,109,97,116,51,0,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,59,120,0,48,
-0,18,99,0,59,122,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0,48,0,18,99,0,59,121,0,
-18,114,0,59,121,0,48,0,18,99,0,59,122,0,18,114,0,59,121,0,48,0,18,99,0,59,120,0,18,114,0,59,122,0,
-48,0,18,99,0,59,121,0,18,114,0,59,122,0,48,0,18,99,0,59,122,0,18,114,0,59,122,0,48,0,0,0,0,1,90,95,
-0,0,15,0,0,111,117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,0,12,0,99,0,0,1,0,0,0,12,0,114,0,
-0,0,1,8,58,109,97,116,52,0,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,59,
-120,0,48,0,18,99,0,59,122,0,18,114,0,59,120,0,48,0,18,99,0,59,119,0,18,114,0,59,120,0,48,0,18,99,0,
-59,120,0,18,114,0,59,121,0,48,0,18,99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,59,122,0,18,114,0,
-59,121,0,48,0,18,99,0,59,119,0,18,114,0,59,121,0,48,0,18,99,0,59,120,0,18,114,0,59,122,0,48,0,18,
-99,0,59,121,0,18,114,0,59,122,0,48,0,18,99,0,59,122,0,18,114,0,59,122,0,48,0,18,99,0,59,119,0,18,
-114,0,59,122,0,48,0,18,99,0,59,120,0,18,114,0,59,119,0,48,0,18,99,0,59,121,0,18,114,0,59,119,0,48,
-0,18,99,0,59,122,0,18,114,0,59,119,0,48,0,18,99,0,59,119,0,18,114,0,59,119,0,48,0,0,0,0,1,90,95,0,
-0,26,0,0,111,117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,0,11,0,99,0,0,1,0,0,0,10,0,114,0,0,
-0,1,8,58,109,97,116,50,120,51,0,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,
-0,59,120,0,48,0,18,99,0,59,122,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0,48,0,18,
-99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,59,122,0,18,114,0,59,121,0,48,0,0,0,0,1,90,95,0,0,27,
-0,0,111,117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,0,10,0,99,0,0,1,0,0,0,11,0,114,0,0,0,1,8,
-58,109,97,116,51,120,50,0,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,59,
-120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0,48,0,18,99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,
-59,120,0,18,114,0,59,122,0,48,0,18,99,0,59,121,0,18,114,0,59,122,0,48,0,0,0,0,1,90,95,0,0,28,0,0,
-111,117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,0,12,0,99,0,0,1,0,0,0,10,0,114,0,0,0,1,8,58,
-109,97,116,50,120,52,0,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,59,120,
-0,48,0,18,99,0,59,122,0,18,114,0,59,120,0,48,0,18,99,0,59,119,0,18,114,0,59,120,0,48,0,18,99,0,59,
-120,0,18,114,0,59,121,0,48,0,18,99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,59,122,0,18,114,0,59,
-121,0,48,0,18,99,0,59,119,0,18,114,0,59,121,0,48,0,0,0,0,1,90,95,0,0,29,0,0,111,117,116,101,114,80,
-114,111,100,117,99,116,0,1,0,0,0,10,0,99,0,0,1,0,0,0,12,0,114,0,0,0,1,8,58,109,97,116,52,120,50,0,
-0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,
-18,114,0,59,121,0,48,0,18,99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,59,120,0,18,114,0,59,122,0,
-48,0,18,99,0,59,121,0,18,114,0,59,122,0,48,0,18,99,0,59,120,0,18,114,0,59,119,0,48,0,18,99,0,59,
-121,0,18,114,0,59,119,0,48,0,0,0,0,1,90,95,0,0,30,0,0,111,117,116,101,114,80,114,111,100,117,99,
-116,0,1,0,0,0,12,0,99,0,0,1,0,0,0,11,0,114,0,0,0,1,8,58,109,97,116,51,120,52,0,0,18,99,0,59,120,0,
-18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,59,120,0,48,0,18,99,0,59,122,0,18,114,0,59,120,0,
-48,0,18,99,0,59,119,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0,48,0,18,99,0,59,
-121,0,18,114,0,59,121,0,48,0,18,99,0,59,122,0,18,114,0,59,121,0,48,0,18,99,0,59,119,0,18,114,0,59,
-121,0,48,0,18,99,0,59,120,0,18,114,0,59,122,0,48,0,18,99,0,59,121,0,18,114,0,59,122,0,48,0,18,99,0,
-59,122,0,18,114,0,59,122,0,48,0,18,99,0,59,119,0,18,114,0,59,122,0,48,0,0,0,0,1,90,95,0,0,31,0,0,
-111,117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,0,11,0,99,0,0,1,0,0,0,12,0,114,0,0,0,1,8,58,
-109,97,116,52,120,51,0,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,59,120,
-0,48,0,18,99,0,59,122,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0,48,0,18,99,0,59,
-121,0,18,114,0,59,121,0,48,0,18,99,0,59,122,0,18,114,0,59,121,0,48,0,18,99,0,59,120,0,18,114,0,59,
-122,0,48,0,18,99,0,59,121,0,18,114,0,59,122,0,48,0,18,99,0,59,122,0,18,114,0,59,122,0,48,0,18,99,0,
-59,120,0,18,114,0,59,119,0,48,0,18,99,0,59,121,0,18,114,0,59,119,0,48,0,18,99,0,59,122,0,18,114,0,
-59,119,0,48,0,0,0,0,1,90,95,0,0,13,0,0,116,114,97,110,115,112,111,115,101,0,1,0,0,0,13,0,109,0,0,0,
-1,8,58,109,97,116,50,0,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,
-0,16,8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,0,0,0,1,90,95,0,0,14,0,0,116,114,97,
-110,115,112,111,115,101,0,1,0,0,0,14,0,109,0,0,0,1,8,58,109,97,116,51,0,0,18,109,0,16,8,48,0,57,59,
-120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,50,0,57,59,120,0,0,18,109,0,16,8,48,0,57,
-59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,10,50,0,57,59,121,0,0,18,109,0,16,8,48,0,
-57,59,122,0,0,18,109,0,16,10,49,0,57,59,122,0,0,18,109,0,16,10,50,0,57,59,122,0,0,0,0,0,1,90,95,0,
-0,15,0,0,116,114,97,110,115,112,111,115,101,0,1,0,0,0,15,0,109,0,0,0,1,8,58,109,97,116,52,0,0,18,
-109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,50,0,57,59,120,0,0,
-18,109,0,16,10,51,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,
-0,18,109,0,16,10,50,0,57,59,121,0,0,18,109,0,16,10,51,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,
-0,0,18,109,0,16,10,49,0,57,59,122,0,0,18,109,0,16,10,50,0,57,59,122,0,0,18,109,0,16,10,51,0,57,59,
-122,0,0,18,109,0,16,8,48,0,57,59,119,0,0,18,109,0,16,10,49,0,57,59,119,0,0,18,109,0,16,10,50,0,57,
-59,119,0,0,18,109,0,16,10,51,0,57,59,119,0,0,0,0,0,1,90,95,0,0,26,0,0,116,114,97,110,115,112,111,
-115,101,0,1,0,0,0,27,0,109,0,0,0,1,8,58,109,97,116,50,120,51,0,0,18,109,0,16,8,48,0,57,59,120,0,0,
-18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,50,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,
-0,18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,10,50,0,57,59,121,0,0,0,0,0,1,90,95,0,0,27,0,0,116,
-114,97,110,115,112,111,115,101,0,1,0,0,0,26,0,109,0,0,0,1,8,58,109,97,116,51,120,50,0,0,18,109,0,
-16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,
-0,16,10,49,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,18,109,0,16,10,49,0,57,59,122,0,0,0,0,
-0,1,90,95,0,0,28,0,0,116,114,97,110,115,112,111,115,101,0,1,0,0,0,29,0,109,0,0,0,1,8,58,109,97,116,
-50,120,52,0,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,50,
-0,57,59,120,0,0,18,109,0,16,10,51,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,10,
-49,0,57,59,121,0,0,18,109,0,16,10,50,0,57,59,121,0,0,18,109,0,16,10,51,0,57,59,121,0,0,0,0,0,1,90,
-95,0,0,29,0,0,116,114,97,110,115,112,111,115,101,0,1,0,0,0,28,0,109,0,0,0,1,8,58,109,97,116,52,120,
-50,0,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,
-121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,18,109,0,16,10,49,0,57,
-59,122,0,0,18,109,0,16,8,48,0,57,59,119,0,0,18,109,0,16,10,49,0,57,59,119,0,0,0,0,0,1,90,95,0,0,30,
-0,0,116,114,97,110,115,112,111,115,101,0,1,0,0,0,31,0,109,0,0,0,1,8,58,109,97,116,51,120,52,0,0,18,
-109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,50,0,57,59,120,0,0,
-18,109,0,16,10,51,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,
-0,18,109,0,16,10,50,0,57,59,121,0,0,18,109,0,16,10,51,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,
-0,0,18,109,0,16,10,49,0,57,59,122,0,0,18,109,0,16,10,50,0,57,59,122,0,0,18,109,0,16,10,51,0,57,59,
-122,0,0,0,0,0,1,90,95,0,0,31,0,0,116,114,97,110,115,112,111,115,101,0,1,0,0,0,30,0,109,0,0,0,1,8,
-58,109,97,116,52,120,51,0,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,
-109,0,16,10,50,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,
-18,109,0,16,10,50,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,18,109,0,16,10,49,0,57,59,122,0,
-0,18,109,0,16,10,50,0,57,59,122,0,0,18,109,0,16,8,48,0,57,59,119,0,0,18,109,0,16,10,49,0,57,59,119,
-0,0,18,109,0,16,10,50,0,57,59,119,0,0,0,0,0,0
diff --git a/src/mesa/shader/slang/library/slang_builtin_120_fragment_gc.h b/src/mesa/shader/slang/library/slang_builtin_120_fragment_gc.h
deleted file mode 100644
index add3b5a..0000000
--- a/src/mesa/shader/slang/library/slang_builtin_120_fragment_gc.h
+++ /dev/null
@@ -1,5 +0,0 @@
-
-/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE FOLLOWING FILE: */
-/* slang_builtin_120_fragment.gc */
-
-5,2,2,90,95,3,0,10,0,1,103,108,95,80,111,105,110,116,67,111,111,114,100,0,0,0,0
diff --git a/src/mesa/shader/slang/library/slang_common_builtin_gc.h b/src/mesa/shader/slang/library/slang_common_builtin_gc.h
deleted file mode 100644
index 3c3666e..0000000
--- a/src/mesa/shader/slang/library/slang_common_builtin_gc.h
+++ /dev/null
@@ -1,880 +0,0 @@
-
-/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE FOLLOWING FILE: */
-/* slang_common_builtin.gc */
-
-5,2,2,90,95,1,0,5,0,1,103,108,95,77,97,120,76,105,103,104,116,115,0,2,16,10,56,0,0,0,2,2,90,95,1,0,
-5,0,1,103,108,95,77,97,120,67,108,105,112,80,108,97,110,101,115,0,2,16,10,54,0,0,0,2,2,90,95,1,0,5,
-0,1,103,108,95,77,97,120,84,101,120,116,117,114,101,85,110,105,116,115,0,2,16,10,56,0,0,0,2,2,90,
-95,1,0,5,0,1,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,2,16,10,56,0,
-0,0,2,2,90,95,1,0,5,0,1,103,108,95,77,97,120,86,101,114,116,101,120,65,116,116,114,105,98,115,0,2,
-16,10,49,54,0,0,0,2,2,90,95,1,0,5,0,1,103,108,95,77,97,120,86,101,114,116,101,120,85,110,105,102,
-111,114,109,67,111,109,112,111,110,101,110,116,115,0,2,16,10,53,49,50,0,0,0,2,2,90,95,1,0,5,0,1,
-103,108,95,77,97,120,86,97,114,121,105,110,103,70,108,111,97,116,115,0,2,16,10,51,50,0,0,0,2,2,90,
-95,1,0,5,0,1,103,108,95,77,97,120,86,101,114,116,101,120,84,101,120,116,117,114,101,73,109,97,103,
-101,85,110,105,116,115,0,2,16,8,48,0,0,0,2,2,90,95,1,0,5,0,1,103,108,95,77,97,120,67,111,109,98,
-105,110,101,100,84,101,120,116,117,114,101,73,109,97,103,101,85,110,105,116,115,0,2,16,10,50,0,0,0,
-2,2,90,95,1,0,5,0,1,103,108,95,77,97,120,84,101,120,116,117,114,101,73,109,97,103,101,85,110,105,
-116,115,0,2,16,10,50,0,0,0,2,2,90,95,1,0,5,0,1,103,108,95,77,97,120,70,114,97,103,109,101,110,116,
-85,110,105,102,111,114,109,67,111,109,112,111,110,101,110,116,115,0,2,16,10,54,52,0,0,0,2,2,90,95,
-1,0,5,0,1,103,108,95,77,97,120,68,114,97,119,66,117,102,102,101,114,115,0,2,16,10,49,0,0,0,2,2,90,
-95,4,0,15,0,1,103,108,95,77,111,100,101,108,86,105,101,119,77,97,116,114,105,120,0,0,0,2,2,90,95,4,
-0,15,0,1,103,108,95,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,2,2,90,95,4,
-0,15,0,1,103,108,95,77,111,100,101,108,86,105,101,119,80,114,111,106,101,99,116,105,111,110,77,97,
-116,114,105,120,0,0,0,2,2,90,95,4,0,15,0,1,103,108,95,84,101,120,116,117,114,101,77,97,116,114,105,
-120,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,
-4,0,14,0,1,103,108,95,78,111,114,109,97,108,77,97,116,114,105,120,0,0,0,2,2,90,95,4,0,15,0,1,103,
-108,95,77,111,100,101,108,86,105,101,119,77,97,116,114,105,120,73,110,118,101,114,115,101,0,0,0,2,
-2,90,95,4,0,15,0,1,103,108,95,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,73,110,
-118,101,114,115,101,0,0,0,2,2,90,95,4,0,15,0,1,103,108,95,77,111,100,101,108,86,105,101,119,80,114,
-111,106,101,99,116,105,111,110,77,97,116,114,105,120,73,110,118,101,114,115,101,0,0,0,2,2,90,95,4,
-0,15,0,1,103,108,95,84,101,120,116,117,114,101,77,97,116,114,105,120,73,110,118,101,114,115,101,0,
-3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,15,
-0,1,103,108,95,77,111,100,101,108,86,105,101,119,77,97,116,114,105,120,84,114,97,110,115,112,111,
-115,101,0,0,0,2,2,90,95,4,0,15,0,1,103,108,95,80,114,111,106,101,99,116,105,111,110,77,97,116,114,
-105,120,84,114,97,110,115,112,111,115,101,0,0,0,2,2,90,95,4,0,15,0,1,103,108,95,77,111,100,101,108,
-86,105,101,119,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,84,114,97,110,115,112,
-111,115,101,0,0,0,2,2,90,95,4,0,15,0,1,103,108,95,84,101,120,116,117,114,101,77,97,116,114,105,120,
-84,114,97,110,115,112,111,115,101,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,
-111,114,100,115,0,0,0,2,2,90,95,4,0,15,0,1,103,108,95,77,111,100,101,108,86,105,101,119,77,97,116,
-114,105,120,73,110,118,101,114,115,101,84,114,97,110,115,112,111,115,101,0,0,0,2,2,90,95,4,0,15,0,
-1,103,108,95,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,73,110,118,101,114,115,
-101,84,114,97,110,115,112,111,115,101,0,0,0,2,2,90,95,4,0,15,0,1,103,108,95,77,111,100,101,108,86,
-105,101,119,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,73,110,118,101,114,115,101,
-84,114,97,110,115,112,111,115,101,0,0,0,2,2,90,95,4,0,15,0,1,103,108,95,84,101,120,116,117,114,101,
-77,97,116,114,105,120,73,110,118,101,114,115,101,84,114,97,110,115,112,111,115,101,0,3,18,103,108,
-95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,9,0,1,103,108,
-95,78,111,114,109,97,108,83,99,97,108,101,0,0,0,2,2,90,95,0,0,24,103,108,95,68,101,112,116,104,82,
-97,110,103,101,80,97,114,97,109,101,116,101,114,115,0,9,0,110,101,97,114,0,0,0,1,9,0,102,97,114,0,
-0,0,1,9,0,100,105,102,102,0,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,68,101,112,116,104,82,97,110,
-103,101,80,97,114,97,109,101,116,101,114,115,0,0,1,103,108,95,68,101,112,116,104,82,97,110,103,101,
-0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,67,108,105,112,80,108,97,110,101,0,3,18,103,108,95,77,97,120,
-67,108,105,112,80,108,97,110,101,115,0,0,0,2,2,90,95,0,0,24,103,108,95,80,111,105,110,116,80,97,
-114,97,109,101,116,101,114,115,0,9,0,115,105,122,101,0,0,0,1,9,0,115,105,122,101,77,105,110,0,0,0,
-1,9,0,115,105,122,101,77,97,120,0,0,0,1,9,0,102,97,100,101,84,104,114,101,115,104,111,108,100,83,
-105,122,101,0,0,0,1,9,0,100,105,115,116,97,110,99,101,67,111,110,115,116,97,110,116,65,116,116,101,
-110,117,97,116,105,111,110,0,0,0,1,9,0,100,105,115,116,97,110,99,101,76,105,110,101,97,114,65,116,
-116,101,110,117,97,116,105,111,110,0,0,0,1,9,0,100,105,115,116,97,110,99,101,81,117,97,100,114,97,
-116,105,99,65,116,116,101,110,117,97,116,105,111,110,0,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,80,
-111,105,110,116,80,97,114,97,109,101,116,101,114,115,0,0,1,103,108,95,80,111,105,110,116,0,0,0,2,2,
-90,95,0,0,24,103,108,95,77,97,116,101,114,105,97,108,80,97,114,97,109,101,116,101,114,115,0,12,0,
-101,109,105,115,115,105,111,110,0,0,0,1,12,0,97,109,98,105,101,110,116,0,0,0,1,12,0,100,105,102,
-102,117,115,101,0,0,0,1,12,0,115,112,101,99,117,108,97,114,0,0,0,1,9,0,115,104,105,110,105,110,101,
-115,115,0,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,77,97,116,101,114,105,97,108,80,97,114,97,109,
-101,116,101,114,115,0,0,1,103,108,95,70,114,111,110,116,77,97,116,101,114,105,97,108,0,0,0,2,2,90,
-95,4,0,25,103,108,95,77,97,116,101,114,105,97,108,80,97,114,97,109,101,116,101,114,115,0,0,1,103,
-108,95,66,97,99,107,77,97,116,101,114,105,97,108,0,0,0,2,2,90,95,0,0,24,103,108,95,76,105,103,104,
-116,83,111,117,114,99,101,80,97,114,97,109,101,116,101,114,115,0,12,0,97,109,98,105,101,110,116,0,
-0,0,1,12,0,100,105,102,102,117,115,101,0,0,0,1,12,0,115,112,101,99,117,108,97,114,0,0,0,1,12,0,112,
-111,115,105,116,105,111,110,0,0,0,1,12,0,104,97,108,102,86,101,99,116,111,114,0,0,0,1,11,0,115,112,
-111,116,68,105,114,101,99,116,105,111,110,0,0,0,1,9,0,115,112,111,116,67,111,115,67,117,116,111,
-102,102,0,0,0,1,9,0,99,111,110,115,116,97,110,116,65,116,116,101,110,117,97,116,105,111,110,0,0,0,
-1,9,0,108,105,110,101,97,114,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,0,113,117,97,100,
-114,97,116,105,99,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,0,115,112,111,116,69,120,112,
-111,110,101,110,116,0,0,0,1,9,0,115,112,111,116,67,117,116,111,102,102,0,0,0,0,0,0,0,2,2,90,95,4,0,
-25,103,108,95,76,105,103,104,116,83,111,117,114,99,101,80,97,114,97,109,101,116,101,114,115,0,0,1,
-103,108,95,76,105,103,104,116,83,111,117,114,99,101,0,3,18,103,108,95,77,97,120,76,105,103,104,116,
-115,0,0,0,2,2,90,95,0,0,24,103,108,95,76,105,103,104,116,77,111,100,101,108,80,97,114,97,109,101,
-116,101,114,115,0,12,0,97,109,98,105,101,110,116,0,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,76,105,
-103,104,116,77,111,100,101,108,80,97,114,97,109,101,116,101,114,115,0,0,1,103,108,95,76,105,103,
-104,116,77,111,100,101,108,0,0,0,2,2,90,95,0,0,24,103,108,95,76,105,103,104,116,77,111,100,101,108,
-80,114,111,100,117,99,116,115,0,12,0,115,99,101,110,101,67,111,108,111,114,0,0,0,0,0,0,0,2,2,90,95,
-4,0,25,103,108,95,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,115,0,0,1,103,
-108,95,70,114,111,110,116,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,0,0,0,2,
-2,90,95,4,0,25,103,108,95,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,115,0,0,
-1,103,108,95,66,97,99,107,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,0,0,0,2,
-2,90,95,0,0,24,103,108,95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,12,0,97,109,98,105,
-101,110,116,0,0,0,1,12,0,100,105,102,102,117,115,101,0,0,0,1,12,0,115,112,101,99,117,108,97,114,0,
-0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,0,1,103,
-108,95,70,114,111,110,116,76,105,103,104,116,80,114,111,100,117,99,116,0,3,18,103,108,95,77,97,120,
-76,105,103,104,116,115,0,0,0,2,2,90,95,4,0,25,103,108,95,76,105,103,104,116,80,114,111,100,117,99,
-116,115,0,0,1,103,108,95,66,97,99,107,76,105,103,104,116,80,114,111,100,117,99,116,0,3,18,103,108,
-95,77,97,120,76,105,103,104,116,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,84,101,120,116,117,114,
-101,69,110,118,67,111,108,111,114,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,73,109,97,
-103,101,85,110,105,116,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,69,121,101,80,108,97,110,101,83,0,
-3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,
-0,1,103,108,95,69,121,101,80,108,97,110,101,84,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,
-101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,69,121,101,80,108,97,110,101,82,0,
-3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,
-0,1,103,108,95,69,121,101,80,108,97,110,101,81,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,
-101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,79,98,106,101,99,116,80,108,97,
-110,101,83,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,
-90,95,4,0,12,0,1,103,108,95,79,98,106,101,99,116,80,108,97,110,101,84,0,3,18,103,108,95,77,97,120,
-84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,79,98,106,
-101,99,116,80,108,97,110,101,82,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,
-114,100,115,0,0,0,2,2,90,95,4,0,12,0,1,103,108,95,79,98,106,101,99,116,80,108,97,110,101,81,0,3,18,
-103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,90,95,0,0,24,103,
-108,95,70,111,103,80,97,114,97,109,101,116,101,114,115,0,12,0,99,111,108,111,114,0,0,0,1,9,0,100,
-101,110,115,105,116,121,0,0,0,1,9,0,115,116,97,114,116,0,0,0,1,9,0,101,110,100,0,0,0,1,9,0,115,99,
-97,108,101,0,0,0,0,0,0,0,2,2,90,95,4,0,25,103,108,95,70,111,103,80,97,114,97,109,101,116,101,114,
-115,0,0,1,103,108,95,70,111,103,0,0,0,1,90,95,0,0,9,0,0,114,97,100,105,97,110,115,0,1,1,0,0,9,0,
-100,101,103,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,49,56,48,0,48,0,
-0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,
-18,100,101,103,0,0,18,99,0,0,0,0,1,90,95,0,0,10,0,0,114,97,100,105,97,110,115,0,1,1,0,0,10,0,100,
-101,103,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,49,56,48,0,48,0,0,
-49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,
-120,121,0,0,18,100,101,103,0,59,120,121,0,0,18,99,0,59,120,120,0,0,0,0,1,90,95,0,0,11,0,0,114,97,
-100,105,97,110,115,0,1,1,0,0,11,0,100,101,103,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,51,0,49,52,49,
-53,57,50,54,0,0,17,49,56,48,0,48,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,
-18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,100,101,103,0,59,120,121,122,0,0,18,99,0,59,
-120,120,120,0,0,0,0,1,90,95,0,0,12,0,0,114,97,100,105,97,110,115,0,1,1,0,0,12,0,100,101,103,0,0,0,
-1,3,2,90,95,1,0,9,0,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,49,56,48,0,48,0,0,49,0,0,4,118,
-101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,100,101,103,0,
-0,18,99,0,59,120,120,120,120,0,0,0,0,1,90,95,0,0,9,0,0,100,101,103,114,101,101,115,0,1,1,0,0,9,0,
-114,97,100,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,49,56,48,0,48,0,0,17,51,0,49,52,49,53,57,50,54,0,
-0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,
-18,114,97,100,0,0,18,99,0,0,0,0,1,90,95,0,0,10,0,0,100,101,103,114,101,101,115,0,1,1,0,0,10,0,114,
-97,100,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,49,56,48,0,48,0,0,17,51,0,49,52,49,53,57,50,54,0,0,49,
-0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,
-121,0,0,18,114,97,100,0,59,120,121,0,0,18,99,0,59,120,120,0,0,0,0,1,90,95,0,0,11,0,0,100,101,103,
-114,101,101,115,0,1,1,0,0,11,0,114,97,100,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,49,56,48,0,48,0,0,
-17,51,0,49,52,49,53,57,50,54,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,
-95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,114,97,100,0,59,120,121,122,0,0,18,99,0,59,120,
-120,120,0,0,0,0,1,90,95,0,0,12,0,0,100,101,103,114,101,101,115,0,1,1,0,0,12,0,114,97,100,0,0,0,1,3,
-2,90,95,1,0,9,0,1,99,0,2,17,49,56,48,0,48,0,0,17,51,0,49,52,49,53,57,50,54,0,0,49,0,0,4,118,101,99,
-52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,114,97,100,0,0,18,99,
-0,59,120,120,120,120,0,0,0,0,1,90,95,0,0,9,0,0,115,105,110,0,1,1,0,0,9,0,114,97,100,105,97,110,115,
-0,0,0,1,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,0,18,114,97,100,
-105,97,110,115,0,0,0,0,1,90,95,0,0,10,0,0,115,105,110,0,1,1,0,0,10,0,114,97,100,105,97,110,115,0,0,
-0,1,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,
-97,100,105,97,110,115,0,59,120,0,0,0,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,
-116,86,97,108,0,59,121,0,0,18,114,97,100,105,97,110,115,0,59,121,0,0,0,0,1,90,95,0,0,11,0,0,115,
-105,110,0,1,1,0,0,11,0,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111,97,116,95,115,105,110,101,0,
-18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,97,100,105,97,110,115,0,59,120,0,0,0,4,102,108,
-111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,114,97,100,105,97,
-110,115,0,59,121,0,0,0,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,
-59,122,0,0,18,114,97,100,105,97,110,115,0,59,122,0,0,0,0,1,90,95,0,0,12,0,0,115,105,110,0,1,1,0,0,
-12,0,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,
-116,86,97,108,0,59,120,0,0,18,114,97,100,105,97,110,115,0,59,120,0,0,0,4,102,108,111,97,116,95,115,
-105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,114,97,100,105,97,110,115,0,59,121,0,
-0,0,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,114,
-97,100,105,97,110,115,0,59,122,0,0,0,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,
-116,86,97,108,0,59,119,0,0,18,114,97,100,105,97,110,115,0,59,119,0,0,0,0,1,90,95,0,0,9,0,0,99,111,
-115,0,1,1,0,0,9,0,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111,97,116,95,99,111,115,105,110,101,
-0,18,95,95,114,101,116,86,97,108,0,0,18,114,97,100,105,97,110,115,0,0,0,0,1,90,95,0,0,10,0,0,99,
-111,115,0,1,1,0,0,10,0,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111,97,116,95,99,111,115,105,
-110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,97,100,105,97,110,115,0,59,120,0,0,0,
-4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,
-114,97,100,105,97,110,115,0,59,121,0,0,0,0,1,90,95,0,0,11,0,0,99,111,115,0,1,1,0,0,11,0,114,97,100,
-105,97,110,115,0,0,0,1,4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,
-108,0,59,120,0,0,18,114,97,100,105,97,110,115,0,59,120,0,0,0,4,102,108,111,97,116,95,99,111,115,
-105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,114,97,100,105,97,110,115,0,59,121,0,
-0,0,4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,
-18,114,97,100,105,97,110,115,0,59,122,0,0,0,0,1,90,95,0,0,12,0,0,99,111,115,0,1,1,0,0,12,0,114,97,
-100,105,97,110,115,0,0,0,1,4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,
-86,97,108,0,59,120,0,0,18,114,97,100,105,97,110,115,0,59,120,0,0,0,4,102,108,111,97,116,95,99,111,
-115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,114,97,100,105,97,110,115,0,59,
-121,0,0,0,4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,122,
-0,0,18,114,97,100,105,97,110,115,0,59,122,0,0,0,4,102,108,111,97,116,95,99,111,115,105,110,101,0,
-18,95,95,114,101,116,86,97,108,0,59,119,0,0,18,114,97,100,105,97,110,115,0,59,119,0,0,0,0,1,90,95,
-0,0,9,0,0,116,97,110,0,1,1,0,0,9,0,97,110,103,108,101,0,0,0,1,3,2,90,95,1,0,9,0,1,115,0,2,58,115,
-105,110,0,0,18,97,110,103,108,101,0,0,0,0,0,3,2,90,95,1,0,9,0,1,99,0,2,58,99,111,115,0,0,18,97,110,
-103,108,101,0,0,0,0,0,8,18,115,0,18,99,0,49,0,0,1,90,95,0,0,10,0,0,116,97,110,0,1,1,0,0,10,0,97,
-110,103,108,101,0,0,0,1,3,2,90,95,1,0,10,0,1,115,0,2,58,115,105,110,0,0,18,97,110,103,108,101,0,0,
-0,0,0,3,2,90,95,1,0,10,0,1,99,0,2,58,99,111,115,0,0,18,97,110,103,108,101,0,0,0,0,0,8,18,115,0,18,
-99,0,49,0,0,1,90,95,0,0,11,0,0,116,97,110,0,1,1,0,0,11,0,97,110,103,108,101,0,0,0,1,3,2,90,95,1,0,
-11,0,1,115,0,2,58,115,105,110,0,0,18,97,110,103,108,101,0,0,0,0,0,3,2,90,95,1,0,11,0,1,99,0,2,58,
-99,111,115,0,0,18,97,110,103,108,101,0,0,0,0,0,8,18,115,0,18,99,0,49,0,0,1,90,95,0,0,12,0,0,116,97,
-110,0,1,1,0,0,12,0,97,110,103,108,101,0,0,0,1,3,2,90,95,1,0,12,0,1,115,0,2,58,115,105,110,0,0,18,
-97,110,103,108,101,0,0,0,0,0,3,2,90,95,1,0,12,0,1,99,0,2,58,99,111,115,0,0,18,97,110,103,108,101,0,
-0,0,0,0,8,18,115,0,18,99,0,49,0,0,1,90,95,0,0,9,0,0,97,115,105,110,0,1,1,0,0,9,0,120,0,0,0,1,3,2,
-90,95,1,0,9,0,1,97,48,0,2,17,49,0,53,55,48,55,50,56,56,0,0,0,0,3,2,90,95,1,0,9,0,1,97,49,0,2,17,48,
-0,50,49,50,49,49,52,52,0,0,54,0,0,3,2,90,95,1,0,9,0,1,97,50,0,2,17,48,0,48,55,52,50,54,49,48,0,0,0,
-0,3,2,90,95,1,0,9,0,1,104,97,108,102,80,105,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,48,0,53,0,0,48,
-0,0,3,2,90,95,1,0,9,0,1,121,0,2,58,97,98,115,0,0,18,120,0,0,0,0,0,9,18,95,95,114,101,116,86,97,108,
-0,18,104,97,108,102,80,105,0,58,115,113,114,116,0,0,17,49,0,48,0,0,18,121,0,47,0,0,18,97,48,0,18,
-121,0,18,97,49,0,18,97,50,0,18,121,0,48,46,48,46,48,47,58,115,105,103,110,0,0,18,120,0,0,0,48,20,0,
-0,1,90,95,0,0,10,0,0,97,115,105,110,0,1,1,0,0,10,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,
-59,120,0,58,97,115,105,110,0,0,18,118,0,59,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,
-121,0,58,97,115,105,110,0,0,18,118,0,59,121,0,0,0,20,0,0,1,90,95,0,0,11,0,0,97,115,105,110,0,1,1,0,
-0,11,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,97,115,105,110,0,0,18,118,0,59,
-120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,97,115,105,110,0,0,18,118,0,59,121,0,
-0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,97,115,105,110,0,0,18,118,0,59,122,0,0,0,
-20,0,0,1,90,95,0,0,12,0,0,97,115,105,110,0,1,1,0,0,12,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,
-108,0,59,120,0,58,97,115,105,110,0,0,18,118,0,59,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,
-59,121,0,58,97,115,105,110,0,0,18,118,0,59,121,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,
-122,0,58,97,115,105,110,0,0,18,118,0,59,122,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,
-58,97,115,105,110,0,0,18,118,0,59,119,0,0,0,20,0,0,1,90,95,0,0,9,0,0,97,99,111,115,0,1,1,0,0,9,0,
-120,0,0,0,1,3,2,90,95,1,0,9,0,1,104,97,108,102,80,105,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,48,0,
-53,0,0,48,0,0,9,18,95,95,114,101,116,86,97,108,0,18,104,97,108,102,80,105,0,58,97,115,105,110,0,0,
-18,120,0,0,0,47,20,0,0,1,90,95,0,0,10,0,0,97,99,111,115,0,1,1,0,0,10,0,118,0,0,0,1,9,18,95,95,114,
-101,116,86,97,108,0,59,120,0,58,97,99,111,115,0,0,18,118,0,59,120,0,0,0,20,0,9,18,95,95,114,101,
-116,86,97,108,0,59,121,0,58,97,99,111,115,0,0,18,118,0,59,121,0,0,0,20,0,0,1,90,95,0,0,11,0,0,97,
-99,111,115,0,1,1,0,0,11,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,97,99,111,115,
-0,0,18,118,0,59,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,97,99,111,115,0,0,18,
-118,0,59,121,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,97,99,111,115,0,0,18,118,0,
-59,122,0,0,0,20,0,0,1,90,95,0,0,12,0,0,97,99,111,115,0,1,1,0,0,12,0,118,0,0,0,1,9,18,95,95,114,101,
-116,86,97,108,0,59,120,0,58,97,99,111,115,0,0,18,118,0,59,120,0,0,0,20,0,9,18,95,95,114,101,116,86,
-97,108,0,59,121,0,58,97,99,111,115,0,0,18,118,0,59,121,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,
-0,59,122,0,58,97,99,111,115,0,0,18,118,0,59,122,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,
-119,0,58,97,99,111,115,0,0,18,118,0,59,119,0,0,0,20,0,0,1,90,95,0,0,9,0,0,97,116,97,110,0,1,1,0,0,
-9,0,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,97,115,105,110,0,0,18,120,0,58,105,110,118,
-101,114,115,101,115,113,114,116,0,0,18,120,0,18,120,0,48,17,49,0,48,0,0,46,0,0,48,0,0,20,0,0,1,90,
-95,0,0,10,0,0,97,116,97,110,0,1,1,0,0,10,0,121,95,111,118,101,114,95,120,0,0,0,1,9,18,95,95,114,
-101,116,86,97,108,0,59,120,0,58,97,116,97,110,0,0,18,121,95,111,118,101,114,95,120,0,59,120,0,0,0,
-20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,97,116,97,110,0,0,18,121,95,111,118,101,114,95,
-120,0,59,121,0,0,0,20,0,0,1,90,95,0,0,11,0,0,97,116,97,110,0,1,1,0,0,11,0,121,95,111,118,101,114,
-95,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,97,116,97,110,0,0,18,121,95,111,118,
-101,114,95,120,0,59,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,97,116,97,110,0,
-0,18,121,95,111,118,101,114,95,120,0,59,121,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,
-58,97,116,97,110,0,0,18,121,95,111,118,101,114,95,120,0,59,122,0,0,0,20,0,0,1,90,95,0,0,12,0,0,97,
-116,97,110,0,1,1,0,0,12,0,121,95,111,118,101,114,95,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,
-59,120,0,58,97,116,97,110,0,0,18,121,95,111,118,101,114,95,120,0,59,120,0,0,0,20,0,9,18,95,95,114,
-101,116,86,97,108,0,59,121,0,58,97,116,97,110,0,0,18,121,95,111,118,101,114,95,120,0,59,121,0,0,0,
-20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,97,116,97,110,0,0,18,121,95,111,118,101,114,95,
-120,0,59,122,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,58,97,116,97,110,0,0,18,121,95,
-111,118,101,114,95,120,0,59,119,0,0,0,20,0,0,1,90,95,0,0,9,0,0,97,116,97,110,0,1,1,0,0,9,0,121,0,0,
-1,1,0,0,9,0,120,0,0,0,1,3,2,90,95,0,0,9,0,1,114,0,0,0,10,58,97,98,115,0,0,18,120,0,0,0,17,49,0,48,
-0,45,52,0,41,0,2,9,18,114,0,58,97,116,97,110,0,0,18,121,0,18,120,0,49,0,0,20,0,10,18,120,0,17,48,0,
-48,0,0,40,0,2,9,18,114,0,18,114,0,58,115,105,103,110,0,0,18,121,0,0,0,17,51,0,49,52,49,53,57,51,0,
-0,48,46,20,0,0,9,14,0,0,2,9,18,114,0,58,115,105,103,110,0,0,18,121,0,0,0,17,49,0,53,55,48,55,57,54,
-53,0,0,48,20,0,0,8,18,114,0,0,0,1,90,95,0,0,10,0,0,97,116,97,110,0,1,1,0,0,10,0,117,0,0,1,1,0,0,10,
-0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,97,116,97,110,0,0,18,117,0,59,120,0,0,
-18,118,0,59,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,97,116,97,110,0,0,18,117,
-0,59,121,0,0,18,118,0,59,121,0,0,0,20,0,0,1,90,95,0,0,11,0,0,97,116,97,110,0,1,1,0,0,11,0,117,0,0,
-1,1,0,0,11,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,97,116,97,110,0,0,18,117,0,
-59,120,0,0,18,118,0,59,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,97,116,97,110,
-0,0,18,117,0,59,121,0,0,18,118,0,59,121,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,
-97,116,97,110,0,0,18,117,0,59,122,0,0,18,118,0,59,122,0,0,0,20,0,0,1,90,95,0,0,12,0,0,97,116,97,
-110,0,1,1,0,0,12,0,117,0,0,1,1,0,0,12,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,
-97,116,97,110,0,0,18,117,0,59,120,0,0,18,118,0,59,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,
-0,59,121,0,58,97,116,97,110,0,0,18,117,0,59,121,0,0,18,118,0,59,121,0,0,0,20,0,9,18,95,95,114,101,
-116,86,97,108,0,59,122,0,58,97,116,97,110,0,0,18,117,0,59,122,0,0,18,118,0,59,122,0,0,0,20,0,9,18,
-95,95,114,101,116,86,97,108,0,59,119,0,58,97,116,97,110,0,0,18,117,0,59,119,0,0,18,118,0,59,119,0,
-0,0,20,0,0,1,90,95,0,0,9,0,0,112,111,119,0,1,1,0,0,9,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,4,102,108,111,
-97,116,95,112,111,119,101,114,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,90,95,
-0,0,10,0,0,112,111,119,0,1,1,0,0,10,0,97,0,0,1,1,0,0,10,0,98,0,0,0,1,4,102,108,111,97,116,95,112,
-111,119,101,114,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,97,0,59,120,0,0,18,98,0,59,120,0,
-0,0,4,102,108,111,97,116,95,112,111,119,101,114,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,
-97,0,59,121,0,0,18,98,0,59,121,0,0,0,0,1,90,95,0,0,11,0,0,112,111,119,0,1,1,0,0,11,0,97,0,0,1,1,0,
-0,11,0,98,0,0,0,1,4,102,108,111,97,116,95,112,111,119,101,114,0,18,95,95,114,101,116,86,97,108,0,
-59,120,0,0,18,97,0,59,120,0,0,18,98,0,59,120,0,0,0,4,102,108,111,97,116,95,112,111,119,101,114,0,
-18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,97,0,59,121,0,0,18,98,0,59,121,0,0,0,4,102,108,111,
-97,116,95,112,111,119,101,114,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,97,0,59,122,0,0,18,
-98,0,59,122,0,0,0,0,1,90,95,0,0,12,0,0,112,111,119,0,1,1,0,0,12,0,97,0,0,1,1,0,0,12,0,98,0,0,0,1,4,
-102,108,111,97,116,95,112,111,119,101,114,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,97,0,59,
-120,0,0,18,98,0,59,120,0,0,0,4,102,108,111,97,116,95,112,111,119,101,114,0,18,95,95,114,101,116,86,
-97,108,0,59,121,0,0,18,97,0,59,121,0,0,18,98,0,59,121,0,0,0,4,102,108,111,97,116,95,112,111,119,
-101,114,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,97,0,59,122,0,0,18,98,0,59,122,0,0,0,4,
-102,108,111,97,116,95,112,111,119,101,114,0,18,95,95,114,101,116,86,97,108,0,59,119,0,0,18,97,0,59,
-119,0,0,18,98,0,59,119,0,0,0,0,1,90,95,0,0,9,0,0,101,120,112,0,1,1,0,0,9,0,97,0,0,0,1,3,2,90,95,0,
-0,9,0,1,116,0,2,18,97,0,17,49,0,52,52,50,54,57,53,48,50,0,0,48,0,0,4,102,108,111,97,116,95,101,120,
-112,50,0,18,95,95,114,101,116,86,97,108,0,0,18,116,0,0,0,0,1,90,95,0,0,10,0,0,101,120,112,0,1,1,0,
-0,10,0,97,0,0,0,1,3,2,90,95,0,0,10,0,1,116,0,2,18,97,0,17,49,0,52,52,50,54,57,53,48,50,0,0,48,0,0,
-4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,116,0,59,
-120,0,0,0,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,
-116,0,59,121,0,0,0,0,1,90,95,0,0,11,0,0,101,120,112,0,1,1,0,0,11,0,97,0,0,0,1,3,2,90,95,0,0,11,0,1,
-116,0,2,18,97,0,17,49,0,52,52,50,54,57,53,48,50,0,0,48,0,0,4,102,108,111,97,116,95,101,120,112,50,
-0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,116,0,59,120,0,0,0,4,102,108,111,97,116,95,101,
-120,112,50,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,116,0,59,121,0,0,0,4,102,108,111,97,
-116,95,101,120,112,50,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,116,0,59,122,0,0,0,0,1,90,
-95,0,0,12,0,0,101,120,112,0,1,1,0,0,12,0,97,0,0,0,1,3,2,90,95,0,0,12,0,1,116,0,2,18,97,0,17,49,0,
-52,52,50,54,57,53,48,50,0,0,48,0,0,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,
-86,97,108,0,59,120,0,0,18,116,0,59,120,0,0,0,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,
-101,116,86,97,108,0,59,121,0,0,18,116,0,59,121,0,0,0,4,102,108,111,97,116,95,101,120,112,50,0,18,
-95,95,114,101,116,86,97,108,0,59,122,0,0,18,116,0,59,122,0,0,0,4,102,108,111,97,116,95,101,120,112,
-50,0,18,95,95,114,101,116,86,97,108,0,59,119,0,0,18,116,0,59,119,0,0,0,0,1,90,95,0,0,9,0,0,108,111,
-103,50,0,1,1,0,0,9,0,120,0,0,0,1,4,102,108,111,97,116,95,108,111,103,50,0,18,95,95,114,101,116,86,
-97,108,0,0,18,120,0,0,0,0,1,90,95,0,0,10,0,0,108,111,103,50,0,1,1,0,0,10,0,118,0,0,0,1,4,102,108,
-111,97,116,95,108,111,103,50,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,118,0,59,120,0,0,0,4,
-102,108,111,97,116,95,108,111,103,50,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,118,0,59,121,
-0,0,0,0,1,90,95,0,0,11,0,0,108,111,103,50,0,1,1,0,0,11,0,118,0,0,0,1,4,102,108,111,97,116,95,108,
-111,103,50,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,118,0,59,120,0,0,0,4,102,108,111,97,
-116,95,108,111,103,50,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,118,0,59,121,0,0,0,4,102,
-108,111,97,116,95,108,111,103,50,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,118,0,59,122,0,0,
-0,0,1,90,95,0,0,12,0,0,108,111,103,50,0,1,1,0,0,12,0,118,0,0,0,1,4,102,108,111,97,116,95,108,111,
-103,50,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,118,0,59,120,0,0,0,4,102,108,111,97,116,95,
-108,111,103,50,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,118,0,59,121,0,0,0,4,102,108,111,
-97,116,95,108,111,103,50,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,118,0,59,122,0,0,0,4,102,
-108,111,97,116,95,108,111,103,50,0,18,95,95,114,101,116,86,97,108,0,59,119,0,0,18,118,0,59,119,0,0,
-0,0,1,90,95,0,0,9,0,0,108,111,103,0,1,1,0,0,9,0,120,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,48,0,54,
-57,51,49,52,55,49,56,49,0,0,0,0,8,58,108,111,103,50,0,0,18,120,0,0,0,18,99,0,48,0,0,1,90,95,0,0,10,
-0,0,108,111,103,0,1,1,0,0,10,0,118,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,48,0,54,57,51,49,52,55,49,
-56,49,0,0,0,0,8,58,108,111,103,50,0,0,18,118,0,0,0,18,99,0,48,0,0,1,90,95,0,0,11,0,0,108,111,103,0,
-1,1,0,0,11,0,118,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,48,0,54,57,51,49,52,55,49,56,49,0,0,0,0,8,
-58,108,111,103,50,0,0,18,118,0,0,0,18,99,0,48,0,0,1,90,95,0,0,12,0,0,108,111,103,0,1,1,0,0,12,0,
-118,0,0,0,1,3,2,90,95,1,0,9,0,1,99,0,2,17,48,0,54,57,51,49,52,55,49,56,49,0,0,0,0,8,58,108,111,103,
-50,0,0,18,118,0,0,0,18,99,0,48,0,0,1,90,95,0,0,9,0,0,101,120,112,50,0,1,1,0,0,9,0,97,0,0,0,1,4,102,
-108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,0,0,1,90,95,0,0,10,
-0,0,101,120,112,50,0,1,1,0,0,10,0,97,0,0,0,1,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,
-101,116,86,97,108,0,59,120,0,0,18,97,0,59,120,0,0,0,4,102,108,111,97,116,95,101,120,112,50,0,18,95,
-95,114,101,116,86,97,108,0,59,121,0,0,18,97,0,59,121,0,0,0,0,1,90,95,0,0,11,0,0,101,120,112,50,0,1,
-1,0,0,11,0,97,0,0,0,1,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,86,97,108,0,59,
-120,0,0,18,97,0,59,120,0,0,0,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,86,97,
-108,0,59,121,0,0,18,97,0,59,121,0,0,0,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,
-116,86,97,108,0,59,122,0,0,18,97,0,59,122,0,0,0,0,1,90,95,0,0,12,0,0,101,120,112,50,0,1,1,0,0,12,0,
-97,0,0,0,1,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,
-97,0,59,120,0,0,0,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,86,97,108,0,59,121,
-0,0,18,97,0,59,121,0,0,0,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,86,97,108,0,
-59,122,0,0,18,97,0,59,122,0,0,0,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,86,
-97,108,0,59,119,0,0,18,97,0,59,119,0,0,0,0,1,90,95,0,0,9,0,0,115,113,114,116,0,1,1,0,0,9,0,120,0,0,
-0,1,3,2,90,95,1,0,9,0,1,110,120,0,2,18,120,0,54,0,0,3,2,90,95,0,0,9,0,1,114,0,0,0,4,102,108,111,97,
-116,95,114,115,113,0,18,114,0,0,18,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,114,0,0,18,
-114,0,0,0,4,118,101,99,52,95,99,109,112,0,18,95,95,114,101,116,86,97,108,0,0,18,110,120,0,0,18,114,
-0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,10,0,0,115,113,114,116,0,1,1,0,0,10,0,120,0,0,0,1,3,2,90,95,1,
-0,10,0,1,110,120,0,2,18,120,0,54,0,1,1,122,101,114,111,0,2,58,118,101,99,50,0,0,17,48,0,48,0,0,0,0,
-0,0,3,2,90,95,0,0,10,0,1,114,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,114,0,59,120,0,0,18,
-120,0,59,120,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,114,0,59,121,0,0,18,120,0,59,121,0,0,0,
-4,102,108,111,97,116,95,114,99,112,0,18,114,0,59,120,0,0,18,114,0,59,120,0,0,0,4,102,108,111,97,
-116,95,114,99,112,0,18,114,0,59,121,0,0,18,114,0,59,121,0,0,0,4,118,101,99,52,95,99,109,112,0,18,
-95,95,114,101,116,86,97,108,0,0,18,110,120,0,0,18,114,0,0,18,122,101,114,111,0,0,0,0,1,90,95,0,0,
-11,0,0,115,113,114,116,0,1,1,0,0,11,0,120,0,0,0,1,3,2,90,95,1,0,11,0,1,110,120,0,2,18,120,0,54,0,1,
-1,122,101,114,111,0,2,58,118,101,99,51,0,0,17,48,0,48,0,0,0,0,0,0,3,2,90,95,0,0,11,0,1,114,0,0,0,4,
-102,108,111,97,116,95,114,115,113,0,18,114,0,59,120,0,0,18,120,0,59,120,0,0,0,4,102,108,111,97,116,
-95,114,115,113,0,18,114,0,59,121,0,0,18,120,0,59,121,0,0,0,4,102,108,111,97,116,95,114,115,113,0,
-18,114,0,59,122,0,0,18,120,0,59,122,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,114,0,59,120,0,0,
-18,114,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,114,0,59,121,0,0,18,114,0,59,121,0,0,
-0,4,102,108,111,97,116,95,114,99,112,0,18,114,0,59,122,0,0,18,114,0,59,122,0,0,0,4,118,101,99,52,
-95,99,109,112,0,18,95,95,114,101,116,86,97,108,0,0,18,110,120,0,0,18,114,0,0,18,122,101,114,111,0,
-0,0,0,1,90,95,0,0,12,0,0,115,113,114,116,0,1,1,0,0,12,0,120,0,0,0,1,3,2,90,95,1,0,12,0,1,110,120,0,
-2,18,120,0,54,0,1,1,122,101,114,111,0,2,58,118,101,99,52,0,0,17,48,0,48,0,0,0,0,0,0,3,2,90,95,0,0,
-12,0,1,114,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,114,0,59,120,0,0,18,120,0,59,120,0,0,0,4,
-102,108,111,97,116,95,114,115,113,0,18,114,0,59,121,0,0,18,120,0,59,121,0,0,0,4,102,108,111,97,116,
-95,114,115,113,0,18,114,0,59,122,0,0,18,120,0,59,122,0,0,0,4,102,108,111,97,116,95,114,115,113,0,
-18,114,0,59,119,0,0,18,120,0,59,119,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,114,0,59,120,0,0,
-18,114,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,114,0,59,121,0,0,18,114,0,59,121,0,0,
-0,4,102,108,111,97,116,95,114,99,112,0,18,114,0,59,122,0,0,18,114,0,59,122,0,0,0,4,102,108,111,97,
-116,95,114,99,112,0,18,114,0,59,119,0,0,18,114,0,59,119,0,0,0,4,118,101,99,52,95,99,109,112,0,18,
-95,95,114,101,116,86,97,108,0,0,18,110,120,0,0,18,114,0,0,18,122,101,114,111,0,0,0,0,1,90,95,0,0,9,
-0,0,105,110,118,101,114,115,101,115,113,114,116,0,1,1,0,0,9,0,120,0,0,0,1,4,102,108,111,97,116,95,
-114,115,113,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,120,0,0,0,0,1,90,95,0,0,10,0,0,105,
-110,118,101,114,115,101,115,113,114,116,0,1,1,0,0,10,0,118,0,0,0,1,4,102,108,111,97,116,95,114,115,
-113,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,118,0,59,120,0,0,0,4,102,108,111,97,116,95,
-114,115,113,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,118,0,59,121,0,0,0,0,1,90,95,0,0,11,0,
-0,105,110,118,101,114,115,101,115,113,114,116,0,1,1,0,0,11,0,118,0,0,0,1,4,102,108,111,97,116,95,
-114,115,113,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,118,0,59,120,0,0,0,4,102,108,111,97,
-116,95,114,115,113,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,118,0,59,121,0,0,0,4,102,108,
-111,97,116,95,114,115,113,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,118,0,59,122,0,0,0,0,1,
-90,95,0,0,12,0,0,105,110,118,101,114,115,101,115,113,114,116,0,1,1,0,0,12,0,118,0,0,0,1,4,102,108,
-111,97,116,95,114,115,113,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,118,0,59,120,0,0,0,4,
-102,108,111,97,116,95,114,115,113,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,118,0,59,121,0,
-0,0,4,102,108,111,97,116,95,114,115,113,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,118,0,59,
-122,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,95,95,114,101,116,86,97,108,0,59,119,0,0,18,118,
-0,59,119,0,0,0,0,1,90,95,0,0,9,0,0,110,111,114,109,97,108,105,122,101,0,1,1,0,0,9,0,120,0,0,0,1,9,
-18,95,95,114,101,116,86,97,108,0,17,49,0,48,0,0,20,0,0,1,90,95,0,0,10,0,0,110,111,114,109,97,108,
-105,122,101,0,1,1,0,0,10,0,118,0,0,0,1,3,2,90,95,1,0,9,0,1,115,0,2,58,105,110,118,101,114,115,101,
-115,113,114,116,0,0,58,100,111,116,0,0,18,118,0,0,18,118,0,0,0,0,0,0,0,4,118,101,99,52,95,109,117,
-108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,118,0,0,18,115,0,0,0,
-0,1,90,95,0,0,11,0,0,110,111,114,109,97,108,105,122,101,0,1,1,0,0,11,0,118,0,0,0,1,3,2,90,95,0,0,9,
-0,1,116,109,112,0,0,0,4,118,101,99,51,95,100,111,116,0,18,116,109,112,0,0,18,118,0,0,18,118,0,0,0,
-4,102,108,111,97,116,95,114,115,113,0,18,116,109,112,0,0,18,116,109,112,0,0,0,4,118,101,99,52,95,
-109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,0,
-18,116,109,112,0,0,0,0,1,90,95,0,0,12,0,0,110,111,114,109,97,108,105,122,101,0,1,1,0,0,12,0,118,0,
-0,0,1,3,2,90,95,0,0,9,0,1,116,109,112,0,0,0,4,118,101,99,52,95,100,111,116,0,18,116,109,112,0,0,18,
-118,0,0,18,118,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,116,109,112,0,0,18,116,109,112,0,0,0,
-4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,
-122,0,0,18,118,0,0,18,116,109,112,0,0,0,0,1,90,95,0,0,9,0,0,97,98,115,0,1,1,0,0,9,0,97,0,0,0,1,4,
-118,101,99,52,95,97,98,115,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,0,0,1,90,95,0,0,10,0,0,
-97,98,115,0,1,1,0,0,10,0,97,0,0,0,1,4,118,101,99,52,95,97,98,115,0,18,95,95,114,101,116,86,97,108,
-0,59,120,121,0,0,18,97,0,0,0,0,1,90,95,0,0,11,0,0,97,98,115,0,1,1,0,0,11,0,97,0,0,0,1,4,118,101,99,
-52,95,97,98,115,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,97,0,0,0,0,1,90,95,0,0,12,
-0,0,97,98,115,0,1,1,0,0,12,0,97,0,0,0,1,4,118,101,99,52,95,97,98,115,0,18,95,95,114,101,116,86,97,
-108,0,0,18,97,0,0,0,0,1,90,95,0,0,9,0,0,115,105,103,110,0,1,1,0,0,9,0,120,0,0,0,1,3,2,90,95,0,0,9,
-0,1,112,0,0,1,1,110,0,0,0,4,118,101,99,52,95,115,103,116,0,18,112,0,0,18,120,0,0,17,48,0,48,0,0,0,
-0,4,118,101,99,52,95,115,103,116,0,18,110,0,0,17,48,0,48,0,0,0,18,120,0,0,0,4,118,101,99,52,95,115,
-117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,0,18,112,0,0,18,110,0,0,0,0,1,90,95,0,
-0,10,0,0,115,105,103,110,0,1,1,0,0,10,0,118,0,0,0,1,3,2,90,95,0,0,10,0,1,112,0,0,1,1,110,0,0,0,4,
-118,101,99,52,95,115,103,116,0,18,112,0,59,120,121,0,0,18,118,0,0,17,48,0,48,0,0,0,0,4,118,101,99,
-52,95,115,103,116,0,18,110,0,59,120,121,0,0,17,48,0,48,0,0,0,18,118,0,0,0,4,118,101,99,52,95,115,
-117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,112,0,0,18,110,0,0,0,
-0,1,90,95,0,0,11,0,0,115,105,103,110,0,1,1,0,0,11,0,118,0,0,0,1,3,2,90,95,0,0,11,0,1,112,0,0,1,1,
-110,0,0,0,4,118,101,99,52,95,115,103,116,0,18,112,0,59,120,121,122,0,0,18,118,0,0,17,48,0,48,0,0,0,
-0,4,118,101,99,52,95,115,103,116,0,18,110,0,59,120,121,122,0,0,17,48,0,48,0,0,0,18,118,0,0,0,4,118,
-101,99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,
-112,0,0,18,110,0,0,0,0,1,90,95,0,0,12,0,0,115,105,103,110,0,1,1,0,0,12,0,118,0,0,0,1,3,2,90,95,0,0,
-12,0,1,112,0,0,1,1,110,0,0,0,4,118,101,99,52,95,115,103,116,0,18,112,0,0,18,118,0,0,17,48,0,48,0,0,
-0,0,4,118,101,99,52,95,115,103,116,0,18,110,0,0,17,48,0,48,0,0,0,18,118,0,0,0,4,118,101,99,52,95,
-115,117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,0,18,112,0,0,18,110,0,0,0,0,1,90,
-95,0,0,9,0,0,102,108,111,111,114,0,1,1,0,0,9,0,97,0,0,0,1,4,118,101,99,52,95,102,108,111,111,114,0,
-18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,0,0,1,90,95,0,0,10,0,0,102,108,111,111,114,0,1,1,0,0,
-10,0,97,0,0,0,1,4,118,101,99,52,95,102,108,111,111,114,0,18,95,95,114,101,116,86,97,108,0,59,120,
-121,0,0,18,97,0,0,0,0,1,90,95,0,0,11,0,0,102,108,111,111,114,0,1,1,0,0,11,0,97,0,0,0,1,4,118,101,
-99,52,95,102,108,111,111,114,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,97,0,0,0,0,1,
-90,95,0,0,12,0,0,102,108,111,111,114,0,1,1,0,0,12,0,97,0,0,0,1,4,118,101,99,52,95,102,108,111,111,
-114,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,0,0,1,90,95,0,0,9,0,0,99,101,105,108,0,1,1,0,0,
-9,0,97,0,0,0,1,3,2,90,95,0,0,9,0,1,98,0,2,18,97,0,54,0,0,4,118,101,99,52,95,102,108,111,111,114,0,
-18,98,0,0,18,98,0,0,0,9,18,95,95,114,101,116,86,97,108,0,18,98,0,54,20,0,0,1,90,95,0,0,10,0,0,99,
-101,105,108,0,1,1,0,0,10,0,97,0,0,0,1,3,2,90,95,0,0,10,0,1,98,0,2,18,97,0,54,0,0,4,118,101,99,52,
-95,102,108,111,111,114,0,18,98,0,0,18,98,0,0,0,9,18,95,95,114,101,116,86,97,108,0,59,120,121,0,18,
-98,0,54,20,0,0,1,90,95,0,0,11,0,0,99,101,105,108,0,1,1,0,0,11,0,97,0,0,0,1,3,2,90,95,0,0,11,0,1,98,
-0,2,18,97,0,54,0,0,4,118,101,99,52,95,102,108,111,111,114,0,18,98,0,0,18,98,0,0,0,9,18,95,95,114,
-101,116,86,97,108,0,59,120,121,122,0,18,98,0,54,20,0,0,1,90,95,0,0,12,0,0,99,101,105,108,0,1,1,0,0,
-12,0,97,0,0,0,1,3,2,90,95,0,0,12,0,1,98,0,2,18,97,0,54,0,0,4,118,101,99,52,95,102,108,111,111,114,
-0,18,98,0,0,18,98,0,0,0,9,18,95,95,114,101,116,86,97,108,0,18,98,0,54,20,0,0,1,90,95,0,0,9,0,0,102,
-114,97,99,116,0,1,1,0,0,9,0,97,0,0,0,1,4,118,101,99,52,95,102,114,97,99,0,18,95,95,114,101,116,86,
-97,108,0,0,18,97,0,0,0,0,1,90,95,0,0,10,0,0,102,114,97,99,116,0,1,1,0,0,10,0,97,0,0,0,1,4,118,101,
-99,52,95,102,114,97,99,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,97,0,0,0,0,1,90,95,0,0,
-11,0,0,102,114,97,99,116,0,1,1,0,0,11,0,97,0,0,0,1,4,118,101,99,52,95,102,114,97,99,0,18,95,95,114,
-101,116,86,97,108,0,59,120,121,122,0,0,18,97,0,0,0,0,1,90,95,0,0,12,0,0,102,114,97,99,116,0,1,1,0,
-0,12,0,97,0,0,0,1,4,118,101,99,52,95,102,114,97,99,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,
-0,0,1,90,95,0,0,9,0,0,109,111,100,0,1,1,0,0,9,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,3,2,90,95,0,0,9,0,1,
-111,110,101,79,118,101,114,66,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,
-114,66,0,0,18,98,0,0,0,9,18,95,95,114,101,116,86,97,108,0,18,97,0,18,98,0,58,102,108,111,111,114,0,
-0,18,97,0,18,111,110,101,79,118,101,114,66,0,48,0,0,48,47,20,0,0,1,90,95,0,0,10,0,0,109,111,100,0,
-1,1,0,0,10,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,3,2,90,95,0,0,9,0,1,111,110,101,79,118,101,114,66,0,0,0,
-4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,114,66,0,0,18,98,0,0,0,9,18,95,95,
-114,101,116,86,97,108,0,59,120,121,0,18,97,0,18,98,0,58,102,108,111,111,114,0,0,18,97,0,18,111,110,
-101,79,118,101,114,66,0,48,0,0,48,47,20,0,0,1,90,95,0,0,11,0,0,109,111,100,0,1,1,0,0,11,0,97,0,0,1,
-1,0,0,9,0,98,0,0,0,1,3,2,90,95,0,0,9,0,1,111,110,101,79,118,101,114,66,0,0,0,4,102,108,111,97,116,
-95,114,99,112,0,18,111,110,101,79,118,101,114,66,0,0,18,98,0,0,0,9,18,95,95,114,101,116,86,97,108,
-0,59,120,121,122,0,18,97,0,18,98,0,58,102,108,111,111,114,0,0,18,97,0,18,111,110,101,79,118,101,
-114,66,0,48,0,0,48,47,20,0,0,1,90,95,0,0,12,0,0,109,111,100,0,1,1,0,0,12,0,97,0,0,1,1,0,0,9,0,98,0,
-0,0,1,3,2,90,95,0,0,9,0,1,111,110,101,79,118,101,114,66,0,0,0,4,102,108,111,97,116,95,114,99,112,0,
-18,111,110,101,79,118,101,114,66,0,0,18,98,0,0,0,9,18,95,95,114,101,116,86,97,108,0,18,97,0,18,98,
-0,58,102,108,111,111,114,0,0,18,97,0,18,111,110,101,79,118,101,114,66,0,48,0,0,48,47,20,0,0,1,90,
-95,0,0,10,0,0,109,111,100,0,1,1,0,0,10,0,97,0,0,1,1,0,0,10,0,98,0,0,0,1,3,2,90,95,0,0,10,0,1,111,
-110,101,79,118,101,114,66,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,114,
-66,0,59,120,0,0,18,98,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,
-101,114,66,0,59,121,0,0,18,98,0,59,121,0,0,0,9,18,95,95,114,101,116,86,97,108,0,18,97,0,18,98,0,58,
-102,108,111,111,114,0,0,18,97,0,18,111,110,101,79,118,101,114,66,0,48,0,0,48,47,20,0,0,1,90,95,0,0,
-11,0,0,109,111,100,0,1,1,0,0,11,0,97,0,0,1,1,0,0,11,0,98,0,0,0,1,3,2,90,95,0,0,11,0,1,111,110,101,
-79,118,101,114,66,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,114,66,0,59,
-120,0,0,18,98,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,114,66,
-0,59,121,0,0,18,98,0,59,121,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,
-114,66,0,59,122,0,0,18,98,0,59,122,0,0,0,9,18,95,95,114,101,116,86,97,108,0,18,97,0,18,98,0,58,102,
-108,111,111,114,0,0,18,97,0,18,111,110,101,79,118,101,114,66,0,48,0,0,48,47,20,0,0,1,90,95,0,0,12,
-0,0,109,111,100,0,1,1,0,0,12,0,97,0,0,1,1,0,0,12,0,98,0,0,0,1,3,2,90,95,0,0,12,0,1,111,110,101,79,
-118,101,114,66,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,114,66,0,59,
-120,0,0,18,98,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,114,66,
-0,59,121,0,0,18,98,0,59,121,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,
-114,66,0,59,122,0,0,18,98,0,59,122,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,
-118,101,114,66,0,59,119,0,0,18,98,0,59,119,0,0,0,9,18,95,95,114,101,116,86,97,108,0,18,97,0,18,98,
-0,58,102,108,111,111,114,0,0,18,97,0,18,111,110,101,79,118,101,114,66,0,48,0,0,48,47,20,0,0,1,90,
-95,0,0,9,0,0,109,105,110,0,1,1,0,0,9,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,109,105,
-110,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,90,95,0,0,10,0,0,109,105,110,0,
-1,1,0,0,10,0,97,0,0,1,1,0,0,10,0,98,0,0,0,1,4,118,101,99,52,95,109,105,110,0,18,95,95,114,101,116,
-86,97,108,0,59,120,121,0,0,18,97,0,59,120,121,0,0,18,98,0,59,120,121,0,0,0,0,1,90,95,0,0,11,0,0,
-109,105,110,0,1,1,0,0,11,0,97,0,0,1,1,0,0,11,0,98,0,0,0,1,4,118,101,99,52,95,109,105,110,0,18,95,
-95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,97,0,59,120,121,122,0,0,18,98,0,59,120,121,122,0,
-0,0,0,1,90,95,0,0,12,0,0,109,105,110,0,1,1,0,0,12,0,97,0,0,1,1,0,0,12,0,98,0,0,0,1,4,118,101,99,52,
-95,109,105,110,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,90,95,0,0,10,0,0,109,
-105,110,0,1,1,0,0,10,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,109,105,110,0,18,95,95,114,
-101,116,86,97,108,0,0,18,97,0,59,120,121,0,0,18,98,0,0,0,0,1,90,95,0,0,11,0,0,109,105,110,0,1,1,0,
-0,11,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,109,105,110,0,18,95,95,114,101,116,86,97,
-108,0,0,18,97,0,59,120,121,122,0,0,18,98,0,0,0,0,1,90,95,0,0,12,0,0,109,105,110,0,1,1,0,0,12,0,97,
-0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,109,105,110,0,18,95,95,114,101,116,86,97,108,0,0,18,
-97,0,0,18,98,0,0,0,0,1,90,95,0,0,9,0,0,109,97,120,0,1,1,0,0,9,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,4,
-118,101,99,52,95,109,97,120,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,90,95,0,
-0,10,0,0,109,97,120,0,1,1,0,0,10,0,97,0,0,1,1,0,0,10,0,98,0,0,0,1,4,118,101,99,52,95,109,97,120,0,
-18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,97,0,59,120,121,0,0,18,98,0,59,120,121,0,0,0,0,
-1,90,95,0,0,11,0,0,109,97,120,0,1,1,0,0,11,0,97,0,0,1,1,0,0,11,0,98,0,0,0,1,4,118,101,99,52,95,109,
-97,120,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,97,0,59,120,121,122,0,0,18,98,0,59,
-120,121,122,0,0,0,0,1,90,95,0,0,12,0,0,109,97,120,0,1,1,0,0,12,0,97,0,0,1,1,0,0,12,0,98,0,0,0,1,4,
-118,101,99,52,95,109,97,120,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,90,95,0,
-0,10,0,0,109,97,120,0,1,1,0,0,10,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,109,97,120,0,
-18,95,95,114,101,116,86,97,108,0,0,18,97,0,59,120,121,0,0,18,98,0,0,0,0,1,90,95,0,0,11,0,0,109,97,
-120,0,1,1,0,0,11,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,109,97,120,0,18,95,95,114,101,
-116,86,97,108,0,0,18,97,0,59,120,121,122,0,0,18,98,0,0,0,0,1,90,95,0,0,12,0,0,109,97,120,0,1,1,0,0,
-12,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,109,97,120,0,18,95,95,114,101,116,86,97,108,
-0,0,18,97,0,0,18,98,0,0,0,0,1,90,95,0,0,9,0,0,99,108,97,109,112,0,1,1,0,0,9,0,118,97,108,0,0,1,1,0,
-0,9,0,109,105,110,86,97,108,0,0,1,1,0,0,9,0,109,97,120,86,97,108,0,0,0,1,4,118,101,99,52,95,99,108,
-97,109,112,0,18,95,95,114,101,116,86,97,108,0,0,18,118,97,108,0,0,18,109,105,110,86,97,108,0,0,18,
-109,97,120,86,97,108,0,0,0,0,1,90,95,0,0,10,0,0,99,108,97,109,112,0,1,1,0,0,10,0,118,97,108,0,0,1,
-1,0,0,9,0,109,105,110,86,97,108,0,0,1,1,0,0,9,0,109,97,120,86,97,108,0,0,0,1,4,118,101,99,52,95,99,
-108,97,109,112,0,18,95,95,114,101,116,86,97,108,0,0,18,118,97,108,0,0,18,109,105,110,86,97,108,0,0,
-18,109,97,120,86,97,108,0,0,0,0,1,90,95,0,0,11,0,0,99,108,97,109,112,0,1,1,0,0,11,0,118,97,108,0,0,
-1,1,0,0,9,0,109,105,110,86,97,108,0,0,1,1,0,0,9,0,109,97,120,86,97,108,0,0,0,1,4,118,101,99,52,95,
-99,108,97,109,112,0,18,95,95,114,101,116,86,97,108,0,0,18,118,97,108,0,0,18,109,105,110,86,97,108,
-0,0,18,109,97,120,86,97,108,0,0,0,0,1,90,95,0,0,12,0,0,99,108,97,109,112,0,1,1,0,0,12,0,118,97,108,
-0,0,1,1,0,0,9,0,109,105,110,86,97,108,0,0,1,1,0,0,9,0,109,97,120,86,97,108,0,0,0,1,4,118,101,99,52,
-95,99,108,97,109,112,0,18,95,95,114,101,116,86,97,108,0,0,18,118,97,108,0,0,18,109,105,110,86,97,
-108,0,0,18,109,97,120,86,97,108,0,0,0,0,1,90,95,0,0,10,0,0,99,108,97,109,112,0,1,1,0,0,10,0,118,97,
-108,0,0,1,1,0,0,10,0,109,105,110,86,97,108,0,0,1,1,0,0,10,0,109,97,120,86,97,108,0,0,0,1,4,118,101,
-99,52,95,99,108,97,109,112,0,18,95,95,114,101,116,86,97,108,0,0,18,118,97,108,0,0,18,109,105,110,
-86,97,108,0,0,18,109,97,120,86,97,108,0,0,0,0,1,90,95,0,0,11,0,0,99,108,97,109,112,0,1,1,0,0,11,0,
-118,97,108,0,0,1,1,0,0,11,0,109,105,110,86,97,108,0,0,1,1,0,0,11,0,109,97,120,86,97,108,0,0,0,1,4,
-118,101,99,52,95,99,108,97,109,112,0,18,95,95,114,101,116,86,97,108,0,0,18,118,97,108,0,0,18,109,
-105,110,86,97,108,0,0,18,109,97,120,86,97,108,0,0,0,0,1,90,95,0,0,12,0,0,99,108,97,109,112,0,1,1,0,
-0,12,0,118,97,108,0,0,1,1,0,0,12,0,109,105,110,86,97,108,0,0,1,1,0,0,12,0,109,97,120,86,97,108,0,0,
-0,1,4,118,101,99,52,95,99,108,97,109,112,0,18,95,95,114,101,116,86,97,108,0,0,18,118,97,108,0,0,18,
-109,105,110,86,97,108,0,0,18,109,97,120,86,97,108,0,0,0,0,1,90,95,0,0,9,0,0,109,105,120,0,1,1,0,0,
-9,0,120,0,0,1,1,0,0,9,0,121,0,0,1,1,0,0,9,0,97,0,0,0,1,4,118,101,99,52,95,108,114,112,0,18,95,95,
-114,101,116,86,97,108,0,0,18,97,0,0,18,121,0,0,18,120,0,0,0,0,1,90,95,0,0,10,0,0,109,105,120,0,1,1,
-0,0,10,0,120,0,0,1,1,0,0,10,0,121,0,0,1,1,0,0,9,0,97,0,0,0,1,4,118,101,99,52,95,108,114,112,0,18,
-95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,121,0,0,18,120,0,0,0,0,1,90,95,0,0,11,0,0,109,105,120,
-0,1,1,0,0,11,0,120,0,0,1,1,0,0,11,0,121,0,0,1,1,0,0,9,0,97,0,0,0,1,4,118,101,99,52,95,108,114,112,
-0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,121,0,0,18,120,0,0,0,0,1,90,95,0,0,12,0,0,109,
-105,120,0,1,1,0,0,12,0,120,0,0,1,1,0,0,12,0,121,0,0,1,1,0,0,9,0,97,0,0,0,1,4,118,101,99,52,95,108,
-114,112,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,121,0,0,18,120,0,0,0,0,1,90,95,0,0,10,0,
-0,109,105,120,0,1,1,0,0,10,0,120,0,0,1,1,0,0,10,0,121,0,0,1,1,0,0,10,0,97,0,0,0,1,4,118,101,99,52,
-95,108,114,112,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,121,0,0,18,120,0,0,0,0,1,90,95,0,
-0,11,0,0,109,105,120,0,1,1,0,0,11,0,120,0,0,1,1,0,0,11,0,121,0,0,1,1,0,0,11,0,97,0,0,0,1,4,118,101,
-99,52,95,108,114,112,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,121,0,0,18,120,0,0,0,0,1,90,
-95,0,0,12,0,0,109,105,120,0,1,1,0,0,12,0,120,0,0,1,1,0,0,12,0,121,0,0,1,1,0,0,12,0,97,0,0,0,1,4,
-118,101,99,52,95,108,114,112,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,121,0,0,18,120,0,0,
-0,0,1,90,95,0,0,9,0,0,115,116,101,112,0,1,1,0,0,9,0,101,100,103,101,0,0,1,1,0,0,9,0,120,0,0,0,1,4,
-118,101,99,52,95,115,103,101,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,18,101,100,103,101,0,
-0,0,0,1,90,95,0,0,10,0,0,115,116,101,112,0,1,1,0,0,10,0,101,100,103,101,0,0,1,1,0,0,10,0,120,0,0,0,
-1,4,118,101,99,52,95,115,103,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,120,0,0,18,
-101,100,103,101,0,0,0,0,1,90,95,0,0,11,0,0,115,116,101,112,0,1,1,0,0,11,0,101,100,103,101,0,0,1,1,
-0,0,11,0,120,0,0,0,1,4,118,101,99,52,95,115,103,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,
-122,0,0,18,120,0,0,18,101,100,103,101,0,0,0,0,1,90,95,0,0,12,0,0,115,116,101,112,0,1,1,0,0,12,0,
-101,100,103,101,0,0,1,1,0,0,12,0,120,0,0,0,1,4,118,101,99,52,95,115,103,101,0,18,95,95,114,101,116,
-86,97,108,0,0,18,120,0,0,18,101,100,103,101,0,0,0,0,1,90,95,0,0,10,0,0,115,116,101,112,0,1,1,0,0,9,
-0,101,100,103,101,0,0,1,1,0,0,10,0,118,0,0,0,1,4,118,101,99,52,95,115,103,101,0,18,95,95,114,101,
-116,86,97,108,0,59,120,121,0,0,18,118,0,0,18,101,100,103,101,0,0,0,0,1,90,95,0,0,11,0,0,115,116,
-101,112,0,1,1,0,0,9,0,101,100,103,101,0,0,1,1,0,0,11,0,118,0,0,0,1,4,118,101,99,52,95,115,103,101,
-0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,0,18,101,100,103,101,0,0,0,0,1,90,
-95,0,0,12,0,0,115,116,101,112,0,1,1,0,0,9,0,101,100,103,101,0,0,1,1,0,0,12,0,118,0,0,0,1,4,118,101,
-99,52,95,115,103,101,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,18,101,100,103,101,0,0,0,0,1,
-90,95,0,0,9,0,0,115,109,111,111,116,104,115,116,101,112,0,1,1,0,0,9,0,101,100,103,101,48,0,0,1,1,0,
-0,9,0,101,100,103,101,49,0,0,1,1,0,0,9,0,120,0,0,0,1,3,2,90,95,0,0,9,0,1,116,0,2,58,99,108,97,109,
-112,0,0,18,120,0,18,101,100,103,101,48,0,47,18,101,100,103,101,49,0,18,101,100,103,101,48,0,47,49,
-0,17,48,0,48,0,0,0,17,49,0,48,0,0,0,0,0,0,8,18,116,0,18,116,0,48,17,51,0,48,0,0,17,50,0,48,0,0,18,
-116,0,48,47,48,0,0,1,90,95,0,0,10,0,0,115,109,111,111,116,104,115,116,101,112,0,1,1,0,0,10,0,101,
-100,103,101,48,0,0,1,1,0,0,10,0,101,100,103,101,49,0,0,1,1,0,0,10,0,118,0,0,0,1,3,2,90,95,0,0,10,0,
-1,116,0,2,58,99,108,97,109,112,0,0,18,118,0,18,101,100,103,101,48,0,47,18,101,100,103,101,49,0,18,
-101,100,103,101,48,0,47,49,0,17,48,0,48,0,0,0,17,49,0,48,0,0,0,0,0,0,8,18,116,0,18,116,0,48,17,51,
-0,48,0,0,17,50,0,48,0,0,18,116,0,48,47,48,0,0,1,90,95,0,0,11,0,0,115,109,111,111,116,104,115,116,
-101,112,0,1,1,0,0,11,0,101,100,103,101,48,0,0,1,1,0,0,11,0,101,100,103,101,49,0,0,1,1,0,0,11,0,118,
-0,0,0,1,3,2,90,95,0,0,11,0,1,116,0,2,58,99,108,97,109,112,0,0,18,118,0,18,101,100,103,101,48,0,47,
-18,101,100,103,101,49,0,18,101,100,103,101,48,0,47,49,0,17,48,0,48,0,0,0,17,49,0,48,0,0,0,0,0,0,8,
-18,116,0,18,116,0,48,17,51,0,48,0,0,17,50,0,48,0,0,18,116,0,48,47,48,0,0,1,90,95,0,0,12,0,0,115,
-109,111,111,116,104,115,116,101,112,0,1,1,0,0,12,0,101,100,103,101,48,0,0,1,1,0,0,12,0,101,100,103,
-101,49,0,0,1,1,0,0,12,0,118,0,0,0,1,3,2,90,95,0,0,12,0,1,116,0,2,58,99,108,97,109,112,0,0,18,118,0,
-18,101,100,103,101,48,0,47,18,101,100,103,101,49,0,18,101,100,103,101,48,0,47,49,0,17,48,0,48,0,0,
-0,17,49,0,48,0,0,0,0,0,0,8,18,116,0,18,116,0,48,17,51,0,48,0,0,17,50,0,48,0,0,18,116,0,48,47,48,0,
-0,1,90,95,0,0,10,0,0,115,109,111,111,116,104,115,116,101,112,0,1,1,0,0,9,0,101,100,103,101,48,0,0,
-1,1,0,0,9,0,101,100,103,101,49,0,0,1,1,0,0,10,0,118,0,0,0,1,3,2,90,95,0,0,10,0,1,116,0,2,58,99,108,
-97,109,112,0,0,18,118,0,18,101,100,103,101,48,0,47,18,101,100,103,101,49,0,18,101,100,103,101,48,0,
-47,49,0,17,48,0,48,0,0,0,17,49,0,48,0,0,0,0,0,0,8,18,116,0,18,116,0,48,17,51,0,48,0,0,17,50,0,48,0,
-0,18,116,0,48,47,48,0,0,1,90,95,0,0,11,0,0,115,109,111,111,116,104,115,116,101,112,0,1,1,0,0,9,0,
-101,100,103,101,48,0,0,1,1,0,0,9,0,101,100,103,101,49,0,0,1,1,0,0,11,0,118,0,0,0,1,3,2,90,95,0,0,
-11,0,1,116,0,2,58,99,108,97,109,112,0,0,18,118,0,18,101,100,103,101,48,0,47,18,101,100,103,101,49,
-0,18,101,100,103,101,48,0,47,49,0,17,48,0,48,0,0,0,17,49,0,48,0,0,0,0,0,0,8,18,116,0,18,116,0,48,
-17,51,0,48,0,0,17,50,0,48,0,0,18,116,0,48,47,48,0,0,1,90,95,0,0,12,0,0,115,109,111,111,116,104,115,
-116,101,112,0,1,1,0,0,9,0,101,100,103,101,48,0,0,1,1,0,0,9,0,101,100,103,101,49,0,0,1,1,0,0,12,0,
-118,0,0,0,1,3,2,90,95,0,0,12,0,1,116,0,2,58,99,108,97,109,112,0,0,18,118,0,18,101,100,103,101,48,0,
-47,18,101,100,103,101,49,0,18,101,100,103,101,48,0,47,49,0,17,48,0,48,0,0,0,17,49,0,48,0,0,0,0,0,0,
-8,18,116,0,18,116,0,48,17,51,0,48,0,0,17,50,0,48,0,0,18,116,0,48,47,48,0,0,1,90,95,0,0,9,0,0,108,
-101,110,103,116,104,0,1,1,0,0,9,0,120,0,0,0,1,8,58,97,98,115,0,0,18,120,0,0,0,0,0,1,90,95,0,0,9,0,
-0,108,101,110,103,116,104,0,1,1,0,0,10,0,118,0,0,0,1,3,2,90,95,0,0,9,0,1,114,0,0,0,3,2,90,95,1,0,9,
-0,1,112,0,2,58,100,111,116,0,0,18,118,0,0,18,118,0,0,0,0,0,4,102,108,111,97,116,95,114,115,113,0,
-18,114,0,0,18,112,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,95,95,114,101,116,86,97,108,0,59,
-120,0,0,18,114,0,0,0,0,1,90,95,0,0,9,0,0,108,101,110,103,116,104,0,1,1,0,0,11,0,118,0,0,0,1,3,2,90,
-95,0,0,9,0,1,114,0,0,0,3,2,90,95,1,0,9,0,1,112,0,2,58,100,111,116,0,0,18,118,0,0,18,118,0,0,0,0,0,
-4,102,108,111,97,116,95,114,115,113,0,18,114,0,0,18,112,0,0,0,4,102,108,111,97,116,95,114,99,112,0,
-18,95,95,114,101,116,86,97,108,0,0,18,114,0,0,0,0,1,90,95,0,0,9,0,0,108,101,110,103,116,104,0,1,1,
-0,0,12,0,118,0,0,0,1,3,2,90,95,0,0,9,0,1,114,0,0,0,3,2,90,95,1,0,9,0,1,112,0,2,58,100,111,116,0,0,
-18,118,0,0,18,118,0,0,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,114,0,0,18,112,0,0,0,4,102,
-108,111,97,116,95,114,99,112,0,18,95,95,114,101,116,86,97,108,0,0,18,114,0,0,0,0,1,90,95,0,0,9,0,0,
-100,105,115,116,97,110,99,101,0,1,1,0,0,9,0,120,0,0,1,1,0,0,9,0,121,0,0,0,1,3,2,90,95,1,0,9,0,1,
-100,0,2,18,120,0,18,121,0,47,0,0,9,18,95,95,114,101,116,86,97,108,0,58,108,101,110,103,116,104,0,0,
-18,100,0,0,0,20,0,0,1,90,95,0,0,9,0,0,100,105,115,116,97,110,99,101,0,1,1,0,0,10,0,118,0,0,1,1,0,0,
-10,0,117,0,0,0,1,3,2,90,95,1,0,10,0,1,100,50,0,2,18,118,0,18,117,0,47,0,0,9,18,95,95,114,101,116,
-86,97,108,0,58,108,101,110,103,116,104,0,0,18,100,50,0,0,0,20,0,0,1,90,95,0,0,9,0,0,100,105,115,
-116,97,110,99,101,0,1,1,0,0,11,0,118,0,0,1,1,0,0,11,0,117,0,0,0,1,3,2,90,95,1,0,11,0,1,100,51,0,2,
-18,118,0,18,117,0,47,0,0,9,18,95,95,114,101,116,86,97,108,0,58,108,101,110,103,116,104,0,0,18,100,
-51,0,0,0,20,0,0,1,90,95,0,0,9,0,0,100,105,115,116,97,110,99,101,0,1,1,0,0,12,0,118,0,0,1,1,0,0,12,
-0,117,0,0,0,1,3,2,90,95,1,0,12,0,1,100,52,0,2,18,118,0,18,117,0,47,0,0,9,18,95,95,114,101,116,86,
-97,108,0,58,108,101,110,103,116,104,0,0,18,100,52,0,0,0,20,0,0,1,90,95,0,0,11,0,0,99,114,111,115,
-115,0,1,1,0,0,11,0,118,0,0,1,1,0,0,11,0,117,0,0,0,1,4,118,101,99,51,95,99,114,111,115,115,0,18,95,
-95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,0,18,117,0,0,0,0,1,90,95,0,0,9,0,0,102,97,
-99,101,102,111,114,119,97,114,100,0,1,1,0,0,9,0,78,0,0,1,1,0,0,9,0,73,0,0,1,1,0,0,9,0,78,114,101,
-102,0,0,0,1,3,2,90,95,1,0,9,0,1,100,0,2,58,100,111,116,0,0,18,78,114,101,102,0,0,18,73,0,0,0,0,0,3,
-2,90,95,0,0,9,0,1,115,0,0,0,4,118,101,99,52,95,115,103,116,0,18,115,0,0,17,48,0,48,0,0,0,18,100,0,
-0,0,8,58,109,105,120,0,0,18,78,0,54,0,18,78,0,0,18,115,0,0,0,0,0,1,90,95,0,0,10,0,0,102,97,99,101,
-102,111,114,119,97,114,100,0,1,1,0,0,10,0,78,0,0,1,1,0,0,10,0,73,0,0,1,1,0,0,10,0,78,114,101,102,0,
-0,0,1,3,2,90,95,1,0,9,0,1,100,0,2,58,100,111,116,0,0,18,78,114,101,102,0,0,18,73,0,0,0,0,0,3,2,90,
-95,0,0,9,0,1,115,0,0,0,4,118,101,99,52,95,115,103,116,0,18,115,0,0,17,48,0,48,0,0,0,18,100,0,0,0,8,
-58,109,105,120,0,0,18,78,0,54,0,18,78,0,0,18,115,0,0,0,0,0,1,90,95,0,0,11,0,0,102,97,99,101,102,
-111,114,119,97,114,100,0,1,1,0,0,11,0,78,0,0,1,1,0,0,11,0,73,0,0,1,1,0,0,11,0,78,114,101,102,0,0,0,
-1,3,2,90,95,1,0,9,0,1,100,0,2,58,100,111,116,0,0,18,78,114,101,102,0,0,18,73,0,0,0,0,0,3,2,90,95,0,
-0,9,0,1,115,0,0,0,4,118,101,99,52,95,115,103,116,0,18,115,0,0,17,48,0,48,0,0,0,18,100,0,0,0,8,58,
-109,105,120,0,0,18,78,0,54,0,18,78,0,0,18,115,0,0,0,0,0,1,90,95,0,0,12,0,0,102,97,99,101,102,111,
-114,119,97,114,100,0,1,1,0,0,12,0,78,0,0,1,1,0,0,12,0,73,0,0,1,1,0,0,12,0,78,114,101,102,0,0,0,1,3,
-2,90,95,1,0,9,0,1,100,0,2,58,100,111,116,0,0,18,78,114,101,102,0,0,18,73,0,0,0,0,0,3,2,90,95,0,0,9,
-0,1,115,0,0,0,4,118,101,99,52,95,115,103,116,0,18,115,0,0,17,48,0,48,0,0,0,18,100,0,0,0,8,58,109,
-105,120,0,0,18,78,0,54,0,18,78,0,0,18,115,0,0,0,0,0,1,90,95,0,0,9,0,0,114,101,102,108,101,99,116,0,
-1,1,0,0,9,0,73,0,0,1,1,0,0,9,0,78,0,0,0,1,8,18,73,0,17,50,0,48,0,0,58,100,111,116,0,0,18,78,0,0,18,
-73,0,0,0,48,18,78,0,48,47,0,0,1,90,95,0,0,10,0,0,114,101,102,108,101,99,116,0,1,1,0,0,10,0,73,0,0,
-1,1,0,0,10,0,78,0,0,0,1,8,18,73,0,17,50,0,48,0,0,58,100,111,116,0,0,18,78,0,0,18,73,0,0,0,48,18,78,
-0,48,47,0,0,1,90,95,0,0,11,0,0,114,101,102,108,101,99,116,0,1,1,0,0,11,0,73,0,0,1,1,0,0,11,0,78,0,
-0,0,1,8,18,73,0,17,50,0,48,0,0,58,100,111,116,0,0,18,78,0,0,18,73,0,0,0,48,18,78,0,48,47,0,0,1,90,
-95,0,0,12,0,0,114,101,102,108,101,99,116,0,1,1,0,0,12,0,73,0,0,1,1,0,0,12,0,78,0,0,0,1,8,18,73,0,
-17,50,0,48,0,0,58,100,111,116,0,0,18,78,0,0,18,73,0,0,0,48,18,78,0,48,47,0,0,1,90,95,0,0,9,0,0,114,
-101,102,114,97,99,116,0,1,1,0,0,9,0,73,0,0,1,1,0,0,9,0,78,0,0,1,1,0,0,9,0,101,116,97,0,0,0,1,3,2,
-90,95,0,0,9,0,1,110,95,100,111,116,95,105,0,2,58,100,111,116,0,0,18,78,0,0,18,73,0,0,0,0,0,3,2,90,
-95,0,0,9,0,1,107,0,2,17,49,0,48,0,0,18,101,116,97,0,18,101,116,97,0,48,17,49,0,48,0,0,18,110,95,
-100,111,116,95,105,0,18,110,95,100,111,116,95,105,0,48,47,48,47,0,0,3,2,90,95,0,0,9,0,1,114,101,
-116,118,97,108,0,0,0,10,18,107,0,17,48,0,48,0,0,40,0,9,18,114,101,116,118,97,108,0,17,48,0,48,0,0,
-20,0,9,18,114,101,116,118,97,108,0,18,101,116,97,0,18,73,0,48,18,101,116,97,0,18,110,95,100,111,
-116,95,105,0,48,58,115,113,114,116,0,0,18,107,0,0,0,46,18,78,0,48,47,20,0,8,18,114,101,116,118,97,
-108,0,0,0,1,90,95,0,0,10,0,0,114,101,102,114,97,99,116,0,1,1,0,0,10,0,73,0,0,1,1,0,0,10,0,78,0,0,1,
-1,0,0,9,0,101,116,97,0,0,0,1,3,2,90,95,0,0,9,0,1,110,95,100,111,116,95,105,0,2,58,100,111,116,0,0,
-18,78,0,0,18,73,0,0,0,0,0,3,2,90,95,0,0,9,0,1,107,0,2,17,49,0,48,0,0,18,101,116,97,0,18,101,116,97,
-0,48,17,49,0,48,0,0,18,110,95,100,111,116,95,105,0,18,110,95,100,111,116,95,105,0,48,47,48,47,0,0,
-3,2,90,95,0,0,10,0,1,114,101,116,118,97,108,0,0,0,10,18,107,0,17,48,0,48,0,0,40,0,9,18,114,101,116,
-118,97,108,0,58,118,101,99,50,0,0,17,48,0,48,0,0,0,0,20,0,9,18,114,101,116,118,97,108,0,18,101,116,
-97,0,18,73,0,48,18,101,116,97,0,18,110,95,100,111,116,95,105,0,48,58,115,113,114,116,0,0,18,107,0,
-0,0,46,18,78,0,48,47,20,0,8,18,114,101,116,118,97,108,0,0,0,1,90,95,0,0,11,0,0,114,101,102,114,97,
-99,116,0,1,1,0,0,11,0,73,0,0,1,1,0,0,11,0,78,0,0,1,1,0,0,9,0,101,116,97,0,0,0,1,3,2,90,95,0,0,9,0,
-1,110,95,100,111,116,95,105,0,2,58,100,111,116,0,0,18,78,0,0,18,73,0,0,0,0,0,3,2,90,95,0,0,9,0,1,
-107,0,2,17,49,0,48,0,0,18,101,116,97,0,18,101,116,97,0,48,17,49,0,48,0,0,18,110,95,100,111,116,95,
-105,0,18,110,95,100,111,116,95,105,0,48,47,48,47,0,0,3,2,90,95,0,0,11,0,1,114,101,116,118,97,108,0,
-0,0,10,18,107,0,17,48,0,48,0,0,40,0,9,18,114,101,116,118,97,108,0,58,118,101,99,51,0,0,17,48,0,48,
-0,0,0,0,20,0,9,18,114,101,116,118,97,108,0,18,101,116,97,0,18,73,0,48,18,101,116,97,0,18,110,95,
-100,111,116,95,105,0,48,58,115,113,114,116,0,0,18,107,0,0,0,46,18,78,0,48,47,20,0,8,18,114,101,116,
-118,97,108,0,0,0,1,90,95,0,0,12,0,0,114,101,102,114,97,99,116,0,1,1,0,0,12,0,73,0,0,1,1,0,0,12,0,
-78,0,0,1,1,0,0,9,0,101,116,97,0,0,0,1,3,2,90,95,0,0,9,0,1,110,95,100,111,116,95,105,0,2,58,100,111,
-116,0,0,18,78,0,0,18,73,0,0,0,0,0,3,2,90,95,0,0,9,0,1,107,0,2,17,49,0,48,0,0,18,101,116,97,0,18,
-101,116,97,0,48,17,49,0,48,0,0,18,110,95,100,111,116,95,105,0,18,110,95,100,111,116,95,105,0,48,47,
-48,47,0,0,3,2,90,95,0,0,12,0,1,114,101,116,118,97,108,0,0,0,10,18,107,0,17,48,0,48,0,0,40,0,9,18,
-114,101,116,118,97,108,0,58,118,101,99,52,0,0,17,48,0,48,0,0,0,0,20,0,9,18,114,101,116,118,97,108,
-0,18,101,116,97,0,18,73,0,48,18,101,116,97,0,18,110,95,100,111,116,95,105,0,48,58,115,113,114,116,
-0,0,18,107,0,0,0,46,18,78,0,48,47,20,0,8,18,114,101,116,118,97,108,0,0,0,1,90,95,0,0,13,0,0,109,97,
-116,114,105,120,67,111,109,112,77,117,108,116,0,1,0,0,0,13,0,109,0,0,1,0,0,0,13,0,110,0,0,0,1,8,58,
-109,97,116,50,0,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,
-16,10,49,0,57,48,0,0,0,0,1,90,95,0,0,14,0,0,109,97,116,114,105,120,67,111,109,112,77,117,108,116,0,
-1,0,0,0,14,0,109,0,0,1,0,0,0,14,0,110,0,0,0,1,8,58,109,97,116,51,0,0,18,109,0,16,8,48,0,57,18,110,
-0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,48,0,18,109,0,16,10,50,0,57,18,
-110,0,16,10,50,0,57,48,0,0,0,0,1,90,95,0,0,15,0,0,109,97,116,114,105,120,67,111,109,112,77,117,108,
-116,0,1,0,0,0,15,0,109,0,0,1,0,0,0,15,0,110,0,0,0,1,8,58,109,97,116,52,0,0,18,109,0,16,8,48,0,57,
-18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,48,0,18,109,0,16,10,50,0,
-57,18,110,0,16,10,50,0,57,48,0,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,48,0,0,0,0,1,90,95,0,
-0,2,0,0,108,101,115,115,84,104,97,110,0,1,1,0,0,10,0,117,0,0,1,1,0,0,10,0,118,0,0,0,1,4,118,101,99,
-52,95,115,108,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,117,0,0,18,118,0,0,0,0,1,90,
-95,0,0,3,0,0,108,101,115,115,84,104,97,110,0,1,1,0,0,11,0,117,0,0,1,1,0,0,11,0,118,0,0,0,1,4,118,
-101,99,52,95,115,108,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,117,0,0,18,118,0,
-0,0,0,1,90,95,0,0,4,0,0,108,101,115,115,84,104,97,110,0,1,1,0,0,12,0,117,0,0,1,1,0,0,12,0,118,0,0,
-0,1,4,118,101,99,52,95,115,108,116,0,18,95,95,114,101,116,86,97,108,0,0,18,117,0,0,18,118,0,0,0,0,
-1,90,95,0,0,2,0,0,108,101,115,115,84,104,97,110,0,1,1,0,0,6,0,117,0,0,1,1,0,0,6,0,118,0,0,0,1,4,
-118,101,99,52,95,115,108,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,117,0,0,18,118,0,
-0,0,0,1,90,95,0,0,3,0,0,108,101,115,115,84,104,97,110,0,1,1,0,0,7,0,117,0,0,1,1,0,0,7,0,118,0,0,0,
-1,4,118,101,99,52,95,115,108,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,117,0,0,
-18,118,0,0,0,0,1,90,95,0,0,4,0,0,108,101,115,115,84,104,97,110,0,1,1,0,0,8,0,117,0,0,1,1,0,0,8,0,
-118,0,0,0,1,4,118,101,99,52,95,115,108,116,0,18,95,95,114,101,116,86,97,108,0,0,18,117,0,0,18,118,
-0,0,0,0,1,90,95,0,0,2,0,0,108,101,115,115,84,104,97,110,69,113,117,97,108,0,1,1,0,0,10,0,117,0,0,1,
-1,0,0,10,0,118,0,0,0,1,4,118,101,99,52,95,115,108,101,0,18,95,95,114,101,116,86,97,108,0,59,120,
-121,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,3,0,0,108,101,115,115,84,104,97,110,69,113,117,97,
-108,0,1,1,0,0,11,0,117,0,0,1,1,0,0,11,0,118,0,0,0,1,4,118,101,99,52,95,115,108,101,0,18,95,95,114,
-101,116,86,97,108,0,59,120,121,122,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,4,0,0,108,101,115,115,
-84,104,97,110,69,113,117,97,108,0,1,1,0,0,12,0,117,0,0,1,1,0,0,12,0,118,0,0,0,1,4,118,101,99,52,95,
-115,108,101,0,18,95,95,114,101,116,86,97,108,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,2,0,0,108,
-101,115,115,84,104,97,110,69,113,117,97,108,0,1,1,0,0,6,0,117,0,0,1,1,0,0,6,0,118,0,0,0,1,4,118,
-101,99,52,95,115,108,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,117,0,0,18,118,0,0,0,
-0,1,90,95,0,0,3,0,0,108,101,115,115,84,104,97,110,69,113,117,97,108,0,1,1,0,0,7,0,117,0,0,1,1,0,0,
-7,0,118,0,0,0,1,4,118,101,99,52,95,115,108,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,
-0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,4,0,0,108,101,115,115,84,104,97,110,69,113,117,97,108,0,1,
-1,0,0,8,0,117,0,0,1,1,0,0,8,0,118,0,0,0,1,4,118,101,99,52,95,115,108,101,0,18,95,95,114,101,116,86,
-97,108,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,2,0,0,103,114,101,97,116,101,114,84,104,97,110,0,
-1,1,0,0,10,0,117,0,0,1,1,0,0,10,0,118,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,
-116,86,97,108,0,59,120,121,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,3,0,0,103,114,101,97,116,101,
-114,84,104,97,110,0,1,1,0,0,11,0,117,0,0,1,1,0,0,11,0,118,0,0,0,1,4,118,101,99,52,95,115,103,116,0,
-18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,4,0,0,
-103,114,101,97,116,101,114,84,104,97,110,0,1,1,0,0,12,0,117,0,0,1,1,0,0,12,0,118,0,0,0,1,4,118,101,
-99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,108,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,2,
-0,0,103,114,101,97,116,101,114,84,104,97,110,0,1,1,0,0,6,0,117,0,0,1,1,0,0,6,0,118,0,0,0,1,4,118,
-101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,117,0,59,120,121,0,0,
-18,118,0,59,120,121,0,0,0,0,1,90,95,0,0,3,0,0,103,114,101,97,116,101,114,84,104,97,110,0,1,1,0,0,7,
-0,117,0,0,1,1,0,0,7,0,118,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,108,
-0,59,120,121,122,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,4,0,0,103,114,101,97,116,101,114,84,104,
-97,110,0,1,1,0,0,8,0,117,0,0,1,1,0,0,8,0,118,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,
-101,116,86,97,108,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,2,0,0,103,114,101,97,116,101,114,84,
-104,97,110,69,113,117,97,108,0,1,1,0,0,10,0,117,0,0,1,1,0,0,10,0,118,0,0,0,1,4,118,101,99,52,95,
-115,103,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,
-0,3,0,0,103,114,101,97,116,101,114,84,104,97,110,69,113,117,97,108,0,1,1,0,0,11,0,117,0,0,1,1,0,0,
-11,0,118,0,0,0,1,4,118,101,99,52,95,115,103,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,
-0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,4,0,0,103,114,101,97,116,101,114,84,104,97,110,69,113,
-117,97,108,0,1,1,0,0,12,0,117,0,0,1,1,0,0,12,0,118,0,0,0,1,4,118,101,99,52,95,115,103,101,0,18,95,
-95,114,101,116,86,97,108,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,2,0,0,103,114,101,97,116,101,
-114,84,104,97,110,69,113,117,97,108,0,1,1,0,0,6,0,117,0,0,1,1,0,0,6,0,118,0,0,0,1,4,118,101,99,52,
-95,115,103,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,
-0,0,3,0,0,103,114,101,97,116,101,114,84,104,97,110,69,113,117,97,108,0,1,1,0,0,7,0,117,0,0,1,1,0,0,
-7,0,118,0,0,0,1,4,118,101,99,52,95,115,103,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,
-0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,4,0,0,103,114,101,97,116,101,114,84,104,97,110,69,113,117,
-97,108,0,1,1,0,0,8,0,117,0,0,1,1,0,0,8,0,118,0,0,0,1,4,118,101,99,52,95,115,103,101,0,18,95,95,114,
-101,116,86,97,108,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,2,0,0,101,113,117,97,108,0,1,1,0,0,10,
-0,117,0,0,1,1,0,0,10,0,118,0,0,0,1,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,
-0,59,120,121,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,3,0,0,101,113,117,97,108,0,1,1,0,0,11,0,117,
-0,0,1,1,0,0,11,0,118,0,0,0,1,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,59,
-120,121,122,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,4,0,0,101,113,117,97,108,0,1,1,0,0,12,0,117,
-0,0,1,1,0,0,12,0,118,0,0,0,1,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,0,
-18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,2,0,0,101,113,117,97,108,0,1,1,0,0,6,0,117,0,0,1,1,0,0,6,0,
-118,0,0,0,1,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,
-117,0,0,18,118,0,0,0,0,1,90,95,0,0,3,0,0,101,113,117,97,108,0,1,1,0,0,7,0,117,0,0,1,1,0,0,7,0,118,
-0,0,0,1,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,
-117,0,0,18,118,0,0,0,0,1,90,95,0,0,4,0,0,101,113,117,97,108,0,1,1,0,0,8,0,117,0,0,1,1,0,0,8,0,118,
-0,0,0,1,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,0,18,117,0,0,18,118,0,0,
-0,0,1,90,95,0,0,2,0,0,101,113,117,97,108,0,1,1,0,0,2,0,117,0,0,1,1,0,0,2,0,118,0,0,0,1,4,118,101,
-99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,117,0,0,18,118,0,0,0,0,1,
-90,95,0,0,3,0,0,101,113,117,97,108,0,1,1,0,0,3,0,117,0,0,1,1,0,0,3,0,118,0,0,0,1,4,118,101,99,52,
-95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,117,0,0,18,118,0,0,0,0,1,
-90,95,0,0,4,0,0,101,113,117,97,108,0,1,1,0,0,4,0,117,0,0,1,1,0,0,4,0,118,0,0,0,1,4,118,101,99,52,
-95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,0,2,0,0,
-110,111,116,69,113,117,97,108,0,1,1,0,0,10,0,117,0,0,1,1,0,0,10,0,118,0,0,0,1,4,118,101,99,52,95,
-115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,117,0,0,18,118,0,0,0,0,1,90,95,0,
-0,3,0,0,110,111,116,69,113,117,97,108,0,1,1,0,0,11,0,117,0,0,1,1,0,0,11,0,118,0,0,0,1,4,118,101,99,
-52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,117,0,0,18,118,0,0,0,0,
-1,90,95,0,0,4,0,0,110,111,116,69,113,117,97,108,0,1,1,0,0,12,0,117,0,0,1,1,0,0,12,0,118,0,0,0,1,4,
-118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,0,18,117,0,0,18,118,0,0,0,0,1,90,
-95,0,0,2,0,0,110,111,116,69,113,117,97,108,0,1,1,0,0,6,0,117,0,0,1,1,0,0,6,0,118,0,0,0,1,4,118,101,
-99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,117,0,0,18,118,0,0,0,0,1,
-90,95,0,0,3,0,0,110,111,116,69,113,117,97,108,0,1,1,0,0,7,0,117,0,0,1,1,0,0,7,0,118,0,0,0,1,4,118,
-101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,117,0,0,18,118,0,
-0,0,0,1,90,95,0,0,4,0,0,110,111,116,69,113,117,97,108,0,1,1,0,0,8,0,117,0,0,1,1,0,0,8,0,118,0,0,0,
-1,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,0,18,117,0,0,18,118,0,0,0,0,1,
-90,95,0,0,2,0,0,110,111,116,69,113,117,97,108,0,1,1,0,0,2,0,117,0,0,1,1,0,0,2,0,118,0,0,0,1,4,118,
-101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,117,0,0,18,118,0,0,0,
-0,1,90,95,0,0,3,0,0,110,111,116,69,113,117,97,108,0,1,1,0,0,3,0,117,0,0,1,1,0,0,3,0,118,0,0,0,1,4,
-118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,117,0,0,18,
-118,0,0,0,0,1,90,95,0,0,4,0,0,110,111,116,69,113,117,97,108,0,1,1,0,0,4,0,117,0,0,1,1,0,0,4,0,118,
-0,0,0,1,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,0,18,117,0,0,18,118,0,0,
-0,0,1,90,95,0,0,1,0,0,97,110,121,0,1,1,0,0,2,0,118,0,0,0,1,3,2,90,95,0,0,9,0,1,115,117,109,0,0,0,4,
-118,101,99,52,95,97,100,100,0,18,115,117,109,0,59,120,0,0,18,118,0,59,120,0,0,18,118,0,59,121,0,0,
-0,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,115,117,109,0,59,
-120,0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,1,0,0,97,110,121,0,1,1,0,0,3,0,118,0,0,0,1,3,2,90,95,0,0,
-9,0,1,115,117,109,0,0,0,4,118,101,99,52,95,97,100,100,0,18,115,117,109,0,59,120,0,0,18,118,0,59,
-120,0,0,18,118,0,59,121,0,0,0,4,118,101,99,52,95,97,100,100,0,18,115,117,109,0,59,120,0,0,18,115,
-117,109,0,59,120,0,0,18,118,0,59,122,0,0,0,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,
-86,97,108,0,59,120,0,0,18,115,117,109,0,59,120,0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,1,0,0,97,110,
-121,0,1,1,0,0,4,0,118,0,0,0,1,3,2,90,95,0,0,9,0,1,115,117,109,0,0,0,4,118,101,99,52,95,97,100,100,
-0,18,115,117,109,0,59,120,0,0,18,118,0,59,120,0,0,18,118,0,59,121,0,0,0,4,118,101,99,52,95,97,100,
-100,0,18,115,117,109,0,59,120,0,0,18,115,117,109,0,59,120,0,0,18,118,0,59,122,0,0,0,4,118,101,99,
-52,95,97,100,100,0,18,115,117,109,0,59,120,0,0,18,115,117,109,0,59,120,0,0,18,118,0,59,119,0,0,0,4,
-118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,115,117,109,0,59,120,
-0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,1,0,0,97,108,108,0,1,1,0,0,2,0,118,0,0,0,1,3,2,90,95,0,0,9,0,
-1,112,114,111,100,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,112,114,111,100,0,
-0,18,118,0,59,120,0,0,18,118,0,59,121,0,0,0,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,
-86,97,108,0,0,18,112,114,111,100,0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,1,0,0,97,108,108,0,1,1,0,0,3,
-0,118,0,0,0,1,3,2,90,95,0,0,9,0,1,112,114,111,100,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,
-108,121,0,18,112,114,111,100,0,0,18,118,0,59,120,0,0,18,118,0,59,121,0,0,0,4,118,101,99,52,95,109,
-117,108,116,105,112,108,121,0,18,112,114,111,100,0,0,18,112,114,111,100,0,0,18,118,0,59,122,0,0,0,
-4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,0,18,112,114,111,100,0,0,17,48,0,
-48,0,0,0,0,0,1,90,95,0,0,1,0,0,97,108,108,0,1,1,0,0,4,0,118,0,0,0,1,3,2,90,95,0,0,9,0,1,112,114,
-111,100,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,112,114,111,100,0,0,18,118,0,
-59,120,0,0,18,118,0,59,121,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,112,114,
-111,100,0,0,18,112,114,111,100,0,0,18,118,0,59,122,0,0,0,4,118,101,99,52,95,109,117,108,116,105,
-112,108,121,0,18,112,114,111,100,0,0,18,112,114,111,100,0,0,18,118,0,59,119,0,0,0,4,118,101,99,52,
-95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,0,18,112,114,111,100,0,0,17,48,0,48,0,0,0,0,0,1,
-90,95,0,0,2,0,0,110,111,116,0,1,1,0,0,2,0,118,0,0,0,1,4,118,101,99,52,95,115,101,113,0,18,95,95,
-114,101,116,86,97,108,0,59,120,121,0,0,18,118,0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,3,0,0,110,111,
-116,0,1,1,0,0,3,0,118,0,0,0,1,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,59,
-120,121,122,0,0,18,118,0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,4,0,0,110,111,116,0,1,1,0,0,4,0,118,0,
-0,0,1,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,17,48,0,48,0,
-0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,49,68,0,1,1,0,0,16,0,115,97,109,112,108,101,
-114,0,0,1,1,0,0,9,0,99,111,111,114,100,0,0,0,1,4,118,101,99,52,95,116,101,120,95,49,100,0,18,95,95,
-114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,0,0,0,1,90,95,
-0,0,12,0,0,116,101,120,116,117,114,101,49,68,80,114,111,106,0,1,1,0,0,16,0,115,97,109,112,108,101,
-114,0,0,1,1,0,0,10,0,99,111,111,114,100,0,0,0,1,4,118,101,99,52,95,116,101,120,95,49,100,95,112,
-114,111,106,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,
-114,100,0,59,120,121,121,121,0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,49,68,80,114,
-111,106,0,1,1,0,0,16,0,115,97,109,112,108,101,114,0,0,1,1,0,0,12,0,99,111,111,114,100,0,0,0,1,4,
-118,101,99,52,95,116,101,120,95,49,100,95,112,114,111,106,0,18,95,95,114,101,116,86,97,108,0,0,18,
-115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,
-117,114,101,50,68,0,1,1,0,0,17,0,115,97,109,112,108,101,114,0,0,1,1,0,0,10,0,99,111,111,114,100,0,
-0,0,1,4,118,101,99,52,95,116,101,120,95,50,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,
-112,108,101,114,0,0,18,99,111,111,114,100,0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,
-50,68,80,114,111,106,0,1,1,0,0,17,0,115,97,109,112,108,101,114,0,0,1,1,0,0,11,0,99,111,111,114,100,
-0,0,0,1,4,118,101,99,52,95,116,101,120,95,50,100,95,112,114,111,106,0,18,95,95,114,101,116,86,97,
-108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,59,120,121,122,122,0,0,0,0,1,90,
-95,0,0,12,0,0,116,101,120,116,117,114,101,50,68,80,114,111,106,0,1,1,0,0,17,0,115,97,109,112,108,
-101,114,0,0,1,1,0,0,12,0,99,111,111,114,100,0,0,0,1,4,118,101,99,52,95,116,101,120,95,50,100,95,
-112,114,111,106,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,
-111,114,100,0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,51,68,0,1,1,0,0,18,0,115,97,109,
-112,108,101,114,0,0,1,1,0,0,11,0,99,111,111,114,100,0,0,0,1,4,118,101,99,52,95,116,101,120,95,51,
-100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,
-0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,51,68,80,114,111,106,0,1,1,0,0,18,0,115,97,
-109,112,108,101,114,0,0,1,1,0,0,12,0,99,111,111,114,100,0,0,0,1,4,118,101,99,52,95,116,101,120,95,
-51,100,95,112,114,111,106,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,
-18,99,111,111,114,100,0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,67,117,98,101,0,1,1,0,
-0,19,0,115,97,109,112,108,101,114,0,0,1,1,0,0,11,0,99,111,111,114,100,0,0,0,1,4,118,101,99,52,95,
-116,101,120,95,99,117,98,101,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,
-0,18,99,111,111,114,100,0,0,0,0,1,90,95,0,0,12,0,0,115,104,97,100,111,119,49,68,0,1,1,0,0,20,0,115,
-97,109,112,108,101,114,0,0,1,1,0,0,11,0,99,111,111,114,100,0,0,0,1,4,118,101,99,52,95,116,101,120,
-95,49,100,95,115,104,97,100,111,119,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,
-114,0,0,18,99,111,111,114,100,0,0,0,0,1,90,95,0,0,12,0,0,115,104,97,100,111,119,49,68,80,114,111,
-106,0,1,1,0,0,20,0,115,97,109,112,108,101,114,0,0,1,1,0,0,12,0,99,111,111,114,100,0,0,0,1,4,118,
-101,99,52,95,116,101,120,95,49,100,95,112,114,111,106,95,115,104,97,100,111,119,0,18,95,95,114,101,
-116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,0,0,0,1,90,95,0,0,12,0,
-0,115,104,97,100,111,119,50,68,0,1,1,0,0,21,0,115,97,109,112,108,101,114,0,0,1,1,0,0,11,0,99,111,
-111,114,100,0,0,0,1,4,118,101,99,52,95,116,101,120,95,50,100,95,115,104,97,100,111,119,0,18,95,95,
-114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,0,0,0,1,90,95,
-0,0,12,0,0,115,104,97,100,111,119,50,68,80,114,111,106,0,1,1,0,0,21,0,115,97,109,112,108,101,114,0,
-0,1,1,0,0,12,0,99,111,111,114,100,0,0,0,1,4,118,101,99,52,95,116,101,120,95,50,100,95,112,114,111,
-106,95,115,104,97,100,111,119,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,
-0,18,99,111,111,114,100,0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,50,68,82,101,99,116,
-0,1,1,0,0,22,0,115,97,109,112,108,101,114,0,0,1,1,0,0,10,0,99,111,111,114,100,0,0,0,1,4,118,101,99,
-52,95,116,101,120,95,114,101,99,116,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,
-114,0,0,18,99,111,111,114,100,0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,50,68,82,101,
-99,116,80,114,111,106,0,1,1,0,0,22,0,115,97,109,112,108,101,114,0,0,1,1,0,0,11,0,99,111,111,114,
-100,0,0,0,1,4,118,101,99,52,95,116,101,120,95,114,101,99,116,95,112,114,111,106,0,18,95,95,114,101,
-116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,59,120,121,122,122,0,0,
-0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,50,68,82,101,99,116,80,114,111,106,0,1,1,0,0,22,
-0,115,97,109,112,108,101,114,0,0,1,1,0,0,12,0,99,111,111,114,100,0,0,0,1,4,118,101,99,52,95,116,
-101,120,95,114,101,99,116,95,112,114,111,106,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,
-112,108,101,114,0,0,18,99,99,111,111,114,100,0,0,0,0,1,90,95,0,0,12,0,0,115,104,97,100,111,119,50,
-68,82,101,99,116,0,1,1,0,0,23,0,115,97,109,112,108,101,114,0,0,1,1,0,0,11,0,99,111,111,114,100,0,0,
-0,1,4,118,101,99,52,95,116,101,120,95,114,101,99,116,95,115,104,97,100,111,119,0,18,95,95,114,101,
-116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,0,0,0,1,90,95,0,0,12,0,
-0,115,104,97,100,111,119,50,68,82,101,99,116,80,114,111,106,0,1,1,0,0,23,0,115,97,109,112,108,101,
-114,0,0,1,1,0,0,12,0,99,111,111,114,100,0,0,0,1,4,118,101,99,52,95,116,101,120,95,114,101,99,116,
-95,112,114,111,106,95,115,104,97,100,111,119,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,
-112,108,101,114,0,0,18,99,111,111,114,100,0,0,0,0,1,90,95,0,0,9,0,0,110,111,105,115,101,49,0,1,1,0,
-0,9,0,120,0,0,0,1,4,102,108,111,97,116,95,110,111,105,115,101,49,0,18,95,95,114,101,116,86,97,108,
-0,0,18,120,0,0,0,0,1,90,95,0,0,9,0,0,110,111,105,115,101,49,0,1,1,0,0,10,0,120,0,0,0,1,4,102,108,
-111,97,116,95,110,111,105,115,101,50,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,90,95,0,
-0,9,0,0,110,111,105,115,101,49,0,1,1,0,0,11,0,120,0,0,0,1,4,102,108,111,97,116,95,110,111,105,115,
-101,51,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,90,95,0,0,9,0,0,110,111,105,115,101,
-49,0,1,1,0,0,12,0,120,0,0,0,1,4,102,108,111,97,116,95,110,111,105,115,101,52,0,18,95,95,114,101,
-116,86,97,108,0,0,18,120,0,0,0,0,1,90,95,0,0,10,0,0,110,111,105,115,101,50,0,1,1,0,0,9,0,120,0,0,0,
-1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,0,18,120,0,0,0,20,0,9,18,
-95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0,0,18,120,0,17,49,57,0,51,52,0,0,
-46,0,0,20,0,0,1,90,95,0,0,10,0,0,110,111,105,115,101,50,0,1,1,0,0,10,0,120,0,0,0,1,9,18,95,95,114,
-101,116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,0,18,120,0,0,0,20,0,9,18,95,95,114,101,
-116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0,0,18,120,0,58,118,101,99,50,0,0,17,49,57,0,51,
-52,0,0,0,17,55,0,54,54,0,0,0,0,46,0,0,20,0,0,1,90,95,0,0,10,0,0,110,111,105,115,101,50,0,1,1,0,0,
-11,0,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,0,18,120,
-0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0,0,18,120,0,58,
-118,101,99,51,0,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,51,0,50,51,0,0,0,0,46,0,0,20,0,0,1,
-90,95,0,0,10,0,0,110,111,105,115,101,50,0,1,1,0,0,12,0,120,0,0,0,1,9,18,95,95,114,101,116,86,97,
-108,0,59,120,0,58,110,111,105,115,101,49,0,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,
-59,121,0,58,110,111,105,115,101,49,0,0,18,120,0,58,118,101,99,52,0,0,17,49,57,0,51,52,0,0,0,17,55,
-0,54,54,0,0,0,17,51,0,50,51,0,0,0,17,50,0,55,55,0,0,0,0,46,0,0,20,0,0,1,90,95,0,0,11,0,0,110,111,
-105,115,101,51,0,1,1,0,0,9,0,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110,111,
-105,115,101,49,0,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,105,
-115,101,49,0,0,18,120,0,17,49,57,0,51,52,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,
-0,58,110,111,105,115,101,49,0,0,18,120,0,17,53,0,52,55,0,0,46,0,0,20,0,0,1,90,95,0,0,11,0,0,110,
-111,105,115,101,51,0,1,1,0,0,10,0,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110,
-111,105,115,101,49,0,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,
-105,115,101,49,0,0,18,120,0,58,118,101,99,50,0,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,0,46,0,
-0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,110,111,105,115,101,49,0,0,18,120,0,58,118,
-101,99,50,0,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,0,46,0,0,20,0,0,1,90,95,0,0,11,0,0,110,
-111,105,115,101,51,0,1,1,0,0,11,0,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110,
-111,105,115,101,49,0,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,
-105,115,101,49,0,0,18,120,0,58,118,101,99,51,0,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,51,
-0,50,51,0,0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,110,111,105,115,101,49,
-0,0,18,120,0,58,118,101,99,51,0,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,17,49,49,0,48,52,0,0,
-0,0,46,0,0,20,0,0,1,90,95,0,0,11,0,0,110,111,105,115,101,51,0,1,1,0,0,12,0,120,0,0,0,1,9,18,95,95,
-114,101,116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,0,18,120,0,0,0,20,0,9,18,95,95,114,
-101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0,0,18,120,0,58,118,101,99,52,0,0,17,49,57,
-0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,51,0,50,51,0,0,0,17,50,0,55,55,0,0,0,0,46,0,0,20,0,9,18,95,95,
-114,101,116,86,97,108,0,59,122,0,58,110,111,105,115,101,49,0,0,18,120,0,58,118,101,99,52,0,0,17,53,
-0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,17,49,49,0,48,52,0,0,0,17,49,51,0,49,57,0,0,0,0,46,0,0,20,0,0,
-1,90,95,0,0,12,0,0,110,111,105,115,101,52,0,1,1,0,0,9,0,120,0,0,0,1,9,18,95,95,114,101,116,86,97,
-108,0,59,120,0,58,110,111,105,115,101,49,0,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,
-59,121,0,58,110,111,105,115,101,49,0,0,18,120,0,17,49,57,0,51,52,0,0,46,0,0,20,0,9,18,95,95,114,
-101,116,86,97,108,0,59,122,0,58,110,111,105,115,101,49,0,0,18,120,0,17,53,0,52,55,0,0,46,0,0,20,0,
-9,18,95,95,114,101,116,86,97,108,0,59,119,0,58,110,111,105,115,101,49,0,0,18,120,0,17,50,51,0,53,
-52,0,0,46,0,0,20,0,0,1,90,95,0,0,12,0,0,110,111,105,115,101,52,0,1,1,0,0,10,0,120,0,0,0,1,9,18,95,
-95,114,101,116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,0,18,120,0,0,0,20,0,9,18,95,95,114,
-101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0,0,18,120,0,58,118,101,99,50,0,0,17,49,57,
-0,51,52,0,0,0,17,55,0,54,54,0,0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,110,
-111,105,115,101,49,0,0,18,120,0,58,118,101,99,50,0,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,0,
-46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,58,110,111,105,115,101,49,0,0,18,120,0,58,
-118,101,99,50,0,0,17,50,51,0,53,52,0,0,0,17,50,57,0,49,49,0,0,0,0,46,0,0,20,0,0,1,90,95,0,0,12,0,0,
-110,111,105,115,101,52,0,1,1,0,0,11,0,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,
-110,111,105,115,101,49,0,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,
-111,105,115,101,49,0,0,18,120,0,58,118,101,99,51,0,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,
-51,0,50,51,0,0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,110,111,105,115,101,
-49,0,0,18,120,0,58,118,101,99,51,0,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,17,49,49,0,48,52,0,
-0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,58,110,111,105,115,101,49,0,0,18,120,
-0,58,118,101,99,51,0,0,17,50,51,0,53,52,0,0,0,17,50,57,0,49,49,0,0,0,17,51,49,0,57,49,0,0,0,0,46,0,
-0,20,0,0,1,90,95,0,0,12,0,0,110,111,105,115,101,52,0,1,1,0,0,12,0,120,0,0,0,1,9,18,95,95,114,101,
-116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,
-97,108,0,59,121,0,58,110,111,105,115,101,49,0,0,18,120,0,58,118,101,99,52,0,0,17,49,57,0,51,52,0,0,
-0,17,55,0,54,54,0,0,0,17,51,0,50,51,0,0,0,17,50,0,55,55,0,0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,
-86,97,108,0,59,122,0,58,110,111,105,115,101,49,0,0,18,120,0,58,118,101,99,52,0,0,17,53,0,52,55,0,0,
-0,17,49,55,0,56,53,0,0,0,17,49,49,0,48,52,0,0,0,17,49,51,0,49,57,0,0,0,0,46,0,0,20,0,9,18,95,95,
-114,101,116,86,97,108,0,59,119,0,58,110,111,105,115,101,49,0,0,18,120,0,58,118,101,99,52,0,0,17,50,
-51,0,53,52,0,0,0,17,50,57,0,49,49,0,0,0,17,51,49,0,57,49,0,0,0,17,51,55,0,52,56,0,0,0,0,46,0,0,20,
-0,0,0
diff --git a/src/mesa/shader/slang/library/slang_core_gc.h b/src/mesa/shader/slang/library/slang_core_gc.h
deleted file mode 100644
index b3d3e87..0000000
--- a/src/mesa/shader/slang/library/slang_core_gc.h
+++ /dev/null
@@ -1,869 +0,0 @@
-
-/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE FOLLOWING FILE: */
-/* slang_core.gc */
-
-5,1,90,95,0,0,5,0,1,1,1,0,0,9,0,102,0,0,0,1,4,118,101,99,52,95,116,111,95,105,118,101,99,52,0,18,
-95,95,114,101,116,86,97,108,0,0,18,102,0,0,0,0,1,90,95,0,0,5,0,1,1,1,0,0,1,0,98,0,0,0,1,9,18,95,95,
-114,101,116,86,97,108,0,18,98,0,20,0,0,1,90,95,0,0,5,0,1,1,1,0,0,5,0,105,0,0,0,1,9,18,95,95,114,
-101,116,86,97,108,0,18,105,0,20,0,0,1,90,95,0,0,1,0,1,1,1,0,0,5,0,105,0,0,0,1,4,118,101,99,52,95,
-115,110,101,0,18,95,95,114,101,116,86,97,108,0,0,18,105,0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,1,0,1,
-1,1,0,0,9,0,102,0,0,0,1,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,0,18,102,
-0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,1,0,1,1,1,0,0,1,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,
-0,18,98,0,20,0,0,1,90,95,0,0,9,0,1,1,1,0,0,5,0,105,0,0,0,1,4,105,118,101,99,52,95,116,111,95,118,
-101,99,52,0,18,95,95,114,101,116,86,97,108,0,0,18,105,0,0,0,0,1,90,95,0,0,9,0,1,1,1,0,0,1,0,98,0,0,
-0,1,4,105,118,101,99,52,95,116,111,95,118,101,99,52,0,18,95,95,114,101,116,86,97,108,0,0,18,98,0,0,
-0,0,1,90,95,0,0,9,0,1,1,1,0,0,9,0,102,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,102,0,20,0,0,1,
-90,95,0,0,10,0,1,1,1,0,0,9,0,120,0,0,1,1,0,0,9,0,121,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,
-120,0,18,120,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,18,121,0,20,0,0,1,90,95,0,0,10,0,1,
-1,1,0,0,9,0,102,0,0,0,1,4,118,101,99,52,95,109,111,118,101,0,18,95,95,114,101,116,86,97,108,0,59,
-120,121,0,0,18,102,0,0,0,0,1,90,95,0,0,10,0,1,1,1,0,0,5,0,105,0,0,0,1,4,105,118,101,99,52,95,116,
-111,95,118,101,99,52,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,105,0,0,0,0,1,90,95,0,0,
-10,0,1,1,1,0,0,1,0,98,0,0,0,1,4,105,118,101,99,52,95,116,111,95,118,101,99,52,0,18,95,95,114,101,
-116,86,97,108,0,59,120,121,0,0,18,98,0,0,0,0,1,90,95,0,0,10,0,1,1,1,0,0,2,0,98,0,0,0,1,4,105,118,
-101,99,52,95,116,111,95,118,101,99,52,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,98,0,0,
-0,0,1,90,95,0,0,10,0,1,1,1,0,0,11,0,118,0,0,0,1,4,118,101,99,52,95,109,111,118,101,0,18,95,95,114,
-101,116,86,97,108,0,59,120,121,0,0,18,118,0,59,120,121,0,0,0,0,1,90,95,0,0,10,0,1,1,1,0,0,12,0,118,
-0,0,0,1,4,118,101,99,52,95,109,111,118,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,
-118,0,59,120,121,0,0,0,0,1,90,95,0,0,11,0,1,1,1,0,0,9,0,120,0,0,1,1,0,0,9,0,121,0,0,1,1,0,0,9,0,
-122,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,18,120,0,20,0,9,18,95,95,114,101,116,86,97,
-108,0,59,121,0,18,121,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,18,122,0,20,0,0,1,90,95,0,
-0,11,0,1,1,1,0,0,9,0,102,0,0,0,1,4,118,101,99,52,95,109,111,118,101,0,18,95,95,114,101,116,86,97,
-108,0,59,120,121,122,0,0,18,102,0,0,0,0,1,90,95,0,0,11,0,1,1,1,0,0,5,0,105,0,0,0,1,4,105,118,101,
-99,52,95,116,111,95,118,101,99,52,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,105,0,0,
-0,0,1,90,95,0,0,11,0,1,1,1,0,0,1,0,98,0,0,0,1,4,105,118,101,99,52,95,116,111,95,118,101,99,52,0,18,
-95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,98,0,0,0,0,1,90,95,0,0,11,0,1,1,1,0,0,3,0,98,0,
-0,0,1,4,105,118,101,99,52,95,116,111,95,118,101,99,52,0,18,95,95,114,101,116,86,97,108,0,59,120,
-121,122,0,0,18,98,0,0,0,0,1,90,95,0,0,11,0,1,1,1,0,0,12,0,118,0,0,0,1,4,118,101,99,52,95,109,111,
-118,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,0,0,0,1,90,95,0,0,12,0,1,1,
-1,0,0,9,0,120,0,0,1,1,0,0,9,0,121,0,0,1,1,0,0,9,0,122,0,0,1,1,0,0,9,0,119,0,0,0,1,9,18,95,95,114,
-101,116,86,97,108,0,59,120,0,18,120,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,18,121,0,20,
-0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,18,122,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,
-119,0,18,119,0,20,0,0,1,90,95,0,0,12,0,1,1,1,0,0,9,0,102,0,0,0,1,4,118,101,99,52,95,109,111,118,
-101,0,18,95,95,114,101,116,86,97,108,0,0,18,102,0,0,0,0,1,90,95,0,0,12,0,1,1,1,0,0,5,0,105,0,0,0,1,
-4,105,118,101,99,52,95,116,111,95,118,101,99,52,0,18,95,95,114,101,116,86,97,108,0,0,18,105,0,0,0,
-0,1,90,95,0,0,12,0,1,1,1,0,0,1,0,98,0,0,0,1,4,105,118,101,99,52,95,116,111,95,118,101,99,52,0,18,
-95,95,114,101,116,86,97,108,0,0,18,98,0,0,0,0,1,90,95,0,0,12,0,1,1,1,0,0,4,0,98,0,0,0,1,4,105,118,
-101,99,52,95,116,111,95,118,101,99,52,0,18,95,95,114,101,116,86,97,108,0,0,18,98,0,0,0,0,1,90,95,0,
-0,12,0,1,1,1,0,0,8,0,105,0,0,0,1,4,105,118,101,99,52,95,116,111,95,118,101,99,52,0,18,95,95,114,
-101,116,86,97,108,0,0,18,105,0,0,0,0,1,90,95,0,0,12,0,1,1,1,0,0,11,0,118,51,0,0,1,1,0,0,9,0,102,0,
-0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,18,118,51,0,20,0,9,18,95,95,114,101,116,
-86,97,108,0,59,119,0,18,102,0,20,0,0,1,90,95,0,0,12,0,1,1,1,0,0,10,0,118,50,0,0,1,1,0,0,9,0,102,49,
-0,0,1,1,0,0,9,0,102,50,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,121,0,18,118,50,0,20,0,9,
-18,95,95,114,101,116,86,97,108,0,59,122,0,18,102,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,
-119,0,18,102,50,0,20,0,0,1,90,95,0,0,6,0,1,1,1,0,0,5,0,105,0,0,1,1,0,0,5,0,106,0,0,0,1,9,18,95,95,
-114,101,116,86,97,108,0,59,120,0,18,105,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,18,106,
-0,20,0,0,1,90,95,0,0,6,0,1,1,1,0,0,5,0,105,0,0,0,1,4,118,101,99,52,95,109,111,118,101,0,18,95,95,
-114,101,116,86,97,108,0,59,120,121,0,0,18,105,0,0,0,0,1,90,95,0,0,6,0,1,1,1,0,0,9,0,102,0,0,0,1,4,
-118,101,99,52,95,116,111,95,105,118,101,99,52,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,
-102,0,0,0,0,1,90,95,0,0,6,0,1,1,1,0,0,1,0,98,0,0,0,1,4,118,101,99,52,95,116,111,95,105,118,101,99,
-52,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,98,0,0,0,0,1,90,95,0,0,7,0,1,1,1,0,0,5,0,
-105,0,0,1,1,0,0,5,0,106,0,0,1,1,0,0,5,0,107,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,18,
-105,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,18,106,0,20,0,9,18,95,95,114,101,116,86,97,
-108,0,59,122,0,18,107,0,20,0,0,1,90,95,0,0,7,0,1,1,1,0,0,5,0,105,0,0,0,1,4,118,101,99,52,95,109,
-111,118,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,105,0,0,0,0,1,90,95,0,0,7,0,1,
-1,1,0,0,9,0,102,0,0,0,1,4,118,101,99,52,95,116,111,95,105,118,101,99,52,0,18,95,95,114,101,116,86,
-97,108,0,59,120,121,122,0,0,18,102,0,0,0,0,1,90,95,0,0,7,0,1,1,1,0,0,1,0,98,0,0,0,1,4,118,101,99,
-52,95,109,111,118,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,98,0,0,0,0,1,90,95,
-0,0,8,0,1,1,1,0,0,5,0,120,0,0,1,1,0,0,5,0,121,0,0,1,1,0,0,5,0,122,0,0,1,1,0,0,5,0,119,0,0,0,1,9,18,
-95,95,114,101,116,86,97,108,0,59,120,0,18,120,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,
-18,121,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,18,122,0,20,0,9,18,95,95,114,101,116,86,
-97,108,0,59,119,0,18,119,0,20,0,0,1,90,95,0,0,8,0,1,1,1,0,0,5,0,105,0,0,0,1,4,118,101,99,52,95,109,
-111,118,101,0,18,95,95,114,101,116,86,97,108,0,0,18,105,0,0,0,0,1,90,95,0,0,8,0,1,1,1,0,0,9,0,102,
-0,0,0,1,4,118,101,99,52,95,116,111,95,105,118,101,99,52,0,18,95,95,114,101,116,86,97,108,0,0,18,
-102,0,0,0,0,1,90,95,0,0,8,0,1,1,1,0,0,1,0,98,0,0,0,1,4,118,101,99,52,95,116,111,95,105,118,101,99,
-52,0,18,95,95,114,101,116,86,97,108,0,0,18,98,0,0,0,0,1,90,95,0,0,2,0,1,1,1,0,0,1,0,98,49,0,0,1,1,
-0,0,1,0,98,50,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,18,98,49,0,20,0,9,18,95,95,114,
-101,116,86,97,108,0,59,121,0,18,98,50,0,20,0,0,1,90,95,0,0,2,0,1,1,1,0,0,5,0,105,49,0,0,1,1,0,0,5,
-0,105,50,0,0,0,1,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,
-105,49,0,0,17,48,0,48,0,0,0,0,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,
-121,0,0,18,105,50,0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,2,0,1,1,1,0,0,1,0,98,0,0,0,1,4,118,101,99,
-52,95,109,111,118,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,98,0,0,0,0,1,90,95,0,0,
-2,0,1,1,1,0,0,9,0,102,0,0,0,1,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,
-120,121,0,0,18,102,0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,2,0,1,1,1,0,0,5,0,105,0,0,0,1,4,118,101,99,
-52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,105,0,0,17,48,0,48,0,0,0,0,
-0,1,90,95,0,0,2,0,1,1,1,0,0,10,0,118,0,0,0,1,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,
-86,97,108,0,59,120,121,0,0,18,118,0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,2,0,1,1,1,0,0,6,0,118,0,0,0,
-1,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,118,0,0,17,
-48,0,48,0,0,0,0,0,1,90,95,0,0,3,0,1,1,1,0,0,1,0,98,49,0,0,1,1,0,0,1,0,98,50,0,0,1,1,0,0,1,0,98,51,
-0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,18,98,49,0,20,0,9,18,95,95,114,101,116,86,97,
-108,0,59,121,0,18,98,50,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,18,98,51,0,20,0,0,1,90,
-95,0,0,3,0,1,1,1,0,0,9,0,102,49,0,0,1,1,0,0,9,0,102,50,0,0,1,1,0,0,9,0,102,51,0,0,0,1,4,118,101,99,
-52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,102,49,0,0,17,48,0,48,0,0,0,0,4,
-118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,102,50,0,0,17,48,0,
-48,0,0,0,0,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,102,51,
-0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,3,0,1,1,1,0,0,1,0,98,0,0,0,1,4,118,101,99,52,95,109,111,118,
-101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,98,0,0,0,0,1,90,95,0,0,3,0,1,1,1,0,0,
-9,0,102,0,0,0,1,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,
-0,18,102,0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,3,0,1,1,1,0,0,5,0,105,0,0,0,1,4,118,101,99,52,95,115,
-110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,105,0,0,17,48,0,48,0,0,0,0,0,1,90,
-95,0,0,3,0,1,1,1,0,0,11,0,118,0,0,0,1,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,
-108,0,59,120,121,122,0,0,18,118,0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,3,0,1,1,1,0,0,7,0,118,0,0,0,1,
-4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,0,17,
-48,0,48,0,0,0,0,0,1,90,95,0,0,4,0,1,1,1,0,0,1,0,98,49,0,0,1,1,0,0,1,0,98,50,0,0,1,1,0,0,1,0,98,51,
-0,0,1,1,0,0,1,0,98,52,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,18,98,49,0,20,0,9,18,95,
-95,114,101,116,86,97,108,0,59,121,0,18,98,50,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,18,
-98,51,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,18,98,52,0,20,0,0,1,90,95,0,0,4,0,1,1,1,0,
-0,9,0,102,49,0,0,1,1,0,0,9,0,102,50,0,0,1,1,0,0,9,0,102,51,0,0,1,1,0,0,9,0,102,52,0,0,0,1,3,2,90,
-95,1,0,9,0,1,122,101,114,111,0,2,17,48,0,48,0,0,0,0,4,118,101,99,52,95,115,110,101,0,18,95,95,114,
-101,116,86,97,108,0,59,120,0,0,18,102,49,0,0,18,122,101,114,111,0,0,0,4,118,101,99,52,95,115,110,
-101,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,102,50,0,0,18,122,101,114,111,0,0,0,4,118,101,
-99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,102,51,0,0,18,122,101,114,
-111,0,0,0,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,119,0,0,18,102,52,0,
-0,18,122,101,114,111,0,0,0,0,1,90,95,0,0,4,0,1,1,1,0,0,1,0,98,0,0,0,1,4,118,101,99,52,95,109,111,
-118,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,119,0,0,18,98,0,0,0,0,1,90,95,0,0,4,0,1,
-1,1,0,0,9,0,102,0,0,0,1,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,
-121,122,119,0,0,18,102,0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,4,0,1,1,1,0,0,5,0,105,0,0,0,1,4,118,
-101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,119,0,0,18,105,0,0,17,
-48,0,48,0,0,0,0,0,1,90,95,0,0,4,0,1,1,1,0,0,12,0,118,0,0,0,1,4,118,101,99,52,95,115,110,101,0,18,
-95,95,114,101,116,86,97,108,0,59,120,121,122,119,0,0,18,118,0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,4,
-0,1,1,1,0,0,8,0,118,0,0,0,1,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,
-120,121,122,119,0,0,18,118,0,0,17,48,0,48,0,0,0,0,0,1,90,95,0,0,13,0,1,1,1,0,0,9,0,109,48,48,0,0,1,
-1,0,0,9,0,109,49,48,0,0,1,1,0,0,9,0,109,48,49,0,0,1,1,0,0,9,0,109,49,49,0,0,0,1,9,18,95,95,114,101,
-116,86,97,108,0,16,8,48,0,57,59,120,0,18,109,48,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,
-48,0,57,59,121,0,18,109,49,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,120,0,18,
-109,48,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,121,0,18,109,49,49,0,20,0,0,1,
-90,95,0,0,13,0,1,1,1,0,0,9,0,102,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,120,0,
-18,102,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,121,0,17,48,0,48,0,0,20,0,9,18,95,
-95,114,101,116,86,97,108,0,16,10,49,0,57,59,120,0,17,48,0,48,0,0,20,0,9,18,95,95,114,101,116,86,97,
-108,0,16,10,49,0,57,59,121,0,18,102,0,20,0,0,1,90,95,0,0,13,0,1,1,1,0,0,5,0,105,0,0,0,1,8,58,109,
-97,116,50,0,0,58,102,108,111,97,116,0,0,18,105,0,0,0,0,0,0,0,1,90,95,0,0,13,0,1,1,1,0,0,1,0,98,0,0,
-0,1,8,58,109,97,116,50,0,0,58,102,108,111,97,116,0,0,18,98,0,0,0,0,0,0,0,1,90,95,0,0,13,0,1,1,1,0,
-0,10,0,99,48,0,0,1,1,0,0,10,0,99,49,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,99,
-48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,99,49,0,20,0,0,1,90,95,0,0,14,0,1,1,
-1,0,0,9,0,109,48,48,0,0,1,1,0,0,9,0,109,49,48,0,0,1,1,0,0,9,0,109,50,48,0,0,1,1,0,0,9,0,109,48,49,
-0,0,1,1,0,0,9,0,109,49,49,0,0,1,1,0,0,9,0,109,50,49,0,0,1,1,0,0,9,0,109,48,50,0,0,1,1,0,0,9,0,109,
-49,50,0,0,1,1,0,0,9,0,109,50,50,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,120,0,
-18,109,48,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,121,0,18,109,49,48,0,20,0,9,
-18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,122,0,18,109,50,48,0,20,0,9,18,95,95,114,101,116,
-86,97,108,0,16,10,49,0,57,59,120,0,18,109,48,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,
-0,57,59,121,0,18,109,49,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,122,0,18,109,
-50,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,59,120,0,18,109,48,50,0,20,0,9,18,95,
-95,114,101,116,86,97,108,0,16,10,50,0,57,59,121,0,18,109,49,50,0,20,0,9,18,95,95,114,101,116,86,97,
-108,0,16,10,50,0,57,59,122,0,18,109,50,50,0,20,0,0,1,90,95,0,0,14,0,1,1,1,0,0,9,0,102,0,0,0,1,3,2,
-90,95,0,0,10,0,1,118,0,2,58,118,101,99,50,0,0,18,102,0,0,17,48,0,48,0,0,0,0,0,0,9,18,95,95,114,101,
-116,86,97,108,0,16,8,48,0,57,18,118,0,59,120,121,121,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,
-10,49,0,57,18,118,0,59,121,120,121,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,118,
-0,59,121,121,120,0,20,0,0,1,90,95,0,0,14,0,1,1,1,0,0,5,0,105,0,0,0,1,8,58,109,97,116,51,0,0,58,102,
-108,111,97,116,0,0,18,105,0,0,0,0,0,0,0,1,90,95,0,0,14,0,1,1,1,0,0,1,0,98,0,0,0,1,8,58,109,97,116,
-51,0,0,58,102,108,111,97,116,0,0,18,98,0,0,0,0,0,0,0,1,90,95,0,0,14,0,1,1,1,0,0,11,0,99,48,0,0,1,1,
-0,0,11,0,99,49,0,0,1,1,0,0,11,0,99,50,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,
-99,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,99,49,0,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,50,0,57,18,99,50,0,20,0,0,1,90,95,0,0,15,0,1,1,1,0,0,9,0,109,48,48,0,0,1,1,0,
-0,9,0,109,49,48,0,0,1,1,0,0,9,0,109,50,48,0,0,1,1,0,0,9,0,109,51,48,0,0,1,1,0,0,9,0,109,48,49,0,0,
-1,1,0,0,9,0,109,49,49,0,0,1,1,0,0,9,0,109,50,49,0,0,1,1,0,0,9,0,109,51,49,0,0,1,1,0,0,9,0,109,48,
-50,0,0,1,1,0,0,9,0,109,49,50,0,0,1,1,0,0,9,0,109,50,50,0,0,1,1,0,0,9,0,109,51,50,0,0,1,1,0,0,9,0,
-109,48,51,0,0,1,1,0,0,9,0,109,49,51,0,0,1,1,0,0,9,0,109,50,51,0,0,1,1,0,0,9,0,109,51,51,0,0,0,1,9,
-18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,120,0,18,109,48,48,0,20,0,9,18,95,95,114,101,116,
-86,97,108,0,16,8,48,0,57,59,121,0,18,109,49,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,
-57,59,122,0,18,109,50,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,119,0,18,109,51,
-48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,120,0,18,109,48,49,0,20,0,9,18,95,95,
-114,101,116,86,97,108,0,16,10,49,0,57,59,121,0,18,109,49,49,0,20,0,9,18,95,95,114,101,116,86,97,
-108,0,16,10,49,0,57,59,122,0,18,109,50,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,
-59,119,0,18,109,51,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,59,120,0,18,109,48,
-50,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,59,121,0,18,109,49,50,0,20,0,9,18,95,95,
-114,101,116,86,97,108,0,16,10,50,0,57,59,122,0,18,109,50,50,0,20,0,9,18,95,95,114,101,116,86,97,
-108,0,16,10,50,0,57,59,119,0,18,109,51,50,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,
-59,120,0,18,109,48,51,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,59,121,0,18,109,49,
-51,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,59,122,0,18,109,50,51,0,20,0,9,18,95,95,
-114,101,116,86,97,108,0,16,10,51,0,57,59,119,0,18,109,51,51,0,20,0,0,1,90,95,0,0,15,0,1,1,1,0,0,9,
-0,102,0,0,0,1,3,2,90,95,0,0,10,0,1,118,0,2,58,118,101,99,50,0,0,18,102,0,0,17,48,0,48,0,0,0,0,0,0,
-9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,118,0,59,120,121,121,121,0,20,0,9,18,95,95,114,
-101,116,86,97,108,0,16,10,49,0,57,18,118,0,59,121,120,121,121,0,20,0,9,18,95,95,114,101,116,86,97,
-108,0,16,10,50,0,57,18,118,0,59,121,121,120,121,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,
-0,57,18,118,0,59,121,121,121,120,0,20,0,0,1,90,95,0,0,15,0,1,1,1,0,0,5,0,105,0,0,0,1,8,58,109,97,
-116,52,0,0,58,102,108,111,97,116,0,0,18,105,0,0,0,0,0,0,0,1,90,95,0,0,15,0,1,1,1,0,0,1,0,98,0,0,0,
-1,8,58,109,97,116,52,0,0,58,102,108,111,97,116,0,0,18,98,0,0,0,0,0,0,0,1,90,95,0,0,15,0,1,1,1,0,0,
-12,0,99,48,0,0,1,1,0,0,12,0,99,49,0,0,1,1,0,0,12,0,99,50,0,0,1,1,0,0,12,0,99,51,0,0,0,1,9,18,95,95,
-114,101,116,86,97,108,0,16,8,48,0,57,18,99,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,
-57,18,99,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,99,50,0,20,0,9,18,95,95,114,
-101,116,86,97,108,0,16,10,51,0,57,18,99,51,0,20,0,0,1,90,95,0,0,5,0,2,26,1,1,0,0,5,0,97,0,0,1,1,0,
-0,5,0,98,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,
-98,0,0,0,0,1,90,95,0,0,5,0,2,27,1,1,0,0,5,0,97,0,0,1,1,0,0,5,0,98,0,0,0,1,4,118,101,99,52,95,115,
-117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,90,95,0,0,
-5,0,2,21,1,1,0,0,5,0,97,0,0,1,1,0,0,5,0,98,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,
-121,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,90,95,0,0,5,0,2,22,1,1,0,0,5,0,
-97,0,0,1,1,0,0,5,0,98,0,0,0,1,3,2,90,95,0,0,9,0,1,98,73,110,118,0,0,1,1,120,0,0,0,4,102,108,111,97,
-116,95,114,99,112,0,18,98,73,110,118,0,0,18,98,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,
-108,121,0,18,120,0,0,18,97,0,0,18,98,73,110,118,0,0,0,4,118,101,99,52,95,116,111,95,105,118,101,99,
-52,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,90,95,0,0,6,0,2,26,1,1,0,0,6,0,97,0,0,1,1,
-0,0,6,0,98,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,
-98,0,0,0,0,1,90,95,0,0,6,0,2,27,1,1,0,0,6,0,97,0,0,1,1,0,0,6,0,98,0,0,0,1,4,118,101,99,52,95,115,
-117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,90,95,0,0,
-6,0,2,21,1,1,0,0,6,0,97,0,0,1,1,0,0,6,0,98,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,
-121,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,90,95,0,0,6,0,2,22,1,1,0,0,6,0,
-97,0,0,1,1,0,0,6,0,98,0,0,0,1,3,2,90,95,0,0,10,0,1,98,73,110,118,0,0,1,1,120,0,0,0,4,102,108,111,
-97,116,95,114,99,112,0,18,98,73,110,118,0,59,120,0,0,18,98,0,59,120,0,0,0,4,102,108,111,97,116,95,
-114,99,112,0,18,98,73,110,118,0,59,121,0,0,18,98,0,59,121,0,0,0,4,118,101,99,52,95,109,117,108,116,
-105,112,108,121,0,18,120,0,0,18,97,0,0,18,98,73,110,118,0,0,0,4,118,101,99,52,95,116,111,95,105,
-118,101,99,52,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,90,95,0,0,7,0,2,26,1,1,0,0,7,0,
-97,0,0,1,1,0,0,7,0,98,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,114,101,116,86,97,108,0,0,
-18,97,0,0,18,98,0,0,0,0,1,90,95,0,0,7,0,2,27,1,1,0,0,7,0,97,0,0,1,1,0,0,7,0,98,0,0,0,1,4,118,101,
-99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,
-1,90,95,0,0,7,0,2,21,1,1,0,0,7,0,97,0,0,1,1,0,0,7,0,98,0,0,0,1,4,118,101,99,52,95,109,117,108,116,
-105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,90,95,0,0,7,0,2,22,
-1,1,0,0,7,0,97,0,0,1,1,0,0,7,0,98,0,0,0,1,3,2,90,95,0,0,11,0,1,98,73,110,118,0,0,1,1,120,0,0,0,4,
-102,108,111,97,116,95,114,99,112,0,18,98,73,110,118,0,59,120,0,0,18,98,0,59,120,0,0,0,4,102,108,
-111,97,116,95,114,99,112,0,18,98,73,110,118,0,59,121,0,0,18,98,0,59,121,0,0,0,4,102,108,111,97,116,
-95,114,99,112,0,18,98,73,110,118,0,59,122,0,0,18,98,0,59,122,0,0,0,4,118,101,99,52,95,109,117,108,
-116,105,112,108,121,0,18,120,0,0,18,97,0,0,18,98,73,110,118,0,0,0,4,118,101,99,52,95,116,111,95,
-105,118,101,99,52,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,90,95,0,0,8,0,2,26,1,1,0,0,
-8,0,97,0,0,1,1,0,0,8,0,98,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,114,101,116,86,97,108,0,
-0,18,97,0,0,18,98,0,0,0,0,1,90,95,0,0,8,0,2,27,1,1,0,0,8,0,97,0,0,1,1,0,0,8,0,98,0,0,0,1,4,118,101,
-99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,
-1,90,95,0,0,8,0,2,21,1,1,0,0,8,0,97,0,0,1,1,0,0,8,0,98,0,0,0,1,4,118,101,99,52,95,109,117,108,116,
-105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,90,95,0,0,8,0,2,22,
-1,1,0,0,8,0,97,0,0,1,1,0,0,8,0,98,0,0,0,1,3,2,90,95,0,0,12,0,1,98,73,110,118,0,0,1,1,120,0,0,0,4,
-102,108,111,97,116,95,114,99,112,0,18,98,73,110,118,0,59,120,0,0,18,98,0,59,120,0,0,0,4,102,108,
-111,97,116,95,114,99,112,0,18,98,73,110,118,0,59,121,0,0,18,98,0,59,121,0,0,0,4,102,108,111,97,116,
-95,114,99,112,0,18,98,73,110,118,0,59,122,0,0,18,98,0,59,122,0,0,0,4,102,108,111,97,116,95,114,99,
-112,0,18,98,73,110,118,0,59,119,0,0,18,98,0,59,119,0,0,0,4,118,101,99,52,95,109,117,108,116,105,
-112,108,121,0,18,120,0,0,18,97,0,0,18,98,73,110,118,0,0,0,4,118,101,99,52,95,116,111,95,105,118,
-101,99,52,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,90,95,0,0,9,0,2,26,1,1,0,0,9,0,97,
-0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,114,101,116,86,97,108,0,0,18,
-97,0,0,18,98,0,0,0,0,1,90,95,0,0,9,0,2,27,1,1,0,0,9,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,
-52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,
-90,95,0,0,9,0,2,21,1,1,0,0,9,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,109,117,108,116,
-105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,90,95,0,0,9,0,2,22,
-1,1,0,0,9,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,3,2,90,95,0,0,9,0,1,98,73,110,118,0,0,0,4,102,108,111,97,
-116,95,114,99,112,0,18,98,73,110,118,0,59,120,0,0,18,98,0,0,0,4,118,101,99,52,95,109,117,108,116,
-105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,73,110,118,0,0,0,0,1,90,95,0,
-0,10,0,2,26,1,1,0,0,10,0,118,0,0,1,1,0,0,10,0,117,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,
-114,101,116,86,97,108,0,59,120,121,0,0,18,118,0,0,18,117,0,0,0,0,1,90,95,0,0,10,0,2,27,1,1,0,0,10,
-0,118,0,0,1,1,0,0,10,0,117,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,
-101,116,86,97,108,0,59,120,121,0,0,18,118,0,0,18,117,0,0,0,0,1,90,95,0,0,10,0,2,21,1,1,0,0,10,0,
-118,0,0,1,1,0,0,10,0,117,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,
-101,116,86,97,108,0,59,120,121,0,0,18,118,0,0,18,117,0,0,0,0,1,90,95,0,0,10,0,2,22,1,1,0,0,10,0,
-118,0,0,1,1,0,0,10,0,117,0,0,0,1,3,2,90,95,0,0,10,0,1,119,0,0,0,4,102,108,111,97,116,95,114,99,112,
-0,18,119,0,59,120,0,0,18,117,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0,59,121,0,
-0,18,117,0,59,121,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,
-86,97,108,0,59,120,121,0,0,18,118,0,0,18,119,0,0,0,0,1,90,95,0,0,11,0,2,26,1,1,0,0,11,0,118,0,0,1,
-1,0,0,11,0,117,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,114,101,116,86,97,108,0,59,120,121,
-122,0,0,18,118,0,0,18,117,0,0,0,0,1,90,95,0,0,11,0,2,27,1,1,0,0,11,0,118,0,0,1,1,0,0,11,0,117,0,0,
-0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,
-122,0,0,18,118,0,0,18,117,0,0,0,0,1,90,95,0,0,11,0,2,21,1,1,0,0,11,0,118,0,0,1,1,0,0,11,0,117,0,0,
-0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,
-121,122,0,0,18,118,0,0,18,117,0,0,0,0,1,90,95,0,0,11,0,2,22,1,1,0,0,11,0,118,0,0,1,1,0,0,11,0,117,
-0,0,0,1,3,2,90,95,0,0,11,0,1,119,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0,59,120,0,0,18,
-117,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0,59,121,0,0,18,117,0,59,121,0,0,0,
-4,102,108,111,97,116,95,114,99,112,0,18,119,0,59,122,0,0,18,117,0,59,122,0,0,0,4,118,101,99,52,95,
-109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,0,
-18,119,0,0,0,0,1,90,95,0,0,12,0,2,26,1,1,0,0,12,0,118,0,0,1,1,0,0,12,0,117,0,0,0,1,4,118,101,99,52,
-95,97,100,100,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,18,117,0,0,0,0,1,90,95,0,0,12,0,2,27,
-1,1,0,0,12,0,118,0,0,1,1,0,0,12,0,117,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,
-95,95,114,101,116,86,97,108,0,0,18,118,0,0,18,117,0,0,0,0,1,90,95,0,0,12,0,2,21,1,1,0,0,12,0,118,0,
-0,1,1,0,0,12,0,117,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,
-116,86,97,108,0,0,18,118,0,0,18,117,0,0,0,0,1,90,95,0,0,12,0,2,22,1,1,0,0,12,0,118,0,0,1,1,0,0,12,
-0,117,0,0,0,1,3,2,90,95,0,0,12,0,1,119,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0,59,120,
-0,0,18,117,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0,59,121,0,0,18,117,0,59,121,
-0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0,59,122,0,0,18,117,0,59,122,0,0,0,4,102,108,111,
-97,116,95,114,99,112,0,18,119,0,59,119,0,0,18,117,0,59,119,0,0,0,4,118,101,99,52,95,109,117,108,
-116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,18,119,0,0,0,0,1,90,95,0,0,10,
-0,2,26,1,1,0,0,9,0,97,0,0,1,1,0,0,10,0,117,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,114,
-101,116,86,97,108,0,59,120,121,0,0,18,97,0,0,18,117,0,59,120,121,0,0,0,0,1,90,95,0,0,10,0,2,26,1,1,
-0,0,10,0,118,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,114,101,116,86,97,
-108,0,59,120,121,0,0,18,118,0,59,120,121,0,0,18,98,0,0,0,0,1,90,95,0,0,10,0,2,27,1,1,0,0,9,0,97,0,
-0,1,1,0,0,10,0,117,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,116,
-86,97,108,0,59,120,121,0,0,18,97,0,0,18,117,0,59,120,121,0,0,0,0,1,90,95,0,0,10,0,2,27,1,1,0,0,10,
-0,118,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,
-101,116,86,97,108,0,59,120,121,0,0,18,118,0,59,120,121,0,0,18,98,0,0,0,0,1,90,95,0,0,10,0,2,21,1,1,
-0,0,9,0,97,0,0,1,1,0,0,10,0,117,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,
-95,114,101,116,86,97,108,0,59,120,121,0,0,18,97,0,0,18,117,0,59,120,121,0,0,0,0,1,90,95,0,0,10,0,2,
-21,1,1,0,0,10,0,118,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,
-0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,118,0,59,120,121,0,0,18,98,0,0,0,0,1,90,95,0,
-0,10,0,2,22,1,1,0,0,9,0,97,0,0,1,1,0,0,10,0,117,0,0,0,1,3,2,90,95,0,0,10,0,1,105,110,118,85,0,0,0,
-4,102,108,111,97,116,95,114,99,112,0,18,105,110,118,85,0,59,120,0,0,18,117,0,59,120,0,0,0,4,102,
-108,111,97,116,95,114,99,112,0,18,105,110,118,85,0,59,121,0,0,18,117,0,59,121,0,0,0,4,118,101,99,
-52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,97,0,0,
-18,105,110,118,85,0,59,120,121,0,0,0,0,1,90,95,0,0,10,0,2,22,1,1,0,0,10,0,118,0,0,1,1,0,0,9,0,98,0,
-0,0,1,3,2,90,95,0,0,9,0,1,105,110,118,66,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,105,110,118,
-66,0,0,18,98,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,
-108,0,59,120,121,0,0,18,118,0,59,120,121,0,0,18,105,110,118,66,0,0,0,0,1,90,95,0,0,11,0,2,26,1,1,0,
-0,9,0,97,0,0,1,1,0,0,11,0,117,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,114,101,116,86,97,
-108,0,59,120,121,122,0,0,18,97,0,0,18,117,0,59,120,121,122,0,0,0,0,1,90,95,0,0,11,0,2,26,1,1,0,0,
-11,0,118,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,114,101,116,86,97,108,
-0,59,120,121,122,0,0,18,118,0,59,120,121,122,0,0,18,98,0,0,0,0,1,90,95,0,0,11,0,2,27,1,1,0,0,9,0,
-97,0,0,1,1,0,0,11,0,117,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,
-116,86,97,108,0,59,120,121,122,0,0,18,97,0,0,18,117,0,59,120,121,122,0,0,0,0,1,90,95,0,0,11,0,2,27,
-1,1,0,0,11,0,118,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,
-95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,59,120,121,122,0,0,18,98,0,0,0,0,1,90,95,
-0,0,11,0,2,21,1,1,0,0,9,0,97,0,0,1,1,0,0,11,0,117,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,
-112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,97,0,0,18,117,0,59,120,121,
-122,0,0,0,0,1,90,95,0,0,11,0,2,21,1,1,0,0,11,0,118,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,
-109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,59,
-120,121,122,0,0,18,98,0,0,0,0,1,90,95,0,0,11,0,2,22,1,1,0,0,9,0,97,0,0,1,1,0,0,11,0,117,0,0,0,1,3,
-2,90,95,0,0,11,0,1,105,110,118,85,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,105,110,118,85,0,
-59,120,0,0,18,117,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,105,110,118,85,0,59,121,0,
-0,18,117,0,59,121,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,105,110,118,85,0,59,122,0,0,18,117,
-0,59,122,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,
-0,59,120,121,122,0,0,18,97,0,0,18,105,110,118,85,0,59,120,121,122,0,0,0,0,1,90,95,0,0,11,0,2,22,1,
-1,0,0,11,0,118,0,0,1,1,0,0,9,0,98,0,0,0,1,3,2,90,95,0,0,9,0,1,105,110,118,66,0,0,0,4,102,108,111,
-97,116,95,114,99,112,0,18,105,110,118,66,0,0,18,98,0,0,0,4,118,101,99,52,95,109,117,108,116,105,
-112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,59,120,121,122,0,0,18,
-105,110,118,66,0,0,0,0,1,90,95,0,0,12,0,2,26,1,1,0,0,9,0,97,0,0,1,1,0,0,12,0,117,0,0,0,1,4,118,101,
-99,52,95,97,100,100,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,117,0,0,0,0,1,90,95,0,0,12,0,
-2,26,1,1,0,0,12,0,118,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,114,101,
-116,86,97,108,0,0,18,118,0,0,18,98,0,0,0,0,1,90,95,0,0,12,0,2,27,1,1,0,0,9,0,97,0,0,1,1,0,0,12,0,
-117,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,0,
-18,97,0,0,18,117,0,0,0,0,1,90,95,0,0,12,0,2,27,1,1,0,0,12,0,118,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,
-101,99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,18,98,0,
-0,0,0,1,90,95,0,0,12,0,2,21,1,1,0,0,9,0,97,0,0,1,1,0,0,12,0,117,0,0,0,1,4,118,101,99,52,95,109,117,
-108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,117,0,0,0,0,1,90,95,0,0,
-12,0,2,21,1,1,0,0,12,0,118,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,
-108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,18,98,0,0,0,0,1,90,95,0,0,12,0,2,22,1,1,0,
-0,9,0,97,0,0,1,1,0,0,12,0,117,0,0,0,1,3,2,90,95,0,0,12,0,1,105,110,118,85,0,0,0,4,102,108,111,97,
-116,95,114,99,112,0,18,105,110,118,85,0,59,120,0,0,18,117,0,59,120,0,0,0,4,102,108,111,97,116,95,
-114,99,112,0,18,105,110,118,85,0,59,121,0,0,18,117,0,59,121,0,0,0,4,102,108,111,97,116,95,114,99,
-112,0,18,105,110,118,85,0,59,122,0,0,18,117,0,59,122,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,
-105,110,118,85,0,59,119,0,0,18,117,0,59,119,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,
-121,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,105,110,118,85,0,0,0,0,1,90,95,0,0,12,0,2,22,
-1,1,0,0,12,0,118,0,0,1,1,0,0,9,0,98,0,0,0,1,3,2,90,95,0,0,9,0,1,105,110,118,66,0,0,0,4,102,108,111,
-97,116,95,114,99,112,0,18,105,110,118,66,0,0,18,98,0,0,0,4,118,101,99,52,95,109,117,108,116,105,
-112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,18,105,110,118,66,0,0,0,0,1,90,95,0,0,
-6,0,2,26,1,1,0,0,5,0,97,0,0,1,1,0,0,6,0,117,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,105,118,
-101,99,50,0,0,18,97,0,0,0,18,117,0,46,20,0,0,1,90,95,0,0,6,0,2,26,1,1,0,0,6,0,118,0,0,1,1,0,0,5,0,
-98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,58,105,118,101,99,50,0,0,18,98,0,0,0,46,20,
-0,0,1,90,95,0,0,6,0,2,27,1,1,0,0,5,0,97,0,0,1,1,0,0,6,0,117,0,0,0,1,9,18,95,95,114,101,116,86,97,
-108,0,58,105,118,101,99,50,0,0,18,97,0,0,0,18,117,0,47,20,0,0,1,90,95,0,0,6,0,2,27,1,1,0,0,6,0,118,
-0,0,1,1,0,0,5,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,58,105,118,101,99,50,0,0,18,
-98,0,0,0,47,20,0,0,1,90,95,0,0,6,0,2,21,1,1,0,0,5,0,97,0,0,1,1,0,0,6,0,117,0,0,0,1,9,18,95,95,114,
-101,116,86,97,108,0,58,105,118,101,99,50,0,0,18,97,0,0,0,18,117,0,48,20,0,0,1,90,95,0,0,6,0,2,21,1,
-1,0,0,6,0,118,0,0,1,1,0,0,5,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,58,105,118,
-101,99,50,0,0,18,98,0,0,0,48,20,0,0,1,90,95,0,0,6,0,2,22,1,1,0,0,5,0,97,0,0,1,1,0,0,6,0,117,0,0,0,
-1,9,18,95,95,114,101,116,86,97,108,0,58,105,118,101,99,50,0,0,18,97,0,0,0,18,117,0,49,20,0,0,1,90,
-95,0,0,6,0,2,22,1,1,0,0,6,0,118,0,0,1,1,0,0,5,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,
-118,0,58,105,118,101,99,50,0,0,18,98,0,0,0,49,20,0,0,1,90,95,0,0,7,0,2,26,1,1,0,0,5,0,97,0,0,1,1,0,
-0,7,0,117,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,105,118,101,99,51,0,0,18,97,0,0,0,18,117,0,
-46,20,0,0,1,90,95,0,0,7,0,2,26,1,1,0,0,7,0,118,0,0,1,1,0,0,5,0,98,0,0,0,1,9,18,95,95,114,101,116,
-86,97,108,0,18,118,0,58,105,118,101,99,51,0,0,18,98,0,0,0,46,20,0,0,1,90,95,0,0,7,0,2,27,1,1,0,0,5,
-0,97,0,0,1,1,0,0,7,0,117,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,105,118,101,99,51,0,0,18,97,
-0,0,0,18,117,0,47,20,0,0,1,90,95,0,0,7,0,2,27,1,1,0,0,7,0,118,0,0,1,1,0,0,5,0,98,0,0,0,1,9,18,95,
-95,114,101,116,86,97,108,0,18,118,0,58,105,118,101,99,51,0,0,18,98,0,0,0,47,20,0,0,1,90,95,0,0,7,0,
-2,21,1,1,0,0,5,0,97,0,0,1,1,0,0,7,0,117,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,105,118,101,
-99,51,0,0,18,97,0,0,0,18,117,0,48,20,0,0,1,90,95,0,0,7,0,2,21,1,1,0,0,7,0,118,0,0,1,1,0,0,5,0,98,0,
-0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,58,105,118,101,99,51,0,0,18,98,0,0,0,48,20,0,0,1,
-90,95,0,0,7,0,2,22,1,1,0,0,5,0,97,0,0,1,1,0,0,7,0,117,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,
-58,105,118,101,99,51,0,0,18,97,0,0,0,18,117,0,49,20,0,0,1,90,95,0,0,7,0,2,22,1,1,0,0,7,0,118,0,0,1,
-1,0,0,5,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,58,105,118,101,99,51,0,0,18,98,0,
-0,0,49,20,0,0,1,90,95,0,0,8,0,2,26,1,1,0,0,5,0,97,0,0,1,1,0,0,8,0,117,0,0,0,1,9,18,95,95,114,101,
-116,86,97,108,0,58,105,118,101,99,52,0,0,18,97,0,0,0,18,117,0,46,20,0,0,1,90,95,0,0,8,0,2,26,1,1,0,
-0,8,0,118,0,0,1,1,0,0,5,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,58,105,118,101,99,
-52,0,0,18,98,0,0,0,46,20,0,0,1,90,95,0,0,8,0,2,27,1,1,0,0,5,0,97,0,0,1,1,0,0,8,0,117,0,0,0,1,9,18,
-95,95,114,101,116,86,97,108,0,58,105,118,101,99,52,0,0,18,97,0,0,0,18,117,0,47,20,0,0,1,90,95,0,0,
-8,0,2,27,1,1,0,0,8,0,118,0,0,1,1,0,0,5,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,58,
-105,118,101,99,52,0,0,18,98,0,0,0,47,20,0,0,1,90,95,0,0,8,0,2,21,1,1,0,0,5,0,97,0,0,1,1,0,0,8,0,
-117,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,105,118,101,99,52,0,0,18,97,0,0,0,18,117,0,48,20,
-0,0,1,90,95,0,0,8,0,2,21,1,1,0,0,8,0,118,0,0,1,1,0,0,5,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,
-108,0,18,118,0,58,105,118,101,99,52,0,0,18,98,0,0,0,48,20,0,0,1,90,95,0,0,8,0,2,22,1,1,0,0,5,0,97,
-0,0,1,1,0,0,8,0,117,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,105,118,101,99,52,0,0,18,97,0,0,
-0,18,117,0,49,20,0,0,1,90,95,0,0,8,0,2,22,1,1,0,0,8,0,118,0,0,1,1,0,0,5,0,98,0,0,0,1,9,18,95,95,
-114,101,116,86,97,108,0,18,118,0,58,105,118,101,99,52,0,0,18,98,0,0,0,49,20,0,0,1,90,95,0,0,5,0,2,
-27,1,1,0,0,5,0,97,0,0,0,1,4,118,101,99,52,95,110,101,103,97,116,101,0,18,95,95,114,101,116,86,97,
-108,0,59,120,0,0,18,97,0,0,0,0,1,90,95,0,0,6,0,2,27,1,1,0,0,6,0,118,0,0,0,1,4,118,101,99,52,95,110,
-101,103,97,116,101,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,0,0,1,90,95,0,0,7,0,2,27,1,1,0,
-0,7,0,118,0,0,0,1,4,118,101,99,52,95,110,101,103,97,116,101,0,18,95,95,114,101,116,86,97,108,0,0,
-18,118,0,0,0,0,1,90,95,0,0,8,0,2,27,1,1,0,0,8,0,118,0,0,0,1,4,118,101,99,52,95,110,101,103,97,116,
-101,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,0,0,1,90,95,0,0,9,0,2,27,1,1,0,0,9,0,97,0,0,0,
-1,4,118,101,99,52,95,110,101,103,97,116,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,97,0,
-0,0,0,1,90,95,0,0,10,0,2,27,1,1,0,0,10,0,118,0,0,0,1,4,118,101,99,52,95,110,101,103,97,116,101,0,
-18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,118,0,59,120,121,0,0,0,0,1,90,95,0,0,11,0,2,27,
-1,1,0,0,11,0,118,0,0,0,1,4,118,101,99,52,95,110,101,103,97,116,101,0,18,95,95,114,101,116,86,97,
-108,0,59,120,121,122,0,0,18,118,0,59,120,121,122,0,0,0,0,1,90,95,0,0,12,0,2,27,1,1,0,0,12,0,118,0,
-0,0,1,4,118,101,99,52,95,110,101,103,97,116,101,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,0,
-0,1,90,95,0,0,13,0,2,27,1,1,0,0,13,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,
-18,109,0,16,8,48,0,57,54,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,
-57,54,20,0,0,1,90,95,0,0,14,0,2,27,1,1,0,0,14,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,
-8,48,0,57,18,109,0,16,8,48,0,57,54,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,
-16,10,49,0,57,54,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,54,
-20,0,0,1,90,95,0,0,15,0,2,27,1,1,0,0,15,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,
-57,18,109,0,16,8,48,0,57,54,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,
-49,0,57,54,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,54,20,0,9,
-18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,109,0,16,10,51,0,57,54,20,0,0,1,90,95,0,0,9,0,0,
-100,111,116,0,1,1,0,0,9,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,97,0,
-18,98,0,48,20,0,0,1,90,95,0,0,9,0,0,100,111,116,0,1,1,0,0,10,0,97,0,0,1,1,0,0,10,0,98,0,0,0,1,9,18,
-95,95,114,101,116,86,97,108,0,18,97,0,59,120,0,18,98,0,59,120,0,48,18,97,0,59,121,0,18,98,0,59,121,
-0,48,46,20,0,0,1,90,95,0,0,9,0,0,100,111,116,0,1,1,0,0,11,0,97,0,0,1,1,0,0,11,0,98,0,0,0,1,4,118,
-101,99,51,95,100,111,116,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,90,95,0,0,
-9,0,0,100,111,116,0,1,1,0,0,12,0,97,0,0,1,1,0,0,12,0,98,0,0,0,1,4,118,101,99,52,95,100,111,116,0,
-18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,90,95,0,0,5,0,2,1,1,0,2,0,5,0,97,0,0,
-1,1,0,0,5,0,98,0,0,0,1,9,18,97,0,18,97,0,18,98,0,46,20,0,8,18,97,0,0,0,1,90,95,0,0,5,0,2,2,1,0,2,0,
-5,0,97,0,0,1,1,0,0,5,0,98,0,0,0,1,9,18,97,0,18,97,0,18,98,0,47,20,0,8,18,97,0,0,0,1,90,95,0,0,5,0,
-2,3,1,0,2,0,5,0,97,0,0,1,1,0,0,5,0,98,0,0,0,1,9,18,97,0,18,97,0,18,98,0,48,20,0,8,18,97,0,0,0,1,90,
-95,0,0,5,0,2,4,1,0,2,0,5,0,97,0,0,1,1,0,0,5,0,98,0,0,0,1,9,18,97,0,18,97,0,18,98,0,49,20,0,8,18,97,
-0,0,0,1,90,95,0,0,6,0,2,1,1,0,2,0,6,0,118,0,0,1,1,0,0,6,0,117,0,0,0,1,9,18,118,0,18,118,0,18,117,0,
-46,20,0,8,18,118,0,0,0,1,90,95,0,0,6,0,2,2,1,0,2,0,6,0,118,0,0,1,1,0,0,6,0,117,0,0,0,1,9,18,118,0,
-18,118,0,18,117,0,47,20,0,8,18,118,0,0,0,1,90,95,0,0,6,0,2,3,1,0,2,0,6,0,118,0,0,1,1,0,0,6,0,117,0,
-0,0,1,9,18,118,0,18,118,0,18,117,0,48,20,0,8,18,118,0,0,0,1,90,95,0,0,6,0,2,4,1,0,2,0,6,0,118,0,0,
-1,1,0,0,6,0,117,0,0,0,1,9,18,118,0,18,118,0,18,117,0,49,20,0,8,18,118,0,0,0,1,90,95,0,0,7,0,2,1,1,
-0,2,0,7,0,118,0,0,1,1,0,0,7,0,117,0,0,0,1,9,18,118,0,18,118,0,18,117,0,46,20,0,8,18,118,0,0,0,1,90,
-95,0,0,7,0,2,2,1,0,2,0,7,0,118,0,0,1,1,0,0,7,0,117,0,0,0,1,9,18,118,0,18,118,0,18,117,0,47,20,0,8,
-18,118,0,0,0,1,90,95,0,0,7,0,2,3,1,0,2,0,7,0,118,0,0,1,1,0,0,7,0,117,0,0,0,1,9,18,118,0,18,118,0,
-18,117,0,48,20,0,8,18,118,0,0,0,1,90,95,0,0,7,0,2,4,1,0,2,0,7,0,118,0,0,1,1,0,0,7,0,117,0,0,0,1,9,
-18,118,0,18,118,0,18,117,0,49,20,0,8,18,118,0,0,0,1,90,95,0,0,8,0,2,1,1,0,2,0,8,0,118,0,0,1,1,0,0,
-8,0,117,0,0,0,1,9,18,118,0,18,118,0,18,117,0,46,20,0,8,18,118,0,0,0,1,90,95,0,0,8,0,2,2,1,0,2,0,8,
-0,118,0,0,1,1,0,0,8,0,117,0,0,0,1,9,18,118,0,18,118,0,18,117,0,47,20,0,8,18,118,0,0,0,1,90,95,0,0,
-8,0,2,3,1,0,2,0,8,0,118,0,0,1,1,0,0,8,0,117,0,0,0,1,9,18,118,0,18,118,0,18,117,0,48,20,0,8,18,118,
-0,0,0,1,90,95,0,0,8,0,2,4,1,0,2,0,8,0,118,0,0,1,1,0,0,8,0,117,0,0,0,1,9,18,118,0,18,118,0,18,117,0,
-49,20,0,8,18,118,0,0,0,1,90,95,0,0,9,0,2,1,1,0,2,0,9,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,9,18,97,0,18,
-97,0,18,98,0,46,20,0,8,18,97,0,0,0,1,90,95,0,0,9,0,2,2,1,0,2,0,9,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,9,
-18,97,0,18,97,0,18,98,0,47,20,0,8,18,97,0,0,0,1,90,95,0,0,9,0,2,3,1,0,2,0,9,0,97,0,0,1,1,0,0,9,0,
-98,0,0,0,1,9,18,97,0,18,97,0,18,98,0,48,20,0,8,18,97,0,0,0,1,90,95,0,0,9,0,2,4,1,0,2,0,9,0,97,0,0,
-1,1,0,0,9,0,98,0,0,0,1,9,18,97,0,18,97,0,18,98,0,49,20,0,8,18,97,0,0,0,1,90,95,0,0,10,0,2,1,1,0,2,
-0,10,0,118,0,0,1,1,0,0,10,0,117,0,0,0,1,9,18,118,0,18,118,0,18,117,0,46,20,0,8,18,118,0,0,0,1,90,
-95,0,0,10,0,2,2,1,0,2,0,10,0,118,0,0,1,1,0,0,10,0,117,0,0,0,1,9,18,118,0,18,118,0,18,117,0,47,20,0,
-8,18,118,0,0,0,1,90,95,0,0,10,0,2,3,1,0,2,0,10,0,118,0,0,1,1,0,0,10,0,117,0,0,0,1,9,18,118,0,18,
-118,0,18,117,0,48,20,0,8,18,118,0,0,0,1,90,95,0,0,10,0,2,4,1,0,2,0,10,0,118,0,0,1,1,0,0,10,0,117,0,
-0,0,1,9,18,118,0,18,118,0,18,117,0,49,20,0,8,18,118,0,0,0,1,90,95,0,0,11,0,2,1,1,0,2,0,11,0,118,0,
-0,1,1,0,0,11,0,117,0,0,0,1,9,18,118,0,18,118,0,18,117,0,46,20,0,8,18,118,0,0,0,1,90,95,0,0,11,0,2,
-2,1,0,2,0,11,0,118,0,0,1,1,0,0,11,0,117,0,0,0,1,9,18,118,0,18,118,0,18,117,0,47,20,0,8,18,118,0,0,
-0,1,90,95,0,0,11,0,2,3,1,0,2,0,11,0,118,0,0,1,1,0,0,11,0,117,0,0,0,1,9,18,118,0,18,118,0,18,117,0,
-48,20,0,8,18,118,0,0,0,1,90,95,0,0,11,0,2,4,1,0,2,0,11,0,118,0,0,1,1,0,0,11,0,117,0,0,0,1,9,18,118,
-0,18,118,0,18,117,0,49,20,0,8,18,118,0,0,0,1,90,95,0,0,12,0,2,1,1,0,2,0,12,0,118,0,0,1,1,0,0,12,0,
-117,0,0,0,1,9,18,118,0,18,118,0,18,117,0,46,20,0,8,18,118,0,0,0,1,90,95,0,0,12,0,2,2,1,0,2,0,12,0,
-118,0,0,1,1,0,0,12,0,117,0,0,0,1,9,18,118,0,18,118,0,18,117,0,47,20,0,8,18,118,0,0,0,1,90,95,0,0,
-12,0,2,3,1,0,2,0,12,0,118,0,0,1,1,0,0,12,0,117,0,0,0,1,9,18,118,0,18,118,0,18,117,0,48,20,0,8,18,
-118,0,0,0,1,90,95,0,0,12,0,2,4,1,0,2,0,12,0,118,0,0,1,1,0,0,12,0,117,0,0,0,1,9,18,118,0,18,118,0,
-18,117,0,49,20,0,8,18,118,0,0,0,1,90,95,0,0,6,0,2,1,1,0,2,0,6,0,118,0,0,1,1,0,0,5,0,97,0,0,0,1,9,
-18,118,0,18,118,0,58,105,118,101,99,50,0,0,18,97,0,0,0,46,20,0,8,18,118,0,0,0,1,90,95,0,0,6,0,2,2,
-1,0,2,0,6,0,118,0,0,1,1,0,0,5,0,97,0,0,0,1,9,18,118,0,18,118,0,58,105,118,101,99,50,0,0,18,97,0,0,
-0,47,20,0,8,18,118,0,0,0,1,90,95,0,0,6,0,2,3,1,0,2,0,6,0,118,0,0,1,1,0,0,5,0,97,0,0,0,1,9,18,118,0,
-18,118,0,58,105,118,101,99,50,0,0,18,97,0,0,0,48,20,0,8,18,118,0,0,0,1,90,95,0,0,6,0,2,4,1,0,2,0,6,
-0,118,0,0,1,1,0,0,5,0,97,0,0,0,1,9,18,118,0,18,118,0,58,105,118,101,99,50,0,0,18,97,0,0,0,49,20,0,
-8,18,118,0,0,0,1,90,95,0,0,7,0,2,1,1,0,2,0,7,0,118,0,0,1,1,0,0,5,0,97,0,0,0,1,9,18,118,0,18,118,0,
-58,105,118,101,99,51,0,0,18,97,0,0,0,46,20,0,8,18,118,0,0,0,1,90,95,0,0,7,0,2,2,1,0,2,0,7,0,118,0,
-0,1,1,0,0,5,0,97,0,0,0,1,9,18,118,0,18,118,0,58,105,118,101,99,51,0,0,18,97,0,0,0,47,20,0,8,18,118,
-0,0,0,1,90,95,0,0,7,0,2,3,1,0,2,0,7,0,118,0,0,1,1,0,0,5,0,97,0,0,0,1,9,18,118,0,18,118,0,58,105,
-118,101,99,51,0,0,18,97,0,0,0,48,20,0,8,18,118,0,0,0,1,90,95,0,0,8,0,2,4,1,0,2,0,7,0,118,0,0,1,1,0,
-0,5,0,97,0,0,0,1,9,18,118,0,18,118,0,58,105,118,101,99,51,0,0,18,97,0,0,0,49,20,0,8,18,118,0,0,0,1,
-90,95,0,0,8,0,2,1,1,0,2,0,8,0,118,0,0,1,1,0,0,5,0,97,0,0,0,1,9,18,118,0,18,118,0,58,105,118,101,99,
-52,0,0,18,97,0,0,0,46,20,0,8,18,118,0,0,0,1,90,95,0,0,8,0,2,2,1,0,2,0,8,0,118,0,0,1,1,0,0,5,0,97,0,
-0,0,1,9,18,118,0,18,118,0,58,105,118,101,99,52,0,0,18,97,0,0,0,47,20,0,8,18,118,0,0,0,1,90,95,0,0,
-8,0,2,3,1,0,2,0,8,0,118,0,0,1,1,0,0,5,0,97,0,0,0,1,9,18,118,0,18,118,0,58,105,118,101,99,52,0,0,18,
-97,0,0,0,48,20,0,8,18,118,0,0,0,1,90,95,0,0,8,0,2,4,1,0,2,0,8,0,118,0,0,1,1,0,0,5,0,97,0,0,0,1,9,
-18,118,0,18,118,0,58,105,118,101,99,52,0,0,18,97,0,0,0,49,20,0,8,18,118,0,0,0,1,90,95,0,0,10,0,2,1,
-1,0,2,0,10,0,118,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,118,0,18,118,0,58,118,101,99,50,0,0,18,97,0,0,0,
-46,20,0,8,18,118,0,0,0,1,90,95,0,0,10,0,2,2,1,0,2,0,10,0,118,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,118,0,
-18,118,0,58,118,101,99,50,0,0,18,97,0,0,0,47,20,0,8,18,118,0,0,0,1,90,95,0,0,10,0,2,3,1,0,2,0,10,0,
-118,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,118,0,18,118,0,58,118,101,99,50,0,0,18,97,0,0,0,48,20,0,8,18,
-118,0,0,0,1,90,95,0,0,10,0,2,4,1,0,2,0,10,0,118,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,118,0,18,118,0,58,
-118,101,99,50,0,0,18,97,0,0,0,49,20,0,8,18,118,0,0,0,1,90,95,0,0,11,0,2,1,1,0,2,0,11,0,118,0,0,1,1,
-0,0,9,0,97,0,0,0,1,9,18,118,0,18,118,0,58,118,101,99,51,0,0,18,97,0,0,0,46,20,0,8,18,118,0,0,0,1,
-90,95,0,0,11,0,2,2,1,0,2,0,11,0,118,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,118,0,18,118,0,58,118,101,99,
-51,0,0,18,97,0,0,0,47,20,0,8,18,118,0,0,0,1,90,95,0,0,11,0,2,3,1,0,2,0,11,0,118,0,0,1,1,0,0,9,0,97,
-0,0,0,1,9,18,118,0,18,118,0,58,118,101,99,51,0,0,18,97,0,0,0,48,20,0,8,18,118,0,0,0,1,90,95,0,0,11,
-0,2,4,1,0,2,0,11,0,118,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,118,0,18,118,0,58,118,101,99,51,0,0,18,97,0,
-0,0,49,20,0,8,18,118,0,0,0,1,90,95,0,0,12,0,2,1,1,0,2,0,12,0,118,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,
-118,0,18,118,0,58,118,101,99,52,0,0,18,97,0,0,0,46,20,0,8,18,118,0,0,0,1,90,95,0,0,12,0,2,2,1,0,2,
-0,12,0,118,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,118,0,18,118,0,58,118,101,99,52,0,0,18,97,0,0,0,47,20,0,
-8,18,118,0,0,0,1,90,95,0,0,12,0,2,3,1,0,2,0,12,0,118,0,0,1,1,0,0,9,0,97,0,0,0,1,9,18,118,0,18,118,
-0,58,118,101,99,52,0,0,18,97,0,0,0,48,20,0,8,18,118,0,0,0,1,90,95,0,0,12,0,2,4,1,0,2,0,12,0,118,0,
-0,1,1,0,0,9,0,97,0,0,0,1,9,18,118,0,18,118,0,58,118,101,99,52,0,0,18,97,0,0,0,49,20,0,8,18,118,0,0,
-0,1,90,95,0,0,13,0,2,26,1,1,0,0,13,0,109,0,0,1,1,0,0,13,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,
-108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,46,20,0,9,18,95,95,114,101,116,86,
-97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,46,20,0,0,1,90,95,0,0,13,0,2,
-27,1,1,0,0,13,0,109,0,0,1,1,0,0,13,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,
-18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,
-57,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,47,20,0,0,1,90,95,0,0,13,0,2,21,1,1,0,0,13,0,109,
-0,0,1,1,0,0,13,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,
-18,110,0,16,8,48,0,57,59,120,120,0,48,18,109,0,16,10,49,0,57,18,110,0,16,8,48,0,57,59,121,121,0,48,
-46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,8,48,0,57,18,110,0,16,10,49,0,
-57,59,120,120,0,48,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,59,121,121,0,48,46,20,0,0,1,90,95,
-0,0,13,0,2,22,1,1,0,0,13,0,109,0,0,1,1,0,0,13,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,
-8,48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,49,20,0,9,18,95,95,114,101,116,86,97,108,0,
-16,10,49,0,57,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,49,20,0,0,1,90,95,0,0,14,0,2,26,1,1,0,
-0,14,0,109,0,0,1,1,0,0,14,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,
-16,8,48,0,57,18,110,0,16,8,48,0,57,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,
-0,16,10,49,0,57,18,110,0,16,10,49,0,57,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,
-109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,46,20,0,0,1,90,95,0,0,14,0,2,27,1,1,0,0,14,0,109,0,0,1,
-1,0,0,14,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,
-110,0,16,8,48,0,57,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,
-18,110,0,16,10,49,0,57,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,
-0,57,18,110,0,16,10,50,0,57,47,20,0,0,1,90,95,0,0,14,0,2,21,1,1,0,0,14,0,109,0,0,1,1,0,0,14,0,110,
-0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,
-57,59,120,120,120,0,48,18,109,0,16,10,49,0,57,18,110,0,16,8,48,0,57,59,121,121,121,0,48,46,18,109,
-0,16,10,50,0,57,18,110,0,16,8,48,0,57,59,122,122,122,0,48,46,20,0,9,18,95,95,114,101,116,86,97,108,
-0,16,10,49,0,57,18,109,0,16,8,48,0,57,18,110,0,16,10,49,0,57,59,120,120,120,0,48,18,109,0,16,10,49,
-0,57,18,110,0,16,10,49,0,57,59,121,121,121,0,48,46,18,109,0,16,10,50,0,57,18,110,0,16,10,49,0,57,
-59,122,122,122,0,48,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,8,48,0,57,
-18,110,0,16,10,50,0,57,59,120,120,120,0,48,18,109,0,16,10,49,0,57,18,110,0,16,10,50,0,57,59,121,
-121,121,0,48,46,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,59,122,122,122,0,48,46,20,0,0,1,90,
-95,0,0,14,0,2,22,1,1,0,0,14,0,109,0,0,1,1,0,0,14,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,
-16,8,48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,49,20,0,9,18,95,95,114,101,116,86,97,108,
-0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,49,20,0,9,18,95,95,114,101,116,86,97,
-108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,49,20,0,0,1,90,95,0,0,15,0,2,26,
-1,1,0,0,15,0,109,0,0,1,1,0,0,15,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,
-109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,
-18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,
-0,57,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,
-10,51,0,57,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,46,20,0,0,1,90,95,0,0,15,0,2,27,1,1,0,0,
-15,0,109,0,0,1,1,0,0,15,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,
-8,48,0,57,18,110,0,16,8,48,0,57,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,
-16,10,49,0,57,18,110,0,16,10,49,0,57,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,
-109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,
-57,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,47,20,0,0,1,90,95,0,0,15,0,2,21,1,1,0,0,15,0,109,
-0,0,1,1,0,0,15,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,
-18,110,0,16,8,48,0,57,59,120,120,120,120,0,48,18,109,0,16,10,49,0,57,18,110,0,16,8,48,0,57,59,121,
-121,121,121,0,48,46,18,109,0,16,10,50,0,57,18,110,0,16,8,48,0,57,59,122,122,122,122,0,48,46,18,109,
-0,16,10,51,0,57,18,110,0,16,8,48,0,57,59,119,119,119,119,0,48,46,20,0,9,18,95,95,114,101,116,86,97,
-108,0,16,10,49,0,57,18,109,0,16,8,48,0,57,18,110,0,16,10,49,0,57,59,120,120,120,120,0,48,18,109,0,
-16,10,49,0,57,18,110,0,16,10,49,0,57,59,121,121,121,121,0,48,46,18,109,0,16,10,50,0,57,18,110,0,16,
-10,49,0,57,59,122,122,122,122,0,48,46,18,109,0,16,10,51,0,57,18,110,0,16,10,49,0,57,59,119,119,119,
-119,0,48,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,8,48,0,57,18,110,0,
-16,10,50,0,57,59,120,120,120,120,0,48,18,109,0,16,10,49,0,57,18,110,0,16,10,50,0,57,59,121,121,121,
-121,0,48,46,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,59,122,122,122,122,0,48,46,18,109,0,16,
-10,51,0,57,18,110,0,16,10,50,0,57,59,119,119,119,119,0,48,46,20,0,9,18,95,95,114,101,116,86,97,108,
-0,16,10,51,0,57,18,109,0,16,8,48,0,57,18,110,0,16,10,51,0,57,59,120,120,120,120,0,48,18,109,0,16,
-10,49,0,57,18,110,0,16,10,51,0,57,59,121,121,121,121,0,48,46,18,109,0,16,10,50,0,57,18,110,0,16,10,
-51,0,57,59,122,122,122,122,0,48,46,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,59,119,119,119,
-119,0,48,46,20,0,0,1,90,95,0,0,15,0,2,22,1,1,0,0,15,0,109,0,0,1,1,0,0,15,0,110,0,0,0,1,9,18,95,95,
-114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,49,20,0,9,18,95,
-95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,49,20,0,9,
-18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,49,20,
-0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,
-49,20,0,0,1,90,95,0,0,13,0,2,26,1,1,0,0,9,0,97,0,0,1,1,0,0,13,0,110,0,0,0,1,9,18,95,95,114,101,116,
-86,97,108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,46,20,0,9,18,95,95,114,101,116,86,97,108,0,
-16,10,49,0,57,18,97,0,18,110,0,16,10,49,0,57,46,20,0,0,1,90,95,0,0,13,0,2,26,1,1,0,0,13,0,109,0,0,
-1,1,0,0,9,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,
-0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,46,20,0,
-0,1,90,95,0,0,13,0,2,27,1,1,0,0,9,0,97,0,0,1,1,0,0,13,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,
-108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,
-49,0,57,18,97,0,18,110,0,16,10,49,0,57,47,20,0,0,1,90,95,0,0,13,0,2,27,1,1,0,0,13,0,109,0,0,1,1,0,
-0,9,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,47,
-20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,47,20,0,0,1,
-90,95,0,0,13,0,2,21,1,1,0,0,9,0,97,0,0,1,1,0,0,13,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,
-16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,
-57,18,97,0,18,110,0,16,10,49,0,57,48,20,0,0,1,90,95,0,0,13,0,2,21,1,1,0,0,13,0,109,0,0,1,1,0,0,9,0,
-98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,48,20,0,9,
-18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,48,20,0,0,1,90,95,0,
-0,13,0,2,22,1,1,0,0,9,0,97,0,0,1,1,0,0,13,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,
-0,57,18,97,0,18,110,0,16,8,48,0,57,49,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,97,
-0,18,110,0,16,10,49,0,57,49,20,0,0,1,90,95,0,0,13,0,2,22,1,1,0,0,13,0,109,0,0,1,1,0,0,9,0,98,0,0,0,
-1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,49,20,0,9,18,95,95,
-114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,49,20,0,0,1,90,95,0,0,14,0,2,
-26,1,1,0,0,9,0,97,0,0,1,1,0,0,14,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,
-97,0,18,110,0,16,8,48,0,57,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,
-0,16,10,49,0,57,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,97,0,18,110,0,16,10,50,
-0,57,46,20,0,0,1,90,95,0,0,14,0,2,26,1,1,0,0,14,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,9,18,95,95,114,
-101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,46,20,0,9,18,95,95,114,101,116,86,
-97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,
-16,10,50,0,57,18,109,0,16,10,50,0,57,18,98,0,46,20,0,0,1,90,95,0,0,14,0,2,27,1,1,0,0,9,0,97,0,0,1,
-1,0,0,14,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,
-57,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,0,16,10,49,0,57,47,20,0,
-9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,97,0,18,110,0,16,10,50,0,57,47,20,0,0,1,90,95,
-0,0,14,0,2,27,1,1,0,0,14,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,
-48,0,57,18,109,0,16,8,48,0,57,18,98,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,
-109,0,16,10,49,0,57,18,98,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,
-10,50,0,57,18,98,0,47,20,0,0,1,90,95,0,0,14,0,2,21,1,1,0,0,9,0,97,0,0,1,1,0,0,14,0,110,0,0,0,1,9,
-18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,
-101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,86,
-97,108,0,16,10,50,0,57,18,97,0,18,110,0,16,10,50,0,57,48,20,0,0,1,90,95,0,0,14,0,2,21,1,1,0,0,14,0,
-109,0,0,1,1,0,0,9,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,
-57,18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,
-48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,98,0,48,20,0,0,
-1,90,95,0,0,14,0,2,22,1,1,0,0,9,0,97,0,0,1,1,0,0,14,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,
-0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,49,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,
-57,18,97,0,18,110,0,16,10,49,0,57,49,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,97,0,
-18,110,0,16,10,50,0,57,49,20,0,0,1,90,95,0,0,14,0,2,22,1,1,0,0,14,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,
-9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,49,20,0,9,18,95,95,
-114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,49,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,98,0,49,20,0,0,1,90,95,0,0,15,0,2,26,1,1,0,
-0,9,0,97,0,0,1,1,0,0,15,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,97,0,18,
-110,0,16,8,48,0,57,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,0,16,10,
-49,0,57,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,97,0,18,110,0,16,10,50,0,57,46,
-20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,97,0,18,110,0,16,10,51,0,57,46,20,0,0,1,
-90,95,0,0,15,0,2,26,1,1,0,0,15,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,
-16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,
-57,18,109,0,16,10,49,0,57,18,98,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,
-0,16,10,50,0,57,18,98,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,109,0,16,10,51,
-0,57,18,98,0,46,20,0,0,1,90,95,0,0,15,0,2,27,1,1,0,0,9,0,97,0,0,1,1,0,0,15,0,110,0,0,0,1,9,18,95,
-95,114,101,116,86,97,108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,47,20,0,9,18,95,95,114,101,
-116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,0,16,10,49,0,57,47,20,0,9,18,95,95,114,101,116,86,97,
-108,0,16,10,50,0,57,18,97,0,18,110,0,16,10,50,0,57,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,
-10,51,0,57,18,97,0,18,110,0,16,10,51,0,57,47,20,0,0,1,90,95,0,0,15,0,2,27,1,1,0,0,15,0,109,0,0,1,1,
-0,0,9,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,
-47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,47,20,0,9,
-18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,98,0,47,20,0,9,18,95,95,
-114,101,116,86,97,108,0,16,10,51,0,57,18,109,0,16,10,51,0,57,18,98,0,47,20,0,0,1,90,95,0,0,15,0,2,
-21,1,1,0,0,9,0,97,0,0,1,1,0,0,15,0,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,
-97,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,
-0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,97,0,18,110,0,16,10,50,
-0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,97,0,18,110,0,16,10,51,0,57,48,20,
-0,0,1,90,95,0,0,15,0,2,21,1,1,0,0,15,0,109,0,0,1,1,0,0,9,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,
-108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,
-49,0,57,18,109,0,16,10,49,0,57,18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,
-109,0,16,10,50,0,57,18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,109,0,16,
-10,51,0,57,18,98,0,48,20,0,0,1,90,95,0,0,15,0,2,22,1,1,0,0,9,0,97,0,0,1,1,0,0,15,0,110,0,0,0,1,9,
-18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,49,20,0,9,18,95,95,114,
-101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,0,16,10,49,0,57,49,20,0,9,18,95,95,114,101,116,86,
-97,108,0,16,10,50,0,57,18,97,0,18,110,0,16,10,50,0,57,49,20,0,9,18,95,95,114,101,116,86,97,108,0,
-16,10,51,0,57,18,97,0,18,110,0,16,10,51,0,57,49,20,0,0,1,90,95,0,0,15,0,2,22,1,1,0,0,15,0,109,0,0,
-1,1,0,0,9,0,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,
-0,49,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,49,20,0,
-9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,98,0,49,20,0,9,18,95,95,
-114,101,116,86,97,108,0,16,10,51,0,57,18,109,0,16,10,51,0,57,18,98,0,49,20,0,0,1,90,95,0,0,10,0,2,
-21,1,1,0,0,13,0,109,0,0,1,1,0,0,10,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,109,0,16,8,
-48,0,57,18,118,0,59,120,120,0,48,18,109,0,16,10,49,0,57,18,118,0,59,121,121,0,48,46,20,0,0,1,90,95,
-0,0,10,0,2,21,1,1,0,0,10,0,118,0,0,1,1,0,0,13,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,
-120,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,8,48,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,
-108,0,59,121,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,10,49,0,57,0,0,20,0,0,1,90,95,0,0,11,0,2,
-21,1,1,0,0,14,0,109,0,0,1,1,0,0,11,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,109,0,16,8,
-48,0,57,18,118,0,59,120,120,120,0,48,18,109,0,16,10,49,0,57,18,118,0,59,121,121,121,0,48,46,18,109,
-0,16,10,50,0,57,18,118,0,59,122,122,122,0,48,46,20,0,0,1,90,95,0,0,11,0,2,21,1,1,0,0,11,0,118,0,0,
-1,1,0,0,14,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,100,111,116,0,0,18,118,0,0,
-18,109,0,16,8,48,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,100,111,116,0,0,18,
-118,0,0,18,109,0,16,10,49,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,100,111,116,
-0,0,18,118,0,0,18,109,0,16,10,50,0,57,0,0,20,0,0,1,90,95,0,0,12,0,2,21,1,1,0,0,15,0,109,0,0,1,1,0,
-0,12,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,109,0,16,8,48,0,57,18,118,0,59,120,120,
-120,120,0,48,18,109,0,16,10,49,0,57,18,118,0,59,121,121,121,121,0,48,46,18,109,0,16,10,50,0,57,18,
-118,0,59,122,122,122,122,0,48,46,18,109,0,16,10,51,0,57,18,118,0,59,119,119,119,119,0,48,46,20,0,0,
-1,90,95,0,0,12,0,2,21,1,1,0,0,12,0,118,0,0,1,1,0,0,15,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,
-108,0,59,120,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,8,48,0,57,0,0,20,0,9,18,95,95,114,101,116,
-86,97,108,0,59,121,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,10,49,0,57,0,0,20,0,9,18,95,95,114,
-101,116,86,97,108,0,59,122,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,10,50,0,57,0,0,20,0,9,18,95,
-95,114,101,116,86,97,108,0,59,119,0,58,100,111,116,0,0,18,118,0,0,18,109,0,16,10,51,0,57,0,0,20,0,
-0,1,90,95,0,0,13,0,2,1,1,0,2,0,13,0,109,0,0,1,1,0,0,13,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,
-109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,46,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,
-18,110,0,16,10,49,0,57,46,20,0,8,18,109,0,0,0,1,90,95,0,0,13,0,2,2,1,0,2,0,13,0,109,0,0,1,1,0,0,13,
-0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,47,20,0,9,18,109,
-0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,47,20,0,8,18,109,0,0,0,1,90,95,0,0,
-13,0,2,3,1,0,2,0,13,0,109,0,0,1,1,0,0,13,0,110,0,0,0,1,9,18,109,0,18,109,0,18,110,0,48,20,0,8,18,
-109,0,0,0,1,90,95,0,0,13,0,2,4,1,0,2,0,13,0,109,0,0,1,1,0,0,13,0,110,0,0,0,1,9,18,109,0,16,8,48,0,
-57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,49,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,
-0,57,18,110,0,16,10,49,0,57,49,20,0,8,18,109,0,0,0,1,90,95,0,0,14,0,2,1,1,0,2,0,14,0,109,0,0,1,1,0,
-0,14,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,46,20,0,9,
-18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,46,20,0,9,18,109,0,16,10,50,0,
-57,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,46,20,0,8,18,109,0,0,0,1,90,95,0,0,14,0,2,2,1,0,2,
-0,14,0,109,0,0,1,1,0,0,14,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,
-8,48,0,57,47,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,47,20,0,9,
-18,109,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,47,20,0,8,18,109,0,0,0,1,90,
-95,0,0,14,0,2,3,1,0,2,0,14,0,109,0,0,1,1,0,0,14,0,110,0,0,0,1,9,18,109,0,18,109,0,18,110,0,48,20,0,
-8,18,109,0,0,0,1,90,95,0,0,14,0,2,4,1,0,2,0,14,0,109,0,0,1,1,0,0,14,0,110,0,0,0,1,9,18,109,0,16,8,
-48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,49,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,
-10,49,0,57,18,110,0,16,10,49,0,57,49,20,0,9,18,109,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,110,0,
-16,10,50,0,57,49,20,0,8,18,109,0,0,0,1,90,95,0,0,15,0,2,1,1,0,2,0,15,0,109,0,0,1,1,0,0,15,0,110,0,
-0,0,1,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,46,20,0,9,18,109,0,16,10,
-49,0,57,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,46,20,0,9,18,109,0,16,10,50,0,57,18,109,0,16,
-10,50,0,57,18,110,0,16,10,50,0,57,46,20,0,9,18,109,0,16,10,51,0,57,18,109,0,16,10,51,0,57,18,110,0,
-16,10,51,0,57,46,20,0,8,18,109,0,0,0,1,90,95,0,0,15,0,2,2,1,0,2,0,15,0,109,0,0,1,1,0,0,15,0,110,0,
-0,0,1,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,47,20,0,9,18,109,0,16,10,
-49,0,57,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,47,20,0,9,18,109,0,16,10,50,0,57,18,109,0,16,
-10,50,0,57,18,110,0,16,10,50,0,57,47,20,0,9,18,109,0,16,10,51,0,57,18,109,0,16,10,51,0,57,18,110,0,
-16,10,51,0,57,47,20,0,8,18,109,0,0,0,1,90,95,0,0,15,0,2,3,1,0,2,0,15,0,109,0,0,1,1,0,0,15,0,110,0,
-0,0,1,9,18,109,0,18,109,0,18,110,0,48,20,0,8,18,109,0,0,0,1,90,95,0,0,15,0,2,4,1,0,2,0,15,0,109,0,
-0,1,1,0,0,15,0,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,49,
-20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,49,20,0,9,18,109,0,16,
-10,50,0,57,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,49,20,0,9,18,109,0,16,10,51,0,57,18,109,0,
-16,10,51,0,57,18,110,0,16,10,51,0,57,49,20,0,8,18,109,0,0,0,1,90,95,0,0,13,0,2,1,1,0,2,0,13,0,109,
-0,0,1,1,0,0,9,0,97,0,0,0,1,3,2,90,95,0,0,10,0,1,118,0,2,58,118,101,99,50,0,0,18,97,0,0,0,0,0,9,18,
-109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,118,0,46,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,
-49,0,57,18,118,0,46,20,0,8,18,109,0,0,0,1,90,95,0,0,13,0,2,2,1,0,2,0,13,0,109,0,0,1,1,0,0,9,0,97,0,
-0,0,1,3,2,90,95,0,0,10,0,1,118,0,2,58,118,101,99,50,0,0,18,97,0,0,0,0,0,9,18,109,0,16,8,48,0,57,18,
-109,0,16,8,48,0,57,18,118,0,47,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,118,0,47,20,
-0,8,18,109,0,0,0,1,90,95,0,0,13,0,2,3,1,0,2,0,13,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,3,2,90,95,0,0,10,
-0,1,118,0,2,58,118,101,99,50,0,0,18,97,0,0,0,0,0,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,
-118,0,48,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,118,0,48,20,0,8,18,109,0,0,0,1,90,
-95,0,0,13,0,2,4,1,0,2,0,13,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,3,2,90,95,0,0,10,0,1,118,0,2,58,118,
-101,99,50,0,0,17,49,0,48,0,0,18,97,0,49,0,0,0,0,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,
-118,0,48,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,118,0,48,20,0,8,18,109,0,0,0,1,90,
-95,0,0,14,0,2,1,1,0,2,0,14,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,3,2,90,95,0,0,11,0,1,118,0,2,58,118,
-101,99,51,0,0,18,97,0,0,0,0,0,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,118,0,46,20,0,9,18,
-109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,118,0,46,20,0,9,18,109,0,16,10,50,0,57,18,109,0,16,
-10,50,0,57,18,118,0,46,20,0,8,18,109,0,0,0,1,90,95,0,0,14,0,2,2,1,0,2,0,14,0,109,0,0,1,1,0,0,9,0,
-97,0,0,0,1,3,2,90,95,0,0,11,0,1,118,0,2,58,118,101,99,51,0,0,18,97,0,0,0,0,0,9,18,109,0,16,8,48,0,
-57,18,109,0,16,8,48,0,57,18,118,0,47,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,118,0,
-47,20,0,9,18,109,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,118,0,47,20,0,8,18,109,0,0,0,1,90,95,0,
-0,14,0,2,3,1,0,2,0,14,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,3,2,90,95,0,0,11,0,1,118,0,2,58,118,101,99,
-51,0,0,18,97,0,0,0,0,0,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,118,0,48,20,0,9,18,109,0,
-16,10,49,0,57,18,109,0,16,10,49,0,57,18,118,0,48,20,0,9,18,109,0,16,10,50,0,57,18,109,0,16,10,50,0,
-57,18,118,0,48,20,0,8,18,109,0,0,0,1,90,95,0,0,14,0,2,4,1,0,2,0,14,0,109,0,0,1,1,0,0,9,0,97,0,0,0,
-1,3,2,90,95,0,0,11,0,1,118,0,2,58,118,101,99,51,0,0,17,49,0,48,0,0,18,97,0,49,0,0,0,0,9,18,109,0,
-16,8,48,0,57,18,109,0,16,8,48,0,57,18,118,0,48,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,
-57,18,118,0,48,20,0,9,18,109,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,118,0,48,20,0,8,18,109,0,0,
-0,1,90,95,0,0,15,0,2,1,1,0,2,0,15,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,3,2,90,95,0,0,12,0,1,118,0,2,58,
-118,101,99,52,0,0,18,97,0,0,0,0,0,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,118,0,46,20,0,9,
-18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,118,0,46,20,0,9,18,109,0,16,10,50,0,57,18,109,0,
-16,10,50,0,57,18,118,0,46,20,0,9,18,109,0,16,10,51,0,57,18,109,0,16,10,51,0,57,18,118,0,46,20,0,8,
-18,109,0,0,0,1,90,95,0,0,15,0,2,2,1,0,2,0,15,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,3,2,90,95,0,0,12,0,1,
-118,0,2,58,118,101,99,52,0,0,18,97,0,0,0,0,0,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,118,
-0,47,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,118,0,47,20,0,9,18,109,0,16,10,50,0,
-57,18,109,0,16,10,50,0,57,18,118,0,47,20,0,9,18,109,0,16,10,51,0,57,18,109,0,16,10,51,0,57,18,118,
-0,47,20,0,8,18,109,0,0,0,1,90,95,0,0,15,0,2,3,1,0,2,0,15,0,109,0,0,1,1,0,0,9,0,97,0,0,0,1,3,2,90,
-95,0,0,12,0,1,118,0,2,58,118,101,99,52,0,0,18,97,0,0,0,0,0,9,18,109,0,16,8,48,0,57,18,109,0,16,8,
-48,0,57,18,118,0,48,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,118,0,48,20,0,9,18,109,
-0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,118,0,48,20,0,9,18,109,0,16,10,51,0,57,18,109,0,16,10,51,
-0,57,18,118,0,48,20,0,8,18,109,0,0,0,1,90,95,0,0,15,0,2,4,1,0,2,0,15,0,109,0,0,1,1,0,0,9,0,97,0,0,
-0,1,3,2,90,95,0,0,12,0,1,118,0,2,58,118,101,99,52,0,0,17,49,0,48,0,0,18,97,0,49,0,0,0,0,9,18,109,0,
-16,8,48,0,57,18,109,0,16,8,48,0,57,18,118,0,48,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,
-57,18,118,0,48,20,0,9,18,109,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,118,0,48,20,0,9,18,109,0,16,
-10,51,0,57,18,109,0,16,10,51,0,57,18,118,0,48,20,0,8,18,109,0,0,0,1,90,95,0,0,10,0,2,3,1,0,2,0,10,
-0,118,0,0,1,1,0,0,13,0,109,0,0,0,1,9,18,118,0,18,118,0,18,109,0,48,20,0,8,18,118,0,0,0,1,90,95,0,0,
-11,0,2,3,1,0,2,0,11,0,118,0,0,1,1,0,0,14,0,109,0,0,0,1,9,18,118,0,18,118,0,18,109,0,48,20,0,8,18,
-118,0,0,0,1,90,95,0,0,12,0,2,3,1,0,2,0,12,0,118,0,0,1,1,0,0,15,0,109,0,0,0,1,9,18,118,0,18,118,0,
-18,109,0,48,20,0,8,18,118,0,0,0,1,90,95,0,0,5,0,2,25,1,0,2,0,5,0,97,0,0,0,1,9,18,97,0,18,97,0,16,
-10,49,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,18,97,0,20,0,0,1,90,95,0,0,6,0,2,25,1,0,2,0,6,0,
-118,0,0,0,1,9,18,118,0,18,118,0,58,105,118,101,99,50,0,0,16,10,49,0,0,0,47,20,0,9,18,95,95,114,101,
-116,86,97,108,0,18,118,0,20,0,0,1,90,95,0,0,7,0,2,25,1,0,2,0,7,0,118,0,0,0,1,9,18,118,0,18,118,0,
-58,105,118,101,99,51,0,0,16,10,49,0,0,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,0,
-1,90,95,0,0,8,0,2,25,1,0,2,0,8,0,118,0,0,0,1,9,18,118,0,18,118,0,58,105,118,101,99,52,0,0,16,10,49,
-0,0,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,0,1,90,95,0,0,9,0,2,25,1,0,2,0,9,0,
-97,0,0,0,1,9,18,97,0,18,97,0,17,49,0,48,0,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,18,97,0,20,
-0,0,1,90,95,0,0,10,0,2,25,1,0,2,0,10,0,118,0,0,0,1,9,18,118,0,18,118,0,58,118,101,99,50,0,0,17,49,
-0,48,0,0,0,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,0,1,90,95,0,0,11,0,2,25,1,0,
-2,0,11,0,118,0,0,0,1,9,18,118,0,18,118,0,58,118,101,99,51,0,0,17,49,0,48,0,0,0,0,47,20,0,9,18,95,
-95,114,101,116,86,97,108,0,18,118,0,20,0,0,1,90,95,0,0,12,0,2,25,1,0,2,0,12,0,118,0,0,0,1,9,18,118,
-0,18,118,0,58,118,101,99,52,0,0,17,49,0,48,0,0,0,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,18,
-118,0,20,0,0,1,90,95,0,0,13,0,2,25,1,0,2,0,13,0,109,0,0,0,1,9,18,109,0,16,8,48,0,57,18,109,0,16,8,
-48,0,57,58,118,101,99,50,0,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,
-0,57,58,118,101,99,50,0,0,17,49,0,48,0,0,0,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,18,109,0,
-20,0,0,1,90,95,0,0,14,0,2,25,1,0,2,0,14,0,109,0,0,0,1,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,
-57,58,118,101,99,51,0,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,
-58,118,101,99,51,0,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,50,0,57,18,109,0,16,10,50,0,57,58,
-118,101,99,51,0,0,17,49,0,48,0,0,0,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,
-90,95,0,0,15,0,2,25,1,0,2,0,15,0,109,0,0,0,1,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,58,118,
-101,99,52,0,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,58,118,
-101,99,52,0,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,50,0,57,18,109,0,16,10,50,0,57,58,118,
-101,99,52,0,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,51,0,57,18,109,0,16,10,51,0,57,58,118,
-101,99,52,0,0,17,49,0,48,0,0,0,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,90,
-95,0,0,5,0,2,24,1,0,2,0,5,0,97,0,0,0,1,9,18,97,0,18,97,0,16,10,49,0,46,20,0,9,18,95,95,114,101,116,
-86,97,108,0,18,97,0,20,0,0,1,90,95,0,0,6,0,2,24,1,0,2,0,6,0,118,0,0,0,1,9,18,118,0,18,118,0,58,105,
-118,101,99,50,0,0,16,10,49,0,0,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,0,1,90,
-95,0,0,7,0,2,24,1,0,2,0,7,0,118,0,0,0,1,9,18,118,0,18,118,0,58,105,118,101,99,51,0,0,16,10,49,0,0,
-0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,0,1,90,95,0,0,8,0,2,24,1,0,2,0,8,0,118,
-0,0,0,1,9,18,118,0,18,118,0,58,105,118,101,99,52,0,0,16,10,49,0,0,0,46,20,0,9,18,95,95,114,101,116,
-86,97,108,0,18,118,0,20,0,0,1,90,95,0,0,9,0,2,24,1,0,2,0,9,0,97,0,0,0,1,9,18,97,0,18,97,0,17,49,0,
-48,0,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,18,97,0,20,0,0,1,90,95,0,0,10,0,2,24,1,0,2,0,10,
-0,118,0,0,0,1,9,18,118,0,18,118,0,58,118,101,99,50,0,0,17,49,0,48,0,0,0,0,46,20,0,9,18,95,95,114,
-101,116,86,97,108,0,18,118,0,20,0,0,1,90,95,0,0,11,0,2,24,1,0,2,0,11,0,118,0,0,0,1,9,18,118,0,18,
-118,0,58,118,101,99,51,0,0,17,49,0,48,0,0,0,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,18,118,0,
-20,0,0,1,90,95,0,0,12,0,2,24,1,0,2,0,12,0,118,0,0,0,1,9,18,118,0,18,118,0,58,118,101,99,52,0,0,17,
-49,0,48,0,0,0,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,0,1,90,95,0,0,13,0,2,24,1,
-0,2,0,13,0,109,0,0,0,1,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,58,118,101,99,50,0,0,17,49,0,
-48,0,0,0,0,46,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,58,118,101,99,50,0,0,17,49,0,48,
-0,0,0,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,90,95,0,0,14,0,2,24,1,0,2,0,
-14,0,109,0,0,0,1,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,58,118,101,99,51,0,0,17,49,0,48,0,0,
-0,0,46,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,58,118,101,99,51,0,0,17,49,0,48,0,0,0,
-0,46,20,0,9,18,109,0,16,10,50,0,57,18,109,0,16,10,50,0,57,58,118,101,99,51,0,0,17,49,0,48,0,0,0,0,
-46,20,0,9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,90,95,0,0,15,0,2,24,1,0,2,0,15,0,109,
-0,0,0,1,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,58,118,101,99,52,0,0,17,49,0,48,0,0,0,0,46,
-20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,58,118,101,99,52,0,0,17,49,0,48,0,0,0,0,46,20,
-0,9,18,109,0,16,10,50,0,57,18,109,0,16,10,50,0,57,58,118,101,99,52,0,0,17,49,0,48,0,0,0,0,46,20,0,
-9,18,109,0,16,10,51,0,57,18,109,0,16,10,51,0,57,58,118,101,99,52,0,0,17,49,0,48,0,0,0,0,46,20,0,9,
-18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,90,95,0,0,5,0,0,95,95,112,111,115,116,68,101,99,
-114,0,1,0,2,0,5,0,97,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,97,0,20,0,9,18,97,0,18,97,0,16,
-10,49,0,47,20,0,0,1,90,95,0,0,6,0,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,0,6,0,118,0,0,0,1,
-9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,9,18,118,0,18,118,0,58,105,118,101,99,50,0,0,16,
-10,49,0,0,0,47,20,0,0,1,90,95,0,0,7,0,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,0,7,0,118,0,0,
-0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,9,18,118,0,18,118,0,58,105,118,101,99,51,0,0,
-16,10,49,0,0,0,47,20,0,0,1,90,95,0,0,8,0,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,0,8,0,118,0,
-0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,9,18,118,0,18,118,0,58,105,118,101,99,52,0,
-0,16,10,49,0,0,0,47,20,0,0,1,90,95,0,0,9,0,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,0,9,0,97,
-0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,97,0,20,0,9,18,97,0,18,97,0,17,49,0,48,0,0,47,20,0,0,
-1,90,95,0,0,10,0,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,0,10,0,118,0,0,0,1,9,18,95,95,114,
-101,116,86,97,108,0,18,118,0,20,0,9,18,118,0,18,118,0,58,118,101,99,50,0,0,17,49,0,48,0,0,0,0,47,
-20,0,0,1,90,95,0,0,11,0,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,0,11,0,118,0,0,0,1,9,18,95,
-95,114,101,116,86,97,108,0,18,118,0,20,0,9,18,118,0,18,118,0,58,118,101,99,51,0,0,17,49,0,48,0,0,0,
-0,47,20,0,0,1,90,95,0,0,12,0,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,0,12,0,118,0,0,0,1,9,18,
-95,95,114,101,116,86,97,108,0,18,118,0,20,0,9,18,118,0,18,118,0,58,118,101,99,52,0,0,17,49,0,48,0,
-0,0,0,47,20,0,0,1,90,95,0,0,13,0,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,0,13,0,109,0,0,0,1,
-9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,58,
-118,101,99,50,0,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,58,
-118,101,99,50,0,0,17,49,0,48,0,0,0,0,47,20,0,0,1,90,95,0,0,14,0,0,95,95,112,111,115,116,68,101,99,
-114,0,1,0,2,0,14,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,9,18,109,0,16,8,48,
-0,57,18,109,0,16,8,48,0,57,58,118,101,99,51,0,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,49,0,
-57,18,109,0,16,10,49,0,57,58,118,101,99,51,0,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,50,0,57,
-18,109,0,16,10,50,0,57,58,118,101,99,51,0,0,17,49,0,48,0,0,0,0,47,20,0,0,1,90,95,0,0,15,0,0,95,95,
-112,111,115,116,68,101,99,114,0,1,0,2,0,15,0,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,109,
-0,20,0,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,58,118,101,99,52,0,0,17,49,0,48,0,0,0,0,47,20,
-0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,58,118,101,99,52,0,0,17,49,0,48,0,0,0,0,47,20,0,
-9,18,109,0,16,10,50,0,57,18,109,0,16,10,50,0,57,58,118,101,99,52,0,0,17,49,0,48,0,0,0,0,47,20,0,9,
-18,109,0,16,10,51,0,57,18,109,0,16,10,51,0,57,58,118,101,99,52,0,0,17,49,0,48,0,0,0,0,47,20,0,0,1,
-90,95,0,0,9,0,0,95,95,112,111,115,116,73,110,99,114,0,1,0,2,0,9,0,97,0,0,0,1,9,18,95,95,114,101,
-116,86,97,108,0,18,97,0,20,0,9,18,97,0,18,97,0,16,10,49,0,46,20,0,0,1,90,95,0,0,10,0,0,95,95,112,
-111,115,116,73,110,99,114,0,1,0,2,0,10,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,
-20,0,9,18,118,0,18,118,0,58,118,101,99,50,0,0,17,49,0,48,0,0,0,0,46,20,0,0,1,90,95,0,0,11,0,0,95,
-95,112,111,115,116,73,110,99,114,0,1,0,2,0,11,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,
-118,0,20,0,9,18,118,0,18,118,0,58,118,101,99,51,0,0,17,49,0,48,0,0,0,0,46,20,0,0,1,90,95,0,0,12,0,
-0,95,95,112,111,115,116,73,110,99,114,0,1,0,2,0,12,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,
-0,18,118,0,20,0,9,18,118,0,18,118,0,58,118,101,99,52,0,0,17,49,0,48,0,0,0,0,46,20,0,0,1,90,95,0,0,
-5,0,0,95,95,112,111,115,116,73,110,99,114,0,1,0,2,0,5,0,97,0,0,0,1,9,18,95,95,114,101,116,86,97,
-108,0,18,97,0,20,0,9,18,97,0,18,97,0,16,10,49,0,46,20,0,0,1,90,95,0,0,6,0,0,95,95,112,111,115,116,
-73,110,99,114,0,1,0,2,0,6,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,9,18,118,
-0,18,118,0,58,105,118,101,99,50,0,0,16,10,49,0,0,0,46,20,0,0,1,90,95,0,0,7,0,0,95,95,112,111,115,
-116,73,110,99,114,0,1,0,2,0,7,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,9,18,
-118,0,18,118,0,58,105,118,101,99,51,0,0,16,10,49,0,0,0,46,20,0,0,1,90,95,0,0,8,0,0,95,95,112,111,
-115,116,73,110,99,114,0,1,0,2,0,8,0,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,9,
-18,118,0,18,118,0,58,105,118,101,99,51,0,0,16,10,49,0,0,0,46,20,0,0,1,90,95,0,0,13,0,0,95,95,112,
-111,115,116,73,110,99,114,0,1,0,2,0,13,0,109,0,0,0,1,3,2,90,95,0,0,13,0,1,110,0,2,18,109,0,0,0,9,
-18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,58,118,101,99,50,0,0,17,49,0,48,0,0,0,0,46,20,0,9,18,
-109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,58,118,101,99,50,0,0,17,49,0,48,0,0,0,0,46,20,0,8,18,
-110,0,0,0,1,90,95,0,0,14,0,0,95,95,112,111,115,116,73,110,99,114,0,1,0,2,0,14,0,109,0,0,0,1,3,2,90,
-95,0,0,14,0,1,110,0,2,18,109,0,0,0,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,58,118,101,99,51,
-0,0,17,49,0,48,0,0,0,0,46,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,58,118,101,99,51,0,
-0,17,49,0,48,0,0,0,0,46,20,0,9,18,109,0,16,10,50,0,57,18,109,0,16,10,50,0,57,58,118,101,99,51,0,0,
-17,49,0,48,0,0,0,0,46,20,0,8,18,110,0,0,0,1,90,95,0,0,15,0,0,95,95,112,111,115,116,73,110,99,114,0,
-1,0,2,0,15,0,109,0,0,0,1,3,2,90,95,0,0,15,0,1,110,0,2,18,109,0,0,0,9,18,109,0,16,8,48,0,57,18,109,
-0,16,8,48,0,57,58,118,101,99,52,0,0,17,49,0,48,0,0,0,0,46,20,0,9,18,109,0,16,10,49,0,57,18,109,0,
-16,10,49,0,57,58,118,101,99,52,0,0,17,49,0,48,0,0,0,0,46,20,0,9,18,109,0,16,10,50,0,57,18,109,0,16,
-10,50,0,57,58,118,101,99,52,0,0,17,49,0,48,0,0,0,0,46,20,0,9,18,109,0,16,10,51,0,57,18,109,0,16,10,
-51,0,57,58,118,101,99,52,0,0,17,49,0,48,0,0,0,0,46,20,0,8,18,110,0,0,0,1,90,95,0,0,1,0,2,15,1,1,0,
-0,9,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,
-108,0,59,120,0,0,18,98,0,0,18,97,0,0,0,0,1,90,95,0,0,1,0,2,15,1,1,0,0,5,0,97,0,0,1,1,0,0,5,0,98,0,
-0,0,1,8,58,102,108,111,97,116,0,0,18,97,0,0,0,58,102,108,111,97,116,0,0,18,98,0,0,0,40,0,0,1,90,95,
-0,0,1,0,2,16,1,1,0,0,9,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,3,2,90,95,0,0,1,0,1,99,0,0,0,4,102,108,111,
-97,116,95,108,101,115,115,0,18,99,0,0,18,98,0,0,18,97,0,0,0,8,18,99,0,0,0,1,90,95,0,0,1,0,2,16,1,1,
-0,0,5,0,97,0,0,1,1,0,0,5,0,98,0,0,0,1,8,58,102,108,111,97,116,0,0,18,97,0,0,0,58,102,108,111,97,
-116,0,0,18,98,0,0,0,41,0,0,1,90,95,0,0,1,0,2,18,1,1,0,0,9,0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,3,2,90,
-95,0,0,1,0,1,103,0,0,1,1,101,0,0,0,4,102,108,111,97,116,95,108,101,115,115,0,18,103,0,0,18,98,0,0,
-18,97,0,0,0,4,102,108,111,97,116,95,101,113,117,97,108,0,18,101,0,0,18,97,0,0,18,98,0,0,0,8,18,103,
-0,18,101,0,32,0,0,1,90,95,0,0,1,0,2,18,1,1,0,0,5,0,97,0,0,1,1,0,0,5,0,98,0,0,0,1,8,58,102,108,111,
-97,116,0,0,18,97,0,0,0,58,102,108,111,97,116,0,0,18,98,0,0,0,43,0,0,1,90,95,0,0,1,0,2,17,1,1,0,0,9,
-0,97,0,0,1,1,0,0,9,0,98,0,0,0,1,3,2,90,95,0,0,1,0,1,103,0,0,1,1,101,0,0,0,4,102,108,111,97,116,95,
-108,101,115,115,0,18,103,0,0,18,97,0,0,18,98,0,0,0,4,102,108,111,97,116,95,101,113,117,97,108,0,18,
-101,0,0,18,97,0,0,18,98,0,0,0,8,18,103,0,18,101,0,32,0,0,1,90,95,0,0,1,0,2,17,1,1,0,0,5,0,97,0,0,1,
-1,0,0,5,0,98,0,0,0,1,8,58,102,108,111,97,116,0,0,18,97,0,0,0,58,102,108,111,97,116,0,0,18,98,0,0,0,
-42,0,0,1,90,95,0,0,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,0,9,0,102,0,0,0,1,4,102,108,111,
-97,116,95,112,114,105,110,116,0,18,102,0,0,0,0,1,90,95,0,0,0,0,0,112,114,105,110,116,77,69,83,65,0,
-1,1,0,0,5,0,105,0,0,0,1,4,105,110,116,95,112,114,105,110,116,0,18,105,0,0,0,0,1,90,95,0,0,0,0,0,
-112,114,105,110,116,77,69,83,65,0,1,1,0,0,1,0,98,0,0,0,1,4,98,111,111,108,95,112,114,105,110,116,0,
-18,98,0,0,0,0,1,90,95,0,0,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,0,10,0,118,0,0,0,1,9,58,
-112,114,105,110,116,77,69,83,65,0,0,18,118,0,59,120,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,
-0,18,118,0,59,121,0,0,0,0,0,1,90,95,0,0,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,0,11,0,118,0,
-0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,0,18,118,0,59,120,0,0,0,0,9,58,112,114,105,110,116,77,
-69,83,65,0,0,18,118,0,59,121,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,0,18,118,0,59,122,0,0,
-0,0,0,1,90,95,0,0,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,0,12,0,118,0,0,0,1,9,58,112,114,
-105,110,116,77,69,83,65,0,0,18,118,0,59,120,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,0,18,
-118,0,59,121,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,0,18,118,0,59,122,0,0,0,0,9,58,112,114,
-105,110,116,77,69,83,65,0,0,18,118,0,59,119,0,0,0,0,0,1,90,95,0,0,0,0,0,112,114,105,110,116,77,69,
-83,65,0,1,1,0,0,6,0,118,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,0,18,118,0,59,120,0,0,0,0,9,
-58,112,114,105,110,116,77,69,83,65,0,0,18,118,0,59,121,0,0,0,0,0,1,90,95,0,0,0,0,0,112,114,105,110,
-116,77,69,83,65,0,1,1,0,0,7,0,118,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,0,18,118,0,59,120,
-0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,0,18,118,0,59,121,0,0,0,0,9,58,112,114,105,110,116,
-77,69,83,65,0,0,18,118,0,59,122,0,0,0,0,0,1,90,95,0,0,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,
-0,0,8,0,118,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,0,18,118,0,59,120,0,0,0,0,9,58,112,114,
-105,110,116,77,69,83,65,0,0,18,118,0,59,121,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,0,18,
-118,0,59,122,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,0,18,118,0,59,119,0,0,0,0,0,1,90,95,0,
-0,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,0,2,0,118,0,0,0,1,9,58,112,114,105,110,116,77,69,
-83,65,0,0,18,118,0,59,120,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,0,18,118,0,59,121,0,0,0,0,
-0,1,90,95,0,0,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,0,3,0,118,0,0,0,1,9,58,112,114,105,110,
-116,77,69,83,65,0,0,18,118,0,59,120,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,0,18,118,0,59,
-121,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,0,18,118,0,59,122,0,0,0,0,0,1,90,95,0,0,0,0,0,
-112,114,105,110,116,77,69,83,65,0,1,1,0,0,4,0,118,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,0,
-18,118,0,59,120,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,0,18,118,0,59,121,0,0,0,0,9,58,112,
-114,105,110,116,77,69,83,65,0,0,18,118,0,59,122,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,0,
-18,118,0,59,119,0,0,0,0,0,1,90,95,0,0,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,0,13,0,109,0,0,
-0,1,9,58,112,114,105,110,116,77,69,83,65,0,0,18,109,0,16,8,48,0,57,0,0,0,9,58,112,114,105,110,116,
-77,69,83,65,0,0,18,109,0,16,10,49,0,57,0,0,0,0,1,90,95,0,0,0,0,0,112,114,105,110,116,77,69,83,65,0,
-1,1,0,0,14,0,109,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,0,18,109,0,16,8,48,0,57,0,0,0,9,58,
-112,114,105,110,116,77,69,83,65,0,0,18,109,0,16,10,49,0,57,0,0,0,9,58,112,114,105,110,116,77,69,83,
-65,0,0,18,109,0,16,10,50,0,57,0,0,0,0,1,90,95,0,0,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,0,
-15,0,109,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,0,18,109,0,16,8,48,0,57,0,0,0,9,58,112,114,
-105,110,116,77,69,83,65,0,0,18,109,0,16,10,49,0,57,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,0,
-18,109,0,16,10,50,0,57,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,0,18,109,0,16,10,51,0,57,0,0,0,
-0,1,90,95,0,0,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,0,16,0,101,0,0,0,1,4,105,110,116,95,
-112,114,105,110,116,0,18,101,0,0,0,0,1,90,95,0,0,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,0,
-17,0,101,0,0,0,1,4,105,110,116,95,112,114,105,110,116,0,18,101,0,0,0,0,1,90,95,0,0,0,0,0,112,114,
-105,110,116,77,69,83,65,0,1,1,0,0,18,0,101,0,0,0,1,4,105,110,116,95,112,114,105,110,116,0,18,101,0,
-0,0,0,1,90,95,0,0,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,0,19,0,101,0,0,0,1,4,105,110,116,
-95,112,114,105,110,116,0,18,101,0,0,0,0,1,90,95,0,0,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,
-0,20,0,101,0,0,0,1,4,105,110,116,95,112,114,105,110,116,0,18,101,0,0,0,0,1,90,95,0,0,0,0,0,112,114,
-105,110,116,77,69,83,65,0,1,1,0,0,21,0,101,0,0,0,1,4,105,110,116,95,112,114,105,110,116,0,18,101,0,
-0,0,0,0
diff --git a/src/mesa/shader/slang/library/slang_fragment_builtin_gc.h b/src/mesa/shader/slang/library/slang_fragment_builtin_gc.h
deleted file mode 100644
index c5a1cce..0000000
--- a/src/mesa/shader/slang/library/slang_fragment_builtin_gc.h
+++ /dev/null
@@ -1,110 +0,0 @@
-
-/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE FOLLOWING FILE: */
-/* slang_fragment_builtin.gc */
-
-5,2,2,90,95,6,0,12,0,1,103,108,95,70,114,97,103,67,111,111,114,100,0,0,0,2,2,90,95,6,0,1,0,1,103,
-108,95,70,114,111,110,116,70,97,99,105,110,103,0,0,0,2,2,90,95,5,0,12,0,1,103,108,95,70,114,97,103,
-67,111,108,111,114,0,0,0,2,2,90,95,5,0,12,0,1,103,108,95,70,114,97,103,68,97,116,97,0,3,18,103,108,
-95,77,97,120,68,114,97,119,66,117,102,102,101,114,115,0,0,0,2,2,90,95,5,0,9,0,1,103,108,95,70,114,
-97,103,68,101,112,116,104,0,0,0,2,2,90,95,3,0,12,0,1,103,108,95,67,111,108,111,114,0,0,0,2,2,90,95,
-3,0,12,0,1,103,108,95,83,101,99,111,110,100,97,114,121,67,111,108,111,114,0,0,0,2,2,90,95,3,0,12,0,
-1,103,108,95,84,101,120,67,111,111,114,100,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,
-67,111,111,114,100,115,0,0,0,2,2,90,95,3,0,9,0,1,103,108,95,70,111,103,70,114,97,103,67,111,111,
-114,100,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,49,68,0,1,1,0,0,16,0,115,97,109,112,
-108,101,114,0,0,1,1,0,0,9,0,99,111,111,114,100,0,0,1,1,0,0,9,0,98,105,97,115,0,0,0,1,3,2,90,95,0,0,
-12,0,1,99,111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,0,18,99,111,111,114,100,0,
-20,0,9,18,99,111,111,114,100,52,0,59,119,0,18,98,105,97,115,0,20,0,4,118,101,99,52,95,116,101,120,
-95,49,100,95,98,105,97,115,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,
-18,99,111,111,114,100,52,0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,49,68,80,114,111,
-106,0,1,1,0,0,16,0,115,97,109,112,108,101,114,0,0,1,1,0,0,10,0,99,111,111,114,100,0,0,1,1,0,0,9,0,
-98,105,97,115,0,0,0,1,3,2,90,95,0,0,12,0,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,
-100,0,59,120,0,18,99,111,111,114,100,0,59,120,0,18,99,111,111,114,100,0,59,121,0,49,20,0,9,18,112,
-99,111,111,114,100,0,59,119,0,18,98,105,97,115,0,20,0,4,118,101,99,52,95,116,101,120,95,49,100,95,
-98,105,97,115,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99,111,
-111,114,100,0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,49,68,80,114,111,106,0,1,1,0,0,
-16,0,115,97,109,112,108,101,114,0,0,1,1,0,0,12,0,99,111,111,114,100,0,0,1,1,0,0,9,0,98,105,97,115,
-0,0,0,1,3,2,90,95,0,0,12,0,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,0,
-18,99,111,111,114,100,0,59,120,0,18,99,111,111,114,100,0,59,122,0,49,20,0,9,18,112,99,111,111,114,
-100,0,59,119,0,18,98,105,97,115,0,20,0,4,118,101,99,52,95,116,101,120,95,49,100,95,98,105,97,115,0,
-18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99,111,111,114,100,0,0,
-0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,50,68,0,1,1,0,0,17,0,115,97,109,112,108,101,114,
-0,0,1,1,0,0,10,0,99,111,111,114,100,0,0,1,1,0,0,9,0,98,105,97,115,0,0,0,1,3,2,90,95,0,0,12,0,1,99,
-111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,121,0,18,99,111,111,114,100,0,59,120,
-121,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0,18,98,105,97,115,0,20,0,4,118,101,99,52,95,116,
-101,120,95,50,100,95,98,105,97,115,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,
-114,0,0,18,99,111,111,114,100,52,0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,50,68,80,
-114,111,106,0,1,1,0,0,17,0,115,97,109,112,108,101,114,0,0,1,1,0,0,11,0,99,111,111,114,100,0,0,1,1,
-0,0,9,0,98,105,97,115,0,0,0,1,3,2,90,95,0,0,12,0,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,
-111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,122,0,
-49,20,0,9,18,112,99,111,111,114,100,0,59,119,0,18,98,105,97,115,0,20,0,4,118,101,99,52,95,116,101,
-120,95,50,100,95,98,105,97,115,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,
-0,0,18,112,99,111,111,114,100,0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,50,68,80,114,
-111,106,0,1,1,0,0,17,0,115,97,109,112,108,101,114,0,0,1,1,0,0,12,0,99,111,111,114,100,0,0,1,1,0,0,
-9,0,98,105,97,115,0,0,0,1,3,2,90,95,0,0,12,0,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,
-114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,119,0,49,20,
-0,9,18,112,99,111,111,114,100,0,59,119,0,18,98,105,97,115,0,20,0,4,118,101,99,52,95,116,101,120,95,
-50,100,95,98,105,97,115,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,
-112,99,111,111,114,100,0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,51,68,0,1,1,0,0,18,0,
-115,97,109,112,108,101,114,0,0,1,1,0,0,11,0,99,111,111,114,100,0,0,1,1,0,0,9,0,98,105,97,115,0,0,0,
-1,3,2,90,95,0,0,12,0,1,99,111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,121,122,0,
-18,99,111,111,114,100,0,59,120,121,122,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0,18,98,105,97,
-115,0,20,0,4,118,101,99,52,95,116,101,120,95,51,100,95,98,105,97,115,0,18,95,95,114,101,116,86,97,
-108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,52,0,0,0,0,1,90,95,0,0,12,0,0,116,
-101,120,116,117,114,101,51,68,80,114,111,106,0,1,1,0,0,18,0,115,97,109,112,108,101,114,0,0,1,1,0,0,
-12,0,99,111,111,114,100,0,0,1,1,0,0,9,0,98,105,97,115,0,0,0,1,3,2,90,95,0,0,12,0,1,112,99,111,111,
-114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,121,122,0,18,99,111,111,114,100,0,59,120,121,
-122,0,18,99,111,111,114,100,0,59,119,0,49,20,0,9,18,112,99,111,111,114,100,0,59,119,0,18,98,105,97,
-115,0,20,0,4,118,101,99,52,95,116,101,120,95,51,100,95,98,105,97,115,0,18,95,95,114,101,116,86,97,
-108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,90,95,0,0,12,0,0,116,
-101,120,116,117,114,101,67,117,98,101,0,1,1,0,0,19,0,115,97,109,112,108,101,114,0,0,1,1,0,0,11,0,
-99,111,111,114,100,0,0,1,1,0,0,9,0,98,105,97,115,0,0,0,1,3,2,90,95,0,0,12,0,1,99,111,111,114,100,
-52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,121,122,0,18,99,111,111,114,100,0,20,0,9,18,99,111,
-111,114,100,52,0,59,119,0,18,98,105,97,115,0,20,0,4,118,101,99,52,95,116,101,120,95,99,117,98,101,
-0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,52,0,
-0,0,0,1,90,95,0,0,12,0,0,115,104,97,100,111,119,49,68,0,1,1,0,0,20,0,115,97,109,112,108,101,114,0,
-0,1,1,0,0,11,0,99,111,111,114,100,0,0,1,1,0,0,9,0,98,105,97,115,0,0,0,1,3,2,90,95,0,0,12,0,1,99,
-111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,121,122,0,18,99,111,111,114,100,0,20,
-0,9,18,99,111,111,114,100,52,0,59,119,0,18,98,105,97,115,0,20,0,4,118,101,99,52,95,116,101,120,95,
-49,100,95,98,105,97,115,95,115,104,97,100,111,119,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,
-109,112,108,101,114,0,0,18,99,111,111,114,100,52,0,0,0,0,1,90,95,0,0,12,0,0,115,104,97,100,111,119,
-49,68,80,114,111,106,0,1,1,0,0,20,0,115,97,109,112,108,101,114,0,0,1,1,0,0,12,0,99,111,111,114,100,
-0,0,1,1,0,0,9,0,98,105,97,115,0,0,0,1,3,2,90,95,0,0,12,0,1,112,99,111,111,114,100,0,0,0,9,18,112,
-99,111,111,114,100,0,59,120,0,18,99,111,111,114,100,0,59,120,0,18,99,111,111,114,100,0,59,119,0,49,
-20,0,9,18,112,99,111,111,114,100,0,59,122,0,18,99,111,111,114,100,0,59,122,0,20,0,9,18,112,99,111,
-111,114,100,0,59,119,0,18,98,105,97,115,0,20,0,4,118,101,99,52,95,116,101,120,95,49,100,95,98,105,
-97,115,95,115,104,97,100,111,119,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,
-114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,90,95,0,0,12,0,0,115,104,97,100,111,119,50,68,0,1,1,0,
-0,21,0,115,97,109,112,108,101,114,0,0,1,1,0,0,11,0,99,111,111,114,100,0,0,1,1,0,0,9,0,98,105,97,
-115,0,0,0,1,3,2,90,95,0,0,12,0,1,99,111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,
-121,122,0,18,99,111,111,114,100,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0,18,98,105,97,115,0,20,
-0,4,118,101,99,52,95,116,101,120,95,50,100,95,98,105,97,115,95,115,104,97,100,111,119,0,18,95,95,
-114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,52,0,0,0,0,1,90,
-95,0,0,12,0,0,115,104,97,100,111,119,50,68,80,114,111,106,0,1,1,0,0,21,0,115,97,109,112,108,101,
-114,0,0,1,1,0,0,12,0,99,111,111,114,100,0,0,1,1,0,0,9,0,98,105,97,115,0,0,0,1,3,2,90,95,0,0,12,0,1,
-112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,
-120,121,0,18,99,111,111,114,100,0,59,119,0,49,20,0,9,18,112,99,111,111,114,100,0,59,122,0,18,99,
-111,111,114,100,0,59,122,0,20,0,9,18,112,99,111,111,114,100,0,59,119,0,18,98,105,97,115,0,20,0,4,
-118,101,99,52,95,116,101,120,95,50,100,95,98,105,97,115,95,115,104,97,100,111,119,0,18,95,95,114,
-101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,90,95,
-0,0,9,0,0,100,70,100,120,0,1,1,0,0,9,0,112,0,0,0,1,4,118,101,99,52,95,100,100,120,0,18,95,95,114,
-101,116,86,97,108,0,59,120,0,0,18,112,0,59,120,120,120,120,0,0,0,0,1,90,95,0,0,10,0,0,100,70,100,
-120,0,1,1,0,0,10,0,112,0,0,0,1,4,118,101,99,52,95,100,100,120,0,18,95,95,114,101,116,86,97,108,0,
-59,120,121,0,0,18,112,0,59,120,121,121,121,0,0,0,0,1,90,95,0,0,11,0,0,100,70,100,120,0,1,1,0,0,11,
-0,112,0,0,0,1,4,118,101,99,52,95,100,100,120,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,
-18,112,0,59,120,121,122,122,0,0,0,0,1,90,95,0,0,12,0,0,100,70,100,120,0,1,1,0,0,12,0,112,0,0,0,1,4,
-118,101,99,52,95,100,100,120,0,18,95,95,114,101,116,86,97,108,0,0,18,112,0,0,0,0,1,90,95,0,0,9,0,0,
-100,70,100,121,0,1,1,0,0,9,0,112,0,0,0,1,4,118,101,99,52,95,100,100,121,0,18,95,95,114,101,116,86,
-97,108,0,59,120,0,0,18,112,0,59,120,120,120,120,0,0,0,0,1,90,95,0,0,10,0,0,100,70,100,121,0,1,1,0,
-0,10,0,112,0,0,0,1,4,118,101,99,52,95,100,100,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,
-0,18,112,0,59,120,121,121,121,0,0,0,0,1,90,95,0,0,11,0,0,100,70,100,121,0,1,1,0,0,11,0,112,0,0,0,1,
-4,118,101,99,52,95,100,100,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,112,0,59,
-120,121,122,122,0,0,0,0,1,90,95,0,0,12,0,0,100,70,100,121,0,1,1,0,0,12,0,112,0,0,0,1,4,118,101,99,
-52,95,100,100,121,0,18,95,95,114,101,116,86,97,108,0,0,18,112,0,0,0,0,1,90,95,0,0,9,0,0,102,119,
-105,100,116,104,0,1,1,0,0,9,0,112,0,0,0,1,8,58,97,98,115,0,0,58,100,70,100,120,0,0,18,112,0,0,0,0,
-0,58,97,98,115,0,0,58,100,70,100,121,0,0,18,112,0,0,0,0,0,46,0,0,1,90,95,0,0,10,0,0,102,119,105,
-100,116,104,0,1,1,0,0,10,0,112,0,0,0,1,8,58,97,98,115,0,0,58,100,70,100,120,0,0,18,112,0,0,0,0,0,
-58,97,98,115,0,0,58,100,70,100,121,0,0,18,112,0,0,0,0,0,46,0,0,1,90,95,0,0,11,0,0,102,119,105,100,
-116,104,0,1,1,0,0,11,0,112,0,0,0,1,8,58,97,98,115,0,0,58,100,70,100,120,0,0,18,112,0,0,0,0,0,58,97,
-98,115,0,0,58,100,70,100,121,0,0,18,112,0,0,0,0,0,46,0,0,1,90,95,0,0,12,0,0,102,119,105,100,116,
-104,0,1,1,0,0,12,0,112,0,0,0,1,8,58,97,98,115,0,0,58,100,70,100,120,0,0,18,112,0,0,0,0,0,58,97,98,
-115,0,0,58,100,70,100,121,0,0,18,112,0,0,0,0,0,46,0,0,0
diff --git a/src/mesa/shader/slang/library/slang_pp_directives.syn b/src/mesa/shader/slang/library/slang_pp_directives.syn
deleted file mode 100644
index b51d168..0000000
--- a/src/mesa/shader/slang/library/slang_pp_directives.syn
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.6
- *
- * Copyright (C) 2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL 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 slang_pp_directives.syn
- * slang preprocessor directives parser
- * \author Michal Krol
- */
-
-.syntax source;
-
-/*
- * This syntax script preprocesses a GLSL shader.
- * It is assumed, that the #version directive has been parsed. Separate pass for parsing
- * version gives better control on behavior depending on the version number given.
- *
- * The output is a source string with comments and directives removed. White spaces and comments
- * are replaced with on or more spaces. All new-lines are preserved and converted to Linux format.
- * Directives are escaped with a null character. The end of the source string is marked by
- * two consecutive null characters. The consumer is responsible for executing the escaped
- * directives, removing dead portions of code and expanding macros.
- */
-
-.emtcode ESCAPE_TOKEN 0
-
-/*
- * The TOKEN_* symbols follow the ESCAPE_TOKEN.
- *
- * NOTE:
- * There is no TOKEN_IFDEF and neither is TOKEN_IFNDEF. They are handled with TOKEN_IF and
- * operator defined.
- * The "#ifdef SYMBOL" is replaced with "#if defined SYMBOL"
- * The "#ifndef SYMBOL" is replaced with "#if !defined SYMBOL"
- */
-.emtcode TOKEN_END       0
-.emtcode TOKEN_DEFINE    1
-.emtcode TOKEN_UNDEF     2
-.emtcode TOKEN_IF        3
-.emtcode TOKEN_ELSE      4
-.emtcode TOKEN_ELIF      5
-.emtcode TOKEN_ENDIF     6
-.emtcode TOKEN_ERROR     7
-.emtcode TOKEN_PRAGMA    8
-.emtcode TOKEN_EXTENSION 9
-.emtcode TOKEN_LINE      10
-
-/*
- * The PARAM_* symbols follow the TOKEN_DEFINE.
- */
-.emtcode PARAM_END       0
-.emtcode PARAM_PARAMETER 1
-
-/*
- * The BEHAVIOR_* symbols follow the TOKEN_EXTENSION.
- */
-.emtcode BEHAVIOR_REQUIRE 1
-.emtcode BEHAVIOR_ENABLE  2
-.emtcode BEHAVIOR_WARN    3
-.emtcode BEHAVIOR_DISABLE 4
-
-/*
- * The PRAGMA_* symbols follow TOKEN_PRAGMA
- */
-.emtcode PRAGMA_NO_PARAM 0
-.emtcode PRAGMA_PARAM    1
-
-source
-   optional_directive .and .loop source_element .and '\0' .emit ESCAPE_TOKEN .emit TOKEN_END;
-
-source_element
-   c_style_comment_block .or cpp_style_comment_block .or new_line_directive .or source_token;
-
-c_style_comment_block
-   '/' .and '*' .and c_style_comment_rest .and .true .emit ' ';
-
-c_style_comment_rest
-   .loop c_style_comment_body .and c_style_comment_end;
-
-c_style_comment_body
-   c_style_comment_char_nostar .or c_style_comment_char_star_noslashstar;
-
-c_style_comment_char_nostar
-   new_line .or '\x2B'-'\xFF' .or '\x01'-'\x29';
-
-c_style_comment_char_star_noslashstar
-   '*' .and c_style_comment_char_star_noslashstar_1;
-c_style_comment_char_star_noslashstar_1
-   c_style_comment_char_noslashstar .or c_style_comment_char_star_noslashstar;
-
-c_style_comment_char_noslashstar
-   new_line .or '\x30'-'\xFF' .or '\x01'-'\x29' .or '\x2B'-'\x2E';
-
-c_style_comment_end
-   '*' .and .loop c_style_comment_char_star .and '/';
-
-c_style_comment_char_star
-   '*';
-
-cpp_style_comment_block
-   '/' .and '/' .and cpp_style_comment_block_1;
-cpp_style_comment_block_1
-   cpp_style_comment_block_2 .or cpp_style_comment_block_3;
-cpp_style_comment_block_2
-   .loop cpp_style_comment_char .and new_line_directive;
-cpp_style_comment_block_3
-   .loop cpp_style_comment_char;
-
-cpp_style_comment_char
-   '\x0E'-'\xFF' .or '\x01'-'\x09' .or '\x0B'-'\x0C';
-
-new_line_directive
-   new_line .and optional_directive;
-
-new_line
-   generic_new_line .emit '\n';
-
-generic_new_line
-   carriage_return_line_feed .or line_feed_carriage_return .or '\n' .or '\r';
-
-carriage_return_line_feed
-   '\r' .and '\n';
-
-line_feed_carriage_return
-   '\n' .and '\r';
-
-optional_directive
-   directive .emit ESCAPE_TOKEN .or .true;
-
-directive
-   dir_define .emit TOKEN_DEFINE .or
-   dir_undef .emit TOKEN_UNDEF .or
-   dir_if .emit TOKEN_IF .or
-   dir_ifdef .emit TOKEN_IF .emit 'd' .emit 'e' .emit 'f' .emit 'i' .emit 'n' .emit 'e' .emit 'd'
-             .emit ' ' .or
-   dir_ifndef .emit TOKEN_IF .emit '!' .emit 'd' .emit 'e' .emit 'f' .emit 'i' .emit 'n' .emit 'e'
-              .emit 'd' .emit ' ' .or
-   dir_else .emit TOKEN_ELSE .or
-   dir_elif .emit TOKEN_ELIF .or
-   dir_endif .emit TOKEN_ENDIF .or
-   dir_ext .emit TOKEN_EXTENSION .or
-   dir_pragma .emit TOKEN_PRAGMA .or
-   dir_line .emit TOKEN_LINE;
-
-dir_define
-   optional_space .and '#' .and optional_space .and "define" .and symbol .and opt_parameters .and
-   definition;
-
-dir_undef
-   optional_space .and '#' .and optional_space .and "undef" .and symbol;
-
-dir_if
-   optional_space .and '#' .and optional_space .and "if" .and expression;
-
-dir_ifdef
-   optional_space .and '#' .and optional_space .and "ifdef" .and symbol;
-
-dir_ifndef
-   optional_space .and '#' .and optional_space .and "ifndef" .and symbol;
-
-dir_else
-   optional_space .and '#' .and optional_space .and "else";
-
-dir_elif
-   optional_space .and '#' .and optional_space .and "elif" .and expression;
-
-dir_endif
-   optional_space .and '#' .and optional_space .and "endif";
-
-dir_ext
-   optional_space .and '#' .and optional_space .and "extension" .and space .and extension_name .and
-   optional_space .and ':' .and optional_space .and extension_behavior;
-
-dir_line
-   optional_space .and '#' .and optional_space .and "line" .and expression;
-
-dir_pragma
-   optional_space .and '#' .and optional_space .and "pragma" .and symbol .and opt_pragma_param;
-
-
-opt_pragma_param
-   pragma_param .or .true .emit PRAGMA_NO_PARAM;
-
-pragma_param
-   optional_space .and '(' .emit PRAGMA_PARAM .and optional_space .and symbol_no_space .and optional_space .and ')';
-
-symbol_no_space
-   symbol_character .emit * .and .loop symbol_character2 .emit * .and .true .emit '\0';
-
-symbol
-   space .and symbol_character .emit * .and .loop symbol_character2 .emit * .and .true .emit '\0';
-
-opt_parameters
-   parameters .or .true .emit PARAM_END;
-
-parameters
-   '(' .and parameters_1 .and optional_space .and ')' .emit PARAM_END;
-parameters_1
-   parameters_2 .or .true;
-parameters_2
-   parameter .emit PARAM_PARAMETER .and .loop parameters_3;
-parameters_3
-   optional_space .and ',' .and parameter .emit PARAM_PARAMETER;
-
-parameter
-   optional_space .and symbol_character .emit * .and .loop symbol_character2 .emit * .and
-   .true .emit '\0';
-
-definition
-   .loop definition_character .emit * .and .true .emit '\0';
-
-definition_character
-   '\x0E'-'\xFF' .or '\x01'-'\x09' .or '\x0B'-'\x0C';
-
-expression
-   expression_element .and .loop expression_element .and .true .emit '\0';
-
-expression_element
-   expression_character .emit *;
-
-expression_character
-   '\x0E'-'\xFF' .or '\x01'-'\x09' .or '\x0B'-'\x0C';
-
-extension_name
-   symbol_character .emit * .and .loop symbol_character2 .emit * .and .true .emit '\0';
-
-extension_behavior
-   "require" .emit BEHAVIOR_REQUIRE .or
-   "enable" .emit BEHAVIOR_ENABLE .or
-   "warn" .emit BEHAVIOR_WARN .or
-   "disable" .emit BEHAVIOR_DISABLE;
-
-optional_space
-   .loop single_space;
-
-space
-   single_space .and .loop single_space;
-
-single_space
-   ' ' .or '\t';
-
-source_token
-   space .emit ' ' .or complex_token .or source_token_1;
-source_token_1
-   simple_token .emit ' ' .and .true .emit ' ';
-
-/*
- * All possible tokens.
- */
-
-complex_token
-   identifier .or number;
-
-simple_token
-   increment .or decrement .or lequal .or gequal .or equal .or nequal .or and .or xor .or or .or
-   addto .or subtractfrom .or multiplyto .or divideto .or other;
-
-identifier
-   identifier_char1 .emit * .and .loop identifier_char2 .emit *;
-identifier_char1
-   'a'-'z' .or 'A'-'Z' .or '_';
-identifier_char2
-   'a'-'z' .or 'A'-'Z' .or '0'-'9' .or '_';
-
-number
-   float .or integer;
-
-digit_oct
-   '0'-'7';
-
-digit_dec
-   '0'-'9';
-
-digit_hex
-   '0'-'9' .or 'A'-'F' .or 'a'-'f';
-
-float
-   float_1 .or float_2;
-float_1
-   float_fractional_constant .and float_optional_exponent_part;
-float_2
-   float_digit_sequence .and float_exponent_part;
-
-float_fractional_constant
-   float_fractional_constant_1 .or float_fractional_constant_2 .or float_fractional_constant_3;
-float_fractional_constant_1
-   float_digit_sequence .and '.' .emit '.' .and float_digit_sequence;
-float_fractional_constant_2
-   float_digit_sequence .and '.' .emit '.';
-float_fractional_constant_3
-   '.' .emit '.' .and float_digit_sequence;
-
-float_optional_exponent_part
-   float_exponent_part .or .true;
-
-float_digit_sequence
-   digit_dec .emit * .and .loop digit_dec .emit *;
-
-float_exponent_part
-   float_exponent_part_1 .or float_exponent_part_2;
-float_exponent_part_1
-   'e' .emit 'e' .and float_optional_sign .and float_digit_sequence;
-float_exponent_part_2
-   'E' .emit 'E' .and float_optional_sign .and float_digit_sequence;
-
-float_optional_sign
-   '+' .emit '+' .or '-' .emit '-' .or .true;
-
-integer
-   integer_hex .or integer_oct .or integer_dec;
-
-integer_hex
-   '0' .emit '0' .and integer_hex_1 .emit * .and digit_hex .emit * .and
-   .loop digit_hex .emit *;
-integer_hex_1
-   'x' .or 'X';
-
-integer_oct
-   '0' .emit '0' .and .loop digit_oct .emit *;
-
-integer_dec
-   digit_dec .emit * .and .loop digit_dec .emit *;
-
-increment
-   '+' .emit * .and '+' .emit *;
-
-decrement
-   '-' .emit * .and '-' .emit *;
-
-lequal
-   '<' .emit * .and '=' .emit *;
-
-gequal
-   '>' .emit * .and '=' .emit *;
-
-equal
-   '=' .emit * .and '=' .emit *;
-
-nequal
-   '!' .emit * .and '=' .emit *;
-
-and
-   '&' .emit * .and '&' .emit *;
-
-xor
-   '^' .emit * .and '^' .emit *;
-
-or
-   '|' .emit * .and '|' .emit *;
-
-addto
-   '+' .emit * .and '=' .emit *;
-
-subtractfrom
-   '-' .emit * .and '=' .emit *;
-
-multiplyto
-   '*' .emit * .and '=' .emit *;
-
-divideto
-   '/' .emit * .and '=' .emit *;
-
-/*
- * All characters except '\0' and '#'.
- */
-other
-   '\x24'-'\xFF' .emit * .or '\x01'-'\x22' .emit *;
-
-symbol_character
-   'A'-'Z' .or 'a'-'z' .or '_';
-
-symbol_character2
-   'A'-'Z' .or 'a'-'z' .or '0'-'9' .or '_';
-
-.string string_lexer;
-
-string_lexer
-   lex_first_identifier_character .and .loop lex_next_identifier_character;
-
-lex_first_identifier_character
-   'a'-'z' .or 'A'-'Z' .or '_';
-
-lex_next_identifier_character
-   'a'-'z' .or 'A'-'Z' .or '0'-'9' .or '_';
-
diff --git a/src/mesa/shader/slang/library/slang_pp_directives_syn.h b/src/mesa/shader/slang/library/slang_pp_directives_syn.h
deleted file mode 100644
index 430f8d8..0000000
--- a/src/mesa/shader/slang/library/slang_pp_directives_syn.h
+++ /dev/null
@@ -1,250 +0,0 @@
-
-/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE .syn FILE */
-
-".syntax source;\n"
-".emtcode ESCAPE_TOKEN 0\n"
-".emtcode TOKEN_END 0\n"
-".emtcode TOKEN_DEFINE 1\n"
-".emtcode TOKEN_UNDEF 2\n"
-".emtcode TOKEN_IF 3\n"
-".emtcode TOKEN_ELSE 4\n"
-".emtcode TOKEN_ELIF 5\n"
-".emtcode TOKEN_ENDIF 6\n"
-".emtcode TOKEN_ERROR 7\n"
-".emtcode TOKEN_PRAGMA 8\n"
-".emtcode TOKEN_EXTENSION 9\n"
-".emtcode TOKEN_LINE 10\n"
-".emtcode PARAM_END 0\n"
-".emtcode PARAM_PARAMETER 1\n"
-".emtcode BEHAVIOR_REQUIRE 1\n"
-".emtcode BEHAVIOR_ENABLE 2\n"
-".emtcode BEHAVIOR_WARN 3\n"
-".emtcode BEHAVIOR_DISABLE 4\n"
-".emtcode PRAGMA_NO_PARAM 0\n"
-".emtcode PRAGMA_PARAM 1\n"
-"source\n"
-" optional_directive .and .loop source_element .and '\\0' .emit ESCAPE_TOKEN .emit TOKEN_END;\n"
-"source_element\n"
-" c_style_comment_block .or cpp_style_comment_block .or new_line_directive .or source_token;\n"
-"c_style_comment_block\n"
-" '/' .and '*' .and c_style_comment_rest .and .true .emit ' ';\n"
-"c_style_comment_rest\n"
-" .loop c_style_comment_body .and c_style_comment_end;\n"
-"c_style_comment_body\n"
-" c_style_comment_char_nostar .or c_style_comment_char_star_noslashstar;\n"
-"c_style_comment_char_nostar\n"
-" new_line .or '\\x2B'-'\\xFF' .or '\\x01'-'\\x29';\n"
-"c_style_comment_char_star_noslashstar\n"
-" '*' .and c_style_comment_char_star_noslashstar_1;\n"
-"c_style_comment_char_star_noslashstar_1\n"
-" c_style_comment_char_noslashstar .or c_style_comment_char_star_noslashstar;\n"
-"c_style_comment_char_noslashstar\n"
-" new_line .or '\\x30'-'\\xFF' .or '\\x01'-'\\x29' .or '\\x2B'-'\\x2E';\n"
-"c_style_comment_end\n"
-" '*' .and .loop c_style_comment_char_star .and '/';\n"
-"c_style_comment_char_star\n"
-" '*';\n"
-"cpp_style_comment_block\n"
-" '/' .and '/' .and cpp_style_comment_block_1;\n"
-"cpp_style_comment_block_1\n"
-" cpp_style_comment_block_2 .or cpp_style_comment_block_3;\n"
-"cpp_style_comment_block_2\n"
-" .loop cpp_style_comment_char .and new_line_directive;\n"
-"cpp_style_comment_block_3\n"
-" .loop cpp_style_comment_char;\n"
-"cpp_style_comment_char\n"
-" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n"
-"new_line_directive\n"
-" new_line .and optional_directive;\n"
-"new_line\n"
-" generic_new_line .emit '\\n';\n"
-"generic_new_line\n"
-" carriage_return_line_feed .or line_feed_carriage_return .or '\\n' .or '\\r';\n"
-"carriage_return_line_feed\n"
-" '\\r' .and '\\n';\n"
-"line_feed_carriage_return\n"
-" '\\n' .and '\\r';\n"
-"optional_directive\n"
-" directive .emit ESCAPE_TOKEN .or .true;\n"
-"directive\n"
-" dir_define .emit TOKEN_DEFINE .or\n"
-" dir_undef .emit TOKEN_UNDEF .or\n"
-" dir_if .emit TOKEN_IF .or\n"
-" dir_ifdef .emit TOKEN_IF .emit 'd' .emit 'e' .emit 'f' .emit 'i' .emit 'n' .emit 'e' .emit 'd'\n"
-" .emit ' ' .or\n"
-" dir_ifndef .emit TOKEN_IF .emit '!' .emit 'd' .emit 'e' .emit 'f' .emit 'i' .emit 'n' .emit 'e'\n"
-" .emit 'd' .emit ' ' .or\n"
-" dir_else .emit TOKEN_ELSE .or\n"
-" dir_elif .emit TOKEN_ELIF .or\n"
-" dir_endif .emit TOKEN_ENDIF .or\n"
-" dir_ext .emit TOKEN_EXTENSION .or\n"
-" dir_pragma .emit TOKEN_PRAGMA .or\n"
-" dir_line .emit TOKEN_LINE;\n"
-"dir_define\n"
-" optional_space .and '#' .and optional_space .and \"define\" .and symbol .and opt_parameters .and\n"
-" definition;\n"
-"dir_undef\n"
-" optional_space .and '#' .and optional_space .and \"undef\" .and symbol;\n"
-"dir_if\n"
-" optional_space .and '#' .and optional_space .and \"if\" .and expression;\n"
-"dir_ifdef\n"
-" optional_space .and '#' .and optional_space .and \"ifdef\" .and symbol;\n"
-"dir_ifndef\n"
-" optional_space .and '#' .and optional_space .and \"ifndef\" .and symbol;\n"
-"dir_else\n"
-" optional_space .and '#' .and optional_space .and \"else\";\n"
-"dir_elif\n"
-" optional_space .and '#' .and optional_space .and \"elif\" .and expression;\n"
-"dir_endif\n"
-" optional_space .and '#' .and optional_space .and \"endif\";\n"
-"dir_ext\n"
-" optional_space .and '#' .and optional_space .and \"extension\" .and space .and extension_name .and\n"
-" optional_space .and ':' .and optional_space .and extension_behavior;\n"
-"dir_line\n"
-" optional_space .and '#' .and optional_space .and \"line\" .and expression;\n"
-"dir_pragma\n"
-" optional_space .and '#' .and optional_space .and \"pragma\" .and symbol .and opt_pragma_param;\n"
-"opt_pragma_param\n"
-" pragma_param .or .true .emit PRAGMA_NO_PARAM;\n"
-"pragma_param\n"
-" optional_space .and '(' .emit PRAGMA_PARAM .and optional_space .and symbol_no_space .and optional_space .and ')';\n"
-"symbol_no_space\n"
-" symbol_character .emit * .and .loop symbol_character2 .emit * .and .true .emit '\\0';\n"
-"symbol\n"
-" space .and symbol_character .emit * .and .loop symbol_character2 .emit * .and .true .emit '\\0';\n"
-"opt_parameters\n"
-" parameters .or .true .emit PARAM_END;\n"
-"parameters\n"
-" '(' .and parameters_1 .and optional_space .and ')' .emit PARAM_END;\n"
-"parameters_1\n"
-" parameters_2 .or .true;\n"
-"parameters_2\n"
-" parameter .emit PARAM_PARAMETER .and .loop parameters_3;\n"
-"parameters_3\n"
-" optional_space .and ',' .and parameter .emit PARAM_PARAMETER;\n"
-"parameter\n"
-" optional_space .and symbol_character .emit * .and .loop symbol_character2 .emit * .and\n"
-" .true .emit '\\0';\n"
-"definition\n"
-" .loop definition_character .emit * .and .true .emit '\\0';\n"
-"definition_character\n"
-" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n"
-"expression\n"
-" expression_element .and .loop expression_element .and .true .emit '\\0';\n"
-"expression_element\n"
-" expression_character .emit *;\n"
-"expression_character\n"
-" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n"
-"extension_name\n"
-" symbol_character .emit * .and .loop symbol_character2 .emit * .and .true .emit '\\0';\n"
-"extension_behavior\n"
-" \"require\" .emit BEHAVIOR_REQUIRE .or\n"
-" \"enable\" .emit BEHAVIOR_ENABLE .or\n"
-" \"warn\" .emit BEHAVIOR_WARN .or\n"
-" \"disable\" .emit BEHAVIOR_DISABLE;\n"
-"optional_space\n"
-" .loop single_space;\n"
-"space\n"
-" single_space .and .loop single_space;\n"
-"single_space\n"
-" ' ' .or '\\t';\n"
-"source_token\n"
-" space .emit ' ' .or complex_token .or source_token_1;\n"
-"source_token_1\n"
-" simple_token .emit ' ' .and .true .emit ' ';\n"
-"complex_token\n"
-" identifier .or number;\n"
-"simple_token\n"
-" increment .or decrement .or lequal .or gequal .or equal .or nequal .or and .or xor .or or .or\n"
-" addto .or subtractfrom .or multiplyto .or divideto .or other;\n"
-"identifier\n"
-" identifier_char1 .emit * .and .loop identifier_char2 .emit *;\n"
-"identifier_char1\n"
-" 'a'-'z' .or 'A'-'Z' .or '_';\n"
-"identifier_char2\n"
-" 'a'-'z' .or 'A'-'Z' .or '0'-'9' .or '_';\n"
-"number\n"
-" float .or integer;\n"
-"digit_oct\n"
-" '0'-'7';\n"
-"digit_dec\n"
-" '0'-'9';\n"
-"digit_hex\n"
-" '0'-'9' .or 'A'-'F' .or 'a'-'f';\n"
-"float\n"
-" float_1 .or float_2;\n"
-"float_1\n"
-" float_fractional_constant .and float_optional_exponent_part;\n"
-"float_2\n"
-" float_digit_sequence .and float_exponent_part;\n"
-"float_fractional_constant\n"
-" float_fractional_constant_1 .or float_fractional_constant_2 .or float_fractional_constant_3;\n"
-"float_fractional_constant_1\n"
-" float_digit_sequence .and '.' .emit '.' .and float_digit_sequence;\n"
-"float_fractional_constant_2\n"
-" float_digit_sequence .and '.' .emit '.';\n"
-"float_fractional_constant_3\n"
-" '.' .emit '.' .and float_digit_sequence;\n"
-"float_optional_exponent_part\n"
-" float_exponent_part .or .true;\n"
-"float_digit_sequence\n"
-" digit_dec .emit * .and .loop digit_dec .emit *;\n"
-"float_exponent_part\n"
-" float_exponent_part_1 .or float_exponent_part_2;\n"
-"float_exponent_part_1\n"
-" 'e' .emit 'e' .and float_optional_sign .and float_digit_sequence;\n"
-"float_exponent_part_2\n"
-" 'E' .emit 'E' .and float_optional_sign .and float_digit_sequence;\n"
-"float_optional_sign\n"
-" '+' .emit '+' .or '-' .emit '-' .or .true;\n"
-"integer\n"
-" integer_hex .or integer_oct .or integer_dec;\n"
-"integer_hex\n"
-" '0' .emit '0' .and integer_hex_1 .emit * .and digit_hex .emit * .and\n"
-" .loop digit_hex .emit *;\n"
-"integer_hex_1\n"
-" 'x' .or 'X';\n"
-"integer_oct\n"
-" '0' .emit '0' .and .loop digit_oct .emit *;\n"
-"integer_dec\n"
-" digit_dec .emit * .and .loop digit_dec .emit *;\n"
-"increment\n"
-" '+' .emit * .and '+' .emit *;\n"
-"decrement\n"
-" '-' .emit * .and '-' .emit *;\n"
-"lequal\n"
-" '<' .emit * .and '=' .emit *;\n"
-"gequal\n"
-" '>' .emit * .and '=' .emit *;\n"
-"equal\n"
-" '=' .emit * .and '=' .emit *;\n"
-"nequal\n"
-" '!' .emit * .and '=' .emit *;\n"
-"and\n"
-" '&' .emit * .and '&' .emit *;\n"
-"xor\n"
-" '^' .emit * .and '^' .emit *;\n"
-"or\n"
-" '|' .emit * .and '|' .emit *;\n"
-"addto\n"
-" '+' .emit * .and '=' .emit *;\n"
-"subtractfrom\n"
-" '-' .emit * .and '=' .emit *;\n"
-"multiplyto\n"
-" '*' .emit * .and '=' .emit *;\n"
-"divideto\n"
-" '/' .emit * .and '=' .emit *;\n"
-"other\n"
-" '\\x24'-'\\xFF' .emit * .or '\\x01'-'\\x22' .emit *;\n"
-"symbol_character\n"
-" 'A'-'Z' .or 'a'-'z' .or '_';\n"
-"symbol_character2\n"
-" 'A'-'Z' .or 'a'-'z' .or '0'-'9' .or '_';\n"
-".string string_lexer;\n"
-"string_lexer\n"
-" lex_first_identifier_character .and .loop lex_next_identifier_character;\n"
-"lex_first_identifier_character\n"
-" 'a'-'z' .or 'A'-'Z' .or '_';\n"
-"lex_next_identifier_character\n"
-" 'a'-'z' .or 'A'-'Z' .or '0'-'9' .or '_';\n"
-""
diff --git a/src/mesa/shader/slang/library/slang_pp_expression.syn b/src/mesa/shader/slang/library/slang_pp_expression.syn
deleted file mode 100644
index bfdb220..0000000
--- a/src/mesa/shader/slang/library/slang_pp_expression.syn
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.6
- *
- * Copyright (C) 2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL 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 slang_pp_expression.syn
- * slang preprocessor expression parser
- * \author Michal Krol
- */
-
-/*
- * Parses one or two (optional) expressions on literal integer constants. Those expressions come
- * from #if #elif and #line directives. The preprocessor already parsed those directives and
- * expanded the expression (expressions). All occurences of the operator "defined" are already
- * replaced with either "0" or "1" literals.
- */
-
-.syntax expression;
-
-/*
- * Those separate individual expressions.
- * For #if/#elif case it is: EXP_EXPRESSION ... EXP_END
- * For #line case it may be: EXP_EXPRESSION ... EXP_EXPRESSION ... EXP_END
- */
-.emtcode EXP_END        0
-.emtcode EXP_EXPRESSION 1
-
-.emtcode OP_END          0
-.emtcode OP_PUSHINT      1
-.emtcode OP_LOGICALOR    2
-.emtcode OP_LOGICALAND   3
-.emtcode OP_OR           4
-.emtcode OP_XOR          5
-.emtcode OP_AND          6
-.emtcode OP_EQUAL        7
-.emtcode OP_NOTEQUAL     8
-.emtcode OP_LESSEQUAL    9
-.emtcode OP_GREATEREQUAL 10
-.emtcode OP_LESS         11
-.emtcode OP_GREATER      12
-.emtcode OP_LEFTSHIFT    13
-.emtcode OP_RIGHTSHIFT   14
-.emtcode OP_ADD          15
-.emtcode OP_SUBTRACT     16
-.emtcode OP_MULTIPLY     17
-.emtcode OP_DIVIDE       18
-.emtcode OP_MODULUS      19
-.emtcode OP_PLUS         20
-.emtcode OP_MINUS        21
-.emtcode OP_NEGATE       22
-.emtcode OP_COMPLEMENT   23
-
-expression
-   first_expression .and optional_second_expression .and optional_space .and '\0' .emit EXP_END;
-
-first_expression
-   optional_space .and logical_or_expression .emit EXP_EXPRESSION .and .true .emit OP_END;
-
-optional_second_expression
-   second_expression .or .true;
-
-second_expression
-   space .and logical_or_expression .emit EXP_EXPRESSION .and .true .emit OP_END;
-
-logical_or_expression
-   logical_and_expression .and .loop logical_or_expression_1;
-logical_or_expression_1
-   barbar .and logical_and_expression .and .true .emit OP_LOGICALOR;
-
-logical_and_expression
-   or_expression .and .loop logical_and_expression_1;
-logical_and_expression_1
-   ampersandampersand .and or_expression .and .true .emit OP_LOGICALAND;
-
-or_expression
-   xor_expression .and .loop or_expression_1;
-or_expression_1
-   bar .and xor_expression .and .true .emit OP_OR;
-
-xor_expression
-    and_expression .and .loop xor_expression_1;
-xor_expression_1
-    caret .and and_expression .and .true .emit OP_XOR;
-
-and_expression
-    equality_expression .and .loop and_expression_1;
-and_expression_1
-    ampersand .and equality_expression .and .true .emit OP_AND;
-
-equality_expression
-    relational_expression .and .loop equality_expression_1;
-equality_expression_1
-    equality_expression_2 .or equality_expression_3;
-equality_expression_2
-    equalsequals .and relational_expression .and .true .emit OP_EQUAL;
-equality_expression_3
-    bangequals .and relational_expression .and .true .emit OP_NOTEQUAL;
-
-relational_expression
-    shift_expression .and .loop relational_expression_1;
-relational_expression_1
-    relational_expression_2 .or relational_expression_3 .or relational_expression_4 .or
-    relational_expression_5;
-relational_expression_2
-    lessequals .and shift_expression .and .true .emit OP_LESSEQUAL;
-relational_expression_3
-    greaterequals .and shift_expression .and .true .emit OP_GREATEREQUAL;
-relational_expression_4
-    less .and shift_expression .and .true .emit OP_LESS;
-relational_expression_5
-    greater .and shift_expression .and .true .emit OP_GREATER;
-
-shift_expression
-    additive_expression .and .loop shift_expression_1;
-shift_expression_1
-    shift_expression_2 .or shift_expression_3;
-shift_expression_2
-    lessless .and additive_expression .and .true .emit OP_LEFTSHIFT;
-shift_expression_3
-    greatergreater .and additive_expression .and .true .emit OP_RIGHTSHIFT;
-
-additive_expression
-    multiplicative_expression .and .loop additive_expression_1;
-additive_expression_1
-    additive_expression_2 .or additive_expression_3;
-additive_expression_2
-    plus .and multiplicative_expression .and .true .emit OP_ADD;
-additive_expression_3
-    dash .and multiplicative_expression .and .true .emit OP_SUBTRACT;
-
-multiplicative_expression
-    unary_expression .and .loop multiplicative_expression_1;
-multiplicative_expression_1
-    multiplicative_expression_2 .or multiplicative_expression_3 .or multiplicative_expression_4;
-multiplicative_expression_2
-    star .and unary_expression .and .true .emit OP_MULTIPLY;
-multiplicative_expression_3
-    slash .and unary_expression .and .true .emit OP_DIVIDE;
-multiplicative_expression_4
-    percent .and unary_expression .and .true .emit OP_MODULUS;
-
-unary_expression
-    primary_expression .or unary_expression_1 .or unary_expression_2 .or unary_expression_3 .or
-    unary_expression_4;
-unary_expression_1
-    plus .and unary_expression .and .true .emit OP_PLUS;
-unary_expression_2
-    dash .and unary_expression .and .true .emit OP_MINUS;
-unary_expression_3
-    bang .and unary_expression .and .true .emit OP_NEGATE;
-unary_expression_4
-    tilda .and unary_expression .and .true .emit OP_COMPLEMENT;
-
-primary_expression
-   intconstant .or primary_expression_1;
-primary_expression_1
-   lparen .and logical_or_expression .and rparen;
-
-intconstant
-   integer .emit OP_PUSHINT;
-
-integer
-   integer_dec;
-
-integer_dec
-   digit_dec .emit 10 .emit * .and .loop digit_dec .emit * .and .true .emit '\0';
-
-digit_dec
-   '0'-'9';
-
-optional_space
-   .loop single_space;
-
-space
-   single_space .and .loop single_space;
-
-single_space
-   ' ' .or '\t';
-
-ampersand
-   optional_space .and '&' .and optional_space;
-
-ampersandampersand
-   optional_space .and '&' .and '&' .and optional_space;
-
-bang
-   optional_space .and '!' .and optional_space;
-
-bangequals
-   optional_space .and '!' .and '=' .and optional_space;
-
-bar
-   optional_space .and '|' .and optional_space;
-
-barbar
-   optional_space .and '|' .and '|' .and optional_space;
-
-caret
-   optional_space .and '^' .and optional_space;
-
-dash
-   optional_space .and '-' .and optional_space;
-
-equalsequals
-   optional_space .and '=' .and '=' .and optional_space;
-
-greater
-   optional_space .and '>' .and optional_space;
-
-greaterequals
-   optional_space .and '>' .and '=' .and optional_space;
-
-greatergreater
-   optional_space .and '>' .and '>' .and optional_space;
-
-less
-   optional_space .and '<' .and optional_space;
-
-lessequals
-   optional_space .and '<' .and '=' .and optional_space;
-
-lessless
-   optional_space .and '<' .and '<' .and optional_space;
-
-lparen
-   optional_space .and '(' .and optional_space;
-
-percent
-   optional_space .and '%' .and optional_space;
-
-plus
-   optional_space .and '+' .and optional_space;
-
-rparen
-   optional_space .and ')' .and optional_space;
-
-slash
-   optional_space .and '/' .and optional_space;
-
-star
-   optional_space .and '*' .and optional_space;
-
-tilda
-   optional_space .and '~' .and optional_space;
-
diff --git a/src/mesa/shader/slang/library/slang_pp_expression_syn.h b/src/mesa/shader/slang/library/slang_pp_expression_syn.h
deleted file mode 100644
index f3e9ef6..0000000
--- a/src/mesa/shader/slang/library/slang_pp_expression_syn.h
+++ /dev/null
@@ -1,179 +0,0 @@
-
-/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE .syn FILE */
-
-".syntax expression;\n"
-".emtcode EXP_END 0\n"
-".emtcode EXP_EXPRESSION 1\n"
-".emtcode OP_END 0\n"
-".emtcode OP_PUSHINT 1\n"
-".emtcode OP_LOGICALOR 2\n"
-".emtcode OP_LOGICALAND 3\n"
-".emtcode OP_OR 4\n"
-".emtcode OP_XOR 5\n"
-".emtcode OP_AND 6\n"
-".emtcode OP_EQUAL 7\n"
-".emtcode OP_NOTEQUAL 8\n"
-".emtcode OP_LESSEQUAL 9\n"
-".emtcode OP_GREATEREQUAL 10\n"
-".emtcode OP_LESS 11\n"
-".emtcode OP_GREATER 12\n"
-".emtcode OP_LEFTSHIFT 13\n"
-".emtcode OP_RIGHTSHIFT 14\n"
-".emtcode OP_ADD 15\n"
-".emtcode OP_SUBTRACT 16\n"
-".emtcode OP_MULTIPLY 17\n"
-".emtcode OP_DIVIDE 18\n"
-".emtcode OP_MODULUS 19\n"
-".emtcode OP_PLUS 20\n"
-".emtcode OP_MINUS 21\n"
-".emtcode OP_NEGATE 22\n"
-".emtcode OP_COMPLEMENT 23\n"
-"expression\n"
-" first_expression .and optional_second_expression .and optional_space .and '\\0' .emit EXP_END;\n"
-"first_expression\n"
-" optional_space .and logical_or_expression .emit EXP_EXPRESSION .and .true .emit OP_END;\n"
-"optional_second_expression\n"
-" second_expression .or .true;\n"
-"second_expression\n"
-" space .and logical_or_expression .emit EXP_EXPRESSION .and .true .emit OP_END;\n"
-"logical_or_expression\n"
-" logical_and_expression .and .loop logical_or_expression_1;\n"
-"logical_or_expression_1\n"
-" barbar .and logical_and_expression .and .true .emit OP_LOGICALOR;\n"
-"logical_and_expression\n"
-" or_expression .and .loop logical_and_expression_1;\n"
-"logical_and_expression_1\n"
-" ampersandampersand .and or_expression .and .true .emit OP_LOGICALAND;\n"
-"or_expression\n"
-" xor_expression .and .loop or_expression_1;\n"
-"or_expression_1\n"
-" bar .and xor_expression .and .true .emit OP_OR;\n"
-"xor_expression\n"
-" and_expression .and .loop xor_expression_1;\n"
-"xor_expression_1\n"
-" caret .and and_expression .and .true .emit OP_XOR;\n"
-"and_expression\n"
-" equality_expression .and .loop and_expression_1;\n"
-"and_expression_1\n"
-" ampersand .and equality_expression .and .true .emit OP_AND;\n"
-"equality_expression\n"
-" relational_expression .and .loop equality_expression_1;\n"
-"equality_expression_1\n"
-" equality_expression_2 .or equality_expression_3;\n"
-"equality_expression_2\n"
-" equalsequals .and relational_expression .and .true .emit OP_EQUAL;\n"
-"equality_expression_3\n"
-" bangequals .and relational_expression .and .true .emit OP_NOTEQUAL;\n"
-"relational_expression\n"
-" shift_expression .and .loop relational_expression_1;\n"
-"relational_expression_1\n"
-" relational_expression_2 .or relational_expression_3 .or relational_expression_4 .or\n"
-" relational_expression_5;\n"
-"relational_expression_2\n"
-" lessequals .and shift_expression .and .true .emit OP_LESSEQUAL;\n"
-"relational_expression_3\n"
-" greaterequals .and shift_expression .and .true .emit OP_GREATEREQUAL;\n"
-"relational_expression_4\n"
-" less .and shift_expression .and .true .emit OP_LESS;\n"
-"relational_expression_5\n"
-" greater .and shift_expression .and .true .emit OP_GREATER;\n"
-"shift_expression\n"
-" additive_expression .and .loop shift_expression_1;\n"
-"shift_expression_1\n"
-" shift_expression_2 .or shift_expression_3;\n"
-"shift_expression_2\n"
-" lessless .and additive_expression .and .true .emit OP_LEFTSHIFT;\n"
-"shift_expression_3\n"
-" greatergreater .and additive_expression .and .true .emit OP_RIGHTSHIFT;\n"
-"additive_expression\n"
-" multiplicative_expression .and .loop additive_expression_1;\n"
-"additive_expression_1\n"
-" additive_expression_2 .or additive_expression_3;\n"
-"additive_expression_2\n"
-" plus .and multiplicative_expression .and .true .emit OP_ADD;\n"
-"additive_expression_3\n"
-" dash .and multiplicative_expression .and .true .emit OP_SUBTRACT;\n"
-"multiplicative_expression\n"
-" unary_expression .and .loop multiplicative_expression_1;\n"
-"multiplicative_expression_1\n"
-" multiplicative_expression_2 .or multiplicative_expression_3 .or multiplicative_expression_4;\n"
-"multiplicative_expression_2\n"
-" star .and unary_expression .and .true .emit OP_MULTIPLY;\n"
-"multiplicative_expression_3\n"
-" slash .and unary_expression .and .true .emit OP_DIVIDE;\n"
-"multiplicative_expression_4\n"
-" percent .and unary_expression .and .true .emit OP_MODULUS;\n"
-"unary_expression\n"
-" primary_expression .or unary_expression_1 .or unary_expression_2 .or unary_expression_3 .or\n"
-" unary_expression_4;\n"
-"unary_expression_1\n"
-" plus .and unary_expression .and .true .emit OP_PLUS;\n"
-"unary_expression_2\n"
-" dash .and unary_expression .and .true .emit OP_MINUS;\n"
-"unary_expression_3\n"
-" bang .and unary_expression .and .true .emit OP_NEGATE;\n"
-"unary_expression_4\n"
-" tilda .and unary_expression .and .true .emit OP_COMPLEMENT;\n"
-"primary_expression\n"
-" intconstant .or primary_expression_1;\n"
-"primary_expression_1\n"
-" lparen .and logical_or_expression .and rparen;\n"
-"intconstant\n"
-" integer .emit OP_PUSHINT;\n"
-"integer\n"
-" integer_dec;\n"
-"integer_dec\n"
-" digit_dec .emit 10 .emit * .and .loop digit_dec .emit * .and .true .emit '\\0';\n"
-"digit_dec\n"
-" '0'-'9';\n"
-"optional_space\n"
-" .loop single_space;\n"
-"space\n"
-" single_space .and .loop single_space;\n"
-"single_space\n"
-" ' ' .or '\\t';\n"
-"ampersand\n"
-" optional_space .and '&' .and optional_space;\n"
-"ampersandampersand\n"
-" optional_space .and '&' .and '&' .and optional_space;\n"
-"bang\n"
-" optional_space .and '!' .and optional_space;\n"
-"bangequals\n"
-" optional_space .and '!' .and '=' .and optional_space;\n"
-"bar\n"
-" optional_space .and '|' .and optional_space;\n"
-"barbar\n"
-" optional_space .and '|' .and '|' .and optional_space;\n"
-"caret\n"
-" optional_space .and '^' .and optional_space;\n"
-"dash\n"
-" optional_space .and '-' .and optional_space;\n"
-"equalsequals\n"
-" optional_space .and '=' .and '=' .and optional_space;\n"
-"greater\n"
-" optional_space .and '>' .and optional_space;\n"
-"greaterequals\n"
-" optional_space .and '>' .and '=' .and optional_space;\n"
-"greatergreater\n"
-" optional_space .and '>' .and '>' .and optional_space;\n"
-"less\n"
-" optional_space .and '<' .and optional_space;\n"
-"lessequals\n"
-" optional_space .and '<' .and '=' .and optional_space;\n"
-"lessless\n"
-" optional_space .and '<' .and '<' .and optional_space;\n"
-"lparen\n"
-" optional_space .and '(' .and optional_space;\n"
-"percent\n"
-" optional_space .and '%' .and optional_space;\n"
-"plus\n"
-" optional_space .and '+' .and optional_space;\n"
-"rparen\n"
-" optional_space .and ')' .and optional_space;\n"
-"slash\n"
-" optional_space .and '/' .and optional_space;\n"
-"star\n"
-" optional_space .and '*' .and optional_space;\n"
-"tilda\n"
-" optional_space .and '~' .and optional_space;\n"
-""
diff --git a/src/mesa/shader/slang/library/slang_pp_version.syn b/src/mesa/shader/slang/library/slang_pp_version.syn
deleted file mode 100644
index 3fe1a57..0000000
--- a/src/mesa/shader/slang/library/slang_pp_version.syn
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.6
- *
- * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL 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 slang_pp_version.syn
- * slang #version directive syntax
- * \author Michal Krol
- */
-
-.syntax version_directive;
-
-version_directive
-	version_directive_1;
-version_directive_1
-	prior_optional_spaces .and optional_version_directive .and .true .emit $;
-
-optional_version_directive
-	version_directive_body .or .true .emit 10 .emit 1;
-
-version_directive_body
-	'#' .and optional_space .and "version" .and space .and version_number .and optional_space .and
-	new_line;
-
-version_number
-	version_number_100 .or version_number_110 .or version_number_120;
-
-version_number_100
-	leading_zeroes .and "100" .emit 0 .emit 1;
-
-version_number_110
-	leading_zeroes .and "110" .emit 10 .emit 1;
-
-version_number_120
-	leading_zeroes .and "120" .emit 20 .emit 1;
-
-leading_zeroes
-	.loop zero;
-
-zero
-	'0';
-
-space
-    single_space .and .loop single_space;
-
-optional_space
-    .loop single_space;
-
-single_space
-    ' ' .or '\t';
-
-prior_optional_spaces
-	.loop prior_space;
-
-prior_space
-	c_style_comment_block .or cpp_style_comment_block .or space .or new_line;
-
-c_style_comment_block
-    '/' .and '*' .and c_style_comment_rest;
-
-c_style_comment_rest
-    .loop c_style_comment_char_no_star .and c_style_comment_rest_1;
-c_style_comment_rest_1
-    c_style_comment_end .or c_style_comment_rest_2;
-c_style_comment_rest_2
-    '*' .and c_style_comment_rest;
-
-c_style_comment_char_no_star
-    '\x2B'-'\xFF' .or '\x01'-'\x29';
-
-c_style_comment_end
-    '*' .and '/';
-
-cpp_style_comment_block
-    '/' .and '/' .and cpp_style_comment_block_1;
-cpp_style_comment_block_1
-    cpp_style_comment_block_2 .or cpp_style_comment_block_3;
-cpp_style_comment_block_2
-    .loop cpp_style_comment_char .and new_line;
-cpp_style_comment_block_3
-    .loop cpp_style_comment_char;
-
-cpp_style_comment_char
-    '\x0E'-'\xFF' .or '\x01'-'\x09' .or '\x0B'-'\x0C';
-
-new_line
-    cr_lf .or lf_cr .or '\n' .or '\r';
-
-cr_lf
-    '\r' .and '\n';
-
-lf_cr
-	'\n' .and '\r';
-
-.string __string_filter;
-
-__string_filter
-    .loop __identifier_char;
-
-__identifier_char
-    'a'-'z' .or 'A'-'Z' .or '_' .or '0'-'9';
-
diff --git a/src/mesa/shader/slang/library/slang_pp_version_syn.h b/src/mesa/shader/slang/library/slang_pp_version_syn.h
deleted file mode 100644
index 54aee3f..0000000
--- a/src/mesa/shader/slang/library/slang_pp_version_syn.h
+++ /dev/null
@@ -1,69 +0,0 @@
-
-/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE .syn FILE */
-
-".syntax version_directive;\n"
-"version_directive\n"
-"	version_directive_1;\n"
-"version_directive_1\n"
-"	prior_optional_spaces .and optional_version_directive .and .true .emit $;\n"
-"optional_version_directive\n"
-"	version_directive_body .or .true .emit 10 .emit 1;\n"
-"version_directive_body\n"
-"	'#' .and optional_space .and \"version\" .and space .and version_number .and optional_space .and\n"
-"	new_line;\n"
-"version_number\n"
-"	version_number_100 .or version_number_110 .or version_number_120;\n"
-"version_number_100\n"
-"	leading_zeroes .and \"100\" .emit 0 .emit 1;\n"
-"version_number_110\n"
-"	leading_zeroes .and \"110\" .emit 10 .emit 1;\n"
-"version_number_120\n"
-"	leading_zeroes .and \"120\" .emit 20 .emit 1;\n"
-"leading_zeroes\n"
-"	.loop zero;\n"
-"zero\n"
-"	'0';\n"
-"space\n"
-" single_space .and .loop single_space;\n"
-"optional_space\n"
-" .loop single_space;\n"
-"single_space\n"
-" ' ' .or '\\t';\n"
-"prior_optional_spaces\n"
-"	.loop prior_space;\n"
-"prior_space\n"
-"	c_style_comment_block .or cpp_style_comment_block .or space .or new_line;\n"
-"c_style_comment_block\n"
-" '/' .and '*' .and c_style_comment_rest;\n"
-"c_style_comment_rest\n"
-" .loop c_style_comment_char_no_star .and c_style_comment_rest_1;\n"
-"c_style_comment_rest_1\n"
-" c_style_comment_end .or c_style_comment_rest_2;\n"
-"c_style_comment_rest_2\n"
-" '*' .and c_style_comment_rest;\n"
-"c_style_comment_char_no_star\n"
-" '\\x2B'-'\\xFF' .or '\\x01'-'\\x29';\n"
-"c_style_comment_end\n"
-" '*' .and '/';\n"
-"cpp_style_comment_block\n"
-" '/' .and '/' .and cpp_style_comment_block_1;\n"
-"cpp_style_comment_block_1\n"
-" cpp_style_comment_block_2 .or cpp_style_comment_block_3;\n"
-"cpp_style_comment_block_2\n"
-" .loop cpp_style_comment_char .and new_line;\n"
-"cpp_style_comment_block_3\n"
-" .loop cpp_style_comment_char;\n"
-"cpp_style_comment_char\n"
-" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n"
-"new_line\n"
-" cr_lf .or lf_cr .or '\\n' .or '\\r';\n"
-"cr_lf\n"
-" '\\r' .and '\\n';\n"
-"lf_cr\n"
-"	'\\n' .and '\\r';\n"
-".string __string_filter;\n"
-"__string_filter\n"
-" .loop __identifier_char;\n"
-"__identifier_char\n"
-" 'a'-'z' .or 'A'-'Z' .or '_' .or '0'-'9';\n"
-""
diff --git a/src/mesa/shader/slang/library/slang_shader.syn b/src/mesa/shader/slang/library/slang_shader.syn
deleted file mode 100644
index cc5c70a..0000000
--- a/src/mesa/shader/slang/library/slang_shader.syn
+++ /dev/null
@@ -1,1716 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2004-2006  Brian Paul   All Rights Reserved.
- * 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, sublicense,
- * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL 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 slang_shader.syn
- * slang vertex/fragment shader syntax
- * \author Michal Krol
- */
-
-/*
- * usage:
- *   syn2c slang_shader.syn > slang_shader_syn.h
- *
- * when modifying or extending this file, several things must be taken into
- * consideration:
- *
- * - when adding new operators that were marked as reserved in the
- *   initial specification, one must only uncomment particular lines of
- *   code that refer to operators being added;
- *
- * - when adding new shader targets, one must reserve a new value for
- *   shader_type register and use it in .if constructs for symbols that
- *   are exclusive for that shader;
- *
- * - some symbols mimic output of other symbols - the best example is
- *   the "for" construct: expression "for (foo(); ; bar())" is seen as
- *   "for (foo(); true; bar())" by the output processor - hence, special
- *   care must be taken when rearranging output of essential symbols;
- *
- * - order of single-quoted tokens does matter in alternatives - so do not
- *   parse "<" operator before "<<" and "<<" before "<<=";
- *
- * - all double-quoted tokens are internally preprocessed to eliminate
- *   problems with parsing strings that are prefixes of other strings,
- *   like "sampler1D" and "sampler1DShadow";
- */
-
-.syntax translation_unit;
-
-/* revision number - increment after each change affecting emitted output */
-.emtcode REVISION                                   5
-
-/* external declaration (or precision or invariant stmt) */
-.emtcode EXTERNAL_NULL                              0
-.emtcode EXTERNAL_FUNCTION_DEFINITION               1
-.emtcode EXTERNAL_DECLARATION                       2
-.emtcode DEFAULT_PRECISION                          3
-.emtcode INVARIANT_STMT                             4
-
-/* precision */
-.emtcode PRECISION_DEFAULT                          0
-.emtcode PRECISION_LOW                              1
-.emtcode PRECISION_MEDIUM                           2
-.emtcode PRECISION_HIGH                             3
-
-/* declaration */
-.emtcode DECLARATION_FUNCTION_PROTOTYPE             1
-.emtcode DECLARATION_INIT_DECLARATOR_LIST           2
-
-/* function type */
-.emtcode FUNCTION_ORDINARY                          0
-.emtcode FUNCTION_CONSTRUCTOR                       1
-.emtcode FUNCTION_OPERATOR                          2
-
-/* function call type */
-.emtcode FUNCTION_CALL_NONARRAY                     0
-.emtcode FUNCTION_CALL_ARRAY                        1
-
-/* operator type */
-.emtcode OPERATOR_ADDASSIGN                         1
-.emtcode OPERATOR_SUBASSIGN                         2
-.emtcode OPERATOR_MULASSIGN                         3
-.emtcode OPERATOR_DIVASSIGN                         4
-/*.emtcode OPERATOR_MODASSIGN                         5*/
-/*.emtcode OPERATOR_LSHASSIGN                         6*/
-/*.emtcode OPERATOR_RSHASSIGN                         7*/
-/*.emtcode OPERATOR_ORASSIGN                          8*/
-/*.emtcode OPERATOR_XORASSIGN                         9*/
-/*.emtcode OPERATOR_ANDASSIGN                         10*/
-.emtcode OPERATOR_LOGICALXOR                        11
-/*.emtcode OPERATOR_BITOR                             12*/
-/*.emtcode OPERATOR_BITXOR                            13*/
-/*.emtcode OPERATOR_BITAND                            14*/
-.emtcode OPERATOR_LESS                              15
-.emtcode OPERATOR_GREATER                           16
-.emtcode OPERATOR_LESSEQUAL                         17
-.emtcode OPERATOR_GREATEREQUAL                      18
-/*.emtcode OPERATOR_LSHIFT                            19*/
-/*.emtcode OPERATOR_RSHIFT                            20*/
-.emtcode OPERATOR_MULTIPLY                          21
-.emtcode OPERATOR_DIVIDE                            22
-/*.emtcode OPERATOR_MODULUS                           23*/
-.emtcode OPERATOR_INCREMENT                         24
-.emtcode OPERATOR_DECREMENT                         25
-.emtcode OPERATOR_PLUS                              26
-.emtcode OPERATOR_MINUS                             27
-/*.emtcode OPERATOR_COMPLEMENT                        28*/
-.emtcode OPERATOR_NOT                               29
-
-/* init declarator list */
-.emtcode DECLARATOR_NONE                            0
-.emtcode DECLARATOR_NEXT                            1
-
-/* variable declaration */
-.emtcode VARIABLE_NONE                              0
-.emtcode VARIABLE_IDENTIFIER                        1
-.emtcode VARIABLE_INITIALIZER                       2
-.emtcode VARIABLE_ARRAY_EXPLICIT                    3
-.emtcode VARIABLE_ARRAY_UNKNOWN                     4
-
-/* type qualifier */
-.emtcode TYPE_QUALIFIER_NONE                        0
-.emtcode TYPE_QUALIFIER_CONST                       1
-.emtcode TYPE_QUALIFIER_ATTRIBUTE                   2
-.emtcode TYPE_QUALIFIER_VARYING                     3
-.emtcode TYPE_QUALIFIER_UNIFORM                     4
-.emtcode TYPE_QUALIFIER_FIXEDOUTPUT                 5
-.emtcode TYPE_QUALIFIER_FIXEDINPUT                  6
-
-/* invariant qualifier */
-.emtcode TYPE_VARIANT                               90
-.emtcode TYPE_INVARIANT                             91
-
-/* centroid qualifier */
-.emtcode TYPE_CENTER                                95
-.emtcode TYPE_CENTROID                              96
-
-/* type specifier */
-.emtcode TYPE_SPECIFIER_VOID                        0
-.emtcode TYPE_SPECIFIER_BOOL                        1
-.emtcode TYPE_SPECIFIER_BVEC2                       2
-.emtcode TYPE_SPECIFIER_BVEC3                       3
-.emtcode TYPE_SPECIFIER_BVEC4                       4
-.emtcode TYPE_SPECIFIER_INT                         5
-.emtcode TYPE_SPECIFIER_IVEC2                       6
-.emtcode TYPE_SPECIFIER_IVEC3                       7
-.emtcode TYPE_SPECIFIER_IVEC4                       8
-.emtcode TYPE_SPECIFIER_FLOAT                       9
-.emtcode TYPE_SPECIFIER_VEC2                        10
-.emtcode TYPE_SPECIFIER_VEC3                        11
-.emtcode TYPE_SPECIFIER_VEC4                        12
-.emtcode TYPE_SPECIFIER_MAT2                        13
-.emtcode TYPE_SPECIFIER_MAT3                        14
-.emtcode TYPE_SPECIFIER_MAT4                        15
-.emtcode TYPE_SPECIFIER_SAMPLER1D                   16
-.emtcode TYPE_SPECIFIER_SAMPLER2D                   17
-.emtcode TYPE_SPECIFIER_SAMPLER3D                   18
-.emtcode TYPE_SPECIFIER_SAMPLERCUBE                 19
-.emtcode TYPE_SPECIFIER_SAMPLER1DSHADOW             20
-.emtcode TYPE_SPECIFIER_SAMPLER2DSHADOW             21
-.emtcode TYPE_SPECIFIER_SAMPLER2DRECT               22
-.emtcode TYPE_SPECIFIER_SAMPLER2DRECTSHADOW         23
-.emtcode TYPE_SPECIFIER_STRUCT                      24
-.emtcode TYPE_SPECIFIER_TYPENAME                    25
-
-/* OpenGL 2.1 */
-.emtcode TYPE_SPECIFIER_MAT23                       26
-.emtcode TYPE_SPECIFIER_MAT32                       27
-.emtcode TYPE_SPECIFIER_MAT24                       28
-.emtcode TYPE_SPECIFIER_MAT42                       29
-.emtcode TYPE_SPECIFIER_MAT34                       30
-.emtcode TYPE_SPECIFIER_MAT43                       31
-
-/* type specifier array */
-.emtcode TYPE_SPECIFIER_NONARRAY                    0
-.emtcode TYPE_SPECIFIER_ARRAY                       1
-
-/* structure field */
-.emtcode FIELD_NONE                                 0
-.emtcode FIELD_NEXT                                 1
-.emtcode FIELD_ARRAY                                2
-
-/* operation */
-.emtcode OP_END                                     0
-.emtcode OP_BLOCK_BEGIN_NO_NEW_SCOPE                1
-.emtcode OP_BLOCK_BEGIN_NEW_SCOPE                   2
-.emtcode OP_DECLARE                                 3
-.emtcode OP_ASM                                     4
-.emtcode OP_BREAK                                   5
-.emtcode OP_CONTINUE                                6
-.emtcode OP_DISCARD                                 7
-.emtcode OP_RETURN                                  8
-.emtcode OP_EXPRESSION                              9
-.emtcode OP_IF                                      10
-.emtcode OP_WHILE                                   11
-.emtcode OP_DO                                      12
-.emtcode OP_FOR                                     13
-.emtcode OP_PUSH_VOID                               14
-.emtcode OP_PUSH_BOOL                               15
-.emtcode OP_PUSH_INT                                16
-.emtcode OP_PUSH_FLOAT                              17
-.emtcode OP_PUSH_IDENTIFIER                         18
-.emtcode OP_SEQUENCE                                19
-.emtcode OP_ASSIGN                                  20
-.emtcode OP_ADDASSIGN                               21
-.emtcode OP_SUBASSIGN                               22
-.emtcode OP_MULASSIGN                               23
-.emtcode OP_DIVASSIGN                               24
-/*.emtcode OP_MODASSIGN                               25*/
-/*.emtcode OP_LSHASSIGN                               26*/
-/*.emtcode OP_RSHASSIGN                               27*/
-/*.emtcode OP_ORASSIGN                                28*/
-/*.emtcode OP_XORASSIGN                               29*/
-/*.emtcode OP_ANDASSIGN                               30*/
-.emtcode OP_SELECT                                  31
-.emtcode OP_LOGICALOR                               32
-.emtcode OP_LOGICALXOR                              33
-.emtcode OP_LOGICALAND                              34
-/*.emtcode OP_BITOR                                   35*/
-/*.emtcode OP_BITXOR                                  36*/
-/*.emtcode OP_BITAND                                  37*/
-.emtcode OP_EQUAL                                   38
-.emtcode OP_NOTEQUAL                                39
-.emtcode OP_LESS                                    40
-.emtcode OP_GREATER                                 41
-.emtcode OP_LESSEQUAL                               42
-.emtcode OP_GREATEREQUAL                            43
-/*.emtcode OP_LSHIFT                                  44*/
-/*.emtcode OP_RSHIFT                                  45*/
-.emtcode OP_ADD                                     46
-.emtcode OP_SUBTRACT                                47
-.emtcode OP_MULTIPLY                                48
-.emtcode OP_DIVIDE                                  49
-/*.emtcode OP_MODULUS                                 50*/
-.emtcode OP_PREINCREMENT                            51
-.emtcode OP_PREDECREMENT                            52
-.emtcode OP_PLUS                                    53
-.emtcode OP_MINUS                                   54
-/*.emtcode OP_COMPLEMENT                              55*/
-.emtcode OP_NOT                                     56
-.emtcode OP_SUBSCRIPT                               57
-.emtcode OP_CALL                                    58
-.emtcode OP_FIELD                                   59
-.emtcode OP_POSTINCREMENT                           60
-.emtcode OP_POSTDECREMENT                           61
-.emtcode OP_PRECISION                               62
-.emtcode OP_METHOD                                  63
-
-/* parameter qualifier */
-.emtcode PARAM_QUALIFIER_IN                         0
-.emtcode PARAM_QUALIFIER_OUT                        1
-.emtcode PARAM_QUALIFIER_INOUT                      2
-
-/* function parameter */
-.emtcode PARAMETER_NONE                             0
-.emtcode PARAMETER_NEXT                             1
-
-/* function parameter array presence */
-.emtcode PARAMETER_ARRAY_NOT_PRESENT                0
-.emtcode PARAMETER_ARRAY_PRESENT                    1
-
-/* INVALID_EXTERNAL_DECLARATION seems to be reported when there's */
-/* any syntax errors... */
-.errtext INVALID_EXTERNAL_DECLARATION               "2001: Syntax error."
-.errtext INVALID_OPERATOR_OVERRIDE                  "2002: Invalid operator override."
-.errtext LBRACE_EXPECTED                            "2003: '{' expected but '$err_token$' found."
-.errtext LPAREN_EXPECTED                            "2004: '(' expected but '$err_token$' found."
-.errtext RPAREN_EXPECTED                            "2005: ')' expected but '$err_token$' found."
-.errtext INVALID_PRECISION                          "2006: Invalid precision specifier '$err_token$'."
-.errtext INVALID_PRECISION_TYPE                     "2007: Invalid precision type '$err_token$'."
-
-
-/*
- * tells whether the shader that is being parsed is a built-in shader or not
- *  0 - normal behaviour
- *  1 - accepts constructor and operator definitions and __asm statements
- * the implementation will set it to 1 when compiling internal built-in shaders
- */
-.regbyte parsing_builtin                            0
-
-/*
- * holds the type of the shader being parsed; possible values are
- * listed below.
- *   FRAGMENT_SHADER            1
- *   VERTEX_SHADER              2
- * shader type is set by the caller before parsing
- */
-.regbyte shader_type                                0
-
-/*
- * <variable_identifier> ::= <identifier>
- */
-variable_identifier
-    identifier .emit OP_PUSH_IDENTIFIER;
-
-/*
- *  <primary_expression> ::= <variable_identifier>
- *                         | <intconstant>
- *                         | <floatconstant>
- *                         | <boolconstant>
- *                         | "(" <expression> ")"
- */
-primary_expression
-    floatconstant .or boolconstant .or intconstant .or variable_identifier .or primary_expression_1;
-primary_expression_1
-    lparen .and expression .and rparen;
-
-/*
- * <postfix_expression> ::= <primary_expression>
- *                        | <postfix_expression> "[" <integer_expression> "]"
- *                        | <function_call>
- *                        | <postfix_expression> "." <field_selection>
- *                        | <postfix_expression> "++"
- *                        | <postfix_expression> "--"
- */
-postfix_expression
-    postfix_expression_1 .and .loop postfix_expression_2;
-postfix_expression_1
-    function_call .or primary_expression;
-postfix_expression_2
-    postfix_expression_3 .or postfix_expression_4 .or
-    plusplus .emit OP_POSTINCREMENT .or
-    minusminus .emit OP_POSTDECREMENT;
-postfix_expression_3
-    lbracket .and integer_expression .and rbracket .emit OP_SUBSCRIPT;
-postfix_expression_4
-    dot .and field_selection .emit OP_FIELD;
-
-/*
- * <integer_expression> ::= <expression>
- */
-integer_expression
-    expression;
-
-/*
- * <function_call> ::= <function_call_generic>
- */
-function_call
-    function_call_or_method;
-
-/*
- * <function_call_or_method> ::= <regular_function_call>
- *                             | <postfix_expression> "." <function_call_generic>
- */
-function_call_or_method
-    regular_function_call .or method_call;
-
-/*
- * <method_call> ::= <identifier> "." <function_call_generic>
- */
-method_call
-    identifier .emit OP_METHOD .and dot .and function_call_generic .and .true .emit OP_END;
-
-/*
- * <regular_function_call> ::= <function_call_generic>
- */
-regular_function_call
-    function_call_generic .emit OP_CALL .and .true .emit OP_END;
-
-/*
- * <function_call_generic> ::= <function_call_header_with_parameters> ")"
- *                           | <function_call_header_no_parameters> ")"
- */
-function_call_generic
-    function_call_generic_1 .or function_call_generic_2;
-function_call_generic_1
-    function_call_header_with_parameters .and rparen .error RPAREN_EXPECTED;
-function_call_generic_2
-    function_call_header_no_parameters .and rparen .error RPAREN_EXPECTED;
-
-/*
- * <function_call_header_no_parameters>::= <function_call_header> "void"
- *                                        | <function_call_header>
- */
-function_call_header_no_parameters
-    function_call_header .and function_call_header_no_parameters_1;
-function_call_header_no_parameters_1
-    "void" .or .true;
-
-/*
- * <function_call_header_with_parameters> ::= <function_call_header> <assignment_expression>
- *                                          | <function_call_header_with_parameters> "," <assignment_expression>
- */
-function_call_header_with_parameters
-    function_call_header .and assignment_expression .and .true .emit OP_END .and
-    .loop function_call_header_with_parameters_1;
-function_call_header_with_parameters_1
-    comma .and assignment_expression .and .true .emit OP_END;
-
-/*
- * <function_call_header> ::= <function_identifier> "("
- */
-function_call_header
-    function_identifier .and lparen;
-
-/*
- * <function_identifier> ::= <constructor_identifier>
- *                         | <identifier>
- *                         | <type_specifier>
- *
- * note: <constructor_identifier> and <type_specifier> have been deleted
- */
-function_identifier
-    identifier .and function_identifier_opt_array;
-function_identifier_opt_array
-    function_identifier_array .emit FUNCTION_CALL_ARRAY .or
-    .true .emit FUNCTION_CALL_NONARRAY;
-function_identifier_array
-    lbracket .and constant_expression .and rbracket;
-
-/*
- * <unary_expression> ::= <postfix_expression>
- *                      | "++" <unary_expression>
- *                      | "--" <unary_expression>
- *                      | <unary_operator> <unary_expression>
- *
- * <unary_operator>   ::= "+"
- *                      | "-"
- *                      | "!"
- *                      | "~" // reserved
- */
-unary_expression
-    postfix_expression .or unary_expression_1 .or unary_expression_2 .or unary_expression_3 .or
-    unary_expression_4 .or unary_expression_5/* .or unary_expression_6*/;
-unary_expression_1
-    plusplus .and unary_expression .and .true .emit OP_PREINCREMENT;
-unary_expression_2
-    minusminus .and unary_expression .and .true .emit OP_PREDECREMENT;
-unary_expression_3
-    plus .and unary_expression .and .true .emit OP_PLUS;
-unary_expression_4
-    minus .and unary_expression .and .true .emit OP_MINUS;
-unary_expression_5
-    bang .and unary_expression .and .true .emit OP_NOT;
-/*unary_expression_6
-    tilde .and unary_expression .and .true .emit OP_COMPLEMENT;*/
-
-/*
- * <multiplicative_expression> ::= <unary_expression>
- *                               | <multiplicative_expression> "*" <unary_expression>
- *                               | <multiplicative_expression> "/" <unary_expression>
- *                               | <multiplicative_expression> "%" <unary_expression> // reserved
- */
-multiplicative_expression
-    unary_expression .and .loop multiplicative_expression_1;
-multiplicative_expression_1
-    multiplicative_expression_2 .or multiplicative_expression_3/* .or multiplicative_expression_4*/;
-multiplicative_expression_2
-    star .and unary_expression .and .true .emit OP_MULTIPLY;
-multiplicative_expression_3
-    slash .and unary_expression .and .true .emit OP_DIVIDE;
-/*multiplicative_expression_4
-    percent .and unary_expression .and .true .emit OP_MODULUS;*/
-
-/*
- * <additive_expression> ::= <multiplicative_expression>
- *                         | <additive_expression> "+" <multiplicative_expression>
- *                         | <additive_expression> "-" <multiplicative_expression>
- */
-additive_expression
-    multiplicative_expression .and .loop additive_expression_1;
-additive_expression_1
-    additive_expression_2 .or additive_expression_3;
-additive_expression_2
-    plus .and multiplicative_expression .and .true .emit OP_ADD;
-additive_expression_3
-    minus .and multiplicative_expression .and .true .emit OP_SUBTRACT;
-
-/*
- * <shift_expression> ::= <additive_expression>
- *                      | <shift_expression> "<<" <additive_expression> // reserved
- *                      | <shift_expression> ">>" <additive_expression> // reserved
- */
-shift_expression
-    additive_expression/* .and .loop shift_expression_1*/;
-/*shift_expression_1
-    shift_expression_2 .or shift_expression_3;*/
-/*shift_expression_2
-    lessless .and additive_expression .and .true .emit OP_LSHIFT;*/
-/*shift_expression_3
-    greatergreater .and additive_expression .and .true .emit OP_RSHIFT;*/
-
-/*
- * <relational_expression> ::= <shift_expression>
- *                           | <relational_expression> "<" <shift_expression>
- *                           | <relational_expression> ">" <shift_expression>
- *                           | <relational_expression> "<=" <shift_expression>
- *                           | <relational_expression> ">=" <shift_expression>
- */
-relational_expression
-    shift_expression .and .loop relational_expression_1;
-relational_expression_1
-    relational_expression_2 .or relational_expression_3 .or relational_expression_4 .or
-    relational_expression_5;
-relational_expression_2
-    lessequals .and shift_expression .and .true .emit OP_LESSEQUAL;
-relational_expression_3
-    greaterequals .and shift_expression .and .true .emit OP_GREATEREQUAL;
-relational_expression_4
-    less .and shift_expression .and .true .emit OP_LESS;
-relational_expression_5
-    greater .and shift_expression .and .true .emit OP_GREATER;
-
-/*
- * <equality_expression> ::= <relational_expression>
- *                         | <equality_expression> "==" <relational_expression>
- *                         | <equality_expression> "!=" <relational_expression>
- */
-equality_expression
-    relational_expression .and .loop equality_expression_1;
-equality_expression_1
-    equality_expression_2 .or equality_expression_3;
-equality_expression_2
-    equalsequals .and relational_expression .and .true .emit OP_EQUAL;
-equality_expression_3
-    bangequals .and relational_expression .and .true .emit OP_NOTEQUAL;
-
-/*
- * <and_expression> ::= <equality_expression>
- *                    | <and_expression> "&" <equality_expression> // reserved
- */
-and_expression
-    equality_expression/* .and .loop and_expression_1*/;
-/*and_expression_1
-    ampersand .and equality_expression .and .true .emit OP_BITAND;*/
-
-/*
- * <exclusive_or_expression> ::= <and_expression>
- *                             | <exclusive_or_expression> "^" <and_expression> // reserved
- */
-exclusive_or_expression
-    and_expression/* .and .loop exclusive_or_expression_1*/;
-/*exclusive_or_expression_1
-    caret .and and_expression .and .true .emit OP_BITXOR;*/
-
-/*
- * <inclusive_or_expression> ::= <exclusive_or_expression>
- *                             | <inclusive_or_expression> "|" <exclusive_or_expression> // reserved
- */
-inclusive_or_expression
-    exclusive_or_expression/* .and .loop inclusive_or_expression_1*/;
-/*inclusive_or_expression_1
-    bar .and exclusive_or_expression .and .true .emit OP_BITOR;*/
-
-/*
- * <logical_and_expression> ::= <inclusive_or_expression>
- *                            | <logical_and_expression> "&&" <inclusive_or_expression>
- */
-logical_and_expression
-    inclusive_or_expression .and .loop logical_and_expression_1;
-logical_and_expression_1
-    ampersandampersand .and inclusive_or_expression .and .true .emit OP_LOGICALAND;
-
-/*
- * <logical_xor_expression> ::= <logical_and_expression>
- *                            | <logical_xor_expression> "^^" <logical_and_expression>
- */
-logical_xor_expression
-    logical_and_expression .and .loop logical_xor_expression_1;
-logical_xor_expression_1
-    caretcaret .and logical_and_expression .and .true .emit OP_LOGICALXOR;
-
-/*
- * <logical_or_expression> ::= <logical_xor_expression>
- *                           | <logical_or_expression> "||" <logical_xor_expression>
- */
-logical_or_expression
-    logical_xor_expression .and .loop logical_or_expression_1;
-logical_or_expression_1
-    barbar .and logical_xor_expression .and .true .emit OP_LOGICALOR;
-
-/*
- * <conditional_expression> ::= <logical_or_expression>
- *                            | <logical_or_expression> "?" <expression> ":" <conditional_expression>
- */
-conditional_expression
-    logical_or_expression .and .loop conditional_expression_1;
-conditional_expression_1
-    question .and expression .and colon .and conditional_expression .and .true .emit OP_SELECT;
-
-/*
- * <assignment_expression> ::= <conditional_expression>
- *                           | <unary_expression> <assignment_operator> <assignment_expression>
- *
- * <assignment_operator> ::= "="
- *                         | "*="
- *                         | "/="
- *                         | "+="
- *                         | "-="
- *                         | "%=" // reserved
- *                         | "<<=" // reserved
- *                         | ">>=" // reserved
- *                         | "&=" // reserved
- *                         | "^=" // reserved
- *                         | "|=" // reserved
- */
-assignment_expression
-    assignment_expression_1 .or assignment_expression_2 .or assignment_expression_3 .or
-    assignment_expression_4 .or assignment_expression_5/* .or assignment_expression_6 .or
-    assignment_expression_7 .or assignment_expression_8 .or assignment_expression_9 .or
-    assignment_expression_10 .or assignment_expression_11*/ .or conditional_expression;
-assignment_expression_1
-    unary_expression .and equals .and assignment_expression .and .true .emit OP_ASSIGN;
-assignment_expression_2
-    unary_expression .and starequals .and assignment_expression .and .true .emit OP_MULASSIGN;
-assignment_expression_3
-    unary_expression .and slashequals .and assignment_expression .and .true .emit OP_DIVASSIGN;
-assignment_expression_4
-    unary_expression .and plusequals .and assignment_expression .and .true .emit OP_ADDASSIGN;
-assignment_expression_5
-    unary_expression .and minusequals .and assignment_expression .and .true .emit OP_SUBASSIGN;
-/*assignment_expression_6
-    unary_expression .and percentequals .and assignment_expression .and .true .emit OP_MODASSIGN;*/
-/*assignment_expression_7
-    unary_expression .and lesslessequals .and assignment_expression .and .true .emit OP_LSHASSIGN;*/
-/*assignment_expression_8
-    unary_expression .and greatergreaterequals .and assignment_expression .and
-    .true .emit OP_RSHASSIGN;*/
-/*assignment_expression_9
-    unary_expression .and ampersandequals .and assignment_expression .and .true .emit OP_ANDASSIGN;*/
-/*assignment_expression_10
-    unary_expression .and caretequals .and assignment_expression .and .true .emit OP_XORASSIGN;*/
-/*assignment_expression_11
-    unary_expression .and barequals .and assignment_expression .and .true .emit OP_ORASSIGN;*/
-
-/*
- * <expression> ::= <assignment_expression>
- *                | <expression> "," <assignment_expression>
- */
-expression
-    assignment_expression .and .loop expression_1;
-expression_1
-    comma .and assignment_expression .and .true .emit OP_SEQUENCE;
-
-/*
- * <constant_expression> ::= <conditional_expression>
- */
-constant_expression
-    conditional_expression .and .true .emit OP_END;
-
-/*
- * <declaration> ::= <function_prototype> ";"
- *                 | <init_declarator_list> ";"
- */
-declaration
-    declaration_1 .or declaration_2;
-declaration_1
-    function_prototype .emit DECLARATION_FUNCTION_PROTOTYPE .and semicolon;
-declaration_2
-    init_declarator_list .emit DECLARATION_INIT_DECLARATOR_LIST .and semicolon;
-
-/*
- * <function_prototype> ::= <function_header> "void" ")"
- *                        | <function_declarator> ")"
- */
-function_prototype
-    function_prototype_1 .or function_prototype_2;
-function_prototype_1
-    function_header .and "void" .and rparen .error RPAREN_EXPECTED .emit PARAMETER_NONE;
-function_prototype_2
-    function_declarator .and rparen .error RPAREN_EXPECTED .emit PARAMETER_NONE;
-
-/*
- * <function_declarator> ::= <function_header>
- *                         | <function_header_with_parameters>
- */
-function_declarator
-    function_header_with_parameters .or function_header;
-
-/*
- * <function_header_with_parameters> ::= <function_header> <parameter_declaration>
- *                                     | <function_header_with_parameters> ","
- *                                       <parameter_declaration>
- */
-function_header_with_parameters
-    function_header .and parameter_declaration .and .loop function_header_with_parameters_1;
-function_header_with_parameters_1
-    comma .and parameter_declaration;
-
-/*
- * <function_header> ::= <fully_specified_type> <identifier> "("
- */
-function_header
-    function_header_nospace .or function_header_space;
-function_header_space
-    fully_specified_type_space .and space .and function_decl_identifier .and lparen;
-function_header_nospace
-    fully_specified_type_nospace .and function_decl_identifier .and lparen;
-
-/*
- * <function_decl_identifier> ::= "__constructor"
- *                              | <__operator>
- *                              | <identifier>
- *
- * note: this is an extension to the standard language specification.
- * normally slang disallows operator and constructor prototypes and definitions
- */
-function_decl_identifier
-    .if (parsing_builtin != 0) __operator .emit FUNCTION_OPERATOR .or
-    .if (parsing_builtin != 0) "__constructor" .emit FUNCTION_CONSTRUCTOR .or
-    identifier .emit FUNCTION_ORDINARY;
-
-/*
- * <__operator> ::= "__operator" <overriden_op>
- *
- * note: this is an extension to the standard language specification.
- * normally slang disallows operator prototypes and definitions
- */
-__operator
-    "__operator" .and overriden_operator .error INVALID_OPERATOR_OVERRIDE;
-
-/*
- * <overriden_op> ::= "="
- *                  | "+="
- *                  | "-="
- *                  | "*="
- *                  | "/="
- *                  | "%=" // reserved
- *                  | "<<=" // reserved
- *                  | ">>=" // reserved
- *                  | "&=" // reserved
- *                  | "^=" // reserved
- *                  | "|=" // reserved
- *                  | "^^"
- *                  | "|" // reserved
- *                  | "^" // reserved
- *                  | "&" // reserved
- *                  | "=="
- *                  | "!="
- *                  | "<"
- *                  | ">"
- *                  | "<="
- *                  | ">="
- *                  | "<<" // reserved
- *                  | ">>" // reserved
- *                  | "*"
- *                  | "/"
- *                  | "%" // reserved
- *                  | "++"
- *                  | "--"
- *                  | "+"
- *                  | "-"
- *                  | "~" // reserved
- *                  | "!"
- *
- * note: this is an extension to the standard language specification.
- * normally slang disallows operator prototypes and definitions
- */
-overriden_operator
-    plusplus .emit OPERATOR_INCREMENT .or
-    plusequals .emit OPERATOR_ADDASSIGN .or
-    plus .emit OPERATOR_PLUS .or
-    minusminus .emit OPERATOR_DECREMENT .or
-    minusequals .emit OPERATOR_SUBASSIGN .or
-    minus .emit OPERATOR_MINUS .or
-    bang .emit OPERATOR_NOT .or
-    starequals .emit OPERATOR_MULASSIGN .or
-    star .emit OPERATOR_MULTIPLY .or
-    slashequals .emit OPERATOR_DIVASSIGN .or
-    slash .emit OPERATOR_DIVIDE .or
-    lessequals .emit OPERATOR_LESSEQUAL .or
-    /*lesslessequals .emit OPERATOR_LSHASSIGN .or*/
-    /*lessless .emit OPERATOR_LSHIFT .or*/
-    less .emit OPERATOR_LESS .or
-    greaterequals .emit OPERATOR_GREATEREQUAL .or
-    /*greatergreaterequals .emit OPERATOR_RSHASSIGN .or*/
-    /*greatergreater .emit OPERATOR_RSHIFT .or*/
-    greater .emit OPERATOR_GREATER .or
-    /*percentequals .emit OPERATOR_MODASSIGN .or*/
-    /*percent .emit OPERATOR_MODULUS .or*/
-    /*ampersandequals .emit OPERATOR_ANDASSIGN */
-    /*ampersand .emit OPERATOR_BITAND .or*/
-    /*barequals .emit OPERATOR_ORASSIGN .or*/
-    /*bar .emit OPERATOR_BITOR .or*/
-    /*tilde .emit OPERATOR_COMPLEMENT .or*/
-    /*caretequals .emit OPERATOR_XORASSIGN .or*/
-    caretcaret .emit OPERATOR_LOGICALXOR /*.or
-    caret .emit OPERATOR_BITXOR*/;
-
-/*
- * <parameter_declarator> ::= <type_specifier> <identifier>
- *                          | <type_specifier> <identifier> "[" <constant_expression> "]"
- */
-parameter_declarator
-    parameter_declarator_nospace .or parameter_declarator_space;
-parameter_declarator_nospace
-    type_specifier_nospace .and identifier .and parameter_declarator_1;
-parameter_declarator_space
-    type_specifier_space .and space .and identifier .and parameter_declarator_1;
-parameter_declarator_1
-    parameter_declarator_2 .emit PARAMETER_ARRAY_PRESENT .or
-    .true .emit PARAMETER_ARRAY_NOT_PRESENT;
-parameter_declarator_2
-    lbracket .and constant_expression .and rbracket;
-
-/*
- * <parameter_declaration> ::= <type_qualifier> <parameter_qualifier>
- *                             <precision> <parameter_declarator>
- *                           | <type_qualifier> <parameter_qualifier>
- *                             <precision> <parameter_type_specifier>
- *                           | <type_qualifier> <parameter_qualifier>
- *                             <parameter_declarator>
- *                           | <type_qualifier> <parameter_qualifier>
- *                             <parameter_type_specifier>
- *                           | <parameter_qualifier> <precision>
- *                             <parameter_declarator>
- *                           | <parameter_qualifier> <precision>
- *                             <parameter_type_specifier>
- *                           | <parameter_qualifier> <parameter_declarator>
- *                           | <parameter_qualifier> <parameter_type_specifier>
- */
-parameter_declaration
-    parameter_declaration_1 .emit PARAMETER_NEXT;
-parameter_declaration_1
-    parameter_declaration_2 .or parameter_declaration_3;
-parameter_declaration_2
-    type_qualifier .and space .and parameter_qualifier .and parameter_declaration_4;
-parameter_declaration_3
-    parameter_qualifier .emit TYPE_QUALIFIER_NONE .and parameter_declaration_4;
-parameter_declaration_4
-    parameter_declaration_optprec .and parameter_declaration_rest;
-parameter_declaration_optprec
-    parameter_declaration_prec .or .true .emit PRECISION_DEFAULT;
-parameter_declaration_prec
-    precision .and space;
-parameter_declaration_rest
-    parameter_declarator .or parameter_type_specifier;
-
-/*
- * <parameter_qualifier> ::= "in"
- *                         | "out"
- *                         | "inout"
- *                         | ""
- */
-parameter_qualifier
-    parameter_qualifier_1 .or .true .emit PARAM_QUALIFIER_IN;
-parameter_qualifier_1
-    parameter_qualifier_2 .and space;
-parameter_qualifier_2
-    "in" .emit PARAM_QUALIFIER_IN .or
-    "out" .emit PARAM_QUALIFIER_OUT .or
-    "inout" .emit PARAM_QUALIFIER_INOUT;
-
-/*
- * <parameter_type_specifier> ::= <type_specifier>
- *                              | <type_specifier> "[" <constant_expression> "]"
- */
-parameter_type_specifier
-    parameter_type_specifier_1 .and .true .emit '\0' .and parameter_type_specifier_2;
-parameter_type_specifier_1
-    type_specifier_nospace .or type_specifier_space;
-parameter_type_specifier_2
-    parameter_type_specifier_3 .emit PARAMETER_ARRAY_PRESENT .or
-    .true .emit PARAMETER_ARRAY_NOT_PRESENT;
-parameter_type_specifier_3
-    lbracket .and constant_expression .and rbracket;
-
-/*
- * <init_declarator_list> ::= <single_declaration>
- *                          | <init_declarator_list> "," <identifier>
- *                          | <init_declarator_list> "," <identifier> "[" "]"
- *                          | <init_declarator_list> "," <identifier> "[" <constant_expression> "]"
- *                          | <init_declarator_list> "," <identifier> "=" <initializer>
- */
-init_declarator_list
-    single_declaration .and .loop init_declarator_list_1 .emit DECLARATOR_NEXT .and
-    .true .emit DECLARATOR_NONE;
-init_declarator_list_1
-    comma .and identifier .emit VARIABLE_IDENTIFIER .and init_declarator_list_2;
-init_declarator_list_2
-    init_declarator_list_3 .or init_declarator_list_4 .or .true .emit VARIABLE_NONE;
-init_declarator_list_3
-    equals .and initializer .emit VARIABLE_INITIALIZER;
-init_declarator_list_4
-    lbracket .and init_declarator_list_5 .and rbracket;
-init_declarator_list_5
-    constant_expression .emit VARIABLE_ARRAY_EXPLICIT .or .true .emit VARIABLE_ARRAY_UNKNOWN;
-
-/*
- * <single_declaration> ::= <fully_specified_type>
- *                        | <fully_specified_type> <identifier>
- *                        | <fully_specified_type> <identifier> "[" "]"
- *                        | <fully_specified_type> <identifier> "[" <constant_expression> "]"
- *                        | <fully_specified_type> <identifier> "=" <initializer>
- */
-single_declaration
-    single_declaration_nospace .or single_declaration_space;
-single_declaration_space
-    fully_specified_type_space .and single_declaration_space_1;
-single_declaration_nospace
-    fully_specified_type_nospace .and single_declaration_nospace_1;
-single_declaration_space_1
-    single_declaration_space_2 .emit VARIABLE_IDENTIFIER .or .true .emit VARIABLE_NONE;
-single_declaration_nospace_1
-    single_declaration_nospace_2 .emit VARIABLE_IDENTIFIER .or .true .emit VARIABLE_NONE;
-single_declaration_space_2
-    space .and identifier .and single_declaration_3;
-single_declaration_nospace_2
-    identifier .and single_declaration_3;
-single_declaration_3
-    single_declaration_4 .or single_declaration_5 .or .true .emit VARIABLE_NONE;
-single_declaration_4
-    equals .and initializer .emit VARIABLE_INITIALIZER;
-single_declaration_5
-    lbracket .and single_declaration_6 .and rbracket;
-single_declaration_6
-    constant_expression .emit VARIABLE_ARRAY_EXPLICIT .or .true .emit VARIABLE_ARRAY_UNKNOWN;
-
-/*
- * <fully_specified_type> ::= <opt_invariant> <opt_centroid> <opt_qualifer> <opt_precision> <type_specifier>
- *
- * Example: "invariant varying highp vec3"
- */
-fully_specified_type_space
-    fully_specified_type_optinvariant .and fully_specified_type_optcentroid .and fully_specified_type_optqual .and fully_specified_type_optprec .and type_specifier_space;
-fully_specified_type_nospace
-    fully_specified_type_optinvariant .and fully_specified_type_optcentroid .and fully_specified_type_optqual .and fully_specified_type_optprec .and type_specifier_nospace;
-fully_specified_type_optinvariant
-    fully_specified_type_invariant .or .true .emit TYPE_VARIANT;
-fully_specified_type_invariant
-    invariant_qualifier .and space;
-fully_specified_type_optcentroid
-    fully_specified_type_centroid .or .true .emit TYPE_CENTER;
-fully_specified_type_centroid
-    centroid_qualifier .and space;
-fully_specified_type_optqual
-    fully_specified_type_qual .or .true .emit TYPE_QUALIFIER_NONE;
-fully_specified_type_qual
-    type_qualifier .and space;
-fully_specified_type_optprec
-    fully_specified_type_prec .or .true .emit PRECISION_DEFAULT;
-fully_specified_type_prec
-    precision .and space;
-
-/*
- * <invariant_qualifier> ::= "invariant"
- */
-invariant_qualifier
-    "invariant" .emit TYPE_INVARIANT;
-
-centroid_qualifier
-    "centroid" .emit TYPE_CENTROID;
-
-
-/*
- * <type_qualifier> ::= "const"
- *                    | "attribute" // Vertex only.
- *                    | "varying"
- *                    | "uniform"
- *                    | "__fixed_output"
- *                    | "__fixed_input"
- *
- * note: this is an extension to the standard language specification,
- * normally slang disallows __fixed_output and __fixed_input type qualifiers
- */
-type_qualifier
-    "const" .emit TYPE_QUALIFIER_CONST .or
-    .if (shader_type == 2) "attribute" .emit TYPE_QUALIFIER_ATTRIBUTE .or
-    "varying" .emit TYPE_QUALIFIER_VARYING .or
-    "uniform" .emit TYPE_QUALIFIER_UNIFORM .or
-    .if (parsing_builtin != 0) "__fixed_output" .emit TYPE_QUALIFIER_FIXEDOUTPUT .or
-    .if (parsing_builtin != 0) "__fixed_input" .emit TYPE_QUALIFIER_FIXEDINPUT;
-
-/*
- * <type_specifier_nonarray> ::= "void"
- *                             | "float"
- *                             | "int"
- *                             | "bool"
- *                             | "vec2"
- *                             | "vec3"
- *                             | "vec4"
- *                             | "bvec2"
- *                             | "bvec3"
- *                             | "bvec4"
- *                             | "ivec2"
- *                             | "ivec3"
- *                             | "ivec4"
- *                             | "mat2"
- *                             | "mat3"
- *                             | "mat4"
- *                             | "mat2x3"
- *                             | "mat3x2"
- *                             | "mat2x4"
- *                             | "mat4x2"
- *                             | "mat3x4"
- *                             | "mat4x3"
- *                             | "sampler1D"
- *                             | "sampler2D"
- *                             | "sampler3D"
- *                             | "samplerCube"
- *                             | "sampler1DShadow"
- *                             | "sampler2DShadow"
- *                             | "sampler2DRect"
- *                             | "sampler2DRectShadow"
- *                             | <struct_specifier>
- *                             | <type_name>
- */
-type_specifier_nonarray_space
-    "void" .emit TYPE_SPECIFIER_VOID .or
-    "float" .emit TYPE_SPECIFIER_FLOAT .or
-    "int" .emit TYPE_SPECIFIER_INT .or
-    "bool" .emit TYPE_SPECIFIER_BOOL .or
-    "vec2" .emit TYPE_SPECIFIER_VEC2 .or
-    "vec3" .emit TYPE_SPECIFIER_VEC3 .or
-    "vec4" .emit TYPE_SPECIFIER_VEC4 .or
-    "bvec2" .emit TYPE_SPECIFIER_BVEC2 .or
-    "bvec3" .emit TYPE_SPECIFIER_BVEC3 .or
-    "bvec4" .emit TYPE_SPECIFIER_BVEC4 .or
-    "ivec2" .emit TYPE_SPECIFIER_IVEC2 .or
-    "ivec3" .emit TYPE_SPECIFIER_IVEC3 .or
-    "ivec4" .emit TYPE_SPECIFIER_IVEC4 .or
-    "mat2" .emit TYPE_SPECIFIER_MAT2 .or
-    "mat3" .emit TYPE_SPECIFIER_MAT3 .or
-    "mat4" .emit TYPE_SPECIFIER_MAT4 .or
-    "mat2x3" .emit TYPE_SPECIFIER_MAT23 .or
-    "mat3x2" .emit TYPE_SPECIFIER_MAT32 .or
-    "mat2x4" .emit TYPE_SPECIFIER_MAT24 .or
-    "mat4x2" .emit TYPE_SPECIFIER_MAT42 .or
-    "mat3x4" .emit TYPE_SPECIFIER_MAT34 .or
-    "mat4x3" .emit TYPE_SPECIFIER_MAT43 .or
-    "sampler1D" .emit TYPE_SPECIFIER_SAMPLER1D .or
-    "sampler2D" .emit TYPE_SPECIFIER_SAMPLER2D .or
-    "sampler3D" .emit TYPE_SPECIFIER_SAMPLER3D .or
-    "samplerCube" .emit TYPE_SPECIFIER_SAMPLERCUBE .or
-    "sampler1DShadow" .emit TYPE_SPECIFIER_SAMPLER1DSHADOW .or
-    "sampler2DShadow" .emit TYPE_SPECIFIER_SAMPLER2DSHADOW .or
-    "sampler2DRect" .emit TYPE_SPECIFIER_SAMPLER2DRECT .or
-    "sampler2DRectShadow" .emit TYPE_SPECIFIER_SAMPLER2DRECTSHADOW .or
-    type_name .emit TYPE_SPECIFIER_TYPENAME;
-type_specifier_nonarray_nospace
-    struct_specifier .emit TYPE_SPECIFIER_STRUCT;
-type_specifier_nonarray
-    type_specifier_nonarray_nospace .or type_specifier_nonarray_space;
-
-/*
- * <type_specifier> ::= <type_specifier_nonarray>
- *                    | <type_specifier_nonarray> "[" <constant_expression> "]"
- */
-type_specifier_space
-    type_specifier_nonarray_space .and .true .emit TYPE_SPECIFIER_NONARRAY;
-type_specifier_nospace
-    type_specifier_nospace_array .or type_specifier_nospace_1;
-type_specifier_nospace_1
-    type_specifier_nonarray_nospace .and .true .emit TYPE_SPECIFIER_NONARRAY;
-type_specifier_nospace_array
-    type_specifier_nonarray .and lbracket .emit TYPE_SPECIFIER_ARRAY .and constant_expression .and rbracket;
-
-/*
- * <struct_specifier> ::= "struct" <identifier> "{" <struct_declaration_list> "}"
- *                      | "struct" "{" <struct_declaration_list> "}"
- */
-struct_specifier
-    "struct" .and struct_specifier_1 .and optional_space .and lbrace .error LBRACE_EXPECTED .and
-    struct_declaration_list .and rbrace .emit FIELD_NONE;
-struct_specifier_1
-    struct_specifier_2 .or .true .emit '\0';
-struct_specifier_2
-    space .and identifier;
-
-/*
- * <struct_declaration_list> ::= <struct_declaration>
- *                             | <struct_declaration_list> <struct_declaration>
- */
-struct_declaration_list
-    struct_declaration .and .loop struct_declaration .emit FIELD_NEXT;
-
-/*
- * <struct_declaration> ::= <type_specifier> <struct_declarator_list> ";"
- */
-struct_declaration
-    struct_declaration_nospace .or struct_declaration_space;
-struct_declaration_space
-    type_specifier_space .and space .and struct_declarator_list .and semicolon .emit FIELD_NONE;
-struct_declaration_nospace
-    type_specifier_nospace .and struct_declarator_list .and semicolon .emit FIELD_NONE;
-
-/*
- * <struct_declarator_list> ::= <struct_declarator>
- *                            | <struct_declarator_list> "," <struct_declarator>
- */
-struct_declarator_list
-    struct_declarator .and .loop struct_declarator_list_1 .emit FIELD_NEXT;
-struct_declarator_list_1
-    comma .and struct_declarator;
-
-/*
- * <struct_declarator> ::= <identifier>
- *                       | <identifier> "[" <constant_expression> "]"
- */
-struct_declarator
-    identifier .and struct_declarator_1;
-struct_declarator_1
-    struct_declarator_2 .emit FIELD_ARRAY .or .true .emit FIELD_NONE;
-struct_declarator_2
-    lbracket .and constant_expression .and rbracket;
-
-/*
- * <initializer> ::= <assignment_expression>
- */
-initializer
-    assignment_expression .and .true .emit OP_END;
-
-/*
- * <declaration_statement> ::= <declaration>
- */
-declaration_statement
-    declaration;
-
-/*
- * <statement> ::= <compound_statement>
- *               | <simple_statement>
- */
-statement
-    compound_statement .or simple_statement;
-statement_space
-    compound_statement .or statement_space_1;
-statement_space_1
-    space .and simple_statement;
-
-/*
- * <simple_statement> ::= <__asm_statement>
- *                      | <selection_statement>
- *                      | <iteration_statement>
- *                      | <jump_statement>
- *                      | <expression_statement>
- *                      | <declaration_statement>
- *
- * note: this is an extension to the standard language specification.
- * normally slang disallows use of __asm statements
- */
-simple_statement
-    .if (parsing_builtin != 0) __asm_statement .emit OP_ASM .or
-    selection_statement .or
-    iteration_statement .or
-    precision_stmt .emit OP_PRECISION .or
-    jump_statement .or
-    expression_statement .emit OP_EXPRESSION .or
-    declaration_statement .emit OP_DECLARE;
-
-/*
- * <compound_statement> ::= "{" "}"
- *                        | "{" <statement_list> "}"
- */
-compound_statement
-    compound_statement_1 .emit OP_BLOCK_BEGIN_NEW_SCOPE .and .true .emit OP_END;
-compound_statement_1
-    compound_statement_2 .or compound_statement_3;
-compound_statement_2
-    lbrace .and rbrace;
-compound_statement_3
-    lbrace .and statement_list .and rbrace;
-
-/*
- * <compound_statement_no_new_scope> ::= "{" "}"
- *                                     | "{" <statement_list> "}"
- */
-compound_statement_no_new_scope
-    compound_statement_no_new_scope_1 .emit OP_BLOCK_BEGIN_NO_NEW_SCOPE .and .true .emit OP_END;
-compound_statement_no_new_scope_1
-    compound_statement_no_new_scope_2 .or compound_statement_no_new_scope_3;
-compound_statement_no_new_scope_2
-    lbrace .and rbrace;
-compound_statement_no_new_scope_3
-    lbrace .and statement_list .and rbrace;
-
-
-/*
- * <statement_list> ::= <statement>
- *                    | <statement_list> <statement>
- */
-statement_list
-    statement .and .loop statement;
-
-/*
- * <expression_statement> ::= ";"
- *                          | <expression> ";"
- */
-expression_statement
-    expression_statement_1 .or expression_statement_2;
-expression_statement_1
-    semicolon .emit OP_PUSH_VOID .emit OP_END;
-expression_statement_2
-    expression .and semicolon .emit OP_END;
-
-/*
- * <selection_statement> ::= "if" "(" <expression> ")" <selection_rest_statement>
- */
-selection_statement
-    "if" .emit OP_IF .and lparen .error LPAREN_EXPECTED .and expression .and
-    rparen .error RPAREN_EXPECTED .emit OP_END .and selection_rest_statement;
-
-/*
- * <selection_rest_statement> ::= <statement> "else" <statement>
- *                              | <statement>
- */
-selection_rest_statement
-    statement .and selection_rest_statement_1;
-selection_rest_statement_1
-    selection_rest_statement_2 .or .true .emit OP_EXPRESSION .emit OP_PUSH_VOID .emit OP_END;
-selection_rest_statement_2
-    "else" .and optional_space .and statement;
-
-/*
- * <condition> ::= <expression>
- *               | <fully_specified_type> <identifier> "=" <initializer>
- *
- * note: if <condition_1> is executed, the emit format must
- * match <declaration> emit format
- */
-condition
-    condition_1 .emit OP_DECLARE .emit DECLARATION_INIT_DECLARATOR_LIST .or
-    condition_3 .emit OP_EXPRESSION;
-condition_1
-    condition_1_nospace .or condition_1_space;
-condition_1_nospace
-    fully_specified_type_nospace .and condition_2;
-condition_1_space
-    fully_specified_type_space .and space .and condition_2;
-condition_2
-    identifier .emit VARIABLE_IDENTIFIER .and equals .emit VARIABLE_INITIALIZER .and
-    initializer .and .true .emit DECLARATOR_NONE;
-condition_3
-    expression .and .true .emit OP_END;
-
-/*
- * <iteration_statement> ::= "while" "(" <condition> ")" <statement>
- *                         | "do" <statement> "while" "(" <expression> ")" ";"
- *                         | "for" "(" <for_init_statement> <for_rest_statement> ")" <statement>
- */
-iteration_statement
-    iteration_statement_1 .or iteration_statement_2 .or iteration_statement_3;
-iteration_statement_1
-    "while" .emit OP_WHILE .and lparen .error LPAREN_EXPECTED .and condition .and
-    rparen .error RPAREN_EXPECTED .and statement;
-iteration_statement_2
-    "do" .emit OP_DO .and statement_space .and "while" .and lparen .error LPAREN_EXPECTED .and
-    expression .and rparen .error RPAREN_EXPECTED .emit OP_END .and semicolon;
-iteration_statement_3
-    "for" .emit OP_FOR .and lparen .error LPAREN_EXPECTED .and for_init_statement .and
-    for_rest_statement .and rparen .error RPAREN_EXPECTED .and statement;
-
-/*
- * <for_init_statement> ::= <expression_statement>
- *                        | <declaration_statement>
- */
-for_init_statement
-    expression_statement .emit OP_EXPRESSION .or declaration_statement .emit OP_DECLARE;
-
-/*
- * <conditionopt> ::= <condition>
- *                  | ""
- *
- * note: <conditionopt> is used only by "for" statement.
- * if <condition> is ommitted, parser simulates default behaviour,
- * that is simulates "true" expression
- */
-conditionopt
-    condition .or
-    .true .emit OP_EXPRESSION .emit OP_PUSH_BOOL .emit 2 .emit '1' .emit '\0' .emit OP_END;
-
-/*
- * <for_rest_statement> ::= <conditionopt> ";"
- *                        | <conditionopt> ";" <expression>
- */
-for_rest_statement
-    conditionopt .and semicolon .and for_rest_statement_1;
-for_rest_statement_1
-    for_rest_statement_2 .or .true .emit OP_PUSH_VOID .emit OP_END;
-for_rest_statement_2
-    expression .and .true .emit OP_END;
-
-/*
- * <jump_statement> ::= "continue" ";"
- *                    | "break" ";"
- *                    | "return" ";"
- *                    | "return" <expression> ";"
- *                    | "discard" ";" // Fragment shader only.
- */
-jump_statement
-    jump_statement_1 .or jump_statement_2 .or jump_statement_3 .or jump_statement_4 .or
-    .if (shader_type == 1) jump_statement_5;
-jump_statement_1
-    "continue" .and semicolon .emit OP_CONTINUE;
-jump_statement_2
-    "break" .and semicolon .emit OP_BREAK;
-jump_statement_3
-    "return" .emit OP_RETURN .and optional_space .and expression .and semicolon .emit OP_END;
-jump_statement_4
-    "return" .emit OP_RETURN .and semicolon .emit OP_PUSH_VOID .emit OP_END;
-jump_statement_5
-    "discard" .and semicolon .emit OP_DISCARD;
-
-/*
- * <__asm_statement> ::= "__asm" <identifier> <asm_arguments> ";"
- *
- * note: this is an extension to the standard language specification.
- * normally slang disallows __asm statements
- */
-__asm_statement
-    "__asm" .and space .and identifier .and space .and asm_arguments .and semicolon .emit OP_END;
-
-/*
- * <asm_arguments> ::= <asm_argument>
- *                   | <asm_arguments> "," <asm_argument>
- *
- * note: this is an extension to the standard language specification.
- * normally slang disallows __asm statements
- */
-asm_arguments
-    asm_argument .and .true .emit OP_END .and .loop asm_arguments_1;
-asm_arguments_1
-    comma .and asm_argument .and .true .emit OP_END;
-
-/*
- * <asm_argument> ::= <variable_identifier>
- *                  | <floatconstant>
- *
- * note: this is an extension to the standard language specification.
- * normally slang disallows __asm statements
- */
-asm_argument
-    var_with_field .or
-    variable_identifier .or
-    floatconstant;
-
-var_with_field
-    variable_identifier .and dot .and field_selection .emit OP_FIELD;
-
-
-/*
- * <translation_unit> ::= <external_declaration>
- *                      | <translation_unit> <external_declaration>
- */
-translation_unit
-    optional_space .emit REVISION .and external_declaration .error INVALID_EXTERNAL_DECLARATION .and
-    .loop external_declaration .and optional_space .and
-    '\0' .error INVALID_EXTERNAL_DECLARATION .emit EXTERNAL_NULL;
-
-
-/*
- * <external_declaration> ::= <function_definition>
- *                          | <declaration>
- */
-external_declaration
-    precision_stmt .emit DEFAULT_PRECISION .or
-    function_definition .emit EXTERNAL_FUNCTION_DEFINITION .or
-    invariant_stmt .emit INVARIANT_STMT .or
-    declaration .emit EXTERNAL_DECLARATION;
-
-
-/*
- * <precision_stmt> ::= "precision" <precision> <prectype>
- */
-precision_stmt
-    "precision" .and space .and precision .error INVALID_PRECISION .and space .and prectype .error INVALID_PRECISION_TYPE .and semicolon;
-
-/*
- * <precision> ::= "lowp"
- *               | "mediump"
- *               | "highp"
- */
-precision
-    "lowp" .emit PRECISION_LOW .or
-    "mediump" .emit PRECISION_MEDIUM .or
-    "highp" .emit PRECISION_HIGH;
-
-/*
- * <prectype> ::= "int"
- *              | "float"
- *              | "a sampler type"
- */
-prectype
-    "int" .emit TYPE_SPECIFIER_INT .or
-    "float" .emit TYPE_SPECIFIER_FLOAT .or
-    "sampler1D" .emit TYPE_SPECIFIER_SAMPLER1D .or
-    "sampler2D" .emit TYPE_SPECIFIER_SAMPLER2D .or
-    "sampler3D" .emit TYPE_SPECIFIER_SAMPLER3D .or
-    "samplerCube" .emit TYPE_SPECIFIER_SAMPLERCUBE .or
-    "sampler1DShadow" .emit TYPE_SPECIFIER_SAMPLER1DSHADOW .or
-    "sampler2DShadow" .emit TYPE_SPECIFIER_SAMPLER2DSHADOW .or
-    "sampler2DRect" .emit TYPE_SPECIFIER_SAMPLER2DRECT .or
-    "sampler2DRectShadow" .emit TYPE_SPECIFIER_SAMPLER2DRECTSHADOW;
-
-
-/*
- * <invariant_stmt> ::= "invariant" identifier;
- */
-invariant_stmt
-    "invariant" .and space .and identifier .and semicolon;
-
-
-/*
- * <function_definition> :: <function_prototype> <compound_statement_no_new_scope>
- */
-function_definition
-    function_prototype .and compound_statement_no_new_scope;
-
-
-
-/*
- * helper rules, not part of the official language syntax
- */
-
-digit_oct
-    '0'-'7';
-
-digit_dec
-    '0'-'9';
-
-digit_hex
-    '0'-'9' .or 'A'-'F' .or 'a'-'f';
-
-id_character_first
-    'a'-'z' .or 'A'-'Z' .or '_';
-
-id_character_next
-    id_character_first .or digit_dec;
-
-identifier
-    id_character_first .emit * .and .loop id_character_next .emit * .and .true .emit '\0';
-
-float
-    float_1 .or float_2 .or float_3;
-float_1
-    float_fractional_constant .and float_optional_exponent_part .and optional_f_suffix;
-float_2
-    float_digit_sequence .and .true .emit '\0' .and float_exponent_part .and optional_f_suffix;
-float_3
-    float_digit_sequence .and .true .emit '\0' .and 'f' .emit '\0';
-
-float_fractional_constant
-    float_fractional_constant_1 .or float_fractional_constant_2 .or float_fractional_constant_3;
-float_fractional_constant_1
-    float_digit_sequence .and '.' .and float_digit_sequence;
-float_fractional_constant_2
-    float_digit_sequence .and '.' .and .true .emit '\0';
-float_fractional_constant_3
-    '.' .emit '\0' .and float_digit_sequence;
-
-float_optional_exponent_part
-    float_exponent_part .or .true .emit '\0';
-
-float_digit_sequence
-    digit_dec .emit * .and .loop digit_dec .emit * .and .true .emit '\0';
-
-float_exponent_part
-    float_exponent_part_1 .or float_exponent_part_2;
-float_exponent_part_1
-    'e' .and float_optional_sign .and float_digit_sequence;
-float_exponent_part_2
-    'E' .and float_optional_sign .and float_digit_sequence;
-
-float_optional_sign
-    float_sign .or .true;
-
-float_sign
-    '+' .or '-' .emit '-';
-
-optional_f_suffix
-    'f' .or .true;
-
-
-integer
-    integer_hex .or integer_oct .or integer_dec;
-
-integer_hex
-    '0' .and integer_hex_1 .emit 0x10 .and digit_hex .emit * .and .loop digit_hex .emit * .and
-    .true .emit '\0';
-integer_hex_1
-    'x' .or 'X';
-
-integer_oct
-    '0' .emit 8 .emit * .and .loop digit_oct .emit * .and .true .emit '\0';
-
-integer_dec
-    digit_dec .emit 10 .emit * .and .loop digit_dec .emit * .and .true .emit '\0';
-
-boolean
-    "true" .emit 2 .emit '1' .emit '\0' .or
-    "false" .emit 2 .emit '0' .emit '\0';
-
-type_name
-    identifier;
-
-field_selection
-    identifier;
-
-floatconstant
-    float .emit OP_PUSH_FLOAT;
-
-intconstant
-    integer .emit OP_PUSH_INT;
-
-boolconstant
-    boolean .emit OP_PUSH_BOOL;
-
-optional_space
-    .loop single_space;
-
-space
-    single_space .and .loop single_space;
-
-single_space
-    white_char .or c_style_comment_block .or cpp_style_comment_block;
-
-white_char
-    ' ' .or '\t' .or new_line .or '\v' .or '\f';
-
-new_line
-    cr_lf .or lf_cr .or '\n' .or '\r';
-
-cr_lf
-    '\r' .and '\n';
-
-lf_cr
-    '\n' .and '\r';
-
-c_style_comment_block
-    '/' .and '*' .and c_style_comment_rest;
-
-c_style_comment_rest
-    .loop c_style_comment_char_no_star .and c_style_comment_rest_1;
-c_style_comment_rest_1
-    c_style_comment_end .or c_style_comment_rest_2;
-c_style_comment_rest_2
-    '*' .and c_style_comment_rest;
-
-c_style_comment_char_no_star
-    '\x2B'-'\xFF' .or '\x01'-'\x29';
-
-c_style_comment_end
-    '*' .and '/';
-
-cpp_style_comment_block
-    '/' .and '/' .and cpp_style_comment_block_1;
-cpp_style_comment_block_1
-    cpp_style_comment_block_2 .or cpp_style_comment_block_3;
-cpp_style_comment_block_2
-    .loop cpp_style_comment_char .and new_line;
-cpp_style_comment_block_3
-    .loop cpp_style_comment_char;
-
-cpp_style_comment_char
-    '\x0E'-'\xFF' .or '\x01'-'\x09' .or '\x0B'-'\x0C';
-
-/* lexical rules */
-
-/*ampersand
-    optional_space .and '&' .and optional_space;*/
-
-ampersandampersand
-    optional_space .and '&' .and '&' .and optional_space;
-
-/*ampersandequals
-    optional_space .and '&' .and '=' .and optional_space;*/
-
-/*bar
-    optional_space .and '|' .and optional_space;*/
-
-barbar
-    optional_space .and '|' .and '|' .and optional_space;
-
-/*barequals
-    optional_space .and '|' .and '=' .and optional_space;*/
-
-bang
-    optional_space .and '!' .and optional_space;
-
-bangequals
-    optional_space .and '!' .and '=' .and optional_space;
-
-/*caret
-    optional_space .and '^' .and optional_space;*/
-
-caretcaret
-    optional_space .and '^' .and '^' .and optional_space;
-
-/*caretequals
-    optional_space .and '^' .and '=' .and optional_space;*/
-
-colon
-    optional_space .and ':' .and optional_space;
-
-comma
-    optional_space .and ',' .and optional_space;
-
-dot
-    optional_space .and '.' .and optional_space;
-
-equals
-    optional_space .and '=' .and optional_space;
-
-equalsequals
-    optional_space .and '=' .and '=' .and optional_space;
-
-greater
-    optional_space .and '>' .and optional_space;
-
-greaterequals
-    optional_space .and '>' .and '=' .and optional_space;
-
-/*greatergreater
-    optional_space .and '>' .and '>' .and optional_space;*/
-
-/*greatergreaterequals
-    optional_space .and '>' .and '>' .and '=' .and optional_space;*/
-
-lbrace
-    optional_space .and '{' .and optional_space;
-
-lbracket
-    optional_space .and '[' .and optional_space;
-
-less
-    optional_space .and '<' .and optional_space;
-
-lessequals
-    optional_space .and '<' .and '=' .and optional_space;
-
-/*lessless
-    optional_space .and '<' .and '<' .and optional_space;*/
-
-/*lesslessequals
-    optional_space .and '<' .and '<' .and '=' .and optional_space;*/
-
-lparen
-    optional_space .and '(' .and optional_space;
-
-minus
-    optional_space .and '-' .and optional_space;
-
-minusequals
-    optional_space .and '-' .and '=' .and optional_space;
-
-minusminus
-    optional_space .and '-' .and '-' .and optional_space;
-
-/*percent
-    optional_space .and '%' .and optional_space;*/
-
-/*percentequals
-    optional_space .and '%' .and '=' .and optional_space;*/
-
-plus
-    optional_space .and '+' .and optional_space;
-
-plusequals
-    optional_space .and '+' .and '=' .and optional_space;
-
-plusplus
-    optional_space .and '+' .and '+' .and optional_space;
-
-question
-    optional_space .and '?' .and optional_space;
-
-rbrace
-    optional_space .and '}' .and optional_space;
-
-rbracket
-    optional_space .and ']' .and optional_space;
-
-rparen
-    optional_space .and ')' .and optional_space;
-
-semicolon
-    optional_space .and ';' .and optional_space;
-
-slash
-    optional_space .and '/' .and optional_space;
-
-slashequals
-    optional_space .and '/' .and '=' .and optional_space;
-
-star
-    optional_space .and '*' .and optional_space;
-
-starequals
-    optional_space .and '*' .and '=' .and optional_space;
-
-/*tilde
-    optional_space .and '~' .and optional_space;*/
-
-/* string rules - these are used internally by the parser when parsing quoted strings */
-
-.string string_lexer;
-
-string_lexer
-    lex_first_identifier_character .and .loop lex_next_identifier_character;
-
-lex_first_identifier_character
-    'a'-'z' .or 'A'-'Z' .or '_';
-
-lex_next_identifier_character
-    'a'-'z' .or 'A'-'Z' .or '0'-'9' .or '_';
-
-/* error rules - these are used by error messages */
-
-err_token
-    '~' .or '`' .or '!' .or '@' .or '#' .or '$' .or '%' .or '^' .or '&' .or '*' .or '(' .or ')' .or
-    '-' .or '+' .or '=' .or '|' .or '\\' .or '[' .or ']' .or '{' .or '}' .or ':' .or ';' .or '"' .or
-    '\'' .or '<' .or ',' .or '>' .or '.' .or '/' .or '?' .or err_identifier;
-
-err_identifier
-    id_character_first .and .loop id_character_next;
-
diff --git a/src/mesa/shader/slang/library/slang_shader_syn.h b/src/mesa/shader/slang/library/slang_shader_syn.h
deleted file mode 100644
index 6a38297..0000000
--- a/src/mesa/shader/slang/library/slang_shader_syn.h
+++ /dev/null
@@ -1,866 +0,0 @@
-
-/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE .syn FILE */
-
-".syntax translation_unit;\n"
-".emtcode REVISION 5\n"
-".emtcode EXTERNAL_NULL 0\n"
-".emtcode EXTERNAL_FUNCTION_DEFINITION 1\n"
-".emtcode EXTERNAL_DECLARATION 2\n"
-".emtcode DEFAULT_PRECISION 3\n"
-".emtcode INVARIANT_STMT 4\n"
-".emtcode PRECISION_DEFAULT 0\n"
-".emtcode PRECISION_LOW 1\n"
-".emtcode PRECISION_MEDIUM 2\n"
-".emtcode PRECISION_HIGH 3\n"
-".emtcode DECLARATION_FUNCTION_PROTOTYPE 1\n"
-".emtcode DECLARATION_INIT_DECLARATOR_LIST 2\n"
-".emtcode FUNCTION_ORDINARY 0\n"
-".emtcode FUNCTION_CONSTRUCTOR 1\n"
-".emtcode FUNCTION_OPERATOR 2\n"
-".emtcode FUNCTION_CALL_NONARRAY 0\n"
-".emtcode FUNCTION_CALL_ARRAY 1\n"
-".emtcode OPERATOR_ADDASSIGN 1\n"
-".emtcode OPERATOR_SUBASSIGN 2\n"
-".emtcode OPERATOR_MULASSIGN 3\n"
-".emtcode OPERATOR_DIVASSIGN 4\n"
-".emtcode OPERATOR_LOGICALXOR 11\n"
-".emtcode OPERATOR_LESS 15\n"
-".emtcode OPERATOR_GREATER 16\n"
-".emtcode OPERATOR_LESSEQUAL 17\n"
-".emtcode OPERATOR_GREATEREQUAL 18\n"
-".emtcode OPERATOR_MULTIPLY 21\n"
-".emtcode OPERATOR_DIVIDE 22\n"
-".emtcode OPERATOR_INCREMENT 24\n"
-".emtcode OPERATOR_DECREMENT 25\n"
-".emtcode OPERATOR_PLUS 26\n"
-".emtcode OPERATOR_MINUS 27\n"
-".emtcode OPERATOR_NOT 29\n"
-".emtcode DECLARATOR_NONE 0\n"
-".emtcode DECLARATOR_NEXT 1\n"
-".emtcode VARIABLE_NONE 0\n"
-".emtcode VARIABLE_IDENTIFIER 1\n"
-".emtcode VARIABLE_INITIALIZER 2\n"
-".emtcode VARIABLE_ARRAY_EXPLICIT 3\n"
-".emtcode VARIABLE_ARRAY_UNKNOWN 4\n"
-".emtcode TYPE_QUALIFIER_NONE 0\n"
-".emtcode TYPE_QUALIFIER_CONST 1\n"
-".emtcode TYPE_QUALIFIER_ATTRIBUTE 2\n"
-".emtcode TYPE_QUALIFIER_VARYING 3\n"
-".emtcode TYPE_QUALIFIER_UNIFORM 4\n"
-".emtcode TYPE_QUALIFIER_FIXEDOUTPUT 5\n"
-".emtcode TYPE_QUALIFIER_FIXEDINPUT 6\n"
-".emtcode TYPE_VARIANT 90\n"
-".emtcode TYPE_INVARIANT 91\n"
-".emtcode TYPE_CENTER 95\n"
-".emtcode TYPE_CENTROID 96\n"
-".emtcode TYPE_SPECIFIER_VOID 0\n"
-".emtcode TYPE_SPECIFIER_BOOL 1\n"
-".emtcode TYPE_SPECIFIER_BVEC2 2\n"
-".emtcode TYPE_SPECIFIER_BVEC3 3\n"
-".emtcode TYPE_SPECIFIER_BVEC4 4\n"
-".emtcode TYPE_SPECIFIER_INT 5\n"
-".emtcode TYPE_SPECIFIER_IVEC2 6\n"
-".emtcode TYPE_SPECIFIER_IVEC3 7\n"
-".emtcode TYPE_SPECIFIER_IVEC4 8\n"
-".emtcode TYPE_SPECIFIER_FLOAT 9\n"
-".emtcode TYPE_SPECIFIER_VEC2 10\n"
-".emtcode TYPE_SPECIFIER_VEC3 11\n"
-".emtcode TYPE_SPECIFIER_VEC4 12\n"
-".emtcode TYPE_SPECIFIER_MAT2 13\n"
-".emtcode TYPE_SPECIFIER_MAT3 14\n"
-".emtcode TYPE_SPECIFIER_MAT4 15\n"
-".emtcode TYPE_SPECIFIER_SAMPLER1D 16\n"
-".emtcode TYPE_SPECIFIER_SAMPLER2D 17\n"
-".emtcode TYPE_SPECIFIER_SAMPLER3D 18\n"
-".emtcode TYPE_SPECIFIER_SAMPLERCUBE 19\n"
-".emtcode TYPE_SPECIFIER_SAMPLER1DSHADOW 20\n"
-".emtcode TYPE_SPECIFIER_SAMPLER2DSHADOW 21\n"
-".emtcode TYPE_SPECIFIER_SAMPLER2DRECT 22\n"
-".emtcode TYPE_SPECIFIER_SAMPLER2DRECTSHADOW 23\n"
-".emtcode TYPE_SPECIFIER_STRUCT 24\n"
-".emtcode TYPE_SPECIFIER_TYPENAME 25\n"
-".emtcode TYPE_SPECIFIER_MAT23 26\n"
-".emtcode TYPE_SPECIFIER_MAT32 27\n"
-".emtcode TYPE_SPECIFIER_MAT24 28\n"
-".emtcode TYPE_SPECIFIER_MAT42 29\n"
-".emtcode TYPE_SPECIFIER_MAT34 30\n"
-".emtcode TYPE_SPECIFIER_MAT43 31\n"
-".emtcode TYPE_SPECIFIER_NONARRAY 0\n"
-".emtcode TYPE_SPECIFIER_ARRAY 1\n"
-".emtcode FIELD_NONE 0\n"
-".emtcode FIELD_NEXT 1\n"
-".emtcode FIELD_ARRAY 2\n"
-".emtcode OP_END 0\n"
-".emtcode OP_BLOCK_BEGIN_NO_NEW_SCOPE 1\n"
-".emtcode OP_BLOCK_BEGIN_NEW_SCOPE 2\n"
-".emtcode OP_DECLARE 3\n"
-".emtcode OP_ASM 4\n"
-".emtcode OP_BREAK 5\n"
-".emtcode OP_CONTINUE 6\n"
-".emtcode OP_DISCARD 7\n"
-".emtcode OP_RETURN 8\n"
-".emtcode OP_EXPRESSION 9\n"
-".emtcode OP_IF 10\n"
-".emtcode OP_WHILE 11\n"
-".emtcode OP_DO 12\n"
-".emtcode OP_FOR 13\n"
-".emtcode OP_PUSH_VOID 14\n"
-".emtcode OP_PUSH_BOOL 15\n"
-".emtcode OP_PUSH_INT 16\n"
-".emtcode OP_PUSH_FLOAT 17\n"
-".emtcode OP_PUSH_IDENTIFIER 18\n"
-".emtcode OP_SEQUENCE 19\n"
-".emtcode OP_ASSIGN 20\n"
-".emtcode OP_ADDASSIGN 21\n"
-".emtcode OP_SUBASSIGN 22\n"
-".emtcode OP_MULASSIGN 23\n"
-".emtcode OP_DIVASSIGN 24\n"
-".emtcode OP_SELECT 31\n"
-".emtcode OP_LOGICALOR 32\n"
-".emtcode OP_LOGICALXOR 33\n"
-".emtcode OP_LOGICALAND 34\n"
-".emtcode OP_EQUAL 38\n"
-".emtcode OP_NOTEQUAL 39\n"
-".emtcode OP_LESS 40\n"
-".emtcode OP_GREATER 41\n"
-".emtcode OP_LESSEQUAL 42\n"
-".emtcode OP_GREATEREQUAL 43\n"
-".emtcode OP_ADD 46\n"
-".emtcode OP_SUBTRACT 47\n"
-".emtcode OP_MULTIPLY 48\n"
-".emtcode OP_DIVIDE 49\n"
-".emtcode OP_PREINCREMENT 51\n"
-".emtcode OP_PREDECREMENT 52\n"
-".emtcode OP_PLUS 53\n"
-".emtcode OP_MINUS 54\n"
-".emtcode OP_NOT 56\n"
-".emtcode OP_SUBSCRIPT 57\n"
-".emtcode OP_CALL 58\n"
-".emtcode OP_FIELD 59\n"
-".emtcode OP_POSTINCREMENT 60\n"
-".emtcode OP_POSTDECREMENT 61\n"
-".emtcode OP_PRECISION 62\n"
-".emtcode OP_METHOD 63\n"
-".emtcode PARAM_QUALIFIER_IN 0\n"
-".emtcode PARAM_QUALIFIER_OUT 1\n"
-".emtcode PARAM_QUALIFIER_INOUT 2\n"
-".emtcode PARAMETER_NONE 0\n"
-".emtcode PARAMETER_NEXT 1\n"
-".emtcode PARAMETER_ARRAY_NOT_PRESENT 0\n"
-".emtcode PARAMETER_ARRAY_PRESENT 1\n"
-".errtext INVALID_EXTERNAL_DECLARATION \"2001: Syntax error.\"\n"
-".errtext INVALID_OPERATOR_OVERRIDE \"2002: Invalid operator override.\"\n"
-".errtext LBRACE_EXPECTED \"2003: '{' expected but '$err_token$' found.\"\n"
-".errtext LPAREN_EXPECTED \"2004: '(' expected but '$err_token$' found.\"\n"
-".errtext RPAREN_EXPECTED \"2005: ')' expected but '$err_token$' found.\"\n"
-".errtext INVALID_PRECISION \"2006: Invalid precision specifier '$err_token$'.\"\n"
-".errtext INVALID_PRECISION_TYPE \"2007: Invalid precision type '$err_token$'.\"\n"
-".regbyte parsing_builtin 0\n"
-".regbyte shader_type 0\n"
-"variable_identifier\n"
-" identifier .emit OP_PUSH_IDENTIFIER;\n"
-"primary_expression\n"
-" floatconstant .or boolconstant .or intconstant .or variable_identifier .or primary_expression_1;\n"
-"primary_expression_1\n"
-" lparen .and expression .and rparen;\n"
-"postfix_expression\n"
-" postfix_expression_1 .and .loop postfix_expression_2;\n"
-"postfix_expression_1\n"
-" function_call .or primary_expression;\n"
-"postfix_expression_2\n"
-" postfix_expression_3 .or postfix_expression_4 .or\n"
-" plusplus .emit OP_POSTINCREMENT .or\n"
-" minusminus .emit OP_POSTDECREMENT;\n"
-"postfix_expression_3\n"
-" lbracket .and integer_expression .and rbracket .emit OP_SUBSCRIPT;\n"
-"postfix_expression_4\n"
-" dot .and field_selection .emit OP_FIELD;\n"
-"integer_expression\n"
-" expression;\n"
-"function_call\n"
-" function_call_or_method;\n"
-"function_call_or_method\n"
-" regular_function_call .or method_call;\n"
-"method_call\n"
-" identifier .emit OP_METHOD .and dot .and function_call_generic .and .true .emit OP_END;\n"
-"regular_function_call\n"
-" function_call_generic .emit OP_CALL .and .true .emit OP_END;\n"
-"function_call_generic\n"
-" function_call_generic_1 .or function_call_generic_2;\n"
-"function_call_generic_1\n"
-" function_call_header_with_parameters .and rparen .error RPAREN_EXPECTED;\n"
-"function_call_generic_2\n"
-" function_call_header_no_parameters .and rparen .error RPAREN_EXPECTED;\n"
-"function_call_header_no_parameters\n"
-" function_call_header .and function_call_header_no_parameters_1;\n"
-"function_call_header_no_parameters_1\n"
-" \"void\" .or .true;\n"
-"function_call_header_with_parameters\n"
-" function_call_header .and assignment_expression .and .true .emit OP_END .and\n"
-" .loop function_call_header_with_parameters_1;\n"
-"function_call_header_with_parameters_1\n"
-" comma .and assignment_expression .and .true .emit OP_END;\n"
-"function_call_header\n"
-" function_identifier .and lparen;\n"
-"function_identifier\n"
-" identifier .and function_identifier_opt_array;\n"
-"function_identifier_opt_array\n"
-" function_identifier_array .emit FUNCTION_CALL_ARRAY .or\n"
-" .true .emit FUNCTION_CALL_NONARRAY;\n"
-"function_identifier_array\n"
-" lbracket .and constant_expression .and rbracket;\n"
-"unary_expression\n"
-" postfix_expression .or unary_expression_1 .or unary_expression_2 .or unary_expression_3 .or\n"
-" unary_expression_4 .or unary_expression_5;\n"
-"unary_expression_1\n"
-" plusplus .and unary_expression .and .true .emit OP_PREINCREMENT;\n"
-"unary_expression_2\n"
-" minusminus .and unary_expression .and .true .emit OP_PREDECREMENT;\n"
-"unary_expression_3\n"
-" plus .and unary_expression .and .true .emit OP_PLUS;\n"
-"unary_expression_4\n"
-" minus .and unary_expression .and .true .emit OP_MINUS;\n"
-"unary_expression_5\n"
-" bang .and unary_expression .and .true .emit OP_NOT;\n"
-"multiplicative_expression\n"
-" unary_expression .and .loop multiplicative_expression_1;\n"
-"multiplicative_expression_1\n"
-" multiplicative_expression_2 .or multiplicative_expression_3;\n"
-"multiplicative_expression_2\n"
-" star .and unary_expression .and .true .emit OP_MULTIPLY;\n"
-"multiplicative_expression_3\n"
-" slash .and unary_expression .and .true .emit OP_DIVIDE;\n"
-"additive_expression\n"
-" multiplicative_expression .and .loop additive_expression_1;\n"
-"additive_expression_1\n"
-" additive_expression_2 .or additive_expression_3;\n"
-"additive_expression_2\n"
-" plus .and multiplicative_expression .and .true .emit OP_ADD;\n"
-"additive_expression_3\n"
-" minus .and multiplicative_expression .and .true .emit OP_SUBTRACT;\n"
-"shift_expression\n"
-" additive_expression;\n"
-"relational_expression\n"
-" shift_expression .and .loop relational_expression_1;\n"
-"relational_expression_1\n"
-" relational_expression_2 .or relational_expression_3 .or relational_expression_4 .or\n"
-" relational_expression_5;\n"
-"relational_expression_2\n"
-" lessequals .and shift_expression .and .true .emit OP_LESSEQUAL;\n"
-"relational_expression_3\n"
-" greaterequals .and shift_expression .and .true .emit OP_GREATEREQUAL;\n"
-"relational_expression_4\n"
-" less .and shift_expression .and .true .emit OP_LESS;\n"
-"relational_expression_5\n"
-" greater .and shift_expression .and .true .emit OP_GREATER;\n"
-"equality_expression\n"
-" relational_expression .and .loop equality_expression_1;\n"
-"equality_expression_1\n"
-" equality_expression_2 .or equality_expression_3;\n"
-"equality_expression_2\n"
-" equalsequals .and relational_expression .and .true .emit OP_EQUAL;\n"
-"equality_expression_3\n"
-" bangequals .and relational_expression .and .true .emit OP_NOTEQUAL;\n"
-"and_expression\n"
-" equality_expression;\n"
-"exclusive_or_expression\n"
-" and_expression;\n"
-"inclusive_or_expression\n"
-" exclusive_or_expression;\n"
-"logical_and_expression\n"
-" inclusive_or_expression .and .loop logical_and_expression_1;\n"
-"logical_and_expression_1\n"
-" ampersandampersand .and inclusive_or_expression .and .true .emit OP_LOGICALAND;\n"
-"logical_xor_expression\n"
-" logical_and_expression .and .loop logical_xor_expression_1;\n"
-"logical_xor_expression_1\n"
-" caretcaret .and logical_and_expression .and .true .emit OP_LOGICALXOR;\n"
-"logical_or_expression\n"
-" logical_xor_expression .and .loop logical_or_expression_1;\n"
-"logical_or_expression_1\n"
-" barbar .and logical_xor_expression .and .true .emit OP_LOGICALOR;\n"
-"conditional_expression\n"
-" logical_or_expression .and .loop conditional_expression_1;\n"
-"conditional_expression_1\n"
-" question .and expression .and colon .and conditional_expression .and .true .emit OP_SELECT;\n"
-"assignment_expression\n"
-" assignment_expression_1 .or assignment_expression_2 .or assignment_expression_3 .or\n"
-" assignment_expression_4 .or assignment_expression_5 .or conditional_expression;\n"
-"assignment_expression_1\n"
-" unary_expression .and equals .and assignment_expression .and .true .emit OP_ASSIGN;\n"
-"assignment_expression_2\n"
-" unary_expression .and starequals .and assignment_expression .and .true .emit OP_MULASSIGN;\n"
-"assignment_expression_3\n"
-" unary_expression .and slashequals .and assignment_expression .and .true .emit OP_DIVASSIGN;\n"
-"assignment_expression_4\n"
-" unary_expression .and plusequals .and assignment_expression .and .true .emit OP_ADDASSIGN;\n"
-"assignment_expression_5\n"
-" unary_expression .and minusequals .and assignment_expression .and .true .emit OP_SUBASSIGN;\n"
-"expression\n"
-" assignment_expression .and .loop expression_1;\n"
-"expression_1\n"
-" comma .and assignment_expression .and .true .emit OP_SEQUENCE;\n"
-"constant_expression\n"
-" conditional_expression .and .true .emit OP_END;\n"
-"declaration\n"
-" declaration_1 .or declaration_2;\n"
-"declaration_1\n"
-" function_prototype .emit DECLARATION_FUNCTION_PROTOTYPE .and semicolon;\n"
-"declaration_2\n"
-" init_declarator_list .emit DECLARATION_INIT_DECLARATOR_LIST .and semicolon;\n"
-"function_prototype\n"
-" function_prototype_1 .or function_prototype_2;\n"
-"function_prototype_1\n"
-" function_header .and \"void\" .and rparen .error RPAREN_EXPECTED .emit PARAMETER_NONE;\n"
-"function_prototype_2\n"
-" function_declarator .and rparen .error RPAREN_EXPECTED .emit PARAMETER_NONE;\n"
-"function_declarator\n"
-" function_header_with_parameters .or function_header;\n"
-"function_header_with_parameters\n"
-" function_header .and parameter_declaration .and .loop function_header_with_parameters_1;\n"
-"function_header_with_parameters_1\n"
-" comma .and parameter_declaration;\n"
-"function_header\n"
-" function_header_nospace .or function_header_space;\n"
-"function_header_space\n"
-" fully_specified_type_space .and space .and function_decl_identifier .and lparen;\n"
-"function_header_nospace\n"
-" fully_specified_type_nospace .and function_decl_identifier .and lparen;\n"
-"function_decl_identifier\n"
-" .if (parsing_builtin != 0) __operator .emit FUNCTION_OPERATOR .or\n"
-" .if (parsing_builtin != 0) \"__constructor\" .emit FUNCTION_CONSTRUCTOR .or\n"
-" identifier .emit FUNCTION_ORDINARY;\n"
-"__operator\n"
-" \"__operator\" .and overriden_operator .error INVALID_OPERATOR_OVERRIDE;\n"
-"overriden_operator\n"
-" plusplus .emit OPERATOR_INCREMENT .or\n"
-" plusequals .emit OPERATOR_ADDASSIGN .or\n"
-" plus .emit OPERATOR_PLUS .or\n"
-" minusminus .emit OPERATOR_DECREMENT .or\n"
-" minusequals .emit OPERATOR_SUBASSIGN .or\n"
-" minus .emit OPERATOR_MINUS .or\n"
-" bang .emit OPERATOR_NOT .or\n"
-" starequals .emit OPERATOR_MULASSIGN .or\n"
-" star .emit OPERATOR_MULTIPLY .or\n"
-" slashequals .emit OPERATOR_DIVASSIGN .or\n"
-" slash .emit OPERATOR_DIVIDE .or\n"
-" lessequals .emit OPERATOR_LESSEQUAL .or\n"
-" \n"
-" \n"
-" less .emit OPERATOR_LESS .or\n"
-" greaterequals .emit OPERATOR_GREATEREQUAL .or\n"
-" \n"
-" \n"
-" greater .emit OPERATOR_GREATER .or\n"
-" \n"
-" \n"
-" \n"
-" \n"
-" \n"
-" \n"
-" \n"
-" \n"
-" caretcaret .emit OPERATOR_LOGICALXOR ;\n"
-"parameter_declarator\n"
-" parameter_declarator_nospace .or parameter_declarator_space;\n"
-"parameter_declarator_nospace\n"
-" type_specifier_nospace .and identifier .and parameter_declarator_1;\n"
-"parameter_declarator_space\n"
-" type_specifier_space .and space .and identifier .and parameter_declarator_1;\n"
-"parameter_declarator_1\n"
-" parameter_declarator_2 .emit PARAMETER_ARRAY_PRESENT .or\n"
-" .true .emit PARAMETER_ARRAY_NOT_PRESENT;\n"
-"parameter_declarator_2\n"
-" lbracket .and constant_expression .and rbracket;\n"
-"parameter_declaration\n"
-" parameter_declaration_1 .emit PARAMETER_NEXT;\n"
-"parameter_declaration_1\n"
-" parameter_declaration_2 .or parameter_declaration_3;\n"
-"parameter_declaration_2\n"
-" type_qualifier .and space .and parameter_qualifier .and parameter_declaration_4;\n"
-"parameter_declaration_3\n"
-" parameter_qualifier .emit TYPE_QUALIFIER_NONE .and parameter_declaration_4;\n"
-"parameter_declaration_4\n"
-" parameter_declaration_optprec .and parameter_declaration_rest;\n"
-"parameter_declaration_optprec\n"
-" parameter_declaration_prec .or .true .emit PRECISION_DEFAULT;\n"
-"parameter_declaration_prec\n"
-" precision .and space;\n"
-"parameter_declaration_rest\n"
-" parameter_declarator .or parameter_type_specifier;\n"
-"parameter_qualifier\n"
-" parameter_qualifier_1 .or .true .emit PARAM_QUALIFIER_IN;\n"
-"parameter_qualifier_1\n"
-" parameter_qualifier_2 .and space;\n"
-"parameter_qualifier_2\n"
-" \"in\" .emit PARAM_QUALIFIER_IN .or\n"
-" \"out\" .emit PARAM_QUALIFIER_OUT .or\n"
-" \"inout\" .emit PARAM_QUALIFIER_INOUT;\n"
-"parameter_type_specifier\n"
-" parameter_type_specifier_1 .and .true .emit '\\0' .and parameter_type_specifier_2;\n"
-"parameter_type_specifier_1\n"
-" type_specifier_nospace .or type_specifier_space;\n"
-"parameter_type_specifier_2\n"
-" parameter_type_specifier_3 .emit PARAMETER_ARRAY_PRESENT .or\n"
-" .true .emit PARAMETER_ARRAY_NOT_PRESENT;\n"
-"parameter_type_specifier_3\n"
-" lbracket .and constant_expression .and rbracket;\n"
-"init_declarator_list\n"
-" single_declaration .and .loop init_declarator_list_1 .emit DECLARATOR_NEXT .and\n"
-" .true .emit DECLARATOR_NONE;\n"
-"init_declarator_list_1\n"
-" comma .and identifier .emit VARIABLE_IDENTIFIER .and init_declarator_list_2;\n"
-"init_declarator_list_2\n"
-" init_declarator_list_3 .or init_declarator_list_4 .or .true .emit VARIABLE_NONE;\n"
-"init_declarator_list_3\n"
-" equals .and initializer .emit VARIABLE_INITIALIZER;\n"
-"init_declarator_list_4\n"
-" lbracket .and init_declarator_list_5 .and rbracket;\n"
-"init_declarator_list_5\n"
-" constant_expression .emit VARIABLE_ARRAY_EXPLICIT .or .true .emit VARIABLE_ARRAY_UNKNOWN;\n"
-"single_declaration\n"
-" single_declaration_nospace .or single_declaration_space;\n"
-"single_declaration_space\n"
-" fully_specified_type_space .and single_declaration_space_1;\n"
-"single_declaration_nospace\n"
-" fully_specified_type_nospace .and single_declaration_nospace_1;\n"
-"single_declaration_space_1\n"
-" single_declaration_space_2 .emit VARIABLE_IDENTIFIER .or .true .emit VARIABLE_NONE;\n"
-"single_declaration_nospace_1\n"
-" single_declaration_nospace_2 .emit VARIABLE_IDENTIFIER .or .true .emit VARIABLE_NONE;\n"
-"single_declaration_space_2\n"
-" space .and identifier .and single_declaration_3;\n"
-"single_declaration_nospace_2\n"
-" identifier .and single_declaration_3;\n"
-"single_declaration_3\n"
-" single_declaration_4 .or single_declaration_5 .or .true .emit VARIABLE_NONE;\n"
-"single_declaration_4\n"
-" equals .and initializer .emit VARIABLE_INITIALIZER;\n"
-"single_declaration_5\n"
-" lbracket .and single_declaration_6 .and rbracket;\n"
-"single_declaration_6\n"
-" constant_expression .emit VARIABLE_ARRAY_EXPLICIT .or .true .emit VARIABLE_ARRAY_UNKNOWN;\n"
-"fully_specified_type_space\n"
-" fully_specified_type_optinvariant .and fully_specified_type_optcentroid .and fully_specified_type_optqual .and fully_specified_type_optprec .and type_specifier_space;\n"
-"fully_specified_type_nospace\n"
-" fully_specified_type_optinvariant .and fully_specified_type_optcentroid .and fully_specified_type_optqual .and fully_specified_type_optprec .and type_specifier_nospace;\n"
-"fully_specified_type_optinvariant\n"
-" fully_specified_type_invariant .or .true .emit TYPE_VARIANT;\n"
-"fully_specified_type_invariant\n"
-" invariant_qualifier .and space;\n"
-"fully_specified_type_optcentroid\n"
-" fully_specified_type_centroid .or .true .emit TYPE_CENTER;\n"
-"fully_specified_type_centroid\n"
-" centroid_qualifier .and space;\n"
-"fully_specified_type_optqual\n"
-" fully_specified_type_qual .or .true .emit TYPE_QUALIFIER_NONE;\n"
-"fully_specified_type_qual\n"
-" type_qualifier .and space;\n"
-"fully_specified_type_optprec\n"
-" fully_specified_type_prec .or .true .emit PRECISION_DEFAULT;\n"
-"fully_specified_type_prec\n"
-" precision .and space;\n"
-"invariant_qualifier\n"
-" \"invariant\" .emit TYPE_INVARIANT;\n"
-"centroid_qualifier\n"
-" \"centroid\" .emit TYPE_CENTROID;\n"
-"type_qualifier\n"
-" \"const\" .emit TYPE_QUALIFIER_CONST .or\n"
-" .if (shader_type == 2) \"attribute\" .emit TYPE_QUALIFIER_ATTRIBUTE .or\n"
-" \"varying\" .emit TYPE_QUALIFIER_VARYING .or\n"
-" \"uniform\" .emit TYPE_QUALIFIER_UNIFORM .or\n"
-" .if (parsing_builtin != 0) \"__fixed_output\" .emit TYPE_QUALIFIER_FIXEDOUTPUT .or\n"
-" .if (parsing_builtin != 0) \"__fixed_input\" .emit TYPE_QUALIFIER_FIXEDINPUT;\n"
-"type_specifier_nonarray_space\n"
-" \"void\" .emit TYPE_SPECIFIER_VOID .or\n"
-" \"float\" .emit TYPE_SPECIFIER_FLOAT .or\n"
-" \"int\" .emit TYPE_SPECIFIER_INT .or\n"
-" \"bool\" .emit TYPE_SPECIFIER_BOOL .or\n"
-" \"vec2\" .emit TYPE_SPECIFIER_VEC2 .or\n"
-" \"vec3\" .emit TYPE_SPECIFIER_VEC3 .or\n"
-" \"vec4\" .emit TYPE_SPECIFIER_VEC4 .or\n"
-" \"bvec2\" .emit TYPE_SPECIFIER_BVEC2 .or\n"
-" \"bvec3\" .emit TYPE_SPECIFIER_BVEC3 .or\n"
-" \"bvec4\" .emit TYPE_SPECIFIER_BVEC4 .or\n"
-" \"ivec2\" .emit TYPE_SPECIFIER_IVEC2 .or\n"
-" \"ivec3\" .emit TYPE_SPECIFIER_IVEC3 .or\n"
-" \"ivec4\" .emit TYPE_SPECIFIER_IVEC4 .or\n"
-" \"mat2\" .emit TYPE_SPECIFIER_MAT2 .or\n"
-" \"mat3\" .emit TYPE_SPECIFIER_MAT3 .or\n"
-" \"mat4\" .emit TYPE_SPECIFIER_MAT4 .or\n"
-" \"mat2x3\" .emit TYPE_SPECIFIER_MAT23 .or\n"
-" \"mat3x2\" .emit TYPE_SPECIFIER_MAT32 .or\n"
-" \"mat2x4\" .emit TYPE_SPECIFIER_MAT24 .or\n"
-" \"mat4x2\" .emit TYPE_SPECIFIER_MAT42 .or\n"
-" \"mat3x4\" .emit TYPE_SPECIFIER_MAT34 .or\n"
-" \"mat4x3\" .emit TYPE_SPECIFIER_MAT43 .or\n"
-" \"sampler1D\" .emit TYPE_SPECIFIER_SAMPLER1D .or\n"
-" \"sampler2D\" .emit TYPE_SPECIFIER_SAMPLER2D .or\n"
-" \"sampler3D\" .emit TYPE_SPECIFIER_SAMPLER3D .or\n"
-" \"samplerCube\" .emit TYPE_SPECIFIER_SAMPLERCUBE .or\n"
-" \"sampler1DShadow\" .emit TYPE_SPECIFIER_SAMPLER1DSHADOW .or\n"
-" \"sampler2DShadow\" .emit TYPE_SPECIFIER_SAMPLER2DSHADOW .or\n"
-" \"sampler2DRect\" .emit TYPE_SPECIFIER_SAMPLER2DRECT .or\n"
-" \"sampler2DRectShadow\" .emit TYPE_SPECIFIER_SAMPLER2DRECTSHADOW .or\n"
-" type_name .emit TYPE_SPECIFIER_TYPENAME;\n"
-"type_specifier_nonarray_nospace\n"
-" struct_specifier .emit TYPE_SPECIFIER_STRUCT;\n"
-"type_specifier_nonarray\n"
-" type_specifier_nonarray_nospace .or type_specifier_nonarray_space;\n"
-"type_specifier_space\n"
-" type_specifier_nonarray_space .and .true .emit TYPE_SPECIFIER_NONARRAY;\n"
-"type_specifier_nospace\n"
-" type_specifier_nospace_array .or type_specifier_nospace_1;\n"
-"type_specifier_nospace_1\n"
-" type_specifier_nonarray_nospace .and .true .emit TYPE_SPECIFIER_NONARRAY;\n"
-"type_specifier_nospace_array\n"
-" type_specifier_nonarray .and lbracket .emit TYPE_SPECIFIER_ARRAY .and constant_expression .and rbracket;\n"
-"struct_specifier\n"
-" \"struct\" .and struct_specifier_1 .and optional_space .and lbrace .error LBRACE_EXPECTED .and\n"
-" struct_declaration_list .and rbrace .emit FIELD_NONE;\n"
-"struct_specifier_1\n"
-" struct_specifier_2 .or .true .emit '\\0';\n"
-"struct_specifier_2\n"
-" space .and identifier;\n"
-"struct_declaration_list\n"
-" struct_declaration .and .loop struct_declaration .emit FIELD_NEXT;\n"
-"struct_declaration\n"
-" struct_declaration_nospace .or struct_declaration_space;\n"
-"struct_declaration_space\n"
-" type_specifier_space .and space .and struct_declarator_list .and semicolon .emit FIELD_NONE;\n"
-"struct_declaration_nospace\n"
-" type_specifier_nospace .and struct_declarator_list .and semicolon .emit FIELD_NONE;\n"
-"struct_declarator_list\n"
-" struct_declarator .and .loop struct_declarator_list_1 .emit FIELD_NEXT;\n"
-"struct_declarator_list_1\n"
-" comma .and struct_declarator;\n"
-"struct_declarator\n"
-" identifier .and struct_declarator_1;\n"
-"struct_declarator_1\n"
-" struct_declarator_2 .emit FIELD_ARRAY .or .true .emit FIELD_NONE;\n"
-"struct_declarator_2\n"
-" lbracket .and constant_expression .and rbracket;\n"
-"initializer\n"
-" assignment_expression .and .true .emit OP_END;\n"
-"declaration_statement\n"
-" declaration;\n"
-"statement\n"
-" compound_statement .or simple_statement;\n"
-"statement_space\n"
-" compound_statement .or statement_space_1;\n"
-"statement_space_1\n"
-" space .and simple_statement;\n"
-"simple_statement\n"
-" .if (parsing_builtin != 0) __asm_statement .emit OP_ASM .or\n"
-" selection_statement .or\n"
-" iteration_statement .or\n"
-" precision_stmt .emit OP_PRECISION .or\n"
-" jump_statement .or\n"
-" expression_statement .emit OP_EXPRESSION .or\n"
-" declaration_statement .emit OP_DECLARE;\n"
-"compound_statement\n"
-" compound_statement_1 .emit OP_BLOCK_BEGIN_NEW_SCOPE .and .true .emit OP_END;\n"
-"compound_statement_1\n"
-" compound_statement_2 .or compound_statement_3;\n"
-"compound_statement_2\n"
-" lbrace .and rbrace;\n"
-"compound_statement_3\n"
-" lbrace .and statement_list .and rbrace;\n"
-"compound_statement_no_new_scope\n"
-" compound_statement_no_new_scope_1 .emit OP_BLOCK_BEGIN_NO_NEW_SCOPE .and .true .emit OP_END;\n"
-"compound_statement_no_new_scope_1\n"
-" compound_statement_no_new_scope_2 .or compound_statement_no_new_scope_3;\n"
-"compound_statement_no_new_scope_2\n"
-" lbrace .and rbrace;\n"
-"compound_statement_no_new_scope_3\n"
-" lbrace .and statement_list .and rbrace;\n"
-"statement_list\n"
-" statement .and .loop statement;\n"
-"expression_statement\n"
-" expression_statement_1 .or expression_statement_2;\n"
-"expression_statement_1\n"
-" semicolon .emit OP_PUSH_VOID .emit OP_END;\n"
-"expression_statement_2\n"
-" expression .and semicolon .emit OP_END;\n"
-"selection_statement\n"
-" \"if\" .emit OP_IF .and lparen .error LPAREN_EXPECTED .and expression .and\n"
-" rparen .error RPAREN_EXPECTED .emit OP_END .and selection_rest_statement;\n"
-"selection_rest_statement\n"
-" statement .and selection_rest_statement_1;\n"
-"selection_rest_statement_1\n"
-" selection_rest_statement_2 .or .true .emit OP_EXPRESSION .emit OP_PUSH_VOID .emit OP_END;\n"
-"selection_rest_statement_2\n"
-" \"else\" .and optional_space .and statement;\n"
-"condition\n"
-" condition_1 .emit OP_DECLARE .emit DECLARATION_INIT_DECLARATOR_LIST .or\n"
-" condition_3 .emit OP_EXPRESSION;\n"
-"condition_1\n"
-" condition_1_nospace .or condition_1_space;\n"
-"condition_1_nospace\n"
-" fully_specified_type_nospace .and condition_2;\n"
-"condition_1_space\n"
-" fully_specified_type_space .and space .and condition_2;\n"
-"condition_2\n"
-" identifier .emit VARIABLE_IDENTIFIER .and equals .emit VARIABLE_INITIALIZER .and\n"
-" initializer .and .true .emit DECLARATOR_NONE;\n"
-"condition_3\n"
-" expression .and .true .emit OP_END;\n"
-"iteration_statement\n"
-" iteration_statement_1 .or iteration_statement_2 .or iteration_statement_3;\n"
-"iteration_statement_1\n"
-" \"while\" .emit OP_WHILE .and lparen .error LPAREN_EXPECTED .and condition .and\n"
-" rparen .error RPAREN_EXPECTED .and statement;\n"
-"iteration_statement_2\n"
-" \"do\" .emit OP_DO .and statement_space .and \"while\" .and lparen .error LPAREN_EXPECTED .and\n"
-" expression .and rparen .error RPAREN_EXPECTED .emit OP_END .and semicolon;\n"
-"iteration_statement_3\n"
-" \"for\" .emit OP_FOR .and lparen .error LPAREN_EXPECTED .and for_init_statement .and\n"
-" for_rest_statement .and rparen .error RPAREN_EXPECTED .and statement;\n"
-"for_init_statement\n"
-" expression_statement .emit OP_EXPRESSION .or declaration_statement .emit OP_DECLARE;\n"
-"conditionopt\n"
-" condition .or\n"
-" .true .emit OP_EXPRESSION .emit OP_PUSH_BOOL .emit 2 .emit '1' .emit '\\0' .emit OP_END;\n"
-"for_rest_statement\n"
-" conditionopt .and semicolon .and for_rest_statement_1;\n"
-"for_rest_statement_1\n"
-" for_rest_statement_2 .or .true .emit OP_PUSH_VOID .emit OP_END;\n"
-"for_rest_statement_2\n"
-" expression .and .true .emit OP_END;\n"
-"jump_statement\n"
-" jump_statement_1 .or jump_statement_2 .or jump_statement_3 .or jump_statement_4 .or\n"
-" .if (shader_type == 1) jump_statement_5;\n"
-"jump_statement_1\n"
-" \"continue\" .and semicolon .emit OP_CONTINUE;\n"
-"jump_statement_2\n"
-" \"break\" .and semicolon .emit OP_BREAK;\n"
-"jump_statement_3\n"
-" \"return\" .emit OP_RETURN .and optional_space .and expression .and semicolon .emit OP_END;\n"
-"jump_statement_4\n"
-" \"return\" .emit OP_RETURN .and semicolon .emit OP_PUSH_VOID .emit OP_END;\n"
-"jump_statement_5\n"
-" \"discard\" .and semicolon .emit OP_DISCARD;\n"
-"__asm_statement\n"
-" \"__asm\" .and space .and identifier .and space .and asm_arguments .and semicolon .emit OP_END;\n"
-"asm_arguments\n"
-" asm_argument .and .true .emit OP_END .and .loop asm_arguments_1;\n"
-"asm_arguments_1\n"
-" comma .and asm_argument .and .true .emit OP_END;\n"
-"asm_argument\n"
-" var_with_field .or\n"
-" variable_identifier .or\n"
-" floatconstant;\n"
-"var_with_field\n"
-" variable_identifier .and dot .and field_selection .emit OP_FIELD;\n"
-"translation_unit\n"
-" optional_space .emit REVISION .and external_declaration .error INVALID_EXTERNAL_DECLARATION .and\n"
-" .loop external_declaration .and optional_space .and\n"
-" '\\0' .error INVALID_EXTERNAL_DECLARATION .emit EXTERNAL_NULL;\n"
-"external_declaration\n"
-" precision_stmt .emit DEFAULT_PRECISION .or\n"
-" function_definition .emit EXTERNAL_FUNCTION_DEFINITION .or\n"
-" invariant_stmt .emit INVARIANT_STMT .or\n"
-" declaration .emit EXTERNAL_DECLARATION;\n"
-"precision_stmt\n"
-" \"precision\" .and space .and precision .error INVALID_PRECISION .and space .and prectype .error INVALID_PRECISION_TYPE .and semicolon;\n"
-"precision\n"
-" \"lowp\" .emit PRECISION_LOW .or\n"
-" \"mediump\" .emit PRECISION_MEDIUM .or\n"
-" \"highp\" .emit PRECISION_HIGH;\n"
-"prectype\n"
-" \"int\" .emit TYPE_SPECIFIER_INT .or\n"
-" \"float\" .emit TYPE_SPECIFIER_FLOAT .or\n"
-" \"sampler1D\" .emit TYPE_SPECIFIER_SAMPLER1D .or\n"
-" \"sampler2D\" .emit TYPE_SPECIFIER_SAMPLER2D .or\n"
-" \"sampler3D\" .emit TYPE_SPECIFIER_SAMPLER3D .or\n"
-" \"samplerCube\" .emit TYPE_SPECIFIER_SAMPLERCUBE .or\n"
-" \"sampler1DShadow\" .emit TYPE_SPECIFIER_SAMPLER1DSHADOW .or\n"
-" \"sampler2DShadow\" .emit TYPE_SPECIFIER_SAMPLER2DSHADOW .or\n"
-" \"sampler2DRect\" .emit TYPE_SPECIFIER_SAMPLER2DRECT .or\n"
-" \"sampler2DRectShadow\" .emit TYPE_SPECIFIER_SAMPLER2DRECTSHADOW;\n"
-"invariant_stmt\n"
-" \"invariant\" .and space .and identifier .and semicolon;\n"
-"function_definition\n"
-" function_prototype .and compound_statement_no_new_scope;\n"
-"digit_oct\n"
-" '0'-'7';\n"
-"digit_dec\n"
-" '0'-'9';\n"
-"digit_hex\n"
-" '0'-'9' .or 'A'-'F' .or 'a'-'f';\n"
-"id_character_first\n"
-" 'a'-'z' .or 'A'-'Z' .or '_';\n"
-"id_character_next\n"
-" id_character_first .or digit_dec;\n"
-"identifier\n"
-" id_character_first .emit * .and .loop id_character_next .emit * .and .true .emit '\\0';\n"
-"float\n"
-" float_1 .or float_2 .or float_3;\n"
-"float_1\n"
-" float_fractional_constant .and float_optional_exponent_part .and optional_f_suffix;\n"
-"float_2\n"
-" float_digit_sequence .and .true .emit '\\0' .and float_exponent_part .and optional_f_suffix;\n"
-"float_3\n"
-" float_digit_sequence .and .true .emit '\\0' .and 'f' .emit '\\0';\n"
-"float_fractional_constant\n"
-" float_fractional_constant_1 .or float_fractional_constant_2 .or float_fractional_constant_3;\n"
-"float_fractional_constant_1\n"
-" float_digit_sequence .and '.' .and float_digit_sequence;\n"
-"float_fractional_constant_2\n"
-" float_digit_sequence .and '.' .and .true .emit '\\0';\n"
-"float_fractional_constant_3\n"
-" '.' .emit '\\0' .and float_digit_sequence;\n"
-"float_optional_exponent_part\n"
-" float_exponent_part .or .true .emit '\\0';\n"
-"float_digit_sequence\n"
-" digit_dec .emit * .and .loop digit_dec .emit * .and .true .emit '\\0';\n"
-"float_exponent_part\n"
-" float_exponent_part_1 .or float_exponent_part_2;\n"
-"float_exponent_part_1\n"
-" 'e' .and float_optional_sign .and float_digit_sequence;\n"
-"float_exponent_part_2\n"
-" 'E' .and float_optional_sign .and float_digit_sequence;\n"
-"float_optional_sign\n"
-" float_sign .or .true;\n"
-"float_sign\n"
-" '+' .or '-' .emit '-';\n"
-"optional_f_suffix\n"
-" 'f' .or .true;\n"
-"integer\n"
-" integer_hex .or integer_oct .or integer_dec;\n"
-"integer_hex\n"
-" '0' .and integer_hex_1 .emit 0x10 .and digit_hex .emit * .and .loop digit_hex .emit * .and\n"
-" .true .emit '\\0';\n"
-"integer_hex_1\n"
-" 'x' .or 'X';\n"
-"integer_oct\n"
-" '0' .emit 8 .emit * .and .loop digit_oct .emit * .and .true .emit '\\0';\n"
-"integer_dec\n"
-" digit_dec .emit 10 .emit * .and .loop digit_dec .emit * .and .true .emit '\\0';\n"
-"boolean\n"
-" \"true\" .emit 2 .emit '1' .emit '\\0' .or\n"
-" \"false\" .emit 2 .emit '0' .emit '\\0';\n"
-"type_name\n"
-" identifier;\n"
-"field_selection\n"
-" identifier;\n"
-"floatconstant\n"
-" float .emit OP_PUSH_FLOAT;\n"
-"intconstant\n"
-" integer .emit OP_PUSH_INT;\n"
-"boolconstant\n"
-" boolean .emit OP_PUSH_BOOL;\n"
-"optional_space\n"
-" .loop single_space;\n"
-"space\n"
-" single_space .and .loop single_space;\n"
-"single_space\n"
-" white_char .or c_style_comment_block .or cpp_style_comment_block;\n"
-"white_char\n"
-" ' ' .or '\\t' .or new_line .or '\\v' .or '\\f';\n"
-"new_line\n"
-" cr_lf .or lf_cr .or '\\n' .or '\\r';\n"
-"cr_lf\n"
-" '\\r' .and '\\n';\n"
-"lf_cr\n"
-" '\\n' .and '\\r';\n"
-"c_style_comment_block\n"
-" '/' .and '*' .and c_style_comment_rest;\n"
-"c_style_comment_rest\n"
-" .loop c_style_comment_char_no_star .and c_style_comment_rest_1;\n"
-"c_style_comment_rest_1\n"
-" c_style_comment_end .or c_style_comment_rest_2;\n"
-"c_style_comment_rest_2\n"
-" '*' .and c_style_comment_rest;\n"
-"c_style_comment_char_no_star\n"
-" '\\x2B'-'\\xFF' .or '\\x01'-'\\x29';\n"
-"c_style_comment_end\n"
-" '*' .and '/';\n"
-"cpp_style_comment_block\n"
-" '/' .and '/' .and cpp_style_comment_block_1;\n"
-"cpp_style_comment_block_1\n"
-" cpp_style_comment_block_2 .or cpp_style_comment_block_3;\n"
-"cpp_style_comment_block_2\n"
-" .loop cpp_style_comment_char .and new_line;\n"
-"cpp_style_comment_block_3\n"
-" .loop cpp_style_comment_char;\n"
-"cpp_style_comment_char\n"
-" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n"
-"ampersandampersand\n"
-" optional_space .and '&' .and '&' .and optional_space;\n"
-"barbar\n"
-" optional_space .and '|' .and '|' .and optional_space;\n"
-"bang\n"
-" optional_space .and '!' .and optional_space;\n"
-"bangequals\n"
-" optional_space .and '!' .and '=' .and optional_space;\n"
-"caretcaret\n"
-" optional_space .and '^' .and '^' .and optional_space;\n"
-"colon\n"
-" optional_space .and ':' .and optional_space;\n"
-"comma\n"
-" optional_space .and ',' .and optional_space;\n"
-"dot\n"
-" optional_space .and '.' .and optional_space;\n"
-"equals\n"
-" optional_space .and '=' .and optional_space;\n"
-"equalsequals\n"
-" optional_space .and '=' .and '=' .and optional_space;\n"
-"greater\n"
-" optional_space .and '>' .and optional_space;\n"
-"greaterequals\n"
-" optional_space .and '>' .and '=' .and optional_space;\n"
-"lbrace\n"
-" optional_space .and '{' .and optional_space;\n"
-"lbracket\n"
-" optional_space .and '[' .and optional_space;\n"
-"less\n"
-" optional_space .and '<' .and optional_space;\n"
-"lessequals\n"
-" optional_space .and '<' .and '=' .and optional_space;\n"
-"lparen\n"
-" optional_space .and '(' .and optional_space;\n"
-"minus\n"
-" optional_space .and '-' .and optional_space;\n"
-"minusequals\n"
-" optional_space .and '-' .and '=' .and optional_space;\n"
-"minusminus\n"
-" optional_space .and '-' .and '-' .and optional_space;\n"
-"plus\n"
-" optional_space .and '+' .and optional_space;\n"
-"plusequals\n"
-" optional_space .and '+' .and '=' .and optional_space;\n"
-"plusplus\n"
-" optional_space .and '+' .and '+' .and optional_space;\n"
-"question\n"
-" optional_space .and '?' .and optional_space;\n"
-"rbrace\n"
-" optional_space .and '}' .and optional_space;\n"
-"rbracket\n"
-" optional_space .and ']' .and optional_space;\n"
-"rparen\n"
-" optional_space .and ')' .and optional_space;\n"
-"semicolon\n"
-" optional_space .and ';' .and optional_space;\n"
-"slash\n"
-" optional_space .and '/' .and optional_space;\n"
-"slashequals\n"
-" optional_space .and '/' .and '=' .and optional_space;\n"
-"star\n"
-" optional_space .and '*' .and optional_space;\n"
-"starequals\n"
-" optional_space .and '*' .and '=' .and optional_space;\n"
-".string string_lexer;\n"
-"string_lexer\n"
-" lex_first_identifier_character .and .loop lex_next_identifier_character;\n"
-"lex_first_identifier_character\n"
-" 'a'-'z' .or 'A'-'Z' .or '_';\n"
-"lex_next_identifier_character\n"
-" 'a'-'z' .or 'A'-'Z' .or '0'-'9' .or '_';\n"
-"err_token\n"
-" '~' .or '`' .or '!' .or '@' .or '#' .or '$' .or '%' .or '^' .or '&' .or '*' .or '(' .or ')' .or\n"
-" '-' .or '+' .or '=' .or '|' .or '\\\\' .or '[' .or ']' .or '{' .or '}' .or ':' .or ';' .or '\"' .or\n"
-" '\\'' .or '<' .or ',' .or '>' .or '.' .or '/' .or '?' .or err_identifier;\n"
-"err_identifier\n"
-" id_character_first .and .loop id_character_next;\n"
-""
diff --git a/src/mesa/shader/slang/library/slang_version.syn b/src/mesa/shader/slang/library/slang_version.syn
deleted file mode 100644
index aaf8bef..0000000
--- a/src/mesa/shader/slang/library/slang_version.syn
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.3
- *
- * Copyright (C) 2005  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL 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 slang_version.syn
- * slang #version directive syntax
- * \author Michal Krol
- */
-
-.syntax version_directive;
-
-version_directive
-	version_directive_1 .and .loop version_directive_2;
-version_directive_1
-	prior_optional_spaces .and optional_version_directive .and .true .emit $;
-version_directive_2
-	prior_optional_spaces .and version_directive_body .and .true .emit $;
-
-optional_version_directive
-	version_directive_body .or .true .emit 10 .emit 1;
-
-version_directive_body
-	'#' .and optional_space .and "version" .and space .and version_number .and optional_space .and
-	new_line;
-
-version_number
-	version_number_110;
-
-version_number_110
-	leading_zeroes .and "110" .emit 10 .emit 1;
-
-leading_zeroes
-	.loop zero;
-
-zero
-	'0';
-
-space
-    single_space .and .loop single_space;
-
-optional_space
-    .loop single_space;
-
-single_space
-    ' ' .or '\t';
-
-prior_optional_spaces
-	.loop prior_space;
-
-prior_space
-	c_style_comment_block .or cpp_style_comment_block .or space .or new_line;
-
-c_style_comment_block
-    '/' .and '*' .and c_style_comment_rest;
-
-c_style_comment_rest
-    .loop c_style_comment_char_no_star .and c_style_comment_rest_1;
-c_style_comment_rest_1
-    c_style_comment_end .or c_style_comment_rest_2;
-c_style_comment_rest_2
-    '*' .and c_style_comment_rest;
-
-c_style_comment_char_no_star
-    '\x2B'-'\xFF' .or '\x01'-'\x29';
-
-c_style_comment_end
-    '*' .and '/';
-
-cpp_style_comment_block
-    '/' .and '/' .and cpp_style_comment_block_1;
-cpp_style_comment_block_1
-    cpp_style_comment_block_2 .or cpp_style_comment_block_3;
-cpp_style_comment_block_2
-    .loop cpp_style_comment_char .and new_line;
-cpp_style_comment_block_3
-    .loop cpp_style_comment_char;
-
-cpp_style_comment_char
-    '\x0E'-'\xFF' .or '\x01'-'\x09' .or '\x0B'-'\x0C';
-
-new_line
-    cr_lf .or lf_cr .or '\n' .or '\r';
-
-cr_lf
-    '\r' .and '\n';
-
-lf_cr
-	'\n' .and '\r';
-
-.string __string_filter;
-
-__string_filter
-    .loop __identifier_char;
-
-__identifier_char
-    'a'-'z' .or 'A'-'Z' .or '_' .or '0'-'9';
-
diff --git a/src/mesa/shader/slang/library/slang_vertex_builtin_gc.h b/src/mesa/shader/slang/library/slang_vertex_builtin_gc.h
deleted file mode 100644
index e5a252b..0000000
--- a/src/mesa/shader/slang/library/slang_vertex_builtin_gc.h
+++ /dev/null
@@ -1,109 +0,0 @@
-
-/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE FOLLOWING FILE: */
-/* slang_vertex_builtin.gc */
-
-5,2,2,90,95,5,0,12,0,1,103,108,95,80,111,115,105,116,105,111,110,0,0,0,2,2,90,95,5,0,9,0,1,103,108,
-95,80,111,105,110,116,83,105,122,101,0,0,0,2,2,90,95,5,0,12,0,1,103,108,95,67,108,105,112,86,101,
-114,116,101,120,0,0,0,2,2,90,95,2,0,12,0,1,103,108,95,67,111,108,111,114,0,0,0,2,2,90,95,2,0,12,0,
-1,103,108,95,83,101,99,111,110,100,97,114,121,67,111,108,111,114,0,0,0,2,2,90,95,2,0,11,0,1,103,
-108,95,78,111,114,109,97,108,0,0,0,2,2,90,95,2,0,12,0,1,103,108,95,86,101,114,116,101,120,0,0,0,2,
-2,90,95,2,0,12,0,1,103,108,95,77,117,108,116,105,84,101,120,67,111,111,114,100,48,0,0,0,2,2,90,95,
-2,0,12,0,1,103,108,95,77,117,108,116,105,84,101,120,67,111,111,114,100,49,0,0,0,2,2,90,95,2,0,12,0,
-1,103,108,95,77,117,108,116,105,84,101,120,67,111,111,114,100,50,0,0,0,2,2,90,95,2,0,12,0,1,103,
-108,95,77,117,108,116,105,84,101,120,67,111,111,114,100,51,0,0,0,2,2,90,95,2,0,12,0,1,103,108,95,
-77,117,108,116,105,84,101,120,67,111,111,114,100,52,0,0,0,2,2,90,95,2,0,12,0,1,103,108,95,77,117,
-108,116,105,84,101,120,67,111,111,114,100,53,0,0,0,2,2,90,95,2,0,12,0,1,103,108,95,77,117,108,116,
-105,84,101,120,67,111,111,114,100,54,0,0,0,2,2,90,95,2,0,12,0,1,103,108,95,77,117,108,116,105,84,
-101,120,67,111,111,114,100,55,0,0,0,2,2,90,95,2,0,9,0,1,103,108,95,70,111,103,67,111,111,114,100,0,
-0,0,2,2,90,95,3,0,12,0,1,103,108,95,70,114,111,110,116,67,111,108,111,114,0,0,0,2,2,90,95,3,0,12,0,
-1,103,108,95,66,97,99,107,67,111,108,111,114,0,0,0,2,2,90,95,3,0,12,0,1,103,108,95,70,114,111,110,
-116,83,101,99,111,110,100,97,114,121,67,111,108,111,114,0,0,0,2,2,90,95,3,0,12,0,1,103,108,95,66,
-97,99,107,83,101,99,111,110,100,97,114,121,67,111,108,111,114,0,0,0,2,2,90,95,3,0,12,0,1,103,108,
-95,84,101,120,67,111,111,114,100,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,
-114,100,115,0,0,0,2,2,90,95,3,0,9,0,1,103,108,95,70,111,103,70,114,97,103,67,111,111,114,100,0,0,0,
-1,90,95,0,0,12,0,0,102,116,114,97,110,115,102,111,114,109,0,0,1,9,18,95,95,114,101,116,86,97,108,0,
-18,103,108,95,77,111,100,101,108,86,105,101,119,80,114,111,106,101,99,116,105,111,110,77,97,116,
-114,105,120,0,16,8,48,0,57,18,103,108,95,86,101,114,116,101,120,0,59,120,120,120,120,0,48,18,103,
-108,95,77,111,100,101,108,86,105,101,119,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,
-120,0,16,10,49,0,57,18,103,108,95,86,101,114,116,101,120,0,59,121,121,121,121,0,48,46,18,103,108,
-95,77,111,100,101,108,86,105,101,119,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,
-16,10,50,0,57,18,103,108,95,86,101,114,116,101,120,0,59,122,122,122,122,0,48,46,18,103,108,95,77,
-111,100,101,108,86,105,101,119,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,16,10,
-51,0,57,18,103,108,95,86,101,114,116,101,120,0,59,119,119,119,119,0,48,46,20,0,0,1,90,95,0,0,12,0,
-0,116,101,120,116,117,114,101,49,68,76,111,100,0,1,1,0,0,16,0,115,97,109,112,108,101,114,0,0,1,1,0,
-0,9,0,99,111,111,114,100,0,0,1,1,0,0,9,0,108,111,100,0,0,0,1,3,2,90,95,0,0,12,0,1,99,111,111,114,
-100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,0,18,99,111,111,114,100,0,20,0,9,18,99,111,111,
-114,100,52,0,59,119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116,101,120,95,49,100,95,98,105,97,
-115,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,
-52,0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,49,68,80,114,111,106,76,111,100,0,1,1,0,
-0,16,0,115,97,109,112,108,101,114,0,0,1,1,0,0,10,0,99,111,111,114,100,0,0,1,1,0,0,9,0,108,111,100,
-0,0,0,1,3,2,90,95,0,0,12,0,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,0,
-18,99,111,111,114,100,0,59,120,0,18,99,111,111,114,100,0,59,121,0,49,20,0,9,18,112,99,111,111,114,
-100,0,59,119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116,101,120,95,49,100,95,98,105,97,115,0,
-18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99,111,111,114,100,0,0,
-0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,49,68,80,114,111,106,76,111,100,0,1,1,0,0,16,0,
-115,97,109,112,108,101,114,0,0,1,1,0,0,12,0,99,111,111,114,100,0,0,1,1,0,0,9,0,108,111,100,0,0,0,1,
-3,2,90,95,0,0,12,0,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,0,18,99,111,
-111,114,100,0,59,120,0,18,99,111,111,114,100,0,59,122,0,49,20,0,9,18,112,99,111,111,114,100,0,59,
-119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116,101,120,95,49,100,95,98,105,97,115,0,18,95,95,
-114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,90,
-95,0,0,12,0,0,116,101,120,116,117,114,101,50,68,76,111,100,0,1,1,0,0,17,0,115,97,109,112,108,101,
-114,0,0,1,1,0,0,10,0,99,111,111,114,100,0,0,1,1,0,0,9,0,108,111,100,0,0,0,1,3,2,90,95,0,0,12,0,1,
-99,111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,121,0,18,99,111,111,114,100,0,59,
-120,121,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116,
-101,120,95,50,100,95,98,105,97,115,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,
-114,0,0,18,99,111,111,114,100,52,0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,50,68,80,
-114,111,106,76,111,100,0,1,1,0,0,17,0,115,97,109,112,108,101,114,0,0,1,1,0,0,11,0,99,111,111,114,
-100,0,0,1,1,0,0,9,0,108,111,100,0,0,0,1,3,2,90,95,0,0,12,0,1,112,99,111,111,114,100,0,0,0,9,18,112,
-99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,
-122,0,49,20,0,9,18,112,99,111,111,114,100,0,59,119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116,
-101,120,95,50,100,95,98,105,97,115,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,
-114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,50,68,80,
-114,111,106,76,111,100,0,1,1,0,0,17,0,115,97,109,112,108,101,114,0,0,1,1,0,0,12,0,99,111,111,114,
-100,0,0,1,1,0,0,9,0,108,111,100,0,0,0,1,3,2,90,95,0,0,12,0,1,112,99,111,111,114,100,0,0,0,9,18,112,
-99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,
-122,0,49,20,0,9,18,112,99,111,111,114,100,0,59,119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116,
-101,120,95,50,100,95,98,105,97,115,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,
-114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,51,68,76,
-111,100,0,1,1,0,0,18,0,115,97,109,112,108,101,114,0,0,1,1,0,0,11,0,99,111,111,114,100,0,0,1,1,0,0,
-9,0,108,111,100,0,0,0,1,3,2,90,95,0,0,12,0,1,99,111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,
-52,0,59,120,121,122,0,18,99,111,111,114,100,0,59,120,121,122,0,20,0,9,18,99,111,111,114,100,52,0,
-59,119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116,101,120,95,51,100,95,98,105,97,115,0,18,95,
-95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,52,0,0,0,0,1,
-90,95,0,0,12,0,0,116,101,120,116,117,114,101,51,68,80,114,111,106,76,111,100,0,1,1,0,0,18,0,115,97,
-109,112,108,101,114,0,0,1,1,0,0,12,0,99,111,111,114,100,0,0,1,1,0,0,9,0,108,111,100,0,0,0,1,3,2,90,
-95,0,0,12,0,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,121,122,0,18,99,
-111,111,114,100,0,59,120,121,122,0,18,99,111,111,114,100,0,59,119,0,49,20,0,9,18,112,99,111,111,
-114,100,0,59,119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116,101,120,95,51,100,95,98,105,97,115,
-0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99,111,111,114,100,0,
-0,0,0,1,90,95,0,0,12,0,0,116,101,120,116,117,114,101,67,117,98,101,76,111,100,0,1,1,0,0,19,0,115,
-97,109,112,108,101,114,0,0,1,1,0,0,11,0,99,111,111,114,100,0,0,1,1,0,0,9,0,108,111,100,0,0,0,1,3,2,
-90,95,0,0,12,0,1,99,111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,121,122,0,18,99,
-111,111,114,100,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0,18,108,111,100,0,20,0,4,118,101,99,52,
-95,116,101,120,95,99,117,98,101,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,
-0,0,18,99,111,111,114,100,52,0,0,0,0,1,90,95,0,0,12,0,0,115,104,97,100,111,119,49,68,76,111,100,0,
-1,1,0,0,20,0,115,97,109,112,108,101,114,0,0,1,1,0,0,11,0,99,111,111,114,100,0,0,1,1,0,0,9,0,108,
-111,100,0,0,0,1,3,2,90,95,0,0,12,0,1,99,111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,
-120,121,122,0,18,99,111,111,114,100,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0,18,108,111,100,0,
-20,0,4,118,101,99,52,95,116,101,120,95,49,100,95,98,105,97,115,95,115,104,97,100,111,119,0,18,95,
-95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,52,0,0,0,0,1,
-90,95,0,0,12,0,0,115,104,97,100,111,119,49,68,80,114,111,106,76,111,100,0,1,1,0,0,20,0,115,97,109,
-112,108,101,114,0,0,1,1,0,0,12,0,99,111,111,114,100,0,0,1,1,0,0,9,0,108,111,100,0,0,0,1,3,2,90,95,
-0,0,12,0,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,0,18,99,111,111,114,
-100,0,59,120,0,18,99,111,111,114,100,0,59,119,0,49,20,0,9,18,112,99,111,111,114,100,0,59,122,0,18,
-99,111,111,114,100,0,59,122,0,20,0,9,18,112,99,111,111,114,100,0,59,119,0,18,108,111,100,0,20,0,4,
-118,101,99,52,95,116,101,120,95,49,100,95,98,105,97,115,95,115,104,97,100,111,119,0,18,95,95,114,
-101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,90,95,
-0,0,12,0,0,115,104,97,100,111,119,50,68,76,111,100,0,1,1,0,0,21,0,115,97,109,112,108,101,114,0,0,1,
-1,0,0,11,0,99,111,111,114,100,0,0,1,1,0,0,9,0,108,111,100,0,0,0,1,3,2,90,95,0,0,12,0,1,99,111,111,
-114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,121,122,0,18,99,111,111,114,100,0,20,0,9,18,
-99,111,111,114,100,52,0,59,119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116,101,120,95,50,100,95,
-98,105,97,115,95,115,104,97,100,111,119,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,
-101,114,0,0,18,99,111,111,114,100,52,0,0,0,0,1,90,95,0,0,12,0,0,115,104,97,100,111,119,50,68,80,
-114,111,106,76,111,100,0,1,1,0,0,21,0,115,97,109,112,108,101,114,0,0,1,1,0,0,12,0,99,111,111,114,
-100,0,0,1,1,0,0,9,0,108,111,100,0,0,0,1,3,2,90,95,0,0,12,0,1,112,99,111,111,114,100,0,0,0,9,18,112,
-99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,
-119,0,49,20,0,9,18,112,99,111,111,114,100,0,59,122,0,18,99,111,111,114,100,0,59,122,0,20,0,9,18,
-112,99,111,111,114,100,0,59,119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116,101,120,95,50,100,
-95,98,105,97,115,95,115,104,97,100,111,119,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,
-108,101,114,0,0,18,112,99,111,111,114,100,0,0,0,0,0
diff --git a/src/mesa/shader/slang/library/syn_to_c.c b/src/mesa/shader/slang/library/syn_to_c.c
deleted file mode 100644
index f997edf..0000000
--- a/src/mesa/shader/slang/library/syn_to_c.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include <stdio.h>
-
-static int was_space = 0;
-static int first_char = 1;
-
-static void put_char (int c)
-{
-   if (c == '\n') {
-      if (!first_char) {
-         fputs ("\\n\"\n\"", stdout);
-         first_char = 1;
-      }
-   }
-   else {
-      first_char = 0;
-      if (c == '\\')
-         fputs ("\\\\", stdout);
-      else if (c == '\"')
-         fputs ("\\\"", stdout);
-      else if (!was_space || !(c == ' ' || c == '\t'))
-         fputc (c, stdout);
-      was_space = (c == ' ' || c == '\t');
-   }
-}
-
-int main (int argc, char *argv[])
-{
-   int c;
-   FILE *f;
-
-   if (argc == 1)
-      return 1;
-   f = fopen (argv[1], "r");
-   if (f == NULL)
-      return 1;
-
-   fputs ("\n", stdout);
-   fputs ("/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE .syn FILE */\n", stdout);
-   fputs ("\n", stdout);
-   fputs ("\"", stdout);
-   c = getc (f);
-   while (c != EOF) {
-      if (c == '/') {
-         int c2 = getc (f);
-         if (c2 == '*') {
-            was_space = 0;
-            c = getc (f);
-            for (;;) {
-               if (c == '*') {
-                  c2 = getc (f);
-                  if (c2 == '/')
-                     break;
-               }
-               c = getc (f);
-            }
-         }
-         else {
-            put_char (c);
-            put_char (c2);
-         }
-      }
-      else {
-         put_char (c);
-      }
-      c = getc (f);
-   }
-   fputs ("\"\n", stdout);
-
-   fclose (f);
-   return 0;
-}
-
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 344dfdc..372a9ac 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -925,7 +925,7 @@
       slang_operation_copy(rhs, &oper->children[0]);
    }
 
-   ///blockOper->locals->outer_scope = oper->locals->outer_scope;
+   /*blockOper->locals->outer_scope = oper->locals->outer_scope;*/
 
    /*slang_print_tree(blockOper, 0);*/
 
@@ -3763,6 +3763,14 @@
 #endif
       }
 
+      if (var->type.qualifier == SLANG_QUAL_UNIFORM &&
+          !A->allow_uniform_initializers) {
+         slang_info_log_error(A->log,
+                              "initializer for uniform %s not allowed",
+                              varName);
+         return NULL;
+      }
+
       /* IR for the variable we're initializing */
       varRef = new_var(A, var);
       if (!varRef) {
@@ -4241,14 +4249,15 @@
 
    if (oper->children[0].type == SLANG_OPER_IDENTIFIER) {
       /* Check that var is writeable */
+      const char *varName = (char *) oper->children[0].a_id;
       slang_variable *var
          = _slang_variable_locate(oper->children[0].locals,
                                   oper->children[0].a_id, GL_TRUE);
       if (!var) {
-         slang_info_log_error(A->log, "undefined variable '%s'",
-                              (char *) oper->children[0].a_id);
+         slang_info_log_error(A->log, "undefined variable '%s'", varName);
          return NULL;
       }
+
       if (var->type.qualifier == SLANG_QUAL_CONST ||
           var->type.qualifier == SLANG_QUAL_ATTRIBUTE ||
           var->type.qualifier == SLANG_QUAL_UNIFORM ||
@@ -4256,7 +4265,7 @@
            A->program->Target == GL_FRAGMENT_PROGRAM_ARB)) {
          slang_info_log_error(A->log,
                               "illegal assignment to read-only variable '%s'",
-                              (char *) oper->children[0].a_id);
+                              varName);
          return NULL;
       }
 
diff --git a/src/mesa/shader/slang/slang_codegen.h b/src/mesa/shader/slang/slang_codegen.h
index ee3be55..461633f 100644
--- a/src/mesa/shader/slang/slang_codegen.h
+++ b/src/mesa/shader/slang/slang_codegen.h
@@ -42,6 +42,7 @@
    struct gl_sl_pragmas *pragmas;
    slang_var_table *vartable;
    slang_info_log *log;
+   GLboolean allow_uniform_initializers;
 
    /* current loop stack */
    const slang_operation *LoopOperStack[MAX_LOOP_DEPTH];
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c
index a270888..6499cfc 100644
--- a/src/mesa/shader/slang/slang_compile.c
+++ b/src/mesa/shader/slang/slang_compile.c
@@ -35,10 +35,10 @@
 #include "shader/prog_optimize.h"
 #include "shader/prog_print.h"
 #include "shader/prog_parameter.h"
-#include "shader/grammar/grammar_mesa.h"
+#include "../../glsl/pp/sl_pp_public.h"
+#include "../../glsl/cl/sl_cl_parse.h"
 #include "slang_codegen.h"
 #include "slang_compile.h"
-#include "slang_preprocess.h"
 #include "slang_storage.h"
 #include "slang_emit.h"
 #include "slang_log.h"
@@ -128,7 +128,7 @@
 
 typedef struct slang_parse_ctx_
 {
-   const byte *I;
+   const unsigned char *I;
    slang_info_log *L;
    int parsing_builtin;
    GLboolean global_scope;   /**< Is object being declared a global? */
@@ -184,22 +184,102 @@
 }
 
 static int
+is_hex_digit(char c)
+{
+   return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
+}
+
+static int
+parse_general_number(slang_parse_ctx *ctx, float *number)
+{
+   char *flt = NULL;
+
+   if (*ctx->I == '0') {
+      int value = 0;
+      const unsigned char *pi;
+
+      if (ctx->I[1] == 'x' || ctx->I[1] == 'X') {
+         ctx->I += 2;
+         if (!is_hex_digit(*ctx->I)) {
+            return 0;
+         }
+         do {
+            int digit;
+
+            if (*ctx->I >= '0' && *ctx->I <= '9') {
+               digit = (int)(*ctx->I - '0');
+            } else if (*ctx->I >= 'a' && *ctx->I <= 'f') {
+               digit = (int)(*ctx->I - 'a') + 10;
+            } else {
+               digit = (int)(*ctx->I - 'A') + 10;
+            }
+            value = value * 0x10 + digit;
+            ctx->I++;
+         } while (is_hex_digit(*ctx->I));
+         if (*ctx->I != '\0') {
+            return 0;
+         }
+         ctx->I++;
+         *number = (float)value;
+         return 1;
+      }
+
+      pi = ctx->I;
+      pi++;
+      while (*pi >= '0' && *pi <= '7') {
+         int digit;
+
+         digit = (int)(*pi - '0');
+         value = value * 010 + digit;
+         pi++;
+      }
+      if (*pi == '\0') {
+         pi++;
+         ctx->I = pi;
+         *number = (float)value;
+         return 1;
+      }
+   }
+
+   parse_identifier_str(ctx, &flt);
+   flt = strdup(flt);
+   if (!flt) {
+      return 0;
+   }
+   if (flt[strlen(flt) - 1] == 'f' || flt[strlen(flt) - 1] == 'F') {
+      flt[strlen(flt) - 1] = '\0';
+   }
+   *number = (float)_mesa_strtod(flt, (char **)NULL);
+   free(flt);
+
+   return 1;
+}
+
+static int
 parse_number(slang_parse_ctx * C, int *number)
 {
    const int radix = (int) (*C->I++);
-   *number = 0;
-   while (*C->I != '\0') {
-      int digit;
-      if (*C->I >= '0' && *C->I <= '9')
-         digit = (int) (*C->I - '0');
-      else if (*C->I >= 'A' && *C->I <= 'Z')
-         digit = (int) (*C->I - 'A') + 10;
-      else
-         digit = (int) (*C->I - 'a') + 10;
-      *number = *number * radix + digit;
+
+   if (radix == 1) {
+      float f = 0.0f;
+
+      parse_general_number(C, &f);
+      *number = (int)f;
+   } else {
+      *number = 0;
+      while (*C->I != '\0') {
+         int digit;
+         if (*C->I >= '0' && *C->I <= '9')
+            digit = (int) (*C->I - '0');
+         else if (*C->I >= 'A' && *C->I <= 'Z')
+            digit = (int) (*C->I - 'A') + 10;
+         else
+            digit = (int) (*C->I - 'a') + 10;
+         *number = *number * radix + digit;
+         C->I++;
+      }
       C->I++;
    }
-   C->I++;
    if (*number > 65535)
       slang_info_log_warning(C->L, "%d: literal integer overflow.", *number);
    return 1;
@@ -208,33 +288,38 @@
 static int
 parse_float(slang_parse_ctx * C, float *number)
 {
-   char *integral = NULL;
-   char *fractional = NULL;
-   char *exponent = NULL;
-   char *whole = NULL;
+   if (*C->I == 1) {
+      C->I++;
+      parse_general_number(C, number);
+   } else {
+      char *integral = NULL;
+      char *fractional = NULL;
+      char *exponent = NULL;
+      char *whole = NULL;
 
-   parse_identifier_str(C, &integral);
-   parse_identifier_str(C, &fractional);
-   parse_identifier_str(C, &exponent);
+      parse_identifier_str(C, &integral);
+      parse_identifier_str(C, &fractional);
+      parse_identifier_str(C, &exponent);
 
-   whole = (char *) _slang_alloc((_mesa_strlen(integral) +
-                                  _mesa_strlen(fractional) +
-                                  _mesa_strlen(exponent) + 3) * sizeof(char));
-   if (whole == NULL) {
-      slang_info_log_memory(C->L);
-      RETURN0;
+      whole = (char *) _slang_alloc((_mesa_strlen(integral) +
+                                     _mesa_strlen(fractional) +
+                                     _mesa_strlen(exponent) + 3) * sizeof(char));
+      if (whole == NULL) {
+         slang_info_log_memory(C->L);
+         RETURN0;
+      }
+
+      slang_string_copy(whole, integral);
+      slang_string_concat(whole, ".");
+      slang_string_concat(whole, fractional);
+      slang_string_concat(whole, "E");
+      slang_string_concat(whole, exponent);
+
+      *number = (float) (_mesa_strtod(whole, (char **) NULL));
+
+      _slang_free(whole);
    }
 
-   slang_string_copy(whole, integral);
-   slang_string_concat(whole, ".");
-   slang_string_concat(whole, fractional);
-   slang_string_concat(whole, "E");
-   slang_string_concat(whole, exponent);
-
-   *number = (float) (_mesa_strtod(whole, (char **) NULL));
-
-   _slang_free(whole);
-
    return 1;
 }
 
@@ -2058,6 +2143,7 @@
    if (C->global_scope) {
       slang_assemble_ctx A;
       memset(&A, 0, sizeof(slang_assemble_ctx));
+      A.allow_uniform_initializers = C->version > 110;
       A.atoms = C->atoms;
       A.space.funcs = O->funs;
       A.space.structs = O->structs;
@@ -2077,6 +2163,7 @@
       if (var->initializer != NULL) {
          slang_assemble_ctx A;
          memset(&A, 0, sizeof(slang_assemble_ctx));
+         A.allow_uniform_initializers = C->version > 110;
          A.atoms = C->atoms;
          A.space.funcs = O->funs;
          A.space.structs = O->structs;
@@ -2434,6 +2521,7 @@
       A.vartable = o.vartable;
       A.EmitContReturn = ctx->Shader.EmitContReturn;
       A.log = C->L;
+      A.allow_uniform_initializers = C->version > 110;
 
       /* main() takes no parameters */
       if (mainFunc->param_count > 0) {
@@ -2455,7 +2543,7 @@
 }
 
 static GLboolean
-compile_binary(const byte * prod, slang_code_unit * unit,
+compile_binary(const unsigned char * prod, slang_code_unit * unit,
                GLuint version,
                slang_unit_type type, slang_info_log * infolog,
                slang_code_unit * builtin, slang_code_unit * downlink,
@@ -2488,17 +2576,56 @@
 }
 
 static GLboolean
-compile_with_grammar(grammar id, const char *source, slang_code_unit * unit,
-                     slang_unit_type type, slang_info_log * infolog,
-                     slang_code_unit * builtin,
+compile_with_grammar(const char *source,
+                     slang_code_unit *unit,
+                     slang_unit_type type,
+                     slang_info_log *infolog,
+                     slang_code_unit *builtin,
                      struct gl_shader *shader,
-                     const struct gl_extensions *extensions,
-                     struct gl_sl_pragmas *pragmas)
+                     struct gl_sl_pragmas *pragmas,
+                     unsigned int shader_type,
+                     unsigned int parsing_builtin)
 {
-   byte *prod;
-   GLuint size, start, version;
-   slang_string preprocessed;
-   GLuint maxVersion;
+   struct sl_pp_purify_options options;
+   struct sl_pp_context *context;
+   unsigned char *prod;
+   GLuint size;
+   unsigned int version;
+   unsigned int maxVersion;
+   int result;
+   char errmsg[200] = "";
+
+   assert(shader_type == 1 || shader_type == 2);
+
+   memset(&options, 0, sizeof(options));
+
+   context = sl_pp_context_create(source, &options);
+   if (!context) {
+      slang_info_log_error(infolog, "out of memory");
+      return GL_FALSE;
+   }
+
+   if (sl_pp_version(context, &version)) {
+      slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
+      sl_pp_context_destroy(context);
+      return GL_FALSE;
+   }
+
+   if (sl_pp_context_add_extension(context, "ARB_draw_buffers", "GL_ARB_draw_buffers") ||
+       sl_pp_context_add_extension(context, "ARB_texture_rectangle", "GL_ARB_texture_rectangle")) {
+      slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
+      sl_pp_context_destroy(context);
+      return GL_FALSE;
+   }
+
+#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")) {
+      slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
+      sl_pp_context_destroy(context);
+      return GL_FALSE;
+   }
+#endif
 
 #if FEATURE_ARB_shading_language_120
    maxVersion = 120;
@@ -2508,36 +2635,30 @@
    maxVersion = 110;
 #endif
 
-   /* First retrieve the version number. */
-   if (!_slang_preprocess_version(source, &version, &start, infolog))
-      return GL_FALSE;
-
-   if (version > maxVersion) {
+   if (version > maxVersion ||
+       (version != 100 && version != 110 && version != 120)) {
       slang_info_log_error(infolog,
                            "language version %.2f is not supported.",
                            version * 0.01);
-      return GL_FALSE;
-   }
-
-   /* Now preprocess the source string. */
-   slang_string_init(&preprocessed);
-   if (!_slang_preprocess_directives(&preprocessed, &source[start],
-                                     infolog, extensions, pragmas)) {
-      slang_string_free(&preprocessed);
-      slang_info_log_error(infolog, "failed to preprocess the source.");
+      sl_pp_context_destroy(context);
       return GL_FALSE;
    }
 
    /* Finally check the syntax and generate its binary representation. */
-   if (!grammar_fast_check(id,
-                           (const byte *) (slang_string_cstr(&preprocessed)),
-                           &prod, &size, 65536)) {
-      char buf[1024];
-      GLint pos;
+   result = sl_cl_compile(context,
+                          shader_type,
+                          parsing_builtin,
+                          &prod,
+                          &size,
+                          errmsg,
+                          sizeof(errmsg));
 
-      slang_string_free(&preprocessed);
-      grammar_get_last_error((byte *) (buf), sizeof(buf), &pos);
-      slang_info_log_error(infolog, buf);
+   sl_pp_context_destroy(context);
+
+   if (result) {
+      /*GLint pos;*/
+
+      slang_info_log_error(infolog, errmsg);
       /* syntax error (possibly in library code) */
 #if 0
       {
@@ -2551,77 +2672,64 @@
 #endif
       return GL_FALSE;
    }
-   slang_string_free(&preprocessed);
 
    /* Syntax is okay - translate it to internal representation. */
    if (!compile_binary(prod, unit, version, type, infolog, builtin,
                        &builtin[SLANG_BUILTIN_TOTAL - 1],
                        shader)) {
-      grammar_alloc_free(prod);
+      free(prod);
       return GL_FALSE;
    }
-   grammar_alloc_free(prod);
+   free(prod);
    return GL_TRUE;
 }
 
-LONGSTRING static const char *slang_shader_syn =
-#include "library/slang_shader_syn.h"
-   ;
-
-static const byte slang_core_gc[] = {
+static const unsigned char slang_core_gc[] = {
 #include "library/slang_core_gc.h"
 };
 
-static const byte slang_120_core_gc[] = {
+static const unsigned char slang_120_core_gc[] = {
 #include "library/slang_120_core_gc.h"
 };
 
-static const byte slang_120_fragment_gc[] = {
+static const unsigned char slang_120_fragment_gc[] = {
 #include "library/slang_builtin_120_fragment_gc.h"
 };
 
-static const byte slang_common_builtin_gc[] = {
+static const unsigned char slang_common_builtin_gc[] = {
 #include "library/slang_common_builtin_gc.h"
 };
 
-static const byte slang_fragment_builtin_gc[] = {
+static const unsigned char slang_fragment_builtin_gc[] = {
 #include "library/slang_fragment_builtin_gc.h"
 };
 
-static const byte slang_vertex_builtin_gc[] = {
+static const unsigned char slang_vertex_builtin_gc[] = {
 #include "library/slang_vertex_builtin_gc.h"
 };
 
 static GLboolean
-compile_object(grammar * id, const char *source, slang_code_object * object,
-               slang_unit_type type, slang_info_log * infolog,
+compile_object(const char *source,
+               slang_code_object *object,
+               slang_unit_type type,
+               slang_info_log *infolog,
                struct gl_shader *shader,
-               const struct gl_extensions *extensions,
                struct gl_sl_pragmas *pragmas)
 {
    slang_code_unit *builtins = NULL;
    GLuint base_version = 110;
-
-   /* load GLSL grammar */
-   *id = grammar_load_from_text((const byte *) (slang_shader_syn));
-   if (*id == 0) {
-      byte buf[1024];
-      int pos;
-
-      grammar_get_last_error(buf, 1024, &pos);
-      slang_info_log_error(infolog, (const char *) (buf));
-      return GL_FALSE;
-   }
+   unsigned int shader_type;
+   unsigned int parsing_builtin;
 
    /* set shader type - the syntax is slightly different for different shaders */
-   if (type == SLANG_UNIT_FRAGMENT_SHADER
-       || type == SLANG_UNIT_FRAGMENT_BUILTIN)
-      grammar_set_reg8(*id, (const byte *) "shader_type", 1);
-   else
-      grammar_set_reg8(*id, (const byte *) "shader_type", 2);
+   if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_FRAGMENT_BUILTIN) {
+      shader_type = 1;
+   } else {
+      shader_type = 2;
+   }
 
    /* enable language extensions */
-   grammar_set_reg8(*id, (const byte *) "parsing_builtin", 1);
+   parsing_builtin = 1;
 
    /* if parsing user-specified shader, load built-in library */
    if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_VERTEX_SHADER) {
@@ -2686,51 +2794,24 @@
       }
 
       /* disable language extensions */
-#if NEW_SLANG /* allow-built-ins */
-      grammar_set_reg8(*id, (const byte *) "parsing_builtin", 1);
-#else
-      grammar_set_reg8(*id, (const byte *) "parsing_builtin", 0);
-#endif
+      parsing_builtin = 0;
+
       builtins = object->builtin;
    }
 
    /* compile the actual shader - pass-in built-in library for external shader */
-   return compile_with_grammar(*id, source, &object->unit, type, infolog,
-                               builtins, shader, extensions, pragmas);
+   return compile_with_grammar(source,
+                               &object->unit,
+                               type,
+                               infolog,
+                               builtins,
+                               shader,
+                               pragmas,
+                               shader_type,
+                               parsing_builtin);
 }
 
 
-static GLboolean
-compile_shader(GLcontext *ctx, slang_code_object * object,
-               slang_unit_type type, slang_info_log * infolog,
-               struct gl_shader *shader)
-{
-   GLboolean success;
-   grammar id = 0;
-
-#if 0 /* for debug */
-   _mesa_printf("********* COMPILE SHADER ***********\n");
-   _mesa_printf("%s\n", shader->Source);
-   _mesa_printf("************************************\n");
-#endif
-
-   assert(shader->Program);
-
-   _slang_code_object_dtr(object);
-   _slang_code_object_ctr(object);
-
-   success = compile_object(&id, shader->Source, object, type, infolog, shader,
-                            &ctx->Extensions, &shader->Pragmas);
-   if (id != 0)
-      grammar_destroy(id);
-   if (!success)
-      return GL_FALSE;
-
-   return GL_TRUE;
-}
-
-
-
 GLboolean
 _slang_compile(GLcontext *ctx, struct gl_shader *shader)
 {
@@ -2738,6 +2819,7 @@
    slang_info_log info_log;
    slang_code_object obj;
    slang_unit_type type;
+   GLenum progTarget;
 
    if (shader->Type == GL_VERTEX_SHADER) {
       type = SLANG_UNIT_VERTEX_SHADER;
@@ -2754,22 +2836,28 @@
 
    shader->Main = GL_FALSE;
 
-   if (!shader->Program) {
-      GLenum progTarget;
-      if (shader->Type == GL_VERTEX_SHADER)
-         progTarget = GL_VERTEX_PROGRAM_ARB;
-      else
-         progTarget = GL_FRAGMENT_PROGRAM_ARB;
-      shader->Program = ctx->Driver.NewProgram(ctx, progTarget, 1);
-      shader->Program->Parameters = _mesa_new_parameter_list();
-      shader->Program->Varying = _mesa_new_parameter_list();
-      shader->Program->Attributes = _mesa_new_parameter_list();
-   }
+   /* free the shader's old instructions, etc */
+   _mesa_reference_program(ctx, &shader->Program, NULL);
+
+   /* allocate new GPU program, parameter lists, etc. */
+   if (shader->Type == GL_VERTEX_SHADER)
+      progTarget = GL_VERTEX_PROGRAM_ARB;
+   else
+      progTarget = GL_FRAGMENT_PROGRAM_ARB;
+   shader->Program = ctx->Driver.NewProgram(ctx, progTarget, 1);
+   shader->Program->Parameters = _mesa_new_parameter_list();
+   shader->Program->Varying = _mesa_new_parameter_list();
+   shader->Program->Attributes = _mesa_new_parameter_list();
 
    slang_info_log_construct(&info_log);
    _slang_code_object_ctr(&obj);
 
-   success = compile_shader(ctx, &obj, type, &info_log, shader);
+   success = compile_object(shader->Source,
+                            &obj,
+                            type,
+                            &info_log,
+                            shader,
+                            &shader->Pragmas);
 
    /* free shader's prev info log */
    if (shader->InfoLog) {
diff --git a/src/mesa/shader/slang/slang_compile_operation.c b/src/mesa/shader/slang/slang_compile_operation.c
index 3e2bdbc..3a15d9d 100644
--- a/src/mesa/shader/slang/slang_compile_operation.c
+++ b/src/mesa/shader/slang/slang_compile_operation.c
@@ -46,12 +46,14 @@
    oper->literal_size = 1;
    oper->array_constructor = GL_FALSE;
    oper->a_id = SLANG_ATOM_NULL;
+   oper->a_obj = SLANG_ATOM_NULL;
    oper->locals = _slang_variable_scope_new(NULL);
    if (oper->locals == NULL)
       return GL_FALSE;
    _slang_variable_scope_ctr(oper->locals);
    oper->fun = NULL;
    oper->var = NULL;
+   oper->label = NULL;
    return GL_TRUE;
 }
 
diff --git a/src/mesa/shader/slang/slang_compile_operation.h b/src/mesa/shader/slang/slang_compile_operation.h
index 58f1ede..1f15c19 100644
--- a/src/mesa/shader/slang/slang_compile_operation.h
+++ b/src/mesa/shader/slang/slang_compile_operation.h
@@ -127,7 +127,6 @@
     * indicate such.  num_children indicates number of elements.
     */
    GLboolean array_constructor;
-   double x;
 } slang_operation;
 
 
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 3af301e..ce3f6ab 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -81,8 +81,8 @@
 
    emitInfo->Subroutines = (struct gl_program **)
       _mesa_realloc(emitInfo->Subroutines,
-                    n * sizeof(struct gl_program),
-                    (n + 1) * sizeof(struct gl_program));
+                    n * sizeof(struct gl_program *),
+                    (n + 1) * sizeof(struct gl_program *));
    emitInfo->Subroutines[n] = ctx->Driver.NewProgram(ctx, emitInfo->prog->Target, 0);
    emitInfo->Subroutines[n]->Parameters = emitInfo->prog->Parameters;
    emitInfo->NumSubroutines++;
@@ -195,6 +195,9 @@
    if (!n->Store) {
       assert(defaultSize > 0);
       n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, defaultSize);
+      if (!n->Store) {
+         return GL_FALSE;
+      }
    }
 
    /* now allocate actual register(s).  I.e. set n->Store->Index >= 0 */
@@ -431,6 +434,9 @@
          _mesa_realloc_instructions(prog->Instructions,
                                     prog->NumInstructions,
                                     emitInfo->MaxInstructions);
+      if (!prog->Instructions) {
+         return NULL;
+      }
    }
 
    inst = prog->Instructions + prog->NumInstructions;
@@ -451,12 +457,14 @@
               gl_register_file file, GLint index, GLuint swizzle)
 {
    struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ARL);
-   inst->SrcReg[0].File = file;
-   inst->SrcReg[0].Index = index;
-   inst->SrcReg[0].Swizzle = fix_swizzle(swizzle);
-   inst->DstReg.File = PROGRAM_ADDRESS;
-   inst->DstReg.Index = 0;
-   inst->DstReg.WriteMask = WRITEMASK_X;
+   if (inst) {
+      inst->SrcReg[0].File = file;
+      inst->SrcReg[0].Index = index;
+      inst->SrcReg[0].Swizzle = fix_swizzle(swizzle);
+      inst->DstReg.File = PROGRAM_ADDRESS;
+      inst->DstReg.Index = 0;
+      inst->DstReg.WriteMask = WRITEMASK_X;
+   }
    return inst;
 }
 
@@ -543,6 +551,9 @@
                                        &srcRelAddr,
                                        NULL,
                                        NULL);
+               if (!inst) {
+                  return NULL;
+               }
 
                src[i] = &newSrc[i];
             }
@@ -765,7 +776,9 @@
 emit_comment(slang_emit_info *emitInfo, const char *comment)
 {
    struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_NOP);
-   inst_comment(inst, comment);
+   if (inst) {
+      inst_comment(inst, comment);
+   }
    return inst;
 }
 
@@ -792,7 +805,9 @@
       emit(emitInfo, n->Children[0]->Children[0]);  /* A */
       emit(emitInfo, n->Children[0]->Children[1]);  /* B */
       emit(emitInfo, n->Children[1]);  /* C */
-      alloc_node_storage(emitInfo, n, -1);  /* dest */
+      if (!alloc_node_storage(emitInfo, n, -1)) {  /* dest */
+         return NULL;
+      }
 
       inst = emit_instruction(emitInfo,
                               OPCODE_MAD,
@@ -813,7 +828,9 @@
       emit(emitInfo, n->Children[0]);  /* A */
       emit(emitInfo, n->Children[1]->Children[0]);  /* B */
       emit(emitInfo, n->Children[1]->Children[1]);  /* C */
-      alloc_node_storage(emitInfo, n, -1);  /* dest */
+      if (!alloc_node_storage(emitInfo, n, -1)) {  /* dest */
+         return NULL;
+      }
 
       inst = emit_instruction(emitInfo,
                               OPCODE_MAD,
@@ -839,7 +856,9 @@
    }
 
    /* result storage */
-   alloc_node_storage(emitInfo, n, -1);
+   if (!alloc_node_storage(emitInfo, n, -1)) {
+      return NULL;
+   }
 
    inst = emit_instruction(emitInfo,
                            info->InstOpcode,
@@ -932,6 +951,9 @@
                               n->Children[0]->Store,
                               n->Children[1]->Store,
                               NULL);
+      if (!inst) {
+         return NULL;
+      }
       inst_comment(inst, "Compare values");
 
       /* Compute val = DOT(temp, temp)  (reduction) */
@@ -941,6 +963,9 @@
                               &tempStore,
                               &tempStore,
                               NULL);
+      if (!inst) {
+         return NULL;
+      }
       inst->SrcReg[0].Swizzle = inst->SrcReg[1].Swizzle = swizzle; /*override*/
       inst_comment(inst, "Reduce vec to bool");
 
@@ -956,6 +981,9 @@
                                  n->Store,
                                  &zero,
                                  NULL);
+         if (!inst) {
+            return NULL;
+         }
          inst_comment(inst, "Invert true/false");
       }
    }
@@ -985,6 +1013,9 @@
                                     &srcStore0,
                                     &srcStore1,
                                     NULL);
+            if (!inst) {
+               return NULL;
+            }
             inst_comment(inst, "Begin struct/array comparison");
          }
          else {
@@ -994,12 +1025,18 @@
                                     &srcStore0,
                                     &srcStore1,
                                     NULL);
+            if (!inst) {
+               return NULL;
+            }
             /* ADD accTemp, accTemp, sneTemp; # like logical-OR */
             inst = emit_instruction(emitInfo, OPCODE_ADD,
                                     &accTemp, /* dest */
                                     &accTemp,
                                     &sneTemp,
                                     NULL);
+            if (!inst) {
+               return NULL;
+            }
          }
       }
 
@@ -1009,6 +1046,9 @@
                               &accTemp,
                               &accTemp,
                               NULL);
+      if (!inst) {
+         return NULL;
+      }
       inst_comment(inst, "End struct/array comparison");
 
       if (n->Opcode == IR_EQUAL) {
@@ -1020,6 +1060,9 @@
                                  n->Store,
                                  &zero,
                                  NULL);
+         if (!inst) {
+            return NULL;
+         }
          inst_comment(inst, "Invert true/false");
       }
 
@@ -1093,7 +1136,9 @@
     * the intermediate result.  Use a temp register instead.
     */
    _mesa_bzero(&tmpNode, sizeof(tmpNode));
-   alloc_node_storage(emitInfo, &tmpNode, n->Store->Size);
+   if (!alloc_node_storage(emitInfo, &tmpNode, n->Store->Size)) {
+      return NULL;
+   }
 
    /* tmp = max(ch[0], ch[1]) */
    inst = emit_instruction(emitInfo, OPCODE_MAX,
@@ -1101,6 +1146,9 @@
                            n->Children[0]->Store,
                            n->Children[1]->Store,
                            NULL);
+   if (!inst) {
+      return NULL;
+   }
 
    /* n->dest = min(tmp, ch[2]) */
    inst = emit_instruction(emitInfo, OPCODE_MIN,
@@ -1135,7 +1183,9 @@
                            n->Children[0]->Store,
                            NULL,
                            NULL);
-   inst->SrcReg[0].Negate = NEGATE_XYZW;
+   if (inst) {
+      inst->SrcReg[0].Negate = NEGATE_XYZW;
+   }
    return inst;
 }
 
@@ -1191,6 +1241,9 @@
        * really just a NOP to attach the label to.
        */
       inst = new_instruction(emitInfo, OPCODE_BGNSUB);
+      if (!inst) {
+         return NULL;
+      }
       inst_comment(inst, n->Label->Name);
    }
 
@@ -1202,10 +1255,16 @@
    inst = prev_instruction(emitInfo);
    if (inst && inst->Opcode != OPCODE_RET) {
       inst = new_instruction(emitInfo, OPCODE_RET);
+      if (!inst) {
+         return NULL;
+      }
    }
 
    if (emitInfo->EmitBeginEndSub) {
       inst = new_instruction(emitInfo, OPCODE_ENDSUB);
+      if (!inst) {
+         return NULL;
+      }
       inst_comment(inst, n->Label->Name);
    }
 
@@ -1215,6 +1274,9 @@
 
    /* emit the function call */
    inst = new_instruction(emitInfo, OPCODE_CAL);
+   if (!inst) {
+      return NULL;
+   }
    /* The branch target is just the subroutine number (changed later) */
    inst->BranchTarget = subroutineId;
    inst_comment(inst, n->Label->Name);
@@ -1235,7 +1297,9 @@
    assert(n->Opcode == IR_RETURN);
    assert(n->Label);
    inst = new_instruction(emitInfo, OPCODE_RET);
-   inst->DstReg.CondMask = COND_TR;  /* always return */
+   if (inst) {
+      inst->DstReg.CondMask = COND_TR;  /* always return */
+   }
    return inst;
 }
 
@@ -1249,6 +1313,9 @@
     * Note that ARB-KILL depends on sign of vector operand.
     */
    inst = new_instruction(emitInfo, OPCODE_KIL_NV);
+   if (!inst) {
+      return NULL;
+   }
    inst->DstReg.CondMask = COND_TR;  /* always kill */
 
    assert(emitInfo->prog->Target == GL_FRAGMENT_PROGRAM_ARB);
@@ -1321,6 +1388,9 @@
                            n->Children[1]->Store,
                            NULL,
                            NULL);
+   if (!inst) {
+      return NULL;
+   }
 
    inst->TexShadow = shadow;
 
@@ -1423,6 +1493,9 @@
                                     &srcStore,
                                     NULL,
                                     NULL);
+            if (!inst) {
+               return NULL;
+            }
             inst_comment(inst, "IR_COPY block");
             srcStore.Index++;
             dstStore.Index++;
@@ -1438,6 +1511,9 @@
                                  n->Children[1]->Store,
                                  NULL,
                                  NULL);
+         if (!inst) {
+            return NULL;
+         }
          dstAnnot = storage_annotation(n->Children[0], emitInfo->prog);
          srcAnnot = storage_annotation(n->Children[1], emitInfo->prog);
          inst->Comment = instruction_annotation(inst->Opcode, dstAnnot,
@@ -1499,6 +1575,9 @@
                                  n->Children[0]->Store,
                                  NULL,
                                  NULL);
+         if (!inst) {
+            return NULL;
+         }
          inst->CondUpdate = GL_TRUE;
          inst_comment(inst, "COND expr");
          _slang_free_temp(emitInfo->vt, n->Store);
@@ -1561,6 +1640,9 @@
                            n->Children[0]->Store,
                            &zero,
                            NULL);
+   if (!inst) {
+      return NULL;
+   }
    inst_comment(inst, "NOT");
 
    free_node_storage(emitInfo->vt, n->Children[0]);
@@ -1600,8 +1682,10 @@
    if (emitInfo->EmitHighLevelInstructions) {
       if (emitInfo->EmitCondCodes) {
          /* IF condcode THEN ... */
-         struct prog_instruction *ifInst;
-         ifInst = new_instruction(emitInfo, OPCODE_IF);
+         struct prog_instruction *ifInst = new_instruction(emitInfo, OPCODE_IF);
+         if (!ifInst) {
+            return NULL;
+         }
          ifInst->DstReg.CondMask = COND_NE;  /* if cond is non-zero */
          /* only test the cond code (1 of 4) that was updated by the
           * previous instruction.
@@ -1609,17 +1693,25 @@
          ifInst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
       }
       else {
+         struct prog_instruction *inst;
+
          /* IF src[0] THEN ... */
-         emit_instruction(emitInfo, OPCODE_IF,
-                          NULL, /* dst */
-                          n->Children[0]->Store, /* op0 */
-                          NULL,
-                          NULL);
+         inst = emit_instruction(emitInfo, OPCODE_IF,
+                                 NULL, /* dst */
+                                 n->Children[0]->Store, /* op0 */
+                                 NULL,
+                                 NULL);
+         if (!inst) {
+            return NULL;
+         }
       }
    }
    else {
       /* conditional jump to else, or endif */
       struct prog_instruction *ifInst = new_instruction(emitInfo, OPCODE_BRA);
+      if (!ifInst) {
+         return NULL;
+      }
       ifInst->DstReg.CondMask = COND_EQ;  /* BRA if cond is zero */
       inst_comment(ifInst, "if zero");
       ifInst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
@@ -1632,16 +1724,22 @@
       /* have else body */
       elseInstLoc = prog->NumInstructions;
       if (emitInfo->EmitHighLevelInstructions) {
-         (void) new_instruction(emitInfo, OPCODE_ELSE);
+         struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ELSE);
+         if (!inst) {
+            return NULL;
+         }
+         prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions - 1;
       }
       else {
          /* jump to endif instruction */
-         struct prog_instruction *inst;
-         inst = new_instruction(emitInfo, OPCODE_BRA);
+         struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_BRA);
+         if (!inst) {
+            return NULL;
+         }
          inst_comment(inst, "else");
          inst->DstReg.CondMask = COND_TR;  /* always branch */
+         prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions;
       }
-      prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions;
       emit(emitInfo, n->Children[2]);
    }
    else {
@@ -1650,11 +1748,20 @@
    }
 
    if (emitInfo->EmitHighLevelInstructions) {
-      (void) new_instruction(emitInfo, OPCODE_ENDIF);
+      struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ENDIF);
+      if (!inst) {
+         return NULL;
+      }
    }
 
-   if (n->Children[2]) {
-      prog->Instructions[elseInstLoc].BranchTarget = prog->NumInstructions;
+   if (elseInstLoc) {
+      /* point ELSE instruction BranchTarget at ENDIF */
+      if (emitInfo->EmitHighLevelInstructions) {
+         prog->Instructions[elseInstLoc].BranchTarget = prog->NumInstructions - 1;
+      }
+      else {
+         prog->Instructions[elseInstLoc].BranchTarget = prog->NumInstructions;
+      }
    }
    return NULL;
 }
@@ -1671,7 +1778,10 @@
    /* emit OPCODE_BGNLOOP */
    beginInstLoc = prog->NumInstructions;
    if (emitInfo->EmitHighLevelInstructions) {
-      (void) new_instruction(emitInfo, OPCODE_BGNLOOP);
+      struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_BGNLOOP);
+      if (!inst) {
+         return NULL;
+      }
    }
 
    /* body */
@@ -1689,10 +1799,16 @@
    if (emitInfo->EmitHighLevelInstructions) {
       /* emit OPCODE_ENDLOOP */
       endInst = new_instruction(emitInfo, OPCODE_ENDLOOP);
+      if (!endInst) {
+         return NULL;
+      }
    }
    else {
       /* emit unconditional BRA-nch */
       endInst = new_instruction(emitInfo, OPCODE_BRA);
+      if (!endInst) {
+         return NULL;
+      }
       endInst->DstReg.CondMask = COND_TR;  /* always true */
    }
    /* ENDLOOP's BranchTarget points to the BGNLOOP inst */
@@ -1705,7 +1821,7 @@
 
    /* Done emitting loop code.  Now walk over the loop's linked list of
     * BREAK and CONT nodes, filling in their BranchTarget fields (which
-    * will point to the ENDLOOP+1 or BGNLOOP instructions, respectively).
+    * will point to the corresponding ENDLOOP instruction.
     */
    for (ir = n->List; ir; ir = ir->List) {
       struct prog_instruction *inst = prog->Instructions + ir->InstLocation;
@@ -1714,8 +1830,13 @@
           ir->Opcode == IR_BREAK_IF_TRUE) {
          assert(inst->Opcode == OPCODE_BRK ||
                 inst->Opcode == OPCODE_BRA);
-         /* go to instruction after end of loop */
-         inst->BranchTarget = endInstLoc + 1;
+         /* go to instruction at end of loop */
+         if (emitInfo->EmitHighLevelInstructions) {
+            inst->BranchTarget = endInstLoc;
+         }
+         else {
+            inst->BranchTarget = endInstLoc + 1;
+         }
       }
       else {
          assert(ir->Opcode == IR_CONT ||
@@ -1762,7 +1883,9 @@
    }
    n->InstLocation = emitInfo->prog->NumInstructions;
    inst = new_instruction(emitInfo, opcode);
-   inst->DstReg.CondMask = COND_TR;  /* always true */
+   if (inst) {
+      inst->DstReg.CondMask = COND_TR;  /* always true */
+   }
    return inst;
 }
 
@@ -1798,8 +1921,10 @@
           */
          const GLuint condWritemask = inst->DstReg.WriteMask;
          inst = new_instruction(emitInfo, opcode);
-         inst->DstReg.CondMask = COND_NE;
-         inst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
+         if (inst) {
+            inst->DstReg.CondMask = COND_NE;
+            inst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
+         }
          return inst;
       }
       else {
@@ -1814,13 +1939,22 @@
                                  n->Children[0]->Store,
                                  NULL,
                                  NULL);
+         if (!inst) {
+            return NULL;
+         }
          n->InstLocation = emitInfo->prog->NumInstructions;
 
          inst = new_instruction(emitInfo, opcode);
+         if (!inst) {
+            return NULL;
+         }
          inst = new_instruction(emitInfo, OPCODE_ENDIF);
+         if (!inst) {
+            return NULL;
+         }
 
          emitInfo->prog->Instructions[ifInstLoc].BranchTarget
-            = emitInfo->prog->NumInstructions;
+            = emitInfo->prog->NumInstructions - 1;
          return inst;
       }
    }
@@ -1828,8 +1962,10 @@
       const GLuint condWritemask = inst->DstReg.WriteMask;
       assert(emitInfo->EmitCondCodes);
       inst = new_instruction(emitInfo, OPCODE_BRA);
-      inst->DstReg.CondMask = COND_NE;
-      inst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
+      if (inst) {
+         inst->DstReg.CondMask = COND_NE;
+         inst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
+      }
       return inst;
    }
 }
@@ -1976,6 +2112,9 @@
                                  indexStore, /* the index */
                                  &elemSizeStore,
                                  NULL);
+         if (!inst) {
+            return NULL;
+         }
 
          indexStore = indexTemp;
       }
@@ -2002,6 +2141,9 @@
                                  indexStore,     /* the index */
                                  &indirectArray, /* indirect array base */
                                  NULL);
+         if (!inst) {
+            return NULL;
+         }
 
          indexStore = indexTemp;
       }
@@ -2201,7 +2343,9 @@
 
    if (n->Comment) {
       inst = new_instruction(emitInfo, OPCODE_NOP);
-      inst->Comment = _mesa_strdup(n->Comment);
+      if (inst) {
+         inst->Comment = _mesa_strdup(n->Comment);
+      }
       inst = NULL;
    }
 
@@ -2503,6 +2647,9 @@
    if (withEnd) {
       struct prog_instruction *inst;
       inst = new_instruction(&emitInfo, OPCODE_END);
+      if (!inst) {
+         return GL_FALSE;
+      }
    }
 
    _slang_resolve_subroutines(&emitInfo);
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index 144c126..ed27821 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -515,7 +515,7 @@
       }
 
       if (inst->DstReg.File == PROGRAM_OUTPUT) {
-         prog->OutputsWritten |= 1 << inst->DstReg.Index;
+         prog->OutputsWritten |= BITFIELD64_BIT(inst->DstReg.Index);
          if (inst->DstReg.RelAddr) {
             /* If the output attribute is indexed with relative addressing
              * we know that it must be a varying or texcoord such as
@@ -528,14 +528,17 @@
             if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
                if (inst->DstReg.Index == VERT_RESULT_TEX0) {
                   /* mark all texcoord outputs as written */
-                  const GLbitfield mask =
-                     ((1 << MAX_TEXTURE_COORD_UNITS) - 1) << VERT_RESULT_TEX0;
+                  const GLbitfield64 mask =
+		     BITFIELD64_RANGE(VERT_RESULT_TEX0,
+				      (VERT_RESULT_TEX0
+				       + MAX_TEXTURE_COORD_UNITS - 1));
                   prog->OutputsWritten |= mask;
                }
                else if (inst->DstReg.Index == VERT_RESULT_VAR0) {
                   /* mark all generic varying outputs as written */
-                  const GLbitfield mask =
-                     ((1 << MAX_VARYING) - 1) << VERT_RESULT_VAR0;
+                  const GLbitfield64 mask =
+		     BITFIELD64_RANGE(VERT_RESULT_VAR0,
+				      (VERT_RESULT_VAR0 + MAX_VARYING - 1));
                   prog->OutputsWritten |= mask;
                }
             }
@@ -587,11 +590,16 @@
 {
    struct gl_shader *newShader;
    const struct gl_shader *firstShader = NULL;
-   GLuint shaderLengths[100];
+   GLuint *shaderLengths;
    GLchar *source;
    GLuint totalLen = 0, len = 0;
    GLuint i;
 
+   shaderLengths = (GLuint *)_mesa_malloc(shProg->NumShaders * sizeof(GLuint));
+   if (!shaderLengths) {
+      return NULL;
+   }
+
    /* compute total size of new shader source code */
    for (i = 0; i < shProg->NumShaders; i++) {
       const struct gl_shader *shader = shProg->Shaders[i];
@@ -603,12 +611,16 @@
       }
    }
 
-   if (totalLen == 0)
+   if (totalLen == 0) {
+      _mesa_free(shaderLengths);
       return NULL;
+   }
 
    source = (GLchar *) _mesa_malloc(totalLen + 1);
-   if (!source)
+   if (!source) {
+      _mesa_free(shaderLengths);
       return NULL;
+   }
 
    /* concatenate shaders */
    for (i = 0; i < shProg->NumShaders; i++) {
@@ -623,9 +635,16 @@
    _mesa_printf("---NEW CONCATENATED SHADER---:\n%s\n------------\n", source);
    */
 
+   _mesa_free(shaderLengths);
+
    remove_extra_version_directives(source);
 
    newShader = CALLOC_STRUCT(gl_shader);
+   if (!newShader) {
+      _mesa_free(source);
+      return NULL;
+   }
+
    newShader->Type = shaderType;
    newShader->Source = source;
    newShader->Pragmas = firstShader->Pragmas;
@@ -807,7 +826,8 @@
    if (shProg->VertexProgram) {
       _slang_update_inputs_outputs(&shProg->VertexProgram->Base);
       _slang_count_temporaries(&shProg->VertexProgram->Base);
-      if (!(shProg->VertexProgram->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) {
+      if (!(shProg->VertexProgram->Base.OutputsWritten
+	    & BITFIELD64_BIT(VERT_RESULT_HPOS))) {
          /* the vertex program did not compute a vertex position */
          link_error(shProg,
                     "gl_Position was not written by vertex shader\n");
@@ -825,7 +845,7 @@
    if (shProg->FragmentProgram) {
       const GLbitfield varyingRead
          = shProg->FragmentProgram->Base.InputsRead >> FRAG_ATTRIB_VAR0;
-      const GLbitfield varyingWritten = shProg->VertexProgram ?
+      const GLbitfield64 varyingWritten = shProg->VertexProgram ?
          shProg->VertexProgram->Base.OutputsWritten >> VERT_RESULT_VAR0 : 0x0;
       if ((varyingRead & varyingWritten) != varyingRead) {
          link_error(shProg,
@@ -836,9 +856,10 @@
 
    /* check that gl_FragColor and gl_FragData are not both written to */
    if (shProg->FragmentProgram) {
-      GLbitfield outputsWritten = shProg->FragmentProgram->Base.OutputsWritten;
-      if ((outputsWritten & ((1 << FRAG_RESULT_COLOR))) &&
-          (outputsWritten >= (1 << FRAG_RESULT_DATA0))) {
+      const GLbitfield64 outputsWritten =
+	 shProg->FragmentProgram->Base.OutputsWritten;
+      if ((outputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) &&
+          (outputsWritten >= BITFIELD64_BIT(FRAG_RESULT_DATA0))) {
          link_error(shProg, "Fragment program cannot write both gl_FragColor"
                     " and gl_FragData[].\n");
          return;
diff --git a/src/mesa/shader/slang/slang_preprocess.c b/src/mesa/shader/slang/slang_preprocess.c
deleted file mode 100644
index e9a24cc..0000000
--- a/src/mesa/shader/slang/slang_preprocess.c
+++ /dev/null
@@ -1,1406 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2005-2008  Brian Paul   All Rights Reserved.
- * Copyright (C) 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, sublicense,
- * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL 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 slang_preprocess.c
- * slang preprocessor
- * \author Michal Krol
- */
-
-#include "main/imports.h"
-#include "shader/grammar/grammar_mesa.h"
-#include "slang_preprocess.h"
-
-LONGSTRING static const char *slang_pp_directives_syn =
-#include "library/slang_pp_directives_syn.h"
-;
-
-LONGSTRING static const char *slang_pp_expression_syn =
-#include "library/slang_pp_expression_syn.h"
-;
-
-LONGSTRING static const char *slang_pp_version_syn =
-#include "library/slang_pp_version_syn.h"
-;
-
-static GLvoid
-grammar_error_to_log (slang_info_log *log)
-{
-   char buf[1024];
-   GLint pos;
-
-   grammar_get_last_error ((byte *) (buf), sizeof (buf), &pos);
-   if (buf[0] == 0) {
-      _mesa_snprintf(buf, sizeof(buf), "Preprocessor error");
-   }
-   slang_info_log_error (log, buf);
-}
-
-GLboolean
-_slang_preprocess_version (const char *text, GLuint *version, GLuint *eaten, slang_info_log *log)
-{
-   grammar id;
-   byte *prod, *I;
-   unsigned int size;
-
-   id = grammar_load_from_text ((const byte *) (slang_pp_version_syn));
-   if (id == 0) {
-      grammar_error_to_log (log);
-      return GL_FALSE;
-   }
-
-   if (!grammar_fast_check (id, (const byte *) (text), &prod, &size, 8)) {
-      grammar_error_to_log (log);
-      grammar_destroy (id);
-      return GL_FALSE;
-   }
-
-   /* there can be multiple #version directives - grab the last one */
-   I = &prod[size - 6];
-   *version = (GLuint) (I[0]) + (GLuint) (I[1]) * 100;
-   *eaten = (GLuint) (I[2]) + ((GLuint) (I[3]) << 8) + ((GLuint) (I[4]) << 16) + ((GLuint) (I[5]) << 24);
-
-   grammar_destroy (id);
-   grammar_alloc_free (prod);
-   return GL_TRUE;
-}
-
-/*
- * The preprocessor does the following work.
- * 1. Remove comments. Each comment block is replaced with a single space and if the
- *    block contains new-lines, they are preserved. This ensures that line numbers
- *    stay the same and if a comment block delimits two tokens, the are delitmited
- *    by the space after comment removal.
- * 2. Remove preprocessor directives from the source string, checking their syntax and
- *    executing them if appropriate. Again, new-lines are preserved.
- * 3. Expand macros.
- * 4. Tokenize the source string by ensuring there is at least one space between every
- *    two adjacent tokens.
- */
-
-#define PP_ANNOTATE 0
-
-static GLvoid
-pp_annotate (slang_string *output, const char *fmt, ...)
-{
-#if PP_ANNOTATE
-   va_list va;
-   char buffer[1024];
-
-   va_start (va, fmt);
-   _mesa_vsprintf (buffer, fmt, va);
-   va_end (va);
-   slang_string_pushs (output, buffer, _mesa_strlen (buffer));
-#else
-   (GLvoid) (output);
-   (GLvoid) (fmt);
-#endif
-}
-
- /*
- * The expression is executed on a fixed-sized stack. The PUSH macro makes a runtime
- * check if the stack is not overflown by too complex expressions. In that situation the
- * GLSL preprocessor should report internal compiler error.
- * The BINARYDIV makes a runtime check if the divider is not 0. If it is, it reports
- * compilation error.
- */
-
-#define EXECUTION_STACK_SIZE 1024
-
-#define PUSH(x)\
-   do {\
-      if (sp == 0) {\
-         slang_info_log_error (elog, "internal compiler error: preprocessor execution stack overflow.");\
-         return GL_FALSE;\
-      }\
-      stack[--sp] = x;\
-   } while (GL_FALSE)
-
-#define POP(x)\
-   do {\
-      assert (sp < EXECUTION_STACK_SIZE);\
-      x = stack[sp++];\
-   } while (GL_FALSE)
-
-#define BINARY(op)\
-   do {\
-      GLint a, b;\
-      POP(b);\
-      POP(a);\
-      PUSH(a op b);\
-   } while (GL_FALSE)
-
-#define BINARYDIV(op)\
-   do {\
-      GLint a, b;\
-      POP(b);\
-      POP(a);\
-      if (b == 0) {\
-         slang_info_log_error (elog, "division by zero in preprocessor expression.");\
-         return GL_FALSE;\
-      }\
-      PUSH(a op b);\
-   } while (GL_FALSE)
-
-#define UNARY(op)\
-   do {\
-      GLint a;\
-      POP(a);\
-      PUSH(op a);\
-   } while (GL_FALSE)
-
-#define OP_END          0
-#define OP_PUSHINT      1
-#define OP_LOGICALOR    2
-#define OP_LOGICALAND   3
-#define OP_OR           4
-#define OP_XOR          5
-#define OP_AND          6
-#define OP_EQUAL        7
-#define OP_NOTEQUAL     8
-#define OP_LESSEQUAL    9
-#define OP_GREATEREQUAL 10
-#define OP_LESS         11
-#define OP_GREATER      12
-#define OP_LEFTSHIFT    13
-#define OP_RIGHTSHIFT   14
-#define OP_ADD          15
-#define OP_SUBTRACT     16
-#define OP_MULTIPLY     17
-#define OP_DIVIDE       18
-#define OP_MODULUS      19
-#define OP_PLUS         20
-#define OP_MINUS        21
-#define OP_NEGATE       22
-#define OP_COMPLEMENT   23
-
-static GLboolean
-execute_expression (slang_string *output, const byte *code, GLuint *pi, GLint *result,
-                    slang_info_log *elog)
-{
-   GLuint i = *pi;
-   GLint stack[EXECUTION_STACK_SIZE];
-   GLuint sp = EXECUTION_STACK_SIZE;
-
-   while (code[i] != OP_END) {
-      switch (code[i++]) {
-         case OP_PUSHINT:
-            i++;
-            PUSH(_mesa_atoi ((const char *) (&code[i])));
-            i += _mesa_strlen ((const char *) (&code[i])) + 1;
-            break;
-         case OP_LOGICALOR:
-            BINARY(||);
-            break;
-         case OP_LOGICALAND:
-            BINARY(&&);
-            break;
-         case OP_OR:
-            BINARY(|);
-            break;
-         case OP_XOR:
-            BINARY(^);
-            break;
-         case OP_AND:
-            BINARY(&);
-            break;
-         case OP_EQUAL:
-            BINARY(==);
-            break;
-         case OP_NOTEQUAL:
-            BINARY(!=);
-            break;
-         case OP_LESSEQUAL:
-            BINARY(<=);
-            break;
-         case OP_GREATEREQUAL:
-            BINARY(>=);
-            break;
-         case OP_LESS:
-            BINARY(<);
-            break;
-         case OP_GREATER:
-            BINARY(>);
-            break;
-         case OP_LEFTSHIFT:
-            BINARY(<<);
-            break;
-         case OP_RIGHTSHIFT:
-            BINARY(>>);
-            break;
-         case OP_ADD:
-            BINARY(+);
-            break;
-         case OP_SUBTRACT:
-            BINARY(-);
-            break;
-         case OP_MULTIPLY:
-            BINARY(*);
-            break;
-         case OP_DIVIDE:
-            BINARYDIV(/);
-            break;
-         case OP_MODULUS:
-            BINARYDIV(%);
-            break;
-         case OP_PLUS:
-            UNARY(+);
-            break;
-         case OP_MINUS:
-            UNARY(-);
-            break;
-         case OP_NEGATE:
-            UNARY(!);
-            break;
-         case OP_COMPLEMENT:
-            UNARY(~);
-            break;
-         default:
-            assert (0);
-      }
-   }
-
-   /* Write-back the index skipping the OP_END. */
-   *pi = i + 1;
-
-   /* There should be exactly one value left on the stack. This is our result. */
-   POP(*result);
-   pp_annotate (output, "%d ", *result);
-   assert (sp == EXECUTION_STACK_SIZE);
-   return GL_TRUE;
-}
-
-/*
- * Function execute_expressions() executes up to 2 expressions. The second expression is there
- * for the #line directive which takes 1 or 2 expressions that indicate line and file numbers.
- * If it fails, it returns 0. If it succeeds, it returns the number of executed expressions.
- */
-
-#define EXP_END        0
-#define EXP_EXPRESSION 1
-
-static GLuint
-execute_expressions (slang_string *output, grammar eid, const byte *expr, GLint results[2],
-                     slang_info_log *elog)
-{
-   GLint success;
-   byte *code;
-   GLuint size, count = 0;
-
-   success = grammar_fast_check (eid, expr, &code, &size, 64);
-   if (success) {
-      GLuint i = 0;
-
-      while (code[i++] == EXP_EXPRESSION) {
-         assert (count < 2);
-
-         if (!execute_expression (output, code, &i, &results[count], elog)) {
-            count = 0;
-            break;
-         }
-         count++;
-      }
-      grammar_alloc_free (code);
-   }
-   else {
-      slang_info_log_error (elog, "syntax error in preprocessor expression.");\
-   }
-   return count;
-}
-
-/*
- * The pp_symbol structure is used to hold macro definitions and macro formal parameters. The
- * pp_symbols strcture is a collection of pp_symbol. It is used both for storing macro formal
- * parameters and all global macro definitions. Making this unification wastes some memory,
- * becuse macro formal parameters don't need further lists of symbols. We lose 8 bytes per
- * formal parameter here, but making this we can use the same code to substitute macro parameters
- * as well as macros in the source string.
- */
-
-typedef struct
-{
-   struct pp_symbol_ *symbols;
-   GLuint count;
-} pp_symbols;
-
-static GLvoid
-pp_symbols_init (pp_symbols *self)
-{
-   self->symbols = NULL;
-   self->count = 0;
-}
-
-static GLvoid
-pp_symbols_free (pp_symbols *);
-
-typedef struct pp_symbol_
-{
-   slang_string name;
-   slang_string replacement;
-   pp_symbols parameters;
-} pp_symbol;
-
-static GLvoid
-pp_symbol_init (pp_symbol *self)
-{
-   slang_string_init (&self->name);
-   slang_string_init (&self->replacement);
-   pp_symbols_init (&self->parameters);
-}
-
-static GLvoid
-pp_symbol_free (pp_symbol *self)
-{
-   slang_string_free (&self->name);
-   slang_string_free (&self->replacement);
-   pp_symbols_free (&self->parameters);
-}
-
-static GLvoid
-pp_symbol_reset (pp_symbol *self)
-{
-   /* Leave symbol name intact. */
-   slang_string_reset (&self->replacement);
-   pp_symbols_free (&self->parameters);
-   pp_symbols_init (&self->parameters);
-}
-
-static GLvoid
-pp_symbols_free (pp_symbols *self)
-{
-   GLuint i;
-
-   for (i = 0; i < self->count; i++)
-      pp_symbol_free (&self->symbols[i]);
-   _mesa_free (self->symbols);
-}
-
-static pp_symbol *
-pp_symbols_push (pp_symbols *self)
-{
-   self->symbols = (pp_symbol *) (_mesa_realloc (self->symbols, self->count * sizeof (pp_symbol),
-                                                 (self->count + 1) * sizeof (pp_symbol)));
-   if (self->symbols == NULL)
-      return NULL;
-   pp_symbol_init (&self->symbols[self->count]);
-   return &self->symbols[self->count++];
-}
-
-static GLboolean
-pp_symbols_erase (pp_symbols *self, pp_symbol *symbol)
-{
-   assert (symbol >= self->symbols && symbol < self->symbols + self->count);
-
-   self->count--;
-   pp_symbol_free (symbol);
-   if (symbol < self->symbols + self->count)
-      _mesa_memcpy (symbol, symbol + 1, sizeof (pp_symbol) * (self->symbols + self->count - symbol));
-   self->symbols = (pp_symbol *) (_mesa_realloc (self->symbols, (self->count + 1) * sizeof (pp_symbol),
-                                                 self->count * sizeof (pp_symbol)));
-   return self->symbols != NULL;
-}
-
-static pp_symbol *
-pp_symbols_find (pp_symbols *self, const char *name)
-{
-   GLuint i;
-
-   for (i = 0; i < self->count; i++)
-      if (_mesa_strcmp (name, slang_string_cstr (&self->symbols[i].name)) == 0)
-         return &self->symbols[i];
-   return NULL;
-}
-
-/*
- * The condition context of a single #if/#else/#endif level. Those can be nested, so there
- * is a stack of condition contexts.
- * There is a special global context on the bottom of the stack. It is there to simplify
- * context handling.
- */
-
-typedef struct
-{
-   GLboolean current;         /* The condition value of this level. */
-   GLboolean effective;       /* The effective product of current condition, outer level conditions
-                               * and position within #if-#else-#endif sections. */
-   GLboolean else_allowed;    /* TRUE if in #if-#else section, FALSE if in #else-#endif section
-                               * and for global context. */
-   GLboolean endif_required;  /* FALSE for global context only. */
-} pp_cond_ctx;
-
-/* Should be enuff. */
-#define CONDITION_STACK_SIZE 64
-
-typedef struct
-{
-   pp_cond_ctx stack[CONDITION_STACK_SIZE];
-   pp_cond_ctx *top;
-} pp_cond_stack;
-
-static GLboolean
-pp_cond_stack_push (pp_cond_stack *self, slang_info_log *elog)
-{
-   if (self->top == self->stack) {
-      slang_info_log_error (elog, "internal compiler error: preprocessor condition stack overflow.");
-      return GL_FALSE;
-   }
-   self->top--;
-   return GL_TRUE;
-}
-
-static GLvoid
-pp_cond_stack_reevaluate (pp_cond_stack *self)
-{
-   /* There must be at least 2 conditions on the stack - one global and one being evaluated. */
-   assert (self->top <= &self->stack[CONDITION_STACK_SIZE - 2]);
-
-   self->top->effective = self->top->current && self->top[1].effective;
-}
-
-
-/**
- * Extension enables through #extension directive.
- * NOTE: Currently, only enable/disable state is stored.
- */
-typedef struct
-{
-   GLboolean ARB_draw_buffers;
-   GLboolean ARB_texture_rectangle;
-} pp_ext;
-
-
-/**
- * Disable all extensions. Called at startup and on #extension all: disable.
- */
-static GLvoid
-pp_ext_disable_all(pp_ext *self)
-{
-   _mesa_memset(self, 0, sizeof(self));
-}
-
-
-/**
- * Called during preprocessor initialization to set the initial enable/disable
- * state of extensions.
- */
-static GLvoid
-pp_ext_init(pp_ext *self, const struct gl_extensions *extensions)
-{
-   pp_ext_disable_all (self);
-   self->ARB_draw_buffers = GL_TRUE;
-   if (extensions->NV_texture_rectangle)
-      self->ARB_texture_rectangle = GL_TRUE;
-}
-
-/**
- * Called in response to #extension directives to enable/disable
- * the named extension.
- */
-static GLboolean
-pp_ext_set(pp_ext *self, const char *name, GLboolean enable)
-{
-   if (_mesa_strcmp (name, "GL_ARB_draw_buffers") == 0)
-      self->ARB_draw_buffers = enable;
-   else if (_mesa_strcmp (name, "GL_ARB_texture_rectangle") == 0)
-      self->ARB_texture_rectangle = enable;
-   else
-      return GL_FALSE;
-   return GL_TRUE;
-}
-
-
-/**
- * Called in response to #pragma.  For example, "#pragma debug(on)" would
- * call this function as pp_pragma("debug", "on").
- * \return GL_TRUE if pragma is valid, GL_FALSE if invalid
- */
-static GLboolean
-pp_pragma(struct gl_sl_pragmas *pragmas, const char *pragma, const char *param)
-{
-#if 0
-   printf("#pragma %s %s\n", pragma, param);
-#endif
-   if (_mesa_strcmp(pragma, "optimize") == 0) {
-      if (!param)
-         return GL_FALSE; /* missing required param */
-      if (_mesa_strcmp(param, "on") == 0) {
-         if (!pragmas->IgnoreOptimize)
-            pragmas->Optimize = GL_TRUE;
-      }
-      else if (_mesa_strcmp(param, "off") == 0) {
-         if (!pragmas->IgnoreOptimize)
-            pragmas->Optimize = GL_FALSE;
-      }
-      else {
-         return GL_FALSE; /* invalid param */
-      }
-   }
-   else if (_mesa_strcmp(pragma, "debug") == 0) {
-      if (!param)
-         return GL_FALSE; /* missing required param */
-      if (_mesa_strcmp(param, "on") == 0) {
-         if (!pragmas->IgnoreDebug)
-            pragmas->Debug = GL_TRUE;
-      }
-      else if (_mesa_strcmp(param, "off") == 0) {
-         if (!pragmas->IgnoreDebug)
-            pragmas->Debug = GL_FALSE;
-      }
-      else {
-         return GL_FALSE; /* invalid param */
-      }
-   }
-   /* all other pragmas are silently ignored */
-   return GL_TRUE;
-}
-
-
-/**
- * The state of preprocessor: current line, file and version number, list
- * of all defined macros and the #if/#endif context.
- */
-typedef struct
-{
-   GLint line;
-   GLint file;
-   GLint version;
-   pp_symbols symbols;
-   pp_ext ext;
-   slang_info_log *elog;
-   pp_cond_stack cond;
-} pp_state;
-
-static GLvoid
-pp_state_init (pp_state *self, slang_info_log *elog,
-               const struct gl_extensions *extensions)
-{
-   self->line = 0;
-   self->file = 1;
-#if FEATURE_es2_glsl
-   self->version = 100;
-#else
-   self->version = 110;
-#endif
-   pp_symbols_init (&self->symbols);
-   pp_ext_init (&self->ext, extensions);
-   self->elog = elog;
-
-   /* Initialize condition stack and create the global context. */
-   self->cond.top = &self->cond.stack[CONDITION_STACK_SIZE - 1];
-   self->cond.top->current = GL_TRUE;
-   self->cond.top->effective = GL_TRUE;
-   self->cond.top->else_allowed = GL_FALSE;
-   self->cond.top->endif_required = GL_FALSE;
-}
-
-static GLvoid
-pp_state_free (pp_state *self)
-{
-   pp_symbols_free (&self->symbols);
-}
-
-#define IS_FIRST_ID_CHAR(x) (((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z') || (x) == '_')
-#define IS_NEXT_ID_CHAR(x) (IS_FIRST_ID_CHAR(x) || ((x) >= '0' && (x) <= '9'))
-#define IS_WHITE(x) ((x) == ' ' || (x) == '\n')
-#define IS_NULL(x) ((x) == '\0')
-
-#define SKIP_WHITE(x) do { while (IS_WHITE(*(x))) (x)++; } while (GL_FALSE)
-
-typedef struct
-{
-   slang_string *output;
-   const char *input;
-   pp_state *state;
-} expand_state;
-
-static GLboolean
-expand_defined (expand_state *e, slang_string *buffer)
-{
-   GLboolean in_paren = GL_FALSE;
-   const char *id;
-
-   /* Parse the optional opening parenthesis. */
-   SKIP_WHITE(e->input);
-   if (*e->input == '(') {
-      e->input++;
-      in_paren = GL_TRUE;
-      SKIP_WHITE(e->input);
-   }
-
-   /* Parse operand. */
-   if (!IS_FIRST_ID_CHAR(*e->input)) {
-      slang_info_log_error (e->state->elog,
-                            "preprocess error: identifier expected after operator 'defined'.");
-      return GL_FALSE;
-   }
-   slang_string_reset (buffer);
-   slang_string_pushc (buffer, *e->input++);
-   while (IS_NEXT_ID_CHAR(*e->input))
-      slang_string_pushc (buffer, *e->input++);
-   id = slang_string_cstr (buffer);
-
-   /* Check if the operand is defined. Output 1 if it is defined, output 0 if not. */
-   if (pp_symbols_find (&e->state->symbols, id) == NULL)
-      slang_string_pushs (e->output, " 0 ", 3);
-   else
-      slang_string_pushs (e->output, " 1 ", 3);
-
-   /* Parse the closing parentehesis if the opening one was there. */
-   if (in_paren) {
-      SKIP_WHITE(e->input);
-      if (*e->input != ')') {
-         slang_info_log_error (e->state->elog, "preprocess error: ')' expected.");
-         return GL_FALSE;
-      }
-      e->input++;
-      SKIP_WHITE(e->input);
-   }
-   return GL_TRUE;
-}
-
-static GLboolean
-expand (expand_state *, pp_symbols *);
-
-static GLboolean
-expand_symbol (expand_state *e, pp_symbol *symbol)
-{
-   expand_state es;
-
-   /* If the macro has some parameters, we need to parse them. */
-   if (symbol->parameters.count != 0) {
-      GLuint i;
-
-      /* Parse the opening parenthesis. */
-      SKIP_WHITE(e->input);
-      if (*e->input != '(') {
-         slang_info_log_error (e->state->elog, "preprocess error: '(' expected.");
-         return GL_FALSE;
-      }
-      e->input++;
-      SKIP_WHITE(e->input);
-
-      /* Parse macro actual parameters. This can be anything, separated by a colon.
-       */
-      for (i = 0; i < symbol->parameters.count; i++) {
-         GLuint nested_paren_count = 0; /* track number of nested parentheses */
-
-         if (*e->input == ')') {
-            slang_info_log_error (e->state->elog, "preprocess error: unexpected ')'.");
-            return GL_FALSE;
-         }
-
-         /* Eat all characters up to the comma or closing parentheses. */
-         pp_symbol_reset (&symbol->parameters.symbols[i]);
-         while (!IS_NULL(*e->input)) {
-            /* Exit loop only when all nested parens have been eaten. */
-            if (nested_paren_count == 0 && (*e->input == ',' || *e->input == ')'))
-               break;
-
-            /* Actually count nested parens here. */
-            if (*e->input == '(')
-               nested_paren_count++;
-            else if (*e->input == ')')
-               nested_paren_count--;
-
-            slang_string_pushc (&symbol->parameters.symbols[i].replacement, *e->input++);
-         }
-
-         /* If it was not the last paremeter, skip the comma. Otherwise, skip the
-          * closing parentheses. */
-         if (i + 1 == symbol->parameters.count) {
-            /* This is the last paremeter - skip the closing parentheses. */
-            if (*e->input != ')') {
-               slang_info_log_error (e->state->elog, "preprocess error: ')' expected.");
-               return GL_FALSE;
-            }
-            e->input++;
-            SKIP_WHITE(e->input);
-         }
-         else {
-            /* Skip the separating comma. */
-            if (*e->input != ',') {
-               slang_info_log_error (e->state->elog, "preprocess error: ',' expected.");
-               return GL_FALSE;
-            }
-            e->input++;
-            SKIP_WHITE(e->input);
-         }
-      }
-   }
-
-   /* Expand the macro. Use its parameters as a priority symbol list to expand
-    * macro parameters correctly. */
-   es.output = e->output;
-   es.input = slang_string_cstr (&symbol->replacement);
-   es.state = e->state;
-   slang_string_pushc (e->output, ' ');
-   if (!expand (&es, &symbol->parameters))
-      return GL_FALSE;
-   slang_string_pushc (e->output, ' ');
-   return GL_TRUE;
-}
-
-/*
- * Function expand() expands source text from <input> to <output>. The expansion is made using
- * the list passed in <symbols> parameter. It allows us to expand macro formal parameters with
- * actual parameters. The global list of symbols from pp state is used when doing a recursive
- * call of expand().
- */
-
-static GLboolean
-expand (expand_state *e, pp_symbols *symbols)
-{
-   while (!IS_NULL(*e->input)) {
-      if (IS_FIRST_ID_CHAR(*e->input)) {
-         slang_string buffer;
-         const char *id;
-
-         /* Parse the identifier. */
-         slang_string_init (&buffer);
-         slang_string_pushc (&buffer, *e->input++);
-         while (IS_NEXT_ID_CHAR(*e->input))
-            slang_string_pushc (&buffer, *e->input++);
-         id = slang_string_cstr (&buffer);
-
-         /* Now check if the identifier is special in some way. The "defined" identifier is
-          * actually an operator that we must handle here and expand it either to " 0 " or " 1 ".
-          * The other identifiers start with "__" and we expand it to appropriate values
-          * taken from the preprocessor state. */
-         if (_mesa_strcmp (id, "defined") == 0) {
-            if (!expand_defined (e, &buffer))
-               return GL_FALSE;
-         }
-         else if (_mesa_strcmp (id, "__LINE__") == 0) {
-            slang_string_pushc (e->output, ' ');
-            slang_string_pushi (e->output, e->state->line);
-            slang_string_pushc (e->output, ' ');
-         }
-         else if (_mesa_strcmp (id, "__FILE__") == 0) {
-            slang_string_pushc (e->output, ' ');
-            slang_string_pushi (e->output, e->state->file);
-            slang_string_pushc (e->output, ' ');
-         }
-         else if (_mesa_strcmp (id, "__VERSION__") == 0) {
-            slang_string_pushc (e->output, ' ');
-            slang_string_pushi (e->output, e->state->version);
-            slang_string_pushc (e->output, ' ');
-         }
-#if FEATURE_es2_glsl
-         else if (_mesa_strcmp (id, "GL_ES") == 0 ||
-                  _mesa_strcmp (id, "GL_FRAGMENT_PRECISION_HIGH") == 0) {
-            slang_string_pushc (e->output, ' ');
-            slang_string_pushi (e->output, '1');
-            slang_string_pushc (e->output, ' ');
-         }
-#endif
-         else {
-            pp_symbol *symbol;
-
-            /* The list of symbols from <symbols> take precedence over the list from <state>.
-             * Note that in some cases this is the same list so avoid double look-up. */
-            symbol = pp_symbols_find (symbols, id);
-            if (symbol == NULL && symbols != &e->state->symbols)
-               symbol = pp_symbols_find (&e->state->symbols, id);
-
-            /* If the symbol was found, recursively expand its definition. */
-            if (symbol != NULL) {
-               if (!expand_symbol (e, symbol)) {
-                  slang_string_free (&buffer);
-                  return GL_FALSE;
-               }
-            }
-            else {
-               slang_string_push (e->output, &buffer);
-            }
-         }
-         slang_string_free (&buffer);
-      }
-      else if (IS_WHITE(*e->input)) {
-         slang_string_pushc (e->output, *e->input++);
-      }
-      else {
-         while (!IS_WHITE(*e->input) && !IS_NULL(*e->input) && !IS_FIRST_ID_CHAR(*e->input))
-            slang_string_pushc (e->output, *e->input++);
-      }
-   }
-   return GL_TRUE;
-}
-
-static GLboolean
-parse_if (slang_string *output, const byte *prod, GLuint *pi, GLint *result, pp_state *state,
-          grammar eid)
-{
-   const char *text;
-   GLuint len;
-
-   text = (const char *) (&prod[*pi]);
-   len = _mesa_strlen (text);
-
-   if (state->cond.top->effective) {
-      slang_string expr;
-      GLuint count;
-      GLint results[2];
-      expand_state es;
-
-      /* Expand the expression. */
-      slang_string_init (&expr);
-      es.output = &expr;
-      es.input = text;
-      es.state = state;
-      if (!expand (&es, &state->symbols))
-         return GL_FALSE;
-
-      /* Execute the expression. */
-      count = execute_expressions (output, eid, (const byte *) (slang_string_cstr (&expr)),
-                                   results, state->elog);
-      slang_string_free (&expr);
-      if (count != 1)
-         return GL_FALSE;
-      *result = results[0];
-   }
-   else {
-      /* The directive is dead. */
-      *result = 0;
-   }
-
-   *pi += len + 1;
-   return GL_TRUE;
-}
-
-#define ESCAPE_TOKEN 0
-
-#define TOKEN_END       0
-#define TOKEN_DEFINE    1
-#define TOKEN_UNDEF     2
-#define TOKEN_IF        3
-#define TOKEN_ELSE      4
-#define TOKEN_ELIF      5
-#define TOKEN_ENDIF     6
-#define TOKEN_ERROR     7
-#define TOKEN_PRAGMA    8
-#define TOKEN_EXTENSION 9
-#define TOKEN_LINE      10
-
-#define PARAM_END       0
-#define PARAM_PARAMETER 1
-
-#define BEHAVIOR_REQUIRE 1
-#define BEHAVIOR_ENABLE  2
-#define BEHAVIOR_WARN    3
-#define BEHAVIOR_DISABLE 4
-
-#define PRAGMA_NO_PARAM  0
-#define PRAGMA_PARAM     1
-
-
-static GLboolean
-preprocess_source (slang_string *output, const char *source,
-                   grammar pid, grammar eid,
-                   slang_info_log *elog,
-                   const struct gl_extensions *extensions,
-                   struct gl_sl_pragmas *pragmas)
-{
-   static const char *predefined[] = {
-      "__FILE__",
-      "__LINE__",
-      "__VERSION__",
-#if FEATURE_es2_glsl
-      "GL_ES",
-      "GL_FRAGMENT_PRECISION_HIGH",
-#endif
-      NULL
-   };
-   byte *prod;
-   GLuint size, i;
-   pp_state state;
-
-   if (!grammar_fast_check (pid, (const byte *) (source), &prod, &size, 65536)) {
-      grammar_error_to_log (elog);
-      return GL_FALSE;
-   }
-
-   pp_state_init (&state, elog, extensions);
-
-   /* add the predefined symbols to the symbol table */
-   for (i = 0; predefined[i]; i++) {
-      pp_symbol *symbol = NULL;
-      symbol = pp_symbols_push(&state.symbols);
-      assert(symbol);
-      slang_string_pushs(&symbol->name,
-                         predefined[i], _mesa_strlen(predefined[i]));
-   }
-
-   i = 0;
-   while (i < size) {
-      if (prod[i] != ESCAPE_TOKEN) {
-         if (state.cond.top->effective) {
-            slang_string input;
-            expand_state es;
-
-            /* Eat only one line of source code to expand it.
-             * FIXME: This approach has one drawback. If a macro with parameters spans across
-             *        multiple lines, the preprocessor will raise an error. */
-            slang_string_init (&input);
-            while (prod[i] != '\0' && prod[i] != '\n')
-               slang_string_pushc (&input, prod[i++]);
-            if (prod[i] != '\0')
-               slang_string_pushc (&input, prod[i++]);
-
-            /* Increment line number. */
-            state.line++;
-
-            es.output = output;
-            es.input = slang_string_cstr (&input);
-            es.state = &state;
-            if (!expand (&es, &state.symbols))
-               goto error;
-
-            slang_string_free (&input);
-         }
-         else {
-            /* Condition stack is disabled - keep track on line numbers and output only newlines. */
-            if (prod[i] == '\n') {
-               state.line++;
-               /*pp_annotate (output, "%c", prod[i]);*/
-            }
-            else {
-               /*pp_annotate (output, "%c", prod[i]);*/
-            }
-            i++;
-         }
-      }
-      else {
-         const char *id;
-         GLuint idlen;
-         GLubyte token;
-
-         i++;
-         token = prod[i++];
-         switch (token) {
-
-         case TOKEN_END:
-            /* End of source string.
-               * Check if all #ifs have been terminated by matching #endifs.
-               * On condition stack there should be only the global condition context. */
-            if (state.cond.top->endif_required) {
-               slang_info_log_error (elog, "end of source without matching #endif.");
-               return GL_FALSE;
-            }
-            break;
-
-         case TOKEN_DEFINE:
-            {
-               pp_symbol *symbol = NULL;
-
-               /* Parse macro name. */
-               id = (const char *) (&prod[i]);
-               idlen = _mesa_strlen (id);
-               if (state.cond.top->effective) {
-                  pp_annotate (output, "// #define %s(", id);
-
-                  /* If the symbol is already defined, override it. */
-                  symbol = pp_symbols_find (&state.symbols, id);
-                  if (symbol == NULL) {
-                     symbol = pp_symbols_push (&state.symbols);
-                     if (symbol == NULL)
-                        goto error;
-                     slang_string_pushs (&symbol->name, id, idlen);
-                  }
-                  else {
-                     pp_symbol_reset (symbol);
-                  }
-               }
-               i += idlen + 1;
-
-               /* Parse optional macro parameters. */
-               while (prod[i++] != PARAM_END) {
-                  pp_symbol *param;
-
-                  id = (const char *) (&prod[i]);
-                  idlen = _mesa_strlen (id);
-                  if (state.cond.top->effective) {
-                     pp_annotate (output, "%s, ", id);
-                     param = pp_symbols_push (&symbol->parameters);
-                     if (param == NULL)
-                        goto error;
-                     slang_string_pushs (&param->name, id, idlen);
-                  }
-                  i += idlen + 1;
-               }
-
-               /* Parse macro replacement. */
-               id = (const char *) (&prod[i]);
-               idlen = _mesa_strlen (id);
-               if (state.cond.top->effective) {
-                  slang_string replacement;
-                  expand_state es;
-
-                  pp_annotate (output, ") %s", id);
-
-                  slang_string_init(&replacement);
-                  slang_string_pushs(&replacement, id, idlen);
-
-                  /* Expand macro replacement. */
-                  es.output = &symbol->replacement;
-                  es.input = slang_string_cstr(&replacement);
-                  es.state = &state;
-                  if (!expand(&es, &state.symbols)) {
-                     slang_string_free(&replacement);
-                     goto error;
-                  }
-                  slang_string_free(&replacement);
-               }
-               i += idlen + 1;
-            }
-            break;
-
-         case TOKEN_UNDEF:
-            id = (const char *) (&prod[i]);
-            i += _mesa_strlen (id) + 1;
-            if (state.cond.top->effective) {
-               pp_symbol *symbol;
-
-               pp_annotate (output, "// #undef %s", id);
-               /* Try to find symbol with given name and remove it. */
-               symbol = pp_symbols_find (&state.symbols, id);
-               if (symbol != NULL)
-                  if (!pp_symbols_erase (&state.symbols, symbol))
-                     goto error;
-            }
-            break;
-
-         case TOKEN_IF:
-            {
-               GLint result;
-
-               /* Parse #if expression end execute it. */
-               pp_annotate (output, "// #if ");
-               if (!parse_if (output, prod, &i, &result, &state, eid))
-                  goto error;
-
-               /* Push new condition on the stack. */
-               if (!pp_cond_stack_push (&state.cond, state.elog))
-                  goto error;
-               state.cond.top->current = result ? GL_TRUE : GL_FALSE;
-               state.cond.top->else_allowed = GL_TRUE;
-               state.cond.top->endif_required = GL_TRUE;
-               pp_cond_stack_reevaluate (&state.cond);
-            }
-            break;
-
-         case TOKEN_ELSE:
-            /* Check if #else is alloved here. */
-            if (!state.cond.top->else_allowed) {
-               slang_info_log_error (elog, "#else without matching #if.");
-               goto error;
-            }
-
-            /* Negate current condition and reevaluate it. */
-            state.cond.top->current = !state.cond.top->current;
-            state.cond.top->else_allowed = GL_FALSE;
-            pp_cond_stack_reevaluate (&state.cond);
-            if (state.cond.top->effective)
-               pp_annotate (output, "// #else");
-            break;
-
-         case TOKEN_ELIF:
-            /* Check if #elif is alloved here. */
-            if (!state.cond.top->else_allowed) {
-               slang_info_log_error (elog, "#elif without matching #if.");
-               goto error;
-            }
-
-            /* Negate current condition and reevaluate it. */
-            state.cond.top->current = !state.cond.top->current;
-            pp_cond_stack_reevaluate (&state.cond);
-
-            if (state.cond.top->effective)
-               pp_annotate (output, "// #elif ");
-
-            {
-               GLint result;
-
-               /* Parse #elif expression end execute it. */
-               if (!parse_if (output, prod, &i, &result, &state, eid))
-                  goto error;
-
-               /* Update current condition and reevaluate it. */
-               state.cond.top->current = result ? GL_TRUE : GL_FALSE;
-               pp_cond_stack_reevaluate (&state.cond);
-            }
-            break;
-
-         case TOKEN_ENDIF:
-            /* Check if #endif is alloved here. */
-            if (!state.cond.top->endif_required) {
-               slang_info_log_error (elog, "#endif without matching #if.");
-               goto error;
-            }
-
-            /* Pop the condition off the stack. */
-            state.cond.top++;
-            if (state.cond.top->effective)
-               pp_annotate (output, "// #endif");
-            break;
-
-         case TOKEN_EXTENSION:
-            /* Parse the extension name. */
-            id = (const char *) (&prod[i]);
-            i += _mesa_strlen (id) + 1;
-            if (state.cond.top->effective)
-               pp_annotate (output, "// #extension %s: ", id);
-
-            /* Parse and apply extension behavior. */
-            if (state.cond.top->effective) {
-               switch (prod[i++]) {
-
-               case BEHAVIOR_REQUIRE:
-                  pp_annotate (output, "require");
-                  if (!pp_ext_set (&state.ext, id, GL_TRUE)) {
-                     if (_mesa_strcmp (id, "all") == 0) {
-                        slang_info_log_error (elog, "require: bad behavior for #extension all.");
-                        goto error;
-                     }
-                     else {
-                        slang_info_log_error (elog, "%s: required extension is not supported.", id);
-                        goto error;
-                     }
-                  }
-                  break;
-
-               case BEHAVIOR_ENABLE:
-                  pp_annotate (output, "enable");
-                  if (!pp_ext_set (&state.ext, id, GL_TRUE)) {
-                     if (_mesa_strcmp (id, "all") == 0) {
-                        slang_info_log_error (elog, "enable: bad behavior for #extension all.");
-                        goto error;
-                     }
-                     else {
-                        slang_info_log_warning (elog, "%s: enabled extension is not supported.", id);
-                     }
-                  }
-                  break;
-
-               case BEHAVIOR_WARN:
-                  pp_annotate (output, "warn");
-                  if (!pp_ext_set (&state.ext, id, GL_TRUE)) {
-                     if (_mesa_strcmp (id, "all") != 0) {
-                        slang_info_log_warning (elog, "%s: enabled extension is not supported.", id);
-                     }
-                  }
-                  break;
-
-               case BEHAVIOR_DISABLE:
-                  pp_annotate (output, "disable");
-                  if (!pp_ext_set (&state.ext, id, GL_FALSE)) {
-                     if (_mesa_strcmp (id, "all") == 0) {
-                        pp_ext_disable_all (&state.ext);
-                     }
-                     else {
-                        slang_info_log_warning (elog, "%s: disabled extension is not supported.", id);
-                     }
-                  }
-                  break;
-
-               default:
-                  assert (0);
-               }
-            }
-            break;
-
-         case TOKEN_PRAGMA:
-            {
-               GLint have_param;
-               const char *pragma, *param;
-
-               pragma = (const char *) (&prod[i]);
-               i += _mesa_strlen(pragma) + 1;
-               have_param = (prod[i++] == PRAGMA_PARAM);
-               if (have_param) {
-                  param = (const char *) (&prod[i]);
-                  i += _mesa_strlen(param) + 1;
-               }
-               else {
-                  param = NULL;
-               }
-               pp_pragma(pragmas, pragma, param);
-            }
-            break;
-
-         case TOKEN_LINE:
-            id = (const char *) (&prod[i]);
-            i += _mesa_strlen (id) + 1;
-
-            if (state.cond.top->effective) {
-               slang_string buffer;
-               GLuint count;
-               GLint results[2];
-               expand_state es;
-
-               slang_string_init (&buffer);
-               state.line++;
-               es.output = &buffer;
-               es.input = id;
-               es.state = &state;
-               if (!expand (&es, &state.symbols))
-                  goto error;
-
-               pp_annotate (output, "// #line ");
-               count = execute_expressions (output, eid,
-                                             (const byte *) (slang_string_cstr (&buffer)),
-                                             results, state.elog);
-               slang_string_free (&buffer);
-               if (count == 0)
-                  goto error;
-
-               state.line = results[0] - 1;
-               if (count == 2)
-                  state.file = results[1];
-            }
-            break;
-         }
-      }
-   }
-
-   /* Check for missing #endifs. */
-   if (state.cond.top->endif_required) {
-      slang_info_log_error (elog, "#endif expected but end of source found.");
-      goto error;
-   }
-
-   grammar_alloc_free(prod);
-   pp_state_free (&state);
-   return GL_TRUE;
-
-error:
-   grammar_alloc_free(prod);
-   pp_state_free (&state);
-   return GL_FALSE;
-}
-
-
-/**
- * Remove the continuation characters from the input string.
- * This is the very first step in preprocessing and is effective
- * even inside comment blocks.
- * If there is a whitespace between a backslash and a newline,
- * this is not considered as a line continuation.
- * \return GL_TRUE for success, GL_FALSE otherwise.
- */
-static GLboolean
-_slang_preprocess_backslashes(slang_string *output,
-                              const char *input)
-{
-   while (*input) {
-      if (input[0] == '\\') {
-         /* If a newline follows, eat the backslash and the newline. */
-         if (input[1] == '\r') {
-            if (input[2] == '\n') {
-               input += 3;
-            } else {
-               input += 2;
-            }
-         } else if (input[1] == '\n') {
-            if (input[2] == '\r') {
-               input += 3;
-            } else {
-               input += 2;
-            }
-         } else {
-            /* Leave the backslash alone. */
-            slang_string_pushc(output, *input++);
-         }
-      } else {
-         slang_string_pushc(output, *input++);
-      }
-   }
-   return GL_TRUE;
-}
-
-
-/**
- * Run preprocessor on source code.
- * \param extensions  indicates which GL extensions are enabled
- * \param output  the post-process results
- * \param input  the input text
- * \param elog  log to record warnings, errors
- * \param extensions  out extension settings
- * \param pragmas  in/out #pragma settings
- * \return GL_TRUE for success, GL_FALSE for error
- */
-GLboolean
-_slang_preprocess_directives(slang_string *output,
-                             const char *input,
-                             slang_info_log *elog,
-                             const struct gl_extensions *extensions,
-                             struct gl_sl_pragmas *pragmas)
-{
-   grammar pid, eid;
-   GLboolean success;
-   slang_string without_backslashes;
-
-   pid = grammar_load_from_text ((const byte *) (slang_pp_directives_syn));
-   if (pid == 0) {
-      grammar_error_to_log (elog);
-      return GL_FALSE;
-   }
-   eid = grammar_load_from_text ((const byte *) (slang_pp_expression_syn));
-   if (eid == 0) {
-      grammar_error_to_log (elog);
-      grammar_destroy (pid);
-      return GL_FALSE;
-   }
-
-   slang_string_init(&without_backslashes);
-   success = _slang_preprocess_backslashes(&without_backslashes, input);
-
-   if (0) {
-      _mesa_printf("Pre-processed shader:\n");
-      _mesa_printf("%s", slang_string_cstr(&without_backslashes));
-      _mesa_printf("----------------------\n");
-   }
-
-   if (success) {
-      success = preprocess_source(output,
-                                  slang_string_cstr(&without_backslashes),
-                                  pid,
-                                  eid,
-                                  elog,
-                                  extensions,
-                                  pragmas);
-   }
-
-   slang_string_free(&without_backslashes);
-   grammar_destroy (eid);
-   grammar_destroy (pid);
-
-   if (0) {
-      _mesa_printf("Post-processed shader:\n");
-      _mesa_printf("%s", slang_string_cstr(output));
-      _mesa_printf("----------------------\n");
-   }
-
-   return success;
-}
-
diff --git a/src/mesa/shader/slang/slang_preprocess.h b/src/mesa/shader/slang/slang_preprocess.h
deleted file mode 100644
index f344820..0000000
--- a/src/mesa/shader/slang/slang_preprocess.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2005-2008  Brian Paul   All Rights Reserved.
- * Copyright (C) 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, sublicense,
- * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL 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.
- */
-
-#ifndef SLANG_PREPROCESS_H
-#define SLANG_PREPROCESS_H
-
-#include "slang_compile.h"
-#include "slang_log.h"
-
-
-extern GLboolean
-_slang_preprocess_version (const char *, GLuint *, GLuint *, slang_info_log *);
-
-extern GLboolean
-_slang_preprocess_directives(slang_string *output, const char *input,
-                             slang_info_log *,
-                             const struct gl_extensions *extensions,
-                             struct gl_sl_pragmas *pragmas);
-
-#endif /* SLANG_PREPROCESS_H */
diff --git a/src/mesa/shader/slang/slang_simplify.c b/src/mesa/shader/slang/slang_simplify.c
index b8a21f6..13b9ca3 100644
--- a/src/mesa/shader/slang/slang_simplify.c
+++ b/src/mesa/shader/slang/slang_simplify.c
@@ -84,10 +84,11 @@
    for (i = 0; info[i].Name; i++) {
       if (strcmp(info[i].Name, name) == 0) {
          /* found */
-         GLint value = -1;
-         _mesa_GetIntegerv(info[i].Token, &value);
-         ASSERT(value >= 0);  /* sanity check that glGetFloatv worked */
-         return value;
+         GLint values[16];
+         values[0] = -1;
+         _mesa_GetIntegerv(info[i].Token, values);
+         ASSERT(values[0] >= 0);  /* sanity check that glGetFloatv worked */
+         return values[0];
       }
    }
    return -1;
diff --git a/src/mesa/shader/slang/slang_vartable.c b/src/mesa/shader/slang/slang_vartable.c
index a4ebacc..e07e3a2 100644
--- a/src/mesa/shader/slang/slang_vartable.c
+++ b/src/mesa/shader/slang/slang_vartable.c
@@ -311,10 +311,10 @@
 {
    struct table *t = vt->Top;
    GLuint i;
-   GLuint r = store->Index;
+   GLint r = store->Index;
    assert(store->Size > 0);
    assert(r >= 0);
-   assert(r + store->Size <= vt->MaxRegisters * 4);
+   assert((GLuint)r + store->Size <= vt->MaxRegisters * 4);
    if (dbg) printf("Free temp sz %d at %d.%s (level %d) store %p\n",
                    store->Size, r,
                    _mesa_swizzle_string(store->Swizzle, 0, 0),
diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak
index 615a558..a4d09c7 100644
--- a/src/mesa/sources.mak
+++ b/src/mesa/sources.mak
@@ -15,6 +15,7 @@
 	main/clear.c \
 	main/clip.c \
 	main/colortab.c \
+	main/condrender.c \
 	main/context.c \
 	main/convolve.c \
 	main/cpuinfo.c \
@@ -80,6 +81,7 @@
 	main/texstate.c \
 	main/texstore.c \
 	main/varray.c \
+	main/version.c \
 	main/viewport.c \
 	main/vtxfmt.c
 
@@ -190,8 +192,8 @@
 	state_tracker/st_cb_blit.c \
 	state_tracker/st_cb_bufferobjects.c \
 	state_tracker/st_cb_clear.c \
+	state_tracker/st_cb_condrender.c \
 	state_tracker/st_cb_flush.c \
-	state_tracker/st_cb_get.c \
 	state_tracker/st_cb_drawpixels.c \
 	state_tracker/st_cb_fbo.c \
 	state_tracker/st_cb_feedback.c \
@@ -202,7 +204,6 @@
 	state_tracker/st_cb_strings.c \
 	state_tracker/st_cb_texture.c \
 	state_tracker/st_cb_viewport.c \
-	state_tracker/st_api.c \
 	state_tracker/st_context.c \
 	state_tracker/st_debug.c \
 	state_tracker/st_draw.c \
@@ -219,7 +220,6 @@
 	shader/arbprogparse.c \
 	shader/arbprogram.c \
 	shader/atifragshader.c \
-	shader/grammar/grammar_mesa.c \
 	shader/hash_table.c \
 	shader/lex.yy.c \
 	shader/nvfragparse.c \
@@ -256,7 +256,6 @@
 	shader/slang/slang_link.c	\
 	shader/slang/slang_log.c	\
 	shader/slang/slang_mem.c	\
-	shader/slang/slang_preprocess.c	\
 	shader/slang/slang_print.c	\
 	shader/slang/slang_simplify.c	\
 	shader/slang/slang_storage.c	\
@@ -366,6 +365,12 @@
 COMMON_DRIVER_OBJECTS = $(COMMON_DRIVER_SOURCES:.c=.o)
 
 
+### Other archives/libraries
+
+GLSL_LIBS = \
+	$(TOP)/src/glsl/pp/libglslpp.a \
+	$(TOP)/src/glsl/cl/libglslcl.a
+
 
 ### Include directories
 
diff --git a/src/mesa/sparc/glapi_sparc.S b/src/mesa/sparc/glapi_sparc.S
index aaa17e6..9b0f802 100644
--- a/src/mesa/sparc/glapi_sparc.S
+++ b/src/mesa/sparc/glapi_sparc.S
@@ -1014,21 +1014,29 @@
 	GL_STUB(gl_dispatch_stub_785, _gloffset_FlushMappedBufferRangeAPPLE)
 	HIDDEN(gl_dispatch_stub_785)
 	GL_STUB(glFramebufferTextureLayerEXT, _gloffset_FramebufferTextureLayerEXT)
+	GL_STUB(glColorMaskIndexedEXT, _gloffset_ColorMaskIndexedEXT)
+	GL_STUB(glDisableIndexedEXT, _gloffset_DisableIndexedEXT)
+	GL_STUB(glEnableIndexedEXT, _gloffset_EnableIndexedEXT)
+	GL_STUB(glGetBooleanIndexedvEXT, _gloffset_GetBooleanIndexedvEXT)
+	GL_STUB(glGetIntegerIndexedvEXT, _gloffset_GetIntegerIndexedvEXT)
+	GL_STUB(glIsEnabledIndexedEXT, _gloffset_IsEnabledIndexedEXT)
+	GL_STUB(glBeginConditionalRenderNV, _gloffset_BeginConditionalRenderNV)
+	GL_STUB(glEndConditionalRenderNV, _gloffset_EndConditionalRenderNV)
 	GL_STUB(glProvokingVertexEXT, _gloffset_ProvokingVertexEXT)
-	GL_STUB(gl_dispatch_stub_788, _gloffset_GetTexParameterPointervAPPLE)
-	HIDDEN(gl_dispatch_stub_788)
-	GL_STUB(gl_dispatch_stub_789, _gloffset_TextureRangeAPPLE)
-	HIDDEN(gl_dispatch_stub_789)
-	GL_STUB(gl_dispatch_stub_790, _gloffset_StencilFuncSeparateATI)
-	HIDDEN(gl_dispatch_stub_790)
-	GL_STUB(gl_dispatch_stub_791, _gloffset_ProgramEnvParameters4fvEXT)
-	HIDDEN(gl_dispatch_stub_791)
-	GL_STUB(gl_dispatch_stub_792, _gloffset_ProgramLocalParameters4fvEXT)
-	HIDDEN(gl_dispatch_stub_792)
-	GL_STUB(gl_dispatch_stub_793, _gloffset_GetQueryObjecti64vEXT)
-	HIDDEN(gl_dispatch_stub_793)
-	GL_STUB(gl_dispatch_stub_794, _gloffset_GetQueryObjectui64vEXT)
-	HIDDEN(gl_dispatch_stub_794)
+	GL_STUB(gl_dispatch_stub_796, _gloffset_GetTexParameterPointervAPPLE)
+	HIDDEN(gl_dispatch_stub_796)
+	GL_STUB(gl_dispatch_stub_797, _gloffset_TextureRangeAPPLE)
+	HIDDEN(gl_dispatch_stub_797)
+	GL_STUB(gl_dispatch_stub_798, _gloffset_StencilFuncSeparateATI)
+	HIDDEN(gl_dispatch_stub_798)
+	GL_STUB(gl_dispatch_stub_799, _gloffset_ProgramEnvParameters4fvEXT)
+	HIDDEN(gl_dispatch_stub_799)
+	GL_STUB(gl_dispatch_stub_800, _gloffset_ProgramLocalParameters4fvEXT)
+	HIDDEN(gl_dispatch_stub_800)
+	GL_STUB(gl_dispatch_stub_801, _gloffset_GetQueryObjecti64vEXT)
+	HIDDEN(gl_dispatch_stub_801)
+	GL_STUB(gl_dispatch_stub_802, _gloffset_GetQueryObjectui64vEXT)
+	HIDDEN(gl_dispatch_stub_802)
 	GL_STUB_ALIAS(glArrayElementEXT, glArrayElement)
 	GL_STUB_ALIAS(glBindTextureEXT, glBindTexture)
 	GL_STUB_ALIAS(glDrawArraysEXT, glDrawArrays)
@@ -1272,6 +1280,7 @@
 	GL_STUB_ALIAS(glGetAttribLocation, glGetAttribLocationARB)
 	GL_STUB_ALIAS(glDrawBuffers, glDrawBuffersARB)
 	GL_STUB_ALIAS(glDrawBuffersATI, glDrawBuffersARB)
+	GL_STUB_ALIAS(glRenderbufferStorageMultisampleEXT, glRenderbufferStorageMultisample)
 	GL_STUB_ALIAS(glPointParameterf, glPointParameterfEXT)
 	GL_STUB_ALIAS(glPointParameterfARB, glPointParameterfEXT)
 	GL_STUB_ALIAS(glPointParameterfSGIS, glPointParameterfEXT)
diff --git a/src/mesa/sparc/xform.S b/src/mesa/sparc/xform.S
index f2b9674..2a7cce4 100644
--- a/src/mesa/sparc/xform.S
+++ b/src/mesa/sparc/xform.S
@@ -17,7 +17,7 @@
 
 #include "sparc_matrix.h"
 
-#if defined(SVR4) || defined(__SVR4) || defined(__svr4__)
+#if defined(SVR4) || defined(__SVR4) || defined(__svr4__) || defined(__arch64__)
 	/* Solaris requires this for 64-bit. */
         .register %g2, #scratch
         .register %g3, #scratch
diff --git a/src/mesa/state_tracker/st_api.c b/src/mesa/state_tracker/st_api.c
deleted file mode 100644
index fc0e9a2..0000000
--- a/src/mesa/state_tracker/st_api.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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.
- * 
- **************************************************************************/
-
-
-/**
- * Just a global symbol for EGL to look for to identify the supported
- * graphics API.
- */
-int st_api_OpenGL = 1;
diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
index ca15ce1..73df44d 100644
--- a/src/mesa/state_tracker/st_atom.c
+++ b/src/mesa/state_tracker/st_atom.c
@@ -46,7 +46,8 @@
    &st_update_clip,
 
    &st_finalize_textures,
-   &st_update_shader,
+   &st_update_fp,
+   &st_update_vp,
 
    &st_update_rasterizer,
    &st_update_polygon_stipple,
@@ -137,7 +138,7 @@
    if (state->st == 0)
       return;
 
-//   _mesa_printf("%s %x/%x\n", __FUNCTION__, state->mesa, state->st);
+   /*_mesa_printf("%s %x/%x\n", __FUNCTION__, state->mesa, state->st);*/
 
    if (1) {
       /* Debug version which enforces various sanity checks on the
@@ -152,7 +153,7 @@
 	 const struct st_tracked_state *atom = atoms[i];
 	 struct st_state_flags generated;
 	 
-//	 _mesa_printf("atom %s %x/%x\n", atom->name, atom->dirty.mesa, atom->dirty.st);
+	 /*_mesa_printf("atom %s %x/%x\n", atom->name, atom->dirty.mesa, atom->dirty.st);*/
 
 	 if (!(atom->dirty.mesa || atom->dirty.st) ||
 	     !atom->update) {
@@ -162,7 +163,7 @@
 
 	 if (check_state(state, &atom->dirty)) {
 	    atoms[i]->update( st );
-//	    _mesa_printf("after: %x\n", atom->dirty.mesa);
+	    /*_mesa_printf("after: %x\n", atom->dirty.mesa);*/
 	 }
 
 	 accumulate_state(&examined, &atom->dirty);
@@ -175,7 +176,7 @@
 	 assert(!check_state(&examined, &generated));
 	 prev = *state;
       }
-//      _mesa_printf("\n");
+      /*_mesa_printf("\n");*/
 
    }
    else {
diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h
index c7cffd8..f34b492 100644
--- a/src/mesa/state_tracker/st_atom.h
+++ b/src/mesa/state_tracker/st_atom.h
@@ -47,7 +47,8 @@
 extern const struct st_tracked_state st_update_framebuffer;
 extern const struct st_tracked_state st_update_clip;
 extern const struct st_tracked_state st_update_depth_stencil_alpha;
-extern const struct st_tracked_state st_update_shader;
+extern const struct st_tracked_state st_update_fp;
+extern const struct st_tracked_state st_update_vp;
 extern const struct st_tracked_state st_update_rasterizer;
 extern const struct st_tracked_state st_update_polygon_stipple;
 extern const struct st_tracked_state st_update_viewport;
diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c
index 35c09c3..43e62c2 100644
--- a/src/mesa/state_tracker/st_atom_blend.c
+++ b/src/mesa/state_tracker/st_atom_blend.c
@@ -200,13 +200,13 @@
    }
 
    /* Colormask - maybe reverse these bits? */
-   if (st->ctx->Color.ColorMask[0])
+   if (st->ctx->Color.ColorMask[0][0])
       blend->colormask |= PIPE_MASK_R;
-   if (st->ctx->Color.ColorMask[1])
+   if (st->ctx->Color.ColorMask[0][1])
       blend->colormask |= PIPE_MASK_G;
-   if (st->ctx->Color.ColorMask[2])
+   if (st->ctx->Color.ColorMask[0][2])
       blend->colormask |= PIPE_MASK_B;
-   if (st->ctx->Color.ColorMask[3])
+   if (st->ctx->Color.ColorMask[0][3])
       blend->colormask |= PIPE_MASK_A;
 
    if (st->ctx->Color.DitherFlag)
diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c
index e18c0f6..8ca4335 100644
--- a/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -40,6 +40,7 @@
 #include "pipe/p_inlines.h"
 #include "cso_cache/cso_context.h"
 #include "util/u_rect.h"
+#include "util/u_math.h"
 
 
 
@@ -64,8 +65,8 @@
       GLuint level;
       /* find matching mipmap level size */
       for (level = 0; level <= texture->last_level; level++) {
-         if (texture->width[level] == rtt_width &&
-             texture->height[level] == rtt_height) {
+         if (u_minify(texture->width0, level) == rtt_width &&
+             u_minify(texture->height0, level) == rtt_height) {
 
             pipe_surface_reference(&strb->surface, NULL);
 
diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c
index babfcc8..6a5854e 100644
--- a/src/mesa/state_tracker/st_atom_pixeltransfer.c
+++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c
@@ -145,7 +145,7 @@
    const GLuint gSize = ctx->PixelMaps.GtoG.Size;
    const GLuint bSize = ctx->PixelMaps.BtoB.Size;
    const GLuint aSize = ctx->PixelMaps.AtoA.Size;
-   const uint texSize = pt->width[0];
+   const uint texSize = pt->width0;
    uint *dest;
    uint i, j;
 
@@ -162,12 +162,14 @@
     */
    for (i = 0; i < texSize; i++) {
       for (j = 0; j < texSize; j++) {
+         union util_color uc;
          int k = (i * texSize + j);
          ubyte r = ctx->PixelMaps.RtoR.Map8[j * rSize / texSize];
          ubyte g = ctx->PixelMaps.GtoG.Map8[i * gSize / texSize];
          ubyte b = ctx->PixelMaps.BtoB.Map8[j * bSize / texSize];
          ubyte a = ctx->PixelMaps.AtoA.Map8[i * aSize / texSize];
-         util_pack_color_ub(r, g, b, a, pt->format, dest + k);
+         util_pack_color_ub(r, g, b, a, pt->format, &uc);
+         *(dest + k) = uc.ui;
       }
    }
 
diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c
index 6611956..7b84a86 100644
--- a/src/mesa/state_tracker/st_atom_sampler.c
+++ b/src/mesa/state_tracker/st_atom_sampler.c
@@ -208,15 +208,11 @@
             assert(sampler->min_lod <= sampler->max_lod);
          }
 
-         xlate_border_color(texobj->BorderColor,
+         xlate_border_color(texobj->BorderColor.f,
                             teximg ? teximg->_BaseFormat : GL_RGBA,
                             sampler->border_color);
 
 	 sampler->max_anisotropy = texobj->MaxAnisotropy;
-         if (sampler->max_anisotropy > 1.0) {
-            sampler->min_img_filter = PIPE_TEX_FILTER_ANISO;
-            sampler->mag_img_filter = PIPE_TEX_FILTER_ANISO;
-         }
 
          /* only care about ARB_shadow, not SGI shadow */
          if (texobj->CompareMode == GL_COMPARE_R_TO_TEXTURE) {
@@ -229,14 +225,23 @@
 
          /*printf("%s su=%u non-null\n", __FUNCTION__, su);*/
          cso_single_sampler(st->cso_context, su, sampler);
+         if (su < st->ctx->Const.MaxVertexTextureImageUnits) {
+            cso_single_vertex_sampler(st->cso_context, su, sampler);
+         }
       }
       else {
          /*printf("%s su=%u null\n", __FUNCTION__, su);*/
          cso_single_sampler(st->cso_context, su, NULL);
+         if (su < st->ctx->Const.MaxVertexTextureImageUnits) {
+            cso_single_vertex_sampler(st->cso_context, su, NULL);
+         }
       }
    }
 
    cso_single_sampler_done(st->cso_context);
+   if (st->ctx->Const.MaxVertexTextureImageUnits > 0) {
+      cso_single_vertex_sampler_done(st->cso_context);
+   }
 }
 
 
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index ee649be..46c8cbb 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -56,82 +56,18 @@
 #include "st_mesa_to_tgsi.h"
 
 
-/**
- * This represents a vertex program, especially translated to match
- * the inputs of a particular fragment shader.
+
+
+
+/*
+ * Translate fragment program if needed.
  */
-struct translated_vertex_program
+static void
+translate_fp(struct st_context *st,
+             struct st_fragment_program *stfp)
 {
-   struct st_vertex_program *master;
-
-   /** The fragment shader "signature" this vertex shader is meant for: */
-   GLbitfield frag_inputs;
-
-   /** Compared against master vertex program's serialNo: */
-   GLuint serialNo;
-
-   /** Maps VERT_RESULT_x to slot */
-   GLuint output_to_slot[VERT_RESULT_MAX];
-   ubyte output_to_semantic_name[VERT_RESULT_MAX];
-   ubyte output_to_semantic_index[VERT_RESULT_MAX];
-
-   /** Pointer to the translated vertex program */
-   struct st_vertex_program *vp;
-
-   struct translated_vertex_program *next;  /**< next in linked list */
-};
-
-
-
-/**
- * Given a vertex program output attribute, return the corresponding
- * fragment program input attribute.
- * \return -1 for vertex outputs that have no corresponding fragment input
- */
-static GLint
-vp_out_to_fp_in(GLuint vertResult)
-{
-   if (vertResult >= VERT_RESULT_TEX0 &&
-       vertResult < VERT_RESULT_TEX0 + MAX_TEXTURE_COORD_UNITS)
-      return FRAG_ATTRIB_TEX0 + (vertResult - VERT_RESULT_TEX0);
-
-   if (vertResult >= VERT_RESULT_VAR0 &&
-       vertResult < VERT_RESULT_VAR0 + MAX_VARYING)
-      return FRAG_ATTRIB_VAR0 + (vertResult - VERT_RESULT_VAR0);
-
-   switch (vertResult) {
-   case VERT_RESULT_HPOS:
-      return FRAG_ATTRIB_WPOS;
-   case VERT_RESULT_COL0:
-      return FRAG_ATTRIB_COL0;
-   case VERT_RESULT_COL1:
-      return FRAG_ATTRIB_COL1;
-   case VERT_RESULT_FOGC:
-      return FRAG_ATTRIB_FOGC;
-   default:
-      /* Back-face colors, edge flags, etc */
-      return -1;
-   }
-}
-
-
-/**
- * Find a translated vertex program that corresponds to stvp and
- * has outputs matched to stfp's inputs.
- * This performs vertex and fragment translation (to TGSI) when needed.
- */
-static struct translated_vertex_program *
-find_translated_vp(struct st_context *st,
-                   struct st_vertex_program *stvp,
-                   struct st_fragment_program *stfp)
-{
-   static const GLuint UNUSED = ~0;
-   struct translated_vertex_program *xvp;
    const GLbitfield fragInputsRead = stfp->Base.Base.InputsRead;
 
-   /*
-    * Translate fragment program if needed.
-    */
    if (!stfp->state.tokens) {
       GLuint inAttr, numIn = 0;
 
@@ -141,7 +77,7 @@
             numIn++;
          }
          else {
-            stfp->input_to_slot[inAttr] = UNUSED;
+            stfp->input_to_slot[inAttr] = -1;
          }
       }
 
@@ -151,170 +87,74 @@
 
       st_translate_fragment_program(st, stfp, stfp->input_to_slot);
    }
+}
 
 
+
+/**
+ * Find a translated vertex program that corresponds to stvp and
+ * has outputs matched to stfp's inputs.
+ * This performs vertex and fragment translation (to TGSI) when needed.
+ */
+static struct st_vp_varient *
+find_translated_vp(struct st_context *st,
+                   struct st_vertex_program *stvp )
+{
+   struct st_vp_varient *vpv;
+   struct st_vp_varient_key key;
+
+   /* Nothing in our key yet.  This will change:
+    */
+   memset(&key, 0, sizeof key);
+
+   /* When this is true, we will add an extra input to the vertex
+    * shader translation (for edgeflags), an extra output with
+    * edgeflag semantics, and extend the vertex shader to pass through
+    * the input to the output.  We'll need to use similar logic to set
+    * up the extra vertex_element input for edgeflags.
+    * _NEW_POLYGON, ST_NEW_EDGEFLAGS_DATA
+    */
+   key.passthrough_edgeflags = (st->vertdata_edgeflags && (
+                                st->ctx->Polygon.FrontMode != GL_FILL ||
+                                st->ctx->Polygon.BackMode != GL_FILL));
+
+
+   /* Do we need to throw away old translations after a change in the
+    * GL program string?
+    */
+   if (stvp->serialNo != stvp->lastSerialNo) {
+      /* These may have changed if the program string changed.
+       */
+      st_prepare_vertex_program( st, stvp );
+
+      /* We are now up-to-date:
+       */
+      stvp->lastSerialNo = stvp->serialNo;
+   }
+   
    /* See if we've got a translated vertex program whose outputs match
     * the fragment program's inputs.
-    * XXX This could be a hash lookup, using InputsRead as the key.
     */
-   for (xvp = stfp->vertex_programs; xvp; xvp = xvp->next) {
-      if (xvp->master == stvp && xvp->frag_inputs == fragInputsRead) {
+   for (vpv = stvp->varients; vpv; vpv = vpv->next) {
+      if (memcmp(&vpv->key, &key, sizeof key) == 0) {
          break;
       }
    }
 
-   /* No?  Allocate translated vp object now */
-   if (!xvp) {
-      xvp = ST_CALLOC_STRUCT(translated_vertex_program);
-      xvp->frag_inputs = fragInputsRead;
-      xvp->master = stvp;
-
-      xvp->next = stfp->vertex_programs;
-      stfp->vertex_programs = xvp;
+   /* No?  Perform new translation here. */
+   if (!vpv) {
+      vpv = st_translate_vertex_program(st, stvp, &key);
+      if (!vpv)
+         return NULL;
+      
+      vpv->next = stvp->varients;
+      stvp->varients = vpv;
    }
 
-   /* See if we need to translate vertex program to TGSI form */
-   if (xvp->serialNo != stvp->serialNo) {
-      GLuint outAttr;
-      const GLbitfield outputsWritten = stvp->Base.Base.OutputsWritten;
-      GLuint numVpOuts = 0;
-      GLboolean emitPntSize = GL_FALSE, emitBFC0 = GL_FALSE, emitBFC1 = GL_FALSE;
-      GLbitfield usedGenerics = 0x0;
-      GLbitfield usedOutputSlots = 0x0;
-
-      /* Compute mapping of vertex program outputs to slots, which depends
-       * on the fragment program's input->slot mapping.
-       */
-      for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
-         /* set defaults: */
-         xvp->output_to_slot[outAttr] = UNUSED;
-         xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_COUNT;
-         xvp->output_to_semantic_index[outAttr] = 99;
-
-         if (outAttr == VERT_RESULT_HPOS) {
-            /* always put xformed position into slot zero */
-            GLuint slot = 0;
-            xvp->output_to_slot[VERT_RESULT_HPOS] = slot;
-            xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_POSITION;
-            xvp->output_to_semantic_index[outAttr] = 0;
-            numVpOuts++;
-            usedOutputSlots |= (1 << slot);
-         }
-         else if (outputsWritten & (1 << outAttr)) {
-            /* see if the frag prog wants this vert output */
-            GLint fpInAttrib = vp_out_to_fp_in(outAttr);
-            if (fpInAttrib >= 0) {
-               GLuint fpInSlot = stfp->input_to_slot[fpInAttrib];
-               if (fpInSlot != ~0) {
-                  /* match this vp output to the fp input */
-                  GLuint vpOutSlot = stfp->input_map[fpInSlot];
-                  xvp->output_to_slot[outAttr] = vpOutSlot;
-                  xvp->output_to_semantic_name[outAttr] = stfp->input_semantic_name[fpInSlot];
-                  xvp->output_to_semantic_index[outAttr] = stfp->input_semantic_index[fpInSlot];
-                  numVpOuts++;
-                  usedOutputSlots |= (1 << vpOutSlot);
-               }
-               else {
-#if 0 /*debug*/
-                  printf("VP output %d not used by FP\n", outAttr);
-#endif
-               }
-            }
-            else if (outAttr == VERT_RESULT_PSIZ)
-               emitPntSize = GL_TRUE;
-            else if (outAttr == VERT_RESULT_BFC0)
-               emitBFC0 = GL_TRUE;
-            else if (outAttr == VERT_RESULT_BFC1)
-               emitBFC1 = GL_TRUE;
-         }
-#if 0 /*debug*/
-         printf("assign vp output_to_slot[%d] = %d\n", outAttr, 
-                xvp->output_to_slot[outAttr]);
-#endif
-      }
-
-      /* must do these last */
-      if (emitPntSize) {
-         GLuint slot = numVpOuts++;
-         xvp->output_to_slot[VERT_RESULT_PSIZ] = slot;
-         xvp->output_to_semantic_name[VERT_RESULT_PSIZ] = TGSI_SEMANTIC_PSIZE;
-         xvp->output_to_semantic_index[VERT_RESULT_PSIZ] = 0;
-         usedOutputSlots |= (1 << slot);
-      }
-      if (emitBFC0) {
-         GLuint slot = numVpOuts++;
-         xvp->output_to_slot[VERT_RESULT_BFC0] = slot;
-         xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR;
-         xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 0;
-         usedOutputSlots |= (1 << slot);
-      }
-      if (emitBFC1) {
-         GLuint slot = numVpOuts++;
-         xvp->output_to_slot[VERT_RESULT_BFC1] = slot;
-         xvp->output_to_semantic_name[VERT_RESULT_BFC1] = TGSI_SEMANTIC_COLOR;
-         xvp->output_to_semantic_index[VERT_RESULT_BFC1] = 1;
-         usedOutputSlots |= (1 << slot);
-      }
-
-      /* build usedGenerics mask */
-      usedGenerics = 0x0;
-      for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
-         if (xvp->output_to_semantic_name[outAttr] == TGSI_SEMANTIC_GENERIC) {
-            usedGenerics |= (1 << xvp->output_to_semantic_index[outAttr]);
-         }
-      }
-
-      /* For each vertex program output that doesn't match up to a fragment
-       * program input, map the vertex program output to a free slot and
-       * free generic attribute.
-       */
-      for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
-         if (outputsWritten & (1 << outAttr)) {
-            if (xvp->output_to_slot[outAttr] == UNUSED) {
-               GLint freeGeneric = _mesa_ffs(~usedGenerics) - 1;
-               GLint freeSlot = _mesa_ffs(~usedOutputSlots) - 1;
-               usedGenerics |= (1 << freeGeneric);
-               usedOutputSlots |= (1 << freeSlot);
-               xvp->output_to_slot[outAttr] = freeSlot;
-               xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_GENERIC;
-               xvp->output_to_semantic_index[outAttr] = freeGeneric;
-            }
-         }
-
-#if 0 /*debug*/
-         printf("vp output_to_slot[%d] = %d\n", outAttr, 
-                xvp->output_to_slot[outAttr]);
-#endif
-      }
-
-      assert(stvp->Base.Base.NumInstructions > 1);
-
-      st_translate_vertex_program(st, stvp, xvp->output_to_slot,
-                                  xvp->output_to_semantic_name,
-                                  xvp->output_to_semantic_index);
-
-      xvp->vp = stvp;
-
-      /* translated VP is up to date now */
-      xvp->serialNo = stvp->serialNo;
-   }
-
-   return xvp;
+   return vpv;
 }
 
 
-void
-st_free_translated_vertex_programs(struct st_context *st,
-                                   struct translated_vertex_program *xvp)
-{
-   struct translated_vertex_program *next;
-
-   while (xvp) {
-      next = xvp->next;
-      _mesa_free(xvp);
-      xvp = next;
-   }
-}
 
 
 static void *
@@ -328,32 +168,19 @@
    return st->passthrough_fs;
 }
 
-
 static void
-update_linkage( struct st_context *st )
+update_fp( struct st_context *st )
 {
-   struct st_vertex_program *stvp;
    struct st_fragment_program *stfp;
-   struct translated_vertex_program *xvp;
-
-   /* find active shader and params -- Should be covered by
-    * ST_NEW_VERTEX_PROGRAM
-    */
-   assert(st->ctx->VertexProgram._Current);
-   stvp = st_vertex_program(st->ctx->VertexProgram._Current);
-   assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB);
 
    assert(st->ctx->FragmentProgram._Current);
    stfp = st_fragment_program(st->ctx->FragmentProgram._Current);
    assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB);
 
-   xvp = find_translated_vp(st, stvp, stfp);
+   translate_fp(st, stfp);
 
-   st_reference_vertprog(st, &st->vp, stvp);
    st_reference_fragprog(st, &st->fp, stfp);
 
-   cso_set_vertex_shader_handle(st->cso_context, stvp->driver_shader);
-
    if (st->missing_textures) {
       /* use a pass-through frag shader that uses no textures */
       void *fs = get_passthrough_fs(st);
@@ -362,16 +189,48 @@
    else {
       cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader);
    }
+}
 
-   st->vertex_result_to_slot = xvp->output_to_slot;
+const struct st_tracked_state st_update_fp = {
+   "st_update_fp",					/* name */
+   {							/* dirty */
+      0,						/* mesa */
+      ST_NEW_FRAGMENT_PROGRAM                           /* st */
+   },
+   update_fp  					/* update */
+};
+
+
+
+
+static void
+update_vp( struct st_context *st )
+{
+   struct st_vertex_program *stvp;
+
+   /* find active shader and params -- Should be covered by
+    * ST_NEW_VERTEX_PROGRAM
+    */
+   assert(st->ctx->VertexProgram._Current);
+   stvp = st_vertex_program(st->ctx->VertexProgram._Current);
+   assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB);
+
+   st->vp_varient = find_translated_vp(st, stvp);
+
+   st_reference_vertprog(st, &st->vp, stvp);
+
+   cso_set_vertex_shader_handle(st->cso_context, 
+                                st->vp_varient->driver_shader);
+
+   st->vertex_result_to_slot = stvp->result_to_output;
 }
 
 
-const struct st_tracked_state st_update_shader = {
-   "st_update_shader",					/* name */
+const struct st_tracked_state st_update_vp = {
+   "st_update_vp",					/* name */
    {							/* dirty */
-      0,						/* mesa */
-      ST_NEW_VERTEX_PROGRAM | ST_NEW_FRAGMENT_PROGRAM	/* st */
+      _NEW_POLYGON,					/* mesa */
+      ST_NEW_VERTEX_PROGRAM | ST_NEW_EDGEFLAGS_DATA	/* st */
    },
-   update_linkage					/* update */
+   update_vp					/* update */
 };
diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
index 4d4f97d..0b68447 100644
--- a/src/mesa/state_tracker/st_atom_texture.c
+++ b/src/mesa/state_tracker/st_atom_texture.c
@@ -32,6 +32,8 @@
   */
  
 
+#include "main/macros.h"
+
 #include "st_context.h"
 #include "st_atom.h"
 #include "st_texture.h"
@@ -99,6 +101,12 @@
    cso_set_sampler_textures(st->cso_context,
                             st->state.num_textures,
                             st->state.sampler_texture);
+   if (st->ctx->Const.MaxVertexTextureImageUnits > 0) {
+      cso_set_vertex_sampler_textures(st->cso_context,
+                                      MIN2(st->state.num_textures,
+                                           st->ctx->Const.MaxVertexTextureImageUnits),
+                                      st->state.sampler_texture);
+   }
 }
 
 
diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c
index a6b9765..da7b97d 100644
--- a/src/mesa/state_tracker/st_cb_accum.c
+++ b/src/mesa/state_tracker/st_cb_accum.c
@@ -229,7 +229,7 @@
 {
    struct pipe_context *pipe = ctx->st->pipe;
    struct pipe_screen *screen = pipe->screen;
-   const GLubyte *colormask = ctx->Color.ColorMask;
+   const GLubyte *colormask = ctx->Color.ColorMask[0];
    enum pipe_transfer_usage usage;
    struct pipe_transfer *color_trans;
    size_t stride = acc_strb->stride;
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index a22fa68..1bdeacc 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -169,11 +169,6 @@
    stfp = (struct st_fragment_program *) p;
    stfp->Base.UsesKill = GL_TRUE;
 
-   /* No need to send this incomplete program down to hardware:
-    *
-    * st_translate_fragment_program(ctx->st, stfp, NULL);
-    */
-
    return stfp;
 }
 
@@ -526,7 +521,7 @@
    struct pipe_screen *screen = pipe->screen;
    struct bitmap_cache *cache = st->bitmap.cache;
 
-   //memset(cache->buffer, 0xff, sizeof(cache->buffer));
+   /*memset(cache->buffer, 0xff, sizeof(cache->buffer));*/
    cache->empty = GL_TRUE;
 
    cache->xmin = 1000000;
diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c
index 8e09d0b..0102d8a 100644
--- a/src/mesa/state_tracker/st_cb_bufferobjects.c
+++ b/src/mesa/state_tracker/st_cb_bufferobjects.c
@@ -103,6 +103,17 @@
    ASSERT(size >= 0);
    ASSERT(offset + size <= obj->Size);
 
+   if (!size)
+      return;
+
+   /*
+    * According to ARB_vertex_buffer_object specification, if data is null,
+    * then the contents of the buffer object's data store is undefined. We just
+    * ignore, and leave it unchanged.
+    */
+   if (!data)
+      return;
+
    st_cond_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer,
 				   offset, size, data);
 }
@@ -125,6 +136,9 @@
    ASSERT(size >= 0);
    ASSERT(offset + size <= obj->Size);
 
+   if (!size)
+      return;
+
    st_cond_flush_pipe_buffer_read(st_context(ctx), st_obj->buffer,
 				  offset, size, data);
 }
@@ -170,15 +184,19 @@
 
    pipe_buffer_reference( &st_obj->buffer, NULL );
 
-   st_obj->buffer = pipe_buffer_create( pipe->screen, 32, buffer_usage, size );
+   if (size != 0) {
+      st_obj->buffer = pipe_buffer_create(pipe->screen, 32, buffer_usage, size);
 
-   if (!st_obj->buffer) {
-      return GL_FALSE;
+      if (!st_obj->buffer) {
+         return GL_FALSE;
+      }
+
+      if (data)
+         st_no_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer, 0,
+				       size, data);
+      return GL_TRUE;
    }
 
-   if (data)
-      st_no_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer, 0,
-				    size, data);
    return GL_TRUE;
 }
 
@@ -219,6 +237,13 @@
 
 
 /**
+ * Dummy data whose's pointer is used for zero length ranges.
+ */
+static long
+st_bufferobj_zero_length_range = 0;
+
+
+/**
  * Called via glMapBufferRange().
  */
 static void *
@@ -239,6 +264,9 @@
    if (access & GL_MAP_FLUSH_EXPLICIT_BIT)
       flags |= PIPE_BUFFER_USAGE_FLUSH_EXPLICIT;
    
+   if (access & GL_MAP_UNSYNCHRONIZED_BIT)
+      flags |= PIPE_BUFFER_USAGE_UNSYNCHRONIZED;
+
    /* ... other flags ...
     */
 
@@ -250,14 +278,26 @@
    assert(offset < obj->Size);
    assert(offset + length <= obj->Size);
 
-   obj->Pointer = pipe_buffer_map_range(pipe->screen, st_obj->buffer, offset, length, flags);
+   /*
+    * We go out of way here to hide the degenerate yet valid case of zero
+    * length range from the pipe driver.
+    */
+   if (!length) {
+      obj->Pointer = &st_bufferobj_zero_length_range;
+   }
+   else {
+      obj->Pointer = pipe_buffer_map_range(pipe->screen, st_obj->buffer, offset, length, flags);
+      if (obj->Pointer) {
+         obj->Pointer = (ubyte *) obj->Pointer + offset;
+      }
+   }
+   
    if (obj->Pointer) {
-      obj->Pointer = (ubyte *) obj->Pointer + offset;
       obj->Offset = offset;
       obj->Length = length;
       obj->AccessFlags = access;
    }
-   
+
    return obj->Pointer;
 }
 
@@ -275,6 +315,9 @@
    assert(length >= 0);
    assert(offset + length <= obj->Length);
    
+   if (!length)
+      return;
+
    pipe_buffer_flush_mapped_range(pipe->screen, st_obj->buffer, 
                                   obj->Offset + offset, length);
 }
@@ -289,7 +332,9 @@
    struct pipe_context *pipe = st_context(ctx)->pipe;
    struct st_buffer_object *st_obj = st_buffer_object(obj);
 
-   pipe_buffer_unmap(pipe->screen, st_obj->buffer);
+   if(obj->Length)
+      pipe_buffer_unmap(pipe->screen, st_obj->buffer);
+
    obj->Pointer = NULL;
    obj->Offset = 0;
    obj->Length = 0;
@@ -312,6 +357,9 @@
    struct st_buffer_object *dstObj = st_buffer_object(dst);
    ubyte *srcPtr, *dstPtr;
 
+   if(!size)
+      return;
+
    /* buffer should not already be mapped */
    assert(!src->Pointer);
    assert(!dst->Pointer);
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index e83b6c9..192d765 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -52,6 +52,7 @@
 #include "pipe/p_inlines.h"
 #include "pipe/p_state.h"
 #include "pipe/p_defines.h"
+#include "util/u_format.h"
 #include "util/u_pack_color.h"
 #include "util/u_simple_shaders.h"
 #include "util/u_draw_quad.h"
@@ -231,13 +232,13 @@
       blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
       blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
       if (color) {
-         if (ctx->Color.ColorMask[0])
+         if (ctx->Color.ColorMask[0][0])
             blend.colormask |= PIPE_MASK_R;
-         if (ctx->Color.ColorMask[1])
+         if (ctx->Color.ColorMask[0][1])
             blend.colormask |= PIPE_MASK_G;
-         if (ctx->Color.ColorMask[2])
+         if (ctx->Color.ColorMask[0][2])
             blend.colormask |= PIPE_MASK_B;
-         if (ctx->Color.ColorMask[3])
+         if (ctx->Color.ColorMask[0][3])
             blend.colormask |= PIPE_MASK_A;
          if (st->ctx->Color.DitherFlag)
             blend.dither = 1;
@@ -299,10 +300,10 @@
         ctx->Scissor.Height < rb->Height))
       return TRUE;
 
-   if (!ctx->Color.ColorMask[0] ||
-       !ctx->Color.ColorMask[1] ||
-       !ctx->Color.ColorMask[2] ||
-       !ctx->Color.ColorMask[3])
+   if (!ctx->Color.ColorMask[0][0] ||
+       !ctx->Color.ColorMask[0][1] ||
+       !ctx->Color.ColorMask[0][2] ||
+       !ctx->Color.ColorMask[0][3])
       return TRUE;
 
    return FALSE;
@@ -341,7 +342,7 @@
 check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
 {
    const struct st_renderbuffer *strb = st_renderbuffer(rb);
-   const GLboolean isDS = pf_is_depth_and_stencil(strb->surface->format);
+   const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format);
 
    if (ctx->Scissor.Enabled &&
        (ctx->Scissor.X != 0 ||
@@ -365,7 +366,7 @@
 check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
 {
    const struct st_renderbuffer *strb = st_renderbuffer(rb);
-   const GLboolean isDS = pf_is_depth_and_stencil(strb->surface->format);
+   const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format);
    const GLuint stencilMax = 0xff;
    const GLboolean maskStencil
       = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
diff --git a/src/mesa/state_tracker/st_cb_condrender.c b/src/mesa/state_tracker/st_cb_condrender.c
new file mode 100644
index 0000000..780b40c
--- /dev/null
+++ b/src/mesa/state_tracker/st_cb_condrender.c
@@ -0,0 +1,95 @@
+/**************************************************************************
+ * 
+ * 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 THE AUTHORS 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.
+ * 
+ **************************************************************************/
+
+
+/**
+ * glBegin/EndCondtionalRender functions
+ *
+ * \author Brian Paul
+ */
+
+
+#include "main/imports.h"
+#include "main/context.h"
+
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "st_context.h"
+#include "st_cb_queryobj.h"
+#include "st_cb_condrender.h"
+
+
+/**
+ * Called via ctx->Driver.BeginConditionalRender()
+ */
+static void
+st_BeginConditionalRender(GLcontext *ctx, struct gl_query_object *q,
+                          GLenum mode)
+{
+   struct st_query_object *stq = st_query_object(q);
+   struct pipe_context *pipe = ctx->st->pipe;
+   uint m;
+
+   switch (mode) {
+   case GL_QUERY_WAIT:
+      m = PIPE_RENDER_COND_WAIT;
+      break;
+   case GL_QUERY_NO_WAIT:
+      m = PIPE_RENDER_COND_NO_WAIT;
+      break;
+   case GL_QUERY_BY_REGION_WAIT:
+      m = PIPE_RENDER_COND_BY_REGION_WAIT;
+      break;
+   case GL_QUERY_BY_REGION_NO_WAIT:
+      m = PIPE_RENDER_COND_BY_REGION_NO_WAIT;
+      break;
+   default:
+      assert(0 && "bad mode in st_BeginConditionalRender");
+   }
+
+   pipe->render_condition(pipe, stq->pq, m);
+}
+
+
+/**
+ * Called via ctx->Driver.BeginConditionalRender()
+ */
+static void
+st_EndConditionalRender(GLcontext *ctx, struct gl_query_object *q)
+{
+   struct pipe_context *pipe = ctx->st->pipe;
+   (void) q;
+   pipe->render_condition(pipe, NULL, 0);
+}
+
+
+
+void st_init_cond_render_functions(struct dd_function_table *functions)
+{
+   functions->BeginConditionalRender = st_BeginConditionalRender;
+   functions->EndConditionalRender = st_EndConditionalRender;
+}
diff --git a/src/mesa/state_tracker/st_cb_get.h b/src/mesa/state_tracker/st_cb_condrender.h
similarity index 83%
copy from src/mesa/state_tracker/st_cb_get.h
copy to src/mesa/state_tracker/st_cb_condrender.h
index 8e9f3e9..891f1cb 100644
--- a/src/mesa/state_tracker/st_cb_get.h
+++ b/src/mesa/state_tracker/st_cb_condrender.h
@@ -1,6 +1,6 @@
 /**************************************************************************
  * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009 VMware, Inc.
  * All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -18,20 +18,18 @@
  * 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 THE AUTHORS 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.
  * 
  **************************************************************************/
 
-
-#ifndef ST_CB_GET_H
-#define ST_CB_GET_H
+#ifndef ST_CB_CONDRENDER_H
+#define ST_CB_CONDRENDER_H
 
 
-extern void
-st_init_get_functions(struct dd_function_table *functions);
+extern void st_init_cond_render_functions(struct dd_function_table *functions);
 
 
 #endif
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 1d33e81..7c66426 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -60,8 +60,10 @@
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
+#include "tgsi/tgsi_ureg.h"
 #include "util/u_tile.h"
 #include "util/u_draw_quad.h"
+#include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_rect.h"
 #include "shader/prog_instruction.h"
@@ -236,78 +238,41 @@
  * Create a simple vertex shader that just passes through the
  * vertex position and texcoord (and optionally, color).
  */
-static struct st_vertex_program *
-st_make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor)
+static void *
+st_make_passthrough_vertex_shader(struct st_context *st, 
+                                  GLboolean passColor)
 {
-   GLcontext *ctx = st->ctx;
-   struct st_vertex_program *stvp;
-   struct gl_program *p;
-   GLuint ic = 0;
+   if (!st->drawpix.vert_shaders[passColor]) {
+      struct ureg_program *ureg = 
+         ureg_create( TGSI_PROCESSOR_VERTEX );
 
-   if (st->drawpix.vert_shaders[passColor])
-      return st->drawpix.vert_shaders[passColor];
+      if (ureg == NULL)
+         return NULL;
 
-   /*
-    * Create shader now
-    */
-   p = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
-   if (!p)
-      return NULL;
+      /* MOV result.pos, vertex.pos; */
+      ureg_MOV(ureg, 
+               ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ),
+               ureg_DECL_vs_input( ureg, 0 ));
+      
+      /* MOV result.texcoord0, vertex.texcoord0; */
+      ureg_MOV(ureg, 
+               ureg_DECL_output( ureg, TGSI_SEMANTIC_GENERIC, 0 ),
+               ureg_DECL_vs_input( ureg, 1 ));
+      
+      if (passColor) {
+         /* MOV result.color0, vertex.color0; */
+         ureg_MOV(ureg, 
+                  ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ),
+                  ureg_DECL_vs_input( ureg, 2 ));
+      }
 
-   if (passColor)
-      p->NumInstructions = 4;
-   else
-      p->NumInstructions = 3;
-
-   p->Instructions = _mesa_alloc_instructions(p->NumInstructions);
-   if (!p->Instructions) {
-      ctx->Driver.DeleteProgram(ctx, p);
-      return NULL;
-   }
-   _mesa_init_instructions(p->Instructions, p->NumInstructions);
-   /* MOV result.pos, vertex.pos; */
-   p->Instructions[0].Opcode = OPCODE_MOV;
-   p->Instructions[0].DstReg.File = PROGRAM_OUTPUT;
-   p->Instructions[0].DstReg.Index = VERT_RESULT_HPOS;
-   p->Instructions[0].SrcReg[0].File = PROGRAM_INPUT;
-   p->Instructions[0].SrcReg[0].Index = VERT_ATTRIB_POS;
-   /* MOV result.texcoord0, vertex.texcoord0; */
-   p->Instructions[1].Opcode = OPCODE_MOV;
-   p->Instructions[1].DstReg.File = PROGRAM_OUTPUT;
-   p->Instructions[1].DstReg.Index = VERT_RESULT_TEX0;
-   p->Instructions[1].SrcReg[0].File = PROGRAM_INPUT;
-   p->Instructions[1].SrcReg[0].Index = VERT_ATTRIB_TEX0;
-   ic = 2;
-   if (passColor) {
-      /* MOV result.color0, vertex.color0; */
-      p->Instructions[ic].Opcode = OPCODE_MOV;
-      p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT;
-      p->Instructions[ic].DstReg.Index = VERT_RESULT_COL0;
-      p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
-      p->Instructions[ic].SrcReg[0].Index = VERT_ATTRIB_COLOR0;
-      ic++;
+      ureg_END( ureg );
+      
+      st->drawpix.vert_shaders[passColor] = 
+         ureg_create_shader_and_destroy( ureg, st->pipe );
    }
 
-   /* END; */
-   p->Instructions[ic].Opcode = OPCODE_END;
-   ic++;
-
-   assert(ic == p->NumInstructions);
-
-   p->InputsRead = VERT_BIT_POS | VERT_BIT_TEX0;
-   p->OutputsWritten = ((1 << VERT_RESULT_TEX0) |
-                        (1 << VERT_RESULT_HPOS));
-   if (passColor) {
-      p->InputsRead |= VERT_BIT_COLOR0;
-      p->OutputsWritten |= (1 << VERT_RESULT_COL0);
-   }
-
-   stvp = (struct st_vertex_program *) p;
-   st_translate_vertex_program(st, stvp, NULL, NULL, NULL);
-
-   st->drawpix.vert_shaders[passColor] = stvp;
-
-   return stvp;
+   return st->drawpix.vert_shaders[passColor];
 }
 
 
@@ -539,8 +504,8 @@
                    GLsizei width, GLsizei height,
                    GLfloat zoomX, GLfloat zoomY,
                    struct pipe_texture *pt,
-                   struct st_vertex_program *stvp,
-                   struct st_fragment_program *stfp,
+                   void *driver_vp,
+                   void *driver_fp,
                    const GLfloat *color,
                    GLboolean invertTex)
 {
@@ -575,10 +540,10 @@
    }
 
    /* fragment shader state: TEX lookup program */
-   cso_set_fragment_shader_handle(cso, stfp->driver_shader);
+   cso_set_fragment_shader_handle(cso, driver_fp);
 
    /* vertex shader state: position + texcoord pass-through */
-   cso_set_vertex_shader_handle(cso, stvp->driver_shader);
+   cso_set_vertex_shader_handle(cso, driver_vp);
 
 
    /* texture sampling state: */
@@ -621,10 +586,10 @@
       struct pipe_texture *textures[2];
       textures[0] = pt;
       textures[1] = st->pixel_xfer.pixelmap_texture;
-      pipe->set_sampler_textures(pipe, 2, textures);
+      pipe->set_fragment_sampler_textures(pipe, 2, textures);
    }
    else {
-      pipe->set_sampler_textures(pipe, 1, &pt);
+      pipe->set_fragment_sampler_textures(pipe, 1, &pt);
    }
 
    /* Compute window coords (y=0=bottom) with pixel zoom.
@@ -637,8 +602,8 @@
    y1 = y + height * ctx->Pixel.ZoomY;
 
    draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex,
-	     (GLfloat) width / pt->width[0],
-	     (GLfloat) height / pt->height[0]);
+	     (GLfloat) width / pt->width0,
+	     (GLfloat) height / pt->height0);
 
    /* restore state */
    cso_restore_rasterizer(cso);
@@ -683,7 +648,7 @@
    }
 
    if(format != GL_DEPTH_STENCIL && 
-      pf_get_component_bits( strb->format, PIPE_FORMAT_COMP_Z ) != 0)
+      util_format_get_component_bits(strb->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0)
       usage = PIPE_TRANSFER_READ_WRITE;
    else
       usage = PIPE_TRANSFER_WRITE;
@@ -737,7 +702,7 @@
             }
 
             /* now pack the stencil (and Z) values in the dest format */
-            switch (pt->format) {
+            switch (pt->texture->format) {
             case PIPE_FORMAT_S8_UNORM:
                {
                   ubyte *dest = stmap + spanY * pt->stride + spanX;
@@ -806,7 +771,7 @@
               const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels)
 {
    struct st_fragment_program *stfp;
-   struct st_vertex_program *stvp;
+   void *driver_vp;
    struct st_context *st = st_context(ctx);
    struct pipe_surface *ps;
    const GLfloat *color;
@@ -826,13 +791,13 @@
    if (format == GL_DEPTH_COMPONENT) {
       ps = st->state.framebuffer.zsbuf;
       stfp = make_fragment_shader_z(st);
-      stvp = st_make_passthrough_vertex_shader(st, GL_TRUE);
+      driver_vp = st_make_passthrough_vertex_shader(st, GL_TRUE);
       color = ctx->Current.RasterColor;
    }
    else {
       ps = st->state.framebuffer.cbufs[0];
       stfp = combined_drawpix_fragment_program(ctx);
-      stvp = st_make_passthrough_vertex_shader(st, GL_FALSE);
+      driver_vp = st_make_passthrough_vertex_shader(st, GL_FALSE);
       color = NULL;
    }
 
@@ -843,7 +808,10 @@
       if (pt) {
          draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
                             width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
-                            pt, stvp, stfp, color, GL_FALSE);
+                            pt, 
+                            driver_vp, 
+                            stfp->driver_shader,
+                            color, GL_FALSE);
          pipe_texture_reference(&pt, NULL);
       }
    }
@@ -875,7 +843,7 @@
                           GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
                           &ctx->DefaultPacking, buffer);
 
-   if(pf_get_component_bits( rbDraw->format, PIPE_FORMAT_COMP_Z ) != 0)
+   if(util_format_get_component_bits(rbDraw->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0)
       usage = PIPE_TRANSFER_READ_WRITE;
    else
       usage = PIPE_TRANSFER_WRITE;
@@ -889,8 +857,8 @@
 					   usage, dstx, dsty,
 					   width, height);
 
-   assert(ptDraw->block.width == 1);
-   assert(ptDraw->block.height == 1);
+   assert(util_format_get_blockwidth(ptDraw->texture->format) == 1);
+   assert(util_format_get_blockheight(ptDraw->texture->format) == 1);
 
    /* map the stencil buffer */
    drawMap = screen->transfer_map(screen, ptDraw);
@@ -911,7 +879,7 @@
       dst = drawMap + y * ptDraw->stride;
       src = buffer + i * width;
 
-      switch (ptDraw->format) {
+      switch (ptDraw->texture->format) {
       case PIPE_FORMAT_S8Z24_UNORM:
          {
             uint *dst4 = (uint *) dst;
@@ -960,7 +928,7 @@
    struct pipe_context *pipe = st->pipe;
    struct pipe_screen *screen = pipe->screen;
    struct st_renderbuffer *rbRead;
-   struct st_vertex_program *stvp;
+   void *driver_vp;
    struct st_fragment_program *stfp;
    struct pipe_texture *pt;
    GLfloat *color;
@@ -1009,14 +977,14 @@
       rbRead = st_get_color_read_renderbuffer(ctx);
       color = NULL;
       stfp = combined_drawpix_fragment_program(ctx);
-      stvp = st_make_passthrough_vertex_shader(st, GL_FALSE);
+      driver_vp = st_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);
-      stvp = st_make_passthrough_vertex_shader(st, GL_TRUE);
+      driver_vp = st_make_passthrough_vertex_shader(st, GL_TRUE);
    }
 
    srcFormat = rbRead->texture->format;
@@ -1116,7 +1084,7 @@
       if (ST_DEBUG & DEBUG_FALLBACK)
          debug_printf("%s: fallback processing\n", __FUNCTION__);
 
-      if (type == GL_DEPTH && pf_is_depth_and_stencil(pt->format))
+      if (type == GL_DEPTH && util_format_is_depth_and_stencil(pt->format))
          transfer_usage = PIPE_TRANSFER_READ_WRITE;
       else
          transfer_usage = PIPE_TRANSFER_WRITE;
@@ -1148,7 +1116,10 @@
    /* draw textured quad */
    draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
                       width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
-                      pt, stvp, stfp, color, GL_TRUE);
+                      pt, 
+                      driver_vp, 
+                      stfp->driver_shader,
+                      color, GL_TRUE);
 
    pipe_texture_reference(&pt, NULL);
 }
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index 65ce12c..45ce34a 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -49,6 +49,7 @@
 #include "st_public.h"
 #include "st_texture.h"
 
+#include "util/u_format.h"
 #include "util/u_rect.h"
 
 
@@ -98,16 +99,14 @@
    strb->defined = GL_FALSE;  /* undefined contents now */
 
    if(strb->software) {
-      struct pipe_format_block block;
       size_t size;
       
       _mesa_free(strb->data);
 
       assert(strb->format != PIPE_FORMAT_NONE);
-      pf_get_block(strb->format, &block);
       
-      strb->stride = pf_get_stride(&block, width);
-      size = pf_get_2d_size(&block, strb->stride, height);
+      strb->stride = util_format_get_stride(strb->format, width);
+      size = util_format_get_2d_size(strb->format, strb->stride, height);
       
       strb->data = _mesa_malloc(size);
       
@@ -127,13 +126,12 @@
       memset(&template, 0, sizeof(template));
       template.target = PIPE_TEXTURE_2D;
       template.format = format;
-      pf_get_block(format, &template.block);
-      template.width[0] = width;
-      template.height[0] = height;
-      template.depth[0] = 1;
+      template.width0 = width;
+      template.height0 = height;
+      template.depth0 = 1;
       template.last_level = 0;
       template.nr_samples = rb->NumSamples;
-      if (pf_is_depth_stencil(format)) {
+      if (util_format_is_depth_or_stencil(format)) {
          template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
       }
       else {
@@ -376,7 +374,7 @@
    rb->_BaseFormat = texImage->_BaseFormat;
    /*printf("***** render to texture level %d: %d x %d\n", att->TextureLevel, rb->Width, rb->Height);*/
 
-   /*printf("***** pipe texture %d x %d\n", pt->width[0], pt->height[0]);*/
+   /*printf("***** pipe texture %d x %d\n", pt->width0, pt->height0);*/
 
    pipe_texture_reference( &strb->texture, pt );
 
diff --git a/src/mesa/state_tracker/st_cb_get.c b/src/mesa/state_tracker/st_cb_get.c
deleted file mode 100644
index e7d7f03..0000000
--- a/src/mesa/state_tracker/st_cb_get.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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.
- * 
- **************************************************************************/
-
-
-/**
- * glGet functions
- *
- * \author Brian Paul
- */
-
-#include "main/imports.h"
-#include "main/context.h"
-
-#include "pipe/p_defines.h"
-
-#include "st_cb_fbo.h"
-#include "st_cb_get.h"
-
-
-
-/**
- * Examine the current color read buffer format to determine
- * which GL pixel format/type combo is the best match.
- */
-static void
-get_preferred_read_format_type(GLcontext *ctx, GLint *format, GLint *type)
-{
-   struct gl_framebuffer *fb = ctx->ReadBuffer;
-   struct st_renderbuffer *strb = st_renderbuffer(fb->_ColorReadBuffer);
-
-   /* defaults */
-   *format = ctx->Const.ColorReadFormat;
-   *type = ctx->Const.ColorReadType;
-
-   if (strb) {
-      /* XXX could add more cases here... */
-      if (strb->format == PIPE_FORMAT_A8R8G8B8_UNORM) {
-         *format = GL_BGRA;
-         if (_mesa_little_endian())
-            *type = GL_UNSIGNED_INT_8_8_8_8_REV;
-         else
-            *type = GL_UNSIGNED_INT_8_8_8_8;
-      }
-   }
-}
-
-
-/**
- * We only intercept the OES preferred ReadPixels format/type.
- * Everything else goes to the default _mesa_GetIntegerv.
- */
-static GLboolean 
-st_GetIntegerv(GLcontext *ctx, GLenum pname, GLint *params)
-{
-   GLint dummy;
-
-   switch (pname) {
-   case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
-      get_preferred_read_format_type(ctx, &dummy, params);
-      return GL_TRUE;
-   case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
-      get_preferred_read_format_type(ctx, params, &dummy);
-      return GL_TRUE;
-   default:
-      return GL_FALSE;
-   }
-}
-
-
-void st_init_get_functions(struct dd_function_table *functions)
-{
-   functions->GetIntegerv = st_GetIntegerv;
-}
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index b2d5c39..8c276f8 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -138,24 +138,7 @@
    case GL_VERTEX_PROGRAM_ARB:
       {
          struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
-
-         if (stvp->driver_shader) {
-            cso_delete_vertex_shader(st->cso_context, stvp->driver_shader);
-            stvp->driver_shader = NULL;
-         }
-
-         if (stvp->draw_shader) {
-#if FEATURE_feedback || FEATURE_drawpix
-            /* this would only have been allocated for the RasterPos path */
-            draw_delete_vertex_shader(st->draw, stvp->draw_shader);
-            stvp->draw_shader = NULL;
-#endif
-         }
-
-         if (stvp->state.tokens) {
-            st_free_tokens(stvp->state.tokens);
-            stvp->state.tokens = NULL;
-         }
+         st_vp_release_varients( st, stvp );
       }
       break;
    case GL_FRAGMENT_PROGRAM_ARB:
@@ -177,8 +160,6 @@
             _mesa_reference_program(ctx, &prg, NULL);
             stfp->bitmap_program = NULL;
          }
-
-         st_free_translated_vertex_programs(st, stfp->vertex_programs);
       }
       break;
    default:
@@ -219,8 +200,6 @@
          stfp->state.tokens = NULL;
       }
 
-      stfp->param_state = stfp->Base.Base.Parameters->StateFlags;
-
       if (st->fp == stfp)
 	 st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
    }
@@ -229,25 +208,7 @@
 
       stvp->serialNo++;
 
-      if (stvp->driver_shader) {
-         cso_delete_vertex_shader(st->cso_context, stvp->driver_shader);
-         stvp->driver_shader = NULL;
-      }
-
-      if (stvp->draw_shader) {
-#if FEATURE_feedback || FEATURE_drawpix
-         /* this would only have been allocated for the RasterPos path */
-         draw_delete_vertex_shader(st->draw, stvp->draw_shader);
-         stvp->draw_shader = NULL;
-#endif
-      }
-
-      if (stvp->state.tokens) {
-         st_free_tokens(stvp->state.tokens);
-         stvp->state.tokens = NULL;
-      }
-
-      stvp->param_state = stvp->Base.Base.Parameters->StateFlags;
+      st_vp_release_varients( st, stvp );
 
       if (st->vp == stvp)
 	 st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
diff --git a/src/mesa/state_tracker/st_cb_queryobj.c b/src/mesa/state_tracker/st_cb_queryobj.c
index dcf4c38..10629e9 100644
--- a/src/mesa/state_tracker/st_cb_queryobj.c
+++ b/src/mesa/state_tracker/st_cb_queryobj.c
@@ -44,23 +44,6 @@
 #include "st_public.h"
 
 
-struct st_query_object
-{
-   struct gl_query_object base;
-   struct pipe_query *pq;
-};
-
-
-/**
- * Cast wrapper
- */
-static struct st_query_object *
-st_query_object(struct gl_query_object *q)
-{
-   return (struct st_query_object *) q;
-}
-
-
 static struct gl_query_object *
 st_NewQueryObject(GLcontext *ctx, GLuint id)
 {
diff --git a/src/mesa/state_tracker/st_cb_queryobj.h b/src/mesa/state_tracker/st_cb_queryobj.h
index 9220a21..fa256b7 100644
--- a/src/mesa/state_tracker/st_cb_queryobj.h
+++ b/src/mesa/state_tracker/st_cb_queryobj.h
@@ -29,6 +29,27 @@
 #define ST_CB_QUERYOBJ_H
 
 
+/**
+ * Subclass of gl_query_object
+ */
+struct st_query_object
+{
+   struct gl_query_object base;
+   struct pipe_query *pq;
+};
+
+
+/**
+ * Cast wrapper
+ */
+static INLINE struct st_query_object *
+st_query_object(struct gl_query_object *q)
+{
+   return (struct st_query_object *) q;
+}
+
+
+
 extern void
 st_init_query_functions(struct dd_function_table *functions);
 
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index 772bb3b..6fa7bb6 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -103,7 +103,7 @@
       }
 
       /* get stencil (and Z) values */
-      switch (pt->format) {
+      switch (pt->texture->format) {
       case PIPE_FORMAT_S8_UNORM:
          {
             const ubyte *src = stmap + srcY * pt->stride;
@@ -243,7 +243,7 @@
       GLint row, col, dy, dstStride;
 
       if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
-         y = strb->texture->height[0] - y - height;
+         y = strb->texture->height0 - y - height;
       }
 
       trans = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture,
@@ -431,8 +431,8 @@
       const GLint dstStride = _mesa_image_row_stride(&clippedPacking, width,
                                                      format, type);
 
-      if (trans->format == PIPE_FORMAT_S8Z24_UNORM ||
-          trans->format == PIPE_FORMAT_X8Z24_UNORM) {
+      if (trans->texture->format == PIPE_FORMAT_S8Z24_UNORM ||
+          trans->texture->format == PIPE_FORMAT_X8Z24_UNORM) {
          if (format == GL_DEPTH_COMPONENT) {
             for (i = 0; i < height; i++) {
                GLuint ztemp[MAX_WIDTH];
@@ -463,8 +463,8 @@
             }
          }
       }
-      else if (trans->format == PIPE_FORMAT_Z24S8_UNORM ||
-               trans->format == PIPE_FORMAT_Z24X8_UNORM) {
+      else if (trans->texture->format == PIPE_FORMAT_Z24S8_UNORM ||
+               trans->texture->format == PIPE_FORMAT_Z24X8_UNORM) {
          if (format == GL_DEPTH_COMPONENT) {
             for (i = 0; i < height; i++) {
                GLuint ztemp[MAX_WIDTH];
@@ -490,7 +490,7 @@
             }
          }
       }
-      else if (trans->format == PIPE_FORMAT_Z16_UNORM) {
+      else if (trans->texture->format == PIPE_FORMAT_Z16_UNORM) {
          for (i = 0; i < height; i++) {
             GLushort ztemp[MAX_WIDTH];
             GLfloat zfloat[MAX_WIDTH];
@@ -505,7 +505,7 @@
             dst += dstStride;
          }
       }
-      else if (trans->format == PIPE_FORMAT_Z32_UNORM) {
+      else if (trans->texture->format == PIPE_FORMAT_Z32_UNORM) {
          for (i = 0; i < height; i++) {
             GLuint ztemp[MAX_WIDTH];
             GLfloat zfloat[MAX_WIDTH];
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 9186db7..f01053c 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -62,6 +62,7 @@
 #include "pipe/p_shader_tokens.h"
 #include "util/u_tile.h"
 #include "util/u_blit.h"
+#include "util/u_format.h"
 #include "util/u_surface.h"
 #include "util/u_math.h"
 
@@ -93,51 +94,6 @@
 }
 
 
-/**
- * Return nominal bytes per texel for a compressed format, 0 for non-compressed
- * format.
- */
-static GLuint
-compressed_num_bytes(gl_format format)
-{
-   switch (format) {
-#if FEATURE_texture_fxt1
-   case MESA_FORMAT_RGB_FXT1:
-   case MESA_FORMAT_RGBA_FXT1:
-#endif
-#if FEATURE_texture_s3tc
-   case MESA_FORMAT_RGB_DXT1:
-   case MESA_FORMAT_RGBA_DXT1:
-      return 2;
-   case MESA_FORMAT_RGBA_DXT3:
-   case MESA_FORMAT_RGBA_DXT5:
-      return 4;
-#endif
-   default:
-      return 0;
-   }
-}
-
-
-static GLboolean
-is_compressed_mesa_format(gl_format format)
-{
-   switch (format) {
-   case MESA_FORMAT_RGB_DXT1:
-   case MESA_FORMAT_RGBA_DXT1:
-   case MESA_FORMAT_RGBA_DXT3:
-   case MESA_FORMAT_RGBA_DXT5:
-   case MESA_FORMAT_SRGB_DXT1:
-   case MESA_FORMAT_SRGBA_DXT1:
-   case MESA_FORMAT_SRGBA_DXT3:
-   case MESA_FORMAT_SRGBA_DXT5:
-      return GL_TRUE;
-   default:
-      return GL_FALSE;
-   }
-}
-
-
 /** called via ctx->Driver.NewTextureImage() */
 static struct gl_texture_image *
 st_NewTextureImage(GLcontext * ctx)
@@ -249,7 +205,7 @@
 default_usage(enum pipe_format fmt)
 {
    GLuint usage = PIPE_TEXTURE_USAGE_SAMPLER;
-   if (pf_is_depth_stencil(fmt))
+   if (util_format_is_depth_or_stencil(fmt))
       usage |= PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
    else
       usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
@@ -450,10 +406,9 @@
    memset(&templ, 0, sizeof(templ));
    templ.target = PIPE_TEXTURE_2D;
    templ.format = st_mesa_format_to_pipe_format(mesa_format);
-   pf_get_block(templ.format, &templ.block);
-   templ.width[0] = width;
-   templ.height[0] = height;
-   templ.depth[0] = 1;
+   templ.width0 = width;
+   templ.height0 = height;
+   templ.depth0 = 1;
    templ.last_level = 0;
    templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
    src_tex = screen->texture_create(screen, &templ);
@@ -663,7 +618,7 @@
     */
    if (!compressed_src &&
        !ctx->Mesa_DXTn &&
-       is_compressed_mesa_format(texImage->TexFormat) &&
+       _mesa_is_format_compressed(texImage->TexFormat) &&
        screen->is_format_supported(screen,
                                    stImage->pt->format,
                                    stImage->pt->target,
@@ -679,7 +634,7 @@
 
    if (stImage->pt) {
       if (format == GL_DEPTH_COMPONENT &&
-          pf_is_depth_and_stencil(stImage->pt->format))
+          util_format_is_depth_and_stencil(stImage->pt->format))
          transfer_usage = PIPE_TRANSFER_READ_WRITE;
       else
          transfer_usage = PIPE_TRANSFER_WRITE;
@@ -725,7 +680,22 @@
     * conversion and copy:
     */
    if (compressed_src) {
-      memcpy(texImage->Data, pixels, imageSize);
+      const GLuint srcImageStride = _mesa_format_row_stride(texImage->TexFormat, width);
+      if(dstRowStride == srcImageStride)
+         memcpy(texImage->Data, pixels, imageSize);
+      else
+      {
+         char *dst = texImage->Data;
+         const char *src = pixels;
+         int i;
+
+         for(i = 0; i < height; ++i)
+         {
+            memcpy(dst, src, srcImageStride);
+            dst += dstRowStride;
+            src += srcImageStride;
+         }
+      }
    }
    else {
       const GLuint srcImageStride =
@@ -878,7 +848,7 @@
    /* copy/pack data into user buffer */
    if (st_equal_formats(stImage->pt->format, format, type)) {
       /* memcpy */
-      const uint bytesPerRow = width * pf_get_size(stImage->pt->format);
+      const uint bytesPerRow = width * util_format_get_blocksize(stImage->pt->format);
       ubyte *map = screen->transfer_map(screen, tex_xfer);
       GLuint row;
       for (row = 0; row < height; row++) {
@@ -935,7 +905,7 @@
    GLubyte *dest;
 
    if (stImage->pt &&
-       pf_is_compressed(stImage->pt->format) &&
+       util_format_is_compressed(stImage->pt->format) &&
        !compressed_dst) {
       /* Need to decompress the texture.
        * We'll do this by rendering a textured quad.
@@ -960,7 +930,7 @@
                                             PIPE_TRANSFER_READ, 0, 0,
                                             stImage->base.Width,
                                             stImage->base.Height);
-      texImage->RowStride = stImage->transfer->stride / stImage->pt->block.size;
+      texImage->RowStride = stImage->transfer->stride / util_format_get_blocksize(stImage->pt->format);
    }
    else {
       /* Otherwise, the image should actually be stored in
@@ -1066,7 +1036,7 @@
    /* See if we can do texture compression with a blit/render.
     */
    if (!ctx->Mesa_DXTn &&
-       is_compressed_mesa_format(texImage->TexFormat) &&
+       _mesa_is_format_compressed(texImage->TexFormat) &&
        screen->is_format_supported(screen,
                                    stImage->pt->format,
                                    stImage->pt->target,
@@ -1086,7 +1056,7 @@
       unsigned face = _mesa_tex_target_to_face(target);
 
       if (format == GL_DEPTH_COMPONENT &&
-          pf_is_depth_and_stencil(stImage->pt->format))
+          util_format_is_depth_and_stencil(stImage->pt->format))
          transfer_usage = PIPE_TRANSFER_READ_WRITE;
       else
          transfer_usage = PIPE_TRANSFER_WRITE;
@@ -1135,7 +1105,7 @@
 done:
    _mesa_unmap_teximage_pbo(ctx, packing);
 
-   if (stImage->pt) {
+   if (stImage->pt && texImage->Data) {
       st_texture_image_unmap(ctx->st, stImage);
       texImage->Data = NULL;
    }
@@ -1208,10 +1178,10 @@
                            struct gl_texture_image *texImage)
 {
    struct st_texture_image *stImage = st_texture_image(texImage);
-   struct pipe_format_block block;
    int srcBlockStride;
    int dstBlockStride;
    int y;
+   enum pipe_format pformat= stImage->pt->format;
 
    if (stImage->pt) {
       unsigned face = _mesa_tex_target_to_face(target);
@@ -1223,8 +1193,7 @@
                                             xoffset, yoffset,
                                             width, height);
       
-      block = stImage->pt->block;
-      srcBlockStride = pf_get_stride(&block, width);
+      srcBlockStride = util_format_get_stride(pformat, width);
       dstBlockStride = stImage->transfer->stride;
    } else {
       assert(stImage->pt);
@@ -1238,16 +1207,16 @@
       return;
    }
 
-   assert(xoffset % block.width == 0);
-   assert(yoffset % block.height == 0);
-   assert(width % block.width == 0);
-   assert(height % block.height == 0);
+   assert(xoffset % util_format_get_blockwidth(pformat) == 0);
+   assert(yoffset % util_format_get_blockheight(pformat) == 0);
+   assert(width % util_format_get_blockwidth(pformat) == 0);
+   assert(height % util_format_get_blockheight(pformat) == 0);
 
-   for (y = 0; y < height; y += block.height) {
+   for (y = 0; y < height; y += util_format_get_blockheight(pformat)) {
       /* don't need to adjust for xoffset and yoffset as st_texture_image_map does that */
-      const char *src = (const char*)data + srcBlockStride * pf_get_nblocksy(&block, y);
-      char *dst = (char*)texImage->Data + dstBlockStride * pf_get_nblocksy(&block, y);
-      memcpy(dst, src, pf_get_stride(&block, width));
+      const char *src = (const char*)data + srcBlockStride * util_format_get_nblocksy(pformat, y);
+      char *dst = (char*)texImage->Data + dstBlockStride * util_format_get_nblocksy(pformat, y);
+      memcpy(dst, src, util_format_get_stride(pformat, width));
    }
 
    if (stImage->pt) {
@@ -1311,7 +1280,7 @@
 
    if ((baseFormat == GL_DEPTH_COMPONENT ||
         baseFormat == GL_DEPTH_STENCIL) &&
-       pf_is_depth_and_stencil(stImage->pt->format))
+       util_format_is_depth_and_stencil(stImage->pt->format))
       transfer_usage = PIPE_TRANSFER_READ_WRITE;
    else
       transfer_usage = PIPE_TRANSFER_WRITE;
@@ -1724,8 +1693,6 @@
       pipe_texture_reference(&stImage->pt, NULL);
    }
    else if (stImage->base.Data) {
-      assert(stImage->base.Data != NULL);
-
       /* More straightforward upload.  
        */
 
@@ -1739,10 +1706,10 @@
                             dstLevel,
                             stImage->base.Data,
                             stImage->base.RowStride * 
-                            stObj->pt->block.size,
+                            util_format_get_blocksize(stObj->pt->format),
                             stImage->base.RowStride *
                             stImage->base.Height *
-                            stObj->pt->block.size);
+                            util_format_get_blocksize(stObj->pt->format));
       _mesa_align_free(stImage->base.Data);
       stImage->base.Data = NULL;
    }
@@ -1764,7 +1731,7 @@
 {
    struct st_texture_object *stObj = st_texture_object(tObj);
    const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
-   GLuint cpp, face;
+   GLuint blockSize, face;
    struct st_texture_image *firstImage;
 
    *needFlush = GL_FALSE;
@@ -1796,13 +1763,8 @@
       pipe_texture_reference(&stObj->pt, firstImage->pt);
    }
 
-   /* FIXME: determine format block instead of cpp */
-   if (_mesa_is_format_compressed(firstImage->base.TexFormat)) {
-      cpp = compressed_num_bytes(firstImage->base.TexFormat);
-   }
-   else {
-      cpp = _mesa_get_format_bytes(firstImage->base.TexFormat);
-   }
+   /* bytes per pixel block (blocks are usually 1x1) */
+   blockSize = _mesa_get_format_bytes(firstImage->base.TexFormat);
 
    /* If we already have a gallium texture, check that it matches the texture
     * object's format, target, size, num_levels, etc.
@@ -1813,11 +1775,9 @@
       if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
           stObj->pt->format != fmt ||
           stObj->pt->last_level < stObj->lastLevel ||
-          stObj->pt->width[0] != firstImage->base.Width2 ||
-          stObj->pt->height[0] != firstImage->base.Height2 ||
-          stObj->pt->depth[0] != firstImage->base.Depth2 ||
-          /* Nominal bytes per pixel: */
-          stObj->pt->block.size / stObj->pt->block.width != cpp)
+          stObj->pt->width0 != firstImage->base.Width2 ||
+          stObj->pt->height0 != firstImage->base.Height2 ||
+          stObj->pt->depth0 != firstImage->base.Depth2)
       {
          pipe_texture_reference(&stObj->pt, NULL);
          ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER;
diff --git a/src/mesa/state_tracker/st_cb_viewport.c b/src/mesa/state_tracker/st_cb_viewport.c
index 75b0a21..ab11c5b 100644
--- a/src/mesa/state_tracker/st_cb_viewport.c
+++ b/src/mesa/state_tracker/st_cb_viewport.c
@@ -42,8 +42,8 @@
 {
    struct st_context *st = ctx->st;
 
-   if (st->pipe->winsys && st->pipe->winsys->update_buffer)
-      st->pipe->winsys->update_buffer( st->pipe->winsys,
+   if (st->pipe->screen && st->pipe->screen->update_buffer)
+      st->pipe->screen->update_buffer( st->pipe->screen,
                                        st->pipe->priv );
 }
 
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index e82598c..145bd62 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -43,6 +43,7 @@
 #include "st_cb_blit.h"
 #include "st_cb_bufferobjects.h"
 #include "st_cb_clear.h"
+#include "st_cb_condrender.h"
 #if FEATURE_drawpix
 #include "st_cb_drawpixels.h"
 #include "st_cb_rasterpos.h"
@@ -51,7 +52,6 @@
 #include "st_cb_drawtex.h"
 #endif
 #include "st_cb_fbo.h"
-#include "st_cb_get.h"
 #if FEATURE_feedback
 #include "st_cb_feedback.h"
 #endif
@@ -336,7 +336,6 @@
 #endif
 
    st_init_fbo_functions(functions);
-   st_init_get_functions(functions);
 #if FEATURE_feedback
    st_init_feedback_functions(functions);
 #endif
@@ -344,6 +343,7 @@
 #if FEATURE_queryobj
    st_init_query_functions(functions);
 #endif
+   st_init_cond_render_functions(functions);
    st_init_readpixels_functions(functions);
    st_init_texture_functions(functions);
    st_init_flush_functions(functions);
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 18adb35..831909a 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -55,6 +55,7 @@
 #define ST_NEW_FRAGMENT_PROGRAM        0x2
 #define ST_NEW_VERTEX_PROGRAM          0x4
 #define ST_NEW_FRAMEBUFFER             0x8
+#define ST_NEW_EDGEFLAGS_DATA          0x10
 
 
 struct st_state_flags {
@@ -120,6 +121,7 @@
    struct st_state_flags dirty;
 
    GLboolean missing_textures;
+   GLboolean vertdata_edgeflags;
 
    /** Mapping from VERT_RESULT_x to post-transformed vertex slot */
    const GLuint *vertex_result_to_slot;
@@ -127,6 +129,8 @@
    struct st_vertex_program *vp;    /**< Currently bound vertex program */
    struct st_fragment_program *fp;  /**< Currently bound fragment program */
 
+   struct st_vp_varient *vp_varient;
+
    struct gl_texture_object *default_texture;
 
    struct {
diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c
index 3009cde..6e699ca 100644
--- a/src/mesa/state_tracker/st_debug.c
+++ b/src/mesa/state_tracker/st_debug.c
@@ -86,7 +86,8 @@
    }
 #endif
 
-   tgsi_dump( st->vp->state.tokens, 0 );
+   if (st->vp->varients)
+      tgsi_dump( st->vp->varients[0].state.tokens, 0 );
    if (st->vp->Base.Base.Parameters)
       _mesa_print_parameter_list(st->vp->Base.Base.Parameters);
 
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index c76bff9..e54f21b 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -25,10 +25,20 @@
  * 
  **************************************************************************/
 
- /*
-  * Authors:
-  *   Keith Whitwell <keith@tungstengraphics.com>
-  */
+/*
+ * This file implements the st_draw_vbo() function which is called from
+ * Mesa's VBO module.  All point/line/triangle rendering is done through
+ * this function whether the user called glBegin/End, glDrawArrays,
+ * glDrawElements, glEvalMesh, or glCalList, etc.
+ *
+ * We basically convert the VBO's vertex attribute/array information into
+ * Gallium vertex state, bind the vertex buffer objects and call
+ * pipe->draw_elements(), pipe->draw_range_elements() or pipe->draw_arrays().
+ *
+ * Authors:
+ *   Keith Whitwell <keith@tungstengraphics.com>
+ */
+
 
 #include "main/imports.h"
 #include "main/image.h"
@@ -207,59 +217,7 @@
 }
 
 
-/*
- * If edge flags are needed, setup an bitvector of flags and call
- * pipe->set_edgeflags().
- * XXX memleak: need to free the returned pointer at some point
- */
-static void *
-setup_edgeflags(GLcontext *ctx, GLenum primMode, GLint start, GLint count,
-                const struct gl_client_array *array)
-{
-   struct pipe_context *pipe = ctx->st->pipe;
 
-   if ((primMode == GL_TRIANGLES ||
-        primMode == GL_QUADS ||
-        primMode == GL_POLYGON) &&
-       (ctx->Polygon.FrontMode != GL_FILL ||
-        ctx->Polygon.BackMode != GL_FILL)) {
-      /* need edge flags */
-      GLint i;
-      unsigned *vec;
-      struct st_buffer_object *stobj = st_buffer_object(array->BufferObj);
-      ubyte *map;
-
-      if (!stobj || stobj->Base.Name == 0) {
-         /* edge flags are not in a VBO */
-         return NULL;
-      }
-
-      vec = (unsigned *) _mesa_calloc(sizeof(unsigned) * ((count + 31) / 32));
-      if (!vec)
-         return NULL;
-
-      map = pipe_buffer_map(pipe->screen, stobj->buffer, PIPE_BUFFER_USAGE_CPU_READ);
-      map = ADD_POINTERS(map, array->Ptr);
-
-      for (i = 0; i < count; i++) {
-         if (*((float *) map))
-            vec[i/32] |= 1 << (i % 32);
-
-         map += array->StrideB;
-      }
-
-      pipe_buffer_unmap(pipe->screen, stobj->buffer);
-
-      pipe->set_edgeflags(pipe, vec);
-
-      return vec;
-   }
-   else {
-      /* edge flags not needed */
-      pipe->set_edgeflags(pipe, NULL);
-      return NULL;
-   }
-}
 
 
 /**
@@ -269,6 +227,7 @@
  */
 static GLboolean
 is_interleaved_arrays(const struct st_vertex_program *vp,
+                      const struct st_vp_varient *vpv,
                       const struct gl_client_array **arrays,
                       GLboolean *userSpace)
 {
@@ -278,7 +237,7 @@
    GLuint num_client_arrays = 0;
    const GLubyte *client_addr = NULL;
 
-   for (attr = 0; attr < vp->num_inputs; attr++) {
+   for (attr = 0; attr < vpv->num_inputs; attr++) {
       const GLuint mesaAttr = vp->index_to_input[attr];
       const struct gl_buffer_object *bufObj = arrays[mesaAttr]->BufferObj;
       const GLsizei stride = arrays[mesaAttr]->StrideB; /* in bytes */
@@ -311,7 +270,7 @@
       }
    }
 
-   *userSpace = (num_client_arrays == vp->num_inputs);
+   *userSpace = (num_client_arrays == vpv->num_inputs);
    /* printf("user space: %d (%d %d)\n", (int) *userSpace,num_client_arrays,vp->num_inputs); */
 
    return GL_TRUE;
@@ -323,15 +282,16 @@
  */
 static void
 get_arrays_bounds(const struct st_vertex_program *vp,
-                       const struct gl_client_array **arrays,
-                       GLuint max_index,
-                       const GLubyte **low, const GLubyte **high)
+                  const struct st_vp_varient *vpv,
+                  const struct gl_client_array **arrays,
+                  GLuint max_index,
+                  const GLubyte **low, const GLubyte **high)
 {
    const GLubyte *low_addr = NULL;
    const GLubyte *high_addr = NULL;
    GLuint attr;
 
-   for (attr = 0; attr < vp->num_inputs; attr++) {
+   for (attr = 0; attr < vpv->num_inputs; attr++) {
       const GLuint mesaAttr = vp->index_to_input[attr];
       const GLint stride = arrays[mesaAttr]->StrideB;
       const GLubyte *start = arrays[mesaAttr]->Ptr;
@@ -363,6 +323,7 @@
 static void
 setup_interleaved_attribs(GLcontext *ctx,
                           const struct st_vertex_program *vp,
+                          const struct st_vp_varient *vpv,
                           const struct gl_client_array **arrays,
                           GLuint max_index,
                           GLboolean userSpace,
@@ -371,9 +332,9 @@
 {
    struct pipe_context *pipe = ctx->st->pipe;
    GLuint attr;
-   const GLubyte *offset0;
+   const GLubyte *offset0 = NULL;
 
-   for (attr = 0; attr < vp->num_inputs; attr++) {
+   for (attr = 0; attr < vpv->num_inputs; attr++) {
       const GLuint mesaAttr = vp->index_to_input[attr];
       struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj;
       struct st_buffer_object *stobj = st_buffer_object(bufobj);
@@ -384,7 +345,7 @@
       if (attr == 0) {
          const GLubyte *low, *high;
 
-         get_arrays_bounds(vp, arrays, max_index, &low, &high);
+         get_arrays_bounds(vp, vpv, arrays, max_index, &low, &high);
          /*printf("buffer range: %p %p  %d\n", low, high, high-low);*/
 
          offset0 = low;
@@ -425,6 +386,7 @@
 static void
 setup_non_interleaved_attribs(GLcontext *ctx,
                               const struct st_vertex_program *vp,
+                              const struct st_vp_varient *vpv,
                               const struct gl_client_array **arrays,
                               GLuint max_index,
                               GLboolean *userSpace,
@@ -434,7 +396,7 @@
    struct pipe_context *pipe = ctx->st->pipe;
    GLuint attr;
 
-   for (attr = 0; attr < vp->num_inputs; attr++) {
+   for (attr = 0; attr < vpv->num_inputs; attr++) {
       const GLuint mesaAttr = vp->index_to_input[attr];
       struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj;
       GLsizei stride = arrays[mesaAttr]->StrideB;
@@ -528,6 +490,20 @@
 }
 
 
+static unsigned translate_prim( GLcontext *ctx,
+                                unsigned prim )
+{
+   /* Avoid quadstrips if it's easy to do so:
+    */
+   if (prim == GL_QUAD_STRIP &&
+       ctx->Light.ShadeModel != GL_FLAT &&
+       ctx->Polygon.FrontMode == GL_FILL &&
+       ctx->Polygon.BackMode == GL_FILL)
+      prim = GL_TRIANGLE_STRIP;
+
+   return prim;
+}
+
 /**
  * This function gets plugged into the VBO module and is called when
  * we have something to render.
@@ -545,25 +521,36 @@
 {
    struct pipe_context *pipe = ctx->st->pipe;
    const struct st_vertex_program *vp;
+   const struct st_vp_varient *vpv;
    const struct pipe_shader_state *vs;
    struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS];
    GLuint attr;
    struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
    unsigned num_vbuffers, num_velements;
-   GLboolean userSpace;
+   GLboolean userSpace = GL_FALSE;
+   GLboolean vertDataEdgeFlags;
 
    /* Gallium probably doesn't want this in some cases. */
    if (!index_bounds_valid)
-      vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
+      if (!vbo_all_varyings_in_vbos(arrays))
+	 vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
 
    /* sanity check for pointer arithmetic below */
    assert(sizeof(arrays[0]->Ptr[0]) == 1);
 
+   vertDataEdgeFlags = arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj &&
+                       arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj->Name;
+   if (vertDataEdgeFlags != ctx->st->vertdata_edgeflags) {
+      ctx->st->vertdata_edgeflags = vertDataEdgeFlags;
+      ctx->st->dirty.st |= ST_NEW_EDGEFLAGS_DATA;
+   }
+
    st_validate_state(ctx->st);
 
    /* must get these after state validation! */
    vp = ctx->st->vp;
-   vs = &ctx->st->vp->state;
+   vpv = ctx->st->vp_varient;
+   vs = &vpv->state;
 
 #if 0
    if (MESA_VERBOSE & VERBOSE_GLSL) {
@@ -576,21 +563,21 @@
    /*
     * Setup the vbuffer[] and velements[] arrays.
     */
-   if (is_interleaved_arrays(vp, arrays, &userSpace)) {
+   if (is_interleaved_arrays(vp, vpv, arrays, &userSpace)) {
       /*printf("Draw interleaved\n");*/
-      setup_interleaved_attribs(ctx, vp, arrays, max_index, userSpace,
+      setup_interleaved_attribs(ctx, vp, vpv, arrays, max_index, userSpace,
                                 vbuffer, velements);
       num_vbuffers = 1;
-      num_velements = vp->num_inputs;
+      num_velements = vpv->num_inputs;
       if (num_velements == 0)
          num_vbuffers = 0;
    }
    else {
       /*printf("Draw non-interleaved\n");*/
-      setup_non_interleaved_attribs(ctx, vp, arrays, max_index,
+      setup_non_interleaved_attribs(ctx, vp, vpv, arrays, max_index,
                                     &userSpace, vbuffer, velements);
-      num_vbuffers = vp->num_inputs;
-      num_velements = vp->num_inputs;
+      num_vbuffers = vpv->num_inputs;
+      num_velements = vpv->num_inputs;
    }
 
 #if 0
@@ -623,6 +610,7 @@
       struct gl_buffer_object *bufobj = ib->obj;
       struct pipe_buffer *indexBuf = NULL;
       unsigned indexSize, indexOffset, i;
+      unsigned prim;
 
       switch (ib->type) {
       case GL_UNSIGNED_INT:
@@ -661,24 +649,20 @@
           * through to driver & draw module.  These interfaces still
           * need a bit of work...
           */
-         setup_edgeflags(ctx, prims[i].mode,
-                         prims[i].start + indexOffset, prims[i].count,
-                         arrays[VERT_ATTRIB_EDGEFLAG]);
+         prim = translate_prim( ctx, prims[i].mode );
 
          pipe->draw_range_elements(pipe, indexBuf, indexSize,
                                    min_index,
                                    max_index,
-                                   prims[i].mode,
+                                   prim,
                                    prims[i].start + indexOffset, prims[i].count);
       }
       else {
          for (i = 0; i < nr_prims; i++) {
-            setup_edgeflags(ctx, prims[i].mode,
-                            prims[i].start + indexOffset, prims[i].count,
-                            arrays[VERT_ATTRIB_EDGEFLAG]);
+            prim = translate_prim( ctx, prims[i].mode );
             
             pipe->draw_elements(pipe, indexBuf, indexSize,
-                                prims[i].mode,
+                                prim,
                                 prims[i].start + indexOffset, prims[i].count);
          }
       }
@@ -688,12 +672,12 @@
    else {
       /* non-indexed */
       GLuint i;
-      for (i = 0; i < nr_prims; i++) {
-         setup_edgeflags(ctx, prims[i].mode,
-                         prims[i].start, prims[i].count,
-                         arrays[VERT_ATTRIB_EDGEFLAG]);
+      GLuint prim;
 
-         pipe->draw_arrays(pipe, prims[i].mode, prims[i].start, prims[i].count);
+      for (i = 0; i < nr_prims; i++) {
+         prim = translate_prim( ctx, prims[i].mode );
+
+         pipe->draw_arrays(pipe, prim, prims[i].start, prims[i].count);
       }
    }
 
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index b2d682e..cfc0caa 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -120,10 +120,10 @@
 
    /* must get these after state validation! */
    vp = ctx->st->vp;
-   vs = &st->vp->state;
+   vs = &st->vp_varient->state;
 
-   if (!st->vp->draw_shader) {
-      st->vp->draw_shader = draw_create_vertex_shader(draw, vs);
+   if (!st->vp_varient->draw_shader) {
+      st->vp_varient->draw_shader = draw_create_vertex_shader(draw, vs);
    }
 
    /*
@@ -136,7 +136,7 @@
    draw_set_viewport_state(draw, &st->state.viewport);
    draw_set_clip_state(draw, &st->state.clip);
    draw_set_rasterizer_state(draw, &st->state.rasterizer);
-   draw_bind_vertex_shader(draw, st->vp->draw_shader);
+   draw_bind_vertex_shader(draw, st->vp_varient->draw_shader);
    set_feedback_vertex_format(ctx);
 
    /* loop over TGSI shader inputs to determine vertex buffer
@@ -241,7 +241,8 @@
    mapped_constants = pipe_buffer_map(pipe->screen,
                                       st->state.constants[PIPE_SHADER_VERTEX].buffer,
                                       PIPE_BUFFER_USAGE_CPU_READ);
-   draw_set_mapped_constant_buffer(st->draw, mapped_constants,
+   draw_set_mapped_constant_buffer(st->draw, PIPE_SHADER_VERTEX,
+                                   mapped_constants,
                                    st->state.constants[PIPE_SHADER_VERTEX].buffer->size);
 
 
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index ce3c302..e25a613 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -92,6 +92,10 @@
       = _min(screen->get_param(screen, PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS),
              MAX_VERTEX_TEXTURE_IMAGE_UNITS);
 
+   c->MaxCombinedTextureImageUnits
+      = _min(screen->get_param(screen, PIPE_CAP_MAX_COMBINED_SAMPLERS),
+             MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+
    c->MaxTextureCoordUnits
       = _min(c->MaxTextureImageUnits, MAX_TEXTURE_COORD_UNITS);
 
@@ -288,6 +292,7 @@
                                    PIPE_TEXTURE_2D, 
                                    PIPE_TEXTURE_USAGE_SAMPLER, 0)) {
       ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE;
+      ctx->Extensions.S3_s3tc = GL_TRUE;
    }
 
    /* ycbcr support */
@@ -305,4 +310,8 @@
       /* we support always support GL_EXT_framebuffer_blit */
       ctx->Extensions.ARB_framebuffer_object = GL_TRUE;
    }
+
+   if (st->pipe->render_condition) {
+      ctx->Extensions.NV_conditional_render = GL_TRUE;
+   }
 }
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index 02f8005..d00b67a 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -42,42 +42,34 @@
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_screen.h"
+#include "util/u_format.h"
 #include "st_context.h"
 #include "st_format.h"
 
-static GLuint
-format_bits(
-   pipe_format_rgbazs_t  info,
-   GLuint comp )
-{
-   return pf_get_component_bits( (enum pipe_format) info, comp );
-}
 
 static GLuint
-format_max_bits(
-   pipe_format_rgbazs_t  info )
+format_max_bits(enum pipe_format format)
 {
-   GLuint   size = format_bits( info, PIPE_FORMAT_COMP_R );
+   GLuint size = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0);
 
-   size = MAX2( size, format_bits( info, PIPE_FORMAT_COMP_G ) );
-   size = MAX2( size, format_bits( info, PIPE_FORMAT_COMP_B ) );
-   size = MAX2( size, format_bits( info, PIPE_FORMAT_COMP_A ) );
-   size = MAX2( size, format_bits( info, PIPE_FORMAT_COMP_Z ) );
-   size = MAX2( size, format_bits( info, PIPE_FORMAT_COMP_S ) );
+   size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1));
+   size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2));
+   size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3));
+   size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0));
+   size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1));
    return size;
 }
 
 static GLuint
-format_size(
-   pipe_format_rgbazs_t  info )
+format_size(enum pipe_format format)
 {
    return
-      format_bits( info, PIPE_FORMAT_COMP_R ) +
-      format_bits( info, PIPE_FORMAT_COMP_G ) +
-      format_bits( info, PIPE_FORMAT_COMP_B ) +
-      format_bits( info, PIPE_FORMAT_COMP_A ) +
-      format_bits( info, PIPE_FORMAT_COMP_Z ) +
-      format_bits( info, PIPE_FORMAT_COMP_S );
+      util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0) +
+      util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1) +
+      util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2) +
+      util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3) +
+      util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0) +
+      util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1);
 }
 
 /*
@@ -86,11 +78,13 @@
 GLboolean
 st_get_format_info(enum pipe_format format, struct pipe_format_info *pinfo)
 {
-   if (pf_layout(format) == PIPE_FORMAT_LAYOUT_RGBAZS) {
-      pipe_format_rgbazs_t info;
+   const struct util_format_description *desc;
 
-      info = format;
+   desc = util_format_description(format);
+   assert(desc);
 
+   if (desc->layout == UTIL_FORMAT_LAYOUT_ARITH ||
+       desc->layout == UTIL_FORMAT_LAYOUT_ARRAY) {
 #if 0
       printf("%s\n", pf_name( format ) );
 #endif
@@ -99,26 +93,27 @@
       if (format == PIPE_FORMAT_A1R5G5B5_UNORM || format == PIPE_FORMAT_R5G6B5_UNORM) {
          pinfo->datatype = GL_UNSIGNED_SHORT;
       }
-      else if (format == PIPE_FORMAT_S8Z24_UNORM) {
+      else if (format == PIPE_FORMAT_S8Z24_UNORM ||
+               format == PIPE_FORMAT_Z24S8_UNORM) {
          pinfo->datatype = GL_UNSIGNED_INT_24_8;
       }
       else {
-         const GLuint size = format_max_bits( info );
+         const GLuint size = format_max_bits(format);
          if (size == 8) {
-            if (pf_type(info) == PIPE_FORMAT_TYPE_UNORM)
+            if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED)
                pinfo->datatype = GL_UNSIGNED_BYTE;
             else
                pinfo->datatype = GL_BYTE;
          }
          else if (size == 16) {
-            if (pf_type(info) == PIPE_FORMAT_TYPE_UNORM)
+            if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED)
                pinfo->datatype = GL_UNSIGNED_SHORT;
             else
                pinfo->datatype = GL_SHORT;
          }
          else {
             assert( size <= 32 );
-            if (pf_type(info) == PIPE_FORMAT_TYPE_UNORM)
+            if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED)
                pinfo->datatype = GL_UNSIGNED_INT;
             else
                pinfo->datatype = GL_INT;
@@ -126,23 +121,23 @@
       }
 
       /* Component bits */
-      pinfo->red_bits = format_bits( info, PIPE_FORMAT_COMP_R );
-      pinfo->green_bits = format_bits( info, PIPE_FORMAT_COMP_G );
-      pinfo->blue_bits = format_bits( info, PIPE_FORMAT_COMP_B );
-      pinfo->alpha_bits = format_bits( info, PIPE_FORMAT_COMP_A );
-      pinfo->depth_bits = format_bits( info, PIPE_FORMAT_COMP_Z );
-      pinfo->stencil_bits = format_bits( info, PIPE_FORMAT_COMP_S );
+      pinfo->red_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0);
+      pinfo->green_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1);
+      pinfo->blue_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2);
+      pinfo->alpha_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3);
+      pinfo->depth_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0);
+      pinfo->stencil_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1);
       pinfo->luminance_bits = 0;
       pinfo->intensity_bits = 0;
 
       /* Format size */
-      pinfo->size = format_size( info ) / 8;
+      pinfo->size = format_size(format) / 8;
 
       /* Luminance & Intensity bits */
-      if( pf_swizzle_x(info) == PIPE_FORMAT_COMP_R &&
-          pf_swizzle_y(info) == PIPE_FORMAT_COMP_R &&
-          pf_swizzle_z(info) == PIPE_FORMAT_COMP_R ) {
-         if( pf_swizzle_w(info) == PIPE_FORMAT_COMP_R ) {
+      if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_X &&
+          desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_X &&
+          desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_X) {
+         if (desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_X) {
             pinfo->intensity_bits = pinfo->red_bits;
          }
          else {
@@ -153,7 +148,7 @@
 
       pinfo->mesa_format = st_pipe_format_to_mesa_format(format);
    }
-   else if (pf_layout(format) == PIPE_FORMAT_LAYOUT_YCBCR) {
+   else if (desc->layout == UTIL_FORMAT_LAYOUT_YUV) {
       pinfo->mesa_format = MESA_FORMAT_YCBCR;
       pinfo->datatype = GL_UNSIGNED_SHORT;
       pinfo->size = 2; /* two bytes per "texel" */
@@ -291,6 +286,8 @@
       return MESA_FORMAT_ARGB8888;
    case PIPE_FORMAT_X8R8G8B8_UNORM:
       return MESA_FORMAT_XRGB8888;
+   case PIPE_FORMAT_B8G8R8A8_UNORM:
+      return MESA_FORMAT_ARGB8888_REV;
    case PIPE_FORMAT_A1R5G5B5_UNORM:
       return MESA_FORMAT_ARGB1555;
    case PIPE_FORMAT_A4R4G4B4_UNORM:
@@ -389,6 +386,33 @@
 }
 
 /**
+ * Find an RGB format supported by the context/winsys.
+ */
+static enum pipe_format
+default_rgb_format(struct pipe_screen *screen, 
+                   enum pipe_texture_target target,
+                   unsigned tex_usage, 
+                   unsigned geom_flags)
+{
+   static const enum pipe_format colorFormats[] = {
+      PIPE_FORMAT_X8R8G8B8_UNORM,
+      PIPE_FORMAT_B8G8R8X8_UNORM,
+      PIPE_FORMAT_R8G8B8X8_UNORM,
+      PIPE_FORMAT_A8R8G8B8_UNORM,
+      PIPE_FORMAT_B8G8R8A8_UNORM,
+      PIPE_FORMAT_R8G8B8A8_UNORM,
+      PIPE_FORMAT_R5G6B5_UNORM
+   };
+   uint i;
+   for (i = 0; i < Elements(colorFormats); i++) {
+      if (screen->is_format_supported( screen, colorFormats[i], target, tex_usage, geom_flags )) {
+         return colorFormats[i];
+      }
+   }
+   return PIPE_FORMAT_NONE;
+}
+
+/**
  * Find an sRGBA format supported by the context/winsys.
  */
 static enum pipe_format
@@ -472,13 +496,14 @@
    case 4:
    case GL_RGBA:
    case GL_COMPRESSED_RGBA:
-   case 3:
-   case GL_RGB:
-   case GL_COMPRESSED_RGB:
    case GL_RGBA8:
    case GL_RGB10_A2:
    case GL_RGBA12:
       return default_rgba_format( screen, target, tex_usage, geom_flags );
+   case 3:
+   case GL_RGB:
+   case GL_COMPRESSED_RGB:
+      return default_rgb_format( screen, target, tex_usage, geom_flags );
    case GL_RGBA16:
       if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET)
          return default_deep_rgba_format( screen, target, tex_usage, geom_flags );
@@ -500,7 +525,7 @@
    case GL_RGB10:
    case GL_RGB12:
    case GL_RGB16:
-      return default_rgba_format( screen, target, tex_usage, geom_flags );
+      return default_rgb_format( screen, target, tex_usage, geom_flags );
 
    case GL_RGB5:
    case GL_RGB4:
diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index 16ca277..2c283d4 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -37,7 +37,9 @@
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
 #include "util/u_gen_mipmap.h"
+#include "util/u_math.h"
 
 #include "cso_cache/cso_cache.h"
 #include "cso_cache/cso_context.h"
@@ -133,29 +135,33 @@
       srcTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face,
 						srcLevel, zslice,
 						PIPE_TRANSFER_READ, 0, 0,
-						pt->width[srcLevel],
-						pt->height[srcLevel]);
+						u_minify(pt->width0, srcLevel),
+						u_minify(pt->height0, srcLevel));
 
       dstTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face,
 						dstLevel, zslice,
 						PIPE_TRANSFER_WRITE, 0, 0,
-						pt->width[dstLevel],
-						pt->height[dstLevel]);
+						u_minify(pt->width0, dstLevel),
+						u_minify(pt->height0, dstLevel));
 
       srcData = (ubyte *) screen->transfer_map(screen, srcTrans);
       dstData = (ubyte *) screen->transfer_map(screen, dstTrans);
 
-      srcStride = srcTrans->stride / srcTrans->block.size;
-      dstStride = dstTrans->stride / dstTrans->block.size;
+      srcStride = srcTrans->stride / util_format_get_blocksize(srcTrans->texture->format);
+      dstStride = dstTrans->stride / util_format_get_blocksize(dstTrans->texture->format);
 
       _mesa_generate_mipmap_level(target, datatype, comps,
-                   0 /*border*/,
-                   pt->width[srcLevel], pt->height[srcLevel], pt->depth[srcLevel],
-                   srcData,
-                   srcStride, /* stride in texels */
-                   pt->width[dstLevel], pt->height[dstLevel], pt->depth[dstLevel],
-                   dstData,
-                   dstStride); /* stride in texels */
+                                  0 /*border*/,
+                                  u_minify(pt->width0, srcLevel),
+                                  u_minify(pt->height0, srcLevel),
+                                  u_minify(pt->depth0, srcLevel),
+                                  srcData,
+                                  srcStride, /* stride in texels */
+                                  u_minify(pt->width0, dstLevel),
+                                  u_minify(pt->height0, dstLevel),
+                                  u_minify(pt->depth0, dstLevel),
+                                  dstData,
+                                  dstStride); /* stride in texels */
 
       screen->transfer_unmap(screen, srcTrans);
       screen->transfer_unmap(screen, dstTrans);
@@ -219,6 +225,9 @@
    /* find expected last mipmap level */
    lastLevel = compute_num_levels(ctx, texObj, target) - 1;
 
+   if (lastLevel == 0)
+      return;
+
    if (pt->last_level < lastLevel) {
       /* The current gallium texture doesn't have space for all the
        * mipmap levels we need to generate.  So allocate a new texture.
@@ -232,9 +241,9 @@
                                     oldTex->target,
                                     oldTex->format,
                                     lastLevel,
-                                    oldTex->width[0],
-                                    oldTex->height[0],
-                                    oldTex->depth[0],
+                                    oldTex->width0,
+                                    oldTex->height0,
+                                    oldTex->depth0,
                                     oldTex->tex_usage);
 
       /* The texture isn't in a "complete" state yet so set the expected
@@ -269,9 +278,9 @@
          = _mesa_get_tex_image(ctx, texObj, target, srcLevel);
       struct gl_texture_image *dstImage;
       struct st_texture_image *stImage;
-      uint dstWidth = pt->width[dstLevel];
-      uint dstHeight = pt->height[dstLevel];
-      uint dstDepth = pt->depth[dstLevel];
+      uint dstWidth = u_minify(pt->width0, dstLevel);
+      uint dstHeight = u_minify(pt->height0, dstLevel);
+      uint dstDepth = u_minify(pt->depth0, dstLevel); 
       uint border = srcImage->Border;
 
       dstImage = _mesa_get_tex_image(ctx, texObj, target, dstLevel);
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index 3d6c215..e788008 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -160,13 +160,14 @@
 static struct ureg_src
 src_register( struct st_translate *t,
               gl_register_file file,
-              GLuint index )
+              GLint index )
 {
    switch( file ) {
    case PROGRAM_UNDEFINED:
       return ureg_src_undef();
 
    case PROGRAM_TEMPORARY:
+      ASSERT(index >= 0);
       if (ureg_dst_is_undef(t->temps[index]))
          t->temps[index] = ureg_DECL_temporary( t->ureg );
       return ureg_src(t->temps[index]);
@@ -174,9 +175,15 @@
    case PROGRAM_STATE_VAR:
    case PROGRAM_NAMED_PARAM:
    case PROGRAM_ENV_PARAM:
+   case PROGRAM_LOCAL_PARAM:
    case PROGRAM_UNIFORM:
-   case PROGRAM_CONSTANT:       /* ie, immediate */
+      ASSERT(index >= 0);
       return t->constants[index];
+   case PROGRAM_CONSTANT:       /* ie, immediate */
+      if (index < 0)
+         return ureg_DECL_constant( t->ureg, 0 );
+      else
+         return t->constants[index];
 
    case PROGRAM_INPUT:
       return t->inputs[t->inputMapping[index]];
@@ -263,9 +270,14 @@
    if (SrcReg->Abs) 
       src = ureg_abs(src);
 
-   if (SrcReg->RelAddr) 
+   if (SrcReg->RelAddr) {
       src = ureg_src_indirect( src, ureg_src(t->address[0]));
-   
+      /* If SrcReg->Index was negative, it was set to zero in
+       * src_register().  Reassign it now.
+       */
+      src.Index = SrcReg->Index;
+   }
+
    return src;
 }
 
@@ -278,7 +290,7 @@
 
 
 /**
- * Translate SWZ instructions into a single MAD.  EG:
+ * Translate a SWZ instruction into a MOV, MUL or MAD instruction.  EG:
  *
  *   SWZ dst, src.x-y10 
  * 
@@ -396,6 +408,23 @@
 }
 
 
+/**
+ * Negate the value of DDY to match GL semantics where (0,0) is the
+ * lower-left corner of the window.
+ * Note that the GL_ARB_fragment_coord_conventions extension will
+ * effect this someday.
+ */
+static void emit_ddy( struct st_translate *t,
+                      struct ureg_dst dst,
+                      const struct prog_src_register *SrcReg )
+{
+   struct ureg_program *ureg = t->ureg;
+   struct ureg_src src = translate_src( t, SrcReg );
+   src = ureg_negate( src );
+   ureg_DDY( ureg, dst, src );
+}
+
+
 
 static unsigned
 translate_opcode( unsigned op )
@@ -619,7 +648,9 @@
       ureg_MOV( ureg, dst[0], ureg_imm1f(ureg, 0.5) );
       break;
 		 
-
+   case OPCODE_DDY:
+      emit_ddy( t, dst[0], &inst->SrcReg[0] );
+      break;
 
    default:
       ureg_insn( ureg, 
@@ -676,6 +707,41 @@
 
 
 /**
+ * OpenGL's fragment gl_FrontFace input is 1 for front-facing, 0 for back.
+ * TGSI uses +1 for front, -1 for back.
+ * This function converts the TGSI value to the GL value.  Simply clamping/
+ * saturating the value to [0,1] does the job.
+ */
+static void
+emit_face_var( struct st_translate *t,
+               const struct gl_program *program )
+{
+   struct ureg_program *ureg = t->ureg;
+   struct ureg_dst face_temp = ureg_DECL_temporary( ureg );
+   struct ureg_src face_input = t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]];
+
+   /* MOV_SAT face_temp, input[face]
+    */
+   face_temp = ureg_saturate( face_temp );
+   ureg_MOV( ureg, face_temp, face_input );
+
+   /* Use face_temp as face input from here on:
+    */
+   t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]] = ureg_src(face_temp);
+}
+
+static void
+emit_edgeflags( struct st_translate *t,
+                 const struct gl_program *program )
+{
+   struct ureg_program *ureg = t->ureg;
+   struct ureg_dst edge_dst = t->outputs[t->outputMapping[VERT_RESULT_EDGE]];
+   struct ureg_src edge_src = t->inputs[t->inputMapping[VERT_ATTRIB_EDGEFLAG]];
+
+   ureg_MOV( ureg, edge_dst, edge_src );
+}
+
+/**
  * Translate Mesa program to TGSI format.
  * \param program  the program to translate
  * \param numInputs  number of input registers used
@@ -694,26 +760,24 @@
  *
  * \return  array of translated tokens, caller's responsibility to free
  */
-const struct tgsi_token *
+enum pipe_error
 st_translate_mesa_program(
    GLcontext *ctx,
    uint procType,
+   struct ureg_program *ureg,
    const struct gl_program *program,
    GLuint numInputs,
    const GLuint inputMapping[],
    const ubyte inputSemanticName[],
    const ubyte inputSemanticIndex[],
    const GLuint interpMode[],
-   const GLbitfield inputFlags[],
    GLuint numOutputs,
    const GLuint outputMapping[],
    const ubyte outputSemanticName[],
    const ubyte outputSemanticIndex[],
-   const GLbitfield outputFlags[] )
+   boolean passthrough_edgeflags )
 {
    struct st_translate translate, *t;
-   struct ureg_program *ureg;
-   const struct tgsi_token *tokens = NULL;
    unsigned i;
 
    t = &translate;
@@ -722,11 +786,7 @@
    t->procType = procType;
    t->inputMapping = inputMapping;
    t->outputMapping = outputMapping;
-   t->ureg = ureg_create( procType );
-   if (t->ureg == NULL)
-      return NULL;
-
-   ureg = t->ureg;
+   t->ureg = ureg;
 
    /*_mesa_print_program(program);*/
 
@@ -748,6 +808,10 @@
          emit_inverted_wpos( t, program );
       }
 
+      if (program->InputsRead & FRAG_BIT_FACE) {
+         emit_face_var( t, program );
+      }
+
       /*
        * Declare output attributes.
        */
@@ -782,6 +846,8 @@
                                            outputSemanticName[i],
                                            outputSemanticIndex[i] );
       }
+      if (passthrough_edgeflags)
+         emit_edgeflags( t, program );
    }
 
    /* Declare address register.
@@ -805,6 +871,7 @@
       for (i = 0; i < program->Parameters->NumParameters; i++) {
          switch (program->Parameters->Parameters[i].Type) {
          case PROGRAM_ENV_PARAM:
+         case PROGRAM_LOCAL_PARAM:
          case PROGRAM_STATE_VAR:
          case PROGRAM_NAMED_PARAM:
          case PROGRAM_UNIFORM:
@@ -853,8 +920,7 @@
                         t->insn[t->labels[i].branch_target] );
    }
 
-   tokens = ureg_get_tokens( ureg, NULL );
-   ureg_destroy( ureg );
+   return PIPE_OK;
 
 out:
    FREE(t->insn);
@@ -863,17 +929,9 @@
 
    if (t->error) {
       debug_printf("%s: translate error flag set\n", __FUNCTION__);
-      FREE((void *)tokens);
-      tokens = NULL;
    }
 
-   if (!tokens) {
-      debug_printf("%s: failed to translate Mesa program:\n", __FUNCTION__);
-      _mesa_print_program(program);
-      debug_assert(0);
-   }
-
-   return tokens;
+   return PIPE_ERROR_OUT_OF_MEMORY;
 }
 
 
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.h b/src/mesa/state_tracker/st_mesa_to_tgsi.h
index c0d1ff5..e3c5bd1 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.h
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.h
@@ -30,6 +30,7 @@
 #define ST_MESA_TO_TGSI_H
 
 #include "main/mtypes.h"
+#include "tgsi/tgsi_ureg.h"
 
 
 #if defined __cplusplus
@@ -39,22 +40,22 @@
 struct tgsi_token;
 struct gl_program;
 
-const struct tgsi_token *
+enum pipe_error
 st_translate_mesa_program(
    GLcontext *ctx,
    uint procType,
+   struct ureg_program *ureg,
    const struct gl_program *program,
    GLuint numInputs,
    const GLuint inputMapping[],
    const ubyte inputSemanticName[],
    const ubyte inputSemanticIndex[],
    const GLuint interpMode[],
-   const GLbitfield inputFlags[],
    GLuint numOutputs,
    const GLuint outputMapping[],
    const ubyte outputSemanticName[],
    const ubyte outputSemanticIndex[],
-   const GLbitfield outputFlags[] );
+   boolean passthrough_edgeflags );
 
 void
 st_free_tokens(const struct tgsi_token *tokens);
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index a9be80c..6a869fa 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -50,6 +50,39 @@
 #include "cso_cache/cso_context.h"
 
 
+
+/**
+ * Clean out any old compilations:
+ */
+void
+st_vp_release_varients( struct st_context *st,
+                        struct st_vertex_program *stvp )
+{
+   struct st_vp_varient *vpv;
+
+   for (vpv = stvp->varients; vpv; ) {
+      struct st_vp_varient *next = vpv->next;
+
+      if (vpv->driver_shader) 
+         cso_delete_vertex_shader(st->cso_context, vpv->driver_shader);
+      
+      if (vpv->draw_shader)
+         draw_delete_vertex_shader( st->draw, vpv->draw_shader );
+      
+      if (vpv->state.tokens)
+         st_free_tokens(vpv->state.tokens);
+      
+      FREE( vpv );
+
+      vpv = next;
+   }
+
+   stvp->varients = NULL;
+}
+
+
+
+
 /**
  * Translate a Mesa vertex shader into a TGSI shader.
  * \param outputMapping  to map vertex program output registers (VERT_RESULT_x)
@@ -58,197 +91,78 @@
  * \return  pointer to cached pipe_shader object.
  */
 void
-st_translate_vertex_program(struct st_context *st,
-                            struct st_vertex_program *stvp,
-                            const GLuint outputMapping[],
-                            const ubyte *outputSemanticName,
-                            const ubyte *outputSemanticIndex)
+st_prepare_vertex_program(struct st_context *st,
+                            struct st_vertex_program *stvp)
 {
-   struct pipe_context *pipe = st->pipe;
-   GLuint defaultOutputMapping[VERT_RESULT_MAX];
-   GLuint attr, i;
-   GLuint num_generic = 0;
+   GLuint attr;
 
-   ubyte vs_input_semantic_name[PIPE_MAX_SHADER_INPUTS];
-   ubyte vs_input_semantic_index[PIPE_MAX_SHADER_INPUTS];
-   uint vs_num_inputs = 0;
-
-   ubyte vs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
-   ubyte vs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
-   uint vs_num_outputs = 0;
-
-   GLbitfield input_flags[MAX_PROGRAM_INPUTS];
-   GLbitfield output_flags[MAX_PROGRAM_OUTPUTS];
-
-//   memset(&vs, 0, sizeof(vs));
-   memset(input_flags, 0, sizeof(input_flags));
-   memset(output_flags, 0, sizeof(output_flags));
+   stvp->num_inputs = 0;
+   stvp->num_outputs = 0;
 
    if (stvp->Base.IsPositionInvariant)
       _mesa_insert_mvp_code(st->ctx, &stvp->Base);
 
+   assert(stvp->Base.Base.NumInstructions > 1);
+
    /*
     * Determine number of inputs, the mappings between VERT_ATTRIB_x
     * and TGSI generic input indexes, plus input attrib semantic info.
     */
    for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
       if (stvp->Base.Base.InputsRead & (1 << attr)) {
-         const GLuint slot = vs_num_inputs;
-
-         vs_num_inputs++;
-
-         stvp->input_to_index[attr] = slot;
-         stvp->index_to_input[slot] = attr;
-
-         switch (attr) {
-         case VERT_ATTRIB_POS:
-            vs_input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
-            vs_input_semantic_index[slot] = 0;
-            break;
-         case VERT_ATTRIB_WEIGHT:
-            /* fall-through */
-         case VERT_ATTRIB_NORMAL:
-            /* just label as a generic */
-            vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
-            vs_input_semantic_index[slot] = 0;
-            break;
-         case VERT_ATTRIB_COLOR0:
-            vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
-            vs_input_semantic_index[slot] = 0;
-            break;
-         case VERT_ATTRIB_COLOR1:
-            vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
-            vs_input_semantic_index[slot] = 1;
-            break;
-         case VERT_ATTRIB_FOG:
-            vs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
-            vs_input_semantic_index[slot] = 0;
-            break;
-         case VERT_ATTRIB_POINT_SIZE:
-            vs_input_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
-            vs_input_semantic_index[slot] = 0;
-            break;
-         case VERT_ATTRIB_TEX0:
-         case VERT_ATTRIB_TEX1:
-         case VERT_ATTRIB_TEX2:
-         case VERT_ATTRIB_TEX3:
-         case VERT_ATTRIB_TEX4:
-         case VERT_ATTRIB_TEX5:
-         case VERT_ATTRIB_TEX6:
-         case VERT_ATTRIB_TEX7:
-            assert(slot < Elements(vs_input_semantic_name));
-            vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
-            vs_input_semantic_index[slot] = num_generic++;
-            break;
-         case VERT_ATTRIB_GENERIC0:
-         case VERT_ATTRIB_GENERIC1:
-         case VERT_ATTRIB_GENERIC2:
-         case VERT_ATTRIB_GENERIC3:
-         case VERT_ATTRIB_GENERIC4:
-         case VERT_ATTRIB_GENERIC5:
-         case VERT_ATTRIB_GENERIC6:
-         case VERT_ATTRIB_GENERIC7:
-         case VERT_ATTRIB_GENERIC8:
-         case VERT_ATTRIB_GENERIC9:
-         case VERT_ATTRIB_GENERIC10:
-         case VERT_ATTRIB_GENERIC11:
-         case VERT_ATTRIB_GENERIC12:
-         case VERT_ATTRIB_GENERIC13:
-         case VERT_ATTRIB_GENERIC14:
-         case VERT_ATTRIB_GENERIC15:
-            assert(attr < VERT_ATTRIB_MAX);
-            assert(slot < Elements(vs_input_semantic_name));
-            vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
-            vs_input_semantic_index[slot] = num_generic++;
-            break;
-         default:
-            assert(0);
-         }
-
-         input_flags[slot] = stvp->Base.Base.InputFlags[attr];
+         stvp->input_to_index[attr] = stvp->num_inputs;
+         stvp->index_to_input[stvp->num_inputs] = attr;
+         stvp->num_inputs++;
       }
    }
+   /* bit of a hack, presetup potentially unused edgeflag input */
+   stvp->input_to_index[VERT_ATTRIB_EDGEFLAG] = stvp->num_inputs;
+   stvp->index_to_input[stvp->num_inputs] = VERT_ATTRIB_EDGEFLAG;
 
-#if 0
-   if (outputMapping && outputSemanticName) {
-      printf("VERT_RESULT  written  out_slot  semantic_name  semantic_index\n");
-      for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
-         printf("    %-2d          %c       %3d          %2d              %2d\n",
-                attr, 
-                ((stvp->Base.Base.OutputsWritten & (1 << attr)) ? 'Y' : ' '),
-                outputMapping[attr],
-                outputSemanticName[attr],
-                outputSemanticIndex[attr]);
-      }
-   }
-#endif
-
-   /* initialize output semantics to defaults */
-   for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
-      assert(i < Elements(vs_output_semantic_name));
-      vs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
-      vs_output_semantic_index[i] = 0;
-      output_flags[i] = 0x0;
-   }
-
-   num_generic = 0;
-   /*
-    * Determine number of outputs, the (default) output register
-    * mapping and the semantic information for each output.
+   /* Compute mapping of vertex program outputs to slots.
     */
    for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
-      if (stvp->Base.Base.OutputsWritten & (1 << attr)) {
-         GLuint slot;
+      if ((stvp->Base.Base.OutputsWritten & (1 << attr)) == 0) {
+         stvp->result_to_output[attr] = ~0;
+      }
+      else {
+         unsigned slot = stvp->num_outputs++;
 
-         /* XXX
-          * Pass in the fragment program's input's semantic info.
-          * Use the generic semantic indexes from there, instead of
-          * guessing below.
-          */
-
-         if (outputMapping) {
-            slot = outputMapping[attr];
-            assert(slot != ~0);
-         }
-         else {
-            slot = vs_num_outputs;
-            vs_num_outputs++;
-            defaultOutputMapping[attr] = slot;
-         }
+         stvp->result_to_output[attr] = slot;
 
          switch (attr) {
          case VERT_RESULT_HPOS:
-            assert(slot == 0);
-            vs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
-            vs_output_semantic_index[slot] = 0;
+            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
+            stvp->output_semantic_index[slot] = 0;
             break;
          case VERT_RESULT_COL0:
-            vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
-            vs_output_semantic_index[slot] = 0;
+            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+            stvp->output_semantic_index[slot] = 0;
             break;
          case VERT_RESULT_COL1:
-            vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
-            vs_output_semantic_index[slot] = 1;
+            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+            stvp->output_semantic_index[slot] = 1;
             break;
          case VERT_RESULT_BFC0:
-            vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
-            vs_output_semantic_index[slot] = 0;
+            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
+            stvp->output_semantic_index[slot] = 0;
             break;
          case VERT_RESULT_BFC1:
-            vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
-            vs_output_semantic_index[slot] = 1;
+            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
+            stvp->output_semantic_index[slot] = 1;
             break;
          case VERT_RESULT_FOGC:
-            vs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
-            vs_output_semantic_index[slot] = 0;
+            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
+            stvp->output_semantic_index[slot] = 0;
             break;
          case VERT_RESULT_PSIZ:
-            vs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
-            vs_output_semantic_index[slot] = 0;
+            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
+            stvp->output_semantic_index[slot] = 0;
             break;
          case VERT_RESULT_EDGE:
             assert(0);
             break;
+
          case VERT_RESULT_TEX0:
          case VERT_RESULT_TEX1:
          case VERT_RESULT_TEX2:
@@ -257,92 +171,79 @@
          case VERT_RESULT_TEX5:
          case VERT_RESULT_TEX6:
          case VERT_RESULT_TEX7:
-            /* fall-through */
+            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+            stvp->output_semantic_index[slot] = attr - VERT_RESULT_TEX0;
+            break;
+
          case VERT_RESULT_VAR0:
-            /* fall-through */
          default:
-            assert(slot < Elements(vs_output_semantic_name));
-            if (outputSemanticName) {
-               /* use provided semantic into */
-               assert(outputSemanticName[attr] != TGSI_SEMANTIC_COUNT);
-               vs_output_semantic_name[slot] = outputSemanticName[attr];
-               vs_output_semantic_index[slot] = outputSemanticIndex[attr];
-            }
-            else {
-               /* use default semantic info */
-               vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
-               vs_output_semantic_index[slot] = num_generic++;
-            }
-         }
-
-         assert(slot < Elements(output_flags));
-         output_flags[slot] = stvp->Base.Base.OutputFlags[attr];
-      }
-   }
-
-   if (outputMapping) {
-      /* find max output slot referenced to compute vs_num_outputs */
-      GLuint maxSlot = 0;
-      for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
-         if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot)
-            maxSlot = outputMapping[attr];
-      }
-      vs_num_outputs = maxSlot + 1;
-   }
-   else {
-      outputMapping = defaultOutputMapping;
-   }
-
-#if 0 /* debug */
-   {
-      GLuint i;
-      printf("outputMapping? %d\n", outputMapping ? 1 : 0);
-      if (outputMapping) {
-         printf("attr -> slot\n");
-         for (i = 0; i < 16;  i++) {
-            printf(" %2d       %3d\n", i, outputMapping[i]);
+            assert(attr < VERT_RESULT_MAX);
+            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+            stvp->output_semantic_index[slot] = (FRAG_ATTRIB_VAR0 - 
+                                                FRAG_ATTRIB_TEX0 +
+                                                attr - 
+                                                VERT_RESULT_VAR0);
+            break;
          }
       }
-      printf("slot    sem_name  sem_index\n");
-      for (i = 0; i < vs_num_outputs; i++) {
-         printf(" %2d         %d         %d\n",
-                i,
-                vs_output_semantic_name[i],
-                vs_output_semantic_index[i]);
-      }
    }
-#endif
+   /* similar hack to above, presetup potentially unused edgeflag output */
+   stvp->result_to_output[VERT_RESULT_EDGE] = stvp->num_outputs;
+   stvp->output_semantic_name[stvp->num_outputs] = TGSI_SEMANTIC_EDGEFLAG;
+   stvp->output_semantic_index[stvp->num_outputs] = 0;
+}
 
-   /* free old shader state, if any */
-   if (stvp->state.tokens) {
-      st_free_tokens(stvp->state.tokens);
-      stvp->state.tokens = NULL;
-   }
-   if (stvp->driver_shader) {
-      cso_delete_vertex_shader(st->cso_context, stvp->driver_shader);
-      stvp->driver_shader = NULL;
+
+struct st_vp_varient *
+st_translate_vertex_program(struct st_context *st,
+                            struct st_vertex_program *stvp,
+                            const struct st_vp_varient_key *key)
+{
+   struct st_vp_varient *vpv = CALLOC_STRUCT(st_vp_varient);
+   struct pipe_context *pipe = st->pipe;
+   struct ureg_program *ureg;
+   enum pipe_error error;
+   unsigned num_outputs;
+
+   ureg = ureg_create( TGSI_PROCESSOR_VERTEX );
+   if (ureg == NULL)
+      return NULL;
+
+   vpv->num_inputs = stvp->num_inputs;
+   num_outputs = stvp->num_outputs;
+   if (key->passthrough_edgeflags) {
+      vpv->num_inputs++;
+      num_outputs++;
    }
 
-   stvp->state.tokens = 
+   error = 
       st_translate_mesa_program(st->ctx,
                                 TGSI_PROCESSOR_VERTEX,
+                                ureg,
                                 &stvp->Base.Base,
                                 /* inputs */
-                                vs_num_inputs,
+                                vpv->num_inputs,
                                 stvp->input_to_index,
-                                vs_input_semantic_name,
-                                vs_input_semantic_index,
+                                NULL, /* input semantic name */
+                                NULL, /* input semantic index */
                                 NULL,
-                                input_flags,
                                 /* outputs */
-                                vs_num_outputs,
-                                outputMapping,
-                                vs_output_semantic_name,
-                                vs_output_semantic_index,
-                                output_flags );
+                                num_outputs,
+                                stvp->result_to_output,
+                                stvp->output_semantic_name,
+                                stvp->output_semantic_index,
+                                key->passthrough_edgeflags );
 
-   stvp->num_inputs = vs_num_inputs;
-   stvp->driver_shader = pipe->create_vs_state(pipe, &stvp->state);
+   if (error)
+      goto fail;
+
+   vpv->state.tokens = ureg_get_tokens( ureg, NULL );
+   if (!vpv->state.tokens)
+      goto fail;
+
+   ureg_destroy( ureg );
+
+   vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->state);
 
    if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
       _mesa_print_program(&stvp->Base.Base);
@@ -350,9 +251,19 @@
    }
 
    if (ST_DEBUG & DEBUG_TGSI) {
-      tgsi_dump( stvp->state.tokens, 0 );
+      tgsi_dump( vpv->state.tokens, 0 );
       debug_printf("\n");
    }
+
+   return vpv;
+
+fail:
+   debug_printf("%s: failed to translate Mesa program:\n", __FUNCTION__);
+   _mesa_print_program(&stvp->Base.Base);
+   debug_assert(0);
+
+   ureg_destroy( ureg );
+   return NULL;
 }
 
 
@@ -373,9 +284,10 @@
    GLuint defaultInputMapping[FRAG_ATTRIB_MAX];
    GLuint interpMode[16];  /* XXX size? */
    GLuint attr;
+   enum pipe_error error;
    const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
+   struct ureg_program *ureg;
    GLuint vslot = 0;
-   GLuint num_generic = 0;
 
    uint fs_num_inputs = 0;
 
@@ -383,13 +295,6 @@
    ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
    uint fs_num_outputs = 0;
 
-   GLbitfield input_flags[MAX_PROGRAM_INPUTS];
-   GLbitfield output_flags[MAX_PROGRAM_OUTPUTS];
-
-//   memset(&fs, 0, sizeof(fs));
-   memset(input_flags, 0, sizeof(input_flags));
-   memset(output_flags, 0, sizeof(output_flags));
-
    /* which vertex output goes to the first fragment input: */
    if (inputsRead & FRAG_BIT_WPOS)
       vslot = 0;
@@ -432,14 +337,25 @@
             break;
          case FRAG_ATTRIB_FACE:
             stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FACE;
-            stfp->input_semantic_index[slot] = num_generic++;
+            stfp->input_semantic_index[slot] = 0;
             interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
             break;
-         case FRAG_ATTRIB_PNTC:
-            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
-            stfp->input_semantic_index[slot] = num_generic++;
-            interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
-            break;
+
+            /* In most cases, there is nothing special about these
+             * inputs, so adopt a convention to use the generic
+             * semantic name and the mesa FRAG_ATTRIB_ number as the
+             * index. 
+             * 
+             * All that is required is that the vertex shader labels
+             * its own outputs similarly, and that the vertex shader
+             * generates at least every output required by the
+             * fragment shader plus fixed-function hardware (such as
+             * BFC).
+             * 
+             * There is no requirement that semantic indexes start at
+             * zero or be restricted to a particular range -- nobody
+             * should be building tables based on semantic index.
+             */
          case FRAG_ATTRIB_TEX0:
          case FRAG_ATTRIB_TEX1:
          case FRAG_ATTRIB_TEX2:
@@ -448,19 +364,18 @@
          case FRAG_ATTRIB_TEX5:
          case FRAG_ATTRIB_TEX6:
          case FRAG_ATTRIB_TEX7:
+         case FRAG_ATTRIB_PNTC:
+         case FRAG_ATTRIB_VAR0:
+         default:
+            /* Actually, let's try and zero-base this just for
+             * 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;
-            stfp->input_semantic_index[slot] = num_generic++;
             interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
             break;
-         case FRAG_ATTRIB_VAR0:
-            /* fall-through */
-         default:
-            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
-            stfp->input_semantic_index[slot] = num_generic++;
-            interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
          }
-
-         input_flags[slot] = stfp->Base.Base.InputFlags[attr];
       }
    }
 
@@ -469,7 +384,7 @@
     */
    {
       uint numColors = 0;
-      GLbitfield outputsWritten = stfp->Base.Base.OutputsWritten;
+      GLbitfield64 outputsWritten = stfp->Base.Base.OutputsWritten;
 
       /* if z is written, emit that first */
       if (outputsWritten & (1 << FRAG_RESULT_DEPTH)) {
@@ -498,8 +413,6 @@
                break;
             }
 
-            output_flags[fs_num_outputs] = stfp->Base.Base.OutputFlags[attr];
-
             fs_num_outputs++;
          }
       }
@@ -508,9 +421,15 @@
    if (!inputMapping)
       inputMapping = defaultInputMapping;
 
-   stfp->state.tokens = 
+   ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
+   if (ureg == NULL)
+      return;
+
+
+   error = 
       st_translate_mesa_program(st->ctx,
                                 TGSI_PROCESSOR_FRAGMENT,
+                                ureg,
                                 &stfp->Base.Base,
                                 /* inputs */
                                 fs_num_inputs,
@@ -518,14 +437,14 @@
                                 stfp->input_semantic_name,
                                 stfp->input_semantic_index,
                                 interpMode,
-                                input_flags,
                                 /* outputs */
                                 fs_num_outputs,
                                 outputMapping,
                                 fs_output_semantic_name,
-                                fs_output_semantic_index,
-                                output_flags );
+                                fs_output_semantic_index, FALSE );
 
+   stfp->state.tokens = ureg_get_tokens( ureg, NULL );
+   ureg_destroy( ureg );
    stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->state);
 
    if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index e2e5edd..6b9a922 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -64,41 +64,73 @@
    struct pipe_shader_state state;
    void *driver_shader;
 
-   GLuint param_state;
-
-   /** List of vertex programs which have been translated such that their
-    * outputs match this fragment program's inputs.
-    */
-   struct translated_vertex_program *vertex_programs;
-
    /** Program prefixed with glBitmap prologue */
    struct st_fragment_program *bitmap_program;
    uint bitmap_sampler;
 };
 
 
+
+struct st_vp_varient_key
+{
+   boolean passthrough_edgeflags;
+};
+
+
+/**
+ * This represents a vertex program, especially translated to match
+ * the inputs of a particular fragment shader.
+ */
+struct st_vp_varient
+{
+   /* Parameters which generated this translated version of a vertex
+    * shader:
+    */
+   struct st_vp_varient_key key;
+
+   /** TGSI tokens -- why?
+    */
+   struct pipe_shader_state state;
+
+   /** Driver's compiled shader */
+   void *driver_shader;
+
+   /** For using our private draw module (glRasterPos) */
+   struct draw_vertex_shader *draw_shader;
+
+   /** Next in linked list */
+   struct st_vp_varient *next;  
+
+   /** similar to that in st_vertex_program, but with information about edgeflags too */
+   GLuint num_inputs;
+};
+
+
+
+
 /**
  * Derived from Mesa gl_fragment_program:
  */
 struct st_vertex_program
 {
    struct gl_vertex_program Base;  /**< The Mesa vertex program */
-   GLuint serialNo;
+   GLuint serialNo, lastSerialNo;
 
    /** maps a Mesa VERT_ATTRIB_x to a packed TGSI input index */
    GLuint input_to_index[VERT_ATTRIB_MAX];
    /** maps a TGSI input index back to a Mesa VERT_ATTRIB_x */
    GLuint index_to_input[PIPE_MAX_SHADER_INPUTS];
-
    GLuint num_inputs;
 
-   struct pipe_shader_state state;
-   void *driver_shader;
+   /** Maps VERT_RESULT_x to slot */
+   GLuint result_to_output[VERT_RESULT_MAX];
+   ubyte output_semantic_name[VERT_RESULT_MAX];
+   ubyte output_semantic_index[VERT_RESULT_MAX];
+   GLuint num_outputs;
 
-   /** For using our private draw module (glRasterPos) */
-   struct draw_vertex_shader *draw_shader;
-
-   GLuint param_state;
+   /** List of translated varients of this vertex program.
+    */
+   struct st_vp_varient *varients;
 };
 
 
@@ -143,13 +175,21 @@
                               const GLuint inputMapping[]);
 
 
+/* Called after program string change, discard all previous
+ * compilation results.
+ */
 extern void
-st_translate_vertex_program(struct st_context *st,
-                            struct st_vertex_program *vp,
-                            const GLuint vert_output_to_slot[],
-                            const ubyte *fs_input_semantic_name,
-                            const ubyte *fs_input_semantic_index);
+st_prepare_vertex_program(struct st_context *st,
+                          struct st_vertex_program *stvp);
 
+extern struct st_vp_varient *
+st_translate_vertex_program(struct st_context *st,
+                            struct st_vertex_program *stvp,
+                            const struct st_vp_varient_key *key);
+
+void
+st_vp_release_varients( struct st_context *st,
+                        struct st_vertex_program *stvp );
 
 extern void
 st_print_shaders(GLcontext *ctx);
diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h
index a5fdac3..98c1981 100644
--- a/src/mesa/state_tracker/st_public.h
+++ b/src/mesa/state_tracker/st_public.h
@@ -56,15 +56,19 @@
 struct pipe_texture;
 
 
+PUBLIC
 struct st_context *st_create_context(struct pipe_context *pipe,
                                      const __GLcontextModes *visual,
                                      struct st_context *share);
 
+PUBLIC
 void st_destroy_context( struct st_context *st );
 
+PUBLIC
 void st_copy_context_state(struct st_context *dst, struct st_context *src,
                            uint mask);
 
+PUBLIC
 struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual,
                                               enum pipe_format colorFormat,
                                               enum pipe_format depthFormat,
@@ -72,50 +76,67 @@
                                               uint width, uint height,
                                               void *privateData);
 
+PUBLIC
 void st_resize_framebuffer( struct st_framebuffer *stfb,
                             uint width, uint height );
 
+PUBLIC
 void st_set_framebuffer_surface(struct st_framebuffer *stfb,
                                 uint surfIndex, struct pipe_surface *surf);
 
+PUBLIC
 void st_get_framebuffer_dimensions( struct st_framebuffer *stfb,
 				    uint *width, uint *height);
 
+PUBLIC
 int st_get_framebuffer_surface(struct st_framebuffer *stfb,
                                uint surfIndex, struct pipe_surface **surface);
 
+PUBLIC
 int st_get_framebuffer_texture(struct st_framebuffer *stfb,
                                uint surfIndex, struct pipe_texture **texture);
 
+PUBLIC
 void *st_framebuffer_private( struct st_framebuffer *stfb );
 
+PUBLIC
 void st_unreference_framebuffer( struct st_framebuffer *stfb );
 
+PUBLIC
 GLboolean st_make_current(struct st_context *st,
                           struct st_framebuffer *draw,
                           struct st_framebuffer *read);
 
+PUBLIC
 struct st_context *st_get_current(void);
 
+PUBLIC
 void st_flush( struct st_context *st, uint pipeFlushFlags,
                struct pipe_fence_handle **fence );
+PUBLIC
 void st_finish( struct st_context *st );
 
+PUBLIC
 void st_notify_swapbuffers(struct st_framebuffer *stfb);
 
+PUBLIC
 void st_swapbuffers(struct st_framebuffer *stfb,
                     struct pipe_surface **front_left,
                     struct pipe_surface **front_right);
 
+PUBLIC
 int st_bind_texture_surface(struct pipe_surface *ps, int target, int level,
                             enum pipe_format format);
+PUBLIC
 int st_unbind_texture_surface(struct pipe_surface *ps, int target, int level);
 
 /** Redirect rendering into stfb's surface to a texture image */
+PUBLIC
 int st_bind_teximage(struct st_framebuffer *stfb, uint surfIndex,
                      int target, int format, int level);
 
 /** Undo surface-to-texture binding */
+PUBLIC
 int st_release_teximage(struct st_framebuffer *stfb, uint surfIndex,
                         int target, int format, int level);
 
@@ -123,6 +144,7 @@
 /** Generic function type */
 typedef void (*st_proc)();
 
+PUBLIC
 st_proc st_get_proc_address(const char *procname);
 
 
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index 3945822..8a3e4cd 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -43,7 +43,9 @@
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
+#include "util/u_format.h"
 #include "util/u_rect.h"
+#include "util/u_math.h"
 
 
 #define DBG if(0) printf
@@ -100,10 +102,9 @@
    pt.target = target;
    pt.format = format;
    pt.last_level = last_level;
-   pt.width[0] = width0;
-   pt.height[0] = height0;
-   pt.depth[0] = depth0;
-   pf_get_block(format, &pt.block);
+   pt.width0 = width0;
+   pt.height0 = height0;
+   pt.depth0 = depth0;
    pt.tex_usage = usage;
 
    newtex = screen->texture_create(screen, &pt);
@@ -135,9 +136,9 @@
    /* Test if this image's size matches what's expected in the
     * established texture.
     */
-   if (image->Width != pt->width[level] ||
-       image->Height != pt->height[level] ||
-       image->Depth != pt->depth[level])
+   if (image->Width != u_minify(pt->width0, level) ||
+       image->Height != u_minify(pt->height0, level) ||
+       image->Depth != u_minify(pt->depth0, level))
       return GL_FALSE;
 
    return GL_TRUE;
@@ -241,8 +242,9 @@
    struct pipe_screen *screen = pipe->screen;
    void *map = screen->transfer_map(screen, dst);
 
+   assert(dst->texture);
    util_copy_rect(map,
-                  &dst->block,
+                  dst->texture->format,
                   dst->stride,
                   dstx, dsty, 
                   width, height, 
@@ -265,7 +267,7 @@
 {
    struct pipe_context *pipe = st->pipe;
    struct pipe_screen *screen = pipe->screen;
-   GLuint depth = dst->depth[level];
+   GLuint depth = u_minify(dst->depth0, level);
    GLuint i;
    const GLubyte *srcUB = src;
    struct pipe_transfer *dst_transfer;
@@ -275,15 +277,16 @@
    for (i = 0; i < depth; i++) {
       dst_transfer = st_no_flush_get_tex_transfer(st, dst, face, level, i,
 						  PIPE_TRANSFER_WRITE, 0, 0,
-						  dst->width[level],
-						  dst->height[level]);
+						  u_minify(dst->width0, level),
+                                                  u_minify(dst->height0, level));
 
       st_surface_data(pipe, dst_transfer,
 		      0, 0,                             /* dstx, dsty */
 		      srcUB,
 		      src_row_stride,
 		      0, 0,                             /* source x, y */
-		      dst->width[level], dst->height[level]);       /* width, height */
+		      u_minify(dst->width0, level),
+                      u_minify(dst->height0, level));      /* width, height */
 
       screen->tex_transfer_destroy(dst_transfer);
 
@@ -301,9 +304,9 @@
                       GLuint face)
 {
    struct pipe_screen *screen = pipe->screen;
-   GLuint width = dst->width[dstLevel];
-   GLuint height = dst->height[dstLevel];
-   GLuint depth = dst->depth[dstLevel];
+   GLuint width = u_minify(dst->width0, dstLevel); 
+   GLuint height = u_minify(dst->height0, dstLevel); 
+   GLuint depth = u_minify(dst->depth0, dstLevel); 
    struct pipe_surface *src_surface;
    struct pipe_surface *dst_surface;
    GLuint i;
@@ -313,13 +316,13 @@
 
       /* find src texture level of needed size */
       for (srcLevel = 0; srcLevel <= src->last_level; srcLevel++) {
-         if (src->width[srcLevel] == width &&
-             src->height[srcLevel] == height) {
+         if (u_minify(src->width0, srcLevel) == width &&
+             u_minify(src->height0, srcLevel) == height) {
             break;
          }
       }
-      assert(src->width[srcLevel] == width);
-      assert(src->height[srcLevel] == height);
+      assert(u_minify(src->width0, srcLevel) == width);
+      assert(u_minify(src->height0, srcLevel) == height);
 
 #if 0
       {
@@ -403,7 +406,7 @@
    }
 
    /* map pipe format to base format for now */
-   if (pf_get_component_bits(format, PIPE_FORMAT_COMP_A) > 0)
+   if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3) > 0)
       internalFormat = GL_RGBA;
    else
       internalFormat = GL_RGB;
@@ -588,5 +591,5 @@
 
    if (referenced && ((referenced & PIPE_REFERENCED_FOR_WRITE) ||
 		      (usage & PIPE_TRANSFER_WRITE)))
-      st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL);
+      st->pipe->flush(st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
 }
diff --git a/src/mesa/swrast/s_accum.c b/src/mesa/swrast/s_accum.c
index c6c7dbf..0e0876e 100644
--- a/src/mesa/swrast/s_accum.c
+++ b/src/mesa/swrast/s_accum.c
@@ -436,10 +436,6 @@
    struct gl_renderbuffer *accumRb = fb->Attachment[BUFFER_ACCUM].Renderbuffer;
    const GLboolean directAccess
       = (accumRb->GetPointer(ctx, accumRb, 0, 0) != NULL);
-   const GLboolean masking = (!ctx->Color.ColorMask[RCOMP] ||
-                              !ctx->Color.ColorMask[GCOMP] ||
-                              !ctx->Color.ColorMask[BCOMP] ||
-                              !ctx->Color.ColorMask[ACOMP]);
 
    static GLchan multTable[32768];
    static GLfloat prevMult = 0.0;
@@ -527,8 +523,12 @@
          /* store colors */
          for (buffer = 0; buffer < fb->_NumColorDrawBuffers; buffer++) {
             struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buffer];
+            const GLboolean masking = (!ctx->Color.ColorMask[buffer][RCOMP] ||
+                                       !ctx->Color.ColorMask[buffer][GCOMP] ||
+                                       !ctx->Color.ColorMask[buffer][BCOMP] ||
+                                       !ctx->Color.ColorMask[buffer][ACOMP]);
             if (masking) {
-               _swrast_mask_rgba_span(ctx, rb, &span);
+               _swrast_mask_rgba_span(ctx, rb, &span, buffer);
             }
             rb->PutRow(ctx, rb, width, xpos, ypos + i, span.array->rgba, NULL);
          }
diff --git a/src/mesa/swrast/s_atifragshader.c b/src/mesa/swrast/s_atifragshader.c
index 5fefae6..e88ff19 100644
--- a/src/mesa/swrast/s_atifragshader.c
+++ b/src/mesa/swrast/s_atifragshader.c
@@ -279,7 +279,7 @@
 /* sample from unit idx using texinst->src as coords */
    GLuint swizzle = texinst->swizzle;
    GLuint coord_source = texinst->src;
-   GLfloat tex_coords[4];
+   GLfloat tex_coords[4] = { 0 };
 
    if (coord_source >= GL_TEXTURE0_ARB && coord_source <= GL_TEXTURE7_ARB) {
       coord_source -= GL_TEXTURE0_ARB;
diff --git a/src/mesa/swrast/s_bitmap.c b/src/mesa/swrast/s_bitmap.c
index 3dbdf2a..46c63aa 100644
--- a/src/mesa/swrast/s_bitmap.c
+++ b/src/mesa/swrast/s_bitmap.c
@@ -30,6 +30,7 @@
 
 #include "main/glheader.h"
 #include "main/bufferobj.h"
+#include "main/condrender.h"
 #include "main/image.h"
 #include "main/macros.h"
 #include "main/pixel.h"
@@ -56,6 +57,9 @@
 
    ASSERT(ctx->RenderMode == GL_RENDER);
 
+   if (!_mesa_check_conditional_render(ctx))
+      return; /* don't draw */
+
    bitmap = (const GLubyte *) _mesa_map_pbo_source(ctx, unpack, bitmap);
    if (!bitmap)
       return;
diff --git a/src/mesa/swrast/s_blit.c b/src/mesa/swrast/s_blit.c
index 8303e4d..f73ac78 100644
--- a/src/mesa/swrast/s_blit.c
+++ b/src/mesa/swrast/s_blit.c
@@ -24,6 +24,7 @@
 
 
 #include "main/glheader.h"
+#include "main/condrender.h"
 #include "main/image.h"
 #include "main/macros.h"
 #include "s_context.h"
@@ -567,6 +568,9 @@
    };
    GLint i;
 
+   if (!_mesa_check_conditional_render(ctx))
+      return; /* don't clear */
+
    if (!ctx->DrawBuffer->_NumColorDrawBuffers)
       return;
 
diff --git a/src/mesa/swrast/s_clear.c b/src/mesa/swrast/s_clear.c
index 002718d..21167a6 100644
--- a/src/mesa/swrast/s_clear.c
+++ b/src/mesa/swrast/s_clear.c
@@ -24,6 +24,7 @@
 
 #include "main/glheader.h"
 #include "main/colormac.h"
+#include "main/condrender.h"
 #include "main/formats.h"
 #include "main/macros.h"
 #include "main/imports.h"
@@ -40,7 +41,8 @@
  * Clear the color buffer when glColorMask is in effect.
  */
 static void
-clear_rgba_buffer_with_masking(GLcontext *ctx, struct gl_renderbuffer *rb)
+clear_rgba_buffer_with_masking(GLcontext *ctx, struct gl_renderbuffer *rb,
+                               GLuint buf)
 {
    const GLint x = ctx->DrawBuffer->_Xmin;
    const GLint y = ctx->DrawBuffer->_Ymin;
@@ -95,7 +97,7 @@
    for (i = 0; i < height; i++) {
       span.x = x;
       span.y = y + i;
-      _swrast_mask_rgba_span(ctx, rb, &span);
+      _swrast_mask_rgba_span(ctx, rb, &span, buf);
       /* write masked row */
       rb->PutRow(ctx, rb, width, x, y + i, span.array->rgba, NULL);
    }
@@ -145,7 +147,7 @@
  * Clear an rgba color buffer without channel masking.
  */
 static void
-clear_rgba_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
+clear_rgba_buffer(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint buf)
 {
    const GLint x = ctx->DrawBuffer->_Xmin;
    const GLint y = ctx->DrawBuffer->_Ymin;
@@ -158,10 +160,10 @@
 
    ASSERT(ctx->Visual.rgbMode);
 
-   ASSERT(ctx->Color.ColorMask[0] &&
-          ctx->Color.ColorMask[1] &&
-          ctx->Color.ColorMask[2] &&
-          ctx->Color.ColorMask[3]);             
+   ASSERT(ctx->Color.ColorMask[buf][0] &&
+          ctx->Color.ColorMask[buf][1] &&
+          ctx->Color.ColorMask[buf][2] &&
+          ctx->Color.ColorMask[buf][3]);             
 
    ASSERT(rb->PutMonoRow);
 
@@ -246,43 +248,24 @@
 static void
 clear_color_buffers(GLcontext *ctx)
 {
-   GLboolean masking;
    GLuint buf;
 
-   if (ctx->Visual.rgbMode) {
-      if (ctx->Color.ColorMask[0] && 
-          ctx->Color.ColorMask[1] && 
-          ctx->Color.ColorMask[2] && 
-          ctx->Color.ColorMask[3]) {
-         masking = GL_FALSE;
-      }
-      else {
-         masking = GL_TRUE;
-      }
-   }
-   else {
-      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
-      const GLuint indexMask = (1 << _mesa_get_format_bits(rb->Format, GL_INDEX_BITS)) - 1;
-      if ((ctx->Color.IndexMask & indexMask) == indexMask) {
-         masking = GL_FALSE;
-      }
-      else {
-         masking = GL_TRUE;
-      }
-   }
-
    for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) {
       struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[buf];
       if (ctx->Visual.rgbMode) {
-         if (masking) {
-            clear_rgba_buffer_with_masking(ctx, rb);
+         if (ctx->Color.ColorMask[buf][0] == 0 || 
+             ctx->Color.ColorMask[buf][1] == 0 || 
+             ctx->Color.ColorMask[buf][2] == 0 || 
+             ctx->Color.ColorMask[buf][3] == 0) {
+            clear_rgba_buffer_with_masking(ctx, rb, buf);
          }
          else {
-            clear_rgba_buffer(ctx, rb);
+            clear_rgba_buffer(ctx, rb, buf);
          }
       }
       else {
-         if (masking) {
+         const GLuint indexMask = (1 << _mesa_get_format_bits(rb->Format, GL_INDEX_BITS)) - 1;
+         if ((ctx->Color.IndexMask & indexMask) != indexMask) {
             clear_ci_buffer_with_masking(ctx, rb);
          }
          else {
@@ -318,6 +301,9 @@
    }
 #endif
 
+   if (!_mesa_check_conditional_render(ctx))
+      return; /* don't clear */
+
    swrast_render_start(ctx);
 
    /* do software clearing here */
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index abf0008..f9092c2 100644
--- a/src/mesa/swrast/s_context.c
+++ b/src/mesa/swrast/s_context.c
@@ -55,6 +55,7 @@
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLbitfield rasterMask = 0;
+   GLuint i;
 
    if (ctx->Color.AlphaEnabled)           rasterMask |= ALPHATEST_BIT;
    if (ctx->Color.BlendEnabled)           rasterMask |= BLEND_BIT;
@@ -63,8 +64,15 @@
    if (ctx->Scissor.Enabled)              rasterMask |= CLIP_BIT;
    if (ctx->Stencil._Enabled)             rasterMask |= STENCIL_BIT;
    if (ctx->Visual.rgbMode) {
-      const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
-      if (colorMask != 0xffffffff)        rasterMask |= MASKING_BIT;
+      for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
+         if (!ctx->Color.ColorMask[i][0] ||
+             !ctx->Color.ColorMask[i][1] ||
+             !ctx->Color.ColorMask[i][2] ||
+             !ctx->Color.ColorMask[i][3]) {
+            rasterMask |= MASKING_BIT;
+            break;
+         }
+      }
       if (ctx->Color._LogicOpEnabled)     rasterMask |= LOGIC_OP_BIT;
       if (ctx->Texture._EnabledUnits)     rasterMask |= TEXTURE_BIT;
    }
@@ -92,13 +100,23 @@
       /* more than one color buffer designated for writing (or zero buffers) */
       rasterMask |= MULTI_DRAW_BIT;
    }
-   else if (ctx->Visual.rgbMode && *((GLuint *) ctx->Color.ColorMask) == 0) {
-      rasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */
-   }
    else if (!ctx->Visual.rgbMode && ctx->Color.IndexMask==0) {
       rasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */
    }
 
+   if (ctx->Visual.rgbMode) {
+      for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
+         if (ctx->Color.ColorMask[i][0] +
+             ctx->Color.ColorMask[i][1] +
+             ctx->Color.ColorMask[i][2] +
+             ctx->Color.ColorMask[i][3] == 0) {
+            rasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */
+            break;
+         }
+      }
+   }
+
+
    if (ctx->FragmentProgram._Current) {
       rasterMask |= FRAGPROG_BIT;
    }
diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c
index 5ecfb1e..986b6af 100644
--- a/src/mesa/swrast/s_copypix.c
+++ b/src/mesa/swrast/s_copypix.c
@@ -26,6 +26,7 @@
 #include "main/glheader.h"
 #include "main/context.h"
 #include "main/colormac.h"
+#include "main/condrender.h"
 #include "main/convolve.h"
 #include "main/histogram.h"
 #include "main/image.h"
@@ -901,6 +902,9 @@
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    swrast_render_start(ctx);
       
+   if (!_mesa_check_conditional_render(ctx))
+      return; /* don't copy */
+
    if (swrast->NewState)
       _swrast_validate_derived( ctx );
 
diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c
index 6970b2e..55a4c4c 100644
--- a/src/mesa/swrast/s_drawpix.c
+++ b/src/mesa/swrast/s_drawpix.c
@@ -25,6 +25,7 @@
 
 #include "main/glheader.h"
 #include "main/bufferobj.h"
+#include "main/condrender.h"
 #include "main/context.h"
 #include "main/convolve.h"
 #include "main/image.h"
@@ -831,6 +832,9 @@
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    GLboolean save_vp_override = ctx->VertexProgram._Overriden;
 
+   if (!_mesa_check_conditional_render(ctx))
+      return; /* don't draw */
+
    /* We are creating fragments directly, without going through vertex
     * programs.
     *
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index 77a77f0..a22d344 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -190,7 +190,7 @@
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const struct gl_fragment_program *program = ctx->FragmentProgram._Current;
-   const GLbitfield outputsWritten = program->Base.OutputsWritten;
+   const GLbitfield64 outputsWritten = program->Base.OutputsWritten;
    struct gl_program_machine *machine = &swrast->FragProgMachine;
    GLuint i;
 
@@ -201,7 +201,7 @@
          if (_mesa_execute_program(ctx, &program->Base, machine)) {
 
             /* Store result color */
-            if (outputsWritten & (1 << FRAG_RESULT_COLOR)) {
+	    if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) {
                COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i],
                        machine->Outputs[FRAG_RESULT_COLOR]);
             }
@@ -212,7 +212,7 @@
                 */
                GLuint buf;
                for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) {
-                  if (outputsWritten & (1 << (FRAG_RESULT_DATA0 + buf))) {
+                  if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_DATA0 + buf)) {
                      COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0 + buf][i],
                              machine->Outputs[FRAG_RESULT_DATA0 + buf]);
                   }
@@ -220,7 +220,7 @@
             }
 
             /* Store result depth/z */
-            if (outputsWritten & (1 << FRAG_RESULT_DEPTH)) {
+            if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
                const GLfloat depth = machine->Outputs[FRAG_RESULT_DEPTH][2];
                if (depth <= 0.0)
                   span->array->z[i] = 0;
@@ -256,12 +256,12 @@
 
    run_program(ctx, span, 0, span->end);
 
-   if (program->Base.OutputsWritten & (1 << FRAG_RESULT_COLOR)) {
+   if (program->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) {
       span->interpMask &= ~SPAN_RGBA;
       span->arrayMask |= SPAN_RGBA;
    }
 
-   if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPTH)) {
+   if (program->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
       span->interpMask &= ~SPAN_Z;
       span->arrayMask |= SPAN_Z;
    }
diff --git a/src/mesa/swrast/s_masking.c b/src/mesa/swrast/s_masking.c
index df779b0..69c2feb 100644
--- a/src/mesa/swrast/s_masking.c
+++ b/src/mesa/swrast/s_masking.c
@@ -41,7 +41,7 @@
  */
 void
 _swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
-                       SWspan *span)
+                       SWspan *span, GLuint buf)
 {
    const GLuint n = span->end;
    void *rbPixels;
@@ -58,7 +58,7 @@
     */
    if (span->array->ChanType == GL_UNSIGNED_BYTE) {
       /* treat 4xGLubyte as 1xGLuint */
-      const GLuint srcMask = *((GLuint *) ctx->Color.ColorMask);
+      const GLuint srcMask = *((GLuint *) ctx->Color.ColorMask[buf]);
       const GLuint dstMask = ~srcMask;
       const GLuint *dst = (const GLuint *) rbPixels;
       GLuint *src = (GLuint *) span->array->rgba8;
@@ -70,10 +70,10 @@
    else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
       /* 2-byte components */
       /* XXX try to use 64-bit arithmetic someday */
-      const GLushort rMask = ctx->Color.ColorMask[RCOMP] ? 0xffff : 0x0;
-      const GLushort gMask = ctx->Color.ColorMask[GCOMP] ? 0xffff : 0x0;
-      const GLushort bMask = ctx->Color.ColorMask[BCOMP] ? 0xffff : 0x0;
-      const GLushort aMask = ctx->Color.ColorMask[ACOMP] ? 0xffff : 0x0;
+      const GLushort rMask = ctx->Color.ColorMask[buf][RCOMP] ? 0xffff : 0x0;
+      const GLushort gMask = ctx->Color.ColorMask[buf][GCOMP] ? 0xffff : 0x0;
+      const GLushort bMask = ctx->Color.ColorMask[buf][BCOMP] ? 0xffff : 0x0;
+      const GLushort aMask = ctx->Color.ColorMask[buf][ACOMP] ? 0xffff : 0x0;
       const GLushort (*dst)[4] = (const GLushort (*)[4]) rbPixels;
       GLushort (*src)[4] = span->array->rgba16;
       GLuint i;
@@ -86,10 +86,10 @@
    }
    else {
       /* 4-byte components */
-      const GLuint rMask = ctx->Color.ColorMask[RCOMP] ? ~0x0 : 0x0;
-      const GLuint gMask = ctx->Color.ColorMask[GCOMP] ? ~0x0 : 0x0;
-      const GLuint bMask = ctx->Color.ColorMask[BCOMP] ? ~0x0 : 0x0;
-      const GLuint aMask = ctx->Color.ColorMask[ACOMP] ? ~0x0 : 0x0;
+      const GLuint rMask = ctx->Color.ColorMask[buf][RCOMP] ? ~0x0 : 0x0;
+      const GLuint gMask = ctx->Color.ColorMask[buf][GCOMP] ? ~0x0 : 0x0;
+      const GLuint bMask = ctx->Color.ColorMask[buf][BCOMP] ? ~0x0 : 0x0;
+      const GLuint aMask = ctx->Color.ColorMask[buf][ACOMP] ? ~0x0 : 0x0;
       const GLuint (*dst)[4] = (const GLuint (*)[4]) rbPixels;
       GLuint (*src)[4] = (GLuint (*)[4]) span->array->attribs[FRAG_ATTRIB_COL0];
       GLuint i;
diff --git a/src/mesa/swrast/s_masking.h b/src/mesa/swrast/s_masking.h
index 3260ca3..fed47f8 100644
--- a/src/mesa/swrast/s_masking.h
+++ b/src/mesa/swrast/s_masking.h
@@ -32,7 +32,7 @@
 
 extern void
 _swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
-                       SWspan *span);
+                       SWspan *span, GLuint buf);
 
 
 extern void
diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c
index a1aeb2e..44a11cd 100644
--- a/src/mesa/swrast/s_readpix.c
+++ b/src/mesa/swrast/s_readpix.c
@@ -29,6 +29,7 @@
 #include "main/convolve.h"
 #include "main/context.h"
 #include "main/feedback.h"
+#include "main/formats.h"
 #include "main/image.h"
 #include "main/macros.h"
 #include "main/imports.h"
@@ -107,7 +108,7 @@
        && !biasOrScale && !packing->SwapBytes) {
       /* Special case: directly read 16-bit unsigned depth values. */
       GLint j;
-      ASSERT(rb->InternalFormat == GL_DEPTH_COMPONENT16);
+      ASSERT(rb->Format == MESA_FORMAT_Z16);
       ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
       for (j = 0; j < height; j++, y++) {
          void *dest =_mesa_image_address2d(packing, pixels, width, height,
@@ -119,8 +120,12 @@
             && !biasOrScale && !packing->SwapBytes) {
       /* Special case: directly read 24-bit unsigned depth values. */
       GLint j;
-      ASSERT(rb->InternalFormat == GL_DEPTH_COMPONENT24);
-      ASSERT(rb->DataType == GL_UNSIGNED_INT);
+      ASSERT(rb->Format == MESA_FORMAT_X8_Z24 ||
+             rb->Format == MESA_FORMAT_S8_Z24 ||
+             rb->Format == MESA_FORMAT_Z24_X8 ||
+             rb->Format == MESA_FORMAT_Z24_S8);
+      ASSERT(rb->DataType == GL_UNSIGNED_INT ||
+             rb->DataType == GL_UNSIGNED_INT_24_8);
       for (j = 0; j < height; j++, y++) {
          GLuint *dest = (GLuint *)
             _mesa_image_address2d(packing, pixels, width, height,
@@ -128,9 +133,18 @@
          GLint k;
          rb->GetRow(ctx, rb, width, x, y, dest);
          /* convert range from 24-bit to 32-bit */
-         for (k = 0; k < width; k++) {
-            /* Note: put MSByte of 24-bit value into LSByte */
-            dest[k] = (dest[k] << 8) | ((dest[k] >> 16) & 0xff);
+         if (rb->Format == MESA_FORMAT_X8_Z24 ||
+             rb->Format == MESA_FORMAT_S8_Z24) {
+            for (k = 0; k < width; k++) {
+               /* Note: put MSByte of 24-bit value into LSByte */
+               dest[k] = (dest[k] << 8) | ((dest[k] >> 16) & 0xff);
+            }
+         }
+         else {
+            for (k = 0; k < width; k++) {
+               /* Note: fill in LSByte by replication */
+               dest[k] = dest[k] | ((dest[k] >> 8) & 0xff);
+            }
          }
       }
    }
@@ -138,7 +152,7 @@
             && !biasOrScale && !packing->SwapBytes) {
       /* Special case: directly read 32-bit unsigned depth values. */
       GLint j;
-      ASSERT(rb->InternalFormat == GL_DEPTH_COMPONENT32);
+      ASSERT(rb->Format == MESA_FORMAT_Z32);
       ASSERT(rb->DataType == GL_UNSIGNED_INT);
       for (j = 0; j < height; j++, y++) {
          void *dest = _mesa_image_address2d(packing, pixels, width, height,
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
index d36c813..4ea9547 100644
--- a/src/mesa/swrast/s_span.c
+++ b/src/mesa/swrast/s_span.c
@@ -1278,7 +1278,7 @@
 _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)
 {
    const SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
+   const GLuint *colorMask = (GLuint *) ctx->Color.ColorMask;
    const GLbitfield origInterpMask = span->interpMask;
    const GLbitfield origArrayMask = span->arrayMask;
    const GLbitfield origArrayAttribs = span->arrayAttribs;
@@ -1389,7 +1389,7 @@
    /* We had to wait until now to check for glColorMask(0,0,0,0) because of
     * the occlusion test.
     */
-   if (colorMask == 0x0) {
+   if (fb->_NumColorDrawBuffers == 1 && colorMask[0] == 0x0) {
       /* no colors to write */
       goto end;
    }
@@ -1479,12 +1479,12 @@
             if (ctx->Color._LogicOpEnabled) {
                _swrast_logicop_rgba_span(ctx, rb, span);
             }
-            else if (ctx->Color.BlendEnabled) {
+            else if ((ctx->Color.BlendEnabled >> buf) & 1) {
                _swrast_blend_span(ctx, rb, span);
             }
 
-            if (colorMask != 0xffffffff) {
-               _swrast_mask_rgba_span(ctx, rb, span);
+            if (colorMask[buf] != 0xffffffff) {
+               _swrast_mask_rgba_span(ctx, rb, span, buf);
             }
 
             if (span->arrayMask & SPAN_XY) {
@@ -1766,9 +1766,7 @@
 
 
 /**
- * Get RGBA pixels from the given renderbuffer.  Put the pixel colors into
- * the span's specular color arrays.  The specular color arrays should no
- * longer be needed by time this function is called.
+ * Get RGBA pixels from the given renderbuffer.
  * Used by blending, logicop and masking functions.
  * \return pointer to the colors we read.
  */
@@ -1779,10 +1777,8 @@
    const GLuint pixelSize = RGBA_PIXEL_SIZE(span->array->ChanType);
    void *rbPixels;
 
-   /*
-    * Point rbPixels to a temporary space (use specular color arrays).
-    */
-   rbPixels = span->array->attribs[FRAG_ATTRIB_COL1];
+   /* Point rbPixels to a temporary space */
+   rbPixels = span->array->attribs[FRAG_ATTRIB_MAX - 1];
 
    /* Get destination values from renderbuffer */
    if (span->arrayMask & SPAN_XY) {
diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c
index 0bb988e..76b65cc 100644
--- a/src/mesa/swrast/s_texfilter.c
+++ b/src/mesa/swrast/s_texfilter.c
@@ -747,28 +747,28 @@
 {
    switch (img->_BaseFormat) {
    case GL_RGB:
-      rgba[0] = tObj->BorderColor[0];
-      rgba[1] = tObj->BorderColor[1];
-      rgba[2] = tObj->BorderColor[2];
+      rgba[0] = tObj->BorderColor.f[0];
+      rgba[1] = tObj->BorderColor.f[1];
+      rgba[2] = tObj->BorderColor.f[2];
       rgba[3] = 1.0F;
       break;
    case GL_ALPHA:
       rgba[0] = rgba[1] = rgba[2] = 0.0;
-      rgba[3] = tObj->BorderColor[3];
+      rgba[3] = tObj->BorderColor.f[3];
       break;
    case GL_LUMINANCE:
-      rgba[0] = rgba[1] = rgba[2] = tObj->BorderColor[0];
+      rgba[0] = rgba[1] = rgba[2] = tObj->BorderColor.f[0];
       rgba[3] = 1.0;
       break;
    case GL_LUMINANCE_ALPHA:
-      rgba[0] = rgba[1] = rgba[2] = tObj->BorderColor[0];
-      rgba[3] = tObj->BorderColor[3];
+      rgba[0] = rgba[1] = rgba[2] = tObj->BorderColor.f[0];
+      rgba[3] = tObj->BorderColor.f[3];
       break;
    case GL_INTENSITY:
-      rgba[0] = rgba[1] = rgba[2] = rgba[3] = tObj->BorderColor[0];
+      rgba[0] = rgba[1] = rgba[2] = rgba[3] = tObj->BorderColor.f[0];
       break;
    default:
-      COPY_4V(rgba, tObj->BorderColor);
+      COPY_4V(rgba, tObj->BorderColor.f);
    }
 }
 
@@ -2331,7 +2331,7 @@
    array = clamp_rect_coord_nearest(tObj->WrapR, texcoord[2], depth);
 
    if (array < 0 || array >= depth) {
-      COPY_4V(rgba, tObj->BorderColor);
+      COPY_4V(rgba, tObj->BorderColor.f);
    }
    else {
       if (img->Border) {
@@ -3002,7 +3002,7 @@
             img->FetchTexelf(img, col, row, slice, &depthSample);
          }
          else {
-            depthSample = tObj->BorderColor[0];
+            depthSample = tObj->BorderColor.f[0];
          }
 
          result = shadow_compare(function, texcoords[i][compare_coord],
@@ -3053,21 +3053,21 @@
          }
 
          if (slice < 0 || slice >= (GLint) depth) {
-            depth00 = tObj->BorderColor[0];
-            depth01 = tObj->BorderColor[0];
-            depth10 = tObj->BorderColor[0];
-            depth11 = tObj->BorderColor[0];
+            depth00 = tObj->BorderColor.f[0];
+            depth01 = tObj->BorderColor.f[0];
+            depth10 = tObj->BorderColor.f[0];
+            depth11 = tObj->BorderColor.f[0];
          }
          else {
             /* get four depth samples from the texture */
             if (useBorderTexel & (I0BIT | J0BIT)) {
-               depth00 = tObj->BorderColor[0];
+               depth00 = tObj->BorderColor.f[0];
             }
             else {
                img->FetchTexelf(img, i0, j0, slice, &depth00);
             }
             if (useBorderTexel & (I1BIT | J0BIT)) {
-               depth10 = tObj->BorderColor[0];
+               depth10 = tObj->BorderColor.f[0];
             }
             else {
                img->FetchTexelf(img, i1, j0, slice, &depth10);
@@ -3075,13 +3075,13 @@
 
             if (tObj->Target != GL_TEXTURE_1D_ARRAY_EXT) {
                if (useBorderTexel & (I0BIT | J1BIT)) {
-                  depth01 = tObj->BorderColor[0];
+                  depth01 = tObj->BorderColor.f[0];
                }
                else {
                   img->FetchTexelf(img, i0, j1, slice, &depth01);
                }
                if (useBorderTexel & (I1BIT | J1BIT)) {
-                  depth11 = tObj->BorderColor[0];
+                  depth11 = tObj->BorderColor.f[0];
                }
                else {
                   img->FetchTexelf(img, i1, j1, slice, &depth11);
diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c
index d80a676..11184b7 100644
--- a/src/mesa/swrast/s_triangle.c
+++ b/src/mesa/swrast/s_triangle.c
@@ -553,6 +553,9 @@
    info.format = texImg->TexFormat;					\
    info.filter = obj->MinFilter;					\
    info.envmode = unit->EnvMode;					\
+   info.er = 0;					\
+   info.eg = 0;					\
+   info.eb = 0;					\
    span.arrayMask |= SPAN_RGBA;						\
 									\
    if (info.envmode == GL_BLEND) {					\
@@ -815,6 +818,9 @@
    info.format = texImg->TexFormat;					\
    info.filter = obj->MinFilter;					\
    info.envmode = unit->EnvMode;					\
+   info.er = 0;					\
+   info.eg = 0;					\
+   info.eb = 0;					\
 									\
    if (info.envmode == GL_BLEND) {					\
       /* potential off-by-one error here? (1.0f -> 2048 -> 0) */	\
@@ -1024,10 +1030,10 @@
           ctx->Depth.Func == GL_LESS &&
           !ctx->Stencil._Enabled) {
          if ((rgbmode &&
-              ctx->Color.ColorMask[0] == 0 &&
-              ctx->Color.ColorMask[1] == 0 &&
-              ctx->Color.ColorMask[2] == 0 &&
-              ctx->Color.ColorMask[3] == 0)
+              ctx->Color.ColorMask[0][0] == 0 &&
+              ctx->Color.ColorMask[0][1] == 0 &&
+              ctx->Color.ColorMask[0][2] == 0 &&
+              ctx->Color.ColorMask[0][3] == 0)
              ||
              (!rgbmode && ctx->Color.IndexMask == 0)) {
             USE(occlusion_zless_triangle);
diff --git a/src/mesa/swrast_setup/ss_tritmp.h b/src/mesa/swrast_setup/ss_tritmp.h
index 724b5e9..8484aab 100644
--- a/src/mesa/swrast_setup/ss_tritmp.h
+++ b/src/mesa/swrast_setup/ss_tritmp.h
@@ -41,9 +41,9 @@
    GLenum mode = GL_FILL;
    GLuint facing = 0;
    GLchan saved_color[3][4];
-   GLfloat saved_col0[3][4];
-   GLfloat saved_spec[3][4];
-   GLfloat saved_index[3];
+   GLfloat saved_col0[3][4] = { { 0 } };
+   GLfloat saved_spec[3][4] = { { 0 } };
+   GLfloat saved_index[3] = { 0 };
 
    v[0] = &verts[e0];
    v[1] = &verts[e1];
@@ -67,8 +67,8 @@
 	 if (facing == 1) {
 	    if (IND & SS_TWOSIDE_BIT) {
 	       if (IND & SS_RGBA_BIT) {
-                  if (VB->ColorPtr[1]) {
-                     GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
+                  if (VB->BackfaceColorPtr) {
+                     GLfloat (*vbcolor)[4] = VB->BackfaceColorPtr->data;
 
                      if (swsetup->intColors) {
                         COPY_CHAN4(saved_color[0], v[0]->color);
@@ -81,7 +81,7 @@
                         COPY_4V(saved_col0[2], v[2]->attrib[FRAG_ATTRIB_COL0]);
                      }
 
-                     if (VB->ColorPtr[1]->stride) {
+                     if (VB->BackfaceColorPtr->stride) {
                         if (swsetup->intColors) {
                            SS_COLOR(v[0]->color, vbcolor[e0]);
                            SS_COLOR(v[1]->color, vbcolor[e1]);
@@ -108,14 +108,14 @@
                      }
                   }
 
-		  if (VB->SecondaryColorPtr[1]) {
-		     GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
+		  if (VB->BackfaceSecondaryColorPtr) {
+		     GLfloat (*vbspec)[4] = VB->BackfaceSecondaryColorPtr->data;
 
 		     COPY_4V(saved_spec[0], v[0]->attrib[FRAG_ATTRIB_COL1]);
 		     COPY_4V(saved_spec[1], v[1]->attrib[FRAG_ATTRIB_COL1]);
 		     COPY_4V(saved_spec[2], v[2]->attrib[FRAG_ATTRIB_COL1]);
 
-		     if (VB->SecondaryColorPtr[1]->stride) {
+		     if (VB->BackfaceSecondaryColorPtr->stride) {
 			SS_SPEC(v[0]->attrib[FRAG_ATTRIB_COL1], vbspec[e0]);
 			SS_SPEC(v[1]->attrib[FRAG_ATTRIB_COL1], vbspec[e1]);
 			SS_SPEC(v[2]->attrib[FRAG_ATTRIB_COL1], vbspec[e2]);
@@ -127,7 +127,7 @@
 		     }
 		  }
 	       } else {
-		  GLfloat *vbindex = (GLfloat *)VB->IndexPtr[1]->data;
+		  GLfloat *vbindex = (GLfloat *)VB->BackfaceIndexPtr->data;
 		  saved_index[0] = v[0]->attrib[FRAG_ATTRIB_CI][0];
 		  saved_index[1] = v[1]->attrib[FRAG_ATTRIB_CI][0];
 		  saved_index[2] = v[2]->attrib[FRAG_ATTRIB_CI][0];
@@ -200,7 +200,7 @@
    if (IND & SS_TWOSIDE_BIT) {
       if (facing == 1) {
 	 if (IND & SS_RGBA_BIT) {
-            if (VB->ColorPtr[1]) {
+            if (VB->BackfaceColorPtr) {
                if (swsetup->intColors) {
                   COPY_CHAN4(v[0]->color, saved_color[0]);
                   COPY_CHAN4(v[1]->color, saved_color[1]);
@@ -213,7 +213,7 @@
                }
             }
 
-	    if (VB->SecondaryColorPtr[1]) {
+	    if (VB->BackfaceSecondaryColorPtr) {
 	       COPY_4V(v[0]->attrib[FRAG_ATTRIB_COL1], saved_spec[0]);
 	       COPY_4V(v[1]->attrib[FRAG_ATTRIB_COL1], saved_spec[1]);
 	       COPY_4V(v[2]->attrib[FRAG_ATTRIB_COL1], saved_spec[2]);
diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c
index f2771cd..db21b45 100644
--- a/src/mesa/tnl/t_context.c
+++ b/src/mesa/tnl/t_context.c
@@ -171,7 +171,7 @@
    if (vp) {
       GLuint i;
       for (i = 0; i < MAX_VARYING; i++) {
-         if (vp->Base.OutputsWritten & (1 << (VERT_RESULT_VAR0 + i))) {
+	 if (vp->Base.OutputsWritten & BITFIELD64_BIT(VERT_RESULT_VAR0 + i)) {
             RENDERINPUTS_SET(tnl->render_inputs_bitset,
                              _TNL_ATTRIB_GENERIC(i));
          }
diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h
index 6137c2d..ebaae63 100644
--- a/src/mesa/tnl/t_context.h
+++ b/src/mesa/tnl/t_context.h
@@ -198,26 +198,23 @@
     */
    GLuint Count;  /**< Number of vertices currently in buffer */
 
-   /* Pointers to current data.
-    * XXX some of these fields alias AttribPtr below and should be removed
-    * such as NormalPtr, TexCoordPtr, FogCoordPtr, etc.
+   /* Pointers to current data.  Most of the data is in AttribPtr -- all of
+    * it that is one of VERT_ATTRIB_X.  For things only produced by TNL,
+    * such as backface color or eye-space coordinates, they are stored
+    * here.
     */
    GLuint      *Elts;		                
-   GLvector4f  *ObjPtr;		                /* _TNL_BIT_POS */
    GLvector4f  *EyePtr;		                /* _TNL_BIT_POS */
    GLvector4f  *ClipPtr;	                /* _TNL_BIT_POS */
    GLvector4f  *NdcPtr;                         /* _TNL_BIT_POS */
    GLubyte     ClipOrMask;	                /* _TNL_BIT_POS */
    GLubyte     ClipAndMask;	                /* _TNL_BIT_POS */
    GLubyte     *ClipMask;		        /* _TNL_BIT_POS */
-   GLvector4f  *NormalPtr;	                /* _TNL_BIT_NORMAL */
    GLfloat     *NormalLengthPtr;	        /* _TNL_BIT_NORMAL */
    GLboolean   *EdgeFlag;	                /* _TNL_BIT_EDGEFLAG */
-   GLvector4f  *TexCoordPtr[MAX_TEXTURE_COORD_UNITS]; /* VERT_TEX_0..n */
-   GLvector4f  *IndexPtr[2];	                /* _TNL_BIT_INDEX */
-   GLvector4f  *ColorPtr[2];	                /* _TNL_BIT_COLOR0 */
-   GLvector4f  *SecondaryColorPtr[2];           /* _TNL_BIT_COLOR1 */
-   GLvector4f  *FogCoordPtr;	                /* _TNL_BIT_FOG */
+   GLvector4f  *BackfaceIndexPtr;
+   GLvector4f  *BackfaceColorPtr;
+   GLvector4f  *BackfaceSecondaryColorPtr;
 
    const struct _mesa_prim  *Primitive;	              
    GLuint      PrimitiveCount;	      
@@ -402,11 +399,6 @@
    /* Alert tnl-aware drivers of changes to material.
     */
 
-   void (*NotifyInputChanges)(GLcontext *ctx, GLuint bitmask);
-   /* Alert tnl-aware drivers of changes to size and stride of input
-    * arrays.
-    */
-
    /***
     *** Rendering -- These functions called only from t_vb_render.c
     ***/
diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c
index 04fa106..d31b29b 100644
--- a/src/mesa/tnl/t_draw.c
+++ b/src/mesa/tnl/t_draw.c
@@ -26,6 +26,7 @@
  */
 
 #include "main/glheader.h"
+#include "main/condrender.h"
 #include "main/context.h"
 #include "main/imports.h"
 #include "main/state.h"
@@ -251,22 +252,10 @@
     */
    VB->Count = count;
 
-
-   /* Legacy pointers -- remove one day.
-    */
-   VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS];
-   VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL];
-   VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0];
-   VB->ColorPtr[1] = NULL;
-   VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR_INDEX];
-   VB->IndexPtr[1] = NULL;
-   VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1];
-   VB->SecondaryColorPtr[1] = NULL;
-   VB->FogCoordPtr = VB->AttribPtr[_TNL_ATTRIB_FOG];
-
-   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
-      VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i];
-   }
+   /* These should perhaps be part of _TNL_ATTRIB_* */
+   VB->BackfaceColorPtr = NULL;
+   VB->BackfaceIndexPtr = NULL;
+   VB->BackfaceSecondaryColorPtr = NULL;
 
    /* Clipping and drawing code still requires this to be a packed
     * array of ubytes which can be written into.  TODO: Fix and
@@ -398,6 +387,9 @@
    GLuint max_basevertex = prim->basevertex;
    GLuint i;
 
+   if (!_mesa_check_conditional_render(ctx))
+      return; /* don't draw */
+
    for (i = 1; i < nr_prims; i++)
       max_basevertex = MAX2(max_basevertex, prim[i].basevertex);
 
diff --git a/src/mesa/tnl/t_pipeline.c b/src/mesa/tnl/t_pipeline.c
index 357ef1e..01b30ba 100644
--- a/src/mesa/tnl/t_pipeline.c
+++ b/src/mesa/tnl/t_pipeline.c
@@ -86,10 +86,6 @@
       }
    }
 
-   if (tnl->pipeline.input_changes &&
-      tnl->Driver.NotifyInputChanges) 
-      tnl->Driver.NotifyInputChanges( ctx, tnl->pipeline.input_changes );
-
    return tnl->pipeline.input_changes;
 }
 
diff --git a/src/mesa/tnl/t_vb_fog.c b/src/mesa/tnl/t_vb_fog.c
index f3a7bd4..4a0e6ad 100644
--- a/src/mesa/tnl/t_vb_fog.c
+++ b/src/mesa/tnl/t_vb_fog.c
@@ -156,7 +156,7 @@
       GLuint i;
       GLfloat *coord;
       /* Fog is computed from vertex or fragment Z values */
-      /* source = VB->ObjPtr or VB->EyePtr coords */
+      /* source = VB->AttribPtr[_TNL_ATTRIB_POS] or VB->EyePtr coords */
       /* dest = VB->AttribPtr[_TNL_ATTRIB_FOG] = fog stage private storage */
       VB->AttribPtr[_TNL_ATTRIB_FOG] = &store->fogcoord;
 
@@ -176,11 +176,12 @@
 	 /* Full eye coords weren't required, just calculate the
 	  * eye Z values.
 	  */
-	 _mesa_dotprod_tab[VB->ObjPtr->size]( (GLfloat *) input->data,
-					      4 * sizeof(GLfloat),
-					      VB->ObjPtr, plane );
+	 _mesa_dotprod_tab[VB->AttribPtr[_TNL_ATTRIB_POS]->size]
+	    ( (GLfloat *) input->data,
+	      4 * sizeof(GLfloat),
+	      VB->AttribPtr[_TNL_ATTRIB_POS], plane );
 
-	 input->count = VB->ObjPtr->count;
+	 input->count = VB->AttribPtr[_TNL_ATTRIB_POS]->count;
 
 	 /* make sure coords are really positive
 	    NOTE should avoid going through array twice */
@@ -213,7 +214,7 @@
       /* input->count may be one if glFogCoord was only called once
        * before glBegin.  But we need to compute fog for all vertices.
        */
-      input->count = VB->ObjPtr->count;
+      input->count = VB->AttribPtr[_TNL_ATTRIB_POS]->count;
 
       VB->AttribPtr[_TNL_ATTRIB_FOG] = &store->fogcoord;  /* dest data */
    }
@@ -227,7 +228,6 @@
       VB->AttribPtr[_TNL_ATTRIB_FOG] = input;
    }
 
-   VB->FogCoordPtr = VB->AttribPtr[_TNL_ATTRIB_FOG];
    return GL_TRUE;
 }
 
diff --git a/src/mesa/tnl/t_vb_light.c b/src/mesa/tnl/t_vb_light.c
index f47f993..8a0fe63 100644
--- a/src/mesa/tnl/t_vb_light.c
+++ b/src/mesa/tnl/t_vb_light.c
@@ -127,7 +127,7 @@
       const GLuint bitmask = ctx->Light.ColorMaterialBitmask;
       for (i = 0 ; i < MAT_ATTRIB_MAX ; i++)
 	 if (bitmask & (1<<i))
-	    VB->AttribPtr[_TNL_ATTRIB_MAT_FRONT_AMBIENT + i] = VB->ColorPtr[0];
+	    VB->AttribPtr[_TNL_ATTRIB_MAT_FRONT_AMBIENT + i] = VB->AttribPtr[_TNL_ATTRIB_COLOR0];
    }
 
    /* Now, for each material attribute that's tracking vertex color, save
@@ -200,7 +200,7 @@
    struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb;
-   GLvector4f *input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr;
+   GLvector4f *input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->AttribPtr[_TNL_ATTRIB_POS];
    GLuint idx;
 
    if (!ctx->Light.Enabled || ctx->VertexProgram._Current)
@@ -208,13 +208,13 @@
 
    /* Make sure we can talk about position x,y and z:
     */
-   if (input->size <= 2 && input == VB->ObjPtr) {
+   if (input->size <= 2 && input == VB->AttribPtr[_TNL_ATTRIB_POS]) {
 
       _math_trans_4f( store->Input.data,
-		      VB->ObjPtr->data,
-		      VB->ObjPtr->stride,
+		      VB->AttribPtr[_TNL_ATTRIB_POS]->data,
+		      VB->AttribPtr[_TNL_ATTRIB_POS]->stride,
 		      GL_FLOAT,
-		      VB->ObjPtr->size,
+		      VB->AttribPtr[_TNL_ATTRIB_POS]->size,
 		      0,
 		      VB->Count );
 
@@ -246,10 +246,6 @@
     */
    store->light_func_tab[idx]( ctx, VB, stage, input );
 
-   VB->AttribPtr[_TNL_ATTRIB_COLOR0] = VB->ColorPtr[0];
-   VB->AttribPtr[_TNL_ATTRIB_COLOR1] = VB->SecondaryColorPtr[0];
-   VB->AttribPtr[_TNL_ATTRIB_COLOR_INDEX] = VB->IndexPtr[0];
-
    return GL_TRUE;
 }
 
diff --git a/src/mesa/tnl/t_vb_lighttmp.h b/src/mesa/tnl/t_vb_lighttmp.h
index 124ca3c..4ebef23 100644
--- a/src/mesa/tnl/t_vb_lighttmp.h
+++ b/src/mesa/tnl/t_vb_lighttmp.h
@@ -72,13 +72,13 @@
    fprintf(stderr, "%s\n", __FUNCTION__ );
 #endif
 
-   VB->ColorPtr[0] = &store->LitColor[0];
-   VB->SecondaryColorPtr[0] = &store->LitSecondary[0];
+   VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0];
+   VB->AttribPtr[_TNL_ATTRIB_COLOR1] = &store->LitSecondary[0];
    sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
 
 #if IDX & LIGHT_TWOSIDE
-   VB->ColorPtr[1] = &store->LitColor[1];
-   VB->SecondaryColorPtr[1] = &store->LitSecondary[1];
+   VB->BackfaceColorPtr = &store->LitColor[1];
+   VB->BackfaceSecondaryColorPtr = &store->LitSecondary[1];
    sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
 #endif
 
@@ -259,11 +259,11 @@
    fprintf(stderr, "%s\n", __FUNCTION__ );
 #endif
 
-   VB->ColorPtr[0] = &store->LitColor[0];
+   VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0];
    sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
 
 #if IDX & LIGHT_TWOSIDE
-   VB->ColorPtr[1] = &store->LitColor[1];
+   VB->BackfaceColorPtr = &store->LitColor[1];
    sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
 #endif
 
@@ -449,9 +449,9 @@
 
    (void) input;		/* doesn't refer to Eye or Obj */
 
-   VB->ColorPtr[0] = &store->LitColor[0];
+   VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0];
 #if IDX & LIGHT_TWOSIDE
-   VB->ColorPtr[1] = &store->LitColor[1];
+   VB->BackfaceColorPtr = &store->LitColor[1];
 #endif
 
    if (nr > 1) {
@@ -559,9 +559,9 @@
    sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
    sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
 
-   VB->ColorPtr[0] = &store->LitColor[0];
+   VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &store->LitColor[0];
 #if IDX & LIGHT_TWOSIDE
-   VB->ColorPtr[1] = &store->LitColor[1];
+   VB->BackfaceColorPtr = &store->LitColor[1];
 #endif
 
    if (nr > 1) {
@@ -665,14 +665,14 @@
    fprintf(stderr, "%s\n", __FUNCTION__ );
 #endif
 
-   VB->IndexPtr[0] = &store->LitIndex[0];
+   VB->AttribPtr[_TNL_ATTRIB_COLOR_INDEX] = &store->LitIndex[0];
 #if IDX & LIGHT_TWOSIDE
-   VB->IndexPtr[1] = &store->LitIndex[1];
+   VB->BackfaceIndexPtr = &store->LitIndex[1];
 #endif
 
-   indexResult[0] = (GLfloat *)VB->IndexPtr[0]->data;
+   indexResult[0] = (GLfloat *)VB->AttribPtr[_TNL_ATTRIB_COLOR_INDEX]->data;
 #if IDX & LIGHT_TWOSIDE
-   indexResult[1] = (GLfloat *)VB->IndexPtr[1]->data;
+   indexResult[1] = (GLfloat *)VB->BackfaceIndexPtr->data;
 #endif
 
    /* loop over vertices */
diff --git a/src/mesa/tnl/t_vb_normals.c b/src/mesa/tnl/t_vb_normals.c
index a4821cc..693d3dc 100644
--- a/src/mesa/tnl/t_vb_normals.c
+++ b/src/mesa/tnl/t_vb_normals.c
@@ -79,7 +79,6 @@
    }
 
    VB->AttribPtr[_TNL_ATTRIB_NORMAL] = &store->normal;
-   VB->NormalPtr = &store->normal;
 
    VB->NormalLengthPtr = NULL;	/* no longer valid */
    return GL_TRUE;
diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c
index c10a276..15a8a67 100644
--- a/src/mesa/tnl/t_vb_program.c
+++ b/src/mesa/tnl/t_vb_program.c
@@ -329,7 +329,7 @@
    /* make list of outputs to save some time below */
    numOutputs = 0;
    for (i = 0; i < VERT_RESULT_MAX; i++) {
-      if (program->Base.OutputsWritten & (1 << i)) {
+      if (program->Base.OutputsWritten & BITFIELD64_BIT(i)) {
          outputs[numOutputs++] = i;
       }
    }
@@ -390,6 +390,13 @@
 #endif
          COPY_4V(store->results[attr].data[i], machine.Outputs[attr]);
       }
+
+      /* FOGC is a special case.  Fragment shader expects (f,0,0,1) */
+      if (program->Base.OutputsWritten & BITFIELD64_BIT(VERT_RESULT_FOGC)) {
+         store->results[VERT_RESULT_FOGC].data[i][1] = 0.0;
+         store->results[VERT_RESULT_FOGC].data[i][2] = 0.0;
+         store->results[VERT_RESULT_FOGC].data[i][3] = 1.0;
+      }
 #ifdef NAN_CHECK
       ASSERT(machine.Outputs[0][3] != 0.0F);
 #endif
@@ -407,14 +414,14 @@
    /* Fixup fog and point size results if needed */
    if (program->IsNVProgram) {
       if (ctx->Fog.Enabled &&
-          (program->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) == 0) {
+          (program->Base.OutputsWritten & BITFIELD64_BIT(VERT_RESULT_FOGC)) == 0) {
          for (i = 0; i < VB->Count; i++) {
             store->results[VERT_RESULT_FOGC].data[i][0] = 1.0;
          }
       }
 
       if (ctx->VertexProgram.PointSizeEnabled &&
-          (program->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ)) == 0) {
+          (program->Base.OutputsWritten & BITFIELD64_BIT(VERT_RESULT_PSIZ)) == 0) {
          for (i = 0; i < VB->Count; i++) {
             store->results[VERT_RESULT_PSIZ].data[i][0] = ctx->Point.Size;
          }
@@ -454,25 +461,20 @@
       VB->ClipPtr->count = VB->Count;
    }
 
-   VB->ColorPtr[0] = &store->results[VERT_RESULT_COL0];
-   VB->ColorPtr[1] = &store->results[VERT_RESULT_BFC0];
-   VB->SecondaryColorPtr[0] = &store->results[VERT_RESULT_COL1];
-   VB->SecondaryColorPtr[1] = &store->results[VERT_RESULT_BFC1];
-   VB->FogCoordPtr = &store->results[VERT_RESULT_FOGC];
-
    VB->AttribPtr[VERT_ATTRIB_COLOR0] = &store->results[VERT_RESULT_COL0];
    VB->AttribPtr[VERT_ATTRIB_COLOR1] = &store->results[VERT_RESULT_COL1];
    VB->AttribPtr[VERT_ATTRIB_FOG] = &store->results[VERT_RESULT_FOGC];
    VB->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &store->results[VERT_RESULT_PSIZ];
+   VB->BackfaceColorPtr = &store->results[VERT_RESULT_BFC0];
+   VB->BackfaceSecondaryColorPtr = &store->results[VERT_RESULT_BFC1];
 
    for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
-      VB->TexCoordPtr[i] = 
       VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]
          = &store->results[VERT_RESULT_TEX0 + i];
    }
 
    for (i = 0; i < ctx->Const.MaxVarying; i++) {
-      if (program->Base.OutputsWritten & (1 << (VERT_RESULT_VAR0 + i))) {
+      if (program->Base.OutputsWritten & BITFIELD64_BIT(VERT_RESULT_VAR0 + i)) {
          /* Note: varying results get put into the generic attributes */
 	 VB->AttribPtr[VERT_ATTRIB_GENERIC0+i]
             = &store->results[VERT_RESULT_VAR0 + i];
diff --git a/src/mesa/tnl/t_vb_texgen.c b/src/mesa/tnl/t_vb_texgen.c
index 7c1819b..9ef13bc 100644
--- a/src/mesa/tnl/t_vb_texgen.c
+++ b/src/mesa/tnl/t_vb_texgen.c
@@ -341,7 +341,7 @@
    GLvector4f *in = VB->AttribPtr[VERT_ATTRIB_TEX0 + unit];
    GLvector4f *out = &store->texcoord[unit];
    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
-   const GLvector4f *obj = VB->ObjPtr;
+   const GLvector4f *obj = VB->AttribPtr[_TNL_ATTRIB_POS];
    const GLvector4f *eye = VB->EyePtr;
    const GLvector4f *normal = VB->AttribPtr[_TNL_ATTRIB_NORMAL];
    const GLfloat *m = store->tmp_m;
@@ -498,7 +498,6 @@
 
 	 store->TexgenFunc[i]( ctx, store, i );
 
-         VB->TexCoordPtr[i] =
          VB->AttribPtr[VERT_ATTRIB_TEX0 + i] = &store->texcoord[i];
       }
    }
diff --git a/src/mesa/tnl/t_vb_texmat.c b/src/mesa/tnl/t_vb_texmat.c
index 0abe8cc..8368829 100644
--- a/src/mesa/tnl/t_vb_texmat.c
+++ b/src/mesa/tnl/t_vb_texmat.c
@@ -73,7 +73,6 @@
 			      ctx->TextureMatrixStack[i].Top,
 			      VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]);
 
-         VB->TexCoordPtr[i] = 
 	 VB->AttribPtr[VERT_ATTRIB_TEX0+i] = &store->texcoord[i];
       }
    }
diff --git a/src/mesa/tnl/t_vb_vertex.c b/src/mesa/tnl/t_vb_vertex.c
index 4734754e..bc7e095 100644
--- a/src/mesa/tnl/t_vb_vertex.c
+++ b/src/mesa/tnl/t_vb_vertex.c
@@ -152,16 +152,16 @@
        * Use combined ModelProject to avoid some depth artifacts
        */
       if (ctx->ModelviewMatrixStack.Top->type == MATRIX_IDENTITY)
-	 VB->EyePtr = VB->ObjPtr;
+	 VB->EyePtr = VB->AttribPtr[_TNL_ATTRIB_POS];
       else
 	 VB->EyePtr = TransformRaw( &store->eye,
 				    ctx->ModelviewMatrixStack.Top,
-				    VB->ObjPtr);
+				    VB->AttribPtr[_TNL_ATTRIB_POS]);
    }
 
    VB->ClipPtr = TransformRaw( &store->clip,
 			       &ctx->_ModelProjectMatrix,
-			       VB->ObjPtr );
+			       VB->AttribPtr[_TNL_ATTRIB_POS] );
 
    /* Drivers expect this to be clean to element 4...
     */
diff --git a/src/mesa/tnl/t_vertex_generic.c b/src/mesa/tnl/t_vertex_generic.c
index 9812f8c..99ddace 100644
--- a/src/mesa/tnl/t_vertex_generic.c
+++ b/src/mesa/tnl/t_vertex_generic.c
@@ -210,7 +210,7 @@
 {
    (void) a; (void) v; (void) in;
    DEBUG_INSERT;
-   _mesa_exit(1);
+   exit(1);
 }
 
 static INLINE void insert_3f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
@@ -1092,33 +1092,33 @@
 {
    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
 
-   /* If stride is zero, ColorPtr[1] is constant across the VB, so
+   /* If stride is zero, BackfaceColorPtr is constant across the VB, so
     * there is no point interpolating between two values as they will
     * be identical.  In all other cases, this value is generated by
     * t_vb_lighttmp.h and has a stride of 4 dwords.
     */
-   if (VB->ColorPtr[1] && VB->ColorPtr[1]->stride) {
-      assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat));
+   if (VB->BackfaceColorPtr && VB->BackfaceColorPtr->stride) {
+      assert(VB->BackfaceColorPtr->stride == 4 * sizeof(GLfloat));
 
       INTERP_4F( t,
-		 VB->ColorPtr[1]->data[dst],
-		 VB->ColorPtr[1]->data[out],
-		 VB->ColorPtr[1]->data[in] );
+		 VB->BackfaceColorPtr->data[dst],
+		 VB->BackfaceColorPtr->data[out],
+		 VB->BackfaceColorPtr->data[in] );
    }
 
-   if (VB->SecondaryColorPtr[1]) {
-      assert(VB->SecondaryColorPtr[1]->stride == 4 * sizeof(GLfloat));
+   if (VB->BackfaceSecondaryColorPtr) {
+      assert(VB->BackfaceSecondaryColorPtr->stride == 4 * sizeof(GLfloat));
       
       INTERP_3F( t,
-		 VB->SecondaryColorPtr[1]->data[dst],
-		 VB->SecondaryColorPtr[1]->data[out],
-		 VB->SecondaryColorPtr[1]->data[in] );
+		 VB->BackfaceSecondaryColorPtr->data[dst],
+		 VB->BackfaceSecondaryColorPtr->data[out],
+		 VB->BackfaceSecondaryColorPtr->data[in] );
    }
    
-   if (VB->IndexPtr[1]) {
-      VB->IndexPtr[1]->data[dst][0] = LINTERP( t,
-					       VB->IndexPtr[1]->data[out][0],
-					       VB->IndexPtr[1]->data[in][0] );
+   if (VB->BackfaceIndexPtr) {
+      VB->BackfaceIndexPtr->data[dst][0] = LINTERP( t,
+					       VB->BackfaceIndexPtr->data[out][0],
+					       VB->BackfaceIndexPtr->data[in][0] );
    }
 
    if (VB->EdgeFlag) {
@@ -1135,18 +1135,18 @@
 
    /* See above comment:
     */
-   if (VB->ColorPtr[1] && VB->ColorPtr[1]->stride) {
-      COPY_4FV( VB->ColorPtr[1]->data[dst], 
-		VB->ColorPtr[1]->data[src] );
+   if (VB->BackfaceColorPtr && VB->BackfaceColorPtr->stride) {
+      COPY_4FV( VB->BackfaceColorPtr->data[dst],
+		VB->BackfaceColorPtr->data[src] );
    }
 
-   if (VB->SecondaryColorPtr[1]) {
-      COPY_4FV( VB->SecondaryColorPtr[1]->data[dst], 
-		VB->SecondaryColorPtr[1]->data[src] );
+   if (VB->BackfaceSecondaryColorPtr) {
+      COPY_4FV( VB->BackfaceSecondaryColorPtr->data[dst],
+		VB->BackfaceSecondaryColorPtr->data[src] );
    }
 
-   if (VB->IndexPtr[1]) {
-      VB->IndexPtr[1]->data[dst][0] = VB->IndexPtr[1]->data[src][0];
+   if (VB->BackfaceIndexPtr) {
+      VB->BackfaceIndexPtr->data[dst][0] = VB->BackfaceIndexPtr->data[src][0];
    }
 
    _tnl_generic_copy_pv(ctx, dst, src);
diff --git a/src/mesa/tnl_dd/t_dd_dmatmp.h b/src/mesa/tnl_dd/t_dd_dmatmp.h
index e4b535f..2424204 100644
--- a/src/mesa/tnl_dd/t_dd_dmatmp.h
+++ b/src/mesa/tnl_dd/t_dd_dmatmp.h
@@ -241,6 +241,7 @@
 	       tmp = ALLOC_VERTS(nr+1);
 	       tmp = TAG(emit_verts)( ctx, j, nr, tmp );
 	       tmp = TAG(emit_verts)( ctx, start, 1, tmp );
+	       (void) tmp;
 	    }
 	    else {
 	       TAG(emit_verts)( ctx, j, nr, ALLOC_VERTS(nr) );
@@ -254,6 +255,7 @@
 	 tmp = ALLOC_VERTS(2);
 	 tmp = TAG(emit_verts)( ctx, start+1, 1, tmp );
 	 tmp = TAG(emit_verts)( ctx, start, 1, tmp );
+	 (void) tmp;
       }
 
       FLUSH();
@@ -358,6 +360,7 @@
 	 tmp = ALLOC_VERTS( nr );
 	 tmp = TAG(emit_verts)( ctx, start, 1, tmp );
 	 tmp = TAG(emit_verts)( ctx, j, nr - 1, tmp );
+	 (void) tmp;
 	 currentsz = dmasz;
       }
 
@@ -397,6 +400,7 @@
 	 tmp = ALLOC_VERTS( nr );
 	 tmp = TAG(emit_verts)( ctx, start, 1, tmp );
 	 tmp = TAG(emit_verts)( ctx, j, nr - 1, tmp );
+	 (void) tmp;
 	 currentsz = dmasz;
       }
 
@@ -443,7 +447,7 @@
 
    } else if (HAVE_TRI_STRIPS && 
 	      ctx->Light.ShadeModel == GL_FLAT &&
-	      TNL_CONTEXT(ctx)->vb.ColorPtr[0]->stride) {
+	      TNL_CONTEXT(ctx)->vb.AttribPtr[_TNL_ATTRIB_COLOR0]->stride) {
       if (HAVE_ELTS) {
 	 LOCAL_VARS;
 	 int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS();
@@ -634,6 +638,7 @@
 	 /* Send v1, v2, v3
 	  */
 	 tmp = EMIT_VERTS(ctx, j + 1, 3, tmp);
+	 (void) tmp;
       }
    }
    else {
@@ -820,6 +825,7 @@
 	       tmp = ALLOC_ELTS(nr+1);
 	       tmp = TAG(emit_elts)( ctx, elts+j, nr, tmp );
 	       tmp = TAG(emit_elts)( ctx, elts+start, 1, tmp );
+	       (void) tmp;
 	    }
 	    else {
 	       TAG(emit_elts)( ctx, elts+j, nr, ALLOC_ELTS(nr) );
@@ -833,6 +839,7 @@
 	 tmp = ALLOC_ELTS(2);
 	 tmp = TAG(emit_elts)( ctx, elts+start+1, 1, tmp );
 	 tmp = TAG(emit_elts)( ctx, elts+start, 1, tmp );
+	 (void) tmp;
       }
 
       FLUSH();
@@ -946,6 +953,7 @@
 	 tmp = ALLOC_ELTS( nr );
 	 tmp = TAG(emit_elts)( ctx, elts+start, 1, tmp );
 	 tmp = TAG(emit_elts)( ctx, elts+j, nr - 1, tmp );
+	 (void) tmp;
 	 FLUSH();
 	 currentsz = dmasz;
       }
@@ -983,6 +991,7 @@
 	 tmp = ALLOC_ELTS( nr );
 	 tmp = TAG(emit_elts)( ctx, elts+start, 1, tmp );
 	 tmp = TAG(emit_elts)( ctx, elts+j, nr - 1, tmp );
+	 (void) tmp;
 	 FLUSH();
 	 currentsz = dmasz;
       }
@@ -1221,7 +1230,7 @@
 	    ok = GL_TRUE;
 	 } else if (HAVE_TRI_STRIPS && 
 		    ctx->Light.ShadeModel == GL_FLAT &&
-		    VB->ColorPtr[0]->stride != 0) {
+		    VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride != 0) {
 	    if (HAVE_ELTS) {
 	       ok = (GLint) count < GET_SUBSEQUENT_VB_MAX_ELTS();
 	    }
diff --git a/src/mesa/tnl_dd/t_dd_dmatmp2.h b/src/mesa/tnl_dd/t_dd_dmatmp2.h
index 2380c49..cd225b6 100644
--- a/src/mesa/tnl_dd/t_dd_dmatmp2.h
+++ b/src/mesa/tnl_dd/t_dd_dmatmp2.h
@@ -266,6 +266,7 @@
 	    if (j + nr < count) {
 	       ELT_TYPE *dest = ALLOC_ELTS( nr );
 	       dest = TAG(emit_consecutive_elts)( ctx, dest, j, nr );
+	       (void) dest;
 	       j += nr - 1;
 	       CLOSE_ELTS();
 	    }
@@ -273,6 +274,7 @@
 	       ELT_TYPE *dest = ALLOC_ELTS( nr + 1 );
 	       dest = TAG(emit_consecutive_elts)( ctx, dest, j, nr );
 	       dest = TAG(emit_consecutive_elts)( ctx, dest, start, 1 );
+	       (void) dest;
 	       j += nr;
 	       CLOSE_ELTS();
 	    }
@@ -554,6 +556,7 @@
       nr = MIN2( dmasz, count - j );
       dest = ALLOC_ELTS( nr );
       dest = TAG(emit_elts)( ctx, dest, elts+j, nr );
+      (void) dest;
       CLOSE_ELTS();
    }
 }
@@ -590,6 +593,7 @@
       nr = MIN2( dmasz, count - j );
       dest = ALLOC_ELTS( nr );
       dest = TAG(emit_elts)( ctx, dest, elts+j, nr );
+      (void) dest;
       CLOSE_ELTS();
    }
 
@@ -621,6 +625,7 @@
       nr = MIN2( dmasz, count - j );
       dest = ALLOC_ELTS( nr );
       dest = TAG(emit_elts)( ctx, dest, elts+j, nr );
+      (void) dest;
       CLOSE_ELTS();
    }
 }
@@ -671,6 +676,7 @@
       j += nr - 1;
       if (j + 1 >= count && (flags & PRIM_END)) {
 	 dest = TAG(emit_elts)( ctx, dest, elts+start, 1 );
+	 (void) dest;
       }
       CLOSE_ELTS();
    }
@@ -703,6 +709,7 @@
       nr = MIN2( dmasz, count - j );
       dest = ALLOC_ELTS( nr );
       dest = TAG(emit_elts)( ctx, dest, elts+j, nr );
+      (void) dest;
       CLOSE_ELTS();
    }
 }
@@ -734,6 +741,7 @@
 
       dest = ALLOC_ELTS( nr );
       dest = TAG(emit_elts)( ctx, dest, elts+j, nr );
+      (void) dest;
       CLOSE_ELTS();
    }
 }
@@ -759,6 +767,7 @@
       dest = ALLOC_ELTS( nr );
       dest = TAG(emit_elts)( ctx, dest, elts+start, 1 );
       dest = TAG(emit_elts)( ctx, dest, elts+j, nr - 1 );
+      (void) dest;
       CLOSE_ELTS();
    }
 }
@@ -785,6 +794,7 @@
       dest = ALLOC_ELTS( nr );
       dest = TAG(emit_elts)( ctx, dest, elts+start, 1 );
       dest = TAG(emit_elts)( ctx, dest, elts+j, nr - 1 );
+      (void) dest;
       CLOSE_ELTS();
    }
 }
@@ -843,6 +853,7 @@
 	    nr = MIN2( dmasz, count - j );
 	    dest = ALLOC_ELTS( nr );
 	    dest = TAG(emit_elts)( ctx, dest, elts+j, nr );
+	    (void) dest;
 	    CLOSE_ELTS();
 	 }
       }
diff --git a/src/mesa/tnl_dd/t_dd_tritmp.h b/src/mesa/tnl_dd/t_dd_tritmp.h
index 1ae70f4..6acd837 100644
--- a/src/mesa/tnl_dd/t_dd_tritmp.h
+++ b/src/mesa/tnl_dd/t_dd_tritmp.h
@@ -132,7 +132,7 @@
    struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
    VERTEX *v[3];
    GLfloat offset = 0;
-   GLfloat z[3];
+   GLfloat z[3] = { 0 };
    GLenum mode = GL_FILL;
    GLuint facing = 0;
    LOCAL_VARS(3);
@@ -195,7 +195,7 @@
 		  }
 	       }
 	       else {
-		  GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
+		  GLfloat (*vbcolor)[4] = VB->BackfaceColorPtr->data;
 		  (void) vbcolor;
 
 		  if (!DO_FLAT) {
@@ -204,8 +204,8 @@
 		  }
 		  VERT_SAVE_RGBA( 2 );
 
-		  if (VB->ColorPtr[1]->stride) {
-		     ASSERT(VB->ColorPtr[1]->stride == 4*sizeof(GLfloat));
+		  if (VB->BackfaceColorPtr->stride) {
+		     ASSERT(VB->BackfaceColorPtr->stride == 4*sizeof(GLfloat));
 
 		     if (!DO_FLAT) {		  
 			VERT_SET_RGBA( v[0], vbcolor[e0] );
@@ -221,9 +221,9 @@
 		     VERT_SET_RGBA( v[2], vbcolor[0] );
 		  }
 
-		  if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
-		     GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
-		     ASSERT(VB->SecondaryColorPtr[1]->stride == 4*sizeof(GLfloat));
+		  if (HAVE_SPEC && VB->BackfaceSecondaryColorPtr) {
+		     GLfloat (*vbspec)[4] = VB->BackfaceSecondaryColorPtr->data;
+		     ASSERT(VB->BackfaceSecondaryColorPtr->stride == 4*sizeof(GLfloat));
 
 		     if (!DO_FLAT) {
 			VERT_SAVE_SPEC( 0 );
@@ -237,7 +237,7 @@
 	       }
 	    }
 	    else {
-	       GLfloat (*vbindex) = (GLfloat *)VB->IndexPtr[1]->data;
+	       GLfloat (*vbindex) = (GLfloat *)VB->BackfaceIndexPtr->data;
 	       if (!DO_FLAT) {
 		  VERT_SAVE_IND( 0 );
 		  VERT_SAVE_IND( 1 );
@@ -279,7 +279,7 @@
 	 VERT_SAVE_RGBA( 1 );
 	 VERT_COPY_RGBA( v[0], v[2] );
 	 VERT_COPY_RGBA( v[1], v[2] );
-	 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
+	 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
 	    VERT_SAVE_SPEC( 0 );
 	    VERT_SAVE_SPEC( 1 );
 	    VERT_COPY_SPEC( v[0], v[2] );
@@ -374,7 +374,7 @@
       if (HAVE_RGBA) {
 	 VERT_RESTORE_RGBA( 0 );
 	 VERT_RESTORE_RGBA( 1 );
-	 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
+	 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
 	    VERT_RESTORE_SPEC( 0 );
 	    VERT_RESTORE_SPEC( 1 );
 	 }
@@ -395,7 +395,7 @@
    struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
    VERTEX *v[4];
    GLfloat offset = 0;
-   GLfloat z[4];
+   GLfloat z[4] = { 0 };
    GLenum mode = GL_FILL;
    GLuint facing = 0;
    LOCAL_VARS(4);
@@ -436,7 +436,7 @@
 	 if (DO_TWOSIDE && facing == 1)
 	 {
 	    if (HAVE_RGBA) {
-	       GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
+	       GLfloat (*vbcolor)[4] = VB->BackfaceColorPtr->data;
 	       (void)vbcolor;
 
 	       if (HAVE_BACK_COLORS) {
@@ -471,7 +471,7 @@
 		  }
 	          VERT_SAVE_RGBA( 3 );
 
-		  if (VB->ColorPtr[1]->stride) {
+		  if (VB->BackfaceColorPtr->stride) {
 		     if (!DO_FLAT) {
 			VERT_SET_RGBA( v[0], vbcolor[e0] );
 			VERT_SET_RGBA( v[1], vbcolor[e1] );
@@ -488,9 +488,9 @@
 		     VERT_SET_RGBA( v[3], vbcolor[0] );
 		  }
 
-	          if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
-		     GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
-		     ASSERT(VB->SecondaryColorPtr[1]->stride==4*sizeof(GLfloat));
+	          if (HAVE_SPEC && VB->BackfaceSecondaryColorPtr) {
+		     GLfloat (*vbspec)[4] = VB->BackfaceSecondaryColorPtr->data;
+		     ASSERT(VB->BackfaceSecondaryColorPtr->stride==4*sizeof(GLfloat));
 
 		     if (!DO_FLAT) {
 		        VERT_SAVE_SPEC( 0 );
@@ -506,7 +506,7 @@
 	       }
 	    }
 	    else {
-	       GLfloat *vbindex = (GLfloat *)VB->IndexPtr[1]->data;
+	       GLfloat *vbindex = (GLfloat *)VB->BackfaceIndexPtr->data;
 	       if (!DO_FLAT) {
 		  VERT_SAVE_IND( 0 );
 		  VERT_SAVE_IND( 1 );
@@ -553,7 +553,7 @@
 	 VERT_COPY_RGBA( v[0], v[3] );
 	 VERT_COPY_RGBA( v[1], v[3] );
 	 VERT_COPY_RGBA( v[2], v[3] );
-	 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
+	 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
 	    VERT_SAVE_SPEC( 0 );
 	    VERT_SAVE_SPEC( 1 );
 	    VERT_SAVE_SPEC( 2 );
@@ -659,7 +659,7 @@
 	 VERT_RESTORE_RGBA( 0 );
 	 VERT_RESTORE_RGBA( 1 );
 	 VERT_RESTORE_RGBA( 2 );
-	 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
+	 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
 	    VERT_RESTORE_SPEC( 0 );
 	    VERT_RESTORE_SPEC( 1 );
 	    VERT_RESTORE_SPEC( 2 );
@@ -708,7 +708,7 @@
       if (HAVE_RGBA) {
 	 VERT_SAVE_RGBA( 0 );
 	 VERT_COPY_RGBA( v[0], v[1] );
-	 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
+	 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
 	    VERT_SAVE_SPEC( 0 );
 	    VERT_COPY_SPEC( v[0], v[1] );
 	 }
@@ -725,7 +725,7 @@
       if (HAVE_RGBA) {
 	 VERT_RESTORE_RGBA( 0 );
 
-	 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
+	 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
 	    VERT_RESTORE_SPEC( 0 );
 	 }
       }
diff --git a/src/mesa/tnl_dd/t_dd_vb.c b/src/mesa/tnl_dd/t_dd_vb.c
index b3937c2..a8a0a69 100644
--- a/src/mesa/tnl_dd/t_dd_vb.c
+++ b/src/mesa/tnl_dd/t_dd_vb.c
@@ -297,19 +297,19 @@
    LOCALVARS
    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
 
-   if (VB->ColorPtr[1]) {
-      assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat));
+   if (VB->BackfaceColorPtr) {
+      assert(VB->BackfaceColorPtr->stride == 4 * sizeof(GLfloat));
 
       INTERP_4F( t,
-		    GET_COLOR(VB->ColorPtr[1], dst),
-		    GET_COLOR(VB->ColorPtr[1], out),
-		    GET_COLOR(VB->ColorPtr[1], in) );
+		    GET_COLOR(VB->BackfaceColorPtr, dst),
+		    GET_COLOR(VB->BackfaceColorPtr, out),
+		    GET_COLOR(VB->BackfaceColorPtr, in) );
 
-      if (VB->SecondaryColorPtr[1]) {
+      if (VB->BackfaceSecondaryColorPtr) {
 	 INTERP_3F( t,
-		       GET_COLOR(VB->SecondaryColorPtr[1], dst),
-		       GET_COLOR(VB->SecondaryColorPtr[1], out),
-		       GET_COLOR(VB->SecondaryColorPtr[1], in) );
+		       GET_COLOR(VB->BackfaceSecondaryColorPtr, dst),
+		       GET_COLOR(VB->BackfaceSecondaryColorPtr, out),
+		       GET_COLOR(VB->BackfaceSecondaryColorPtr, in) );
       }
    }
 
@@ -326,13 +326,13 @@
    LOCALVARS
       struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
 
-   if (VB->ColorPtr[1]) {
-      COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst), 
-		GET_COLOR(VB->ColorPtr[1], src) );
+   if (VB->BackfaceColorPtr) {
+      COPY_4FV( GET_COLOR(VB->BackfaceColorPtr, dst),
+		GET_COLOR(VB->BackfaceColorPtr, src) );
 
-      if (VB->SecondaryColorPtr[1]) {
-	 COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst), 
-		   GET_COLOR(VB->SecondaryColorPtr[1], src) );
+      if (VB->BackfaceSecondaryColorPtr) {
+	 COPY_4FV( GET_COLOR(VB->BackfaceSecondaryColorPtr, dst),
+		   GET_COLOR(VB->BackfaceSecondaryColorPtr, src) );
       }
    }
 
diff --git a/src/mesa/tnl_dd/t_dd_vbtmp.h b/src/mesa/tnl_dd/t_dd_vbtmp.h
index 92dd893..85101b9 100644
--- a/src/mesa/tnl_dd/t_dd_vbtmp.h
+++ b/src/mesa/tnl_dd/t_dd_vbtmp.h
@@ -153,46 +153,46 @@
 
    if (DO_TEX3) {
       const GLuint t3 = GET_TEXSOURCE(3);
-      tc3 = VB->TexCoordPtr[t3]->data;
-      tc3_stride = VB->TexCoordPtr[t3]->stride;
+      tc3 = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t3]->data;
+      tc3_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t3]->stride;
       if (DO_PTEX)
-	 tc3_size = VB->TexCoordPtr[t3]->size;
+	 tc3_size = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t3]->size;
    }
 
    if (DO_TEX2) {
       const GLuint t2 = GET_TEXSOURCE(2);
-      tc2 = VB->TexCoordPtr[t2]->data;
-      tc2_stride = VB->TexCoordPtr[t2]->stride;
+      tc2 = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->data;
+      tc2_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->stride;
       if (DO_PTEX)
-	 tc2_size = VB->TexCoordPtr[t2]->size;
+	 tc2_size = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->size;
    }
 
    if (DO_TEX1) {
       const GLuint t1 = GET_TEXSOURCE(1);
-      tc1 = VB->TexCoordPtr[t1]->data;
-      tc1_stride = VB->TexCoordPtr[t1]->stride;
+      tc1 = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->data;
+      tc1_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->stride;
       if (DO_PTEX)
-	 tc1_size = VB->TexCoordPtr[t1]->size;
+	 tc1_size = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->size;
    }
 
    if (DO_TEX0) {
       const GLuint t0 = GET_TEXSOURCE(0);
-      tc0_stride = VB->TexCoordPtr[t0]->stride;
-      tc0 = VB->TexCoordPtr[t0]->data;
+      tc0_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->stride;
+      tc0 = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->data;
       if (DO_PTEX) 
-	 tc0_size = VB->TexCoordPtr[t0]->size;
+	 tc0_size = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->size;
    }
 
    if (DO_RGBA) {
-      col_stride = VB->ColorPtr[0]->stride;
-      col = VB->ColorPtr[0]->data;
-      col_size = VB->ColorPtr[0]->size;
+      col_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride;
+      col = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;
+      col_size = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->size;
    }
 
    if (DO_SPEC) {
-      if (VB->SecondaryColorPtr[0]) {
-	 spec_stride = VB->SecondaryColorPtr[0]->stride;
-	 spec = VB->SecondaryColorPtr[0]->data;
+      if (VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
+	 spec_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->stride;
+	 spec = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->data;
       } else {
 	 spec = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
 	 spec_stride = 0;
@@ -200,9 +200,9 @@
    }
 
    if (DO_FOG) {
-      if (VB->FogCoordPtr) {
-	 fog = VB->FogCoordPtr->data;
-	 fog_stride = VB->FogCoordPtr->stride;
+      if (VB->AttribPtr[_TNL_ATTRIB_FOG]) {
+	 fog = VB->AttribPtr[_TNL_ATTRIB_FOG]->data;
+	 fog_stride = VB->AttribPtr[_TNL_ATTRIB_FOG]->stride;
       }
       else {
 	 static GLfloat tmp[4] = {0, 0, 0, 0};
@@ -356,9 +356,9 @@
 
    ASSERT(stride == 4);
 
-   col = VB->ColorPtr[0]->data;
-   col_stride = VB->ColorPtr[0]->stride;
-   col_size = VB->ColorPtr[0]->size;
+   col = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;
+   col_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride;
+   col_size = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->size;
 
 /*     fprintf(stderr, "%s(small) importable %x\n",  */
 /*  	   __FUNCTION__, VB->importable_data); */
@@ -410,22 +410,22 @@
 
    /* Force 'missing' texcoords to something valid.
     */
-   if (DO_TEX3 && VB->TexCoordPtr[2] == 0)
-      VB->TexCoordPtr[2] = VB->TexCoordPtr[3];
+   if (DO_TEX3 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + 2] == 0)
+      VB->AttribPtr[_TNL_ATTRIB_TEX0 + 2] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + 3];
 
-   if (DO_TEX2 && VB->TexCoordPtr[1] == 0)
-      VB->TexCoordPtr[1] = VB->TexCoordPtr[2];
+   if (DO_TEX2 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + 1] == 0)
+      VB->AttribPtr[_TNL_ATTRIB_TEX0 + 1] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + 2];
 
-   if (DO_TEX1 && VB->TexCoordPtr[0] == 0)
-      VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
+   if (DO_TEX1 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + 0] == 0)
+      VB->AttribPtr[_TNL_ATTRIB_TEX0 + 0] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + 1];
 
    if (DO_PTEX)
       return GL_TRUE;
    
-   if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) ||
-       (DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) ||
-       (DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4) ||
-       (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4))
+   if ((DO_TEX3 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(3)]->size == 4) ||
+       (DO_TEX2 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(2)]->size == 4) ||
+       (DO_TEX1 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(1)]->size == 4) ||
+       (DO_TEX0 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(0)]->size == 4))
       return GL_FALSE;
 
    return GL_TRUE;
@@ -438,14 +438,14 @@
 
    /* Force 'missing' texcoords to something valid.
     */
-   if (DO_TEX3 && VB->TexCoordPtr[2] == 0)
-      VB->TexCoordPtr[2] = VB->TexCoordPtr[3];
+   if (DO_TEX3 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + 2] == 0)
+      VB->AttribPtr[_TNL_ATTRIB_TEX0 + 2] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + 3];
 
-   if (DO_TEX2 && VB->TexCoordPtr[1] == 0)
-      VB->TexCoordPtr[1] = VB->TexCoordPtr[2];
+   if (DO_TEX2 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + 1] == 0)
+      VB->AttribPtr[_TNL_ATTRIB_TEX0 + 1] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + 2];
 
-   if (DO_TEX1 && VB->TexCoordPtr[0] == 0)
-      VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
+   if (DO_TEX1 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + 0] == 0)
+      VB->AttribPtr[_TNL_ATTRIB_TEX0 + 0] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + 1];
 
    if (DO_PTEX)
       return GL_TRUE;
@@ -453,14 +453,14 @@
    /* No hardware support for projective texture.  Can fake it for
     * TEX0 only.
     */
-   if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) ||
-       (DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) ||
-       (DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4)) {
+   if ((DO_TEX3 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(3)]->size == 4) ||
+       (DO_TEX2 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(2)]->size == 4) ||
+       (DO_TEX1 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(1)]->size == 4)) {
       PTEX_FALLBACK();
       return GL_FALSE;
    }
 
-   if (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4) {
+   if (DO_TEX0 && VB->AttribPtr[_TNL_ATTRIB_TEX0 + GET_TEXSOURCE(0)]->size == 4) {
       if (DO_TEX1 || DO_TEX2 || DO_TEX3) {
 	 PTEX_FALLBACK();
       }
diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h
index 0a05b8d..98c1f36 100644
--- a/src/mesa/vbo/vbo_exec.h
+++ b/src/mesa/vbo/vbo_exec.h
@@ -138,6 +138,10 @@
        */
       const struct gl_client_array *inputs[VERT_ATTRIB_MAX];
    } array;
+
+#ifdef DEBUG
+   GLint flush_call_depth;
+#endif
 };
 
 
diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c
index f72d2d8..f0a7eea 100644
--- a/src/mesa/vbo/vbo_exec_api.c
+++ b/src/mesa/vbo/vbo_exec_api.c
@@ -867,15 +867,27 @@
 }
 
 
-
+/**
+ * \param flags  bitmask of FLUSH_STORED_VERTICES, FLUSH_UPDATE_CURRENT
+ */
 void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags )
 {
    struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
 
+#ifdef DEBUG
+   /* debug check: make sure we don't get called recursively */
+   exec->flush_call_depth++;
+   assert(exec->flush_call_depth == 1);
+#endif
+
    if (0) _mesa_printf("%s\n", __FUNCTION__);
 
    if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
       if (0) _mesa_printf("%s - inside begin/end\n", __FUNCTION__);
+#ifdef DEBUG
+      exec->flush_call_depth--;
+      assert(exec->flush_call_depth == 0);
+#endif
       return;
    }
 
@@ -889,6 +901,11 @@
    }
 
    exec->ctx->Driver.NeedFlush &= ~flags;
+
+#ifdef DEBUG
+   exec->flush_call_depth--;
+   assert(exec->flush_call_depth == 0);
+#endif
 }
 
 
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index fd70b57..6de8f05 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -146,7 +146,7 @@
                                array->Ptr, array->BufferObj->Name);
                   f[k] = 1.0; /* XXX replace the bad value! */
                }
-               //assert(!IS_INF_OR_NAN(f[k]));
+               /*assert(!IS_INF_OR_NAN(f[k]));*/
             }
          }
          break;
diff --git a/src/mesa/vbo/vbo_exec_eval.c b/src/mesa/vbo/vbo_exec_eval.c
index 0c691b3..a784621 100644
--- a/src/mesa/vbo/vbo_exec_eval.c
+++ b/src/mesa/vbo/vbo_exec_eval.c
@@ -35,17 +35,20 @@
 
 static void clear_active_eval1( struct vbo_exec_context *exec, GLuint attr ) 
 {
+   assert(attr < Elements(exec->eval.map1));
    exec->eval.map1[attr].map = NULL;
 }
 
 static void clear_active_eval2( struct vbo_exec_context *exec, GLuint attr ) 
 {
+   assert(attr < Elements(exec->eval.map2));
    exec->eval.map2[attr].map = NULL;
 }
 
 static void set_active_eval1( struct vbo_exec_context *exec, GLuint attr, GLuint dim, 
 			      struct gl_1d_map *map )
 {
+   assert(attr < Elements(exec->eval.map1));
    if (!exec->eval.map1[attr].map) {
       exec->eval.map1[attr].map = map;
       exec->eval.map1[attr].sz = dim;
@@ -55,6 +58,7 @@
 static void set_active_eval2( struct vbo_exec_context *exec, GLuint attr, GLuint dim, 
 			      struct gl_2d_map *map )
 {
+   assert(attr < Elements(exec->eval.map2));
    if (!exec->eval.map2[attr].map) {
       exec->eval.map2[attr].map = map;
       exec->eval.map2[attr].sz = dim;
@@ -73,18 +77,6 @@
       clear_active_eval2( exec, attr );
    }
 
-   /* _NEW_PROGRAM */
-   if (ctx->VertexProgram._Enabled) {
-      for (attr = 0; attr < VBO_ATTRIB_FIRST_MATERIAL; attr++) {
-	 /* _NEW_EVAL */
-	 if (ctx->Eval.Map1Attrib[attr]) 
-	    set_active_eval1( exec, attr, 4, &ctx->EvalMap.Map1Attrib[attr] );
-
-	 if (ctx->Eval.Map2Attrib[attr]) 
-	    set_active_eval2( exec, attr, 4, &ctx->EvalMap.Map2Attrib[attr] );
-      }
-   }
-
    if (ctx->Eval.Map1Color4) 
       set_active_eval1( exec, VBO_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map1Color4 );
       
@@ -125,6 +117,23 @@
    else if (ctx->Eval.Map2Vertex3) 
       set_active_eval2( exec, VBO_ATTRIB_POS, 3, &ctx->EvalMap.Map2Vertex3 );
 
+   /* _NEW_PROGRAM */
+   if (ctx->VertexProgram._Enabled) {
+      /* These are the 16 evaluators which GL_NV_vertex_program defines.
+       * They alias and override the conventional vertex attributs.
+       */
+      for (attr = 0; attr < 16; attr++) {
+         /* _NEW_EVAL */
+         assert(attr < Elements(ctx->Eval.Map1Attrib));
+         if (ctx->Eval.Map1Attrib[attr]) 
+            set_active_eval1( exec, attr, 4, &ctx->EvalMap.Map1Attrib[attr] );
+
+         assert(attr < Elements(ctx->Eval.Map2Attrib));
+         if (ctx->Eval.Map2Attrib[attr]) 
+            set_active_eval2( exec, attr, 4, &ctx->EvalMap.Map2Attrib[attr] );
+      }
+   }
+
    exec->eval.recalculate_maps = 0;
 }
 
diff --git a/src/mesa/vf/vf_generic.c b/src/mesa/vf/vf_generic.c
index baa00af..0af8893 100644
--- a/src/mesa/vf/vf_generic.c
+++ b/src/mesa/vf/vf_generic.c
@@ -211,7 +211,7 @@
 static INLINE void insert_3f_xyw_err( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
 {
    (void) a; (void) v; (void) in;
-   _mesa_exit(1);
+   exit(1);
 }
 
 static INLINE void insert_3f_3( const struct vf_attr *a, GLubyte *v, const GLfloat *in )
diff --git a/src/mesa/x86-64/glapi_x86-64.S b/src/mesa/x86-64/glapi_x86-64.S
index 05afbb2..8edb69b 100644
--- a/src/mesa/x86-64/glapi_x86-64.S
+++ b/src/mesa/x86-64/glapi_x86-64.S
@@ -29800,42 +29800,338 @@
 	.size	GL_PREFIX(FramebufferTextureLayerEXT), .-GL_PREFIX(FramebufferTextureLayerEXT)
 
 	.p2align	4,,15
+	.globl	GL_PREFIX(ColorMaskIndexedEXT)
+	.type	GL_PREFIX(ColorMaskIndexedEXT), @function
+GL_PREFIX(ColorMaskIndexedEXT):
+#if defined(GLX_USE_TLS)
+	call	_x86_64_get_dispatch@PLT
+	movq	6296(%rax), %r11
+	jmp	*%r11
+#elif defined(PTHREADS)
+	pushq	%rdi
+	pushq	%rsi
+	pushq	%rdx
+	pushq	%rcx
+	pushq	%r8
+	call	_x86_64_get_dispatch@PLT
+	popq	%r8
+	popq	%rcx
+	popq	%rdx
+	popq	%rsi
+	popq	%rdi
+	movq	6296(%rax), %r11
+	jmp	*%r11
+#else
+	movq	_glapi_Dispatch(%rip), %rax
+	testq	%rax, %rax
+	je	1f
+	movq	6296(%rax), %r11
+	jmp	*%r11
+1:
+	pushq	%rdi
+	pushq	%rsi
+	pushq	%rdx
+	pushq	%rcx
+	pushq	%r8
+	call	_glapi_get_dispatch
+	popq	%r8
+	popq	%rcx
+	popq	%rdx
+	popq	%rsi
+	popq	%rdi
+	movq	6296(%rax), %r11
+	jmp	*%r11
+#endif /* defined(GLX_USE_TLS) */
+	.size	GL_PREFIX(ColorMaskIndexedEXT), .-GL_PREFIX(ColorMaskIndexedEXT)
+
+	.p2align	4,,15
+	.globl	GL_PREFIX(DisableIndexedEXT)
+	.type	GL_PREFIX(DisableIndexedEXT), @function
+GL_PREFIX(DisableIndexedEXT):
+#if defined(GLX_USE_TLS)
+	call	_x86_64_get_dispatch@PLT
+	movq	6304(%rax), %r11
+	jmp	*%r11
+#elif defined(PTHREADS)
+	pushq	%rdi
+	pushq	%rsi
+	pushq	%rbp
+	call	_x86_64_get_dispatch@PLT
+	popq	%rbp
+	popq	%rsi
+	popq	%rdi
+	movq	6304(%rax), %r11
+	jmp	*%r11
+#else
+	movq	_glapi_Dispatch(%rip), %rax
+	testq	%rax, %rax
+	je	1f
+	movq	6304(%rax), %r11
+	jmp	*%r11
+1:
+	pushq	%rdi
+	pushq	%rsi
+	pushq	%rbp
+	call	_glapi_get_dispatch
+	popq	%rbp
+	popq	%rsi
+	popq	%rdi
+	movq	6304(%rax), %r11
+	jmp	*%r11
+#endif /* defined(GLX_USE_TLS) */
+	.size	GL_PREFIX(DisableIndexedEXT), .-GL_PREFIX(DisableIndexedEXT)
+
+	.p2align	4,,15
+	.globl	GL_PREFIX(EnableIndexedEXT)
+	.type	GL_PREFIX(EnableIndexedEXT), @function
+GL_PREFIX(EnableIndexedEXT):
+#if defined(GLX_USE_TLS)
+	call	_x86_64_get_dispatch@PLT
+	movq	6312(%rax), %r11
+	jmp	*%r11
+#elif defined(PTHREADS)
+	pushq	%rdi
+	pushq	%rsi
+	pushq	%rbp
+	call	_x86_64_get_dispatch@PLT
+	popq	%rbp
+	popq	%rsi
+	popq	%rdi
+	movq	6312(%rax), %r11
+	jmp	*%r11
+#else
+	movq	_glapi_Dispatch(%rip), %rax
+	testq	%rax, %rax
+	je	1f
+	movq	6312(%rax), %r11
+	jmp	*%r11
+1:
+	pushq	%rdi
+	pushq	%rsi
+	pushq	%rbp
+	call	_glapi_get_dispatch
+	popq	%rbp
+	popq	%rsi
+	popq	%rdi
+	movq	6312(%rax), %r11
+	jmp	*%r11
+#endif /* defined(GLX_USE_TLS) */
+	.size	GL_PREFIX(EnableIndexedEXT), .-GL_PREFIX(EnableIndexedEXT)
+
+	.p2align	4,,15
+	.globl	GL_PREFIX(GetBooleanIndexedvEXT)
+	.type	GL_PREFIX(GetBooleanIndexedvEXT), @function
+GL_PREFIX(GetBooleanIndexedvEXT):
+#if defined(GLX_USE_TLS)
+	call	_x86_64_get_dispatch@PLT
+	movq	6320(%rax), %r11
+	jmp	*%r11
+#elif defined(PTHREADS)
+	pushq	%rdi
+	pushq	%rsi
+	pushq	%rdx
+	call	_x86_64_get_dispatch@PLT
+	popq	%rdx
+	popq	%rsi
+	popq	%rdi
+	movq	6320(%rax), %r11
+	jmp	*%r11
+#else
+	movq	_glapi_Dispatch(%rip), %rax
+	testq	%rax, %rax
+	je	1f
+	movq	6320(%rax), %r11
+	jmp	*%r11
+1:
+	pushq	%rdi
+	pushq	%rsi
+	pushq	%rdx
+	call	_glapi_get_dispatch
+	popq	%rdx
+	popq	%rsi
+	popq	%rdi
+	movq	6320(%rax), %r11
+	jmp	*%r11
+#endif /* defined(GLX_USE_TLS) */
+	.size	GL_PREFIX(GetBooleanIndexedvEXT), .-GL_PREFIX(GetBooleanIndexedvEXT)
+
+	.p2align	4,,15
+	.globl	GL_PREFIX(GetIntegerIndexedvEXT)
+	.type	GL_PREFIX(GetIntegerIndexedvEXT), @function
+GL_PREFIX(GetIntegerIndexedvEXT):
+#if defined(GLX_USE_TLS)
+	call	_x86_64_get_dispatch@PLT
+	movq	6328(%rax), %r11
+	jmp	*%r11
+#elif defined(PTHREADS)
+	pushq	%rdi
+	pushq	%rsi
+	pushq	%rdx
+	call	_x86_64_get_dispatch@PLT
+	popq	%rdx
+	popq	%rsi
+	popq	%rdi
+	movq	6328(%rax), %r11
+	jmp	*%r11
+#else
+	movq	_glapi_Dispatch(%rip), %rax
+	testq	%rax, %rax
+	je	1f
+	movq	6328(%rax), %r11
+	jmp	*%r11
+1:
+	pushq	%rdi
+	pushq	%rsi
+	pushq	%rdx
+	call	_glapi_get_dispatch
+	popq	%rdx
+	popq	%rsi
+	popq	%rdi
+	movq	6328(%rax), %r11
+	jmp	*%r11
+#endif /* defined(GLX_USE_TLS) */
+	.size	GL_PREFIX(GetIntegerIndexedvEXT), .-GL_PREFIX(GetIntegerIndexedvEXT)
+
+	.p2align	4,,15
+	.globl	GL_PREFIX(IsEnabledIndexedEXT)
+	.type	GL_PREFIX(IsEnabledIndexedEXT), @function
+GL_PREFIX(IsEnabledIndexedEXT):
+#if defined(GLX_USE_TLS)
+	call	_x86_64_get_dispatch@PLT
+	movq	6336(%rax), %r11
+	jmp	*%r11
+#elif defined(PTHREADS)
+	pushq	%rdi
+	pushq	%rsi
+	pushq	%rbp
+	call	_x86_64_get_dispatch@PLT
+	popq	%rbp
+	popq	%rsi
+	popq	%rdi
+	movq	6336(%rax), %r11
+	jmp	*%r11
+#else
+	movq	_glapi_Dispatch(%rip), %rax
+	testq	%rax, %rax
+	je	1f
+	movq	6336(%rax), %r11
+	jmp	*%r11
+1:
+	pushq	%rdi
+	pushq	%rsi
+	pushq	%rbp
+	call	_glapi_get_dispatch
+	popq	%rbp
+	popq	%rsi
+	popq	%rdi
+	movq	6336(%rax), %r11
+	jmp	*%r11
+#endif /* defined(GLX_USE_TLS) */
+	.size	GL_PREFIX(IsEnabledIndexedEXT), .-GL_PREFIX(IsEnabledIndexedEXT)
+
+	.p2align	4,,15
+	.globl	GL_PREFIX(BeginConditionalRenderNV)
+	.type	GL_PREFIX(BeginConditionalRenderNV), @function
+GL_PREFIX(BeginConditionalRenderNV):
+#if defined(GLX_USE_TLS)
+	call	_x86_64_get_dispatch@PLT
+	movq	6344(%rax), %r11
+	jmp	*%r11
+#elif defined(PTHREADS)
+	pushq	%rdi
+	pushq	%rsi
+	pushq	%rbp
+	call	_x86_64_get_dispatch@PLT
+	popq	%rbp
+	popq	%rsi
+	popq	%rdi
+	movq	6344(%rax), %r11
+	jmp	*%r11
+#else
+	movq	_glapi_Dispatch(%rip), %rax
+	testq	%rax, %rax
+	je	1f
+	movq	6344(%rax), %r11
+	jmp	*%r11
+1:
+	pushq	%rdi
+	pushq	%rsi
+	pushq	%rbp
+	call	_glapi_get_dispatch
+	popq	%rbp
+	popq	%rsi
+	popq	%rdi
+	movq	6344(%rax), %r11
+	jmp	*%r11
+#endif /* defined(GLX_USE_TLS) */
+	.size	GL_PREFIX(BeginConditionalRenderNV), .-GL_PREFIX(BeginConditionalRenderNV)
+
+	.p2align	4,,15
+	.globl	GL_PREFIX(EndConditionalRenderNV)
+	.type	GL_PREFIX(EndConditionalRenderNV), @function
+GL_PREFIX(EndConditionalRenderNV):
+#if defined(GLX_USE_TLS)
+	call	_x86_64_get_dispatch@PLT
+	movq	6352(%rax), %r11
+	jmp	*%r11
+#elif defined(PTHREADS)
+	pushq	%rbp
+	call	_x86_64_get_dispatch@PLT
+	popq	%rbp
+	movq	6352(%rax), %r11
+	jmp	*%r11
+#else
+	movq	_glapi_Dispatch(%rip), %rax
+	testq	%rax, %rax
+	je	1f
+	movq	6352(%rax), %r11
+	jmp	*%r11
+1:
+	pushq	%rbp
+	call	_glapi_get_dispatch
+	popq	%rbp
+	movq	6352(%rax), %r11
+	jmp	*%r11
+#endif /* defined(GLX_USE_TLS) */
+	.size	GL_PREFIX(EndConditionalRenderNV), .-GL_PREFIX(EndConditionalRenderNV)
+
+	.p2align	4,,15
 	.globl	GL_PREFIX(ProvokingVertexEXT)
 	.type	GL_PREFIX(ProvokingVertexEXT), @function
 GL_PREFIX(ProvokingVertexEXT):
 #if defined(GLX_USE_TLS)
 	call	_x86_64_get_dispatch@PLT
-	movq	6296(%rax), %r11
+	movq	6360(%rax), %r11
 	jmp	*%r11
 #elif defined(PTHREADS)
 	pushq	%rdi
 	call	_x86_64_get_dispatch@PLT
 	popq	%rdi
-	movq	6296(%rax), %r11
+	movq	6360(%rax), %r11
 	jmp	*%r11
 #else
 	movq	_glapi_Dispatch(%rip), %rax
 	testq	%rax, %rax
 	je	1f
-	movq	6296(%rax), %r11
+	movq	6360(%rax), %r11
 	jmp	*%r11
 1:
 	pushq	%rdi
 	call	_glapi_get_dispatch
 	popq	%rdi
-	movq	6296(%rax), %r11
+	movq	6360(%rax), %r11
 	jmp	*%r11
 #endif /* defined(GLX_USE_TLS) */
 	.size	GL_PREFIX(ProvokingVertexEXT), .-GL_PREFIX(ProvokingVertexEXT)
 
 	.p2align	4,,15
-	.globl	GL_PREFIX(_dispatch_stub_788)
-	.type	GL_PREFIX(_dispatch_stub_788), @function
-	HIDDEN(GL_PREFIX(_dispatch_stub_788))
-GL_PREFIX(_dispatch_stub_788):
+	.globl	GL_PREFIX(_dispatch_stub_796)
+	.type	GL_PREFIX(_dispatch_stub_796), @function
+	HIDDEN(GL_PREFIX(_dispatch_stub_796))
+GL_PREFIX(_dispatch_stub_796):
 #if defined(GLX_USE_TLS)
 	call	_x86_64_get_dispatch@PLT
-	movq	6304(%rax), %r11
+	movq	6368(%rax), %r11
 	jmp	*%r11
 #elif defined(PTHREADS)
 	pushq	%rdi
@@ -29845,13 +30141,13 @@
 	popq	%rdx
 	popq	%rsi
 	popq	%rdi
-	movq	6304(%rax), %r11
+	movq	6368(%rax), %r11
 	jmp	*%r11
 #else
 	movq	_glapi_Dispatch(%rip), %rax
 	testq	%rax, %rax
 	je	1f
-	movq	6304(%rax), %r11
+	movq	6368(%rax), %r11
 	jmp	*%r11
 1:
 	pushq	%rdi
@@ -29861,19 +30157,19 @@
 	popq	%rdx
 	popq	%rsi
 	popq	%rdi
-	movq	6304(%rax), %r11
+	movq	6368(%rax), %r11
 	jmp	*%r11
 #endif /* defined(GLX_USE_TLS) */
-	.size	GL_PREFIX(_dispatch_stub_788), .-GL_PREFIX(_dispatch_stub_788)
+	.size	GL_PREFIX(_dispatch_stub_796), .-GL_PREFIX(_dispatch_stub_796)
 
 	.p2align	4,,15
-	.globl	GL_PREFIX(_dispatch_stub_789)
-	.type	GL_PREFIX(_dispatch_stub_789), @function
-	HIDDEN(GL_PREFIX(_dispatch_stub_789))
-GL_PREFIX(_dispatch_stub_789):
+	.globl	GL_PREFIX(_dispatch_stub_797)
+	.type	GL_PREFIX(_dispatch_stub_797), @function
+	HIDDEN(GL_PREFIX(_dispatch_stub_797))
+GL_PREFIX(_dispatch_stub_797):
 #if defined(GLX_USE_TLS)
 	call	_x86_64_get_dispatch@PLT
-	movq	6312(%rax), %r11
+	movq	6376(%rax), %r11
 	jmp	*%r11
 #elif defined(PTHREADS)
 	pushq	%rdi
@@ -29883,13 +30179,13 @@
 	popq	%rdx
 	popq	%rsi
 	popq	%rdi
-	movq	6312(%rax), %r11
+	movq	6376(%rax), %r11
 	jmp	*%r11
 #else
 	movq	_glapi_Dispatch(%rip), %rax
 	testq	%rax, %rax
 	je	1f
-	movq	6312(%rax), %r11
+	movq	6376(%rax), %r11
 	jmp	*%r11
 1:
 	pushq	%rdi
@@ -29899,19 +30195,19 @@
 	popq	%rdx
 	popq	%rsi
 	popq	%rdi
-	movq	6312(%rax), %r11
+	movq	6376(%rax), %r11
 	jmp	*%r11
 #endif /* defined(GLX_USE_TLS) */
-	.size	GL_PREFIX(_dispatch_stub_789), .-GL_PREFIX(_dispatch_stub_789)
+	.size	GL_PREFIX(_dispatch_stub_797), .-GL_PREFIX(_dispatch_stub_797)
 
 	.p2align	4,,15
-	.globl	GL_PREFIX(_dispatch_stub_790)
-	.type	GL_PREFIX(_dispatch_stub_790), @function
-	HIDDEN(GL_PREFIX(_dispatch_stub_790))
-GL_PREFIX(_dispatch_stub_790):
+	.globl	GL_PREFIX(_dispatch_stub_798)
+	.type	GL_PREFIX(_dispatch_stub_798), @function
+	HIDDEN(GL_PREFIX(_dispatch_stub_798))
+GL_PREFIX(_dispatch_stub_798):
 #if defined(GLX_USE_TLS)
 	call	_x86_64_get_dispatch@PLT
-	movq	6320(%rax), %r11
+	movq	6384(%rax), %r11
 	jmp	*%r11
 #elif defined(PTHREADS)
 	pushq	%rdi
@@ -29925,13 +30221,13 @@
 	popq	%rdx
 	popq	%rsi
 	popq	%rdi
-	movq	6320(%rax), %r11
+	movq	6384(%rax), %r11
 	jmp	*%r11
 #else
 	movq	_glapi_Dispatch(%rip), %rax
 	testq	%rax, %rax
 	je	1f
-	movq	6320(%rax), %r11
+	movq	6384(%rax), %r11
 	jmp	*%r11
 1:
 	pushq	%rdi
@@ -29945,19 +30241,19 @@
 	popq	%rdx
 	popq	%rsi
 	popq	%rdi
-	movq	6320(%rax), %r11
+	movq	6384(%rax), %r11
 	jmp	*%r11
 #endif /* defined(GLX_USE_TLS) */
-	.size	GL_PREFIX(_dispatch_stub_790), .-GL_PREFIX(_dispatch_stub_790)
+	.size	GL_PREFIX(_dispatch_stub_798), .-GL_PREFIX(_dispatch_stub_798)
 
 	.p2align	4,,15
-	.globl	GL_PREFIX(_dispatch_stub_791)
-	.type	GL_PREFIX(_dispatch_stub_791), @function
-	HIDDEN(GL_PREFIX(_dispatch_stub_791))
-GL_PREFIX(_dispatch_stub_791):
+	.globl	GL_PREFIX(_dispatch_stub_799)
+	.type	GL_PREFIX(_dispatch_stub_799), @function
+	HIDDEN(GL_PREFIX(_dispatch_stub_799))
+GL_PREFIX(_dispatch_stub_799):
 #if defined(GLX_USE_TLS)
 	call	_x86_64_get_dispatch@PLT
-	movq	6328(%rax), %r11
+	movq	6392(%rax), %r11
 	jmp	*%r11
 #elif defined(PTHREADS)
 	pushq	%rdi
@@ -29971,13 +30267,13 @@
 	popq	%rdx
 	popq	%rsi
 	popq	%rdi
-	movq	6328(%rax), %r11
+	movq	6392(%rax), %r11
 	jmp	*%r11
 #else
 	movq	_glapi_Dispatch(%rip), %rax
 	testq	%rax, %rax
 	je	1f
-	movq	6328(%rax), %r11
+	movq	6392(%rax), %r11
 	jmp	*%r11
 1:
 	pushq	%rdi
@@ -29991,19 +30287,19 @@
 	popq	%rdx
 	popq	%rsi
 	popq	%rdi
-	movq	6328(%rax), %r11
+	movq	6392(%rax), %r11
 	jmp	*%r11
 #endif /* defined(GLX_USE_TLS) */
-	.size	GL_PREFIX(_dispatch_stub_791), .-GL_PREFIX(_dispatch_stub_791)
+	.size	GL_PREFIX(_dispatch_stub_799), .-GL_PREFIX(_dispatch_stub_799)
 
 	.p2align	4,,15
-	.globl	GL_PREFIX(_dispatch_stub_792)
-	.type	GL_PREFIX(_dispatch_stub_792), @function
-	HIDDEN(GL_PREFIX(_dispatch_stub_792))
-GL_PREFIX(_dispatch_stub_792):
+	.globl	GL_PREFIX(_dispatch_stub_800)
+	.type	GL_PREFIX(_dispatch_stub_800), @function
+	HIDDEN(GL_PREFIX(_dispatch_stub_800))
+GL_PREFIX(_dispatch_stub_800):
 #if defined(GLX_USE_TLS)
 	call	_x86_64_get_dispatch@PLT
-	movq	6336(%rax), %r11
+	movq	6400(%rax), %r11
 	jmp	*%r11
 #elif defined(PTHREADS)
 	pushq	%rdi
@@ -30017,13 +30313,13 @@
 	popq	%rdx
 	popq	%rsi
 	popq	%rdi
-	movq	6336(%rax), %r11
+	movq	6400(%rax), %r11
 	jmp	*%r11
 #else
 	movq	_glapi_Dispatch(%rip), %rax
 	testq	%rax, %rax
 	je	1f
-	movq	6336(%rax), %r11
+	movq	6400(%rax), %r11
 	jmp	*%r11
 1:
 	pushq	%rdi
@@ -30037,19 +30333,19 @@
 	popq	%rdx
 	popq	%rsi
 	popq	%rdi
-	movq	6336(%rax), %r11
+	movq	6400(%rax), %r11
 	jmp	*%r11
 #endif /* defined(GLX_USE_TLS) */
-	.size	GL_PREFIX(_dispatch_stub_792), .-GL_PREFIX(_dispatch_stub_792)
+	.size	GL_PREFIX(_dispatch_stub_800), .-GL_PREFIX(_dispatch_stub_800)
 
 	.p2align	4,,15
-	.globl	GL_PREFIX(_dispatch_stub_793)
-	.type	GL_PREFIX(_dispatch_stub_793), @function
-	HIDDEN(GL_PREFIX(_dispatch_stub_793))
-GL_PREFIX(_dispatch_stub_793):
+	.globl	GL_PREFIX(_dispatch_stub_801)
+	.type	GL_PREFIX(_dispatch_stub_801), @function
+	HIDDEN(GL_PREFIX(_dispatch_stub_801))
+GL_PREFIX(_dispatch_stub_801):
 #if defined(GLX_USE_TLS)
 	call	_x86_64_get_dispatch@PLT
-	movq	6344(%rax), %r11
+	movq	6408(%rax), %r11
 	jmp	*%r11
 #elif defined(PTHREADS)
 	pushq	%rdi
@@ -30059,13 +30355,13 @@
 	popq	%rdx
 	popq	%rsi
 	popq	%rdi
-	movq	6344(%rax), %r11
+	movq	6408(%rax), %r11
 	jmp	*%r11
 #else
 	movq	_glapi_Dispatch(%rip), %rax
 	testq	%rax, %rax
 	je	1f
-	movq	6344(%rax), %r11
+	movq	6408(%rax), %r11
 	jmp	*%r11
 1:
 	pushq	%rdi
@@ -30075,19 +30371,19 @@
 	popq	%rdx
 	popq	%rsi
 	popq	%rdi
-	movq	6344(%rax), %r11
+	movq	6408(%rax), %r11
 	jmp	*%r11
 #endif /* defined(GLX_USE_TLS) */
-	.size	GL_PREFIX(_dispatch_stub_793), .-GL_PREFIX(_dispatch_stub_793)
+	.size	GL_PREFIX(_dispatch_stub_801), .-GL_PREFIX(_dispatch_stub_801)
 
 	.p2align	4,,15
-	.globl	GL_PREFIX(_dispatch_stub_794)
-	.type	GL_PREFIX(_dispatch_stub_794), @function
-	HIDDEN(GL_PREFIX(_dispatch_stub_794))
-GL_PREFIX(_dispatch_stub_794):
+	.globl	GL_PREFIX(_dispatch_stub_802)
+	.type	GL_PREFIX(_dispatch_stub_802), @function
+	HIDDEN(GL_PREFIX(_dispatch_stub_802))
+GL_PREFIX(_dispatch_stub_802):
 #if defined(GLX_USE_TLS)
 	call	_x86_64_get_dispatch@PLT
-	movq	6352(%rax), %r11
+	movq	6416(%rax), %r11
 	jmp	*%r11
 #elif defined(PTHREADS)
 	pushq	%rdi
@@ -30097,13 +30393,13 @@
 	popq	%rdx
 	popq	%rsi
 	popq	%rdi
-	movq	6352(%rax), %r11
+	movq	6416(%rax), %r11
 	jmp	*%r11
 #else
 	movq	_glapi_Dispatch(%rip), %rax
 	testq	%rax, %rax
 	je	1f
-	movq	6352(%rax), %r11
+	movq	6416(%rax), %r11
 	jmp	*%r11
 1:
 	pushq	%rdi
@@ -30113,10 +30409,10 @@
 	popq	%rdx
 	popq	%rsi
 	popq	%rdi
-	movq	6352(%rax), %r11
+	movq	6416(%rax), %r11
 	jmp	*%r11
 #endif /* defined(GLX_USE_TLS) */
-	.size	GL_PREFIX(_dispatch_stub_794), .-GL_PREFIX(_dispatch_stub_794)
+	.size	GL_PREFIX(_dispatch_stub_802), .-GL_PREFIX(_dispatch_stub_802)
 
 	.globl GL_PREFIX(ArrayElementEXT) ; .set GL_PREFIX(ArrayElementEXT), GL_PREFIX(ArrayElement)
 	.globl GL_PREFIX(BindTextureEXT) ; .set GL_PREFIX(BindTextureEXT), GL_PREFIX(BindTexture)
@@ -30302,6 +30598,7 @@
 	.globl GL_PREFIX(GetAttribLocation) ; .set GL_PREFIX(GetAttribLocation), GL_PREFIX(GetAttribLocationARB)
 	.globl GL_PREFIX(DrawBuffers) ; .set GL_PREFIX(DrawBuffers), GL_PREFIX(DrawBuffersARB)
 	.globl GL_PREFIX(DrawBuffersATI) ; .set GL_PREFIX(DrawBuffersATI), GL_PREFIX(DrawBuffersARB)
+	.globl GL_PREFIX(RenderbufferStorageMultisampleEXT) ; .set GL_PREFIX(RenderbufferStorageMultisampleEXT), GL_PREFIX(RenderbufferStorageMultisample)
 	.globl GL_PREFIX(PointParameterf) ; .set GL_PREFIX(PointParameterf), GL_PREFIX(PointParameterfEXT)
 	.globl GL_PREFIX(PointParameterfARB) ; .set GL_PREFIX(PointParameterfARB), GL_PREFIX(PointParameterfEXT)
 	.globl GL_PREFIX(PointParameterfv) ; .set GL_PREFIX(PointParameterfv), GL_PREFIX(PointParameterfvEXT)
diff --git a/src/mesa/x86/gen_matypes.c b/src/mesa/x86/gen_matypes.c
index d56b701..14cfa91 100644
--- a/src/mesa/x86/gen_matypes.c
+++ b/src/mesa/x86/gen_matypes.c
@@ -61,21 +61,11 @@
    printf( "\n" );							\
 } while (0)
 
-#if defined(__BEOS__) || defined(__HAIKU__) || defined(_LP64)
 #define OFFSET( s, t, m )						\
-   printf( "#define %s\t%ld\n", s, offsetof( t, m ) );
-#else
-#define OFFSET( s, t, m )						\
-   printf( "#define %s\t%d\n", s, offsetof( t, m ) );
-#endif
+   printf( "#define %s\t%lu\n", s, (unsigned long) offsetof( t, m ) );
 
-#if defined(__BEOS__) || defined(__HAIKU__) || defined(_LP64)
 #define SIZEOF( s, t )							\
-   printf( "#define %s\t%ld\n", s, sizeof(t) );
-#else
-#define SIZEOF( s, t )							\
-   printf( "#define %s\t%d\n", s, sizeof(t) );
-#endif
+   printf( "#define %s\t%lu\n", s, (unsigned long) sizeof(t) );
 
 #define DEFINE( s, d )							\
    printf( "#define %s\t0x%x\n", s, d );
@@ -120,22 +110,22 @@
    OFFSET( "VB_COUNT               ", struct vertex_buffer, Count );
    printf( "\n" );
    OFFSET( "VB_ELTS                ", struct vertex_buffer, Elts );
-   OFFSET( "VB_OBJ_PTR             ", struct vertex_buffer, ObjPtr );
+   OFFSET( "VB_OBJ_PTR             ", struct vertex_buffer, AttribPtr[_TNL_ATTRIB_POS] );
    OFFSET( "VB_EYE_PTR             ", struct vertex_buffer, EyePtr );
    OFFSET( "VB_CLIP_PTR            ", struct vertex_buffer, ClipPtr );
    OFFSET( "VB_PROJ_CLIP_PTR       ", struct vertex_buffer, NdcPtr );
    OFFSET( "VB_CLIP_OR_MASK        ", struct vertex_buffer, ClipOrMask );
    OFFSET( "VB_CLIP_MASK           ", struct vertex_buffer, ClipMask );
-   OFFSET( "VB_NORMAL_PTR          ", struct vertex_buffer, NormalPtr );
+   OFFSET( "VB_NORMAL_PTR          ", struct vertex_buffer, AttribPtr[_TNL_ATTRIB_NORMAL] );
    OFFSET( "VB_EDGE_FLAG           ", struct vertex_buffer, EdgeFlag );
-   OFFSET( "VB_TEX0_COORD_PTR      ", struct vertex_buffer, TexCoordPtr[0] );
-   OFFSET( "VB_TEX1_COORD_PTR      ", struct vertex_buffer, TexCoordPtr[1] );
-   OFFSET( "VB_TEX2_COORD_PTR      ", struct vertex_buffer, TexCoordPtr[2] );
-   OFFSET( "VB_TEX3_COORD_PTR      ", struct vertex_buffer, TexCoordPtr[3] );
-   OFFSET( "VB_INDEX_PTR           ", struct vertex_buffer, IndexPtr );
-   OFFSET( "VB_COLOR_PTR           ", struct vertex_buffer, ColorPtr );
-   OFFSET( "VB_SECONDARY_COLOR_PTR ", struct vertex_buffer, SecondaryColorPtr );
-   OFFSET( "VB_FOG_COORD_PTR       ", struct vertex_buffer, FogCoordPtr );
+   OFFSET( "VB_TEX0_COORD_PTR      ", struct vertex_buffer, AttribPtr[_TNL_ATTRIB_TEX0] );
+   OFFSET( "VB_TEX1_COORD_PTR      ", struct vertex_buffer, AttribPtr[_TNL_ATTRIB_TEX1] );
+   OFFSET( "VB_TEX2_COORD_PTR      ", struct vertex_buffer, AttribPtr[_TNL_ATTRIB_TEX2] );
+   OFFSET( "VB_TEX3_COORD_PTR      ", struct vertex_buffer, AttribPtr[_TNL_ATTRIB_TEX3] );
+   OFFSET( "VB_INDEX_PTR           ", struct vertex_buffer, AttribPtr[_TNL_ATTRIB_COLOR_INDEX] );
+   OFFSET( "VB_COLOR_PTR           ", struct vertex_buffer, AttribPtr[_TNL_ATTRIB_COLOR0] );
+   OFFSET( "VB_SECONDARY_COLOR_PTR ", struct vertex_buffer, AttribPtr[_TNL_ATTRIB_COLOR1] );
+   OFFSET( "VB_FOG_COORD_PTR       ", struct vertex_buffer, AttribPtr[_TNL_ATTRIB_FOG] );
    OFFSET( "VB_PRIMITIVE           ", struct vertex_buffer, Primitive );
    printf( "\n" );
 
diff --git a/src/mesa/x86/glapi_x86.S b/src/mesa/x86/glapi_x86.S
index 117e31e..2e640ec 100644
--- a/src/mesa/x86/glapi_x86.S
+++ b/src/mesa/x86/glapi_x86.S
@@ -968,21 +968,29 @@
 	GL_STUB(_dispatch_stub_785, _gloffset_FlushMappedBufferRangeAPPLE, _dispatch_stub_785@12)
 	HIDDEN(GL_PREFIX(_dispatch_stub_785, _dispatch_stub_785@12))
 	GL_STUB(FramebufferTextureLayerEXT, _gloffset_FramebufferTextureLayerEXT, FramebufferTextureLayerEXT@20)
+	GL_STUB(ColorMaskIndexedEXT, _gloffset_ColorMaskIndexedEXT, ColorMaskIndexedEXT@20)
+	GL_STUB(DisableIndexedEXT, _gloffset_DisableIndexedEXT, DisableIndexedEXT@8)
+	GL_STUB(EnableIndexedEXT, _gloffset_EnableIndexedEXT, EnableIndexedEXT@8)
+	GL_STUB(GetBooleanIndexedvEXT, _gloffset_GetBooleanIndexedvEXT, GetBooleanIndexedvEXT@12)
+	GL_STUB(GetIntegerIndexedvEXT, _gloffset_GetIntegerIndexedvEXT, GetIntegerIndexedvEXT@12)
+	GL_STUB(IsEnabledIndexedEXT, _gloffset_IsEnabledIndexedEXT, IsEnabledIndexedEXT@8)
+	GL_STUB(BeginConditionalRenderNV, _gloffset_BeginConditionalRenderNV, BeginConditionalRenderNV@8)
+	GL_STUB(EndConditionalRenderNV, _gloffset_EndConditionalRenderNV, EndConditionalRenderNV@0)
 	GL_STUB(ProvokingVertexEXT, _gloffset_ProvokingVertexEXT, ProvokingVertexEXT@4)
-	GL_STUB(_dispatch_stub_788, _gloffset_GetTexParameterPointervAPPLE, _dispatch_stub_788@12)
-	HIDDEN(GL_PREFIX(_dispatch_stub_788, _dispatch_stub_788@12))
-	GL_STUB(_dispatch_stub_789, _gloffset_TextureRangeAPPLE, _dispatch_stub_789@12)
-	HIDDEN(GL_PREFIX(_dispatch_stub_789, _dispatch_stub_789@12))
-	GL_STUB(_dispatch_stub_790, _gloffset_StencilFuncSeparateATI, _dispatch_stub_790@16)
-	HIDDEN(GL_PREFIX(_dispatch_stub_790, _dispatch_stub_790@16))
-	GL_STUB(_dispatch_stub_791, _gloffset_ProgramEnvParameters4fvEXT, _dispatch_stub_791@16)
-	HIDDEN(GL_PREFIX(_dispatch_stub_791, _dispatch_stub_791@16))
-	GL_STUB(_dispatch_stub_792, _gloffset_ProgramLocalParameters4fvEXT, _dispatch_stub_792@16)
-	HIDDEN(GL_PREFIX(_dispatch_stub_792, _dispatch_stub_792@16))
-	GL_STUB(_dispatch_stub_793, _gloffset_GetQueryObjecti64vEXT, _dispatch_stub_793@12)
-	HIDDEN(GL_PREFIX(_dispatch_stub_793, _dispatch_stub_793@12))
-	GL_STUB(_dispatch_stub_794, _gloffset_GetQueryObjectui64vEXT, _dispatch_stub_794@12)
-	HIDDEN(GL_PREFIX(_dispatch_stub_794, _dispatch_stub_794@12))
+	GL_STUB(_dispatch_stub_796, _gloffset_GetTexParameterPointervAPPLE, _dispatch_stub_796@12)
+	HIDDEN(GL_PREFIX(_dispatch_stub_796, _dispatch_stub_796@12))
+	GL_STUB(_dispatch_stub_797, _gloffset_TextureRangeAPPLE, _dispatch_stub_797@12)
+	HIDDEN(GL_PREFIX(_dispatch_stub_797, _dispatch_stub_797@12))
+	GL_STUB(_dispatch_stub_798, _gloffset_StencilFuncSeparateATI, _dispatch_stub_798@16)
+	HIDDEN(GL_PREFIX(_dispatch_stub_798, _dispatch_stub_798@16))
+	GL_STUB(_dispatch_stub_799, _gloffset_ProgramEnvParameters4fvEXT, _dispatch_stub_799@16)
+	HIDDEN(GL_PREFIX(_dispatch_stub_799, _dispatch_stub_799@16))
+	GL_STUB(_dispatch_stub_800, _gloffset_ProgramLocalParameters4fvEXT, _dispatch_stub_800@16)
+	HIDDEN(GL_PREFIX(_dispatch_stub_800, _dispatch_stub_800@16))
+	GL_STUB(_dispatch_stub_801, _gloffset_GetQueryObjecti64vEXT, _dispatch_stub_801@12)
+	HIDDEN(GL_PREFIX(_dispatch_stub_801, _dispatch_stub_801@12))
+	GL_STUB(_dispatch_stub_802, _gloffset_GetQueryObjectui64vEXT, _dispatch_stub_802@12)
+	HIDDEN(GL_PREFIX(_dispatch_stub_802, _dispatch_stub_802@12))
 	GL_STUB_ALIAS(ArrayElementEXT, _gloffset_ArrayElement, ArrayElementEXT@4, ArrayElement, ArrayElement@4)
 	GL_STUB_ALIAS(BindTextureEXT, _gloffset_BindTexture, BindTextureEXT@8, BindTexture, BindTexture@8)
 	GL_STUB_ALIAS(DrawArraysEXT, _gloffset_DrawArrays, DrawArraysEXT@12, DrawArrays, DrawArrays@12)
@@ -1226,6 +1234,7 @@
 	GL_STUB_ALIAS(GetAttribLocation, _gloffset_GetAttribLocationARB, GetAttribLocation@8, GetAttribLocationARB, GetAttribLocationARB@8)
 	GL_STUB_ALIAS(DrawBuffers, _gloffset_DrawBuffersARB, DrawBuffers@8, DrawBuffersARB, DrawBuffersARB@8)
 	GL_STUB_ALIAS(DrawBuffersATI, _gloffset_DrawBuffersARB, DrawBuffersATI@8, DrawBuffersARB, DrawBuffersARB@8)
+	GL_STUB_ALIAS(RenderbufferStorageMultisampleEXT, _gloffset_RenderbufferStorageMultisample, RenderbufferStorageMultisampleEXT@20, RenderbufferStorageMultisample, RenderbufferStorageMultisample@20)
 	GL_STUB_ALIAS(PointParameterf, _gloffset_PointParameterfEXT, PointParameterf@8, PointParameterfEXT, PointParameterfEXT@8)
 	GL_STUB_ALIAS(PointParameterfARB, _gloffset_PointParameterfEXT, PointParameterfARB@8, PointParameterfEXT, PointParameterfEXT@8)
 	GL_STUB_ALIAS(PointParameterfSGIS, _gloffset_PointParameterfEXT, PointParameterfSGIS@8, PointParameterfEXT, PointParameterfEXT@8)
diff --git a/src/mesa/x86/rtasm/x86sse.c b/src/mesa/x86/rtasm/x86sse.c
index 5aedf5b..647be99 100644
--- a/src/mesa/x86/rtasm/x86sse.c
+++ b/src/mesa/x86/rtasm/x86sse.c
@@ -7,10 +7,12 @@
 #define DISASSEM 0
 #define X86_TWOB 0x0f
 
+#if 0
 static unsigned char *cptr( void (*label)() )
 {
    return (unsigned char *)(unsigned long)label;
 }
+#endif
 
 
 static void do_realloc( struct x86_function *p )
diff --git a/windows/VC6/progs/glut/glut.dsp b/windows/VC6/progs/glut/glut.dsp
deleted file mode 100644
index 0a67689..0000000
--- a/windows/VC6/progs/glut/glut.dsp
+++ /dev/null
@@ -1,333 +0,0 @@
-# Microsoft Developer Studio Project File - Name="glut" - Package Owner=<4>

-# Microsoft Developer Studio Generated Build File, Format Version 6.00

-# ** DO NOT EDIT **

-

-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102

-

-CFG=glut - Win32 Debug

-!MESSAGE This is not a valid makefile. To build this project using NMAKE,

-!MESSAGE use the Export Makefile command and run

-!MESSAGE 

-!MESSAGE NMAKE /f "glut.mak".

-!MESSAGE 

-!MESSAGE You can specify a configuration when running NMAKE

-!MESSAGE by defining the macro CFG on the command line. For example:

-!MESSAGE 

-!MESSAGE NMAKE /f "glut.mak" CFG="glut - Win32 Debug"

-!MESSAGE 

-!MESSAGE Possible choices for configuration are:

-!MESSAGE 

-!MESSAGE "glut - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")

-!MESSAGE "glut - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")

-!MESSAGE 

-

-# Begin Project

-# PROP AllowPerConfigDependencies 0

-# PROP Scc_ProjName ""

-# PROP Scc_LocalPath ""

-CPP=cl.exe

-MTL=midl.exe

-RSC=rc.exe

-

-!IF  "$(CFG)" == "glut - Win32 Release"

-

-# PROP BASE Use_MFC 0

-# PROP BASE Use_Debug_Libraries 0

-# PROP BASE Output_Dir "Release"

-# PROP BASE Intermediate_Dir "Release"

-# PROP BASE Target_Dir ""

-# PROP Use_MFC 0

-# PROP Use_Debug_Libraries 0

-# PROP Output_Dir "Release"

-# PROP Intermediate_Dir "Release"

-# PROP Ignore_Export_Lib 0

-# PROP Target_Dir ""

-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GLUT_EXPORTS" /YX /FD /c

-# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_DLL" /D "_USRDLL" /D "GLUT_EXPORTS" /D "MESA" /D "BUILD_GL32" /FD /c

-# SUBTRACT CPP /YX

-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32

-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32

-# ADD BASE RSC /l 0x409 /d "NDEBUG"

-# ADD RSC /l 0x409 /d "NDEBUG"

-BSC32=bscmake.exe

-# ADD BASE BSC32 /nologo

-# ADD BSC32 /nologo

-LINK32=link.exe

-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386

-# ADD LINK32 opengl32.lib glu32.lib winmm.lib msvcrt.lib oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /nodefaultlib /out:"Release/GLUT32.DLL" /libpath:"../../mesa/Release"

-# Begin Special Build Tool

-SOURCE="$(InputPath)"

-PostBuild_Cmds=if not exist ..\..\..\..\lib md ..\..\..\..\lib	copy Release\GLUT32.LIB ..\..\..\..\lib	copy Release\GLUT32.DLL ..\..\..\..\lib	if exist ..\..\..\..\progs\demos copy Release\GLUT32.DLL ..\..\..\..\progs\demos

-# End Special Build Tool

-

-!ELSEIF  "$(CFG)" == "glut - Win32 Debug"

-

-# PROP BASE Use_MFC 0

-# PROP BASE Use_Debug_Libraries 1

-# PROP BASE Output_Dir "Debug"

-# PROP BASE Intermediate_Dir "Debug"

-# PROP BASE Target_Dir ""

-# PROP Use_MFC 0

-# PROP Use_Debug_Libraries 1

-# PROP Output_Dir "Debug"

-# PROP Intermediate_Dir "Debug"

-# PROP Ignore_Export_Lib 0

-# PROP Target_Dir ""

-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GLUT_EXPORTS" /YX /FD /GZ /c

-# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "../../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_DLL" /D "_USRDLL" /D "GLUT_EXPORTS" /D "MESA" /D "BUILD_GL32" /FD /GZ /c

-# SUBTRACT CPP /YX

-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32

-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32

-# ADD BASE RSC /l 0x409 /d "_DEBUG"

-# ADD RSC /l 0x409 /d "_DEBUG"

-BSC32=bscmake.exe

-# ADD BASE BSC32 /nologo

-# ADD BSC32 /nologo

-LINK32=link.exe

-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept

-# ADD LINK32 winmm.lib msvcrtd.lib oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib /nologo /dll /incremental:no /debug /machine:I386 /nodefaultlib /out:"Debug/GLUT32.DLL" /pdbtype:sept /libpath:"../../mesa/Debug"

-# Begin Special Build Tool

-SOURCE="$(InputPath)"

-PostBuild_Cmds=if not exist ..\..\..\..\lib md ..\..\..\..\lib	copy Debug\GLUT32.LIB ..\..\..\..\lib	copy Debug\GLUT32.DLL ..\..\..\..\lib	if exist ..\..\..\..\progs\demos copy Debug\GLUT32.DLL ..\..\..\..\progs\demos

-# End Special Build Tool

-

-!ENDIF 

-

-# Begin Target

-

-# Name "glut - Win32 Release"

-# Name "glut - Win32 Debug"

-# Begin Group "Source Files"

-

-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_8x13.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_9x15.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_bitmap.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_bwidth.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_cindex.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_cmap.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_cursor.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_dials.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_dstr.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_event.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_ext.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_fcb.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_fullscrn.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_gamemode.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_get.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_hel10.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_hel12.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_hel18.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_init.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_input.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_joy.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_key.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_keyctrl.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_keyup.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_mesa.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_modifier.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_mroman.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_overlay.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_roman.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_shapes.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_space.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_stroke.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_swap.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_swidth.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_tablet.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_teapot.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_tr10.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_tr24.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_util.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_vidresize.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_warp.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_win.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glut_winmisc.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\win32_glx.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\win32_menu.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\win32_util.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\win32_winproc.c

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\win32_x11.c

-# End Source File

-# End Group

-# Begin Group "Header Files"

-

-# PROP Default_Filter "h;hpp;hxx;hm;inl"

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glutbitmap.h

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glutint.h

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glutstroke.h

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\glutwin32.h

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\stroke.h

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\win32_glx.h

-# End Source File

-# Begin Source File

-

-SOURCE=..\..\..\..\src\glut\glx\win32_x11.h

-# End Source File

-# End Group

-# Begin Group "Resource Files"

-

-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"

-# End Group

-# End Target

-# End Project

diff --git a/windows/VC7/mesa/mesa/mesa.vcproj b/windows/VC7/mesa/mesa/mesa.vcproj
index 3a93544..caee6c0 100644
--- a/windows/VC7/mesa/mesa/mesa.vcproj
+++ b/windows/VC7/mesa/mesa/mesa.vcproj
@@ -22,7 +22,7 @@
 				Name="VCCLCompilerTool"

 				AdditionalOptions="/Zm1000 "

 				InlineFunctionExpansion="1"

-				AdditionalIncludeDirectories="../../../../include,../../../../src/mesa,../../../../src/mesa/glapi,../../../../src/mesa/main,../../../../src/mesa/shader,../../../../src/mesa/shader/slang,../../../../src/mesa/shader/grammar"

+				AdditionalIncludeDirectories="../../../../include,../../../../src/mesa,../../../../src/mesa/glapi,../../../../src/mesa/main,../../../../src/mesa/shader,../../../../src/mesa/shader/slang"

 				PreprocessorDefinitions="NDEBUG,WIN32,_LIB,_DLL,BUILD_GL32,MESA_MINWARN"

 				StringPooling="TRUE"

 				RuntimeLibrary="4"

@@ -74,7 +74,7 @@
 				Name="VCCLCompilerTool"

 				AdditionalOptions="/Zm1000 "

 				Optimization="0"

-				AdditionalIncludeDirectories="../../../../include,../../../../src/mesa,../../../../src/mesa/glapi,../../../../src/mesa/main,../../../../src/mesa/shader,../../../../src/mesa/shader/slang,../../../../src/mesa/shader/grammar"

+				AdditionalIncludeDirectories="../../../../include,../../../../src/mesa,../../../../src/mesa/glapi,../../../../src/mesa/main,../../../../src/mesa/shader,../../../../src/mesa/shader/slang"

 				PreprocessorDefinitions="_DEBUG,WIN32,_LIB,_DLL,BUILD_GL32,MESA_MINWARN"

 				BasicRuntimeChecks="3"

 				RuntimeLibrary="5"

@@ -230,33 +230,6 @@
 				RelativePath="..\..\..\..\src\mesa\glapi\glthread.c">

 			</File>

 			<File

-				RelativePath="..\..\..\..\src\mesa\shader\grammar\grammar.c">

-				<FileConfiguration

-					Name="Release|Win32"

-					ExcludedFromBuild="TRUE">

-					<Tool

-						Name="VCCLCompilerTool"/>

-				</FileConfiguration>

-				<FileConfiguration

-					Name="Debug|Win32"

-					ExcludedFromBuild="TRUE">

-					<Tool

-						Name="VCCLCompilerTool"/>

-				</FileConfiguration>

-			</File>

-			<File

-				RelativePath="..\..\..\..\src\mesa\shader\grammar\grammar_crt.c">

-				<FileConfiguration

-					Name="Debug|Win32"

-					ExcludedFromBuild="TRUE">

-					<Tool

-						Name="VCCLCompilerTool"/>

-				</FileConfiguration>

-			</File>

-			<File

-				RelativePath="..\..\..\..\src\mesa\shader\grammar\grammar_mesa.c">

-			</File>

-			<File

 				RelativePath="..\..\..\..\src\mesa\main\hash.c">

 			</File>

 			<File

@@ -810,18 +783,6 @@
 				RelativePath="..\..\..\..\src\mesa\glapi\glthread.h">

 			</File>

 			<File

-				RelativePath="..\..\..\..\src\mesa\shader\grammar\grammar.h">

-			</File>

-			<File

-				RelativePath="..\..\..\..\src\mesa\shader\grammar\grammar_crt.h">

-			</File>

-			<File

-				RelativePath="..\..\..\..\src\mesa\shader\grammar\grammar_mesa.h">

-			</File>

-			<File

-				RelativePath="..\..\..\..\src\mesa\shader\grammar\grammar_syn.h">

-			</File>

-			<File

 				RelativePath="..\..\..\..\src\mesa\main\hash.h">

 			</File>

 			<File

diff --git a/windows/VC8/mesa/mesa/mesa.vcproj b/windows/VC8/mesa/mesa/mesa.vcproj
index 993c28d..05bf7d2 100644
--- a/windows/VC8/mesa/mesa/mesa.vcproj
+++ b/windows/VC8/mesa/mesa/mesa.vcproj
@@ -43,7 +43,7 @@
 				Name="VCCLCompilerTool"

 				AdditionalOptions="/Zm1000 "

 				InlineFunctionExpansion="1"

-				AdditionalIncludeDirectories="../../../../include,../../../../src/mesa,../../../../src/mesa/glapi,../../../../src/mesa/main,../../../../src/mesa/shader,../../../../src/mesa/shader/slang,../../../../src/mesa/shader/grammar"

+				AdditionalIncludeDirectories="../../../../include,../../../../src/mesa,../../../../src/mesa/glapi,../../../../src/mesa/main,../../../../src/mesa/shader,../../../../src/mesa/shader/slang"

 				PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_DLL;BUILD_GL32;MESA_MINWARN;_CRT_SECURE_NO_DEPRECATE"

 				StringPooling="true"

 				RuntimeLibrary="2"

@@ -114,7 +114,7 @@
 				Name="VCCLCompilerTool"

 				AdditionalOptions="/Zm1000 "

 				Optimization="0"

-				AdditionalIncludeDirectories="../../../../include,../../../../src/mesa,../../../../src/mesa/glapi,../../../../src/mesa/main,../../../../src/mesa/shader,../../../../src/mesa/shader/slang,../../../../src/mesa/shader/grammar"

+				AdditionalIncludeDirectories="../../../../include,../../../../src/mesa,../../../../src/mesa/glapi,../../../../src/mesa/main,../../../../src/mesa/shader,../../../../src/mesa/shader/slang"

 				PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_DLL;BUILD_GL32;MESA_MINWARN;_CRT_SECURE_NO_DEPRECATE"

 				BasicRuntimeChecks="3"

 				RuntimeLibrary="3"

@@ -185,7 +185,7 @@
 				Name="VCCLCompilerTool"

 				AdditionalOptions="/Zm1000 "

 				Optimization="0"

-				AdditionalIncludeDirectories="../../../../include,../../../../src/mesa,../../../../src/mesa/glapi,../../../../src/mesa/main,../../../../src/mesa/shader,../../../../src/mesa/shader/slang,../../../../src/mesa/shader/grammar"

+				AdditionalIncludeDirectories="../../../../include,../../../../src/mesa,../../../../src/mesa/glapi,../../../../src/mesa/main,../../../../src/mesa/shader,../../../../src/mesa/shader/slang"

 				PreprocessorDefinitions="_DEBUG;WIN32;_LIB;BUILD_GL32;MESA_MINWARN;_CRT_SECURE_NO_DEPRECATE"

 				BasicRuntimeChecks="3"

 				RuntimeLibrary="1"

@@ -256,7 +256,7 @@
 				Name="VCCLCompilerTool"

 				AdditionalOptions="/Zm1000 "

 				InlineFunctionExpansion="1"

-				AdditionalIncludeDirectories="../../../../include,../../../../src/mesa,../../../../src/mesa/glapi,../../../../src/mesa/main,../../../../src/mesa/shader,../../../../src/mesa/shader/slang,../../../../src/mesa/shader/grammar"

+				AdditionalIncludeDirectories="../../../../include,../../../../src/mesa,../../../../src/mesa/glapi,../../../../src/mesa/main,../../../../src/mesa/shader,../../../../src/mesa/shader/slang"

 				PreprocessorDefinitions="NDEBUG;WIN32;_LIB;BUILD_GL32;MESA_MINWARN;_CRT_SECURE_NO_DEPRECATE"

 				StringPooling="true"

 				RuntimeLibrary="0"

@@ -475,10 +475,6 @@
 				>

 			</File>

 			<File

-				RelativePath="..\..\..\..\src\mesa\shader\grammar\grammar_mesa.c"

-				>

-			</File>

-			<File

 				RelativePath="..\..\..\..\src\mesa\main\hash.c"

 				>

 			</File>

@@ -1360,22 +1356,6 @@
 				>

 			</File>

 			<File

-				RelativePath="..\..\..\..\src\mesa\shader\grammar\grammar.h"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\..\src\mesa\shader\grammar\grammar_crt.h"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\..\src\mesa\shader\grammar\grammar_mesa.h"

-				>

-			</File>

-			<File

-				RelativePath="..\..\..\..\src\mesa\shader\grammar\grammar_syn.h"

-				>

-			</File>

-			<File

 				RelativePath="..\..\..\..\src\mesa\main\hash.h"

 				>

 			</File>